aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorBen Dooks <ben-netdev@fluff.org>2005-07-23 12:25:18 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-18 16:59:14 -0400
commit9ef9ac51cc5fa5f5811230b5fb242536b636ff47 (patch)
tree228175f622065b3683e2c2b94468210752004804 /drivers/net
parenta4cf0761493495681d72dcc0b34efb86e94a5527 (diff)
[PATCH] DM9000 - spinlock fixes
Fix DM9000 driver usage of spinlocks, which mainly came to light when running a kernel with spinlock debugging. These come down to: 1) Un-initialised spin lock 2) Several cases of using spin_xxx(lock) and not spin_xxx(&lock) 3) move the locking around the phy reg for read/write to only keep the lock when actually reading or writing to the phy. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/dm9000.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 5fddc0ff8878..1d92ddd1ec35 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -48,6 +48,10 @@
48 * net_device_stats 48 * net_device_stats
49 * * introduced tx_timeout function 49 * * introduced tx_timeout function
50 * * reworked locking 50 * * reworked locking
51 *
52 * 01-Jul-2005 Ben Dooks <ben@simtec.co.uk>
53 * * fixed spinlock call without pointer
54 * * ensure spinlock is initialised
51 */ 55 */
52 56
53#include <linux/module.h> 57#include <linux/module.h>
@@ -322,7 +326,7 @@ static void dm9000_timeout(struct net_device *dev)
322 326
323 /* Save previous register address */ 327 /* Save previous register address */
324 reg_save = readb(db->io_addr); 328 reg_save = readb(db->io_addr);
325 spin_lock_irqsave(db->lock,flags); 329 spin_lock_irqsave(&db->lock,flags);
326 330
327 netif_stop_queue(dev); 331 netif_stop_queue(dev);
328 dm9000_reset(db); 332 dm9000_reset(db);
@@ -333,7 +337,7 @@ static void dm9000_timeout(struct net_device *dev)
333 337
334 /* Restore previous register address */ 338 /* Restore previous register address */
335 writeb(reg_save, db->io_addr); 339 writeb(reg_save, db->io_addr);
336 spin_unlock_irqrestore(db->lock,flags); 340 spin_unlock_irqrestore(&db->lock,flags);
337} 341}
338 342
339 343
@@ -405,6 +409,8 @@ dm9000_probe(struct device *dev)
405 db = (struct board_info *) ndev->priv; 409 db = (struct board_info *) ndev->priv;
406 memset(db, 0, sizeof (*db)); 410 memset(db, 0, sizeof (*db));
407 411
412 spin_lock_init(&db->lock);
413
408 if (pdev->num_resources < 2) { 414 if (pdev->num_resources < 2) {
409 ret = -ENODEV; 415 ret = -ENODEV;
410 goto out; 416 goto out;
@@ -612,7 +618,7 @@ dm9000_open(struct net_device *dev)
612 618
613 /* set and active a timer process */ 619 /* set and active a timer process */
614 init_timer(&db->timer); 620 init_timer(&db->timer);
615 db->timer.expires = DM9000_TIMER_WUT * 2; 621 db->timer.expires = DM9000_TIMER_WUT;
616 db->timer.data = (unsigned long) dev; 622 db->timer.data = (unsigned long) dev;
617 db->timer.function = &dm9000_timer; 623 db->timer.function = &dm9000_timer;
618 add_timer(&db->timer); 624 add_timer(&db->timer);
@@ -864,21 +870,11 @@ dm9000_timer(unsigned long data)
864{ 870{
865 struct net_device *dev = (struct net_device *) data; 871 struct net_device *dev = (struct net_device *) data;
866 board_info_t *db = (board_info_t *) dev->priv; 872 board_info_t *db = (board_info_t *) dev->priv;
867 u8 reg_save;
868 unsigned long flags;
869 873
870 PRINTK3("dm9000_timer()\n"); 874 PRINTK3("dm9000_timer()\n");
871 875
872 spin_lock_irqsave(db->lock,flags);
873 /* Save previous register address */
874 reg_save = readb(db->io_addr);
875
876 mii_check_media(&db->mii, netif_msg_link(db), 0); 876 mii_check_media(&db->mii, netif_msg_link(db), 0);
877 877
878 /* Restore previous register address */
879 writeb(reg_save, db->io_addr);
880 spin_unlock_irqrestore(db->lock,flags);
881
882 /* Set timer again */ 878 /* Set timer again */
883 db->timer.expires = DM9000_TIMER_WUT; 879 db->timer.expires = DM9000_TIMER_WUT;
884 add_timer(&db->timer); 880 add_timer(&db->timer);
@@ -1098,9 +1094,14 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
1098{ 1094{
1099 board_info_t *db = (board_info_t *) dev->priv; 1095 board_info_t *db = (board_info_t *) dev->priv;
1100 unsigned long flags; 1096 unsigned long flags;
1097 unsigned int reg_save;
1101 int ret; 1098 int ret;
1102 1099
1103 spin_lock_irqsave(&db->lock,flags); 1100 spin_lock_irqsave(&db->lock,flags);
1101
1102 /* Save previous register address */
1103 reg_save = readb(db->io_addr);
1104
1104 /* Fill the phyxcer register into REG_0C */ 1105 /* Fill the phyxcer register into REG_0C */
1105 iow(db, DM9000_EPAR, DM9000_PHY | reg); 1106 iow(db, DM9000_EPAR, DM9000_PHY | reg);
1106 1107
@@ -1111,6 +1112,9 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
1111 /* The read data keeps on REG_0D & REG_0E */ 1112 /* The read data keeps on REG_0D & REG_0E */
1112 ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); 1113 ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
1113 1114
1115 /* restore the previous address */
1116 writeb(reg_save, db->io_addr);
1117
1114 spin_unlock_irqrestore(&db->lock,flags); 1118 spin_unlock_irqrestore(&db->lock,flags);
1115 1119
1116 return ret; 1120 return ret;
@@ -1124,9 +1128,13 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
1124{ 1128{
1125 board_info_t *db = (board_info_t *) dev->priv; 1129 board_info_t *db = (board_info_t *) dev->priv;
1126 unsigned long flags; 1130 unsigned long flags;
1131 unsigned long reg_save;
1127 1132
1128 spin_lock_irqsave(&db->lock,flags); 1133 spin_lock_irqsave(&db->lock,flags);
1129 1134
1135 /* Save previous register address */
1136 reg_save = readb(db->io_addr);
1137
1130 /* Fill the phyxcer register into REG_0C */ 1138 /* Fill the phyxcer register into REG_0C */
1131 iow(db, DM9000_EPAR, DM9000_PHY | reg); 1139 iow(db, DM9000_EPAR, DM9000_PHY | reg);
1132 1140
@@ -1138,6 +1146,9 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
1138 udelay(500); /* Wait write complete */ 1146 udelay(500); /* Wait write complete */
1139 iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ 1147 iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */
1140 1148
1149 /* restore the previous address */
1150 writeb(reg_save, db->io_addr);
1151
1141 spin_unlock_irqrestore(&db->lock,flags); 1152 spin_unlock_irqrestore(&db->lock,flags);
1142} 1153}
1143 1154