public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* mtd: gpmi: issue with raw access support
@ 2016-01-25 21:53 Han Xu
  2016-01-26  6:39 ` Boris Brezillon
  2016-01-26  6:42 ` [PATCH] remove deprecated oobinfo retrieval Boris Brezillon
  0 siblings, 2 replies; 7+ messages in thread
From: Han Xu @ 2016-01-25 21:53 UTC (permalink / raw)
  To: boris.brezillon, Brian Norris, Huang Shijie,
	linux-mtd@lists.infradead.org

Hi Boris,

There is an issue on Kernel 4.1 with your gpmi raw access support
patch. I can understand with your implementation all data are stored
in BCH layout, even without HW ECC. But for NAND boot function on i.MX
family, it requires to write BOOT CONFIGURATION DATA at the beginning
of NAND chip, so ROM code could understand how to configure BCH
register to read data with proper ECC handling.

All these BOOT CONFIURATION DATA must be written with proper ROM
defined format, including data layout, parity checking algorithm( NOT
BCH ECC for some platforms). A user-space tool, named kobs-ng was
provided to generate all necessary data, and it called the mtd raw
functions to write the UNFORMATTED data to NAND chip.

With the new patch, all NAND boot function on kernel 4.1 failed since
ROM couldn't read the proper configuration. To solve the issue, I am
planning to export a switch in debugfs to let the user applications to
choose raw access mode, unformatted mode or BCH layout one, while I
got stuck.

The problem is how could I dynamically change the raw functions from
the new ones you provided to the default ones in nand_base. It more or
less a hacking either getting the pointer of functions
nand_read_page_raw /nand_write_page_raw or copy-pasting the implement
of these two functions to gpmi layer. So I was wondering if you have
any better idea for this issue? Thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: mtd: gpmi: issue with raw access support
  2016-01-25 21:53 mtd: gpmi: issue with raw access support Han Xu
@ 2016-01-26  6:39 ` Boris Brezillon
  2016-01-26  6:42 ` [PATCH] remove deprecated oobinfo retrieval Boris Brezillon
  1 sibling, 0 replies; 7+ messages in thread
From: Boris Brezillon @ 2016-01-26  6:39 UTC (permalink / raw)
  To: Han Xu; +Cc: Brian Norris, Huang Shijie, linux-mtd@lists.infradead.org

Hi,

On Mon, 25 Jan 2016 15:53:23 -0600
Han Xu <xhnjupt@gmail.com> wrote:

> Hi Boris,
> 
> There is an issue on Kernel 4.1 with your gpmi raw access support
> patch. I can understand with your implementation all data are stored
> in BCH layout, even without HW ECC. But for NAND boot function on i.MX
> family, it requires to write BOOT CONFIGURATION DATA at the beginning
> of NAND chip, so ROM code could understand how to configure BCH
> register to read data with proper ECC handling.
> 
> All these BOOT CONFIURATION DATA must be written with proper ROM
> defined format, including data layout, parity checking algorithm( NOT
> BCH ECC for some platforms). A user-space tool, named kobs-ng was
> provided to generate all necessary data, and it called the mtd raw
> functions to write the UNFORMATTED data to NAND chip.

Yes, I had the same problem, actually I made 2 patches for kobs-ng
(I'll send them in reply to this email), but since the project seemed to
be unmaintained, I didn't submit it.

> 
> With the new patch, all NAND boot function on kernel 4.1 failed since
> ROM couldn't read the proper configuration. To solve the issue, I am
> planning to export a switch in debugfs to let the user applications to
> choose raw access mode, unformatted mode or BCH layout one, while I
> got stuck.

Hm, providing two different set of raw access functions is a bad idea
IMO. If we had a per-partition configuration infrastructure that could
be done, but so far we don't have that.

> 
> The problem is how could I dynamically change the raw functions from
> the new ones you provided to the default ones in nand_base. It more or
> less a hacking either getting the pointer of functions
> nand_read_page_raw /nand_write_page_raw or copy-pasting the implement
> of these two functions to gpmi layer. So I was wondering if you have
> any better idea for this issue? Thanks.

I recommend to patch kobs-ng, and let him reorganize the data to make
the ROM firmware happy. That's what I did in my patches, but IIRC, I
only took the "aligned ECC bytes" case into consideration, and this is
not necessarily true depending on the ECC config, so you'll have to
rework my patches to address that.

Best Regards,

Boris

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] remove deprecated oobinfo retrieval
  2016-01-25 21:53 mtd: gpmi: issue with raw access support Han Xu
  2016-01-26  6:39 ` Boris Brezillon
@ 2016-01-26  6:42 ` Boris Brezillon
  2016-01-26  6:42   ` [PATCH] Adapt raw page accesses to match the new raw_read/write implementation Boris Brezillon
  2016-01-26 19:59   ` [PATCH] remove deprecated oobinfo retrieval Brian Norris
  1 sibling, 2 replies; 7+ messages in thread
