diff options
author | Simon Glass <sjg@chromium.org> | 2015-03-25 12:22:09 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-04-18 11:11:21 -0600 |
commit | 361ad6afc479d8aac330525b98df7a36dea4116d (patch) | |
tree | c215280d678ee62869825c8b54da940702bb1ca3 | |
parent | 95fbfe42980ea75c7955a6ddf4f28be1a6407920 (diff) | |
download | u-boot-imx-361ad6afc479d8aac330525b98df7a36dea4116d.zip u-boot-imx-361ad6afc479d8aac330525b98df7a36dea4116d.tar.gz u-boot-imx-361ad6afc479d8aac330525b98df7a36dea4116d.tar.bz2 |
dm: usb: Split hub detection into its own function
Split out the hub detection logic so it can be used by driver model. Also
adjust the code to return errors correctly.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Marek Vasut <marex@denx.de>
-rw-r--r-- | common/usb_hub.c | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/common/usb_hub.c b/common/usb_hub.c index 2277e6f..f62bdd8 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -305,27 +305,30 @@ static int usb_hub_configure(struct usb_device *dev) struct usb_hub_descriptor *descriptor; struct usb_hub_device *hub; __maybe_unused struct usb_hub_status *hubsts; + int ret; /* "allocate" Hub device */ hub = usb_hub_allocate(); if (hub == NULL) - return -1; + return -ENOMEM; hub->pusb_dev = dev; /* Get the the hub descriptor */ - if (usb_get_hub_descriptor(dev, buffer, 4) < 0) { + ret = usb_get_hub_descriptor(dev, buffer, 4); + if (ret < 0) { debug("usb_hub_configure: failed to get hub " \ "descriptor, giving up %lX\n", dev->status); - return -1; + return ret; } descriptor = (struct usb_hub_descriptor *)buffer; length = min_t(int, descriptor->bLength, sizeof(struct usb_hub_descriptor)); - if (usb_get_hub_descriptor(dev, buffer, length) < 0) { + ret = usb_get_hub_descriptor(dev, buffer, length); + if (ret < 0) { debug("usb_hub_configure: failed to get hub " \ "descriptor 2nd giving up %lX\n", dev->status); - return -1; + return ret; } memcpy((unsigned char *)&hub->desc, buffer, length); /* adjust 16bit values */ @@ -393,13 +396,14 @@ static int usb_hub_configure(struct usb_device *dev) if (sizeof(struct usb_hub_status) > USB_BUFSIZ) { debug("usb_hub_configure: failed to get Status - " \ "too long: %d\n", descriptor->bLength); - return -1; + return -EFBIG; } - if (usb_get_hub_status(dev, buffer) < 0) { + ret = usb_get_hub_status(dev, buffer); + if (ret < 0) { debug("usb_hub_configure: failed to get Status %lX\n", dev->status); - return -1; + return ret; } #ifdef DEBUG @@ -431,6 +435,7 @@ static int usb_hub_configure(struct usb_device *dev) int ret; ulong start = get_timer(0); + debug("\n\nScanning port %d\n", i + 1); /* * Wait for (whichever finishes first) * - A maximum of 10 seconds @@ -511,33 +516,53 @@ static int usb_hub_configure(struct usb_device *dev) return 0; } -int usb_hub_probe(struct usb_device *dev, int ifnum) +static int usb_hub_check(struct usb_device *dev, int ifnum) { struct usb_interface *iface; - struct usb_endpoint_descriptor *ep; - int ret; + struct usb_endpoint_descriptor *ep = NULL; iface = &dev->config.if_desc[ifnum]; /* Is it a hub? */ if (iface->desc.bInterfaceClass != USB_CLASS_HUB) - return 0; + goto err; /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ if ((iface->desc.bInterfaceSubClass != 0) && (iface->desc.bInterfaceSubClass != 1)) - return 0; + goto err; /* Multiple endpoints? What kind of mutant ninja-hub is this? */ if (iface->desc.bNumEndpoints != 1) - return 0; + goto err; ep = &iface->ep_desc[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(ep->bEndpointAddress & USB_DIR_IN)) - return 0; + goto err; /* If it's not an interrupt endpoint, we'd better punt! */ if ((ep->bmAttributes & 3) != 3) - return 0; + goto err; /* We found a hub */ debug("USB hub found\n"); + return 0; + +err: + debug("USB hub not found: bInterfaceClass=%d, bInterfaceSubClass=%d, bNumEndpoints=%d\n", + iface->desc.bInterfaceClass, iface->desc.bInterfaceSubClass, + iface->desc.bNumEndpoints); + if (ep) { + debug(" bEndpointAddress=%#x, bmAttributes=%d", + ep->bEndpointAddress, ep->bmAttributes); + } + + return -ENOENT; +} + +int usb_hub_probe(struct usb_device *dev, int ifnum) +{ + int ret; + + ret = usb_hub_check(dev, ifnum); + if (ret) + return 0; ret = usb_hub_configure(dev); return ret; } |