mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.99,1.100
David Woodhouse
dwmw2 at infradead.org
Fri Jul 9 12:07:25 EDT 2004
Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv7532
Modified Files:
cfi_cmdset_0002.c
Log Message:
First attempt at updating to new geometry mess. Doesn't work yet.
Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -r1.99 -r1.100
--- cfi_cmdset_0002.c 5 Jun 2004 10:20:38 -0000 1.99
+++ cfi_cmdset_0002.c 9 Jul 2004 16:07:22 -0000 1.100
@@ -212,7 +212,7 @@
break;
case CFI_DEVICETYPE_X16:
cfi->addr_unlock1 = 0xaaa;
- if (map->buswidth == cfi->interleave) {
+ if (map_bankwidth(map) == cfi_interleave(cfi)) {
/* X16 chip(s) in X8 mode */
cfi->addr_unlock2 = 0x555;
} else {
@@ -220,8 +220,13 @@
}
break;
case CFI_DEVICETYPE_X32:
- cfi->addr_unlock1 = 0x1555;
- cfi->addr_unlock2 = 0xaaa;
+ cfi->addr_unlock1 = 0x1554;
+ if (map_bankwidth(map) == cfi_interleave(cfi)*2) {
+ /* X32 chip(s) in X16 mode */
+ cfi->addr_unlock1 = 0xaaa;
+ } else {
+ cfi->addr_unlock2 = 0xaa8;
+ }
break;
default:
printk(KERN_WARNING
@@ -306,45 +311,29 @@
}
#endif
- switch (CFIDEV_BUSWIDTH)
- {
- case 1:
- case 2:
- case 4:
-#ifdef CFI_WORD_64
- case 8:
-#endif
- if (mtd->numeraseregions == 1
- && ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) {
- mtd->erase = cfi_amdstd_erase_chip;
- } else {
- mtd->erase = cfi_amdstd_erase_varsize;
- mtd->lock = cfi_amdstd_lock_varsize;
- mtd->unlock = cfi_amdstd_unlock_varsize;
- }
+ if (mtd->numeraseregions == 1
+ && ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) {
+ mtd->erase = cfi_amdstd_erase_chip;
+ } else {
+ mtd->erase = cfi_amdstd_erase_varsize;
+ mtd->lock = cfi_amdstd_lock_varsize;
+ mtd->unlock = cfi_amdstd_unlock_varsize;
+ }
- if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
- DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
- mtd->write = cfi_amdstd_write_buffers;
- } else {
- DEBUG(MTD_DEBUG_LEVEL1, "Using word write method\n" );
- mtd->write = cfi_amdstd_write_words;
- }
+ if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
+ DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
+ mtd->write = cfi_amdstd_write_buffers;
+ } else {
+ DEBUG(MTD_DEBUG_LEVEL1, "Using word write method\n" );
+ mtd->write = cfi_amdstd_write_words;
+ }
- mtd->read = cfi_amdstd_read;
- break;
+ mtd->read = cfi_amdstd_read;
- default:
- printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
- __func__, CFIDEV_BUSWIDTH);
- goto setup_err;
- break;
- }
/* FIXME: erase-suspend-program is broken. See
http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */
printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n");
-
/* does this chip have a secsi area? */
if(cfi->mfr==1){
@@ -397,12 +386,12 @@
*/
static int chip_ready(struct map_info *map, unsigned long addr)
{
- cfi_word d, t;
+ map_word d, t;
- d = cfi_read(map, addr);
- t = d ^ cfi_read(map, addr);
+ d = map_read(map, addr);
+ t = map_read(map, addr);
- return t == 0;
+ return map_word_equal(map, d, t);
}
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
@@ -455,7 +444,7 @@
/* Erase suspend */
/* It's harmless to issue the Erase-Suspend and Erase-Resume
* commands when the erase algorithm isn't in progress. */
- cfi_write(map, CMD(0xB0), chip->in_progress_block_addr);
+ map_write(map, CMD(0xB0), chip->in_progress_block_addr);
chip->oldstate = FL_ERASING;
chip->state = FL_ERASE_SUSPENDING;
chip->erase_suspended = 1;
@@ -469,7 +458,7 @@
* there was an error (so leave the erase
* routine to recover from it) or we trying to
* use the erase-in-progress sector. */
- cfi_write(map, CMD(0x30), chip->in_progress_block_addr);
+ map_write(map, CMD(0x30), chip->in_progress_block_addr);
chip->state = FL_ERASING;
chip->oldstate = FL_READY;
printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
@@ -510,7 +499,7 @@
switch(chip->oldstate) {
case FL_ERASING:
chip->state = chip->oldstate;
- cfi_write(map, CMD(0x30), chip->in_progress_block_addr);
+ map_write(map, CMD(0x30), chip->in_progress_block_addr);
chip->oldstate = FL_READY;
chip->state = FL_ERASING;
break;
@@ -536,7 +525,7 @@
adr += chip->start;
/* Ensure cmd read/writes are aligned. */
- cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
+ cmd_addr = adr & ~(map_bankwidth(map)-1);
cfi_spin_lock(chip->mutex);
ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -546,7 +535,7 @@
}
if (chip->state != FL_POINT && chip->state != FL_READY) {
- cfi_write(map, CMD(0xf0), cmd_addr);
+ map_write(map, CMD(0xf0), cmd_addr);
chip->state = FL_READY;
}
@@ -697,7 +686,7 @@
}
-static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum)
+static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
{
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
@@ -712,6 +701,7 @@
*/
unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
int ret = 0;
+ map_word oldd;
adr += chip->start;
@@ -722,8 +712,8 @@
return ret;
}
- DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n",
- __func__, adr, datum );
+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
+ __func__, adr, datum.x[0] );
/*
* Check for a NOP for the case when the datum to write is already
@@ -731,7 +721,8 @@
* data at other locations when 0xff is written to a location that
* already contains 0xff.
*/
- if (cfi_read(map, adr) == datum) {
+ oldd = map_read(map, adr);
+ if (map_word_equal(map, oldd, datum)) {
DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP\n",
__func__);
goto op_done;
@@ -749,7 +740,7 @@
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_write(map, datum, adr);
+ map_write(map, datum, adr);
chip->state = FL_WRITING;
cfi_spin_unlock(chip->mutex);
@@ -788,9 +779,8 @@
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
- op_failed:
/* reset on all failures. */
- cfi_write( map, CMD(0xF0), chip->start );
+ map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
ret = -EIO;
@@ -822,12 +812,11 @@
chipstart = cfi->chips[chipnum].start;
/* If it's not bus-aligned, do the first byte write */
- if (ofs & (CFIDEV_BUSWIDTH-1)) {
- unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
+ if (ofs & (map_bankwidth(map)-1)) {
+ unsigned long bus_ofs = ofs & ~(map_bankwidth(map)-1);
int i = ofs - bus_ofs;
int n = 0;
- u_char tmp_buf[8];
- cfi_word datum;
+ map_word tmp_buf;
retry:
cfi_spin_lock(cfi->chips[chipnum].mutex);
@@ -850,32 +839,33 @@
goto retry;
}
- map_copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
+ /* Load 'tmp_buf' with old contents of flash */
+ tmp_buf = map_read(map, bus_ofs+chipstart);
cfi_spin_unlock(cfi->chips[chipnum].mutex);
- while (len && i < CFIDEV_BUSWIDTH) {
- tmp_buf[i++] = buf[n++];
- len--;
- }
-
- /* already know that buswidth > 1 */
- if (cfi_buswidth_is_2()) {
- datum = *(__u16*)tmp_buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)tmp_buf;
-#ifdef CFI_WORD_64
- } else if (cfi_buswidth_is_8()) {
- datum = *(__u64*)tmp_buf;
-#endif
+ if (map_bankwidth_is_large(map)) {
+ /* Copy in the bytes we want from the data we were asked to write */
+ while (len && i < map_bankwidth(map)) {
+ ((char *)&tmp_buf)[i++] = buf[n++];
+ len--;
+ }
} else {
- printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
- __func__, CFIDEV_BUSWIDTH);
- return -EINVAL;
+ while (len && i < map_bankwidth(map)) {
+ int bitpos;
+#ifdef __LITTLE_ENDIAN
+ bitpos = i*8;
+#else /* __BIG_ENDIAN */
+ bitpos = (map_bankwidth(map)-i)*8;
+#endif
+ tmp_buf.x[0] &= ~(0xff << bitpos);
+ tmp_buf.x[0] |= buf[n++] << bitpos;
+ i++;
+ }
}
ret = do_write_oneword(map, &cfi->chips[chipnum],
- bus_ofs, datum);
+ bus_ofs, tmp_buf);
if (ret)
return ret;
@@ -892,33 +882,20 @@
}
/* We are now aligned, write as much as possible */
- while(len >= CFIDEV_BUSWIDTH) {
- cfi_word datum;
+ while(len >= map_bankwidth(map)) {
+ map_word datum;
+
+ datum = map_word_load(map, buf);
- if (cfi_buswidth_is_1()) {
- datum = *(__u8*)buf;
- } else if (cfi_buswidth_is_2()) {
- datum = *(__u16*)buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)buf;
-#ifdef CFI_WORD_64
- } else if (cfi_buswidth_is_8()) {
- datum = *(__u64*)buf;
-#endif
- } else {
- printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
- __func__, CFIDEV_BUSWIDTH);
- return -EINVAL;
- }
ret = do_write_oneword(map, &cfi->chips[chipnum],
ofs, datum);
if (ret)
return ret;
- ofs += CFIDEV_BUSWIDTH;
- buf += CFIDEV_BUSWIDTH;
- (*retlen) += CFIDEV_BUSWIDTH;
- len -= CFIDEV_BUSWIDTH;
+ ofs += map_bankwidth(map);
+ buf += map_bankwidth(map);
+ (*retlen) += map_bankwidth(map);
+ len -= map_bankwidth(map);
if (ofs >> cfi->chipshift) {
chipnum ++;
@@ -930,10 +907,9 @@
}
/* Write the trailing bytes if any */
- if (len & (CFIDEV_BUSWIDTH-1)) {
+ if (len & (map_bankwidth(map)-1)) {
int i = 0, n = 0;
- u_char tmp_buf[8];
- cfi_word datum;
+ map_word tmp_buf;
retry1:
cfi_spin_lock(cfi->chips[chipnum].mutex);
@@ -956,29 +932,31 @@
goto retry1;
}
- map_copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
+ tmp_buf = map_read(map, ofs + chipstart);
cfi_spin_unlock(cfi->chips[chipnum].mutex);
- while (len--)
- tmp_buf[i++] = buf[n++];
-
- if (cfi_buswidth_is_2()) {
- datum = *(__u16*)tmp_buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)tmp_buf;
-#ifdef CFI_WORD_64
- } else if (cfi_buswidth_is_8()) {
- datum = *(__u64*)tmp_buf;
-#endif
+
+ if (map_bankwidth_is_large(map)) {
+ /* Copy in the bytes we want from the data we were asked to write */
+ while (len--)
+ ((char *)&tmp_buf)[i++] = buf[n++];
} else {
- printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
- __func__, CFIDEV_BUSWIDTH);
- return -EINVAL;
+ while (len--) {
+ int bitpos;
+#ifdef __LITTLE_ENDIAN
+ bitpos = i*8;
+#else /* __BIG_ENDIAN */
+ bitpos = (map_bankwidth(map)-i)*8;
+#endif
+ tmp_buf.x[0] &= ~(0xff << bitpos);
+ tmp_buf.x[0] |= buf[n++] << bitpos;
+ i++;
+ }
}
-
+
ret = do_write_oneword(map, &cfi->chips[chipnum],
- ofs, datum);
+ ofs, tmp_buf);
if (ret)
return ret;
@@ -1001,8 +979,8 @@
static unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
int ret = -EIO;
unsigned long cmd_adr;
- int z, bytes, words;
- cfi_word datum;
+ int z, words;
+ map_word datum;
adr += chip->start;
cmd_adr = adr;
@@ -1014,24 +992,10 @@
return ret;
}
- if (cfi_buswidth_is_1()) {
- datum = *(__u8*)buf;
- } else if (cfi_buswidth_is_2()) {
- datum = *(__u16*)buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)buf;
-#ifdef CFI_WORD_64
- } else if (cfi_buswidth_is_8()) {
- datum = *(__u64*)buf;
-#endif
- } else {
- printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
- __func__, CFIDEV_BUSWIDTH);
- return -EINVAL;
- }
+ datum = map_word_load(map, buf);
- DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n",
- __func__, adr, datum );
+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
+ __func__, adr, datum.x[0] );
ENABLE_VPP(map);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
@@ -1039,73 +1003,28 @@
//cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
/* Write Buffer Load */
- cfi_write(map, CMD(0x25), cmd_adr);
+ map_write(map, CMD(0x25), cmd_adr);
chip->state = FL_WRITING_TO_BUFFER;
/* Write length of data to come */
- bytes = len & (CFIDEV_BUSWIDTH-1);
- words = len / CFIDEV_BUSWIDTH;
- cfi_write(map, CMD(words - !bytes), cmd_adr );
+ words = len / map_bankwidth(map);
+ map_write(map, CMD(words - 1), cmd_adr);
/* Write data */
z = 0;
- while(z < words * CFIDEV_BUSWIDTH) {
- if (cfi_buswidth_is_1()) {
- datum = *((__u8*)buf);
- map_write8 (map, *((__u8*)buf), adr+z);
- } else if (cfi_buswidth_is_2()) {
- datum = *((__u16*)buf);
- map_write16 (map, *((__u16*)buf), adr+z);
- } else if (cfi_buswidth_is_4()) {
- datum = *((__u32*)buf);
- map_write32 (map, *((__u32*)buf), adr+z);
-#ifdef CFI_WORD_64
- } else if (cfi_buswidth_is_8()) {
- datum = *((__u64*)buf);
- map_write64 (map, *((__u64*)buf), adr+z);
-#endif
- } else {
- printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
- __func__, CFIDEV_BUSWIDTH);
- ret = -EINVAL;
- goto op_failed;
- }
- z += CFIDEV_BUSWIDTH;
- buf += CFIDEV_BUSWIDTH;
- }
- if (bytes) {
- int i = 0, n = 0;
- u_char tmp_buf[8], *tmp_p = tmp_buf;
+ while(z < words * map_bankwidth(map)) {
+ datum = map_word_load(map, buf);
+ map_write(map, datum, adr + z);
- while (bytes--)
- tmp_buf[i++] = buf[n++];
- while (i < CFIDEV_BUSWIDTH)
- tmp_buf[i++] = 0xff;
- if (cfi_buswidth_is_2()) {
- datum = *((__u16*)tmp_p);
- map_write16 (map, *((__u16*)tmp_p), adr+z);
- } else if (cfi_buswidth_is_4()) {
- datum = *((__u32*)tmp_p);
- map_write32 (map, *((__u32*)tmp_p), adr+z);
-#ifdef CFI_WORD_64
- } else if (cfi_buswidth_is_8()) {
- datum = *((__u64*)tmp_p);
- map_write64 (map, *((__u64*)tmp_p), adr+z);
-#endif
- } else {
- printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
- __func__, CFIDEV_BUSWIDTH);
- ret = -EINVAL;
- goto op_failed;
- }
- } else if (words > 0) {
- z -= CFIDEV_BUSWIDTH;
+ z += map_bankwidth(map);
+ buf += map_bankwidth(map);
}
+ z -= map_bankwidth(map);
adr += z;
/* Write Buffer Program Confirm: GO GO GO */
- cfi_write(map, CMD(0x29), cmd_adr);
+ map_write(map, CMD(0x29), cmd_adr);
chip->state = FL_WRITING;
cfi_spin_unlock(chip->mutex);
@@ -1144,9 +1063,8 @@
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
- op_failed:
/* reset on all failures. */
- cfi_write( map, CMD(0xF0), chip->start );
+ map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
ret = -EIO;
@@ -1164,7 +1082,7 @@
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
- int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
+ int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
int ret = 0;
int chipnum;
unsigned long ofs;
@@ -1177,8 +1095,8 @@
ofs = to - (chipnum << cfi->chipshift);
/* If it's not bus-aligned, do the first word write */
- if (ofs & (CFIDEV_BUSWIDTH-1)) {
- size_t local_len = (-ofs)&(CFIDEV_BUSWIDTH-1);
+ if (ofs & (map_bankwidth(map)-1)) {
+ size_t local_len = (-ofs)&(map_bankwidth(map)-1);
if (local_len > len)
local_len = len;
ret = cfi_amdstd_write_words(mtd, to, local_len,
@@ -1198,12 +1116,15 @@
}
/* Write buffer is worth it only if more than one word to write... */
- while (len) {
+ while (len >= map_bankwidth(map) * 2) {
/* We must not cross write block boundaries */
int size = wbufsize - (ofs & (wbufsize-1));
if (size > len)
size = len;
+ if (size % map_bankwidth(map))
+ size -= size % map_bankwidth(map);
+
ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size);
if (ret)
@@ -1222,6 +1143,15 @@
}
}
+ if (len) {
+ size_t retlen_dregs = 0;
+
+ ret = cfi_amdstd_write_words(mtd, to, len, &retlen_dregs, buf);
+
+ *retlen += retlen_dregs;
+ return ret;
+ }
+
return 0;
}
@@ -1303,9 +1233,8 @@
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
- op_failed:
/* reset on all failures. */
- cfi_write( map, CMD(0xF0), chip->start );
+ map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
ret = -EIO;
@@ -1436,7 +1365,7 @@
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_write(map, CMD(0x30), adr);
+ map_write(map, CMD(0x30), adr);
chip->state = FL_ERASING;
chip->erase_suspended = 0;
@@ -1483,9 +1412,8 @@
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
- op_failed:
/* reset on all failures. */
- cfi_write( map, CMD(0xF0), chip->start );
+ map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
ret = -EIO;
@@ -1670,7 +1598,7 @@
if (chip->state == FL_PM_SUSPENDED) {
chip->state = FL_READY;
- cfi_write(map, CMD(0xF0), chip->start);
+ map_write(map, CMD(0xF0), chip->start);
wake_up(&chip->wq);
}
else
@@ -1711,7 +1639,7 @@
struct xxlock_thunk {
- cfi_word val;
+ uint8_t val;
flstate_t state;
};
@@ -1754,7 +1682,7 @@
}
chip->state = xxlt->state;
- cfi_write(map, CMD(xxlt->val), adr);
+ map_write(map, CMD(xxlt->val), adr);
/* Done and happy. */
chip->state = FL_READY;
More information about the linux-mtd-cvs
mailing list