patch-2.4.0-test5 linux/drivers/scsi/ppa.c

Next file: linux/drivers/scsi/ppa.h
Previous file: linux/drivers/scsi/pluto.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test4/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
@@ -125,7 +125,7 @@
     }
   retry_entry:
     for (i = 0; pb; i++, pb = pb->next) {
-	int modes, ppb;
+	int modes, ppb, ppb_hi;
 
 	ppa_hosts[i].dev =
 	    parport_register_device(pb, "ppa", NULL, ppa_wakeup,
@@ -150,6 +150,7 @@
 	    }
 	}
 	ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base;
+	ppb_hi =  ppa_hosts[i].dev->port->base_hi;
 	w_ctr(ppb, 0x0c);
 	modes = ppa_hosts[i].dev->port->modes;
 
@@ -162,11 +163,11 @@
 	    ppa_hosts[i].mode = PPA_PS2;
 
 	if (modes & PARPORT_MODE_ECP) {
-	    w_ecr(ppb, 0x20);
+	    w_ecr(ppb_hi, 0x20);
 	    ppa_hosts[i].mode = PPA_PS2;
 	}
 	if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP))
-	    w_ecr(ppb, 0x80);
+	    w_ecr(ppb_hi, 0x80);
 
 	/* Done configuration */
 	ppa_pb_release(i);
@@ -298,12 +299,11 @@
     unsigned char r;
 
     k = PPA_SPIN_TMO;
-    do {
-	r = r_str(ppb);
-	k--;
-	udelay(1);
+    /* Wait for bit 6 and 7 - PJC */
+    for (r = r_str (ppb); ((r & 0xc0)!=0xc0) && (k); k--) {
+	    udelay (1);
+	    r = r_str (ppb);
     }
-    while (!(r & 0x80) && (k));
 
     /*
      * return some status information.
@@ -322,8 +322,7 @@
 }
 
 /*
- * output a string, in whatever mode is available, according to the
- * PPA protocol. 
+ * Clear EPP Timeout Bit 
  */
 static inline void epp_reset(unsigned short ppb)
 {
@@ -334,19 +333,23 @@
     w_str(ppb, i & 0xfe);
 }
 
-static inline void ecp_sync(unsigned short ppb)
+/* 
+ * Wait for empty ECP fifo (if we are in ECP fifo mode only)
+ */
+static inline void ecp_sync(unsigned short hostno)
 {
-    int i;
+    int i, ppb_hi=ppa_hosts[hostno].dev->port->base_hi;
 
-    if ((r_ecr(ppb) & 0xe0) != 0x80)
-	return;
+    if (ppb_hi == 0) return;
 
-    for (i = 0; i < 100; i++) {
-	if (r_ecr(ppb) & 0x01)
-	    return;
-	udelay(5);
+    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
+        for (i = 0; i < 100; i++) {
+            if (r_ecr(ppb_hi) & 0x01)
+                return;
+            udelay(5);
+        }
+        printk("ppa: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("ppa: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int ppa_byte_out(unsigned short base, const char *buffer, int len)
@@ -421,7 +424,7 @@
 	w_ctr(ppb, 0xc);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0xc);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
@@ -474,7 +477,7 @@
 	w_ctr(ppb, 0x2c);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0x2c);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
@@ -637,7 +640,6 @@
      *  1     Finished data transfer
      */
     int host_no = cmd->host->unique_id;
-    unsigned short ppb = PPA_BASE(host_no);
     unsigned long start_jiffies = jiffies;
 
     unsigned char r, v;
@@ -649,11 +651,7 @@
 	    (v == WRITE_6) ||
 	    (v == WRITE_10));
 
-    /*
-     * We only get here if the drive is ready to comunicate,
-     * hence no need for a full ppa_wait.
-     */
-    r = (r_str(ppb) & 0xf0);
+    r = ppa_wait(host_no); /* Need a ppa_wait() - PJC */
 
     while (r != (unsigned char) 0xf0) {
 	/*
@@ -691,7 +689,7 @@
 	    }
 	}
 	/* Now check to see if the drive is ready to comunicate */
-	r = (r_str(ppb) & 0xf0);
+	r = ppa_wait(host_no); /* need ppa_wait() - PJC */
 	/* If not, drop back down to the scheduler and wait a timer tick */
 	if (!(r & 0x80))
 	    return 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)