[PATCH] fix root cause of NAND trouble

Werner Almesberger werner at openmoko.org
Sat Nov 1 15:34:52 CET 2008

Ben Dooks wrote:
> If you are getting unaligned reads, then there isn't much hope for
> correctly assessing the ECC code, which we generally (unless you've
> overriden it) is expecting 256byte blocks. 

Ah, I should have been clearer on what happens there: the actual data
is still read in large power-of-two chunks. What nand_read_subpage
does is that it tries to optimize accesses to the ECC bytes in the
OOB data. So if we just need, say, three ECC bytes, it requests only
those three bytes, starting at the right offset, instead of retrieving
all of the OOB data.

Unfortunately, the logic in nand_read_subpage hard to decipher.
Below is a little pseudo-patch that should do exactly the same, but
in a less cryptic way. I need to check it a bit more before I'd
feel confident about submitting it, though.

- Werner

---------------------------------- cut here -----------------------------------

 	if (gaps) {
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
 		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 	} else {
+		int pos;
 		/* send the command to read the particular ecc bytes */
 		/* take care about buswidth alignment in read_buf */
-		aligned_pos = eccpos[start_step * chip->ecc.bytes] & ~(busw - 1);
-		aligned_len = eccfrag_len;
-		if (eccpos[start_step * chip->ecc.bytes] & (busw - 1))
-			aligned_len++;
-		if (eccpos[(start_step + num_steps) * chip->ecc.bytes] & (busw - 1))
-			aligned_len++;
+		pos = eccpos[start_step * chip->ecc.bytes];
+		aligned_pos = pos & ~(busw - 1);
+		aligned_len = ALIGN(eccfrag_len+(pos-aligned_pos), busw);
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize + aligned_pos, -1);

More information about the openmoko-kernel mailing list