diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-10-21 12:09:53 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-10-21 12:48:58 -0400 |
commit | 7dcdcbef5d2b60d1db68fd2c07351f7afd8ad376 (patch) | |
tree | 8a3817d93520bf28aaea42534a953909f9bb10e3 | |
parent | 513b046c96cc2fbce730a3474f6f7ff0c4fdd05c (diff) |
[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 <dwmw2@infradead.org>
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 15 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 6 |
2 files changed, 6 insertions, 15 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 53c66d5c8d1a..29090c6d4819 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, | |||
971 | page = realpage & chip->pagemask; | 971 | page = realpage & chip->pagemask; |
972 | 972 | ||
973 | col = (int)(from & (mtd->writesize - 1)); | 973 | col = (int)(from & (mtd->writesize - 1)); |
974 | chip->oob_poi = chip->buffers->oobrbuf; | ||
975 | 974 | ||
976 | buf = ops->datbuf; | 975 | buf = ops->datbuf; |
977 | oob = ops->oobbuf; | 976 | oob = ops->oobbuf; |
@@ -1270,8 +1269,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
1270 | realpage = (int)(from >> chip->page_shift); | 1269 | realpage = (int)(from >> chip->page_shift); |
1271 | page = realpage & chip->pagemask; | 1270 | page = realpage & chip->pagemask; |
1272 | 1271 | ||
1273 | chip->oob_poi = chip->buffers->oobrbuf; | ||
1274 | |||
1275 | while(1) { | 1272 | while(1) { |
1276 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); | 1273 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); |
1277 | buf = nand_transfer_oob(chip, buf, ops); | 1274 | buf = nand_transfer_oob(chip, buf, ops); |
@@ -1625,7 +1622,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
1625 | (chip->pagebuf << chip->page_shift) < (to + ops->len)) | 1622 | (chip->pagebuf << chip->page_shift) < (to + ops->len)) |
1626 | chip->pagebuf = -1; | 1623 | chip->pagebuf = -1; |
1627 | 1624 | ||
1628 | chip->oob_poi = chip->buffers->oobwbuf; | 1625 | /* If we're not given explicit OOB data, let it be 0xFF */ |
1626 | if (likely(!oob)) | ||
1627 | memset(chip->oob_poi, 0xff, mtd->oobsize); | ||
1629 | 1628 | ||
1630 | while(1) { | 1629 | while(1) { |
1631 | int cached = writelen > bytes && page != blockmask; | 1630 | int cached = writelen > bytes && page != blockmask; |
@@ -1654,9 +1653,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
1654 | } | 1653 | } |
1655 | } | 1654 | } |
1656 | 1655 | ||
1657 | if (unlikely(oob)) | ||
1658 | memset(chip->oob_poi, 0xff, mtd->oobsize); | ||
1659 | |||
1660 | ops->retlen = ops->len - writelen; | 1656 | ops->retlen = ops->len - writelen; |
1661 | return ret; | 1657 | return ret; |
1662 | } | 1658 | } |
@@ -1744,7 +1740,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
1744 | if (page == chip->pagebuf) | 1740 | if (page == chip->pagebuf) |
1745 | chip->pagebuf = -1; | 1741 | chip->pagebuf = -1; |
1746 | 1742 | ||
1747 | chip->oob_poi = chip->buffers->oobwbuf; | ||
1748 | memset(chip->oob_poi, 0xff, mtd->oobsize); | 1743 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
1749 | nand_fill_oob(chip, ops->oobbuf, ops); | 1744 | nand_fill_oob(chip, ops->oobbuf, ops); |
1750 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); | 1745 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); |
@@ -2348,8 +2343,8 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
2348 | if (!chip->buffers) | 2343 | if (!chip->buffers) |
2349 | return -ENOMEM; | 2344 | return -ENOMEM; |
2350 | 2345 | ||
2351 | /* Preset the internal oob write buffer */ | 2346 | /* Set the internal oob buffer location, just after the page data */ |
2352 | memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize); | 2347 | chip->oob_poi = chip->buffers + mtd->writesize; |
2353 | 2348 | ||
2354 | /* | 2349 | /* |
2355 | * If no default placement scheme is given, select an appropriate one | 2350 | * 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 70420bbae82b..6fc3e07497e0 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -286,9 +286,7 @@ struct nand_ecc_ctrl { | |||
286 | * struct nand_buffers - buffer structure for read/write | 286 | * struct nand_buffers - buffer structure for read/write |
287 | * @ecccalc: buffer for calculated ecc | 287 | * @ecccalc: buffer for calculated ecc |
288 | * @ecccode: buffer for ecc read from flash | 288 | * @ecccode: buffer for ecc read from flash |
289 | * @oobwbuf: buffer for write oob data | ||
290 | * @databuf: buffer for data - dynamically sized | 289 | * @databuf: buffer for data - dynamically sized |
291 | * @oobrbuf: buffer to read oob data | ||
292 | * | 290 | * |
293 | * Do not change the order of buffers. databuf and oobrbuf must be in | 291 | * Do not change the order of buffers. databuf and oobrbuf must be in |
294 | * consecutive order. | 292 | * consecutive order. |
@@ -296,9 +294,7 @@ struct nand_ecc_ctrl { | |||
296 | struct nand_buffers { | 294 | struct nand_buffers { |
297 | uint8_t ecccalc[NAND_MAX_OOBSIZE]; | 295 | uint8_t ecccalc[NAND_MAX_OOBSIZE]; |
298 | uint8_t ecccode[NAND_MAX_OOBSIZE]; | 296 | uint8_t ecccode[NAND_MAX_OOBSIZE]; |
299 | uint8_t oobwbuf[NAND_MAX_OOBSIZE]; | 297 | uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE]; |
300 | uint8_t databuf[NAND_MAX_PAGESIZE]; | ||
301 | uint8_t oobrbuf[NAND_MAX_OOBSIZE]; | ||
302 | }; | 298 | }; |
303 | 299 | ||
304 | /** | 300 | /** |