aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/mod_gadget.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-11-24 20:28:04 -0500
committerFelipe Balbi <balbi@ti.com>2011-12-12 04:45:16 -0500
commit17f7f76940214af91bfefcf9a2ca156701d905e6 (patch)
treeba11ca3a5c1d5cc8d8b0db004f252db23ffd3158 /drivers/usb/renesas_usbhs/mod_gadget.c
parentced6e09e6ec4f52c9bd76d6b8debd67517fdcc1c (diff)
usb: renesas_usbhs: add basic USB_REQ_GET_STATUS support
This patch adds basic get-status support for chapter 9 test. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_gadget.c')
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 3130089eacff..812960ba95e1 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -305,6 +305,104 @@ struct usbhsg_recip_handle req_set_feature = {
305}; 305};
306 306
307/* 307/*
308 * USB_TYPE_STANDARD / get status functions
309 */
310static void __usbhsg_recip_send_complete(struct usb_ep *ep,
311 struct usb_request *req)
312{
313 struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
314
315 /* free allocated recip-buffer/usb_request */
316 kfree(ureq->pkt.buf);
317 usb_ep_free_request(ep, req);
318}
319
320static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv,
321 unsigned short status)
322{
323 struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
324 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp);
325 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
326 struct usb_request *req;
327 unsigned short *buf;
328
329 /* alloc new usb_request for recip */
330 req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC);
331 if (!req) {
332 dev_err(dev, "recip request allocation fail\n");
333 return;
334 }
335
336 /* alloc recip data buffer */
337 buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
338 if (!buf) {
339 usb_ep_free_request(&dcp->ep, req);
340 dev_err(dev, "recip data allocation fail\n");
341 return;
342 }
343
344 /* recip data is status */
345 *buf = cpu_to_le16(status);
346
347 /* allocated usb_request/buffer will be freed */
348 req->complete = __usbhsg_recip_send_complete;
349 req->buf = buf;
350 req->length = sizeof(*buf);
351 req->zero = 0;
352
353 /* push packet */
354 pipe->handler = &usbhs_fifo_pio_push_handler;
355 usbhsg_queue_push(dcp, usbhsg_req_to_ureq(req));
356}
357
358static int usbhsg_recip_handler_std_get_device(struct usbhs_priv *priv,
359 struct usbhsg_uep *uep,
360 struct usb_ctrlrequest *ctrl)
361{
362 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
363 unsigned short status = 1 << USB_DEVICE_SELF_POWERED;
364
365 __usbhsg_recip_send_status(gpriv, status);
366
367 return 0;
368}
369
370static int usbhsg_recip_handler_std_get_interface(struct usbhs_priv *priv,
371 struct usbhsg_uep *uep,
372 struct usb_ctrlrequest *ctrl)
373{
374 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
375 unsigned short status = 0;
376
377 __usbhsg_recip_send_status(gpriv, status);
378
379 return 0;
380}
381
382static int usbhsg_recip_handler_std_get_endpoint(struct usbhs_priv *priv,
383 struct usbhsg_uep *uep,
384 struct usb_ctrlrequest *ctrl)
385{
386 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
387 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
388 unsigned short status = 0;
389
390 if (usbhs_pipe_is_stall(pipe))
391 status = 1 << USB_ENDPOINT_HALT;
392
393 __usbhsg_recip_send_status(gpriv, status);
394
395 return 0;
396}
397
398struct usbhsg_recip_handle req_get_status = {
399 .name = "get status",
400 .device = usbhsg_recip_handler_std_get_device,
401 .interface = usbhsg_recip_handler_std_get_interface,
402 .endpoint = usbhsg_recip_handler_std_get_endpoint,
403};
404
405/*
308 * USB_TYPE handler 406 * USB_TYPE handler
309 */ 407 */
310static int usbhsg_recip_run_handle(struct usbhs_priv *priv, 408static int usbhsg_recip_run_handle(struct usbhs_priv *priv,
@@ -431,6 +529,9 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
431 case USB_REQ_SET_FEATURE: 529 case USB_REQ_SET_FEATURE:
432 recip_handler = &req_set_feature; 530 recip_handler = &req_set_feature;
433 break; 531 break;
532 case USB_REQ_GET_STATUS:
533 recip_handler = &req_get_status;
534 break;
434 } 535 }
435 } 536 }
436 537