[U-Boot] [PATCH 1/5] nand util: read/write: accept unaligned length

Ben Gardiner bengardiner at nanometrics.ca
Tue Aug 31 23:45:51 CEST 2010


On Mon, Aug 30, 2010 at 7:03 PM, Scott Wood <scottwood at freescale.com> wrote:
> The underlying code in nand_base.c already supports non-page-aligned reads
> and writes, but the block-skipping wrapper code did not.
>
> With block skipping, an unaligned start address is not useful since you
> really want to be starting at the beginning of a partition -- or at least
> that's where you want to start checking for blocks to skip, but we don't
> (yet) support that.  So we still require the start address to be aligned.
>
> An unaligned length, though, is useful for passing $filesize to the
> read/write command, and handling it does not complicate block skipping.

This is a great feature.

> Signed-off-by: Scott Wood <scottwood at freescale.com>

applies  to 962ad59e25640e586e2bceabf67a628a27f8f508 of
git://git.denx.de/u-boot.git -- some checkpatch errors.

Tested on da850evm_config with NAND enabled;

Tested-by: Ben Gardiner <bengardiner at nanometrics.ca>

>  /**
> @@ -474,29 +487,41 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
>  {
>        int rval;
>        size_t left_to_write = *length;
> -       size_t len_incl_bad;
>        u_char *p_buffer = buffer;
> +       int need_skip;
>
> -       /* Reject writes, which are not page aligned */
> -       if ((offset & (nand->writesize - 1)) != 0 ||
> -           (*length & (nand->writesize - 1)) != 0) {
> +       /*
> +        * nand_write() handles unaligned, partial page writes.
> +        *
> +        * We allow length to be unaligned, for convenience in
> +        * using the $filesize variable.
> +        *
> +        * However, starting at an unaligned offset makes the
> +        * semantics of bad block skipping ambiguous (really,
> +        * you should only start a block skipping access at a
> +        * partition boundary).  So don't try to handle that.
> +        */
> +       if ((offset & (nand->writesize - 1)) != 0) {
>                printf ("Attempt to write non page aligned data\n");
> +               *length = 0;
>                return -EINVAL;
>        }
>
> -       len_incl_bad = get_len_incl_bad (nand, offset, *length);
> -
> -       if ((offset + len_incl_bad) > nand->size) {
> +       need_skip = check_skip_len(nand, offset, *length);
> +       if (need_skip < 0) {
>                printf ("Attempt to write outside the flash area\n");
> +               *length = 0;
>                return -EINVAL;
>        }
>
> -       if (len_incl_bad == *length) {
> +       if (!need_skip) {
>                rval = nand_write (nand, offset, length, buffer);
> -               if (rval != 0)
> -                       printf ("NAND write to offset %llx failed %d\n",
> -                               offset, rval);
> +               if (rval == 0)
> +                       return 0;
>
> +               *length = 0;
> +               printf ("NAND write to offset %llx failed %d\n",

no space between printf and the open parenthesis.

> +                       offset, rval);
>                return rval;
>        }
>
> @@ -553,20 +578,28 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
>  {
>        int rval;
>        size_t left_to_read = *length;
> -       size_t len_incl_bad;
>        u_char *p_buffer = buffer;
> +       int need_skip;
>
> -       len_incl_bad = get_len_incl_bad (nand, offset, *length);
> +       if ((offset & (nand->writesize - 1)) != 0) {
> +               printf ("Attempt to read non page aligned data\n");

no space between the printf and open parenthesis.

Best Regards,
Ben Gardiner

---
Nanometrics Inc.
http://www.nanometrics.ca


More information about the U-Boot mailing list