aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd/nftlmount.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-06-22 22:11:56 -0400
committerJeff Garzik <jeff@garzik.org>2006-06-22 22:11:56 -0400
commit71d530cd1b6d97094481002a04c77fea1c8e1c22 (patch)
treee786da7145d83c19a594adf76ed90d52c51058b1 /drivers/mtd/nftlmount.c
parentd7a80dad2fe19a2b8c119c8e9cba605474a75a2b (diff)
parentd588fcbe5a7ba8bba2cebf7799ab2d573717a806 (diff)
Merge branch 'master' into upstream
Conflicts: drivers/scsi/libata-core.c drivers/scsi/libata-scsi.c include/linux/pci_ids.h
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 3b104ebb219..067262ee8df 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -33,6 +33,11 @@
char nftlmountrev[]="$Revision: 1.41 $";
+extern int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
+ size_t *retlen, uint8_t *buf);
+extern int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
+ size_t *retlen, uint8_t *buf);
+
/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
* various device information of the NFTL partition and Bad Unit Table. Update
* the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
@@ -45,6 +50,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
size_t retlen;
u8 buf[SECTORSIZE];
struct NFTLMediaHeader *mh = &nftl->MediaHdr;
+ struct mtd_info *mtd = nftl->mbd.mtd;
unsigned int i;
/* Assume logical EraseSize == physical erasesize for starting the scan.
@@ -65,7 +71,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
/* Check for ANAND header first. Then can whinge if it's found but later
checks fail */
- ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf);
+ ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
+ &retlen, buf);
/* We ignore ret in case the ECC of the MediaHeader is invalid
(which is apparently acceptable) */
if (retlen != SECTORSIZE) {
@@ -90,8 +97,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
}
/* To be safer with BIOS, also use erase mark as discriminant */
- if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
- 8, &retlen, (char *)&h1) < 0)) {
+ if ((ret = nftl_read_oob(mtd, block * nftl->EraseSize +
+ SECTORSIZE + 8, 8, &retlen,
+ (char *)&h1) < 0)) {
printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
continue;
@@ -109,8 +117,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
}
/* Finally reread to check ECC */
- if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE,
- &retlen, buf, (char *)&oob, NULL) < 0)) {
+ if ((ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
+ &retlen, buf) < 0)) {
printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
continue;
@@ -228,9 +236,9 @@ device is already correct.
The new DiskOnChip driver already scanned the bad block table. Just query it.
if ((i & (SECTORSIZE - 1)) == 0) {
/* read one sector for every SECTORSIZE of blocks */
- if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize +
- i + SECTORSIZE, SECTORSIZE, &retlen, buf,
- (char *)&oob, NULL)) < 0) {
+ if ((ret = mtd->read(nftl->mbd.mtd, block * nftl->EraseSize +
+ i + SECTORSIZE, SECTORSIZE, &retlen,
+ buf)) < 0) {
printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
ret);
kfree(nftl->ReplUnitTable);
@@ -268,18 +276,22 @@ static int memcmpb(void *a, int c, int n)
static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
int check_oob)
{
- int i;
- size_t retlen;
u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize];
+ struct mtd_info *mtd = nftl->mbd.mtd;
+ size_t retlen;
+ int i;
for (i = 0; i < len; i += SECTORSIZE) {
- if (MTD_READECC(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf, &buf[SECTORSIZE], &nftl->oobinfo) < 0)
+ if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
return -1;
if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
return -1;
if (check_oob) {
- if (memcmpb(buf + SECTORSIZE, 0xff, nftl->mbd.mtd->oobsize) != 0)
+ if(nftl_read_oob(mtd, address, mtd->oobsize,
+ &retlen, &buf[SECTORSIZE]) < 0)
+ return -1;
+ if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0)
return -1;
}
address += SECTORSIZE;
@@ -301,10 +313,11 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
unsigned int nb_erases, erase_mark;
struct nftl_uci1 uci;
struct erase_info *instr = &nftl->instr;
+ struct mtd_info *mtd = nftl->mbd.mtd;
/* Read the Unit Control Information #1 for Wear-Leveling */
- if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
- 8, &retlen, (char *)&uci) < 0)
+ if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8,
+ 8, &retlen, (char *)&uci) < 0)
goto default_uci1;
erase_mark = le16_to_cpu ((uci.EraseMark | uci.EraseMark1));
@@ -321,7 +334,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
instr->mtd = nftl->mbd.mtd;
instr->addr = block * nftl->EraseSize;
instr->len = nftl->EraseSize;
- MTD_ERASE(nftl->mbd.mtd, instr);
+ mtd->erase(mtd, instr);
if (instr->state == MTD_ERASE_FAILED) {
printk("Error while formatting block %d\n", block);
@@ -343,8 +356,8 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
goto fail;
uci.WearInfo = le32_to_cpu(nb_erases);
- if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&uci) < 0)
+ if (nftl_write_oob(mtd, block * nftl->EraseSize + SECTORSIZE +
+ 8, 8, &retlen, (char *)&uci) < 0)
goto fail;
return 0;
fail:
@@ -365,6 +378,7 @@ fail:
* case. */
static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block)
{
+ struct mtd_info *mtd = nftl->mbd.mtd;
unsigned int block, i, status;
struct nftl_bci bci;
int sectors_per_block;
@@ -374,8 +388,9 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
block = first_block;
for (;;) {
for (i = 0; i < sectors_per_block; i++) {
- if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE,
- 8, &retlen, (char *)&bci) < 0)
+ if (nftl_read_oob(mtd,
+ block * nftl->EraseSize + i * SECTORSIZE,
+ 8, &retlen, (char *)&bci) < 0)
status = SECTOR_IGNORE;
else
status = bci.Status | bci.Status1;
@@ -394,9 +409,10 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
/* sector not free actually : mark it as SECTOR_IGNORE */
bci.Status = SECTOR_IGNORE;
bci.Status1 = SECTOR_IGNORE;
- MTD_WRITEOOB(nftl->mbd.mtd,
- block * nftl->EraseSize + i * SECTORSIZE,
- 8, &retlen, (char *)&bci);
+ nftl_write_oob(mtd, block *
+ nftl->EraseSize +
+ i * SECTORSIZE, 8,
+ &retlen, (char *)&bci);
}
break;
default:
@@ -481,13 +497,14 @@ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
* 1. */
static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
{
+ struct mtd_info *mtd = nftl->mbd.mtd;
struct nftl_uci1 h1;
unsigned int erase_mark;
size_t retlen;
/* check erase mark. */
- if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0)
+ if (nftl_read_oob(mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
+ &retlen, (char *)&h1) < 0)
return -1;
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)
h1.EraseMark = cpu_to_le16(ERASE_MARK);
h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
h1.WearInfo = cpu_to_le32(0);
- if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0)
+ if (nftl_write_oob(mtd,
+ block * nftl->EraseSize + SECTORSIZE + 8, 8,
+ &retlen, (char *)&h1) < 0)
return -1;
} else {
#if 0
@@ -513,8 +531,8 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
SECTORSIZE, 0) != 0)
return -1;
- if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i,
- 16, &retlen, buf) < 0)
+ if (nftl_read_oob(mtd, block * nftl->EraseSize + i,
+ 16, &retlen, buf) < 0)
return -1;
if (i == SECTORSIZE) {
/* skip erase mark */
@@ -540,11 +558,12 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
*/
static int get_fold_mark(struct NFTLrecord *nftl, unsigned int block)
{
+ struct mtd_info *mtd = nftl->mbd.mtd;
struct nftl_uci2 uci;
size_t retlen;
- if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
- 8, &retlen, (char *)&uci) < 0)
+ if (nftl_read_oob(mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
+ 8, &retlen, (char *)&uci) < 0)
return 0;
return le16_to_cpu((uci.FoldMark | uci.FoldMark1));
@@ -558,6 +577,7 @@ int NFTL_mount(struct NFTLrecord *s)
int chain_length, do_format_chain;
struct nftl_uci0 h0;
struct nftl_uci1 h1;
+ struct mtd_info *mtd = s->mbd.mtd;
size_t retlen;
/* search for NFTL MediaHeader and Spare NFTL Media Header */
@@ -582,10 +602,13 @@ int NFTL_mount(struct NFTLrecord *s)
for (;;) {
/* read the block header. If error, we format the chain */
- if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
- &retlen, (char *)&h0) < 0 ||
- MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0) {
+ if (nftl_read_oob(mtd,
+ block * s->EraseSize + 8, 8,
+ &retlen, (char *)&h0) < 0 ||
+ nftl_read_oob(mtd,
+ block * s->EraseSize +
+ SECTORSIZE + 8, 8,
+ &retlen, (char *)&h1) < 0) {
s->ReplUnitTable[block] = BLOCK_NIL;
do_format_chain = 1;
break;