From: David Woodhouse Date: Sat, 21 Oct 2006 16:09:53 +0000 (+0100) Subject: [MTD] NAND: Combined oob buffer so it's contiguous with data X-Git-Tag: v2.6.20-rc6~47^2~46 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7dcdcbef5d2b60d1db68fd2c07351f7afd8ad376;p=linux-2.6 [MTD] NAND: Combined oob buffer so it's contiguous with data Ditch the separate oobrbuf and oobwbuf fields from the chip buffers, and use only a single buffer immediately after the data. This accommodates NAND controllers such as the OLPC CAFÉ chip, which can't do scatter/gather DMA so needs the OOB buffer to be contiguous with the data, for both read and write. Signed-off-by: David Woodhouse --- diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 53c66d5c8d..29090c6d48 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -971,7 +971,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, page = realpage & chip->pagemask; col = (int)(from & (mtd->writesize - 1)); - chip->oob_poi = chip->buffers->oobrbuf; buf = ops->datbuf; oob = ops->oobbuf; @@ -1270,8 +1269,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, realpage = (int)(from >> chip->page_shift); page = realpage & chip->pagemask; - chip->oob_poi = chip->buffers->oobrbuf; - while(1) { sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); buf = nand_transfer_oob(chip, buf, ops); @@ -1625,7 +1622,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, (chip->pagebuf << chip->page_shift) < (to + ops->len)) chip->pagebuf = -1; - chip->oob_poi = chip->buffers->oobwbuf; + /* If we're not given explicit OOB data, let it be 0xFF */ + if (likely(!oob)) + memset(chip->oob_poi, 0xff, mtd->oobsize); while(1) { int cached = writelen > bytes && page != blockmask; @@ -1654,9 +1653,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, } } - if (unlikely(oob)) - memset(chip->oob_poi, 0xff, mtd->oobsize); - ops->retlen = ops->len - writelen; return ret; } @@ -1744,7 +1740,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, if (page == chip->pagebuf) chip->pagebuf = -1; - chip->oob_poi = chip->buffers->oobwbuf; memset(chip->oob_poi, 0xff, mtd->oobsize); nand_fill_oob(chip, ops->oobbuf, ops); status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); @@ -2348,8 +2343,8 @@ int nand_scan_tail(struct mtd_info *mtd) if (!chip->buffers) return -ENOMEM; - /* Preset the internal oob write buffer */ - memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize); + /* Set the internal oob buffer location, just after the page data */ + chip->oob_poi = chip->buffers + mtd->writesize; /* * If no default placement scheme is given, select an appropriate one diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 70420bbae8..6fc3e07497 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -286,9 +286,7 @@ struct nand_ecc_ctrl { * struct nand_buffers - buffer structure for read/write * @ecccalc: buffer for calculated ecc * @ecccode: buffer for ecc read from flash - * @oobwbuf: buffer for write oob data * @databuf: buffer for data - dynamically sized - * @oobrbuf: buffer to read oob data * * Do not change the order of buffers. databuf and oobrbuf must be in * consecutive order. @@ -296,9 +294,7 @@ struct nand_ecc_ctrl { struct nand_buffers { uint8_t ecccalc[NAND_MAX_OOBSIZE]; uint8_t ecccode[NAND_MAX_OOBSIZE]; - uint8_t oobwbuf[NAND_MAX_OOBSIZE]; - uint8_t databuf[NAND_MAX_PAGESIZE]; - uint8_t oobrbuf[NAND_MAX_OOBSIZE]; + uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE]; }; /**