cache invalidation error for buffered write

The bug causes corruptions of data read from flash.

The original code performs cache invalidation from "adr" to "adr + len"
in do_write_buffer().  Since len and adr could be updated in the code
before invalidation - it causes improper setting of cache invalidation
regions.

Signed-off-by: Massimo Cirillo <maxcir@gmail.com>
Signed-off-by: Giuseppe D'Eliseo <giuseppedeliseo@gmail.com>
Acked-by: Nicolas Pitre <nico@cam.org>
Acked-by: Jörn Engel <joern@logfs.org>
Signed-off-by: David Woohouse <dwmw2@infradead.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Massimo Cirillo 2008-01-11 10:24:11 +00:00 committed by Linus Torvalds
parent 7c48c56e9b
commit 646fd12784

View file

@ -1504,9 +1504,12 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
int ret, wbufsize, word_gap, words; int ret, wbufsize, word_gap, words;
const struct kvec *vec; const struct kvec *vec;
unsigned long vec_seek; unsigned long vec_seek;
unsigned long initial_adr;
int initial_len = len;
wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
adr += chip->start; adr += chip->start;
initial_adr = adr;
cmd_adr = adr & ~(wbufsize-1); cmd_adr = adr & ~(wbufsize-1);
/* Let's determine this according to the interleave only once */ /* Let's determine this according to the interleave only once */
@ -1519,7 +1522,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
return ret; return ret;
} }
XIP_INVAL_CACHED_RANGE(map, adr, len); XIP_INVAL_CACHED_RANGE(map, initial_adr, initial_len);
ENABLE_VPP(map); ENABLE_VPP(map);
xip_disable(map, chip, cmd_adr); xip_disable(map, chip, cmd_adr);
@ -1610,7 +1613,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
chip->state = FL_WRITING; chip->state = FL_WRITING;
ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
adr, len, initial_adr, initial_len,
chip->buffer_write_time); chip->buffer_write_time);
if (ret) { if (ret) {
map_write(map, CMD(0x70), cmd_adr); map_write(map, CMD(0x70), cmd_adr);