aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nftlmount.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nftlmount.c')
-rw-r--r--drivers/mtd/nftlmount.c91
1 files changed, 57 insertions, 34 deletions
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 3b104ebb219a..067262ee8df0 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -33,6 +33,11 @@
33 33
34char nftlmountrev[]="$Revision: 1.41 $"; 34char nftlmountrev[]="$Revision: 1.41 $";
35 35
36extern int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
37 size_t *retlen, uint8_t *buf);
38extern int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
39 size_t *retlen, uint8_t *buf);
40
36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the 41/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
37 * various device information of the NFTL partition and Bad Unit Table. Update 42 * various device information of the NFTL partition and Bad Unit Table. Update
38 * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[] 43 * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
@@ -45,6 +50,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
45 size_t retlen; 50 size_t retlen;
46 u8 buf[SECTORSIZE]; 51 u8 buf[SECTORSIZE];
47 struct NFTLMediaHeader *mh = &nftl->MediaHdr; 52 struct NFTLMediaHeader *mh = &nftl->MediaHdr;
53 struct mtd_info *mtd = nftl->mbd.mtd;
48 unsigned int i; 54 unsigned int i;
49 55
50 /* Assume logical EraseSize == physical erasesize for starting the scan. 56 /* Assume logical EraseSize == physical erasesize for starting the scan.
@@ -65,7 +71,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
65 71
66 /* Check for ANAND header first. Then can whinge if it's found but later 72 /* Check for ANAND header first. Then can whinge if it's found but later
67 checks fail */ 73 checks fail */
68 ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf); 74 ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
75 &retlen, buf);
69 /* We ignore ret in case the ECC of the MediaHeader is invalid 76 /* We ignore ret in case the ECC of the MediaHeader is invalid
70 (which is apparently acceptable) */ 77 (which is apparently acceptable) */
71 if (retlen != SECTORSIZE) { 78 if (retlen != SECTORSIZE) {
@@ -90,8 +97,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
90 } 97 }
91 98
92 /* To be safer with BIOS, also use erase mark as discriminant */ 99 /* To be safer with BIOS, also use erase mark as discriminant */
93 if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 100 if ((ret = nftl_read_oob(mtd, block * nftl->EraseSize +
94 8, &retlen, (char *)&h1) < 0)) { 101 SECTORSIZE + 8, 8, &retlen,
102 (char *)&h1) < 0)) {
95 printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n", 103 printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
96 block * nftl->EraseSize, nftl->mbd.mtd->index, ret); 104 block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
97 continue; 105 continue;
@@ -109,8 +117,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
109 } 117 }
110 118
111 /* Finally reread to check ECC */ 119 /* Finally reread to check ECC */
112 if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, 120 if ((ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
113 &retlen, buf, (char *)&oob, NULL) < 0)) { 121 &retlen, buf) < 0)) {
114 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n", 122 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
115 block * nftl->EraseSize, nftl->mbd.mtd->index, ret); 123 block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
116 continue; 124 continue;
@@ -228,9 +236,9 @@ device is already correct.
228The new DiskOnChip driver already scanned the bad block table. Just query it. 236The new DiskOnChip driver already scanned the bad block table. Just query it.
229 if ((i & (SECTORSIZE - 1)) == 0) { 237 if ((i & (SECTORSIZE - 1)) == 0) {
230 /* read one sector for every SECTORSIZE of blocks */ 238 /* read one sector for every SECTORSIZE of blocks */
231 if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize + 239 if ((ret = mtd->read(nftl->mbd.mtd, block * nftl->EraseSize +
232 i + SECTORSIZE, SECTORSIZE, &retlen, buf, 240 i + SECTORSIZE, SECTORSIZE, &retlen,
233 (char *)&oob, NULL)) < 0) { 241 buf)) < 0) {
234 printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n", 242 printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
235 ret); 243 ret);
236 kfree(nftl->ReplUnitTable); 244 kfree(nftl->ReplUnitTable);
@@ -268,18 +276,22 @@ static int memcmpb(void *a, int c, int n)
268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, 276static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
269 int check_oob) 277 int check_oob)
270{ 278{
271 int i;
272 size_t retlen;
273 u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize]; 279 u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize];
280 struct mtd_info *mtd = nftl->mbd.mtd;
281 size_t retlen;
282 int i;
274 283
275 for (i = 0; i < len; i += SECTORSIZE) { 284 for (i = 0; i < len; i += SECTORSIZE) {
276 if (MTD_READECC(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &nftl->oobinfo) < 0) 285 if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
277 return -1; 286 return -1;
278 if (memcmpb(buf, 0xff, SECTORSIZE) != 0) 287 if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
279 return -1; 288 return -1;
280 289
281 if (check_oob) { 290 if (check_oob) {
282 if (memcmpb(buf + SECTORSIZE, 0xff, nftl->mbd.mtd->oobsize) != 0) 291 if(nftl_read_oob(mtd, address, mtd->oobsize,
292 &retlen, &buf[SECTORSIZE]) < 0)
293 return -1;
294 if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
283 return -1; 295 return -1;
284 } 296 }
285 address += SECTORSIZE; 297 address += SECTORSIZE;
@@ -301,10 +313,11 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
301 unsigned int nb_erases, erase_mark; 313 unsigned int nb_erases, erase_mark;
302 struct nftl_uci1 uci; 314 struct nftl_uci1 uci;
303 struct erase_info *instr = &nftl->instr; 315 struct erase_info *instr = &nftl->instr;
316 struct mtd_info *mtd = nftl->mbd.mtd;
304 317
305 /* Read the Unit Control Information #1 for Wear-Leveling */ 318 /* Read the Unit Control Information #1 for Wear-Leveling */
306 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 319 if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8,
307 8, &retlen, (char *)&uci) < 0) 320 8, &retlen, (char *)&uci) < 0)
308 goto default_uci1; 321 goto default_uci1;
309 322
310 erase_mark = le16_to_cpu ((uci.EraseMark | uci.EraseMark1)); 323 erase_mark = le16_to_cpu ((uci.EraseMark | uci.EraseMark1));
@@ -321,7 +334,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
321 instr->mtd = nftl->mbd.mtd; 334 instr->mtd = nftl->mbd.mtd;
322 instr->addr = block * nftl->EraseSize; 335 instr->addr = block * nftl->EraseSize;
323 instr->len = nftl->EraseSize; 336 instr->len = nftl->EraseSize;
324 MTD_ERASE(nftl->mbd.mtd, instr); 337 mtd->erase(mtd, instr);
325 338
326 if (instr->state == MTD_ERASE_FAILED) { 339 if (instr->state == MTD_ERASE_FAILED) {
327 printk("Error while formatting block %d\n", block); 340 printk("Error while formatting block %d\n", block);
@@ -343,8 +356,8 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
343 goto fail; 356 goto fail;
344 357
345 uci.WearInfo = le32_to_cpu(nb_erases); 358 uci.WearInfo = le32_to_cpu(nb_erases);
346 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 359 if (nftl_write_oob(mtd, block * nftl->EraseSize + SECTORSIZE +
347 &retlen, (char *)&uci) < 0) 360 8, 8, &retlen, (char *)&uci) < 0)
348 goto fail; 361 goto fail;
349 return 0; 362 return 0;
350fail: 363fail:
@@ -365,6 +378,7 @@ fail:
365 * case. */ 378 * case. */
366static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block) 379static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block)
367{ 380{
381 struct mtd_info *mtd = nftl->mbd.mtd;
368 unsigned int block, i, status; 382 unsigned int block, i, status;
369 struct nftl_bci bci; 383 struct nftl_bci bci;
370 int sectors_per_block; 384 int sectors_per_block;
@@ -374,8 +388,9 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
374 block = first_block; 388 block = first_block;
375 for (;;) { 389 for (;;) {
376 for (i = 0; i < sectors_per_block; i++) { 390 for (i = 0; i < sectors_per_block; i++) {
377 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE, 391 if (nftl_read_oob(mtd,
378 8, &retlen, (char *)&bci) < 0) 392 block * nftl->EraseSize + i * SECTORSIZE,
393 8, &retlen, (char *)&bci) < 0)
379 status = SECTOR_IGNORE; 394 status = SECTOR_IGNORE;
380 else 395 else
381 status = bci.Status | bci.Status1; 396 status = bci.Status | bci.Status1;
@@ -394,9 +409,10 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
394 /* sector not free actually : mark it as SECTOR_IGNORE */ 409 /* sector not free actually : mark it as SECTOR_IGNORE */
395 bci.Status = SECTOR_IGNORE; 410 bci.Status = SECTOR_IGNORE;
396 bci.Status1 = SECTOR_IGNORE; 411 bci.Status1 = SECTOR_IGNORE;
397 MTD_WRITEOOB(nftl->mbd.mtd, 412 nftl_write_oob(mtd, block *
398 block * nftl->EraseSize + i * SECTORSIZE, 413 nftl->EraseSize +
399 8, &retlen, (char *)&bci); 414 i * SECTORSIZE, 8,
415 &retlen, (char *)&bci);
400 } 416 }
401 break; 417 break;
402 default: 418 default:
@@ -481,13 +497,14 @@ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
481 * 1. */ 497 * 1. */
482static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) 498static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
483{ 499{
500 struct mtd_info *mtd = nftl->mbd.mtd;
484 struct nftl_uci1 h1; 501 struct nftl_uci1 h1;
485 unsigned int erase_mark; 502 unsigned int erase_mark;
486 size_t retlen; 503 size_t retlen;
487 504
488 /* check erase mark. */ 505 /* check erase mark. */
489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 506 if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
490 &retlen, (char *)&h1) < 0) 507 &retlen, (char *)&h1) < 0)
491 return -1; 508 return -1;
492 509
493 erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1)); 510 erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
@@ -501,8 +518,9 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
501 h1.EraseMark = cpu_to_le16(ERASE_MARK); 518 h1.EraseMark = cpu_to_le16(ERASE_MARK);
502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK); 519 h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
503 h1.WearInfo = cpu_to_le32(0); 520 h1.WearInfo = cpu_to_le32(0);
504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 521 if (nftl_write_oob(mtd,
505 &retlen, (char *)&h1) < 0) 522 block * nftl->EraseSize + SECTORSIZE + 8, 8,
523 &retlen, (char *)&h1) < 0)
506 return -1; 524 return -1;
507 } else { 525 } else {
508#if 0 526#if 0
@@ -513,8 +531,8 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
513 SECTORSIZE, 0) != 0) 531 SECTORSIZE, 0) != 0)
514 return -1; 532 return -1;
515 533
516 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i, 534 if (nftl_read_oob(mtd, block * nftl->EraseSize + i,
517 16, &retlen, buf) < 0) 535 16, &retlen, buf) < 0)
518 return -1; 536 return -1;
519 if (i == SECTORSIZE) { 537 if (i == SECTORSIZE) {
520 /* skip erase mark */ 538 /* skip erase mark */
@@ -540,11 +558,12 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
540 */ 558 */
541static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block) 559static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block)
542{ 560{
561 struct mtd_info *mtd = nftl->mbd.mtd;
543 struct nftl_uci2 uci; 562 struct nftl_uci2 uci;
544 size_t retlen; 563 size_t retlen;
545 564
546 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, 565 if (nftl_read_oob(mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
547 8, &retlen, (char *)&uci) < 0) 566 8, &retlen, (char *)&uci) < 0)
548 return 0; 567 return 0;
549 568
550 return le16_to_cpu((uci.FoldMark | uci.FoldMark1)); 569 return le16_to_cpu((uci.FoldMark | uci.FoldMark1));
@@ -558,6 +577,7 @@ int NFTL_mount(struct NFTLrecord *s)
558 int chain_length, do_format_chain; 577 int chain_length, do_format_chain;
559 struct nftl_uci0 h0; 578 struct nftl_uci0 h0;
560 struct nftl_uci1 h1; 579 struct nftl_uci1 h1;
580 struct mtd_info *mtd = s->mbd.mtd;
561 size_t retlen; 581 size_t retlen;
562 582
563 /* search for NFTL MediaHeader and Spare NFTL Media Header */ 583 /* search for NFTL MediaHeader and Spare NFTL Media Header */
@@ -582,10 +602,13 @@ int NFTL_mount(struct NFTLrecord *s)
582 602
583 for (;;) { 603 for (;;) {
584 /* read the block header. If error, we format the chain */ 604 /* read the block header. If error, we format the chain */
585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, 605 if (nftl_read_oob(mtd,
586 &retlen, (char *)&h0) < 0 || 606 block * s->EraseSize + 8, 8,
587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, 607 &retlen, (char *)&h0) < 0 ||
588 &retlen, (char *)&h1) < 0) { 608 nftl_read_oob(mtd,
609 block * s->EraseSize +
610 SECTORSIZE + 8, 8,
611 &retlen, (char *)&h1) < 0) {
589 s->ReplUnitTable[block] = BLOCK_NIL; 612 s->ReplUnitTable[block] = BLOCK_NIL;
590 do_format_chain = 1; 613 do_format_chain = 1;
591 break; 614 break;