summaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax/i2400m/usb.c
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2009-09-17 02:10:55 +0200
committerInaky Perez-Gonzalez <inaky@linux.intel.com>2009-10-19 08:56:07 +0200
commitc2315b4ea9ac9c3f8caf03c3511d86fabe4a5fcd (patch)
tree17e2d15abfd26fa83f8a9654bf581f6d40fc8c33 /drivers/net/wimax/i2400m/usb.c
parentwimax/i2400m: cleanup initialization/destruction flow (diff)
downloadlinux-c2315b4ea9ac9c3f8caf03c3511d86fabe4a5fcd.tar.xz
linux-c2315b4ea9ac9c3f8caf03c3511d86fabe4a5fcd.zip
wimax/i2400m: clarify and fix i2400m->{ready,updown}
The i2400m driver uses two different bits to distinguish how much the driver is up. i2400m->ready is used to denote that the infrastructure to communicate with the device is up and running. i2400m->updown is used to indicate if 'ready' and the device is up and running, ready to take control and data traffic. However, all this was pretty dirty and not clear, with many open spots where race conditions were present. This commit cleans up the situation by: - documenting the usage of both bits - setting them only in specific, well controlled places (i2400m_dev_start, i2400m_dev_stop) - ensuring the i2400m workqueue can't get in the middle of the setting by flushing it when i2400m->ready is set to zero. This allows the report hook not having to check again for the bit to be set [rx.c:i2400m_report_hook_work()]. - using i2400m->updown to determine if the device is up and running instead of the wimax state in i2400m_dev_reset_handle(). - not loosing missed messages sent by the hardware before i2400m->ready is set. In rx.c, whatever the device sends can be sent to user space over the message pipes as soon as the wimax device is registered, so don't wait for i2400m->ready to be set. Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'drivers/net/wimax/i2400m/usb.c')
-rw-r--r--drivers/net/wimax/i2400m/usb.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 07653ded6c59..f4dfb60bb628 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -516,7 +516,10 @@ void i2400mu_disconnect(struct usb_interface *iface)
* So at the end, the three cases require common handling.
*
* If at the time of this call the device's firmware is not loaded,
- * nothing has to be done.
+ * nothing has to be done. Note we can be "loose" about not reading
+ * i2400m->updown under i2400m->init_mutex. If it happens to change
+ * inmediately, other parts of the call flow will fail and effectively
+ * catch it.
*
* If the firmware is loaded, we need to:
*
@@ -555,6 +558,7 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg)
#endif
d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event);
+ rmb(); /* see i2400m->updown's documentation */
if (i2400m->updown == 0)
goto no_firmware;
if (i2400m->state == I2400M_SS_DATA_PATH_CONNECTED && is_autosuspend) {
@@ -608,6 +612,7 @@ int i2400mu_resume(struct usb_interface *iface)
struct i2400m *i2400m = &i2400mu->i2400m;
d_fnstart(3, dev, "(iface %p)\n", iface);
+ rmb(); /* see i2400m->updown's documentation */
if (i2400m->updown == 0) {
d_printf(1, dev, "fw was down, no resume neeed\n");
goto out;