diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/usb.c | 33 | 
1 files changed, 31 insertions, 2 deletions
| diff --git a/common/usb.c b/common/usb.c index c97f522be..e23d78885 100644 --- a/common/usb.c +++ b/common/usb.c @@ -855,6 +855,16 @@ void usb_free_device(void)  }  /* + * XHCI issues Enable Slot command and thereafter + * allocates device contexts. Provide a weak alias + * function for the purpose, so that XHCI overrides it + * and EHCI/OHCI just work out of the box. + */ +__weak int usb_alloc_device(struct usb_device *udev) +{ +	return 0; +} +/*   * By the time we get here, the device has gotten a new device ID   * and is in the default state. We need to identify the thing and   * get the ball rolling.. @@ -867,6 +877,17 @@ int usb_new_device(struct usb_device *dev)  	int tmp;  	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); +	/* +	 * Allocate usb 3.0 device context. +	 * USB 3.0 (xHCI) protocol tries to allocate device slot +	 * and related data structures first. This call does that. +	 * Refer to sec 4.3.2 in xHCI spec rev1.0 +	 */ +	if (usb_alloc_device(dev)) { +		printf("Cannot allocate device context to get SLOT_ID\n"); +		return -1; +	} +  	/* We still haven't set the Address yet */  	addr = dev->devnum;  	dev->devnum = 0; @@ -897,7 +918,7 @@ int usb_new_device(struct usb_device *dev)  	 * http://sourceforge.net/mailarchive/forum.php?  	 * thread_id=5729457&forum_id=5398  	 */ -	struct usb_device_descriptor *desc; +	__maybe_unused struct usb_device_descriptor *desc;  	int port = -1;  	struct usb_device *parent = dev->parent;  	unsigned short portstatus; @@ -914,6 +935,13 @@ int usb_new_device(struct usb_device *dev)  	dev->epmaxpacketin[0] = 64;  	dev->epmaxpacketout[0] = 64; +	/* +	 * XHCI needs to issue a Address device command to setup +	 * proper device context structures, before it can interact +	 * with the device. So a get_descriptor will fail before any +	 * of that is done for XHCI unlike EHCI. +	 */ +#ifndef CONFIG_USB_XHCI  	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);  	if (err < 0) {  		debug("usb_new_device: usb_get_descriptor() failed\n"); @@ -926,11 +954,12 @@ int usb_new_device(struct usb_device *dev)  	 * to differentiate between HUB and DEVICE.  	 */  	dev->descriptor.bDeviceClass = desc->bDeviceClass; +#endif -	/* find the port number we're at */  	if (parent) {  		int j; +		/* find the port number we're at */  		for (j = 0; j < parent->maxchild; j++) {  			if (parent->children[j] == dev) {  				port = j; |