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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html