aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-04-27 22:57:26 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:49 -0400
commitc6515272b858742962c1de0f3bf497a048b9abd7 (patch)
tree5172d9b646fa5e364b5b35004f10628aed934a71
parent0f2a79300a1471cf92ab43af165ea13555c8b0a5 (diff)
USB: Support for addressing a USB device under xHCI
Add host controller driver API and a slot_id variable to struct usb_device. This allows the xHCI host controller driver to ask the hardware to allocate a slot for the device when a struct usb_device is allocated. The slot needs to be allocated at that point because the hardware can run out of internal resources, and we want to know that very early in the device connection process. Don't call this new API for root hubs, since they aren't real devices. Add HCD API to let the host controller choose the device address. This is especially important for xHCI hardware running in a virtualized environment. The guests running under the VM don't need to know which addresses on the bus are taken, because the hardware picks the address for them. Announce SuperSpeed USB devices after the address has been assigned by the hardware. Don't use the new get descriptor/set address scheme with xHCI. Unless special handling is done in the host controller driver, the xHC can't issue control transfers before you set the device address. Support for the older addressing scheme will be added when the xHCI driver supports the Block Set Address Request (BSR) flag in the Address Device command. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/hcd.h8
-rw-r--r--drivers/usb/core/hub.c74
-rw-r--r--drivers/usb/core/usb.c14
-rw-r--r--include/linux/usb.h2
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
231extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); 239extern 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 */
1332static void choose_address(struct usb_device *udev) 1337static 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);
2400static int hub_set_address(struct usb_device *udev, int devnum) 2408static 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);
184static void usb_release_dev(struct device *dev) 184static 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