/******************************************************************* * Reconstruct bmt, called when found bmt info doesn't match bad * block info in flash. * * Return NULL for failure *******************************************************************/ bmt_struct *reconstruct_bmt(bmt_struct * bmt) { int i; int index = system_block_count; unsigned short bad_index; // init everything in BMT struct bmt->version = BMT_VERSION; bmt->bad_count = 0; bmt->mapped_count = 0; memset(bmt->table, 0, bmt_block_count * sizeof(bmt_entry)); for (i = 0; i < bmt_block_count; i++, index++) { if (nand_block_bad_bmt(OFFSET(index), BAD_BLOCK_RAW) || nand_block_bad_bmt(OFFSET(index), BMT_BADBLOCK_GENERATE_LATER)) { MSG("Skip bad block: %d \n", index); continue; } nand_read_page_bmt(PAGE_ADDR(index), dat_buf, oob_buf); if ((bad_index = get_bad_index_from_oob(oob_buf)) >= system_block_count) { MSG("get bad index: 0x%x \n", bad_index); if (bad_index != 0xFFFF) MSG("Invalid bad index found in block: %d \n", index); continue; } MSG("Block 0x%x is mapped to bad block: 0x%x\n", index, bad_index); if (!nand_block_bad_bmt(OFFSET(bad_index), BAD_BLOCK_RAW)) { mark_block_bad_bmt(OFFSET(bad_index), BAD_BLOCK_RAW); MSG("block %d is not marked as bad, mark it\n", bad_index); } { // add mapping to BMT bmt->table[bmt->mapped_count].bad_index = bad_index; bmt->table[bmt->mapped_count].mapped_index = index; bmt->mapped_count++; } MSG("Add mapping: %d -> %d to BMT\n", bad_index, index); } MSG("Scan replace pool done, mapped block: %d\n", bmt->mapped_count); return bmt; }
/******************************************************************* * Reconstruct bmt, called when found bmt info doesn't match bad * block info in flash. * * Return NULL for failure *******************************************************************/ bmt_struct *reconstruct_bmt(bmt_struct * bmt) { int i; int index = system_block_count; unsigned short bad_index; int mapped; bmt->version = BMT_VERSION; bmt->bad_count = 0; bmt->mapped_count = 0; memset(bmt->table, 0, bmt_block_count * sizeof(bmt_entry)); for (i = 0; i < bmt_block_count; i++, index++) { if (nand_block_bad_bmt(OFFSET(index))) { MSG(INFO, "Skip bad block: 0x%x\n", index); continue; } nand_read_page_bmt(PAGE_ADDR(index), dat_buf, oob_buf); if ((bad_index = get_bad_index_from_oob(oob_buf)) >= system_block_count) { MSG(INIT, "get bad index: 0x%x\n", bad_index); if (bad_index != 0xFFFF) MSG(INIT, "Invalid bad index found in block 0x%x, bad index 0x%x\n", index, bad_index); continue; } MSG(INIT, "Block 0x%x is mapped to bad block: 0x%x\n", index, bad_index); if (!nand_block_bad_bmt(OFFSET(bad_index))) { MSG(INIT, "\tbut block 0x%x is not marked as bad, invalid mapping\n", bad_index); continue; // no need to erase here, it will be erased later when trying to write BMT } if ((mapped = is_block_mapped(bad_index)) >= 0) { MSG(INIT, "bad block 0x%x is mapped to 0x%x, should be caused by power lost, replace with one\n", bmt->table[mapped].bad_index, bmt->table[mapped].mapped_index); bmt->table[mapped].mapped_index = index; // use new one instead. } else { bmt->table[bmt->mapped_count].bad_index = bad_index; bmt->table[bmt->mapped_count].mapped_index = index; bmt->mapped_count++; } MSG(INIT, "Add mapping: 0x%x -> 0x%x to BMT\n", bad_index, index); } MSG(INIT, "Scan replace pool done, mapped block: %d\n", bmt->mapped_count); memset(oob_buf, 0xFF, sizeof(oob_buf)); fill_nand_bmt_buffer(bmt, dat_buf, oob_buf); if (!write_bmt_to_flash(dat_buf, oob_buf)) { MSG(INIT, "TRAGEDY: cannot find a place to write BMT!!!!\n"); } return bmt; }
/******************************************************************* * Reconstruct bmt, called when found bmt info doesn't match bad * block info in flash. * * Return NULL for failure *******************************************************************/ bmt_struct *reconstruct_bmt(bmt_struct * bmt) { int i; int index = system_block_count; unsigned short bad_index; int mapped; // init everything in BMT struct bmt->version = BMT_VERSION; bmt->bad_count = 0; bmt->mapped_count = 0; memset(bmt->table, 0, bmt_block_count * sizeof(bmt_entry)); for (i = 0; i < bmt_block_count; i++, index++) { if (nand_block_bad_bmt(OFFSET(index))) { // MSG(INIT, "Skip bad block: 0x%x\n", index); // bmt->bad_count++; continue; } // MSG(INIT, "read page: 0x%x\n", PAGE_ADDR(index)); nand_read_page_bmt(PAGE_ADDR(index), dat_buf, oob_buf); /* if (mt6573_nand_read_page_hw(PAGE_ADDR(index), dat_buf)) { MSG(INIT, "Error when read block %d\n", bmt_block_index); continue; } */ if ((bad_index = get_bad_index_from_oob(oob_buf)) >= system_block_count) { // MSG(INIT, "get bad index: 0x%x\n", bad_index); if (bad_index != 0xFFFF) MSG(INIT, "warning @ 0x%x\n", index); continue; } // MSG(INIT, "Block 0x%x is mapped to bad block: 0x%x\n", index, bad_index); if (!nand_block_bad_bmt(OFFSET(bad_index))) { // MSG(INIT, "\tbut block 0x%x is not marked as bad, invalid mapping\n", bad_index); continue; // no need to erase here, it will be erased later when trying to write BMT } if ( (mapped = is_block_mapped(bad_index)) >= 0) { // MSG(INIT, "bad block 0x%x is mapped to 0x%x, should be caused by power lost, replace with one\n", // bmt->table[mapped].bad_index, bmt->table[mapped].mapped_index); bmt->table[mapped].mapped_index = index; // use new one instead. } else { // add mapping to BMT bmt->table[bmt->mapped_count].bad_index = bad_index; bmt->table[bmt->mapped_count].mapped_index = index; bmt->mapped_count++; } MSG(INIT, "Add mapping: 0x%x -> 0x%x to BMT\n", bad_index, index); } MSG(INIT, "Scan replace pool done, mapped block: %d\n", bmt->mapped_count); // dump_bmt_info(bmt); // fill NAND BMT buffer memset(oob_buf, 0xFF, sizeof(oob_buf)); fill_nand_bmt_buffer(bmt, dat_buf, oob_buf); // write BMT back if (!write_bmt_to_flash(dat_buf, oob_buf)) { MSG(INIT, "TRAGEDY\n"); } return bmt; }