mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* mtd partition handling updates
@ 2015-02-12  8:54 Sascha Hauer
  2015-02-12  8:54 ` [PATCH 01/17] of: Add for_each_child_of_node_safe Sascha Hauer
                   ` (17 more replies)
  0 siblings, 18 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

This series updates the mtd partition handling in barebox. It used
to be too simple to create conflicting or inconsistent partitions on
mtd devices. mtd partitions can be changed from board code, from the
device tree, using addpart/delpart and with this series also with
the newly created 'partitions' parameter for mtd devices. The
informations are now kept in a consistent state, with each changed
partition the partitions parameter is updated and when starting
the kernel partitions in the device tree are also updated to the
current partitioning.
What's still missing is a way to store the partitioning somewhere
in the environment, perhaps in a nonvolatile variable.

Sascha


The following changes since commit d7dc46d5d6f2c80d1719ef877df728457790ac45:

  defaultenv: ignore barebox_zero_env (2015-02-11 08:34:29 +0100)

are available in the git repository at:

  git://git.pengutronix.de/git/barebox.git 

for you to fetch changes up to cd7feae00b43eeddcaeb229f861d0ddac93f91e2:

  defaultenv-2: mtdparts-add: Use new partition parameter (2015-02-12 09:33:44 +0100)

----------------------------------------------------------------
Sascha Hauer (17):
      of: Add for_each_child_of_node_safe
      mtd: core: add error checks
      mtd: partitions: Use xstrdup
      mtd: partitions: Add error check
      mtd: Add partitions to list
      mtd: nand: remove automatically created bb devices
      move cmdline partition parsing code to separate file
      cmdlinepart: Change SIZE_REMAINING to loff_t
      cmdlinepart: make argument types safer
      cmdlinepart: add function to parse a cmdline partition string
      cmndlinepart: skip devname if partstr already contains it
      mtd: forbid conflicting mtd partitions
      mtd: Use flags parameter in mtd_add_partition
      mtd: Add a partitions parameter to mtd devices
      mtd: fixup device tree partitions
      defaultenv-2: mtdparts-add: remove unused variable
      defaultenv-2: mtdparts-add: Use new partition parameter

 commands/partition.c                          | 104 +------------
 defaultenv/defaultenv-2-base/bin/mtdparts-add |  15 +-
 drivers/mtd/core.c                            | 213 +++++++++++++++++++++++++-
 drivers/mtd/nand/nand-bb.c                    |  16 +-
 drivers/mtd/partition.c                       |  14 +-
 include/cmdlinepart.h                         |  14 ++
 include/linux/mtd/mtd.h                       |   5 +
 include/nand.h                                |   7 +-
 include/of.h                                  |   2 +
 lib/Makefile                                  |   1 +
 lib/cmdlinepart.c                             | 124 +++++++++++++++
 11 files changed, 393 insertions(+), 122 deletions(-)
 create mode 100644 include/cmdlinepart.h
 create mode 100644 lib/cmdlinepart.c

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/17] of: Add for_each_child_of_node_safe
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 02/17] mtd: core: add error checks Sascha Hauer
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

