aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/uwb
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2009-08-25 11:41:06 -0400
committerDavid Vrabel <david.vrabel@csr.com>2009-08-26 07:39:29 -0400
commit0396c215f301e92677d1e9a064b405e31501dc1d (patch)
treea54229672abc6f244fcf184701b8a8bf98b70544 /drivers/uwb
parenta9e75a389254801ca160b72c6e221e5bb7e35df9 (diff)
uwb: avoid radio controller reset loops
If a radio controller reset attempt occurs while a probe() or remove() is in progress it fails and is retried endlessly, potentially preventing the probe() or remove() from completing. If a reset fails, sleep for a bit before retrying the reset. This allows the probe()/remove() to complete. Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/uwb')
-rw-r--r--drivers/uwb/hwa-rc.c3
-rw-r--r--drivers/uwb/reset.c21
-rw-r--r--drivers/uwb/umc-bus.c2
-rw-r--r--drivers/uwb/whc-rc.c3
4 files changed, 14 insertions, 15 deletions
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index 9052bcb4f528..e7eeb63fab23 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -887,8 +887,7 @@ static int hwarc_post_reset(struct usb_interface *iface)
887 struct hwarc *hwarc = usb_get_intfdata(iface); 887 struct hwarc *hwarc = usb_get_intfdata(iface);
888 struct uwb_rc *uwb_rc = hwarc->uwb_rc; 888 struct uwb_rc *uwb_rc = hwarc->uwb_rc;
889 889
890 uwb_rc_post_reset(uwb_rc); 890 return uwb_rc_post_reset(uwb_rc);
891 return 0;
892} 891}
893 892
894/** USB device ID's that we handle */ 893/** USB device ID's that we handle */
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c
index 70f8050221ff..7f0512e43d9d 100644
--- a/drivers/uwb/reset.c
+++ b/drivers/uwb/reset.c
@@ -30,6 +30,7 @@
30 */ 30 */
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/err.h> 32#include <linux/err.h>
33#include <linux/delay.h>
33 34
34#include "uwb-internal.h" 35#include "uwb-internal.h"
35 36
@@ -323,13 +324,15 @@ int uwbd_msg_handle_reset(struct uwb_event *evt)
323 324
324 dev_info(&rc->uwb_dev.dev, "resetting radio controller\n"); 325 dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
325 ret = rc->reset(rc); 326 ret = rc->reset(rc);
326 if (ret) { 327 if (ret < 0) {
327 dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret); 328 dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
328 goto error; 329 goto error;
329 } 330 }
330 return 0; 331 return 0;
331error: 332error:
332 /* Nothing can be done except try the reset again. */ 333 /* Nothing can be done except try the reset again. Wait a bit
334 to avoid reset loops during probe() or remove(). */
335 msleep(1000);
333 uwb_rc_reset_all(rc); 336 uwb_rc_reset_all(rc);
334 return ret; 337 return ret;
335} 338}
@@ -368,22 +371,20 @@ void uwb_rc_pre_reset(struct uwb_rc *rc)
368} 371}
369EXPORT_SYMBOL_GPL(uwb_rc_pre_reset); 372EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
370 373
371void uwb_rc_post_reset(struct uwb_rc *rc) 374int uwb_rc_post_reset(struct uwb_rc *rc)
372{ 375{
373 int ret; 376 int ret;
374 377
375 ret = rc->start(rc); 378 ret = rc->start(rc);
376 if (ret) 379 if (ret)
377 goto error; 380 goto out;
378 ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr); 381 ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
379 if (ret) 382 if (ret)
380 goto error; 383 goto out;
381 ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr); 384 ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
382 if (ret) 385 if (ret)
383 goto error; 386 goto out;
384 return; 387out:
385error: 388 return ret;
386 /* Nothing can be done except try the reset again. */
387 uwb_rc_reset_all(rc);
388} 389}
389EXPORT_SYMBOL_GPL(uwb_rc_post_reset); 390EXPORT_SYMBOL_GPL(uwb_rc_post_reset);
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c
index 5ad36164c13b..cdd6c8efc9f8 100644
--- a/drivers/uwb/umc-bus.c
+++ b/drivers/uwb/umc-bus.c
@@ -66,7 +66,7 @@ int umc_controller_reset(struct umc_dev *umc)
66 return -EAGAIN; 66 return -EAGAIN;
67 ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper); 67 ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
68 if (ret >= 0) 68 if (ret >= 0)
69 device_for_each_child(parent, parent, umc_bus_post_reset_helper); 69 ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
70 up(&parent->sem); 70 up(&parent->sem);
71 71
72 return ret; 72 return ret;
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c
index 19a1dd129212..1d9a6f54658e 100644
--- a/drivers/uwb/whc-rc.c
+++ b/drivers/uwb/whc-rc.c
@@ -443,8 +443,7 @@ static int whcrc_post_reset(struct umc_dev *umc)
443 struct whcrc *whcrc = umc_get_drvdata(umc); 443 struct whcrc *whcrc = umc_get_drvdata(umc);
444 struct uwb_rc *uwb_rc = whcrc->uwb_rc; 444 struct uwb_rc *uwb_rc = whcrc->uwb_rc;
445 445
446 uwb_rc_post_reset(uwb_rc); 446 return uwb_rc_post_reset(uwb_rc);
447 return 0;
448} 447}
449 448
450/* PCI device ID's that we handle [so it gets loaded] */ 449/* PCI device ID's that we handle [so it gets loaded] */