From cb3e4b749134a8e4f26d1dd7bfd2d3ece38105a4 Mon Sep 17 00:00:00 2001 From: rongbaichuan Date: Mon, 31 Aug 2026 01:09:12 +0800 Subject: [PATCH] boards: fix mtd_partition() argument units in flash partition loops mtd_partition(mtd, firstblock, nblocks) takes the partition offset and size in units of the underlying device "blocks" (geo.blocksize), not erase blocks. Several board drivers accumulated partoffset and computed the partition size in erase-block units and passed them straight to mtd_partition(), so on devices where blocksize != erasesize (W25/SST25: 256B vs 4KB, SAMD5E5 progmem: 512B vs 8KB) every partition came out erasesize/blocksize (16x) too small and misaligned. Convert partoffset and partszbytes to geo.blocksize units at the mtd_partition() call site while keeping the erase-block accumulation. Affected boards: - stm32f103-minimum (W25) - at32f437-mini (W25) - stm32f429i-disco (SST25F064, enabled in the extflash defconfig) - metro-m4 (SAMD5E5 progmem) Also fix pre-existing nxstyle violations in the touched files so the change passes checkpatch (see CONTRIBUTING.md). Assisted-by: DeepSeek Harness:deepseek-v4-flash Signed-off-by: rongbaichuan --- boards/arm/at32/at32f437-mini/src/at32_w25.c | 218 ++++++++++-------- boards/arm/samd5e5/metro-m4/src/sam_smartfs.c | 179 +++++++------- .../stm32f1/stm32f103-minimum/src/stm32_w25.c | 15 +- .../stm32f429i-disco/src/stm32_bringup.c | 21 +- 4 files changed, 244 insertions(+), 189 deletions(-) diff --git a/boards/arm/at32/at32f437-mini/src/at32_w25.c b/boards/arm/at32/at32f437-mini/src/at32_w25.c index bd8dc736d8a5d..aa53967595d81 100644 --- a/boards/arm/at32/at32f437-mini/src/at32_w25.c +++ b/boards/arm/at32/at32f437-mini/src/at32_w25.c @@ -129,6 +129,7 @@ int at32_w25initialize(int minor) /* Register the MTD driver */ char path[32]; + snprintf(path, sizeof(path), "/dev/mtdblock%d", minor); ret = register_mtddriver(path, mtd, 0755, NULL); if (ret < 0) @@ -141,136 +142,149 @@ int at32_w25initialize(int minor) /* Initialize to provide SMARTFS on the MTD interface */ #ifdef FLASH_PART -{ - int partno; - int partsize; - int partoffset; - int partszbytes; - int erasesize; - const char *partstring = FLASH_PART_LIST; - const char *ptr; - struct mtd_dev_s *mtd_part; - char partref[16]; - struct mtd_geometry_s geo; - - /* Now create a partition on the FLASH device */ - - partno = 0; - ptr = partstring; - partoffset = 0; - - /* Get the geometry of the FLASH device */ - - ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo)); - if (ret < 0) - { - syslog(LOG_ERR, "ERROR: mtd->ioctl failed: %d\n", ret); - return ret; - } - - /* Get the Flash erase size */ - - erasesize = geo.erasesize; - - while (*ptr != '\0') + do { - /* Get the partition size */ - - partsize = atoi(ptr); - partszbytes = (partsize << 10); /* partsize is defined in KB */ - - /* Check if partition size is bigger then erase block */ - - if (partszbytes < erasesize) + int partno; + int partsize; + int partoffset; + int partszbytes; + int erasesize; + int blkpererase; + const char *partstring = FLASH_PART_LIST; + const char *ptr; + struct mtd_dev_s *mtd_part; + char partref[16]; + struct mtd_geometry_s geo; + + /* Now create a partition on the FLASH device */ + + partno = 0; + ptr = partstring; + partoffset = 0; + + /* Get the geometry of the FLASH device */ + + ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, + (unsigned long)((uintptr_t)&geo)); + if (ret < 0) { - syslog(LOG_ERR, - "ERROR: Partition size is lesser than erasesize!\n"); - return -1; + syslog(LOG_ERR, "ERROR: mtd->ioctl failed: %d\n", ret); + return ret; } - /* Check if partition size is multiple of erase block */ + /* Get the Flash erase size */ - if ((partszbytes % erasesize) != 0) + erasesize = geo.erasesize; + + while (*ptr != '\0') { - syslog(LOG_ERR, - "ERROR: Partition size isn't multiple of erasesize!\n"); - return -1; - } + /* Get the partition size */ + + partsize = atoi(ptr); + partszbytes = (partsize << 10); /* partsize is defined in KB */ + + /* Check if partition size is bigger then erase block */ + + if (partszbytes < erasesize) + { + syslog(LOG_ERR, + "ERROR: Partition size is lesser than erasesize!\n"); + return -1; + } + + /* Check if partition size is multiple of erase block */ + + if ((partszbytes % erasesize) != 0) + { + syslog(LOG_ERR, + "ERROR: Partition size isn't multiple of erasesize!\n"); + return -1; + } + + /* mtd_partition() expects the offset and size in units of the + * underlying device "blocks" (geo.blocksize, 256B for the W25), + * not erase blocks. partoffset is tracked in erase blocks, so + * convert. Without this, partitions are erasesize/blocksize + * (16x for the W25) too small and misaligned. + */ - mtd_part = mtd_partition(mtd, partoffset, partszbytes / erasesize); - partoffset += partszbytes / erasesize; + blkpererase = geo.blocksize > 0 ? erasesize / geo.blocksize : 1; + mtd_part = mtd_partition(mtd, partoffset * blkpererase, + partszbytes / geo.blocksize); + partoffset += partszbytes / erasesize; #ifdef FLASH_CONFIG_PART - /* Test if this is the config partition */ + /* Test if this is the config partition */ - if (FLASH_CONFIG_PART_NUMBER == partno) - { - /* Register the partition as the config device */ + if (FLASH_CONFIG_PART_NUMBER == partno) + { + /* Register the partition as the config device */ - mtdconfig_register(mtd_part); - } - else + mtdconfig_register(mtd_part); + } + else #endif - { - /* Now initialize a SMART Flash block device and bind it - * to the MTD device. - */ + { + /* Now initialize a SMART Flash block device and bind it + * to the MTD device. + */ #if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) - snprintf(partref, sizeof(partref), "p%d", partno); - smart_initialize(W25QXX_FLASH_MINOR, - mtd_part, partref); + snprintf(partref, sizeof(partref), "p%d", partno); + smart_initialize(W25QXX_FLASH_MINOR, + mtd_part, partref); #endif - } + } - /* Set the partition name */ + /* Set the partition name */ #if defined(CONFIG_MTD_PARTITION_NAMES) - if (!mtd_part) - { - syslog(LOG_ERR, "Error: failed to create partition %s\n", - partname); - return -1; - } - - mtd_setpartitionname(mtd_part, partname); - - /* Now skip to next name. We don't need to split the string here - * because the MTD partition logic will only display names up to - * the comma, thus allowing us to use a single static name - * in the code. - */ + if (!mtd_part) + { + syslog(LOG_ERR, "Error: failed to create partition %s\n", + partname); + return -1; + } + + mtd_setpartitionname(mtd_part, partname); + + /* Now skip to next name. We don't need to split the string here + * because the MTD partition logic will only display names up to + * the comma, thus allowing us to use a single static name + * in the code. + */ - while (*partname != ',' && *partname != '\0') - { - /* Skip to next ',' */ + while (*partname != ',' && *partname != '\0') + { + /* Skip to next ',' */ - partname++; - } + partname++; + } - if (*partname == ',') - { - partname++; - } + if (*partname == ',') + { + partname++; + } #endif - /* Update the pointer to point to the next size in the list */ + /* Update the pointer to point to the next size in the list */ - while ((*ptr >= '0') && (*ptr <= '9')) - { - ptr++; - } + while ((*ptr >= '0') && (*ptr <= '9')) + { + ptr++; + } - if (*ptr == ',') - { - ptr++; - } + if (*ptr == ',') + { + ptr++; + } - /* Increment the part number */ + /* Increment the part number */ - partno++; + partno++; + } } -} + while (0); #else /* CONFIG_FLASH_PART */ diff --git a/boards/arm/samd5e5/metro-m4/src/sam_smartfs.c b/boards/arm/samd5e5/metro-m4/src/sam_smartfs.c index 1bdea7f5b2df8..f66dfe062af5b 100644 --- a/boards/arm/samd5e5/metro-m4/src/sam_smartfs.c +++ b/boards/arm/samd5e5/metro-m4/src/sam_smartfs.c @@ -93,13 +93,15 @@ int sam_smartfs_initialize(void) return ret; } - #ifdef CONFIG_MTD_PARTITION +#ifdef CONFIG_MTD_PARTITION + do { int partno; int partsize; int partoffset; int partszbytes; int erasesize; + int blkpererase; const char *partstring = "256"; const char *ptr; struct mtd_dev_s *mtd_part; @@ -111,95 +113,105 @@ int sam_smartfs_initialize(void) ptr = partstring; partoffset = 0; - /* Get the Flash erase size */ + /* Get the Flash erase size */ - erasesize = geo.erasesize; + erasesize = geo.erasesize; - while (*ptr != '\0') - { - /* Get the partition size */ + while (*ptr != '\0') + { + /* Get the partition size */ - partsize = atoi(ptr); - partszbytes = (partsize << 10); /* partsize is defined in KB */ - printf("partsize %d partszbytes %d\n", partsize, partszbytes); + partsize = atoi(ptr); + partszbytes = (partsize << 10); /* partsize is defined in KB */ + printf("partsize %d partszbytes %d\n", partsize, partszbytes); - /* Check if partition size is bigger then erase block */ + /* Check if partition size is bigger then erase block */ - if (partszbytes < erasesize) - { - syslog(LOG_ERR, + if (partszbytes < erasesize) + { + syslog(LOG_ERR, "ERROR: Partition size is lesser than erasesize!\n"); - return -1; - } + return -1; + } - /* Check if partition size is multiple of erase block */ + /* Check if partition size is multiple of erase block */ - if ((partszbytes % erasesize) != 0) - { - syslog(LOG_ERR, + if ((partszbytes % erasesize) != 0) + { + syslog(LOG_ERR, "ERROR: Partition size is not multiple of erasesize!\n"); - return -1; - } - - mtd_part = mtd_partition(mtd, partoffset, - partszbytes / erasesize); - partoffset += partszbytes / erasesize; - - /* Test if this is the config partition */ - - #ifndef CONFIG_MTD_CONFIG_NONE - if (partno == 0) - { - /* Register the partition as the config device */ - - mtdconfig_register(mtd_part); - } - else - #endif - { - /* Now initialize a SMART Flash block device - * and bind it to the MTD device. - */ - - #if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) - snprintf(partref, sizeof(partref), "p%d", partno); - smart_initialize(0, mtd_part, partref); - #endif - } - - /* Set the partition name */ - - #ifdef CONFIG_MTD_PARTITION_NAMES - if (!mtd_part) - { - syslog(LOG_ERR, - "Error: failed to create partition %s\n", - partname); - return -1; - } - - mtd_setpartitionname(mtd_part, partname); - - /* Now skip to next name. - * We don't need to split the string here - * because the MTD partition logic will only - * display names up to the comma, - * thus allowing us to use a single static name - * in the code. - */ - - while (*partname != ',' && *partname != '\0') - { - /* Skip to next ',' */ - - partname++; - } - - if (*partname == ',') - { - partname++; - } - #endif + return -1; + } + + /* mtd_partition() expects the offset and size in units of + * the underlying device "blocks" (geo.blocksize, 512B for + * the SAMD5E5 progmem), not erase blocks. partoffset is + * tracked in erase blocks, so convert. Without this, + * partitions are erasesize/blocksize (16x) too small and + * misaligned. + */ + + blkpererase = geo.blocksize > 0 ? + erasesize / geo.blocksize : 1; + mtd_part = mtd_partition(mtd, partoffset * blkpererase, + partszbytes / geo.blocksize); + partoffset += partszbytes / erasesize; + + /* Test if this is the config partition */ + +#ifndef CONFIG_MTD_CONFIG_NONE + if (partno == 0) + { + /* Register the partition as the config device */ + + mtdconfig_register(mtd_part); + } + else +#endif + { + /* Now initialize a SMART Flash block device + * and bind it to the MTD device. + */ + +#if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) + snprintf(partref, sizeof(partref), "p%d", partno); + smart_initialize(0, mtd_part, partref); +#endif + } + + /* Set the partition name */ + +#ifdef CONFIG_MTD_PARTITION_NAMES + if (!mtd_part) + { + syslog(LOG_ERR, + "Error: failed to create partition %s\n", + partname); + return -1; + } + + mtd_setpartitionname(mtd_part, partname); + + /* Now skip to next name. + * We don't need to split the string here + * because the MTD partition logic will only + * display names up to the comma, + * thus allowing us to use a single static name + * in the code. + */ + + while (*partname != ',' && *partname != '\0') + { + /* Skip to next ',' */ + + partname++; + } + + if (*partname == ',') + { + partname++; + } +#endif /* Update the pointer to point to the next size in the list */ @@ -218,7 +230,8 @@ int sam_smartfs_initialize(void) partno++; } } - #else /* CONFIG_MTD_PARTITION */ + while (0); +#else /* CONFIG_MTD_PARTITION */ /* Configure the device with no partition support */ @@ -229,7 +242,7 @@ int sam_smartfs_initialize(void) return ret; } - #endif +#endif return OK; } diff --git a/boards/arm/stm32f1/stm32f103-minimum/src/stm32_w25.c b/boards/arm/stm32f1/stm32f103-minimum/src/stm32_w25.c index 96b95da27caff..2a2d2c41825cd 100644 --- a/boards/arm/stm32f1/stm32f103-minimum/src/stm32_w25.c +++ b/boards/arm/stm32f1/stm32f103-minimum/src/stm32_w25.c @@ -123,6 +123,7 @@ int stm32_w25initialize(int minor) /* Register the MTD driver */ char path[32]; + snprintf(path, sizeof(path), "/dev/mtdblock%d", minor); ret = register_mtddriver(path, mtd, 0755, NULL); if (ret < 0) @@ -145,12 +146,14 @@ int stm32_w25initialize(int minor) } #ifdef CONFIG_STM32F103MINIMUM_FLASH_PART + do { int partno; int partsize; int partoffset; int partszbytes; int erasesize; + int blkpererase; const char *partstring = CONFIG_STM32F103MINIMUM_FLASH_PART_LIST; const char *ptr; struct mtd_dev_s *mtd_part; @@ -191,7 +194,16 @@ int stm32_w25initialize(int minor) return -1; } - mtd_part = mtd_partition(mtd, partoffset, partszbytes / erasesize); + /* mtd_partition() expects the offset and size in units of the + * underlying device "blocks" (geo.blocksize, 256B for the W25), + * not erase blocks. partoffset is tracked in erase blocks, so + * convert. Without this, partitions are erasesize/blocksize + * (16x for the W25) too small and misaligned. + */ + + blkpererase = geo.blocksize > 0 ? erasesize / geo.blocksize : 1; + mtd_part = mtd_partition(mtd, partoffset * blkpererase, + partszbytes / geo.blocksize); partoffset += partszbytes / erasesize; #ifdef CONFIG_STM32F103MINIMUM_FLASH_CONFIG_PART @@ -265,6 +277,7 @@ int stm32_w25initialize(int minor) partno++; } } + while (0); #else /* CONFIG_STM32F103MINIMUM_FLASH_PART */ /* Configure the device with no partition support */ diff --git a/boards/arm/stm32f4/stm32f429i-disco/src/stm32_bringup.c b/boards/arm/stm32f4/stm32f429i-disco/src/stm32_bringup.c index 5b59f2dcf00c6..a61a077d447dd 100644 --- a/boards/arm/stm32f4/stm32f429i-disco/src/stm32_bringup.c +++ b/boards/arm/stm32f4/stm32f429i-disco/src/stm32_bringup.c @@ -180,12 +180,14 @@ int stm32_bringup(void) } #ifdef CONFIG_STM32F429I_DISCO_FLASH_PART + do { int partno; int partsize; int partoffset; int partszbytes; int erasesize; + int blkpererase; const char *partstring = CONFIG_STM32F429I_DISCO_FLASH_PART_LIST; const char *ptr; struct mtd_dev_s *mtd_part; @@ -225,8 +227,18 @@ int stm32_bringup(void) return -1; } - mtd_part = mtd_partition(mtd, partoffset, - partszbytes / erasesize); + /* mtd_partition() expects the offset and size in units of + * the underlying device "blocks" (geo.blocksize, 256B for + * the SST25), not erase blocks. partoffset is tracked in + * erase blocks, so convert. Without this, partitions are + * erasesize/blocksize (16x for the SST25) too small and + * misaligned. + */ + + blkpererase = geo.blocksize > 0 ? + erasesize / geo.blocksize : 1; + mtd_part = mtd_partition(mtd, partoffset * blkpererase, + partszbytes / geo.blocksize); partoffset += partszbytes / erasesize; #ifdef CONFIG_STM32F429I_DISCO_FLASH_CONFIG_PART @@ -299,6 +311,7 @@ int stm32_bringup(void) partno++; } } + while (0); #else /* CONFIG_STM32F429I_DISCO_FLASH_PART */ /* Configure the device with no partition support */ @@ -324,9 +337,11 @@ int stm32_bringup(void) #if defined(CONFIG_RAMMTD) && defined(CONFIG_STM32F429I_DISCO_RAMMTD) /* Create a RAM MTD device if configured */ + do { uint8_t *start = kmm_malloc(CONFIG_STM32F429I_DISCO_RAMMTD_SIZE * 1024); + mtd = rammtd_initialize(start, CONFIG_STM32F429I_DISCO_RAMMTD_SIZE * 1024); mtd->ioctl(mtd, MTDIOC_BULKERASE, 0); @@ -339,7 +354,7 @@ int stm32_bringup(void) smart_initialize(CONFIG_STM32F429I_DISCO_RAMMTD_MINOR, mtd, NULL); #endif } - + while (0); #endif /* CONFIG_RAMMTD && CONFIG_STM32F429I_DISCO_RAMMTD */ #ifdef HAVE_USBHOST