Re: [Bug 42472] USB 3.0 port does not detect disconnect

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(Switching to email)

On Thu, Sep 08, 2011 at 12:04:06PM +0000, bugzilla-daemon@xxxxxxxxxxxxxxxxxxx wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=42472
> 
> 
> 
> 
> 
> --- Comment #2 from Harald Brennich <harald.brennich@xxxxxx>  2011-09-08 12:03:56 ---
> Hello Sarah,
> the Renesas (formerly NEC) uPD720200 USB 3.0 Host works fine with the following
> change in function hub_port_wait_reset:

Look, I really don't think this is the correct solution.  If a device
disconnects in the middle of a port reset, then we need to treat it as
if it's a new device.  Someone could have yanked out the device during
the port reset and inserted a new one.

Let me take a look at why the warm port reset patch didn't work and get
back to you next week, after I'm back from a conference.

Do other USB 3.0 devices work under this host controller?  Is it just
this device?

Sarah Sharp

> Current version:
> static int hub_port_wait_reset(struct usb_hub *hub, int port1,
>                 struct usb_device *udev, unsigned int delay)
> {
>     int delay_time, ret;
>     u16 portstatus;
>     u16 portchange;
> 
>     for (delay_time = 0;
>             delay_time < HUB_RESET_TIMEOUT;
>             delay_time += delay) {
>         /* wait to give the device a chance to reset */
>         msleep(delay);
> 
>         /* read and decode port status */
>         ret = hub_port_status(hub, port1, &portstatus, &portchange);
>         if (ret < 0)
>             return ret;
> 
>         /* Device went away? */
>         if (!(portstatus & USB_PORT_STAT_CONNECTION))
>             return -ENOTCONN;
> 
>           /* bomb out completely if the connection bounced */
>           if ((portchange & USB_PORT_STAT_C_CONNECTION))
>             return -ENOTCONN;
> 
>         /* if we`ve finished resetting, then break out of the loop */
>         if (!(portstatus & USB_PORT_STAT_RESET) &&
>             (portstatus & USB_PORT_STAT_ENABLE)) {
>           if (hub_is_wusb(hub))
>             udev->speed = USB_SPEED_WIRELESS;
>           else if (hub_is_superspeed(hub->hdev))
>             udev->speed = USB_SPEED_SUPER;
>           else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
>             udev->speed = USB_SPEED_HIGH;
>           else if (portstatus & USB_PORT_STAT_LOW_SPEED)
>             udev->speed = USB_SPEED_LOW;
>           else
>             udev->speed = USB_SPEED_FULL;
>           return 0;
>         }
> 
>         /* switch to the long delay after two short delay failures */
>         if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
>             delay = HUB_LONG_RESET_TIME;
> 
>         dev_dbg (hub->intfdev,
>             "port %d not reset yet, waiting %dms\n",
>             port1, delay);
>     }
> }
> 
> Modified version:
> In the first modification (see report 41752), the portchange was ignored. Then
> the external drive could be used, but the disconnect was not detected. This is
> now resolved with checking portstatus for USB_PORT_STAT_C_CONNECTION and
> USB_PORT_FEAT_C_PORT_LINK_STATE (the flags set by the uPD720200).
> Is there a part in the USB spec that disallows disconnecting a port by the hub
> during RESET? Or do you have another solution?
> 
> static int hub_port_wait_reset(struct usb_hub *hub, int port1,
>                 struct usb_device *udev, unsigned int delay)
> {
>     int delay_time, ret;
>     u16 portstatus;
>     u16 portchange;
> 
>     for (delay_time = 0;
>             delay_time < HUB_RESET_TIMEOUT;
>             delay_time += delay) {
>         /* wait to give the device a chance to reset */
>         msleep(delay);
> 
>         /* read and decode port status */
>         ret = hub_port_status(hub, port1, &portstatus, &portchange);
>         if (ret < 0)
>             return ret;
> 
>         /* if we`ve finished resetting, then break out of the loop */
>         if (!(portstatus & USB_PORT_STAT_RESET) &&
>             (portstatus & USB_PORT_STAT_ENABLE)) {
>           /* ADDED 2011.09.08 BRE BEGIN */
>           /* Device went away? */
>           if (!(portstatus & USB_PORT_STAT_CONNECTION))
>             return -ENOTCONN;
>           if (portchange & USB_PORT_STAT_C_CONNECTION) 
>             clear_port_feature(hub->hdev, port1,
>                     USB_PORT_FEAT_C_CONNECTION);
>           if (portchange & USB_PORT_STAT_C_LINK_STATE) 
>             clear_port_feature(hub->hdev, port1,
>                     USB_PORT_FEAT_C_PORT_LINK_STATE);
>           /* ADDED 2011.09.08 BRE END */
>           if (hub_is_wusb(hub))
>             udev->speed = USB_SPEED_WIRELESS;
>           else if (hub_is_superspeed(hub->hdev))
>             udev->speed = USB_SPEED_SUPER;
>           else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
>             udev->speed = USB_SPEED_HIGH;
>           else if (portstatus & USB_PORT_STAT_LOW_SPEED)
>             udev->speed = USB_SPEED_LOW;
>           else
>             udev->speed = USB_SPEED_FULL;
>           return 0;
>         }
> 
>         /* switch to the long delay after two short delay failures */
>         if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
>             delay = HUB_LONG_RESET_TIME;
> 
>         dev_dbg (hub->intfdev,
>             "port %d not reset yet, waiting %dms\n",
>             port1, delay);
>     }
> 
>     /* ADDED 2011.09.05 BRE BEGIN */
>     /* Device went away? */
>     if (!(portstatus & USB_PORT_STAT_CONNECTION))
>       return -ENOTCONN;
>     /* bomb out completely if the connection bounced */
>     if ((portchange & USB_PORT_STAT_C_CONNECTION))
>       return -ENOTCONN;
>     /* ADDED 2011.09.05 BRE END */
>     return -EBUSY;
> }
> 
> -- 
> Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
> ------- You are receiving this mail because: -------
> You are the assignee for the bug.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux