summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/imm.c35
-rw-r--r--drivers/scsi/imm.h9
-rw-r--r--drivers/scsi/ppa.c36
-rw-r--r--drivers/scsi/ppa.h9
4 files changed, 53 insertions, 36 deletions
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index b8e134fa5..effaf3ec1 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -32,6 +32,7 @@ static int device_check(int host_no);
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 @@ typedef struct {
#define IMM_EMPTY \
{ dev: NULL, \
base: -1, \
+ base_hi: 0, \
mode: IMM_AUTODETECT, \
host: -1, \
cur_cmd: NULL, \
@@ -63,6 +65,7 @@ static imm_struct imm_hosts[NO_HOSTS] =
{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 @@ int imm_detect(Scsi_Host_Template * host)
}
}
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 @@ static int imm_negotiate(imm_struct * tmp)
return a;
}
+/*
+ * Clear EPP timeout bit.
+ */
static inline void epp_reset(unsigned short ppb)
{
int i;
@@ -383,19 +390,23 @@ static inline void epp_reset(unsigned short ppb)
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 @@ static int imm_out(int host_no, char *buffer, int len)
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 @@ static int imm_in(int host_no, char *buffer, int len)
w_ctr(ppb, 0x2c);
r = !(r_str(ppb) & 0x01);
w_ctr(ppb, 0x2c);
- ecp_sync(ppb);
+ ecp_sync(host_no);
break;
default:
@@ -1235,7 +1246,7 @@ static int device_check(int host_no)
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));
diff --git a/drivers/scsi/imm.h b/drivers/scsi/imm.h
index 8221706db..0abe7a6cd 100644
--- a/drivers/scsi/imm.h
+++ b/drivers/scsi/imm.h
@@ -125,14 +125,15 @@ int imm_sg = SG_ALL; /* enable/disable scatter-gather. */
#define r_str(x) (unsigned char)inb((x)+1)
#define r_ctr(x) (unsigned char)inb((x)+2)
#define r_epp(x) (unsigned char)inb((x)+4)
-#define r_fifo(x) (unsigned char)inb((x)+0x400)
-#define r_ecr(x) (unsigned char)inb((x)+0x402)
+#define r_fifo(x) (unsigned char)inb((x)) /* x must be base_hi */
+ /* On PCI is: base+0x400 != base_hi */
+#define r_ecr(x) (unsigned char)inb((x)+2) /* x must be base_hi */
#define w_dtr(x,y) outb(y, (x))
#define w_str(x,y) outb(y, (x)+1)
#define w_epp(x,y) outb(y, (x)+4)
-#define w_fifo(x,y) outb(y, (x)+0x400)
-#define w_ecr(x,y) outb(y, (x)+0x402)
+#define w_fifo(x,y) outb(y, (x)) /* x must be base_hi */
+#define w_ecr(x,y) outb(y, (x)+0x2) /* x must be base_hi */
#ifdef CONFIG_SCSI_IZIP_SLOW_CTR
#define w_ctr(x,y) outb_p(y, (x)+2)
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index d31a72d3d..54f7da01f 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -125,7 +125,7 @@ int ppa_detect(Scsi_Host_Template * host)
}
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 @@ int ppa_detect(Scsi_Host_Template * host)
}
}
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 @@ int ppa_detect(Scsi_Host_Template * host)
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);
@@ -321,8 +322,7 @@ static unsigned char ppa_wait(int host_no)
}
/*
- * 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)
{
@@ -333,19 +333,23 @@ static inline void epp_reset(unsigned short ppb)
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)
@@ -420,7 +424,7 @@ static int ppa_out(int host_no, char *buffer, int len)
w_ctr(ppb, 0xc);
r = !(r_str(ppb) & 0x01);
w_ctr(ppb, 0xc);
- ecp_sync(ppb);
+ ecp_sync(host_no);
break;
default:
@@ -473,7 +477,7 @@ static int ppa_in(int host_no, char *buffer, int len)
w_ctr(ppb, 0x2c);
r = !(r_str(ppb) & 0x01);
w_ctr(ppb, 0x2c);
- ecp_sync(ppb);
+ ecp_sync(host_no);
break;
default:
diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h
index 9f2ebcdb9..7ab442bbb 100644
--- a/drivers/scsi/ppa.h
+++ b/drivers/scsi/ppa.h
@@ -123,14 +123,15 @@ int ppa_sg = SG_ALL; /* enable/disable scatter-gather. */
#define r_str(x) (unsigned char)inb((x)+1)
#define r_ctr(x) (unsigned char)inb((x)+2)
#define r_epp(x) (unsigned char)inb((x)+4)
-#define r_fifo(x) (unsigned char)inb((x)+0x400)
-#define r_ecr(x) (unsigned char)inb((x)+0x402)
+#define r_fifo(x) (unsigned char)inb((x)) /* x must be base_hi */
+ /* On PCI is base+0x400 != base_hi */
+#define r_ecr(x) (unsigned char)inb((x)+0x2) /* x must be base_hi */
#define w_dtr(x,y) outb(y, (x))
#define w_str(x,y) outb(y, (x)+1)
#define w_epp(x,y) outb(y, (x)+4)
-#define w_fifo(x,y) outb(y, (x)+0x400)
-#define w_ecr(x,y) outb(y, (x)+0x402)
+#define w_fifo(x,y) outb(y, (x)) /* x must be base_hi */
+#define w_ecr(x,y) outb(y, (x)+0x2)/* x must be base_hi */
#ifdef CONFIG_SCSI_IZIP_SLOW_CTR
#define w_ctr(x,y) outb_p(y, (x)+2)