aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/dummy_hcd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-17 15:43:52 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-17 15:43:52 -0700
commit0cfd81031a26717fe14380d18275f8e217571615 (patch)
tree78a84e4cb97e7f45eb77dc0fbd8857a5dd717869 /drivers/usb/gadget/dummy_hcd.c
parentf7ea4a4ba84f382e8eb143e435551de0feee5b4b (diff)
parent802f389a2cc6e2771b8de915ac241456d41eb79e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (94 commits) USB: remove err() macro from more usb drivers USB: remove err() macro from usb misc drivers USB: remove err() macro from usb core code USB: remove err() macro from usb class drivers USB: remove use of err() in drivers/usb/serial USB: remove info() macro from usb mtd drivers USB: remove info() macro from usb input drivers USB: remove info() macro from usb network drivers USB: remove info() macro from remaining usb drivers USB: remove info() macro from usb/misc drivers USB: remove info() macro from usb/serial drivers USB: remove warn macro from HID core USB: remove warn() macro from usb drivers USB: remove warn() macro from usb net drivers USB: remove warn() macro from usb media drivers USB: remove warn() macro from usb input drivers usb/fsl_qe_udc: clear data toggle on clear halt request usb/fsl_qe_udc: fix response to get status request fsl_usb2_udc: Fix oops on probe failure. fsl_usb2_udc: Add a wmb before priming endpoint. ...
Diffstat (limited to 'drivers/usb/gadget/dummy_hcd.c')
-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 7600a0c7875..9064696636a 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -82,6 +82,7 @@ struct dummy_ep {
const struct usb_endpoint_descriptor *desc;
struct usb_ep ep;
unsigned halted : 1;
+ unsigned wedged : 1;
unsigned already_seen : 1;
unsigned setup_stage : 1;
};
@@ -436,6 +437,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
/* at this point real hardware should be NAKing transfers
* to that endpoint, until a buffer is queued to it.
*/
+ ep->halted = ep->wedged = 0;
retval = 0;
done:
return retval;
@@ -597,7 +599,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
}
static int
-dummy_set_halt (struct usb_ep *_ep, int value)
+dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
{
struct dummy_ep *ep;
struct dummy *dum;
@@ -609,16 +611,32 @@ dummy_set_halt (struct usb_ep *_ep, int value)
if (!dum->driver)
return -ESHUTDOWN;
if (!value)
- ep->halted = 0;
+ ep->halted = ep->wedged = 0;
else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
!list_empty (&ep->queue))
return -EAGAIN;
- else
+ else {
ep->halted = 1;
+ if (wedged)
+ ep->wedged = 1;
+ }
/* FIXME clear emulated data toggle too */
return 0;
}
+static int
+dummy_set_halt(struct usb_ep *_ep, int value)
+{
+ return dummy_set_halt_and_wedge(_ep, value, 0);
+}
+
+static int dummy_set_wedge(struct usb_ep *_ep)
+{
+ if (!_ep || _ep->name == ep0name)
+ return -EINVAL;
+ return dummy_set_halt_and_wedge(_ep, 1, 1);
+}
+
static const struct usb_ep_ops dummy_ep_ops = {
.enable = dummy_enable,
.disable = dummy_disable,
@@ -630,6 +648,7 @@ static const struct usb_ep_ops dummy_ep_ops = {
.dequeue = dummy_dequeue,
.set_halt = dummy_set_halt,
+ .set_wedge = dummy_set_wedge,
};
/*-------------------------------------------------------------------------*/
@@ -760,7 +779,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
ep->ep.name = ep_name [i];
ep->ep.ops = &dummy_ep_ops;
list_add_tail (&ep->ep.ep_list, &dum->gadget.ep_list);
- ep->halted = ep->already_seen = ep->setup_stage = 0;
+ ep->halted = ep->wedged = ep->already_seen =
+ ep->setup_stage = 0;
ep->ep.maxpacket = ~0;
ep->last_io = jiffies;
ep->gadget = &dum->gadget;
@@ -1351,7 +1371,7 @@ restart:
} else if (setup.bRequestType == Ep_Request) {
// endpoint halt
ep2 = find_endpoint (dum, w_index);
- if (!ep2) {
+ if (!ep2 || ep2->ep.name == ep0name) {
value = -EOPNOTSUPP;
break;
}
@@ -1380,7 +1400,8 @@ restart:
value = -EOPNOTSUPP;
break;
}
- ep2->halted = 0;
+ if (!ep2->wedged)
+ ep2->halted = 0;
value = 0;
status = 0;
}