[PATCH] mtd: nand: support BENAND (Built-in ECC NAND)

Vikram Narayanan vikram186 at gmail.com
Wed Feb 13 12:14:37 EST 2013


On 2/12/2013 5:55 AM, katsuki.uwatoko at toshiba.co.jp wrote:
> This enables support for BENAND, which is an SLC NAND flash solution
> with embedded error correction code (ECC), currently supports only
> 128bytes OOB type.
>
> In the read sequence, "status read command" is executed to check the
> ECC status after read data. If bitflips occur, these are
> automatically corrected by BENAND and the status indicates the result.
>
> The write sequence is the same as raw write and the ECC data are
> automatically written to OOB by BENAND.

Couple of comments. Not related to the functionality though :)

> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index 1a03b7f..2b0c178 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -43,6 +43,7 @@
>   #include <linux/mtd/nand.h>
>   #include <linux/mtd/nand_ecc.h>
>   #include <linux/mtd/nand_bch.h>
> +#include <linux/mtd/nand_benand.h>
>   #include <linux/interrupt.h>
>   #include <linux/bitops.h>
>   #include <linux/leds.h>
> @@ -3076,6 +3077,11 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
>   		extid >>= 2;
>   		/* Get buswidth information */
>   		*busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
> +
> +		/* check BENAND (embedded ECC) */
> +		if (id_data[0] == NAND_MFR_TOSHIBA &&
> +		    (id_data[4] & 1 << 7))

Can the (1 << 7) be made as some macro, with an understandable name?

> +			nand_benand_setupecc(mtd, &(chip->ecc.mode));
>   	}
>   }
>
> @@ -3530,6 +3536,25 @@ int nand_scan_tail(struct mtd_info *mtd)
>   			chip->ecc.bytes * 8 / fls(8 * chip->ecc.size);
>   		break;
>
> +	case NAND_ECC_BENAND:
> +		if (!mtd_nand_has_benand()) {

Can IS_ENABLED be used here instead?

> +			pr_warn("CONFIG_MTD_BENAND not enabled\n");
> +			BUG();

Should you really BUG here?

> +		}
> +
> +		chip->ecc.read_page = nand_read_page_benand;
> +		chip->ecc.write_page = nand_write_page_raw;
> +		chip->ecc.read_page_raw = nand_read_page_raw;
> +		chip->ecc.write_page_raw = nand_write_page_raw;
> +		chip->ecc.read_oob = nand_read_oob_std;
> +		chip->ecc.write_oob = nand_write_oob_std;
> +
> +		if (nand_benand_init(mtd)) {
> +			pr_warn("BENAND initialization failed!\n");
> +			BUG();
> +		}
> +		break;
> +
>   	case NAND_ECC_NONE:
>   		pr_warn("NAND_ECC_NONE selected by board driver. "
>   			   "This is not recommended!\n");
<snip>
> diff --git a/include/linux/mtd/nand_benand.h b/include/linux/mtd/nand_benand.h
> new file mode 100644
> index 0000000..ac043e5
> --- /dev/null
> +++ b/include/linux/mtd/nand_benand.h
> @@ -0,0 +1,47 @@
> +/*
> + * (C) Copyright TOSHIBA CORPORATION 2013
> + * All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file is the header for the NAND BENAND implementation.
> + */
> +
> +#ifndef __MTD_NAND_BENAND_H__
> +#define __MTD_NAND_BENAND_H__
> +
> +#if defined(CONFIG_MTD_NAND_BENAND)
> +
> +static inline int mtd_nand_has_benand(void) { return 1; }

If IS_ENABLED is used, the above would go off.

~Vikram



More information about the linux-mtd mailing list