Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=39c341a8dcf060b246b0beddac90cd7de11d4a20
Commit:     39c341a8dcf060b246b0beddac90cd7de11d4a20
Parent:     c991d168cb649d416c5a773a50d0754299f31366
Author:     Ben Dooks <[EMAIL PROTECTED]>
AuthorDate: Tue Feb 5 00:02:17 2008 +0000
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Mon Feb 11 11:06:33 2008 -0500

    DM9000: Fix delays used by EEPROM read and write
    
    The code was using a delay of 8ms, when it should have been
    using the EEPROM status flag from the device to indicate the
    EEPROM transaction had finished.
    
    Signed-off-by: Ben Dooks <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/dm9000.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 8516183..1d790a8 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1048,6 +1048,50 @@ dm9000_rx(struct net_device *dev)
        } while (rxbyte == DM9000_PKT_RDY);
 }
 
+static unsigned int
+dm9000_read_locked(board_info_t *db, int reg)
+{
+       unsigned long flags;
+       unsigned int ret;
+
+       spin_lock_irqsave(&db->lock, flags);
+       ret = ior(db, reg);
+       spin_unlock_irqrestore(&db->lock, flags);
+
+       return ret;
+}
+
+static int dm9000_wait_eeprom(board_info_t *db)
+{
+       unsigned int status;
+       int timeout = 8;        /* wait max 8msec */
+
+       /* The DM9000 data sheets say we should be able to
+        * poll the ERRE bit in EPCR to wait for the EEPROM
+        * operation. From testing several chips, this bit
+        * does not seem to work. 
+        *
+        * We attempt to use the bit, but fall back to the
+        * timeout (which is why we do not return an error
+        * on expiry) to say that the EEPROM operation has
+        * completed.
+        */
+
+       while (1) {
+               status = dm9000_read_locked(db, DM9000_EPCR);
+
+               if ((status & EPCR_ERRE) == 0)
+                       break;
+
+               if (timeout-- < 0) {
+                       dev_dbg(db->dev, "timeout waiting EEPROM\n");
+                       break;
+               }
+       }
+
+       return 0;
+}
+
 /*
  *  Read a word data from EEPROM
  */
@@ -1065,8 +1109,10 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
 
        spin_unlock_irqrestore(&db->lock, flags);
 
-       mdelay(8);              /* according to the datasheet 200us should be 
enough,
-                                  but it doesn't work */
+       dm9000_wait_eeprom(db);
+
+       /* delay for at-least 150uS */
+       msleep(1);
 
        spin_lock_irqsave(&db->lock, flags);
 
@@ -1097,7 +1143,9 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 
*data)
        iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
        spin_unlock_irqrestore(&db->lock, flags);
 
-       mdelay(8);              /* same shit */
+       dm9000_wait_eeprom(db);
+
+       mdelay(1);      /* wait at least 150uS to clear */
 
        spin_lock_irqsave(&db->lock, flags);
        iow(db, DM9000_EPCR, 0);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to