Skip to content

Commit a7dcabc

Browse files
committed
Fix the implementation of sg_pcopy_to_buffer() and sg_pcopy_from_buffer().
This ensures that firmware loading works properly without any signature errors. Issue: #149 Issue: #151 Signed-off-by: Hans Petter Selasky <hps@selasky.org>
1 parent f304e52 commit a7dcabc

File tree

1 file changed

+43
-42
lines changed

1 file changed

+43
-42
lines changed

sys/compat/linuxkpi/gplv2/include/linux/scatterlist.h

+43-42
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,42 @@
3131

3232
#include_next <linux/scatterlist.h>
3333

34-
/*
35-
* XXX please review these
36-
*
37-
* XXXMJ curoff is ignored
38-
*/
3934
static inline size_t
4035
sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents,
41-
const void *buf, size_t buflen, off_t skip)
36+
const void *buf, size_t buflen, off_t offset)
4237
{
4338
struct sg_page_iter iter;
4439
struct scatterlist *sg;
4540
struct page *page;
4641
void *vaddr;
47-
off_t off;
48-
int len, curlen, curoff;
42+
size_t total = 0;
43+
size_t len;
4944

50-
off = 0;
5145
for_each_sg_page(sgl, &iter, nents, 0) {
5246
sg = iter.sg;
53-
curlen = sg->length;
54-
curoff = sg->offset;
55-
if (skip != 0 && curlen >= skip) {
56-
skip -= curlen;
47+
48+
if (offset >= sg->length) {
49+
offset -= sg->length;
5750
continue;
5851
}
59-
if (skip != 0) {
60-
curlen -= skip;
61-
curoff += skip;
62-
skip = 0;
63-
}
64-
len = min(curlen, buflen - off);
52+
len = min(buflen, sg->length - offset);
53+
if (len == 0)
54+
break;
55+
6556
page = sg_page_iter_page(&iter);
66-
vaddr = ((caddr_t)kmap(page)) + sg->offset;
67-
memcpy(vaddr, (const char *)buf + off, len);
68-
off += len;
57+
vaddr = ((caddr_t)kmap(page)) + sg->offset + offset;
58+
memcpy(vaddr, buf, len);
6959
kunmap(page);
60+
61+
/* start at beginning of next page */
62+
offset = 0;
63+
64+
/* advance buffer */
65+
buf = (const char *)buf + len;
66+
buflen -= len;
67+
total += len;
7068
}
71-
return (off);
69+
return (total);
7270
}
7371

7472
static inline size_t
@@ -80,37 +78,40 @@ sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
8078

8179
static inline size_t
8280
sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents,
83-
void *buf, size_t buflen, off_t skip)
81+
void *buf, size_t buflen, off_t offset)
8482
{
8583
struct sg_page_iter iter;
8684
struct scatterlist *sg;
8785
struct page *page;
8886
void *vaddr;
89-
off_t off;
90-
int len, curlen, curoff;
87+
size_t total = 0;
88+
size_t len;
9189

92-
off = 0;
9390
for_each_sg_page(sgl, &iter, nents, 0) {
9491
sg = iter.sg;
95-
curlen = sg->length;
96-
curoff = sg->offset;
97-
if (skip != 0 && curlen >= skip) {
98-
skip -= curlen;
92+
93+
if (offset >= sg->length) {
94+
offset -= sg->length;
9995
continue;
10096
}
101-
if (skip != 0) {
102-
curlen -= skip;
103-
curoff += skip;
104-
skip = 0;
105-
}
106-
len = min(curlen, buflen - off);
97+
len = min(buflen, sg->length - offset);
98+
if (len == 0)
99+
break;
100+
107101
page = sg_page_iter_page(&iter);
108-
vaddr = (caddr_t)kmap(page) + sg->offset;
109-
memcpy(((caddr_t)buf) + off, vaddr, len);
110-
off += len;
102+
vaddr = ((caddr_t)kmap(page)) + sg->offset + offset;
103+
memcpy(buf, vaddr, len);
111104
kunmap(page);
105+
106+
/* start at beginning of next page */
107+
offset = 0;
108+
109+
/* advance buffer */
110+
buf = (char *)buf + len;
111+
buflen -= len;
112+
total += len;
112113
}
113-
return (off);
114+
return (total);
114115
}
115116

116-
#endif /* _LINUX_GPLV2_SCATTERLIST_H_ */
117+
#endif /* _LINUX_GPLV2_SCATTERLIST_H_ */

0 commit comments

Comments
 (0)