Re: On the 19th Dec I reported an OOPS when attaching a BeagleBone

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

 



On Wednesday 04 Jan 2012, Alan Stern wrote:
> On Wed, 4 Jan 2012, Huajun Li wrote:
> > Hi Alan,
> > 
> >    Is any chance for user to trigger the window if the driver has been
> > 
> > unregistered?  thanks.
> 
> Yes, that possibility does exist.
> 
> > How about adding more codes into usb_store_new_id() to find out
> > whether the driver is registered while receiving such requests? and
> > this could give useful info to user space if the requests fail.
> 
> I don't think that's the best approach.  Furthermore, your proposed fix
> still contains a race because is_drv_ready() calls put_driver() before
> returning.
> 
> In order to fix this properly, we have to make sure that
> usb_store_new_id() is mutually exclusive with driver registration and
> unregistration.  The patch below will accomplish that.
> 
> However it does leave one problem unsolved.  The udev rule still can
> run too quickly.  Now instead of getting an oops, the rule simply won't
> work.  I don't know how to fix that.
> 
> David, can you test this patch in place of the earlier one?
I can try.  Building kernels on this elderly box takes hours, and I 
had all manner of problems getting to the point of testing the last
patch, but I will give it a go.  It will probably be early next week
when I have time to do it (I am busy tomorrow, friday, saturday and
sunday).

David
> 
> Alan Stern
> 
> 
> 
> Index: usb-3.2/drivers/usb/core/driver.c
> ===================================================================
> --- usb-3.2.orig/drivers/usb/core/driver.c
> +++ usb-3.2/drivers/usb/core/driver.c
> @@ -31,6 +31,10 @@
> 
>  #include "usb.h"
> 
> +/* Mutual exclusion for drvwrap->is_registered */
> +DEFINE_MUTEX(usb_driver_reg_mutex);
> +EXPORT_SYMBOL_GPL(usb_driver_reg_mutex);
> +
> 
>  #ifdef CONFIG_HOTPLUG
> 
> @@ -815,6 +819,10 @@ int usb_register_device_driver(struct us
>  			usbcore_name, retval, new_udriver->name);
>  	}
> 
> +	mutex_lock(&usb_driver_reg_mutex);
> +	new_udriver->drvwrap.is_registered = 1;
> +	mutex_unlock(&usb_driver_reg_mutex);
> +
>  	return retval;
>  }
>  EXPORT_SYMBOL_GPL(usb_register_device_driver);
> @@ -831,6 +839,10 @@ void usb_deregister_device_driver(struct
>  	pr_info("%s: deregistering device driver %s\n",
>  			usbcore_name, udriver->name);
> 
> +	mutex_lock(&usb_driver_reg_mutex);
> +	udriver->drvwrap.is_registered = 0;
> +	mutex_unlock(&usb_driver_reg_mutex);
> +
>  	driver_unregister(&udriver->drvwrap.driver);
>  	usbfs_update_special();
>  }
> @@ -873,6 +885,10 @@ int usb_register_driver(struct usb_drive
>  	if (retval)
>  		goto out;
> 
> +	mutex_lock(&usb_driver_reg_mutex);
> +	new_driver->drvwrap.is_registered = 1;
> +	mutex_unlock(&usb_driver_reg_mutex);
> +
>  	usbfs_update_special();
> 
>  	retval = usb_create_newid_file(new_driver);
> @@ -917,6 +933,10 @@ void usb_deregister(struct usb_driver *d
>  	pr_info("%s: deregistering interface driver %s\n",
>  			usbcore_name, driver->name);
> 
> +	mutex_lock(&usb_driver_reg_mutex);
> +	driver->drvwrap.is_registered = 0;
> +	mutex_unlock(&usb_driver_reg_mutex);
> +
>  	usb_remove_removeid_file(driver);
>  	usb_remove_newid_file(driver);
>  	usb_free_dynids(driver);
> Index: usb-3.2/drivers/usb/serial/bus.c
> ===================================================================
> --- usb-3.2.orig/drivers/usb/serial/bus.c
> +++ usb-3.2/drivers/usb/serial/bus.c
> @@ -119,13 +119,20 @@ static int usb_serial_device_remove(stru
>  static ssize_t store_new_id(struct device_driver *driver,
>  			    const char *buf, size_t count)
>  {
> -	struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
> -	ssize_t retval = usb_store_new_id(&usb_drv->dynids, driver, buf, count);
> -
> -	if (retval >= 0 && usb_drv->usb_driver != NULL)
> -		retval = usb_store_new_id(&usb_drv->usb_driver->dynids,
> -					  &usb_drv->usb_driver->drvwrap.driver,
> +	struct usb_serial_driver *ser_drv = to_usb_serial_driver(driver);
> +	struct usb_driver *usb_drv = ser_drv->usb_driver;
> +	ssize_t retval = usb_store_new_id(&ser_drv->dynids, driver, buf, count);
> +
> +	if (retval >= 0 && usb_drv != NULL) {
> +		mutex_lock(&usb_driver_reg_mutex);
> +		if (usb_drv->drvwrap.is_registered)
> +			retval = usb_store_new_id(&usb_drv->dynids,
> +					  &usb_drv->drvwrap.driver,
>  					  buf, count);
> +		else
> +			retval = -EAGAIN;
> +		mutex_unlock(&usb_driver_reg_mutex);
> +	}
>  	return retval;
>  }
> 
> @@ -178,7 +185,7 @@ int usb_serial_bus_register(struct usb_s
> 
>  void usb_serial_bus_deregister(struct usb_serial_driver *driver)
>  {
> -	free_dynids(driver);
>  	driver_unregister(&driver->driver);
> +	free_dynids(driver);
>  }
> 
> Index: usb-3.2/include/linux/usb.h
> ===================================================================
> --- usb-3.2.orig/include/linux/usb.h
> +++ usb-3.2/include/linux/usb.h
> @@ -792,14 +792,18 @@ extern ssize_t usb_store_new_id(struct u
>  				struct device_driver *driver,
>  				const char *buf, size_t count);
> 
> +extern struct mutex usb_driver_reg_mutex;
> +
>  /**
>   * struct usbdrv_wrap - wrapper for driver-model structure
>   * @driver: The driver-model core driver structure.
>   * @for_devices: Non-zero for device drivers, 0 for interface drivers.
> + * @is_registered: The driver is registered (protected by
> usb_driver_reg_mutex) */
>  struct usbdrv_wrap {
>  	struct device_driver driver;
> -	int for_devices;
> +	unsigned int for_devices:1;
> +	unsigned int is_registered:1;
>  };
> 
>  /**
> 
> --
> 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

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