Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 884cfd90 authored by Boris Brezillon's avatar Boris Brezillon
Browse files

mtd: Stop assuming mtd_erase() is asynchronous



None of the mtd->_erase() implementations work in an asynchronous manner,
so let's simplify MTD users that call mtd_erase(). All they need to do
is check the value returned by mtd_erase() and assume that != 0 means
failure.

Signed-off-by: default avatarBoris Brezillon <boris.brezillon@bootlin.com>
Reviewed-by: default avatarRichard Weinberger <richard@nod.at>
parent dcba51bb
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -95,9 +95,6 @@ static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
	else
		erase->state = MTD_ERASE_DONE;

	if (erase->callback)
		erase->callback(erase);

	return err;
}

+8 −43
Original line number Diff line number Diff line
@@ -140,12 +140,6 @@ typedef struct partition_t {
#define XFER_PREPARED	0x03
#define XFER_FAILED	0x04

/*====================================================================*/


static void ftl_erase_callback(struct erase_info *done);


/*======================================================================

    Scan_header() checks to see if a memory region contains an FTL
@@ -349,16 +343,18 @@ static int erase_xfer(partition_t *part,
            return -ENOMEM;

    erase->mtd = part->mbd.mtd;
    erase->callback = ftl_erase_callback;
    erase->addr = xfer->Offset;
    erase->len = 1 << part->header.EraseUnitSize;
    erase->priv = (u_long)part;

    ret = mtd_erase(part->mbd.mtd, erase);

    if (!ret)
    if (!ret) {
	xfer->state = XFER_ERASED;
	xfer->EraseCount++;
    else
    } else {
	xfer->state = XFER_FAILED;
	pr_notice("ftl_cs: erase failed: err = %d\n", ret);
    }

    kfree(erase);

    return ret;
@@ -371,37 +367,6 @@ static int erase_xfer(partition_t *part,

======================================================================*/

static void ftl_erase_callback(struct erase_info *erase)
{
    partition_t *part;
    struct xfer_info_t *xfer;
    int i;

    /* Look up the transfer unit */
    part = (partition_t *)(erase->priv);

    for (i = 0; i < part->header.NumTransferUnits; i++)
	if (part->XferInfo[i].Offset == erase->addr) break;

    if (i == part->header.NumTransferUnits) {
	printk(KERN_NOTICE "ftl_cs: internal error: "
	       "erase lookup failed!\n");
	return;
    }

    xfer = &part->XferInfo[i];
    if (erase->state == MTD_ERASE_DONE)
	xfer->state = XFER_ERASED;
    else {
	xfer->state = XFER_FAILED;
	printk(KERN_NOTICE "ftl_cs: erase failed: state = %d\n",
	       erase->state);
    }

    kfree(erase);

} /* ftl_erase_callback */

static int prepare_xfer(partition_t *part, int i)
{
    erase_unit_header_t header;
+3 −2
Original line number Diff line number Diff line
@@ -393,9 +393,10 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
	   mark only the failed block in the bbt. */
	for (physblock = 0; physblock < inftl->EraseSize;
	     physblock += instr->len, instr->addr += instr->len) {
		mtd_erase(inftl->mbd.mtd, instr);
		int ret;

		if (instr->state == MTD_ERASE_FAILED) {
		ret = mtd_erase(inftl->mbd.mtd, instr);
		if (ret) {
			printk(KERN_WARNING "INFTL: error while formatting block %d\n",
				block);
			goto fail;
+0 −20
Original line number Diff line number Diff line
@@ -55,48 +55,28 @@ struct mtdblk_dev {
 * being written to until a different sector is required.
 */

static void erase_callback(struct erase_info *done)
{
	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
	wake_up(wait_q);
}

static int erase_write (struct mtd_info *mtd, unsigned long pos,
			int len, const char *buf)
{
	struct erase_info erase;
	DECLARE_WAITQUEUE(wait, current);
	wait_queue_head_t wait_q;
	size_t retlen;
	int ret;

	/*
	 * First, let's erase the flash block.
	 */

	init_waitqueue_head(&wait_q);
	erase.mtd = mtd;
	erase.callback = erase_callback;
	erase.addr = pos;
	erase.len = len;
	erase.priv = (u_long)&wait_q;

	set_current_state(TASK_INTERRUPTIBLE);
	add_wait_queue(&wait_q, &wait);

	ret = mtd_erase(mtd, &erase);
	if (ret) {
		set_current_state(TASK_RUNNING);
		remove_wait_queue(&wait_q, &wait);
		printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "
				     "on \"%s\" failed\n",
			pos, len, mtd->name);
		return ret;
	}

	schedule();  /* Wait for erase to finish. */
	remove_wait_queue(&wait_q, &wait);

	/*
	 * Next, write the data to flash.
	 */
+1 −32
Original line number Diff line number Diff line
@@ -324,10 +324,6 @@ static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t c
    IOCTL calls for getting device parameters.

======================================================================*/
static void mtdchar_erase_callback (struct erase_info *instr)
{
	wake_up((wait_queue_head_t *)instr->priv);
}

static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
{
@@ -709,11 +705,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
		if (!erase)
			ret = -ENOMEM;
		else {
			wait_queue_head_t waitq;
			DECLARE_WAITQUEUE(wait, current);

			init_waitqueue_head(&waitq);

			if (cmd == MEMERASE64) {
				struct erase_info_user64 einfo64;

@@ -736,30 +727,8 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
				erase->len = einfo32.length;
			}
			erase->mtd = mtd;
			erase->callback = mtdchar_erase_callback;
			erase->priv = (unsigned long)&waitq;

			/*
			  FIXME: Allow INTERRUPTIBLE. Which means
			  not having the wait_queue head on the stack.

			  If the wq_head is on the stack, and we
			  leave because we got interrupted, then the
			  wq_head is no longer there when the
			  callback routine tries to wake us up.
			*/
			ret = mtd_erase(mtd, erase);
			if (!ret) {
				set_current_state(TASK_UNINTERRUPTIBLE);
				add_wait_queue(&waitq, &wait);
				if (erase->state != MTD_ERASE_DONE &&
				    erase->state != MTD_ERASE_FAILED)
					schedule();
				remove_wait_queue(&waitq, &wait);
				set_current_state(TASK_RUNNING);

				ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0;
			}
			kfree(erase);
		}
		break;
Loading