diff options
-rw-r--r-- | drivers/mtd/mtdchar.c | 48 | ||||
-rw-r--r-- | drivers/mtd/nand/davinci_nand.c | 3 | ||||
-rw-r--r-- | include/linux/mtd/mtd.h | 15 | ||||
-rw-r--r-- | include/linux/mtd/partitions.h | 2 | ||||
-rw-r--r-- | include/mtd/mtd-abi.h | 4 | ||||
-rw-r--r-- | include/mtd/mtd-user.h | 2 |
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 | */ | ||
488 | static 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 | |||
480 | static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) | 513 | static 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 | */ | ||
121 | struct 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 | |||
113 | struct mtd_info { | 128 | struct 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 | */ |
151 | struct nand_ecclayout { | 151 | struct 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; | |||
29 | typedef struct erase_info_user erase_info_t; | 29 | typedef struct erase_info_user erase_info_t; |
30 | typedef struct region_info_user region_info_t; | 30 | typedef struct region_info_user region_info_t; |
31 | typedef struct nand_oobinfo nand_oobinfo_t; | 31 | typedef struct nand_oobinfo nand_oobinfo_t; |
32 | typedef struct nand_ecclayout nand_ecclayout_t; | 32 | typedef struct nand_ecclayout_user nand_ecclayout_t; |
33 | 33 | ||
34 | #endif /* __MTD_USER_H__ */ | 34 | #endif /* __MTD_USER_H__ */ |