SPI-NAND support
Subsystems (2)
Miquel Raynal
maintainerv7 cover SPI-NAND support
During the last months, Boris Brezillon shared his work to support serial flashes within Linux. First, he delivered (and merged) a new layer called spi-mem. He also initiated in Linux MTD subsystem the move of all 'raw' NAND related code to a raw/ subdirectory, adding at the same time a NAND core that would be shared with all NAND devices. Then, he contributed a generic SPI-NAND driver, making use of this NAND core, as well as some vendor code to drive a few chips.
On top of this work, I made some cleanups in the MTD layer and added an 'mtd' U-Boot command to handle all sort of MTD devices. This should become the default command instead of having one per flash flavor ('sf', 'nand', 'spi-nand' ?).
The series has been tested on an Ocelot board PCB123 (VSC7514), featuring a Macronix SPI NAND chip.
TL;DR: the series contains (stripped version since 23 patches have already been taken):
- Various fixes
- Support for spi-nand devices in mtdparts.
- Generics mtdparts/mtdids parsers.
- A new 'mtd' command.
- A note to set mtdparts command legacy.
To test your SPI-NAND device with U-Boot, you can test someting like:
Quoted 4 lines
setenv mtdparts 'spi-nand0:1m(foo),-(bar)'
setenv mtdids 'spi-nand0=spi0.0' # spi0.0 is Linux MTD name for this device
ubi part bar # create a static UBI volume in the bar partition
mtd list # show the current MTD devices/partitions
Thanks,
Miquèl
Changes since v7:
-----------------
* Added Stefan R-b tags.
* Used tolower() as suggested by Stefan in lib/strto.c.
* Added a mention saying that we continue to abuse the kB suffix in lib/strto.c by not making a difference between kB and kiB which both mean "* 1024" for us. This has been added in the commit log.
* Fixed various bugs in the mtd command and in the parsers, they should be pretty stable now (tested with two MTD devices probed and several different partition configurations).
* mtdids is not deprecated at all as opposed at what I wrote in v6. U-Boot still uses its own MTD names (being <type><idx> like nor0 or spi-nand1) and mtdids is still needed to do the glue.
* Removed a useless patch removing a Kconfig entry I added myself since during a rebase someone else also added this symbol.
Changes since v6:
-----------------
* Squashed Boris' fixes about build issues in Travis.
* Merged Stefan Roese's contributions.
* cmd: mtdparts:
* added fallthrough comments in switch blocks deriving sizes.
* balanced debug messages to compare freed and allocated partitions.
* move mtdparts_init() declaration in mtd/partitions.h to be used in mtd command as well.
* introduced a "compatibility" function to return what the MTD device name could be thanks to the mtdids environment variable (which is useless with the new partitioning logic).
* mtd: mtdpart:
* reworked the way partitions are created/handled.
* cmd: mtd:
* implement a partitioning logic that takes the best out of the MTD layer without re-inventing the wheel. Partitions are all freed correctly when the value of mtdparts changes.
* balance get_mtd_device() by put_mtd_device() calls.
* prevent memory leak by reorganizing the code a bit in do_mtd.
* do not reconstruct partition list when a partition is already in use (complain about that instead).
* add support for the legacy mtdids (not needed anymore if mtdparts directly uses the MTD device names as in Linux.
* cmd: ubi:
* clean and simplify the partition handling a bit to make use the best use of the MTD layer as well and keep the code simple.
Changes since v5:
-----------------
* Included Boris fixup about the build issues.
* Added Rb/Ab tags from Jagan on patchs 20/21.
Changes since v4:
-----------------
* Added Jagan's Acked-by tags to every patch related to the SPI-mem/SPI-NAND addition.
* Rebased on top of master.
Changes since v3:
-----------------
* Fixed the debug messages in spi-mem to print either Rx or Tx data.
* Fixed a Kconfig error that prevented to build mtdparts with plain defconfig.
* Fixed a compilation error due to the above error that prevented one file to be compiled.
* Adapted the mtd command to probe MTD partitions also.
* Declared mtd_probe_devices() in a header so mtdparts or UBI could use it too (to probe all devices and MTD partitions in a clean way).
* As I worked on mtdparts, I found annoying and completely useless the fact that we need to prefix the environment variable with "mtdparts=". Canceled this obligation.
* Added one patch to allow spi-nand devices to be recognized by mtdparts (this is purely useless but needed to be done in order to use this command).
* Removed useless definitions of MTD device types in UBI code.
* Wrote a generic mtdparts environment variable parser, used by the mtd command.
* Used the mtd_probe_devices() function from get_mtd_info() in cmd/mtdparts.c to be sure the desired partition really does not exist (otherwise it will be probed and then found).
Changes since v2:
-----------------
* Rebased on u-boot master branch.
* Removed extra-parenthesis in
"mtd: Fallback to ->_read/write() when ->_read/write_oob() is missing"
* s/fiels/files/ in "mtd: move NAND fiels into a raw/ subdirectory"
* Do not describe generic SPI device properties in SPI NAND bindings.
* Changes in the mtd command:
* Printing more information in 'mtd list' (device type, device characteristics)
* Switch to do_div() instead of '(u32)value64b % value32b' which only worked because value32b was a power of 2.
* Removed erase.chip option.
* By default, erase/read/write happen on the full MTD device while a dump will only work on a single page.
Changes since v1:
-----------------
* Fixed the nand_memorg structure of the MX35LF2GE4AB chip.
* Added Reviewed-by tags from Jagan.
* Backported and squashed two patches fixing things in the SPI NAND core received on the Linux ML.
* Backported more changes in mtdcore.c from Linux.
* Added a patch to add a fallback on mtd->_read/_write() in mtdcore.c when mtd->_read/write_oob() is not supported.
* Removed the DT changes, useless as the DTs are not available in mainline yet.
* Addressed Boris/Stefan comments on the 'mtd' command.
* Added support for multi-pages OOB read/write.
Miquel Raynal (12):
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefix
mtd: uclass: add probe function
mtd: uclass: add a generic 'mtdparts' parser
mtd: uclass: search for an equivalent MTD name with the mtdids
mtd: mtdpart: implement proper partition handling
cmd: mtd: add 'mtd' command
cmd: mtdparts: try to probe the MTD devices as a fallback
cmd: ubi: clean the partition handling
cmd: mtdparts: describe as legacy
cmd/Kconfig | 18 +- cmd/Makefile | 1 + cmd/mtd.c | 521 ++++++++++++++++++++++++++ cmd/mtdparts.c | 46 ++- cmd/ubi.c | 100 ++--- drivers/mtd/Makefile | 2 +- drivers/mtd/mtd-uclass.c | 16 + drivers/mtd/mtdcore.c | 2 + drivers/mtd/mtdpart.c | 660 +++++++++++++++++++++------------ include/jffs2/load_kernel.h | 7 +- include/linux/mtd/mtd.h | 31 ++ include/linux/mtd/partitions.h | 5 +- include/mtd.h | 3 + lib/strto.c | 36 +- 14 files changed, 1094 insertions(+), 354 deletions(-) create mode 100644 cmd/mtd.c
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 1/12 lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
Both ustrtoul and ustrtoull interpret 1k but not 1m or 1g. Even if the SI symbols for Mega and Giga are 'M' and 'G', certain entries of eg. mtdparts also use (wrongly) the metric prefix 'm' and 'g'.
I do not see how parsing lowercase prefixes could break anything, so parse them like their uppercase counterpart.
Also, even though kiB is not equal to kB in general, lets not change U-Boot behavior and always use kiB and kB (same applies for MiB vs. MB and GiB vs. GB) as a representation for 1024 instead of 1000.
--- lib/strto.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
lib/strto.c +6 -8
@@ -85,14 +85,13 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)unsigned long ustrtoul (const char *cp,char **endp,unsigned int base) {unsigned long result =simple_strtoul (cp, endp, base); -switch (**endp) { -case 'G' : +switch (tolower (**endp)) { +case 'g' : result *=1024 ;/* fall through */ -case 'M' : +case 'm' : result *=1024 ;/* fall through */ -case 'K' :case 'k' : result *=1024 ;if ((*endp)[1 ] =='i' ) {
@@ -108,14 +107,13 @@ unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)unsigned long long ustrtoull (const char *cp,char **endp,unsigned int base) {unsigned long long result =simple_strtoull (cp, endp, base); -switch (**endp) { -case 'G' : +switch (tolower (**endp)) { +case 'g' : result *=1024 ;/* fall through */ -case 'M' : +case 'm' : result *=1024 ;/* fall through */ -case 'K' :case 'k' : result *=1024 ;if ((*endp)[1 ] =='i' ) {
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 2/12 lib: strto: fix metric suffix parsing in strtoul[l]
In reply to Miquel RaynalWhile 1kB or 1kiB will be parsed correctly, 1k will return the right amount, but the metric suffix will not be escaped once the char pointer updated. Fix this situation by simplifying the move of the endp pointer.
--- lib/strto.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
lib/strto.c +10 -12
@@ -94,12 +94,11 @@ unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)/* fall through */ case 'k' : result *=1024 ; -if ((*endp)[1 ] =='i' ) { -if ((*endp)[2 ] =='B' ) - (*endp) +=3 ; -else - (*endp) +=2 ; - } + (*endp)++; +if (**endp =='i' ) + (*endp)++; +if (**endp =='B' ) + (*endp)++; }return result; }
@@ -116,12 +115,11 @@ unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base)/* fall through */ case 'k' : result *=1024 ; -if ((*endp)[1 ] =='i' ) { -if ((*endp)[2 ] =='B' ) - (*endp) +=3 ; -else - (*endp) +=2 ; - } + (*endp)++; +if (**endp =='i' ) + (*endp)++; +if (**endp =='B' ) + (*endp)++; }return result; }
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 3/12 cmd: mtdparts: accept spi-nand devices
In reply to Miquel RaynalLet spi-nand devices be recognized by mtdparts. This is superfluous but a full mtdparts rework would be very time-consuming.
--- cmd/mtdparts.c | 13 ++++++++----- include/jffs2/load_kernel.h | 7 +++++-- 2 files changed, 13 insertions(+), 7 deletions(-)
cmd/mtdparts.c +8 -5
@@ -37,7 +37,7 @@* mtdids=<idmap>[,<idmap>,...] * * <idmap> := <dev-id>=<mtd-id> -* <dev-id> := 'nand'|'nor'|'onenand'<dev-num> +* <dev-id> := 'nand'|'nor'|'onenand'|'spi-nand'<dev-num> * <dev-num> := mtd device number, 0... * <mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name) *
@@ -339,7 +339,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)if (!mtd->numeraseregions) {/* -* Only one eraseregion (NAND, OneNAND or uniform NOR), +* Only one eraseregion (NAND, SPI-NAND, OneNAND or uniform NOR), * checking for alignment is easy here */ offset = part->offset;
@@ -1030,7 +1030,7 @@ static struct mtdids* id_find_by_mtd_id(const char *mtd_id, unsigned int mtd_id_ }/** -* Parse device id string <dev-id> := 'nand'|'nor'|'onenand'<dev-num>, +* Parse device id string <dev-id> := 'nand'|'nor'|'onenand'|'spi-nand'<dev-num>, * return device type and number. * * @param id string describing device id
@@ -1054,6 +1054,9 @@ int mtd_id_parse(const char *id, const char **ret_id, u8 *dev_type, }else if (strncmp (p,"onenand" ,7 ) ==0 ) { *dev_type =MTD_DEV_TYPE_ONENAND ; p +=7 ; + }else if (strncmp (p,"spi-nand" ,8 ) ==0 ) { + *dev_type =MTD_DEV_TYPE_SPINAND ; + p +=8 ; }else {printf ("incorrect device type in %s\n" , id);return 1 ;
@@ -1636,7 +1639,7 @@ static int parse_mtdids(const char *const ids)while (p && (*p !='\0' )) { ret =1 ; -/* parse 'nor'|'nand'|'onenand'<dev-num> */ +/* parse 'nor'|'nand'|'onenand'|'spi-nand'<dev-num> */ if (mtd_id_parse (p, &p, &type, &num) !=0 )break ;
@@ -2112,7 +2115,7 @@ static char mtdparts_help_text[] ="'mtdids' - linux kernel mtd device id <-> u-boot device id mapping\n\n" "mtdids=<idmap>[,<idmap>,...]\n\n" "<idmap> := <dev-id>=<mtd-id>\n" -"<dev-id> := 'nand'|'nor'|'onenand'<dev-num>\n" +"<dev-id> := 'nand'|'nor'|'onenand'|'spi-nand'<dev-num>\n" "<dev-num> := mtd device number, 0...\n" "<mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)\n\n" "'mtdparts' - partition list\n\n"
include/jffs2/load_kernel.h +5 -2
@@ -15,9 +15,12 @@#define MTD_DEV_TYPE_NOR 0x0001#define MTD_DEV_TYPE_NAND 0x0002#define MTD_DEV_TYPE_ONENAND 0x0004 +#define MTD_DEV_TYPE_SPINAND 0x0008 -#define MTD_DEV_TYPE (type) ((type == MTD_DEV_TYPE_NAND) ? "nand" : \ - (type == MTD_DEV_TYPE_ONENAND) ? "onenand" : "nor") +#define MTD_DEV_TYPE (type) (type == MTD_DEV_TYPE_NAND ? "nand" : \ + (type == MTD_DEV_TYPE_NOR ? "nor" : \ + (type == MTD_DEV_TYPE_ONENAND ? "onenand" : \ + "spi-nand"))) \struct mtd_device {struct list_head link;
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 4/12 cmd: mtdparts: remove mandatory 'mtdparts=' prefix
In reply to Miquel RaynalAll U-Boot users must define the mtdparts environment variable with:
setenv mtdparts mtdparts=...
While this may ease the partition declaration job to be passed to Linux, this is a pure software limitation and forcing this prefix is a complete non-sense. Let the user to declare manually the mtdparts variable without the prefix.
--- cmd/mtdparts.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)
cmd/mtdparts.c +6 -11
@@ -44,7 +44,7 @@* * 'mtdparts' - partition list * -* mtdparts=mtdparts=<mtd-def>[;<mtd-def>...] +* mtdparts=[mtdparts=]<mtd-def>[;<mtd-def>...] * * <mtd-def> := <mtd-id>:<part-def>[,<part-def>...] * <mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)
@@ -62,11 +62,11 @@* * 1 NOR Flash, with 1 single writable partition: * mtdids=nor0=edb7312-nor -* mtdparts=mtdparts=edb7312-nor:- +* mtdparts=[mtdparts=]edb7312-nor:- * * 1 NOR Flash with 2 partitions, 1 NAND with one * mtdids=nor0=edb7312-nor,nand0=edb7312-nand -* mtdparts=mtdparts=edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) +* mtdparts=[mtdparts=]edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) * */
@@ -1099,9 +1099,6 @@ static int generate_mtdparts(char *buf, u32 buflen)return 0 ; } -strcpy (p,"mtdparts=" ); - p +=9 ; -list_for_each (dentry, &devices) { dev = list_entry(dentry, struct mtd_device, link);
@@ -1572,11 +1569,9 @@ static int parse_mtdparts(const char *const mtdparts)if (!p) p = mtdparts; -if (strncmp (p,"mtdparts=" ,9 ) !=0 ) { -printf ("mtdparts variable doesn't start with 'mtdparts='\n" ); -return err; - } - p +=9 ; +/* Skip the useless prefix, if any */ +if (strncmp (p,"mtdparts=" ,9 ) ==0 ) + p +=9 ;while (*p !='\0' ) { err =1 ;
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 5/12 mtd: uclass: add probe function
In reply to Miquel RaynalThe user might want to trigger the probe of any MTD device, export these functions so they can be called from a command source file.
--- drivers/mtd/mtd-uclass.c | 16 ++++++++++++++++ include/mtd.h | 2 ++ 2 files changed, 18 insertions(+)
drivers/mtd/mtd-uclass.c +16 -0
@@ -5,9 +5,25 @@#include <common.h> #include <dm.h> +#include <dm/device-internal.h> #include <errno.h> #include <mtd.h> +/** +* mtd_probe - Probe the device @dev if not already done +* +* @dev: U-Boot device to probe +* +* @return 0 on success, an error otherwise. +*/ +int mtd_probe (struct udevice *dev) +{ +if (device_active (dev)) +return 0 ; + +return device_probe (dev); +} +/* * Implement a MTD uclass which should include most flash drivers. * The uclass private is pointed to mtd_info.
include/mtd.h +2 -0
@@ -19,4 +19,6 @@ static inline struct mtd_info *mtd_get_info(struct udevice *dev) return dev_get_uclass_priv(dev); } +int mtd_probe (struct udevice *dev); +#endif /* _MTD_H_ */
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 6/12 mtd: uclass: add a generic 'mtdparts' parser
In reply to Miquel RaynalThe current parser is very specific to U-Boot mtdparts implementation. It does not use MTD structures like mtd_info and mtd_partition. Copy and adapt the current parser in drivers/mtd/mtd-uclass.c (to not break the current use of mtdparts.c itself) and write some kind of a wrapper around the current implementation to allow other commands to benefit from this parsing in a user-friendly way.
This new function will allocate an mtd_partition array for each successful call. This array must be freed after use by the caller. The given 'mtdparts' buffer pointer will be moved forward to the next MTD device (if any, it will point towards a '\0' character otherwise).
--- drivers/mtd/mtdpart.c | 187 +++++++++++++++++++++++++++++++++ include/linux/mtd/partitions.h | 2 + 2 files changed, 189 insertions(+)
drivers/mtd/mtdpart.c +187 -0
@@ -76,6 +76,193 @@ char *kstrdup(const char *s, gfp_t gfp) }#endif +#define MTD_SIZE_REMAINING (~0LLU) +#define MTD_OFFSET_NOT_SPECIFIED (~0LLU) + +/** +* mtd_parse_partition - Parse @mtdparts partition definition, fill @partition +* with it and update the @mtdparts string pointer. +* +* The partition name is allocated and must be freed by the caller. +* +* This function is widely inspired from part_parse (mtdparts.c). +* +* @mtdparts: String describing the partition with mtdparts command syntax +* @partition: MTD partition structure to fill +* +* @return 0 on success, an error otherwise. +*/ +static int mtd_parse_partition (const char **_mtdparts, +struct mtd_partition *partition) +{ +const char *mtdparts = *_mtdparts; +const char *name =NULL ; +int name_len; +char *buf; + +/* Ensure the partition structure is empty */ +memset (partition,0 ,sizeof (struct mtd_partition )); + +/* Fetch the partition size */ +if (*mtdparts =='-' ) { +/* Assign all remaining space to this partition */ + partition->size =MTD_SIZE_REMAINING ; + mtdparts++; + }else { + partition->size =ustrtoull (mtdparts, (char **)&mtdparts,0 ); +if (partition->size <SZ_4K ) { +printf ("Minimum partition size 4kiB, %lldB requested\n" , + partition->size); +return -EINVAL ; + } + } + +/* Check for the offset */ + partition->offset =MTD_OFFSET_NOT_SPECIFIED ; +if (*mtdparts =='@' ) { + mtdparts++; + partition->offset =ustrtoull (mtdparts, (char **)&mtdparts,0 ); + } + +/* Now look for the name */ +if (*mtdparts =='(' ) { + name = ++mtdparts; + mtdparts =strchr (name,')' ); +if (!mtdparts) { +printf ("No closing ')' found in partition name\n" ); +return -EINVAL ; + } + name_len = mtdparts - name +1 ; +if ((name_len -1 ) ==0 ) { +printf ("Empty partition name\n" ); +return -EINVAL ; + } + mtdparts++; + }else { +/* Name will be of the form size at offset */ + name_len =22 ; + } + +/* Check if the partition is read-only */ +if (strncmp (mtdparts,"ro" ,2 ) ==0 ) { + partition->mask_flags |=MTD_WRITEABLE ; + mtdparts +=2 ; + } + +/* Check for a potential next partition definition */ +if (*mtdparts ==',' ) { +if (partition->size ==MTD_SIZE_REMAINING ) { +printf ("No partitions allowed after a fill-up\n" ); +return -EINVAL ; + } + ++mtdparts; + }else if ((*mtdparts ==';' ) || (*mtdparts =='\0' )) { +/* NOP */ + }else { +printf ("Unexpected character '%c' in mtdparts\n" , *mtdparts); +return -EINVAL ; + } + +/* +* Allocate a buffer for the name and either copy the provided name or +* auto-generate it with the form 'size at offset'. +*/ + buf =malloc (name_len); +if (!buf) +return -ENOMEM ; + +if (name) +strncpy (buf, name, name_len -1 ); +else +snprintf (buf, name_len,"0x%08llx at 0x%08llx" , + partition->size, partition->offset); + + buf[name_len -1 ] ='\0' ; + partition->name = buf; + + *_mtdparts = mtdparts; + +return 0 ; +} + +/** +* mtdparts_parse_part - Create a partition array from an mtdparts definition +* +* Stateless function that takes a @parent MTD device, a string @_mtdparts +* describing the partitions (with the "mtdparts" command syntax) and creates +* the corresponding MTD partition structure array @_parts. Both the name and +* the structure partition itself must be freed freed by the caller. +* +* @parent: MTD device which contains the partitions +* @_mtdparts: Pointer to a string describing the partitions with "mtdparts" +* command syntax. +* @_parts: Allocated array containing the partitions, must be freed by the +* caller. +* @_nb_parts: Size of @_parts array. +* +* @return 0 on success, an error otherwise. +*/ +int mtd_parse_partitions (struct mtd_info *parent,const char **_mtdparts, +struct mtd_partition **_parts,int *_nb_parts) +{ +struct mtd_partition partition = {}, *parts; +const char *mtdparts = *_mtdparts; +int cur_off =0 , cur_sz =0 ; +int nb_parts =0 ; +int ret, idx; +u64 sz; + +/* First, iterate over the partitions until we know their number */ +while (mtdparts[0 ] !='\0' && mtdparts[0 ] !=';' ) { + ret =mtd_parse_partition (&mtdparts, &partition); +if (ret) +return ret; + +free ((char *)partition.name); + nb_parts++; + } + +/* Allocate an array of partitions to give back to the caller */ + parts =malloc (sizeof (*parts) * nb_parts); +if (!parts) { +printf ("Not enough space to save partitions meta-data\n" ); +return -ENOMEM ; + } + +/* Iterate again over each partition to save the data in our array */ +for (idx =0 ; idx < nb_parts; idx++) { + ret =mtd_parse_partition (_mtdparts, &parts[idx]); +if (ret) +return ret; + +if (parts[idx].size ==MTD_SIZE_REMAINING ) + parts[idx].size = parent->size - cur_sz; + cur_sz += parts[idx].size; + + sz = parts[idx].size; +if (sz < parent->writesize ||do_div (sz, parent->writesize)) { +printf ("Partition size must be a multiple of %d\n" , + parent->writesize); +return -EINVAL ; + } + +if (parts[idx].offset ==MTD_OFFSET_NOT_SPECIFIED ) + parts[idx].offset = cur_off; + cur_off += parts[idx].size; + + parts[idx].ecclayout = parent->ecclayout; + } + +/* Offset by one mtdparts to point to the next device if any */ +if (*_mtdparts[0 ] ==';' ) + (*_mtdparts)++; + + *_parts = parts; + *_nb_parts = nb_parts; + +return 0 ; +} +/* * MTD methods which simply translate the effective address and pass through * to the _real_ device.
include/linux/mtd/partitions.h +2 -0
@@ -86,5 +86,7 @@ int mtd_add_partition(struct mtd_info *master, const char *name, long long offset, long long length);int mtd_del_partition (struct mtd_info *master,int partno);uint64_t mtd_get_device_size (const struct mtd_info *mtd); +int mtd_parse_partitions (struct mtd_info *parent,const char **_mtdparts, +struct mtd_partition **_parts,int *_nb_parts);#endif
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 7/12 mtd: uclass: search for an equivalent MTD name with the mtdids
In reply to Miquel RaynalUsing an MTD device (resp. partition) name in mtdparts is simple and straightforward. However, for a long time already, another name was given in mtdparts to indicate a device (resp. partition) so the "mtdids" environment variable was created to do the match.
Let's create a function that, from an MTD device (resp. partition) name, search for the equivalent name in the "mtdparts" environment variable thanks to the "mtdids" string.
--- drivers/mtd/mtdpart.c | 61 ++++++++++++++++++++++++++++++++++ include/linux/mtd/partitions.h | 2 ++ 2 files changed, 63 insertions(+)
drivers/mtd/mtdpart.c +61 -0
@@ -263,6 +263,67 @@ int mtd_parse_partitions(struct mtd_info *parent, const char **_mtdparts,return 0 ; } +/** +* mtd_search_alternate_name - Search an alternate name for @mtdname thanks to +* the mtdids legacy environment variable. +* +* The mtdids string is a list of comma-separated 'dev_id=mtd_id' tupples. +* Check if one of the mtd_id matches mtdname, in this case save dev_id in +* altname. +* +* @mtdname: Current MTD device name +* @altname: Alternate name to return +* @max_len: Length of the alternate name buffer +* +* @return 0 on success, an error otherwise. +*/ +int mtd_search_alternate_name (const char *mtdname,char *altname, +unsigned int max_len) +{ +const char *mtdids, *equal, *comma, *dev_id, *mtd_id; +int dev_id_len, mtd_id_len; + + mtdids =env_get ("mtdids" ); +if (!mtdids) +return -EINVAL ; + +do { +/* Find the '=' sign */ + dev_id = mtdids; + equal =strchr (dev_id,'=' ); +if (!equal) +break ; + dev_id_len = equal - mtdids; + mtd_id = equal +1 ; + +/* Find the end of the tupple */ + comma =strchr (mtdids,',' ); +if (comma) + mtd_id_len = comma - mtd_id; +else + mtd_id_len = &mtdids[strlen (mtdids)] - mtd_id +1 ; + +if (!dev_id_len || !mtd_id_len) +return -EINVAL ; + +if (dev_id_len +1 > max_len) +continue ; + +/* Compare the name we search with the current mtd_id */ +if (!strncmp (mtdname, mtd_id, mtd_id_len)) { +strncpy (altname, dev_id, dev_id_len); + altname[dev_id_len] =0 ; + +return 0 ; + } + +/* Go to the next tupple */ + mtdids = comma +1 ; + }while (comma); + +return -EINVAL ; +} +/* * MTD methods which simply translate the effective address and pass through * to the _real_ device.
include/linux/mtd/partitions.h +2 -0
@@ -88,5 +88,7 @@ int mtd_del_partition(struct mtd_info *master, int partno);uint64_t mtd_get_device_size (const struct mtd_info *mtd);int mtd_parse_partitions (struct mtd_info *parent,const char **_mtdparts,struct mtd_partition **_parts,int *_nb_parts); +int mtd_search_alternate_name (const char *mtdname,char *altname, +unsigned int max_len);#endif
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 8/12 mtd: mtdpart: implement proper partition handling
In reply to Miquel RaynalInstead of collecting partitions in a flat list, create a hierarchy within the mtd_info structure: use a partitions list to keep track of the partitions of an MTD device (which might be itself a partition of another MTD device), a pointer to the parent device (NULL when the MTD device is the root one, not a partition).
By also saving directly in mtd_info the offset of the partition, we can get rid of the mtd_part structure.
--- drivers/mtd/mtdcore.c | 2 + drivers/mtd/mtdpart.c | 412 ++++++++++++++------------------- include/linux/mtd/mtd.h | 31 +++ include/linux/mtd/partitions.h | 1 - 4 files changed, 208 insertions(+), 238 deletions(-)
drivers/mtd/mtdcore.c +2 -0
@@ -426,6 +426,8 @@ int add_mtd_device(struct mtd_info *mtd) mtd->index = i; mtd->usecount =0 ; +INIT_LIST_HEAD (&mtd->partitions); +/* default value if not set by driver */ if (mtd->bitflip_threshold ==0 ) mtd->bitflip_threshold = mtd->ecc_strength;
drivers/mtd/mtdpart.c +175 -237
758 lines not on this page · raw message
include/linux/mtd/mtd.h +31 -0
@@ -307,6 +307,27 @@ struct mtd_info {struct udevice *dev;#endif int usecount; + +/* MTD devices do not have any parent. MTD partitions do. */ +struct mtd_info *parent; + +/* +* Offset of the partition relatively to the parent offset. +* Is 0 for real MTD devices (ie. not partitions). +*/ +u64 offset; + +/* +* List node used to add an MTD partition to the parent +* partition list. +*/ +struct list_head node; + +/* +* List of partitions attached to this MTD device (the parent +* MTD device can itself be a partition). +*/ +struct list_head partitions; };#if IS_ENABLED (CONFIG_DM )
@@ -334,6 +355,16 @@ static inline const struct device_node *mtd_get_of_node(struct mtd_info *mtd) }#endif +static inline bool mtd_is_partition (const struct mtd_info *mtd) +{ +return mtd->parent; +} + +static inline bool mtd_has_partitions (const struct mtd_info *mtd) +{ +return !list_empty (&mtd->partitions); +} +int mtd_ooblayout_ecc (struct mtd_info *mtd,int section,struct mtd_oob_region *oobecc); int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
include/linux/mtd/partitions.h +0 -1
@@ -81,7 +81,6 @@ extern void register_mtd_parser(struct mtd_part_parser *parser);extern void deregister_mtd_parser (struct mtd_part_parser *parser);#endif -int mtd_is_partition (const struct mtd_info *mtd);int mtd_add_partition (struct mtd_info *master,const char *name,long long offset,long long length);int mtd_del_partition (struct mtd_info *master,int partno);
Signature · 1 line
2.17.1
Miquel Raynal
maintainerPATCH v7 9/12 cmd: mtd: add 'mtd' command
In reply to Miquel RaynalThere should not be a 'nand' command, a 'sf' command and certainly not a new 'spi-nand' command. Write a 'mtd' command instead to manage all MTD devices/partitions at once. This should be the preferred way to access any MTD device.
--- cmd/Kconfig | 10 +- cmd/Makefile | 1 + cmd/mtd.c | 521 +++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/Makefile | 2 +- include/mtd.h | 1 + 5 files changed, 532 insertions(+), 3 deletions(-) create mode 100644 cmd/mtd.c
cmd/Kconfig +8 -2
@@ -854,6 +854,12 @@ config CMD_MMC_SWRITE Enable support for the "mmc swrite" command to write Android sparse images to eMMC. +config CMD_MTD + bool "mtd" + select MTD_PARTITIONS + help + MTD commands support. + config CMD_NAND bool "nand" default y if NAND_SUNXI
@@ -1678,14 +1684,14 @@ config CMD_MTDPARTS config MTDIDS_DEFAULT string "Default MTD IDs" - depends on CMD_MTDPARTS || CMD_NAND || CMD_FLASH + depends on CMD_MTD || CMD_MTDPARTS || CMD_NAND || CMD_FLASH help Defines a default MTD IDs list for use with MTD partitions in the Linux MTD command line partitions format. config MTDPARTS_DEFAULT string "Default MTD partition scheme" - depends on CMD_MTDPARTS || CMD_NAND || CMD_FLASH + depends on CMD_MTD || CMD_MTDPARTS || CMD_NAND || CMD_FLASH help Defines a default MTD partitioning scheme in the Linux MTD command line partitions format
cmd/Makefile +1 -0
@@ -91,6 +91,7 @@ obj-$(CONFIG_CMD_MISC) += misc.o obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_CMD_MMC_SPI) += mmc_spi.o obj-$(CONFIG_MP) += mp.o +obj-$(CONFIG_CMD_MTD) += mtd.o obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o obj-$(CONFIG_CMD_NAND) += nand.o obj-$(CONFIG_CMD_NET) += net.o
cmd/mtd.c new file +521 -0
521 lines not on this page · raw message
drivers/mtd/Makefile +1 -1
@@ -3,7 +3,7 @@ # (C) Copyright 2000-2007 # Wolfgang Denk, DENX Software Engineering, wd at denx.de. -ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND)$(CONFIG_CMD_SF))) +ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND)$(CONFIG_CMD_SF)$(CONFIG_CMD_MTD))) obj-y += mtdcore.o mtd_uboot.o endif obj-$(CONFIG_MTD) += mtd-uclass.o
include/mtd.h +1 -0
@@ -20,5 +20,6 @@ static inline struct mtd_info *mtd_get_info(struct udevice *dev) }int mtd_probe (struct udevice *dev); +int mtd_probe_devices (void );#endif /* _MTD_H_ */
Signature · 1 line
2.17.1
PATCH v7 9/12 cmd: mtd: add 'mtd' command
Quoted 37 lines · On Thu, 6 Sep 2018 09:08:51 +0200 Miquel Raynal <[email protected]>…
cmd/mtd.c new file +37
-0+ +int mtd_probe_devices (void ) +{ +const char *mtdparts =env_get ("mtdparts" ); +const char *mtdids =env_get ("mtdids" ); +bool remaining_partitions = true; +struct mtd_info *mtd; +int i; + +mtd_probe_uclass_mtd_devs (); + +/* Check if mtdparts/mtdids changed since last call, otherwise: exit */ +if (!strcmp (mtdparts, old_mtdparts) && !strcmp (mtdids, old_mtdids)) +return CMD_RET_SUCCESS ; + +/* Update the local copy of mtdparts */ +free (old_mtdparts); +free (old_mtdids); + old_mtdparts =strdup (mtdparts); + old_mtdids =strdup (mtdids); + +/* If at least one partition is still in use, do not delete anything */ +mtd_for_each_device (mtd) { +if (mtd->usecount) { +printf ("Partition \"%s\" already in use, aborting\n" , + mtd->name); +return CMD_RET_FAILURE ; + } + } + +/* +* Everything looks clear, remove all partitions. It is not safe to +* remove entries from the mtd_for_each_device loop as it uses idr +* indexes and the partitions removal is done in bulk (all partitions of +* one device at the same time), so break and iterate from start each +* time a new partition is found and deleted. +*/
cmd/mtd.c line 182
Quoted 10 lines
cmd/mtd.c new file +10
-0+while (remaining_partitions) { + remaining_partitions = false; +mtd_for_each_device (mtd) { +if (!mtd_is_partition (mtd) &&mtd_has_partitions (mtd)) { +del_mtd_partitions (mtd); + remaining_partitions = true; +break ; + } + } + }
Just a detail, but I think this logic could be moved in moved in the core (mtd_uboot.c).
Quoted 43 lines
cmd/mtd.c new file +43
-0+ +/* Start the parsing by ignoring the extra 'mtdparts=' prefix, if any */ +if (strstr (mtdparts,"mtdparts=" )) + mtdparts +=9 ; + +/* For each MTD device in mtdparts */ +while (mtdparts[0 ] !='\0' ) { +char mtd_name[MTD_NAME_MAX_LEN ], *colon; +struct mtd_partition *parts; +int mtd_name_len, len; +int ret; + + colon =strchr (mtdparts,':' ); +if (!colon) { +printf ("Wrong mtdparts: %s\n" , mtdparts); +return CMD_RET_FAILURE ; + } + + mtd_name_len = colon - mtdparts; +strncpy (mtd_name, mtdparts, mtd_name_len); + mtd_name[mtd_name_len] ='\0' ; +/* Move the pointer forward (including the ':') */ + mtdparts += mtd_name_len +1 ; + mtd =get_mtd_device_nm (mtd_name); +if (IS_ERR_OR_NULL (mtd)) { +char linux_name[MTD_NAME_MAX_LEN ]; + +/* +* The MTD device named "mtd_name" does not exist. Try +* to find a correspondance with an MTD device having +* the same type and number as defined in the mtdids. +*/ +debug ("No device named %s\n" , mtd_name); + ret =mtd_search_alternate_name (mtd_name, linux_name, +MTD_NAME_MAX_LEN ); +if (!ret) + mtd =get_mtd_device_nm (linux_name); + +/* +* If no device could be found, move the mtdparts +* pointer forward until the next set of partitions. +*/ +if (ret ||IS_ERR_OR_NULL (mtd)) {
cmd/mtd.c line 235
Quoted 10 lines
cmd/mtd.c new file +10
-0+printf ("Could not find a valid device for %s\n" , + mtd_name); + mtdparts =strchr (mtdparts,';' ); +if (mtdparts) + mtdparts++; + +continue ; + } + } +put_mtd_device (mtd);
Don't know if the refcounting is a nop or not, but shouldn't we keep a reference to mtd until we're done manipulating it (after the call to add_mtd_partitions())?
Quoted 14 lines
cmd/mtd.c new file +14
-0+ +/* +* Parse the MTD device partitions. It will update the mtdparts +* pointer, create an array of parts (that must be freed), and +* return the number of partition structures in the array. +*/ + ret =mtd_parse_partitions (mtd, &mtdparts, &parts, &len); +if (ret) { +printf ("Could not parse device %s\n" , mtd->name); +return CMD_RET_FAILURE ; + } + +if (!len) +continue ;
cmd/mtd.c line 259
Quoted 10 lines
cmd/mtd.c new file +10
-0+ +/* +* Create the new MTD partitions and free the structures +* allocated during the parsing. +*/ +add_mtd_partitions (mtd, parts, len); + +for (i =0 ; i < len; i++) +free ((char *)parts[i].name); +free (parts);
I'd recommend creating an helper for parts deletion:
void mtd_free_partitions(struct mtd_partitions *parts,
unsigned int nparts)
{
for (i = 0; i < len; i++)
free(parts[i].name);
free(parts);
}cmd/mtd.c line 163
Quoted 4 lines
cmd/mtd.c new file +4
-0+ } + +return CMD_RET_SUCCESS ; +}
Actually, I think the whole mtd_probe_devices() function (and its dependencies) should be moved in the core (mtd_uboot.c?) so that other components (ubi, cmd/mtdparts) can use it without depending/selecting CONFIG_CMD_MTD.
Miquel Raynal
maintainerPATCH v7 10/12 cmd: mtdparts: try to probe the MTD devices as a fallback
In reply to Miquel RaynalCurrent implementation of mtdparts command errors out if the desired MTD device is not found. Fallback to the new probe function in this case before erroring out.
This will the save the user the need to call something like 'mtd list' before mtdparts.
--- cmd/mtdparts.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
cmd/mtdparts.c +13 -3
@@ -79,6 +79,10 @@#include <linux/err.h> #include <linux/mtd/mtd.h> +#if defined(CONFIG_MTD ) +#include <mtd.h> +#endif +#if defined(CONFIG_CMD_NAND )#include <linux/mtd/rawnand.h> #include <nand.h>
@@ -307,9 +311,15 @@ static int get_mtd_info(u8 type, u8 num, struct mtd_info **mtd)sprintf (mtd_dev,"%s%d" ,MTD_DEV_TYPE (type), num); *mtd =get_mtd_device_nm (mtd_dev); -if (IS_ERR (*mtd)) { -printf ("Device %s not found!\n" , mtd_dev); -return 1 ; +if (IS_ERR_OR_NULL (*mtd)) { +#ifdef CONFIG_MTD +mtd_probe_devices (); + *mtd =get_mtd_device_nm (mtd_dev); +#endif +if (IS_ERR_OR_NULL (*mtd)) { +printf ("Device %s not found!\n" , mtd_dev); +return 1 ; + } }put_mtd_device (*mtd);
Signature · 1 line
2.17.1
PATCH v7 10/12 cmd: mtdparts: try to probe the MTD devices as a fallback
Quoted 30 lines · On Thu, 6 Sep 2018 09:08:52 +0200 Miquel Raynal <[email protected]>…
Current implementation of mtdparts command errors out if the desired MTD device is not found. Fallback to the new probe function in this case before erroring out.
This will the save the user the need to call something like 'mtd list' before mtdparts.
Signed-off-by Miquel Raynal <[email protected]>Acked-by Jagan Teki <[email protected]>Reviewed-by Stefan Roese <[email protected]>--- cmd/mtdparts.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)cmd/mtdparts.c +4
-0@@ -79,6 +79,10 @@#include <linux/err.h> #include <linux/mtd/mtd.h> +#if defined(CONFIG_MTD ) +#include <mtd.h> +#endif +#if defined(CONFIG_CMD_NAND )#include <linux/mtd/rawnand.h> #include <nand.h>
cmd/mtdparts.c static int get_mtd_info(u8 type, u8 num, struct mtd_info **mtd) · line 315
Quoted 8 lines
cmd/mtdparts.c +2
-3@@ -307,9 +311,15 @@ static int get_mtd_info(u8 type, u8 num, struct mtd_info **mtd)sprintf (mtd_dev,"%s%d" ,MTD_DEV_TYPE (type), num); *mtd =get_mtd_device_nm (mtd_dev); -if (IS_ERR (*mtd)) { -printf ("Device %s not found!\n" , mtd_dev); -return 1 ; +if (IS_ERR_OR_NULL (*mtd)) { +#ifdef CONFIG_MTD
In its current state, it should #ifdef CONFIG_CMD_MTD, since mtd_probe_devices() is implemented in cmd/mtd.c. Anyway, as I suggested, I think it's better to just move that in mtd_uboot.c and drop the #ifdef.
cmd/mtdparts.c static int get_mtd_info(u8 type, u8 num, struct mtd_info **mtd) · line 318
Quoted 3 lines
cmd/mtdparts.c +3
-0+mtd_probe_devices (); + *mtd =get_mtd_device_nm (mtd_dev); +#endif
BTW, I'm not sure why we need to call mtd_probe_devices() here. If we really want to deprecate this command, then I'd recommend not adding new features to it.
Quoted 7 lines
cmd/mtdparts.c +4
-0+if (IS_ERR_OR_NULL (*mtd)) { +printf ("Device %s not found!\n" , mtd_dev); +return 1 ; + } }put_mtd_device (*mtd);
Miquel Raynal
maintainerPATCH v7 11/12 cmd: ubi: clean the partition handling
In reply to Miquel RaynalUBI should not mess with MTD partitions, now that the partitions are handled in a clean way, clean the ubi command and avoid using this uneeded extra-glue to reference the devices.
--- cmd/Kconfig | 2 ++ cmd/ubi.c | 100 +++++++++++++++------------------------------------- 2 files changed, 31 insertions(+), 71 deletions(-)
cmd/Kconfig +2 -0
@@ -1822,6 +1822,8 @@ config CMD_UBI capabilities. Please, consult the MTD web site for more details (www.linux-mtd.infradead.org). Activate this option if you want to use U-Boot UBI commands. + It is also strongly encouraged to also enable CONFIG_MTD to get full + partition support. config CMD_UBIFS tristate "Enable UBIFS - Unsorted block images filesystem commands"
cmd/ubi.c +29 -71
166 lines not on this page · raw message
Signature · 1 line
2.17.1
PATCH v7 11/12 cmd: ubi: clean the partition handling
Hi Miquel,
Quoted 9 lines · On Thu, 6 Sep 2018 09:08:53 +0200 Miquel Raynal <[email protected]>…
int
ubi_part(char *part_name, const char *vid_header_offset){cmd/ubi.c +1
-4+struct mtd_info *mtd;int err =0 ; -char mtd_dev[16 ]; -struct mtd_device *dev; -struct part_info *part; -u8 pnum;
cmd/ubi.c int ubi_detach(void) · line 458
Quoted 10 lines
cmd/ubi.c +4
-5ubi_detach (); -/* -* Search the mtd device number where this partition -* is located -*/ -if (find_dev_and_part (part_name, &dev, &pnum, &part)) { + +#ifdef CONFIG_MTD +mtd_probe_devices (); +#endif
Okay, so just like for the mtdparts patch, the #ifdef is incorrect, but more importantly, with you're rework, you're breaking all non-DM platforms, because the UBI layer no longer creates an MTD device on the fly, and the mtd partition creation won't take place if CONFIG_MTD is not activated.
My suggestion would be to make mtd_probe_devices() available to everyone (not only those who have CONFIG_MTD selected, which in turn depends on CONFIG_DM) so that the mtd part creation is done unconditionally, and you can safely get rid of the "dummy MTD device creation" done in UBI.
cmd/ubi.c int ubi_detach(void) · line 460
Quoted 2 lines
cmd/ubi.c +2
-0+ mtd =get_mtd_device_nm (part_name); +if (IS_ERR (mtd)) {
Regards,
Boris
Miquel Raynal
maintainerPATCH v7 12/12 cmd: mtdparts: describe as legacy
In reply to Miquel RaynalThe 'mtdparts' command is not needed anymore. While the environment variable is still valid (and useful, along with the 'mtdids' one), the command has been replaced by 'mtd' which is much more close to the MTD stack and do not add its own specific glue.
--- cmd/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
cmd/Kconfig +5 -1
@@ -1680,7 +1680,11 @@ config CMD_MTDPARTS bool "MTD partition support" select MTD_DEVICE if (CMD_NAND || NAND) help - MTD partition support + MTD partitioning tool support. + It is strongly encouraged to avoid using this command + anymore. One can still declare the partitions in the + mtdparts environment variable but better use the MTD stack + and the mtd command instead than this one. config MTDIDS_DEFAULT string "Default MTD IDs"
Signature · 1 line
2.17.1
PATCH v7 12/12 cmd: mtdparts: describe as legacy
Quoted 16 lines · On Thu, 6 Sep 2018 09:08:54 +0200 Miquel Raynal <[email protected]>…
The 'mtdparts' command is not needed anymore. While the environment variable is still valid (and useful, along with the 'mtdids' one), the command has been replaced by 'mtd' which is much more close to the MTD stack and do not add its own specific glue.
Signed-off-by Miquel Raynal <[email protected]>Reviewed-by Stefan Roese <[email protected]>--- cmd/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)cmd/Kconfig +0
-0
cmd/Kconfig config CMD_MTDPARTS · line 1687
Quoted 9 lines
cmd/Kconfig +5
-1@@ -1680,7 +1680,11 @@ config CMD_MTDPARTS bool "MTD partition support" select MTD_DEVICE if (CMD_NAND || NAND) help - MTD partition support + MTD partitioning tool support. + It is strongly encouraged to avoid using this command + anymore. One can still declare the partitions in the + mtdparts environment variable but better use the MTD stack + and the mtd command instead than this one.
Well, that's only working if people stop using nand,onenand,sf,... commands in favor the mtd ones, otherwise they still need mtdparts, unfortunately :-(.
I guess a long term goal could be to define aliases between flash specific commands and the generic mtd ones so that we can get rid of cmd/<flashcmd>.c drivers.
Regards,
Boris
Miquel Raynal
maintainerv7 cover SPI-NAND support
In reply to Miquel RaynalHello,
I failed the numbering, this is actually the v8. The below changelog is still right though. I don't plan to resend unless I am explicitly told to do so.
Sorry for the mistake.
Thanks,
Miquèl
Miquel Raynal <[email protected]> wrote on Thu, 6 Sep 2018 09:08:42 +0200:
Quoted 174 lines
During the last months, Boris Brezillon shared his work to support serial flashes within Linux. First, he delivered (and merged) a new layer called spi-mem. He also initiated in Linux MTD subsystem the move of all 'raw' NAND related code to a raw/ subdirectory, adding at the same time a NAND core that would be shared with all NAND devices. Then, he contributed a generic SPI-NAND driver, making use of this NAND core, as well as some vendor code to drive a few chips.
On top of this work, I made some cleanups in the MTD layer and added an 'mtd' U-Boot command to handle all sort of MTD devices. This should become the default command instead of having one per flash flavor ('sf', 'nand', 'spi-nand' ?).
The series has been tested on an Ocelot board PCB123 (VSC7514), featuring a Macronix SPI NAND chip.
TL;DR: the series contains (stripped version since 23 patches have already been taken):
- Various fixes
- Support for spi-nand devices in mtdparts.
- Generics mtdparts/mtdids parsers.
- A new 'mtd' command.
- A note to set mtdparts command legacy.To test your SPI-NAND device with U-Boot, you can test someting like:
Quoted 4 lines
setenv mtdparts 'spi-nand0:1m(foo),-(bar)'
setenv mtdids 'spi-nand0=spi0.0' # spi0.0 is Linux MTD name for this device
ubi part bar # create a static UBI volume in the bar partition
mtd list # show the current MTD devices/partitionsThanks,
MiquèlChanges since v7:
-----------------
* Added Stefan R-b tags.
* Usedtolower()as suggested by Stefan inlib/strto.c.
* Added a mention saying that we continue to abuse the kB suffix inlib/strto.cby not making a difference between kB and kiB which both mean "* 1024" for us. This has been added in the commit log.
* Fixed various bugs in the mtd command and in the parsers, they should be pretty stable now (tested with two MTD devices probed and several different partition configurations).
* mtdids is not deprecated at all as opposed at what I wrote in v6. U-Boot still uses its own MTD names (being <type><idx> like nor0 or spi-nand1) and mtdids is still needed to do the glue.
* Removed a useless patch removing aKconfigentry I added myself since during a rebase someone else also added this symbol.Changes since v6:
-----------------
* Squashed Boris' fixes about build issues in Travis.
* Merged Stefan Roese's contributions.
* cmd: mtdparts:
* added fallthrough comments in switch blocks deriving sizes.
* balanced debug messages to compare freed and allocated partitions.
* movemtdparts_init()declaration inmtd/partitions.hto be used in mtd command as well.
* introduced a "compatibility" function to return what the MTD device name could be thanks to the mtdids environment variable (which is useless with the new partitioning logic).
* mtd: mtdpart:
* reworked the way partitions are created/handled.
* cmd: mtd:
* implement a partitioning logic that takes the best out of the MTD layer without re-inventing the wheel. Partitions are all freed correctly when the value of mtdparts changes.
* balanceget_mtd_device()byput_mtd_device()calls.
* prevent memory leak by reorganizing the code a bit indo_mtd.
* do not reconstruct partition list when a partition is already in use (complain about that instead).
* add support for the legacy mtdids (not needed anymore if mtdparts directly uses the MTD device names as in Linux.
* cmd: ubi:
* clean and simplify the partition handling a bit to make use the best use of the MTD layer as well and keep the code simple.Changes since v5:
-----------------
* Included Boris fixup about the build issues.
* Added Rb/Ab tags from Jagan on patchs 20/21.Changes since v4:
-----------------
* Added Jagan's Acked-by tags to every patch related to the SPI-mem/SPI-NAND addition.
* Rebased on top of master.Changes since v3:
-----------------
* Fixed the debug messages in spi-mem to print either Rx or Tx data.
* Fixed aKconfigerror that prevented to build mtdparts with plain defconfig.
* Fixed a compilation error due to the above error that prevented one file to be compiled.
* Adapted the mtd command to probe MTD partitions also.
* Declaredmtd_probe_devices()in a header so mtdparts or UBI could use it too (to probe all devices and MTD partitions in a clean way).
* As I worked on mtdparts, I found annoying and completely useless the fact that we need to prefix the environment variable with "mtdparts=". Canceled this obligation.
* Added one patch to allow spi-nand devices to be recognized by mtdparts (this is purely useless but needed to be done in order to use this command).
* Removed useless definitions of MTD device types in UBI code.
* Wrote a generic mtdparts environment variable parser, used by the mtd command.
* Used themtd_probe_devices()function fromget_mtd_info()incmd/mtdparts.cto be sure the desired partition really does not exist (otherwise it will be probed and then found).Changes since v2:
-----------------
* Rebased on u-boot master branch.
* Removed extra-parenthesis in
"mtd: Fallback to ->_read/write() when ->_read/write_oob() is missing"
* s/fiels/files/ in "mtd: move NAND fiels into a raw/ subdirectory"
* Do not describe generic SPI device properties in SPI NAND bindings.
* Changes in the mtd command:
* Printing more information in 'mtd list' (device type, device characteristics)
* Switch todo_div()instead of '(u32)value64b % value32b' which only worked because value32b was a power of 2.
* Removed erase.chip option.
* By default, erase/read/write happen on the full MTD device while a dump will only work on a single page.Changes since v1:
-----------------
* Fixed thenand_memorgstructure of the MX35LF2GE4AB chip.
* Added Reviewed-by tags from Jagan.
* Backported and squashed two patches fixing things in the SPI NAND core received on the Linux ML.
* Backported more changes inmtdcore.cfrom Linux.
* Added a patch to add a fallback on mtd->_read/_write() inmtdcore.cwhen mtd->_read/write_oob() is not supported.
* Removed the DT changes, useless as the DTs are not available in mainline yet.
* Addressed Boris/Stefan comments on the 'mtd' command.
* Added support for multi-pages OOB read/write.Miquel Raynal (12):
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefix
mtd: uclass: add probe function
mtd: uclass: add a generic 'mtdparts' parser
mtd: uclass: search for an equivalent MTD name with the mtdids
mtd: mtdpart: implement proper partition handling
cmd: mtd: add 'mtd' command
cmd: mtdparts: try to probe the MTD devices as a fallback
cmd: ubi: clean the partition handling
cmd: mtdparts: describe as legacycmd/Kconfig | 18 +- cmd/Makefile | 1 + cmd/mtd.c | 521 ++++++++++++++++++++++++++ cmd/mtdparts.c | 46 ++- cmd/ubi.c | 100 ++--- drivers/mtd/Makefile | 2 +- drivers/mtd/mtd-uclass.c | 16 + drivers/mtd/mtdcore.c | 2 + drivers/mtd/mtdpart.c | 660 +++++++++++++++++++++------------ include/jffs2/load_kernel.h | 7 +- include/linux/mtd/mtd.h | 31 ++ include/linux/mtd/partitions.h | 5 +- include/mtd.h | 3 + lib/strto.c | 36 +- 14 files changed, 1094 insertions(+), 354 deletions(-) create mode 100644 cmd/mtd.c
Signature · 3 lines
Miquel Raynal, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
v7 cover SPI-NAND support
Hi Jagan,
I just wanted to ask about the timeline for the SPI-NAND patches. I remember that Tom wanted to have them in 2018.11. Is this going to happen or is there anything preventing this?
Thanks,
Frieder
Quoted 192 lines · Miquel Raynal
Hello,
I failed the numbering, this is actually the v8. The below changelog is still right though. I don't plan to resend unless I am explicitly told to do so.
Sorry for the mistake.
Thanks,
MiquèlMiquel Raynal <[email protected]> wrote on Thu, 6 Sep 2018 09:08:42 +0200:
Quoted 174 lines
During the last months, Boris Brezillon shared his work to support serial flashes within Linux. First, he delivered (and merged) a new layer called spi-mem. He also initiated in Linux MTD subsystem the move of all 'raw' NAND related code to a raw/ subdirectory, adding at the same time a NAND core that would be shared with all NAND devices. Then, he contributed a generic SPI-NAND driver, making use of this NAND core, as well as some vendor code to drive a few chips.
On top of this work, I made some cleanups in the MTD layer and added an 'mtd' U-Boot command to handle all sort of MTD devices. This should become the default command instead of having one per flash flavor ('sf', 'nand', 'spi-nand' ?).
The series has been tested on an Ocelot board PCB123 (VSC7514), featuring a Macronix SPI NAND chip.
TL;DR: the series contains (stripped version since 23 patches have already been taken):
- Various fixes
- Support for spi-nand devices in mtdparts.
- Generics mtdparts/mtdids parsers.
- A new 'mtd' command.
- A note to set mtdparts command legacy.To test your SPI-NAND device with U-Boot, you can test someting like:
Quoted 4 lines
setenv mtdparts 'spi-nand0:1m(foo),-(bar)'
setenv mtdids 'spi-nand0=spi0.0' # spi0.0 is Linux MTD name for this device
ubi part bar # create a static UBI volume in the bar partition
mtd list # show the current MTD devices/partitionsThanks,
MiquèlChanges since v7:
-----------------
* Added Stefan R-b tags.
* Usedtolower()as suggested by Stefan inlib/strto.c.
* Added a mention saying that we continue to abuse the kB suffix inlib/strto.cby not making a difference between kB and kiB which both mean "* 1024" for us. This has been added in the commit log.
* Fixed various bugs in the mtd command and in the parsers, they should be pretty stable now (tested with two MTD devices probed and several different partition configurations).
* mtdids is not deprecated at all as opposed at what I wrote in v6. U-Boot still uses its own MTD names (being <type><idx> like nor0 or spi-nand1) and mtdids is still needed to do the glue.
* Removed a useless patch removing aKconfigentry I added myself since during a rebase someone else also added this symbol.Changes since v6:
-----------------
* Squashed Boris' fixes about build issues in Travis.
* Merged Stefan Roese's contributions.
* cmd: mtdparts:
* added fallthrough comments in switch blocks deriving sizes.
* balanced debug messages to compare freed and allocated partitions.
* movemtdparts_init()declaration inmtd/partitions.hto be used in mtd command as well.
* introduced a "compatibility" function to return what the MTD device name could be thanks to the mtdids environment variable (which is useless with the new partitioning logic).
* mtd: mtdpart:
* reworked the way partitions are created/handled.
* cmd: mtd:
* implement a partitioning logic that takes the best out of the MTD layer without re-inventing the wheel. Partitions are all freed correctly when the value of mtdparts changes.
* balanceget_mtd_device()byput_mtd_device()calls.
* prevent memory leak by reorganizing the code a bit indo_mtd.
* do not reconstruct partition list when a partition is already in use (complain about that instead).
* add support for the legacy mtdids (not needed anymore if mtdparts directly uses the MTD device names as in Linux.
* cmd: ubi:
* clean and simplify the partition handling a bit to make use the best use of the MTD layer as well and keep the code simple.Changes since v5:
-----------------
* Included Boris fixup about the build issues.
* Added Rb/Ab tags from Jagan on patchs 20/21.Changes since v4:
-----------------
* Added Jagan's Acked-by tags to every patch related to the SPI-mem/SPI-NAND addition.
* Rebased on top of master.Changes since v3:
-----------------
* Fixed the debug messages in spi-mem to print either Rx or Tx data.
* Fixed aKconfigerror that prevented to build mtdparts with plain defconfig.
* Fixed a compilation error due to the above error that prevented one file to be compiled.
* Adapted the mtd command to probe MTD partitions also.
* Declaredmtd_probe_devices()in a header so mtdparts or UBI could use it too (to probe all devices and MTD partitions in a clean way).
* As I worked on mtdparts, I found annoying and completely useless the fact that we need to prefix the environment variable with "mtdparts=". Canceled this obligation.
* Added one patch to allow spi-nand devices to be recognized by mtdparts (this is purely useless but needed to be done in order to use this command).
* Removed useless definitions of MTD device types in UBI code.
* Wrote a generic mtdparts environment variable parser, used by the mtd command.
* Used themtd_probe_devices()function fromget_mtd_info()incmd/mtdparts.cto be sure the desired partition really does not exist (otherwise it will be probed and then found).Changes since v2:
-----------------
* Rebased on u-boot master branch.
* Removed extra-parenthesis in
"mtd: Fallback to ->_read/write() when ->_read/write_oob() is missing"
* s/fiels/files/ in "mtd: move NAND fiels into a raw/ subdirectory"
* Do not describe generic SPI device properties in SPI NAND bindings.
* Changes in the mtd command:
* Printing more information in 'mtd list' (device type, device characteristics)
* Switch todo_div()instead of '(u32)value64b % value32b' which only worked because value32b was a power of 2.
* Removed erase.chip option.
* By default, erase/read/write happen on the full MTD device while a dump will only work on a single page.Changes since v1:
-----------------
* Fixed thenand_memorgstructure of the MX35LF2GE4AB chip.
* Added Reviewed-by tags from Jagan.
* Backported and squashed two patches fixing things in the SPI NAND core received on the Linux ML.
* Backported more changes inmtdcore.cfrom Linux.
* Added a patch to add a fallback on mtd->_read/_write() inmtdcore.cwhen mtd->_read/write_oob() is not supported.
* Removed the DT changes, useless as the DTs are not available in mainline yet.
* Addressed Boris/Stefan comments on the 'mtd' command.
* Added support for multi-pages OOB read/write.Miquel Raynal (12):
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefix
mtd: uclass: add probe function
mtd: uclass: add a generic 'mtdparts' parser
mtd: uclass: search for an equivalent MTD name with the mtdids
mtd: mtdpart: implement proper partition handling
cmd: mtd: add 'mtd' command
cmd: mtdparts: try to probe the MTD devices as a fallback
cmd: ubi: clean the partition handling
cmd: mtdparts: describe as legacycmd/Kconfig | 18 +- cmd/Makefile | 1 + cmd/mtd.c | 521 ++++++++++++++++++++++++++ cmd/mtdparts.c | 46 ++- cmd/ubi.c | 100 ++--- drivers/mtd/Makefile | 2 +- drivers/mtd/mtd-uclass.c | 16 + drivers/mtd/mtdcore.c | 2 + drivers/mtd/mtdpart.c | 660 +++++++++++++++++++++------------ include/jffs2/load_kernel.h | 7 +- include/linux/mtd/mtd.h | 31 ++ include/linux/mtd/partitions.h | 5 +- include/mtd.h | 3 + lib/strto.c | 36 +- 14 files changed, 1094 insertions(+), 354 deletions(-)create mode 100644
cmd/mtd.c
v7 cover SPI-NAND support
Quoted 5 lines · Frieder Schrempf
Hi Jagan,
I just wanted to ask about the timeline for the SPI-NAND patches. I remember that Tom wanted to have them in 2018.11. Is this going to happen or is there anything preventing this?
Travis[1] for combination of earlier series + this. Will send PR soon I get the results.
Miquel, Let me know if anything miss here?
[1] https://travis-ci.org/openedev/u-boot-amarula/builds/431062285
Miquel Raynal
maintainerv7 cover SPI-NAND support
Hi Jagan, Frieder,
Jagan Teki <[email protected]> wrote on Thu, 20 Sep 2018 20:16:06 +0530:
Quoted 8 lines
Quoted 5 lines · Frieder Schrempf
Hi Jagan,
I just wanted to ask about the timeline for the SPI-NAND patches. I remember that Tom wanted to have them in 2018.11. Is this going to happen or is there anything preventing this?
Quoted 6 lines
Travis[1] for combination of earlier series + this. Will send PR soon I get the results.
Miquel, Let me know if anything miss here?
[1] https://travis-ci.org/openedev/u-boot-amarula/builds/431062285
You can definitely take the earlier series, they are fine and work on their own. About this one, the four first patches are fine and won't be changed, please keep them:
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefix
For the rest, as pointed by Boris, it would break UBI for certain users so I want to make a last version (mostly code moves) next week to fit it. I will resend a v9 only for patches:
mtd: uclass: add probe function
mtd: uclass: add a generic 'mtdparts' parser
mtd: uclass: search for an equivalent MTD name with the mtdids
mtd: mtdpart: implement proper partition handling
cmd: mtd: add 'mtd' command
cmd: mtdparts: try to probe the MTD devices as a fallback
cmd: ubi: clean the partition handling
cmd: mtdparts: describe as legacy
2018.11 is definitely the target.
Thanks,
Miquèl
v7 cover SPI-NAND support
Hi Miquel,
Quoted 40 lines · Miquel Raynal
Hi Jagan, Frieder,
Jagan Teki <[email protected]> wrote on Thu, 20 Sep 2018 20:16:06 +0530:
Quoted 8 lines
Quoted 5 lines · Frieder Schrempf
Hi Jagan,
I just wanted to ask about the timeline for the SPI-NAND patches. I remember that Tom wanted to have them in 2018.11. Is this going to happen or is there anything preventing this?
Quoted 6 lines
Travis[1] for combination of earlier series + this. Will send PR soon I get the results.
Miquel, Let me know if anything miss here?
[1] https://travis-ci.org/openedev/u-boot-amarula/builds/431062285
You can definitely take the earlier series, they are fine and work on their own. About this one, the four first patches are fine and won't be changed, please keep them:
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefixFor the rest, as pointed by Boris, it would break UBI for certain users so I want to make a last version (mostly code moves) next week to fit it. I will resend a v9 only for patches:
mtd: uclass: add probe function
mtd: uclass: add a generic 'mtdparts' parser
mtd: uclass: search for an equivalent MTD name with the mtdids
mtd: mtdpart: implement proper partition handling
cmd: mtd: add 'mtd' command
cmd: mtdparts: try to probe the MTD devices as a fallback
cmd: ubi: clean the partition handling
cmd: mtdparts: describe as legacy
Quoted 1 line
2018.11 is definitely the target.
Ok, good to know and thanks a lot for the effort you are putting into this.
Thanks,
Frieder
Quoted 5 lines
Thanks,
Miquèl
v7 cover SPI-NAND support
In reply to Miquel RaynalQuoted 21 lines · Miquel Raynal
Hi Jagan, Frieder,
Jagan Teki <[email protected]> wrote on Thu, 20 Sep 2018 20:16:06 +0530:
Quoted 8 lines
Quoted 5 lines · Frieder Schrempf
Hi Jagan,
I just wanted to ask about the timeline for the SPI-NAND patches. I remember that Tom wanted to have them in 2018.11. Is this going to happen or is there anything preventing this?
Quoted 6 lines
Travis[1] for combination of earlier series + this. Will send PR soon I get the results.
Miquel, Let me know if anything miss here?
[1] https://travis-ci.org/openedev/u-boot-amarula/builds/431062285
Quoted 7 lines
You can definitely take the earlier series, they are fine and work on their own. About this one, the four first patches are fine and won't be changed, please keep them:
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefix
I shall pick upto this and wait for v8 to send PR together.
Miquel Raynal
maintainerv7 cover SPI-NAND support
Hi Jagan,
Jagan Teki <[email protected]> wrote on Fri, 21 Sep 2018 13:45:56 +0530:
Quoted 30 lines · Miquel Raynal
Quoted 21 lines
Hi Jagan, Frieder,
Jagan Teki <[email protected]> wrote on Thu, 20 Sep 2018 20:16:06 +0530:
Quoted 8 lines
Quoted 5 lines · Frieder Schrempf
Hi Jagan,
I just wanted to ask about the timeline for the SPI-NAND patches. I remember that Tom wanted to have them in 2018.11. Is this going to happen or is there anything preventing this?
Quoted 6 lines
Travis[1] for combination of earlier series + this. Will send PR soon I get the results.
Miquel, Let me know if anything miss here?
[1] https://travis-ci.org/openedev/u-boot-amarula/builds/431062285
Quoted 7 lines
You can definitely take the earlier series, they are fine and work on their own. About this one, the four first patches are fine and won't be changed, please keep them:
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefix
Quoted 1 line
I shall pick upto this and wait for v8 to send PR together.
Perfect!
Thanks,
Miquèl
Miquel Raynal
maintainerv7 cover SPI-NAND support
In reply to Jagan TekiHi Jagan,
Jagan Teki <[email protected]> wrote on Fri, 21 Sep 2018 13:45:56 +0530:
Quoted 30 lines · Miquel Raynal
Quoted 21 lines
Hi Jagan, Frieder,
Jagan Teki <[email protected]> wrote on Thu, 20 Sep 2018 20:16:06 +0530:
Quoted 8 lines
Quoted 5 lines · Frieder Schrempf
Hi Jagan,
I just wanted to ask about the timeline for the SPI-NAND patches. I remember that Tom wanted to have them in 2018.11. Is this going to happen or is there anything preventing this?
Quoted 6 lines
Travis[1] for combination of earlier series + this. Will send PR soon I get the results.
Miquel, Let me know if anything miss here?
[1] https://travis-ci.org/openedev/u-boot-amarula/builds/431062285
Quoted 7 lines
You can definitely take the earlier series, they are fine and work on their own. About this one, the four first patches are fine and won't be changed, please keep them:
lib: strto: parse all lowercase metric prefixes in ustrtoul[l]
lib: strto: fix metric suffix parsing in strtoul[l]
cmd: mtdparts: accept spi-nand devices
cmd: mtdparts: remove mandatory 'mtdparts=' prefix
Quoted 1 line
I shall pick upto this and wait for v8 to send PR together.
Here you have the v9 in your mailbox (this was the v8 but I messed-up with git-format-patch). For me all the features (both for spi-nand and the 'mtd' command) are available.
I hope this is not too late before the merge window closes, I spent more time than expected testing/fixing small errors. Of course I'm still there and listen for feedback/bug reports.
Thanks,
Miquèl
Signature · 3 lines
Miquel Raynal, Bootlin Embedded Linux and Kernel engineering https://bootlin.com