On Mon, 11 Jul 2016: Alan Stern wrote:

> On Mon, 11 Jul 2016, Huang, Huki wrote:

> > When end user inserts a usb3 device and put dut to s3.

> What does "dut" mean?

DUT : Device under test

> > Then hotplug the usb3 disk under s3.

> Do you mean that the device is unplugged and the USB disk then is plugged 
> into the same port?  Or do you mean that the device remains plugged in and 
> the disk is plugged into a different port?

Yes, the USB disk is unplugged and plugged on the same port when the system 
under s3

> > The device will be lost upon resuming from s3.

> If the device is unplugged then it _should_ be lost.

> > There is a corner case that the hub->change_bits for the usb3 port is 
> > not set when usb port change event happens.

> Under what conditions does this corner case occur?

The USB disk is unplugged and plugged on the same port under s3.

> > This will cause hub driver ignore the device enumeration in the end of 
> > port_event in hub.c
> >  
> > Signed-off-by: huki.hu...@intel.com
> > ---
> >  drivers/usb/core/hub.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 
> > bee1351..859adcb 100644
> > --- a/drivers/usb/core/hub.c
> > +++ b/drivers/usb/core/hub.c
> > @@ -4747,6 +4747,7 @@ static void hub_port_connect(struct usb_hub *hub, int 
> > port1, u16 portstatus,
> >                          if (hcd->usb_phy && !hdev->parent)
> >                                          
> >usb_phy_notify_disconnect(hcd->usb_phy, udev->speed);
> >                          usb_disconnect(&port_dev->child);
> > +                      set_bit(port1, hub->change_bits);

> Why is this needed?  The only reason for setting hub->change_bits is to tell 
> hub_event() that it needs to call port_event() and to tell
> port_event() that it needs to call hub_port_connect_change().  Once
> hub_port_connect_change() is running, there is no reason to set 
> hub->change_bits.

When the USB disk is unplugged and plugged on the same port under s3.
You can see a series of disconnect/connect events happen.
There is a chance driver receives a port_event but not enumerate device due to 
change_bits is not set.

When usb_disconnect is called, it doesn't set_bit(port1, hub->change_bits);
Then port_event is called again very soon after the above usb_disconnect is 
called.

In the end of the port_event function.
The connect_change is not true so that device is not enumerated.
       if (connect_change)
           hub_port_connect_change(hub, port1, portstatus, portchange);

> >          }
> >  
> >          /* We can forget about a "removed" device when there's a physical

> Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to