aboutsummaryrefslogtreecommitdiff
path: root/lib/libusb
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2016-08-02 11:19:42 +0200
committerAlexey Kardashevskiy <aik@ozlabs.ru>2016-08-03 13:48:18 +1000
commitcf7963a12c7fb516a1addcba40d78977d61fbcc5 (patch)
tree6ba78d0fd596cdd5c4e1947d2961059266c373e2 /lib/libusb
parentf1d7dc911c0203f91af5dfbc462106623c6b8a9b (diff)
downloadSLOF-cf7963a12c7fb516a1addcba40d78977d61fbcc5.zip
SLOF-cf7963a12c7fb516a1addcba40d78977d61fbcc5.tar.gz
SLOF-cf7963a12c7fb516a1addcba40d78977d61fbcc5.tar.bz2
usb: Initialize USB3 devices on a hub and keep track of hub topology
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> Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Diffstat (limited to 'lib/libusb')
-rw-r--r--lib/libusb/usb-core.h1
-rw-r--r--lib/libusb/usb-hub.c36
-rw-r--r--lib/libusb/usb-xhci.c10
-rw-r--r--lib/libusb/usb-xhci.h3
4 files changed, 39 insertions, 11 deletions
diff --git a/lib/libusb/usb-core.h b/lib/libusb/usb-core.h
index a35df34..070aab5 100644
--- a/lib/libusb/usb-core.h
+++ b/lib/libusb/usb-core.h
@@ -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;
diff --git a/lib/libusb/usb-hub.c b/lib/libusb/usb-hub.c
index bb8a309..5f56630 100644
--- a/lib/libusb/usb-hub.c
+++ b/lib/libusb/usb-hub.c
@@ -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);
}
}
diff --git a/lib/libusb/usb-xhci.c b/lib/libusb/usb-xhci.c
index 931d779..f3de6fb 100644
--- a/lib/libusb/usb-xhci.c
+++ b/lib/libusb/usb-xhci.c
@@ -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");
}
}
diff --git a/lib/libusb/usb-xhci.h b/lib/libusb/usb-xhci.h
index 793f18c..0fd2d8e 100644
--- a/lib/libusb/usb-xhci.h
+++ b/lib/libusb/usb-xhci.h
@@ -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 */