A memory controller enabling recovery of failed data units from non-volatile memory using two parity values, the memory controller comprising:
- input/output circuitry configured to:
- receive a plurality of user data units from a host device;
- and
- store the plurality of user data units in non-volatile memory communicatively coupled to the memory controller;
- and
- control circuitry configured to:
- calculate a first parity value for the plurality of user data units using a first parity calculation, the first parity calculation comprising a first series of operations;
- calculate a second parity value for the plurality of user data units using a second parity calculation, the second parity value being different from the first parity value, and the second parity calculation comprising a second series of operations;
- store, using the input/output circuitry, the first parity value in a first parity data unit in the non-volatile memory and the second parity value in a second parity data unit in the non-volatile memory;
- enable recovery from a failure of up to two data units from among the plurality of user data units and the first and second parity data units by recalculating the value of the failed data units based on one or more of the first parity data unit, the second parity data unit, and the values of other user data units of the plurality of data units;
- retrieve, using the input/output circuitry, the plurality of user data units from the non-volatile memory;
- decode the retrieved user data units using an ECC decoder;
- determine, for each retrieved user data unit, whether the respective user data unit was successfully decoded;
- in response to determining that the respective user data unit was not successfully decoded:
- retrieve, using the input/output circuitry, the first parity data unit from the non-volatile memory, and
- retrieve, using the input/output circuitry, the second parity data unit from the non-volatile memory;
- and
- in response to determining that a second user data unit of the plurality of user data units was also not successfully decoded:
- calculate auxiliary first parity data using the first parity calculation,
- calculate auxiliary second parity data using the second parity calculation,
- calculate a first scaling factor for the auxiliary first parity data by dividing a primitive element of a finite field raised to a power corresponding to an index of the first user data unit by the sum of (a) the primitive element raised to the power corresponding to the index of the first user data unit and (b) the primitive element raised to a power corresponding to an index of the second user data unit,
- calculate a second scaling factor for the auxiliary second parity data by taking the inverse of one more than the primitive element raised to the power corresponding to the index of the second user data unit,
- recover the second user data unit based on the first parity data unit, the auxiliary first parity data, the first scaling factor, the second parity data unit, the auxiliary second parity data, and the second scaling factor, and
- recover the respective user data unit based on the recovered second user data unit, the first parity data unit, and the auxiliary first parity data.