diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-10-11 09:39:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-11 15:04:26 -0400 |
commit | a13c8f3133b250e732c383b1c390d625e755db03 (patch) | |
tree | e95a4f2d6cbe22722628844bcbb808e119af52f9 | |
parent | 1a397696536e896e7d763c0c38f3ae3e588b5d52 (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.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 18 |
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 | ||
254 | void rt2x00lib_dmadone(struct queue_entry *entry) | 254 | void 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 | } |
258 | EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); | 259 | EXPORT_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 | ||
259 | void rt2x00usb_kick_tx_queue(struct data_queue *queue) | 262 | void 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 | ||
293 | void rt2x00usb_kill_tx_queue(struct data_queue *queue) | 288 | void 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 | } |
475 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); | 473 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); |