From ac2b495945f1dadd3f992c430e5bb0885fe8f8c8 Mon Sep 17 00:00:00 2001 From: wangzhi16 Date: Wed, 15 Jan 2025 14:09:34 +0800 Subject: [PATCH] Use small lock to protect usbdev and endpoint in arch mips Signed-off-by: wangzhi16 --- 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 0e0bb90d40bbf..11565900a6a77 100644 --- a/arch/mips/src/pic32mx/pic32mx_usbdev.c +++ b/arch/mips/src/pic32mx/pic32mx_usbdev.c @@ -44,8 +44,10 @@ #include #include #include +#include #include +#include #include #include #include @@ -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; }