ath9k_htc: Handle device unplug properly
authorSujith <Sujith.Manoharan@atheros.com>
Fri, 23 Apr 2010 04:58:10 +0000 (10:28 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 26 Apr 2010 18:21:16 +0000 (14:21 -0400)
When the USB device has been unplugged, there is
no point in trying to send commands to the target.
Fix this by denying all WMI commands in such a case.

Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/wmi.c

index c765ff4a505c54ea265b423c83d3dc1b752ddb3d..b771e20075a55e4aa36cab69a1a6547d0a845539 100644 (file)
@@ -329,6 +329,7 @@ struct htc_beacon_config {
 #define OP_ASSOCIATED     BIT(8)
 #define OP_ENABLE_BEACON  BIT(9)
 #define OP_LED_DEINIT     BIT(10)
+#define OP_UNPLUGGED      BIT(11)
 
 struct ath9k_htc_priv {
        struct device *dev;
index a86189629d92bd41f310803270ff4ecb2f6066e9..701f2ef5a440724f21a43b85e49600b302941030 100644 (file)
@@ -744,6 +744,9 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
        if (ret)
                goto err_init;
 
+       /* The device may have been unplugged earlier. */
+       priv->op_flags &= ~OP_UNPLUGGED;
+
        ret = ath9k_init_device(priv, devid);
        if (ret)
                goto err_init;
@@ -760,6 +763,11 @@ err_free:
 void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
 {
        if (htc_handle->drv_priv) {
+
+               /* Check if the device has been yanked out. */
+               if (hotunplug)
+                       htc_handle->drv_priv->op_flags |= OP_UNPLUGGED;
+
                ath9k_deinit_device(htc_handle->drv_priv);
                ath9k_deinit_wmi(htc_handle->drv_priv);
                ieee80211_free_hw(htc_handle->drv_priv->hw);
index dc6c6fc2e095bcdf8d01a3eaaf55b5957ecb5e97..c688545326592af48b85274007cfa82814ae9503 100644 (file)
@@ -276,6 +276,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
        int time_left, ret = 0;
        unsigned long flags;
 
+       if (wmi->drv_priv->op_flags & OP_UNPLUGGED)
+               return 0;
+
        if (!wmi)
                return -EINVAL;