X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmtd%2Fonenand%2Fonenand_bbt.c;h=52509f1ae9ab4747a80f14304b05231c9466ced1;hb=b4857aa90105ea85bf029f8eb99e72fbadc0e2d0;hp=5a610ee5ea8b3fc381da19104112f227ce82e176;hpb=6a40ef62c4300e9f606deef0a4618cbc4b514a51;p=u-boot diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 5a610ee5ea..52509f1ae9 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; @@ -135,7 +140,6 @@ static inline int onenand_memory_bbt(struct mtd_info *mtd, { unsigned char data_buf[MAX_ONENAND_PAGESIZE]; - bd->options &= ~NAND_BBT_SCANEMPTY; return create_bbt(mtd, data_buf, bd, -1); } @@ -153,12 +157,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 +196,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 +263,3 @@ int onenand_default_bbt(struct mtd_info *mtd) return onenand_scan_bbt(mtd, bbm->badblock_pattern); } - -#endif /* CFG_CMD_ONENAND */