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

Commit bd6b0242 authored by Pavel Andrianov's avatar Pavel Andrianov Committed by Kalle Valo
Browse files

wl3501_cs: Add spinlock to wl3501_reset



Likely wl3501_reset should acquire spinlock as wl3501_{open, close}.
One of calls of wl3501_reset has been already protected.
The others were unprotected and might lead to a race condition.
The patch adds spinlock into the wl3501_reset and removes it from
wl3501_tx_timeout.

Found by Linux Driver Verification project (linuxtesting.org)

Signed-off-by: default avatarPavel Andrianov <andrianov@ispras.ru>
Acked-by: default avatarVaishali Thakkar <vaishali.thakkar@oracle.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent b0d80f19
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -1258,7 +1258,9 @@ static int wl3501_reset(struct net_device *dev)
{
	struct wl3501_card *this = netdev_priv(dev);
	int rc = -ENODEV;
	unsigned long flags;

	spin_lock_irqsave(&this->lock, flags);
	wl3501_block_interrupt(this);

	if (wl3501_init_firmware(this)) {
@@ -1280,20 +1282,17 @@ static int wl3501_reset(struct net_device *dev)
	pr_debug("%s: device reset", dev->name);
	rc = 0;
out:
	spin_unlock_irqrestore(&this->lock, flags);
	return rc;
}

static void wl3501_tx_timeout(struct net_device *dev)
{
	struct wl3501_card *this = netdev_priv(dev);
	struct net_device_stats *stats = &dev->stats;
	unsigned long flags;
	int rc;

	stats->tx_errors++;
	spin_lock_irqsave(&this->lock, flags);
	rc = wl3501_reset(dev);
	spin_unlock_irqrestore(&this->lock, flags);
	if (rc)
		printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
		       dev->name, rc);