[U-Boot-Users] [RFC]Nand write/read without ecc

Hi,
This patch is specifically for u-bootloader to program binaries generated by mkyaffsimage, for example, as these binaries includes the 16 bytes oob. All comments are appreciated.
Typical usage will be "nand write.noecc <source address> <Nand offset address> <size>".
Terence.
diff /data/src/u-boot-1.1.4/common/cmd_nand.c ./common/cmd_nand.c
8a9,12
- Added programming in both block and spare column area
- Specifically, it is meant for programming binary generated by
mkyaffsimage
- (C) 2006 Applied Biosystems Instruments
terence.soh@appliedbiosystems.com 70a75
#define NANDRW_NOECC 0x08
93a99,105
static int nand_write_noecc (struct nand_chip* nand, size_t to, size_t
len,
size_t * retlen, const u_char * buf);
static int nand_read_noecc(struct nand_chip *nand, size_t start, size_t
len,
size_t * retlen, u_char *buf);
int nand_rw_noecc (struct nand_chip* nand, int cmd, size_t start, size_t len, size_t * retlen, u_char * buf);
98a111
static int pages_per_block;
219a233,235
else if (cmdtail && !strncmp(cmdtail, ".noecc", 2)) { cmd |= NANDRW_NOECC; /* read/write to OOB
without ECC */
}
243,244c259,265 < ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size, < (size_t *)&total, (u_char*)addr); ---
if(cmd & NANDRW_NOECC){ ret = nand_rw_noecc(nand_dev_desc + curr_device,
cmd, off, size,
&total, (u_char*)addr); } else { ret = nand_rw(nand_dev_desc + curr_device, cmd,
off, size,
&total, (u_char*)addr); }
287a309,310
"nand read.noecc addr off size - read data without ECC" "nand write.noecc addr off size - write data without ECC"
447a471,528
/* Dealing in (nand->oobblock + nand->oobsize) i.e. 528, 2112... bytes
per page */
int nand_rw_noecc (struct nand_chip* nand, int cmd, size_t start, size_t len, size_t * retlen, u_char * buf) { int ret = 0, n, total = 0; unsigned long eblk;
while (len) { if (start%((nand->oobblock +
nand->oobsize)*pages_per_block) == 0) {
/* have crossed into new erase block, deal with * it if it is sure marked bad. */ eblk = start/((nand->oobblock +
nand->oobsize)*pages_per_block);
eblk *= nand->oobblock; if (check_block(nand, eblk)) { if (cmd == (NANDRW_WRITE | NANDRW_NOECC))
{
start += ((nand->oobblock +
nand->oobsize)*pages_per_block);
continue; } } } if(cmd & NANDRW_NOECC){ /* Start on 528/2112 bytes boundary */ if(start%((nand->oobblock + nand->oobsize))){ printf("\nError: Reading/Writing must
start from %d byte page boundary, 0x%8X\n",
(nand->oobblock +
nand->oobsize),start);
return -1; } else{ /* reading and writing without ECC */ if (cmd & NANDRW_READ) { ret = nand_read_noecc(nand, start, min(len,
(nand->oobblock + nand->oobsize)*pages_per_block),
&n, (u_char*)buf); } else { ret = nand_write_noecc(nand,
start,
min(len,
(nand->oobblock + nand->oobsize)*pages_per_block),
&n, (u_char*)buf); } } } if (ret) break; start += n; buf += n; total += n; len -= n; } if (retlen) *retlen = total; return ret;
}
724a806
pages_per_block = nand->erasesize /
nand->oobblock; 878a961,1010
/* Read entire page (without ECC) */ static int nand_read_noecc(struct nand_chip *nand, size_t start, size_t
len,
size_t * retlen, u_char *buf)
{ int col, page;
/* First we calculate the starting page */ /* Address here take spare area into account */ page = start / (nand->oobblock + nand->oobsize); /* Get raw starting column */ col = start % (nand->oobblock + nand->oobsize); /* Initialize return value */ *retlen = 0; NAND_ENABLE_CE(nand); /* set pin low */ /* Loop until all data read */ while (*retlen < len) { /* Send the read command */ NanD_Command(nand, NAND_CMD_READ0); /* Address to NAND flash don't take the spare area into
account */
if (nand->bus16) { NanD_Address(nand, ADDR_COLUMN_PAGE, (page * nand->oobblock) + (col >>
1));
} else { NanD_Address(nand, ADDR_COLUMN_PAGE, (page * nand->oobblock) + col); } /* Read the data directly into the return buffer */ if ((*retlen + (nand->oobblock + nand->oobsize - col)) >=
len) {
NanD_ReadBuf(nand, buf + *retlen, len - *retlen); *retlen = len; /* We're done */ continue; } else { NanD_ReadBuf(nand, buf + *retlen, nand->oobblock +
nand->oobsize - col);
*retlen += nand->oobblock + nand->oobsize - col; } /* For subsequent reads align to page boundary. */ col = 0; /* Increment page address */ page++; } /* De-select the NAND device */ NAND_DISABLE_CE(nand); /* set pin high */ /* Always successful. No ECC */ return 0;
}
1247a1380,1457
/* Write entire page (including out of bound area) */ static int nand_write_noecc (struct nand_chip* nand, size_t to, size_t
len,
size_t * retlen, const u_char * buf)
{ int i, page, col, ret, cnt = 0;
/* Initialize return length value */ *retlen = 0; ret = 0; /* Get page */ page = ((int) to) / (nand->oobblock + nand->oobsize); /* Get the starting column. Should be zero */ col = to % (nand->oobblock + nand->oobsize); /* Loop until all data is written */ while (*retlen < len) { /* Write data into buffer */ if ((col + len - *retlen) >= (nand->oobblock +
nand->oobsize)) {
/* >= (nand->oobblock + nand->oobsize) bytes to be
written */
for (i = col, cnt = 0; i < (nand->oobblock +
nand->oobsize); i++, cnt++) {
nand->data_buf[i] = buf[(*retlen + cnt)]; } } else { /* Less than (nand->oobblock + nand->oobsize)
bytes to be written */
for (i = col, cnt = 0; cnt < (len - *retlen); i++,
cnt++) {
nand->data_buf[i] = buf[(*retlen + cnt)]; } } /* set pin low */ NAND_ENABLE_CE(nand); NanD_Command (nand, NAND_CMD_SEQIN); if (nand->bus16) { NanD_Address (nand, ADDR_COLUMN_PAGE, (page * nand->oobblock) + (col >>
1));
} else { NanD_Address (nand, ADDR_COLUMN_PAGE, (page * nand->oobblock) + col); } /* Write out complete page of data */ if (nand->bus16) { for (i = 0; i < cnt; i += 2) { WRITE_NAND (nand->data_buf[i] + (nand->data_buf[i + 1] << 8), nand->IO_ADDR); } } else { /* Send command to begin auto page programming */ for (i = 0; i < cnt ; i++) WRITE_NAND (nand->data_buf[i],
nand->IO_ADDR);
} /* Send command to actually program the data */ NanD_Command (nand, NAND_CMD_PAGEPROG); NanD_Command (nand, NAND_CMD_STATUS); NAND_WAIT_READY(nand); /* See if device thinks it succeeded */ if(READ_NAND (nand->IO_ADDR) & 0x01) { printf ("%s: Failed write, page 0x%08x, ",
__FUNCTION__,
page); ret = -1; } /* De-select the NAND device */ NAND_DISABLE_CE(nand); /* set pin high */ /* Next data start at page boundary */ col = 0; /* Update written bytes count */ *retlen += cnt; /* Increment page address */ page++; } return ret;
}

