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

Next file: linux/drivers/scsi/imm.h
Previous file: linux/drivers/scsi/3w-xxxx.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test4/linux/drivers/scsi/imm.c linux/drivers/scsi/imm.c
@@ -32,6 +32,7 @@
 typedef struct {
     struct pardevice *dev;	/* Parport device entry         */
     int base;			/* Actual port address          */
+    int base_hi;		/* Hi Base address for ECP-ISA chipset */
     int mode;			/* Transfer mode                */
     int host;			/* Host number (for proc)       */
     Scsi_Cmnd *cur_cmd;		/* Current queued command       */
@@ -46,6 +47,7 @@
 #define IMM_EMPTY \
 {	dev:		NULL,		\
 	base:		-1,		\
+	base_hi:	0,		\
 	mode:		IMM_AUTODETECT,	\
 	host:		-1,		\
 	cur_cmd:	NULL,		\
@@ -63,6 +65,7 @@
 {IMM_EMPTY, IMM_EMPTY, IMM_EMPTY, IMM_EMPTY};
 
 #define IMM_BASE(x)	imm_hosts[(x)].base
+#define IMM_BASE_HI(x)     imm_hosts[(x)].base_hi
 
 int parbus_base[NO_HOSTS] =
 {0x03bc, 0x0378, 0x0278, 0x0000};
@@ -158,6 +161,7 @@
 	    }
 	}
 	ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base;
+	IMM_BASE_HI(i) = imm_hosts[i].dev->port->base_hi;
 	w_ctr(ppb, 0x0c);
 	modes = imm_hosts[i].dev->port->modes;
 
@@ -374,6 +378,9 @@
     return a;
 }
 
+/* 
+ * Clear EPP timeout bit. 
+ */
 static inline void epp_reset(unsigned short ppb)
 {
     int i;
@@ -383,19 +390,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=IMM_BASE_HI(hostno);
 
-    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("imm: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("imm: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int imm_byte_out(unsigned short base, const char *buffer, int len)
@@ -483,7 +494,7 @@
 	w_ctr(ppb, 0xc);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0xc);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     case IMM_NIBBLE:
@@ -545,7 +556,7 @@
 	w_ctr(ppb, 0x2c);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0x2c);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
@@ -815,10 +826,8 @@
 		 * Make sure that we transfer even number of bytes
 		 * otherwise it makes imm_byte_out() messy.
 		 */
-		if (cmd->SCp.this_residual & 0x01) {
+		if (cmd->SCp.this_residual & 0x01)
 		    cmd->SCp.this_residual++;
-		    printk("IMM: adjusted buffer for 16 bit transfer\n");
-		}
 	    }
 	}
 	/* Now check to see if the drive is ready to comunicate */
@@ -994,10 +1003,8 @@
 	}
 	cmd->SCp.buffers_residual = cmd->use_sg;
 	cmd->SCp.phase++;
-	if (cmd->SCp.this_residual & 0x01) {
+	if (cmd->SCp.this_residual & 0x01)
 	    cmd->SCp.this_residual++;
-	    printk("IMM: adjusted buffer for 16 bit transfer\n");
-	}
 	/* Phase 5 - Pre-Data transfer stage */
     case 5:
 	/* Spin lock for BUSY */
@@ -1239,7 +1246,7 @@
 	    return 1;
 	}
 	imm_disconnect(host_no);
-	printk("imm: Communication established with ID %i using %s\n", loop,
+	printk("imm: Communication established at 0x%x with ID %i using %s\n", ppb, loop,
 	       IMM_MODE_STRING[imm_hosts[host_no].mode]);
 	imm_connect(host_no, CONNECT_EPP_MAYBE);
 	imm_reset_pulse(IMM_BASE(host_no));

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