Needed for iterating over child nodes and deleting the children.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/of.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/of.h b/include/of.h
index 5273f87..2ad9418 100644
--- a/include/of.h
+++ b/include/of.h
@@ -623,6 +623,8 @@ static inline struct device_node *of_find_matching_node(
 	for (dn = of_find_node_with_property(NULL, prop_name); dn; \
 	     dn = of_find_node_with_property(dn, prop_name))
 
+#define for_each_child_of_node_safe(parent, tmp, child) \
+	list_for_each_entry_safe(child, tmp, &parent->children, parent_list)
 #define for_each_child_of_node(parent, child) \
 	list_for_each_entry(child, &parent->children, parent_list)
 #define for_each_available_child_of_node(parent, child) \
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 02/17] mtd: core: add error checks
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
  2015-02-12  8:54 ` [PATCH 01/17] of: Add for_each_child_of_node_safe Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 03/17] mtd: partitions: Use xstrdup Sascha Hauer
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

register_device and devfs_create can fail. Add error checks for these.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 345752e..21d04a1 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -380,6 +380,7 @@ static struct file_operations mtd_ops = {
 int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 {
 	struct mtddev_hook *hook;
+	int ret;
 
 	if (!devname)
 		devname = "mtd";
@@ -387,7 +388,10 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 	mtd->class_dev.id = device_id;
 	if (mtd->parent)
 		mtd->class_dev.parent = mtd->parent;
-	register_device(&mtd->class_dev);
+
+	ret = register_device(&mtd->class_dev);
+	if (ret)
+		return ret;
 
 	mtd->cdev.ops = &mtd_ops;
 	mtd->cdev.size = mtd->size;
@@ -407,7 +411,9 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 		dev_add_param_int_ro(&mtd->class_dev, "oobsize", mtd->oobsize, "%u");
 	}
 
-	devfs_create(&mtd->cdev);
+	ret = devfs_create(&mtd->cdev);
+	if (ret)
+		goto err;
 
 	if (mtd_can_have_bb(mtd))
 		mtd->cdev_bb = mtd_add_bb(mtd, NULL);
@@ -420,6 +426,11 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 			hook->add_mtd_device(mtd, devname, &hook->priv);
 
 	return 0;
+err:
+	free(mtd->cdev.name);
+	unregister_device(&mtd->class_dev);
+
+	return ret;
 }
 
 int del_mtd_device (struct mtd_info *mtd)
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 03/17] mtd: partitions: Use xstrdup
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
  2015-02-12  8:54 ` [PATCH 01/17] of: Add for_each_child_of_node_safe Sascha Hauer
  2015-02-12  8:54 ` [PATCH 02/17] mtd: core: add error checks Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 04/17] mtd: partitions: Add error check Sascha Hauer
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

The return value of strdup is not checked. Use xstrdup instead.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/partition.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
index e393fa6..033a7d2 100644
--- a/drivers/mtd/partition.c
+++ b/drivers/mtd/partition.c
@@ -160,7 +160,7 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 
 	part->block_isbad = mtd->block_isbad ? mtd_part_block_isbad : NULL;
 	part->size = size;
-	part->name = strdup(name);
+	part->name = xstrdup(name);
 
 	part->master_offset = offset;
 	part->master = mtd;
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 04/17] mtd: partitions: Add error check
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (2 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 03/17] mtd: partitions: Use xstrdup Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 05/17] mtd: Add partitions to list Sascha Hauer
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

add_mtd_device can fail. Add an error check and bail out properly.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/partition.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
index 033a7d2..c514d4b 100644
--- a/drivers/mtd/partition.c
+++ b/drivers/mtd/partition.c
@@ -108,6 +108,7 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 		uint64_t size, unsigned long flags, const char *name)
 {
 	struct mtd_info *part;
+	int ret;
 
 	part = xzalloc(sizeof(*part));
 
@@ -168,9 +169,17 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 	if (!strncmp(mtd->cdev.name, name, strlen(mtd->cdev.name)))
 		part->cdev.partname = xstrdup(name + strlen(mtd->cdev.name) + 1);
 
-	add_mtd_device(part, part->name, DEVICE_ID_SINGLE);
+	ret = add_mtd_device(part, part->name, DEVICE_ID_SINGLE);
+	if (ret)
+		goto err;
 
 	return part;
+err:
+	free(part->cdev.partname);
+	free(part->name);
+	free(part);
+
+	return ERR_PTR(ret);
 }
 
 int mtd_del_partition(struct mtd_info *part)
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 05/17] mtd: Add partitions to list
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (3 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 04/17] mtd: partitions: Add error check Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 06/17] mtd: nand: remove automatically created bb devices Sascha Hauer
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

So that we can iterate over the existing partitions from the master
mtd device.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c      | 8 ++++++++
 include/linux/mtd/mtd.h | 3 +++
 2 files changed, 11 insertions(+)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 21d04a1..f5c03db 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -400,6 +400,8 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 	else
 		mtd->cdev.name = asprintf("%s%d", devname, mtd->class_dev.id);
 
+	INIT_LIST_HEAD(&mtd->partitions);
+
 	mtd->cdev.priv = mtd;
 	mtd->cdev.dev = &mtd->class_dev;
 	mtd->cdev.mtd = mtd;
@@ -421,6 +423,9 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 	if (mtd->parent && !mtd->master)
 		of_parse_partitions(&mtd->cdev, mtd->parent->device_node);
 
+	if (mtd->master)
+		list_add_tail(&mtd->partitions_entry, &mtd->master->partitions);
+
 	list_for_each_entry(hook, &mtd_register_hooks, hook)
 		if (hook->add_mtd_device)
 			hook->add_mtd_device(mtd, devname, &hook->priv);
@@ -445,6 +450,9 @@ int del_mtd_device (struct mtd_info *mtd)
 	unregister_device(&mtd->class_dev);
 	free(mtd->param_size.value);
 	free(mtd->cdev.name);
+	if (mtd->master)
+		list_del(&mtd->partitions_entry);
+
 	return 0;
 }
 
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 1d33592..72bd66b 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -220,6 +220,9 @@ struct mtd_info {
 
 	struct mtd_info *master;
 	loff_t master_offset;
+
+	struct list_head partitions;
+	struct list_head partitions_entry;
 };
 
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 06/17] mtd: nand: remove automatically created bb devices
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (4 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 05/17] mtd: Add partitions to list Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 07/17] move cmdline partition parsing code to separate file Sascha Hauer
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

the bb devices which are created in add_mtd_device() must be removed
in del_mtd_device(). Also remove deletion of the bb devices in the
mtdparts-add environment file.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 defaultenv/defaultenv-2-base/bin/mtdparts-add |  3 ---
 drivers/mtd/core.c                            |  2 ++
 drivers/mtd/nand/nand-bb.c                    | 16 ++++++++++++----
 include/nand.h                                |  7 +++++--
 4 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/defaultenv/defaultenv-2-base/bin/mtdparts-add b/defaultenv/defaultenv-2-base/bin/mtdparts-add
index 05ab638..f49561c 100644
--- a/defaultenv/defaultenv-2-base/bin/mtdparts-add
+++ b/defaultenv/defaultenv-2-base/bin/mtdparts-add
@@ -30,9 +30,6 @@ if [ -z "${parts}" ]; then
 fi
 
 if [ -e /tmp/mtdparts/${device} ]; then
-	if [ -n "/dev/${device}.*.bb" ]; then
-		nand -d /dev/${device}.*.bb
-	fi
 	delpart /dev/${device}.*
 fi
 
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index f5c03db..813edc5 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -447,6 +447,8 @@ int del_mtd_device (struct mtd_info *mtd)
 			hook->del_mtd_device(mtd, &hook->priv);
 
 	devfs_remove(&mtd->cdev);
+	if (mtd->cdev_bb)
+		mtd_del_bb(mtd);
 	unregister_device(&mtd->class_dev);
 	free(mtd->param_size.value);
 	free(mtd->cdev.name);
diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c
index 23957c3..539c685 100644
--- a/drivers/mtd/nand/nand-bb.c
+++ b/drivers/mtd/nand/nand-bb.c
@@ -307,6 +307,17 @@ err:
 	return ERR_PTR(ret);
 }
 
+void mtd_del_bb(struct mtd_info *mtd)
+{
+	struct cdev *cdev = mtd->cdev_bb;
+	struct nand_bb *bb = container_of(cdev, struct nand_bb, cdev);
+
+	devfs_remove(&bb->cdev);
+	list_del_init(&bb->list);
+	free(bb->name);
+	free(bb);
+}
+
 /**
  * Add a bad block aware device ontop of another (NAND) device
  * @param[in] dev The device to add a partition on
@@ -335,10 +346,7 @@ int dev_remove_bb_dev(const char *name)
 
 	list_for_each_entry_safe(bb, tmp, &bb_list, list) {
 		if (!strcmp(bb->cdev.name, name)) {
-			devfs_remove(&bb->cdev);
-			list_del_init(&bb->list);
-			free(bb->name);
-			free(bb);
+			mtd_del_bb(bb->mtd);
 			return 0;
 		}
 	}
diff --git a/include/nand.h b/include/nand.h
index 1da35d0..fb3b5a1 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -1,4 +1,3 @@
-
 #ifndef __NAND_H__
 #define __NAND_H__
 
@@ -8,6 +7,7 @@ struct nand_bb;
 int dev_add_bb_dev(const char *filename, const char *name);
 int dev_remove_bb_dev(const char *name);
 struct cdev *mtd_add_bb(struct mtd_info *mtd, const char *name);
+void mtd_del_bb(struct mtd_info *mtd);
 #else
 static inline int dev_add_bb_dev(const char *filename, const char *name) {
 	return 0;
@@ -21,7 +21,10 @@ static inline struct cdev *mtd_add_bb(struct mtd_info *mtd, const char *name)
 {
 	return NULL;
 }
+
+static inline void mtd_del_bb(struct mtd_info *mtd)
+{
+}
 #endif
 
 #endif /* __NAND_H__ */
-
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 07/17] move cmdline partition parsing code to separate file
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (5 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 06/17] mtd: nand: remove automatically created bb devices Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 08/17] cmdlinepart: Change SIZE_REMAINING to loff_t Sascha Hauer
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

So it's no longer local to the addpart/delpart code and can be used
from other code.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/partition.c  | 81 +++----------------------------------------
 include/cmdlinepart.h | 11 ++++++
 lib/Makefile          |  1 +
 lib/cmdlinepart.c     | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 77 deletions(-)
 create mode 100644 include/cmdlinepart.h
 create mode 100644 lib/cmdlinepart.c

diff --git a/commands/partition.c b/commands/partition.c
index ef6d9c9..c95433f 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -35,82 +35,9 @@
 #include <linux/stat.h>
 #include <libgen.h>
 #include <getopt.h>
+#include <cmdlinepart.h>
 #include <linux/err.h>
 
-#define SIZE_REMAINING ((ulong)-1)
-
-#define PART_ADD_DEVNAME (1 << 0)
-
-static int mtd_part_do_parse_one(char *devname, const char *partstr,
-				 char **endp, loff_t *offset,
-				 loff_t devsize, size_t *retsize,
-				 unsigned int pflags)
-{
-	loff_t size;
-	char *end;
-	char buf[PATH_MAX] = {};
-	unsigned long flags = 0;
-	int ret = 0;
-	struct cdev *cdev;
-
-	memset(buf, 0, PATH_MAX);
-
-	if (*partstr == '-') {
-		size = SIZE_REMAINING;
-		end = (char *)partstr + 1;
-	} else {
-		size = strtoull_suffix(partstr, &end, 0);
-	}
-
-	if (*end == '@')
-		*offset = strtoull_suffix(end+1, &end, 0);
-
-	if (size == SIZE_REMAINING)
-		size = devsize - *offset;
-
-	partstr = end;
-
-	if (*partstr == '(') {
-		partstr++;
-		end = strchr((char *) partstr, ')');
-		if (!end) {
-			printf("could not find matching ')'\n");
-			return -EINVAL;
-		}
-
-		if (pflags & PART_ADD_DEVNAME)
-			sprintf(buf, "%s.", devname);
-		memcpy(buf + strlen(buf), partstr, end - partstr);
-
-		end++;
-	}
-
-	if (size + *offset > devsize) {
-		printf("%s: partition end is beyond device\n", buf);
-		return -EINVAL;
-	}
-
-	partstr = end;
-
-	if (*partstr == 'r' && *(partstr + 1) == 'o') {
-		flags |= DEVFS_PARTITION_READONLY;
-		end = (char *)(partstr + 2);
-	}
-
-	if (endp)
-		*endp = end;
-
-	*retsize = size;
-
-	cdev = devfs_add_partition(devname, *offset, size, flags, buf);
-	if (IS_ERR(cdev)) {
-		ret = PTR_ERR(cdev);
-		printf("cannot create %s: %s\n", buf, strerror(-ret));
-	}
-
-	return ret;
-}
-
 static int do_addpart(int argc, char *argv[])
 {
 	char *devname;
@@ -119,12 +46,12 @@ static int do_addpart(int argc, char *argv[])
 	loff_t devsize;
 	struct stat s;
 	int opt;
-	unsigned int flags = PART_ADD_DEVNAME;
+	unsigned int flags = CMDLINEPART_ADD_DEVNAME;
 
 	while ((opt = getopt(argc, argv, "n")) > 0) {
 		switch (opt) {
 		case 'n':
-			flags &= ~PART_ADD_DEVNAME;
+			flags &= ~CMDLINEPART_ADD_DEVNAME;
 			break;
 		}
 	}
@@ -145,7 +72,7 @@ static int do_addpart(int argc, char *argv[])
 	while (1) {
 		size_t size = 0;
 
-		if (mtd_part_do_parse_one(devname, endp, &endp, &offset,
+		if (cmdlinepart_do_parse_one(devname, endp, &endp, &offset,
 					devsize, &size, flags))
 			return 1;
 
diff --git a/include/cmdlinepart.h b/include/cmdlinepart.h
new file mode 100644
index 0000000..5ffa3c4
--- /dev/null
+++ b/include/cmdlinepart.h
@@ -0,0 +1,11 @@
+#ifndef __CMD_LINE_PART_H
+#define __CMD_LINE_PART_H
+
+#define CMDLINEPART_ADD_DEVNAME (1 << 0)
+
+int cmdlinepart_do_parse_one(char *devname, const char *partstr,
+				 char **endp, loff_t *offset,
+				 loff_t devsize, size_t *retsize,
+				 unsigned int partition_flags);
+
+#endif /* __CMD_LINE_PART_H */
diff --git a/lib/Makefile b/lib/Makefile
index 226570a..b97e52d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -18,6 +18,7 @@ obj-y			+= kfifo.o
 obj-y			+= libbb.o
 obj-y			+= libgen.o
 obj-y			+= stringlist.o
+obj-y			+= cmdlinepart.o
 obj-y			+= recursive_action.o
 obj-y			+= make_directory.o
 obj-y			+= math.o
diff --git a/lib/cmdlinepart.c b/lib/cmdlinepart.c
new file mode 100644
index 0000000..0474992
--- /dev/null
+++ b/lib/cmdlinepart.c
@@ -0,0 +1,95 @@
+/*
+ * command line partition parsing code
+ *
+ * Copyright (c) 2015 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <driver.h>
+#include <fs.h>
+#include <linux/err.h>
+#include <cmdlinepart.h>
+
+#define SIZE_REMAINING ((size_t)-1)
+
+int cmdlinepart_do_parse_one(char *devname, const char *partstr,
+				 char **endp, loff_t *offset,
+				 loff_t devsize, size_t *retsize,
+				 unsigned int partition_flags)
+{
+	loff_t size;
+	char *end;
+	char buf[PATH_MAX] = {};
+	unsigned long flags = 0;
+	int ret = 0;
+	struct cdev *cdev;
+
+	memset(buf, 0, PATH_MAX);
+
+	if (*partstr == '-') {
+		size = SIZE_REMAINING;
+		end = (char *)partstr + 1;
+	} else {
+		size = strtoull_suffix(partstr, &end, 0);
+	}
+
+	if (*end == '@')
+		*offset = strtoull_suffix(end+1, &end, 0);
+
+	if (size == SIZE_REMAINING)
+		size = devsize - *offset;
+
+	partstr = end;
+
+	if (*partstr == '(') {
+		partstr++;
+		end = strchr((char *) partstr, ')');
+		if (!end) {
+			printf("could not find matching ')'\n");
+			return -EINVAL;
+		}
+
+		if (partition_flags & CMDLINEPART_ADD_DEVNAME)
+			sprintf(buf, "%s.", devname);
+		memcpy(buf + strlen(buf), partstr, end - partstr);
+
+		end++;
+	}
+
+	if (size + *offset > devsize) {
+		printf("%s: partition end is beyond device\n", buf);
+		return -EINVAL;
+	}
+
+	partstr = end;
+
+	if (*partstr == 'r' && *(partstr + 1) == 'o') {
+		flags |= DEVFS_PARTITION_READONLY;
+		end = (char *)(partstr + 2);
+	}
+
+	if (endp)
+		*endp = end;
+
+	*retsize = size;
+
+	cdev = devfs_add_partition(devname, *offset, size, flags, buf);
+	if (IS_ERR(cdev)) {
+		ret = PTR_ERR(cdev);
+		printf("cannot create %s: %s\n", buf, strerror(-ret));
+	}
+
+	return ret;
+}
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 08/17] cmdlinepart: Change SIZE_REMAINING to loff_t
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (6 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 07/17] move cmdline partition parsing code to separate file Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 09/17] cmdlinepart: make argument types safer Sascha Hauer
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

For compatibility with devices > 4G.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 lib/cmdlinepart.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/cmdlinepart.c b/lib/cmdlinepart.c
index 0474992..4781d82 100644
--- a/lib/cmdlinepart.c
+++ b/lib/cmdlinepart.c
@@ -22,7 +22,7 @@
 #include <linux/err.h>
 #include <cmdlinepart.h>
 
-#define SIZE_REMAINING ((size_t)-1)
+#define SIZE_REMAINING ((loff_t)-1)
 
 int cmdlinepart_do_parse_one(char *devname, const char *partstr,
 				 char **endp, loff_t *offset,
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 09/17] cmdlinepart: make argument types safer
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (7 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 08/17] cmdlinepart: Change SIZE_REMAINING to loff_t Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 10/17] cmdlinepart: add function to parse a cmdline partition string Sascha Hauer
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

The return size should be loff_t to support partitions bigger
than 4G. Also use const for the devname and endp.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/partition.c  | 4 ++--
 include/cmdlinepart.h | 6 +++---
 lib/cmdlinepart.c     | 6 +++---
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/commands/partition.c b/commands/partition.c
index c95433f..17ca136 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -41,7 +41,7 @@
 static int do_addpart(int argc, char *argv[])
 {
 	char *devname;
-	char *endp;
+	const char *endp;
 	loff_t offset = 0;
 	loff_t devsize;
 	struct stat s;
@@ -70,7 +70,7 @@ static int do_addpart(int argc, char *argv[])
 	endp = argv[optind + 1];
 
 	while (1) {
-		size_t size = 0;
+		loff_t size = 0;
 
 		if (cmdlinepart_do_parse_one(devname, endp, &endp, &offset,
 					devsize, &size, flags))
diff --git a/include/cmdlinepart.h b/include/cmdlinepart.h
index 5ffa3c4..3f8e136 100644
--- a/include/cmdlinepart.h
+++ b/include/cmdlinepart.h
@@ -3,9 +3,9 @@
 
 #define CMDLINEPART_ADD_DEVNAME (1 << 0)
 
-int cmdlinepart_do_parse_one(char *devname, const char *partstr,
-				 char **endp, loff_t *offset,
-				 loff_t devsize, size_t *retsize,
+int cmdlinepart_do_parse_one(const char *devname, const char *partstr,
+				 const char **endp, loff_t *offset,
+				 loff_t devsize, loff_t *retsize,
 				 unsigned int partition_flags);
 
 #endif /* __CMD_LINE_PART_H */
diff --git a/lib/cmdlinepart.c b/lib/cmdlinepart.c
index 4781d82..9351587 100644
--- a/lib/cmdlinepart.c
+++ b/lib/cmdlinepart.c
@@ -24,9 +24,9 @@
 
 #define SIZE_REMAINING ((loff_t)-1)
 
-int cmdlinepart_do_parse_one(char *devname, const char *partstr,
-				 char **endp, loff_t *offset,
-				 loff_t devsize, size_t *retsize,
+int cmdlinepart_do_parse_one(const char *devname, const char *partstr,
+				 const char **endp, loff_t *offset,
+				 loff_t devsize, loff_t *retsize,
 				 unsigned int partition_flags)
 {
 	loff_t size;
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 10/17] cmdlinepart: add function to parse a cmdline partition string
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (8 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 09/17] cmdlinepart: make argument types safer Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 11/17] cmndlinepart: skip devname if partstr already contains it Sascha Hauer
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

This adds a function to parse a full cmdline partition string. The
addpart command is switched to use this function.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/partition.c  | 25 +------------------------
 include/cmdlinepart.h |  3 +++
 lib/cmdlinepart.c     | 28 ++++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/commands/partition.c b/commands/partition.c
index 17ca136..64ccaf0 100644
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -41,8 +41,6 @@
 static int do_addpart(int argc, char *argv[])
 {
 	char *devname;
-	const char *endp;
-	loff_t offset = 0;
 	loff_t devsize;
 	struct stat s;
 	int opt;
@@ -67,28 +65,7 @@ static int do_addpart(int argc, char *argv[])
 
 	devname = basename(argv[optind]);
 
-	endp = argv[optind + 1];
-
-	while (1) {
-		loff_t size = 0;
-
-		if (cmdlinepart_do_parse_one(devname, endp, &endp, &offset,
-					devsize, &size, flags))
-			return 1;
-
-		offset += size;
-
-		if (!*endp)
-			break;
-
-		if (*endp != ',') {
-			printf("parse error\n");
-			return 1;
-		}
-		endp++;
-	}
-
-	return 0;
+	return cmdlinepart_do_parse(devname, argv[optind + 1], devsize, flags);
 }
 
 BAREBOX_CMD_HELP_START(addpart)
diff --git a/include/cmdlinepart.h b/include/cmdlinepart.h
index 3f8e136..bf8cdfa 100644
--- a/include/cmdlinepart.h
+++ b/include/cmdlinepart.h
@@ -8,4 +8,7 @@ int cmdlinepart_do_parse_one(const char *devname, const char *partstr,
 				 loff_t devsize, loff_t *retsize,
 				 unsigned int partition_flags);
 
+int cmdlinepart_do_parse(const char *devname, const char *parts, loff_t devsize,
+		unsigned partition_flags);
+
 #endif /* __CMD_LINE_PART_H */
diff --git a/lib/cmdlinepart.c b/lib/cmdlinepart.c
index 9351587..df6f17a 100644
--- a/lib/cmdlinepart.c
+++ b/lib/cmdlinepart.c
@@ -93,3 +93,31 @@ int cmdlinepart_do_parse_one(const char *devname, const char *partstr,
 
 	return ret;
 }
+
+int cmdlinepart_do_parse(const char *devname, const char *parts, loff_t devsize,
+		unsigned partition_flags)
+{
+	loff_t offset = 0;
+	int ret;
+
+	while (1) {
+		loff_t size = 0;
+
+		ret = cmdlinepart_do_parse_one(devname, parts, &parts, &offset,
+				devsize, &size, partition_flags);
+		if (ret)
+			return ret;
+
+		offset += size;
+		if (!*parts)
+			break;
+
+		if (*parts != ',') {
+			printf("parse error\n");
+			return -EINVAL;
+		}
+		parts++;
+	}
+
+	return 0;
+}
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 11/17] cmndlinepart: skip devname if partstr already contains it
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (9 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 10/17] cmdlinepart: add function to parse a cmdline partition string Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 12/17] mtd: forbid conflicting mtd partitions Sascha Hauer
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

When the partition name already starts with "devname." skip this
when adding the partition.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 lib/cmdlinepart.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/cmdlinepart.c b/lib/cmdlinepart.c
index df6f17a..d7d4441 100644
--- a/lib/cmdlinepart.c
+++ b/lib/cmdlinepart.c
@@ -61,7 +61,8 @@ int cmdlinepart_do_parse_one(const char *devname, const char *partstr,
 			return -EINVAL;
 		}
 
-		if (partition_flags & CMDLINEPART_ADD_DEVNAME)
+		if ((partition_flags & CMDLINEPART_ADD_DEVNAME) &&
+				strncmp(devname, partstr, strlen(devname)))
 			sprintf(buf, "%s.", devname);
 		memcpy(buf + strlen(buf), partstr, end - partstr);
 
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 12/17] mtd: forbid conflicting mtd partitions
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (10 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 11/17] cmndlinepart: skip devname if partstr already contains it Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 13/17] mtd: Use flags parameter in mtd_add_partition Sascha Hauer
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

mtd partitions should not conflict with each other, so forbid this.
Also add the partitions to the partitions list sorted, so that they
can be easier translated into a cmdline partition string.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 813edc5..99d50f1 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -377,6 +377,18 @@ static struct file_operations mtd_ops = {
 	.lseek  = dev_lseek_default,
 };
 
+static int mtd_part_compare(struct list_head *a, struct list_head *b)
+{
+	struct mtd_info *mtda = container_of(a, struct mtd_info, partitions_entry);
+	struct mtd_info *mtdb = container_of(b, struct mtd_info, partitions_entry);
+
+	if (mtda->master_offset > mtdb->master_offset)
+		return 1;
+	if (mtda->master_offset < mtdb->master_offset)
+		return -1;
+	return 0;
+}
+
 int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 {
 	struct mtddev_hook *hook;
@@ -417,20 +429,35 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 	if (ret)
 		goto err;
 
+	if (mtd->master && !(mtd->cdev.flags & DEVFS_PARTITION_FIXED)) {
+		struct mtd_info *mtdpart;
+
+		list_for_each_entry(mtdpart, &mtd->master->partitions, partitions_entry) {
+			if (mtdpart->master_offset + mtdpart->size <= mtd->master_offset)
+				continue;
+			if (mtd->master_offset + mtd->size <= mtdpart->master_offset)
+				continue;
+			dev_err(&mtd->class_dev, "New partition %s conflicts with %s\n",
+					mtd->name, mtdpart->name);
+			goto err1;
+		}
+
+		list_add_sort(&mtd->partitions_entry, &mtd->master->partitions, mtd_part_compare);
+	}
+
 	if (mtd_can_have_bb(mtd))
 		mtd->cdev_bb = mtd_add_bb(mtd, NULL);
 
 	if (mtd->parent && !mtd->master)
 		of_parse_partitions(&mtd->cdev, mtd->parent->device_node);
 
-	if (mtd->master)
-		list_add_tail(&mtd->partitions_entry, &mtd->master->partitions);
-
 	list_for_each_entry(hook, &mtd_register_hooks, hook)
 		if (hook->add_mtd_device)
 			hook->add_mtd_device(mtd, devname, &hook->priv);
 
 	return 0;
+err1:
+	devfs_remove(&mtd->cdev);
 err:
 	free(mtd->cdev.name);
 	unregister_device(&mtd->class_dev);
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 13/17] mtd: Use flags parameter in mtd_add_partition
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (11 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 12/17] mtd: forbid conflicting mtd partitions Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 14/17] mtd: Add a partitions parameter to mtd devices Sascha Hauer
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

mtd_add_partition is passed a flag parameter. This has been unused
so the DEVFS_PARTITION_FIXED and DEVFS_PARTITION_READONLY were ignored.
Fix this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/partition.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
index c514d4b..98b9081 100644
--- a/drivers/mtd/partition.c
+++ b/drivers/mtd/partition.c
@@ -123,6 +123,7 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 	part->ecclayout = mtd->ecclayout;
 	part->ecc_strength = mtd->ecc_strength;
 	part->subpage_sft = mtd->subpage_sft;
+	part->cdev.flags = flags;
 
 	if (mtd->numeraseregions > 1) {
 		/* Deal with variable erase size stuff */
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 14/17] mtd: Add a partitions parameter to mtd devices
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (12 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 13/17] mtd: Use flags parameter in mtd_add_partition Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 15/17] mtd: fixup device tree partitions Sascha Hauer
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

The partitions parameter allows to partition a mtd device
using a standard cmdline partition description string. This
way the partitions of a mtd device can be changed at once.
The output of the string can be used to be passed to the kernel
as cmdline partition string. The partitions can also still be
changed with addpart/delpart, the partitions parameter will
be updated accordingly.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 99d50f1..ac1001e 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -18,6 +18,7 @@
 #include <common.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/mtd.h>
+#include <cmdlinepart.h>
 #include <init.h>
 #include <xfuncs.h>
 #include <driver.h>
@@ -377,6 +378,98 @@ static struct file_operations mtd_ops = {
 	.lseek  = dev_lseek_default,
 };
 
+static int mtd_partition_set(struct device_d *dev, struct param_d *p, const char *val)
+{
+	struct mtd_info *mtd = container_of(dev, struct mtd_info, class_dev);
+	struct mtd_info *mtdpart, *tmp;
+	int ret;
+
+	list_for_each_entry_safe(mtdpart, tmp, &mtd->partitions, partitions_entry) {
+		ret = mtd_del_partition(mtdpart);
+		if (ret)
+			return ret;
+	}
+
+	return cmdlinepart_do_parse(mtd->cdev.name, val, mtd->size, CMDLINEPART_ADD_DEVNAME);
+}
+
+static char *print_size(uint64_t s)
+{
+	if (!(s & ((1 << 20) - 1)))
+		return asprintf("%lldM", s >> 20);
+	if (!(s & ((1 << 10) - 1)))
+		return asprintf("%lldk", s >> 10);
+	return asprintf("0x%lld", s);
+}
+
+static int print_part(char *buf, int bufsize, struct mtd_info *mtd, uint64_t last_ofs,
+		int is_last)
+{
+	char *size = print_size(mtd->size);
+	char *ofs = print_size(mtd->master_offset);
+	int ret;
+
+	if (!size || !ofs) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (mtd->master_offset == last_ofs)
+		ret = snprintf(buf, bufsize, "%s(%s)%s", size,
+				mtd->cdev.partname,
+				is_last ? "" : ",");
+	else
+		ret = snprintf(buf, bufsize, "%s@%s(%s)%s", size,
+				ofs,
+				mtd->cdev.partname,
+				is_last ? "" : ",");
+out:
+	free(size);
+	free(ofs);
+
+	return ret;
+}
+
+static int print_parts(char *buf, int bufsize, struct mtd_info *mtd)
+{
+	struct mtd_info *mtdpart;
+	uint64_t last_ofs = 0;
+	int ret = 0;
+
+	list_for_each_entry(mtdpart, &mtd->partitions, partitions_entry) {
+		int now;
+		int is_last = list_is_last(&mtdpart->partitions_entry,
+					&mtd->partitions);
+
+		now = print_part(buf, bufsize, mtdpart, last_ofs, is_last);
+		if (now < 0)
+			return now;
+
+		if (buf && bufsize) {
+			buf += now;
+			bufsize -= now;
+		}
+		ret += now;
+		last_ofs = mtdpart->master_offset + mtdpart->size;
+	}
+
+	return ret;
+}
+
+static const char *mtd_partition_get(struct device_d *dev, struct param_d *p)
+{
+	struct mtd_info *mtd = container_of(dev, struct mtd_info, class_dev);
+	int len = 0;
+
+	free(p->value);
+
+	len = print_parts(NULL, 0, mtd);
+	p->value = xzalloc(len + 1);
+	print_parts(p->value, len + 1, mtd);
+
+	return p->value;
+}
+
 static int mtd_part_compare(struct list_head *a, struct list_head *b)
 {
 	struct mtd_info *mtda = container_of(a, struct mtd_info, partitions_entry);
@@ -448,8 +541,10 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 	if (mtd_can_have_bb(mtd))
 		mtd->cdev_bb = mtd_add_bb(mtd, NULL);
 
-	if (mtd->parent && !mtd->master)
+	if (mtd->parent && !mtd->master) {
+		dev_add_param(&mtd->class_dev, "partitions", mtd_partition_set, mtd_partition_get, 0);
 		of_parse_partitions(&mtd->cdev, mtd->parent->device_node);
+	}
 
 	list_for_each_entry(hook, &mtd_register_hooks, hook)
 		if (hook->add_mtd_device)
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 15/17] mtd: fixup device tree partitions
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (13 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 14/17] mtd: Add a partitions parameter to mtd devices Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 16/17] defaultenv-2: mtdparts-add: remove unused variable Sascha Hauer
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c      | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/mtd.h |  2 ++
 2 files changed, 66 insertions(+)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index ac1001e..63b1e4a 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -482,6 +482,66 @@ static int mtd_part_compare(struct list_head *a, struct list_head *b)
 	return 0;
 }
 
+static int of_mtd_fixup(struct device_node *root, void *ctx)
+{
+	struct mtd_info *mtd = ctx, *partmtd;
+	struct device_node *np, *part, *tmp;
+	int ret, i = 0;
+
+	np = of_find_node_by_path(mtd->of_path);
+	if (!np) {
+		dev_err(&mtd->class_dev, "Cannot find nodepath %s, cannot fixup\n",
+				mtd->of_path);
+		return -EINVAL;
+	}
+
+	for_each_child_of_node_safe(np, tmp, part) {
+		if (of_get_property(part, "compatible", NULL))
+			continue;
+		of_delete_node(part);
+	}
+
+	list_for_each_entry(partmtd, &mtd->partitions, partitions_entry) {
+		int na, ns, len = 0;
+		char *name = asprintf("partition@%d", i++);
+		void *p;
+		u8 tmp[16 * 16]; /* Up to 64-bit address + 64-bit size */
+
+		if (!name)
+			return -ENOMEM;
+
+		part = of_new_node(np, name);
+		free(name);
+		if (!part)
+			return -ENOMEM;
+
+		p = of_new_property(part, "label", partmtd->cdev.partname,
+                                strlen(partmtd->cdev.partname) + 1);
+		if (!p)
+			return -ENOMEM;
+
+		na = of_n_addr_cells(np);
+		ns = of_n_size_cells(np);
+
+		of_write_number(tmp + len, partmtd->master_offset, na);
+		len += na * 4;
+		of_write_number(tmp + len, partmtd->size, ns);
+		len += ns * 4;
+
+		ret = of_set_property(part, "reg", tmp, len, 1);
+		if (ret)
+			return ret;
+
+		if (partmtd->cdev.flags & DEVFS_PARTITION_READONLY) {
+			ret = of_set_property(part, "read-only", NULL, 0, 1);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
 int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 {
 	struct mtddev_hook *hook;
@@ -544,6 +604,10 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 	if (mtd->parent && !mtd->master) {
 		dev_add_param(&mtd->class_dev, "partitions", mtd_partition_set, mtd_partition_get, 0);
 		of_parse_partitions(&mtd->cdev, mtd->parent->device_node);
+		if (IS_ENABLED(CONFIG_OFDEVICE) && mtd->parent->device_node) {
+			mtd->of_path = xstrdup(mtd->parent->device_node->full_name);
+			of_register_fixup(of_mtd_fixup, mtd);
+		}
 	}
 
 	list_for_each_entry(hook, &mtd_register_hooks, hook)
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 72bd66b..33f1fd5 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -223,6 +223,8 @@ struct mtd_info {
 
 	struct list_head partitions;
 	struct list_head partitions_entry;
+
+	char *of_path;
 };
 
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 16/17] defaultenv-2: mtdparts-add: remove unused variable
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (14 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 15/17] mtd: fixup device tree partitions Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-12  8:54 ` [PATCH 17/17] defaultenv-2: mtdparts-add: Use new partition parameter Sascha Hauer
  2015-02-13  5:54 ` mtd partition handling updates Bo Shen
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 defaultenv/defaultenv-2-base/bin/mtdparts-add | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/defaultenv/defaultenv-2-base/bin/mtdparts-add b/defaultenv/defaultenv-2-base/bin/mtdparts-add
index f49561c..a0e419e 100644
--- a/defaultenv/defaultenv-2-base/bin/mtdparts-add
+++ b/defaultenv/defaultenv-2-base/bin/mtdparts-add
@@ -5,7 +5,6 @@ mkdir -p /tmp/mtdparts
 parts=
 device=
 kernelname=
-bbdev=
 
 while getopt "p:d:k:b" opt; do
         if [ ${opt} = p ]; then
@@ -14,8 +13,6 @@ while getopt "p:d:k:b" opt; do
                 device=${OPTARG}
         elif [ ${opt} = k ]; then
                 kernelname=${OPTARG}
-	elif [ ${opt} = b ]; then
-		bbdev=true
         fi
 done
 
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 17/17] defaultenv-2: mtdparts-add: Use new partition parameter
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (15 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 16/17] defaultenv-2: mtdparts-add: remove unused variable Sascha Hauer
@ 2015-02-12  8:54 ` Sascha Hauer
  2015-02-13  5:54 ` mtd partition handling updates Bo Shen
  17 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2015-02-12  8:54 UTC (permalink / raw)
  To: Barebox List

mtd devices now have a partition parameter to create mtd partitions.
Use it to simplify the mtdparts-add script.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 defaultenv/defaultenv-2-base/bin/mtdparts-add | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/defaultenv/defaultenv-2-base/bin/mtdparts-add b/defaultenv/defaultenv-2-base/bin/mtdparts-add
index a0e419e..805e3e2 100644
--- a/defaultenv/defaultenv-2-base/bin/mtdparts-add
+++ b/defaultenv/defaultenv-2-base/bin/mtdparts-add
@@ -26,13 +26,12 @@ if [ -z "${parts}" ]; then
 	exit
 fi
 
-if [ -e /tmp/mtdparts/${device} ]; then
-	delpart /dev/${device}.*
+${device}.partitions="$parts"
+if [ $? != 0 ]; then
+	echo "Failed to add partitions $parts to $device"
+	exit 1
 fi
 
-addpart -n /dev/${device} "$parts" || exit
-mkdir -p /tmp/mtdparts/${device}
-
 if [ -n ${kernelname} ]; then
 	global linux.mtdparts.${device}
 	global.linux.mtdparts.${device}="${kernelname}:${parts}"
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: mtd partition handling updates
  2015-02-12  8:54 mtd partition handling updates Sascha Hauer
                   ` (16 preceding siblings ...)
  2015-02-12  8:54 ` [PATCH 17/17] defaultenv-2: mtdparts-add: Use new partition parameter Sascha Hauer
@ 2015-02-13  5:54 ` Bo Shen
  17 siblings, 0 replies; 19+ messages in thread
From: Bo Shen @ 2015-02-13  5:54 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List

Hi Sascha,

On 02/12/2015 04:54 PM, Sascha Hauer wrote:
> This series updates the mtd partition handling in barebox. It used
> to be too simple to create conflicting or inconsistent partitions on
> mtd devices. mtd partitions can be changed from board code, from the
> device tree, using addpart/delpart and with this series also with
> the newly created 'partitions' parameter for mtd devices. The
> informations are now kept in a consistent state, with each changed
> partition the partitions parameter is updated and when starting
> the kernel partitions in the device tree are also updated to the
> current partitioning.
> What's still missing is a way to store the partitioning somewhere
> in the environment, perhaps in a nonvolatile variable.
>
> Sascha
>
>
> The following changes since commit d7dc46d5d6f2c80d1719ef877df728457790ac45:
>
>    defaultenv: ignore barebox_zero_env (2015-02-11 08:34:29 +0100)
>
> are available in the git repository at:
>
>    git://git.pengutronix.de/git/barebox.git
>
> for you to fetch changes up to cd7feae00b43eeddcaeb229f861d0ddac93f91e2:
>
>    defaultenv-2: mtdparts-add: Use new partition parameter (2015-02-12 09:33:44 +0100)
>
> ----------------------------------------------------------------
> Sascha Hauer (17):
>        of: Add for_each_child_of_node_safe
>        mtd: core: add error checks
>        mtd: partitions: Use xstrdup
>        mtd: partitions: Add error check
>        mtd: Add partitions to list
>        mtd: nand: remove automatically created bb devices
>        move cmdline partition parsing code to separate file
>        cmdlinepart: Change SIZE_REMAINING to loff_t
>        cmdlinepart: make argument types safer
>        cmdlinepart: add function to parse a cmdline partition string
>        cmndlinepart: skip devname if partstr already contains it
>        mtd: forbid conflicting mtd partitions
>        mtd: Use flags parameter in mtd_add_partition
>        mtd: Add a partitions parameter to mtd devices
>        mtd: fixup device tree partitions
>        defaultenv-2: mtdparts-add: remove unused variable
>        defaultenv-2: mtdparts-add: Use new partition parameter

For the whole series, test OK with Doug's patch on sama5d4ek board.

Tested-by: Bo Shen <voice.shen@atmel.com>

>   commands/partition.c                          | 104 +------------
>   defaultenv/defaultenv-2-base/bin/mtdparts-add |  15 +-
>   drivers/mtd/core.c                            | 213 +++++++++++++++++++++++++-
>   drivers/mtd/nand/nand-bb.c                    |  16 +-
>   drivers/mtd/partition.c                       |  14 +-
>   include/cmdlinepart.h                         |  14 ++
>   include/linux/mtd/mtd.h                       |   5 +
>   include/nand.h                                |   7 +-
>   include/of.h                                  |   2 +
>   lib/Makefile                                  |   1 +
>   lib/cmdlinepart.c                             | 124 +++++++++++++++
>   11 files changed, 393 insertions(+), 122 deletions(-)
>   create mode 100644 include/cmdlinepart.h
>   create mode 100644 lib/cmdlinepart.c

Best Regards,
Bo Shen


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-02-13  6:01 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-12  8:54 mtd partition handling updates Sascha Hauer
2015-02-12  8:54 ` [PATCH 01/17] of: Add for_each_child_of_node_safe Sascha Hauer
2015-02-12  8:54 ` [PATCH 02/17] mtd: core: add error checks Sascha Hauer
2015-02-12  8:54 ` [PATCH 03/17] mtd: partitions: Use xstrdup Sascha Hauer
2015-02-12  8:54 ` [PATCH 04/17] mtd: partitions: Add error check Sascha Hauer
2015-02-12  8:54 ` [PATCH 05/17] mtd: Add partitions to list Sascha Hauer
2015-02-12  8:54 ` [PATCH 06/17] mtd: nand: remove automatically created bb devices Sascha Hauer
2015-02-12  8:54 ` [PATCH 07/17] move cmdline partition parsing code to separate file Sascha Hauer
2015-02-12  8:54 ` [PATCH 08/17] cmdlinepart: Change SIZE_REMAINING to loff_t Sascha Hauer
2015-02-12  8:54 ` [PATCH 09/17] cmdlinepart: make argument types safer Sascha Hauer
2015-02-12  8:54 ` [PATCH 10/17] cmdlinepart: add function to parse a cmdline partition string Sascha Hauer
2015-02-12  8:54 ` [PATCH 11/17] cmndlinepart: skip devname if partstr already contains it Sascha Hauer
2015-02-12  8:54 ` [PATCH 12/17] mtd: forbid conflicting mtd partitions Sascha Hauer
2015-02-12  8:54 ` [PATCH 13/17] mtd: Use flags parameter in mtd_add_partition Sascha Hauer
2015-02-12  8:54 ` [PATCH 14/17] mtd: Add a partitions parameter to mtd devices Sascha Hauer
2015-02-12  8:54 ` [PATCH 15/17] mtd: fixup device tree partitions Sascha Hauer
2015-02-12  8:54 ` [PATCH 16/17] defaultenv-2: mtdparts-add: remove unused variable Sascha Hauer
2015-02-12  8:54 ` [PATCH 17/17] defaultenv-2: mtdparts-add: Use new partition parameter Sascha Hauer
2015-02-13  5:54 ` mtd partition handling updates Bo Shen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox