/** * \brief Read the data and/or spare of a page of a NAND Flash chip, and verify * that the data is valid using the ECC information contained in the spare. If * one buffer pointer is 0, the corresponding area is not saved. * * \param ecc Pointer to an nand_flash_ecc instance. * \param block Number of block to read from. * \param page Number of page to read inside given block. * \param data Data area buffer. * \param spare Spare area buffer. * * \return 0 if the data has been read and is valid; otherwise returns either * NAND_COMMON_ERROR_CORRUPTEDDATA or ... */ uint32_t nand_flash_ecc_read_page(const struct nand_flash_ecc *ecc, uint16_t block, uint16_t page, uint8_t *data, uint8_t *spare) { uint32_t error; uint8_t hamming_code[NAND_COMMON_MAX_SPARE_ECC_BYTES]; uint8_t spare_buffer[NAND_COMMON_MAX_PAGE_SPARE_SIZE]; uint16_t page_data_size = nand_flash_model_get_page_data_size(MODEL(ecc)); /* if no buffer provided, use a temp one */ if (!spare) { spare = spare_buffer; } memset(spare, 0xFF, NAND_COMMON_MAX_PAGE_SPARE_SIZE); /* Start by reading the spare and the data */ nand_flash_raw_read_page(RAW(ecc), block, page, data, spare); /* Retrieve ECC information from page and verify the data */ nand_flash_spare_scheme_read_ecc(nand_flash_model_get_scheme(MODEL(ecc)), spare, hamming_code); error = hamming_verify_256x(data, page_data_size, hamming_code); if (error && (error != HAMMING_ERROR_SINGLE_BIT)) { return NAND_COMMON_ERROR_CORRUPTEDDATA; } return 0; }
/** * \brief Reads the data and/or spare of a page of a NANDFLASH chip, and verify that * the data is valid using the ECC information contained in the spare. If one * buffer pointer is 0, the corresponding area is not saved. * \param nand Pointer to an EccNandFlash instance. * \param block Number of block to read from. * \param page Number of page to read inside given block. * \param data Data area buffer. * \param spare Spare area buffer. * \return 0 if the data has been read and is valid; otherwise returns either * NAND_ERROR_CORRUPTEDDATA or ... */ static uint8_t ecc_read_page_with_swecc(const struct _nand_flash *nand, uint16_t block, uint16_t page, void *data, void *spare) { uint8_t error; uint8_t hamming[NAND_MAX_SPARE_ECC_BYTES]; uint16_t page_data_size = nand_model_get_page_data_size(&nand->model); uint8_t page_spare_size = nand_model_get_page_spare_size(&nand->model); /* Start by reading the spare data */ error = nand_raw_read_page(nand, block, page, NULL, spare_buf); if (error) { trace_error("nand_ecc_read_page: Failed to read page\r\n"); return error; } /* Then reading the data */ error = nand_raw_read_page(nand, block, page, data, NULL); if (error) { trace_error("nand_ecc_read_page: Failed to read page\r\n"); return error; } /* Retrieve ECC information from page and verify the data */ nand_spare_scheme_read_ecc(nand_model_get_scheme(&nand->model), spare_buf, hamming); error = hamming_verify_256x(data, page_data_size, hamming); if (error && (error != HAMMING_ERROR_SINGLEBIT)) { trace_error("nand_ecc_read_page: at B%d.P%d Unrecoverable data\r\n", block, page); return NAND_ERROR_CORRUPTEDDATA; } if (spare) { memcpy(spare, spare_buf, page_spare_size); } return 0; }