On 04.06.23 01:59, Warren Togami wrote:
On 3/27/23 03:05, Oliver Neukum wrote:
Hi,
https://blockstream.com/jade/
We have a mass produced device Blockstream Jade with USB serial chip CH9102F 1a86:55d4 misbehaving in the same manner. Tens of thousands of this device were manufactured and sold worldwide. This board fails to communicate with Linux cdc-acm unless autosuspend is turned off (power/control set to 'on'). lsusb -v similarly reports "Bus Powered" and "Remote Wakeup". [1]
OK, then we need to do something about it.
Either of these workarounds allow this device to work by disabling autosuspend:
* udev rule: ATTRS{idProduct}=="55d4", ATTRS{idVendor}=="1a86", SUBSYSTEM=="usb", TEST=="power/control" ATTR{power/control}="on"
* usbcore.quirks=1a86:55d4:b
[..]
During the pandemic supply chain constraints led to some switching to the CH9102F which is described here as *almost* a drop-in replacement. Unfortunately the pinout differences might have mattered. I am uncertain if the board design could have been better but that is now in the past. Too many were mass produced so I am hoping for a USB quirk to stabilize this going forward.
I have confirmed USB_QUIRK_RESET_RESUME allows this device to function for the same reason it works for the Cypress. I am uncertain if a narrower new quirk "ignore the remote wakeup bit" would work here. How can I test that?
Please test the attached patch by giving the new 'p' quirk
as usbcore.quirks
Regards
Oliver
From 6c6160bb9e315caf2016da20709553ed4f3ca2fd Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Wed, 7 Jun 2023 15:03:57 +0200
Subject: [PATCH] usb: divorce RESET_RESUME from broken remote wakeup
Some devices falsely advertise supporting remote wakeup.
Such devices fail to work if needs_remote_wakeup needs to be set.
Giving the RESET_RESUME quirk to them, however, can erase
state in case the device alternates between operating modes
in which needs_remote_wakeup is set and not set.
Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx>
---
drivers/usb/core/driver.c | 3 +++
drivers/usb/core/quirks.c | 3 +++
include/linux/usb/quirks.h | 3 +++
3 files changed, 9 insertions(+)
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 039ae981503b..ceff0bb752e5 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1913,6 +1913,9 @@ static int autosuspend_check(struct usb_device *udev)
intf->needs_remote_wakeup)
return -EOPNOTSUPP;
}
+ if (udev->quirks & USB_QUIRK_REMOTE_BROKEN)
+ if (intf->needs_remote_wakeup)
+ return -EOPNOTSUPP;
}
}
if (w && !device_can_wakeup(&udev->dev)) {
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 934b3d997702..ff49c55c513d 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -138,6 +138,9 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp)
case 'o':
flags |= USB_QUIRK_HUB_SLOW_RESET;
break;
+ case 'p':
+ flags |= USB_QUIRK_REMOTE_BROKEN;
+ break;
/* Ignore unrecognized flag characters */
}
}
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index eeb7c2157c72..7c81ad49f1a0 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -72,4 +72,7 @@
/* device has endpoints that should be ignored */
#define USB_QUIRK_ENDPOINT_IGNORE BIT(15)
+/* device falsely claims to support remote wakeup */
+#define USB_QUIRK_REMOTE_BROKEN BIT(16)
+
#endif /* __LINUX_USB_QUIRKS_H */
--
2.40.1