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

acassis 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 50f93a986a0 drivers/usbhost: Register the partitions on a mass storage 
device.
50f93a986a0 is described below

commit 50f93a986a00f6f9092c2f5d9059989a124f4dd3
Author: Justin Hammond <[email protected]>
AuthorDate: Wed Aug 5 10:13:51 2026 +0800

    drivers/usbhost: Register the partitions on a mass storage device.
    
    A drive that has been anywhere near another operating system almost
    always carries a partition table rather than a filesystem starting at
    sector zero, so the single block device this driver registers is usually
    the one thing nobody can mount.  A USB stick written with an installer
    image is a good example: sector zero holds a protective MBR, and what
    somebody wants is the EFI system partition several gigabytes in.
    
    Read the table and give each partition a block device of its own beside
    the whole drive, named the way every other system names them.  The
    parsing is already in the tree and understands both MBR and GPT; this
    only calls it and registers what it finds.
    
    The whole-drive node stays exactly where it was, for anyone who wants
    the raw thing or whose drive really does hold a bare filesystem.
    
    Assisted-by: Claude:claude-opus-5
    Signed-off-by: Justin Hammond <[email protected]>
---
 drivers/usbhost/Kconfig           | 15 ++++++++++++
 drivers/usbhost/usbhost_storage.c | 48 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/usbhost/Kconfig b/drivers/usbhost/Kconfig
index 4d98e382bb6..2aae3cdae68 100644
--- a/drivers/usbhost/Kconfig
+++ b/drivers/usbhost/Kconfig
@@ -141,6 +141,21 @@ config USBHOST_MSC
        ---help---
                Enable support for the mass storage class driver.
 
+config USBHOST_MSC_PARTITIONS
+       bool "Register partitions found on a drive"
+       default y
+       depends on USBHOST_MSC && !DISABLE_MOUNTPOINT
+       depends on MBR_PARTITION || GPT_PARTITION
+       ---help---
+               Read the partition table of a mass storage device and register a
+               block device for each partition, /dev/sda1 beside /dev/sda and 
so
+               on.
+
+               Most drives that have been anywhere near another operating 
system
+               carry a partition table rather than a filesystem at sector zero,
+               so without this a perfectly good drive cannot be mounted.  The
+               whole-drive node stays where it was.
+
 config USBHOST_MSC_NOTIFIER
        bool "Support USB Mass Storage notifications"
        default n
diff --git a/drivers/usbhost/usbhost_storage.c 
b/drivers/usbhost/usbhost_storage.c
index ecb3eae76cb..13de617f172 100644
--- a/drivers/usbhost/usbhost_storage.c
+++ b/drivers/usbhost/usbhost_storage.c
@@ -43,6 +43,7 @@
 #include <nuttx/wqueue.h>
 #include <nuttx/scsi.h>
 #include <nuttx/fs/fs.h>
+#include <nuttx/fs/partition.h>
 #include <nuttx/mutex.h>
 
 #include <nuttx/usb/usb.h>
@@ -870,6 +871,41 @@ static inline int usbhost_inquiry(FAR struct 
usbhost_state_s *priv)
   return nbytes < 0 ? (int)nbytes : OK;
 }
 
+#ifdef CONFIG_USBHOST_MSC_PARTITIONS
+/****************************************************************************
+ * Name: usbhost_part_handler
+ *
+ * Description:
+ *   Give one partition found on a drive a block device of its own, named
+ *   after the drive it came from with the partition number after it, which
+ *   is the convention every other system uses.
+ *
+ ****************************************************************************/
+
+static void usbhost_part_handler(FAR struct partition_s *part, FAR void *arg)
+{
+  FAR const char *devname = arg;
+  char            partname[DEV_NAMELEN + 4];
+
+  if (part->nblocks == 0)
+    {
+      return;
+    }
+
+  snprintf(partname, sizeof(partname), "%s%zu", devname, part->index + 1);
+
+  if (register_blockpartition(partname, 0, devname, part->firstblock,
+                              part->nblocks) < 0)
+    {
+      uerr("ERROR: cannot register %s\n", partname);
+      return;
+    }
+
+  uinfo("%s: %zu blocks from %zu\n", partname, part->nblocks,
+        part->firstblock);
+}
+#endif
+
 /****************************************************************************
  * Name: usbhost_destroy
  *
@@ -1331,6 +1367,18 @@ static inline int usbhost_initvolume(FAR struct 
usbhost_state_s *priv)
       uinfo("Register block driver\n");
       usbhost_mkdevname(priv, devname);
       ret = register_blockdriver(devname, &g_bops, 0, priv);
+
+#ifdef CONFIG_USBHOST_MSC_PARTITIONS
+      /* Such a drive is usually partitioned rather than holding a
+       * filesystem outright.  Give each partition a block device beside
+       * the whole drive, which stays available.
+       */
+
+      if (ret >= 0)
+        {
+          parse_block_partition(devname, usbhost_part_handler, devname);
+        }
+#endif
     }
 
   /* Decrement the reference count.  We incremented the reference count

Reply via email to