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

commit a7af894cd390b575d8b077337d7950d92c17cd7e
Author: yangsong8 <[email protected]>
AuthorDate: Fri Jun 27 15:00:58 2025 +0800

    driver/usbhost: use small lock to protect usbhost cdcmbim
    
    replace critical_section with spinlock
    
    Signed-off-by: yangsong8 <[email protected]>
---
 drivers/usbhost/usbhost_cdcmbim.c | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/usbhost/usbhost_cdcmbim.c 
b/drivers/usbhost/usbhost_cdcmbim.c
index 2acc4bb3ed3..e70551257e9 100644
--- a/drivers/usbhost/usbhost_cdcmbim.c
+++ b/drivers/usbhost/usbhost_cdcmbim.c
@@ -43,6 +43,7 @@
 #include <nuttx/kmalloc.h>
 #include <nuttx/kthread.h>
 #include <nuttx/mutex.h>
+#include <nuttx/spinlock.h>
 #include <nuttx/fs/fs.h>
 #include <nuttx/wqueue.h>
 #include <nuttx/signal.h>
@@ -200,6 +201,7 @@ struct usbhost_cdcmbim_s
   uint16_t                dataif;       /* Data interface number */
   int16_t                 crefs;        /* Reference count on the driver 
instance */
   mutex_t                 lock;         /* Used to maintain mutual exclusive 
access */
+  spinlock_t              spinlock;     /* Used to protect critical section */
   struct work_s           ntwork;       /* Notification work */
   struct work_s           comm_rxwork;  /* Communication interface RX work */
   struct work_s           bulk_rxwork;
@@ -360,6 +362,8 @@ static const struct file_operations g_cdcwdm_fops =
 
 static uint32_t g_devinuse;
 
+static spinlock_t g_lock = SP_UNLOCKED;
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -401,7 +405,7 @@ static ssize_t usbhost_readmessage(FAR struct 
usbhost_cdcmbim_s *priv,
   irqstate_t flags;
   ssize_t ret = -EAGAIN;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->spinlock);
 
   if (priv->comm_rxlen > 0)
     {
@@ -421,7 +425,7 @@ static ssize_t usbhost_readmessage(FAR struct 
usbhost_cdcmbim_s *priv,
         }
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->spinlock, flags);
   return ret;
 }
 
@@ -676,7 +680,7 @@ static int usbhost_allocdevno(FAR struct usbhost_cdcmbim_s 
*priv)
   irqstate_t flags;
   int devno;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&g_lock);
   for (devno = 0; devno < 32; devno++)
     {
       uint32_t bitno = 1 << devno;
@@ -684,12 +688,12 @@ static int usbhost_allocdevno(FAR struct 
usbhost_cdcmbim_s *priv)
         {
           g_devinuse |= bitno;
           priv->minor = devno;
-          leave_critical_section(flags);
+          spin_unlock_irqrestore(&g_lock, flags);
           return OK;
         }
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&g_lock, flags);
   return -EMFILE;
 }
 
@@ -699,9 +703,9 @@ static void usbhost_freedevno(FAR struct usbhost_cdcmbim_s 
*priv)
 
   if (devno >= 0 && devno < 26)
     {
-      irqstate_t flags = enter_critical_section();
+      irqstate_t flags = spin_lock_irqsave(&g_lock);
       g_devinuse &= ~(1 << devno);
-      leave_critical_section(flags);
+      spin_unlock_irqrestore(&g_lock, flags);
     }
 }
 
@@ -1927,6 +1931,7 @@ usbhost_create(FAR struct usbhost_hubport_s *hport,
           /* Initialize mutex (this works in the interrupt context) */
 
           nxmutex_init(&priv->lock);
+          spin_lock_init(&priv->spinlock);
 
           /* Return the instance of the USB class driver */
 
@@ -2045,7 +2050,7 @@ static int usbhost_disconnected(FAR struct 
usbhost_class_s *usbclass)
    * longer available.
    */
 
-  flags              = enter_critical_section();
+  flags              = spin_lock_irqsave(&priv->spinlock);
   priv->disconnected = true;
 
   /* Now check the number of references on the class instance.  If it is one,
@@ -2057,6 +2062,8 @@ static int usbhost_disconnected(FAR struct 
usbhost_class_s *usbclass)
   uinfo("crefs: %d\n", priv->crefs);
   if (priv->crefs == 1)
     {
+      spin_unlock_irqrestore(&priv->spinlock, flags);
+
       /* Destroy the class instance.  If we are executing from an interrupt
        * handler, then defer the destruction to the worker thread.
        * Otherwise, destroy the instance now.
@@ -2078,9 +2085,11 @@ static int usbhost_disconnected(FAR struct 
usbhost_class_s *usbclass)
 
           usbhost_destroy(priv);
         }
+
+      return OK;
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->spinlock, flags);
   return OK;
 }
 
@@ -2363,13 +2372,13 @@ static int cdcmbim_ifdown(FAR struct net_driver_s *dev)
       (FAR struct usbhost_cdcmbim_s *)dev->d_private;
   irqstate_t flags;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->spinlock);
 
   /* Mark the device "down" */
 
   priv->bifup = false;
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->spinlock, flags);
   return OK;
 }
 

Reply via email to