Re: [PATCH 1/2] usb: gadget: composite: Race between disconnect/unbind and setup

2012-07-09 Thread Alan Stern
On Sun, 8 Jul 2012, Kevin Cernekee wrote:

 On Sun, Jul 8, 2012 at 5:33 PM, Alan Stern st...@rowland.harvard.edu wrote:
  On Sun, 8 Jul 2012, Kevin Cernekee wrote:
 
  usb_gadget_remove_driver() runs through a four-step sequence to shut down
  the gadget driver.  For the case of a composite gadget + at91 UDC, this
  would look like:
 
      udc-driver-disconnect(udc-gadget);          // 
  composite_disconnect()
      usb_gadget_disconnect(udc-gadget);            // at91_pullup(gadget, 
  0)
      udc-driver-unbind(udc-gadget);              // composite_unbind()
      usb_gadget_udc_stop(udc-gadget, udc-driver); // at91_stop()
 
  composite_disconnect() says:
 
      if (cdev-config)
          reset_config(cdev);
 
  reset_config() sets cdev-config to NULL.  composite_unbind() later tests
  for this:
 
      WARN_ON(cdev-config);
 
  But SETUP packets may be sent to the composite driver up until the point
  when usb_gadget_disconnect() returns.
 
  That doesn't sound right.  A host can't send SETUP packets to a
  disconnected port.  The packets should stop arriving when
  udc-driver-disconnect returns -- assuming the UDC driver implements
  a disconnect method.
 
 udc-driver-disconnect points to composite_disconnect().  What is
 composite_disconnect() doing to tell the UDC driver to disconnect the
 port from the host?

Oops -- you're right and I was wrong.  It's the usb_gadget_disconnect() 
call which turns off the pullup.  Sorry about the confusion.

 What I see is that usb_gadget_disconnect() does tell the UDC driver to
 stop activity on the port, but that only happens after
 composite_disconnect() was called.  Can you confirm that the order of
 the calls in usb_gadget_remove_driver() is correct?

They might need to be changed.  It does seems like a bad idea to tell 
the gadget driver that a disconnect occurred before the host knows 
about it.

If you change the order of those two calls, does that make your posted 
patch unnecessary?

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


Re: [PATCH 1/2] usb: gadget: composite: Race between disconnect/unbind and setup

2012-07-09 Thread Peter Chen

 They might need to be changed.  It does seems like a bad idea to tell
 the gadget driver that a disconnect occurred before the host knows
 about it.

Yes, it should pull down dp first, then, tell class driver, it has
been disconnected.

 If you change the order of those two calls, does that make your posted
 patch unnecessary?

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


Re: [PATCH 1/2] usb: gadget: composite: Race between disconnect/unbind and setup

2012-07-08 Thread Kevin Cernekee
On Sun, Jul 8, 2012 at 5:33 PM, Alan Stern st...@rowland.harvard.edu wrote:
 On Sun, 8 Jul 2012, Kevin Cernekee wrote:

 usb_gadget_remove_driver() runs through a four-step sequence to shut down
 the gadget driver.  For the case of a composite gadget + at91 UDC, this
 would look like:

     udc-driver-disconnect(udc-gadget);          // composite_disconnect()
     usb_gadget_disconnect(udc-gadget);            // at91_pullup(gadget, 0)
     udc-driver-unbind(udc-gadget);              // composite_unbind()
     usb_gadget_udc_stop(udc-gadget, udc-driver); // at91_stop()

 composite_disconnect() says:

     if (cdev-config)
         reset_config(cdev);

 reset_config() sets cdev-config to NULL.  composite_unbind() later tests
 for this:

     WARN_ON(cdev-config);

 But SETUP packets may be sent to the composite driver up until the point
 when usb_gadget_disconnect() returns.

 That doesn't sound right.  A host can't send SETUP packets to a
 disconnected port.  The packets should stop arriving when
 udc-driver-disconnect returns -- assuming the UDC driver implements
 a disconnect method.

udc-driver-disconnect points to composite_disconnect().  What is
composite_disconnect() doing to tell the UDC driver to disconnect the
port from the host?

What I see is that usb_gadget_disconnect() does tell the UDC driver to
stop activity on the port, but that only happens after
composite_disconnect() was called.  Can you confirm that the order of
the calls in usb_gadget_remove_driver() is correct?

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