summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2018-05-24 21:58:40 +0200
committerJagan Teki <jagan@amarulasolutions.com>2018-06-04 23:31:37 +0530
commit8ff4130debcc09594b550209c44abf6c7e3ee595 (patch)
tree145cbe641d32efcdfb5be8e25da6a68dda97dafc /drivers
parent6c353674bd5219b1129e29d16484eb540e0d3925 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/spi/spi_flash.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 0ed2317554..c159124259 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -128,6 +128,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);
}