From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
To: linux-mtd@lists.infradead.org
Subject: cfi_cmd0001.c broken w.r.t Erase Suspend
Date: Sun, 12 Nov 2006 17:28:37 +0100 [thread overview]
Message-ID: <45574BB5.5010601@transmode.se> (raw)
[-- Attachment #1: Type: text/plain, Size: 1323 bytes --]
Hi List
I found some problems that I think is flash driver
related(cfi_cmd0001.c). Somehow the
flash is in Erase suspend when do_erase_oneblock has returned from
INVAL_CACHE_AND_WAIT
I have tried lots of "fixes" but the only one that works is to detect
the Suspend in do_erase_oneblock
and issue a new resume and go back to INVAL_CAHCE_AND_WAIT, see attached
patch.
I am uing Intel P30 flash and 2.6.19-rc3 on powerpc
How to reproduce:
apply patch to kernel
boot to userspace and do:
cp -a /bin /root/tt1
cp -a /bin /root/tt2
cp -a /bin /root/tt3
cp -a /bin /root/tt4
cp -a /bin /root/tt5
Fill up the rest JFFS2 FS to it is full using dd to create an huge file
until the FS is full.
make sure syslog and klogd is running and is logging to file on the
JFFS2 FS.
Now do
1)
rm -rf /root/tt5
cp -a /root/tt1 /root/tt5
wait a few secs to a minute, then go to 1)
a few other observations:
It is very hard to trigger a erase, seems like the gc daemon uses that
as its last resort. Why not
erase blocks as soon they are ready to be erased?
I have seen cp consume 100% CPU sevral times
Also noticed gc sleeping whil cp is running and making no progress.
had to kick gc with a kill -HUP <gc pid> to make it run to make room for
the cp.
The above observations makes me think there is a bug or two in JFFS2 as
well.
Jocke
[-- Attachment #2: cfi_cmd0001.patch --]
[-- Type: text/x-patch, Size: 2370 bytes --]
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 2fd5cef..6f2d2d9 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -751,6 +751,8 @@ static int get_chip(struct map_info *map
map_write(map, CMD(0x70), adr);
chip->oldstate = FL_ERASING;
chip->state = FL_ERASE_SUSPENDING;
+ if (chip->erase_suspended)
+ printk("chip already suspended");
chip->erase_suspended = 1;
for (;;) {
status = map_read(map, adr);
@@ -775,6 +777,9 @@ static int get_chip(struct map_info *map
/* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
So we can just loop here. */
}
+ if (chip->erase_suspended != 1)
+ printk("SUSPEND: chip not suspended");
+
chip->state = FL_STATUS;
return 0;
@@ -854,10 +859,15 @@ static void put_chip(struct map_info *ma
sending the 0x70 (Read Status) command to an erasing
chip and expecting it to be ignored, that's what we
do. */
+ if (chip->erase_suspended != 1)
+ printk("RESUME: chip not suspended");
+ chip->erase_suspended = 0;
map_write(map, CMD(0xd0), adr);
map_write(map, CMD(0x70), adr);
chip->oldstate = FL_READY;
chip->state = FL_ERASING;
+ if (chip->erase_suspended)
+ printk("RESUME: chip suspended");
break;
case FL_XIP_WHILE_ERASING:
@@ -1718,7 +1728,7 @@ static int __xipram do_erase_oneblock(st
map_write(map, CMD(0xD0), adr);
chip->state = FL_ERASING;
chip->erase_suspended = 0;
-
+ again:
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len,
chip->erase_time);
@@ -1734,6 +1744,15 @@ static int __xipram do_erase_oneblock(st
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
status = map_read(map, adr);
+#if 1
+ if (map_word_bitsset(map, status, CMD(0x40))) {
+ printk("resume again:%lx\n", MERGESTATUS(status));
+ chip->state = FL_ERASING;
+ map_write(map, CMD(0x50), adr); /* reset status */
+ map_write(map, CMD(0xd0), adr); /* resume */
+ goto again;
+ }
+#endif
/* check for errors */
if (map_word_bitsset(map, status, CMD(0x3a))) {
@@ -1770,6 +1789,7 @@ static int __xipram do_erase_oneblock(st
xip_enable(map, chip, adr);
out: put_chip(map, chip, adr);
spin_unlock(chip->mutex);
+ printk("ERASE DONE: chip:%p adr:%x, status 0x%lx\n", chip, adr, MERGESTATUS(status));
return ret;
}
next reply other threads:[~2006-11-12 16:29 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-12 16:28 Joakim Tjernlund [this message]
2006-11-13 12:02 ` cfi_cmd0001.c broken w.r.t Erase Suspend solved, patch included Joakim Tjernlund
2006-11-16 14:46 ` 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=45574BB5.5010601@transmode.se \
--to=joakim.tjernlund@transmode.se \
--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