On 07.10.2010 23:59, Joshua Roys wrote:
> On 10/04/2010 08:58 AM, Carl-Daniel Hailfinger wrote:
>   
>> Bugfix, 0.9.3 candidate.
>>
>> SPI write status register (WRSR) may take longer than 100 ms, and it
>> makes sense to poll for completion in 10 ms steps.
>> This patch complements r1115.
>>
>> Signed-off-by: Carl-Daniel Hailfinger <[email protected]>
>>     
>
>   
>> +     * This may take 50-85 ms in most cases, and some chips apparently
>> +     * allow running RDSR only once. Pick an initial delay of 100 ms,
>> +     * then wait in 10 ms steps.
>>
>>     
> I might say "So, pick an initial delay..." or "Therefore pick an initial
> delay..." to make it a little clearer.  With or without,
>
> Acked-by: Joshua Roys <[email protected]>
>   

SPI write status register (WRSR) may take longer than 100 ms, and it
makes sense to poll for completion in 10 ms steps until 5 s are over.
This patch complements r1115.

Josh, I reused your ack. Any objections?

Signed-off-by: Carl-Daniel Hailfinger <[email protected]>
Acked-by: Joshua Roys <[email protected]>

Index: flashrom-wrsr_delay/flash.h
===================================================================
--- flashrom-wrsr_delay/flash.h (Revision 1200)
+++ flashrom-wrsr_delay/flash.h (Arbeitskopie)
@@ -35,6 +35,9 @@
 
 #define ERROR_PTR ((void*)-1)
 
+/* Error codes */
+#define TIMEOUT_ERROR  -101
+
 typedef unsigned long chipaddr;
 
 int register_shutdown(void (*function) (void *data), void *data);
Index: flashrom-wrsr_delay/spi25.c
===================================================================
--- flashrom-wrsr_delay/spi25.c (Revision 1200)
+++ flashrom-wrsr_delay/spi25.c (Arbeitskopie)
@@ -856,6 +856,7 @@
 static int spi_write_status_register_ewsr(struct flashchip *flash, int status)
 {
        int result;
+       int i = 0;
        struct spi_command cmds[] = {
        {
        /* WRSR requires either EWSR or WREN depending on chip type. */
@@ -879,15 +880,31 @@
        if (result) {
                msg_cerr("%s failed during command execution\n",
                        __func__);
+               /* No point in waiting for the command to complete if execution
+                * failed.
+                */
+               return result;
        }
-       /* WRSR performs a self-timed erase before the changes take effect. */
+       /* WRSR performs a self-timed erase before the changes take effect.
+        * This may take 50-85 ms in most cases, and some chips apparently
+        * allow running RDSR only once. Therefore pick an initial delay of
+        * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
+        */
        programmer_delay(100 * 1000);
-       return result;
+       while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) {
+               if (++i > 490) {
+                       msg_cerr("Error: WIP bit after WRSR never cleared\n");
+                       return TIMEOUT_ERROR;
+               }
+               programmer_delay(10 * 1000);
+       }
+       return 0;
 }
 
 static int spi_write_status_register_wren(struct flashchip *flash, int status)
 {
        int result;
+       int i = 0;
        struct spi_command cmds[] = {
        {
        /* WRSR requires either EWSR or WREN depending on chip type. */
@@ -911,10 +928,25 @@
        if (result) {
                msg_cerr("%s failed during command execution\n",
                        __func__);
+               /* No point in waiting for the command to complete if execution
+                * failed.
+                */
+               return result;
        }
-       /* WRSR performs a self-timed erase before the changes take effect. */
+       /* WRSR performs a self-timed erase before the changes take effect.
+        * This may take 50-85 ms in most cases, and some chips apparently
+        * allow running RDSR only once. Therefore pick an initial delay of
+        * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
+        */
        programmer_delay(100 * 1000);
-       return result;
+       while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) {
+               if (++i > 490) {
+                       msg_cerr("Error: WIP bit after WRSR never cleared\n");
+                       return TIMEOUT_ERROR;
+               }
+               programmer_delay(10 * 1000);
+       }
+       return 0;
 }
 
 static int spi_write_status_register(struct flashchip *flash, int status)


-- 
http://www.hailfinger.org/


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to