aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-10-14 07:22:51 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 10:22:12 -0700
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 5da546c4fd7..f07ab71859d 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)
return 0;
if (udev->state != USB_STATE_DEFAULT)
return -EINVAL;
- if (hcd->driver->address_device) {
+ if (hcd->driver->address_device)
retval = hcd->driver->address_device(hcd, udev);
- } else {
+ else
retval = usb_control_msg(udev, usb_sndaddr0pipe(),
USB_REQ_SET_ADDRESS, 0, devnum, 0,
NULL, 0, USB_CTRL_SET_TIMEOUT);
- if (retval == 0)
- update_address(udev, devnum);
- }
if (retval == 0) {
+ update_address(udev, devnum);
/* Device now using proper address. */
usb_set_device_state(udev, USB_STATE_ADDRESS);
usb_ep0_reinit(udev);
@@ -3097,16 +3095,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
udev->speed = USB_SPEED_UNKNOWN;
/*
- * xHCI needs to issue an address device command later
- * in the hub_port_init sequence for SS/HS/FS/LS devices.
+ * Set the address.
+ * Note xHCI needs to issue an address device command later
+ * in the hub_port_init sequence for SS/HS/FS/LS devices,
+ * and xHC will assign an address to the device. But use
+ * kernel assigned address here, to avoid any address conflict
+ * issue.
*/
- if (!(hcd->driver->flags & HCD_USB3)) {
- /* set the address */
- choose_address(udev);
- if (udev->devnum <= 0) {
- status = -ENOTCONN; /* Don't retry */
- goto loop;
- }
+ choose_address(udev);
+ if (udev->devnum <= 0) {
+ status = -ENOTCONN; /* Don't retry */
+ goto loop;
}
/* reset (non-USB 3.0 devices) and get descriptor */