public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
From: jfaslist <jfaslist@yahoo.fr>
To: linux-mtd@lists.infradead.org
Subject: I/O errors from do_erase_oneblock()
Date: Wed, 31 May 2006 13:35:31 +0200	[thread overview]
Message-ID: <447D7F83.1000500@yahoo.fr> (raw)

Hi,
I have a question on the chips/cfi_cmdset0002.c:do_erase_oneblock()  
function (see below). It is probably a stupid question but I can't find 
the answer:

-What is the use of  INVALIDATE_CACHE_UDELAY (seems to be just a call to 
cfi_udelay() ) . I guess I don't understand the reason for having this 
delay, plus the HZ*20 delay in the following for(;;) loop.
-After the function do a "add_wait_queue" and "schedule", what code is 
going to send a "wake_up()" to end the wait?

My problem is that on erase, I get I/O errors coming  from this 
function. I have added call to cfi_udelay() (up to 12ms) and that seems 
to solve the problem (even though ST Micro claims worst case is 6ms). 
But I  prefer to understand what's going on. I have a suspicion that 
chip_ready() may be ending the for(;;) loop too soon causing chip_good() 
to fail.

My geometry is:
-interleave = 4
-bankwidth = 8 (64b)
p/n = ST MICRO M29DW640

I use the  MTD code from linux-2.6.15

Thanks for the help,
-jf simon


static int __xipram do_erase_oneblock(struct map_info *map, struct 
flchip *chip, unsigned long adr, int len, void *thunk)
{
        struct cfi_private *cfi = map->fldrv_priv;
        unsigned long timeo = jiffies + HZ;
        DECLARE_WAITQUEUE(wait, current);
        int ret = 0;

        adr += chip->start;

        spin_lock(chip->mutex);
        ret = get_chip(map, chip, adr, FL_ERASING);
        if (ret) {
                spin_unlock(chip->mutex);
                return ret;
        }

        DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
               __func__, adr );

        XIP_INVAL_CACHED_RANGE(map, adr, len);
        ENABLE_VPP(map);
        xip_disable(map, chip, adr);

        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, 
cfi->device_type, NULL);
        cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, 
cfi->device_type, NULL);
        map_write(map, CMD(0x30), adr);

        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
        chip->in_progress_block_addr = adr;
 

     INVALIDATE_CACHE_UDELAY(map, chip,
                                adr, len,
                                chip->erase_time*500);

        timeo = jiffies + (HZ*20);

        for (;;) {
                if (chip->state != FL_ERASING) {
                        /* Someone's suspended the erase. Sleep */
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
                        spin_unlock(chip->mutex);
                        schedule();
                        remove_wait_queue(&chip->wq, &wait);
                        spin_lock(chip->mutex);
                        continue;
                }
                if (chip->erase_suspended) {
                        /* This erase was suspended and resumed.
                           Adjust the timeout */
                        timeo = jiffies + (HZ*20); /* FIXME */
                        chip->erase_suspended = 0;
                }

                if (chip_ready(map, adr)) {
                        xip_enable(map, chip, adr);
                        break;
                }

                if (time_after(jiffies, timeo)) {
                        xip_enable(map, chip, adr);
                        printk(KERN_WARNING "MTD %s(): software timeout\n",
                                __func__ );
                        break;
                }

                /* Latency issues. Drop the lock, wait a while and retry */
                UDELAY(map, chip, adr, 1000000/HZ);
        }
        /* Did we succeed? */
        if (!chip_good(map, adr, map_word_ff(map))) {
                /* reset on all failures. */
                map_write( map, CMD(0xF0), chip->start );
                /* FIXME - should have reset delay before continuing */

                ret = -EIO;
        }

        chip->state = FL_READY;
        put_chip(map, chip, adr);
        spin_unlock(chip->mutex);
        return ret;
}

                                    


	

	
		
___________________________________________________________________________ 
Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son interface révolutionnaire.
http://fr.mail.yahoo.com

                 reply	other threads:[~2006-05-31 11:36 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=447D7F83.1000500@yahoo.fr \
    --to=jfaslist@yahoo.fr \
    --cc=linux-mtd@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox