提交 58237983 编写于 作者: A Andrew Ruder 提交者: David S. Miller

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: NAndrew Ruder <andrew.ruder@elecsyscorp.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 aac6d022
...@@ -109,6 +109,7 @@ typedef struct board_info { ...@@ -109,6 +109,7 @@ typedef struct board_info {
u8 imr_all; u8 imr_all;
unsigned int flags; unsigned int flags;
unsigned int in_timeout:1;
unsigned int in_suspend:1; unsigned int in_suspend:1;
unsigned int wake_supported:1; unsigned int wake_supported:1;
...@@ -273,7 +274,7 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count) ...@@ -273,7 +274,7 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count)
*/ */
static void dm9000_msleep(board_info_t *db, unsigned int ms) static void dm9000_msleep(board_info_t *db, unsigned int ms)
{ {
if (db->in_suspend) if (db->in_suspend || db->in_timeout)
mdelay(ms); mdelay(ms);
else else
msleep(ms); msleep(ms);
...@@ -334,7 +335,8 @@ dm9000_phy_write(struct net_device *dev, ...@@ -334,7 +335,8 @@ dm9000_phy_write(struct net_device *dev,
unsigned long reg_save; unsigned long reg_save;
dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
mutex_lock(&db->addr_lock); if (!db->in_timeout)
mutex_lock(&db->addr_lock);
spin_lock_irqsave(&db->lock, flags); spin_lock_irqsave(&db->lock, flags);
...@@ -365,7 +367,8 @@ dm9000_phy_write(struct net_device *dev, ...@@ -365,7 +367,8 @@ dm9000_phy_write(struct net_device *dev,
writeb(reg_save, db->io_addr); writeb(reg_save, db->io_addr);
spin_unlock_irqrestore(&db->lock, flags); spin_unlock_irqrestore(&db->lock, flags);
mutex_unlock(&db->addr_lock); if (!db->in_timeout)
mutex_unlock(&db->addr_lock);
} }
/* dm9000_set_io /* dm9000_set_io
...@@ -971,6 +974,7 @@ static void dm9000_timeout(struct net_device *dev) ...@@ -971,6 +974,7 @@ static void dm9000_timeout(struct net_device *dev)
/* Save previous register address */ /* Save previous register address */
spin_lock_irqsave(&db->lock, flags); spin_lock_irqsave(&db->lock, flags);
db->in_timeout = 1;
reg_save = readb(db->io_addr); reg_save = readb(db->io_addr);
netif_stop_queue(dev); netif_stop_queue(dev);
...@@ -982,6 +986,7 @@ static void dm9000_timeout(struct net_device *dev) ...@@ -982,6 +986,7 @@ static void dm9000_timeout(struct net_device *dev)
/* Restore previous register address */ /* Restore previous register address */
writeb(reg_save, db->io_addr); writeb(reg_save, db->io_addr);
db->in_timeout = 0;
spin_unlock_irqrestore(&db->lock, flags); spin_unlock_irqrestore(&db->lock, flags);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册