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;
}