On Thu, Jan 24, 2013 at 10:51:04AM -0500, Alan Stern wrote: > On Wed, 23 Jan 2013, Sarah Sharp wrote: > > > > So I guess my next question is: What are you plans, if any, to add the > > > "new" enumeration scheme to xHCI? Is this a huge amount of work? > > > > Not a huge amount of work, but it does require an API change to the USB > > host controller driver functions, so the patch itself is not likely to > > get backported to stable kernels. And I have no idea how the current > > batch of USB 3.0 devices will react to an enumeration sequence change. > > I thought this wasn't possible at all, because the xHCI hardware > automatically assigns an address to the device when a reset completes. No, the xHCI hardware doesn't assign an address on reset completion. The xHCI host assigns an address and sends the Set Address control transfer when the Set Address command issued (when hcd->address_device is called in hub_set_address). The Set Address command does two things: it tells the xHC that the default control endpoint ring and associated device context information is set up, and it tells the xHC to issue the Set Address control transfer. There's a flag you can pass to the Set Address command to make it not actually send the control transfer. It's called 'Block Set Address Request' (BSR). After you issue the Set Address command with the BSR flag set, you can get the device descriptor through the default control endpoint. Then you send the Set Address command again, with BSR cleared, when you want to actually set the device address. I asked the xHCI spec author to put the flag in, because I saw the two enumeration schemes. I just haven't had time or motivation to implement it. > "Old" scheme: > > Reset > Get device descriptor (8 bytes) > Set address > Get device descriptor (18 bytes) Does the core really get the 8 byte device descriptor before set address? I'm pretty sure that would be skipped in the if block when we try the old scheme: for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) { struct usb_device_descriptor *buf; int r = 0; #define GET_DESCRIPTOR_BUFSIZE 64 buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); if (!buf) { retval = -ENOMEM; continue; } /* Retry on all errors; some devices are flakey. * 255 is for WUSB devices, we actually need to use * 512 (WUSB1.0[4.8.1]). */ for (j = 0; j < 3; ++j) { buf->bMaxPacketSize0 = 0; r = usb_control_msg(udev, usb_rcvaddr0pipe(), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8, 0, buf, GET_DESCRIPTOR_BUFSIZE, initial_descriptor_timeout); ... } } ... if (udev->wusb == 0) { for (j = 0; j < SET_ADDRESS_TRIES; ++j) { retval = hub_set_address(udev, devnum); if (retval >= 0) break; msleep(200); } ... } I thought the old scheme was: Reset Set address Get device descriptor (8 bytes) Get device descriptor (18 bytes) > "New" scheme: > > Reset > Get device descriptor (64 bytes) > Reset > Set address > Get device descriptor (18 bytes) > > Given the way the hardware behaves, it's not really possible to do > either of these. I think it's still possible to do the new enumeration scheme with the flag to the Set Address command. The new scheme would look like: "New" scheme: Reset Set Address command (BSR flag set) Get device descriptor (64 bytes) Reset Reset Device command Set address Set Address command (BSR flag clear) Get device descriptor (18 bytes) Does that make sense? Sarah Sharp -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html