OSDN Git Service

wil6210: prevent access to 11AD device if resume fails
authorMaya Erez <merez@codeaurora.org>
Wed, 5 Apr 2017 08:26:45 +0000 (11:26 +0300)
committerMaya Erez <merez@codeaurora.org>
Wed, 5 Apr 2017 08:26:45 +0000 (11:26 +0300)
In case wil6210 resume fails, wil6210 suspend function will try
to access the suspended device in the next kernel suspend.
To prevent that, add wil_status_suspended flag to indicate if the
device is already suspended and clear it only if the resume succeeds.

Change-Id: I548e5b516cfa62389ce5f6cafcf1568206f7c2a9
Signed-off-by: Maya Erez <merez@codeaurora.org>
drivers/net/wireless/ath/wil6210/pm.c
drivers/net/wireless/ath/wil6210/wil6210.h

index 7260bef..2ae4fe8 100644 (file)
@@ -71,6 +71,11 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
 
        wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
 
+       if (test_bit(wil_status_suspended, wil->status)) {
+               wil_dbg_pm(wil, "trying to suspend while suspended\n");
+               return 0;
+       }
+
        /* if netif up, hardware is alive, shut it down */
        if (ndev->flags & IFF_UP) {
                rc = wil_down(wil);
@@ -86,10 +91,14 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
 
        if (wil->platform_ops.suspend) {
                rc = wil->platform_ops.suspend(wil->platform_handle);
-               if (rc)
+               if (rc) {
                        wil_enable_irq(wil);
+                       goto out;
+               }
        }
 
+       set_bit(wil_status_suspended, wil->status);
+
 out:
        wil_dbg_pm(wil, "suspend: %s => %d\n",
                   is_runtime ? "runtime" : "system", rc);
@@ -117,10 +126,13 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime)
 
        /* if netif up, bring hardware up
         * During open(), IFF_UP set after actual device method
-        * invocation. This prevent recursive call to wil_up()
+        * invocation. This prevent recursive call to wil_up().
+        * wil_status_suspended will be cleared in wil_reset
         */
        if (ndev->flags & IFF_UP)
                rc = wil_up(wil);
+       else
+               clear_bit(wil_status_suspended, wil->status);
 
 out:
        wil_dbg_pm(wil, "resume: %s => %d\n",
index f64323b..45df2d1 100644 (file)
@@ -417,6 +417,7 @@ enum { /* for wil6210_priv.status */
        wil_status_irqen, /* FIXME: interrupts enabled - for debug */
        wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
        wil_status_resetting, /* reset in progress */
+       wil_status_suspended, /* suspend completed, device is suspended */
        wil_status_last /* keep last */
 };