Re: [PATCH 1/2] usb: dwc3: allocate gadget structure dynamically

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

 



On Thu, Aug 06, 2020 at 10:54:14AM -0400, Alan Stern wrote:
> On Thu, Aug 06, 2020 at 05:07:16PM +0800, Peter Chen wrote:
> > The current code uses commit fac323471df6 ("usb: udc: allow adding
> > and removing the same gadget device") as the workaround to let
> > the gadget device is re-used, but it is not allowed from driver
> > core point. In this commit, we allocate gadget structure dynamically,
> > and free it at its release function. Since the gadget device's
> > driver_data has already occupied by usb_composite_dev structure, we have
> > to use gadget device's platform data to store dwc3 structure.
> > 
> > Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> > Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
> > Signed-off-by: Peter Chen <peter.chen@xxxxxxx>
> 
> There's one problem with this patch...
> 
> > @@ -3670,21 +3685,22 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> >  
> >  	ret = dwc3_gadget_init_endpoints(dwc, dwc->num_eps);
> >  	if (ret)
> > -		goto err3;
> > +		goto err4;
> >  
> > -	ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
> > +	ret = usb_add_gadget_udc_release(dwc->dev, dwc->gadget, dwc_gadget_release);
> >  	if (ret) {
> >  		dev_err(dwc->dev, "failed to register udc\n");
> > -		goto err4;
> > +		goto err5;
> >  	}
> >  
> > -	dwc3_gadget_set_speed(&dwc->gadget, dwc->maximum_speed);
> > +	dwc3_gadget_set_speed(dwc->gadget, dwc->maximum_speed);
> >  
> >  	return 0;
> >  
> > -err4:
> > +err5:
> >  	dwc3_gadget_free_endpoints(dwc);
> > -
> > +err4:
> > +	kfree(dwc->gadget);
> 
> Once you call usb_add_gadget_udc_release() -- even if the call fails --
> you must not call kfree() directly.  Instead you have to do
> put_device(&dwc->gadget.dev).  That's a little awkward given the code
> arrangement here.

Sorry, I got that wrong.  If usb_add_gadget_udc_release() succeeds then 
you must call put_device() in order to destroy the gadget.  But if it 
fails then it calls put_device() for you, so that dwc->gadget is a stale 
pointer.  In this case you must not call either kfree() or put_device().

Alan Stern



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

  Powered by Linux