Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 194661
b: refs/heads/master
c: c11d8f8
h: refs/heads/master
i:
  194659: f7397a2
v: v3
  • Loading branch information
Sujith authored and John W. Linville committed Apr 26, 2010
1 parent 0e316c6 commit 3a682a5
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 59 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d4cde88c1c025ffa18150ec29e80e456f2a5c65a
refs/heads/master: c11d8f89d3b785f3ef987c2d9ee1bfea6f8b3d0f
106 changes: 49 additions & 57 deletions trunk/drivers/net/wireless/ath/ath9k/hif_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,72 +93,72 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
return ret;
}

static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
struct sk_buff_head *list)
{
struct sk_buff *skb;

while ((skb = __skb_dequeue(list)) != NULL) {
dev_kfree_skb_any(skb);
TX_STAT_INC(skb_dropped);
}
}

static void hif_usb_tx_cb(struct urb *urb)
{
struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
struct hif_device_usb *hif_dev = tx_buf->hif_dev;
struct sk_buff *skb;
bool drop, flush;

if (!hif_dev)
if (!hif_dev || !tx_buf)
return;

switch (urb->status) {
case 0:
break;
case -ENOENT:
case -ECONNRESET:
break;
case -ENODEV:
case -ESHUTDOWN:
/*
* The URB has been killed, free the SKBs
* and return.
*/
ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
return;
default:
break;
}

if (tx_buf) {
spin_lock(&hif_dev->tx.tx_lock);
drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP);
flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH);
spin_unlock(&hif_dev->tx.tx_lock);

while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
if (!drop && !flush) {
ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
skb, 1);
TX_STAT_INC(skb_completed);
} else {
dev_kfree_skb_any(skb);
TX_STAT_INC(skb_dropped);
}
}

if (flush)
return;

tx_buf->len = tx_buf->offset = 0;
__skb_queue_head_init(&tx_buf->skb_queue);

spin_lock(&hif_dev->tx.tx_lock);
list_del(&tx_buf->list);
list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
hif_dev->tx.tx_buf_cnt++;
if (!drop)
__hif_usb_tx(hif_dev); /* Check for pending SKBs */
TX_STAT_INC(buf_completed);
/* Check if TX has been stopped */
spin_lock(&hif_dev->tx.tx_lock);
if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
spin_unlock(&hif_dev->tx.tx_lock);
}
}

static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
struct sk_buff_head *list)
{
struct sk_buff *skb;

while ((skb = __skb_dequeue(list)) != NULL) {
dev_kfree_skb_any(skb);
TX_STAT_INC(skb_dropped);
}
ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
goto add_free;
}
spin_unlock(&hif_dev->tx.tx_lock);

/* Complete the queued SKBs. */
while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
skb, 1);
TX_STAT_INC(skb_completed);
}

add_free:
/* Re-initialize the SKB queue */
tx_buf->len = tx_buf->offset = 0;
__skb_queue_head_init(&tx_buf->skb_queue);

/* Add this TX buffer to the free list */
spin_lock(&hif_dev->tx.tx_lock);
list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
hif_dev->tx.tx_buf_cnt++;
if (!(hif_dev->tx.flags & HIF_USB_TX_STOP))
__hif_usb_tx(hif_dev); /* Check for pending SKBs */
TX_STAT_INC(buf_completed);
spin_unlock(&hif_dev->tx.tx_lock);
}

/* TX lock has to be taken */
Expand All @@ -178,8 +178,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
return 0;

tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
list_del(&tx_buf->list);
list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
list_move_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
hif_dev->tx.tx_buf_cnt--;

tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);
Expand Down Expand Up @@ -548,20 +547,17 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)

static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
{
unsigned long flags;
struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;

list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) {
list_for_each_entry_safe(tx_buf, tx_buf_tmp,
&hif_dev->tx.tx_buf, list) {
usb_kill_urb(tx_buf->urb);
list_del(&tx_buf->list);
usb_free_urb(tx_buf->urb);
kfree(tx_buf->buf);
kfree(tx_buf);
}

spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

list_for_each_entry_safe(tx_buf, tx_buf_tmp,
&hif_dev->tx.tx_pending, list) {
usb_kill_urb(tx_buf->urb);
Expand All @@ -570,10 +566,6 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
kfree(tx_buf->buf);
kfree(tx_buf);
}

spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH;
spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
}

static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/net/wireless/ath/ath9k/hif_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ struct tx_buf {
};

#define HIF_USB_TX_STOP BIT(0)
#define HIF_USB_TX_FLUSH BIT(1)

struct hif_usb_tx {
u8 flags;
Expand Down

0 comments on commit 3a682a5

Please sign in to comment.