aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdchar.c
diff options
context:
space:
mode:
authorRoman Tereshonkov <roman.tereshonkov@nokia.com>2010-09-17 06:31:42 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-10-24 19:48:49 -0400
commitd0f7959e2b708d775c3b6b53cc6a8abb8ff0a00b (patch)
treeccb0dc2fdcc6b0611fe1b19faaa841ff4430fd2b /drivers/mtd/mtdchar.c
parent5daa7b21496aebf057c12be03038e7220e33353b (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.c60
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
515static 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
513static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) 553static 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