On Wed, 14 Jun 2017, Peter Chen wrote:

> On Tue, Jun 13, 2017 at 10:22:26AM -0400, Alan Stern wrote:
> > On Tue, 13 Jun 2017, Felipe Balbi wrote:
> > 
> > > 
> > > Hi Alan,
> > > 
> > > Alan Stern <st...@rowland.harvard.edu> writes:
> > > > Felipe:
> > > >
> > > > A UDC driver will invoke the gadget driver's ->disconnect callback
> > > > whenever the D+ pullup is turned off.  During gadget driver unbinding,
> > > > this happens automatically when usb_gadget_remove_driver() calls
> > > > usb_gadget_disconnect().
> > > 
> > > usb_gadget_disconnect() only calls UDC's ->pullup(), not gadget driver's
> > > ->disconnect()
> > > 
> > > int usb_gadget_disconnect(struct usb_gadget *gadget)
> > > {
> > >   int ret = 0;
> > > 
> > >   if (!gadget->ops->pullup) {
> > >           ret = -EOPNOTSUPP;
> > >           goto out;
> > >   }
> > > 
> > >   if (gadget->deactivated) {
> > >           /*
> > >            * If gadget is deactivated we only save new state.
> > >            * Gadget will stay disconnected after activation.
> > >            */
> > >           gadget->connected = false;
> > >           goto out;
> > >   }
> > > 
> > >   ret = gadget->ops->pullup(gadget, 0);
> > >   if (!ret)
> > >           gadget->connected = 0;
> > > 
> > > out:
> > >   trace_usb_gadget_disconnect(gadget, ret);
> > > 
> > >   return ret;
> > > }
> > > EXPORT_SYMBOL_GPL(usb_gadget_disconnect);
> > 
> > Yes, but as I mentioned above, the pullup routine calls the gadget
> > driver's disconnect method.
> > 
> > > > But immediately thereafter, usb_gadget_remove_driver() calls the gadget 
> > > > driver's ->disconnect callback directly!  Do we have any reason for 
> > > > doing this?  I don't see point to it.  Should that call be removed?
> > > 
> > > Unless I'm missing something, that call is necessary :-) Have you faced
> > > any issues with it? Are there any UDCs calling gadget driver's
> > > ->disconnect() from ->pullup() ?
> > 
> > I haven't faced any issues because gadget drivers don't seem to mind 
> > ->disconnect getting called twice in a row.  :-)  (And note that the 
> > API doesn't have a corresponding ->connect callback...  Although to 
> > tell the truth, it's not clear what a gadget driver needs to do in 
> > either callback.  Can we simply remove ->disconnect altogether?)
> > 
> > Both dummy-hcd and net2280 call ->disconnect from ->pullup.  I haven't
> > checked other UDC drivers, but it seems like something they should all
> > do.  Except perhaps in the case where the UDC driver doesn't have a
> > pullup method.
> > 
> 
> No, ->pullup is expected to be called from UDC core, and the UDC core
> makes sure the coming ->disconnect at kinds of situations.

I think you are wrong.  The UDC core calls ->pullup from the 
usb_gadget_disconnect() routine, but it does not call ->disconnect from 
that routine.

Furthermore, there is an advantage to having the UDC driver call
->disconnect from within its ->pullup method: It can retain its private
spinlock across the ->disconnect call.  This will help prevent races.  
For example, what would happen if ->disconnect was called while a
->setup callback was in progress?  Or vice versa?

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