From 90845dc542f646fbb796da06e11f6459cb2a8171 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Tigeot?= Date: Wed, 20 Jul 2016 23:22:57 +0200 Subject: [PATCH] linux/scatterlist.h: Add __sg_page_iter_next() Obtained-from: Matt Macy --- sys/dev/drm/include/linux/scatterlist.h | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/sys/dev/drm/include/linux/scatterlist.h b/sys/dev/drm/include/linux/scatterlist.h index 26204dc0cc..9b8bf65e7b 100644 --- a/sys/dev/drm/include/linux/scatterlist.h +++ b/sys/dev/drm/include/linux/scatterlist.h @@ -4,6 +4,7 @@ * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. * Copyright (c) 2015 Matthew Dillon + * Copyright (c) 2016 Matt Macy * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -72,6 +73,8 @@ struct sg_page_iter { struct scatterlist *sg; unsigned int sg_pgoffset; /* page index */ unsigned int maxents; + unsigned int __nents; + int __pg_advance; }; @@ -339,6 +342,27 @@ sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask) return ret; } +static inline int +sg_nents(struct scatterlist *sg) +{ + int nents; + for (nents = 0; sg; sg = sg_next(sg)) + nents++; + return nents; +} + +static inline void +__sg_page_iter_start(struct sg_page_iter *piter, + struct scatterlist *sglist, unsigned int nents, + unsigned long pgoffset) +{ + piter->__pg_advance = 0; + piter->__nents = nents; + + piter->sg = sglist; + piter->sg_pgoffset = pgoffset; +} + /* * Iterate pages in sg list. */ @@ -363,6 +387,34 @@ _sg_iter_next(struct sg_page_iter *iter) iter->sg = sg; } +static inline int +sg_page_count(struct scatterlist *sg) +{ + return PAGE_ALIGN(sg->offset + sg->length) >> PAGE_SHIFT; +} + +static inline bool +__sg_page_iter_next(struct sg_page_iter *piter) +{ + if (piter->__nents == 0) + return (false); + if (piter->sg == NULL) + return (false); + + piter->sg_pgoffset += piter->__pg_advance; + piter->__pg_advance = 1; + + while (piter->sg_pgoffset >= sg_page_count(piter->sg)) { + piter->sg_pgoffset -= sg_page_count(piter->sg); + piter->sg = sg_next(piter->sg); + if (--piter->__nents == 0) + return (false); + if (piter->sg == NULL) + return (false); + } + return (true); +} + /* * NOTE: pgoffset is really a page index, not a byte offset. */ -- 2.11.4.GIT