KM_SOFTIRQ1,
};
-void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
-{
- if (nbytes <= walk->len_this_page &&
- (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
- PAGE_CACHE_SIZE)
- return walk->data;
- else
- return scratch;
-}
-
static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
{
if (out)
walk->page = sg->page;
walk->len_this_segment = sg->length;
+ BUG_ON(!sg->length);
+
rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
walk->len_this_page = min(sg->length, rest_of_page);
walk->offset = sg->offset;
walk->data = crypto_kmap(walk->page, out) + walk->offset;
}
-static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
- unsigned int more)
+static inline void scatterwalk_unmap(struct scatter_walk *walk, int out)
{
/* walk->data may be pointing the first byte of the next page;
however, we know we transfered at least one byte. So,
- walk->data - 1 will be a virutual address in the mapped page. */
+ walk->data - 1 will be a virtual address in the mapped page. */
+ crypto_kunmap(walk->data - 1, out);
+}
+static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
+ unsigned int more)
+{
if (out)
flush_dcache_page(walk->page);
void scatterwalk_done(struct scatter_walk *walk, int out, int more)
{
- crypto_kunmap(walk->data, out);
+ scatterwalk_unmap(walk, out);
if (walk->len_this_page == 0 || !more)
scatterwalk_pagedone(walk, out, more);
}
int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
size_t nbytes, int out)
{
- if (buf != walk->data) {
- while (nbytes > walk->len_this_page) {
- memcpy_dir(buf, walk->data, walk->len_this_page, out);
- buf += walk->len_this_page;
- nbytes -= walk->len_this_page;
-
- crypto_kunmap(walk->data, out);
- scatterwalk_pagedone(walk, out, 1);
- scatterwalk_map(walk, out);
- }
-
- memcpy_dir(buf, walk->data, nbytes, out);
+ while (nbytes > walk->len_this_page) {
+ memcpy_dir(buf, walk->data, walk->len_this_page, out);
+ buf += walk->len_this_page;
+ nbytes -= walk->len_this_page;
+
+ scatterwalk_unmap(walk, out);
+ scatterwalk_pagedone(walk, out, 1);
+ scatterwalk_map(walk, out);
}
- walk->offset += nbytes;
- walk->len_this_page -= nbytes;
- walk->len_this_segment -= nbytes;
- return 0;
+ memcpy_dir(buf, walk->data, nbytes, out);
+ return nbytes;
}