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