at91sam9260ek: nand-ecc-mode = "none": flasherase stops Linux

This forum is for users of Microchip MPUs and who are interested in using Linux OS.

Moderator: nferre

mmanzel
Posts: 17
Joined: Mon May 25, 2020 10:42 am

at91sam9260ek: nand-ecc-mode = "none": flasherase stops Linux

Mon Jul 06, 2020 10:22 am

I would like to switch off ecc for my new nand-chip in Linux.
I use: Linux version 4.8.6 (gcc version 8.3.0 , Buildroot 2019.11)

If I select:
nand-ecc-mode = "none"
in the dts file for the at91sam9260ek then:
flash_erase /dev/mtd3 0 0
stops Linux (interrupts still work but all shells do not work anymore).

The same command with nand-ecc-mode = "soft" (in at91sam9260ek.dts) works fine.

I tryed to add some printk-messages into the function nand_erase() (in nand_base.c)
to find the origin, but no message comes (after flash_erase ...) to the serial debug terminal anymore.

As the system stops so completely I do not know how to get the information out of it where the
problem sits.

In u-boot I could use ecc_mode = NAND_ECC_NONE; and it works fine.
Here nand erase 0x140000 0x300000 does what I expect it to do.

I should add the used nand: Micron MT29F2G08ABAGAWP
I attached the description. (It is too big, so it wasn't attached.)

Does someone have a hint where or who to look for the origin?

Thank you.
Last edited by mmanzel on Tue Jul 07, 2020 6:12 pm, edited 1 time in total.
mmanzel
Posts: 17
Joined: Mon May 25, 2020 10:42 am

Re: at91sam9260ek: nand-ecc-mode = "none": flasherase stops Linux

Wed Jul 08, 2020 1:37 pm

I think I could find the problem:

With setting nand-ecc-mode = "none" in the device tree
in nand_base.c: ecc->mode becomes NAND_ECC_NONE.

In nand_scan_tail() in case NAND_ECC_NONE: we find:
ecc->bytes = 0;

a bit later:
ecc->total = ecc->steps * ecc->bytes; //With bytes = 0 --> total = 0

in nand_ooblayout_ecc_lp() we find:
oobregion->length = ecc->total; //thus length = 0

The problem arises in mtdchar.c in shrink_ecclayout() with the construction:

for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) {
u32 eccpos;

ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
if (ret < 0) {
if (ret != -ERANGE)
return ret;

break;
}

eccpos = oobregion.offset;
for (; i < MTD_MAX_ECCPOS_ENTRIES &&
eccpos < oobregion.offset + oobregion.length; i++) {
to->eccpos = eccpos++;
to->eccbytes++;
}
}

In the second for-loop we will never reach i++,
because eccpos is from the beginning = oobregion.offset + oobregion.length,
because length = 0.

We stay in the loop and as we are in a module Linux stops.

Return to “LINUX”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 4 guests