
On Tue, Jan 30, 2024 at 10:14:16AM +0530, Venkatesh Yadav Abbarapu wrote:
@@ -1444,28 +1465,66 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, { struct spi_nor *nor = mtd_to_spi_nor(mtd); int ret;
- u32 offset = from;
Declare offset as loff_t otherwise it's limited to 4GB. I don't know if we support more than 4GB here but it's just weird and forces us to add casts later...
- u32 stack_shift = 0;
This variable is never used.
- u32 read_len = 0;
- u32 rem_bank_len = 0;
- u8 bank;
- u8 is_ofst_odd = 0;
If you wanted, you could make this bool true/false.
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
- if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
/* We can hit this case when we use file system like ubifs */
from = (loff_t)(from - 1);
len = (size_t)(len + 1);
These casts are unnecessary. Just write:
from--; len++;
is_ofst_odd = 1;
- }
- while (len) {
loff_t addr = from;
size_t read_len = len;
if (nor->addr_width == 3) {
if (nor->flags & SNOR_F_HAS_PARALLEL) {
bank = (u32)from / (SZ_16M << 0x01);
rem_bank_len = ((SZ_16M << 0x01) *
(bank + 1)) - from;
} else {
bank = (u32)from / SZ_16M;
rem_bank_len = (SZ_16M * (bank + 1)) - from;
}
}
If nor->addr_width != 3 then rem_bank_len is zero and I think we're going to have a problem...
offset = from;
if (nor->flags & SNOR_F_HAS_STACKED) {
stack_shift = 1;
if (offset >= (mtd->size / 2)) {
offset = offset - (mtd->size / 2);
nor->spi->flags |= SPI_XFER_U_PAGE;
} else {
nor->spi->flags &= ~SPI_XFER_U_PAGE;
}
}
-#ifdef CONFIG_SPI_FLASH_BAR
u32 remain_len;
if (nor->flags & SNOR_F_HAS_PARALLEL)
offset /= 2;
ret = write_bar(nor, addr);
if (ret < 0)
return log_ret(ret);
remain_len = (SZ_16M * (nor->bank_curr + 1)) - addr;
if (nor->addr_width == 3) {
+#ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, offset);
if (ret < 0)
return log_ret(ret);
+#endif
}
if (len < remain_len)
elseif (len < rem_bank_len) read_len = len;
read_len = remain_len;
-#endif
read_len = rem_bank_len;
If rem_bank_len is zero then read_len is zero.
ret = spi_nor_wait_till_ready(nor);
if (ret)
goto read_err;
ret = nor->read(nor, addr, read_len, buf);
if (ret == 0) { /* We shouldn't see 0-length reads */ ret = -EIO;ret = nor->read(nor, offset, read_len, buf);
When read_len is zero we return -EIO.
@@ -1474,8 +1533,15 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, if (ret < 0) goto read_err;
*retlen += ret;
buf += ret;
if (is_ofst_odd == 1) {
memcpy(buf, (buf + 1), (len - 1));
This needs to be memmove(). memcpy() is undefined for overlapped buffers.
*retlen += (ret - 1);
buf += ret - 1;
is_ofst_odd = 0;
} else {
*retlen += ret;
buf += ret;
from += ret; len -= ret; }}
regards, dan carpenter