Re: [PATCH] usb: gadget: dummy: don't disconnect on gadget removal

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

 



Hi,

On Wed, Apr 18, 2012 at 12:17:48PM -0400, Alan Stern wrote:
> On Wed, 18 Apr 2012, Alexander Shishkin wrote:
> 
> > On Tue, 17 Apr 2012 10:49:52 -0400 (EDT), Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> > > On Tue, 17 Apr 2012, Alexander Shishkin wrote:
> > > 
> > > > Currently, on gadget removal path, dummy_pullup() gets called after
> > > > gadget's disconnect(). Now, dummy_pullup() decides that it needs to
> > > > disconnect again, resulting in a crash. IOW, rmmod g_zero will crash
> > > > with dummy_hcd.
> > > 
> > > This doesn't sound right.  The gadget removal path is dummy_udc_stop(), 
> > > right?  That routine sets dum->driver to NULL before calling 
> > > dummy_pullup().  Consequently the last test in the "if" statement you 
> > > are changing won't succeed, so the gadget's disconnect method won't be 
> > > called.
> > 
> > Since the new style gadgets were introduced, the removal path is like
> > this:
> > 
> >         udc->driver->disconnect(udc->gadget);
> >         udc->driver->unbind(udc->gadget);
> >         usb_gadget_disconnect(udc->gadget);
> >         usb_gadget_udc_stop(udc->gadget, udc->driver);
> > 
> > where usb_gadget_disconnect() calls gadget's pullup(), which in case of
> > dummy_hcd will end up calling driver->disconnect(), which has already
> > been called higher up in usb_gadget_remove. And all that before
> > dummy_udc_stop(), which indeed gets it right.
> 
> You'd be right except for one thing: You listed the code from
> udc-core.c:usb_gadget_remove_driver() wrongly.  In my tree it actually
> looks like this:
> 
> 	if (udc_is_newstyle(udc)) {
> 		udc->driver->disconnect(udc->gadget);
> 		udc->driver->unbind(udc->gadget);
> 		usb_gadget_udc_stop(udc->gadget, udc->driver);
> 		usb_gadget_disconnect(udc->gadget);
> 	} else {
> 		usb_gadget_stop(udc->gadget, udc->driver);
> 	}
> 
> Notice the relative order of the usb_gadget_disconnect() and 
> usb_gadget_udc_stop() calls.  This hasn't been changed since 3.4-rc2, 
> has it?  I hope not -- if it has changed then it is now wrong.

you need to fetch Greg's usb-linus branch ;-)

> On the other hand, it's certainly true that dummy_udc_stop() doesn't
> need to call dummy_pullup() -- usb_gadget_disconnect() calls it for us.

fixed in my tree, will send a patch shortly.

> On Wed, 18 Apr 2012, Felipe Balbi wrote:
> 
> > Alan, maybe you're more aware of how dummy_hcd works, but can we get a
> > disconnect event initiated by the dummy_hcd instead of the dummy_udc ?
> 
> As a matter of fact, we can.  If the host turns off the port power 
> feature then there's an immediate disconnect.  This is the way hubs 
> (including root hubs) are supposed to behave, although a lot of them 
> probably don't.

ok, good.

> > looking closer at that part from dummy, it's quite badly written.
> > There's no easy way for us to differentiate a bus reset from a gadget
> > driver removal.
> 
> Gadget driver removal is indicated by the fact that dum->driver is 
> NULL.
> 
> > I think your patch is closer to being right than mine. We still need to
> > notify gadget driver about a disconnect when a reset happens and my
> > patch will break that, while yours won't.
> 
> I'm still not convinced the problem has been properly identified.  In 
> fact, I'm not convinced there's any problem at all.  I just booted my 
> test kernel (a lightly modified 3.4-rc2), loaded dummy-hcd and g-zero, 
> and then removed both of them.  Nothing went wrong.
> 
> A patch to remove the unneeded call of dummy_pullup() would be
> acceptable.

I have that...

-- 
balbi

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux