DM9000: Ensure spinlock held whilst accessing EEPROM registers
authorBen Dooks <ben-linux@fluff.org>
Tue, 5 Feb 2008 00:02:14 +0000 (00:02 +0000)
committerJeff Garzik <jeff@garzik.org>
Mon, 11 Feb 2008 16:06:31 +0000 (11:06 -0500)
Ensure we hold the spinlock whilst the registers and being
modified even though we hold the overall lock. This should
protect against an interrupt happening whilst we are using
the device.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/dm9000.c

index 3bef3b25ff0ec2f533418b6d8f555f3851d056da..5a883711d1f4548be5330c306fc6ab949b3e18d3 100644 (file)
@@ -1073,17 +1073,29 @@ dm9000_rx(struct net_device *dev)
 static void
 dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
 {
+       unsigned long flags;
+
        mutex_lock(&db->addr_lock);
 
+       spin_lock_irqsave(&db->lock, flags);
+
        iow(db, DM9000_EPAR, offset);
        iow(db, DM9000_EPCR, EPCR_ERPRR);
+
+       spin_unlock_irqrestore(&db->lock, flags);
+
        mdelay(8);              /* according to the datasheet 200us should be enough,
                                   but it doesn't work */
+
+       spin_lock_irqsave(&db->lock, flags);
+
        iow(db, DM9000_EPCR, 0x0);
 
        to[0] = ior(db, DM9000_EPDRL);
        to[1] = ior(db, DM9000_EPDRH);
 
+       spin_unlock_irqrestore(&db->lock, flags);
+
        mutex_unlock(&db->addr_lock);
 }
 
@@ -1093,14 +1105,22 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
 static void
 dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
 {
+       unsigned long flags;
+
        mutex_lock(&db->addr_lock);
 
+       spin_lock_irqsave(&db->lock, flags);
        iow(db, DM9000_EPAR, offset);
        iow(db, DM9000_EPDRH, data[1]);
        iow(db, DM9000_EPDRL, data[0]);
        iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
+       spin_unlock_irqrestore(&db->lock, flags);
+
        mdelay(8);              /* same shit */
+
+       spin_lock_irqsave(&db->lock, flags);
        iow(db, DM9000_EPCR, 0);
+       spin_unlock_irqrestore(&db->lock, flags);
 
        mutex_unlock(&db->addr_lock);
 }