diff options
-rw-r--r-- | drivers/usb/core/hcd.h | 8 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 74 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 14 | ||||
-rw-r--r-- | include/linux/usb.h | 2 |
4 files changed, 78 insertions, 20 deletions
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 4f6ee60d97c6..ae6d9db41ca9 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -226,6 +226,14 @@ struct hc_driver { | |||
226 | void (*relinquish_port)(struct usb_hcd *, int); | 226 | void (*relinquish_port)(struct usb_hcd *, int); |
227 | /* has a port been handed over to a companion? */ | 227 | /* has a port been handed over to a companion? */ |
228 | int (*port_handed_over)(struct usb_hcd *, int); | 228 | int (*port_handed_over)(struct usb_hcd *, int); |
229 | |||
230 | /* xHCI specific functions */ | ||
231 | /* Called by usb_alloc_dev to alloc HC device structures */ | ||
232 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); | ||
233 | /* Called by usb_release_dev to free HC device structures */ | ||
234 | void (*free_dev)(struct usb_hcd *, struct usb_device *); | ||
235 | /* Returns the hardware-chosen device address */ | ||
236 | int (*address_device)(struct usb_hcd *, struct usb_device *udev); | ||
229 | }; | 237 | }; |
230 | 238 | ||
231 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | 239 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 3c28bde6cbd5..2af3b4f06054 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1328,6 +1328,11 @@ EXPORT_SYMBOL_GPL(usb_set_device_state); | |||
1328 | * 0 is reserved by USB for default address; (b) Linux's USB stack | 1328 | * 0 is reserved by USB for default address; (b) Linux's USB stack |
1329 | * uses always #1 for the root hub of the controller. So USB stack's | 1329 | * uses always #1 for the root hub of the controller. So USB stack's |
1330 | * port #1, which is wusb virtual-port #0 has address #2. | 1330 | * port #1, which is wusb virtual-port #0 has address #2. |
1331 | * | ||
1332 | * Devices connected under xHCI are not as simple. The host controller | ||
1333 | * supports virtualization, so the hardware assigns device addresses and | ||
1334 | * the HCD must setup data structures before issuing a set address | ||
1335 | * command to the hardware. | ||
1331 | */ | 1336 | */ |
1332 | static void choose_address(struct usb_device *udev) | 1337 | static void choose_address(struct usb_device *udev) |
1333 | { | 1338 | { |
@@ -1647,6 +1652,9 @@ int usb_new_device(struct usb_device *udev) | |||
1647 | err = usb_configure_device(udev); /* detect & probe dev/intfs */ | 1652 | err = usb_configure_device(udev); /* detect & probe dev/intfs */ |
1648 | if (err < 0) | 1653 | if (err < 0) |
1649 | goto fail; | 1654 | goto fail; |
1655 | dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n", | ||
1656 | udev->devnum, udev->bus->busnum, | ||
1657 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); | ||
1650 | /* export the usbdev device-node for libusb */ | 1658 | /* export the usbdev device-node for libusb */ |
1651 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, | 1659 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, |
1652 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); | 1660 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); |
@@ -2400,19 +2408,29 @@ EXPORT_SYMBOL_GPL(usb_ep0_reinit); | |||
2400 | static int hub_set_address(struct usb_device *udev, int devnum) | 2408 | static int hub_set_address(struct usb_device *udev, int devnum) |
2401 | { | 2409 | { |
2402 | int retval; | 2410 | int retval; |
2411 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
2403 | 2412 | ||
2404 | if (devnum <= 1) | 2413 | /* |
2414 | * The host controller will choose the device address, | ||
2415 | * instead of the core having chosen it earlier | ||
2416 | */ | ||
2417 | if (!hcd->driver->address_device && devnum <= 1) | ||
2405 | return -EINVAL; | 2418 | return -EINVAL; |
2406 | if (udev->state == USB_STATE_ADDRESS) | 2419 | if (udev->state == USB_STATE_ADDRESS) |
2407 | return 0; | 2420 | return 0; |
2408 | if (udev->state != USB_STATE_DEFAULT) | 2421 | if (udev->state != USB_STATE_DEFAULT) |
2409 | return -EINVAL; | 2422 | return -EINVAL; |
2410 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | 2423 | if (hcd->driver->address_device) { |
2411 | USB_REQ_SET_ADDRESS, 0, devnum, 0, | 2424 | retval = hcd->driver->address_device(hcd, udev); |
2412 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 2425 | } else { |
2426 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | ||
2427 | USB_REQ_SET_ADDRESS, 0, devnum, 0, | ||
2428 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
2429 | if (retval == 0) | ||
2430 | update_address(udev, devnum); | ||
2431 | } | ||
2413 | if (retval == 0) { | 2432 | if (retval == 0) { |
2414 | /* Device now using proper address. */ | 2433 | /* Device now using proper address. */ |
2415 | update_address(udev, devnum); | ||
2416 | usb_set_device_state(udev, USB_STATE_ADDRESS); | 2434 | usb_set_device_state(udev, USB_STATE_ADDRESS); |
2417 | usb_ep0_reinit(udev); | 2435 | usb_ep0_reinit(udev); |
2418 | } | 2436 | } |
@@ -2525,10 +2543,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2525 | break; | 2543 | break; |
2526 | default: speed = "?"; break; | 2544 | default: speed = "?"; break; |
2527 | } | 2545 | } |
2528 | dev_info (&udev->dev, | 2546 | if (udev->speed != USB_SPEED_SUPER) |
2529 | "%s %s speed %sUSB device using %s and address %d\n", | 2547 | dev_info(&udev->dev, |
2530 | (udev->config) ? "reset" : "new", speed, type, | 2548 | "%s %s speed %sUSB device using %s and address %d\n", |
2531 | udev->bus->controller->driver->name, devnum); | 2549 | (udev->config) ? "reset" : "new", speed, type, |
2550 | udev->bus->controller->driver->name, devnum); | ||
2532 | 2551 | ||
2533 | /* Set up TT records, if needed */ | 2552 | /* Set up TT records, if needed */ |
2534 | if (hdev->tt) { | 2553 | if (hdev->tt) { |
@@ -2553,7 +2572,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2553 | * value. | 2572 | * value. |
2554 | */ | 2573 | */ |
2555 | for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { | 2574 | for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { |
2556 | if (USE_NEW_SCHEME(retry_counter)) { | 2575 | /* |
2576 | * An xHCI controller cannot send any packets to a device until | ||
2577 | * a set address command successfully completes. | ||
2578 | */ | ||
2579 | if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) { | ||
2557 | struct usb_device_descriptor *buf; | 2580 | struct usb_device_descriptor *buf; |
2558 | int r = 0; | 2581 | int r = 0; |
2559 | 2582 | ||
@@ -2619,7 +2642,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2619 | * unauthorized address in the Connect Ack sequence; | 2642 | * unauthorized address in the Connect Ack sequence; |
2620 | * authorization will assign the final address. | 2643 | * authorization will assign the final address. |
2621 | */ | 2644 | */ |
2622 | if (udev->wusb == 0) { | 2645 | if (udev->wusb == 0) { |
2623 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { | 2646 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { |
2624 | retval = hub_set_address(udev, devnum); | 2647 | retval = hub_set_address(udev, devnum); |
2625 | if (retval >= 0) | 2648 | if (retval >= 0) |
@@ -2632,13 +2655,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2632 | devnum, retval); | 2655 | devnum, retval); |
2633 | goto fail; | 2656 | goto fail; |
2634 | } | 2657 | } |
2658 | if (udev->speed == USB_SPEED_SUPER) { | ||
2659 | devnum = udev->devnum; | ||
2660 | dev_info(&udev->dev, | ||
2661 | "%s SuperSpeed USB device using %s and address %d\n", | ||
2662 | (udev->config) ? "reset" : "new", | ||
2663 | udev->bus->controller->driver->name, devnum); | ||
2664 | } | ||
2635 | 2665 | ||
2636 | /* cope with hardware quirkiness: | 2666 | /* cope with hardware quirkiness: |
2637 | * - let SET_ADDRESS settle, some device hardware wants it | 2667 | * - let SET_ADDRESS settle, some device hardware wants it |
2638 | * - read ep0 maxpacket even for high and low speed, | 2668 | * - read ep0 maxpacket even for high and low speed, |
2639 | */ | 2669 | */ |
2640 | msleep(10); | 2670 | msleep(10); |
2641 | if (USE_NEW_SCHEME(retry_counter)) | 2671 | if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) |
2642 | break; | 2672 | break; |
2643 | } | 2673 | } |
2644 | 2674 | ||
@@ -2877,13 +2907,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2877 | udev->level = hdev->level + 1; | 2907 | udev->level = hdev->level + 1; |
2878 | udev->wusb = hub_is_wusb(hub); | 2908 | udev->wusb = hub_is_wusb(hub); |
2879 | 2909 | ||
2880 | /* set the address */ | ||
2881 | choose_address(udev); | ||
2882 | if (udev->devnum <= 0) { | ||
2883 | status = -ENOTCONN; /* Don't retry */ | ||
2884 | goto loop; | ||
2885 | } | ||
2886 | |||
2887 | /* | 2910 | /* |
2888 | * USB 3.0 devices are reset automatically before the connect | 2911 | * USB 3.0 devices are reset automatically before the connect |
2889 | * port status change appears, and the root hub port status | 2912 | * port status change appears, and the root hub port status |
@@ -2901,6 +2924,19 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2901 | else | 2924 | else |
2902 | udev->speed = USB_SPEED_UNKNOWN; | 2925 | udev->speed = USB_SPEED_UNKNOWN; |
2903 | 2926 | ||
2927 | /* | ||
2928 | * xHCI needs to issue an address device command later | ||
2929 | * in the hub_port_init sequence for SS/HS/FS/LS devices. | ||
2930 | */ | ||
2931 | if (!(hcd->driver->flags & HCD_USB3)) { | ||
2932 | /* set the address */ | ||
2933 | choose_address(udev); | ||
2934 | if (udev->devnum <= 0) { | ||
2935 | status = -ENOTCONN; /* Don't retry */ | ||
2936 | goto loop; | ||
2937 | } | ||
2938 | } | ||
2939 | |||
2904 | /* reset (non-USB 3.0 devices) and get descriptor */ | 2940 | /* reset (non-USB 3.0 devices) and get descriptor */ |
2905 | status = hub_port_init(hub, udev, port1, i); | 2941 | status = hub_port_init(hub, udev, port1, i); |
2906 | if (status < 0) | 2942 | if (status < 0) |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index f026991d0bdf..55b8d3a22d26 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -184,11 +184,16 @@ EXPORT_SYMBOL_GPL(usb_find_interface); | |||
184 | static void usb_release_dev(struct device *dev) | 184 | static void usb_release_dev(struct device *dev) |
185 | { | 185 | { |
186 | struct usb_device *udev; | 186 | struct usb_device *udev; |
187 | struct usb_hcd *hcd; | ||
187 | 188 | ||
188 | udev = to_usb_device(dev); | 189 | udev = to_usb_device(dev); |
190 | hcd = bus_to_hcd(udev->bus); | ||
189 | 191 | ||
190 | usb_destroy_configuration(udev); | 192 | usb_destroy_configuration(udev); |
191 | usb_put_hcd(bus_to_hcd(udev->bus)); | 193 | /* Root hubs aren't real devices, so don't free HCD resources */ |
194 | if (hcd->driver->free_dev && udev->parent) | ||
195 | hcd->driver->free_dev(hcd, udev); | ||
196 | usb_put_hcd(hcd); | ||
192 | kfree(udev->product); | 197 | kfree(udev->product); |
193 | kfree(udev->manufacturer); | 198 | kfree(udev->manufacturer); |
194 | kfree(udev->serial); | 199 | kfree(udev->serial); |
@@ -348,6 +353,13 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
348 | kfree(dev); | 353 | kfree(dev); |
349 | return NULL; | 354 | return NULL; |
350 | } | 355 | } |
356 | /* Root hubs aren't true devices, so don't allocate HCD resources */ | ||
357 | if (usb_hcd->driver->alloc_dev && parent && | ||
358 | !usb_hcd->driver->alloc_dev(usb_hcd, dev)) { | ||
359 | usb_put_hcd(bus_to_hcd(bus)); | ||
360 | kfree(dev); | ||
361 | return NULL; | ||
362 | } | ||
351 | 363 | ||
352 | device_initialize(&dev->dev); | 364 | device_initialize(&dev->dev); |
353 | dev->dev.bus = &usb_bus_type; | 365 | dev->dev.bus = &usb_bus_type; |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 2b380a16c62f..475cb75cc378 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -420,6 +420,7 @@ struct usb_tt; | |||
420 | * @skip_sys_resume: skip the next system resume | 420 | * @skip_sys_resume: skip the next system resume |
421 | * @wusb_dev: if this is a Wireless USB device, link to the WUSB | 421 | * @wusb_dev: if this is a Wireless USB device, link to the WUSB |
422 | * specific data for the device. | 422 | * specific data for the device. |
423 | * @slot_id: Slot ID assigned by xHCI | ||
423 | * | 424 | * |
424 | * Notes: | 425 | * Notes: |
425 | * Usbcore drivers should not set usbdev->state directly. Instead use | 426 | * Usbcore drivers should not set usbdev->state directly. Instead use |
@@ -504,6 +505,7 @@ struct usb_device { | |||
504 | unsigned skip_sys_resume:1; | 505 | unsigned skip_sys_resume:1; |
505 | #endif | 506 | #endif |
506 | struct wusb_dev *wusb_dev; | 507 | struct wusb_dev *wusb_dev; |
508 | int slot_id; | ||
507 | }; | 509 | }; |
508 | #define to_usb_device(d) container_of(d, struct usb_device, dev) | 510 | #define to_usb_device(d) container_of(d, struct usb_device, dev) |
509 | 511 | ||