2019-05-27 08:55:01 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2005-04-16 15:20:36 -07:00
/*
2007-12-07 18:52:49 +08:00
* Cryptographic scatter and gather helpers .
2005-04-16 15:20:36 -07:00
*
* Copyright ( c ) 2002 James Morris < jmorris @ intercode . com . au >
* Copyright ( c ) 2002 Adam J . Richter < adam @ yggdrasil . com >
* Copyright ( c ) 2004 Jean - Luc Cooke < jlcooke @ certainkey . com >
2007-12-07 18:52:49 +08:00
* Copyright ( c ) 2007 Herbert Xu < herbert @ gondor . apana . org . au >
2005-04-16 15:20:36 -07:00
*/
# ifndef _CRYPTO_SCATTERWALK_H
# define _CRYPTO_SCATTERWALK_H
2006-08-12 21:56:17 +10:00
2007-12-07 18:52:49 +08:00
# include <crypto/algapi.h>
# include <linux/highmem.h>
# include <linux/kernel.h>
2006-08-12 21:56:17 +10:00
# include <linux/scatterlist.h>
2005-04-16 15:20:36 -07:00
2010-11-22 11:25:50 +01:00
static inline void scatterwalk_crypto_chain ( struct scatterlist * head ,
2018-07-23 10:01:33 -07:00
struct scatterlist * sg , int num )
2010-11-22 11:25:50 +01:00
{
if ( sg )
2015-08-07 18:15:13 +02:00
sg_chain ( head , num , sg ) ;
2010-11-22 11:25:50 +01:00
else
sg_mark_end ( head ) ;
}
2006-08-12 21:56:17 +10:00
static inline unsigned int scatterwalk_pagelen ( struct scatter_walk * walk )
{
unsigned int len = walk - > sg - > offset + walk - > sg - > length - walk - > offset ;
unsigned int len_this_page = offset_in_page ( ~ walk - > offset ) + 1 ;
return len_this_page > len ? len : len_this_page ;
2005-04-16 15:20:36 -07:00
}
2005-07-06 13:51:31 -07:00
static inline unsigned int scatterwalk_clamp ( struct scatter_walk * walk ,
unsigned int nbytes )
2005-04-16 15:20:36 -07:00
{
2006-08-12 21:56:17 +10:00
unsigned int len_this_page = scatterwalk_pagelen ( walk ) ;
return nbytes > len_this_page ? len_this_page : nbytes ;
2005-04-16 15:20:36 -07:00
}
static inline void scatterwalk_advance ( struct scatter_walk * walk ,
unsigned int nbytes )
{
walk - > offset + = nbytes ;
}
2005-07-06 13:52:09 -07:00
static inline unsigned int scatterwalk_aligned ( struct scatter_walk * walk ,
unsigned int alignmask )
{
return ! ( walk - > offset & alignmask ) ;
}
2006-08-12 21:56:17 +10:00
static inline struct page * scatterwalk_page ( struct scatter_walk * walk )
{
2007-10-22 19:40:16 +02:00
return sg_page ( walk - > sg ) + ( walk - > offset > > PAGE_SHIFT ) ;
2006-08-12 21:56:17 +10:00
}
2011-11-25 23:14:17 +08:00
static inline void scatterwalk_unmap ( void * vaddr )
2006-08-12 21:56:17 +10:00
{
2011-11-25 23:14:17 +08:00
kunmap_atomic ( vaddr ) ;
2006-08-12 21:56:17 +10:00
}
2016-07-12 13:18:00 +08:00
static inline void scatterwalk_start ( struct scatter_walk * walk ,
struct scatterlist * sg )
{
walk - > sg = sg ;
walk - > offset = sg - > offset ;
}
static inline void * scatterwalk_map ( struct scatter_walk * walk )
{
return kmap_atomic ( scatterwalk_page ( walk ) ) +
offset_in_page ( walk - > offset ) ;
}
static inline void scatterwalk_pagedone ( struct scatter_walk * walk , int out ,
unsigned int more )
{
if ( out ) {
struct page * page ;
page = sg_page ( walk - > sg ) + ( ( walk - > offset - 1 ) > > PAGE_SHIFT ) ;
2021-06-24 14:32:15 +08:00
flush_dcache_page ( page ) ;
2016-07-12 13:18:00 +08:00
}
if ( more & & walk - > offset > = walk - > sg - > offset + walk - > sg - > length )
scatterwalk_start ( walk , sg_next ( walk - > sg ) ) ;
}
static inline void scatterwalk_done ( struct scatter_walk * walk , int out ,
int more )
{
if ( ! more | | walk - > offset > = walk - > sg - > offset + walk - > sg - > length | |
! ( walk - > offset & ( PAGE_SIZE - 1 ) ) )
scatterwalk_pagedone ( walk , out , more ) ;
}
2006-08-12 21:56:17 +10:00
void scatterwalk_copychunks ( void * buf , struct scatter_walk * walk ,
size_t nbytes , int out ) ;
2011-11-25 23:14:17 +08:00
void * scatterwalk_map ( struct scatter_walk * walk ) ;
2005-04-16 15:20:36 -07:00
2007-08-29 16:31:34 +08:00
void scatterwalk_map_and_copy ( void * buf , struct scatterlist * sg ,
unsigned int start , unsigned int nbytes , int out ) ;
2015-05-21 15:10:59 +08:00
struct scatterlist * scatterwalk_ffwd ( struct scatterlist dst [ 2 ] ,
struct scatterlist * src ,
unsigned int len ) ;
2005-04-16 15:20:36 -07:00
# endif /* _CRYPTO_SCATTERWALK_H */