summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/usb_subr.c')
-rw-r--r--sys/dev/usb/usb_subr.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 905a86c..fa21645 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -1046,13 +1046,14 @@ usbd_status
usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
int speed, int port, struct usbd_port *up)
{
- usbd_device_handle dev;
+ usbd_device_handle dev, adev;
struct usbd_device *hub;
usb_device_descriptor_t *dd;
usb_port_status_t ps;
usbd_status err;
int addr;
int i;
+ int p;
DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
bus, port, depth, speed));
@@ -1086,11 +1087,27 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
dev->depth = depth;
dev->powersrc = up;
dev->myhub = up->parent;
- for (hub = up->parent;
+
+ up->device = dev;
+
+ /* Locate port on upstream high speed hub */
+ for (adev = dev, hub = up->parent;
hub != NULL && hub->speed != USB_SPEED_HIGH;
- hub = hub->myhub)
+ adev = hub, hub = hub->myhub)
;
- dev->myhighhub = hub;
+ if (hub) {
+ for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
+ if (hub->hub->ports[p].device == adev) {
+ dev->myhsport = &hub->hub->ports[p];
+ goto found;
+ }
+ }
+ panic("usbd_new_device: cannot find HS port\n");
+ found:
+ DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
+ } else {
+ dev->myhsport = NULL;
+ }
dev->speed = speed;
dev->langid = USBD_NOLANG;
dev->cookie.cookie = ++usb_cookie_no;
@@ -1103,8 +1120,6 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
return (err);
}
- up->device = dev;
-
/* Set the address. Do this early; some devices need that. */
/* Try a few times in case the device is slow (i.e. outside specs.) */
DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
@@ -1228,8 +1243,8 @@ usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
if (dev->default_pipe != NULL)
usbd_kill_pipe(dev->default_pipe);
- up->device = 0;
- dev->bus->devices[dev->address] = 0;
+ up->device = NULL;
+ dev->bus->devices[dev->address] = NULL;
free(dev, M_USB);
}
OpenPOWER on IntegriCloud