Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58237983 authored by Andrew Ruder's avatar Andrew Ruder Committed by David S. Miller
Browse files

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: default avatarAndrew Ruder <andrew.ruder@elecsyscorp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent aac6d022
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ typedef struct board_info {
	u8		imr_all;

	unsigned int	flags;
	unsigned int	in_timeout:1;
	unsigned int	in_suspend: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)
{
	if (db->in_suspend)
	if (db->in_suspend || db->in_timeout)
		mdelay(ms);
	else
		msleep(ms);
@@ -334,6 +335,7 @@ dm9000_phy_write(struct net_device *dev,
	unsigned long reg_save;

	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
	if (!db->in_timeout)
		mutex_lock(&db->addr_lock);

	spin_lock_irqsave(&db->lock, flags);
@@ -365,6 +367,7 @@ dm9000_phy_write(struct net_device *dev,
	writeb(reg_save, db->io_addr);

	spin_unlock_irqrestore(&db->lock, flags);
	if (!db->in_timeout)
		mutex_unlock(&db->addr_lock);
}

@@ -971,6 +974,7 @@ static void dm9000_timeout(struct net_device *dev)

	/* Save previous register address */
	spin_lock_irqsave(&db->lock, flags);
	db->in_timeout = 1;
	reg_save = readb(db->io_addr);

	netif_stop_queue(dev);
@@ -982,6 +986,7 @@ static void dm9000_timeout(struct net_device *dev)

	/* Restore previous register address */
	writeb(reg_save, db->io_addr);
	db->in_timeout = 0;
	spin_unlock_irqrestore(&db->lock, flags);
}