From 621ddcb0461baee26a5e7c86a76938f0aa83dec1 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 5 Feb 2008 00:02:14 +0000 Subject: 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 Signed-off-by: Jeff Garzik --- drivers/net/dm9000.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/net/dm9000.c') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 3bef3b25ff0..5a883711d1f 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -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); } -- cgit v1.2.3