mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 16:37:50 +00:00
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>
This commit is contained in:
parent
aac6d02280
commit
582379839b
1 changed files with 8 additions and 3 deletions
|
@ -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)
|
||||||
*/
|
*/
|
||||||
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,6 +335,7 @@ 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);
|
||||||
|
if (!db->in_timeout)
|
||||||
mutex_lock(&db->addr_lock);
|
mutex_lock(&db->addr_lock);
|
||||||
|
|
||||||
spin_lock_irqsave(&db->lock, flags);
|
spin_lock_irqsave(&db->lock, flags);
|
||||||
|
@ -365,6 +367,7 @@ 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);
|
||||||
|
if (!db->in_timeout)
|
||||||
mutex_unlock(&db->addr_lock);
|
mutex_unlock(&db->addr_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue