#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;
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 = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+ flush_dcache_page(page);
+ }
if (more) {
walk->offset += PAGE_SIZE - 1;
memcpy_dir(buf, vaddr, len_this_page, out);
scatterwalk_unmap(vaddr, out);
+ scatterwalk_advance(walk, len_this_page);
+
if (nbytes == len_this_page)
break;
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;
+
+ for (;;) {
+ scatterwalk_start(&walk, sg);
+
+ if (start < offset + sg->length)
+ break;
+
+ offset += sg->length;
+ sg = 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);