diff options
author | Simon Glass <sjg@chromium.org> | 2015-03-25 12:22:01 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-04-18 11:11:20 -0600 |
commit | 79b5888729b65e7040d6a964f0015fc2c21b2385 (patch) | |
tree | 3497e7a22e622a32b7f3257682456087b17e409c /common/usb_hub.c | |
parent | cad4291cd053f8eaa404e47ab289a6169c19ae93 (diff) | |
download | u-boot-79b5888729b65e7040d6a964f0015fc2c21b2385.tar.gz u-boot-79b5888729b65e7040d6a964f0015fc2c21b2385.tar.bz2 u-boot-79b5888729b65e7040d6a964f0015fc2c21b2385.zip |
dm: usb: Adjust usb_alloc_new_device() to return an error
This function returns NULL on error at present. Adjust it so that we can
return a real error, as is needed with driver model. Also improve the
error handling in its caller, usb_hub_port_connect_change(), and adjust
the code order to prepare for driver model.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'common/usb_hub.c')
-rw-r--r-- | common/usb_hub.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/common/usb_hub.c b/common/usb_hub.c index f54a404a49..020cdc6605 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -24,6 +24,7 @@ #include <common.h> #include <command.h> +#include <errno.h> #include <asm/processor.h> #include <asm/unaligned.h> #include <linux/ctype.h> @@ -214,16 +215,18 @@ int hub_port_reset(struct usb_device *dev, int port, } -void usb_hub_port_connect_change(struct usb_device *dev, int port) +int usb_hub_port_connect_change(struct usb_device *dev, int port) { struct usb_device *usb; ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus; + int ret, speed; /* Check status */ - if (usb_get_port_status(dev, port + 1, portsts) < 0) { + ret = usb_get_port_status(dev, port + 1, portsts); + if (ret < 0) { debug("get_port_status failed\n"); - return; + return ret; } portstatus = le16_to_cpu(portsts->wPortStatus); @@ -241,47 +244,55 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) debug("usb_disconnect(&hub->children[port]);\n"); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) - return; + return -ENOTCONN; } mdelay(200); /* Reset the port */ - if (hub_port_reset(dev, port, &portstatus) < 0) { + ret = hub_port_reset(dev, port, &portstatus); + if (ret < 0) { printf("cannot reset port %i!?\n", port + 1); - return; + return ret; } mdelay(200); - /* Allocate a new device struct for it */ - usb = usb_alloc_new_device(dev->controller); - switch (portstatus & USB_PORT_STAT_SPEED_MASK) { case USB_PORT_STAT_SUPER_SPEED: - usb->speed = USB_SPEED_SUPER; + speed = USB_SPEED_SUPER; break; case USB_PORT_STAT_HIGH_SPEED: - usb->speed = USB_SPEED_HIGH; + speed = USB_SPEED_HIGH; break; case USB_PORT_STAT_LOW_SPEED: - usb->speed = USB_SPEED_LOW; + speed = USB_SPEED_LOW; break; default: - usb->speed = USB_SPEED_FULL; + speed = USB_SPEED_FULL; break; } + ret = usb_alloc_new_device(dev->controller, &usb); + if (ret) { + printf("cannot create new device: ret=%d", ret); + return ret; + } + dev->children[port] = usb; + usb->speed = speed; usb->parent = dev; usb->portnr = port + 1; /* Run it through the hoops (find a driver, etc) */ - if (usb_new_device(usb)) { + ret = usb_new_device(usb); + if (ret < 0) { /* Woops, disable the port */ - usb_free_device(); + usb_free_device(dev->controller); dev->children[port] = NULL; debug("hub: disabling port %d\n", port + 1); usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE); } + + return ret; } |