
On Mon, Aug 30, 2010 at 7:03 PM, Scott Wood scottwood@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@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@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