On 03/12/2019 15:29, John Garry wrote:
Here's an example flow (with my hack to stop using 16b SR method):
root@ubuntu:/home/john# flash_lock -l /dev/mtd0
root@ubuntu:/home/john# mtd_debug erase /dev/mtd0 0xe00000 4096
[ 69.650642] spi-nor spi-PRP0001:00: at 0xe00000, len 4096
Erased 4096 bytes from address 0x00e00000 in flash
root@ubuntu:/home/john# mtd_debug write /dev/mtd0 0xe00000 4096 dump4096
[ 77.093755] spi-nor spi-PRP0001:00: to 0x00e00000, len 4096
Copied 4096 bytes from dump4096 to address 0x00e00000 in flash
root@ubuntu:/home/john# mtd_debug read /dev/mtd0 0xe00000 4096 temp
[ 82.162445] spi-nor spi-PRP0001:00: from 0x00e00000, len 4096
Copied 4096 bytes from address 0x00e00000 in flash to temp
root@ubuntu:/home/john# flash_lock -u /dev/mtd0
[ 87.558435] spi-nor spi-PRP0001:00: SR1: read back test failed
flash_lock: error!: could not unlock device: /dev/mtd0
error 5 (Input/output error)
root@ubuntu:/home/john#
Unlock reports an error as the the read back test in
spi_nor_write_sr1_and_check() fails as the SR.WEL has never been
cleared.
Interesting.
I note that spi_nor_erase() exits with a call to
spi_nor_write_disable(), yet spi_nor_write() doesn't - maybe we should
add a similar call there.
So this remedies that issue for me:
commit c90de583d81f7c5c6cb1c8c021108a0e7e244b91 (HEAD)
Author: John Garry <john.garry@xxxxxxxxxx>
Date: Wed Dec 4 10:26:49 2019 +0000
Ensure we clear SR.WEL for any write failure due to locking
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index aeb3ad2dbfb8..3f12335eb20c 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2875,6 +2875,8 @@ static int spi_nor_write(struct mtd_info *mtd,
loff_t to, size_t len,
i += written;
}
+ ret = spi_nor_write_disable(nor);
+
write_err:
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
return ret;
Does the following do the trick?
- { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K |
SPI_NOR_QUAD_READ) },
+ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K |
USE_FSR |
+ SPI_NOR_QUAD_READ) },
Yes, that works and it's nice to not have the silent failures:
root@ubuntu:/home/john# flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x1000000
Lock status: locked
Return code: 1
root@ubuntu:/home/john#
root@ubuntu:/home/john# mtd_debug erase /dev/mtd0 0xe00000 4096
[ 45.023353] spi-nor spi0.0: Erase operation failed.
[ 45.028257] spi-nor spi0.0: Attempted to modify a protected sector.
MEMERASE: Input/output error
mtd_debug write /dev/mtd0 0xe00000 4096 dump4096
[ 50.212013] spi-nor spi0.0: Program operation failed.
[ 50.217084] spi-nor spi0.0: Attempted to modify a protected sector.
file_to_flash: write, size 0x1000, n 0x1000
write(): Input/output error
root@ubuntu:/home/john# mtd_debug read /dev/mtd0 0xe00000 4096 temp
Copied 4096 bytes from address 0x00e00000 in flash to temp
root@ubuntu:/home/john# flash_lock -u /dev/mtd0
flash_lock: error!: could not unlock device: /dev/mtd0
error 5 (Input/output error)
root@ubuntu:/home/john# flash_lock -i /dev/mtd0
Device: /dev/mtd0
Start: 0
Len: 0x1000000
Lock status: unlocked
Return code: 0
root@ubuntu:/home/john# flash_lock -u /dev/mtd0
root@ubuntu:/home/john#
But, as you may see, it seems that my change to spi_nor_write() is still
required to stop the first unlock failure message, but it needs to be
relocated to after write_err label, as we now jump there for
spi_nor_wait_till_ready() failure. I guess the equivalent relocation is
also required for spi_nor_erase().
Or maybe spi_nor_wait_till_ready() should clear this flag always.
I'll give it a spin - along with your SR lock fix - when I get back on
the HW again.
This can of course be extended to all micron flashes, if all support
FSR, but
some documentation work has to be made.
Thanks,
John
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/