In message OFDAFA0526.9999E3EB-ON482571AE.002B5AD3-482571AE.002BF887@applera.com you wrote:
This patch is specifically for u-bootloader to program binaries generated by mkyaffsimage, for example, as these binaries includes the 16 bytes oob. All comments are appreciated.
Sorry, but this is unusable. A plain diff cannot be applied. Also, your mailer wrapped the lines which broke it completely. Also, you did not provide a CHANGELOG antry, and did not follow the Coding Style requirements (trailing white space, indentation not by TABs, at least in one place incorrect brace style, ...).
Please clean up and resubmit. See the README for instructions.
Best regards,
Wolfgang Denk

Sorry, but this is unusable. A plain diff cannot be applied. Also, your mailer wrapped the lines which broke it completely. Also, you did not provide a CHANGELOG antry, and did not follow the Coding Style requirements (trailing white space, indentation not by TABs, at least in one place incorrect brace style, ...).
Please clean up and resubmit. See the README for instructions.
Sorry, my first attempt at submitting a patch... For your review and comments.
Patch is attached to write entire (oob inclusive) to NAND flash. mkyaffsimage generate binary
CHANGELOG * added "nand write.noecc" for writing binary generated by mkyaffsimage in cmd_nand.c Patch by Terence Soh terence.soh@appliedbiosystems.com July 17, 2006
Signed-off-by: Terence Soh terence.soh@appliedbiosystems.com

Terence Soh wrote:
Patch is attached to write entire (oob inclusive) to NAND flash. mkyaffsimage generate binary
CHANGELOG
- added "nand write.noecc" for writing binary generated by mkyaffsimage
in cmd_nand.c Patch by Terence Soh terence.soh@appliedbiosystems.com July 17, 2006
Signed-off-by: Terence Soh terence.soh@appliedbiosystems.com
Terence,
This is a very useful contribution to U-Boot. I just about to start on this myself.
I notice that your patch is for the older, legacy NAND code, and unfortunately I am using the newer MTD-based NAND code that was implemented after version 1.1.4.
Are you at all interested in providing this functionality for the new NAND code? If not, I'll start working on it. Hopefully your code will help.
Regards, ../fam
participants (3)
-
Frank Mandarino
-
Terence Soh
-
Wolfgang Denk