All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baruch Siach <baruch@tkos.co.il>
To: David Woodhouse <dwmw2@infradead.org>,
	Brian Norris <computersforpeace@gmail.com>
Cc: "Fabio Estevam" <Fabio.Estevam@freescale.com>,
	"Baruch Siach" <baruch@tkos.co.il>,
	linux-mtd@lists.infradead.org,
	"Sascha Hauer" <kernel@pengutronix.de>,
	"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
	"Shawn Guo" <shawn.guo@linaro.org>,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 3/4] mtd: mxc_nand: fix truncate of unaligned oob copying
Date: Sun,  3 May 2015 10:18:53 +0300	[thread overview]
Message-ID: <ff526c6b889682e36e7d086dd5e6dec8936f86d9.1430636819.git.baruch@tkos.co.il> (raw)
In-Reply-To: <cover.1430636819.git.baruch@tkos.co.il>

Copy to/from oob io area might not be aligned to 4 bytes. When 8 bit ECC is
used, the buffer size is 26. Add memcpy16_{to,from}io, and use them to avoid
truncating the buffer. Prefer memcpy32_{to,from}io when the buffer is properly
aligned for better performance.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
v2:
   * Use memcpy16_{to,from}io (Uwe Kleine-König)
---
 drivers/mtd/nand/mxc_nand.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 51c1600d7eb9..010be8aa41d4 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -281,12 +281,44 @@ static void memcpy32_fromio(void *trg, const void __iomem  *src, size_t size)
 		*t++ = __raw_readl(s++);
 }
 
+static void memcpy16_fromio(void *trg, const void __iomem  *src, size_t size)
+{
+	int i;
+	u16 *t = trg;
+	const __iomem u16 *s = src;
+
+	/* We assume that src (IO) is always 32bit aligned */
+	if (PTR_ALIGN(trg, 4) == trg && IS_ALIGNED(size, 4)) {
+		memcpy32_fromio(trg, src, size);
+		return;
+	}
+
+	for (i = 0; i < (size >> 1); i++)
+		*t++ = __raw_readw(s++);
+}
+
 static inline void memcpy32_toio(void __iomem *trg, const void *src, int size)
 {
 	/* __iowrite32_copy use 32bit size values so divide by 4 */
 	__iowrite32_copy(trg, src, size / 4);
 }
 
