diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-07-11 06:25:46 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-12 16:05:34 -0400 |
commit | c965c74bbc650e5466d2f3e32bd28112ebcdd00c (patch) | |
tree | b24e5a745a40b5f7d83b8fb7b04a5abd1c32445f /drivers/net/wireless/rt2x00/rt2x00link.c | |
parent | 223dcc26591aa8e4a6bf623164b775b5bd89c9e1 (diff) |
rt2x00: Implement watchdog monitoring
Implement watchdog monitoring for USB devices (PCI support can
be added later). This will determine if URBs being uploaded to
the hardware are actually returning. Both rt2500usb and rt2800usb
have shown that URBs being uploaded can remain hanging without
being released by the hardware.
By using this watchdog, a queue can be reset when this occurs.
For rt2800usb it has been tested that the connection is preserved
even though this interruption.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00link.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00link.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 9acfc5c70389..666cef3f8472 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c | |||
@@ -407,7 +407,45 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
407 | &link->work, LINK_TUNE_INTERVAL); | 407 | &link->work, LINK_TUNE_INTERVAL); |
408 | } | 408 | } |
409 | 409 | ||
410 | void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev) | ||
411 | { | ||
412 | struct link *link = &rt2x00dev->link; | ||
413 | |||
414 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || | ||
415 | !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) | ||
416 | return; | ||
417 | |||
418 | ieee80211_queue_delayed_work(rt2x00dev->hw, | ||
419 | &link->watchdog_work, WATCHDOG_INTERVAL); | ||
420 | } | ||
421 | |||
422 | void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) | ||
423 | { | ||
424 | cancel_delayed_work_sync(&rt2x00dev->link.watchdog_work); | ||
425 | } | ||
426 | |||
427 | static void rt2x00link_watchdog(struct work_struct *work) | ||
428 | { | ||
429 | struct rt2x00_dev *rt2x00dev = | ||
430 | container_of(work, struct rt2x00_dev, link.watchdog_work.work); | ||
431 | struct link *link = &rt2x00dev->link; | ||
432 | |||
433 | /* | ||
434 | * When the radio is shutting down we should | ||
435 | * immediately cease the watchdog monitoring. | ||
436 | */ | ||
437 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
438 | return; | ||
439 | |||
440 | rt2x00dev->ops->lib->watchdog(rt2x00dev); | ||
441 | |||
442 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
443 | ieee80211_queue_delayed_work(rt2x00dev->hw, | ||
444 | &link->watchdog_work, WATCHDOG_INTERVAL); | ||
445 | } | ||
446 | |||
410 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) | 447 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) |
411 | { | 448 | { |
449 | INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog); | ||
412 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); | 450 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); |
413 | } | 451 | } |