Re: [REGRESSION] Re: [PATCH 0/3] USB: core: Don't overwrite device descriptor during reinitialization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Mar 12, 2024 at 09:57:06AM +0100, Jan Čermák wrote:
> Hi Alan
> 
> On 11. 03. 24 15:43, Alan Stern wrote:
> > Well, at least this means you do have a way of using the device, even
> > if it is rather awkward.  It might even work on the Raspberry Pi machine.
> 
> Still, I'm looking for a more permanent and robust solution. If it were only
> a single device I'm using myself, I could come up with a workaround.
> However, this is one of the very few available Z-Wave USB interfaces and
> there are more users affected. So far we went with reverting the patches,
> but that's surely not the way we want to go forward.
> 
> > The device is so non-responsive, I'm amazed it ever works at all.
> > Judging by the usbmon traces, it doesn't look as if it would work on a
> > Windows system.
> > 
> > Actually, if you have access to a computer running Windows or Mac OSX
> > and you can try out the device on that computer, it would be good to
> > get the equivalent of a usbmon trace (something like a Wireshark
> > capture log would do).  If those systems manage to do something that
> > Linux doesn't, we ought to know what it is.
> 
> Fredrik (one of the original reporters) is following this conversation, here
> [1] are logs from his machine with some details in the ticket [2]. He also
> wonders why the initialization doesn't work only on USB2 ports but works on
> USB3 if the initialization code is shared between those two.

It's very difficult to compare the Windows log with the usbmon trace.  
However, something Frederik mentioned about the number of resets led me 
to check more closely.  There are some extra unnecessary resets in the 
usbmon trace, and a reset that should be there is missing.

Below is a patch meant to get the number of resets back to what it 
should be.  I'd appreciate it if you can test this, and report the 
kernel log output along with the usbmon output for the normal case and 
also with the "old_scheme_first" parameter set.

I'm not very hopeful that this will solve the problem, but there's a 
good chance it will help point us in the right direction by removing 
extraneous complications.

Alan Stern



 drivers/usb/core/hub.c |   27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

Index: usb-devel/drivers/usb/core/hub.c
===================================================================
--- usb-devel.orig/drivers/usb/core/hub.c
+++ usb-devel/drivers/usb/core/hub.c
@@ -4961,6 +4961,18 @@ hub_port_init(struct usb_hub *hub, struc
 			break;
 		}
 
+		if (retries > 0) {
+			retval = hub_port_reset(hub, port1, udev, delay, false);
+			if (retval < 0)		/* error or disconnect */
+				goto fail;
+			if (oldspeed != udev->speed) {
+				dev_dbg(&udev->dev,
+					"device reset changed speed!\n");
+				retval = -ENODEV;
+				goto fail;
+			}
+		}
+
 		if (do_new_scheme) {
 			retval = hub_enable_device(udev);
 			if (retval < 0) {
@@ -4972,6 +4984,13 @@ hub_port_init(struct usb_hub *hub, struc
 
 			maxp0 = get_bMaxPacketSize0(udev, buf,
 					GET_DESCRIPTOR_BUFSIZE, retries == 0);
+			if (maxp0 < 0) {
+				if (maxp0 != -ENODEV)
+					dev_err(&udev->dev, "device descriptor read/64, error %d\n",
+							maxp0);
+				retval = maxp0;
+				continue;
+			}
 			if (maxp0 > 0 && !initial &&
 					maxp0 != udev->descriptor.bMaxPacketSize0) {
 				dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n");
@@ -4988,13 +5007,6 @@ hub_port_init(struct usb_hub *hub, struc
 				retval = -ENODEV;
 				goto fail;
 			}
-			if (maxp0 < 0) {
-				if (maxp0 != -ENODEV)
-					dev_err(&udev->dev, "device descriptor read/64, error %d\n",
-							maxp0);
-				retval = maxp0;
-				continue;
-			}
 		}
 
 		for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) {
@@ -5533,6 +5545,7 @@ loop:
 			msleep(2 * hub_power_on_good_delay(hub));
 			usb_hub_set_port_power(hdev, hub, port1, true);
 			msleep(hub_power_on_good_delay(hub));
+			hub_port_debounce_be_stable(hub, port1);
 		}
 	}
 	if (hub->hdev->parent ||





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux