Skip to content

Commit

Permalink
mtd: rawnand: Ensure all continuous terms are always in sync
Browse files Browse the repository at this point in the history
[ Upstream commit 6fb075f ]

While crossing a LUN boundary, it is probably safer (and clearer) to
keep all members of the continuous read structure aligned, including the
pause page (which is the last page of the lun or the last page of the
continuous read). Once these members properly in sync, we can use the
rawnand_cap_cont_reads() helper everywhere to "prepare" the next
continuous read if there is one.

Fixes: bbcd80f ("mtd: rawnand: Prevent crossing LUN boundaries during sequential reads")
Cc: stable@vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20240223115545.354541-4-miquel.raynal@bootlin.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
miquelraynal authored and gregkh committed Apr 3, 2024
1 parent a90dbe2 commit f64f8be
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions drivers/mtd/nand/raw/nand_base.c
Expand Up @@ -1232,6 +1232,15 @@ static void rawnand_cap_cont_reads(struct nand_chip *chip)
chip->cont_read.pause_page = rawnand_last_page_of_lun(ppl, first_lun);
else
chip->cont_read.pause_page = chip->cont_read.last_page;

if (chip->cont_read.first_page == chip->cont_read.pause_page) {
chip->cont_read.first_page++;
chip->cont_read.pause_page = min(chip->cont_read.last_page,
rawnand_last_page_of_lun(ppl, first_lun + 1));
}

if (chip->cont_read.first_page >= chip->cont_read.last_page)
chip->cont_read.ongoing = false;
}

static int nand_lp_exec_cont_read_page_op(struct nand_chip *chip, unsigned int page,
Expand Down Expand Up @@ -1298,12 +1307,11 @@ static int nand_lp_exec_cont_read_page_op(struct nand_chip *chip, unsigned int p
if (!chip->cont_read.ongoing)
return 0;

if (page == chip->cont_read.pause_page &&
page != chip->cont_read.last_page) {
chip->cont_read.first_page = chip->cont_read.pause_page + 1;
rawnand_cap_cont_reads(chip);
} else if (page == chip->cont_read.last_page) {
if (page == chip->cont_read.last_page) {
chip->cont_read.ongoing = false;
} else if (page == chip->cont_read.pause_page) {
chip->cont_read.first_page++;
rawnand_cap_cont_reads(chip);
}

return 0;
Expand Down Expand Up @@ -3510,10 +3518,7 @@ static void rawnand_cont_read_skip_first_page(struct nand_chip *chip, unsigned i
return;

chip->cont_read.first_page++;
if (chip->cont_read.first_page == chip->cont_read.pause_page)
chip->cont_read.first_page++;
if (chip->cont_read.first_page >= chip->cont_read.last_page)
chip->cont_read.ongoing = false;
rawnand_cap_cont_reads(chip);
}

/**
Expand Down

0 comments on commit f64f8be

Please sign in to comment.