From: Boris Brezillon @ 2016-01-26  6:42 UTC (permalink / raw)
  To: Han Xu; +Cc: Brian Norris, Huang Shijie, linux-mtd, Boris BREZILLON

From: Boris BREZILLON <boris.brezillon@free-electrons.com>

This remove OOB info retrieval, which is not used anywhere else in the code
and can generate errors when called on newer NAND that have more than 32
bytes of ECC or 16 bytes available for user usage in the OOB area.

Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
---
 src/mtd.c | 8 --------
 src/mtd.h | 1 -
 2 files changed, 9 deletions(-)

diff --git a/src/mtd.c b/src/mtd.c
index 02af33b..cf8428a 100644
--- a/src/mtd.c
+++ b/src/mtd.c
@@ -700,14 +700,6 @@ struct mtd_data *mtd_open(const struct mtd_config *cfg, int flags)
 			goto out;
 		}
 
-		/* keep original oobinfo */
-		r = ioctl(mp->fd, MEMGETOOBSEL, &mp->old_oobinfo);
-		if (r != 0) {
-			fprintf(stderr, "mtd: device %s can't ioctl MEMGETOOBSEL: %d\n",
-					mp->name, r);
-			goto out;
-		}
-
 		/* get info about the mtd device (partition) */
 		r = ioctl(mp->fd, MEMGETINFO, miu);
 		if (r != 0) {
diff --git a/src/mtd.h b/src/mtd.h
index 99d7887..946a49c 100644
--- a/src/mtd.h
+++ b/src/mtd.h
@@ -112,7 +112,6 @@ struct mtd_part {
 	int nrbad;
 
         int oobinfochanged;
-	struct nand_oobinfo old_oobinfo;
 	int ecc;
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH] Adapt raw page accesses to match the new raw_read/write implementation
  2016-01-26  6:42 ` [PATCH] remove deprecated oobinfo retrieval Boris Brezillon
@ 2016-01-26  6:42   ` Boris Brezillon
  2016-01-26 19:59   ` [PATCH] remove deprecated oobinfo retrieval Brian Norris
  1 sibling, 0 replies; 7+ messages in thread
From: Boris Brezillon @ 2016-01-26  6:42 UTC (permalink / raw)
  To: Han Xu; +Cc: Brian Norris, Huang Shijie, linux-mtd, Boris BREZILLON

From: Boris BREZILLON <boris.brezillon@free-electrons.com>

The old raw access implementation (in GPMI driver) was considering that
data and OOB data were separated in their respective regions (the data
area and the OOB area of the page), which is not true.
They are actually interleaved this way:

METADATA + ((DATA + ECCBYTES) * N)

The new raw access implementation (in the GPMI driver) is hiding this weird
layout to MTD users by exposing a more common layout:

DATA + METADATA + (N * ECCBYTES)

Here METADATA + (N * ECCBYTES) are exposed as if they were stored in the
OOB area.

Unfortunately kobs-ng rely on this weird layout when accessing the NAND
in raw mode.
This patch take the new layout into account.

Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
---
 src/mtd.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 92 insertions(+), 5 deletions(-)

diff --git a/src/mtd.c b/src/mtd.c
index 02af33b..f6fa962 100644
--- a/src/mtd.c
+++ b/src/mtd.c
@@ -254,14 +254,26 @@ int mtd_read_page(struct mtd_data *md, int chip, loff_t ofs, int ecc)
 
 	mtd_set_ecc_mode(md, ecc);
 
-	data = md->buf;
+	if (ecc) {
+		data = md->buf;
+	} else {
+		data = malloc(mtd_writesize(md) + mtd_oobsize(md));
+		if (!data) {
+			fprintf(stderr, "mtd: %s failed to allocate buffer\n", __func__);
+			return -1;
+		}
+	}
+
 	oobdata = data + mtd_writesize(md);
 
 	/* make sure it's aligned to a page */
-	if ((ofs % mtd_writesize(md)) != 0)
+	if ((ofs % mtd_writesize(md)) != 0) {
+		if (!ecc)
+			free(data);
 		return -1;
+	}
 
-	memset(md->buf, 0, mtd_writesize(md) + mtd_oobsize(md));
+	memset(data, 0, mtd_writesize(md) + mtd_oobsize(md));
 
 	size = mtd_writesize(md);
 
@@ -269,6 +281,33 @@ int mtd_read_page(struct mtd_data *md, int chip, loff_t ofs, int ecc)
 		r = pread(md->part[chip].fd, data, size, ofs);
 	} while (r == -1 && (errno == EAGAIN || errno == EBUSY));
 
+	if (!ecc) {
+		int i;
+		struct nfc_geometry *nfc_geo = &md->nfc_geometry;
+		int eccbytes = ((nfc_geo->ecc_strength * nfc_geo->gf_len) + 7) / 8;
+		int chunksize = nfc_geo->ecc_chunk_size_in_bytes;
+		int dst_offset = 0;
+
+		memcpy(md->buf, oobdata, nfc_geo->metadata_size_in_bytes);
+		dst_offset += nfc_geo->metadata_size_in_bytes;
+		for (i = 0; i < nfc_geo->ecc_chunk_count; i++) {
+			memcpy(md->buf + dst_offset, data + (i * chunksize), chunksize);
+			dst_offset += chunksize;
+			memcpy(md->buf + dst_offset,
+			       oobdata + nfc_geo->metadata_size_in_bytes + (i * eccbytes),
+			       eccbytes);
+			dst_offset += eccbytes;
+		}
+
+		if (mtd_writesize(md) + mtd_oobsize(md) > dst_offset) {
+			memcpy(md->buf + dst_offset,
+			       oobdata + nfc_geo->metadata_size_in_bytes + (i * eccbytes),
+			       mtd_writesize(md) + mtd_oobsize(md) - dst_offset);
+		}
+
+		free(data);
+	}
+
 	/* end of partition? */
 	if (r == 0)
 		return 0;
@@ -329,23 +368,71 @@ int mtd_write_page(struct mtd_data *md, int chip, loff_t ofs, int ecc)
 	int r;
 	const void *data;
 	const void *oobdata;
+	struct mtd_write_req ops;
 
 	mtd_set_ecc_mode(md, ecc);
 
-	data = md->buf;
-	oobdata = data + mtd_oobsize(md);
+	if (ecc) {
+		data = md->buf;
+		oobdata = data + mtd_writesize(md);
+	} else {
+		int i;
+		struct nfc_geometry *nfc_geo = &md->nfc_geometry;
+		int eccbytes = ((nfc_geo->ecc_strength * nfc_geo->gf_len) + 7) / 8;
+		int chunksize = nfc_geo->ecc_chunk_size_in_bytes;
+		int src_offset = 0;
+
+		data = malloc(mtd_writesize(md) + mtd_oobsize(md));
+		if (!data) {
+			fprintf(stderr, "mtd: %s failed to allocate buffer\n", __func__);
+			return -1;
+		}
+		oobdata = data + mtd_writesize(md);
+		memset(data, 0, mtd_writesize(md) + mtd_oobsize(md));
+		memcpy(oobdata, md->buf, nfc_geo->metadata_size_in_bytes);
+		src_offset += nfc_geo->metadata_size_in_bytes;
+		for (i = 0; i < nfc_geo->ecc_chunk_count; i++) {
+			memcpy(data + (i * chunksize), md->buf + src_offset, chunksize);
+			src_offset += chunksize;
+			memcpy(oobdata + nfc_geo->metadata_size_in_bytes + (i * eccbytes),
+			       md->buf + src_offset, eccbytes);
+			src_offset += eccbytes;
+		}
+
+		if (mtd_writesize(md) + mtd_oobsize(md) > src_offset) {
+			memcpy(oobdata + nfc_geo->metadata_size_in_bytes + (i * eccbytes),
+			       md->buf + src_offset,
+			       mtd_writesize(md) + mtd_oobsize(md) - src_offset);
+		}
+	}
 
 	/* make sure it's aligned to a page */
 	if ((ofs % mtd_writesize(md)) != 0) {
 		fprintf(stderr, "mtd: %s failed\n", __func__);
+		if (!ecc)
+			free(data);
 		return -1;
 	}
 
 	size = mtd_writesize(md);
 
+	ops.start = ofs;
+	ops.len = size;
+	ops.ooblen = ecc ? 0 : mtd_oobsize(md);
+	ops.usr_oob = (uint64_t)(unsigned long)oobdata;
+	ops.usr_data = (uint64_t)(unsigned long)data;
+	ops.mode = ecc ? MTD_OPS_AUTO_OOB : MTD_OPS_RAW;
+	r = ioctl(md->part[chip].fd, MEMWRITE, &ops);
+	if (!r)
+		r = size;
+	/*
 	do {
 		r = pwrite(md->part[chip].fd, data, size, ofs);
 	} while (r == -1 && (errno == EAGAIN || errno == EBUSY));
+	*/
+
+	if (!ecc)
+		free(data);
 
 	/* end of partition? */
 	if (r == 0) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] remove deprecated oobinfo retrieval
  2016-01-26  6:42 ` [PATCH] remove deprecated oobinfo retrieval Boris Brezillon
  2016-01-26  6:42   ` [PATCH] Adapt raw page accesses to match the new raw_read/write implementation Boris Brezillon
@ 2016-01-26 19:59   ` Brian Norris
  2016-01-26 20:15     ` Han Xu
  2016-01-26 20:16     ` Boris Brezillon
  1 sibling, 2 replies; 7+ messages in thread
From: Brian Norris @ 2016-01-26 19:59 UTC (permalink / raw)
  To: Boris Brezillon; +Cc: Han Xu, Huang Shijie, linux-mtd

On Tue, Jan 26, 2016 at 07:42:16AM +0100, Boris Brezillon wrote:
> From: Boris BREZILLON <boris.brezillon@free-electrons.com>
> 
> This remove OOB info retrieval, which is not used anywhere else in the code
> and can generate errors when called on newer NAND that have more than 32
> bytes of ECC or 16 bytes available for user usage in the OOB area.
> 
> Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
> ---
>  src/mtd.c | 8 --------
>  src/mtd.h | 1 -
>  2 files changed, 9 deletions(-)

What source are you trying to patch? Doesn't look like Linux or
mtd-utils.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] remove deprecated oobinfo retrieval
  2016-01-26 19:59   ` [PATCH] remove deprecated oobinfo retrieval Brian Norris
@ 2016-01-26 20:15     ` Han Xu
  2016-01-26 20:16     ` Boris Brezillon
  1 sibling, 0 replies; 7+ messages in thread
From: Han Xu @ 2016-01-26 20:15 UTC (permalink / raw)
  To: Brian Norris; +Cc: Boris Brezillon, Huang Shijie, linux-mtd@lists.infradead.org

No, it's a user-space tool named kobs-ng.

On Tue, Jan 26, 2016 at 1:59 PM, Brian Norris
<computersforpeace@gmail.com> wrote:
> On Tue, Jan 26, 2016 at 07:42:16AM +0100, Boris Brezillon wrote:
>> From: Boris BREZILLON <boris.brezillon@free-electrons.com>
>>
>> This remove OOB info retrieval, which is not used anywhere else in the code
>> and can generate errors when called on newer NAND that have more than 32
>> bytes of ECC or 16 bytes available for user usage in the OOB area.
>>
>> Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
>> ---
>>  src/mtd.c | 8 --------
>>  src/mtd.h | 1 -
>>  2 files changed, 9 deletions(-)
>
> What source are you trying to patch? Doesn't look like Linux or
> mtd-utils.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] remove deprecated oobinfo retrieval
  2016-01-26 19:59   ` [PATCH] remove deprecated oobinfo retrieval Brian Norris
  2016-01-26 20:15     ` Han Xu
@ 2016-01-26 20:16     ` Boris Brezillon
  1 sibling, 0 replies; 7+ messages in thread
From: Boris Brezillon @ 2016-01-26 20:16 UTC (permalink / raw)
  To: Brian Norris; +Cc: Han Xu, Huang Shijie, linux-mtd

On Tue, 26 Jan 2016 11:59:41 -0800
Brian Norris <computersforpeace@gmail.com> wrote:

> On Tue, Jan 26, 2016 at 07:42:16AM +0100, Boris Brezillon wrote:
> > From: Boris BREZILLON <boris.brezillon@free-electrons.com>
> > 
> > This remove OOB info retrieval, which is not used anywhere else in the code
> > and can generate errors when called on newer NAND that have more than 32
> > bytes of ECC or 16 bytes available for user usage in the OOB area.
> > 
> > Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
> > ---
> >  src/mtd.c | 8 --------
> >  src/mtd.h | 1 -
> >  2 files changed, 9 deletions(-)
> 
> What source are you trying to patch? Doesn't look like Linux or
> mtd-utils.

Nope, those patches apply on the kobs-ng project (BTW, didn't find any
git repo hosting this project).
I realize I shouldn't send those patches to the MTD ML (I just kept
the @ Han Xu sent his request to, including the ML).

Sorry for the inconvenience.


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

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-01-26 20:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-25 21:53 mtd: gpmi: issue with raw access support Han Xu
2016-01-26  6:39 ` Boris Brezillon
2016-01-26  6:42 ` [PATCH] remove deprecated oobinfo retrieval Boris Brezillon
2016-01-26  6:42   ` [PATCH] Adapt raw page accesses to match the new raw_read/write implementation Boris Brezillon
2016-01-26 19:59   ` [PATCH] remove deprecated oobinfo retrieval Brian Norris
2016-01-26 20:15     ` Han Xu
2016-01-26 20:16     ` Boris Brezillon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox