mtd/drivers/mtd/chips cfi_cmdset_0001.c,1.142,1.143

Nicolas Pitre nico at infradead.org
Wed Jun 9 14:35:54 EDT 2004


Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv27991/drivers/mtd/chips

Modified Files:
	cfi_cmdset_0001.c 
Log Message:
No, I'm nuts.  My curent approach for L18 support is getting more
and more messy as I consider all the details that were still missing
and needed extra mods here and there.  When I can't stand my own code
anymore that's a sign that the whole thing should be scrapped.  And
this commit is exactly that.  Stay tuned for an alternate approach. 


Index: cfi_cmdset_0001.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0001.c,v
retrieving revision 1.142
retrieving revision 1.143
diff -u -r1.142 -r1.143
--- cfi_cmdset_0001.c	8 Jun 2004 21:26:21 -0000	1.142
+++ cfi_cmdset_0001.c	9 Jun 2004 18:35:51 -0000	1.143
@@ -216,35 +216,10 @@
 	}
 
 	for (i=0; i< cfi->numchips; i++) {
-		struct flchip *chip = &cfi->chips[i];
-		chip->word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
-		chip->buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
-		chip->erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
-		chip->ref_point_counter = 0;
-
-		/*
-		 * Probing of multi-partition flash ships.
-		 * This is extremely crude at the moment and should be
-		 * extracted entirely from the Intel extended query
-		 * data instead. 
-		 */
-		if (cfi->cmdset_priv) {
-			struct cfi_pri_intelext *extp = cfi->cmdset_priv;
-			if (extp->FeatureSupport & (1 << 9)) {
-				/*
-				 * The L18 flash memory array is divided
-				 * into multiple 8-Mbit partitions.
-				 */
-				int nbparts = 1 << (cfi->cfiq->DevSize - 20);
-				chip->partshift = __ffs(cfi->interleave) + 20;
-				chip->parts = kmalloc(nbparts * sizeof(*chip->parts), GFP_KERNEL);
-				if (!chip->parts) {
-					kfree(extp);
-					return NULL;
-				}
-				memset(chip->parts, 0, nbparts * sizeof(*chip->parts));
-			}
-		}
+		cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
+		cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
+		cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
+		cfi->chips[i].ref_point_counter = 0;
 	}		
 
 	map->fldrv = &cfi_intelext_chipdrv;
@@ -354,82 +329,7 @@
  *  *********** CHIP ACCESS FUNCTIONS ***********
  */
 
-static flstate_t get_state(struct flchip *chip, unsigned long adr)
-{
-	flstate_t state = chip->state;
-	if (chip->parts) {
-		int part = (adr - chip->start) >> chip->partshift;
-		state = chip->parts[part].state;
-	}
-	return state;
-}
-
-static void set_state(struct flchip *chip, unsigned long adr, flstate_t mode)
-{
-	if (!chip->parts) {
-		chip->state = mode;
-	} else {
-		int part = (adr - chip->start) >> chip->partshift;
-		chip->parts[part].state = mode;
-		/* erasing and writing are global states to the chip */
-		switch (mode) {
-		case FL_ERASING:
-			chip->in_progress_block_addr = adr;
-		case FL_ERASE_SUSPENDING:
-		case FL_ERASE_SUSPENDED:
-		case FL_WRITING:
-		case FL_WRITING_TO_BUFFER:
-		case FL_WRITE_SUSPENDING:
-		case FL_WRITE_SUSPENDED:
-			chip->state = mode;
-		default:
-			chip->state = FL_READY;
-		}
-	}
-}
-
-static flstate_t get_oldstate(struct flchip *chip, unsigned long adr)
-{
-	flstate_t state = chip->oldstate;
-	if (chip->parts) {
-		int part = (adr - chip->start) >> chip->partshift;
-		state = chip->parts[part].oldstate;
-	}
-	return state;
-}
-
-static void set_oldstate(struct flchip *chip, unsigned long adr, flstate_t mode)
-{
-	if (!chip->parts) {
-		chip->oldstate = mode;
-	} else {
-		int part = (adr - chip->start) >> chip->partshift;
-		chip->parts[part].oldstate = mode;
-		/* erasing and writing are still global states to the chip */
-		switch (mode) {
-		case FL_ERASING:
-		case FL_ERASE_SUSPENDING:
-		case FL_ERASE_SUSPENDED:
-		case FL_WRITING:
-		case FL_WRITING_TO_BUFFER:
-		case FL_WRITE_SUSPENDING:
-		case FL_WRITE_SUSPENDED:
-			chip->oldstate = mode;
-		default:
-			chip->oldstate = FL_READY;
-		}
-	}
-}
-
-static inline int same_partition(struct flchip *chip,
-				 unsigned long addr_a, unsigned long addr_b)
-{
-	if (!chip->parts)
-		return 1;
-	return (((addr_a ^ addr_b) >> chip->partshift) == 0);
-}
-
-static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, flstate_t mode)
+static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct cfi_private *cfi = map->fldrv_priv;
@@ -440,23 +340,7 @@
  resettime:
 	timeo = jiffies + HZ;
  retry:
