/* locates, validates, and loads ecc data from `f->fd' */ static int load_ecc(fec_handle *f) { check(f); debug("size = %" PRIu64, f->data_size); uint64_t offset = f->data_size - FEC_BLOCKSIZE; if (parse_ecc(f, offset) == 0) { debug("found at %" PRIu64 " (start %" PRIu64 ")", offset, f->ecc.start); return 0; } return -1; }
static void ecc_test(NANDDriver *nandp, uint32_t block){ uint32_t corrupted; uint32_t byte, bit; const uint32_t ecclen = 28; uint32_t ecc_ref, ecc_broken; uint8_t op_status; ecc_result_t ecc_result = ECC_NO_ERROR; /* This test requires good block.*/ osalDbgCheck(!nandIsBad(nandp, block)); if (!is_erased(nandp, block)) nandErase(&NAND, block); pattern_fill(); /*** Correctable errors ***/ op_status = nandWritePageData(nandp, block, 0, nand_buf, nandp->config->page_data_size, &ecc_ref); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ nandReadPageData(nandp, block, 0, nand_buf, nandp->config->page_data_size, &ecc_broken); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_NO_ERROR == ecc_result); /* unexpected error */ /**/ byte = 0; bit = 7; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 1, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /**/ byte = 2047; bit = 0; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 2, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /**/ byte = 1027; bit = 3; invert_bit(nand_buf, byte, bit); op_status = nandWritePageData(nandp, block, 3, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, bit); ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */ osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */ /*** Uncorrectable error ***/ byte = 1027; invert_bit(nand_buf, byte, 3); invert_bit(nand_buf, byte, 4); op_status = nandWritePageData(nandp, block, 4, nand_buf, nandp->config->page_data_size, &ecc_broken); osalDbgCheck(0 == (op_status & 1)); /* operation failed */ invert_bit(nand_buf, byte, 3); invert_bit(nand_buf, byte, 4); ecc_result = parse_ecc(28, ecc_ref, ecc_broken, &corrupted); osalDbgCheck(ECC_UNCORRECTABLE_ERROR == ecc_result); /* This error must be NOT correctable */ /*** make clean ***/ nandErase(&NAND, block); }