Problem using orion_nand.

Jaap de Wolff jaap at de-wolff.org
Fri Jul 20 18:16:34 EDT 2012


Hello,

I am trying to create a working kernel for a LS-WXL Buffalo NAS.
This contains a Kirkwood Feroceon (Kirkwood: MV88F6281-A1) processor,
with buildin support for a NAND device. The board actually contains a
512 Mb Nand.
In the kirkwood sources is already support for this nand chip, and it is
working on several hw boards.
However, whenever I load the driver, my system stops.
I did try it with linux 2.6.32.1, 2.6.32.59, 3.0.36, 3.2.23. 3.4.4, and
with debian kernels 2.6.32-31 and 2.6.32-45. Nice detail is that even
with the latest kernel supplied  by the manufacturer it is not able to
access the nand from linux. However the system is booting from nand.

I am creating the kernel using crosscompilation on a debian wheezy
machine, using gcc version 4.4.5-8 (g++-4.4-arm-linux-gnueabi)

I did build it with both 
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- 
and 
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CFLAGS="-march=armv5te
-mfloat-abi=soft -marm" 

options.
I also tried with and  without dma enabled.

Anyhow, with almost the latest kernel, I decided to dig into the code to
find out what was really the problem. I did use netconsole, and put the
nand modules apart from the modules.
I wait until fully booted, and then load the module using insmod.

In the NAND modules I put some print statements, to look what was
happening. The result is unbelievable. It looks like there is a
recursive function call. 
My logging when I do an 
insmod orion_nand.ko is:

orion_nand_probe: starting ***
orion_nand_probe: Resource allocated ***
orion_nand_probe: chip_delay 25 ***
orion_nand_probe: starting platform_set_drvdata. ***
orion_nand_probe: starting nand_scan. ***
nand_scan : starting . ***
nand_scan_ident: starting  ***
nand_scan_ident: starting nand_set_defaults ***
nand_scan_ident: starting nand_get_flash_type ***
nand_get_flash_type: starting ***
nand_get_flash_type: starting  cmdfunc(NAND_CMD_RESET) ***
orion_nand_cmd_ctrl: starting ***
orion_nand_cmd_ctrl: writeb to c8a0c001 ***
orion_nand_cmd_ctrl: starting ***
orion_nand_cmd_ctrl: starting ***
orion_nand_cmd_ctrl: writeb to c8a0c001 ***
orion_nand_cmd_ctrl: starting ***
---- And then the system is frozen ----
As you can see in code below, after the line:
nand_get_flash_type: starting  cmdfunc(NAND_CMD_RESET) ***
I only expect one time orion_nand_cmd_ctrl: starting ***, before I
expect the next log line from nand_get_flash_type.
And I see it four times.

Anyone with a hint/ clue?

Relevant parts of code are:
>From orion_nand.c:
static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned
int ctrl)
{
	struct nand_chip *nc = mtd->priv;
	struct orion_nand_data *board = nc->priv;
	u32 offs;
	pr_info("%s: starting ***", __func__);

	if (cmd == NAND_CMD_NONE)
		return;

	if (ctrl & NAND_CLE)
		offs = (1 << board->cle);
	else if (ctrl & NAND_ALE)
		offs = (1 << board->ale);
	else
		return;

	if (nc->options & NAND_BUSWIDTH_16)
		offs <<= 1;
	pr_info("%s: writeb to %lx ***", __func__, (long)(nc->IO_ADDR_W +
offs));

	writeb(cmd, nc->IO_ADDR_W + offs);
}

from nand_base.c:
/*
 * Get the flash and manufacturer id and lookup if the type is
supported.
 */
static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
						  struct nand_chip *chip,
						  int busw,
						  int *maf_id, int *dev_id,
						  struct nand_flash_dev *type)
{
	int i, maf_idx;
	u8 id_data[8];
	int ret;

	pr_info("%s: starting ***", __func__);

	/* Select the device */
	chip->select_chip(mtd, 0);

	/*
	 * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
	 * after power-up.
	 */
	pr_info("%s: starting  cmdfunc(NAND_CMD_RESET) ***", __func__);
	chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);

	/* Send the command for reading device ID */
	pr_info("%s: starting  cmdfunc(NAND_CMD_READID) ***", __func__);
	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);







More information about the linux-mtd mailing list