From patchwork Mon Mar 7 02:14:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sujith Manoharan X-Patchwork-Id: 614291 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 p272FJWs018739 for ; Mon, 7 Mar 2011 02:15:19 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755227Ab1CGCPK (ORCPT ); Sun, 6 Mar 2011 21:15:10 -0500 Received: from mail-gy0-f174.google.com ([209.85.160.174]:52332 "EHLO mail-gy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755223Ab1CGCPE (ORCPT ); Sun, 6 Mar 2011 21:15:04 -0500 Received: by gyh20 with SMTP id 20so1494682gyh.19 for ; Sun, 06 Mar 2011 18:15:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:mime-version:content-type :content-transfer-encoding:message-id:date:to:x-mailer:cc:subject; bh=51Xgto4aaN12qJLSGpbGEL+flh2dXoKghQG3iv1jixI=; b=TJu9bLV7ZtO3VoTZlxRzQqMGaErDXzO9cLikPf59hasMORV+4rN0mt8pHBzGOMU0xF osH6Sm1QvaL2dkyaT7RF3S40eOSQ1eqeDYVYULSOP3kO15/ED/+0+qMZnZoXLTnsZbJs hP0GTQJsp7kEJWu7lrjHt8s9CwXC7EsSEWomQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:mime-version:content-type:content-transfer-encoding:message-id :date:to:x-mailer:cc:subject; b=SDKaR1hkZWZwgAXhFjTS6+SgSCM86TNIT2PPVighSxA5Q+yZTWhpTt6Vg76FKwLIbP 7cIRPy3cs7vZB0G3v0HEY5FNcyGq8G0cWVAJu+lpk2g7iNYp9B+7FisFT6HAEvqCQtiZ RAHZGjs1qrY1yWsvBI7RJQPucLfKuMpUBuVjs= Received: by 10.151.134.7 with SMTP id l7mr3806381ybn.126.1299464104141; Sun, 06 Mar 2011 18:15:04 -0800 (PST) Received: from bodhi ([117.197.194.30]) by mx.google.com with ESMTPS id u49sm1394567yhn.37.2011.03.06.18.15.01 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 06 Mar 2011 18:15:03 -0800 (PST) From: Sujith MIME-Version: 1.0 Message-ID: <19828.16287.414555.471688@gargle.gargle.HOWL> Date: Mon, 7 Mar 2011 07:44:55 +0530 To: linux-wireless@vger.kernel.org X-Mailer: VM 8.1.1 under 23.2.1 (x86_64-unknown-linux-gnu) CC: ath9k-devel@venema.h4ckr.net Subject: [RFC 21/34] ath9k_htc: Increase URB count for REG_IN pipe 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.6 (demeter1.kernel.org [140.211.167.41]); Mon, 07 Mar 2011 02:15:32 +0000 (UTC) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index d56a10c..a8134f8 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -568,6 +568,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) case -ESHUTDOWN: goto free; default: + skb_reset_tail_pointer(skb); + skb_trim(skb, 0); + goto resubmit; } @@ -592,23 +595,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, nskb); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) { - kfree_skb(nskb); - urb->context = NULL; - } - - return; } resubmit: - skb_reset_tail_pointer(skb); - skb_trim(skb, 0); - + usb_anchor_urb(urb, &hif_dev->reg_in_submitted); ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) + if (ret) { + usb_unanchor_urb(urb); goto free; + } return; free: @@ -749,43 +744,67 @@ err_urb: return ret; } -static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) +static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - if (hif_dev->reg_in_urb) { - usb_kill_urb(hif_dev->reg_in_urb); - if (hif_dev->reg_in_urb->context) - kfree_skb((void *)hif_dev->reg_in_urb->context); - usb_free_urb(hif_dev->reg_in_urb); - hif_dev->reg_in_urb = NULL; - } + usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); } -static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) +static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - struct sk_buff *skb; + struct urb *urb = NULL; + struct sk_buff *skb = NULL; + int i, ret; - hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); - if (hif_dev->reg_in_urb == NULL) - return -ENOMEM; + init_usb_anchor(&hif_dev->reg_in_submitted); - skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); - if (!skb) - goto err; + for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { - usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, - usb_rcvbulkpipe(hif_dev->udev, - USB_REG_IN_PIPE), - skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb); + /* Allocate URB */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (urb == NULL) { + ret = -ENOMEM; + goto err_urb; + } - if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) - goto err; + /* Allocate buffer */ + skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_skb; + } + + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_rcvbulkpipe(hif_dev->udev, + USB_REG_IN_PIPE), + skb->data, MAX_REG_IN_BUF_SIZE, + ath9k_hif_usb_reg_in_cb, skb); + + /* Anchor URB */ + usb_anchor_urb(urb, &hif_dev->reg_in_submitted); + + /* Submit URB */ + ret = usb_submit_urb(urb, GFP_KERNEL); + if (ret) { + usb_unanchor_urb(urb); + goto err_submit; + } + + /* + * Drop reference count. + * This ensures that the URB is freed when killing them. + */ + usb_free_urb(urb); + } return 0; -err: - ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); - return -ENOMEM; +err_submit: + kfree_skb(skb); +err_skb: + usb_free_urb(urb); +err_urb: + ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); + return ret; } static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) @@ -802,7 +821,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) goto err_rx; /* Register Read */ - if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) + if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0) goto err_reg; return 0; @@ -817,7 +836,7 @@ err: static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->regout_submitted); - ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); + ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); ath9k_hif_usb_dealloc_tx_urbs(hif_dev); ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index f82b32b..8b98d64 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -40,7 +40,7 @@ #define MAX_PKT_NUM_IN_TRANSFER 10 #define MAX_REG_OUT_URB_NUM 1 -#define MAX_REG_OUT_BUF_NUM 8 +#define MAX_REG_IN_URB_NUM 64 #define MAX_REG_IN_BUF_SIZE 64 @@ -90,9 +90,9 @@ struct hif_device_usb { const struct firmware *firmware; struct htc_target *htc_handle; struct hif_usb_tx tx; - struct urb *reg_in_urb; struct usb_anchor regout_submitted; struct usb_anchor rx_submitted; + struct usb_anchor reg_in_submitted; struct sk_buff *remain_skb; const char *fw_name; int rx_remain_len;