mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 05/10] devfs: partitioning: add new helper devfs_create_partitions
Date: Tue, 25 Feb 2014 23:51:16 +0100	[thread overview]
Message-ID: <1393368681-1190-6-git-send-email-u.kleine-koenig@pengutronix.de> (raw)
In-Reply-To: <1393368681-1190-1-git-send-email-u.kleine-koenig@pengutronix.de>

Compared to devfs_add_partition which adds a single partition
devfs_create_partitions creates several partitions at once. One nice
benefit is that this simplifies appending partitions because the start
of the latter partition doesn't need to be specified explicitly.
Also dev_add_bb_dev() is called by the new helper if the bbname is
specified for a partition.

Note that adding partitions is also more flexible now (also via
devfs_add_partition) because negative values for offset and size now
have a proper meaning instead of creating broken partitions.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 fs/devfs-core.c  | 96 ++++++++++++++++++++++++++++++++++++++++++++++----------
 include/driver.h | 33 +++++++++++++++++++
 2 files changed, 113 insertions(+), 16 deletions(-)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index f92a07c43d3e..237e13a93172 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <malloc.h>
 #include <ioctl.h>
+#include <nand.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
 
@@ -260,32 +261,52 @@ int devfs_remove(struct cdev *cdev)
 	return 0;
 }
 
-struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size,
-		unsigned int flags, const char *name)
+static struct cdev *__devfs_add_partition(struct cdev *cdev,
+		const struct devfs_partition *partinfo, loff_t *end)
 {
-	struct cdev *cdev, *new;
+	loff_t offset, size;
+	static struct cdev *new;
 
-	cdev = cdev_by_name(name);
-	if (cdev)
+	if (cdev_by_name(partinfo->name))
 		return ERR_PTR(-EEXIST);
 
-	cdev = cdev_by_name(devname);
-	if (!cdev)
-		return ERR_PTR(-ENOENT);
-
-	if (offset + size > cdev->size)
+	if (partinfo->offset > 0)
+		offset = partinfo->offset;
+	else if (partinfo->offset == 0)
+		/* append to previous partition */
+		offset = *end;
+	else
+		/* relative to end of cdev */
+		offset = cdev->size + partinfo->offset;
+
+	if (partinfo->size > 0)
+		size = partinfo->size;
+	else
+		size = cdev->size + partinfo->size - offset;
+
+	if (offset >= 0 && offset < *end)
+		pr_debug("partition %s not after previous partition\n",
+				partinfo->name);
+
+	*end = offset + size;
+
+	if (offset < 0 || *end > cdev->size) {
+		pr_warn("partition %s not completely inside device %s\n",
+				partinfo->name, cdev->name);
 		return ERR_PTR(-EINVAL);
+	}
 
-	new = xzalloc(sizeof (*new));
-	new->name = strdup(name);
-	if (!strncmp(devname, name, strlen(devname)))
-		new->partname = xstrdup(name + strlen(devname) + 1);
+	new = xzalloc(sizeof(*new));
+	new->name = strdup(partinfo->name);
+	if (!strncmp(cdev->name, partinfo->name, strlen(cdev->name)))
+		new->partname = xstrdup(partinfo->name + strlen(cdev->name) + 1);
 	new->ops = cdev->ops;
 	new->priv = cdev->priv;
 	new->size = size;
-	new->offset = offset + cdev->offset;
+	new->offset = cdev->offset + offset;
+
 	new->dev = cdev->dev;
-	new->flags = flags | DEVFS_IS_PARTITION;
+	new->flags = partinfo->flags | DEVFS_IS_PARTITION;
 
 #ifdef CONFIG_PARTITION_NEED_MTD
 	if (cdev->mtd) {
@@ -304,6 +325,25 @@ struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size
 	return new;
 }
 
+struct cdev *devfs_add_partition(const char *devname, loff_t offset,
+		loff_t size, unsigned int flags, const char *name)
+{
+	struct cdev *cdev;
+	loff_t end = 0;
+	const struct devfs_partition partinfo = {
+		.offset = offset,
+		.size = size,
+		.flags = flags,
+		.name = name,
+	};
+
+	cdev = cdev_by_name(devname);
+	if (!cdev)
+		return ERR_PTR(-ENOENT);
+
+	return __devfs_add_partition(cdev, &partinfo, &end);
+}
+
 int devfs_del_partition(const char *name)
 {
 	struct cdev *cdev;
@@ -333,3 +373,27 @@ int devfs_del_partition(const char *name)
 
 	return 0;
 }
+
+int devfs_create_partitions(const char *devname,
+		const struct devfs_partition partinfo[])
+{
+	loff_t offset = 0;
+	struct cdev *cdev;
+
+	cdev = cdev_by_name(devname);
+	if (!cdev)
+		return -ENOENT;
+
+	for (; partinfo->name; ++partinfo) {
+		struct cdev *new;
+
+		new = __devfs_add_partition(cdev, partinfo, &offset);
+		if (IS_ERR(new))
+			return PTR_ERR(new);
+
+		if (partinfo->bbname)
+			dev_add_bb_dev(partinfo->name, partinfo->bbname);
+	}
+
+	return 0;
+}
diff --git a/include/driver.h b/include/driver.h
index 33b82c3e969b..31bdecf6d82e 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -491,6 +491,39 @@ struct cdev *devfs_add_partition(const char *devname, loff_t offset,
 		loff_t size, unsigned int flags, const char *name);
 int devfs_del_partition(const char *name);
 
+#define DEVFS_PARTITION_APPEND		0
+
+/**
+ * struct devfs_partition - defines parameters for a single partition
+ * @offset: start of partition
+ * 	a negative offset requests to start the partition relative to the
+ * 	device's end. DEVFS_PARTITION_APPEND (i.e. 0) means start directly at
+ * 	the end of the previous partition.
+ * @size: size of partition
+ * 	a non-positive value requests to use a size that keeps -size free space
+ * 	after the current partition. A special case of this is passing 0, which
+ * 	means "until end of device".
+ * @flags: flags passed to devfs_add_partition
+ * @name: name passed to devfs_add_partition
+ * @bbname: if non-NULL also dev_add_bb_dev() is called for the partition during
+ * 	devfs_create_partitions().
+ */
+struct devfs_partition {
+	loff_t offset;
+	loff_t size;
+	unsigned int flags;
+	const char *name;
+	const char *bbname;
+};
+/**
+ * devfs_create_partitions - create a set of partitions for a device
+ * @devname: name of the device to partition
+ * @partinfo: array of partition parameters
+ * 	The array is processed until an entry with .name = NULL is found.
+ */
+int devfs_create_partitions(const char *devname,
+		const struct devfs_partition partinfo[]);
+
 #define DRV_OF_COMPAT(compat) \
 	IS_ENABLED(CONFIG_OFDEVICE) ? (compat) : NULL
 
-- 
1.8.5.3


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

  parent reply	other threads:[~2014-02-25 22:51 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-25 22:51 [PATCH 00/10] new partitioning helper Uwe Kleine-König
2014-02-25 22:51 ` [PATCH 01/10] devfs: partitioning: add missing free in error path Uwe Kleine-König
2014-02-25 22:51 ` [PATCH 02/10] devfs_add_partition: make flags parameter unsigned Uwe Kleine-König
2014-02-25 22:51 ` [PATCH 03/10] Documentation: fix example call to devfs_add_partition Uwe Kleine-König
2014-02-25 22:51 ` [PATCH 04/10] mtd/nand: constify filename parameter Uwe Kleine-König
2014-02-25 22:51 ` Uwe Kleine-König [this message]
2014-02-25 22:51 ` [PATCH 06/10] ARM: a9m2410: convert to devfs_create_partitions Uwe Kleine-König
2014-02-25 23:25   ` Sebastian Hesselbarth
2014-02-26 15:55     ` Uwe Kleine-König
2014-02-26 16:30       ` Sebastian Hesselbarth
2014-02-27 13:17     ` Sascha Hauer
2014-02-25 22:51 ` [PATCH 07/10] ARM: freescale-mx35-3-stack: " Uwe Kleine-König
2014-02-25 22:51 ` [PATCH 08/10] ARM: pca100: " Uwe Kleine-König
2014-02-25 22:51 ` [PATCH 09/10] ARM: pcm038: " Uwe Kleine-König
2014-02-25 22:51 ` [PATCH 10/10] ARM: sama5d3xek: " Uwe Kleine-König

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1393368681-1190-6-git-send-email-u.kleine-koenig@pengutronix.de \
    --to=u.kleine-koenig@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox