static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
{
- unsigned long ofs, len;
- int ret;
-
- ofs = instr->addr;
- len = instr->len;
-
- ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL);
- if (ret)
- return ret;
-
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
- return 0;
+ return cfi_varsize_frob(mtd, do_erase_oneblock, instr->addr,
+ instr->len, NULL);
}
static void cfi_intelext_sync (struct mtd_info *mtd)
static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
{
- unsigned long ofs, len;
- int ret;
-
- ofs = instr->addr;
- len = instr->len;
-
- ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL);
- if (ret)
- return ret;
-
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
- return 0;
+ return cfi_varsize_frob(mtd, do_erase_oneblock, instr->addr,
+ instr->len, NULL);
}
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
- int ret = 0;
if (instr->addr != 0)
return -EINVAL;
if (instr->len != mtd->size)
return -EINVAL;
- ret = do_erase_chip(map, &cfi->chips[0]);
- if (ret)
- return ret;
-
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
- return 0;
+ return do_erase_chip(map, &cfi->chips[0]);
}
static int do_atmel_lock(struct map_info *map, struct flchip *chip,
}
}
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
return 0;
}
allff = map_word_ff(map);
for (i=0; i<instr->len; i += map_bankwidth(map))
map_write(map, allff, instr->addr + i);
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
{
struct bcm47xxsflash *b47s = mtd->priv;
- int err;
switch (b47s->type) {
case BCM47XXSFLASH_TYPE_ST:
break;
}
- err = bcm47xxsflash_poll(b47s, HZ);
- if (err)
- erase->state = MTD_ERASE_FAILED;
- else
- erase->state = MTD_ERASE_DONE;
-
- return err;
+ return bcm47xxsflash_poll(b47s, HZ);
}
static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t len = instr->len;
int err;
- instr->state = MTD_ERASING;
mutex_lock(&dev->write_mutex);
err = _block2mtd_erase(dev, from, len);
mutex_unlock(&dev->write_mutex);
- if (err) {
+ if (err)
pr_err("erase failed err = %d\n", err);
- instr->state = MTD_ERASE_FAILED;
- } else
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return err;
}
{
struct docg3 *docg3 = mtd->priv;
uint64_t len;
- int block0, block1, page, ret, ofs = 0;
+ int block0, block1, page, ret = 0, ofs = 0;
doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len);
- info->state = MTD_ERASE_PENDING;
calc_block_sector(info->addr + info->len, &block0, &block1, &page,
&ofs, docg3->reliable);
- ret = -EINVAL;
if (info->addr + info->len > mtd->size || page || ofs)
- goto reset_err;
+ return -EINVAL;
- ret = 0;
calc_block_sector(info->addr, &block0, &block1, &page, &ofs,
docg3->reliable);
mutex_lock(&docg3->cascade->lock);
doc_set_device_id(docg3, docg3->device_id);
doc_set_reliable_mode(docg3);
for (len = info->len; !ret && len > 0; len -= mtd->erasesize) {
- info->state = MTD_ERASING;
ret = doc_erase_block(docg3, block0, block1);
block0 += 2;
block1 += 2;
}
mutex_unlock(&docg3->cascade->lock);
- if (ret)
- goto reset_err;
-
- info->state = MTD_ERASE_DONE;
- return 0;
-
-reset_err:
- info->state = MTD_ERASE_FAILED;
return ret;
}
while (len)
{
if (!erase_block (addr))
- {
- instr->state = MTD_ERASE_FAILED;
return (-EIO);
- }
addr += mtd->eraseregions[i].erasesize;
len -= mtd->eraseregions[i].erasesize;
if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++;
}
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
return (0);
}
}
mutex_unlock(&priv->lock);
- /* Inform MTD subsystem that erase is complete */
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
return 0;
}
if (check_offs_len(mtd, instr->addr, instr->len))
return -EINVAL;
memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
+
return 0;
}
memset(start + instr->addr, 0xff, instr->len);
- /*
- * This'll catch a few races. Free the thing before returning :)
- * I don't feel at all ashamed. This kind of thing is possible anyway
- * with flash, but unlikely.
- */
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
}
out:
- instr->state = MTD_ERASE_DONE;
#ifdef CONFIG_MTD_PMC551_DEBUG
printk(KERN_DEBUG "pmc551_erase() done\n");
#endif
- mtd_erase_callback(instr);
return 0;
}
{
int rc;
- erase->state = MTD_ERASING;
-
- /* todo: register our own notifier to do a true async implementation */
rc = powernv_flash_async_op(mtd, FLASH_OP_ERASE, erase->addr,
erase->len, NULL, NULL);
-
- if (rc) {
+ if (rc)
erase->fail_addr = erase->addr;
- erase->state = MTD_ERASE_FAILED;
- } else {
- erase->state = MTD_ERASE_DONE;
- }
- mtd_erase_callback(erase);
+
return rc;
}
slram_priv_t *priv = mtd->priv;
memset(priv->start + instr->addr, 0xff, instr->len);
- /* This'll catch a few races. Free the thing before returning :)
- * I don't feel at all ashamed. This kind of thing is possible anyway
- * with flash, but unlikely.
- */
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
+
return(0);
}
/* preparing the command for flash */
ret = spear_smi_erase_sector(dev, bank, command, 4);
if (ret) {
- e_info->state = MTD_ERASE_FAILED;
mutex_unlock(&flash->lock);
return ret;
}
}
mutex_unlock(&flash->lock);
- e_info->state = MTD_ERASE_DONE;
- mtd_erase_callback(e_info);
return 0;
}
err = sst25l_erase_sector(flash, addr);
if (err) {
mutex_unlock(&flash->lock);
- instr->state = MTD_ERASE_FAILED;
dev_err(&flash->spi->dev, "Erase failed\n");
return err;
}
mutex_unlock(&flash->lock);
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
mutex_unlock(&fsm->lock);
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
return 0;
out1:
- instr->state = MTD_ERASE_FAILED;
mutex_unlock(&fsm->lock);
return ret;
*/
static int lpddr2_nvm_erase(struct mtd_info *mtd, struct erase_info *instr)
{
- int ret = lpddr2_nvm_do_block_op(mtd, instr->addr, instr->len,
- LPDDR2_NVM_ERASE);
- if (!ret) {
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
- }
-
- return ret;
+ return lpddr2_nvm_do_block_op(mtd, instr->addr, instr->len,
+ LPDDR2_NVM_ERASE);
}
/*
ofs += size;
len -= size;
}
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
erase->addr = 0;
offset += subdev->size;
}
- instr->state = erase->state;
kfree(erase);
return err;
if (!(mtd->flags & MTD_WRITEABLE))
return -EROFS;
- if (!instr->len) {
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
+ if (!instr->len)
return 0;
- }
+
ledtrig_mtd_activity();
return mtd->_erase(mtd, instr);
}
return ret;
}
-void mtd_erase_callback(struct erase_info *instr)
-{
-}
-EXPORT_SYMBOL_GPL(mtd_erase_callback);
-
static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct mtd_part *part = mtd_to_part(mtd);
if (nand_check_wp(mtd)) {
pr_debug("%s: device is write protected!\n",
__func__);
- instr->state = MTD_ERASE_FAILED;
+ ret = -EIO;
goto erase_exit;
}
/* Loop through the pages */
len = instr->len;
- instr->state = MTD_ERASING;
-
while (len) {
/* Check if we have a bad block, we do not erase bad blocks! */
if (nand_block_checkbad(mtd, ((loff_t) page) <<
chip->page_shift, allowbbt)) {
pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
__func__, page);
- instr->state = MTD_ERASE_FAILED;
+ ret = -EIO;
goto erase_exit;
}
if (status) {
pr_debug("%s: failed erase, page 0x%08x\n",
__func__, page);
- instr->state = MTD_ERASE_FAILED;
+ ret = -EIO;
instr->fail_addr =
((loff_t)page << chip->page_shift);
goto erase_exit;
chip->select_chip(mtd, chipnr);
}
}
- instr->state = MTD_ERASE_DONE;
+ ret = 0;
erase_exit:
- ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
-
/* Deselect and wake up anyone waiting on the device */
chip->select_chip(mtd, -1);
nand_release_device(mtd);
- /* Do call back function */
- if (!ret)
- mtd_erase_callback(instr);
-
/* Return more or less happy */
return ret;
}
if (ret) {
printk(KERN_ERR "%s: Failed verify, block %d\n",
__func__, onenand_block(this, addr));
- instr->state = MTD_ERASE_FAILED;
instr->fail_addr = addr;
return -1;
}
int ret = 0;
int bdry_block = 0;
- instr->state = MTD_ERASING;
-
if (ONENAND_IS_DDP(this)) {
loff_t bdry_addr = this->chipsize >> 1;
if (addr < bdry_addr && (addr + len) > bdry_addr)
printk(KERN_WARNING "%s: attempt to erase a bad block "
"at addr 0x%012llx\n",
__func__, (unsigned long long) addr);
- instr->state = MTD_ERASE_FAILED;
return -EIO;
}
len -= block_size;
printk(KERN_ERR "%s: Failed multiblock erase, "
"block %d\n", __func__,
onenand_block(this, addr));
- instr->state = MTD_ERASE_FAILED;
instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
return -EIO;
}
if (ret) {
printk(KERN_ERR "%s: Failed erase, block %d\n",
__func__, onenand_block(this, addr));
- instr->state = MTD_ERASE_FAILED;
instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
return -EIO;
}
/* verify */
verify_instr.len = eb_count * block_size;
if (onenand_multiblock_erase_verify(mtd, &verify_instr)) {
- instr->state = verify_instr.state;
instr->fail_addr = verify_instr.fail_addr;
return -EIO;
}
region_end = region->offset + region->erasesize * region->numblocks;
}
- instr->state = MTD_ERASING;
-
/* Loop through the blocks */
while (len) {
cond_resched();
printk(KERN_WARNING "%s: attempt to erase a bad block "
"at addr 0x%012llx\n",
__func__, (unsigned long long) addr);
- instr->state = MTD_ERASE_FAILED;
return -EIO;
}
if (ret) {
printk(KERN_ERR "%s: Failed erase, block %d\n",
__func__, onenand_block(this, addr));
- instr->state = MTD_ERASE_FAILED;
instr->fail_addr = addr;
return -EIO;
}
/* Deselect and wake up anyone waiting on the device */
onenand_release_device(mtd);
- /* Do call back function */
- if (!ret) {
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
- }
-
return ret;
}
erase_err:
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
- instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
return ret;
}
if (err)
goto out_err;
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
out_err:
- instr->state = MTD_ERASE_FAILED;
instr->fail_addr = (long long)lnum * mtd->erasesize;
return err;
}
static int ef4_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
{
struct ef4_nic *efx = mtd->priv;
- int rc;
- rc = efx->type->mtd_erase(mtd, erase->addr, erase->len);
- if (rc == 0) {
- erase->state = MTD_ERASE_DONE;
- } else {
- erase->state = MTD_ERASE_FAILED;
- erase->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
- }
- mtd_erase_callback(erase);
- return rc;
+ return efx->type->mtd_erase(mtd, erase->addr, erase->len);
}
static void ef4_mtd_sync(struct mtd_info *mtd)
static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
{
struct efx_nic *efx = mtd->priv;
- int rc;
- rc = efx->type->mtd_erase(mtd, erase->addr, erase->len);
- if (rc == 0) {
- erase->state = MTD_ERASE_DONE;
- } else {
- erase->state = MTD_ERASE_FAILED;
- erase->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
- }
- mtd_erase_callback(erase);
- return rc;
+ return efx->type->mtd_erase(mtd, erase->addr, erase->len);
}
static void efx_mtd_sync(struct mtd_info *mtd)
return -EIO;
}
- instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
return 0;
invalid_arg:
#include <asm/div64.h>
-#define MTD_ERASE_PENDING 0x01
-#define MTD_ERASING 0x02
-#define MTD_ERASE_SUSPEND 0x04
-#define MTD_ERASE_DONE 0x08
-#define MTD_ERASE_FAILED 0x10
-
#define MTD_FAIL_ADDR_UNKNOWN -1LL
struct mtd_info;
uint64_t addr;
uint64_t len;
uint64_t fail_addr;
- u_char state;
};
struct mtd_erase_region_info {
extern int unregister_mtd_user (struct mtd_notifier *old);
void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
-void mtd_erase_callback(struct erase_info *instr);
-
static inline int mtd_is_bitflip(int err) {
return err == -EUCLEAN;
}