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