pci: Add SR-IOV convenience functions and macros
[safe/jmp/linux-2.6] / drivers / uwb / reset.c
index 8de856f..7f0512e 100644 (file)
  */
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 
 #include "uwb-internal.h"
-#define D_LOCAL 0
-#include <linux/uwb/debug.h>
 
 /**
  * Command result codes (WUSB1.0[T8-69])
@@ -323,17 +322,18 @@ int uwbd_msg_handle_reset(struct uwb_event *evt)
        struct uwb_rc *rc = evt->rc;
        int ret;
 
-       /* Need to prevent the RC hardware module going away while in
-          the rc->reset() call. */
-       if (!try_module_get(rc->owner))
-               return 0;
-
        dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
        ret = rc->reset(rc);
-       if (ret)
+       if (ret < 0) {
                dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
-
-       module_put(rc->owner);
+               goto error;
+       }
+       return 0;
+error:
+       /* Nothing can be done except try the reset again. Wait a bit
+          to avoid reset loops during probe() or remove(). */
+       msleep(1000);
+       uwb_rc_reset_all(rc);
        return ret;
 }
 
@@ -360,3 +360,31 @@ void uwb_rc_reset_all(struct uwb_rc *rc)
        uwbd_event_queue(evt);
 }
 EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
+
+void uwb_rc_pre_reset(struct uwb_rc *rc)
+{
+       rc->stop(rc);
+       uwbd_flush(rc);
+
+       uwb_radio_reset_state(rc);
+       uwb_rsv_remove_all(rc);
+}
+EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
+
+int uwb_rc_post_reset(struct uwb_rc *rc)
+{
+       int ret;
+
+       ret = rc->start(rc);
+       if (ret)
+               goto out;
+       ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
+       if (ret)
+               goto out;
+       ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
+       if (ret)
+               goto out;
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(uwb_rc_post_reset);