usb:tests: kernel side patches
Subsystems (2)
v2 cover usb:tests: kernel side patches
This patch series adds support for 2 proprietary control request to be handled by dummy_hcd and g_zero gadget. These requests are used for testing purposes
Tatyana Brokhman (2):
usb:dummy_hcd: connect/disconnect test support
usb:g_zero: bulk in/out unittest support
drivers/usb/gadget/dummy_hcd.c | 53 ++++++++++++++ drivers/usb/gadget/f_sourcesink.c | 145 +++++++++++++++++++------------------ 2 files changed, 128 insertions(+), 70 deletions(-)
--
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 [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 1/2 usb:dummy_hcd: connect/disconnect test support
This implementation adds a new proprietary device control requests (to be handled by the dummy_hcd) that initiates a connect/disconnect sequence. The bRequest value of the new control request is 0x52.
It is used by the user-space Unit testing application.
--- drivers/usb/gadget/dummy_hcd.c | 53 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 53 insertions(+), 0 deletions(-)
drivers/usb/gadget/dummy_hcd.c +53 -0
@@ -61,6 +61,10 @@#define POWER_BUDGET 500/* in mA; use 8 for low-power port testing */ +/* Proprietary requests: values for the bRequest field of a SETUP packet. */ +/* TESTING: Connect/disconnect the device */ +#define USB_TEST_REQ_CONN_DISCON 0x52 +static const char driver_name [] ="dummy_hcd" ;static const char driver_desc [] ="USB Host+Gadget Emulator" ;
@@ -179,6 +183,7 @@ struct dummy_hcd { unsigned active:1; unsigned old_active:1; unsigned resuming:1; +struct work_struct conn_disc_work; };struct dummy {
@@ -1337,6 +1342,42 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address)#define Ep_Request (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT)#define Ep_InRequest (Ep_Request | USB_DIR_IN) +#define Dev_Test_Request (USB_TYPE_VENDOR | USB_RECIP_DEVICE) +#define Dev_Test_OutRequest (Dev_Test_Request | USB_DIR_OUT) + +/** +* dummy_hcd_conn_disc_work() - performs a disconnect/connect sequence. +* @data: pointer to the scheduled work_struct +*/ +static void dummy_hcd_conn_disc_work (struct work_struct *data) +{ +struct dummy_hcd *dum_hcd = + container_of(data, struct dummy_hcd, conn_disc_work); +int ret_val; + +if (!dum_hcd->dum->driver) { +dev_err (dummy_dev (dum_hcd), +"dummy_hcd_conn_disc_work called without connected " +"device\n" ); +return ; + } + +dev_info (dummy_dev (dum_hcd),"disconnecting device...\n" ); + ret_val =dummy_pullup (&dum_hcd->dum->gadget,0 ); +if (ret_val) { +dev_err (dummy_dev (dum_hcd),"%s: couldn't disconnect --> %d\n" , + __func__, ret_val); +return ; + } + +/* We have to let the hub task to update the device disconnect state */ +msleep_interruptible (1000 ); +dev_info (dummy_dev (dum_hcd),"re-connecting device...\n" ); + ret_val =dummy_pullup (&dum_hcd->dum->gadget,1 ); +if (ret_val) +dev_err (dummy_dev (dum_hcd),"%s: couldn't re-connect --> %d\n" , + __func__, ret_val); +}/** * handle_control_request() - handles all control transfers
@@ -1509,6 +1550,12 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb, *status =0 ; }break ; +case USB_TEST_REQ_CONN_DISCON : +if (setup->bRequestType == Dev_Test_OutRequest) { +schedule_work (&dum_hcd->conn_disc_work); + ret_val =0 ; + } +break ; }return ret_val; }
@@ -2224,6 +2271,8 @@ static int dummy_setup(struct usb_hcd *hcd)if (usb_hcd_is_primary_hcd (hcd)) { the_controller.hs_hcd =hcd_to_dummy_hcd (hcd); the_controller.hs_hcd->dum = &the_controller; +INIT_WORK (&the_controller.hs_hcd->conn_disc_work, + dummy_hcd_conn_disc_work);/* * Mark the first roothub as being USB 2.0. * The USB 3.0 roothub will be registered later by
@@ -2234,6 +2283,8 @@ static int dummy_setup(struct usb_hcd *hcd) }else { the_controller.ss_hcd =hcd_to_dummy_hcd (hcd); the_controller.ss_hcd->dum = &the_controller; +INIT_WORK (&the_controller.ss_hcd->conn_disc_work, + dummy_hcd_conn_disc_work); hcd->speed =HCD_USB3 ; hcd->self.root_hub->speed =USB_SPEED_SUPER ; }
@@ -2341,10 +2392,12 @@ static int dummy_hcd_remove(struct platform_device *pdev)if (dum->ss_hcd) {usb_remove_hcd (dummy_hcd_to_hcd (dum->ss_hcd));usb_put_hcd (dummy_hcd_to_hcd (dum->ss_hcd)); +cancel_work_sync (&dum->ss_hcd->conn_disc_work); }usb_remove_hcd (dummy_hcd_to_hcd (dum->hs_hcd));usb_put_hcd (dummy_hcd_to_hcd (dum->hs_hcd)); +cancel_work_sync (&dum->hs_hcd->conn_disc_work); the_controller.hs_hcd =NULL ; the_controller.ss_hcd =NULL ;
Signature · 5 lines
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.
Re: [RFC/PATCH v2 1/2] usb:dummy_hcd: connect/disconnect test support
Quoted 6 lines · * Tatyana Brokhman | 2011-06-22 11:39:00 [+0300]:
This implementation adds a new proprietary device control requests (to be handled by the
dummy_hcd) that initiates a connect/disconnect sequence. The bRequest value of the new control request is0x52.
It is used by the user-space Unit testing application.Signed-off-by Tatyana Linder <[email protected]>
As far as I understand this should be used to test real Hardware. Mind moving this to composite_setup() so it can be re-used by other ucd as well? usb_gadget_*nect() should do the pullup() trick.
Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [RFC/PATCH v2 1/2] usb:dummy_hcd: connect/disconnect test support
Hi Sebastian,
Quoted 6 lines · * Tatyana Brokhman | 2011-06-22 11:39:00 [+0300]:
Quoted 2 lines
This implementation adds a new proprietary device control requests (to
be
Quoted 1 line
handled by the
dummy_hcd) that initiates a connect/disconnectsequence.
Quoted 9 lines
Quoted 4 lines
The bRequest value of the new control request is
0x52. It is used by the user-space Unit testing application.Signed-off-by Tatyana Linder <[email protected]>As far as I understand this should be used to test real Hardware. Mind moving this to
composite_setup()so it can be re-used by other ucd as well? usb_gadget_*nect() should do thepullup()trick.
Felipe also suggested that on the last version of this patch. Here is a quote of his email on the subject:
"actually, this is quite useful. Specially for the controllers which _can_ do soft-connect by toggling data pullups. I would rather have these sort of thing maybe in composite.c, so that we can build tests with all gadget drivers/controllers, not only dummy_hcd.
That said, I think now it's not the time to fiddle too much with these details right now. So best to keep this in dummy_hcd until we know the test tools are actually good."
So, right now I'll leave it in dummy_hcd if it's ok with you.
Thanks,
Tanya Brokhman
---
Sent by an consultant of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
PATCH v2 2/2 usb:g_zero: bulk in/out unittest support
In reply to Tatyana BrokhmanThis 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.
--- drivers/usb/gadget/f_sourcesink.c | 145 +++++++++++++++++++------------------ 1 files changed, 75 insertions(+), 70 deletions(-)
drivers/usb/gadget/f_sourcesink.c +75 -70
@@ -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 */
Signature · 5 lines
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.