forked from linuxppc/linux-ci
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscatterwalk.c
112 lines (93 loc) · 2.59 KB
/
scatterwalk.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Cryptographic API.
*
* Cipher operations.
*
* Copyright (c) 2002 James Morris <[email protected]>
* 2002 Adam J. Richter <[email protected]>
* 2004 Jean-Luc Cooke <[email protected]>
*/
#include <crypto/scatterwalk.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
void scatterwalk_skip(struct scatter_walk *walk, unsigned int nbytes)
{
struct scatterlist *sg = walk->sg;
nbytes += walk->offset - sg->offset;
while (nbytes > sg->length) {
nbytes -= sg->length;
sg = sg_next(sg);
}
walk->sg = sg;
walk->offset = sg->offset + nbytes;
}
EXPORT_SYMBOL_GPL(scatterwalk_skip);
inline void memcpy_from_scatterwalk(void *buf, struct scatter_walk *walk,
unsigned int nbytes)
{
do {
const void *src_addr;
unsigned int to_copy;
src_addr = scatterwalk_next(walk, nbytes, &to_copy);
memcpy(buf, src_addr, to_copy);
scatterwalk_done_src(walk, src_addr, to_copy);
buf += to_copy;
nbytes -= to_copy;
} while (nbytes);
}
EXPORT_SYMBOL_GPL(memcpy_from_scatterwalk);
inline void memcpy_to_scatterwalk(struct scatter_walk *walk, const void *buf,
unsigned int nbytes)
{
do {
void *dst_addr;
unsigned int to_copy;
dst_addr = scatterwalk_next(walk, nbytes, &to_copy);
memcpy(dst_addr, buf, to_copy);
scatterwalk_done_dst(walk, dst_addr, to_copy);
buf += to_copy;
nbytes -= to_copy;
} while (nbytes);
}
EXPORT_SYMBOL_GPL(memcpy_to_scatterwalk);
void memcpy_from_sglist(void *buf, struct scatterlist *sg,
unsigned int start, unsigned int nbytes)
{
struct scatter_walk walk;
if (unlikely(nbytes == 0)) /* in case sg == NULL */
return;
scatterwalk_start_at_pos(&walk, sg, start);
memcpy_from_scatterwalk(buf, &walk, nbytes);
}
EXPORT_SYMBOL_GPL(memcpy_from_sglist);
void memcpy_to_sglist(struct scatterlist *sg, unsigned int start,
const void *buf, unsigned int nbytes)
{
struct scatter_walk walk;
if (unlikely(nbytes == 0)) /* in case sg == NULL */
return;
scatterwalk_start_at_pos(&walk, sg, start);
memcpy_to_scatterwalk(&walk, buf, nbytes);
}
EXPORT_SYMBOL_GPL(memcpy_to_sglist);
struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2],
struct scatterlist *src,
unsigned int len)
{
for (;;) {
if (!len)
return src;
if (src->length > len)
break;
len -= src->length;
src = sg_next(src);
}
sg_init_table(dst, 2);
sg_set_page(dst, sg_page(src), src->length - len, src->offset + len);
scatterwalk_crypto_chain(dst, sg_next(src), 2);
return dst;
}
EXPORT_SYMBOL_GPL(scatterwalk_ffwd);