aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 84c1897188d..27115b45edc 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -758,6 +758,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
clear_port_feature(hdev, port1,
USB_PORT_FEAT_ENABLE);
portstatus &= ~USB_PORT_STAT_ENABLE;
+ } else {
+ /* Pretend that power was lost for USB3 devs */
+ portstatus &= ~USB_PORT_STAT_ENABLE;
}
}
@@ -2594,16 +2597,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);
@@ -2860,13 +2861,16 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
else
i = udev->descriptor.bMaxPacketSize0;
if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
- if (udev->speed != USB_SPEED_FULL ||
+ if (udev->speed == USB_SPEED_LOW ||
!(i == 8 || i == 16 || i == 32 || i == 64)) {
- dev_err(&udev->dev, "ep0 maxpacket = %d\n", i);
+ dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);
retval = -EMSGSIZE;
goto fail;
}
- dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+ if (udev->speed == USB_SPEED_FULL)
+ dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+ else
+ dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
usb_ep0_reinit(udev);
}
@@ -3097,16 +3101,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 */
@@ -3629,7 +3634,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
}
if (!parent_hdev) {
- /* this requires hcd-specific logic; see OHCI hc_restart() */
+ /* this requires hcd-specific logic; see ohci_restart() */
dev_dbg(&udev->dev, "%s for root hub!\n", __func__);
return -EISDIR;
}