diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-11-18 22:51:51 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 22:55:25 +0300 |
commit | 47e9760529a9823be59d879f726acdc7e2fcbe11 (patch) | |
tree | d9c5d1ac662e0bd54c0b3a0fd40639ddcf4b177d | |
parent | 196f1b7a387546f425df2f1fad26772e3d513aea (diff) | |
download | linux-47e9760529a9823be59d879f726acdc7e2fcbe11.tar.xz |
USB: musb_gadget: implement set_wedge() method
Implement the driver's set_wedge() method by adding the 'wedged' flag
to the 'struct musb_ep'.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 20 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget_ep0.c | 6 |
3 files changed, 26 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 74073f9a43f0..173c963e7f02 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -966,6 +966,7 @@ static int musb_gadget_enable(struct usb_ep *ep, musb_ep->desc = desc; musb_ep->busy = 0; + musb_ep->wedged = 0; status = 0; pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n", @@ -1262,7 +1263,8 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value) goto done; } } - } + } else + musb_ep->wedged = 0; /* set/clear the stall and toggle bits */ DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear"); @@ -1301,6 +1303,21 @@ done: return status; } +/* + * Sets the halt feature with the clear requests ignored + */ +int musb_gadget_set_wedge(struct usb_ep *ep) +{ + struct musb_ep *musb_ep = to_musb_ep(ep); + + if (!ep) + return -EINVAL; + + musb_ep->wedged = 1; + + return usb_ep_set_halt(ep); +} + static int musb_gadget_fifo_status(struct usb_ep *ep) { struct musb_ep *musb_ep = to_musb_ep(ep); @@ -1371,6 +1388,7 @@ static const struct usb_ep_ops musb_ep_ops = { .queue = musb_gadget_queue, .dequeue = musb_gadget_dequeue, .set_halt = musb_gadget_set_halt, + .set_wedge = musb_gadget_set_wedge, .fifo_status = musb_gadget_fifo_status, .fifo_flush = musb_gadget_fifo_flush }; diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h index 59502da9f739..90966695ae53 100644 --- a/drivers/usb/musb/musb_gadget.h +++ b/drivers/usb/musb/musb_gadget.h @@ -75,6 +75,8 @@ struct musb_ep { /* later things are modified based on usage */ struct list_head req_list; + u8 wedged; + /* true if lock must be dropped but req_list may not be advanced */ u8 busy; }; diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 1c44b975049c..c63aff110c45 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -273,6 +273,11 @@ __acquires(musb->lock) if (!musb_ep->desc) break; + handled = 1; + /* Ignore request if endpoint is wedged */ + if (musb_ep->wedged) + break; + /* REVISIT do it directly, no locking games */ spin_unlock(&musb->lock); musb_gadget_set_halt(&musb_ep->end_point, 0); @@ -280,7 +285,6 @@ __acquires(musb->lock) /* select ep0 again */ musb_ep_select(mbase, 0); - handled = 1; } break; default: /* class, vendor, etc ... delegate */ |