diff options
author | Vasily Khoruzhick <anarsoul@gmail.com> | 2011-04-06 10:49:15 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-04-07 14:17:45 -0400 |
commit | 850a28ecd8044ef36b2c7699d2e3736a410b4d0a (patch) | |
tree | 42a67f4ca8a624df752ad790fe0614fa584817d6 | |
parent | 454abcc57f1d48a976291bc4af73b5f087e21d70 (diff) |
spi: Fix race condition in stop_queue()
There's a race condition in stop_queue() in some drivers -
if drv_data->queue is empty, but drv_data->busy is still set
(or opposite situation) stop_queue will return -EBUSY.
So fix loop condition to check that both drv_data->queue is empty
and drv_data->busy is not set.
This patch affects following drivers:
pxa2xx_spi
spi_bfin5xx
amba-pl022
dw_spi
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Acked-by: Eric Miao <eric.y.miao@gmail.com>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r-- | drivers/spi/amba-pl022.c | 2 | ||||
-rw-r--r-- | drivers/spi/dw_spi.c | 2 | ||||
-rw-r--r-- | drivers/spi/pxa2xx_spi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 2 |
4 files changed, 4 insertions, 4 deletions
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 5a4e0afb9ad6..4b8357b728cb 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -1555,7 +1555,7 @@ static int stop_queue(struct pl022 *pl022) | |||
1555 | * A wait_queue on the pl022->busy could be used, but then the common | 1555 | * A wait_queue on the pl022->busy could be used, but then the common |
1556 | * execution path (pump_messages) would be required to call wake_up or | 1556 | * execution path (pump_messages) would be required to call wake_up or |
1557 | * friends on every SPI message. Do this instead */ | 1557 | * friends on every SPI message. Do this instead */ |
1558 | while (!list_empty(&pl022->queue) && pl022->busy && limit--) { | 1558 | while ((!list_empty(&pl022->queue) || pl022->busy) && limit--) { |
1559 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | 1559 | spin_unlock_irqrestore(&pl022->queue_lock, flags); |
1560 | msleep(10); | 1560 | msleep(10); |
1561 | spin_lock_irqsave(&pl022->queue_lock, flags); | 1561 | spin_lock_irqsave(&pl022->queue_lock, flags); |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 9a6196461b27..d040debc07c2 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -821,7 +821,7 @@ static int stop_queue(struct dw_spi *dws) | |||
821 | 821 | ||
822 | spin_lock_irqsave(&dws->lock, flags); | 822 | spin_lock_irqsave(&dws->lock, flags); |
823 | dws->run = QUEUE_STOPPED; | 823 | dws->run = QUEUE_STOPPED; |
824 | while (!list_empty(&dws->queue) && dws->busy && limit--) { | 824 | while ((!list_empty(&dws->queue) || dws->busy) && limit--) { |
825 | spin_unlock_irqrestore(&dws->lock, flags); | 825 | spin_unlock_irqrestore(&dws->lock, flags); |
826 | msleep(10); | 826 | msleep(10); |
827 | spin_lock_irqsave(&dws->lock, flags); | 827 | spin_lock_irqsave(&dws->lock, flags); |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index a429b01d0285..3aa782067b68 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -1493,7 +1493,7 @@ static int stop_queue(struct driver_data *drv_data) | |||
1493 | * execution path (pump_messages) would be required to call wake_up or | 1493 | * execution path (pump_messages) would be required to call wake_up or |
1494 | * friends on every SPI message. Do this instead */ | 1494 | * friends on every SPI message. Do this instead */ |
1495 | drv_data->run = QUEUE_STOPPED; | 1495 | drv_data->run = QUEUE_STOPPED; |
1496 | while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { | 1496 | while ((!list_empty(&drv_data->queue) || drv_data->busy) && limit--) { |
1497 | spin_unlock_irqrestore(&drv_data->lock, flags); | 1497 | spin_unlock_irqrestore(&drv_data->lock, flags); |
1498 | msleep(10); | 1498 | msleep(10); |
1499 | spin_lock_irqsave(&drv_data->lock, flags); | 1499 | spin_lock_irqsave(&drv_data->lock, flags); |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index a28462486df8..f3a1c52c0fb0 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -1284,7 +1284,7 @@ static inline int bfin_spi_stop_queue(struct bfin_spi_master_data *drv_data) | |||
1284 | * friends on every SPI message. Do this instead | 1284 | * friends on every SPI message. Do this instead |
1285 | */ | 1285 | */ |
1286 | drv_data->running = false; | 1286 | drv_data->running = false; |
1287 | while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { | 1287 | while ((!list_empty(&drv_data->queue) || drv_data->busy) && limit--) { |
1288 | spin_unlock_irqrestore(&drv_data->lock, flags); | 1288 | spin_unlock_irqrestore(&drv_data->lock, flags); |
1289 | msleep(10); | 1289 | msleep(10); |
1290 | spin_lock_irqsave(&drv_data->lock, flags); | 1290 | spin_lock_irqsave(&drv_data->lock, flags); |