summaryrefslogtreecommitdiff
path: root/drivers/usb/core/hub.c
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/hub.c
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/hub.c')
-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)
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 */