mtd/drivers/mtd/chips cfi_cmdset_0001.c,1.138,1.139

Nicolas Pitre nico at infradead.org
Sun Jun 6 22:01:04 EDT 2004


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

Modified Files:
	cfi_cmdset_0001.c 
Log Message:
Abstract chip state in preparation for multiple hw partition support
as found on the Intel l18 and l30 flash series.
There is no functional change just yet. 


Index: cfi_cmdset_0001.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0001.c,v
retrieving revision 1.138
retrieving revision 1.139
diff -u -r1.138 -r1.139
--- cfi_cmdset_0001.c	5 Jun 2004 10:20:38 -0000	1.138
+++ cfi_cmdset_0001.c	7 Jun 2004 02:01:01 -0000	1.139
@@ -328,6 +328,26 @@
  *  *********** CHIP ACCESS FUNCTIONS ***********
  */
 
+static inline flstate_t get_state(struct flchip *chip, unsigned long adr)
+{
+	return chip->state;
+}
+
+static inline void set_state(struct flchip *chip, unsigned long adr, flstate_t mode)
+{
+	chip->state = mode;
+}
+
+static inline flstate_t get_oldstate(struct flchip *chip, unsigned long adr)
+{
+	return chip->oldstate;
+}
+
+static inline void set_oldstate(struct flchip *chip, unsigned long adr, flstate_t mode)
+{
+	chip->oldstate = mode;
+}
+
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
 {
 	DECLARE_WAITQUEUE(wait, current);
@@ -339,7 +359,7 @@
  resettime:
 	timeo = jiffies + HZ;
  retry:
-	switch (chip->state) {
+	switch (get_state(chip, adr)) {
 
 	case FL_STATUS:
 		for (;;) {
@@ -381,8 +401,8 @@
 		 * mode so we get the right data. --rmk
 		 */
 		cfi_write(map, CMD(0x70), adr);
-		chip->oldstate = FL_ERASING;
-		chip->state = FL_ERASE_SUSPENDING;
+		set_oldstate(chip, adr, FL_ERASING);
+		set_state(chip, adr, FL_ERASE_SUSPENDING);
 		chip->erase_suspended = 1;
 		for (;;) {
 			status = cfi_read(map, adr);
@@ -394,8 +414,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);
-				chip->state = FL_ERASING;
-				chip->oldstate = FL_READY;
+				set_state(chip, adr, FL_ERASING);
+				set_oldstate(chip, adr, FL_READY);
 				printk(KERN_ERR "Chip not ready after erase "
 				       "suspended: status = 0x%x\n", status);
 				return -EIO;
@@ -407,12 +427,12 @@
 			/* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
 			   So we can just loop here. */
 		}
-		chip->state = FL_STATUS;
+		set_state(chip, adr, FL_STATUS);
 		return 0;
 
 	case FL_POINT:
 		/* Only if there's no operation suspended... */
-		if (mode == FL_READY && chip->oldstate == FL_READY)
+		if (mode == FL_READY && get_state(chip, adr) == FL_READY)
 			return 0;
 
 	default:
@@ -431,9 +451,8 @@
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 
-	switch(chip->oldstate) {
+	switch(get_oldstate(chip, adr)) {
 	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 
@@ -445,8 +464,8 @@
 		   do. */
 		cfi_write(map, CMD(0xd0), adr);
 		cfi_write(map, CMD(0x70), adr);
-		chip->oldstate = FL_READY;
-		chip->state = FL_ERASING;
+		set_oldstate(chip, adr, FL_READY);
+		set_state(chip, adr, FL_ERASING);
 		break;
 
 	case FL_READY:
@@ -456,7 +475,7 @@
 		DISABLE_VPP(map);
 		break;
 	default:
-		printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate);
+		printk(KERN_ERR "put_chip() called with oldstate %d!!\n", get_oldstate(chip, adr));
 	}
 	wake_up(&chip->wq);
 }
@@ -477,10 +496,15 @@
 	ret = get_chip(map, chip, cmd_addr, FL_POINT);
 
 	if (!ret) {
-		if (chip->state != FL_POINT && chip->state != FL_READY)
+		switch (get_state(chip, cmd_addr)) {
+		case FL_POINT:
+		case FL_READY:
+			break;
+		default:
 			cfi_write(map, CMD(0xff), cmd_addr);
+		}
 
-		chip->state = FL_POINT;
+		set_state(chip, cmd_addr, FL_POINT);
 		chip->ref_point_counter++;
 	}
 	spin_unlock(chip->mutex);
@@ -548,6 +572,7 @@
 	while (len) {
 		unsigned long thislen;
 		struct flchip *chip;
+		unsigned long cmd_addr;
 
 		chip = &cfi->chips[chipnum];
 		if (chipnum >= cfi->numchips)
@@ -558,15 +583,17 @@
 		else
 			thislen = len;
 
+		cmd_addr = (chip->start + ofs) & ~(CFIDEV_BUSWIDTH-1); 
+
 		spin_lock(chip->mutex);
-		if (chip->state == FL_POINT) {
+		if (get_state(chip, cmd_addr) == FL_POINT) {
 			chip->ref_point_counter--;
 			if(chip->ref_point_counter == 0)
-				chip->state = FL_READY;
+				set_state(chip, cmd_addr, FL_READY);
 		} else
 			printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */
 
-		put_chip(map, chip, chip->start);
+		put_chip(map, chip, cmd_addr);
 		spin_unlock(chip->mutex);
 
 		len -= thislen;
@@ -593,10 +620,13 @@
 		return ret;
 	}
 
-	if (chip->state != FL_POINT && chip->state != FL_READY) {
+	switch (get_state(chip, cmd_addr)) {
+	case FL_POINT:
+	case FL_READY:
+		break;
+	default:
 		cfi_write(map, CMD(0xff), cmd_addr);
-
-		chip->state = FL_READY;
+		set_state(chip, cmd_addr, FL_READY);
 	}
 
 	map_copy_from(map, buf, adr, len);
@@ -675,9 +705,9 @@
 			return (len-count)?:ret;
 		}
 
-		if (chip->state != FL_JEDEC_QUERY) {
+		if (get_state(chip, chip->start) != FL_JEDEC_QUERY) {
 			cfi_write(map, CMD(0x90), chip->start);
-			chip->state = FL_JEDEC_QUERY;
+			set_state(chip, chip->start, FL_JEDEC_QUERY);
 		}
 
 		while (count && ((offst-base_offst) < reg_sz)) {
@@ -760,7 +790,7 @@
 	ENABLE_VPP(map);
 	cfi_write(map, CMD(0x40), adr);
 	cfi_write(map, datum, adr);
-	chip->state = FL_WRITING;
+	set_state(chip, adr, FL_WRITING);
 
 	spin_unlock(chip->mutex);
 	INVALIDATE_CACHED_RANGE(map, adr, CFIDEV_BUSWIDTH);
@@ -770,7 +800,7 @@
 	timeo = jiffies + (HZ/2);
 	z = 0;
 	for (;;) {
-		if (chip->state != FL_WRITING) {
+		if (get_state(chip, adr) != FL_WRITING) {
 			/* Someone's suspended the write. Sleep */
 			DECLARE_WAITQUEUE(wait, current);
 
@@ -790,7 +820,7 @@
 		
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
-			chip->state = FL_STATUS;
+			set_state(chip, adr, FL_STATUS);
 			printk(KERN_ERR "waiting for chip to be ready timed out in word write\n");
 			ret = -EIO;
 			goto out;
@@ -811,7 +841,7 @@
 		chip->word_write_time++;
 
 	/* Done and happy. */
-	chip->state = FL_STATUS;
+	set_state(chip, adr, FL_STATUS);
 	/* check for lock bit */
 	if (status & CMD(0x02)) {
 		/* clear status */
@@ -972,27 +1002,25 @@
 		return ret;
 	}
 
-	if (chip->state != FL_STATUS)
-		cfi_write(map, CMD(0x70), cmd_adr);
-
-	status = cfi_read(map, cmd_adr);
-
 	/* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
 	   [...], 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)
+		cfi_write(map, CMD(0x70), cmd_adr);
+	status = cfi_read(map, cmd_adr);
 	if (status & CMD(0x30)) {
 		printk(KERN_WARNING "SR.4 or SR.5 bits set in buffer write (status %x). Clearing.\n", status);
 		cfi_write(map, CMD(0x50), cmd_adr);
 		cfi_write(map, CMD(0x70), cmd_adr);
 	}
+
 	ENABLE_VPP(map);
-	chip->state = FL_WRITING_TO_BUFFER;
+	set_state(chip, cmd_adr, 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;
@@ -1004,7 +1032,7 @@
 		if (++z > 20) {
 			/* Argh. Not ready for write to buffer */
 			cfi_write(map, CMD(0x70), cmd_adr);
-			chip->state = FL_STATUS;
+			set_state(chip, cmd_adr, 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);
@@ -1058,7 +1086,7 @@
 	}
 	/* GO GO GO */
 	cfi_write(map, CMD(0xd0), cmd_adr);
-	chip->state = FL_WRITING;
+	set_state(chip, cmd_adr, FL_WRITING);
 
 	spin_unlock(chip->mutex);
 	INVALIDATE_CACHED_RANGE(map, adr, len);
@@ -1068,7 +1096,7 @@
 	timeo = jiffies + (HZ/2);
 	z = 0;
 	for (;;) {
-		if (chip->state != FL_WRITING) {
+		if (get_state(chip, cmd_adr) != FL_WRITING) {
 			/* Someone's suspended the write. Sleep */
 			DECLARE_WAITQUEUE(wait, current);
 			set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1087,7 +1115,7 @@
 
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
-			chip->state = FL_STATUS;
+			set_state(chip, cmd_adr, FL_STATUS);
 			printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
 			ret = -EIO;
 			goto out;
@@ -1108,7 +1136,7 @@
 		chip->buffer_write_time++;
 
 	/* Done and happy. */
- 	chip->state = FL_STATUS;
+ 	set_state(chip, cmd_adr, FL_STATUS);
 
 	/* check for lock bit */
 	if (status & CMD(0x02)) {
@@ -1310,7 +1338,7 @@
 	/* Now erase */
 	cfi_write(map, CMD(0x20), adr);
 	cfi_write(map, CMD(0xD0), adr);
-	chip->state = FL_ERASING;
+	set_state(chip, adr, FL_ERASING);
 	chip->erase_suspended = 0;
 
 	spin_unlock(chip->mutex);
@@ -1325,7 +1353,7 @@
 
 	timeo = jiffies + (HZ*20);
 	for (;;) {
-		if (chip->state != FL_ERASING) {
+		if (get_state(chip, adr) != FL_ERASING) {
 			/* Someone's suspended the erase. Sleep */
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
@@ -1349,7 +1377,7 @@
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
 			cfi_write(map, CMD(0x70), adr);
-			chip->state = FL_STATUS;
+			set_state(chip, adr, 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 */
@@ -1372,7 +1400,7 @@
 
 	/* We've broken this before. It doesn't hurt to be safe */
 	cfi_write(map, CMD(0x70), adr);
-	chip->state = FL_STATUS;
+	set_state(chip, adr, FL_STATUS);
 	status = cfi_read(map, adr);
 
 	/* check for lock bit */
@@ -1403,7 +1431,7 @@
 			if (retries--) {
 				printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%llx. Retrying...\n", adr, (__u64)status);
 				timeo = jiffies + HZ;
-				chip->state = FL_STATUS;
+				set_state(chip, adr, FL_STATUS);
 				spin_unlock(chip->mutex);
 				goto retry;
 			}
@@ -1454,8 +1482,8 @@
 		ret = get_chip(map, chip, chip->start, FL_SYNCING);
 
 		if (!ret) {
-			chip->oldstate = chip->state;
-			chip->state = FL_SYNCING;
+			set_oldstate(chip, chip->start, get_state(chip, chip->start));
+			set_state(chip, chip->start, 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.
@@ -1471,8 +1499,8 @@
 
 		spin_lock(chip->mutex);
 		
-		if (chip->state == FL_SYNCING) {
-			chip->state = chip->oldstate;
+		if (get_state(chip, chip->start) == FL_SYNCING) {
+			set_state(chip, chip->start, get_oldstate(chip, chip->start));
 			wake_up(&chip->wq);
 		}
 		spin_unlock(chip->mutex);
@@ -1488,7 +1516,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)));
-	chip->state = FL_JEDEC_QUERY;
+	set_state(chip, chip->start, FL_JEDEC_QUERY);
 	return 0;
 }
 #endif
@@ -1520,10 +1548,10 @@
 
 	if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
 		cfi_write(map, CMD(0x01), adr);
-		chip->state = FL_LOCKING;
+		set_state(chip, adr, FL_LOCKING);
 	} else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) {
 		cfi_write(map, CMD(0xD0), adr);
-		chip->state = FL_UNLOCKING;
+		set_state(chip, adr, FL_UNLOCKING);
 	} else
 		BUG();
 
@@ -1544,7 +1572,7 @@
 		/* OK Still waiting */
 		if (time_after(jiffies, timeo)) {
 			cfi_write(map, CMD(0x70), adr);
-			chip->state = FL_STATUS;
+			set_state(chip, adr, 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);
@@ -1558,7 +1586,7 @@
 	}
 	
 	/* Done and happy. */
-	chip->state = FL_STATUS;
+	set_state(chip, adr, FL_STATUS);
 	put_chip(map, chip, adr);
 	spin_unlock(chip->mutex);
 	return 0;
@@ -1624,14 +1652,14 @@
 
 		spin_lock(chip->mutex);
 
-		switch (chip->state) {
+		switch (get_state(chip, chip->start)) {
 		case FL_READY:
 		case FL_STATUS:
 		case FL_CFI_QUERY:
 		case FL_JEDEC_QUERY:
-			if (chip->oldstate == FL_READY) {
-				chip->oldstate = chip->state;
-				chip->state = FL_PM_SUSPENDED;
+			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);
 				/* No need to wake_up() on this state change - 
 				 * as the whole point is that nobody can do anything
 				 * with the chip now anyway.
@@ -1654,11 +1682,11 @@
 			
 			spin_lock(chip->mutex);
 			
-			if (chip->state == FL_PM_SUSPENDED) {
+			if (get_state(chip, chip->start) == 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 */
-				chip->state = chip->oldstate;
+				set_state(chip, chip->start, get_oldstate(chip, chip->start));
 				wake_up(&chip->wq);
 			}
 			spin_unlock(chip->mutex);
@@ -1682,9 +1710,9 @@
 		spin_lock(chip->mutex);
 		
 		/* Go to known state. Chip may have been power cycled */
-		if (chip->state == FL_PM_SUSPENDED) {
+		if (get_state(chip, chip->start) == FL_PM_SUSPENDED) {
 			cfi_write(map, CMD(0xFF), cfi->chips[i].start);
-			chip->state = FL_READY;
+			set_state(chip, chip->start, FL_READY);
 			wake_up(&chip->wq);
 		}
 





More information about the linux-mtd-cvs mailing list