Commit 621ddcb0 authored by Ben Dooks's avatar Ben Dooks Committed by Jeff Garzik

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: default avatarBen Dooks <ben-linux@fluff.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 3927f1c8
...@@ -1073,17 +1073,29 @@ dm9000_rx(struct net_device *dev) ...@@ -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) ...@@ -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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment