aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGrazvydas Ignotas <notasas@gmail.com>2012-05-17 20:04:08 -0400
committerLuis Henriques <luis.henriques@canonical.com>2012-07-03 11:29:05 -0400
commit567b958e65b38a19e20133d06fa867145edb838f (patch)
tree1ed3837a0775f4af9b59984afa3589ef7307f6f8 /drivers/net
parent47a670de321e95ecb685567415316d7dde6984fa (diff)
wl1251: fix oops on early interrupt
BugLink: http://bugs.launchpad.net/bugs/1013748 commit f380f2c4a12e913356bd49f8790ec1063c4fe9f8 upstream. 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(). Signed-off-by: Grazvydas Ignotas <notasas@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/wl1251/sdio.c2
-rw-r--r--drivers/net/wireless/wl1251/spi.c3
2 files changed, 2 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c
index 85a710182a8..4cf5c2e201d 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
@@ -259,6 +259,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
259 } 259 }
260 260
261 if (wl->irq) { 261 if (wl->irq) {
262 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
262 ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); 263 ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
263 if (ret < 0) { 264 if (ret < 0) {
264 wl1251_error("request_irq() failed: %d", ret); 265 wl1251_error("request_irq() failed: %d", ret);
@@ -266,7 +267,6 @@ static int wl1251_sdio_probe(struct sdio_func *func,
266 } 267 }
267 268
268 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 269 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
269 disable_irq(wl->irq);
270 270
271 wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; 271 wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
272 wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; 272 wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c
index af6448c4d3e..49f3651423d 100644
--- a/drivers/net/wireless/wl1251/spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -280,6 +280,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
280 280
281 wl->use_eeprom = pdata->use_eeprom; 281 wl->use_eeprom = pdata->use_eeprom;
282 282
283 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
283 ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); 284 ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
284 if (ret < 0) { 285 if (ret < 0) {
285 wl1251_error("request_irq() failed: %d", ret); 286 wl1251_error("request_irq() failed: %d", ret);
@@ -288,8 +289,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
288 289
289 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 290 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
290 291
291 disable_irq(wl->irq);
292
293 ret = wl1251_init_ieee80211(wl); 292 ret = wl1251_init_ieee80211(wl);
294 if (ret) 293 if (ret)
295 goto out_irq; 294 goto out_irq;