9
0
Fork 0

Merge branch 'for-next/partitionhelper'

Conflicts:
	fs/devfs-core.c
This commit is contained in:
Sascha Hauer 2014-03-07 09:25:53 +01:00
commit 74213ed9a7
9 changed files with 249 additions and 55 deletions

View File

@ -50,7 +50,7 @@ extra-y += barebox.lds
is not ported yet. is not ported yet.
- Call devfs_add_partition() to add an environment partition for your device: - Call devfs_add_partition() to add an environment partition for your device:
devfs_add_partition("nor0", 0x40000, 0x20000, "env0"); devfs_add_partition("nor0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0");
This will add an area starting at 0x40000 of size 0x20000 of the device This will add an area starting at 0x40000 of size 0x20000 of the device
nor0 as env0. nor0 as env0.

View File

@ -82,6 +82,24 @@ static int a9m2410_mem_init(void)
} }
mem_initcall(a9m2410_mem_init); mem_initcall(a9m2410_mem_init);
static const struct devfs_partition a9m2410_nand0_partitions[] = {
{
.offset = 0,
.size = 0x40000,
.flags = DEVFS_PARTITION_FIXED,
.name = "self_raw",
.bbname = "self0",
}, {
.offset = DEVFS_PARTITION_APPEND,
.size = 0x20000,
.flags = DEVFS_PARTITION_FIXED,
.name = "env_raw",
.bbname = "env0",
}, {
/* sentinel */
}
};
static int a9m2410_devices_init(void) static int a9m2410_devices_init(void)
{ {
uint32_t reg; uint32_t reg;
@ -116,14 +134,9 @@ static int a9m2410_devices_init(void)
add_generic_device("smc91c111", DEVICE_ID_DYNAMIC, NULL, S3C_CS1_BASE + 0x300, add_generic_device("smc91c111", DEVICE_ID_DYNAMIC, NULL, S3C_CS1_BASE + 0x300,
16, IORESOURCE_MEM, NULL); 16, IORESOURCE_MEM, NULL);
#ifdef CONFIG_NAND if (IS_ENABLED(CONFIG_NAND))
/* ----------- add some vital partitions -------- */ devfs_create_partitions("nand0", a9m2410_nand0_partitions);
devfs_add_partition("nand0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self_raw");
dev_add_bb_dev("self_raw", "self0");
devfs_add_partition("nand0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env_raw");
dev_add_bb_dev("env_raw", "env0");
#endif
armlinux_set_architecture(MACH_TYPE_A9M2410); armlinux_set_architecture(MACH_TYPE_A9M2410);
return 0; return 0;

View File

@ -129,6 +129,40 @@ static void set_board_rev(int rev)
imx35_3ds_system_rev = (imx35_3ds_system_rev & ~(0xF << 8)) | (rev & 0xF) << 8; imx35_3ds_system_rev = (imx35_3ds_system_rev & ~(0xF << 8)) | (rev & 0xF) << 8;
} }
static const struct devfs_partition f3s_nand0_partitions[] = {
{
.offset = 0,
.size = 0x40000,
.flags = DEVFS_PARTITION_FIXED,
.name = "self_raw",
.bbname = "self0",
}, {
.offset = DEVFS_PARTITION_APPEND, /* 0x40000 */
.size = 0x80000,
.flags = DEVFS_PARTITION_FIXED,
.name = "env_raw",
.bbname = "env0",
}, {
/* sentinel */
}
};
static const struct devfs_partition f3s_nor0_partitions[] = {
{
.offset = 0,
.size = 0x40000,
.flags = DEVFS_PARTITION_FIXED,
.name = "self0",
}, {
.offset = DEVFS_PARTITION_APPEND, /* 0x40000 */
.size = 0x80000,
.flags = DEVFS_PARTITION_FIXED,
.name = "env0",
}, {
/* sentinel */
}
};
static int f3s_devices_init(void) static int f3s_devices_init(void)
{ {
uint32_t reg; uint32_t reg;
@ -151,15 +185,11 @@ static int f3s_devices_init(void)
switch ((reg >> 25) & 0x3) { switch ((reg >> 25) & 0x3) {
case 0x01: /* NAND is the source */ case 0x01: /* NAND is the source */
devfs_add_partition("nand0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self_raw"); devfs_create_partitions("nand0", f3s_nand0_partitions);
dev_add_bb_dev("self_raw", "self0");
devfs_add_partition("nand0", 0x40000, 0x80000, DEVFS_PARTITION_FIXED, "env_raw");
dev_add_bb_dev("env_raw", "env0");
break; break;
case 0x00: /* NOR is the source */ case 0x00: /* NOR is the source */
devfs_add_partition("nor0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self0"); devfs_create_partitions("nor0", f3s_nor0_partitions);
devfs_add_partition("nor0", 0x40000, 0x80000, DEVFS_PARTITION_FIXED, "env0");
protect_file("/dev/env0", 1); protect_file("/dev/env0", 1);
break; break;
} }

View File

@ -199,6 +199,40 @@ struct imxusb_platformdata pcm038_otg_pdata = {
.flags = MXC_EHCI_MODE_ULPI | MXC_EHCI_INTERFACE_DIFF_UNI, .flags = MXC_EHCI_MODE_ULPI | MXC_EHCI_INTERFACE_DIFF_UNI,
}; };
static const struct devfs_partition pcm038_nand0_partitions[] = {
{
.offset = 0,
.size = SZ_512K,
.flags = DEVFS_PARTITION_FIXED,
.name = "self_raw",
.bbname = "self0",
}, {
.offset = DEVFS_PARTITION_APPEND, /* 512 KiB */
.size = SZ_128K,
.flags = DEVFS_PARTITION_FIXED,
.name = "env_raw",
.bbname = "env0",
}, {
/* sentinel */
}
};
static const struct devfs_partition pcm038_nor0_partitions[] = {
{
.offset = 0,
.size = SZ_512K,
.flags = DEVFS_PARTITION_FIXED,
.name = "self0",
}, {
.offset = DEVFS_PARTITION_APPEND, /* 512 KiB */
.size = SZ_128K,
.flags = DEVFS_PARTITION_FIXED,
.name = "env0",
}, {
/* sentinel */
}
};
static int pcm038_devices_init(void) static int pcm038_devices_init(void)
{ {
int i; int i;
@ -336,19 +370,12 @@ static int pcm038_devices_init(void)
switch (bootsource_get()) { switch (bootsource_get()) {
case BOOTSOURCE_NAND: case BOOTSOURCE_NAND:
devfs_add_partition("nand0", 0, SZ_512K, devfs_create_partitions("nand0", pcm038_nand0_partitions);
DEVFS_PARTITION_FIXED, "self_raw");
dev_add_bb_dev("self_raw", "self0");
devfs_add_partition("nand0", SZ_512K, SZ_128K,
DEVFS_PARTITION_FIXED, "env_raw");
dev_add_bb_dev("env_raw", "env0");
envdev = "NAND"; envdev = "NAND";
break; break;
default: default:
devfs_add_partition("nor0", 0, SZ_512K, devfs_create_partitions("nor0", pcm038_nor0_partitions);
DEVFS_PARTITION_FIXED, "self0");
devfs_add_partition("nor0", SZ_512K, SZ_128K,
DEVFS_PARTITION_FIXED, "env0");
protect_file("/dev/env0", 1); protect_file("/dev/env0", 1);
envdev = "NOR"; envdev = "NOR";
} }

View File

@ -400,6 +400,38 @@ static void ek_add_device_hdmi(void)
} }
#endif #endif
static const struct devfs_partition at91sama5d3xek_nand0_partitions[] = {
{
.offset = 0x00000,
.size = SZ_256K,
.flags = DEVFS_PARTITION_FIXED,
.name = "at91bootstrap_raw",
.bbname = "at91bootstrap",
}, {
.offset = DEVFS_PARTITION_APPEND, /* 256 KiB */
.size = SZ_256K + SZ_128K,
.flags = DEVFS_PARTITION_FIXED,
.name = "self_raw",
.bbname = "self0",
},
/* hole of 128 KiB */
{
.offset = SZ_512K + SZ_256K,
.size = SZ_256K,
.flags = DEVFS_PARTITION_FIXED,
.name = "env_raw",
.bbname = "env0",
}, {
.offset = DEVFS_PARTITION_APPEND, /* 1 MiB */
.size = SZ_256K,
.flags = DEVFS_PARTITION_FIXED,
.name = "env_raw1",
.bbname = "env1",
}, {
/* sentinel */
}
};
static int at91sama5d3xek_devices_init(void) static int at91sama5d3xek_devices_init(void)
{ {
ek_add_device_w1(); ek_add_device_w1();
@ -411,14 +443,7 @@ static int at91sama5d3xek_devices_init(void)
ek_add_device_mci(); ek_add_device_mci();
ek_add_device_lcdc(); ek_add_device_lcdc();
devfs_add_partition("nand0", 0x00000, SZ_256K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw"); devfs_create_partitions("nand0", at91sama5d3xek_nand0_partitions);
dev_add_bb_dev("at91bootstrap_raw", "at91bootstrap");
devfs_add_partition("nand0", SZ_256K, SZ_256K + SZ_128K, DEVFS_PARTITION_FIXED, "self_raw");
dev_add_bb_dev("self_raw", "self0");
devfs_add_partition("nand0", SZ_512K + SZ_256K, SZ_256K, DEVFS_PARTITION_FIXED, "env_raw");
dev_add_bb_dev("env_raw", "env0");
devfs_add_partition("nand0", SZ_1M, SZ_256K, DEVFS_PARTITION_FIXED, "env_raw1");
dev_add_bb_dev("env_raw1", "env1");
return 0; return 0;
} }

View File

@ -261,7 +261,7 @@ static LIST_HEAD(bb_list);
* @param[in] name Partition name (can be obtained with devinfo command) * @param[in] name Partition name (can be obtained with devinfo command)
* @return The device representing the new partition. * @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; struct nand_bb *bb;
int ret = -ENOMEM; int ret = -ENOMEM;

View File

@ -22,6 +22,7 @@
#include <errno.h> #include <errno.h>
#include <malloc.h> #include <malloc.h>
#include <ioctl.h> #include <ioctl.h>
#include <nand.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
@ -260,47 +261,88 @@ int devfs_remove(struct cdev *cdev)
return 0; return 0;
} }
struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size, static struct cdev *__devfs_add_partition(struct cdev *cdev,
int flags, const char *name) 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_by_name(partinfo->name))
if (cdev)
return ERR_PTR(-EEXIST); return ERR_PTR(-EEXIST);
cdev = cdev_by_name(devname); if (partinfo->offset > 0)
if (!cdev) offset = partinfo->offset;
return ERR_PTR(-ENOENT); else if (partinfo->offset == 0)
/* append to previous partition */
offset = *end;
else
/* relative to end of cdev */
offset = cdev->size + partinfo->offset;
if (offset + size > cdev->size) 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); return ERR_PTR(-EINVAL);
}
if (IS_ENABLED(CONFIG_PARTITION_NEED_MTD) && cdev->mtd) { if (IS_ENABLED(CONFIG_PARTITION_NEED_MTD) && cdev->mtd) {
struct mtd_info *mtd; struct mtd_info *mtd;
mtd = mtd_add_partition(cdev->mtd, offset, size, flags, name); mtd = mtd_add_partition(cdev->mtd, offset, size,
partinfo->flags, partinfo->name);
if (IS_ERR(mtd)) if (IS_ERR(mtd))
return (void *)mtd; return (void *)mtd;
return 0; return 0;
} }
new = xzalloc(sizeof (*new)); new = xzalloc(sizeof(*new));
new->name = strdup(name); new->name = strdup(partinfo->name);
if (!strncmp(devname, name, strlen(devname))) if (!strncmp(cdev->name, partinfo->name, strlen(cdev->name)))
new->partname = xstrdup(name + strlen(devname) + 1); new->partname = xstrdup(partinfo->name + strlen(cdev->name) + 1);
new->ops = cdev->ops; new->ops = cdev->ops;
new->priv = cdev->priv; new->priv = cdev->priv;
new->size = size; new->size = size;
new->offset = offset + cdev->offset; new->offset = cdev->offset + offset;
new->dev = cdev->dev; new->dev = cdev->dev;
new->flags = flags | DEVFS_IS_PARTITION; new->flags = partinfo->flags | DEVFS_IS_PARTITION;
devfs_create(new); devfs_create(new);
return new; 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) int devfs_del_partition(const char *name)
{ {
struct cdev *cdev; struct cdev *cdev;
@ -330,3 +372,27 @@ int devfs_del_partition(const char *name)
return 0; 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;
}

View File

@ -482,15 +482,48 @@ 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_ioctl(struct cdev *cdev, int cmd, void *buf);
int cdev_erase(struct cdev *cdev, size_t count, loff_t offset); int cdev_erase(struct cdev *cdev, size_t count, loff_t offset);
#define DEVFS_PARTITION_FIXED (1 << 0) #define DEVFS_PARTITION_FIXED (1U << 0)
#define DEVFS_PARTITION_READONLY (1 << 1) #define DEVFS_PARTITION_READONLY (1U << 1)
#define DEVFS_IS_PARTITION (1 << 2) #define DEVFS_IS_PARTITION (1 << 2)
#define DEVFS_IS_CHARACTER_DEV (1 << 3) #define DEVFS_IS_CHARACTER_DEV (1 << 3)
struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size, struct cdev *devfs_add_partition(const char *devname, loff_t offset,
int flags, const char *name); loff_t size, unsigned int flags, const char *name);
int devfs_del_partition(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) \ #define DRV_OF_COMPAT(compat) \
IS_ENABLED(CONFIG_OFDEVICE) ? (compat) : NULL IS_ENABLED(CONFIG_OFDEVICE) ? (compat) : NULL

View File

@ -5,10 +5,10 @@
struct nand_bb; struct nand_bb;
#ifdef CONFIG_NAND #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); int dev_remove_bb_dev(const char *name);
#else #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; return 0;
} }
static inline int dev_remove_bb_dev(const char *name) static inline int dev_remove_bb_dev(const char *name)