+static void memcpy16_toio(void __iomem *trg, const void *src, int size)
+{
+	int i;
+	__iomem u16 *t = trg;
+	const u16 *s = src;
+
+	/* We assume that trg (IO) is always 32bit aligned */
+	if (PTR_ALIGN(src, 4) == src && IS_ALIGNED(size, 4)) {
+		memcpy32_toio(trg, src, size);
+		return;
+	}
+
+	for (i = 0; i < (size >> 1); i++)
+		__raw_writew(*s++, t++);
+}
+
 static int check_int_v3(struct mxc_nand_host *host)
 {
 	uint32_t tmp;
@@ -832,22 +864,22 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
 
 	if (bfrom) {
 		for (i = 0; i < num_chunks - 1; i++)
-			memcpy32_fromio(d + i * oob_chunk_size,
+			memcpy16_fromio(d + i * oob_chunk_size,
 					s + i * sparebuf_size,
 					oob_chunk_size);
 
 		/* the last chunk */
-		memcpy32_fromio(d + i * oob_chunk_size,
+		memcpy16_fromio(d + i * oob_chunk_size,
 				s + i * sparebuf_size,
 				host->used_oobsize - i * oob_chunk_size);
 	} else {
 		for (i = 0; i < num_chunks - 1; i++)
-			memcpy32_toio(&s[i * sparebuf_size],
+			memcpy16_toio(&s[i * sparebuf_size],
 				      &d[i * oob_chunk_size],
 				      oob_chunk_size);
 
 		/* the last chunk */
-		memcpy32_toio(&s[oob_chunk_size * sparebuf_size],
+		memcpy16_toio(&s[oob_chunk_size * sparebuf_size],
 			      &d[i * oob_chunk_size],
 			      host->used_oobsize - i * oob_chunk_size);
 	}
-- 
2.1.4

WARNING: multiple messages have this Message-ID (diff)
From: baruch@tkos.co.il (Baruch Siach)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 3/4] mtd: mxc_nand: fix truncate of unaligned oob copying
Date: Sun,  3 May 2015 10:18:53 +0300	[thread overview]
Message-ID: <ff526c6b889682e36e7d086dd5e6dec8936f86d9.1430636819.git.baruch@tkos.co.il> (raw)
In-Reply-To: <cover.1430636819.git.baruch@tkos.co.il>

Copy to/from oob io area might not be aligned to 4 bytes. When 8 bit ECC is
used, the buffer size is 26. Add memcpy16_{to,from}io, and use them to avoid
truncating the buffer. Prefer memcpy32_{to,from}io when the buffer is properly
aligned for better performance.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
v2:
   * Use memcpy16_{to,from}io (Uwe Kleine-K?nig)
---
 drivers/mtd/nand/mxc_nand.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 51c1600d7eb9..010be8aa41d4 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -281,12 +281,44 @@ static void memcpy32_fromio(void *trg, const void __iomem  *src, size_t size)
 		*t++ = __raw_readl(s++);
 }
 
+static void memcpy16_fromio(void *trg, const void __iomem  *src, size_t size)
+{
+	int i;
+	u16 *t = trg;
+	const __iomem u16 *s = src;
+
+	/* We assume that src (IO) is always 32bit aligned */
+	if (PTR_ALIGN(trg, 4) == trg && IS_ALIGNED(size, 4)) {
+		memcpy32_fromio(trg, src, size);
+		return;
+	}
+
+	for (i = 0; i < (size >> 1); i++)
+		*t++ = __raw_readw(s++);
+}
+
 static inline void memcpy32_toio(void __iomem *trg, const void *src, int size)
 {
 	/* __iowrite32_copy use 32bit size values so divide by 4 */
 	__iowrite32_copy(trg, src, size / 4);
 }
 
+static void memcpy16_toio(void __iomem *trg, const void *src, int size)
+{
+	int i;
+	__iomem u16 *t = trg;
+	const u16 *s = src;
+
+	/* We assume that trg (IO) is always 32bit aligned */
+	if (PTR_ALIGN(src, 4) == src && IS_ALIGNED(size, 4)) {
+		memcpy32_toio(trg, src, size);
+		return;
+	}
+
+	for (i = 0; i < (size >> 1); i++)
+		__raw_writew(*s++, t++);
+}
+
 static int check_int_v3(struct mxc_nand_host *host)
 {
 	uint32_t tmp;
@@ -832,22 +864,22 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
 
 	if (bfrom) {
 		for (i = 0; i < num_chunks - 1; i++)
-			memcpy32_fromio(d + i * oob_chunk_size,
+			memcpy16_fromio(d + i * oob_chunk_size,
 					s + i * sparebuf_size,
 					oob_chunk_size);
 
 		/* the last chunk */
-		memcpy32_fromio(d + i * oob_chunk_size,
+		memcpy16_fromio(d + i * oob_chunk_size,
 				s + i * sparebuf_size,
 				host->used_oobsize - i * oob_chunk_size);
 	} else {
 		for (i = 0; i < num_chunks - 1; i++)
-			memcpy32_toio(&s[i * sparebuf_size],
+			memcpy16_toio(&s[i * sparebuf_size],
 				      &d[i * oob_chunk_size],
 				      oob_chunk_size);
 
 		/* the last chunk */
-		memcpy32_toio(&s[oob_chunk_size * sparebuf_size],
+		memcpy16_toio(&s[oob_chunk_size * sparebuf_size],
 			      &d[i * oob_chunk_size],
 			      host->used_oobsize - i * oob_chunk_size);
 	}
-- 
2.1.4

  parent reply	other threads:[~2015-05-03  7:18 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-03  7:18 [PATCH v2 0/4] mtd: mxc_nand: fix 8 bit ECC and large oob Baruch Siach
2015-05-03  7:18 ` Baruch Siach
2015-05-03  7:18 ` [PATCH v2 1/4] mtd: nand: mxc_nand: cleanup copy_spare function Baruch Siach
2015-05-03  7:18   ` Baruch Siach
2015-05-03  7:18 ` [PATCH v2 2/4] mtd: mxc_nand: limit the size of used oob Baruch Siach
2015-05-03  7:18   ` Baruch Siach
2015-05-03  7:18 ` Baruch Siach [this message]
2015-05-03  7:18   ` [PATCH v2 3/4] mtd: mxc_nand: fix truncate of unaligned oob copying Baruch Siach
2015-05-08  7:24   ` Uwe Kleine-König
2015-05-08  7:24     ` Uwe Kleine-König
2015-05-13  5:12     ` Baruch Siach
2015-05-13  5:12       ` Baruch Siach
2015-05-13  6:39       ` Uwe Kleine-König
2015-05-13  6:39         ` Uwe Kleine-König
2015-05-13  6:44         ` Baruch Siach
2015-05-13  6:44           ` Baruch Siach
2015-05-13  6:47           ` Uwe Kleine-König
2015-05-13  6:47             ` Uwe Kleine-König
2015-05-13  6:59             ` Baruch Siach
2015-05-13  6:59               ` Baruch Siach
2015-05-13  7:01               ` Uwe Kleine-König
2015-05-13  7:01                 ` Uwe Kleine-König
2015-05-13  7:12                 ` Baruch Siach
2015-05-13  7:12                   ` Baruch Siach
2015-05-13  7:18                   ` Uwe Kleine-König
2015-05-13  7:18                     ` Uwe Kleine-König
2015-05-03  7:18 ` [PATCH v2 4/4] mtd: mxc_nand: generate nand_ecclayout for 8 bit ECC Baruch Siach
2015-05-03  7:18   ` Baruch Siach
2015-05-08  7:21   ` Uwe Kleine-König
2015-05-08  7:21     ` Uwe Kleine-König
2015-05-08  5:15 ` [PATCH v2 0/4] mtd: mxc_nand: fix 8 bit ECC and large oob Sascha Hauer
2015-05-08  5:15   ` Sascha Hauer
2015-05-13  5:22   ` Baruch Siach
2015-05-13  5:22     ` Baruch Siach

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=ff526c6b889682e36e7d086dd5e6dec8936f86d9.1430636819.git.baruch@tkos.co.il \
    --to=baruch@tkos.co.il \
    --cc=Fabio.Estevam@freescale.com \
    --cc=computersforpeace@gmail.com \
    --cc=dwmw2@infradead.org \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=shawn.guo@linaro.org \
    --cc=u.kleine-koenig@pengutronix.de \
    /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.