All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris BREZILLON <boris.brezillon@free-electrons.com>
To: Brian Norris <computersforpeace@gmail.com>
Cc: Huang Shijie <shijie8@gmail.com>,
	Huang Shijie <shijie.huang@intel.com>,
	Mike Voytovich <mvoytovich@paypal.com>,
	linux-kernel@vger.kernel.org, Huang Shijie <b32955@freescale.com>,
	linux-mtd@lists.infradead.org, Roy Lee <roylee@paypal.com>,
	David Woodhouse <dwmw2@infradead.org>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] mtd: nand: gpmi: add proper raw access support
Date: Sun, 14 Sep 2014 16:07:52 +0200	[thread overview]
Message-ID: <20140914160752.1cb404cc@bbrezillon> (raw)
In-Reply-To: <20140913173841.GA18093@brian-ubuntu>

Hi Brian, Huang,

On Sat, 13 Sep 2014 10:38:41 -0700
Brian Norris <computersforpeace@gmail.com> wrote:

> On Sat, Sep 13, 2014 at 11:36:24PM +0800, Huang Shijie wrote:
> > On Fri, Sep 12, 2014 at 02:30:50PM +0200, Boris BREZILLON wrote:
> > > This test validates what's returned by ecc_strength file in sysfs
> > > (which in turn is specified by the NAND controller when initializing
> > > the NAND chip).
> > > 
> > > Doing this should not imply knowing the ECC algorithm in use in the
> > > NAND controller or the layout used to store data on NAND.
> > the difficulty is that the ECC parity area can be not byte aligned.
> 
> Is there a problem with just rounding up to the nearest byte alignment
> and ignoring the few bits that are wasted?
> 
> > As I ever said, it is hard to implement the two hooks.
> 
> "Hard" doesn't mean we shouldn't. I really would like to encourage more
> NAND drivers to be programmed against the expected MTD behavior -- that
> (if possible with the given hardware) they can pass the MTD tests
> (drivers/mtd/tests/*).

Here is a draft for a gpmi_move_bits function we could use to move bits
(not bytes :-) from one memory region to another:

void gpmi_move_bits(u8 *dst, size_t dst_bit_off,
		    const u8 *src, size_t src_bit_off,
		    size_t nbits)
{
	size_t i;
	size_t nbytes;
	u32 src_byte = 0;

	src += src_bit_off / 8;
	src_bit_off %= 8;

	dst += dst_bit_off / 8;
	dst_bit_off %= 8;

	if (src_bit_off) {
		src_byte = src[0] >> src_bit_off;
		nbits -= 8 - src_bit_off;
		src++;
	}

	nbytes = nbits / 8;

	if (src_bit_off <= dst_bit_off) {
		dst[0] &= GENMASK(dst_bit_off - 1, 0);
		dst[0] |= src_byte << dst_bit_off;
		src_bit_off += (8 - dst_bit_off);
		src_byte >>= (8 - dst_bit_off);
		dst_bit_off = 0;
		dst++;
	} else if (nbytes) {
		src_byte |= src[0] << (8 - src_bit_off);
		dst[0] &= GENMASK(dst_bit_off - 1, 0);
		dst[0] |= src_byte << dst_bit_off;
		src_bit_off += dst_bit_off;
		src_byte >>= (8 - dst_bit_off);
		dst_bit_off = 0;
		dst++;
		nbytes--;
		src++;
		if (src_bit_off > 7) {
			src_bit_off -= 8;
			dst[0] = src_byte;
			dst++;
			src_byte >>= 8;
		}
	}

	if (!src_bit_off && !dst_bit_off) {
		if (nbytes)
			memcpy(dst, src, nbytes);
	} else {
		for (i = 0; i < nbytes; i++) {
			src_byte |= src[i] << (8 - src_bit_off);
			dst[i] = src_byte;
			src_byte >>= 8;
		}
	}

	dst += nbytes;
	src += nbytes;
	nbits %= 8;

	if (!nbits && !src_bit_off)
		return;

	if (nbits)
		src_byte |= (*src & GENMASK(nbits - 1, 0)) <<
			    ((8 - src_bit_off) % 8);
	nbits += (8 - src_bit_off) % 8;

	if (dst_bit_off)
		src_byte = (src_byte << dst_bit_off) |
			   (*dst & GENMASK(dst_bit_off - 1, 0));
	nbits += dst_bit_off;

	if (nbits % 8)
		src_byte |= (dst[nbits / 8] & GENMASK(7, nbits % 8)) <<
			    (nbits / 8);

	nbytes = DIV_ROUND_UP(nbits, 8);
	for (i = 0; i < nbytes; i++) {
		dst[i] = src_byte;
		src_byte >>= 8;
	}
}

I haven't tested it, and I think there is room for optimization.

My point is that performance is not a key aspect of raw functions
(those are often used by testing and debugging tools), hence we could
rely on this move_bits function to address the ECC bit alignment
problem.

Let me know what's your opinion on this approach.

Best Regards,

Boris

-- 
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@free-electrons.com>
To: Brian Norris <computersforpeace@gmail.com>
Cc: Mike Voytovich <mvoytovich@paypal.com>,
	linux-kernel@vger.kernel.org, Huang Shijie <b32955@freescale.com>,
	linux-mtd@lists.infradead.org, Roy Lee <roylee@paypal.com>,
	Huang Shijie <shijie.huang@intel.com>,
	Huang Shijie <shijie8@gmail.com>,
	David Woodhouse <dwmw2@infradead.org>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] mtd: nand: gpmi: add proper raw access support
Date: Sun, 14 Sep 2014 16:07:52 +0200	[thread overview]
Message-ID: <20140914160752.1cb404cc@bbrezillon> (raw)
In-Reply-To: <20140913173841.GA18093@brian-ubuntu>

Hi Brian, Huang,

On Sat, 13 Sep 2014 10:38:41 -0700
Brian Norris <computersforpeace@gmail.com> wrote:

> On Sat, Sep 13, 2014 at 11:36:24PM +0800, Huang Shijie wrote:
> > On Fri, Sep 12, 2014 at 02:30:50PM +0200, Boris BREZILLON wrote:
> > > This test validates what's returned by ecc_strength file in sysfs
> > > (which in turn is specified by the NAND controller when initializing
> > > the NAND chip).
> > > 
> > > Doing this should not imply knowing the ECC algorithm in use in the
> > > NAND controller or the layout used to store data on NAND.
> > the difficulty is that the ECC parity area can be not byte aligned.
> 
> Is there a problem with just rounding up to the nearest byte alignment
> and ignoring the few bits that are wasted?
> 
> > As I ever said, it is hard to implement the two hooks.
> 
> "Hard" doesn't mean we shouldn't. I really would like to encourage more
> NAND drivers to be programmed against the expected MTD behavior -- that
> (if possible with the given hardware) they can pass the MTD tests
> (drivers/mtd/tests/*).

Here is a draft for a gpmi_move_bits function we could use to move bits
(not bytes :-) from one memory region to another:

void gpmi_move_bits(u8 *dst, size_t dst_bit_off,
		    const u8 *src, size_t src_bit_off,
		    size_t nbits)
{
	size_t i;
	size_t nbytes;
	u32 src_byte = 0;

	src += src_bit_off / 8;
	src_bit_off %= 8;

	dst += dst_bit_off / 8;
	dst_bit_off %= 8;

	if (src_bit_off) {
		src_byte = src[0] >> src_bit_off;
		nbits -= 8 - src_bit_off;
		src++;
	}

	nbytes = nbits / 8;

	if (src_bit_off <= dst_bit_off) {
		dst[0] &= GENMASK(dst_bit_off - 1, 0);
		dst[0] |= src_byte << dst_bit_off;
		src_bit_off += (8 - dst_bit_off);
		src_byte >>= (8 - dst_bit_off);
		dst_bit_off = 0;
		dst++;
	} else if (nbytes) {
		src_byte |= src[0] << (8 - src_bit_off);
		dst[0] &= GENMASK(dst_bit_off - 1, 0);
		dst[0] |= src_byte << dst_bit_off;
		src_bit_off += dst_bit_off;
		src_byte >>= (8 - dst_bit_off);
		dst_bit_off = 0;
		dst++;
		nbytes--;
		src++;
		if (src_bit_off > 7) {
			src_bit_off -= 8;
			dst[0] = src_byte;
			dst++;
			src_byte >>= 8;
		}
	}

	if (!src_bit_off && !dst_bit_off) {
		if (nbytes)
			memcpy(dst, src, nbytes);
	} else {
		for (i = 0; i < nbytes; i++) {
			src_byte |= src[i] << (8 - src_bit_off);
			dst[i] = src_byte;
			src_byte >>= 8;
		}
	}

	dst += nbytes;
	src += nbytes;
	nbits %= 8;

	if (!nbits && !src_bit_off)
		return;

	if (nbits)
		src_byte |= (*src & GENMASK(nbits - 1, 0)) <<
			    ((8 - src_bit_off) % 8);
	nbits += (8 - src_bit_off) % 8;

	if (dst_bit_off)
		src_byte = (src_byte << dst_bit_off) |
			   (*dst & GENMASK(dst_bit_off - 1, 0));
	nbits += dst_bit_off;

	if (nbits % 8)
		src_byte |= (dst[nbits / 8] & GENMASK(7, nbits % 8)) <<
			    (nbits / 8);

	nbytes = DIV_ROUND_UP(nbits, 8);
	for (i = 0; i < nbytes; i++) {
		dst[i] = src_byte;
		src_byte >>= 8;
	}
}

I haven't tested it, and I think there is room for optimization.

My point is that performance is not a key aspect of raw functions
(those are often used by testing and debugging tools), hence we could
rely on this move_bits function to address the ECC bit alignment
problem.

Let me know what's your opinion on this approach.

Best Regards,

Boris

-- 
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] mtd: nand: gpmi: add proper raw access support
Date: Sun, 14 Sep 2014 16:07:52 +0200	[thread overview]
Message-ID: <20140914160752.1cb404cc@bbrezillon> (raw)
In-Reply-To: <20140913173841.GA18093@brian-ubuntu>

Hi Brian, Huang,

On Sat, 13 Sep 2014 10:38:41 -0700
Brian Norris <computersforpeace@gmail.com> wrote:

> On Sat, Sep 13, 2014 at 11:36:24PM +0800, Huang Shijie wrote:
> > On Fri, Sep 12, 2014 at 02:30:50PM +0200, Boris BREZILLON wrote:
> > > This test validates what's returned by ecc_strength file in sysfs
> > > (which in turn is specified by the NAND controller when initializing
> > > the NAND chip).
> > > 
> > > Doing this should not imply knowing the ECC algorithm in use in the
> > > NAND controller or the layout used to store data on NAND.
> > the difficulty is that the ECC parity area can be not byte aligned.
> 
> Is there a problem with just rounding up to the nearest byte alignment
> and ignoring the few bits that are wasted?
> 
> > As I ever said, it is hard to implement the two hooks.
> 
> "Hard" doesn't mean we shouldn't. I really would like to encourage more
> NAND drivers to be programmed against the expected MTD behavior -- that
> (if possible with the given hardware) they can pass the MTD tests
> (drivers/mtd/tests/*).

Here is a draft for a gpmi_move_bits function we could use to move bits
(not bytes :-) from one memory region to another:

void gpmi_move_bits(u8 *dst, size_t dst_bit_off,
		    const u8 *src, size_t src_bit_off,
		    size_t nbits)
{
	size_t i;
	size_t nbytes;
	u32 src_byte = 0;

	src += src_bit_off / 8;
	src_bit_off %= 8;

	dst += dst_bit_off / 8;
	dst_bit_off %= 8;

	if (src_bit_off) {
		src_byte = src[0] >> src_bit_off;
		nbits -= 8 - src_bit_off;
		src++;
	}

	nbytes = nbits / 8;

	if (src_bit_off <= dst_bit_off) {
		dst[0] &= GENMASK(dst_bit_off - 1, 0);
		dst[0] |= src_byte << dst_bit_off;
		src_bit_off += (8 - dst_bit_off);
		src_byte >>= (8 - dst_bit_off);
		dst_bit_off = 0;
		dst++;
	} else if (nbytes) {
		src_byte |= src[0] << (8 - src_bit_off);
		dst[0] &= GENMASK(dst_bit_off - 1, 0);
		dst[0] |= src_byte << dst_bit_off;
		src_bit_off += dst_bit_off;
		src_byte >>= (8 - dst_bit_off);
		dst_bit_off = 0;
		dst++;
		nbytes--;
		src++;
		if (src_bit_off > 7) {
			src_bit_off -= 8;
			dst[0] = src_byte;
			dst++;
			src_byte >>= 8;
		}
	}

	if (!src_bit_off && !dst_bit_off) {
		if (nbytes)
			memcpy(dst, src, nbytes);
	} else {
		for (i = 0; i < nbytes; i++) {
			src_byte |= src[i] << (8 - src_bit_off);
			dst[i] = src_byte;
			src_byte >>= 8;
		}
	}

	dst += nbytes;
	src += nbytes;
	nbits %= 8;

	if (!nbits && !src_bit_off)
		return;

	if (nbits)
		src_byte |= (*src & GENMASK(nbits - 1, 0)) <<
			    ((8 - src_bit_off) % 8);
	nbits += (8 - src_bit_off) % 8;

	if (dst_bit_off)
		src_byte = (src_byte << dst_bit_off) |
			   (*dst & GENMASK(dst_bit_off - 1, 0));
	nbits += dst_bit_off;

	if (nbits % 8)
		src_byte |= (dst[nbits / 8] & GENMASK(7, nbits % 8)) <<
			    (nbits / 8);

	nbytes = DIV_ROUND_UP(nbits, 8);
	for (i = 0; i < nbytes; i++) {
		dst[i] = src_byte;
		src_byte >>= 8;
	}
}

I haven't tested it, and I think there is room for optimization.

My point is that performance is not a key aspect of raw functions
(those are often used by testing and debugging tools), hence we could
rely on this move_bits function to address the ECC bit alignment
problem.

Let me know what's your opinion on this approach.

Best Regards,

Boris

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

  reply	other threads:[~2014-09-14 14:07 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-10  8:55 [PATCH] mtd: nand: gpmi: add proper raw access support Boris BREZILLON
2014-09-10  8:55 ` Boris BREZILLON
2014-09-10  8:55 ` Boris BREZILLON
2014-09-11 12:09 ` Huang Shijie
2014-09-11 12:09   ` Huang Shijie
2014-09-11 12:09   ` Huang Shijie
2014-09-11 12:36   ` Boris BREZILLON
2014-09-11 12:36     ` Boris BREZILLON
2014-09-11 12:36     ` Boris BREZILLON
2014-09-11 14:25     ` Huang Shijie
2014-09-11 14:25       ` Huang Shijie
2014-09-11 14:25       ` Huang Shijie
2014-09-11 14:38       ` Boris BREZILLON
2014-09-11 14:38         ` Boris BREZILLON
2014-09-11 14:38         ` Boris BREZILLON
2014-09-12  0:45         ` Huang Shijie
2014-09-12  0:45           ` Huang Shijie
2014-09-12  0:45           ` Huang Shijie
2014-09-12 12:30           ` Boris BREZILLON
2014-09-12 12:30             ` Boris BREZILLON
2014-09-12 12:30             ` Boris BREZILLON
2014-09-13 15:36             ` Huang Shijie
2014-09-13 15:36               ` Huang Shijie
2014-09-13 15:36               ` Huang Shijie
2014-09-13 17:38               ` Brian Norris
2014-09-13 17:38                 ` Brian Norris
2014-09-13 17:38                 ` Brian Norris
2014-09-14 14:07                 ` Boris BREZILLON [this message]
2014-09-14 14:07                   ` Boris BREZILLON
2014-09-14 14:07                   ` Boris BREZILLON
2014-09-15 14:43                 ` Huang Shijie
2014-09-15 14:43                   ` Huang Shijie
2014-09-15 14:43                   ` Huang Shijie
2014-09-15 20:12                   ` Boris BREZILLON
2014-09-15 20:12                     ` Boris BREZILLON
2014-09-15 20:12                     ` Boris BREZILLON
2014-09-17 15:26                     ` Huang Shijie
2014-09-17 15:26                       ` Huang Shijie
2014-09-17 15:26                       ` Huang Shijie
2014-09-17 18:16                       ` Boris BREZILLON
2014-09-17 18:16                         ` Boris BREZILLON
2014-09-17 18:16                         ` Boris BREZILLON
2014-09-29  1:22     ` Iwo Mergler
2014-09-29  1:22       ` Iwo Mergler
2014-09-29  1:22       ` Iwo Mergler
2014-09-30  8:04       ` Boris Brezillon
2014-09-30  8:04         ` Boris Brezillon
2014-09-30  8:04         ` Boris Brezillon
2014-10-02  6:52         ` Iwo Mergler
2014-10-02  6:52           ` Iwo Mergler
2014-10-02  6:52           ` Iwo Mergler
2014-09-11 14:29 ` Huang Shijie
2014-09-11 14:29   ` Huang Shijie
2014-09-11 14:29   ` Huang Shijie
2014-09-11 14:45   ` Boris BREZILLON
2014-09-11 14:45     ` Boris BREZILLON
2014-09-11 14:45     ` Boris BREZILLON
2014-09-12  0:40     ` Huang Shijie
2014-09-12  0:40       ` Huang Shijie
2014-09-12  0:40       ` Huang Shijie

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=20140914160752.1cb404cc@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=b32955@freescale.com \
    --cc=computersforpeace@gmail.com \
    --cc=dwmw2@infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=mvoytovich@paypal.com \
    --cc=roylee@paypal.com \
    --cc=shijie.huang@intel.com \
    --cc=shijie8@gmail.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.