mtd/drivers/mtd/chips cfi_cmdset_0001.c,1.165,1.166
Nicolas Pitre
nico at infradead.org
Fri Feb 4 21:35:29 EST 2005
Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv17087/drivers/mtd/chips
Modified Files:
cfi_cmdset_0001.c
Log Message:
Another fix to the put_chip() concurrency logic.
Problem was occurring when:
1) one thread was erasing a block in partition x;
2) another thread suspended the erase in order to write to
partition y;
3) a third thread came along to read a different block from
partition x and, when it called put_chip(), chip->oldstate was
FL_ERASING and the erase (mistakenly) resumed;
4) the write in partition y obviously failed.
Incidentally, the fix for this problem also fixed the case where
suspending writes for MTD XIP usage was not working properly.
Index: cfi_cmdset_0001.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0001.c,v
retrieving revision 1.165
retrieving revision 1.166
diff -u -r1.165 -r1.166
--- cfi_cmdset_0001.c 5 Feb 2005 02:06:15 -0000 1.165
+++ cfi_cmdset_0001.c 5 Feb 2005 02:35:26 -0000 1.166
@@ -36,10 +36,7 @@
#include <linux/mtd/cfi.h>
/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
-
-#ifdef CONFIG_MTD_XIP
-#define CMDSET0001_DISABLE_WRITE_SUSPEND
-#endif
+/* #define CMDSET0001_DISABLE_WRITE_SUSPEND */
// debugging, turns off buffer write mode if set to 1
#define FORCE_WORD_WRITE 0
@@ -152,7 +149,6 @@
#endif
#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
-/* The XIP config appears to have problems using write suspend at the moment */
static void fixup_no_write_suspend(struct mtd_info *mtd, void* param)
{
struct map_info *map = mtd->priv;
@@ -735,7 +731,7 @@
if (chip->priv) {
struct flchip_shared *shared = chip->priv;
spin_lock(&shared->lock);
- if (shared->writing == chip) {
+ if (shared->writing == chip && chip->oldstate == FL_READY) {
/* We own the ability to write, but we're done */
shared->writing = shared->erasing;
if (shared->writing && shared->writing != chip) {
@@ -747,17 +743,24 @@
put_chip(map, loaner, loaner->start);
spin_lock(chip->mutex);
spin_unlock(loaner->mutex);
- } else {
- if (chip->oldstate != FL_ERASING) {
- shared->erasing = NULL;
- if (chip->oldstate != FL_WRITING)
- shared->writing = NULL;
- }
- spin_unlock(&shared->lock);
+ wake_up(&chip->wq);
+ return;
}
- } else {
+ shared->erasing = NULL;
+ shared->writing = NULL;
+ } else if (shared->erasing == chip && shared->writing != chip) {
+ /*
+ * We own the ability to erase without the ability
+ * to write, which means the erase was suspended
+ * and some other partition is currently writing.
+ * Don't let the switch below mess things up since
+ * we don't have ownership to resume anything.
+ */
spin_unlock(&shared->lock);
+ wake_up(&chip->wq);
+ return;
}
+ spin_unlock(&shared->lock);
}
switch(chip->oldstate) {
More information about the linux-mtd-cvs
mailing list