X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmtd%2Fonenand%2Fonenand_bbt.c;h=0267c2c5c90a8b7f8b0bba69422638e625c22c0c;hb=97eeae1a0735fc17351f10b9978e966392badedc;hp=5a610ee5ea8b3fc381da19104112f227ce82e176;hpb=4985ca5af3767ffe13ea96e1dc26f88c81084414;p=u-boot diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 5a610ee5ea..0267c2c5c9 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -3,7 +3,7 @@ * * Bad Block Table support for the OneNAND driver * - * Copyright(c) 2005-2007 Samsung Electronics + * Copyright(c) 2005-2008 Samsung Electronics * Kyungmin Park * * TODO: @@ -15,10 +15,7 @@ */ #include - -#ifdef CONFIG_CMD_ONENAND - -#include +#include #include #include #include @@ -71,6 +68,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf, int startblock; loff_t from; size_t readlen, ooblen; + struct mtd_oob_ops ops; + int rgn; printk(KERN_INFO "Scanning device for bad blocks\n"); @@ -84,30 +83,31 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf, /* Note that numblocks is 2 * (real numblocks) here; * see i += 2 below as it makses shifting and masking less painful */ - numblocks = mtd->size >> (bbm->bbt_erase_shift - 1); + numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1); startblock = 0; from = 0; + ops.mode = MTD_OPS_PLACE_OOB; + ops.ooblen = readlen; + ops.oobbuf = buf; + ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0; + for (i = startblock; i < numblocks;) { int ret; for (j = 0; j < len; j++) { - size_t retlen; - /* No need to read pages fully, * just read required OOB bytes */ - ret = onenand_read_oob(mtd, - from + j * mtd->oobblock + - bd->offs, readlen, &retlen, - &buf[0]); - - if (ret && ret != -EAGAIN) { - printk("ret = %d\n", ret); - return ret; - } + ret = onenand_bbt_read_oob(mtd, + from + j * mtd->writesize + + bd->offs, &ops); - if (check_short_pattern - (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { + /* If it is a initial bad block, just ignore it */ + if (ret == ONENAND_BBT_READ_FATAL_ERROR) + return -EIO; + + if (ret || check_short_pattern + (&buf[j * scanlen], scanlen, mtd->writesize, bd)) { bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", i >> 1, @@ -116,7 +116,12 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf, } } i += 2; - from += (1 << bbm->bbt_erase_shift); + + if (FLEXONENAND(this)) { + rgn = flexonenand_region(mtd, from); + from += mtd->eraseregions[rgn].erasesize; + } else + from += (1 << bbm->bbt_erase_shift); } return 0; @@ -153,12 +158,12 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) uint8_t res; /* Get block number * 2 */ - block = (int)(offs >> (bbm->bbt_erase_shift - 1)); + block = (int) (onenand_block(this, offs) << 1); res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03; - DEBUG(MTD_DEBUG_LEVEL2, - "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n", - (unsigned int)offs, block >> 1, res); + MTDDEBUG (MTD_DEBUG_LEVEL2, + "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n", + (unsigned int)offs, block >> 1, res); switch ((int)res) { case 0x00: @@ -192,13 +197,11 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) struct bbm_info *bbm = this->bbm; int len, ret = 0; - len = mtd->size >> (this->erase_shift + 2); + len = this->chipsize >> (this->erase_shift + 2); /* Allocate memory (2bit per block) */ bbm->bbt = malloc(len); - if (!bbm->bbt) { - printk(KERN_ERR "onenand_scan_bbt: Out of memory\n"); + if (!bbm->bbt) return -ENOMEM; - } /* Clear the memory bad block table */ memset(bbm->bbt, 0x00, len); @@ -261,5 +264,3 @@ int onenand_default_bbt(struct mtd_info *mtd) return onenand_scan_bbt(mtd, bbm->badblock_pattern); } - -#endif /* CFG_CMD_ONENAND */