mtd/drivers/mtd/nand nand_base.c,1.157,1.158
Vitaly Wool
vwool at ru.mvista.com
Tue Nov 22 05:54:58 EST 2005
- Previous message: mtd/drivers/mtd/nand nand_base.c,1.156,1.157
- Next message: mtd/Documentation/jffs3/pics comprex-02.eps, NONE,
1.1 comprex-02.pdf, NONE, 1.1 comprex-02.png, NONE,
1.1 btree-01.eps, 1.2, 1.3 btree-01.pdf, 1.2, 1.3 btree-01.png,
1.1, 1.2 comprex-01.eps, 1.1, 1.2 comprex-01.pdf, 1.1,
1.2 comprex-01.png, 1.1, 1.2 flash-01.eps, 1.2,
1.3 idxprobl.eps, 1.1, 1.2 idxprobl.pdf, 1.2, 1.3 idxprobl.png,
1.1, 1.2 journal-01.eps, 1.4, 1.5 journal-01.pdf, 1.4,
1.5 journal-01.png, 1.3, 1.4 journal-02.eps, 1.2,
1.3 journal-02.pdf, 1.2, 1.3 journal-02.png, 1.1,
1.2 keyex-01.eps, 1.2, 1.3 keyex-01.pdf, 1.2, 1.3 keyex-01.png,
1.2, 1.3 node-01.eps, 1.5, 1.6 node-01.pdf, 1.5,
1.6 node-01.png, 1.4, 1.5 trivkey-01.eps, 1.3,
1.4 trivkey-01.pdf, 1.3, 1.4 trivkey-01.png, 1.3,
1.4 wandtree.eps, 1.3, 1.4 wandtree.pdf, 1.3, 1.4 wandtree.png,
1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv30320/drivers/mtd/nand
Modified Files:
nand_base.c
Log Message:
[MTD] NAND: eliminate nand_{read,write}_oob_hwecc
Merge the functionality of nand_{read,write}_oob_hwecc into the corresponding nand_{read,write}_oob functions and eliminate nand_{read,write}_oob_hwecc. Having separate functions for HW ECC is redundant and was discouraged by tglx :)
From: Vitaly Wool <vwool at ru.mvista.com>
Signed-off-by: Vitaly Wool <vwool at ru.mvista.com>
Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.157
retrieving revision 1.158
diff -u -r1.157 -r1.158
--- nand_base.c 21 Nov 2005 22:14:55 -0000 1.157
+++ nand_base.c 22 Nov 2005 10:54:54 -0000 1.158
@@ -113,7 +113,7 @@
.oobfree = { {2, 38} }
};
-/* This is used for padding purposes in nand_write_oob/nand_write_oob_hwecc */
+/* This is used for padding purposes in nand_write_oob */
#define FFCHARS_SIZE 2048
static u_char ffchars[FFCHARS_SIZE];
@@ -1425,102 +1425,7 @@
*
* NAND read out-of-band data from the spare area
*/
-static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
-{
- int i, col, page, chipnr;
- struct nand_chip *this = mtd->priv;
- int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
-
- /* Shift to get page */
- page = (int)(from >> this->page_shift);
- chipnr = (int)(from >> this->chip_shift);
-
- /* Mask to get column */
- col = from & (mtd->oobsize - 1);
-
- /* Initialize return length value */
- *retlen = 0;
-
- /* Do not allow reads past end of device */
- if ((from + len) > mtd->size) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
- *retlen = 0;
- return -EINVAL;
- }
-
- /* Grab the lock and see if the device is available */
- nand_get_device (this, mtd , FL_READING);
-
- /* Select the NAND device */
- this->select_chip(mtd, chipnr);
-
- /* Send the read command */
- this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
- /*
- * Read the data, if we read more than one page
- * oob data, let the device transfer the data !
- */
- i = 0;
- while (i < len) {
- int thislen = mtd->oobsize - col;
- thislen = min_t(int, thislen, len);
- this->read_buf(mtd, &buf[i], thislen);
- i += thislen;
-
- /* Read more ? */
- if (i < len) {
- page++;
- col = 0;
-
- /* Check, if we cross a chip boundary */
- if (!(page & this->pagemask)) {
- chipnr++;
- this->select_chip(mtd, -1);
- this->select_chip(mtd, chipnr);
- }
-
- /* Apply delay or wait for ready/busy pin
- * Do this before the AUTOINCR check, so no problems
- * arise if a chip which does auto increment
- * is marked as NOAUTOINCR by the board driver.
- */
- if (!this->dev_ready)
- udelay (this->chip_delay);
- else
- nand_wait_ready(mtd);
-
- /* Check, if the chip supports auto page increment
- * or if we have hit a block boundary.
- */
- if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
- /* For subsequent page reads set offset to 0 */
- this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
- }
- }
- }
-
- /* Deselect and wake up anyone waiting on the device */
- nand_release_device(mtd);
-
- /* Return happy */
- *retlen = len;
- return 0;
-}
-
-/**
- * nand_read_oob_hwecc - [MTD Interface] NAND read out-of-band (HW ECC)
- * @mtd: MTD device structure
- * @from: offset to read from
- * @len: number of bytes to read
- * @retlen: pointer to variable to store the number of read bytes
- * @oob_buf: the databuffer to put data
- *
- * NAND read out-of-band data from the spare area
- * W/o assumptions that are valid only for software ECC
- */
-static int nand_read_oob_hwecc (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * oob_buf)
+static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * oob_buf)
{
int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1i, reallen = 0;
@@ -1558,87 +1463,99 @@
/* Loop until all data read */
while (read < len) {
- /* Check, if we must send the read command */
- if (sndcmd) {
- this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
- sndcmd = 0;
- }
-
- eccsteps = this->eccsteps;
+ if (this->eccmode == NAND_ECC_SOFT || this->eccmode == NAND_ECC_NONE) {
+ int thislen = mtd->oobsize - col;
+ if (sndcmd) {
+ this->cmdfunc (mtd, NAND_CMD_READOOB, col, page);
+ col = 0;
+ sndcmd = 0;
+ }
+ thislen = min_t(int, thislen, len);
+ this->read_buf(mtd, &oob_buf[read], thislen);
+ read += thislen;
+ } else {
+ /* Check, if we must send the read command */
+ if (sndcmd) {
+ this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
+ sndcmd = 0;
+ }
- for (; eccsteps; eccsteps--) {
- for (j = 0; this->layout[j].length; j++) {
- i = 0;
- switch (this->layout[j].type) {
- case ITEM_TYPE_DATA:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: dummy data read\n", __FUNCTION__);
- reallen += this->layout[j].length;
- if (this->options & NAND_BUSWIDTH_16)
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
- else
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
- break;
+ eccsteps = this->eccsteps;
- case ITEM_TYPE_ECC:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: ecc bytes read\n", __FUNCTION__);
- i = min_t(int, col, this->layout[j].length);
- if (i) {
- reallen += i;
+ for (; eccsteps; eccsteps--) {
+ for (j = 0; this->layout[j].length; j++) {
+ i = 0;
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_DATA:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: dummy data read\n", __FUNCTION__);
+ reallen += this->layout[j].length;
if (this->options & NAND_BUSWIDTH_16)
this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
else
this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
- }
- col -= i;
- i = min_t(int, len - read, this->layout[j].length - i);
- this->enable_hwecc(mtd, NAND_ECC_READSYN);
- if (i) {
- if (this->options & NAND_BUSWIDTH_16 && reallen & 1) {
- oob_data[0] = cpu_to_le16(this->read_word(mtd)) >> 8;
- oob_data++; i--; reallen++;
+ break;
+
+ case ITEM_TYPE_ECC:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: ecc bytes read\n", __FUNCTION__);
+ i = min_t(int, col, this->layout[j].length);
+ if (i) {
+ reallen += i;
+ if (this->options & NAND_BUSWIDTH_16)
+ this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
+ else
+ this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
}
+ col -= i;
+ i = min_t(int, len - read, this->layout[j].length - i);
+ this->enable_hwecc(mtd, NAND_ECC_READSYN);
+ if (i) {
+ if (this->options & NAND_BUSWIDTH_16 && reallen & 1) {
+ oob_data[0] = cpu_to_le16(this->read_word(mtd)) >> 8;
+ oob_data++; i--; reallen++;
+ }
- this->read_buf(mtd, oob_data, i);
- reallen += i;
- }
- if (oob_buf + len == oob_data + i) {
- read += i;
- goto out;
- }
- break;
- case ITEM_TYPE_OOB:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: free oob bytes read\n", __FUNCTION__);
- i = min_t(int, col, this->layout[j].length);
- if (i) {
- reallen += i;
- if (this->options & NAND_BUSWIDTH_16)
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
- else
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
- }
- col -= i;
+ this->read_buf(mtd, oob_data, i);
+ reallen += i;
+ }
+ if (oob_buf + len == oob_data + i) {
+ read += i;
+ goto out;
+ }
+ break;
+ case ITEM_TYPE_OOB:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: free oob bytes read\n", __FUNCTION__);
+ i = min_t(int, col, this->layout[j].length);
+ if (i) {
+ reallen += i;
+ if (this->options & NAND_BUSWIDTH_16)
+ this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
+ else
+ this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
+ }
+ col -= i;
- this->enable_hwecc(mtd, NAND_ECC_READOOB);
- i = min_t(int, len - read, this->layout[j].length - i);
- if (i) {
- if (this->options & NAND_BUSWIDTH_16 && reallen & 1) {
- oob_data[0] = cpu_to_le16(this->read_word(mtd)) >> 8;
- oob_data++; i--; reallen++;
+ this->enable_hwecc(mtd, NAND_ECC_READOOB);
+ i = min_t(int, len - read, this->layout[j].length - i);
+ if (i) {
+ if (this->options & NAND_BUSWIDTH_16 && reallen & 1) {
+ oob_data[0] = cpu_to_le16(this->read_word(mtd)) >> 8;
+ oob_data++; i--; reallen++;
+ }
+
+ this->read_buf(mtd, oob_data, i);
+ reallen += i;
+ }
+ if (oob_buf + len == oob_data + i) {
+ read += i;
+ goto out;
}
- this->read_buf(mtd, oob_data, i);
- reallen += i;
- }
- if (oob_buf + len == oob_data + i) {
- read += i;
- goto out;
+ break;
}
+ read += i;
+ oob_data += i;
- break;
}
- read += i;
- oob_data += i;
-
}
}
out:
@@ -1989,109 +1906,7 @@
*
* NAND write out-of-band
*/
-static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
-{
- int column, page, status, ret = -EIO, chipnr;
- struct nand_chip *this = mtd->priv;
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
- /* Shift to get page */
- page = (int) (to >> this->page_shift);
- chipnr = (int) (to >> this->chip_shift);
-
- /* Mask to get column */
- column = to & (mtd->oobsize - 1);
-
- /* Initialize return length value */
- *retlen = 0;
-
- /* Do not allow write past end of page */
- if ((column + len) > mtd->oobsize) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
- return -EINVAL;
- }
-
- /* Grab the lock and see if the device is available */
- nand_get_device (this, mtd, FL_WRITING);
-
- /* Select the NAND device */
- this->select_chip(mtd, chipnr);
-
- /* Reset the chip. Some chips (like the Toshiba TC5832DC found
- in one of my DiskOnChip 2000 test units) will clear the whole
- data page too if we don't do this. I have no clue why, but
- I seem to have 'fixed' it in the doc2000 driver in
- August 1999. dwmw2. */
- this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
- /* Check, if it is write protected */
- if (nand_check_wp(mtd))
- goto out;
-
- /* Invalidate the page cache, if we write to the cached page */
- if (page == this->pagebuf)
- this->pagebuf = -1;
-
- if (NAND_MUST_PAD(this)) {
- /* Write out desired data */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
- /* prepad 0xff for partial programming */
- this->write_buf(mtd, ffchars, column);
- /* write data */
- this->write_buf(mtd, buf, len);
- /* postpad 0xff for partial programming */
- this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
- } else {
- /* Write out desired data */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
- /* write data */
- this->write_buf(mtd, buf, len);
- }
- /* Send command to program the OOB data */
- this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-
- status = this->waitfunc (mtd, this, FL_WRITING);
-
- /* See if device thinks it succeeded */
- if (status & NAND_STATUS_FAIL) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
- ret = -EIO;
- goto out;
- }
- /* Return happy */
- *retlen = len;
-
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
- /* Send command to read back the data */
- this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
-
- if (this->verify_buf(mtd, buf, len)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
- ret = -EIO;
- goto out;
- }
-#endif
- ret = 0;
-out:
- /* Deselect and wake up anyone waiting on the device */
- nand_release_device(mtd);
-
- return ret;
-}
-
-/**
- * nand_write_oob_hwecc - [MTD Interface] NAND write out-of-band
- * @mtd: MTD device structure
- * @to: offset to write to
- * @len: number of bytes to write
- * @retlen: pointer to variable to store the number of written bytes
- * @oob_buf: the data to write
- *
- * NAND write out-of-band
- * W/o assumptions that are valid only for software ECC
- */
-static int nand_write_oob_hwecc (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * oob_buf)
+static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * oob_buf)
{
int column, page, status, ret = -EIO, chipnr, eccsteps, fflen, ooblen;
struct nand_chip *this = mtd->priv;
@@ -2135,46 +1950,63 @@
if (page == this->pagebuf)
this->pagebuf = -1;
- /* Write out desired data */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, 0, page & this->pagemask);
-
- eccsteps = this->eccsteps;
+ if (this->eccmode == NAND_ECC_SOFT || this->eccmode == NAND_ECC_NONE) {
+ if (NAND_MUST_PAD(this)) {
+ /* Write out desired data */
+ this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
+ /* prepad 0xff for partial programming */
+ this->write_buf(mtd, ffchars, column);
+ /* write data */
+ this->write_buf(mtd, oob_buf, len);
+ /* postpad 0xff for partial programming */
+ this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
+ } else {
+ /* Write out desired data */
+ this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
+ /* write data */
+ this->write_buf(mtd, oob_buf, len);
+ }
+ } else {
+ /* Write out desired data */
+ this->cmdfunc (mtd, NAND_CMD_SEQIN, 0, page & this->pagemask);
- for (fflen = 0, ooblen = 0; eccsteps; eccsteps--)
- int i, j;
+ eccsteps = this->eccsteps;
- for (j = 0; this->layout[j].length; j++) {
- switch (this->layout[j].type) {
- case ITEM_TYPE_DATA:
- this->enable_hwecc(mtd, NAND_ECC_WRITE);
- this->write_buf(mtd, ffchars, this->layout[j].length);
- fflen += this->layout[j].length;
- break;
+ for (fflen = 0, ooblen = 0; eccsteps; eccsteps--) {
+ int i, j;
+ for (j = 0; this->layout[j].length; j++) {
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_DATA:
+ this->enable_hwecc(mtd, NAND_ECC_WRITE);
+ this->write_buf(mtd, ffchars, this->layout[j].length);
+ fflen += this->layout[j].length;
+ break;
- case ITEM_TYPE_ECC:
- this->enable_hwecc(mtd, NAND_ECC_WRITESYN);
- this->write_buf(mtd, ffchars, this->layout[j].length);
- ooblen += this->layout[j].length;
- break;
+ case ITEM_TYPE_ECC:
+ this->enable_hwecc(mtd, NAND_ECC_WRITESYN);
+ this->write_buf(mtd, ffchars, this->layout[j].length);
+ ooblen += this->layout[j].length;
+ break;
- case ITEM_TYPE_OOB:
- this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
- i = min_t(int, column, this->layout[j].length);
- if (i)
- this->write_buf(mtd, ffchars, i);
- column -= i;
- i = min_t(int, len + column - ooblen, this->layout[j].length - i);
-
- if (i)
- this->write_buf(mtd, &oob_buf[ooblen], i);
- ooblen += i;
- if (ooblen == len) {
- if (NAND_MUST_PAD(this))
- this->write_buf(mtd, ffchars,
- mtd->oobsize + mtd->oobblock - fflen - ooblen);
- goto finish;
+ case ITEM_TYPE_OOB:
+ this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
+ i = min_t(int, column, this->layout[j].length);
+ if (i)
+ this->write_buf(mtd, ffchars, i);
+ column -= i;
+ fflen += i;
+ i = min_t(int, len + column - ooblen, this->layout[j].length - i);
+
+ if (i)
+ this->write_buf(mtd, &oob_buf[ooblen], i);
+ ooblen += i;
+ if (ooblen == len) {
+ if (NAND_MUST_PAD(this))
+ this->write_buf(mtd, ffchars, mtd->oobsize + mtd->oobblock - fflen - ooblen);
+ goto finish;
+ }
+ break;
}
- break;
}
}
}
@@ -2194,6 +2026,16 @@
*retlen = len;
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
+ if (this->eccmode == NAND_ECC_SOFT | this->eccmode == NAND_ECC_NONE) {
+ /* Send command to read back the data */
+ this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
+
+ if (this->verify_buf(mtd, buf, len)) {
+ DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
+ ret = -EIO;
+ goto out;
+ }
+ }
#warning "Verify for OOB data in HW ECC case is NOT YET implemented"
#endif
ret = 0;
@@ -2733,10 +2575,6 @@
{
int i, nand_maf_id, nand_dev_id, busw, maf_id;
struct nand_chip *this = mtd->priv;
- int hwecc = 1;
-
- if (this->eccmode == NAND_ECC_NONE || this->eccmode == NAND_ECC_SOFT)
- hwecc = 0;
/* Get buswidth to select the correct functions*/
busw = this->options & NAND_BUSWIDTH_16;
@@ -3118,8 +2956,8 @@
mtd->write = nand_write;
mtd->read_ecc = nand_read_ecc;
mtd->write_ecc = nand_write_ecc;
- mtd->read_oob = hwecc ? nand_read_oob_hwecc : nand_read_oob;
- mtd->write_oob = hwecc ? nand_write_oob_hwecc : nand_write_oob;
+ mtd->read_oob = nand_read_oob;
+ mtd->write_oob = nand_write_oob;
mtd->readv = NULL;
mtd->writev = nand_writev;
mtd->writev_ecc = nand_writev_ecc;
- Previous message: mtd/drivers/mtd/nand nand_base.c,1.156,1.157
- Next message: mtd/Documentation/jffs3/pics comprex-02.eps, NONE,
1.1 comprex-02.pdf, NONE, 1.1 comprex-02.png, NONE,
1.1 btree-01.eps, 1.2, 1.3 btree-01.pdf, 1.2, 1.3 btree-01.png,
1.1, 1.2 comprex-01.eps, 1.1, 1.2 comprex-01.pdf, 1.1,
1.2 comprex-01.png, 1.1, 1.2 flash-01.eps, 1.2,
1.3 idxprobl.eps, 1.1, 1.2 idxprobl.pdf, 1.2, 1.3 idxprobl.png,
1.1, 1.2 journal-01.eps, 1.4, 1.5 journal-01.pdf, 1.4,
1.5 journal-01.png, 1.3, 1.4 journal-02.eps, 1.2,
1.3 journal-02.pdf, 1.2, 1.3 journal-02.png, 1.1,
1.2 keyex-01.eps, 1.2, 1.3 keyex-01.pdf, 1.2, 1.3 keyex-01.png,
1.2, 1.3 node-01.eps, 1.5, 1.6 node-01.pdf, 1.5,
1.6 node-01.png, 1.4, 1.5 trivkey-01.eps, 1.3,
1.4 trivkey-01.pdf, 1.3, 1.4 trivkey-01.png, 1.3,
1.4 wandtree.eps, 1.3, 1.4 wandtree.pdf, 1.3, 1.4 wandtree.png,
1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the linux-mtd-cvs
mailing list