]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/usb/core/hub.c
Merge branch 'master' into csb1725
[mv-sheeva.git] / drivers / usb / core / hub.c
index 84c1897188d274bff4b5ade992f45ef34aa35a01..27115b45edc51fa4462147077be9b3de36f6142a 100644 (file)
@@ -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;
        }