--- cfi_cmdset_0002.c	Tue Apr 17 15:13:54 2001
+++ C:\TEMP/cfi_cmdset_0002.c	Tue Apr 24 10:46:22 2001
@@ -304,7 +304,7 @@
  retry:
 	cfi_spin_lock(chip->mutex);
 
-	if (chip->state != FL_READY){
+	if (!fast && chip->state != FL_READY){
 	        printk("Waiting for chip to write, status = %d\n", chip->state);
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		add_wait_queue(&chip->wq, &wait);
@@ -331,9 +331,9 @@
 		cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi->interleave, cfi->device_type, NULL);
 	}
 	else {
-	        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
+	        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi->interleave, cfi->device_type, NULL);
+	        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi->interleave, cfi->device_type, NULL);
+	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi->interleave, cfi->device_type, NULL);
 	}
 
 	cfi_write(map, datum, adr);
@@ -365,13 +365,79 @@
 		ret = -EIO;
 	}       
 	DISABLE_VPP(map);
-	chip->state = FL_READY;
-	wake_up(&chip->wq);
+        if (!fast) {
+	        chip->state = FL_READY;
+	        wake_up(&chip->wq);
+        }
 	cfi_spin_unlock(chip->mutex);
 	
 	return ret;
 }
 
+static void cfi_enter_bypass_mode (struct mtd_info *mtd, int chipnum)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+        unsigned long chipstart;
+        struct flchip *chip = &cfi->chips[chipnum];
+	unsigned long timeo = jiffies + HZ;
+	DECLARE_WAITQUEUE(wait, current);
+
+ retry:
+	cfi_spin_lock(chip->mutex);
+
+	if (chip->state != FL_READY){
+	        printk("Waiting for chip to write, status = %d\n", chip->state);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		cfi_spin_unlock(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+		printk("Wake up to write:\n");
+#if 0
+		if(signal_pending(current))
+			return -EINTR;
+#endif
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	chip->state = FL_WRITING;
+
+        chipstart = cfi->chips[chipnum].start;
+
+	/* Go into unlock bypass mode */
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+
+	cfi_spin_unlock(chip->mutex);
+}
+
+static void cfi_exit_bypass_mode (struct mtd_info *mtd, int chipnum)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+        unsigned long chipstart;
+        struct flchip *chip = &cfi->chips[chipnum];
+
+	chipstart = cfi->chips[chipnum].start;
+
+	cfi_spin_lock(chip->mutex);
+
+	/* Come out of bypass mode */
+	cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+
+	chip->state = FL_READY;
+	wake_up(&chip->wq);
+
+        cfi_spin_unlock(chip->mutex);
+}
+
 static int cfi_amdstd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
 {
 	struct map_info *map = mtd->priv;
@@ -425,10 +491,10 @@
 		}
 	}
 	
-	/* Go into unlock bypass mode */
-	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
+        if (cfi->fast_prog) {
+  	        /* Go into unlock bypass mode */
+                cfi_enter_bypass_mode (mtd, chipnum);
+        }
 
 	/* We are now aligned, write as much as possible */
 	while(len >= CFIDEV_BUSWIDTH) {
@@ -448,8 +514,7 @@
 		if (ret) {
 			if (cfi->fast_prog){
 				/* Get out of unlock bypass mode */
-				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
-				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+                                cfi_exit_bypass_mode (mtd, chipnum);
 			}
 			return ret;
 		}
@@ -462,8 +527,7 @@
 		if (ofs >> cfi->chipshift) {
 			if (cfi->fast_prog){
 				/* Get out of unlock bypass mode */
-				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
-				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+                                cfi_exit_bypass_mode (mtd, chipnum);
 			}
 
 			chipnum ++; 
@@ -473,17 +537,14 @@
 			chipstart = cfi->chips[chipnum].start;
 			if (cfi->fast_prog){
 				/* Go into unlock bypass mode for next set of chips */
-				cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-				cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-				cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
+                                cfi_enter_bypass_mode (mtd, chipnum);
 			}
 		}
 	}
 
 	if (cfi->fast_prog){
 		/* Get out of unlock bypass mode */
-		cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
-		cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi->interleave, cfi->device_type, NULL);
+                cfi_exit_bypass_mode (mtd, chipnum);
 	}
 
 	if (len & (CFIDEV_BUSWIDTH-1)) {
@@ -546,11 +607,11 @@
 
 	adr += chip->start;
 	ENABLE_VPP(map);
-	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi->interleave, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi->interleave, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi->interleave, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi->interleave, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi->interleave, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi->interleave, cfi->device_type, NULL);
 	cfi_write(map, CMD(0x30), adr);
 	
 	timeo = jiffies + (HZ*20);