All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: David Woodhouse <dwmw2@infradead.org>,
	Brian Norris <computersforpeace@gmail.com>,
	linux-mtd@lists.infradead.org,
	Boris Brezillon <boris.brezillon@free-electrons.com>,
	Richard Weinberger <richard@nod.at>
Cc: Daniel Mack <daniel@zonque.org>,
	Haojian Zhuang <haojian.zhuang@gmail.com>,
	Robert Jarzmik <robert.jarzmik@free.fr>,
	Kukjin Kim <kgene@kernel.org>,
	Krzysztof Kozlowski <k.kozlowski@samsung.com>,
	linux-samsung-soc@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Ralf Baechle <ralf@linux-mips.org>,
	linux-mips@linux-mips.org,
	Nicolas Ferre <nicolas.ferre@atmel.com>,
	Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>,
	Alexandre Belloni <alexandre.belloni@free-electrons.com>,
	Wenyou Yang <wenyou.yang@atmel.com>,
	Josh Wu <rainyfeeling@outlook.com>,
	Ezequiel Garcia <ezequiel.garcia@free-electrons.com>,
	Maxime Ripard <maxime.ripard@free-electrons.com>,
	Chen-Yu Tsai <wens@csie.org>,
	linux-sunxi@googlegroups.com, Stefan Agner <stefan@agner.ch>,
	Kyungmin Park <kyungmin.park@samsung.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
	punnaiah choudary kalluri <punnaia@xilinx.com>,
	Priit Laes <plaes@plaes.org>, Kamal Dasu <kdasu.kdev@gmail.com>,
	bcm-kernel-feedback-list@broadcom.com, linux-api@vger.kernel.org,
	Harvey Hunt <harvey.hunt@imgtec.com>,
	Archit Taneja <architt@codeaurora.org>,
	Han Xu <b45815@freescale.com>,
	Huang Shijie <shijie.huang@arm.com>
Subject: Re: [PATCH v5 04/50] mtd: nand: atmel: use mtd_ooblayout_xxx() helpers where appropriate
Date: Wed, 13 Apr 2016 16:40:20 +0200	[thread overview]
Message-ID: <20160413164020.6c67b542@bbrezillon> (raw)
In-Reply-To: <1459354505-32551-5-git-send-email-boris.brezillon@free-electrons.com>

On Wed, 30 Mar 2016 18:14:19 +0200
Boris Brezillon <boris.brezillon@free-electrons.com> wrote:

> The mtd_ooblayout_xxx() helper functions have been added to avoid direct
> accesses to the ecclayout field, and thus ease for future reworks.
> Use these helpers in all places where the oobfree[] and eccpos[] arrays
> where directly accessed.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>

Tested with mtd_oobtest.ko on sama5d4ek.

Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com>

