mirror of
https://xff.cz/git/u-boot/
synced 2025-09-01 16:52:14 +02:00
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>
This commit is contained in:
@@ -305,27 +305,30 @@ static int usb_hub_configure(struct usb_device *dev)
|
|||||||
struct usb_hub_descriptor *descriptor;
|
struct usb_hub_descriptor *descriptor;
|
||||||
struct usb_hub_device *hub;
|
struct usb_hub_device *hub;
|
||||||
__maybe_unused struct usb_hub_status *hubsts;
|
__maybe_unused struct usb_hub_status *hubsts;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* "allocate" Hub device */
|
/* "allocate" Hub device */
|
||||||
hub = usb_hub_allocate();
|
hub = usb_hub_allocate();
|
||||||
if (hub == NULL)
|
if (hub == NULL)
|
||||||
return -1;
|
return -ENOMEM;
|
||||||
hub->pusb_dev = dev;
|
hub->pusb_dev = dev;
|
||||||
/* Get the the hub descriptor */
|
/* 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 " \
|
debug("usb_hub_configure: failed to get hub " \
|
||||||
"descriptor, giving up %lX\n", dev->status);
|
"descriptor, giving up %lX\n", dev->status);
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
descriptor = (struct usb_hub_descriptor *)buffer;
|
descriptor = (struct usb_hub_descriptor *)buffer;
|
||||||
|
|
||||||
length = min_t(int, descriptor->bLength,
|
length = min_t(int, descriptor->bLength,
|
||||||
sizeof(struct usb_hub_descriptor));
|
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 " \
|
debug("usb_hub_configure: failed to get hub " \
|
||||||
"descriptor 2nd giving up %lX\n", dev->status);
|
"descriptor 2nd giving up %lX\n", dev->status);
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
memcpy((unsigned char *)&hub->desc, buffer, length);
|
memcpy((unsigned char *)&hub->desc, buffer, length);
|
||||||
/* adjust 16bit values */
|
/* adjust 16bit values */
|
||||||
@@ -393,13 +396,14 @@ static int usb_hub_configure(struct usb_device *dev)
|
|||||||
if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
|
if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
|
||||||
debug("usb_hub_configure: failed to get Status - " \
|
debug("usb_hub_configure: failed to get Status - " \
|
||||||
"too long: %d\n", descriptor->bLength);
|
"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",
|
debug("usb_hub_configure: failed to get Status %lX\n",
|
||||||
dev->status);
|
dev->status);
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -431,6 +435,7 @@ static int usb_hub_configure(struct usb_device *dev)
|
|||||||
int ret;
|
int ret;
|
||||||
ulong start = get_timer(0);
|
ulong start = get_timer(0);
|
||||||
|
|
||||||
|
debug("\n\nScanning port %d\n", i + 1);
|
||||||
/*
|
/*
|
||||||
* Wait for (whichever finishes first)
|
* Wait for (whichever finishes first)
|
||||||
* - A maximum of 10 seconds
|
* - A maximum of 10 seconds
|
||||||
@@ -511,33 +516,53 @@ static int usb_hub_configure(struct usb_device *dev)
|
|||||||
return 0;
|
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_interface *iface;
|
||||||
struct usb_endpoint_descriptor *ep;
|
struct usb_endpoint_descriptor *ep = NULL;
|
||||||
int ret;
|
|
||||||
|
|
||||||
iface = &dev->config.if_desc[ifnum];
|
iface = &dev->config.if_desc[ifnum];
|
||||||
/* Is it a hub? */
|
/* Is it a hub? */
|
||||||
if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
|
if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
|
||||||
return 0;
|
goto err;
|
||||||
/* Some hubs have a subclass of 1, which AFAICT according to the */
|
/* Some hubs have a subclass of 1, which AFAICT according to the */
|
||||||
/* specs is not defined, but it works */
|
/* specs is not defined, but it works */
|
||||||
if ((iface->desc.bInterfaceSubClass != 0) &&
|
if ((iface->desc.bInterfaceSubClass != 0) &&
|
||||||
(iface->desc.bInterfaceSubClass != 1))
|
(iface->desc.bInterfaceSubClass != 1))
|
||||||
return 0;
|
goto err;
|
||||||
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
|
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
|
||||||
if (iface->desc.bNumEndpoints != 1)
|
if (iface->desc.bNumEndpoints != 1)
|
||||||
return 0;
|
goto err;
|
||||||
ep = &iface->ep_desc[0];
|
ep = &iface->ep_desc[0];
|
||||||
/* Output endpoint? Curiousier and curiousier.. */
|
/* Output endpoint? Curiousier and curiousier.. */
|
||||||
if (!(ep->bEndpointAddress & USB_DIR_IN))
|
if (!(ep->bEndpointAddress & USB_DIR_IN))
|
||||||
return 0;
|
goto err;
|
||||||
/* If it's not an interrupt endpoint, we'd better punt! */
|
/* If it's not an interrupt endpoint, we'd better punt! */
|
||||||
if ((ep->bmAttributes & 3) != 3)
|
if ((ep->bmAttributes & 3) != 3)
|
||||||
return 0;
|
goto err;
|
||||||
/* We found a hub */
|
/* We found a hub */
|
||||||
debug("USB hub found\n");
|
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);
|
ret = usb_hub_configure(dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user