lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-id: <1454503191-11796-14-git-send-email-r.baldyga@samsung.com>
Date:	Wed, 03 Feb 2016 13:39:21 +0100
From:	Robert Baldyga <r.baldyga@...sung.com>
To:	balbi@...com
Cc:	gregkh@...uxfoundation.org, andrzej.p@...sung.com,
	m.szyprowski@...sung.com, b.zolnierkie@...sung.com,
	linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org,
	Robert Baldyga <r.baldyga@...sung.com>
Subject: [PATCH v4 13/43] usb: gadget: composite: enable eps before calling
 set_alt() callback

Change set_alt() behavior for functions using new API. Before we call
set_alt() callback, we disable endpoints of previously selected altsetting,
and enable endpoints of currently selected altsetting, which reduces
amount of boilerplate code in USB functions.

We also calculate index of interface in function and pass it to set_alt()
callback instead of passing index of interface in configuration which has
to be obtained from interface descriptor. This simplifies altsetting
changes handling in code of USB functions.

Signed-off-by: Robert Baldyga <r.baldyga@...sung.com>
---
 drivers/usb/gadget/composite.c | 83 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f2c08b3..0c962d4 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -650,6 +650,26 @@ static void usb_function_free_vendor_descs(struct usb_function *f)
 }
 
 /**
+ * usb_interface_id_to_index - if interface with a specified id belongs
+ *	to given USB function, return its index within descriptors array
+ *	of this function
+ * @f: USB function
+ * @id: id number of interface
+ *
+ * Returns interface index on success, else negative errno.
+ */
+static int usb_interface_id_to_index(struct usb_function *f, u8 id)
+{
+	int i;
+
+	for (i = 0; i < f->descs->intfs_num; ++i)
+		if (f->descs->intfs[i]->id == id)
+			return i;
+
+	return -EINVAL;
+}
+
+/**
  * usb_interface_id() - allocate an unused interface ID
  * @config: configuration associated with the interface
  * @function: function handling the interface
@@ -995,6 +1015,65 @@ static void reset_config(struct usb_composite_dev *cdev)
 	cdev->delayed_status = 0;
 }
 
+/**
+ * set_alt() - select specified altsetting in given interface
+ * @f: USB function
+ * @i: interface id number
+ * @a: altsetting number
+ *
+ * This function has different behavior depending on which API is used by
+ * given USB function. For functions using old API behavior stays unchanged,
+ * while for functions using new API index of interface in function is
+ * calculated and endpoints are configured and enabled before calling
+ * set_alt() callback.
+ */
+static int set_alt(struct usb_function *f, unsigned i, unsigned a)
+{
+	struct usb_composite_dev *cdev = f->config->cdev;
+	struct usb_composite_altset *alt;
+	struct usb_composite_ep *ep;
+	int e, ret = -EINVAL;
+
+	/* To be removed after switch to new API */
+	if (!usb_function_is_new_api(f))
+		return f->set_alt(f, i, a);
+
+	i = usb_interface_id_to_index(f, i);
+	if (i < 0)
+		return i;
+
+	disable_interface(f, i);
+
+	if (a >= f->descs->intfs[i]->altsets_num)
+		return -EINVAL;
+
+	alt = f->descs->intfs[i]->altsets[a];
+	for (e = 0; e < alt->eps_num; ++e) {
+		ep = alt->eps[e];
+		ret = config_ep_by_speed(cdev->gadget, f, ep->ep);
+		if (ret)
+			goto err;
+		ret = usb_ep_enable(ep->ep);
+		if (ret)
+			goto err;
+	}
+
+	f->descs->intfs[i]->cur_altset = a;
+	ret = f->set_alt(f, i, a);
+	if (ret == USB_GADGET_DELAYED_STATUS)
+		goto out;
+	if (ret < 0)
+		goto err;
+
+	return 0;
+err:
+	for (e = 0; e < alt->eps_num; ++e)
+		usb_ep_disable(alt->eps[e]->ep);
+	f->descs->intfs[i]->cur_altset = -1;
+out:
+	return ret;
+}
+
 static int set_config(struct usb_composite_dev *cdev,
 		const struct usb_ctrlrequest *ctrl, unsigned number)
 {
@@ -1074,7 +1153,7 @@ static int set_config(struct usb_composite_dev *cdev,
 			set_bit(addr, f->endpoints);
 		}
 
-		result = f->set_alt(f, tmp, 0);
+		result = set_alt(f, tmp, 0);
 		if (result < 0) {
 			DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n",
 					tmp, f->name, f, result);
@@ -1975,7 +2054,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
 			break;
 		if (w_value && !f->set_alt)
 			break;
-		value = f->set_alt(f, w_index, w_value);
+		value = set_alt(f, w_index, w_value);
 		if (value == USB_GADGET_DELAYED_STATUS) {
 			DBG(cdev,
 			 "%s: interface %d (%s) requested delayed status\n",
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