aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-10-14 10:22:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:22:12 -0400
commitc8d4af8e2af12cd4835ba5c4b54bdafe9deda71a (patch)
treee89c7c700bfe5022eaba3508a818a51717bbd12d /drivers/usb/core
parentf0615c45ce5feb141c1172480c5198d4b8d25436 (diff)
USB: core: use kernel assigned address for devices under xHCI
xHCI driver uses hardware assigned device address. This may cause device address conflict in certain cases. Use kernel assigned address for devices under xHCI. Store the xHC assigned address locally in xHCI driver. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/hub.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5da546c4fd79..f07ab71859dd 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2594,16 +2594,14 @@ static int hub_set_address(struct usb_device *udev, int devnum)
2594 return 0; 2594 return 0;
2595 if (udev->state != USB_STATE_DEFAULT) 2595 if (udev->state != USB_STATE_DEFAULT)
2596 return -EINVAL; 2596 return -EINVAL;
2597 if (hcd->driver->address_device) { 2597 if (hcd->driver->address_device)
2598 retval = hcd->driver->address_device(hcd, udev); 2598 retval = hcd->driver->address_device(hcd, udev);
2599 } else { 2599 else
2600 retval = usb_control_msg(udev, usb_sndaddr0pipe(), 2600 retval = usb_control_msg(udev, usb_sndaddr0pipe(),
2601 USB_REQ_SET_ADDRESS, 0, devnum, 0, 2601 USB_REQ_SET_ADDRESS, 0, devnum, 0,
2602 NULL, 0, USB_CTRL_SET_TIMEOUT); 2602 NULL, 0, USB_CTRL_SET_TIMEOUT);
2603 if (retval == 0)
2604 update_address(udev, devnum);
2605 }
2606 if (retval == 0) { 2603 if (retval == 0) {
2604 update_address(udev, devnum);
2607 /* Device now using proper address. */ 2605 /* Device now using proper address. */
2608 usb_set_device_state(udev, USB_STATE_ADDRESS); 2606 usb_set_device_state(udev, USB_STATE_ADDRESS);
2609 usb_ep0_reinit(udev); 2607 usb_ep0_reinit(udev);
@@ -3097,16 +3095,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3097 udev->speed = USB_SPEED_UNKNOWN; 3095 udev->speed = USB_SPEED_UNKNOWN;
3098 3096
3099 /* 3097 /*
3100 * xHCI needs to issue an address device command later 3098 * Set the address.
3101 * in the hub_port_init sequence for SS/HS/FS/LS devices. 3099 * Note xHCI needs to issue an address device command later
3100 * in the hub_port_init sequence for SS/HS/FS/LS devices,
3101 * and xHC will assign an address to the device. But use
3102 * kernel assigned address here, to avoid any address conflict
3103 * issue.
3102 */ 3104 */
3103 if (!(hcd->driver->flags & HCD_USB3)) { 3105 choose_address(udev);
3104 /* set the address */ 3106 if (udev->devnum <= 0) {
3105 choose_address(udev); 3107 status = -ENOTCONN; /* Don't retry */
3106 if (udev->devnum <= 0) { 3108 goto loop;
3107 status = -ENOTCONN; /* Don't retry */
3108 goto loop;
3109 }
3110 } 3109 }
3111 3110
3112 /* reset (non-USB 3.0 devices) and get descriptor */ 3111 /* reset (non-USB 3.0 devices) and get descriptor */