[PATCH 1/1][MTD] Adding IOCTLs for run-time partitioning support
Rohit Hassan Sathyanarayan
rohit.hs at samsung.com
Thu Jul 29 07:30:59 EDT 2010
Hi All
Sending the patch on MTD for adding four IOCTLs.
MTDPARTITIONCREATE
MTDPARTITIONDELETE
MTDPARTITIONSETPERMISSION
MTDPARTITIONMERGE
Signed-off-by: Rohit HS <rohit.hs at samsung.com>
---
drivers/mtd/mtdchar.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/mtd/mtd-abi.h | 17 ++++++
2 files changed, 142 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 8b223c0..704788c 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -22,6 +22,10 @@
#include <asm/uaccess.h>
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
#define MTD_INODE_FS_MAGIC 0x11307854
static struct vfsmount *mtd_inode_mnt __read_mostly;
@@ -826,6 +830,128 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
}
file->f_pos = 0;
break;
+#ifdef CONFIG_MTD_PARTITIONS
+
+ case MTDPARTITIONCREATE:
+ {
+ struct mtd_partition *pst_minfo = NULL;
+ struct mtd_partition *pst_minfo_hold = NULL;
+ struct mtd_partition st_free;
+ uint64_t u64_userfreeoffset = 0;
+ uint64_t u64_userfreesize = 0;
+ struct user_mtd *puser_partitions = NULL;
+ struct user_mtd_info upartition;
+ int i;
+
+ if (copy_from_user(&upartition, argp,
+ sizeof(struct user_mtd_info))) {
+ ret = -EFAULT;
+ break;
+ }
+ puser_partitions = kzalloc(sizeof(struct user_mtd)*
+ upartition.num_partitions
+ , GFP_KERNEL);
+ pst_minfo = kzalloc(sizeof(struct mtd_partition)*
+ upartition.num_partitions,
+ GFP_KERNEL);
+ pst_minfo_hold = pst_minfo;
+ if (puser_partitions == NULL) {
+ ret = -EFAULT;
+ break;
+ }
+ if (copy_from_user(puser_partitions,
+ upartition.pst_user_partitions,
+ sizeof(struct user_mtd)*
+ upartition.num_partitions)) {
+ ret = -EFAULT;
+ break;
+ }
+ for (i = 0; i < upartition.num_partitions; i++) {
+ pst_minfo->name = puser_partitions->name;
+ pst_minfo->size =
+ puser_partitions->partition_size;
+ u64_userfreesize += pst_minfo->size;
+ pst_minfo->offset =
+ puser_partitions->partition_offset;
+ u64_userfreeoffset += pst_minfo->offset;
+ pst_minfo->mask_flags =
+ puser_partitions->partition_mask;
+
+ puser_partitions++;
+ pst_minfo++;
+ }
+ add_mtd_partitions(mtd, pst_minfo_hold,
+ upartition.num_partitions);
+ if ((mtd->size - u64_userfreesize) > 0) {
+ st_free.name = "FREE";
+ st_free.size = mtd->size - u64_userfreesize;
+ st_free.offset = u64_userfreesize;
+ st_free.mask_flags = 0;
+ add_mtd_partitions(mtd, &st_free, 1);
+ }
+ break;
+ }
+ case MTDPARTITIONDELETE:
+ {
+ struct mtd_info *pst_del_info = NULL;
+ uint32_t mtd_partition_number;
+
+ if (copy_from_user(&mtd_partition_number, argp,
+ sizeof(mtd_partition_number))) {
+ ret = -EFAULT;
+ break;
+ }
+ pst_del_info = get_mtd_device(NULL,
+ mtd_partition_number);
+
+ if (pst_del_info != NULL) {
+ put_mtd_device(pst_del_info);
+ del_mtd_device(pst_del_info);
+ }
+ break;
+ }
+ case MTDPARTITIONSETPERMISSION:
+ {
+ uint32_t u32_mask_flags;
+ struct mtd_info *pst_device = NULL;
+ int i32_dev_num;
+
+ if (copy_from_user(&u32_mask_flags, argp,
+ sizeof(u32_mask_flags))) {
+ ret = -EFAULT;
+ break;
+ }
+ i32_dev_num = (u32_mask_flags & 0x0000FFFF);
+ u32_mask_flags = (u32_mask_flags & 0xFFFF0000) >> 16;
+ pst_device = get_mtd_device(NULL, i32_dev_num);
+ pst_device->flags = u32_mask_flags;
+ break;
+ }
+ case MTDPARTITIONMERGE:
+ {
+ struct mtd_info *pst_merge_device1 = NULL;
+ struct mtd_info *pst_merge_device2 = NULL;
+ unsigned char partition_number[2];
+
+ if (copy_from_user(partition_number, argp, 2)) {
+ ret = -EFAULT;
+ break;
+ }
+ pst_merge_device1 = get_mtd_device(NULL,
+ partition_number[0]);
+ pst_merge_device2 = get_mtd_device(NULL,
+ partition_number[1]);
+ if ((pst_merge_device1 != NULL) &&
+ (pst_merge_device2 != NULL)) {
+ pst_merge_device1->size +=
+ pst_merge_device2->size;
+ put_mtd_device(pst_merge_device2);
+ del_mtd_device(pst_merge_device2);
+ }
+ break;
+ }
+#endif
+
}
default:
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index be51ae2..85168f2 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -30,6 +30,18 @@ struct mtd_oob_buf64 {
__u64 usr_ptr;
};
+struct user_mtd {
+ char name[32];
+ __u64 partition_size;
+ __u64 partition_offset;
+ __u32 partition_mask;
+};
+
+struct user_mtd_info {
+ struct user_mtd *pst_user_partitions;
+ __u32 num_partitions;
+};
+
#define MTD_ABSENT 0
#define MTD_RAM 1
#define MTD_ROM 2
@@ -110,7 +122,10 @@ struct otp_info {
#define MEMERASE64 _IOW('M', 20, struct erase_info_user64)
#define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64)
#define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64)
-
+#define MTDPARTITIONCREATE _IOW('M', 23, int)
+#define MTDPARTITIONDELETE _IOW('M', 24, int)
+#define MTDPARTITIONSETPERMISSION _IOW('M', 26, int)
+#define MTDPARTITIONMERGE _IOW('M', 27, int)
/*
* Obsolete legacy interface. Keep it in order not to break userspace
* interfaces
---
More information about the linux-mtd
mailing list