Commit bfa62a52 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by Kalle Valo

rt2x00usb: mark device removed when get ENOENT usb error

ENOENT usb error mean "specified interface or endpoint does not exist or
is not enabled". Mark device not present when we encounter this error
similar like we do with ENODEV error.

Otherwise we can have infinite loop in rt2x00usb_work_rxdone(), because
we remove and put again RX entries to the queue infinitely.

We can have similar situation when submit urb will fail all the time
with other error, so we need consider to limit number of entries
processed by rxdone work. But for now, since the patch fixes
reproducible soft lockup issue on single processor systems
and taken ENOENT error meaning, let apply this fix.

Patch adds additional ENOENT check not only in rx kick routine, but
also on other places where we check for ENODEV error.
Reported-by: default avatarRichard Genoud <richard.genoud@gmail.com>
Debugged-by: default avatarRichard Genoud <richard.genoud@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Tested-by: default avatarRichard Genoud <richard.genoud@gmail.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent c9889671
...@@ -57,7 +57,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, ...@@ -57,7 +57,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
if (status >= 0) if (status >= 0)
return 0; return 0;
if (status == -ENODEV) { if (status == -ENODEV || status == -ENOENT) {
/* Device has disappeared. */ /* Device has disappeared. */
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
break; break;
...@@ -321,7 +321,7 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) ...@@ -321,7 +321,7 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data)
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
if (status) { if (status) {
if (status == -ENODEV) if (status == -ENODEV || status == -ENOENT)
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry); rt2x00lib_dmadone(entry);
...@@ -410,7 +410,7 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data) ...@@ -410,7 +410,7 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data)
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
if (status) { if (status) {
if (status == -ENODEV) if (status == -ENODEV || status == -ENOENT)
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry); rt2x00lib_dmadone(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