Commit a13c8f31 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville

rt2x00: Fix URB error handling

kill_urb guarentees that when the function returns, the URB has
been fully killed. This means we don't need the extra sleeping
after the call to kill_urb.

kill_urb can however also guarentee the submit_urb to fail, as
a result, we must catch the return value from submit_urb an
correctly mark the entry as owned by the driver, and the
status as broken.
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1a397696
...@@ -253,6 +253,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); ...@@ -253,6 +253,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
void rt2x00lib_dmadone(struct queue_entry *entry) void rt2x00lib_dmadone(struct queue_entry *entry)
{ {
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
} }
EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
......
...@@ -253,7 +253,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) ...@@ -253,7 +253,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
entry->skb->data, length, entry->skb->data, length,
rt2x00usb_interrupt_txdone, entry); rt2x00usb_interrupt_txdone, entry);
usb_submit_urb(entry_priv->urb, GFP_ATOMIC); if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry);
}
} }
void rt2x00usb_kick_tx_queue(struct data_queue *queue) void rt2x00usb_kick_tx_queue(struct data_queue *queue)
...@@ -280,14 +283,6 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) ...@@ -280,14 +283,6 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
if ((entry->queue->qid == QID_BEACON) && if ((entry->queue->qid == QID_BEACON) &&
(test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
usb_kill_urb(bcn_priv->guardian_urb); usb_kill_urb(bcn_priv->guardian_urb);
/*
* We need a short delay here to wait for
* the URB to be canceled
*/
do {
udelay(100);
} while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
} }
void rt2x00usb_kill_tx_queue(struct data_queue *queue) void rt2x00usb_kill_tx_queue(struct data_queue *queue)
...@@ -469,7 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) ...@@ -469,7 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
rt2x00usb_interrupt_rxdone, entry); rt2x00usb_interrupt_rxdone, entry);
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
usb_submit_urb(entry_priv->urb, GFP_ATOMIC); if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry);
}
} }
} }
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment