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>
This commit is contained in:
Sujith 2010-04-06 15:28:17 +05:30 committed by John W. Linville
parent c503269a0f
commit 6f0f2669f5
2 changed files with 15 additions and 16 deletions

View File

@ -32,27 +32,15 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev);
static void hif_usb_regout_cb(struct urb *urb) static void hif_usb_regout_cb(struct urb *urb)
{ {
struct cmd_buf *cmd = (struct cmd_buf *)urb->context; 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) { switch (urb->status) {
case 0: case 0:
break; break;
case -ENOENT: case -ENOENT:
case -ECONNRESET: case -ECONNRESET:
break;
case -ENODEV: case -ENODEV:
case -ESHUTDOWN: case -ESHUTDOWN:
return; goto free;
default: default:
break; break;
} }
@ -61,8 +49,12 @@ static void hif_usb_regout_cb(struct urb *urb)
ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
cmd->skb, 1); cmd->skb, 1);
kfree(cmd); 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, 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, skb->data, skb->len,
hif_usb_regout_cb, cmd, 1); hif_usb_regout_cb, cmd, 1);
usb_anchor_urb(urb, &hif_dev->regout_submitted);
ret = usb_submit_urb(urb, GFP_KERNEL); ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) { if (ret) {
usb_free_urb(urb); usb_unanchor_urb(urb);
kfree(cmd); kfree(cmd);
} }
usb_free_urb(urb);
return ret; return ret;
} }
@ -711,6 +705,9 @@ static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
{ {
/* Register Write */
init_usb_anchor(&hif_dev->regout_submitted);
/* TX */ /* TX */
if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0) if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
goto err; 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) if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
goto err; goto err;
/* Register Read/Write */ /* Register Read */
if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
goto err; goto err;
@ -816,6 +813,7 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) 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_urb(hif_dev);
ath9k_hif_usb_dealloc_tx_urbs(hif_dev); ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
ath9k_hif_usb_dealloc_rx_urbs(hif_dev); ath9k_hif_usb_dealloc_rx_urbs(hif_dev);

View File

@ -88,6 +88,7 @@ struct hif_device_usb {
struct htc_target *htc_handle; struct htc_target *htc_handle;
struct hif_usb_tx tx; struct hif_usb_tx tx;
struct urb *reg_in_urb; struct urb *reg_in_urb;
struct usb_anchor regout_submitted;
struct usb_anchor rx_submitted; struct usb_anchor rx_submitted;
struct sk_buff *remain_skb; struct sk_buff *remain_skb;
int rx_remain_len; int rx_remain_len;