diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-02-04 19:02:14 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-02-11 11:06:31 -0500 |
commit | 621ddcb0461baee26a5e7c86a76938f0aa83dec1 (patch) | |
tree | 40fed02f95849d05370ee7bb59df63852ee13fe1 | |
parent | 3927f1c88efc25b2972c8cbd7ed10d5f1b88b52a (diff) |
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>
-rw-r--r-- | drivers/net/dm9000.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 3bef3b25ff0e..5a883711d1f4 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -1073,17 +1073,29 @@ dm9000_rx(struct net_device *dev) | |||
1073 | static void | 1073 | static void |
1074 | dm9000_read_eeprom(board_info_t *db, int offset, u8 *to) | 1074 | dm9000_read_eeprom(board_info_t *db, int offset, u8 *to) |
1075 | { | 1075 | { |
1076 | unsigned long flags; | ||
1077 | |||
1076 | mutex_lock(&db->addr_lock); | 1078 | mutex_lock(&db->addr_lock); |
1077 | 1079 | ||
1080 | spin_lock_irqsave(&db->lock, flags); | ||
1081 | |||
1078 | iow(db, DM9000_EPAR, offset); | 1082 | iow(db, DM9000_EPAR, offset); |
1079 | iow(db, DM9000_EPCR, EPCR_ERPRR); | 1083 | iow(db, DM9000_EPCR, EPCR_ERPRR); |
1084 | |||
1085 | spin_unlock_irqrestore(&db->lock, flags); | ||
1086 | |||
1080 | mdelay(8); /* according to the datasheet 200us should be enough, | 1087 | mdelay(8); /* according to the datasheet 200us should be enough, |
1081 | but it doesn't work */ | 1088 | but it doesn't work */ |
1089 | |||
1090 | spin_lock_irqsave(&db->lock, flags); | ||
1091 | |||
1082 | iow(db, DM9000_EPCR, 0x0); | 1092 | iow(db, DM9000_EPCR, 0x0); |
1083 | 1093 | ||
1084 | to[0] = ior(db, DM9000_EPDRL); | 1094 | to[0] = ior(db, DM9000_EPDRL); |
1085 | to[1] = ior(db, DM9000_EPDRH); | 1095 | to[1] = ior(db, DM9000_EPDRH); |
1086 | 1096 | ||
1097 | spin_unlock_irqrestore(&db->lock, flags); | ||
1098 | |||
1087 | mutex_unlock(&db->addr_lock); | 1099 | mutex_unlock(&db->addr_lock); |
1088 | } | 1100 | } |
1089 | 1101 | ||
@@ -1093,14 +1105,22 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to) | |||
1093 | static void | 1105 | static void |
1094 | dm9000_write_eeprom(board_info_t *db, int offset, u8 *data) | 1106 | dm9000_write_eeprom(board_info_t *db, int offset, u8 *data) |
1095 | { | 1107 | { |
1108 | unsigned long flags; | ||
1109 | |||
1096 | mutex_lock(&db->addr_lock); | 1110 | mutex_lock(&db->addr_lock); |
1097 | 1111 | ||
1112 | spin_lock_irqsave(&db->lock, flags); | ||
1098 | iow(db, DM9000_EPAR, offset); | 1113 | iow(db, DM9000_EPAR, offset); |
1099 | iow(db, DM9000_EPDRH, data[1]); | 1114 | iow(db, DM9000_EPDRH, data[1]); |
1100 | iow(db, DM9000_EPDRL, data[0]); | 1115 | iow(db, DM9000_EPDRL, data[0]); |
1101 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); | 1116 | iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); |
1117 | spin_unlock_irqrestore(&db->lock, flags); | ||
1118 | |||
1102 | mdelay(8); /* same shit */ | 1119 | mdelay(8); /* same shit */ |
1120 | |||
1121 | spin_lock_irqsave(&db->lock, flags); | ||
1103 | iow(db, DM9000_EPCR, 0); | 1122 | iow(db, DM9000_EPCR, 0); |
1123 | spin_unlock_irqrestore(&db->lock, flags); | ||
1104 | 1124 | ||
1105 | mutex_unlock(&db->addr_lock); | 1125 | mutex_unlock(&db->addr_lock); |
1106 | } | 1126 | } |