Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'spi-nor/for-6.18' into mtd/next

SPI NOR changes for 6.18

Notable changes:

- Some flashes can't perform reads or writes with start or end being an
odd number in Octal DTR mode. File systems like UBIFS can request such
reads or writes, causing the transaction to error out. Pad the read or
write transactions with extra bytes to avoid this problem.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

+143 -2
+143 -2
drivers/mtd/spi-nor/core.c
··· 2014 2014 return info; 2015 2015 } 2016 2016 2017 + /* 2018 + * On Octal DTR capable flashes, reads cannot start or end at an odd 2019 + * address in Octal DTR mode. Extra bytes need to be read at the start 2020 + * or end to make sure both the start address and length remain even. 2021 + */ 2022 + static int spi_nor_octal_dtr_read(struct spi_nor *nor, loff_t from, size_t len, 2023 + u_char *buf) 2024 + { 2025 + u_char *tmp_buf; 2026 + size_t tmp_len; 2027 + loff_t start, end; 2028 + int ret, bytes_read; 2029 + 2030 + if (IS_ALIGNED(from, 2) && IS_ALIGNED(len, 2)) 2031 + return spi_nor_read_data(nor, from, len, buf); 2032 + else if (IS_ALIGNED(from, 2) && len > PAGE_SIZE) 2033 + return spi_nor_read_data(nor, from, round_down(len, PAGE_SIZE), 2034 + buf); 2035 + 2036 + tmp_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 2037 + if (!tmp_buf) 2038 + return -ENOMEM; 2039 + 2040 + start = round_down(from, 2); 2041 + end = round_up(from + len, 2); 2042 + 2043 + /* 2044 + * Avoid allocating too much memory. The requested read length might be 2045 + * quite large. Allocating a buffer just as large (slightly bigger, in 2046 + * fact) would put unnecessary memory pressure on the system. 2047 + * 2048 + * For example if the read is from 3 to 1M, then this will read from 2 2049 + * to 4098. The reads from 4098 to 1M will then not need a temporary 2050 + * buffer so they can proceed as normal. 2051 + */ 2052 + tmp_len = min_t(size_t, end - start, PAGE_SIZE); 2053 + 2054 + ret = spi_nor_read_data(nor, start, tmp_len, tmp_buf); 2055 + if (ret == 0) { 2056 + ret = -EIO; 2057 + goto out; 2058 + } 2059 + if (ret < 0) 2060 + goto out; 2061 + 2062 + /* 2063 + * More bytes are read than actually requested, but that number can't be 2064 + * reported to the calling function or it will confuse its calculations. 2065 + * Calculate how many of the _requested_ bytes were read. 2066 + */ 2067 + bytes_read = ret; 2068 + 2069 + if (from != start) 2070 + ret -= from - start; 2071 + 2072 + /* 2073 + * Only account for extra bytes at the end if they were actually read. 2074 + * For example, if the total length was truncated because of temporary 2075 + * buffer size limit then the adjustment for the extra bytes at the end 2076 + * is not needed. 2077 + */ 2078 + if (start + bytes_read == end) 2079 + ret -= end - (from + len); 2080 + 2081 + memcpy(buf, tmp_buf + (from - start), ret); 2082 + out: 2083 + kfree(tmp_buf); 2084 + return ret; 2085 + } 2086 + 2017 2087 static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, 2018 2088 size_t *retlen, u_char *buf) 2019 2089 { ··· 2101 2031 while (len) { 2102 2032 loff_t addr = from; 2103 2033 2104 - ret = spi_nor_read_data(nor, addr, len, buf); 2034 + if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) 2035 + ret = spi_nor_octal_dtr_read(nor, addr, len, buf); 2036 + else 2037 + ret = spi_nor_read_data(nor, addr, len, buf); 2038 + 2105 2039 if (ret == 0) { 2106 2040 /* We shouldn't see 0-length reads */ 2107 2041 ret = -EIO; ··· 2125 2051 read_err: 2126 2052 spi_nor_unlock_and_unprep_rd(nor, from_lock, len_lock); 2127 2053 2054 + return ret; 2055 + } 2056 + 2057 + /* 2058 + * On Octal DTR capable flashes, writes cannot start or end at an odd address 2059 + * in Octal DTR mode. Extra 0xff bytes need to be appended or prepended to 2060 + * make sure the start address and end address are even. 0xff is used because 2061 + * on NOR flashes a program operation can only flip bits from 1 to 0, not the 2062 + * other way round. 0 to 1 flip needs to happen via erases. 2063 + */ 2064 + static int spi_nor_octal_dtr_write(struct spi_nor *nor, loff_t to, size_t len, 2065 + const u8 *buf) 2066 + { 2067 + u8 *tmp_buf; 2068 + size_t bytes_written; 2069 + loff_t start, end; 2070 + int ret; 2071 + 2072 + if (IS_ALIGNED(to, 2) && IS_ALIGNED(len, 2)) 2073 + return spi_nor_write_data(nor, to, len, buf); 2074 + 2075 + tmp_buf = kmalloc(nor->params->page_size, GFP_KERNEL); 2076 + if (!tmp_buf) 2077 + return -ENOMEM; 2078 + 2079 + memset(tmp_buf, 0xff, nor->params->page_size); 2080 + 2081 + start = round_down(to, 2); 2082 + end = round_up(to + len, 2); 2083 + 2084 + memcpy(tmp_buf + (to - start), buf, len); 2085 + 2086 + ret = spi_nor_write_data(nor, start, end - start, tmp_buf); 2087 + if (ret == 0) { 2088 + ret = -EIO; 2089 + goto out; 2090 + } 2091 + if (ret < 0) 2092 + goto out; 2093 + 2094 + /* 2095 + * More bytes are written than actually requested, but that number can't 2096 + * be reported to the calling function or it will confuse its 2097 + * calculations. Calculate how many of the _requested_ bytes were 2098 + * written. 2099 + */ 2100 + bytes_written = ret; 2101 + 2102 + if (to != start) 2103 + ret -= to - start; 2104 + 2105 + /* 2106 + * Only account for extra bytes at the end if they were actually 2107 + * written. For example, if for some reason the controller could only 2108 + * complete a partial write then the adjustment for the extra bytes at 2109 + * the end is not needed. 2110 + */ 2111 + if (start + bytes_written == end) 2112 + ret -= end - (to + len); 2113 + 2114 + out: 2115 + kfree(tmp_buf); 2128 2116 return ret; 2129 2117 } 2130 2118 ··· 2226 2090 goto write_err; 2227 2091 } 2228 2092 2229 - ret = spi_nor_write_data(nor, addr, page_remain, buf + i); 2093 + if (nor->write_proto == SNOR_PROTO_8_8_8_DTR) 2094 + ret = spi_nor_octal_dtr_write(nor, addr, page_remain, 2095 + buf + i); 2096 + else 2097 + ret = spi_nor_write_data(nor, addr, page_remain, 2098 + buf + i); 2230 2099 spi_nor_unlock_device(nor); 2231 2100 if (ret < 0) 2232 2101 goto write_err;