From patchwork Sun Dec 26 17:22:29 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Lamparter X-Patchwork-Id: 433221 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBRKCV56025997 for ; Mon, 27 Dec 2010 20:14:05 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752615Ab0LZT5R (ORCPT ); Sun, 26 Dec 2010 14:57:17 -0500 Received: from mail-bw0-f46.google.com ([209.85.214.46]:45094 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752633Ab0LZT5H (ORCPT ); Sun, 26 Dec 2010 14:57:07 -0500 Received: by bwz15 with SMTP id 15so9183399bwz.19 for ; Sun, 26 Dec 2010 11:57:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:received:received:received:message-id:subject :to:cc:from:date:x-kmail-signatureactionenabled :x-kmail-encryptactionenabled:x-kmail-cryptomessageformat :mime-version:x-length:x-uid:content-type:content-transfer-encoding; bh=gr6zFX7yKFpAfwsATb7MlxSxN6P5/AU1WIHSkfQMRw4=; b=RU2nUOCP4OkRqVm1osFk6B1fd/cAv5sY204JQBJuwQgBwP44uB/yRA3pXSFTs6W01C fCzhQxUOO9+yekkLp5nEQj+Df74pLjMvdxoZMJZJ0Kbmzh+pTFQlxAbOvK7dE4BPNaKJ qBo5jBHJiA7gYgir/543J0Je9LbMi/Vjz4K9s= DomainKey-Signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=message-id:subject:to:cc:from:date:x-kmail-signatureactionenabled :x-kmail-encryptactionenabled:x-kmail-cryptomessageformat :mime-version:x-length:x-uid:content-type:content-transfer-encoding; b=H4JwMLCB/jPditdpkR+jBHKSlpMVq8YvO9brWh/wkN3HRFjVNNeXuiBlPrfDi5vKqQ oGmJxhUH4TfW3WiZJdkAfgc+d4Ro40nBvPx4qgdzPVV73NBAPlzEWaIZUmxZqOE4P2k+ 9GsdcjOOZDjXgE/ZWL0NZuIRCQr9ifZBj21jY= Received: by 10.204.70.130 with SMTP id d2mr9798619bkj.166.1293393425087; Sun, 26 Dec 2010 11:57:05 -0800 (PST) Received: from debian64.daheim (p549CCE78.dip.t-dialin.net [84.156.206.120]) by mx.google.com with ESMTPS id x38sm5962728bkj.13.2010.12.26.11.57.02 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 26 Dec 2010 11:57:03 -0800 (PST) Received: from debian64.daheim ([192.168.0.4] helo=debian64.localnet ident=chuck) by debian64.daheim with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1PWwiD-0003TF-Lf; Sun, 26 Dec 2010 20:57:01 +0100 Message-Id: Subject: [PATCH 3/3] carl9170: fix usb pm suspend->resume woes To: linux-wireless@vger.kernel.org Cc: linville@tuxdriver.com, angus_rt@hotmail.com From: Christian Lamparter Date: Sun, 26 Dec 2010 18:22:29 +0100 X-KMail-SignatureActionEnabled: false X-KMail-EncryptActionEnabled: false X-KMail-CryptoMessageFormat: 15 MIME-Version: 1.0 X-Length: 4956 X-UID: 82 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Mon, 27 Dec 2010 20:14:05 +0000 (UTC) diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 2d947a3..537732e 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -834,7 +834,7 @@ static int carl9170_usb_load_firmware(struct ar9170 *ar) if (err) goto err_out; - /* firmware restarts cmd counter */ + /* now, start the command response counter */ ar->cmd_seq = -1; return 0; @@ -851,7 +851,12 @@ int carl9170_usb_restart(struct ar9170 *ar) if (ar->intf->condition != USB_INTERFACE_BOUND) return 0; - /* Disable command response sequence counter. */ + /* + * Disable the command response sequence counter check. + * We already know that the device/firmware is in a bad state. + * So, no extra points are awarded to anyone who reminds the + * driver about that. + */ ar->cmd_seq = -2; err = carl9170_reboot(ar); @@ -903,6 +908,15 @@ static int carl9170_usb_init_device(struct ar9170 *ar) { int err; + /* + * The carl9170 firmware let's the driver know when it's + * ready for action. But we have to be prepared to gracefully + * handle all spurious [flushed] messages after each (re-)boot. + * Thus the command response counter remains disabled until it + * can be safely synchronized. + */ + ar->cmd_seq = -2; + err = carl9170_usb_send_rx_irq_urb(ar); if (err) goto err_out; @@ -911,14 +925,21 @@ static int carl9170_usb_init_device(struct ar9170 *ar) if (err) goto err_unrx; + err = carl9170_usb_open(ar); + if (err) + goto err_unrx; + mutex_lock(&ar->mutex); err = carl9170_usb_load_firmware(ar); mutex_unlock(&ar->mutex); if (err) - goto err_unrx; + goto err_stop; return 0; +err_stop: + carl9170_usb_stop(ar); + err_unrx: carl9170_usb_cancel_urbs(ar); @@ -964,10 +985,6 @@ static void carl9170_usb_firmware_finish(struct ar9170 *ar) if (err) goto err_freefw; - err = carl9170_usb_open(ar); - if (err) - goto err_unrx; - err = carl9170_register(ar); carl9170_usb_stop(ar); @@ -1043,7 +1060,6 @@ static int carl9170_usb_probe(struct usb_interface *intf, atomic_set(&ar->rx_work_urbs, 0); atomic_set(&ar->rx_anch_urbs, 0); atomic_set(&ar->rx_pool_urbs, 0); - ar->cmd_seq = -2; usb_get_dev(ar->udev); @@ -1090,10 +1106,6 @@ static int carl9170_usb_suspend(struct usb_interface *intf, carl9170_usb_cancel_urbs(ar); - /* - * firmware automatically reboots for usb suspend. - */ - return 0; } @@ -1106,12 +1118,20 @@ static int carl9170_usb_resume(struct usb_interface *intf) return -ENODEV; usb_unpoison_anchored_urbs(&ar->rx_anch); + carl9170_set_state(ar, CARL9170_STOPPED); - err = carl9170_usb_init_device(ar); - if (err) - goto err_unrx; + /* + * The USB documentation demands that [for suspend] all traffic + * to and from the device has to stop. This would be fine, but + * there's a catch: the device[usb phy] does not come back. + * + * Upon resume the firmware will "kill" itself and the + * boot-code sorts out the magic voodoo. + * Not very nice, but there's not much what could go wrong. + */ + msleep(1100); - err = carl9170_usb_open(ar); + err = carl9170_usb_init_device(ar); if (err) goto err_unrx; @@ -1133,6 +1153,7 @@ static struct usb_driver carl9170_driver = { #ifdef CONFIG_PM .suspend = carl9170_usb_suspend, .resume = carl9170_usb_resume, + .reset_resume = carl9170_usb_resume, #endif /* CONFIG_PM */ };