aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2010-10-11 09:37:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-11 15:04:25 -0400
commitcdfd2c5cffac2e744c855f9998212867387bb2de (patch)
tree14d1d3a4b6c78756a526cc2f11e1af5e31d7aad1
parentfa69560f317d961c56e29dea788b346d2b34fb87 (diff)
rt2x00: Move watchdog work to kernel work_queue
The watchdog function must run on a work_queue which is independent of any other work inside rt2x00. The main reasons, being that a broken work on the mac80211 work_queue can otherwise prevent the watchdog to run (while in fact the watchdog could fix the issue). And on the other hand because the watchdog relies on the completion of the completion handlers for RX/TX which for the USB case, occur on the mac80211 workqueue. This fixes some "Queue %d failed to flush" errors, which were caused by the watchdog function waiting on the completion handler which was scheduled to run right after the watchdog. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c6
2 files changed, 7 insertions, 4 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2322c84adc1c..94fe589acfaa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -338,6 +338,11 @@ struct link {
338 338
339 /* 339 /*
340 * Work structure for scheduling periodic watchdog monitoring. 340 * Work structure for scheduling periodic watchdog monitoring.
341 * This work must be scheduled on the kernel workqueue, while
342 * all other work structures must be queued on the mac80211
343 * workqueue. This guarantees that the watchdog can schedule
344 * other work structures and wait for their completion in order
345 * to bring the device/driver back into the desired state.
341 */ 346 */
342 struct delayed_work watchdog_work; 347 struct delayed_work watchdog_work;
343}; 348};
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 46836f801b35..b971d8798ebf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -417,8 +417,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
417 !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) 417 !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
418 return; 418 return;
419 419
420 ieee80211_queue_delayed_work(rt2x00dev->hw, 420 schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
421 &link->watchdog_work, WATCHDOG_INTERVAL);
422} 421}
423 422
424void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) 423void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -442,8 +441,7 @@ static void rt2x00link_watchdog(struct work_struct *work)
442 rt2x00dev->ops->lib->watchdog(rt2x00dev); 441 rt2x00dev->ops->lib->watchdog(rt2x00dev);
443 442
444 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) 443 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
445 ieee80211_queue_delayed_work(rt2x00dev->hw, 444 schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL);
446 &link->watchdog_work, WATCHDOG_INTERVAL);
447} 445}
448 446
449void rt2x00link_register(struct rt2x00_dev *rt2x00dev) 447void rt2x00link_register(struct rt2x00_dev *rt2x00dev)