Browse Source

DM9000: Ensure spinlock held whilst accessing EEPROM registers

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>
Ben Dooks 17 years ago
parent
commit
621ddcb046
1 changed files with 20 additions and 0 deletions
  1. 20 0
      drivers/net/dm9000.c

+ 20 - 0
drivers/net/dm9000.c

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