[U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
Guennadi Liakhovetski
lg at denx.de
Tue Aug 5 15:08:04 CEST 2008
On Mon, 4 Aug 2008, Scott Wood wrote:
> On Mon, Aug 04, 2008 at 02:45:33PM +0200, Guennadi Liakhovetski wrote:
> > I _think_ this should work with all NAND chips. Otherwise we might have to
> > introduce a configuration variable.
>
> Which small-page NAND chips can't handle READOOB? On large page devices,
> nand_command changes it to READ0.
It's a large-page device. And, as far as I understand the datasheet, to
read data at arbitrary offset in a page, you first have to issue a READ
PAGE (READ0) for _the_ _whole_ page, then you can use RANDOM DATA READ to
read arbitrary data within this page. Whereas, the driver attempts to use
READ0 to read the bad-block marker directly, which doesn't work with this
chip. At least this is my understanding.
> That said, doing it all at once could result in smaller, faster, and
> simpler code.
>
> > @@ -150,8 +135,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
> > u_char *ecc_code;
> > u_char *oob_data;
> > int i;
> > - int eccsize = CFG_NAND_ECCSIZE;
> > - int eccbytes = CFG_NAND_ECCBYTES;
>
> Any particular reason for this change? It's more readable as is, IMHO.
Acually, it was to improve readability:-) First, this way you can easier
grep. Secondly, when I see an assignment to a _variable_, I expect, that
this variable's value can indeed _vary_. So, it makes extra work looking
through the code and verifying what other values this variable takes.
Thus, at the very least I would add "const" to the definition. And, I do
think using constants directly makes it clearer...
> > @@ -195,6 +180,7 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst)
> > int block;
> > int blockcopy_count;
> > int page;
> > + unsigned read = 0;
>
> "unsigned int", please.
Ok...
> > + int badblock = 0;
> > + for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) {
> > + nand_read_page(mtd, block, page, dst);
> > + if ((!page
> > +#ifdef CFG_NAND_BBT_2NDPAGE
> > + || page == 1
> > +#endif
>
> Please use page == 0 rather than !page when checking for an actual value
> of zero as opposed to a zero that means "not valid" or similar.
Ok...
> > + ) && dst[CFG_NAND_PAGE_SIZE] != 0xff) {
> > + badblock = 1;
> > + break;
> > }
> > + /* Overwrite skipped pages */
> > + if (read >= offs)
> > + dst += CFG_NAND_PAGE_SIZE;
> > + read += CFG_NAND_PAGE_SIZE;
> > + }
>
> I don't follow the logic here -- you're discarding a number of good
> blocks equal to the offset? That might make sense if we were starting at
> block zero, and defining the offset as not including any bad blocks
> before the image -- but the first block we read is at the start of the
> image, not the start of flash.
Right, that's a bug. Hope, it's fixed now.
> > @@ -241,12 +239,18 @@ void nand_boot(void)
> > nand_chip.dev_ready = NULL; /* preset to NULL */
> > board_nand_init(&nand_chip);
> >
> > + if (nand_chip.select_chip)
> > + nand_chip.select_chip(&nand_info, 0);
> > +
> > /*
> > * Load U-Boot image from NAND into RAM
> > */
> > ret = nand_load(&nand_info, CFG_NAND_U_BOOT_OFFS, CFG_NAND_U_BOOT_SIZE,
> > (uchar *)CFG_NAND_U_BOOT_DST);
> >
> > + if (nand_chip.select_chip)
> > + nand_chip.select_chip(&nand_info, -1);
> > +
>
> This seems like an unrelated change, that wasn't described in the
> changelog.
Ok, will describe in the changelog.
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
More information about the U-Boot
mailing list