aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Andrianov <andrianov@ispras.ru>2016-08-02 12:41:53 +0300
committerKalle Valo <kvalo@codeaurora.org>2016-09-03 13:01:18 +0300
commitbd6b0242652a8a284eed2adec5ac1fc043b8f2ef (patch)
tree27ebd6c1668fd09df467db60337e43752112d7e5
parentb0d80f19c14fc5752e806860fe2c702448f5b442 (diff)
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: Pavel Andrianov <andrianov@ispras.ru> Acked-by: Vaishali Thakkar <vaishali.thakkar@oracle.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/wl3501_cs.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 82d94f8..932f3f81 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -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);