On Wed, Oct 2, 2013 at 9:14 AM, Sarah Sharp
<[email protected]> wrote:
> On Mon, Sep 23, 2013 at 04:29:40PM -0700, Dan Williams wrote:
>> Change the enumeration scheme for xhci attached devices from:
>>
>> SetAddress
>> GetDescriptor(8)
>> GetDescriptor(18)
>>
>> ...to:
>>
>> GetDescriptor(64)
>> SetAddress
>> GetDescriptor(18)
>
> Thinking about this sequence again, I'm trying to figure out if that
> first 64-byte descriptor fetch is going to be an issue. We set up the
> control endpoint context with a max packet size of 8 bytes, but it can
> be larger, depending on the device. We don't know what it is until we
> fetch the device descriptors.
>
> So if the USB core asks for 64-bytes of the device descriptor before the
> xHCI driver sets the real max packet size in the control endpoint
> context, won't the host controller expect to receive 8-byte packets, but
> may instead get larger packets?
>
> Alan, how would this work under EHCI?
>
> Dan, I was also testing under HSW-ULT with a (possibly buggy) device,
> and I managed to get the device context into a bad state. The device
> refused to respond to the first 64-byte control transfer (it timed out
> three times), and then the USB core reset the device. The xHCI driver
> then attempted to issue a Reset Device command, which failed because the
> device was in the default state.
>
> I think this meant the endpoint toggles in the control endpoint on the
> device were mis-matched to the host's toggle state. That would cause
> protocol errors. I'm not quite sure what the solution for this is yet,
> but I think it may be why you get the context state error on the second
> Set Address command. Because the Reset Device command didn't complete
> successfully, the host thinks the device is still in the default state.
>
> Not sure why the Set Address with BSR=1 fails on a different system.
>
So this is working for me now with the following incremental patch. I
simply disable new scheme detection for USB3 devices. This should be
safe since:
1/ it was already the default case for USB3 devices (previously we
disabled it for all xHC attached devices)
2/ we don't need to worry about xHC implementation quirks with
handling USB3 devices in the default state, we just go straight to
addressed as before.
We can revisit this when/if a USB3 device shows up that needs
new_scheme detection.
--
Dan
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 355a09d..a9eb65c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2514,6 +2514,14 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
#define HUB_LONG_RESET_TIME 200
#define HUB_RESET_TIMEOUT 800
+static bool use_new_scheme(struct usb_device *udev, int retry)
+{
+ if (udev->speed == USB_SPEED_SUPER)
+ return false;
+
+ return USE_NEW_SCHEME(retry);
+}
+
static int hub_port_reset(struct usb_hub *hub, int port1,
struct usb_device *udev, unsigned int delay, bool warm);
@@ -4069,7 +4077,7 @@ hub_port_init (struct usb_hub *hub, struct
usb_device *udev, int port1,
* this area, and this is how Linux has done it for ages.
* Change it cautiously.
*
- * NOTE: If USE_NEW_SCHEME() is true we will start by issuing
+ * NOTE: If use_new_scheme() is true we will start by issuing
* a 64-byte GET_DESCRIPTOR request. This is what Windows does,
* so it may help with some non-standards-compliant devices.
* Otherwise we start with SET_ADDRESS and then try to read the
@@ -4077,10 +4085,12 @@ hub_port_init (struct usb_hub *hub, struct
usb_device *udev, int port1,
* value.
*/
for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
- if (USE_NEW_SCHEME(retry_counter)) {
- struct usb_device_descriptor *buf;
+ bool did_new_scheme = false;
+
+ if (use_new_scheme(udev, retry_counter)) {
int r = 0;
+ did_new_scheme = true;
#define GET_DESCRIPTOR_BUFSIZE 64
buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO);
if (!buf) {
@@ -4173,7 +4183,7 @@ hub_port_init (struct usb_hub *hub, struct
usb_device *udev, int port1,
* - read ep0 maxpacket even for high and low speed,
*/
msleep(10);
- if (USE_NEW_SCHEME(retry_counter))
+ if (did_new_scheme)
break;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html