>From 6868dd3db38574ec486707dbbe303a3958ad1ff3 Mon Sep 17 00:00:00 2001 From: Markus Pietrek <markus.pietrek@xxxxxxxxxx> Date: Fri, 4 Jun 2010 09:59:13 +0200 Signed-off-by: Markus Pietrek <markus.pietrek@xxxxxxxxxx> --- drivers/usb/gadget/isp1181_udc.c | 54 +++++++++++++++++++++++++++++++------ drivers/usb/gadget/isp1181_udc.h | 1 + 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/isp1181_udc.c b/drivers/usb/gadget/isp1181_udc.c index 7e6ae14..b1e93d9 100644 --- a/drivers/usb/gadget/isp1181_udc.c +++ b/drivers/usb/gadget/isp1181_udc.c @@ -598,30 +598,60 @@ static void isp1181_set_halt(struct isp1181_priv *priv, struct isp1181_ep *ep, i isp1181_hep_stall(priv, &priv->hep[to_hnum(ep->num)], value); } -static int isp1181_ep_set_halt(struct usb_ep *_ep, int value) +static int isp1181_ep_set_halt_locked(struct usb_ep *_ep, int value) { struct isp1181_ep *ep = to_isp1181_ep(_ep); struct isp1181_hep *hep = to_isp1181_hep(ep); struct isp1181_priv *priv = ep->priv; - unsigned long flags; int active; if (!_ep) return -EINVAL; - spin_lock_irqsave(&priv->lock, flags); - active = (hep->active_in.req != NULL); if (!ep->num && !active) active = (priv->hep[HW_EP0_OUT].active_in.req != NULL); - if (!active) + if (!active) { /* we can't halt an endpoint which might be read by the host in the moment */ isp1181_set_halt(priv, ep, value); + return 0; + } else + return -EAGAIN; +} + +static int isp1181_ep_set_halt(struct usb_ep *_ep, int value) +{ + struct isp1181_ep *ep = to_isp1181_ep(_ep); + struct isp1181_priv *priv = ep->priv; + unsigned long flags; + int retval; + + spin_lock_irqsave(&priv->lock, flags); + retval = isp1181_ep_set_halt_locked(_ep, value); + + if (!value) + ep->wedge = 0; + + spin_unlock_irqrestore(&priv->lock, flags); + + return retval; +} + +static int isp1181_ep_set_wedge(struct usb_ep *_ep) +{ + struct isp1181_ep *ep = to_isp1181_ep(_ep); + struct isp1181_priv *priv = ep->priv; + unsigned long flags; + int retval; + + spin_lock_irqsave(&priv->lock, flags); + ep->wedge = 1; + retval = isp1181_ep_set_halt_locked(_ep, 1); spin_unlock_irqrestore(&priv->lock, flags); - return active ? -EAGAIN : 0; + return retval; } static void isp1181_ep_fifo_flush(struct usb_ep *_ep) @@ -647,7 +677,7 @@ static struct usb_ep_ops isp1181_ep_ops = { .dequeue = isp1181_ep_dequeue, .set_halt = isp1181_ep_set_halt, - + .set_wedge = isp1181_ep_set_wedge, .fifo_flush = isp1181_ep_fifo_flush, }; @@ -758,6 +788,7 @@ static int isp1181_get_status(struct isp1181_priv *priv, const struct usb_ctrlre static void isp1181_handle_setup(struct isp1181_priv *priv) { struct usb_ctrlrequest crq; + struct isp1181_ep *ep; int len; int handled = 0; int ep_num; @@ -799,8 +830,13 @@ static void isp1181_handle_setup(struct isp1181_priv *priv) if (ep_num >= ISP1181_ENDPOINTS) break; - isp1181_set_halt(priv, &priv->ep[ep_num], - (crq.bRequest==USB_REQ_CLEAR_FEATURE) ? 0 : 1); + ep = &priv->ep[ep_num]; + if (crq.bRequest==USB_REQ_CLEAR_FEATURE) { + if (!ep->wedge) + isp1181_set_halt(priv, ep, 0); + } else + isp1181_set_halt(priv, ep, 1); + isp1181_write_zero(priv); handled = 1; break; diff --git a/drivers/usb/gadget/isp1181_udc.h b/drivers/usb/gadget/isp1181_udc.h index 235acc7..23f017c 100644 --- a/drivers/usb/gadget/isp1181_udc.h +++ b/drivers/usb/gadget/isp1181_udc.h @@ -140,6 +140,7 @@ struct isp1181_request { struct isp1181_ep { struct isp1181_priv *priv; struct usb_ep ep; + int wedge; const struct usb_endpoint_descriptor *desc; int num; /* EP0...EPn */ -- 1.6.3.3 _____________________________________ Amtsgericht Mannheim HRB 110 300 Geschäftsführer: Dieter Baur, Ramona Maurer _____________________________________ Important Note: - This e-mail may contain trade secrets or privileged, undisclosed or otherwise confidential information. - If you have received this e-mail in error, you are hereby notified that any review, copying or distribution of it is strictly prohibited. - Please inform us immediately and destroy the original transmittal. Thank you for your cooperation. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html