From 4558db18e447e77c4dac7c8b0d7099b56e2b4d67 Mon Sep 17 00:00:00 2001 From: wangzhi16 Date: Wed, 15 Jan 2025 15:55:33 +0800 Subject: [PATCH] Use small lock to protect usbdev and endpoint in sim. Signed-off-by: wangzhi16 --- arch/sim/src/sim/sim_usbdev.c | 57 ++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/arch/sim/src/sim/sim_usbdev.c b/arch/sim/src/sim/sim_usbdev.c index f04e84a582..71f8dabe2d 100644 --- a/arch/sim/src/sim/sim_usbdev.c +++ b/arch/sim/src/sim/sim_usbdev.c @@ -36,9 +36,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -156,6 +158,7 @@ struct sim_usbdev_s uint8_t selfpowered:1; /* 1: Device is self powered */ uint16_t epavail; /* Bitset of available endpoints */ struct sim_ep_s eps[SIM_USB_EPNUM]; + spinlock_t lock; /* Spinlock */ }; struct sim_req_s @@ -347,9 +350,9 @@ static void sim_reqcomplete(struct sim_ep_s *privep, int16_t result) /* Remove the completed request at the head of the endpoint request list */ - flags = enter_critical_section(); + flags = spin_lock_irqsave(&privep->dev->lock); privreq = sim_rqdequeue(&privep->reqq); - leave_critical_section(flags); + spin_unlock_irqrestore(&privep->dev->lock, flags); if (privreq) { @@ -640,7 +643,8 @@ static int sim_ep_disable(struct usbdev_ep_s *ep) /* Cancel any ongoing activity */ - flags = enter_critical_section(); + flags = spin_lock_irqsave(&privep->dev->lock); + sched_lock(); /* Disable TX; disable RX */ @@ -648,7 +652,8 @@ static int sim_ep_disable(struct usbdev_ep_s *ep) privep->epstate = SIM_EPSTATE_DISABLED; - leave_critical_section(flags); + spin_unlock_irqrestore(&privep->dev->lock, flags); + sched_unlock(); return OK; } @@ -703,14 +708,16 @@ static int sim_ep_stall(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(); usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, epno); ret = host_usbdev_epstall(epno, resume); privep->epstate = SIM_EPSTATE_STALLED; - leave_critical_section(flags); + spin_unlock_irqrestore(&privep->dev->lock, flags); + sched_unlock(); return ret; } @@ -738,12 +745,14 @@ static int sim_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) epno = USB_EPNO(ep->eplog); req->result = -EINPROGRESS; req->xfrd = 0; - flags = enter_critical_section(); + flags = spin_lock_irqsave(&priv->lock); + sched_lock(); if (privep->epstate == SIM_EPSTATE_STALLED) { sim_reqabort(privep, privreq, -EBUSY); - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); + sched_unlock(); return -EPERM; } @@ -778,7 +787,8 @@ static int sim_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) sim_rqenqueue(&privep->reqq, privreq); } - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); + sched_unlock(); return ret; } @@ -788,13 +798,14 @@ static int sim_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) static int sim_ep_cancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) { + struct sim_ep_s *privep = (struct sim_ep_s *)ep; irqstate_t flags; usbtrace(TRACE_EPCANCEL, USB_EPNO(ep->eplog)); - flags = enter_critical_section(); + flags = spin_lock_irqsave(&privep->dev->lock); host_usbdev_epcancel(USB_EPNO(ep->eplog)); - leave_critical_section(flags); + spin_unlock_irqrestore(&privep->dev->lock, flags); return OK; } @@ -818,7 +829,7 @@ static struct sim_ep_s *sim_ep_reserve(struct sim_usbdev_s *priv, irqstate_t flags; int epndx = 0; - flags = enter_critical_section(); + flags = spin_lock_irqsave(&priv->lock); epset &= priv->epavail; if (epset) { @@ -843,7 +854,7 @@ static struct sim_ep_s *sim_ep_reserve(struct sim_usbdev_s *priv, } } - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); return privep; } @@ -860,9 +871,9 @@ static struct sim_ep_s *sim_ep_reserve(struct sim_usbdev_s *priv, static void sim_ep_unreserve(struct sim_usbdev_s *priv, struct sim_ep_s *privep) { - irqstate_t flags = enter_critical_section(); + irqstate_t flags = spin_lock_irqsave(&priv->lock); priv->epavail |= SIM_EP_BIT(USB_EPNO(privep->ep.eplog)); - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); } /**************************************************************************** @@ -1004,13 +1015,14 @@ static int sim_usbdev_selfpowered(struct usbdev_s *dev, bool selfpowered) static int sim_usbdev_pullup(struct usbdev_s *dev, bool enable) { + struct sim_usbdev_s *priv = (struct sim_usbdev_s *)dev; irqstate_t flags; usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); - flags = enter_critical_section(); + flags = spin_lock_irqsave(&priv->lock); host_usbdev_pullup(enable); - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); return OK; } @@ -1059,6 +1071,9 @@ static void sim_usbdev_devinit(struct sim_usbdev_s *dev) void sim_usbdev_initialize(void) { + /* Initialize driver lock */ + + spin_lock_init(&g_sim_usbdev.lock); } /**************************************************************************** @@ -1132,9 +1147,9 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver) * canceled while the class driver is still bound. */ - flags = enter_critical_section(); + flags = spin_lock_irqsave(&priv->lock); CLASS_DISCONNECT(driver, &priv->usbdev); - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); /* Unbind the class driver */ @@ -1142,7 +1157,7 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver) /* Disable USB controller interrupts */ - flags = enter_critical_section(); + flags = spin_lock_irqsave(&priv->lock); /* Disconnect device */ @@ -1152,7 +1167,7 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver) /* Unhook the driver */ priv->driver = NULL; - leave_critical_section(flags); + spin_unlock_irqrestore(&priv->lock, flags); return OK; }