chipstatus = status.x[0]; if (!map_word_equal(map, status, CMD(chipstatus))) { int i, w; for (w=0; w<map_words(map); w++) { for (i = 0; i<cfi_interleave(cfi); i++) { chipstatus |= status.x[w] >> (cfi->device_type * 8); } } printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n", status.x[0], chipstatus); } 
chipstatus = MERGESTATUS(status); 
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;	map_word status, status_OK;	unsigned long timeo;	int retries = 3;	DECLARE_WAITQUEUE(wait, current);	int ret = 0;	adr += chip->start;	/* Let's determine this according to the interleave only once */	status_OK = CMD(0x80); retry:	spin_lock(chip->mutex);	ret = get_chip(map, chip, adr, FL_ERASING);	if (ret) {		spin_unlock(chip->mutex);		return ret;	}	XIP_INVAL_CACHED_RANGE(map, adr, len);	ENABLE_VPP(map);	xip_disable(map, chip, adr);	/* Clear the status register first */	map_write(map, CMD(0x50), adr);	/* Now erase */	map_write(map, CMD(0x20), adr);	map_write(map, CMD(0xD0), adr);	chip->state = FL_ERASING;	chip->erase_suspended = 0;	spin_unlock(chip->mutex);	INVALIDATE_CACHED_RANGE(map, adr, len);	UDELAY(map, chip, adr, chip->erase_time*1000/2);	spin_lock(chip->mutex);	/* FIXME. Use a timer to check this, and return immediately. */	/* Once the state machine's known to be working I'll do that */	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;		}		status = map_read(map, adr);		if (map_word_andequal(map, status, status_OK, status_OK))			break;				/* OK Still waiting */		if (time_after(jiffies, timeo)) {			map_word Xstatus;			map_write(map, CMD(0x70), adr);			chip->state = FL_STATUS;			Xstatus = map_read(map, adr);			/* Clear status bits */			map_write(map, CMD(0x50), adr);			map_write(map, CMD(0x70), adr);			xip_enable(map, chip, adr);			printk(KERN_ERR "waiting for erase at %08lx to complete timed out. status = %lx, Xstatus = %lx.\n",			       adr, status.x[0], Xstatus.x[0]);			ret = -EIO;			goto out;		}				/* Latency issues. Drop the lock, wait a while and retry */		spin_unlock(chip->mutex);		UDELAY(map, chip, adr, 1000000/HZ);		spin_lock(chip->mutex);	}	/* We've broken this before. It doesn't hurt to be safe */	map_write(map, CMD(0x70), adr);	chip->state = FL_STATUS;	status = map_read(map, adr);	/* check for lock bit */	if (map_word_bitsset(map, status, CMD(0x3a))) {		unsigned char chipstatus;		/* Reset the error bits */		map_write(map, CMD(0x50), adr);		map_write(map, CMD(0x70), adr);		xip_enable(map, chip, adr);		chipstatus = status.x[0];		if (!map_word_equal(map, status, CMD(chipstatus))) {			int i, w;			for (w=0; w<map_words(map); w++) {				for (i = 0; i<cfi_interleave(cfi); i++) {					chipstatus |= status.x[w] >> (cfi->device_type * 8);				}			}			printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n",			       status.x[0], chipstatus);		}		if ((chipstatus & 0x30) == 0x30) {			printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);			ret = -EIO;		} else if (chipstatus & 0x02) {			/* Protection bit set */			ret = -EROFS;		} else if (chipstatus & 0x8) {			/* Voltage */			printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus);			ret = -EIO;		} else if (chipstatus & 0x20) {			if (retries--) {				printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus);				timeo = jiffies + HZ;				put_chip(map, chip, adr);				spin_unlock(chip->mutex);				goto retry;			}			printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus);			ret = -EIO;		}	} else {		xip_enable(map, chip, adr);		ret = 0;	} out:	put_chip(map, chip, adr);	spin_unlock(chip->mutex);	return ret;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/3a70025047f90de2133744a8918e90fcf5a93366/cfi_cmdset_0001.c/clean/drivers/mtd/chips/cfi_cmdset_0001.c