aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGrazvydas Ignotas <notasas@gmail.com>2012-05-17 20:04:08 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-25 11:16:16 -0400
commitf380f2c4a12e913356bd49f8790ec1063c4fe9f8 (patch)
treea2e73c632dd3e892d7997d6c4287e3eee60ca3e9 /drivers/net
parent75813bde1f671aaab3185a9438da7730d356cea6 (diff)
wl1251: fix oops on early interrupt
This driver disables interrupt just after requesting it and enables it later, after interface is up. However currently there is a time window between request_irq() and disable_irq() where if interrupt arrives, the driver oopses because it's not yet ready to process it. This can be reproduced by inserting the module, associating and removing the module multiple times. Eliminate this race by setting IRQF_NOAUTOEN flag before request_irq(). Cc: stable@vger.kernel.org # v2.6.37+ Signed-off-by: Grazvydas Ignotas <notasas@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c2
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c3
2 files changed, 2 insertions, 3 deletions
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index 1b851f650e07..e2750a12c6f1 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -260,6 +260,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
260 } 260 }
261 261
262 if (wl->irq) { 262 if (wl->irq) {
263 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
263 ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); 264 ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
264 if (ret < 0) { 265 if (ret < 0) {
265 wl1251_error("request_irq() failed: %d", ret); 266 wl1251_error("request_irq() failed: %d", ret);
@@ -267,7 +268,6 @@ static int wl1251_sdio_probe(struct sdio_func *func,
267 } 268 }
268 269
269 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 270 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
270 disable_irq(wl->irq);
271 271
272 wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; 272 wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
273 wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; 273 wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 6248c354fc5c..87f6305bda2c 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -281,6 +281,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
281 281
282 wl->use_eeprom = pdata->use_eeprom; 282 wl->use_eeprom = pdata->use_eeprom;
283 283
284 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
284 ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); 285 ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
285 if (ret < 0) { 286 if (ret < 0) {
286 wl1251_error("request_irq() failed: %d", ret); 287 wl1251_error("request_irq() failed: %d", ret);
@@ -289,8 +290,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
289 290
290 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 291 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
291 292
292 disable_irq(wl->irq);
293
294 ret = wl1251_init_ieee80211(wl); 293 ret = wl1251_init_ieee80211(wl);
295 if (ret) 294 if (ret)
296 goto out_irq; 295 goto out_irq;