struct spi_flash *flash = mtd->priv;
int err;
+ if (!flash)
+ return -ENODEV;
+
instr->state = MTD_ERASING;
err = spi_flash_erase(flash, instr->addr, instr->len);
struct spi_flash *flash = mtd->priv;
int err;
+ if (!flash)
+ return -ENODEV;
+
err = spi_flash_read(flash, from, len, buf);
if (!err)
*retlen = len;
struct spi_flash *flash = mtd->priv;
int err;
+ if (!flash)
+ return -ENODEV;
+
err = spi_flash_write(flash, to, len, buf);
if (!err)
*retlen = len;
{
int ret;
- if (sf_mtd_registered)
- del_mtd_device(&sf_mtd_info);
+ if (sf_mtd_registered) {
+ ret = del_mtd_device(&sf_mtd_info);
+ if (ret)
+ return ret;
+
+ sf_mtd_registered = false;
+ }
sf_mtd_registered = false;
memset(&sf_mtd_info, 0, sizeof(sf_mtd_info));
void spi_flash_mtd_unregister(void)
{
- del_mtd_device(&sf_mtd_info);
+ int ret;
+
+ if (!sf_mtd_registered)
+ return;
+
+ ret = del_mtd_device(&sf_mtd_info);
+ if (!ret) {
+ sf_mtd_registered = false;
+ return;
+ }
+
+ /*
+ * Setting mtd->priv to NULL is the best we can do. Thanks to that,
+ * the MTD layer can still call mtd hooks without risking a
+ * use-after-free bug. Still, things should be fixed to prevent the
+ * spi_flash object from being destroyed when del_mtd_device() fails.
+ */
+ sf_mtd_info.priv = NULL;
+ printf("Failed to unregister MTD %s and the spi_flash object is going away: you're in deep trouble!",
+ sf_mtd_info.name);
}