aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/mtdchar.c48
-rw-r--r--drivers/mtd/nand/davinci_nand.c3
-rw-r--r--include/linux/mtd/mtd.h15
-rw-r--r--include/linux/mtd/partitions.h2
-rw-r--r--include/mtd/mtd-abi.h4
-rw-r--r--include/mtd/mtd-user.h2
6 files changed, 67 insertions, 7 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index a825002123c..24d35ba62b8 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -477,6 +477,39 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
477 return ret; 477 return ret;
478} 478}
479 479
480/*
481 * Copies (and truncates, if necessary) data from the larger struct,
482 * nand_ecclayout, to the smaller, deprecated layout struct,
483 * nand_ecclayout_user. This is necessary only to suppport the deprecated
484 * API ioctl ECCGETLAYOUT while allowing all new functionality to use
485 * nand_ecclayout flexibly (i.e. the struct may change size in new
486 * releases without requiring major rewrites).
487 */
488static int shrink_ecclayout(const struct nand_ecclayout *from,
489 struct nand_ecclayout_user *to)
490{
491 int i;
492
493 if (!from || !to)
494 return -EINVAL;
495
496 memset(to, 0, sizeof(*to));
497
498 to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES_OLD);
499 for (i = 0; i < to->eccbytes; i++)
500 to->eccpos[i] = from->eccpos[i];
501
502 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
503 if (from->oobfree[i].length == 0 &&
504 from->oobfree[i].offset == 0)
505 break;
506 to->oobavail += from->oobfree[i].length;
507 to->oobfree[i] = from->oobfree[i];
508 }
509
510 return 0;
511}
512
480static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) 513static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
481{ 514{
482 struct mtd_file_info *mfi = file->private_data; 515 struct mtd_file_info *mfi = file->private_data;
@@ -812,14 +845,23 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
812 } 845 }
813#endif 846#endif
814 847
848 /* This ioctl is being deprecated - it truncates the ecc layout */
815 case ECCGETLAYOUT: 849 case ECCGETLAYOUT:
816 { 850 {
851 struct nand_ecclayout_user *usrlay;
852
817 if (!mtd->ecclayout) 853 if (!mtd->ecclayout)
818 return -EOPNOTSUPP; 854 return -EOPNOTSUPP;
819 855
820 if (copy_to_user(argp, mtd->ecclayout, 856 usrlay = kmalloc(sizeof(*usrlay), GFP_KERNEL);
821 sizeof(struct nand_ecclayout))) 857 if (!usrlay)
822 return -EFAULT; 858 return -ENOMEM;
859
860 shrink_ecclayout(mtd->ecclayout, usrlay);
861
862 if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
863 ret = -EFAULT;
864 kfree(usrlay);
823 break; 865 break;
824 } 866 }
825 867
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 2ac7367afe7..70698e86e43 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -749,6 +749,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
749 * breaks userspace ioctl interface with mtd-utils. Once we 749 * breaks userspace ioctl interface with mtd-utils. Once we
750 * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used 750 * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used
751 * for the 4KiB page chips. 751 * for the 4KiB page chips.
752 *
753 * TODO: Note that nand_ecclayout has now been expanded and can
754 * hold plenty of OOB entries.
752 */ 755 */
753 dev_warn(&pdev->dev, "no 4-bit ECC support yet " 756 dev_warn(&pdev->dev, "no 4-bit ECC support yet "
754 "for 4KiB-page NAND\n"); 757 "for 4KiB-page NAND\n");
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 8485e42a9b0..03a1e954c58 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -110,6 +110,21 @@ struct mtd_oob_ops {
110 uint8_t *oobbuf; 110 uint8_t *oobbuf;
111}; 111};
112 112
113#define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
114#define MTD_MAX_ECCPOS_ENTRIES_LARGE 448
115#define MTD_MAX_ECCPOS_ENTRIES_OLD 64 /* Previous maximum */
116/*
117 * Correct ECC layout control structure. This replaces old nand_ecclayout
118 * (mtd-abi.h) that is exported via ECCGETLAYOUT ioctl. It should be expandable
119 * in the future simply by the above macros.
120 */
121struct nand_ecclayout {
122 __u32 eccbytes;
123 __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
124 __u32 oobavail;
125 struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
126};
127
113struct mtd_info { 128struct mtd_info {
114 u_char type; 129 u_char type;
115 uint32_t flags; 130 uint32_t flags;
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 274b6196091..930c8ac198d 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -39,7 +39,7 @@ struct mtd_partition {
39 uint64_t size; /* partition size */ 39 uint64_t size; /* partition size */
40 uint64_t offset; /* offset within the master MTD space */ 40 uint64_t offset; /* offset within the master MTD space */
41 uint32_t mask_flags; /* master MTD flags to mask out for this partition */ 41 uint32_t mask_flags; /* master MTD flags to mask out for this partition */
42 struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ 42 struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */
43}; 43};
44 44
45#define MTDPART_OFS_NXTBLK (-2) 45#define MTDPART_OFS_NXTBLK (-2)
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 4debb451463..5bce0838434 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -119,7 +119,7 @@ struct otp_info {
119#define OTPGETREGIONCOUNT _IOW('M', 14, int) 119#define OTPGETREGIONCOUNT _IOW('M', 14, int)
120#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) 120#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info)
121#define OTPLOCK _IOR('M', 16, struct otp_info) 121#define OTPLOCK _IOR('M', 16, struct otp_info)
122#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) 122#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout_user)
123#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) 123#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats)
124#define MTDFILEMODE _IO('M', 19) 124#define MTDFILEMODE _IO('M', 19)
125#define MEMERASE64 _IOW('M', 20, struct erase_info_user64) 125#define MEMERASE64 _IOW('M', 20, struct erase_info_user64)
@@ -148,7 +148,7 @@ struct nand_oobfree {
148 * ECC layout control structure. Exported to userspace for 148 * ECC layout control structure. Exported to userspace for
149 * diagnosis and to allow creation of raw images 149 * diagnosis and to allow creation of raw images
150 */ 150 */
151struct nand_ecclayout { 151struct nand_ecclayout_user {
152 __u32 eccbytes; 152 __u32 eccbytes;
153 __u32 eccpos[64]; 153 __u32 eccpos[64];
154 __u32 oobavail; 154 __u32 oobavail;
diff --git a/include/mtd/mtd-user.h b/include/mtd/mtd-user.h
index aa3c2f86a91..83327c808c8 100644
--- a/include/mtd/mtd-user.h
+++ b/include/mtd/mtd-user.h
@@ -29,6 +29,6 @@ typedef struct mtd_info_user mtd_info_t;
29typedef struct erase_info_user erase_info_t; 29typedef struct erase_info_user erase_info_t;
30typedef struct region_info_user region_info_t; 30typedef struct region_info_user region_info_t;
31typedef struct nand_oobinfo nand_oobinfo_t; 31typedef struct nand_oobinfo nand_oobinfo_t;
32typedef struct nand_ecclayout nand_ecclayout_t; 32typedef struct nand_ecclayout_user nand_ecclayout_t;
33 33
34#endif /* __MTD_USER_H__ */ 34#endif /* __MTD_USER_H__ */