ath6kl: cold reset target after host warm boot
authorKalle Valo <kvalo@qca.qualcomm.com>
Sat, 9 Mar 2013 10:01:50 +0000 (12:01 +0200)
committerKalle Valo <kvalo@qca.qualcomm.com>
Mon, 18 Mar 2013 11:38:37 +0000 (13:38 +0200)
Julien reported that ar6004 usb device fails to initialise
after host has been rebooted and power is still on for the ar6004 device. He
found out that doing a cold reset fixes the issue.

I wasn't sure what would be the best way to detect if target needs a reset so I
settled on checking a timeout from htc_wait_recv_ctrl_message().

Reported-by: Julien Massot <jmassot@aldebaran-robotics.com>
Tested-by: Julien Massot <jmassot@aldebaran-robotics.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/htc_pipe.c
drivers/net/wireless/ath/ath6kl/init.c

index c02d9d34f74d7e51a174e061b3f0a8c415abd5f3..67aa924ed8b317f9d5240ad1560a820553790c24 100644 (file)
@@ -1168,7 +1168,7 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
 
        if (count <= 0) {
                ath6kl_warn("htc pipe control receive timeout!\n");
-               return -ECOMM;
+               return -ETIMEDOUT;
        }
 
        return 0;
index 8b01ec3d2b8cf6783f272cf587fc03387156d4fc..4ad45bb3cf55f217fa19b6ea150227aa536cca47 100644 (file)
@@ -1658,7 +1658,18 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar)
         * size.
         */
        ret = ath6kl_htc_wait_target(ar->htc_target);
-       if (ret) {
+
+       if (ret == -ETIMEDOUT) {
+               /*
+                * Most likely USB target is in odd state after reboot and
+                * needs a reset. A cold reset makes the whole device
+                * disappear from USB bus and initialisation starts from
+                * beginning.
+                */
+               ath6kl_warn("htc wait target timed out, resetting device\n");
+               ath6kl_init_hw_reset(ar);
+               goto err_power_off;
+       } else if (ret) {
                ath6kl_err("htc wait target failed: %d\n", ret);
                goto err_power_off;
        }