Skip to content

Commit 010dc7f

Browse files
mkshevetskiymiquelraynal
authored andcommitted
mtd: spinand: repeat reading in regular mode if continuous reading fails
Continuous reading may result in multiple flash pages reading in one operation. Unfortunately, not all spinand controllers support such large reading. They will read less data. Unfortunately, the operation can't be continued. In this case: * disable continuous reading on this (not good enough) spi controller * repeat reading in regular mode. Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
1 parent 004f8ea commit 010dc7f

1 file changed

Lines changed: 21 additions & 4 deletions

File tree

drivers/mtd/nand/spi/core.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,16 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
430430
* Dirmap accesses are allowed to toggle the CS.
431431
* Toggling the CS during a continuous read is forbidden.
432432
*/
433-
if (nbytes && req->continuous)
434-
return -EIO;
433+
if (nbytes && req->continuous) {
434+
/*
435+
* Spi controller with broken support of continuous
436+
* reading was detected. Disable future use of
437+
* continuous reading and return -EAGAIN to retry
438+
* reading within regular mode.
439+
*/
440+
spinand->cont_read_possible = false;
441+
return -EAGAIN;
442+
}
435443
}
436444

437445
if (req->datalen)
@@ -899,10 +907,19 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
899907

900908
old_stats = mtd->ecc_stats;
901909

902-
if (spinand_use_cont_read(mtd, from, ops))
910+
if (spinand_use_cont_read(mtd, from, ops)) {
903911
ret = spinand_mtd_continuous_page_read(mtd, from, ops, &max_bitflips);
904-
else
912+
if (ret == -EAGAIN && !spinand->cont_read_possible) {
913+
/*
914+
* Spi controller with broken support of continuous
915+
* reading was detected (see spinand_read_from_cache_op()),
916+
* repeat reading in regular mode.
917+
*/
918+
ret = spinand_mtd_regular_page_read(mtd, from, ops, &max_bitflips);
919+
}
920+
} else {
905921
ret = spinand_mtd_regular_page_read(mtd, from, ops, &max_bitflips);
922+
}
906923

907924
if (ops->stats) {
908925
ops->stats->uncorrectable_errors +=

0 commit comments

Comments
 (0)