From a7f78e72732806cd777a1f5aaa2e3832e92de303 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 27 Feb 2014 21:39:02 +0100 Subject: devfs_add_partition: make flags parameter unsigned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The value is only used to assign to a (*struct cdev)->flags which is an unsigned int and it is passed as fourth parameter of mtd_add_partition which is an unsigned long. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- include/driver.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/driver.h b/include/driver.h index bbe789b51e..33b82c3e96 100644 --- a/include/driver.h +++ b/include/driver.h @@ -482,13 +482,13 @@ ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offs int cdev_ioctl(struct cdev *cdev, int cmd, void *buf); int cdev_erase(struct cdev *cdev, size_t count, loff_t offset); -#define DEVFS_PARTITION_FIXED (1 << 0) -#define DEVFS_PARTITION_READONLY (1 << 1) +#define DEVFS_PARTITION_FIXED (1U << 0) +#define DEVFS_PARTITION_READONLY (1U << 1) #define DEVFS_IS_PARTITION (1 << 2) #define DEVFS_IS_CHARACTER_DEV (1 << 3) -struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size, - int flags, const char *name); +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 DRV_OF_COMPAT(compat) \ -- cgit v1.2.3 From 14d0355d7c1b55bc4713b8c7768ae012840bbc85 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 27 Feb 2014 21:39:04 +0100 Subject: mtd/nand: constify filename parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The string pointed to isn't modified, so declare it as const. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/mtd/nand/nand-bb.c | 2 +- include/nand.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c index 0292f2f426..f387ef687a 100644 --- a/drivers/mtd/nand/nand-bb.c +++ b/drivers/mtd/nand/nand-bb.c @@ -261,7 +261,7 @@ static LIST_HEAD(bb_list); * @param[in] name Partition name (can be obtained with devinfo command) * @return The device representing the new partition. */ -int dev_add_bb_dev(char *path, const char *name) +int dev_add_bb_dev(const char *path, const char *name) { struct nand_bb *bb; int ret = -ENOMEM; diff --git a/include/nand.h b/include/nand.h index b1762dfa45..a0e77cc8cd 100644 --- a/include/nand.h +++ b/include/nand.h @@ -5,10 +5,10 @@ struct nand_bb; #ifdef CONFIG_NAND -int dev_add_bb_dev(char *filename, const char *name); +int dev_add_bb_dev(const char *filename, const char *name); int dev_remove_bb_dev(const char *name); #else -static inline int dev_add_bb_dev(char *filename, const char *name) { +static inline int dev_add_bb_dev(const char *filename, const char *name) { return 0; } static inline int dev_remove_bb_dev(const char *name) -- cgit v1.2.3 From 2a644bed634bdf8afdd79e672fd67306a0e5dc3c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 27 Feb 2014 21:39:05 +0100 Subject: devfs: partitioning: add new helper devfs_create_partitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Sascha Hauer --- fs/devfs-core.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++---------- include/driver.h | 33 +++++++++++++++++++ 2 files changed, 115 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/fs/devfs-core.c b/fs/devfs-core.c index f92a07c43d..193cd10234 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -260,36 +261,57 @@ 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) { - new->mtd = mtd_add_partition(cdev->mtd, offset, size, flags, name); + new->mtd = mtd_add_partition(cdev->mtd, offset, size, + partinfo->flags, partinfo->name); if (IS_ERR(new->mtd)) { int ret = PTR_ERR(new->mtd); free(new->partname); @@ -304,6 +326,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 +374,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 33b82c3e96..31bdecf6d8 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 -- cgit v1.2.3