Fix for CFI Flash Driver bug in 2.4 Kernel

Matsen, Dean (WA26) Dean.Matsen at Honeywell.com
Fri Feb 24 08:33:37 EST 2006


All,

 

This patch applies to 2.4.22 from Monta Vista.  We started seeing a
kernel panic due to the really SLOOOOW 29LV641MH-120 flash parts.

Interestingly, the same part with 90mS access time (29LV641MH-120) are
about 10 times faster erasing and programming.

 

Turns out there are two problems in the driver code: 

 

1- the timeout is calculated incorrectly, based on HZ/100, which is zero
on my system 'cuz "HZ" is equal to 100

 

2- when the timeout occurs, the code erroneously releases a spinlock
twice.

 

I have not checked to see if there is a similar problem in the 2.6
kernel

 

Regards,

Dean Matsen

Software Architect

Alerton Honeywell

dean.matsen at honeywell.com

 

Patch follows:

 

 

------------------------------------------------------------------------
----------------------

diff --unified --recursive
ppc-linux-kernel.org/drivers/mtd/chips/cfi_cmdset_0002.c
ppc-linux-kernel/drivers/mtd/chips/cfi_cmdset_0002.c

--- ppc-linux-kernel.org/drivers/mtd/chips/cfi_cmdset_0002.c      Sat
Jul 12 01:08:17 2003

+++ ppc-linux-kernel/drivers/mtd/chips/cfi_cmdset_0002.c    Thu Feb 23
12:50:34 2006

@@ -10,6 +10,15 @@

  *

  * $Id: cfi_cmdset_0002.c,v 1.1.1.1 2003/07/12 08:08:17 dean Exp $

  *

+ * - 2006/02/23 : Dean Matsen (dean.matsen at honeywell.com) Fixed write 

+ *   timeout bug: timeout was based on HZ/1000 before (which is equal
to

+ *   zero in my system), also the exit path unlocked the spinlock
twice.

+ *   Increased timeout from 1mS to 100mS, because new 100K write
flashes

+ *   such as 29LV641MH say "TBD" in the data sheet for worst case
programming

+ *   time.  Problem was detected due to the really slow 29LV641MH-120
part,

+ *   which erases and programs 10 times slower than any other flash
we've

+ *   ever encountered (including the 29LV641MH-90, which is in the same

+ *   100K write family of parts!).

  */

 

 #include <linux/module.h>

@@ -511,7 +520,7 @@

         or tells us why it failed. */        

      dq6 = CMD(1<<6);

      dq5 = CMD(1<<5);

-     timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */

+     timeo = jiffies + (HZ/10); /* setting timeout to 100ms for now */

            

      oldstatus = cfi_read(map, adr);

      status = cfi_read(map, adr);

@@ -532,10 +541,10 @@

      }

      

      if( (status & dq6) != (oldstatus & dq6) ) {

-           /* The erasing didn't stop?? */

+           /* The writing 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

+                    if DQ6 is toggling.  If not, the write has been

                     completed OK.  If not, reset chip. */

                  oldstatus = cfi_read(map, adr);

                  status = cfi_read(map, adr);

@@ -543,7 +552,7 @@

                  if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) {

                        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 */

+                       /* DQ5 is active so we can do a reset and stop
the write */

                        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" );

                  }

@@ -554,7 +563,7 @@

                  wake_up(&chip->wq);

                  cfi_spin_unlock(chip->mutex);

                  DISABLE_VPP(map);

-                 ret = -EIO;

+                 return -EIO;

            }

      }

------------------------------------------------------------------------
-----------------------------------

 

 

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20060223/4c35a0cc/attachment.htm>


More information about the Linuxppc-dev mailing list