[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