Re: problem with Roseweil eusb3 enclosure

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

 



On Sat, Oct 27, 2012 at 04:48:55AM -0400, covici@xxxxxxxxxxxxxx wrote:
> Hi.  Well, here is an interesting piece of information -- I started from
> a poweroff state and the disk drive is seen even when its plugged in!
> However, I  almost never do it that way and certainly it would not  work
> remotely.

Yes, I agree, let's fix the issue when you don't cold-boot.

> With that said, here is the syslog and the dmesg from a boot with the
> power on, so you should see the error.

Thanks.  I think I see the issue.  Can you try to apply the attached
patch and see if it allows your device to work when connected on boot?

You can follow the instructions in the "Patching your kernel" section of
http://kernelnewbies.org/KernelBuild if you need help.

Alan, can you take a look at the patch and see what I can do in the case
where five warm port resets fail?  I think it's a pretty unlikely
scenario, but if you have a good solution, I'm all ears.

Sarah Sharp
>From caca74e2dc2b8a71a73dce6d60608e2ebae44a43 Mon Sep 17 00:00:00 2001
From: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
Date: Thu, 1 Nov 2012 11:20:44 -0700
Subject: [PATCH] USB: Check for disconnect on warm reset completion.

When a warm (BH) reset completes, the port state may be moved into one
of three states, as Figure Figure 10-9 in the USB 3.0 bus spec shows.

If the reset succeeds, the port will move into the Enabled state, and
the U0 link state.  If the reset fails, the port will move into the
disconnected state, and the RxDetect link state.  If a U1/U2 exit failed
during the attempt to reset, the device may move to the Error state, and
the SS.Inactive link state.  The only way to get out of the Error state
is to issue another warm reset.

The warm (BH) reset code in the USB core blindly assumes that the reset
has successfully completed if the BH reset change bit is set.  Make that
code check for the other error states.

First, report a disconnect on transition to the RxDetect state.  Second,
return -EBUSY on a transition to the SS.Inactive state.  The USB core
will try another warm reset when -EBUSY is returned, but if we continue
to go into SS.Inactive after PORT_RESET_TRIES (5 tries), the port will
remain in SS.Inactive.

FIXME: Not sure what else we can do in that case.  Perhaps disable the
port?

Without this commit, when John boots with his USB hard drive connected,
the log files show failed warm resets, followed by an attempt to address
the device, in an endless loop.  If the USB core reports the device
disconnect on the failed warm reset, it won't try to issue the Set
Address control transfer, and the device may have time to settle and
successfully reconnect.

This commit should be backported to kernels as old as 3.2, that contain
the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
warm reset logic".

Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
Reported-by: John Covici <covici@xxxxxxxxxxxxxx>
Cc: Andiry Xu <andiry.xu@xxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
 drivers/usb/core/hub.c |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1af04bd..2dd3586 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2498,9 +2498,26 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
 					udev->speed = USB_SPEED_FULL;
 				return 0;
 			}
-		} else {
-			if (portchange & USB_PORT_STAT_C_BH_RESET)
-				return 0;
+		} else if (portchange & USB_PORT_STAT_C_BH_RESET) {
+			/*
+			 * If the warm reset failed, the port state can move to
+			 * the Disconnect state and report a RxDetect link
+			 * state.  Assume the device disconnected in this case.
+			 */
+			if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
+					USB_SS_PORT_LS_RX_DETECT)
+				return -ENOTCONN;
+
+			/*
+			 * A warm reset can also move to the Error state, and
+			 * the only way to get it out is to issue another warm
+			 * reset.
+			 */
+			if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
+					USB_SS_PORT_LS_SS_INACTIVE)
+				return -EBUSY;
+
+			return 0;
 		}
 
 		/* switch to the long delay after two short delay failures */
-- 
1.7.9


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

  Powered by Linux