Skip to content

Commit cb3e4b7

Browse files
committed
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 <rongbaichuan1027@163.com>
1 parent 7609a72 commit cb3e4b7

4 files changed

Lines changed: 244 additions & 189 deletions

File tree

boards/arm/at32/at32f437-mini/src/at32_w25.c

Lines changed: 116 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ int at32_w25initialize(int minor)
129129
/* Register the MTD driver */
130130

131131
char path[32];
132+
132133
snprintf(path, sizeof(path), "/dev/mtdblock%d", minor);
133134
ret = register_mtddriver(path, mtd, 0755, NULL);
134135
if (ret < 0)
@@ -141,136 +142,149 @@ int at32_w25initialize(int minor)
141142
/* Initialize to provide SMARTFS on the MTD interface */
142143

143144
#ifdef FLASH_PART
144-
{
145-
int partno;
146-
int partsize;
147-
int partoffset;
148-
int partszbytes;
149-
int erasesize;
150-
const char *partstring = FLASH_PART_LIST;
151-
const char *ptr;
152-
struct mtd_dev_s *mtd_part;
153-
char partref[16];
154-
struct mtd_geometry_s geo;
155-
156-
/* Now create a partition on the FLASH device */
157-
158-
partno = 0;
159-
ptr = partstring;
160-
partoffset = 0;
161-
162-
/* Get the geometry of the FLASH device */
163-
164-
ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo));
165-
if (ret < 0)
166-
{
167-
syslog(LOG_ERR, "ERROR: mtd->ioctl failed: %d\n", ret);
168-
return ret;
169-
}
170-
171-
/* Get the Flash erase size */
172-
173-
erasesize = geo.erasesize;
174-
175-
while (*ptr != '\0')
145+
do
176146
{
177-
/* Get the partition size */
178-
179-
partsize = atoi(ptr);
180-
partszbytes = (partsize << 10); /* partsize is defined in KB */
181-
182-
/* Check if partition size is bigger then erase block */
183-
184-
if (partszbytes < erasesize)
147+
int partno;
148+
int partsize;
149+
int partoffset;
150+
int partszbytes;
151+
int erasesize;
152+
int blkpererase;
153+
const char *partstring = FLASH_PART_LIST;
154+
const char *ptr;
155+
struct mtd_dev_s *mtd_part;
156+
char partref[16];
157+
struct mtd_geometry_s geo;
158+
159+
/* Now create a partition on the FLASH device */
160+
161+
partno = 0;
162+
ptr = partstring;
163+
partoffset = 0;
164+
165+
/* Get the geometry of the FLASH device */
166+
167+
ret = mtd->ioctl(mtd, MTDIOC_GEOMETRY,
168+
(unsigned long)((uintptr_t)&geo));
169+
if (ret < 0)
185170
{
186-
syslog(LOG_ERR,
187-
"ERROR: Partition size is lesser than erasesize!\n");
188-
return -1;
171+
syslog(LOG_ERR, "ERROR: mtd->ioctl failed: %d\n", ret);
172+
return ret;
189173
}
190174

191-
/* Check if partition size is multiple of erase block */
175+
/* Get the Flash erase size */
192176

193-
if ((partszbytes % erasesize) != 0)
177+
erasesize = geo.erasesize;
178+
179+
while (*ptr != '\0')
194180
{
195-
syslog(LOG_ERR,
196-
"ERROR: Partition size isn't multiple of erasesize!\n");
197-
return -1;
198-
}
181+
/* Get the partition size */
182+
183+
partsize = atoi(ptr);
184+
partszbytes = (partsize << 10); /* partsize is defined in KB */
185+
186+
/* Check if partition size is bigger then erase block */
187+
188+
if (partszbytes < erasesize)
189+
{
190+
syslog(LOG_ERR,
191+
"ERROR: Partition size is lesser than erasesize!\n");
192+
return -1;
193+
}
194+
195+
/* Check if partition size is multiple of erase block */
196+
197+
if ((partszbytes % erasesize) != 0)
198+
{
199+
syslog(LOG_ERR,
200+
"ERROR: Partition size isn't multiple of erasesize!\n");
201+
return -1;
202+
}
203+
204+
/* mtd_partition() expects the offset and size in units of the
205+
* underlying device "blocks" (geo.blocksize, 256B for the W25),
206+
* not erase blocks. partoffset is tracked in erase blocks, so
207+
* convert. Without this, partitions are erasesize/blocksize
208+
* (16x for the W25) too small and misaligned.
209+
*/
199210

200-
mtd_part = mtd_partition(mtd, partoffset, partszbytes / erasesize);
201-
partoffset += partszbytes / erasesize;
211+
blkpererase = geo.blocksize > 0 ? erasesize / geo.blocksize : 1;
212+
mtd_part = mtd_partition(mtd, partoffset * blkpererase,
213+
partszbytes / geo.blocksize);
214+
partoffset += partszbytes / erasesize;
202215

203216
#ifdef FLASH_CONFIG_PART
204-
/* Test if this is the config partition */
217+
/* Test if this is the config partition */
205218

206-
if (FLASH_CONFIG_PART_NUMBER == partno)
207-
{
208-
/* Register the partition as the config device */
219+
if (FLASH_CONFIG_PART_NUMBER == partno)
220+
{
221+
/* Register the partition as the config device */
209222

210-
mtdconfig_register(mtd_part);
211-
}
212-
else
223+
mtdconfig_register(mtd_part);
224+
}
225+
else
213226
#endif
214-
{
215-
/* Now initialize a SMART Flash block device and bind it
216-
* to the MTD device.
217-
*/
227+
{
228+
/* Now initialize a SMART Flash block device and bind it
229+
* to the MTD device.
230+
*/
218231

219232
#if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS)
220-
snprintf(partref, sizeof(partref), "p%d", partno);
221-
smart_initialize(W25QXX_FLASH_MINOR,
222-
mtd_part, partref);
233+
snprintf(partref, sizeof(partref), "p%d", partno);
234+
smart_initialize(W25QXX_FLASH_MINOR,
235+
mtd_part, partref);
223236
#endif
224-
}
237+
}
225238

226-
/* Set the partition name */
239+
/* Set the partition name */
227240

228241
#if defined(CONFIG_MTD_PARTITION_NAMES)
229-
if (!mtd_part)
230-
{
231-
syslog(LOG_ERR, "Error: failed to create partition %s\n",
232-
partname);
233-
return -1;
234-
}
235-
236-
mtd_setpartitionname(mtd_part, partname);
237-
238-
/* Now skip to next name. We don't need to split the string here
239-
* because the MTD partition logic will only display names up to
240-
* the comma, thus allowing us to use a single static name
241-
* in the code.
242-
*/
242+
if (!mtd_part)
243+
{
244+
syslog(LOG_ERR, "Error: failed to create partition %s\n",
245+
partname);
246+
return -1;
247+
}
248+
249+
mtd_setpartitionname(mtd_part, partname);
250+
251+
/* Now skip to next name. We don't need to split the string here
252+
* because the MTD partition logic will only display names up to
253+
* the comma, thus allowing us to use a single static name
254+
* in the code.
255+
*/
243256

244-
while (*partname != ',' && *partname != '\0')
245-
{
246-
/* Skip to next ',' */
257+
while (*partname != ',' && *partname != '\0')
258+
{
259+
/* Skip to next ',' */
247260

248-
partname++;
249-
}
261+
partname++;
262+
}
250263

251-
if (*partname == ',')
252-
{
253-
partname++;
254-
}
264+
if (*partname == ',')
265+
{
266+
partname++;
267+
}
255268
#endif
256269

257-
/* Update the pointer to point to the next size in the list */
270+
/* Update the pointer to point to the next size in the list */
258271

259-
while ((*ptr >= '0') && (*ptr <= '9'))
260-
{
261-
ptr++;
262-
}
272+
while ((*ptr >= '0') && (*ptr <= '9'))
273+
{
274+
ptr++;
275+
}
263276

264-
if (*ptr == ',')
265-
{
266-
ptr++;
267-
}
277+
if (*ptr == ',')
278+
{
279+
ptr++;
280+
}
268281

269-
/* Increment the part number */
282+
/* Increment the part number */
270283

271-
partno++;
284+
partno++;
285+
}
272286
}
273-
}
287+
while (0);
274288

275289
#else /* CONFIG_FLASH_PART */
276290

0 commit comments

Comments
 (0)