Re: problem with Roseweil eusb3 enclosure

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

 



On Thu, 1 Nov 2012, Sarah Sharp wrote:

> On Thu, Nov 01, 2012 at 03:46:37PM -0400, Alan Stern wrote:
> > On Thu, 1 Nov 2012, Sarah Sharp wrote:
> > 
> > > Alan, can you take a look at the patch and see what I can do in the case
> > > where five warm port resets fail?  I think it's a pretty unlikely
> > > scenario, but if you have a good solution, I'm all ears.
> > 
> > Hmmm.  Overall I'm not really sure about the logic in that routine.
> > It would make more sense for the decision about whether to issue a warm 
> > vs. a hot reset to be made by the caller.
> 
> Are you talking about this bit of code in hub_port_wait_reset?
> 
>                 if (!warm) {
...
>                                 ret = hub_port_reset(hub, port1,
>                                                 udev, HUB_BH_RESET_TIME,
>                                                 true);

> If so, then yes, I agree that the decision to issue a warm reset should
> probably be made in hub_port_reset() instead.
> 
> Actually, there's a couple other issues I see with warm reset.
> 
> First, under USB 3.0 hubs (and roothubs), a failed hot reset will
> automatically move to a warm reset.  That means the warm reset change
> bit can be set if we only asked for a hot reset.
> hub_port_finish_reset() assumes that only the hot reset change bit needs
> to be cleared if warm is false, but it may also need to clear the warm
> reset change bit.  This needs to be fixed, or we can lose port status
> change events.

That should go away once hub_port_wait_reset stops doing its own warm 
resets.

> Second, this bit of code in hub_port_finish_reset() looks wrong:
> 
>         case 0:
>                 if (!warm) {
>                         struct usb_hcd *hcd;
>                         /* TRSTRCY = 10 ms; plus some extra */
>                         msleep(10 + 40);
>                         update_devnum(udev, 0);
>                         hcd = bus_to_hcd(udev->bus);
>                         if (hcd->driver->reset_device) {
>                                 *status = hcd->driver->reset_device(hcd, udev);
>                                 if (*status < 0) {
>                                         dev_err(&udev->dev, "Cannot reset "
>                                                         "HCD device state\n");
>                                         break;
>                                 }
>                         }
>                 }
> 
> Why wouldn't we want to notify the xHCI driver that the device was reset
> if we issued a warm reset?  Maybe that's due to the code in
> hub_port_wait_reset() that initiates a warm reset when the normal reset
> fails?  hub_port_finish_reset() would get called twice with the current
> code structure, and I think this code snippet is trying to work around
> the fact that we can only notify the xHC once that the device has been
> reset.  Once the Reset Device command has completed, the xHC will move
> its internal device state to Default, and subsequent Reset Device
> commands will fail with a context error until the device is
> re-addressed.
> 
> I'm actually not sure we even want to break on a Reset Device command
> failure.  If we do, we never clear the port reset change bits (warm or
> normal), which would cause port status change events to be lost.

Straightening out the overall logic should help a lot.  And yes, when 
an attempted reset is finished (successfully or not), the reset-change 
bits always need to be cleared.

> > Anyway, if five resets in a row all fail then we should do our best to
> > ignore the device.  Let the user unplug it and try again.  Will this
> > patch do that?
> 
> I think the patch will leave the port in SS.Inactive (the old code would
> too).  The port will stay in that state (even when a device is
> connected) until either the USB core issues a warm port reset, or the
> port is disabled.  But if we disable a SuperSpeed port, we don't get
> connect events until we set the link state to RxDetect.  So there's
> basically no way to get an automatic notification of a device connect
> when the port goes into this state.

Even if the device is physically unplugged and plugged back in?

> Can we set a timer to kick khubd after some amount of time (30 seconds?)
> and make hub_events check for ports in SS.Inactive even if none of the
> change bits are set?

I don't like that idea.  It would be much simpler to put the port back 
into a useful state.  For example, disable the port, then put it into 
RxDetect, then clear any change bits, and set the port's bit in 
hub->removed_bits.

(hub->removed_bits was meant to help implement Windows' "Safely remove
hardware" feature.  When a port's bit is set, khubd will ignore any
device attached to that port until it sees a connect-change.)

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