This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new ac2b495945 Use small lock to protect usbdev and endpoint in arch mips
ac2b495945 is described below

commit ac2b495945f1dadd3f992c430e5bb0885fe8f8c8
Author: wangzhi16 <[email protected]>
AuthorDate: Wed Jan 15 14:09:34 2025 +0800

    Use small lock to protect usbdev and endpoint in arch mips
    
    Signed-off-by: wangzhi16 <[email protected]>
---
 arch/mips/src/pic32mx/pic32mx_usbdev.c | 62 +++++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/arch/mips/src/pic32mx/pic32mx_usbdev.c 
b/arch/mips/src/pic32mx/pic32mx_usbdev.c
index 0e0bb90d40..11565900a6 100644
--- a/arch/mips/src/pic32mx/pic32mx_usbdev.c
+++ b/arch/mips/src/pic32mx/pic32mx_usbdev.c
@@ -44,8 +44,10 @@
 #include <assert.h>
 #include <errno.h>
 #include <debug.h>
+#include <sched.h>
 
 #include <nuttx/arch.h>
+#include <nuttx/spinlock.h>
 #include <nuttx/wdog.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/usb/usb.h>
@@ -407,6 +409,10 @@ struct pic32mx_usbdev_s
   /* The endpoint list */
 
   struct pic32mx_ep_s      eplist[PIC32MX_NENDPOINTS];
+
+  /* Spinlock */
+
+  spinlock_t               lock;
 };
 
 /****************************************************************************
@@ -797,9 +803,9 @@ static void pic32mx_reqcomplete(struct pic32mx_ep_s 
*privep, int16_t result)
    * request list.
    */
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&privep->dev->lock);
   privreq = pic32mx_remfirst(&privep->active);
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&privep->dev->lock, flags);
 
   if (privreq)
     {
@@ -3003,7 +3009,7 @@ static void pic32mx_resume(struct pic32mx_usbdev_s *priv)
   irqstate_t flags;
   uint16_t regval;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
 
   /* Start RESUME signaling */
 
@@ -3051,7 +3057,7 @@ static void pic32mx_resume(struct pic32mx_usbdev_s *priv)
       CLASS_RESUME(priv->driver, &priv->usbdev);
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 /****************************************************************************
@@ -3069,7 +3075,7 @@ pic32mx_epreserve(struct pic32mx_usbdev_s *priv, uint8_t 
epset)
   irqstate_t flags;
   int epndx = 0;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
   epset &= priv->epavail;
   if (epset)
     {
@@ -3094,7 +3100,7 @@ pic32mx_epreserve(struct pic32mx_usbdev_s *priv, uint8_t 
epset)
         }
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
   return privep;
 }
 
@@ -3106,9 +3112,9 @@ static inline void
 pic32mx_epunreserve(struct pic32mx_usbdev_s *priv,
                     struct pic32mx_ep_s *privep)
 {
-  irqstate_t flags = enter_critical_section();
+  irqstate_t flags = spin_lock_irqsave(&priv->lock);
   priv->epavail   |= PIC32MX_ENDP_BIT(USB_EPNO(privep->ep.eplog));
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 /****************************************************************************
@@ -3328,7 +3334,8 @@ static int pic32mx_epdisable(struct usbdev_ep_s *ep)
 
   /* Cancel any ongoing activity */
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&privep->dev->lock);
+  sched_lock();
   pic32mx_cancelrequests(privep, -ESHUTDOWN);
 
   /* Disable the endpoint */
@@ -3345,7 +3352,8 @@ static int pic32mx_epdisable(struct usbdev_ep_s *ep)
       *ptr++ = 0;
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&privep->dev->lock, flags);
+  sched_unlock();
   return OK;
 }
 
@@ -3445,7 +3453,8 @@ static int pic32mx_epsubmit(struct usbdev_ep_s *ep, 
struct usbdev_req_s *req)
 #ifndef CONFIG_USBDEV_NOWRITEAHEAD
   privreq->inflight[1] = 0;
 #endif
-  flags                = enter_critical_section();
+  flags                = spin_lock_irqsave(&priv->lock);
+  sched_lock();
 
   /* Add the new request to the request queue for the OUT endpoint */
 
@@ -3489,7 +3498,8 @@ static int pic32mx_epsubmit(struct usbdev_ep_s *ep, 
struct usbdev_req_s *req)
         }
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
+  sched_unlock();
   return ret;
 }
 
@@ -3512,9 +3522,11 @@ static int pic32mx_epcancel(struct usbdev_ep_s *ep, 
struct usbdev_req_s *req)
 
   usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog));
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&privep->dev->lock);
+  sched_lock();
   pic32mx_cancelrequests(privep, -EAGAIN);
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&privep->dev->lock, flags);
+  sched_unlock();
   return OK;
 }
 
@@ -3705,7 +3717,8 @@ static int pic32mx_epstall(struct usbdev_ep_s *ep, bool 
resume)
 
   /* STALL or RESUME the endpoint */
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&privep->dev->lock);
+  sched_lock();
 
   /* Special case EP0.  When we stall EP0 we have to stall both the IN and
    * OUT BDTs.
@@ -3734,7 +3747,8 @@ static int pic32mx_epstall(struct usbdev_ep_s *ep, bool 
resume)
       ret = pic32mx_epbdtstall(ep, resume, USB_ISEPIN(ep->eplog));
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&privep->dev->lock, flags);
+  sched_unlock();
   return ret;
 }
 
@@ -4336,6 +4350,10 @@ void mips_usbinitialize(void)
 
   usbtrace(TRACE_DEVINIT, 0);
 
+  /* Initialize driver lock */
+
+  spin_lock_init(&priv->lock);
+
   /* Initialize the driver state structure */
 
   pic32mx_stateinit(priv);
@@ -4383,7 +4401,8 @@ void mips_usbuninitialize(void)
   struct pic32mx_usbdev_s *priv = &g_usbdev;
   irqstate_t flags;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
+  sched_lock();
   usbtrace(TRACE_DEVUNINIT, 0);
 
   /* Disable and detach the USB IRQs */
@@ -4400,7 +4419,8 @@ void mips_usbuninitialize(void)
   /* Put the hardware in an inactive state */
 
   pic32mx_hwshutdown(priv);
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
+  sched_unlock();
 }
 
 /****************************************************************************
@@ -4504,7 +4524,8 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver)
    * the hardware back into its initial, unconnected state.
    */
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
+  sched_lock();
   pic32mx_swreset(priv);
   pic32mx_hwreset(priv);
 
@@ -4527,7 +4548,8 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver)
   /* Unhook the driver */
 
   priv->driver = NULL;
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
+  sched_unlock();
   return OK;
 }
 

Reply via email to