aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2010-10-11 09:39:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-11 15:04:26 -0400
commita13c8f3133b250e732c383b1c390d625e755db03 (patch)
treee95a4f2d6cbe22722628844bcbb808e119af52f9
parent1a397696536e896e7d763c0c38f3ae3e588b5d52 (diff)
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: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c18
2 files changed, 9 insertions, 10 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index e5e8ba3bf228..5ba79b935f09 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -253,6 +253,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
253 253
254void rt2x00lib_dmadone(struct queue_entry *entry) 254void rt2x00lib_dmadone(struct queue_entry *entry)
255{ 255{
256 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
256 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); 257 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
257} 258}
258EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); 259EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 89d77f55d76c..b3317df7a7d4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -253,7 +253,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
253 entry->skb->data, length, 253 entry->skb->data, length,
254 rt2x00usb_interrupt_txdone, entry); 254 rt2x00usb_interrupt_txdone, entry);
255 255
256 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 256 if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
257 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
258 rt2x00lib_dmadone(entry);
259 }
257} 260}
258 261
259void rt2x00usb_kick_tx_queue(struct data_queue *queue) 262void rt2x00usb_kick_tx_queue(struct data_queue *queue)
@@ -280,14 +283,6 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
280 if ((entry->queue->qid == QID_BEACON) && 283 if ((entry->queue->qid == QID_BEACON) &&
281 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) 284 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
282 usb_kill_urb(bcn_priv->guardian_urb); 285 usb_kill_urb(bcn_priv->guardian_urb);
283
284 /*
285 * We need a short delay here to wait for
286 * the URB to be canceled
287 */
288 do {
289 udelay(100);
290 } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
291} 286}
292 287
293void rt2x00usb_kill_tx_queue(struct data_queue *queue) 288void rt2x00usb_kill_tx_queue(struct data_queue *queue)
@@ -469,7 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
469 rt2x00usb_interrupt_rxdone, entry); 464 rt2x00usb_interrupt_rxdone, entry);
470 465
471 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 466 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
472 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 467 if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
468 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
469 rt2x00lib_dmadone(entry);
470 }
473 } 471 }
474} 472}
475EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); 473EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);