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>
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user