1 From e5d05cbd6d8b01f08c95c427a36c66aac769af4f Mon Sep 17 00:00:00 2001
2 From: Michal Suchanek <hramrach@gmail.com>
3 Date: Thu, 5 May 2016 17:31:54 -0700
4 Subject: [PATCH 08/10] mtd: spi-nor: simplify write loop
6 The spi-nor write loop assumes that what is passed to the hardware
7 driver write() is what gets written.
9 When write() writes less than page size at once data is dropped on the
10 floor. Check the amount of data writen and exit if it does not match
13 Signed-off-by: Michal Suchanek <hramrach@gmail.com>
14 Signed-off-by: Brian Norris <computersforpeace@gmail.com>
15 Tested-by Cyrille Pitchen <cyrille.pitchen@atmel.com>
16 Acked-by: Michal Suchanek <hramrach@gmail.com>
17 Tested-by: Michal Suchanek <hramrach@gmail.com>
19 drivers/mtd/spi-nor/spi-nor.c | 58 +++++++++++++++++++------------------------
20 1 file changed, 25 insertions(+), 33 deletions(-)
22 --- a/drivers/mtd/spi-nor/spi-nor.c
23 +++ b/drivers/mtd/spi-nor/spi-nor.c
24 @@ -988,8 +988,8 @@ static int spi_nor_write(struct mtd_info
25 size_t *retlen, const u_char *buf)
27 struct spi_nor *nor = mtd_to_spi_nor(mtd);
28 - u32 page_offset, page_size, i;
30 + size_t page_offset, page_remain, i;
33 dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
35 @@ -997,45 +997,37 @@ static int spi_nor_write(struct mtd_info
40 + for (i = 0; i < len; ) {
43 - page_offset = to & (nor->page_size - 1);
45 - /* do all the bytes fit onto one page? */
46 - if (page_offset + len <= nor->page_size) {
47 - ret = nor->write(nor, to, len, buf);
52 + page_offset = (to + i) & (nor->page_size - 1);
53 + WARN_ONCE(page_offset,
54 + "Writing at offset %zu into a NOR page. Writing partial pages may decrease reliability and increase wear of NOR flash.",
56 /* the size of data remaining on the first page */
57 - page_size = nor->page_size - page_offset;
58 - ret = nor->write(nor, to, page_size, buf);
59 + page_remain = min_t(size_t,
60 + nor->page_size - page_offset, len - i);
63 + ret = nor->write(nor, to + i, page_remain, buf + i);
69 - /* write everything in nor->page_size chunks */
70 - for (i = ret; i < len; ) {
71 - page_size = len - i;
72 - if (page_size > nor->page_size)
73 - page_size = nor->page_size;
75 - ret = spi_nor_wait_till_ready(nor);
81 - ret = nor->write(nor, to + i, page_size, buf + i);
86 + ret = spi_nor_wait_till_ready(nor);
91 + if (written != page_remain) {
93 + "While writing %zu bytes written %zd bytes\n",
94 + page_remain, written);
100 - ret = spi_nor_wait_till_ready(nor);
102 spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);