- ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
- adr, map_bankwidth(map),
- chip->word_write_time);
- if (ret) {
- xip_enable(map, chip, adr);
- printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
- goto out;
+ INVALIDATE_CACHE_UDELAY(map, chip, adr,
+ adr, map_bankwidth(map),
+ chip->word_write_time);
+
+ timeo = jiffies + (HZ/2);
+ z = 0;
+ for (;;) {
+ if (chip->state != mode) {
+ /* Someone's suspended the write. Sleep */
+ DECLARE_WAITQUEUE(wait, current);
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&chip->wq, &wait);
+ spin_unlock(chip->mutex);
+ schedule();
+ remove_wait_queue(&chip->wq, &wait);
+ timeo = jiffies + (HZ / 2); /* FIXME */
+ spin_lock(chip->mutex);
+ continue;
+ }
+
+ status = map_read(map, adr);
+ if (map_word_andequal(map, status, status_OK, status_OK))
+ break;
+
+ /* OK Still waiting */
+ if (time_after(jiffies, timeo)) {
+ map_write(map, CMD(0x70), adr);
+ chip->state = FL_STATUS;
+ xip_enable(map, chip, adr);
+ printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
+ ret = -EIO;
+ goto out;
+ }
+
+ /* Latency issues. Drop the lock, wait a while and retry */
+ z++;
+ UDELAY(map, chip, adr, 1);
+ }
+ if (!z) {
+ chip->word_write_time--;
+ if (!chip->word_write_time)
+ chip->word_write_time = 1;