diff options
author | Marek Vasut <marex@denx.de> | 2018-05-24 21:58:40 +0200 |
---|---|---|
committer | Ye Li <ye.li@nxp.com> | 2019-07-04 22:39:15 -0700 |
commit | 5ab6ff7987e02d411e9fa5a7912cae3ff0991eaa (patch) | |
tree | 5e6100f28d4c0dd746dabcffcde45b04222b6301 /drivers | |
parent | b70191078f7635b90878721222b21d2104c0e598 (diff) |
sf: Set current flash bank to 0 in clean_bar()
The clean_bar() function resets the SPI NOR BAR register to 0, but
does not set the flash->curr_bar to 0 , therefore those two can get
out of sync, which could ultimatelly result in corrupted flash content.
The simplest test case is this:
=> mw 0x10000000 0x1234abcd 0x4000
=> sf probe
=> sf erase 0x1000000 0x10000
=> sf write 0x10000000 0x1000000 0x10000
=> sf probe ; sf read 0x12000000 0 0x10000 ; md 0x12000000
That is, erase a sector above the 16 MiB boundary and write it with
random pre-configured data. What will actually happen without this
patch is the sector will be erased, but the data will be written to
BAR 0 offset 0x0 in the flash.
This is because the erase command will call write_bar()+clean_bar(),
which will leave flash->bank_curr = 1 while the hardware BAR registers
will be set to 0 through clean_bar(). The subsequent write will also
trigger write_bar()+clean_bar(), but write_bar checks if the target
bank == flash->bank_curr and if so, does NOT reconfigure the BAR in
the SPI NOR. Since flash->bank_curr is still 1 and out of sync with
the HW, the condition matches, BAR programming is skipped and write
ends up at address 0x0, thus corrupting flash content.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Tom Rini <trini@konsulko.com>
Reviewed-by: Jagan Teki <jagan@openedev.com>
(cherry picked from commit 8ff4130debcc09594b550209c44abf6c7e3ee595)
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/spi/spi_flash.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index de35707948b..426e39a7547 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -141,6 +141,7 @@ static int clean_bar(struct spi_flash *flash) if (flash->bank_curr == 0) return 0; cmd = flash->bank_write_cmd; + flash->bank_curr = 0; return spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); } |