mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.62,1.63
fgiasson at infradead.org
fgiasson at infradead.org
Mon Jan 27 11:34:38 EST 2003
Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv4785/mtd/drivers/mtd/chips
Modified Files:
cfi_cmdset_0002.c
Log Message:
do_write_oneword: Fixed double cfi_spin_unlock when timeout occurs. Also
fixed data polling algorithm and timeout calculation.
-
Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -r1.62 -r1.63
--- cfi_cmdset_0002.c 24 Jan 2003 23:30:13 -0000 1.62
+++ cfi_cmdset_0002.c 27 Jan 2003 16:34:36 -0000 1.63
@@ -460,6 +460,15 @@
unsigned int oldstatus, status;
unsigned int dq6, dq5;
struct cfi_private *cfi = map->fldrv_priv;
+ /* We use a 1ms + 1 jiffies generic timeout for writes (most devices have
+ a max write time of a few hundreds usec). However, we should use the
+ maximum timeout value given by the chip at probe time instead.
+ Unfortunately, struct flchip does have a field for maximum timeout,
+ only for typical which can be far too short depending of the conditions.
+ The ' + 1' is to avoid having a timeout of 0 jiffies if HZ is smaller
+ than 1000. Using a static variable allows makes us save the costly
+ divide operation at each word write.*/
+ static unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
@@ -511,7 +520,8 @@
or tells us why it failed. */
dq6 = CMD(1<<6);
dq5 = CMD(1<<5);
- timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */
+ /* See comment above for timeout value. */
+ timeo = jiffies + uWriteTimeout;
oldstatus = cfi_read(map, adr);
status = cfi_read(map, adr);
@@ -534,26 +544,22 @@
if( (status & dq6) != (oldstatus & dq6) ) {
/* The erasing didn't stop?? */
if( (status & dq5) == dq5 ) {
- /* When DQ5 raises, we must check once again
- if DQ6 is toggling. If not, the erase has been
- completed OK. If not, reset chip. */
+ /* When DQ5 raises, we must check once again if DQ6 is toggling.
+ If not, the erase has been completed OK. Then, we must reset
+ the chip. */
oldstatus = cfi_read(map, adr);
status = cfi_read(map, adr);
- if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) {
+ if( (status & dq6) == (oldstatus & dq6) ) {
printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" );
- } else {
- /* DQ5 is active so we can do a reset and stop the erase */
- cfi_write(map, CMD(0xF0), chip->start);
- printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" );
+ } else {
+ printk(KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was programming.\n" );
}
+
+ /* When DQ5 raises, we must do a reset. */
+ cfi_write( map, CMD(0xF0), chip->start );
} else {
- printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword.");
-
- chip->state = FL_READY;
- wake_up(&chip->wq);
- cfi_spin_unlock(chip->mutex);
- DISABLE_VPP(map);
+ printk( "Waiting for write to complete timed out in do_write_oneword.");
ret = -EIO;
}
}
More information about the linux-mtd-cvs
mailing list