diff options
author | Roman Tereshonkov <roman.tereshonkov@nokia.com> | 2010-09-17 06:31:42 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-10-24 19:48:49 -0400 |
commit | d0f7959e2b708d775c3b6b53cc6a8abb8ff0a00b (patch) | |
tree | ccb0dc2fdcc6b0611fe1b19faaa841ff4430fd2b /drivers/mtd/mtdchar.c | |
parent | 5daa7b21496aebf057c12be03038e7220e33353b (diff) |
mtd: add BLKPG API based repartition support
Add support for mtd repartition based on the block
device BLKPG interface:
BLKPG_ADD_PARTITION - for partition creation;
BLKPG_DEL_PARTITION - for partition delete
The usage is based on BLKPG ioctl called with
struct blkpg_ioctl_arg argument which includes the
reference to struct blkpg_partition discribing the
partition offset and length.
Disadvantage: there is no implementation for mtd
flags control. The flags are always borrowed from
the master device.
Signed-off-by: Roman Tereshonkov <roman.tereshonkov@nokia.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/mtdchar.c')
-rw-r--r-- | drivers/mtd/mtdchar.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 5895de7018d4..b7ed09c57903 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -30,8 +30,9 @@ | |||
30 | #include <linux/backing-dev.h> | 30 | #include <linux/backing-dev.h> |
31 | #include <linux/compat.h> | 31 | #include <linux/compat.h> |
32 | #include <linux/mount.h> | 32 | #include <linux/mount.h> |
33 | 33 | #include <linux/blkpg.h> | |
34 | #include <linux/mtd/mtd.h> | 34 | #include <linux/mtd/mtd.h> |
35 | #include <linux/mtd/partitions.h> | ||
35 | #include <linux/mtd/map.h> | 36 | #include <linux/mtd/map.h> |
36 | 37 | ||
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
@@ -510,6 +511,45 @@ static int shrink_ecclayout(const struct nand_ecclayout *from, | |||
510 | return 0; | 511 | return 0; |
511 | } | 512 | } |
512 | 513 | ||
514 | #ifdef CONFIG_MTD_PARTITIONS | ||
515 | static int mtd_blkpg_ioctl(struct mtd_info *mtd, | ||
516 | struct blkpg_ioctl_arg __user *arg) | ||
517 | { | ||
518 | struct blkpg_ioctl_arg a; | ||
519 | struct blkpg_partition p; | ||
520 | |||
521 | if (!capable(CAP_SYS_ADMIN)) | ||
522 | return -EPERM; | ||
523 | |||
524 | /* Only master mtd device must be used to control partitions */ | ||
525 | if (!mtd_is_master(mtd)) | ||
526 | return -EINVAL; | ||
527 | |||
528 | if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg))) | ||
529 | return -EFAULT; | ||
530 | |||
531 | if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) | ||
532 | return -EFAULT; | ||
533 | |||
534 | switch (a.op) { | ||
535 | case BLKPG_ADD_PARTITION: | ||
536 | |||
537 | return mtd_add_partition(mtd, p.devname, p.start, p.length); | ||
538 | |||
539 | case BLKPG_DEL_PARTITION: | ||
540 | |||
541 | if (p.pno < 0) | ||
542 | return -EINVAL; | ||
543 | |||
544 | return mtd_del_partition(mtd, p.pno); | ||
545 | |||
546 | default: | ||
547 | return -EINVAL; | ||
548 | } | ||
549 | } | ||
550 | #endif | ||
551 | |||
552 | |||
513 | static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) | 553 | static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) |
514 | { | 554 | { |
515 | struct mtd_file_info *mfi = file->private_data; | 555 | struct mtd_file_info *mfi = file->private_data; |
@@ -900,6 +940,22 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) | |||
900 | break; | 940 | break; |
901 | } | 941 | } |
902 | 942 | ||
943 | #ifdef CONFIG_MTD_PARTITIONS | ||
944 | case BLKPG: | ||
945 | { | ||
946 | ret = mtd_blkpg_ioctl(mtd, | ||
947 | (struct blkpg_ioctl_arg __user *)arg); | ||
948 | break; | ||
949 | } | ||
950 | |||
951 | case BLKRRPART: | ||
952 | { | ||
953 | /* No reread partition feature. Just return ok */ | ||
954 | ret = 0; | ||
955 | break; | ||
956 | } | ||
957 | #endif | ||
958 | |||
903 | default: | 959 | default: |
904 | ret = -ENOTTY; | 960 | ret = -ENOTTY; |
905 | } | 961 | } |
@@ -1078,7 +1134,7 @@ static int mtd_inodefs_get_sb(struct file_system_type *fs_type, int flags, | |||
1078 | const char *dev_name, void *data, | 1134 | const char *dev_name, void *data, |
1079 | struct vfsmount *mnt) | 1135 | struct vfsmount *mnt) |
1080 | { | 1136 | { |
1081 | return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC, | 1137 | return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC, |
1082 | mnt); | 1138 | mnt); |
1083 | } | 1139 | } |
1084 | 1140 | ||