Skip to contentSkip to conversation

rt2x00usb: mark device removed when get ENOENT usb error

PATCH In review Stanislaw Gruszka 3 participants 3 messages Nov 9, 2017 – Nov 10, 2017 Ralink RT2X00 wireless LAN driver

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---
 drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +3 -3
index e2f4f5778267..086aad22743d 100644
@@ -57,7 +57,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
 		if (status >= 0)
 			return 0;
 
-		if (status == -ENODEV) {
+		if (status == -ENODEV || status == -ENOENT) {
 			/* Device has disappeared. */
 			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 			break;
@@ -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);
 	if (status) {
-		if (status == -ENODEV)
+		if (status == -ENODEV || status == -ENOENT)
 			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 		rt2x00lib_dmadone(entry);
@@ -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);
 	if (status) {
-		if (status == -ENODEV)
+		if (status == -ENODEV || status == -ENOENT)
 			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 		rt2x00lib_dmadone(entry);
Signature · 1 line
2.7.5
Tested-by on v1 1/1
#1 lore raw
Quoted 13 lines · Stanislaw Gruszka

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.

Quoted 7 lines

Patch adds additional ENOENT check not only in rx kick routine, but also on other places where we check for ENODEV error.

(on 4.14-rc8)

This is working like a charm now !

Thanks !!

Richard.

Quoted 36 lines
---
 drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +3 -3
index e2f4f5778267..086aad22743d 100644
@@ -57,7 +57,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
 		if (status >= 0)
 			return 0;
 
-		if (status == -ENODEV) {
+		if (status == -ENODEV || status == -ENOENT) {
 			/* Device has disappeared. */
 			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 			break;
@@ -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);
 	if (status) {
-		if (status == -ENODEV)
+		if (status == -ENODEV || status == -ENOENT)
 			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 		rt2x00lib_dmadone(entry);
@@ -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);
 	if (status) {
-		if (status == -ENODEV)
+		if (status == -ENODEV || status == -ENOENT)
 			clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 		rt2x00lib_dmadone(entry);
#2 lore raw
In reply to Stanislaw Gruszka
Quoted 13 lines · Stanislaw Gruszka

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.

Quoted 8 lines

Patch adds additional ENOENT check not only in rx kick routine, but also on other places where we check for ENODEV error.

Patch applied to wireless-drivers-next.git, thanks.

bfa62a52cad9 rt2x00usb: mark device removed when get ENOENT usb error

Signature · 3 lines
https://patchwork.kernel.org/patch/10050781/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches