[PATCH] isp1181_udc: implemented .set_wedge()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux