diff options
Diffstat (limited to 'drivers/mtd/inftlmount.c')
-rw-r--r-- | drivers/mtd/inftlmount.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index 43fdc9433882..8f6006f1a519 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c | |||
@@ -43,6 +43,11 @@ | |||
43 | 43 | ||
44 | char inftlmountrev[]="$Revision: 1.18 $"; | 44 | char inftlmountrev[]="$Revision: 1.18 $"; |
45 | 45 | ||
46 | extern int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len, | ||
47 | size_t *retlen, uint8_t *buf); | ||
48 | extern int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len, | ||
49 | size_t *retlen, uint8_t *buf); | ||
50 | |||
46 | /* | 51 | /* |
47 | * find_boot_record: Find the INFTL Media Header and its Spare copy which | 52 | * find_boot_record: Find the INFTL Media Header and its Spare copy which |
48 | * contains the various device information of the INFTL partition and | 53 | * contains the various device information of the INFTL partition and |
@@ -57,6 +62,7 @@ static int find_boot_record(struct INFTLrecord *inftl) | |||
57 | unsigned int i, block; | 62 | unsigned int i, block; |
58 | u8 buf[SECTORSIZE]; | 63 | u8 buf[SECTORSIZE]; |
59 | struct INFTLMediaHeader *mh = &inftl->MediaHdr; | 64 | struct INFTLMediaHeader *mh = &inftl->MediaHdr; |
65 | struct mtd_info *mtd = inftl->mbd.mtd; | ||
60 | struct INFTLPartition *ip; | 66 | struct INFTLPartition *ip; |
61 | size_t retlen; | 67 | size_t retlen; |
62 | 68 | ||
@@ -80,8 +86,8 @@ static int find_boot_record(struct INFTLrecord *inftl) | |||
80 | * Check for BNAND header first. Then whinge if it's found | 86 | * Check for BNAND header first. Then whinge if it's found |
81 | * but later checks fail. | 87 | * but later checks fail. |
82 | */ | 88 | */ |
83 | ret = MTD_READ(inftl->mbd.mtd, block * inftl->EraseSize, | 89 | ret = mtd->read(mtd, block * inftl->EraseSize, |
84 | SECTORSIZE, &retlen, buf); | 90 | SECTORSIZE, &retlen, buf); |
85 | /* We ignore ret in case the ECC of the MediaHeader is invalid | 91 | /* We ignore ret in case the ECC of the MediaHeader is invalid |
86 | (which is apparently acceptable) */ | 92 | (which is apparently acceptable) */ |
87 | if (retlen != SECTORSIZE) { | 93 | if (retlen != SECTORSIZE) { |
@@ -106,8 +112,9 @@ static int find_boot_record(struct INFTLrecord *inftl) | |||
106 | } | 112 | } |
107 | 113 | ||
108 | /* To be safer with BIOS, also use erase mark as discriminant */ | 114 | /* To be safer with BIOS, also use erase mark as discriminant */ |
109 | if ((ret = MTD_READOOB(inftl->mbd.mtd, block * inftl->EraseSize + | 115 | if ((ret = inftl_read_oob(mtd, block * inftl->EraseSize + |
110 | SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0)) { | 116 | SECTORSIZE + 8, 8, &retlen, |
117 | (char *)&h1) < 0)) { | ||
111 | printk(KERN_WARNING "INFTL: ANAND header found at " | 118 | printk(KERN_WARNING "INFTL: ANAND header found at " |
112 | "0x%x in mtd%d, but OOB data read failed " | 119 | "0x%x in mtd%d, but OOB data read failed " |
113 | "(err %d)\n", block * inftl->EraseSize, | 120 | "(err %d)\n", block * inftl->EraseSize, |
@@ -123,8 +130,8 @@ static int find_boot_record(struct INFTLrecord *inftl) | |||
123 | memcpy(mh, buf, sizeof(struct INFTLMediaHeader)); | 130 | memcpy(mh, buf, sizeof(struct INFTLMediaHeader)); |
124 | 131 | ||
125 | /* Read the spare media header at offset 4096 */ | 132 | /* Read the spare media header at offset 4096 */ |
126 | MTD_READ(inftl->mbd.mtd, block * inftl->EraseSize + 4096, | 133 | mtd->read(mtd, block * inftl->EraseSize + 4096, |
127 | SECTORSIZE, &retlen, buf); | 134 | SECTORSIZE, &retlen, buf); |
128 | if (retlen != SECTORSIZE) { | 135 | if (retlen != SECTORSIZE) { |
129 | printk(KERN_WARNING "INFTL: Unable to read spare " | 136 | printk(KERN_WARNING "INFTL: Unable to read spare " |
130 | "Media Header\n"); | 137 | "Media Header\n"); |
@@ -233,7 +240,7 @@ static int find_boot_record(struct INFTLrecord *inftl) | |||
233 | */ | 240 | */ |
234 | instr->addr = ip->Reserved0 * inftl->EraseSize; | 241 | instr->addr = ip->Reserved0 * inftl->EraseSize; |
235 | instr->len = inftl->EraseSize; | 242 | instr->len = inftl->EraseSize; |
236 | MTD_ERASE(inftl->mbd.mtd, instr); | 243 | mtd->erase(mtd, instr); |
237 | } | 244 | } |
238 | if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) { | 245 | if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) { |
239 | printk(KERN_WARNING "INFTL: Media Header " | 246 | printk(KERN_WARNING "INFTL: Media Header " |
@@ -350,21 +357,21 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address, | |||
350 | int len, int check_oob) | 357 | int len, int check_oob) |
351 | { | 358 | { |
352 | u8 buf[SECTORSIZE + inftl->mbd.mtd->oobsize]; | 359 | u8 buf[SECTORSIZE + inftl->mbd.mtd->oobsize]; |
360 | struct mtd_info *mtd = inftl->mbd.mtd; | ||
353 | size_t retlen; | 361 | size_t retlen; |
354 | int i; | 362 | int i; |
355 | 363 | ||
356 | DEBUG(MTD_DEBUG_LEVEL3, "INFTL: check_free_sectors(inftl=%p," | ||
357 | "address=0x%x,len=%d,check_oob=%d)\n", inftl, | ||
358 | address, len, check_oob); | ||
359 | |||
360 | for (i = 0; i < len; i += SECTORSIZE) { | 364 | for (i = 0; i < len; i += SECTORSIZE) { |
361 | if (MTD_READECC(inftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &inftl->oobinfo) < 0) | 365 | if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf)) |
362 | return -1; | 366 | return -1; |
363 | if (memcmpb(buf, 0xff, SECTORSIZE) != 0) | 367 | if (memcmpb(buf, 0xff, SECTORSIZE) != 0) |
364 | return -1; | 368 | return -1; |
365 | 369 | ||
366 | if (check_oob) { | 370 | if (check_oob) { |
367 | if (memcmpb(buf + SECTORSIZE, 0xff, inftl->mbd.mtd->oobsize) != 0) | 371 | if(inftl_read_oob(mtd, address, mtd->oobsize, |
372 | &retlen, &buf[SECTORSIZE]) < 0) | ||
373 | return -1; | ||
374 | if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0) | ||
368 | return -1; | 375 | return -1; |
369 | } | 376 | } |
370 | address += SECTORSIZE; | 377 | address += SECTORSIZE; |
@@ -387,6 +394,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block) | |||
387 | size_t retlen; | 394 | size_t retlen; |
388 | struct inftl_unittail uci; | 395 | struct inftl_unittail uci; |
389 | struct erase_info *instr = &inftl->instr; | 396 | struct erase_info *instr = &inftl->instr; |
397 | struct mtd_info *mtd = inftl->mbd.mtd; | ||
390 | int physblock; | 398 | int physblock; |
391 | 399 | ||
392 | DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p," | 400 | DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p," |
@@ -404,8 +412,9 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block) | |||
404 | /* Erase one physical eraseblock at a time, even though the NAND api | 412 | /* Erase one physical eraseblock at a time, even though the NAND api |
405 | allows us to group them. This way we if we have a failure, we can | 413 | allows us to group them. This way we if we have a failure, we can |
406 | mark only the failed block in the bbt. */ | 414 | mark only the failed block in the bbt. */ |
407 | for (physblock = 0; physblock < inftl->EraseSize; physblock += instr->len, instr->addr += instr->len) { | 415 | for (physblock = 0; physblock < inftl->EraseSize; |
408 | MTD_ERASE(inftl->mbd.mtd, instr); | 416 | physblock += instr->len, instr->addr += instr->len) { |
417 | mtd->erase(inftl->mbd.mtd, instr); | ||
409 | 418 | ||
410 | if (instr->state == MTD_ERASE_FAILED) { | 419 | if (instr->state == MTD_ERASE_FAILED) { |
411 | printk(KERN_WARNING "INFTL: error while formatting block %d\n", | 420 | printk(KERN_WARNING "INFTL: error while formatting block %d\n", |
@@ -414,10 +423,10 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block) | |||
414 | } | 423 | } |
415 | 424 | ||
416 | /* | 425 | /* |
417 | * Check the "freeness" of Erase Unit before updating metadata. | 426 | * Check the "freeness" of Erase Unit before updating metadata. |
418 | * FixMe: is this check really necessary? Since we have check the | 427 | * FixMe: is this check really necessary? Since we have check |
419 | * return code after the erase operation. | 428 | * the return code after the erase operation. |
420 | */ | 429 | */ |
421 | if (check_free_sectors(inftl, instr->addr, instr->len, 1) != 0) | 430 | if (check_free_sectors(inftl, instr->addr, instr->len, 1) != 0) |
422 | goto fail; | 431 | goto fail; |
423 | } | 432 | } |
@@ -429,8 +438,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block) | |||
429 | uci.Reserved[2] = 0; | 438 | uci.Reserved[2] = 0; |
430 | uci.Reserved[3] = 0; | 439 | uci.Reserved[3] = 0; |
431 | instr->addr = block * inftl->EraseSize + SECTORSIZE * 2; | 440 | instr->addr = block * inftl->EraseSize + SECTORSIZE * 2; |
432 | if (MTD_WRITEOOB(inftl->mbd.mtd, instr->addr + | 441 | if (inftl_write_oob(mtd, instr->addr + 8, 8, &retlen, (char *)&uci) < 0) |
433 | 8, 8, &retlen, (char *)&uci) < 0) | ||
434 | goto fail; | 442 | goto fail; |
435 | return 0; | 443 | return 0; |
436 | fail: | 444 | fail: |
@@ -549,6 +557,7 @@ void INFTL_dumpVUchains(struct INFTLrecord *s) | |||
549 | 557 | ||
550 | int INFTL_mount(struct INFTLrecord *s) | 558 | int INFTL_mount(struct INFTLrecord *s) |
551 | { | 559 | { |
560 | struct mtd_info *mtd = s->mbd.mtd; | ||
552 | unsigned int block, first_block, prev_block, last_block; | 561 | unsigned int block, first_block, prev_block, last_block; |
553 | unsigned int first_logical_block, logical_block, erase_mark; | 562 | unsigned int first_logical_block, logical_block, erase_mark; |
554 | int chain_length, do_format_chain; | 563 | int chain_length, do_format_chain; |
@@ -607,10 +616,11 @@ int INFTL_mount(struct INFTLrecord *s) | |||
607 | break; | 616 | break; |
608 | } | 617 | } |
609 | 618 | ||
610 | if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, | 619 | if (inftl_read_oob(mtd, block * s->EraseSize + 8, |
611 | 8, &retlen, (char *)&h0) < 0 || | 620 | 8, &retlen, (char *)&h0) < 0 || |
612 | MTD_READOOB(s->mbd.mtd, block * s->EraseSize + | 621 | inftl_read_oob(mtd, block * s->EraseSize + |
613 | 2 * SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) { | 622 | 2 * SECTORSIZE + 8, 8, &retlen, |
623 | (char *)&h1) < 0) { | ||
614 | /* Should never happen? */ | 624 | /* Should never happen? */ |
615 | do_format_chain++; | 625 | do_format_chain++; |
616 | break; | 626 | break; |