aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Ruder <andrew.ruder@elecsyscorp.com>2014-06-04 18:28:49 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-05 18:12:11 -0400
commit582379839bbdb76f2f0ad956a39f920cfd84fcea (patch)
tree8d3fb538f4c94b13d9dad30d99da4022e6fdbdfa
parentaac6d02280e61bc30302024ffd7541e0951a2cf6 (diff)
dm9000: avoid sleeping in dm9000_timeout callback
On the DM9000B, dm9000_msleep() is called during the dm9000_timeout() routine. Since dm9000_timeout() holds the main spinlock through the entire routine, mdelay() needs to be used rather than msleep(). Furthermore, the mutex_lock()/mutex_unlock() should be avoided so as to not sleep with spinlocks held. Signed-off-by: Andrew Ruder <andrew.ruder@elecsyscorp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/davicom/dm9000.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 48870a8b39a4..13723c96d1a2 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -109,6 +109,7 @@ typedef struct board_info {
109 u8 imr_all; 109 u8 imr_all;
110 110
111 unsigned int flags; 111 unsigned int flags;
112 unsigned int in_timeout:1;
112 unsigned int in_suspend:1; 113 unsigned int in_suspend:1;
113 unsigned int wake_supported:1; 114 unsigned int wake_supported:1;
114 115
@@ -273,7 +274,7 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count)
273 */ 274 */
274static void dm9000_msleep(board_info_t *db, unsigned int ms) 275static void dm9000_msleep(board_info_t *db, unsigned int ms)
275{ 276{
276 if (db->in_suspend) 277 if (db->in_suspend || db->in_timeout)
277 mdelay(ms); 278 mdelay(ms);
278 else 279 else
279 msleep(ms); 280 msleep(ms);
@@ -334,7 +335,8 @@ dm9000_phy_write(struct net_device *dev,
334 unsigned long reg_save; 335 unsigned long reg_save;
335 336
336 dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); 337 dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
337 mutex_lock(&db->addr_lock); 338 if (!db->in_timeout)
339 mutex_lock(&db->addr_lock);
338 340
339 spin_lock_irqsave(&db->lock, flags); 341 spin_lock_irqsave(&db->lock, flags);
340 342
@@ -365,7 +367,8 @@ dm9000_phy_write(struct net_device *dev,
365 writeb(reg_save, db->io_addr); 367 writeb(reg_save, db->io_addr);
366 368
367 spin_unlock_irqrestore(&db->lock, flags); 369 spin_unlock_irqrestore(&db->lock, flags);
368 mutex_unlock(&db->addr_lock); 370 if (!db->in_timeout)
371 mutex_unlock(&db->addr_lock);
369} 372}
370 373
371/* dm9000_set_io 374/* dm9000_set_io
@@ -971,6 +974,7 @@ static void dm9000_timeout(struct net_device *dev)
971 974
972 /* Save previous register address */ 975 /* Save previous register address */
973 spin_lock_irqsave(&db->lock, flags); 976 spin_lock_irqsave(&db->lock, flags);
977 db->in_timeout = 1;
974 reg_save = readb(db->io_addr); 978 reg_save = readb(db->io_addr);
975 979
976 netif_stop_queue(dev); 980 netif_stop_queue(dev);
@@ -982,6 +986,7 @@ static void dm9000_timeout(struct net_device *dev)
982 986
983 /* Restore previous register address */ 987 /* Restore previous register address */
984 writeb(reg_save, db->io_addr); 988 writeb(reg_save, db->io_addr);
989 db->in_timeout = 0;
985 spin_unlock_irqrestore(&db->lock, flags); 990 spin_unlock_irqrestore(&db->lock, flags);
986} 991}
987 992