// return valid index if found BMT, else return 0 static int load_bmt_data(int start, int pool_size) { int bmt_index = start + pool_size - 1; // find from the end phys_bmt_struct phys_table; int i; MSG(INIT, "[%s]: begin to search BMT from block 0x%x\n", __FUNCTION__, bmt_index); for (bmt_index = start + pool_size - 1; bmt_index >= start; bmt_index--) { if (nand_block_bad_bmt(OFFSET(bmt_index))) { MSG(INIT, "Skip bad block: %d\n", bmt_index); continue; } if (!nand_read_page_bmt(PAGE_ADDR(bmt_index), dat_buf, oob_buf)) { MSG(INIT, "Error found when read block %d\n", bmt_index); continue; } if (!match_bmt_signature(dat_buf, oob_buf)) { continue; } MSG(INIT, "Match bmt signature @ block: 0x%x\n", bmt_index); memcpy(&phys_table, dat_buf + MAIN_SIGNATURE_OFFSET, sizeof(phys_table)); if (!valid_bmt_data(&phys_table)) { MSG(INIT, "BMT data is not correct %d\n", bmt_index); continue; } else { bmt.mapped_count = phys_table.header.mapped_count; bmt.version = phys_table.header.version; // bmt.bad_count = phys_table.header.bad_count; memcpy(bmt.table, phys_table.table, bmt.mapped_count * sizeof(bmt_entry)); MSG(INIT, "bmt found at block: %d, mapped block: %d\n", bmt_index, bmt.mapped_count); for (i = 0; i < bmt.mapped_count; i++) { if (!nand_block_bad_bmt(OFFSET(bmt.table[i].bad_index))) { MSG(INIT, "block 0x%x is not mark bad, should be power lost last time\n", bmt.table[i].bad_index); mark_block_bad_bmt(OFFSET(bmt.table[i].bad_index)); } } return bmt_index; } } MSG(INIT, "bmt block not found!\n"); return 0; }
// return valid index if found BMT, else return 0 static int load_bmt_data(int start, int pool_size) { int bmt_index = start + pool_size - 1; // find from the end int i; MSG("begin to search BMT from block %d \n", bmt_index); for (bmt_index = start + pool_size - 1; bmt_index >= start; bmt_index--) { if (nand_block_bad_bmt(OFFSET(bmt_index), BAD_BLOCK_RAW) || nand_block_bad_bmt(OFFSET(bmt_index), BMT_BADBLOCK_GENERATE_LATER)) { MSG("Skip bad block: %d \n", bmt_index); continue; } if (nand_read_page_bmt(PAGE_ADDR(bmt_index), dat_buf, oob_buf)) { MSG("Error found when read block: %d\n", bmt_index); continue; } if (!match_bmt_signature(dat_buf, oob_buf)) { continue; } MSG("Match bmt signature @ block: %d\n", bmt_index); memcpy(&lbd_phys_table, dat_buf + MAIN_SIGNATURE_OFFSET, sizeof(lbd_phys_table)); if (!valid_bmt_data(&lbd_phys_table)) { MSG("BMT data is not correct: %d\n", bmt_index); continue; } else { bmt.mapped_count = lbd_phys_table.header.mapped_count; bmt.version = lbd_phys_table.header.version; memcpy(bmt.table, lbd_phys_table.table, bmt.mapped_count * sizeof(bmt_entry)); MSG("bmt found at block: %d, mapped block: %d\n", bmt_index, bmt.mapped_count); for (i = 0; i < bmt.mapped_count; i++) { if (!nand_block_bad_bmt(OFFSET(bmt.table[i].bad_index), BAD_BLOCK_RAW)) { MSG("block %d is not mark bad, should be power lost last time\n", bmt.table[i].bad_index); mark_block_bad_bmt(OFFSET(bmt.table[i].bad_index), BAD_BLOCK_RAW); } } return bmt_index; } } MSG("bmt not found!\n"); return 0; }