aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2010-04-06 05:58:17 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-08 15:24:10 -0400
commit6f0f2669f508fb239a0f589a8b453dbe22112bf9 (patch)
tree3b857e1bfe5a74bd7f7a77d10ea794d2140f6b52
parentc503269a0f77e9b2d6de9e8a5f66ace53dde6e04 (diff)
ath9k_htc: Use anchors for REGOUT pipe
hif_usb_regout_cb() frees the given URB, which is borked by design. Use an anchor to simplify URB management. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h1
2 files changed, 15 insertions, 16 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 69bef1de71ae..e2117e7222e7 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -32,27 +32,15 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev);
32static void hif_usb_regout_cb(struct urb *urb) 32static void hif_usb_regout_cb(struct urb *urb)
33{ 33{
34 struct cmd_buf *cmd = (struct cmd_buf *)urb->context; 34 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
35 struct hif_device_usb *hif_dev = cmd->hif_dev;
36
37 if (!hif_dev) {
38 usb_free_urb(urb);
39 if (cmd) {
40 if (cmd->skb)
41 dev_kfree_skb_any(cmd->skb);
42 kfree(cmd);
43 }
44 return;
45 }
46 35
47 switch (urb->status) { 36 switch (urb->status) {
48 case 0: 37 case 0:
49 break; 38 break;
50 case -ENOENT: 39 case -ENOENT:
51 case -ECONNRESET: 40 case -ECONNRESET:
52 break;
53 case -ENODEV: 41 case -ENODEV:
54 case -ESHUTDOWN: 42 case -ESHUTDOWN:
55 return; 43 goto free;
56 default: 44 default:
57 break; 45 break;
58 } 46 }
@@ -61,8 +49,12 @@ static void hif_usb_regout_cb(struct urb *urb)
61 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, 49 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
62 cmd->skb, 1); 50 cmd->skb, 1);
63 kfree(cmd); 51 kfree(cmd);
64 usb_free_urb(urb);
65 } 52 }
53
54 return;
55free:
56 dev_kfree_skb_any(cmd->skb);
57 kfree(cmd);
66} 58}
67 59
68static int hif_usb_send_regout(struct hif_device_usb *hif_dev, 60static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
@@ -90,11 +82,13 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
90 skb->data, skb->len, 82 skb->data, skb->len,
91 hif_usb_regout_cb, cmd, 1); 83 hif_usb_regout_cb, cmd, 1);
92 84
85 usb_anchor_urb(urb, &hif_dev->regout_submitted);
93 ret = usb_submit_urb(urb, GFP_KERNEL); 86 ret = usb_submit_urb(urb, GFP_KERNEL);
94 if (ret) { 87 if (ret) {
95 usb_free_urb(urb); 88 usb_unanchor_urb(urb);
96 kfree(cmd); 89 kfree(cmd);
97 } 90 }
91 usb_free_urb(urb);
98 92
99 return ret; 93 return ret;
100} 94}
@@ -711,6 +705,9 @@ err:
711 705
712static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) 706static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
713{ 707{
708 /* Register Write */
709 init_usb_anchor(&hif_dev->regout_submitted);
710
714 /* TX */ 711 /* TX */
715 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0) 712 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
716 goto err; 713 goto err;
@@ -719,7 +716,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
719 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0) 716 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
720 goto err; 717 goto err;
721 718
722 /* Register Read/Write */ 719 /* Register Read */
723 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) 720 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
724 goto err; 721 goto err;
725 722
@@ -816,6 +813,7 @@ err_fw_req:
816 813
817static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) 814static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
818{ 815{
816 usb_kill_anchored_urbs(&hif_dev->regout_submitted);
819 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); 817 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
820 ath9k_hif_usb_dealloc_tx_urbs(hif_dev); 818 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
821 ath9k_hif_usb_dealloc_rx_urbs(hif_dev); 819 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 179cea46a8e7..7d49a8af420e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -88,6 +88,7 @@ struct hif_device_usb {
88 struct htc_target *htc_handle; 88 struct htc_target *htc_handle;
89 struct hif_usb_tx tx; 89 struct hif_usb_tx tx;
90 struct urb *reg_in_urb; 90 struct urb *reg_in_urb;
91 struct usb_anchor regout_submitted;
91 struct usb_anchor rx_submitted; 92 struct usb_anchor rx_submitted;
92 struct sk_buff *remain_skb; 93 struct sk_buff *remain_skb;
93 int rx_remain_len; 94 int rx_remain_len;