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

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

commit 8520a4086699e99b20b169d837626a8cf9813cc8
Author: dinglongfei <[email protected]>
AuthorDate: Wed Jun 21 14:46:34 2023 +0800

    usb:When the adbd task is running, the usb uninstall process will panic in 
the adbd task, because the memory of the adb driver has been freed.
    
    unbind will call the adb_char_on_connect interface to wake up the adbd task,
    adbd will then access the adb device and fail to return, at this time it 
will
    close the adb device, we can do the final memory release operation in the
    second unbind
    
    Signed-off-by: dinglongfei <[email protected]>
---
 drivers/usbdev/adb.c       | 23 ++++++++++++++++++++++-
 drivers/usbdev/composite.c |  5 +++++
 drivers/usbdev/rndis.c     | 14 ++++++++++----
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/usbdev/adb.c b/drivers/usbdev/adb.c
index 64aa5f8078..6a75b11113 100644
--- a/drivers/usbdev/adb.c
+++ b/drivers/usbdev/adb.c
@@ -161,6 +161,8 @@ struct usbdev_adb_s
    * EPBULKIN; Read requests will be queued in the EBULKOUT.
    */
 
+  bool registered;                    /* Has register_driver() been called */
+
   struct usbadb_wrreq_s wrreqs[CONFIG_USBADB_NWRREQS];
   struct usbadb_rdreq_s rdreqs[CONFIG_USBADB_NRDREQS];
 
@@ -1545,6 +1547,7 @@ static int usbclass_classobject(int minor,
       goto exit_free_driver;
     }
 
+  alloc->dev.registered = true;
   *classdev = &alloc->drvr;
   return OK;
 
@@ -1571,10 +1574,28 @@ static void usbclass_uninitialize(FAR struct 
usbdevclass_driver_s *classdev)
     classdev, FAR struct adb_driver_s, drvr);
 
   #warning FIXME Maybe missing logic here
+  if (!alloc->dev.registered)
+    {
+      if (alloc->dev.crefs == 0)
+        {
+#ifdef CONFIG_USBADB_COMPOSITE
+          kmm_free(alloc);
+#endif
+        }
+
+      return;
+    }
 
   unregister_driver(USBADB_CHARDEV_PATH);
 
-  kmm_free(alloc);
+  if (alloc->dev.registered)
+    {
+      alloc->dev.registered = false;
+#ifndef CONFIG_USBADB_COMPOSITE
+      kmm_free(alloc);
+#endif
+      return;
+    }
 }
 
 /****************************************************************************
diff --git a/drivers/usbdev/composite.c b/drivers/usbdev/composite.c
index bcf3fdb138..b3795b5c2b 100644
--- a/drivers/usbdev/composite.c
+++ b/drivers/usbdev/composite.c
@@ -994,6 +994,11 @@ void composite_uninitialize(FAR void *handle)
 
   priv = &alloc->dev;
 
+  for (i = 0; i < priv->ndevices; i++)
+    {
+      priv->device[i].compdesc.uninitialize(priv->device[i].dev);
+    }
+
   /* Then unregister and destroy the composite class */
 
   usbdev_unregister(&alloc->drvr.drvr);
diff --git a/drivers/usbdev/rndis.c b/drivers/usbdev/rndis.c
index 4f7dcfe86f..145a1a6925 100644
--- a/drivers/usbdev/rndis.c
+++ b/drivers/usbdev/rndis.c
@@ -2880,15 +2880,21 @@ static void usbclass_uninitialize(FAR struct 
usbdevclass_driver_s *classdev)
 {
   FAR struct rndis_driver_s *drvr = (FAR struct rndis_driver_s *)classdev;
   FAR struct rndis_alloc_s *alloc = (FAR struct rndis_alloc_s *)drvr->dev;
-
+  if (!alloc->dev.registered)
+    {
+#ifdef CONFIG_USBADB_COMPOSITE
+      kmm_free(alloc);
+#endif
+      return;
+    }
   if (drvr->dev->registered)
     {
       netdev_unregister(&drvr->dev->netdev);
       drvr->dev->registered = false;
-    }
-  else
-    {
+#ifndef CONFIG_RNDIS_COMPOSITE
       kmm_free(alloc);
+#endif
+      return;
     }
 }
 

Reply via email to