I/O errors from do_erase_oneblock()
jfaslist
jfaslist at yahoo.fr
Wed May 31 07:35:31 EDT 2006
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
More information about the linux-mtd
mailing list