It was observed that reads crossing 4K address boundary are failing.
This limitation is mentioned in Intel documents:
Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:
"5.26.3 Flash Access Program Register Access: * Program Register Accesses are not allowed to cross a 4 KB boundary..."
Enhanced Serial Peripheral Interface (eSPI) Interface Base Specification (for Client and Server Platforms):
"5.1.4 Address For other memory transactions, the address may start or end at any byte boundary. However, the address and payload length combination must not cross the naturally aligned address boundary of the corresponding Maximum Payload Size. It must not cross a 4 KB address boundary."
Avoid this by splitting an operation crossing the boundary into two operations.
Cc: stable@vger.kernel.org Reported-by: Romain Porte romain.porte@nokia.com Tested-by: Pascal Fabreges pascal.fabreges@nokia.com Signed-off-by: Alexander Sverdlin alexander.sverdlin@nokia.com --- drivers/mtd/spi-nor/intel-spi.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index af0a220..b83ea79 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c @@ -632,6 +632,10 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
+ /* Read cannot cross 4K boundary */ + if ((from ^ (from + block_size - 1)) & ~(SZ_4K - 1LL)) + block_size -= (from + block_size) & (SZ_4K - 1); + writel(from, ispi->base + FADDR);
val = readl(ispi->base + HSFSTS_CTL); @@ -685,6 +689,10 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
+ /* Write cannot cross 4K boundary */ + if ((to ^ (to + block_size - 1)) & ~(SZ_4K - 1LL)) + block_size -= (to + block_size) & (SZ_4K - 1); + writel(to, ispi->base + FADDR);
val = readl(ispi->base + HSFSTS_CTL);
On Tue, Feb 26, 2019 at 11:23:49AM +0000, Sverdlin, Alexander (Nokia - DE/Ulm) wrote:
It was observed that reads crossing 4K address boundary are failing.
This limitation is mentioned in Intel documents:
Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:
"5.26.3 Flash Access Program Register Access:
- Program Register Accesses are not allowed to cross a 4 KB boundary..."
Enhanced Serial Peripheral Interface (eSPI) Interface Base Specification (for Client and Server Platforms):
"5.1.4 Address For other memory transactions, the address may start or end at any byte boundary. However, the address and payload length combination must not cross the naturally aligned address boundary of the corresponding Maximum Payload Size. It must not cross a 4 KB address boundary."
Avoid this by splitting an operation crossing the boundary into two operations.
Cc: stable@vger.kernel.org Reported-by: Romain Porte romain.porte@nokia.com Tested-by: Pascal Fabreges pascal.fabreges@nokia.com Signed-off-by: Alexander Sverdlin alexander.sverdlin@nokia.com
drivers/mtd/spi-nor/intel-spi.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index af0a220..b83ea79 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c @@ -632,6 +632,10 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
/* Read cannot cross 4K boundary */
if ((from ^ (from + block_size - 1)) & ~(SZ_4K - 1LL))
Don't we have existing macros in kernel.h that can be used here and below?
block_size -= (from + block_size) & (SZ_4K - 1);
- writel(from, ispi->base + FADDR);
val = readl(ispi->base + HSFSTS_CTL); @@ -685,6 +689,10 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
/* Write cannot cross 4K boundary */
if ((to ^ (to + block_size - 1)) & ~(SZ_4K - 1LL))
block_size -= (to + block_size) & (SZ_4K - 1);
- writel(to, ispi->base + FADDR);
val = readl(ispi->base + HSFSTS_CTL); -- 2.4.6
It was observed that reads crossing 4K address boundary are failing.
This limitation is mentioned in Intel documents:
Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:
"5.26.3 Flash Access Program Register Access: * Program Register Accesses are not allowed to cross a 4 KB boundary..."
Enhanced Serial Peripheral Interface (eSPI) Interface Base Specification (for Client and Server Platforms):
"5.1.4 Address For other memory transactions, the address may start or end at any byte boundary. However, the address and payload length combination must not cross the naturally aligned address boundary of the corresponding Maximum Payload Size. It must not cross a 4 KB address boundary."
Avoid this by splitting an operation crossing the boundary into two operations.
Cc: stable@vger.kernel.org Reported-by: Romain Porte romain.porte@nokia.com Tested-by: Pascal Fabreges pascal.fabreges@nokia.com Signed-off-by: Alexander Sverdlin alexander.sverdlin@nokia.com --- Changelog: v2: More macros! As Mika suggested.
drivers/mtd/spi-nor/intel-spi.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index af0a220..8c279c4 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c @@ -632,6 +632,10 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
+ /* Read cannot cross 4K boundary */ + blocksize = min(from + block_size, round_up(from + 1, SZ_4K)) - + from; + writel(from, ispi->base + FADDR);
val = readl(ispi->base + HSFSTS_CTL); @@ -685,6 +689,9 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
+ /* Write cannot cross 4K boundary */ + blocksize = min(to + block_size, round_up(to + 1, SZ_4K)) - to; + writel(to, ispi->base + FADDR);
val = readl(ispi->base + HSFSTS_CTL);
On Wed, Feb 27, 2019 at 09:57:15AM +0000, Sverdlin, Alexander (Nokia - DE/Ulm) wrote:
It was observed that reads crossing 4K address boundary are failing.
This limitation is mentioned in Intel documents:
Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:
"5.26.3 Flash Access Program Register Access:
- Program Register Accesses are not allowed to cross a 4 KB boundary..."
Enhanced Serial Peripheral Interface (eSPI) Interface Base Specification (for Client and Server Platforms):
"5.1.4 Address For other memory transactions, the address may start or end at any byte boundary. However, the address and payload length combination must not cross the naturally aligned address boundary of the corresponding Maximum Payload Size. It must not cross a 4 KB address boundary."
Avoid this by splitting an operation crossing the boundary into two operations.
Cc: stable@vger.kernel.org Reported-by: Romain Porte romain.porte@nokia.com Tested-by: Pascal Fabreges pascal.fabreges@nokia.com Signed-off-by: Alexander Sverdlin alexander.sverdlin@nokia.com
Changelog: v2: More macros! As Mika suggested.
drivers/mtd/spi-nor/intel-spi.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index af0a220..8c279c4 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c @@ -632,6 +632,10 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
/* Read cannot cross 4K boundary */
blocksize = min(from + block_size, round_up(from + 1, SZ_4K)) -
from;
Nit:
It looks better if you put it into one line like:
blocksize = min(from + block_size, round_up(from + 1, SZ_4K)) - from;
Regardless of that,
Acked-by: Mika Westerberg mika.westerberg@linux.intel.com
Hello Mika and all,
On 27/02/2019 11:27, Mika Westerberg wrote:
On Wed, Feb 27, 2019 at 09:57:15AM +0000, Sverdlin, Alexander (Nokia - DE/Ulm) wrote:
It was observed that reads crossing 4K address boundary are failing.
[...]
Reported-by: Romain Porte romain.porte@nokia.com Tested-by: Pascal Fabreges pascal.fabreges@nokia.com Signed-off-by: Alexander Sverdlin alexander.sverdlin@nokia.com
Changelog: v2: More macros! As Mika suggested.
drivers/mtd/spi-nor/intel-spi.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index af0a220..8c279c4 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c @@ -632,6 +632,10 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, while (len > 0) { block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
/* Read cannot cross 4K boundary */
blocksize = min(from + block_size, round_up(from + 1, SZ_4K)) -
from;
Nit:
It looks better if you put it into one line like:
blocksize = min(from + block_size, round_up(from + 1, SZ_4K)) - from;
Regardless of that,
Acked-by: Mika Westerberg mika.westerberg@linux.intel.com
Please ignore v2! There was a failure in build/test process on my side. I will send v3.
linux-stable-mirror@lists.linaro.org