-	if ( !same_partition(chip, adr, chip->in_progress_block_addr) &&
-	     !(chip->state == FL_READY && chip->oldstate == FL_READY) &&
-	      (mode == FL_WRITING || mode == FL_ERASING) ) {
-		/*
-		 * OK. We have contension on the write/erase operations
-		 * which are global to the chip and not per partition.
-		 * So let's fight it over in the partition where the
-		 * write/erase is currently occurring first.
-		 */
-		int ret = get_chip(map, chip, chip->in_progress_block_addr, mode);
-		if (ret)
-			return ret;
-		chip->suspender_block_addr = adr;
-		timeo = jiffies + HZ;
-	}
-
-	switch (get_state(chip, adr)) {
+	switch (chip->state) {
 
 	case FL_STATUS:
 		for (;;) {
@@ -498,8 +382,8 @@
 		 * mode so we get the right data. --rmk
 		 */
 		cfi_write(map, CMD(0x70), adr);
-		set_oldstate(chip, adr, FL_ERASING);
-		set_state(chip, adr, FL_ERASE_SUSPENDING);
+		chip->oldstate = FL_ERASING;
+		chip->state = FL_ERASE_SUSPENDING;
 		chip->erase_suspended = 1;
 		for (;;) {
 			status = cfi_read(map, adr);
@@ -511,8 +395,8 @@
 				cfi_write(map, CMD(0xd0), adr);
 				/* Make sure we're in 'read status' mode if it had finished */
 				cfi_write(map, CMD(0x70), adr);
-				set_state(chip, adr, FL_ERASING);
-				set_oldstate(chip, adr, FL_READY);
+				chip->state = FL_ERASING;
+				chip->oldstate = FL_READY;
 				printk(KERN_ERR "Chip not ready after erase "
 				       "suspended: status = 0x%x\n", status);
 				return -EIO;
@@ -524,12 +408,12 @@
 			/* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
 			   So we can just loop here. */
 		}
-		set_state(chip, adr, FL_STATUS);
+		chip->state = FL_STATUS;
 		return 0;
 
 	case FL_POINT:
 		/* Only if there's no operation suspended... */
-		if (mode == FL_READY && get_state(chip, adr) == FL_READY)
+		if (mode == FL_READY && chip->oldstate == FL_READY)
 			return 0;
 
 	default:
@@ -548,13 +432,9 @@
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 
-	if ( !same_partition(chip, adr, chip->in_progress_block_addr) &&
-	      same_partition(chip, adr, chip->suspender_block_addr) &&
-	      chip->oldstate != FL_READY )
-		put_chip(map, chip, chip->in_progress_block_addr);
-
-	switch(get_oldstate(chip, adr)) {
+	switch(chip->oldstate) {
 	case FL_ERASING:
+		chip->state = chip->oldstate;
 		/* What if one interleaved chip has finished and the 
 		   other hasn't? The old code would leave the finished
 		   one in READY mode. That's bad, and caused -EROFS 
@@ -566,8 +446,8 @@
 		   do. */
 		cfi_write(map, CMD(0xd0), adr);
 		cfi_write(map, CMD(0x70), adr);
-		set_oldstate(chip, adr, FL_READY);
-		set_state(chip, adr, FL_ERASING);
+		chip->oldstate = FL_READY;
+		chip->state = FL_ERASING;
 		break;
 
 	case FL_READY:
@@ -577,7 +457,7 @@
 		DISABLE_VPP(map);
 		break;
 	default:
-		printk(KERN_ERR "put_chip() called with oldstate %d!!\n", get_oldstate(chip, adr));
+		printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate);
 	}
 	wake_up(&chip->wq);
 }
@@ -598,15 +478,10 @@
 	ret = get_chip(map, chip, cmd_addr, FL_POINT);
 
 	if (!ret) {
-		switch (get_state(chip, cmd_addr)) {
-		case FL_POINT:
-		case FL_READY:
-			break;
-		default:
+		if (chip->state != FL_POINT && chip->state != FL_READY)
 			cfi_write(map, CMD(0xff), cmd_addr);
-		}
 
-		set_state(chip, cmd_addr, FL_POINT);
+		chip->state = FL_POINT;
 		chip->ref_point_counter++;
 	}
 	spin_unlock(chip->mutex);
@@ -674,7 +549,6 @@
 	while (len) {
 		unsigned long thislen;
 		struct flchip *chip;
-		unsigned long cmd_addr;
 
 		chip = &cfi->chips[chipnum];
 		if (chipnum >= cfi->numchips)
@@ -685,17 +559,15 @@
 		else
 			thislen = len;
 
-		cmd_addr = (chip->start + ofs) & ~(CFIDEV_BUSWIDTH-1); 
-
 		spin_lock(chip->mutex);
-		if (get_state(chip, cmd_addr) == FL_POINT) {
+		if (chip->state == FL_POINT) {
 			chip->ref_point_counter--;
 			if(chip->ref_point_counter == 0)
-				set_state(chip, cmd_addr, FL_READY);
+				chip->state = FL_READY;
 		} else
 			printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */
 
-		put_chip(map, chip, cmd_addr);
+		put_chip(map, chip, chip->start);
 		spin_unlock(chip->mutex);
 
 		len -= thislen;
@@ -722,13 +594,10 @@
 		return ret;
 	}
 
-	switch (get_state(chip, cmd_addr)) {
-	case FL_POINT:
-	case FL_READY:
-		break;
-	default:
+	if (chip->state != FL_POINT && chip->state != FL_READY) {
 		cfi_write(map, CMD(0xff), cmd_addr);
-		set_state(chip, cmd_addr, FL_READY);
+
+		chip->state = FL_READY;
 	}
 
 	map_copy_from(map, buf, adr, len);
@@ -807,9 +676,9 @@
 			return (len-count)?:ret;
 		}
 
-		if (get_state(chip, chip->start) != FL_JEDEC_QUERY) {
+		if (chip->state != FL_JEDEC_QUERY) {
 			cfi_write(map, CMD(0x90), chip->start);
-			set_state(chip, chip->start, FL_JEDEC_QUERY);
+			chip->state = FL_JEDEC_QUERY;
 		}
 
 		while (count && ((offst-base_offst) < reg_sz)) {
@@ -892,7 +761,7 @@
 	ENABLE_VPP(map);
 	cfi_write(map, CMD(0x40), adr);
 	cfi_write(map, datum, adr);
-	set_state(chip, adr, FL_WRITING);
+	chip->state = FL_WRITING;
 
 	spin_unlock(chip->mutex);
 	INVALIDATE_CACHED_RANGE(map, adr, CFIDEV_BUSWIDTH);
@@ -902,7 +771,7 @@
 	timeo = jiffies + (HZ/2);
 	z = 0;
 	for (;;) {
-		if (get_state(chip, adr) != FL_WRITING) {
+		if (chip->state != FL_WRITING) {
 			/* Someone's suspended the write. Sleep */
 			DECLARE_WAITQUEUE(wait, current);
 
@@ -922,7 +791,7 @@
 		
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
-			set_state(chip, adr, FL_STATUS);
+			chip->state = FL_STATUS;
 			printk(KERN_ERR "waiting for chip to be ready timed out in word write\n");
 			ret = -EIO;
 			goto out;
@@ -943,7 +812,7 @@
 		chip->word_write_time++;
 
 	/* Done and happy. */
-	set_state(chip, adr, FL_STATUS);
+	chip->state = FL_STATUS;
 	/* check for lock bit */
 	if (status & CMD(0x02)) {
 		/* clear status */
@@ -1108,7 +977,7 @@
 	   [...], the device will not accept any more Write to Buffer commands". 
 	   So we must check here and reset those bits if they're set. Otherwise
 	   we're just pissing in the wind */
-	if (get_state(chip, cmd_adr) != FL_STATUS)
+	if (chip->state != FL_STATUS)
 		cfi_write(map, CMD(0x70), cmd_adr);
 	status = cfi_read(map, cmd_adr);
 	if (status & CMD(0x30)) {
@@ -1118,11 +987,12 @@
 	}
 
 	ENABLE_VPP(map);
-	set_state(chip, cmd_adr, FL_WRITING_TO_BUFFER);
+	chip->state = FL_WRITING_TO_BUFFER;
 
 	z = 0;
 	for (;;) {
 		cfi_write(map, CMD(0xe8), cmd_adr);
+
 		status = cfi_read(map, cmd_adr);
 		if ((status & status_OK) == status_OK)
 			break;
@@ -1134,7 +1004,7 @@
 		if (++z > 20) {
 			/* Argh. Not ready for write to buffer */
 			cfi_write(map, CMD(0x70), cmd_adr);
-			set_state(chip, cmd_adr, FL_STATUS);
+			chip->state = FL_STATUS;
 			printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %llx, status = %llx\n", (__u64)status, (__u64)cfi_read(map, cmd_adr));
 			/* Odd. Clear status bits */
 			cfi_write(map, CMD(0x50), cmd_adr);
@@ -1185,7 +1055,7 @@
 	}
 	/* GO GO GO */
 	cfi_write(map, CMD(0xd0), cmd_adr);
-	set_state(chip, cmd_adr, FL_WRITING);
+	chip->state = FL_WRITING;
 
 	spin_unlock(chip->mutex);
 	INVALIDATE_CACHED_RANGE(map, adr, len);
@@ -1195,7 +1065,7 @@
 	timeo = jiffies + (HZ/2);
 	z = 0;
 	for (;;) {
-		if (get_state(chip, cmd_adr) != FL_WRITING) {
+		if (chip->state != FL_WRITING) {
 			/* Someone's suspended the write. Sleep */
 			DECLARE_WAITQUEUE(wait, current);
 			set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1214,7 +1084,7 @@
 
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
-			set_state(chip, cmd_adr, FL_STATUS);
+			chip->state = FL_STATUS;
 			printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
 			ret = -EIO;
 			goto out;
@@ -1235,7 +1105,7 @@
 		chip->buffer_write_time++;
 
 	/* Done and happy. */
- 	set_state(chip, cmd_adr, FL_STATUS);
+ 	chip->state = FL_STATUS;
 
 	/* check for lock bit */
 	if (status & CMD(0x02)) {
@@ -1442,7 +1312,7 @@
 	/* Now erase */
 	cfi_write(map, CMD(0x20), adr);
 	cfi_write(map, CMD(0xD0), adr);
-	set_state(chip, adr, FL_ERASING);
+	chip->state = FL_ERASING;
 	chip->erase_suspended = 0;
 
 	spin_unlock(chip->mutex);
@@ -1456,7 +1326,7 @@
 
 	timeo = jiffies + (HZ*20);
 	for (;;) {
-		if (get_state(chip, adr) != FL_ERASING) {
+		if (chip->state != FL_ERASING) {
 			/* Someone's suspended the erase. Sleep */
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
@@ -1480,7 +1350,7 @@
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
 			cfi_write(map, CMD(0x70), adr);
-			set_state(chip, adr, FL_STATUS);
+			chip->state = FL_STATUS;
 			printk(KERN_ERR "waiting for erase at %08lx to complete timed out. Xstatus = %llx, status = %llx.\n",
 			       adr, (__u64)status, (__u64)cfi_read(map, adr));
 			/* Clear status bits */
@@ -1503,7 +1373,7 @@
 
 	/* We've broken this before. It doesn't hurt to be safe */
 	cfi_write(map, CMD(0x70), adr);
-	set_state(chip, adr, FL_STATUS);
+	chip->state = FL_STATUS;
 	status = cfi_read(map, adr);
 
 	/* check for lock bit */
@@ -1534,7 +1404,7 @@
 			if (retries--) {
 				printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%llx. Retrying...\n", adr, (__u64)status);
 				timeo = jiffies + HZ;
-				set_state(chip, adr, FL_STATUS);
+				chip->state = FL_STATUS;
 				spin_unlock(chip->mutex);
 				goto retry;
 			}
@@ -1582,8 +1452,8 @@
 		ret = get_chip(map, chip, chip->start, FL_SYNCING);
 
 		if (!ret) {
-			set_oldstate(chip, chip->start, get_state(chip, chip->start));
-			set_state(chip, chip->start, FL_SYNCING);
+			chip->oldstate = chip->state;
+			chip->state = FL_SYNCING;
 			/* No need to wake_up() on this state change - 
 			 * as the whole point is that nobody can do anything
 			 * with the chip now anyway.
@@ -1599,8 +1469,8 @@
 
 		spin_lock(chip->mutex);
 		
-		if (get_state(chip, chip->start) == FL_SYNCING) {
-			set_state(chip, chip->start, get_oldstate(chip, chip->start));
+		if (chip->state == FL_SYNCING) {
+			chip->state = chip->oldstate;
 			wake_up(&chip->wq);
 		}
 		spin_unlock(chip->mutex);
@@ -1617,7 +1487,7 @@
 	cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
 	printk(KERN_DEBUG "block status register for 0x%08lx is %x\n",
 	       adr, cfi_read_query(map, adr+(2*ofs_factor)));
-	set_state(chip, chip->start, FL_JEDEC_QUERY);
+	chip->state = FL_JEDEC_QUERY;
 	return 0;
 }
 #endif
@@ -1650,10 +1520,10 @@
 
 	if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
 		cfi_write(map, CMD(0x01), adr);
-		set_state(chip, adr, FL_LOCKING);
+		chip->state = FL_LOCKING;
 	} else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) {
 		cfi_write(map, CMD(0xD0), adr);
-		set_state(chip, adr, FL_UNLOCKING);
+		chip->state = FL_UNLOCKING;
 	} else
 		BUG();
 
@@ -1674,7 +1544,7 @@
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
 			cfi_write(map, CMD(0x70), adr);
-			set_state(chip, adr, FL_STATUS);
+			chip->state = FL_STATUS;
 			printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %llx, status = %llx.\n", (__u64)status, (__u64)cfi_read(map, adr));
 			DISABLE_VPP(map);
 			spin_unlock(chip->mutex);
@@ -1688,7 +1558,7 @@
 	}
 	
 	/* Done and happy. */
-	set_state(chip, adr, FL_STATUS);
+	chip->state = FL_STATUS;
 	put_chip(map, chip, adr);
 	spin_unlock(chip->mutex);
 	return 0;
@@ -1754,14 +1624,14 @@
 
 		spin_lock(chip->mutex);
 
-		switch (get_state(chip, chip->start)) {
+		switch (chip->state) {
 		case FL_READY:
 		case FL_STATUS:
 		case FL_CFI_QUERY:
 		case FL_JEDEC_QUERY:
-			if (get_oldstate(chip, chip->start) == FL_READY) {
-				set_oldstate(chip, chip->start, get_state(chip, chip->start));
-				set_state(chip, chip->start, FL_PM_SUSPENDED);
+			if (chip->oldstate == FL_READY) {
+				chip->oldstate = chip->state;
+				chip->state = FL_PM_SUSPENDED;
 				/* No need to wake_up() on this state change - 
 				 * as the whole point is that nobody can do anything
 				 * with the chip now anyway.
@@ -1784,11 +1654,11 @@
 			
 			spin_lock(chip->mutex);
 			
-			if (get_state(chip, chip->start) == FL_PM_SUSPENDED) {
+			if (chip->state == FL_PM_SUSPENDED) {
 				/* No need to force it into a known state here,
 				   because we're returning failure, and it didn't
 				   get power cycled */
-				set_state(chip, chip->start, get_oldstate(chip, chip->start));
+				chip->state = chip->oldstate;
 				wake_up(&chip->wq);
 			}
 			spin_unlock(chip->mutex);
@@ -1812,9 +1682,9 @@
 		spin_lock(chip->mutex);
 		
 		/* Go to known state. Chip may have been power cycled */
-		if (get_state(chip, chip->start) == FL_PM_SUSPENDED) {
+		if (chip->state == FL_PM_SUSPENDED) {
 			cfi_write(map, CMD(0xFF), cfi->chips[i].start);
-			set_state(chip, chip->start, FL_READY);
+			chip->state = FL_READY;
 			wake_up(&chip->wq);
 		}
 
@@ -1824,13 +1694,10 @@
 
 static void cfi_intelext_destroy(struct mtd_info *mtd)
 {
-	int i;
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
 	kfree(cfi->cmdset_priv);
 	kfree(cfi->cfiq);
-	for (i = 0; i < cfi->numchips; i++)
-		kfree(cfi->chips[i].parts);
 	kfree(cfi);
 	kfree(mtd->eraseregions);
 }





More information about the linux-mtd-cvs mailing list