Hi All:

It seems that the ECC correction is broken on the Linux with the 4xx NDFC driver.
It uses the SMC order when reading the ECC code. 2-1-3

static int ndfc_calculate_ecc(struct mtd_info *mtd,
                              const u_char *dat, u_char *ecc_code)
{
        struct ndfc_controller *ndfc = &ndfc_ctrl;
        uint32_t ecc;
        uint8_t *p = (uint8_t *)&ecc;

        wmb();
        ecc = in_be32(ndfc->ndfcbase + NDFC_ECC);
        /* The NDFC uses Smart Media (SMC) bytes order */
        ecc_code[0] = p[2];
        ecc_code[1] = p[1];
        ecc_code[2] = p[3];

        return 0;
}

However, when in the correction function, the byte address order is again reverses
causing incorrect byte location.

                 * performace it does not make any difference
                 */
                if (eccsize_mult == 1)
byte_addr = (addressbits[b0] << 4) + addressbits[b1]; >>>> The above really should be byte_addr = (addressbits[b1] << 4) + addressbits[b0];

                else
                        byte_addr = (addressbits[b2 & 0x3] << 8) +
(addressbits[b1] << 4) + addressbits[b0];
                bit_addr = addressbits[b2 >> 2];
                /* flip the bit */
                buf[byte_addr] ^= (1 << bit_addr);
                printk(KERN_INFO "Corrected b[0] 0x%x b[1]0x%x\n", b0, b1);
printk(KERN_INFO "cal ecc b[0] 0x%x b[1]0x%x\n", calc_ecc[0] , calc_ecc[1]); printk(KERN_INFO "read ecc b[0] 0x%x b[1]0x%x\n", read_ecc[0] , read_ecc[1]);
                return 1;

I see other boards using SMC as well, can someone comment on the change I am proposing. Should I change the correction algorithm or the calculate function? If the later is preferred
it would mean the change must be pushed in both U-Boot and Linux.

Feng Kan
AMCC Software
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to