flash: spi_nor: error-checking fixes

Check the return values of commands such as spi_nor_cmd_* and
spi_nor_wait_until_ready and ensure they are propagated back to the
caller on error.

Signed-off-by: Robert Hancock <robert.hancock@calian.com>
This commit is contained in:
Robert Hancock 2024-02-05 16:51:15 -06:00 committed by Anas Nashif
parent c026b55fe5
commit 1af474b575

View file

@ -624,13 +624,15 @@ static int spi_nor_wrsr(const struct device *dev,
{ {
int ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN); int ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN);
if (ret == 0) { if (ret != 0) {
ret = spi_nor_access(dev, SPI_NOR_CMD_WRSR, NOR_ACCESS_WRITE, 0, &sr, return ret;
sizeof(sr));
spi_nor_wait_until_ready(dev, WAIT_READY_REGISTER);
} }
ret = spi_nor_access(dev, SPI_NOR_CMD_WRSR, NOR_ACCESS_WRITE, 0, &sr,
return ret; sizeof(sr));
if (ret != 0) {
return ret;
}
return spi_nor_wait_until_ready(dev, WAIT_READY_REGISTER);
} }
#if ANY_INST_HAS_MXICY_MX25R_POWER_MODE #if ANY_INST_HAS_MXICY_MX25R_POWER_MODE
@ -692,18 +694,23 @@ static int mxicy_wrcr(const struct device *dev,
} }
ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN); ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN);
if (ret != 0) {
if (ret == 0) { return ret;
uint8_t data[] = {
sr,
cr & 0xFF, /* Configuration register 1 */
cr >> 8 /* Configuration register 2 */
};
ret = spi_nor_access(dev, SPI_NOR_CMD_WRSR, NOR_ACCESS_WRITE, 0,
data, sizeof(data));
spi_nor_wait_until_ready(dev, WAIT_READY_REGISTER);
} }
uint8_t data[] = {
sr,
cr & 0xFF, /* Configuration register 1 */
cr >> 8 /* Configuration register 2 */
};
ret = spi_nor_access(dev, SPI_NOR_CMD_WRSR, NOR_ACCESS_WRITE, 0,
data, sizeof(data));
if (ret != 0) {
return ret;
}
ret = spi_nor_wait_until_ready(dev, WAIT_READY_REGISTER);
} }
return ret; return ret;
@ -851,7 +858,10 @@ static int spi_nor_write(const struct device *dev, off_t addr,
src = (const uint8_t *)src + to_write; src = (const uint8_t *)src + to_write;
addr += to_write; addr += to_write;
spi_nor_wait_until_ready(dev, WAIT_READY_WRITE); ret = spi_nor_wait_until_ready(dev, WAIT_READY_WRITE);
if (ret != 0) {
break;
}
} }
} }
@ -889,11 +899,14 @@ static int spi_nor_erase(const struct device *dev, off_t addr, size_t size)
ret = spi_nor_write_protection_set(dev, false); ret = spi_nor_write_protection_set(dev, false);
while ((size > 0) && (ret == 0)) { while ((size > 0) && (ret == 0)) {
spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN); ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN);
if (ret) {
break;
}
if (size == flash_size) { if (size == flash_size) {
/* chip erase */ /* chip erase */
spi_nor_cmd_write(dev, SPI_NOR_CMD_CE); ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_CE);
size -= flash_size; size -= flash_size;
} else { } else {
const struct jesd216_erase_type *erase_types = const struct jesd216_erase_type *erase_types =
@ -913,7 +926,7 @@ static int spi_nor_erase(const struct device *dev, off_t addr, size_t size)
} }
} }
if (bet != NULL) { if (bet != NULL) {
spi_nor_cmd_addr_write(dev, bet->cmd, addr, NULL, 0); ret = spi_nor_cmd_addr_write(dev, bet->cmd, addr, NULL, 0);
addr += BIT(bet->exp); addr += BIT(bet->exp);
size -= BIT(bet->exp); size -= BIT(bet->exp);
} else { } else {
@ -922,18 +935,11 @@ static int spi_nor_erase(const struct device *dev, off_t addr, size_t size)
ret = -EINVAL; ret = -EINVAL;
} }
} }
if (ret != 0) {
break;
}
#ifdef __XCC__ ret = spi_nor_wait_until_ready(dev, WAIT_READY_ERASE);
/*
* FIXME: remove this hack once XCC is fixed.
*
* Without this volatile return value, XCC would segfault
* compiling this file complaining about failure in CGPREP
* phase.
*/
volatile int xcc_ret =
#endif
spi_nor_wait_until_ready(dev, WAIT_READY_ERASE);
} }
int ret2 = spi_nor_write_protection_set(dev, true); int ret2 = spi_nor_write_protection_set(dev, true);
@ -1321,9 +1327,13 @@ static int spi_nor_configure(const struct device *dev)
rc = spi_nor_rdsr(dev); rc = spi_nor_rdsr(dev);
if (rc > 0 && (rc & SPI_NOR_WIP_BIT)) { if (rc > 0 && (rc & SPI_NOR_WIP_BIT)) {
LOG_WRN("Waiting until flash is ready"); LOG_WRN("Waiting until flash is ready");
spi_nor_wait_until_ready(dev, WAIT_READY_REGISTER); rc = spi_nor_wait_until_ready(dev, WAIT_READY_REGISTER);
} }
release_device(dev); release_device(dev);
if (rc < 0) {
LOG_ERR("Failed to wait until flash is ready (%d)", rc);
return -ENODEV;
}
/* now the spi bus is configured, we can verify SPI /* now the spi bus is configured, we can verify SPI
* connectivity by reading the JEDEC ID. * connectivity by reading the JEDEC ID.