From: Kyungmin Park <kyungmin.park@samsung.com>
To: Artem Bityutskiy <dedekind@infradead.org>
Cc: linux-mtd <linux-mtd@lists.infradead.org>
Subject: Eraseblocks torture: OneNAND results
Date: Fri, 15 Dec 2006 05:02:23 +0000 (GMT) [thread overview]
Message-ID: <24414989.16841166158970543.JavaMail.weblogic@ep_ml08> (raw)
Hi, Artem
> FYI: now I see that the tortured eraseblocks do not contain all 0xFFs
> after erase which is strange - the driver must have returned an error.
> But mtd->erase is totally silent about this. Most probably it is a bug
> in the OneNAND driver.
>
> May you please take a look at onenand_wait() from
> drivers/mtd/onenand/onenand_base.c in mtd-2.6.git. I see the following
> code there:
>
> -----------------------------------------------------------------------
> ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
>
> if (ctrl & ONENAND_CTRL_ERROR) {
> /* It maybe occur at initial bad block */
> DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n",
> ctrl);
> /* Clear other interrupt bits for preventing ECC error */
> interrupt &= ONENAND_INT_MASTER;
> }
> AFAIU, this is exactly the place when we should catch erase errors. But
> what we do - we only change local 'interrupt' variable and later return
> 0. So we do not report about errors. This looks suspiciously. May you
> comment on this?
Yes, you're right. onenand_wait has a bug. It don't report the any error. it's my falut.
And also it don't check the locked block error.
The below patch fix the onenand_wait bug. (This is temporary one. I also try to fix another things)
please test this one.
(You may have some parts already. please ignore it)
In my opition, if the block goes worn-out. it occurs as following.
First, 2-bit ecc read error occurs. (bit error)
Second, Write failed. (page error)
Finally, Erase failed. (block error)
Thank you,
Kyungmin Park
P.S., In target environment, it still can't report any error. I'm also surpise with the OneNAND which has good erase guarantee.
--
Index: drivers/mtd/onenand/onenand_base.c
===================================================================
RCS file: /cvsroot/linux-2.6.18-omap/drivers/mtd/onenand/onenand_base.c,v
retrieving revision 1.2
diff -u -p -r1.2 onenand_base.c
--- drivers/mtd/onenand/onenand_base.c 12 Oct 2006 06:59:27 -0000 1.2
+++ drivers/mtd/onenand/onenand_base.c 15 Dec 2006 04:36:02 -0000
@@ -316,22 +316,20 @@ static int onenand_wait(struct mtd_info
ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
if (ctrl & ONENAND_CTRL_ERROR) {
- /* It maybe occur at initial bad block */
DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
- /* Clear other interrupt bits for preventing ECC error */
- interrupt &= ONENAND_INT_MASTER;
- }
-
- if (ctrl & ONENAND_CTRL_LOCK) {
- DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);
- return -EACCES;
+ if (ctrl & ONENAND_CTRL_LOCK)
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
+ return ctrl;
}
if (interrupt & ONENAND_INT_READ) {
ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
- if (ecc & ONENAND_ECC_2BIT_ALL) {
+ if (ecc) {
DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
- return -EBADMSG;
+ if (ecc & ONENAND_ECC_2BIT_ALL)
+ mtd->ecc_stats.failed++;
+ else if (ecc & ONENAND_ECC_1BIT_ALL)
+ mtd->ecc_stats.corrected++;
}
}
@@ -608,6 +606,7 @@ static int onenand_read(struct mtd_info
size_t *retlen, u_char *buf)
{
struct onenand_chip *this = mtd->priv;
+ struct mtd_ecc_stats stats;
int read = 0, column;
int thislen;
int ret = 0;
@@ -626,6 +625,7 @@ static int onenand_read(struct mtd_info
/* TODO handling oob */
+ stats = mtd->ecc_stats;
while (read < len) {
thislen = min_t(int, mtd->writesize, len - read);
@@ -643,16 +643,16 @@ static int onenand_read(struct mtd_info
this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
- read += thislen;
-
- if (read == len)
- break;
-
if (ret) {
DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);
goto out;
}
+ read += thislen;
+
+ if (read == len)
+ break;
+
from += thislen;
buf += thislen;
}
@@ -667,7 +667,10 @@ out:
* retlen == desired len and result == -EBADMSG
*/
*retlen = read;
- return ret;
+ if (mtd->ecc_stats.failed - stats.failed)
+ return -EBADMSG;
+
+ return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
}
/**
@@ -716,15 +719,16 @@ int onenand_do_read_oob(struct mtd_info
this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
+ if (ret) {
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret);
+ goto out;
+ }
+
read += thislen;
if (read == len)
break;
- if (ret) {
- DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
- goto out;
- }
buf += thislen;
@@ -1083,10 +1087,7 @@ static int onenand_erase(struct mtd_info
ret = this->wait(mtd, FL_ERASING);
/* Check, if it is write protected */
if (ret) {
- if (ret == -EPERM)
- DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
- else
- DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
instr->state = MTD_ERASE_FAILED;
instr->fail_addr = addr;
goto erase_exit;
Index: drivers/mtd/onenand/onenand_bbt.c
===================================================================
RCS file: /cvsroot/linux-2.6.18-omap/drivers/mtd/onenand/onenand_bbt.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 onenand_bbt.c
--- drivers/mtd/onenand/onenand_bbt.c 12 Oct 2006 05:49:24 -0000 1.1.1.1
+++ drivers/mtd/onenand/onenand_bbt.c 15 Dec 2006 04:36:02 -0000
@@ -93,7 +93,8 @@ static int create_bbt(struct mtd_info *m
ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,
readlen, &retlen, &buf[0]);
- if (ret)
+ /* Handle initial bad block */
+ if (ret && !(ret & ONENAND_CTRL_LOAD))
return ret;
if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
next reply other threads:[~2006-12-15 5:03 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-15 5:02 Kyungmin Park [this message]
2006-12-15 7:54 ` Eraseblocks torture: OneNAND results Enrico Migliore
2006-12-15 8:44 ` Ricard Wanderlof
2006-12-21 15:30 ` Jarkko Lavinen
-- strict thread matches above, loose matches on Subject: below --
2006-12-22 7:58 Kyungmin Park
2006-12-22 9:22 ` Artem Bityutskiy
2006-12-11 8:31 Kyungmin Park
2006-12-13 13:46 ` Artem Bityutskiy
2006-12-08 7:42 Kyungmin Park
2006-12-08 8:08 ` Artem Bityutskiy
2006-12-08 13:30 ` Artem Bityutskiy
2006-12-08 2:00 Kyungmin Park
2006-12-08 6:19 ` Artem Bityutskiy
2006-12-08 13:43 ` Ricard Wanderlof
2006-12-08 13:52 ` Artem Bityutskiy
2006-12-07 14:30 Artem Bityutskiy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=24414989.16841166158970543.JavaMail.weblogic@ep_ml08 \
--to=kyungmin.park@samsung.com \
--cc=dedekind@infradead.org \
--cc=linux-mtd@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox