Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 4555
b: refs/heads/master
c: fb4a90b
h: refs/heads/master
i:
  4553: f18d52c
  4551: f336c94
v: v3
  • Loading branch information
Eric W. Biedermann authored and Thomas Gleixner committed May 23, 2005
1 parent 749e8ab commit f738bff
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6da70124a1cc05bdbd7c847901964edc6f634a91
refs/heads/master: fb4a90bfcd6d86e8531073c42fae7fde40974f5d
99 changes: 67 additions & 32 deletions trunk/drivers/mtd/chips/cfi_cmdset_0002.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* This code is GPL
*
* $Id: cfi_cmdset_0002.c,v 1.114 2004/12/11 15:43:53 dedekind Exp $
* $Id: cfi_cmdset_0002.c,v 1.115 2005/05/20 03:28:23 eric Exp $
*
*/

Expand Down Expand Up @@ -43,6 +43,7 @@
#define MANUFACTURER_AMD 0x0001
#define MANUFACTURER_SST 0x00BF
#define SST49LF004B 0x0060
#define SST49LF008A 0x005a

static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
Expand Down Expand Up @@ -191,6 +192,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
};
static struct cfi_fixup jedec_fixup_table[] = {
{ MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
{ MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
{ 0, 0, NULL, NULL }
};

Expand Down Expand Up @@ -401,6 +403,32 @@ static int chip_ready(struct map_info *map, unsigned long addr)
return map_word_equal(map, d, t);
}

/*
* Return true if the chip is ready and has the correct value.
*
* Ready is one of: read mode, query mode, erase-suspend-read mode (in any
* non-suspended sector) and it is indicated by no bits toggling.
*
* Error are indicated by toggling bits or bits held with the wrong value,
* or with bits toggling.
*
* Note that anything more complicated than checking if no bits are toggling
* (including checking DQ5 for an error status) is tricky to get working
* correctly and is therefore not done (particulary with interleaved chips
* as each chip must be checked independantly of the others).
*
*/
static int chip_good(struct map_info *map, unsigned long addr, map_word expected)
{
map_word oldd, curd;

oldd = map_read(map, addr);
curd = map_read(map, addr);

return map_word_equal(map, oldd, curd) &&
map_word_equal(map, curd, expected);
}

static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
{
DECLARE_WAITQUEUE(wait, current);
Expand Down Expand Up @@ -765,26 +793,29 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
}

if (chip_ready(map, adr))
goto op_done;
break;

if (time_after(jiffies, timeo))
if (time_after(jiffies, timeo)) {
printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
break;
}

/* Latency issues. Drop the lock, wait a while and retry */
cfi_spin_unlock(chip->mutex);
cfi_udelay(1);
cfi_spin_lock(chip->mutex);
}
/* Did we succeed? */
if (!chip_good(map, adr, datum)) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */

printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);

/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
if (++retry_cnt <= MAX_WORD_RETRIES)
goto retry;
if (++retry_cnt <= MAX_WORD_RETRIES)
goto retry;

ret = -EIO;
ret = -EIO;
}
op_done:
chip->state = FL_READY;
put_chip(map, chip, adr);
Expand Down Expand Up @@ -1187,27 +1218,29 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
}

if (chip_ready(map, adr))
goto op_done;
break;

if (time_after(jiffies, timeo))
if (time_after(jiffies, timeo)) {
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
break;
}

/* Latency issues. Drop the lock, wait a while and retry */
cfi_spin_unlock(chip->mutex);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
cfi_spin_lock(chip->mutex);
}
/* Did we succeed? */
if (!chip_good(map, adr, map_word_ff(map))) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */

printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );

/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
ret = -EIO;
}

ret = -EIO;
op_done:
chip->state = FL_READY;
put_chip(map, chip, adr);
cfi_spin_unlock(chip->mutex);
Expand Down Expand Up @@ -1272,27 +1305,29 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
}

if (chip_ready(map, adr))
goto op_done;
break;

if (time_after(jiffies, timeo))
if (time_after(jiffies, timeo)) {
printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
break;
}

/* Latency issues. Drop the lock, wait a while and retry */
cfi_spin_unlock(chip->mutex);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
cfi_spin_lock(chip->mutex);
}

printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );

/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
/* Did we succeed? */
if (chip_good(map, adr, map_word_ff(map))) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */

ret = -EIO;
}

ret = -EIO;
op_done:
chip->state = FL_READY;
put_chip(map, chip, adr);
cfi_spin_unlock(chip->mutex);
Expand Down

0 comments on commit f738bff

Please sign in to comment.