Re: about possible port reset when disconnect

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

 



On Fri, 4 Apr 2014, vichy wrote:

> >> 1. Platform-ehci Platform-ehci.0: port 1 reset error -110
> >>     the -110 is due to below handshake timeout.
> >>           retval = handshake(ehci, status_reg,
> >>                      PORT_RESET, 0, 1000);
> >>           if (retval != 0) {
> >>                  ehci_err (ehci, "port %d reset error %d\n",
> >>                      wIndex + 1, retval);
> >>                  goto error;
> >>              }
> >
> > Right -- although the handshake shouldn't time out.  That's a bug in
> > the hardware.
> if there is no connection, it is reasonable have return value as timeout.

No, it isn't.  That handshake call waits for up to 1000 microseconds 
for the controller to turn off the PORT_RESET bit, after the kernel 
told it to turn the bit off.  The controller should be able to turn the 
RESET bit off whether there is a connection or not.

> Why you think it is a bug in hardware?

The timeout error means that the kernel told the controller to turn off 
the PORT_RESET bit, and 1000 us later the bit was still on.  That's a 
hardware bug.

> >>  2. hub 4-0:1.0: hub_port_status failed (err = -32)
> >>      the -32 is due to below error label we set retval = -EPIPE
> >>      error:
> >>          /* "stall" on error */
> >>          retval = -EPIPE;
> >
> > But...  This will happen only the first time we get the port status.
> > After that, ehci->reset_done[wIndex] will be 0 and so handshake() won't
> > get called.
> >
> > hub_port_status() calls get_port_status(), which performs the operation
> > up to 3 times.  The first time it will fail with -EPIPE, but what about
> > the second time?
> >
> in hub_port_reset, there PORT_RESET_TRIES, 5 in right now definition
> to reset port.
> and ehci->reset_done[wIndex] will refilled the (jiffies + 50ms) when
> set port reset.
> if in all PORT_RESET_TRIES loops, there is no device connected.
> We will get -EPIPE all the time, right?

No.

> for (i = 0; i < PORT_RESET_TRIES; i++) {
>                 status = set_port_feature(hub->hdev, port1, (warm ?
>                                         USB_PORT_FEAT_BH_PORT_RESET :
>                                         USB_PORT_FEAT_RESET));
>                 if (status) {
>                         dev_err(hub->intfdev,
>                                         "cannot %sreset port %d (err = %d)\n",
>                                         warm ? "warm " : "", port1, status);
>                 } else {
>                         status = hub_port_wait_reset(hub, port1, udev, delay,
>                                                                 warm);

You didn't look at what hub_port_wait_reset does.  It calls 
hub_port_status, which calls get_port_status, which has a loop.

>                         if (status && status != -ENOTCONN)
>                                 dev_dbg(hub->intfdev,
>                                                 "port_wait_reset: err = %d\n",
>                                                 status);
>                 }

Alan Stern

--
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