X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=crypto%2Fscatterwalk.c;h=3de89a424401c1918818145a3d27df627c99f7ef;hb=0198b3bcaed1374f454e56e46f0e1ca1fc24e0a1;hp=35172d3f043b47f02ef5c8e20a0ffaf7976bac5b;hpb=5c64097aa0f6dc4f27718ef47ca9a12538d62860;p=safe%2Fjmp%2Flinux-2.6 diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 35172d3..3de89a4 100644 --- a/crypto/scatterwalk.c +++ b/crypto/scatterwalk.c @@ -13,6 +13,8 @@ * any later version. * */ + +#include #include #include #include @@ -20,17 +22,6 @@ #include #include -#include "internal.h" -#include "scatterwalk.h" - -enum km_type crypto_km_types[] = { - KM_USER0, - KM_USER1, - KM_SOFTIRQ0, - KM_SOFTIRQ1, -}; -EXPORT_SYMBOL_GPL(crypto_km_types); - static inline void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out) { void *src = out ? buf : sgdata; @@ -59,14 +50,19 @@ EXPORT_SYMBOL_GPL(scatterwalk_map); static void scatterwalk_pagedone(struct scatter_walk *walk, int out, unsigned int more) { - if (out) - flush_dcache_page(scatterwalk_page(walk)); + if (out) { + struct page *page; + + page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT); + if (!PageSlab(page)) + flush_dcache_page(page); + } if (more) { walk->offset += PAGE_SIZE - 1; walk->offset &= PAGE_MASK; if (walk->offset >= walk->sg->offset + walk->sg->length) - scatterwalk_start(walk, sg_next(walk->sg)); + scatterwalk_start(walk, scatterwalk_sg_next(walk->sg)); } } @@ -91,6 +87,8 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk, memcpy_dir(buf, vaddr, len_this_page, out); scatterwalk_unmap(vaddr, out); + scatterwalk_advance(walk, len_this_page); + if (nbytes == len_this_page) break; @@ -99,7 +97,30 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk, scatterwalk_pagedone(walk, out, 1); } - - scatterwalk_advance(walk, nbytes); } EXPORT_SYMBOL_GPL(scatterwalk_copychunks); + +void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg, + unsigned int start, unsigned int nbytes, int out) +{ + struct scatter_walk walk; + unsigned int offset = 0; + + if (!nbytes) + return; + + for (;;) { + scatterwalk_start(&walk, sg); + + if (start < offset + sg->length) + break; + + offset += sg->length; + sg = scatterwalk_sg_next(sg); + } + + scatterwalk_advance(&walk, start - offset); + scatterwalk_copychunks(buf, &walk, nbytes, out); + scatterwalk_done(&walk, out, 0); +} +EXPORT_SYMBOL_GPL(scatterwalk_map_and_copy);