--- linux/drivers/scsi/imm.c-240t5p2-orig Wed Jul 19 20:21:28 2000 +++ linux/drivers/scsi/imm.c Thu Jul 20 22:36:54 2000 @@ -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: @@ -1235,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)); --- linux/drivers/scsi/imm.h-240t5p2 Thu Jul 20 21:41:42 2000 +++ linux/drivers/scsi/imm.h Thu Jul 20 21:54:49 2000 @@ -125,14 +125,15 @@ #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) --- linux/drivers/scsi/ppa.h-240t5p2-orig Thu Jul 20 21:54:59 2000 +++ linux/drivers/scsi/ppa.h Thu Jul 20 21:56:17 2000 @@ -123,14 +123,15 @@ #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) --- linux/drivers/scsi/ppa.c-240t5-orig Thu Jul 20 21:57:07 2000 +++ linux/drivers/scsi/ppa.c Thu Jul 20 22:33:12 2000 @@ -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); @@ -321,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) { @@ -333,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) @@ -420,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: @@ -473,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: