aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-08-14 15:48:30 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-17 17:40:52 -0400
commit851a526dcf97964265cadcc6664a9f0ff7c143c7 (patch)
treefaf8bdb4322b89db72f8c1c8738733a9b86dba2f /drivers/usb/gadget
parenta7a19fac8a9fbc0182fb1b464848a31529c39433 (diff)
USB: gadget: dummy_hcd: implement set_wedge
This patch (as1131) implements the set_wedge() method for dummy_hcd. This method is necessary for strict USBCV compliance in g_file_storage. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/dummy_hcd.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 7600a0c78753..9064696636ac 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -82,6 +82,7 @@ struct dummy_ep {
82 const struct usb_endpoint_descriptor *desc; 82 const struct usb_endpoint_descriptor *desc;
83 struct usb_ep ep; 83 struct usb_ep ep;
84 unsigned halted : 1; 84 unsigned halted : 1;
85 unsigned wedged : 1;
85 unsigned already_seen : 1; 86 unsigned already_seen : 1;
86 unsigned setup_stage : 1; 87 unsigned setup_stage : 1;
87}; 88};
@@ -436,6 +437,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
436 /* at this point real hardware should be NAKing transfers 437 /* at this point real hardware should be NAKing transfers
437 * to that endpoint, until a buffer is queued to it. 438 * to that endpoint, until a buffer is queued to it.
438 */ 439 */
440 ep->halted = ep->wedged = 0;
439 retval = 0; 441 retval = 0;
440done: 442done:
441 return retval; 443 return retval;
@@ -597,7 +599,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
597} 599}
598 600
599static int 601static int
600dummy_set_halt (struct usb_ep *_ep, int value) 602dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
601{ 603{
602 struct dummy_ep *ep; 604 struct dummy_ep *ep;
603 struct dummy *dum; 605 struct dummy *dum;
@@ -609,16 +611,32 @@ dummy_set_halt (struct usb_ep *_ep, int value)
609 if (!dum->driver) 611 if (!dum->driver)
610 return -ESHUTDOWN; 612 return -ESHUTDOWN;
611 if (!value) 613 if (!value)
612 ep->halted = 0; 614 ep->halted = ep->wedged = 0;
613 else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && 615 else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
614 !list_empty (&ep->queue)) 616 !list_empty (&ep->queue))
615 return -EAGAIN; 617 return -EAGAIN;
616 else 618 else {
617 ep->halted = 1; 619 ep->halted = 1;
620 if (wedged)
621 ep->wedged = 1;
622 }
618 /* FIXME clear emulated data toggle too */ 623 /* FIXME clear emulated data toggle too */
619 return 0; 624 return 0;
620} 625}
621 626
627static int
628dummy_set_halt(struct usb_ep *_ep, int value)
629{
630 return dummy_set_halt_and_wedge(_ep, value, 0);
631}
632
633static int dummy_set_wedge(struct usb_ep *_ep)
634{
635 if (!_ep || _ep->name == ep0name)
636 return -EINVAL;
637 return dummy_set_halt_and_wedge(_ep, 1, 1);
638}
639
622static const struct usb_ep_ops dummy_ep_ops = { 640static const struct usb_ep_ops dummy_ep_ops = {
623 .enable = dummy_enable, 641 .enable = dummy_enable,
624 .disable = dummy_disable, 642 .disable = dummy_disable,
@@ -630,6 +648,7 @@ static const struct usb_ep_ops dummy_ep_ops = {
630 .dequeue = dummy_dequeue, 648 .dequeue = dummy_dequeue,
631 649
632 .set_halt = dummy_set_halt, 650 .set_halt = dummy_set_halt,
651 .set_wedge = dummy_set_wedge,
633}; 652};
634 653
635/*-------------------------------------------------------------------------*/ 654/*-------------------------------------------------------------------------*/
@@ -760,7 +779,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
760 ep->ep.name = ep_name [i]; 779 ep->ep.name = ep_name [i];
761 ep->ep.ops = &dummy_ep_ops; 780 ep->ep.ops = &dummy_ep_ops;
762 list_add_tail (&ep->ep.ep_list, &dum->gadget.ep_list); 781 list_add_tail (&ep->ep.ep_list, &dum->gadget.ep_list);
763 ep->halted = ep->already_seen = ep->setup_stage = 0; 782 ep->halted = ep->wedged = ep->already_seen =
783 ep->setup_stage = 0;
764 ep->ep.maxpacket = ~0; 784 ep->ep.maxpacket = ~0;
765 ep->last_io = jiffies; 785 ep->last_io = jiffies;
766 ep->gadget = &dum->gadget; 786 ep->gadget = &dum->gadget;
@@ -1351,7 +1371,7 @@ restart:
1351 } else if (setup.bRequestType == Ep_Request) { 1371 } else if (setup.bRequestType == Ep_Request) {
1352 // endpoint halt 1372 // endpoint halt
1353 ep2 = find_endpoint (dum, w_index); 1373 ep2 = find_endpoint (dum, w_index);
1354 if (!ep2) { 1374 if (!ep2 || ep2->ep.name == ep0name) {
1355 value = -EOPNOTSUPP; 1375 value = -EOPNOTSUPP;
1356 break; 1376 break;
1357 } 1377 }
@@ -1380,7 +1400,8 @@ restart:
1380 value = -EOPNOTSUPP; 1400 value = -EOPNOTSUPP;
1381 break; 1401 break;
1382 } 1402 }
1383 ep2->halted = 0; 1403 if (!ep2->wedged)
1404 ep2->halted = 0;
1384 value = 0; 1405 value = 0;
1385 status = 0; 1406 status = 0;
1386 } 1407 }