[RFC/PATCH v2 2/2] usb:g_zero: bulk in/out unittest support

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

 



This commit adds a new vendor specific request to be handled by the
g_zero module in it's sourcesink configuration. The purpose if this
request is to update the length of the BULK transfer to a given value.
The bRequest value of the new control request is 0x5e.
It is used by the user-space Unit testing application for bulk in/out
tests.

The sourcesink_setup function was moved to be ->setup() of the function
and not the configuration.

Signed-off-by: Tatyana Brokhman <tlinder@xxxxxxxxxxxxxx>

---
 drivers/usb/gadget/f_sourcesink.c |  145 +++++++++++++++++++------------------
 1 files changed, 75 insertions(+), 70 deletions(-)

diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index caf2f95..ff8840d 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -385,6 +385,80 @@ fail:
 	return result;
 }
 
+static int sourcesink_setup(struct usb_function *f,
+			    const struct usb_ctrlrequest *ctrl)
+{
+	struct f_sourcesink		*ss = func_to_ss(f);
+	struct usb_composite_dev	*cdev = f->config->cdev;
+	struct usb_request		*req = f->config->cdev->req;
+	int				retval = -EOPNOTSUPP;
+	u16				w_index = le16_to_cpu(ctrl->wIndex);
+	u16				w_value = le16_to_cpu(ctrl->wValue);
+	u16				w_length = le16_to_cpu(ctrl->wLength);
+
+	switch (ctrl->bRequest) {
+	/*
+	 * These are the same vendor-specific requests supported by
+	 * Intel's USB 2.0 compliance test devices.  We exceed that
+	 * device spec by allowing multiple-packet requests.
+	 *
+	 * NOTE:  the Control-OUT data stays in req->buf ... better
+	 * would be copying it into a scratch buffer, so that other
+	 * requests may safely intervene.
+	 */
+	case 0x5b:	/* control WRITE test -- fill the buffer */
+		if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
+			goto unknown;
+		if (w_value || w_index)
+			break;
+		/* just read that many bytes into the buffer */
+		if (w_length > req->length)
+			break;
+		retval = w_length;
+		break;
+	case 0x5c:	/* control READ test -- return the buffer */
+		if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
+			goto unknown;
+		if (w_value || w_index)
+			break;
+		/* expect those bytes are still in the buffer; send back */
+		if (w_length > req->length)
+			break;
+		retval = w_length;
+		break;
+
+	case 0x5e:
+		/*
+		 * Change bulk ep buffer size. buflen is the length of
+		 * the BULK transfer (req->length=buflen). Defined in g_zero.h
+		 */
+		disable_source_sink(ss);
+		buflen = w_value;
+		retval = enable_source_sink(cdev, ss);
+		break;
+	default:
+unknown:
+		VDBG(cdev, "unknown control req%02x.%02x v%04x i%04x l%d\n",
+		     ctrl->bRequestType, ctrl->bRequest,
+		     w_value, w_index, w_length);
+	}
+
+	/* respond with data transfer or status phase? */
+	if (retval >= 0) {
+		VDBG(cdev, "source/sink req%02x.%02x v%04x i%04x l%d\n",
+		     ctrl->bRequestType, ctrl->bRequest,
+		     w_value, w_index, w_length);
+		req->zero = 0;
+		req->length = retval;
+		retval = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
+		if (retval < 0)
+			ERROR(cdev, "source/sinkc response, err %d\n", retval);
+	}
+
+	/* device either stalls (value < 0) or reports success */
+	return retval;
+}
+
 static int sourcesink_set_alt(struct usb_function *f,
 		unsigned intf, unsigned alt)
 {
@@ -421,6 +495,7 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
 	ss->function.unbind = sourcesink_unbind;
 	ss->function.set_alt = sourcesink_set_alt;
 	ss->function.disable = sourcesink_disable;
+	ss->function.setup = sourcesink_setup;
 
 	status = usb_add_function(c, &ss->function);
 	if (status)
@@ -428,79 +503,9 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
 	return status;
 }
 
-static int sourcesink_setup(struct usb_configuration *c,
-		const struct usb_ctrlrequest *ctrl)
-{
-	struct usb_request	*req = c->cdev->req;
-	int			value = -EOPNOTSUPP;
-	u16			w_index = le16_to_cpu(ctrl->wIndex);
-	u16			w_value = le16_to_cpu(ctrl->wValue);
-	u16			w_length = le16_to_cpu(ctrl->wLength);
-
-	/* composite driver infrastructure handles everything except
-	 * the two control test requests.
-	 */
-	switch (ctrl->bRequest) {
-
-	/*
-	 * These are the same vendor-specific requests supported by
-	 * Intel's USB 2.0 compliance test devices.  We exceed that
-	 * device spec by allowing multiple-packet requests.
-	 *
-	 * NOTE:  the Control-OUT data stays in req->buf ... better
-	 * would be copying it into a scratch buffer, so that other
-	 * requests may safely intervene.
-	 */
-	case 0x5b:	/* control WRITE test -- fill the buffer */
-		if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
-			goto unknown;
-		if (w_value || w_index)
-			break;
-		/* just read that many bytes into the buffer */
-		if (w_length > req->length)
-			break;
-		value = w_length;
-		break;
-	case 0x5c:	/* control READ test -- return the buffer */
-		if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
-			goto unknown;
-		if (w_value || w_index)
-			break;
-		/* expect those bytes are still in the buffer; send back */
-		if (w_length > req->length)
-			break;
-		value = w_length;
-		break;
-
-	default:
-unknown:
-		VDBG(c->cdev,
-			"unknown control req%02x.%02x v%04x i%04x l%d\n",
-			ctrl->bRequestType, ctrl->bRequest,
-			w_value, w_index, w_length);
-	}
-
-	/* respond with data transfer or status phase? */
-	if (value >= 0) {
-		VDBG(c->cdev, "source/sink req%02x.%02x v%04x i%04x l%d\n",
-			ctrl->bRequestType, ctrl->bRequest,
-			w_value, w_index, w_length);
-		req->zero = 0;
-		req->length = value;
-		value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
-		if (value < 0)
-			ERROR(c->cdev, "source/sinkc response, err %d\n",
-					value);
-	}
-
-	/* device either stalls (value < 0) or reports success */
-	return value;
-}
-
 static struct usb_configuration sourcesink_driver = {
 	.label		= "source/sink",
 	.strings	= sourcesink_strings,
-	.setup		= sourcesink_setup,
 	.bConfigurationValue = 3,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
 	/* .iConfiguration = DYNAMIC */
-- 
1.7.0.4

--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
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