diff options
Diffstat (limited to 'common/usb.c')
-rw-r--r-- | common/usb.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/common/usb.c b/common/usb.c index c97f522..60daa10 100644 --- a/common/usb.c +++ b/common/usb.c @@ -33,6 +33,7 @@ #include <linux/ctype.h> #include <asm/byteorder.h> #include <asm/unaligned.h> +#include <compiler.h> #include <usb.h> #ifdef CONFIG_4xx @@ -74,7 +75,7 @@ int usb_init(void) for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { /* init low_level USB */ printf("USB%d: ", i); - if (usb_lowlevel_init(i, &ctrl)) { + if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl)) { puts("lowlevel init failed\n"); continue; } @@ -855,6 +856,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 +878,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 +919,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 +936,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 +955,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; @@ -1037,4 +1067,9 @@ int usb_new_device(struct usb_device *dev) return 0; } +__weak +int board_usb_init(int index, enum usb_init_type init) +{ + return 0; +} /* EOF */ |