@@ -79,6 +79,7 @@ enum USB_SPEED_TYPE {
struct usb_dev {
struct usb_dev *next;
+ struct usb_dev *hub;
struct usb_hcd_dev *hcidev;
struct usb_pipe *intr;
struct usb_pipe *control;
@@ -13,6 +13,7 @@
#include <stdio.h>
#include <string.h>
#include "usb-core.h"
+#include "usb-xhci.h"
#undef HUB_DEBUG
//#define HUB_DEBUG
@@ -151,11 +152,37 @@ static int hub_check_port(struct usb_dev *dev, int port)
return false;
}
+static bool usb_hub_init_dev(struct usb_dev *hub_dev, int port)
+{
+ struct usb_dev *newdev;
+
+ if (hub_dev->hcidev->type == USB_XHCI) {
+ /*
+ * USB3 devices need special setup (e.g. with assigning
+ * a slot ID and route string), which will all be done
+ * by usb3_dev_init() - it also calls usb_devpool_get(),
+ * usb_setup_new_device() and usb_slof_populate_new_device()
+ * internally, so we can return immediately after this step.
+ */
+ return usb3_dev_init(hub_dev->hcidev->priv, hub_dev, port);
+ }
+
+ newdev = usb_devpool_get();
+ dprintf("usb-hub: allocated device %p\n", newdev);
+ newdev->hub = hub_dev;
+ newdev->hcidev = hub_dev->hcidev;
+ if (usb_setup_new_device(newdev, port)) {
+ usb_slof_populate_new_device(newdev);
+ return true;
+ }
+
+ return false;
+}
+
unsigned int usb_hub_init(void *hubdev)
{
struct usb_dev *dev = hubdev;
struct usb_dev_hub_descr hub;
- struct usb_dev *newdev;
int i;
dprintf("%s: enter %p\n", __func__, dev);
@@ -172,12 +199,7 @@ unsigned int usb_hub_init(void *hubdev)
dprintf("***********************************************\n");
dprintf("\t\tusb-hub: device found %d\n", i);
dprintf("***********************************************\n");
- newdev = usb_devpool_get();
- dprintf("usb-hub: allocated device %p\n", newdev);
- newdev->hcidev = dev->hcidev;
- if (usb_setup_new_device(newdev, i))
- usb_slof_populate_new_device(newdev);
- else
+ if (!usb_hub_init_dev(dev, i))
printf("usb-hub: unable to setup device on port %d\n", i);
}
}
@@ -528,7 +528,8 @@ static uint32_t usb_control_max_packet(uint32_t speed)
return max_packet;
}
-static bool xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t port)
+static bool xhci_alloc_dev(struct xhci_hcd *xhcd, struct usb_dev *hub,
+ uint32_t slot_id, uint32_t port)
{
struct usb_dev *dev;
struct xhci_dev *xdev;
@@ -629,6 +630,7 @@ static bool xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t por
dev->speed = USB_SUPER_SPEED;
dev->addr = USB_DEV_ADDRESS(slot->field4);
dev->port = newport;
+ dev->hub = hub;
dev->priv = xdev;
xdev->dev = dev;
if (usb_setup_new_device(dev, newport)) {
@@ -654,7 +656,7 @@ static void xhci_free_dev(struct xhci_dev *xdev)
xhci_free_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE);
}
-static bool usb3_dev_init(struct xhci_hcd *xhcd, uint32_t port)
+bool usb3_dev_init(struct xhci_hcd *xhcd, struct usb_dev *hub, uint32_t port)
{
/* Device enable slot */
xhci_send_enable_slot(xhcd, port);
@@ -663,7 +665,7 @@ static bool usb3_dev_init(struct xhci_hcd *xhcd, uint32_t port)
return false;
}
dprintf("SLOT ID: %d\n", xhcd->slot_id);
- if (!xhci_alloc_dev(xhcd, xhcd->slot_id, port)) {
+ if (!xhci_alloc_dev(xhcd, hub, xhcd->slot_id, port)) {
dprintf("Unable to allocate device\n");
return false;
}
@@ -741,7 +743,7 @@ static int xhci_port_scan(struct xhci_hcd *xhcd,
dprintf("Port reset complete %d\n", i);
}
print_port_status(prs);
- if (!usb3_dev_init(xhcd, (i - (port_off - 1)))) {
+ if (!usb3_dev_init(xhcd, NULL, (i - (port_off - 1)))) {
dprintf("USB device initialization failed\n");
}
}
@@ -372,4 +372,7 @@ struct xhci_pipe {
uint32_t buflen;
};
+extern bool usb3_dev_init(struct xhci_hcd *xhcd, struct usb_dev *hub,
+ uint32_t port);
+
#endif /* USB_XHCI_H */
USB3 devices need to be initialized with usb3_dev_init(), so that they get assigned a proper slot ID. And for USB3 devices that are attached to a (non-root) hub, we also need to keep track of the hub topology, so a new field called "hub" is added to the struct usb_dev which references the hub devices where the current USB devices is attached to. The hub topology will be used later to build the so-called "route string" for the USB3 devices. Signed-off-by: Thomas Huth <thuth@redhat.com> --- lib/libusb/usb-core.h | 1 + lib/libusb/usb-hub.c | 36 +++++++++++++++++++++++++++++------- lib/libusb/usb-xhci.c | 10 ++++++---- lib/libusb/usb-xhci.h | 3 +++ 4 files changed, 39 insertions(+), 11 deletions(-)