> ---
>  drivers/mtd/nand/atmel_nand.c | 48 ++++++++++++++++++++++++++-----------------
>  1 file changed, 29 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index 0b5da72..321d331 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -836,13 +836,16 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
>  			dev_dbg(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
>  				pos, bit_pos, err_byte, *(buf + byte_pos));
>  		} else {
> +			struct mtd_oob_region oobregion;
> +
>  			/* Bit flip in OOB area */
>  			tmp = sector_num * nand_chip->ecc.bytes
>  					+ (byte_pos - sector_size);
>  			err_byte = ecc[tmp];
>  			ecc[tmp] ^= (1 << bit_pos);
>  
> -			pos = tmp + nand_chip->ecc.layout->eccpos[0];
> +			mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +			pos = tmp + oobregion.offset;
>  			dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
>  				pos, bit_pos, err_byte, ecc[tmp]);
>  		}
> @@ -934,7 +937,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
>  	struct atmel_nand_host *host = nand_get_controller_data(chip);
>  	int eccsize = chip->ecc.size * chip->ecc.steps;
>  	uint8_t *oob = chip->oob_poi;
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
>  	uint32_t stat;
>  	unsigned long end_time;
>  	int bitflips = 0;
> @@ -956,7 +958,11 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
>  
>  	stat = pmecc_readl_relaxed(host->ecc, ISR);
>  	if (stat != 0) {
> -		bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
> +		struct mtd_oob_region oobregion;
> +
> +		mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +		bitflips = pmecc_correction(mtd, stat, buf,
> +					    &oob[oobregion.offset]);
>  		if (bitflips < 0)
>  			/* uncorrectable errors */
>  			return 0;
> @@ -970,8 +976,8 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
>  		int page)
>  {
>  	struct atmel_nand_host *host = nand_get_controller_data(chip);
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
> -	int i, j;
> +	struct mtd_oob_region oobregion = { };
> +	int i, j, section = 0;
>  	unsigned long end_time;
>  
>  	if (!host->nfc || !host->nfc->write_by_sram) {
> @@ -990,11 +996,12 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
>  
>  	for (i = 0; i < chip->ecc.steps; i++) {
>  		for (j = 0; j < chip->ecc.bytes; j++) {
> -			int pos;
> +			if (!oobregion.length)
> +				mtd_ooblayout_ecc(mtd, section++, &oobregion);
>  
> -			pos = i * chip->ecc.bytes + j;
> -			chip->oob_poi[eccpos[pos]] =
> +			chip->oob_poi[oobregion.offset++] =
>  				pmecc_readb_ecc_relaxed(host->ecc, i, j);
> +			oobregion.length--;
>  		}
>  	}
>  	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> @@ -1008,6 +1015,7 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
>  	struct atmel_nand_host *host = nand_get_controller_data(nand_chip);
>  	uint32_t val = 0;
>  	struct nand_ecclayout *ecc_layout;
> +	struct mtd_oob_region oobregion;
>  
>  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
>  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
> @@ -1059,9 +1067,10 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
>  
>  	ecc_layout = nand_chip->ecc.layout;
>  	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
> -	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
> +	mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +	pmecc_writel(host->ecc, SADDR, oobregion.offset);
>  	pmecc_writel(host->ecc, EADDR,
> -			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
> +		     oobregion.offset + ecc_layout->eccbytes - 1);
>  	/* See datasheet about PMECC Clock Control Register */
>  	pmecc_writel(host->ecc, CLK, 2);
>  	pmecc_writel(host->ecc, IDR, 0xff);
> @@ -1362,12 +1371,12 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  {
>  	int eccsize = chip->ecc.size;
>  	int eccbytes = chip->ecc.bytes;
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
>  	uint8_t *p = buf;
>  	uint8_t *oob = chip->oob_poi;
>  	uint8_t *ecc_pos;
>  	int stat;
>  	unsigned int max_bitflips = 0;
> +	struct mtd_oob_region oobregion = {};
>  
>  	/*
>  	 * Errata: ALE is incorrectly wired up to the ECC controller
> @@ -1385,19 +1394,20 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  	chip->read_buf(mtd, p, eccsize);
>  
>  	/* move to ECC position if needed */
> -	if (eccpos[0] != 0) {
> -		/* This only works on large pages
> -		 * because the ECC controller waits for
> -		 * NAND_CMD_RNDOUTSTART after the
> -		 * NAND_CMD_RNDOUT.
> -		 * anyway, for small pages, the eccpos[0] == 0
> +	mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +	if (oobregion.offset != 0) {
> +		/*
> +		 * This only works on large pages because the ECC controller
> +		 * waits for NAND_CMD_RNDOUTSTART after the NAND_CMD_RNDOUT.
> +		 * Anyway, for small pages, the first ECC byte is at offset
> +		 * 0 in the OOB area.
>  		 */
>  		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
> -				mtd->writesize + eccpos[0], -1);
> +			      mtd->writesize + oobregion.offset, -1);
>  	}
>  
>  	/* the ECC controller needs to read the ECC just after the data */
> -	ecc_pos = oob + eccpos[0];
> +	ecc_pos = oob + oobregion.offset;
>  	chip->read_buf(mtd, ecc_pos, eccbytes);
>  
>  	/* check if there's an error */



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

WARNING: multiple messages have this Message-ID (diff)
From: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
To: David Woodhouse <dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
	Brian Norris
	<computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Boris Brezillon
	<boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Richard Weinberger <richard-/L3Ra7n9ekc@public.gmane.org>
Cc: Daniel Mack <daniel-cYrQPVfZoowdnm+yROfE0A@public.gmane.org>,
	Haojian Zhuang
	<haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Robert Jarzmik <robert.jarzmik-GANU6spQydw@public.gmane.org>,
	Kukjin Kim <kgene-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Krzysztof Kozlowski
	<k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>,
	linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org,
	Nicolas Ferre
	<nicolas.ferre-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>,
	Jean-Christophe Plagniol-Villard
	<plagnioj-sclMFOaUSTBWk0Htik3J/w@public.gmane.org>,
	Alexandre Belloni
	<alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Wenyou Yang <wenyou.yang-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>,
	Josh Wu <rainyfeeling-1ViLX0X+lBJBDgjK7y7TUQ@public.gmane.org>,
	Ezequiel Garcia
	<ezequiel.garcia-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Maxime Ripard
	<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>,
	Kyungmin Park
	<kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	Greg Kroah-Hartman
	<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
	devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b@public.gmane.orglinux
Subject: Re: [PATCH v5 04/50] mtd: nand: atmel: use mtd_ooblayout_xxx() helpers where appropriate
Date: Wed, 13 Apr 2016 16:40:20 +0200	[thread overview]
Message-ID: <20160413164020.6c67b542@bbrezillon> (raw)
In-Reply-To: <1459354505-32551-5-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

On Wed, 30 Mar 2016 18:14:19 +0200
Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:

> The mtd_ooblayout_xxx() helper functions have been added to avoid direct
> accesses to the ecclayout field, and thus ease for future reworks.
> Use these helpers in all places where the oobfree[] and eccpos[] arrays
> where directly accessed.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Tested with mtd_oobtest.ko on sama5d4ek.

Tested-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

> ---
>  drivers/mtd/nand/atmel_nand.c | 48 ++++++++++++++++++++++++++-----------------
>  1 file changed, 29 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index 0b5da72..321d331 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -836,13 +836,16 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
>  			dev_dbg(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
>  				pos, bit_pos, err_byte, *(buf + byte_pos));
>  		} else {
> +			struct mtd_oob_region oobregion;
> +
>  			/* Bit flip in OOB area */
>  			tmp = sector_num * nand_chip->ecc.bytes
>  					+ (byte_pos - sector_size);
>  			err_byte = ecc[tmp];
>  			ecc[tmp] ^= (1 << bit_pos);
>  
> -			pos = tmp + nand_chip->ecc.layout->eccpos[0];
> +			mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +			pos = tmp + oobregion.offset;
>  			dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
>  				pos, bit_pos, err_byte, ecc[tmp]);
>  		}
> @@ -934,7 +937,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
>  	struct atmel_nand_host *host = nand_get_controller_data(chip);
>  	int eccsize = chip->ecc.size * chip->ecc.steps;
>  	uint8_t *oob = chip->oob_poi;
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
>  	uint32_t stat;
>  	unsigned long end_time;
>  	int bitflips = 0;
> @@ -956,7 +958,11 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
>  
>  	stat = pmecc_readl_relaxed(host->ecc, ISR);
>  	if (stat != 0) {
> -		bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
> +		struct mtd_oob_region oobregion;
> +
> +		mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +		bitflips = pmecc_correction(mtd, stat, buf,
> +					    &oob[oobregion.offset]);
>  		if (bitflips < 0)
>  			/* uncorrectable errors */
>  			return 0;
> @@ -970,8 +976,8 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
>  		int page)
>  {
>  	struct atmel_nand_host *host = nand_get_controller_data(chip);
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
> -	int i, j;
> +	struct mtd_oob_region oobregion = { };
> +	int i, j, section = 0;
>  	unsigned long end_time;
>  
>  	if (!host->nfc || !host->nfc->write_by_sram) {
> @@ -990,11 +996,12 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
>  
>  	for (i = 0; i < chip->ecc.steps; i++) {
>  		for (j = 0; j < chip->ecc.bytes; j++) {
> -			int pos;
> +			if (!oobregion.length)
> +				mtd_ooblayout_ecc(mtd, section++, &oobregion);
>  
> -			pos = i * chip->ecc.bytes + j;
> -			chip->oob_poi[eccpos[pos]] =
> +			chip->oob_poi[oobregion.offset++] =
>  				pmecc_readb_ecc_relaxed(host->ecc, i, j);
> +			oobregion.length--;
>  		}
>  	}
>  	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> @@ -1008,6 +1015,7 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
>  	struct atmel_nand_host *host = nand_get_controller_data(nand_chip);
>  	uint32_t val = 0;
>  	struct nand_ecclayout *ecc_layout;
> +	struct mtd_oob_region oobregion;
>  
>  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
>  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
> @@ -1059,9 +1067,10 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
>  
>  	ecc_layout = nand_chip->ecc.layout;
>  	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
> -	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
> +	mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +	pmecc_writel(host->ecc, SADDR, oobregion.offset);
>  	pmecc_writel(host->ecc, EADDR,
> -			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
> +		     oobregion.offset + ecc_layout->eccbytes - 1);
>  	/* See datasheet about PMECC Clock Control Register */
>  	pmecc_writel(host->ecc, CLK, 2);
>  	pmecc_writel(host->ecc, IDR, 0xff);
> @@ -1362,12 +1371,12 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  {
>  	int eccsize = chip->ecc.size;
>  	int eccbytes = chip->ecc.bytes;
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
>  	uint8_t *p = buf;
>  	uint8_t *oob = chip->oob_poi;
>  	uint8_t *ecc_pos;
>  	int stat;
>  	unsigned int max_bitflips = 0;
> +	struct mtd_oob_region oobregion = {};
>  
>  	/*
>  	 * Errata: ALE is incorrectly wired up to the ECC controller
> @@ -1385,19 +1394,20 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  	chip->read_buf(mtd, p, eccsize);
>  
>  	/* move to ECC position if needed */
> -	if (eccpos[0] != 0) {
> -		/* This only works on large pages
> -		 * because the ECC controller waits for
> -		 * NAND_CMD_RNDOUTSTART after the
> -		 * NAND_CMD_RNDOUT.
> -		 * anyway, for small pages, the eccpos[0] == 0
> +	mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +	if (oobregion.offset != 0) {
> +		/*
> +		 * This only works on large pages because the ECC controller
> +		 * waits for NAND_CMD_RNDOUTSTART after the NAND_CMD_RNDOUT.
> +		 * Anyway, for small pages, the first ECC byte is at offset
> +		 * 0 in the OOB area.
>  		 */
>  		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
> -				mtd->writesize + eccpos[0], -1);
> +			      mtd->writesize + oobregion.offset, -1);
>  	}
>  
>  	/* the ECC controller needs to read the ECC just after the data */
> -	ecc_pos = oob + eccpos[0];
> +	ecc_pos = oob + oobregion.offset;
>  	chip->read_buf(mtd, ecc_pos, eccbytes);
>  
>  	/* check if there's an error */



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

WARNING: multiple messages have this Message-ID (diff)
From: boris.brezillon@free-electrons.com (Boris Brezillon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 04/50] mtd: nand: atmel: use mtd_ooblayout_xxx() helpers where appropriate
Date: Wed, 13 Apr 2016 16:40:20 +0200	[thread overview]
Message-ID: <20160413164020.6c67b542@bbrezillon> (raw)
In-Reply-To: <1459354505-32551-5-git-send-email-boris.brezillon@free-electrons.com>

On Wed, 30 Mar 2016 18:14:19 +0200
Boris Brezillon <boris.brezillon@free-electrons.com> wrote:

> The mtd_ooblayout_xxx() helper functions have been added to avoid direct
> accesses to the ecclayout field, and thus ease for future reworks.
> Use these helpers in all places where the oobfree[] and eccpos[] arrays
> where directly accessed.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>

Tested with mtd_oobtest.ko on sama5d4ek.

Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com>

> ---
>  drivers/mtd/nand/atmel_nand.c | 48 ++++++++++++++++++++++++++-----------------
>  1 file changed, 29 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index 0b5da72..321d331 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -836,13 +836,16 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
>  			dev_dbg(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
>  				pos, bit_pos, err_byte, *(buf + byte_pos));
>  		} else {
> +			struct mtd_oob_region oobregion;
> +
>  			/* Bit flip in OOB area */
>  			tmp = sector_num * nand_chip->ecc.bytes
>  					+ (byte_pos - sector_size);
>  			err_byte = ecc[tmp];
>  			ecc[tmp] ^= (1 << bit_pos);
>  
> -			pos = tmp + nand_chip->ecc.layout->eccpos[0];
> +			mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +			pos = tmp + oobregion.offset;
>  			dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
>  				pos, bit_pos, err_byte, ecc[tmp]);
>  		}
> @@ -934,7 +937,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
>  	struct atmel_nand_host *host = nand_get_controller_data(chip);
>  	int eccsize = chip->ecc.size * chip->ecc.steps;
>  	uint8_t *oob = chip->oob_poi;
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
>  	uint32_t stat;
>  	unsigned long end_time;
>  	int bitflips = 0;
> @@ -956,7 +958,11 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
>  
>  	stat = pmecc_readl_relaxed(host->ecc, ISR);
>  	if (stat != 0) {
> -		bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
> +		struct mtd_oob_region oobregion;
> +
> +		mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +		bitflips = pmecc_correction(mtd, stat, buf,
> +					    &oob[oobregion.offset]);
>  		if (bitflips < 0)
>  			/* uncorrectable errors */
>  			return 0;
> @@ -970,8 +976,8 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
>  		int page)
>  {
>  	struct atmel_nand_host *host = nand_get_controller_data(chip);
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
> -	int i, j;
> +	struct mtd_oob_region oobregion = { };
> +	int i, j, section = 0;
>  	unsigned long end_time;
>  
>  	if (!host->nfc || !host->nfc->write_by_sram) {
> @@ -990,11 +996,12 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
>  
>  	for (i = 0; i < chip->ecc.steps; i++) {
>  		for (j = 0; j < chip->ecc.bytes; j++) {
> -			int pos;
> +			if (!oobregion.length)
> +				mtd_ooblayout_ecc(mtd, section++, &oobregion);
>  
> -			pos = i * chip->ecc.bytes + j;
> -			chip->oob_poi[eccpos[pos]] =
> +			chip->oob_poi[oobregion.offset++] =
>  				pmecc_readb_ecc_relaxed(host->ecc, i, j);
> +			oobregion.length--;
>  		}
>  	}
>  	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
> @@ -1008,6 +1015,7 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
>  	struct atmel_nand_host *host = nand_get_controller_data(nand_chip);
>  	uint32_t val = 0;
>  	struct nand_ecclayout *ecc_layout;
> +	struct mtd_oob_region oobregion;
>  
>  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
>  	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
> @@ -1059,9 +1067,10 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
>  
>  	ecc_layout = nand_chip->ecc.layout;
>  	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
> -	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
> +	mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +	pmecc_writel(host->ecc, SADDR, oobregion.offset);
>  	pmecc_writel(host->ecc, EADDR,
> -			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
> +		     oobregion.offset + ecc_layout->eccbytes - 1);
>  	/* See datasheet about PMECC Clock Control Register */
>  	pmecc_writel(host->ecc, CLK, 2);
>  	pmecc_writel(host->ecc, IDR, 0xff);
> @@ -1362,12 +1371,12 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  {
>  	int eccsize = chip->ecc.size;
>  	int eccbytes = chip->ecc.bytes;
> -	uint32_t *eccpos = chip->ecc.layout->eccpos;
>  	uint8_t *p = buf;
>  	uint8_t *oob = chip->oob_poi;
>  	uint8_t *ecc_pos;
>  	int stat;
>  	unsigned int max_bitflips = 0;
> +	struct mtd_oob_region oobregion = {};
>  
>  	/*
>  	 * Errata: ALE is incorrectly wired up to the ECC controller
> @@ -1385,19 +1394,20 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
>  	chip->read_buf(mtd, p, eccsize);
>  
>  	/* move to ECC position if needed */
> -	if (eccpos[0] != 0) {
> -		/* This only works on large pages
> -		 * because the ECC controller waits for
> -		 * NAND_CMD_RNDOUTSTART after the
> -		 * NAND_CMD_RNDOUT.
> -		 * anyway, for small pages, the eccpos[0] == 0
> +	mtd_ooblayout_ecc(mtd, 0, &oobregion);
> +	if (oobregion.offset != 0) {
> +		/*
> +		 * This only works on large pages because the ECC controller
> +		 * waits for NAND_CMD_RNDOUTSTART after the NAND_CMD_RNDOUT.
> +		 * Anyway, for small pages, the first ECC byte is at offset
> +		 * 0 in the OOB area.
>  		 */
>  		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
> -				mtd->writesize + eccpos[0], -1);
> +			      mtd->writesize + oobregion.offset, -1);
>  	}
>  
>  	/* the ECC controller needs to read the ECC just after the data */
> -	ecc_pos = oob + eccpos[0];
> +	ecc_pos = oob + oobregion.offset;
>  	chip->read_buf(mtd, ecc_pos, eccbytes);
>  
>  	/* check if there's an error */



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

  reply	other threads:[~2016-04-13 14:40 UTC|newest]

Thread overview: 217+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-30 16:14 [PATCH v5 00/52] mtd: rework ECC layout definition Boris Brezillon
2016-03-30 16:14 ` Boris Brezillon
2016-03-30 16:14 ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 01/50] mtd: add mtd_ooblayout_xxx() helper functions Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 02/50] mtd: use mtd_ooblayout_xxx() helpers where appropriate Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 03/50] mtd: nand: core: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 04/50] mtd: nand: atmel: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-04-13 14:40   ` Boris Brezillon [this message]
2016-04-13 14:40     ` Boris Brezillon
2016-04-13 14:40     ` Boris Brezillon
2016-04-13 15:28   ` Nicolas Ferre
2016-04-13 15:28     ` Nicolas Ferre
2016-04-13 15:28     ` Nicolas Ferre
2016-04-13 15:28     ` Nicolas Ferre
2016-04-13 15:53   ` [PATCH v6 " Boris Brezillon
2016-04-13 15:53     ` Boris Brezillon
2016-04-13 16:05     ` Nicolas Ferre
2016-04-13 16:05       ` Nicolas Ferre
2016-03-30 16:14 ` [PATCH v5 05/50] mtd: nand: fsl_ifc: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 06/50] mtd: nand: gpmi: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 07/50] mtd: nand: lpc32xx: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 08/50] mtd: nand: omap2: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 09/50] mtd: nand: qcom: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 10/50] mtd: onenand: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 11/50] mtd: add mtd_set_ecclayout() helper function Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 12/50] mtd: use mtd_set_ecclayout() where appropriate Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 13/50] mtd: nand: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 14/50] mtd: onenand: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 15/50] mtd: docg3: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 16/50] mtd: create an mtd_ooblayout_ops struct to ease ECC layout definition Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 17/50] mtd: docg3: switch to mtd_ooblayout_ops Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 18/50] mtd: nand: implement the default mtd_ooblayout_ops Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 19/50] mtd: nand: bch: switch to mtd_ooblayout_ops Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 20/50] mtd: nand: sharpsl: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 21/50] mtd: nand: jz4740: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 19:17   ` Lars-Peter Clausen
2016-03-30 19:17     ` Lars-Peter Clausen
2016-03-30 19:17     ` Lars-Peter Clausen
2016-03-30 16:14 ` [PATCH v5 22/50] mtd: nand: atmel: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-04-13 14:41   ` Boris Brezillon
2016-04-13 14:41     ` Boris Brezillon
2016-04-13 14:41     ` Boris Brezillon
2016-04-13 15:15   ` Nicolas Ferre
2016-04-13 15:15     ` Nicolas Ferre
2016-04-13 15:15     ` Nicolas Ferre
2016-04-13 15:15     ` Nicolas Ferre
2016-03-30 16:14 ` [PATCH v5 23/50] mtd: nand: bf5xx: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 24/50] mtd: nand: brcm: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 25/50] mtd: nand: cafe: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 26/50] mtd: nand: davinci: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 27/50] mtd: nand: denali: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 28/50] mtd: nand: diskonchip: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 29/50] mtd: nand: docg4: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 30/50] mtd: nand: fsl_elbc: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 31/50] mtd: nand: fsl_ifc: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 32/50] mtd: nand: fsmc: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 33/50] mtd: nand: fsmc: get rid of the fsmc_nand_eccplace struct Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 34/50] mtd: nand: gpmi: switch to mtd_ooblayout_ops Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
     [not found]   ` <1459354505-32551-35-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-04-12 22:27     ` Han Xu
2016-04-12 22:31       ` Boris Brezillon
2016-04-12 22:31         ` Boris Brezillon
2016-04-12 22:31         ` Boris Brezillon
2016-04-12 22:31         ` Boris Brezillon
2016-04-12 22:41         ` Han Xu
2016-03-30 16:14 ` [PATCH v5 35/50] mtd: nand: hisi504: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 36/50] mtd: nand: jz4780: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 37/50] mtd: nand: lpc32xx: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 38/50] mtd: nand: mxc: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 39/50] mtd: nand: omap2: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-04-18 14:32   ` Roger Quadros
2016-04-18 14:32     ` Roger Quadros
2016-04-18 14:32     ` Roger Quadros
2016-04-18 14:32     ` Roger Quadros
2016-04-18 15:05     ` Boris Brezillon
2016-04-18 15:05       ` Boris Brezillon
2016-04-18 15:05       ` Boris Brezillon
2016-04-18 15:05       ` Boris Brezillon
2016-04-19 10:28       ` Roger Quadros
2016-04-19 10:28         ` Roger Quadros
2016-04-19 10:28         ` Roger Quadros
2016-04-19 10:28         ` Roger Quadros
2016-04-19 11:22         ` Boris Brezillon
2016-04-19 11:22           ` Boris Brezillon
2016-04-19 11:22           ` Boris Brezillon
2016-04-19 11:22           ` Boris Brezillon
2016-04-19 12:30           ` Roger Quadros
2016-04-19 12:30             ` Roger Quadros
2016-04-19 12:30             ` Roger Quadros
2016-04-19 12:30             ` Roger Quadros
2016-04-19 12:41             ` Boris Brezillon
2016-04-19 12:41               ` Boris Brezillon
2016-04-19 12:41               ` Boris Brezillon
2016-04-19 12:41               ` Boris Brezillon
2016-04-19 12:49               ` Roger Quadros
2016-04-19 12:49                 ` Roger Quadros
2016-04-19 12:49                 ` Roger Quadros
2016-04-19 12:49                 ` Roger Quadros
2016-03-30 16:14 ` [PATCH v5 40/50] mtd: nand: pxa3xx: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 41/50] mtd: nand: s3c2410: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 42/50] mtd: nand: sh_flctl: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 43/50] mtd: nand: sm_common: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14 ` [PATCH v5 44/50] mtd: nand: sunxi: " Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:14   ` Boris Brezillon
2016-03-30 16:15 ` [PATCH v5 45/50] mtd: nand: vf610: " Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-04-01 16:38   ` Stefan Agner
2016-04-01 16:38     ` Stefan Agner
2016-04-01 16:38     ` Stefan Agner
2016-03-30 16:15 ` [PATCH v5 46/50] mtd: nand: qcom: " Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15 ` [PATCH v5 47/50] mtd: onenand: " Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15 ` [PATCH v5 48/50] staging: mt29f_spinand: " Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15 ` [PATCH v5 49/50] mtd: nand: kill the ecc->layout field Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15 ` [PATCH v5 50/50] mtd: kill the nand_ecclayout struct Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:15   ` Boris Brezillon
2016-03-30 16:18 ` [PATCH v5 00/52] mtd: rework ECC layout definition Boris Brezillon
2016-03-30 16:18   ` Boris Brezillon
2016-03-30 16:18   ` Boris Brezillon
2016-04-13 16:14 ` Boris Brezillon
2016-04-13 16:14   ` Boris Brezillon
2016-04-13 16:14   ` Boris Brezillon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160413164020.6c67b542@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=alexandre.belloni@free-electrons.com \
    --cc=architt@codeaurora.org \
    --cc=b45815@freescale.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=computersforpeace@gmail.com \
    --cc=daniel@zonque.org \
    --cc=devel@driverdev.osuosl.org \
    --cc=dwmw2@infradead.org \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=haojian.zhuang@gmail.com \
    --cc=harvey.hunt@imgtec.com \
    --cc=k.kozlowski@samsung.com \
    --cc=kdasu.kdev@gmail.com \
    --cc=kgene@kernel.org \
    --cc=kyungmin.park@samsung.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=maxime.ripard@free-electrons.com \
    --cc=nicolas.ferre@atmel.com \
    --cc=plaes@plaes.org \
    --cc=plagnioj@jcrosoft.com \
    --cc=punnaia@xilinx.com \
    --cc=rainyfeeling@outlook.com \
    --cc=ralf@linux-mips.org \
    --cc=richard@nod.at \
    --cc=robert.jarzmik@free.fr \
    --cc=shijie.huang@arm.com \
    --cc=stefan@agner.ch \
    --cc=wens@csie.org \
    --cc=wenyou.yang@atmel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.