RE: Disable bus's drivers_autoprobe before rootfs has mounted

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

 



On Fri, 13 Jun 2014, Peter Chen wrote:

> OK, we can keep our g_xxx gadget driver just support the basic feature. But
> the bug that causes gadget driver load fail due to udc is probed deferral should
> be fixed, do you think so, we can't wait until configfs has total been ready.

That problem has always existed.  There never has been a time when a
gadget driver could be loaded before the UDC driver was ready.  Does it 
really need to be fixed now?

If you do want to fix the problem, there's a much easier way than what
you posted.  See below.

Alan Stern



Index: usb-3.15/include/linux/usb/gadget.h
===================================================================
--- usb-3.15.orig/include/linux/usb/gadget.h
+++ usb-3.15/include/linux/usb/gadget.h
@@ -821,6 +821,7 @@ static inline int usb_gadget_disconnect(
  * @suspend: Invoked on USB suspend.  May be called in_interrupt.
  * @resume: Invoked on USB resume.  May be called in_interrupt.
  * @driver: Driver model state for this driver.
+ * @probe_list: List of drivers waiting to be probed.
  *
  * Devices are disabled till a gadget driver successfully bind()s, which
  * means the driver will handle setup() requests needed to enumerate (and
@@ -881,6 +882,7 @@ struct usb_gadget_driver {
 
 	/* FIXME support safe rmmod */
 	struct device_driver	driver;
+	struct list_head	probe_list;
 };
 
 
Index: usb-3.15/drivers/usb/gadget/udc-core.c
===================================================================
--- usb-3.15.orig/drivers/usb/gadget/udc-core.c
+++ usb-3.15/drivers/usb/gadget/udc-core.c
@@ -47,8 +47,12 @@ struct usb_udc {
 
 static struct class *udc_class;
 static LIST_HEAD(udc_list);
+static LIST_HEAD(pending_drivers);
 static DEFINE_MUTEX(udc_lock);
 
+static int udc_bind_to_driver(struct usb_udc *udc,
+		struct usb_gadget_driver *driver);
+
 /* ------------------------------------------------------------------------- */
 
 #ifdef	CONFIG_HAS_DMA
@@ -242,6 +246,15 @@ int usb_add_gadget_udc_release(struct de
 
 	usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
 
+	while (!list_empty(&pending_drivers)) {
+		struct usb_gadget_driver *driver;
+
+		driver = list_first_entry(&pending_drivers,
+				struct usb_gadget_driver, probe_list);
+		if (udc_bind_to_driver(udc, driver) == 0)
+			break;
+	}
+
 	mutex_unlock(&udc_lock);
 
 	return 0;
@@ -338,6 +351,7 @@ static int udc_bind_to_driver(struct usb
 
 	dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
 			driver->function);
+	list_del_init(&driver->probe_list);
 
 	udc->driver = driver;
 	udc->dev.driver = &driver->driver;
@@ -400,6 +414,7 @@ int usb_gadget_probe_driver(struct usb_g
 		return -EINVAL;
 
 	mutex_lock(&udc_lock);
+	INIT_LIST_HEAD(&driver->probe_list);
 	list_for_each_entry(udc, &udc_list, list) {
 		/* For now we take the first one */
 		if (!udc->driver)
@@ -407,8 +422,9 @@ int usb_gadget_probe_driver(struct usb_g
 	}
 
 	pr_debug("couldn't find an available UDC\n");
+	list_add_tail(&driver->probe_list, &pending_drivers);
 	mutex_unlock(&udc_lock);
-	return -ENODEV;
+	return 0;
 found:
 	ret = udc_bind_to_driver(udc, driver);
 	mutex_unlock(&udc_lock);
@@ -425,6 +441,7 @@ int usb_gadget_unregister_driver(struct
 		return -EINVAL;
 
 	mutex_lock(&udc_lock);
+	list_del(&driver->probe_list);
 	list_for_each_entry(udc, &udc_list, list)
 		if (udc->driver == driver) {
 			usb_gadget_remove_driver(udc);


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