int elm_decode_bch_error(int bch_type, char *ecc_calc, unsigned int *err_loc) { u8 ecc_data[28] = {0}; u32 reg_val; int i, err_no; rotate_ecc_bytes(ecc_calc, ecc_data); elm_load_syndrome(bch_type, ecc_data); elm_start_processing(); wait_for_completion(&elm_completion); reg_val = elm_read_reg(ELM_LOCATION_STATUS); if (reg_val & ECC_CORRECTABLE_MASK) { err_no = reg_val & ECC_NB_ERRORS_MASK; for (i = 0; i < err_no; i++) { reg_val = elm_read_reg(ELM_ERROR_LOCATION_0 + i * 4); err_loc[i] = reg_val; } return err_no; } return -EINVAL; }
int elm_decode_bch_error(int bch_type, char *ecc_calc, unsigned int *err_loc) { u8 ecc_data[28] = {0}; u32 reg_val; int i, err_no; /* input calculated ECC syndrome to ELM engine */ switch (bch_type) { case ECC_TYPE_BCH16: rotate_ecc_bytes(ECC_BYTES_BCH16, ecc_calc, ecc_data); elm_load_syndrome(ECC_BYTES_BCH16, ecc_data); break; case ECC_TYPE_BCH8: rotate_ecc_bytes(ECC_BYTES_BCH8, ecc_calc, ecc_data); elm_load_syndrome(ECC_BYTES_BCH8, ecc_data); break; case ECC_TYPE_BCH4: rotate_ecc_bytes(ECC_BYTES_BCH4, ecc_calc, ecc_data); elm_load_syndrome(ECC_BYTES_BCH4, ecc_data); break; default: return -EINVAL; } /* start elm processing */ reg_val = elm_read_reg(ELM_SYNDROME_FRAGMENT_6); reg_val |= ELM_SYNDROME_VALID; elm_write_reg(ELM_SYNDROME_FRAGMENT_6, reg_val); wait_for_completion(&elm_completion); reg_val = elm_read_reg(ELM_LOCATION_STATUS); if (reg_val & ECC_CORRECTABLE_MASK) { err_no = reg_val & ECC_NB_ERRORS_MASK; for (i = 0; i < err_no; i++) { reg_val = elm_read_reg(ELM_ERROR_LOCATION_0 + i * 4); err_loc[i] = reg_val; } return err_no; } return -EINVAL; }