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
*
* 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 21:56:17 +10:00
2007-12-07 18:52:49 +08:00
# include <asm/kmap_types.h>
# include <crypto/algapi.h>
# include <linux/hardirq.h>
# include <linux/highmem.h>
# include <linux/kernel.h>
2005-04-16 15:20:36 -07:00
# include <linux/mm.h>
2006-08-12 21:56:17 +10:00
# include <linux/scatterlist.h>
2007-12-24 08:54:24 +08:00
# include <linux/sched.h>
2005-04-16 15:20:36 -07:00
2007-12-07 18:52:49 +08:00
static inline enum km_type crypto_kmap_type ( int out )
{
enum km_type type ;
if ( in_softirq ( ) )
type = out * ( KM_SOFTIRQ1 - KM_SOFTIRQ0 ) + KM_SOFTIRQ0 ;
else
type = out * ( KM_USER1 - KM_USER0 ) + KM_USER0 ;
return type ;
}
static inline void * crypto_kmap ( struct page * page , int out )
{
return kmap_atomic ( page , crypto_kmap_type ( out ) ) ;
}
static inline void crypto_kunmap ( void * vaddr , int out )
{
kunmap_atomic ( vaddr , crypto_kmap_type ( out ) ) ;
}
static inline void crypto_yield ( u32 flags )
{
if ( flags & CRYPTO_TFM_REQ_MAY_SLEEP )
cond_resched ( ) ;
}
2005-04-16 15:20:36 -07:00
2007-12-05 20:59:25 +11: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 21:53:52 +08:00
sg1 [ num - 1 ] . page_link & = ~ 0x02 ;
2007-12-05 20:59:25 +11:00
}
static inline struct scatterlist * scatterwalk_sg_next ( struct scatterlist * sg )
{
2008-04-29 21:53:52 +08:00
if ( sg_is_last ( sg ) )
return NULL ;
2007-12-05 20:59:25 +11:00
return ( + + sg ) - > length ? sg : ( void * ) sg_page ( sg ) ;
}
2006-08-12 21:56:17 +10:00
static inline unsigned long scatterwalk_samebuf ( struct scatter_walk * walk_in ,
struct scatter_walk * walk_out )
2005-04-16 15:20:36 -07:00
{
2007-10-22 19:40:16 +02:00
return ! ( ( ( sg_page ( walk_in - > sg ) - sg_page ( walk_out - > sg ) ) < < PAGE_SHIFT ) +
2006-08-12 21:56:17 +10: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-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
}
static inline void scatterwalk_unmap ( void * vaddr , int out )
{
crypto_kunmap ( vaddr , out ) ;
}
2005-04-16 15:20:36 -07:00
void scatterwalk_start ( struct scatter_walk * walk , struct scatterlist * sg ) ;
2006-08-12 21:56:17 +10:00
void scatterwalk_copychunks ( void * buf , struct scatter_walk * walk ,
size_t nbytes , int out ) ;
void * scatterwalk_map ( struct scatter_walk * walk , int out ) ;
2005-04-16 15:20:36 -07:00
void scatterwalk_done ( struct scatter_walk * walk , int out , int more ) ;
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 ) ;
2005-04-16 15:20:36 -07:00
# endif /* _CRYPTO_SCATTERWALK_H */