summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2010-04-06 15:28:17 +0530
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 69bef1de71a..e2117e7222e 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);
static void hif_usb_regout_cb(struct urb *urb)
{
struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
- struct hif_device_usb *hif_dev = cmd->hif_dev;
-
- if (!hif_dev) {
- usb_free_urb(urb);
- if (cmd) {
- if (cmd->skb)
- dev_kfree_skb_any(cmd->skb);
- kfree(cmd);
- }
- return;
- }
switch (urb->status) {
case 0:
break;
case -ENOENT:
case -ECONNRESET:
- break;
case -ENODEV:
case -ESHUTDOWN:
- return;
+ goto free;
default:
break;
}
@@ -61,8 +49,12 @@ static void hif_usb_regout_cb(struct urb *urb)
ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
cmd->skb, 1);
kfree(cmd);
- usb_free_urb(urb);
}
+
+ return;
+free:
+ dev_kfree_skb_any(cmd->skb);
+ kfree(cmd);
}
static 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,
skb->data, skb->len,
hif_usb_regout_cb, cmd, 1);
+ usb_anchor_urb(urb, &hif_dev->regout_submitted);
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) {
- usb_free_urb(urb);
+ usb_unanchor_urb(urb);
kfree(cmd);
}
+ usb_free_urb(urb);
return ret;
}
@@ -711,6 +705,9 @@ err:
static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
{
+ /* Register Write */
+ init_usb_anchor(&hif_dev->regout_submitted);
+
/* TX */
if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
goto err;
@@ -719,7 +716,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
goto err;
- /* Register Read/Write */
+ /* Register Read */
if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
goto err;
@@ -816,6 +813,7 @@ err_fw_req:
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_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 179cea46a8e..7d49a8af420 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 {
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 sk_buff *remain_skb;
int rx_remain_len;