summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/usb.c12
-rw-r--r--common/usb_hub.c2
-rw-r--r--include/usb.h1
3 files changed, 15 insertions, 0 deletions
diff --git a/common/usb.c b/common/usb.c
index ac9b4ca8d5..6fc0fc1c0e 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -805,6 +805,18 @@ struct usb_device *usb_alloc_new_device(void *controller)
return &usb_dev[dev_index - 1];
}
+/*
+ * Free the newly created device node.
+ * Called in error cases where configuring a newly attached
+ * device fails for some reason.
+ */
+void usb_free_device(void)
+{
+ dev_index--;
+ USB_PRINTF("Freeing device node: %d\n", dev_index);
+ memset(&usb_dev[dev_index], 0, sizeof(struct usb_device));
+ usb_dev[dev_index].devnum = -1;
+}
/*
* By the time we get here, the device has gotten a new device ID
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 4d75b902ff..b5eeb62fbe 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -259,6 +259,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
/* Run it through the hoops (find a driver, etc) */
if (usb_new_device(usb)) {
/* Woops, disable the port */
+ usb_free_device();
+ dev->children[port] = NULL;
USB_HUB_PRINTF("hub: disabling port %d\n", port + 1);
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
}
diff --git a/include/usb.h b/include/usb.h
index 8d8a2c9b9d..d79c865884 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -392,5 +392,6 @@ int hub_port_reset(struct usb_device *dev, int port,
struct usb_device *usb_alloc_new_device(void *controller);
int usb_new_device(struct usb_device *dev);
+void usb_free_device(void);
#endif /*_USB_H_ */