2005-04-17 02:20:36 +04:00
/*
2007-12-07 13:52:49 +03:00
* Cryptographic scatter and gather helpers .
2005-04-17 02:20:36 +04: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 13:52:49 +03:00
* Copyright ( c ) 2007 Herbert Xu < herbert @ gondor . apana . org . au >
2005-04-17 02:20:36 +04:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation ; either version 2 of the License , or ( at your option )
* any later version .
*
*/
# ifndef _CRYPTO_SCATTERWALK_H
# define _CRYPTO_SCATTERWALK_H
2006-08-12 15:56:17 +04:00
2007-12-07 13:52:49 +03:00
# include <asm/kmap_types.h>
# include <crypto/algapi.h>
# include <linux/hardirq.h>
# include <linux/highmem.h>
# include <linux/kernel.h>
2005-04-17 02:20:36 +04:00
# include <linux/mm.h>
2006-08-12 15:56:17 +04:00
# include <linux/scatterlist.h>
2007-12-24 03:54:24 +03:00
# include <linux/sched.h>
2005-04-17 02:20:36 +04:00
2007-12-05 12:59:25 +03:00
static inline void scatterwalk_sg_chain ( struct scatterlist * sg1 , int num ,
struct scatterlist * sg2 )
{
sg_set_page ( & sg1 [ num - 1 ] , ( void * ) sg2 , 0 , 0 ) ;
2008-04-29 17:53:52 +04:00
sg1 [ num - 1 ] . page_link & = ~ 0x02 ;
2013-11-12 21:46:10 +04:00
sg1 [ num - 1 ] . page_link | = 0x01 ;
2007-12-05 12:59:25 +03:00
}
2010-11-22 13:25:50 +03:00
static inline void scatterwalk_crypto_chain ( struct scatterlist * head ,
struct scatterlist * sg ,
int chain , int num )
{
if ( chain ) {
head - > length + = sg - > length ;
2015-01-20 11:06:16 +03:00
sg = sg_next ( sg ) ;
2010-11-22 13:25:50 +03:00
}
if ( sg )
scatterwalk_sg_chain ( head , num , sg ) ;
else
sg_mark_end ( head ) ;
}
2006-08-12 15:56:17 +04:00
static inline unsigned long scatterwalk_samebuf ( struct scatter_walk * walk_in ,
struct scatter_walk * walk_out )
2005-04-17 02:20:36 +04:00
{
2007-10-22 21:40:16 +04:00
return ! ( ( ( sg_page ( walk_in - > sg ) - sg_page ( walk_out - > sg ) ) < < PAGE_SHIFT ) +
2006-08-12 15:56:17 +04:00
( int ) ( walk_in - > offset - walk_out - > offset ) ) ;
}
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-17 02:20:36 +04:00
}
2005-07-07 00:51:31 +04:00
static inline unsigned int scatterwalk_clamp ( struct scatter_walk * walk ,
unsigned int nbytes )
2005-04-17 02:20:36 +04:00
{
2006-08-12 15:56:17 +04:00
unsigned int len_this_page = scatterwalk_pagelen ( walk ) ;
return nbytes > len_this_page ? len_this_page : nbytes ;
2005-04-17 02:20:36 +04:00
}
static inline void scatterwalk_advance ( struct scatter_walk * walk ,
unsigned int nbytes )
{
walk - > offset + = nbytes ;
}
2005-07-07 00:52:09 +04:00
static inline unsigned int scatterwalk_aligned ( struct scatter_walk * walk ,
unsigned int alignmask )
{
return ! ( walk - > offset & alignmask ) ;
}
2006-08-12 15:56:17 +04:00
static inline struct page * scatterwalk_page ( struct scatter_walk * walk )
{
2007-10-22 21:40:16 +04:00
return sg_page ( walk - > sg ) + ( walk - > offset > > PAGE_SHIFT ) ;
2006-08-12 15:56:17 +04:00
}
2011-11-25 19:14:17 +04:00
static inline void scatterwalk_unmap ( void * vaddr )
2006-08-12 15:56:17 +04:00
{
2011-11-25 19:14:17 +04:00
kunmap_atomic ( vaddr ) ;
2006-08-12 15:56:17 +04:00
}
2005-04-17 02:20:36 +04:00
void scatterwalk_start ( struct scatter_walk * walk , struct scatterlist * sg ) ;
2006-08-12 15:56:17 +04:00
void scatterwalk_copychunks ( void * buf , struct scatter_walk * walk ,
size_t nbytes , int out ) ;
2011-11-25 19:14:17 +04:00
void * scatterwalk_map ( struct scatter_walk * walk ) ;
2005-04-17 02:20:36 +04:00
void scatterwalk_done ( struct scatter_walk * walk , int out , int more ) ;
2007-08-29 12:31:34 +04:00
void scatterwalk_map_and_copy ( void * buf , struct scatterlist * sg ,
unsigned int start , unsigned int nbytes , int out ) ;
2013-08-18 06:42:22 +04:00
int scatterwalk_bytes_sglen ( struct scatterlist * sg , int num_bytes ) ;
2005-04-17 02:20:36 +04:00
# endif /* _CRYPTO_SCATTERWALK_H */