All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Baldyga <r.baldyga@samsung.com>
To: balbi@ti.com
Cc: gregkh@linuxfoundation.org, andrzej.p@samsung.com,
	m.szyprowski@samsung.com, b.zolnierkie@samsung.com,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	Robert Baldyga <r.baldyga@samsung.com>
Subject: [PATCH v4 01/43] usb: gadget: f_sourcesink: make ISO altset user-selectable
Date: Wed, 03 Feb 2016 13:39:09 +0100	[thread overview]
Message-ID: <1454503191-11796-2-git-send-email-r.baldyga@samsung.com> (raw)
In-Reply-To: <1454503191-11796-1-git-send-email-r.baldyga@samsung.com>

So far it was decided during the bind process whether is iso altsetting
included to f_sourcesink function or not. This decision was based on
availability of isochronous endpoints.

Since we can assemble gadget driver using composite framework and configfs
from many different functions, availability of given type of endpoint
can depend on selected components or even on their order in given
configuration.

This can result with non-obvious behavior - even small, seemingly unrelated
change in gadget configuration can decide if we have second altsetting with
iso endpoints in given sourcesink function instance or not.

Because of this it's way better to have additional parameter allowing user
to decide if he/she wants to have iso altsetting, and if iso altsetting is
included, and there are no iso endpoints available, function bind will fail
instead of silently allowing to have non-complete function bound.

Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
---
 drivers/usb/gadget/function/f_sourcesink.c | 98 ++++++++++++++++++++----------
 drivers/usb/gadget/function/g_zero.h       |  3 +
 drivers/usb/gadget/legacy/zero.c           |  6 ++
 3 files changed, 76 insertions(+), 31 deletions(-)

diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c
index 242ba5c..e950031 100644
--- a/drivers/usb/gadget/function/f_sourcesink.c
+++ b/drivers/usb/gadget/function/f_sourcesink.c
@@ -49,6 +49,7 @@ struct f_sourcesink {
 	unsigned isoc_maxpacket;
 	unsigned isoc_mult;
 	unsigned isoc_maxburst;
+	unsigned isoc_enabled;
 	unsigned buflen;
 	unsigned bulk_qlen;
 	unsigned iso_qlen;
@@ -336,17 +337,28 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 
 	/* allocate bulk endpoints */
 	ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
-	if (!ss->in_ep) {
-autoconf_fail:
-		ERROR(cdev, "%s: can't autoconfigure on %s\n",
-			f->name, cdev->gadget->name);
-		return -ENODEV;
-	}
+	if (!ss->in_ep)
+		goto autoconf_fail;
 
 	ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
 	if (!ss->out_ep)
 		goto autoconf_fail;
 
+	/* support high speed hardware */
+	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
+	hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
+
+	/* support super speed hardware */
+	ss_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
+	ss_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
+
+	if (!ss->isoc_enabled) {
+		fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL;
+		hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL;
+		ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
+		goto no_iso;
+	}
+
 	/* sanity check the isoc module parameters */
 	if (ss->isoc_interval < 1)
 		ss->isoc_interval = 1;
@@ -368,30 +380,14 @@ autoconf_fail:
 	/* allocate iso endpoints */
 	ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
 	if (!ss->iso_in_ep)
-		goto no_iso;
+		goto autoconf_fail;
 
 	ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
-	if (!ss->iso_out_ep) {
-		usb_ep_autoconfig_release(ss->iso_in_ep);
-		ss->iso_in_ep = NULL;
-no_iso:
-		/*
-		 * We still want to work even if the UDC doesn't have isoc
-		 * endpoints, so null out the alt interface that contains
-		 * them and continue.
-		 */
-		fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL;
-		hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL;
-		ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
-	}
+	if (!ss->iso_out_ep)
+		goto autoconf_fail;
 
 	if (ss->isoc_maxpacket > 1024)
 		ss->isoc_maxpacket = 1024;
-
-	/* support high speed hardware */
-	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
-	hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
-
 	/*
 	 * Fill in the HS isoc descriptors from the module parameters.
 	 * We assume that the user knows what they are doing and won't
@@ -408,12 +404,6 @@ no_iso:
 	hs_iso_sink_desc.bInterval = ss->isoc_interval;
 	hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
-	/* support super speed hardware */
-	ss_source_desc.bEndpointAddress =
-		fs_source_desc.bEndpointAddress;
-	ss_sink_desc.bEndpointAddress =
-		fs_sink_desc.bEndpointAddress;
-
 	/*
 	 * Fill in the SS isoc descriptors from the module parameters.
 	 * We assume that the user knows what they are doing and won't
@@ -436,6 +426,7 @@ no_iso:
 		(ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
 	ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
+no_iso:
 	ret = usb_assign_descriptors(f, fs_source_sink_descs,
 			hs_source_sink_descs, ss_source_sink_descs);
 	if (ret)
@@ -448,6 +439,11 @@ no_iso:
 			ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
 			ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
 	return 0;
+
+autoconf_fail:
+	ERROR(cdev, "%s: can't autoconfigure on %s\n",
+			f->name, cdev->gadget->name);
+	return -ENODEV;
 }
 
 static void
@@ -857,6 +853,7 @@ static struct usb_function *source_sink_alloc_func(
 	ss->isoc_maxpacket = ss_opts->isoc_maxpacket;
 	ss->isoc_mult = ss_opts->isoc_mult;
 	ss->isoc_maxburst = ss_opts->isoc_maxburst;
+	ss->isoc_enabled = ss_opts->isoc_enabled;
 	ss->buflen = ss_opts->bulk_buflen;
 	ss->bulk_qlen = ss_opts->bulk_qlen;
 	ss->iso_qlen = ss_opts->iso_qlen;
@@ -1106,6 +1103,44 @@ end:
 
 CONFIGFS_ATTR(f_ss_opts_, isoc_maxburst);
 
+static ssize_t f_ss_opts_isoc_enabled_show(struct config_item *item, char *page)
+{
+	struct f_ss_opts *opts = to_f_ss_opts(item);
+	int result;
+
+	mutex_lock(&opts->lock);
+	result = sprintf(page, "%u\n", opts->isoc_enabled);
+	mutex_unlock(&opts->lock);
+
+	return result;
+}
+
+static ssize_t f_ss_opts_isoc_enabled_store(struct config_item *item,
+				       const char *page, size_t len)
+{
+	struct f_ss_opts *opts = to_f_ss_opts(item);
+	int ret;
+	bool enabled;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	ret = strtobool(page, &enabled);
+	if (ret)
+		goto end;
+
+	opts->isoc_enabled = enabled;
+	ret = len;
+end:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+CONFIGFS_ATTR(f_ss_opts_, isoc_enabled);
+
 static ssize_t f_ss_opts_bulk_buflen_show(struct config_item *item, char *page)
 {
 	struct f_ss_opts *opts = to_f_ss_opts(item);
@@ -1226,6 +1261,7 @@ static struct configfs_attribute *ss_attrs[] = {
 	&f_ss_opts_attr_isoc_maxpacket,
 	&f_ss_opts_attr_isoc_mult,
 	&f_ss_opts_attr_isoc_maxburst,
+	&f_ss_opts_attr_isoc_enabled,
 	&f_ss_opts_attr_bulk_buflen,
 	&f_ss_opts_attr_bulk_qlen,
 	&f_ss_opts_attr_iso_qlen,
diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h
index 492924d0..ae03278 100644
--- a/drivers/usb/gadget/function/g_zero.h
+++ b/drivers/usb/gadget/function/g_zero.h
@@ -10,6 +10,7 @@
 #define GZERO_QLEN		32
 #define GZERO_ISOC_INTERVAL	4
 #define GZERO_ISOC_MAXPACKET	1024
+#define GZERO_ISOC_ENABLED	1
 #define GZERO_SS_BULK_QLEN	1
 #define GZERO_SS_ISO_QLEN	8
 
@@ -19,6 +20,7 @@ struct usb_zero_options {
 	unsigned isoc_maxpacket;
 	unsigned isoc_mult;
 	unsigned isoc_maxburst;
+	unsigned isoc_enabled;
 	unsigned bulk_buflen;
 	unsigned qlen;
 	unsigned ss_bulk_qlen;
@@ -32,6 +34,7 @@ struct f_ss_opts {
 	unsigned isoc_maxpacket;
 	unsigned isoc_mult;
 	unsigned isoc_maxburst;
+	unsigned isoc_enabled;
 	unsigned bulk_buflen;
 	unsigned bulk_qlen;
 	unsigned iso_qlen;
diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c
index d02e2ce..6adfc88 100644
--- a/drivers/usb/gadget/legacy/zero.c
+++ b/drivers/usb/gadget/legacy/zero.c
@@ -66,6 +66,7 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
 static struct usb_zero_options gzero_options = {
 	.isoc_interval = GZERO_ISOC_INTERVAL,
 	.isoc_maxpacket = GZERO_ISOC_MAXPACKET,
+	.isoc_enabled = GZERO_ISOC_ENABLED,
 	.bulk_buflen = GZERO_BULK_BUFLEN,
 	.qlen = GZERO_QLEN,
 	.ss_bulk_qlen = GZERO_SS_BULK_QLEN,
@@ -251,6 +252,10 @@ module_param_named(isoc_maxburst, gzero_options.isoc_maxburst, uint,
 		S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
 
+module_param_named(isoc_enabled, gzero_options.isoc_enabled, uint,
+		S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(isoc_enabled, "0 - disabled, 1 - enabled");
+
 static struct usb_function *func_lb;
 static struct usb_function_instance *func_inst_lb;
 
@@ -294,6 +299,7 @@ static int zero_bind(struct usb_composite_dev *cdev)
 	ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket;
 	ss_opts->isoc_mult = gzero_options.isoc_mult;
 	ss_opts->isoc_maxburst = gzero_options.isoc_maxburst;
+	ss_opts->isoc_enabled = gzero_options.isoc_enabled;
 	ss_opts->bulk_buflen = gzero_options.bulk_buflen;
 	ss_opts->bulk_qlen = gzero_options.ss_bulk_qlen;
 	ss_opts->iso_qlen = gzero_options.ss_iso_qlen;
-- 
1.9.1

  reply	other threads:[~2016-02-03 12:56 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-03 12:39 [PATCH v4 00/43] usb: gadget: composite: introduce new function API Robert Baldyga
2016-02-03 12:39 ` Robert Baldyga [this message]
2016-02-03 12:39 ` [PATCH v4 02/43] usb: gadget: f_sourcesink: free requests in sourcesink_disable() Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 03/43] usb: gadget: f_loopback: free requests in loopback_disable() Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 04/43] usb: gadget: configfs: fix error path Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 05/43] usb: gadget: composite: fix recursive spinlock locking Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 06/43] usb: gadget: composite: introduce new descriptors format Robert Baldyga
2016-02-04  5:16   ` kbuild test robot
2016-02-03 12:39 ` [PATCH v4 07/43] usb: gadget: composite: add functions for descriptors handling Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 08/43] usb: gadget: composite: introduce new USB function ops Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 09/43] usb: gadget: composite: handle function bind Robert Baldyga
2016-02-04  5:42   ` kbuild test robot
2016-02-03 12:39 ` [PATCH v4 10/43] usb: gadget: composite: handle vendor descs Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 11/43] usb: gadget: composite: generate old descs for compatibility Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 12/43] usb: gadget: composite: disable eps before calling disable() callback Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 13/43] usb: gadget: composite: enable eps before calling set_alt() callback Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 14/43] usb: gadget: composite: introduce clear_alt() operation Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 15/43] usb: gadget: composite: handle get_alt() automatically Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 16/43] usb: gadget: composite: add usb_function_get_ep() function Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 17/43] usb: gadget: composite: add usb_get_interface_id() function Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 18/43] usb: gadget: composite: usb_get_endpoint_address() function Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 19/43] usb: gadget: composite: enable adding USB functions using new API Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 20/43] usb: gadget: configfs: add new composite API support Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 21/43] usb: gadget: f_loopback: convert to new API Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 22/43] usb: gadget: f_sourcesink: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 23/43] usb: gadget: f_ecm: conversion " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 24/43] usb: gadget: f_rndis: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 25/43] usb: gadget: f_hid: handle requests lifetime properly Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 26/43] usb: gadget: f_hid: conversion to new API Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 27/43] usb: gadget: f_acm: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 28/43] usb: gadget: f_eem: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 29/43] usb: gadget: f_ncm: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 30/43] usb: gadget: f_printer: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 31/43] usb: gadget: f_serial: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 32/43] usb: gadget: f_obex: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 33/43] usb: gadget: f_phonet: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 34/43] usb: gadget: f_subset: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 35/43] usb: gadget: f_uac1: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 36/43] usb: gadget: f_uac2: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 37/43] usb: gadget: f_mass_storage: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 38/43] usb: gadget: u_serial: remove usb_ep_enable()/usb_ep_disable() Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 39/43] usb: gadget: u_ether: " Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 40/43] usb: gadget: uvc: fix typo in UVCG_OPTS_ATTR() macro Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 41/43] usb: gadget: uvc: simplify descriptors generation Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 42/43] Documentation: update uvc configfs interface description Robert Baldyga
2016-02-03 12:39 ` [PATCH v4 43/43] usb: gadget: f_uvc: conversion to new API Robert Baldyga

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=1454503191-11796-2-git-send-email-r.baldyga@samsung.com \
    --to=r.baldyga@samsung.com \
    --cc=andrzej.p@samsung.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=balbi@ti.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.