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