mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 16/23] USB: gadget: DFU: register as USB function
Date: Mon, 21 Jul 2014 17:14:40 +0200	[thread overview]
Message-ID: <1405955687-27433-17-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1405955687-27433-1-git-send-email-s.hauer@pengutronix.de>

Register DFU as usb_function_instance to make it work with composite
gadgets. Also use this internally for registering as DFU device (with
the 'dfu' command).

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/dfu.c           |  12 ++--
 drivers/usb/gadget/dfu.c | 141 ++++++++++++++++++++++++++++++++---------------
 include/usb/dfu.h        |   8 ++-
 3 files changed, 107 insertions(+), 54 deletions(-)

diff --git a/commands/dfu.c b/commands/dfu.c
index 1610349..99fec9b 100644
--- a/commands/dfu.c
+++ b/commands/dfu.c
@@ -33,7 +33,7 @@
  */
 static int do_dfu(int argc, char *argv[])
 {
-	struct usb_dfu_pdata pdata;
+	struct f_dfu_opts opts;
 	char *argstr;
 	struct usb_dfu_dev *dfu_alts = NULL;
 	int ret;
@@ -43,15 +43,15 @@ static int do_dfu(int argc, char *argv[])
 
 	argstr = argv[optind];
 
-	pdata.files = file_list_parse(argstr);
-	if (IS_ERR(pdata.files)) {
-		ret = PTR_ERR(pdata.files);
+	opts.files = file_list_parse(argstr);
+	if (IS_ERR(opts.files)) {
+		ret = PTR_ERR(opts.files);
 		goto out;
 	}
 
-	ret = usb_dfu_register(&pdata);
+	ret = usb_dfu_register(&opts);
 
-	file_list_free(pdata.files);
+	file_list_free(opts.files);
 out:
 
 	free(dfu_alts);
diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
index ca7462b..3684edd 100644
--- a/drivers/usb/gadget/dfu.c
+++ b/drivers/usb/gadget/dfu.c
@@ -182,6 +182,13 @@ dfu_bind(struct usb_configuration *c, struct usb_function *f)
 	int			status;
 	struct usb_string	*us;
 
+	if (!dfu_files) {
+		const struct usb_function_instance *fi = f->fi;
+		struct f_dfu_opts *opts = container_of(fi, struct f_dfu_opts, func_inst);
+
+		dfu_files = opts->files;
+	}
+
 	dfu_string_defs = xzalloc(sizeof(struct usb_string) * (dfu_files->num_entries + 2));
 	dfu_string_defs[0].s = "Generic DFU";
 	i = 0;
@@ -652,42 +659,6 @@ static struct usb_gadget_strings *dev_strings[] = {
 	NULL,
 };
 
-static int dfu_bind_config(struct usb_configuration *c)
-{
-	struct f_dfu *dfu;
-	struct usb_function *func;
-	int		status;
-
-	/* config description */
-	status = usb_string_id(c->cdev);
-	if (status < 0)
-		return status;
-	strings_dev[STRING_DESCRIPTION_IDX].id = status;
-
-	/* allocate and initialize one new instance */
-	dfu = xzalloc(sizeof *dfu);
-
-	func = &dfu->func;
-	func->name = "DFU";
-	func->strings = dfu_strings;
-	/* descriptors are per-instance copies */
-	func->bind = dfu_bind;
-	func->unbind = dfu_unbind;
-	func->set_alt = dfu_set_alt;
-	func->setup = dfu_setup;
-	func->disable = dfu_disable;
-
-	status = usb_add_function(c, func);
-	if (status)
-		goto out;
-
-	return 0;
-out:
-	free(dfu);
-
-	return status;
-}
-
 static void dfu_unbind_config(struct usb_configuration *c)
 {
 	free(dfu_string_defs);
@@ -713,6 +684,9 @@ static struct usb_device_descriptor dfu_dev_descriptor = {
 	.bNumConfigurations	= 0x01,
 };
 
+static struct usb_function_instance *fi_dfu;
+static struct usb_function *f_dfu;
+
 static int dfu_driver_bind(struct usb_composite_dev *cdev)
 {
 	struct usb_gadget *gadget = cdev->gadget;
@@ -748,52 +722,129 @@ static int dfu_driver_bind(struct usb_composite_dev *cdev)
 	strings_dev[STRING_DESCRIPTION_IDX].id = status;
 	dfu_config_driver.iConfiguration = status;
 
-	status = usb_add_config(cdev, &dfu_config_driver, dfu_bind_config);
+	status = usb_add_config_only(cdev, &dfu_config_driver);
 	if (status < 0)
 		goto fail;
 
+	fi_dfu = usb_get_function_instance("dfu");
+	if (IS_ERR(fi_dfu)) {
+		status = PTR_ERR(fi_dfu);
+		goto fail;
+	}
+
+	f_dfu = usb_get_function(fi_dfu);
+	if (IS_ERR(f_dfu)) {
+		status = PTR_ERR(f_dfu);
+		goto fail;
+	}
+
+	status = usb_add_function(&dfu_config_driver, f_dfu);
+	if (status)
+		goto fail;
+
 	return 0;
 fail:
 	return status;
 }
 
+static int dfu_driver_unbind(struct usb_composite_dev *cdev)
+{
+	usb_put_function(f_dfu);
+	usb_put_function_instance(fi_dfu);
+
+	return 0;
+}
+
 static struct usb_composite_driver dfu_driver = {
 	.name		= "g_dfu",
 	.dev		= &dfu_dev_descriptor,
 	.strings	= dev_strings,
 	.bind		= dfu_driver_bind,
+	.unbind		= dfu_driver_unbind,
 };
 
-int usb_dfu_register(struct usb_dfu_pdata *pdata)
+int usb_dfu_register(struct f_dfu_opts *opts)
 {
 	int ret;
 
-	dfu_files = pdata->files;
+	if (dfu_files)
+		return -EBUSY;
+
+	dfu_files = opts->files;
 
 	ret = usb_composite_probe(&dfu_driver);
 	if (ret)
-		return ret;
+		goto out;
 
 	while (1) {
 		ret = usb_gadget_poll();
 		if (ret < 0)
-			goto out;
+			goto out1;
 
 		if (dfudetach) {
 			ret = 0;
-			goto out;
+			goto out1;
 		}
 
 		if (ctrlc()) {
 			ret = -EINTR;
-			goto out;
+			goto out1;
 		}
 	}
 
-out:
+out1:
 	dfudetach = 0;
 	usb_composite_unregister(&dfu_driver);
+out:
+	dfu_files = NULL;
 
-	return 0;
+	return ret;
+}
+
+static void dfu_free_func(struct usb_function *f)
+{
+	struct f_dfu *dfu = container_of(f, struct f_dfu, func);
+
+	free(dfu);
+}
+
+static struct usb_function *dfu_alloc_func(struct usb_function_instance *fi)
+{
+	struct f_dfu *dfu;
+
+	dfu = xzalloc(sizeof(*dfu));
+
+	dfu->func.name = "dfu";
+	dfu->func.strings = dfu_strings;
+	/* descriptors are per-instance copies */
+	dfu->func.bind = dfu_bind;
+	dfu->func.set_alt = dfu_set_alt;
+	dfu->func.setup = dfu_setup;
+	dfu->func.disable = dfu_disable;
+	dfu->func.unbind = dfu_unbind;
+	dfu->func.free_func = dfu_free_func;
+
+	return &dfu->func;
+}
+
+static void dfu_free_instance(struct usb_function_instance *fi)
+{
+	struct f_dfu_opts *opts;
+
+	opts = container_of(fi, struct f_dfu_opts, func_inst);
+	kfree(opts);
+}
+
+static struct usb_function_instance *dfu_alloc_instance(void)
+{
+	struct f_dfu_opts *opts;
+
+	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+	if (!opts)
+		return ERR_PTR(-ENOMEM);
+	opts->func_inst.free_func_inst = dfu_free_instance;
+
+	return &opts->func_inst;
 }
 
+DECLARE_USB_FUNCTION_INIT(dfu, dfu_alloc_instance, dfu_alloc_func);
diff --git a/include/usb/dfu.h b/include/usb/dfu.h
index f9dd381..560a031 100644
--- a/include/usb/dfu.h
+++ b/include/usb/dfu.h
@@ -22,11 +22,13 @@
 
 #include <linux/types.h>
 #include <file-list.h>
+#include <usb/composite.h>
 
-struct usb_dfu_pdata {
-	struct file_list	*files;
+struct f_dfu_opts {
+	struct usb_function_instance func_inst;
+	struct file_list *files;
 };
 
-int usb_dfu_register(struct usb_dfu_pdata *);
+int usb_dfu_register(struct f_dfu_opts *);
 
 #endif /* _USB_DFU_H */
-- 
2.0.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2014-07-21 15:15 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-21 15:14 USB Gadget updates Sascha Hauer
2014-07-21 15:14 ` [PATCH 01/23] USB: gadget: Update to 3.15 Sascha Hauer
2014-07-21 15:14 ` [PATCH 02/23] USB: gadget: dequeue descriptor before freeing it Sascha Hauer
2014-07-21 15:14 ` [PATCH 03/23] USB: gadget: composite: Break out of potential endless loop Sascha Hauer
2014-07-21 15:14 ` [PATCH 04/23] USB: gadget: fsl_udc: Warn about freeing queued descriptors Sascha Hauer
2014-07-21 15:14 ` [PATCH 05/23] USB: gadget: usbserial: Always enable console Sascha Hauer
2014-07-21 15:14 ` [PATCH 06/23] param: Add dev_add_param_string Sascha Hauer
2014-07-21 15:14 ` [PATCH 07/23] USB: gadget: specify vendor/product id with device parameters Sascha Hauer
2014-07-21 15:14 ` [PATCH 08/23] USB: gadget: DFU: remove unused code Sascha Hauer
2014-07-21 15:14 ` [PATCH 09/23] USB: gadget: DFU: Use usb_assign_descriptors/usb_free_all_descriptors Sascha Hauer
2014-07-21 15:14 ` [PATCH 10/23] USB: gadget: DFU: Move locally used defines/structs to dfu driver Sascha Hauer
2014-07-21 15:14 ` [PATCH 11/23] Add function to parse a string in dfu format Sascha Hauer
2014-07-21 15:14 ` [PATCH 12/23] USB: gadget: DFU: Move stuff to dfu_bind Sascha Hauer
2014-07-21 15:14 ` [PATCH 13/23] USB: gadget: DFU: use usb_gstrings_attach Sascha Hauer
2014-07-21 15:14 ` [PATCH 14/23] USB: gadget: DFU: free resources when usb_gadget_poll fails Sascha Hauer
2014-07-21 15:14 ` [PATCH 15/23] USB: gadget: DFU: return -EINTR when interrupted Sascha Hauer
2014-07-21 15:14 ` Sascha Hauer [this message]
2014-07-21 15:14 ` [PATCH 17/23] USB: gadget: DFU: drop app idle state Sascha Hauer
2014-07-21 15:14 ` [PATCH 18/23] Add release string Sascha Hauer
2014-07-21 15:14 ` [PATCH 19/23] USB: gadget: Add Android fastboot support Sascha Hauer
2014-07-22  7:25   ` Holger Schurig
2014-07-22  9:23     ` Sascha Hauer
2014-07-21 15:14 ` [PATCH 20/23] USB: gadget: Add a multi function gadget Sascha Hauer
2014-07-21 15:14 ` [PATCH 21/23] USB: gadget: fsl_udc: Be more tolerant in fsl_ep_dequeue Sascha Hauer
2014-07-21 15:14 ` [PATCH 22/23] Documentation: Add documentation for USB serial console Sascha Hauer
2014-07-21 15:14 ` [PATCH 23/23] Documentation: Add documentation for Fastboot and Composite Multifunction Gadget Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1405955687-27433-17-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox