mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2025-12-08 13:42:10 -05:00
Continuous reading mode is broken for some spi controllers. There are two possible bug scenarios: 1) "continuous mode" flash and spi controller without dirmap support, but with restriction on transfer length in adjust_op_size() 2) "continuous mode" flash and spi controller with dirmap support for a single flash page In the first case, any read that exceeds the limit specified in adjust_op_size() will result in an EIO error. The limit may even be less than a size of a single flash page. In this case, any read will result in an error. In the second case, any read larger than flash page size will result in an EIO error or spinand driver spoofing (because the spi controller driver returns more bytes than were actually read). This patch series tries to fix continuous reading (spinand driver side). Unfortunately these fixes can't resolve "spinand driver spoofing" case. Spi controller drivers might need fixes as well. Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> Link: https://github.com/openwrt/openwrt/pull/20295 Signed-off-by: Robert Marko <robimarko@gmail.com>
63 lines
2.3 KiB
Diff
63 lines
2.3 KiB
Diff
From 5eea4228aaa3c5aeba843d8ea2a60993c268419d Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
|
Date: Sun, 3 Aug 2025 17:23:27 +0300
|
|
Subject: [PATCH RESEND v5 1/3] mtd: spinand: fix direct mapping creation sizes
|
|
|
|
Continuous mode is only supported for data reads, thus writing
|
|
requires only single flash page mapping.
|
|
|
|
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
|
---
|
|
drivers/mtd/nand/spi/core.c | 14 +++++++-------
|
|
1 file changed, 7 insertions(+), 7 deletions(-)
|
|
|
|
--- a/drivers/mtd/nand/spi/core.c
|
|
+++ b/drivers/mtd/nand/spi/core.c
|
|
@@ -1028,18 +1028,13 @@ static int spinand_create_dirmap(struct
|
|
unsigned int plane)
|
|
{
|
|
struct nand_device *nand = spinand_to_nand(spinand);
|
|
- struct spi_mem_dirmap_info info = {
|
|
- .length = nanddev_page_size(nand) +
|
|
- nanddev_per_page_oobsize(nand),
|
|
- };
|
|
+ struct spi_mem_dirmap_info info = { 0 };
|
|
struct spi_mem_dirmap_desc *desc;
|
|
|
|
- if (spinand->cont_read_possible)
|
|
- info.length = nanddev_eraseblock_size(nand);
|
|
-
|
|
/* The plane number is passed in MSB just above the column address */
|
|
info.offset = plane << fls(nand->memorg.pagesize);
|
|
|
|
+ info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
|
|
info.op_tmpl = *spinand->op_templates.update_cache;
|
|
desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
|
|
spinand->spimem, &info);
|
|
@@ -1048,6 +1043,8 @@ static int spinand_create_dirmap(struct
|
|
|
|
spinand->dirmaps[plane].wdesc = desc;
|
|
|
|
+ if (spinand->cont_read_possible)
|
|
+ info.length = nanddev_eraseblock_size(nand);
|
|
info.op_tmpl = *spinand->op_templates.read_cache;
|
|
desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
|
|
spinand->spimem, &info);
|
|
@@ -1063,6 +1060,7 @@ static int spinand_create_dirmap(struct
|
|
return 0;
|
|
}
|
|
|
|
+ info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
|
|
info.op_tmpl = *spinand->op_templates.update_cache;
|
|
info.op_tmpl.data.ecc = true;
|
|
desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
|
|
@@ -1072,6 +1070,8 @@ static int spinand_create_dirmap(struct
|
|
|
|
spinand->dirmaps[plane].wdesc_ecc = desc;
|
|
|
|
+ if (spinand->cont_read_possible)
|
|
+ info.length = nanddev_eraseblock_size(nand);
|
|
info.op_tmpl = *spinand->op_templates.read_cache;
|
|
info.op_tmpl.data.ecc = true;
|
|
desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
|