mtd/drivers/mtd/nand nand_base.c,1.161,1.162
Vitaly Wool
vwool at ru.mvista.com
Tue Dec 13 10:39:11 EST 2005
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv31751/drivers/mtd/nand
Modified Files:
nand_base.c
Log Message:
[MTD] NAND: restoring the default behaviour when layout is not specified
struct nand_oobinfo is in a way ambiguous: it doesn't specify in any
way how the data is laid out across the NAND page. Both ECC bytes and
OOB free chunks are defined as relative to start of the OOB data.
Therefore it's silently presumed that data and oob are contiguous for
the page which may be true and may be false.
I. e. for SanDisk MLC it's false. This NAND controller is used on
PNX4008 and AFAIK on some Freescale's.
So, there's a conclusion. fill_autooob_layout attempts to create a
layout basing on nand_oobinfo provided. It can be done only assuming
something -- either assuming that the data is contiguous and then
follows oob, or assuming that the data starts at sub-block boundaries
and is spread across the page. The former implementation followed the
latter way, but now it's been changed to work in the former way to
provide backward-compatibility.
This rework resulted in slight ideological change: layouts are now
describing the full page not the page divided by eccsteps.
Conclusion: now HW ECC mode is transparently backward-compatible, though
some fixes will be necessary for 16-bit mode, which are the subject of the
next patches
Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.161
retrieving revision 1.162
diff -u -r1.161 -r1.162
--- nand_base.c 9 Dec 2005 10:58:29 -0000 1.161
+++ nand_base.c 13 Dec 2005 15:39:07 -0000 1.162
@@ -117,42 +117,7 @@
#define FFCHARS_SIZE 2048
static u_char ffchars[FFCHARS_SIZE];
-static struct page_layout_item hw3_256_layout[] = {
- { .length = 256, .type = ITEM_TYPE_DATA, },
- { .length = 3, .type = ITEM_TYPE_ECC, },
- { .length = 5, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw3_512_layout[] = {
- { .length = 512, .type = ITEM_TYPE_DATA, },
- { .length = 3, .type = ITEM_TYPE_ECC, },
- { .length = 13, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw6_512_layout[] = {
- { .length = 512, .type = ITEM_TYPE_DATA, },
- { .length = 6, .type = ITEM_TYPE_ECC, },
- { .length = 10, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw8_512_layout[] = {
- { .length = 512, .type = ITEM_TYPE_DATA, },
- { .length = 8, .type = ITEM_TYPE_ECC, },
- { .length = 8, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw12_2048_layout[] = {
- { .length = 2048, .type = ITEM_TYPE_DATA, },
- { .length = 12, .type = ITEM_TYPE_ECC, },
- { .length = 52, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-#define HW_AUTOOOB_LAYOUT_SIZE 8 /* should be enough */
+#define HW_AUTOOOB_LAYOUT_SIZE 32 /* should be enough */
/*
* NAND low-level MTD interface functions
@@ -893,11 +858,12 @@
static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
{
- int i, oobidx, status;
+ int i = 0, j = 0, oobidx = 0, status;
u_char ecc_code[40];
int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
int *oob_config = oobsel->eccpos;
- int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
+ int datidx = 0, last_datidx = 0, last_oobidx = 0, eccidx = 0;
+ int eccsteps = this->eccsteps;
int eccbytes = 0;
/* FIXME: Enable cached programming */
@@ -927,30 +893,26 @@
break;
default:
eccbytes = this->eccbytes;
- for (oobidx = 0; eccsteps; eccsteps--) {
- int j = 0, last_datidx = datidx, last_oobidx;
- for (; 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, &this->data_poi[datidx], this->layout[j].length);
- datidx += this->layout[j].length;
- break;
- case ITEM_TYPE_ECC:
- this->enable_hwecc(mtd, NAND_ECC_WRITESYN);
- this->calculate_ecc(mtd, &this->data_poi[last_datidx], &ecc_code[eccidx]);
- for (last_oobidx = oobidx; oobidx < last_oobidx + this->layout[j].length; oobidx++, eccidx++)
- oob_buf[oobidx] = ecc_code[eccidx];
- this->write_buf(mtd, ecc_code, this->layout[j].length);
- break;
- case ITEM_TYPE_OOB:
- this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
- this->write_buf(mtd, &oob_buf[oobidx], this->layout[j].length);
- oobidx += this->layout[j].length;
- break;
- }
- }
-
+ for (; 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, &this->data_poi[datidx], this->layout[j].length);
+ datidx += this->layout[j].length;
+ break;
+ case ITEM_TYPE_ECC:
+ this->enable_hwecc(mtd, NAND_ECC_WRITESYN);
+ this->calculate_ecc(mtd, &this->data_poi[last_datidx], &ecc_code[eccidx]);
+ for (last_oobidx = oobidx; oobidx < last_oobidx + this->layout[j].length; oobidx++, eccidx++)
+ oob_buf[oobidx] = ecc_code[eccidx];
+ this->write_buf(mtd, ecc_code, this->layout[j].length);
+ break;
+ case ITEM_TYPE_OOB:
+ this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
+ this->write_buf(mtd, &oob_buf[oobidx], this->layout[j].length);
+ oobidx += this->layout[j].length;
+ break;
+ }
}
break;
}
@@ -1154,6 +1116,7 @@
int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
int read = 0, oob = 0, oobidx, ecc_status = 0, ecc_failed = 0, eccidx;
+ int last_datidx, last_oobidx;
struct nand_chip *this = mtd->priv;
u_char *data_poi, *oob_data = oob_buf;
u_char ecc_calc[32];
@@ -1265,45 +1228,47 @@
break;
default:
- for (oobidx = 0, datidx = 0, eccidx = 0; eccsteps; eccsteps--) {
- int last_datidx = datidx, last_oobidx = oobidx;
- for (j = 0; this->layout[j].length; j++) {
- switch (this->layout[j].type) {
- case ITEM_TYPE_DATA:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d bytes of data\n", __FUNCTION__, this->layout[j].length);
- this->enable_hwecc(mtd, NAND_ECC_READ);
- this->read_buf(mtd, &data_poi[datidx], this->layout[j].length);
- datidx += this->layout[j].length;
- break;
-
- case ITEM_TYPE_ECC:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d ecc bytes\n", __FUNCTION__, this->layout[j].length);
- /* let the particular driver decide whether to read ECC */
- this->enable_hwecc(mtd, NAND_ECC_READSYN);
- this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
- if (!compareecc) {
- /* We calc error correction directly, it checks the hw
- * generator for an error, reads back the syndrome and
- * does the error correction on the fly */
- ecc_status = this->correct_data(mtd, &data_poi[last_datidx], &oob_data[last_oobidx], &ecc_code[eccidx]);
- if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
- "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
- ecc_failed++;
- }
- } else
- this->calculate_ecc(mtd, &data_poi[last_datidx], &ecc_calc[eccidx]);
- oobidx += this->layout[j].length;
- eccidx += this->layout[j].length;
- break;
- case ITEM_TYPE_OOB:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d free oob bytes\n", __FUNCTION__, this->layout[j].length);
- this->enable_hwecc(mtd, NAND_ECC_READOOB);
+ oobidx = 0;
+ datidx = 0;
+ eccidx = 0;
+ last_datidx = datidx;
+ last_oobidx = oobidx;
+ for (j = 0; this->layout[j].length; j++) {
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_DATA:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d bytes of data\n", __FUNCTION__, this->layout[j].length);
+ this->enable_hwecc(mtd, NAND_ECC_READ);
+ this->read_buf(mtd, &data_poi[datidx], this->layout[j].length);
+ datidx += this->layout[j].length;
+ break;
- this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
- oobidx += this->layout[j].length;
- break;
- }
+ case ITEM_TYPE_ECC:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d ecc bytes\n", __FUNCTION__, this->layout[j].length);
+ /* let the particular driver decide whether to read ECC */
+ this->enable_hwecc(mtd, NAND_ECC_READSYN);
+ this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
+ if (!compareecc) {
+ /* We calc error correction directly, it checks the hw
+ * generator for an error, reads back the syndrome and
+ * does the error correction on the fly */
+ ecc_status = this->correct_data(mtd, &data_poi[last_datidx], &oob_data[last_oobidx], &ecc_code[eccidx]);
+ if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
+ DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
+ "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
+ ecc_failed++;
+ }
+ } else
+ this->calculate_ecc(mtd, &data_poi[last_datidx], &ecc_calc[eccidx]);
+ oobidx += this->layout[j].length;
+ eccidx += this->layout[j].length;
+ break;
+ case ITEM_TYPE_OOB:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d free oob bytes\n", __FUNCTION__, this->layout[j].length);
+ this->enable_hwecc(mtd, NAND_ECC_READOOB);
+
+ this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
+ oobidx += this->layout[j].length;
+ break;
}
}
break;
@@ -1481,81 +1446,52 @@
}
eccsteps = this->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;
- 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;
+ case ITEM_TYPE_ECC:
+ case ITEM_TYPE_OOB:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: %s bytes read\n", __FUNCTION__, this->layout[j].type == ITEM_TYPE_ECC ? "ecc" : "oob");
+ 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);
- break;
+ }
+ col -= i;
- 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);
+ if (this->layout[j].type == ITEM_TYPE_ECC)
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;
-
+ else
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;
- }
-
- break;
+ 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;
}
- read += i;
- oob_data += i;
-
- }
+ if (oob_buf + len == oob_data + i) {
+ read += i;
+ goto out;
+ }
+ break;
+ }
+ read += i;
+ oob_data += i;
}
}
out:
@@ -1908,7 +1844,7 @@
*/
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;
+ int column, page, status, ret = -EIO, chipnr, eccsteps;
struct nand_chip *this = mtd->priv;
DEBUG (MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n", __FUNCTION__, (unsigned int) to, (int) len);
@@ -1967,46 +1903,42 @@
this->write_buf(mtd, oob_buf, len);
}
} else {
+ int i = 0, j = 0;
+ int fflen = 0, ooblen = 0;
+
/* Write out desired data */
this->cmdfunc (mtd, NAND_CMD_SEQIN, 0, page & this->pagemask);
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:
+ case ITEM_TYPE_ECC:
+ case ITEM_TYPE_OOB:
+ if (this->layout[j].type == 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:
+ else
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;
+ 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;
}
}
}
@@ -2513,13 +2445,21 @@
}
+/**
+ * fill_autooob_layout - [NAND Interface] build the layout for hardware ECC case
+ * @mtd: MTD device structure
+ * @eccbytes: Number of ECC bytes per page
+ *
+ * Build the page_layout array for NAND page handling for hardware ECC
+ * handling basing on the nand_oobinfo structure supplied for the chip
+ */
static int fill_autooob_layout(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct nand_oobinfo *oob = this->autooob;
- int datasize = mtd->oobblock / this->eccsteps;
- int i = 0, res = 0;
- int eccpos = 0, eccbytes = 0, cur = 0;
+ int oobfreesize = 0;
+ int i = 1, res = 0;
+ int eccpos = 0, eccbytes = 0, cur = 0, oobcur = 0;
this->layout = kmalloc(HW_AUTOOOB_LAYOUT_SIZE * sizeof (struct page_layout_item), GFP_KERNEL);
@@ -2528,34 +2468,67 @@
else
this->layout_allocated = 1;
- while (i < HW_AUTOOOB_LAYOUT_SIZE - 1 &&
- cur < (mtd->oobsize + mtd->oobblock) / this->eccsteps - 1) {
- if (cur == 0) {
- this->layout[i].type = ITEM_TYPE_DATA;
- this->layout[i].length = datasize;
- } else if (oob->eccpos[eccpos] == cur - datasize) {
+ memset(this->layout, 0, HW_AUTOOOB_LAYOUT_SIZE * sizeof (struct page_layout_item));
+
+
+ this->layout[0].type = ITEM_TYPE_DATA;
+ this->layout[0].length = mtd->oobblock;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: data type, length %d\n", this->layout[0].length);
+
+ while (i < HW_AUTOOOB_LAYOUT_SIZE / this->eccsteps - 1 && cur < mtd->oobsize / this->eccsteps) {
+ if (oob->oobfree[oobcur][0] == cur) {
+ int len = oob->oobfree[oobcur][1];
+ oobfreesize += this->layout[i].length;
+ oobcur++;
+ if (i > 0 && this->layout[i-1].type == ITEM_TYPE_OOB) {
+ i--;
+ cur -= this->layout[i].length;
+ this->layout[i].length += len;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: oob concatenated, aggregate length %d\n", this->layout[i].length);
+ } else {
+ this->layout[i].type = ITEM_TYPE_OOB;
+ this->layout[i].length = len;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: oob type, length %d\n", this->layout[i].length);
+ }
+ } else if (oob->eccpos[eccpos] == cur) {
int eccpos_cur = eccpos;
do {
eccpos++;
eccbytes++;
- } while (eccbytes < oob->eccbytes / this->eccsteps && oob->eccpos[eccpos] == oob->eccpos[eccpos+1] - 1);
+ } while (eccbytes < oob->eccbytes && oob->eccpos[eccpos] == oob->eccpos[eccpos+1] - 1);
eccpos++;
eccbytes++;
this->layout[i].type = ITEM_TYPE_ECC;
this->layout[i].length = eccpos - eccpos_cur;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: ecc type, length %d\n", this->layout[i].length);
} else {
- this->layout[i].type = ITEM_TYPE_OOB;
- if (eccbytes < oob->eccbytes / this->eccsteps)
- this->layout[i].length = datasize - cur + oob->eccpos[eccpos];
- else
- this->layout[i].length = mtd->oobsize / this->eccsteps - (cur - datasize);
+ int len = min_t(int, oob->eccpos[eccpos], oob->oobfree[oobcur][0]);
+ if (i > 0 && this->layout[i-1].type == ITEM_TYPE_OOB) {
+ i--;
+ cur -= this->layout[i].length;
+ this->layout[i].length += len;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: oob concatenated, aggregate length %d\n", this->layout[i].length);
+ } else {
+ this->layout[i].type = ITEM_TYPE_OOB;
+ this->layout[i].length = len;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: oob type, length %d\n", this->layout[i].length);
+ }
}
cur += this->layout[i].length;
i++;
}
- if (cur < (mtd->oobsize + mtd->oobblock) / this->eccsteps - 1)
+ if (cur < mtd->oobsize / this->eccsteps - 1) {
+ kfree(this->layout);
res = -1;
-
+ } else if (this->eccsteps > 1) {
+ int j = i;
+ i--;
+ while (j < this->eccsteps * i + 1) {
+ this->layout[j].length = this->layout[j-i].length;
+ this->layout[j].type = this->layout[j-i].type;
+ j++;
+ }
+ }
return res;
}
@@ -2910,29 +2883,9 @@
/* We consider only layout allocation performed in nand_base */
this->layout_allocated = 0;
- if (!this->layout) {
- if (this->autooob)
- fill_autooob_layout(mtd);
- else {
- switch (this->eccmode) {
- case NAND_ECC_HW12_2048:
- this->layout = hw12_2048_layout;
- break;
- case NAND_ECC_HW3_512:
- this->layout = hw3_512_layout;
- break;
- case NAND_ECC_HW6_512:
- this->layout = hw6_512_layout;
- break;
- case NAND_ECC_HW8_512:
- this->layout = hw8_512_layout;
- break;
- case NAND_ECC_HW3_256:
- this->layout = hw3_256_layout;
- break;
- }
- }
- }
+ if (!this->layout && this->autooob)
+ if (fill_autooob_layout(mtd) < 0)
+ BUG();
/* Initialize state, waitqueue and spinlock */
this->state = FL_READY;
More information about the linux-mtd-cvs
mailing list