Re: [patch]unbalanced calls to post_reset() from usb_reset_device()

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

 



Am Freitag, 27. November 2009 18:15:22 schrieb Alan Stern:
> On Thu, 26 Nov 2009, Oliver Neukum wrote:
> > Am Donnerstag, 26. November 2009 18:03:04 schrieb Alan Stern:
> > > If the interface is in the middle of binding or unbinding when the
> > > reset occurs, the driver need not have a pre_reset or post_reset
> > > method.  This exception is for the drivers that do a reset within their
> > > probe routine, of which there are (or were) several.  So the test has
> > > to be retained.
> >
> > This way?
> >
> > @@ -3672,6 +3673,10 @@ int usb_reset_device(struct usb_device *udev)
> >  				drv = to_usb_driver(cintf->dev.driver);
> >  				if (drv->pre_reset && drv->post_reset)
> >  					unbind = (drv->pre_reset)(cintf);
> > +				/*
> > +				 * you can use usb_reset_device() from
> > +				 * probe() without providing reset
> 
> Without providing pre_reset or post_reset.  "without providing reset"
> doesn't make sense.

Roger.

> > +				 */
> >  				else if (cintf->condition ==
> >  						USB_INTERFACE_BOUND)
> >  					unbind = 1;
> > @@ -3687,17 +3692,30 @@ int usb_reset_device(struct usb_device *udev)
> >  		for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) {
> >  			struct usb_interface *cintf = config->interface[i];
> >  			struct usb_driver *drv;
> > -			int rebind = cintf->needs_binding;
> >
> > -			if (!rebind && cintf->dev.driver) {
> > +			if (!cintf->needs_binding && cintf->dev.driver) {
> >  				drv = to_usb_driver(cintf->dev.driver);
> >  				if (drv->post_reset)
> > -					rebind = (drv->post_reset)(cintf);
> > -				else if (cintf->condition ==
> > -						USB_INTERFACE_BOUND)
> > -					rebind = 1;
> > +					cintf->needs_binding =
> > +					(drv->post_reset)(cintf) ? 1 : 0;
> 
> Purely as a matter of taste, it might be clearer to write this as
> 
> 					if (drv->post_reset(cintf))
> 						cintf->needs_binding = 1;
> 
> > +				else if (cintf->condition == USB_INTERFACE_BOUND)
> > +					cintf->needs_binding = 1;
> 
> I think these two lines aren't needed, and in fact they weren't needed
> in the original code.  The only way to reach this spot is if you are in
> the middle of binding or unbinding; hence the test can never succeed.

Roger.

> >  			}
> > -			if (ret == 0 && rebind)
> > +		}
> > +
> > +		/*
> > +		 * Don't rebind until after all the post_reset() calls
> > +		 * so that a newly bound driver does not get an unbalanced
> > +		 * call to post_reset()
> > +		 */
> > +		for (i = config->desc.bNumInterfaces - 1; i >= 0; --i){
> > +			struct usb_interface *cintf = config->interface[i];
> > +
> > +			/*
> > +			 * safe w.r.t. usb_claim_interface() as
> > +			 * that clears needs_binding
> > +			 */
> 
> Hmm.  If your probe routine claims some other interfaces and then does
> a reset, and you don't provide pre_reset and post_reset methods, you're
> likely to run into trouble anyway.  Drivers just shouldn't do that.
> They should carry out the reset first.

Suppose another driver is rebound.

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

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

  Powered by Linux