[PATCH] usb: gadget: move gadget start to bind of each driver

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

 



We currently enable the udc on bind_to_driver. This breaks the
de/activate mechanism for drivers that depent on userspace components.
This patch fixes this by moving the pullup call to each bind.

Signed-off-by: Michael Grzeschik <m.grzeschik@xxxxxxxxxxxxxx>
---
 drivers/usb/gadget/f_acm.c          | 3 +++
 drivers/usb/gadget/f_ecm.c          | 3 +++
 drivers/usb/gadget/f_eem.c          | 3 +++
 drivers/usb/gadget/f_fs.c           | 5 +++++
 drivers/usb/gadget/f_hid.c          | 2 ++
 drivers/usb/gadget/f_loopback.c     | 3 +++
 drivers/usb/gadget/f_mass_storage.c | 2 ++
 drivers/usb/gadget/f_midi.c         | 2 ++
 drivers/usb/gadget/f_ncm.c          | 3 +++
 drivers/usb/gadget/f_phonet.c       | 3 +++
 drivers/usb/gadget/f_rndis.c        | 3 +++
 drivers/usb/gadget/f_serial.c       | 3 +++
 drivers/usb/gadget/f_sourcesink.c   | 3 +++
 drivers/usb/gadget/f_subset.c       | 3 +++
 drivers/usb/gadget/f_uac1.c         | 3 +++
 drivers/usb/gadget/f_uac2.c         | 3 +++
 drivers/usb/gadget/g_ffs.c          | 6 +++++-
 drivers/usb/gadget/inode.c          | 2 ++
 drivers/usb/gadget/udc-core.c       | 1 -
 19 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index ab1065a..045176f 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -697,6 +697,9 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
 			acm->port.in->name, acm->port.out->name,
 			acm->notify->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index 8d9e6f7..58cb39a 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -813,6 +813,9 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
 			ecm->port.in_ep->name, ecm->port.out_ep->name,
 			ecm->notify->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index d61c11d..94cf705 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -322,6 +322,9 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
 			gadget_is_superspeed(c->cdev->gadget) ? "super" :
 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
 			eem->port.in_ep->name, eem->port.out_ep->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 44cf775..a6349ee 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1496,6 +1496,11 @@ static int functionfs_bind_config(struct usb_composite_dev *cdev,
 	if (unlikely(ret))
 		ffs_func_free(func);
 
+	/* Avoid letting this gadget enumerate until the userspace server is
+	 * active.
+	 */
+	ret = usb_function_deactivate(&func->function);
+
 	return ret;
 }
 
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 6e69a8e..03cfa3ee 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -633,6 +633,8 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
 
 	device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor);
 
+	usb_gadget_connect(c->cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 4a3873a..08ff937 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -225,6 +225,9 @@ autoconf_fail:
 	    (gadget_is_superspeed(c->cdev->gadget) ? "super" :
 	     (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
 			f->name, loop->in_ep->name, loop->out_ep->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 }
 
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index a03ba2c..20458bd 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -3161,6 +3161,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
 	if (ret)
 		goto autoconf_fail;
 
+	usb_gadget_connect(gadget);
+
 	return 0;
 
 autoconf_fail:
diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c
index 263e721..8589717 100644
--- a/drivers/usb/gadget/f_midi.c
+++ b/drivers/usb/gadget/f_midi.c
@@ -895,6 +895,8 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 
 	kfree(midi_function);
 
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail_f_midi:
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index 1c28fe1..40518ac 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -1271,6 +1271,9 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
 			ncm->port.in_ep->name, ncm->port.out_ep->name,
 			ncm->notify->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index eb3aa81..72abd73 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -565,6 +565,9 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f)
 	INFO(cdev, "USB CDC Phonet function\n");
 	INFO(cdev, "using %s, OUT %s, IN %s\n", cdev->gadget->name,
 		fp->out_ep->name, fp->in_ep->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 err_req:
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 717ed7f..3a3da34 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -807,6 +807,9 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
 			rndis->port.in_ep->name, rndis->port.out_ep->name,
 			rndis->notify->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 981113c..19581d5 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -244,6 +244,9 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f)
 			gadget_is_superspeed(c->cdev->gadget) ? "super" :
 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
 			gser->port.in->name, gser->port.out->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index a889585..43d5b10 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -484,6 +484,9 @@ no_iso:
 			f->name, ss->in_ep->name, ss->out_ep->name,
 			ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
 			ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 }
 
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index 7c8674f..5aa743c 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -378,6 +378,9 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
 			gadget_is_superspeed(c->cdev->gadget) ? "super" :
 			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
 			geth->port.in_ep->name, geth->port.out_ep->name);
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c
index 2b4c82d..00f9581 100644
--- a/drivers/usb/gadget/f_uac1.c
+++ b/drivers/usb/gadget/f_uac1.c
@@ -663,6 +663,9 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 	status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL);
 	if (status)
 		goto fail;
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c
index 2f23566..ac6d075 100644
--- a/drivers/usb/gadget/f_uac2.c
+++ b/drivers/usb/gadget/f_uac2.c
@@ -994,6 +994,9 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
 	ret = alsa_uac2_init(agdev);
 	if (ret)
 		goto err;
+
+	usb_gadget_connect(cdev->gadget);
+
 	return 0;
 err:
 	kfree(agdev->uac2.p_prm.rbuf);
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 2344efe..9f87c60 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -247,6 +247,7 @@ static struct gfs_ffs_obj *gfs_find_dev(const char *dev_name)
 static int functionfs_ready_callback(struct ffs_data *ffs)
 {
 	struct gfs_ffs_obj *ffs_obj;
+	struct ffs_function *func = ffs->func;
 	int ret;
 
 	ENTER();
@@ -277,9 +278,12 @@ static int functionfs_ready_callback(struct ffs_data *ffs)
 	gfs_registered = true;
 
 	ret = usb_composite_probe(&gfs_driver);
-	if (unlikely(ret < 0))
+	if (unlikely(ret < 0)) {
 		gfs_registered = false;
+		goto done;
+	}
 
+	ret = usb_function_activate(&func->function);
 done:
 	mutex_unlock(&gfs_lock);
 	return ret;
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index b94c049..f30a6c5 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1844,6 +1844,7 @@ static ssize_t
 dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 {
 	struct dev_data		*dev = fd->private_data;
+	struct usb_gadget	*gadget = dev->gadget;
 	ssize_t			value = len, length = len;
 	unsigned		total;
 	u32			tag;
@@ -1913,6 +1914,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 		kfree (dev->buf);
 		dev->buf = NULL;
 	} else {
+		usb_gadget_connect(gadget);
 		/* at this point "good" hardware has for the first time
 		 * let the USB the host see us.  alternatively, if users
 		 * unplug/replug that will clear all the error state.
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 27768a7..b906ac7 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -351,7 +351,6 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
 		driver->unbind(udc->gadget);
 		goto err1;
 	}
-	usb_gadget_connect(udc->gadget);
 
 	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 	return 0;
-- 
1.8.4.2

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