aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2023-01-10 10:10:30 +0000
committerJean-Sébastien Pédron <dumbbell@FreeBSD.org>2023-02-16 11:55:16 +0000
commit71e12e26417f9af8824b1cd544391d3fc7d74478 (patch)
tree974e1b0e09e61ae1f24352a3c1fafa9c5d7d0a81
parentc5c4d2f523fcef1b82a43d4bb9334e26132ea871 (diff)
downloadsrc-71e12e26417f9af8824b1cd544391d3fc7d74478.tar.gz
src-71e12e26417f9af8824b1cd544391d3fc7d74478.zip
linuxkpi: Fix `sg_alloc_table_from_pages()` to have the same API as Linux
It now returns a `struct scatterlist *` pointer instead of an error code only. The implementation is incomplete because it doesn't use the `prv` argument. Reviewed by: manu Approved by: manu Differential Revision: https://reviews.freebsd.org/D38077 (cherry picked from commit 3e0856b63fe0e375a0951e05c2ef98bb2ebd9421)
-rw-r--r--sys/compat/linuxkpi/common/include/linux/scatterlist.h44
1 files changed, 43 insertions, 1 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/scatterlist.h b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
index 86aeefafb501..d1a71258c27d 100644
--- a/sys/compat/linuxkpi/common/include/linux/scatterlist.h
+++ b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
@@ -327,18 +327,40 @@ sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
return (ret);
}
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+static inline struct scatterlist *
+__sg_alloc_table_from_pages(struct sg_table *sgt,
+ struct page **pages, unsigned int count,
+ unsigned long off, unsigned long size,
+ unsigned int max_segment,
+ struct scatterlist *prv, unsigned int left_pages,
+ gfp_t gfp_mask)
+#else
static inline int
__sg_alloc_table_from_pages(struct sg_table *sgt,
struct page **pages, unsigned int count,
unsigned long off, unsigned long size,
unsigned int max_segment, gfp_t gfp_mask)
+#endif
{
unsigned int i, segs, cur, len;
int rc;
struct scatterlist *s;
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ if (prv != NULL) {
+ panic(
+ "Support for prv != NULL not implemented in "
+ "__sg_alloc_table_from_pages()");
+ }
+#endif
+
if (__predict_false(!max_segment || offset_in_page(max_segment)))
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ return (ERR_PTR(-EINVAL));
+#else
return (-EINVAL);
+#endif
len = 0;
for (segs = i = 1; i < count; ++i) {
@@ -350,13 +372,19 @@ __sg_alloc_table_from_pages(struct sg_table *sgt,
}
}
if (__predict_false((rc = sg_alloc_table(sgt, segs, gfp_mask))))
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ return (ERR_PTR(rc));
+#else
return (rc);
+#endif
cur = 0;
- for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+ for (i = 0, s = sgt->sgl; i < sgt->orig_nents; i++) {
unsigned long seg_size;
unsigned int j;
+ s = sg_next(s);
+
len = 0;
for (j = cur + 1; j < count; ++j) {
len += PAGE_SIZE;
@@ -371,7 +399,16 @@ __sg_alloc_table_from_pages(struct sg_table *sgt,
off = 0;
cur = j;
}
+ KASSERT(s != NULL, ("s is NULL after loop in __sg_alloc_table_from_pages()"));
+
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ if (left_pages == 0)
+ sg_mark_end(s);
+
+ return (s);
+#else
return (0);
+#endif
}
static inline int
@@ -381,8 +418,13 @@ sg_alloc_table_from_pages(struct sg_table *sgt,
gfp_t gfp_mask)
{
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+ return (PTR_ERR_OR_ZERO(__sg_alloc_table_from_pages(sgt, pages, count, off, size,
+ SCATTERLIST_MAX_SEGMENT, NULL, 0, gfp_mask)));
+#else
return (__sg_alloc_table_from_pages(sgt, pages, count, off, size,
SCATTERLIST_MAX_SEGMENT, gfp_mask));
+#endif
}
static inline int