Commit 864aa034f3a0e10ce710e8bbda171df3cab59414
Committed by
Wolfgang Denk
1 parent
d558107c18
Exists in
master
and in
54 other branches
cmd_mtdparts: Move to common handling of FLASH devices via MTD layer
This patch removes all references to the direct CFI FLASH interface (via flash_info[]). Now that all FLASH types currently handled in mtdparts are available (if selected, see below) via the MTD infrastructure. This is NOR, NAND and OneNAND right now. This can be achieved by defining the following options: CONFIG_MTD_DEVICE (for all FLASH types) plus CONFIG_FLASH_CFI_MTD (for NOR FLASH) So we need to add those defines to the board config headers currently using the mtdparts commands. This is done via another patch, so we shouldn't break mtdparts compatibility. One big advantage from this solution is that the cmd_mtdparts.c is *much* cleaner now. Lot's of #ifdef's are removed and the code itself is smaller. Additionally the newly added MDT concatenation feature can new be used via the mtdparts infrastructure and therefor via UBI etc. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Ladislav Michl <ladis@linux-mips.org> Cc: Scott Wood <scottwood@freescale.com>
Showing 1 changed file with 80 additions and 160 deletions Side-by-side Diff
common/cmd_mtdparts.c
... | ... | @@ -90,7 +90,8 @@ |
90 | 90 | #include <jffs2/load_kernel.h> |
91 | 91 | #include <linux/list.h> |
92 | 92 | #include <linux/ctype.h> |
93 | -#include <cramfs/cramfs_fs.h> | |
93 | +#include <linux/err.h> | |
94 | +#include <linux/mtd/mtd.h> | |
94 | 95 | |
95 | 96 | #if defined(CONFIG_CMD_NAND) |
96 | 97 | #ifdef CONFIG_NAND_LEGACY |
... | ... | @@ -102,7 +103,6 @@ |
102 | 103 | #endif |
103 | 104 | |
104 | 105 | #if defined(CONFIG_CMD_ONENAND) |
105 | -#include <linux/mtd/mtd.h> | |
106 | 106 | #include <linux/mtd/onenand.h> |
107 | 107 | #include <onenand_uboot.h> |
108 | 108 | #endif |
109 | 109 | |
110 | 110 | |
111 | 111 | |
112 | 112 | |
113 | 113 | |
114 | 114 | |
115 | 115 | |
116 | 116 | |
117 | 117 | |
118 | 118 | |
119 | 119 | |
120 | 120 | |
121 | 121 | |
122 | 122 | |
123 | 123 | |
124 | 124 | |
125 | 125 | |
126 | 126 | |
... | ... | @@ -303,137 +303,91 @@ |
303 | 303 | } |
304 | 304 | |
305 | 305 | /** |
306 | - * Performs sanity check for supplied NOR flash partition. Table of existing | |
307 | - * NOR flash devices is searched and partition device is located. Alignment | |
308 | - * with the granularity of NOR flash sectors is verified. | |
306 | + * Performs sanity check for supplied flash partition. | |
307 | + * Table of existing MTD flash devices is searched and partition device | |
308 | + * is located. Alignment with the granularity of nand erasesize is verified. | |
309 | 309 | * |
310 | 310 | * @param id of the parent device |
311 | 311 | * @param part partition to validate |
312 | 312 | * @return 0 if partition is valid, 1 otherwise |
313 | 313 | */ |
314 | -static int part_validate_nor(struct mtdids *id, struct part_info *part) | |
314 | +static int part_validate_eraseblock(struct mtdids *id, struct part_info *part) | |
315 | 315 | { |
316 | -#if defined(CONFIG_CMD_FLASH) | |
317 | - /* info for FLASH chips */ | |
318 | - extern flash_info_t flash_info[]; | |
319 | - flash_info_t *flash; | |
320 | - int offset_aligned; | |
321 | - u32 end_offset, sector_size = 0; | |
322 | - int i; | |
316 | + struct mtd_info *mtd; | |
317 | + char mtd_dev[16]; | |
318 | + int i, j; | |
319 | + ulong start; | |
323 | 320 | |
324 | - flash = &flash_info[id->num]; | |
321 | + sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(id->type), id->num); | |
322 | + mtd = get_mtd_device_nm(mtd_dev); | |
323 | + if (IS_ERR(mtd)) { | |
324 | + printf("Partition %s not found on device %s!\n", part->name, mtd_dev); | |
325 | + return 1; | |
326 | + } | |
325 | 327 | |
326 | - /* size of last sector */ | |
327 | - part->sector_size = flash->size - | |
328 | - (flash->start[flash->sector_count-1] - flash->start[0]); | |
328 | + part->sector_size = mtd->erasesize; | |
329 | 329 | |
330 | - offset_aligned = 0; | |
331 | - for (i = 0; i < flash->sector_count; i++) { | |
332 | - if ((flash->start[i] - flash->start[0]) == part->offset) { | |
333 | - offset_aligned = 1; | |
334 | - break; | |
330 | + if (!mtd->numeraseregions) { | |
331 | + /* | |
332 | + * Only one eraseregion (NAND, OneNAND or uniform NOR), | |
333 | + * checking for alignment is easy here | |
334 | + */ | |
335 | + if ((unsigned long)part->offset % mtd->erasesize) { | |
336 | + printf("%s%d: partition (%s) start offset" | |
337 | + "alignment incorrect\n", | |
338 | + MTD_DEV_TYPE(id->type), id->num, part->name); | |
339 | + return 1; | |
335 | 340 | } |
336 | - } | |
337 | - if (offset_aligned == 0) { | |
338 | - printf("%s%d: partition (%s) start offset alignment incorrect\n", | |
339 | - MTD_DEV_TYPE(id->type), id->num, part->name); | |
340 | - return 1; | |
341 | - } | |
342 | 341 | |
343 | - end_offset = part->offset + part->size; | |
344 | - offset_aligned = 0; | |
345 | - for (i = 0; i < flash->sector_count; i++) { | |
346 | - if (i) { | |
347 | - sector_size = flash->start[i] - flash->start[i-1]; | |
348 | - if (part->sector_size < sector_size) | |
349 | - part->sector_size = sector_size; | |
342 | + if (part->size % mtd->erasesize) { | |
343 | + printf("%s%d: partition (%s) size alignment incorrect\n", | |
344 | + MTD_DEV_TYPE(id->type), id->num, part->name); | |
345 | + return 1; | |
350 | 346 | } |
351 | - if ((flash->start[i] - flash->start[0]) == end_offset) | |
352 | - offset_aligned = 1; | |
353 | - } | |
347 | + } else { | |
348 | + /* | |
349 | + * Multiple eraseregions (non-uniform NOR), | |
350 | + * checking for alignment is more complex here | |
351 | + */ | |
354 | 352 | |
355 | - if (offset_aligned || flash->size == end_offset) | |
356 | - return 0; | |
353 | + /* Check start alignment */ | |
354 | + for (i = 0; i < mtd->numeraseregions; i++) { | |
355 | + start = mtd->eraseregions[i].offset; | |
356 | + for (j = 0; j < mtd->eraseregions[i].numblocks; j++) { | |
357 | + if (part->offset == start) | |
358 | + goto start_ok; | |
359 | + start += mtd->eraseregions[i].erasesize; | |
360 | + } | |
361 | + } | |
357 | 362 | |
358 | - printf("%s%d: partition (%s) size alignment incorrect\n", | |
359 | - MTD_DEV_TYPE(id->type), id->num, part->name); | |
360 | -#endif | |
361 | - return 1; | |
362 | -} | |
363 | - | |
364 | -/** | |
365 | - * Performs sanity check for supplied NAND flash partition. Table of existing | |
366 | - * NAND flash devices is searched and partition device is located. Alignment | |
367 | - * with the granularity of nand erasesize is verified. | |
368 | - * | |
369 | - * @param id of the parent device | |
370 | - * @param part partition to validate | |
371 | - * @return 0 if partition is valid, 1 otherwise | |
372 | - */ | |
373 | -static int part_validate_nand(struct mtdids *id, struct part_info *part) | |
374 | -{ | |
375 | -#if defined(CONFIG_CMD_NAND) | |
376 | - /* info for NAND chips */ | |
377 | - nand_info_t *nand; | |
378 | - | |
379 | - nand = &nand_info[id->num]; | |
380 | - | |
381 | - part->sector_size = nand->erasesize; | |
382 | - | |
383 | - if ((unsigned long)(part->offset) % nand->erasesize) { | |
384 | 363 | printf("%s%d: partition (%s) start offset alignment incorrect\n", |
385 | - MTD_DEV_TYPE(id->type), id->num, part->name); | |
364 | + MTD_DEV_TYPE(id->type), id->num, part->name); | |
386 | 365 | return 1; |
387 | - } | |
388 | 366 | |
389 | - if (part->size % nand->erasesize) { | |
390 | - printf("%s%d: partition (%s) size alignment incorrect\n", | |
391 | - MTD_DEV_TYPE(id->type), id->num, part->name); | |
392 | - return 1; | |
393 | - } | |
367 | + start_ok: | |
394 | 368 | |
395 | - return 0; | |
396 | -#else | |
397 | - return 1; | |
398 | -#endif | |
399 | -} | |
369 | + /* Check end/size alignment */ | |
370 | + for (i = 0; i < mtd->numeraseregions; i++) { | |
371 | + start = mtd->eraseregions[i].offset; | |
372 | + for (j = 0; j < mtd->eraseregions[i].numblocks; j++) { | |
373 | + if ((part->offset + part->size) == start) | |
374 | + goto end_ok; | |
375 | + start += mtd->eraseregions[i].erasesize; | |
376 | + } | |
377 | + } | |
378 | + /* Check last sector alignment */ | |
379 | + if ((part->offset + part->size) == start) | |
380 | + goto end_ok; | |
400 | 381 | |
401 | -/** | |
402 | - * Performs sanity check for supplied OneNAND flash partition. | |
403 | - * Table of existing OneNAND flash devices is searched and partition device | |
404 | - * is located. Alignment with the granularity of nand erasesize is verified. | |
405 | - * | |
406 | - * @param id of the parent device | |
407 | - * @param part partition to validate | |
408 | - * @return 0 if partition is valid, 1 otherwise | |
409 | - */ | |
410 | -static int part_validate_onenand(struct mtdids *id, struct part_info *part) | |
411 | -{ | |
412 | -#if defined(CONFIG_CMD_ONENAND) | |
413 | - /* info for OneNAND chips */ | |
414 | - struct mtd_info *mtd; | |
415 | - | |
416 | - mtd = &onenand_mtd; | |
417 | - | |
418 | - part->sector_size = mtd->erasesize; | |
419 | - | |
420 | - if ((unsigned long)(part->offset) % mtd->erasesize) { | |
421 | - printf("%s%d: partition (%s) start offset" | |
422 | - "alignment incorrect\n", | |
423 | - MTD_DEV_TYPE(id->type), id->num, part->name); | |
424 | - return 1; | |
425 | - } | |
426 | - | |
427 | - if (part->size % mtd->erasesize) { | |
428 | 382 | printf("%s%d: partition (%s) size alignment incorrect\n", |
429 | - MTD_DEV_TYPE(id->type), id->num, part->name); | |
383 | + MTD_DEV_TYPE(id->type), id->num, part->name); | |
430 | 384 | return 1; |
385 | + | |
386 | + end_ok: | |
387 | + return 0; | |
431 | 388 | } |
432 | 389 | |
433 | 390 | return 0; |
434 | -#else | |
435 | - return 1; | |
436 | -#endif | |
437 | 391 | } |
438 | 392 | |
439 | 393 | |
... | ... | @@ -469,16 +423,11 @@ |
469 | 423 | return 1; |
470 | 424 | } |
471 | 425 | |
472 | - if (id->type == MTD_DEV_TYPE_NAND) | |
473 | - return part_validate_nand(id, part); | |
474 | - else if (id->type == MTD_DEV_TYPE_NOR) | |
475 | - return part_validate_nor(id, part); | |
476 | - else if (id->type == MTD_DEV_TYPE_ONENAND) | |
477 | - return part_validate_onenand(id, part); | |
478 | - else | |
479 | - DEBUGF("part_validate: invalid dev type\n"); | |
480 | - | |
481 | - return 1; | |
426 | + /* | |
427 | + * Now we need to check if the partition starts and ends on | |
428 | + * sector (eraseblock) regions | |
429 | + */ | |
430 | + return part_validate_eraseblock(id, part); | |
482 | 431 | } |
483 | 432 | |
484 | 433 | /** |
485 | 434 | |
486 | 435 | |
487 | 436 | |
... | ... | @@ -762,48 +711,19 @@ |
762 | 711 | */ |
763 | 712 | int mtd_device_validate(u8 type, u8 num, u32 *size) |
764 | 713 | { |
765 | - if (type == MTD_DEV_TYPE_NOR) { | |
766 | -#if defined(CONFIG_CMD_FLASH) | |
767 | - if (num < CONFIG_SYS_MAX_FLASH_BANKS) { | |
768 | - extern flash_info_t flash_info[]; | |
769 | - *size = flash_info[num].size; | |
714 | + struct mtd_info *mtd; | |
715 | + char mtd_dev[16]; | |
770 | 716 | |
771 | - return 0; | |
772 | - } | |
717 | + sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(type), num); | |
718 | + mtd = get_mtd_device_nm(mtd_dev); | |
719 | + if (IS_ERR(mtd)) { | |
720 | + printf("Device %s not found!\n", mtd_dev); | |
721 | + return 1; | |
722 | + } | |
773 | 723 | |
774 | - printf("no such FLASH device: %s%d (valid range 0 ... %d\n", | |
775 | - MTD_DEV_TYPE(type), num, CONFIG_SYS_MAX_FLASH_BANKS - 1); | |
776 | -#else | |
777 | - printf("support for FLASH devices not present\n"); | |
778 | -#endif | |
779 | - } else if (type == MTD_DEV_TYPE_NAND) { | |
780 | -#if defined(CONFIG_CMD_NAND) | |
781 | - if (num < CONFIG_SYS_MAX_NAND_DEVICE) { | |
782 | -#ifndef CONFIG_NAND_LEGACY | |
783 | - *size = nand_info[num].size; | |
784 | -#else | |
785 | - extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE]; | |
786 | - *size = nand_dev_desc[num].totlen; | |
787 | -#endif | |
788 | - return 0; | |
789 | - } | |
724 | + *size = mtd->size; | |
790 | 725 | |
791 | - printf("no such NAND device: %s%d (valid range 0 ... %d)\n", | |
792 | - MTD_DEV_TYPE(type), num, CONFIG_SYS_MAX_NAND_DEVICE - 1); | |
793 | -#else | |
794 | - printf("support for NAND devices not present\n"); | |
795 | -#endif | |
796 | - } else if (type == MTD_DEV_TYPE_ONENAND) { | |
797 | -#if defined(CONFIG_CMD_ONENAND) | |
798 | - *size = onenand_mtd.size; | |
799 | - return 0; | |
800 | -#else | |
801 | - printf("support for OneNAND devices not present\n"); | |
802 | -#endif | |
803 | - } else | |
804 | - printf("Unknown defice type %d\n", type); | |
805 | - | |
806 | - return 1; | |
726 | + return 0; | |
807 | 727 | } |
808 | 728 | |
809 | 729 | /** |