Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: rawnand: Clarify conditions to enable continuous reads

The current logic is probably fine but is a bit convoluted. Plus, we
don't want partial pages to be part of the sequential operation just in
case the core would optimize the page read with a subpage read (which
would break the sequence). This may happen on the first and last page
only, so if the start offset or the end offset is not aligned with a
page boundary, better avoid them to prevent any risk.

Cc: stable@vger.kernel.org
Fixes: 003fe4b9545b ("mtd: rawnand: Support for sequential cache reads")
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Tested-by: Martin Hundebøll <martin@geanix.com>
Link: https://lore.kernel.org/linux-mtd/20231215123208.516590-5-miquel.raynal@bootlin.com

+17 -9
+17 -9
drivers/mtd/nand/raw/nand_base.c
··· 3460 3460 u32 readlen, int col) 3461 3461 { 3462 3462 struct mtd_info *mtd = nand_to_mtd(chip); 3463 + unsigned int end_page, end_col; 3464 + 3465 + chip->cont_read.ongoing = false; 3463 3466 3464 3467 if (!chip->controller->supported_op.cont_read) 3465 3468 return; 3466 3469 3467 - if ((col && col + readlen < (3 * mtd->writesize)) || 3468 - (!col && readlen < (2 * mtd->writesize))) { 3469 - chip->cont_read.ongoing = false; 3470 - return; 3471 - } 3470 + end_page = DIV_ROUND_UP(col + readlen, mtd->writesize); 3471 + end_col = (col + readlen) % mtd->writesize; 3472 3472 3473 - chip->cont_read.ongoing = true; 3474 - chip->cont_read.first_page = page; 3475 3473 if (col) 3476 - chip->cont_read.first_page++; 3477 - chip->cont_read.last_page = page + ((readlen >> chip->page_shift) & chip->pagemask); 3474 + page++; 3475 + 3476 + if (end_col && end_page) 3477 + end_page--; 3478 + 3479 + if (page + 1 > end_page) 3480 + return; 3481 + 3482 + chip->cont_read.first_page = page; 3483 + chip->cont_read.last_page = end_page; 3484 + chip->cont_read.ongoing = true; 3485 + 3478 3486 rawnand_cap_cont_reads(chip); 3479 3487 } 3480 3488