/** * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for * 256 byte block * * @dat: raw data * @ecc_code: buffer for ECC */ int nand_calculate_ecc(const uint8_t *dat, uint8_t *ecc_code) { uint8_t idx, reg1, reg2, reg3; int j; /* Initialize variables */ reg1 = reg2 = reg3 = 0; ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; /* Build up column parity */ for(j = 0; j < 256; j++) { /* Get CP0 - CP5 from table */ idx = nand_ecc_precalc_table[dat[j]]; reg1 ^= (idx & 0x3f); /* All bit XOR = 1 ? */ if (idx & 0x40) { reg3 ^= (uint8_t) j; reg2 ^= ~((uint8_t) j); } } /* Create non-inverted ECC code from line parity */ nand_trans_result(reg2, reg3, ecc_code); /* Calculate final ECC code */ ecc_code[0] = ~ecc_code[0]; ecc_code[1] = ~ecc_code[1]; ecc_code[2] = ((~reg1) << 2) | 0x03; return 0; }
/** * nand_calculate_ecc - Calc 3 byte ECC code for 512 byte block * @dat: raw data * @ecc_code: buffer for ECC */ int nand_calculate_ecc(const U8 *dat, U8 *ecc_code) { U16 idx, reg1, reg2, reg3; int j; /* Initialize variables */ reg1 = reg2 = reg3 = 0; ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; /* Build up column parity */ for(j = 0; j < 512; j++) { /* Get CP0 - CP5 from table */ idx = (U16) nand_ecc_precalc_table[dat[j]]; reg1 ^= (idx & 0x3f); /* All bit XOR = 1 ? */ if (idx & 0x40) { reg3 ^= (U16) j; reg2 ^= ~((U16) j); reg3 &= 0x1FF ; reg2 &= 0x1FF ; } } /* Populate the ECC Codes from the parity bits in reg1-3 */ nand_trans_result(reg1, reg2, reg3, ecc_code); return 0; }