0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/kernel.h>
0027 #include <linux/slab.h>
0028 #include <linux/module.h>
0029 #include <linux/types.h>
0030 #include <linux/bitops.h>
0031 #include <linux/sizes.h>
0032 #include <linux/mtd/mtd.h>
0033 #include <linux/mtd/partitions.h>
0034
0035
0036 #define NAND_NOOB_LOGADDR_00 8
0037 #define NAND_NOOB_LOGADDR_01 9
0038 #define NAND_NOOB_LOGADDR_10 10
0039 #define NAND_NOOB_LOGADDR_11 11
0040 #define NAND_NOOB_LOGADDR_20 12
0041 #define NAND_NOOB_LOGADDR_21 13
0042
0043 #define BLOCK_IS_RESERVED 0xffff
0044 #define BLOCK_UNMASK_COMPLEMENT 1
0045
0046
0047 #define SHARPSL_NAND_PARTS 3
0048 #define SHARPSL_FTL_PART_SIZE (7 * SZ_1M)
0049 #define SHARPSL_PARTINFO1_LADDR 0x00060000
0050 #define SHARPSL_PARTINFO2_LADDR 0x00064000
0051
0052 #define BOOT_MAGIC 0x424f4f54
0053 #define FSRO_MAGIC 0x4653524f
0054 #define FSRW_MAGIC 0x46535257
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 struct sharpsl_ftl {
0065 unsigned int logmax;
0066 unsigned int *log2phy;
0067 };
0068
0069
0070 static int sharpsl_nand_check_ooblayout(struct mtd_info *mtd)
0071 {
0072 u8 freebytes = 0;
0073 int section = 0;
0074
0075 while (true) {
0076 struct mtd_oob_region oobfree = { };
0077 int ret, i;
0078
0079 ret = mtd_ooblayout_free(mtd, section++, &oobfree);
0080 if (ret)
0081 break;
0082
0083 if (!oobfree.length || oobfree.offset > 15 ||
0084 (oobfree.offset + oobfree.length) < 8)
0085 continue;
0086
0087 i = oobfree.offset >= 8 ? oobfree.offset : 8;
0088 for (; i < oobfree.offset + oobfree.length && i < 16; i++)
0089 freebytes |= BIT(i - 8);
0090
0091 if (freebytes == 0xff)
0092 return 0;
0093 }
0094
0095 return -ENOTSUPP;
0096 }
0097
0098 static int sharpsl_nand_read_oob(struct mtd_info *mtd, loff_t offs, u8 *buf)
0099 {
0100 struct mtd_oob_ops ops = { };
0101 int ret;
0102
0103 ops.mode = MTD_OPS_PLACE_OOB;
0104 ops.ooblen = mtd->oobsize;
0105 ops.oobbuf = buf;
0106
0107 ret = mtd_read_oob(mtd, offs, &ops);
0108 if (ret != 0 || mtd->oobsize != ops.oobretlen)
0109 return -1;
0110
0111 return 0;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 static int sharpsl_nand_get_logical_num(u8 *oob)
0133 {
0134 u16 us;
0135 int good0, good1;
0136
0137 if (oob[NAND_NOOB_LOGADDR_00] == oob[NAND_NOOB_LOGADDR_10] &&
0138 oob[NAND_NOOB_LOGADDR_01] == oob[NAND_NOOB_LOGADDR_11]) {
0139 good0 = NAND_NOOB_LOGADDR_00;
0140 good1 = NAND_NOOB_LOGADDR_01;
0141 } else if (oob[NAND_NOOB_LOGADDR_10] == oob[NAND_NOOB_LOGADDR_20] &&
0142 oob[NAND_NOOB_LOGADDR_11] == oob[NAND_NOOB_LOGADDR_21]) {
0143 good0 = NAND_NOOB_LOGADDR_10;
0144 good1 = NAND_NOOB_LOGADDR_11;
0145 } else if (oob[NAND_NOOB_LOGADDR_20] == oob[NAND_NOOB_LOGADDR_00] &&
0146 oob[NAND_NOOB_LOGADDR_21] == oob[NAND_NOOB_LOGADDR_01]) {
0147 good0 = NAND_NOOB_LOGADDR_20;
0148 good1 = NAND_NOOB_LOGADDR_21;
0149 } else {
0150 return -EINVAL;
0151 }
0152
0153 us = oob[good0] | oob[good1] << 8;
0154
0155
0156 if (hweight16(us) & BLOCK_UNMASK_COMPLEMENT)
0157 return -EINVAL;
0158
0159
0160 if (us == BLOCK_IS_RESERVED)
0161 return BLOCK_IS_RESERVED;
0162
0163 return (us >> 1) & GENMASK(9, 0);
0164 }
0165
0166 static int sharpsl_nand_init_ftl(struct mtd_info *mtd, struct sharpsl_ftl *ftl)
0167 {
0168 unsigned int block_num, phymax;
0169 int i, ret, log_num;
0170 loff_t block_adr;
0171 u8 *oob;
0172
0173 oob = kzalloc(mtd->oobsize, GFP_KERNEL);
0174 if (!oob)
0175 return -ENOMEM;
0176
0177 phymax = mtd_div_by_eb(SHARPSL_FTL_PART_SIZE, mtd);
0178
0179
0180 ftl->logmax = ((phymax * 95) / 100) - 1;
0181
0182 ftl->log2phy = kmalloc_array(ftl->logmax, sizeof(*ftl->log2phy),
0183 GFP_KERNEL);
0184 if (!ftl->log2phy) {
0185 ret = -ENOMEM;
0186 goto exit;
0187 }
0188
0189
0190 for (i = 0; i < ftl->logmax; i++)
0191 ftl->log2phy[i] = UINT_MAX;
0192
0193
0194 for (block_num = 0; block_num < phymax; block_num++) {
0195 block_adr = (loff_t)block_num * mtd->erasesize;
0196
0197 if (mtd_block_isbad(mtd, block_adr))
0198 continue;
0199
0200 if (sharpsl_nand_read_oob(mtd, block_adr, oob))
0201 continue;
0202
0203
0204 log_num = sharpsl_nand_get_logical_num(oob);
0205
0206
0207 if (log_num > 0 && log_num < ftl->logmax) {
0208 if (ftl->log2phy[log_num] == UINT_MAX)
0209 ftl->log2phy[log_num] = block_num;
0210 }
0211 }
0212
0213 pr_info("Sharp SL FTL: %d blocks used (%d logical, %d reserved)\n",
0214 phymax, ftl->logmax, phymax - ftl->logmax);
0215
0216 ret = 0;
0217 exit:
0218 kfree(oob);
0219 return ret;
0220 }
0221
0222 static void sharpsl_nand_cleanup_ftl(struct sharpsl_ftl *ftl)
0223 {
0224 kfree(ftl->log2phy);
0225 }
0226
0227 static int sharpsl_nand_read_laddr(struct mtd_info *mtd,
0228 loff_t from,
0229 size_t len,
0230 void *buf,
0231 struct sharpsl_ftl *ftl)
0232 {
0233 unsigned int log_num, final_log_num;
0234 unsigned int block_num;
0235 loff_t block_adr;
0236 loff_t block_ofs;
0237 size_t retlen;
0238 int err;
0239
0240 log_num = mtd_div_by_eb((u32)from, mtd);
0241 final_log_num = mtd_div_by_eb(((u32)from + len - 1), mtd);
0242
0243 if (len <= 0 || log_num >= ftl->logmax || final_log_num > log_num)
0244 return -EINVAL;
0245
0246 block_num = ftl->log2phy[log_num];
0247 block_adr = (loff_t)block_num * mtd->erasesize;
0248 block_ofs = mtd_mod_by_eb((u32)from, mtd);
0249
0250 err = mtd_read(mtd, block_adr + block_ofs, len, &retlen, buf);
0251
0252 if (mtd_is_bitflip(err))
0253 err = 0;
0254
0255 if (!err && retlen != len)
0256 err = -EIO;
0257
0258 if (err)
0259 pr_err("sharpslpart: error, read failed at %#llx\n",
0260 block_adr + block_ofs);
0261
0262 return err;
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282 struct sharpsl_nand_partinfo {
0283 __le32 start;
0284 __le32 end;
0285 __be32 magic;
0286 u32 reserved;
0287 };
0288
0289 static int sharpsl_nand_read_partinfo(struct mtd_info *master,
0290 loff_t from,
0291 size_t len,
0292 struct sharpsl_nand_partinfo *buf,
0293 struct sharpsl_ftl *ftl)
0294 {
0295 int ret;
0296
0297 ret = sharpsl_nand_read_laddr(master, from, len, buf, ftl);
0298 if (ret)
0299 return ret;
0300
0301
0302 if (be32_to_cpu(buf[0].magic) != BOOT_MAGIC ||
0303 be32_to_cpu(buf[1].magic) != FSRO_MAGIC ||
0304 be32_to_cpu(buf[2].magic) != FSRW_MAGIC) {
0305 pr_err("sharpslpart: magic values mismatch\n");
0306 return -EINVAL;
0307 }
0308
0309
0310 buf[2].end = cpu_to_le32(master->size);
0311
0312
0313 if (le32_to_cpu(buf[0].end) <= le32_to_cpu(buf[0].start) ||
0314 le32_to_cpu(buf[1].start) < le32_to_cpu(buf[0].end) ||
0315 le32_to_cpu(buf[1].end) <= le32_to_cpu(buf[1].start) ||
0316 le32_to_cpu(buf[2].start) < le32_to_cpu(buf[1].end) ||
0317 le32_to_cpu(buf[2].end) <= le32_to_cpu(buf[2].start)) {
0318 pr_err("sharpslpart: partition sizes mismatch\n");
0319 return -EINVAL;
0320 }
0321
0322 return 0;
0323 }
0324
0325 static int sharpsl_parse_mtd_partitions(struct mtd_info *master,
0326 const struct mtd_partition **pparts,
0327 struct mtd_part_parser_data *data)
0328 {
0329 struct sharpsl_ftl ftl;
0330 struct sharpsl_nand_partinfo buf[SHARPSL_NAND_PARTS];
0331 struct mtd_partition *sharpsl_nand_parts;
0332 int err;
0333
0334
0335 err = sharpsl_nand_check_ooblayout(master);
0336 if (err)
0337 return err;
0338
0339
0340 err = sharpsl_nand_init_ftl(master, &ftl);
0341 if (err)
0342 return err;
0343
0344
0345 pr_info("sharpslpart: try reading first partition table\n");
0346 err = sharpsl_nand_read_partinfo(master,
0347 SHARPSL_PARTINFO1_LADDR,
0348 sizeof(buf), buf, &ftl);
0349 if (err) {
0350
0351 pr_warn("sharpslpart: first partition table is invalid, retry using the second\n");
0352 err = sharpsl_nand_read_partinfo(master,
0353 SHARPSL_PARTINFO2_LADDR,
0354 sizeof(buf), buf, &ftl);
0355 }
0356
0357
0358 sharpsl_nand_cleanup_ftl(&ftl);
0359
0360 if (err) {
0361 pr_err("sharpslpart: both partition tables are invalid\n");
0362 return err;
0363 }
0364
0365 sharpsl_nand_parts = kcalloc(SHARPSL_NAND_PARTS,
0366 sizeof(*sharpsl_nand_parts),
0367 GFP_KERNEL);
0368 if (!sharpsl_nand_parts)
0369 return -ENOMEM;
0370
0371
0372 sharpsl_nand_parts[0].name = "smf";
0373 sharpsl_nand_parts[0].offset = le32_to_cpu(buf[0].start);
0374 sharpsl_nand_parts[0].size = le32_to_cpu(buf[0].end) -
0375 le32_to_cpu(buf[0].start);
0376
0377 sharpsl_nand_parts[1].name = "root";
0378 sharpsl_nand_parts[1].offset = le32_to_cpu(buf[1].start);
0379 sharpsl_nand_parts[1].size = le32_to_cpu(buf[1].end) -
0380 le32_to_cpu(buf[1].start);
0381
0382 sharpsl_nand_parts[2].name = "home";
0383 sharpsl_nand_parts[2].offset = le32_to_cpu(buf[2].start);
0384 sharpsl_nand_parts[2].size = le32_to_cpu(buf[2].end) -
0385 le32_to_cpu(buf[2].start);
0386
0387 *pparts = sharpsl_nand_parts;
0388 return SHARPSL_NAND_PARTS;
0389 }
0390
0391 static struct mtd_part_parser sharpsl_mtd_parser = {
0392 .parse_fn = sharpsl_parse_mtd_partitions,
0393 .name = "sharpslpart",
0394 };
0395 module_mtd_part_parser(sharpsl_mtd_parser);
0396
0397 MODULE_LICENSE("GPL");
0398 MODULE_AUTHOR("Andrea Adami <andrea.adami@gmail.com>");
0399 MODULE_DESCRIPTION("MTD partitioning for NAND flash on Sharp SL Series");