Commit 7dcdcbef authored by David Woodhouse's avatar David Woodhouse

[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: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 513b046c
...@@ -971,7 +971,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, ...@@ -971,7 +971,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
page = realpage & chip->pagemask; page = realpage & chip->pagemask;
col = (int)(from & (mtd->writesize - 1)); col = (int)(from & (mtd->writesize - 1));
chip->oob_poi = chip->buffers->oobrbuf;
buf = ops->datbuf; buf = ops->datbuf;
oob = ops->oobbuf; oob = ops->oobbuf;
...@@ -1270,8 +1269,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, ...@@ -1270,8 +1269,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
realpage = (int)(from >> chip->page_shift); realpage = (int)(from >> chip->page_shift);
page = realpage & chip->pagemask; page = realpage & chip->pagemask;
chip->oob_poi = chip->buffers->oobrbuf;
while(1) { while(1) {
sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
buf = nand_transfer_oob(chip, buf, ops); 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,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 << chip->page_shift) < (to + ops->len))
chip->pagebuf = -1; 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) { while(1) {
int cached = writelen > bytes && page != blockmask; int cached = writelen > bytes && page != blockmask;
...@@ -1654,9 +1653,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, ...@@ -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; ops->retlen = ops->len - writelen;
return ret; return ret;
} }
...@@ -1744,7 +1740,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, ...@@ -1744,7 +1740,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
if (page == chip->pagebuf) if (page == chip->pagebuf)
chip->pagebuf = -1; chip->pagebuf = -1;
chip->oob_poi = chip->buffers->oobwbuf;
memset(chip->oob_poi, 0xff, mtd->oobsize); memset(chip->oob_poi, 0xff, mtd->oobsize);
nand_fill_oob(chip, ops->oobbuf, ops); nand_fill_oob(chip, ops->oobbuf, ops);
status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
...@@ -2348,8 +2343,8 @@ int nand_scan_tail(struct mtd_info *mtd) ...@@ -2348,8 +2343,8 @@ int nand_scan_tail(struct mtd_info *mtd)
if (!chip->buffers) if (!chip->buffers)
return -ENOMEM; return -ENOMEM;
/* Preset the internal oob write buffer */ /* Set the internal oob buffer location, just after the page data */
memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize); chip->oob_poi = chip->buffers + mtd->writesize;
/* /*
* If no default placement scheme is given, select an appropriate one * If no default placement scheme is given, select an appropriate one
......
...@@ -286,9 +286,7 @@ struct nand_ecc_ctrl { ...@@ -286,9 +286,7 @@ struct nand_ecc_ctrl {
* struct nand_buffers - buffer structure for read/write * struct nand_buffers - buffer structure for read/write
* @ecccalc: buffer for calculated ecc * @ecccalc: buffer for calculated ecc
* @ecccode: buffer for ecc read from flash * @ecccode: buffer for ecc read from flash
* @oobwbuf: buffer for write oob data
* @databuf: buffer for data - dynamically sized * @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 * Do not change the order of buffers. databuf and oobrbuf must be in
* consecutive order. * consecutive order.
...@@ -296,9 +294,7 @@ struct nand_ecc_ctrl { ...@@ -296,9 +294,7 @@ struct nand_ecc_ctrl {
struct nand_buffers { struct nand_buffers {
uint8_t ecccalc[NAND_MAX_OOBSIZE]; uint8_t ecccalc[NAND_MAX_OOBSIZE];
uint8_t ecccode[NAND_MAX_OOBSIZE]; uint8_t ecccode[NAND_MAX_OOBSIZE];
uint8_t oobwbuf[NAND_MAX_OOBSIZE]; uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];
uint8_t databuf[NAND_MAX_PAGESIZE];
uint8_t oobrbuf[NAND_MAX_OOBSIZE];
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment