static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) { struct onenand_chip *this = mtd->priv; struct bbm_info *bbm = this->bbm; int i, j, numblocks, len, scanlen; 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"); len = 2; /* We need only read few bytes from the OOB area */ scanlen = ooblen = 0; readlen = bd->len; /* chip == -1 case only */ /* Note that numblocks is 2 * (real numblocks) here; * see i += 2 below as it makses shifting and masking less painful */ numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1); startblock = 0; from = 0; ops.mode = MTD_OOB_PLACE; 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++) { /* No need to read pages fully, * just read required OOB bytes */ ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops); /* 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, (unsigned int) from); mtd->ecc_stats.badblocks++; break; } } i += 2; if (FLEXONENAND(this)) { rgn = flexonenand_region(mtd, from); from += mtd->eraseregions[rgn].erasesize; } else from += (1 << bbm->bbt_erase_shift); }
static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) { struct onenand_chip *this = mtd->priv; struct bbm_info *bbm = this->bbm; int i, j, numblocks, len, scanlen; 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"); len = 2; scanlen = ooblen = 0; readlen = bd->len; numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1); startblock = 0; from = 0; ops.mode = MTD_OOB_PLACE; 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++) { ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops); 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, (unsigned int) from); mtd->ecc_stats.badblocks++; break; } } i += 2; if (FLEXONENAND(this)) { rgn = flexonenand_region(mtd, from); from += mtd->eraseregions[rgn].erasesize; } else from += (1 << bbm->bbt_erase_shift); }