Message ID | 1489646857-10112-3-git-send-email-peterpandong@micron.com |
---|---|
State | Superseded |
Delegated to: | Boris Brezillon |
Headers | show |
On Thu, 16 Mar 2017 14:47:31 +0800 Peter Pan <peterpandong@micron.com> wrote: > Iterate nand pages by both page and oob operation. > > Signed-off-by: Peter Pan <peterpandong@micron.com> > --- > include/linux/mtd/nand.h | 28 +++++++++++++++++++++++++--- > 1 file changed, 25 insertions(+), 3 deletions(-) > > diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h > index 4a812e6..822547e 100644 > --- a/include/linux/mtd/nand.h > +++ b/include/linux/mtd/nand.h > @@ -87,6 +87,9 @@ struct nand_page_iter { > loff_t offs; > int page; > int pageoffs; > + int ooboffs; > + int oobsize; > + size_t oobleft; Maybe we should also add dataleft so that you don't have to pass start and len when you call nand_page_iter_end(). > }; > > /** > @@ -194,6 +197,7 @@ static inline int nand_per_page_oobsize(struct nand_device *nand) > * @iter: page iterator > */ > static inline void nand_page_iter_init(struct nand_device *nand, loff_t offs, > + u32 ooboffs, size_t ooblen, u32 oobsize, > struct nand_page_iter *iter) > { > u64 page = offs; > @@ -201,6 +205,9 @@ static inline void nand_page_iter_init(struct nand_device *nand, loff_t offs, > iter->pageoffs = do_div(page, nand->memorg.pagesize); > iter->page = page; > iter->offs = offs; > + iter->ooboffs = ooboffs; > + iter->oobsize = oobsize; > + iter->oobleft = ooblen; > } > > /** > @@ -214,11 +221,26 @@ static inline void nand_page_iter_next(struct nand_device *nand, > iter->page++; > iter->offs += nand_page_size(nand) - iter->pageoffs; > iter->pageoffs = 0; > + if (iter->oobleft) > + iter->oobleft -= min_t(int, iter->oobsize - iter->ooboffs, > + iter->oobleft); > +} > + > +static inline bool nand_page_iter_end(struct nand_device *nand, loff_t offs, > + u32 len, struct nand_page_iter *iter) > +{ > + if (iter->offs < offs + len) > + return false; > + if (iter->oobleft) > + return false; > + return true; > } > > -#define nand_for_each_page(nand, start, len, iter) \ > - for (nand_page_iter_init(nand, start, iter); \ > - (iter)->offs < (start) + (len); \ > +#define nand_for_each_page(nand, start, len, ooboffs, ooblen, \ > + oobsize, iter) \ > + for (nand_page_iter_init(nand, start, ooboffs, \ > + ooblen, oobsize, iter); \ > + !nand_page_iter_end(nand, start, len, iter); \ > nand_page_iter_next(nand, iter)) > > /**
Hi Boris, On Fri, Mar 17, 2017 at 9:11 PM, Boris Brezillon <boris.brezillon@free-electrons.com> wrote: > On Thu, 16 Mar 2017 14:47:31 +0800 > Peter Pan <peterpandong@micron.com> wrote: > >> Iterate nand pages by both page and oob operation. >> >> Signed-off-by: Peter Pan <peterpandong@micron.com> >> --- >> include/linux/mtd/nand.h | 28 +++++++++++++++++++++++++--- >> 1 file changed, 25 insertions(+), 3 deletions(-) >> >> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h >> index 4a812e6..822547e 100644 >> --- a/include/linux/mtd/nand.h >> +++ b/include/linux/mtd/nand.h >> @@ -87,6 +87,9 @@ struct nand_page_iter { >> loff_t offs; >> int page; >> int pageoffs; >> + int ooboffs; >> + int oobsize; >> + size_t oobleft; > > Maybe we should also add dataleft so that you don't have to pass start > and len when you call nand_page_iter_end(). Yes, it's better. Fix this in v4 Thanks, Peter Pan
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 4a812e6..822547e 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -87,6 +87,9 @@ struct nand_page_iter { loff_t offs; int page; int pageoffs; + int ooboffs; + int oobsize; + size_t oobleft; }; /** @@ -194,6 +197,7 @@ static inline int nand_per_page_oobsize(struct nand_device *nand) * @iter: page iterator */ static inline void nand_page_iter_init(struct nand_device *nand, loff_t offs, + u32 ooboffs, size_t ooblen, u32 oobsize, struct nand_page_iter *iter) { u64 page = offs; @@ -201,6 +205,9 @@ static inline void nand_page_iter_init(struct nand_device *nand, loff_t offs, iter->pageoffs = do_div(page, nand->memorg.pagesize); iter->page = page; iter->offs = offs; + iter->ooboffs = ooboffs; + iter->oobsize = oobsize; + iter->oobleft = ooblen; } /** @@ -214,11 +221,26 @@ static inline void nand_page_iter_next(struct nand_device *nand, iter->page++; iter->offs += nand_page_size(nand) - iter->pageoffs; iter->pageoffs = 0; + if (iter->oobleft) + iter->oobleft -= min_t(int, iter->oobsize - iter->ooboffs, + iter->oobleft); +} + +static inline bool nand_page_iter_end(struct nand_device *nand, loff_t offs, + u32 len, struct nand_page_iter *iter) +{ + if (iter->offs < offs + len) + return false; + if (iter->oobleft) + return false; + return true; } -#define nand_for_each_page(nand, start, len, iter) \ - for (nand_page_iter_init(nand, start, iter); \ - (iter)->offs < (start) + (len); \ +#define nand_for_each_page(nand, start, len, ooboffs, ooblen, \ + oobsize, iter) \ + for (nand_page_iter_init(nand, start, ooboffs, \ + ooblen, oobsize, iter); \ + !nand_page_iter_end(nand, start, len, iter); \ nand_page_iter_next(nand, iter)) /**
Iterate nand pages by both page and oob operation. Signed-off-by: Peter Pan <peterpandong@micron.com> --- include/linux/mtd/nand.h | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)