@@ 468,7 468,6 @@ reset(Ctlr *ctlr, ulong port, ulong id)
void
resetscsi(void)
{
- uchar rs;
ulong port;
/*
@@ 484,10 483,8 @@ resetscsi(void)
*/
outb(port+Rc, Srst|Scrst);
delay(500);
- if((rs = inb(port+Rs)) != (Init|Idle)){
- /*print("adaptec%d: reset status #%2.2ux\n", 0, rs);/**/
+ if(inb(port+Rs) != (Init|Idle))
return;
- }
setvec(Int0vec+Irq, interrupt);
reset(&softctlr[0], port, CtlrID);
@@ 9,11 9,16 @@
#include "ether.h"
+/*
+ * Western Digital/Standard Microsystems Corporation cards (WD80[01]3).
+ * Configuration code based on that provided by SMC.
+ */
enum { /* 83C584 Bus Interface Controller */
Msr = 0x00, /* Memory Select Register */
Icr = 0x01, /* Interface Configuration Register */
Iar = 0x02, /* I/O Address Register */
Bio = 0x03, /* BIOS ROM Address Register */
+ Ear = 0x03, /* EEROM Address Register (shared with Bio) */
Irr = 0x04, /* Interrupt Request Register */
Laar = 0x05, /* LA Address Register */
Ijr = 0x06, /* Initialisation Jumpers */
@@ 28,6 33,17 @@ enum { /* Msr */
Menb = 0x40, /* memory enable */
};
+enum { /* Icr */
+ Bit16 = 0x01, /* 16-bit bus */
+ Other = 0x02, /* other register access */
+ Ir2 = 0x04, /* IR2 */
+ Msz = 0x08, /* SRAM size */
+ Rla = 0x10, /* recall LAN address */
+ Rx7 = 0x20, /* recall all but I/O and LAN address */
+ Rio = 0x40, /* recall I/O address from EEROM */
+ Sto = 0x80, /* non-volatile EEROM store */
+};
+
enum { /* Laar */
ZeroWS16 = (1<<5), /* zero wait states for 16-bit ops */
L16en = (1<<6), /* enable 16-bit LAN operation */
@@ 43,23 59,28 @@ static int intrmap[] = {
/*
* Get configuration parameters, enable memory.
+ * There are opportunities here for buckets of code.
+ * We'll try to resist.
*/
static int
reset(Ctlr *ctlr)
{
int i;
- uchar msr, icr, laar, irr, sum;
+ uchar ic[8], sum;
/*
* Look for the interface. We read the LAN address ROM
* and validate the checksum - the sum of all 8 bytes
* should be 0xFF.
+ * While we're at it, get the (possible) interface chip
+ * registers, we'll use them to check for aliasing later.
*/
for(ctlr->card.io = 0x200; ctlr->card.io < 0x400; ctlr->card.io += 0x20){
sum = 0;
for(i = 0; i < sizeof(ctlr->ea); i++){
ctlr->ea[i] = inb(ctlr->card.io+Lar+i);
sum += ctlr->ea[i];
+ ic[i] = inb(ctlr->card.io+i);
}
sum += inb(ctlr->card.io+Id);
sum += inb(ctlr->card.io+Cksum);
@@ 70,17 91,6 @@ reset(Ctlr *ctlr)
return -1;
/*
- * Found it, reset it.
- * Be careful to preserve the Msr address bits,
- * they don't get reloaded from the EEPROM on reset.
- */
- msr = inb(ctlr->card.io+Msr);
- outb(ctlr->card.io+Msr, Rst|msr);
- delay(1);
- outb(ctlr->card.io+Msr, msr);
- delay(2);
-
- /*
* Check for old, dumb 8003E, which doesn't have an interface
* chip. Only the msr exists out of the 1st eight registers, reads
* of the others just alias the 2nd eight registers, the LAN
@@ 89,32 99,53 @@ reset(Ctlr *ctlr)
* 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which
* case the default irq gets used.
*/
- msr = inb(ctlr->card.io+Msr);
- icr = inb(ctlr->card.io+Icr);
- laar = inb(ctlr->card.io+Laar);
- irr = inb(ctlr->card.io+Irr);
- if(icr != ctlr->ea[1] || irr != ctlr->ea[4] || laar != ctlr->ea[5])
- ctlr->card.irq = intrmap[((irr>>5) & 0x3)|(icr & 0x4)];
- else {
- msr = (((ulong)ctlr->card.ramstart)>>13) & 0x3F;
- icr = laar = 0;
+ if(memcmp(&ctlr->ea[1], &ic[1], 5) == 0){
+ memset(ic, 0, sizeof(ic));
+ ic[Msr] = (((ulong)ctlr->card.ramstart)>>13) & 0x3F;
ctlr->card.watch = 0;
}
+ else{
+ /*
+ * As a final sanity check for the 8013EBT, which doesn't have
+ * the 83C584 interface chip, but has 2 real registers, write Gp2 and if
+ * it reads back the same, it's not an 8013EBT.
+ */
+ outb(ctlr->card.io+Gp2, 0xAA);
+ inb(ctlr->card.io+Msr); /* wiggle bus */
+ if(inb(ctlr->card.io+Gp2) != 0xAA){
+ memset(ic, 0, sizeof(ic));
+ ic[Msr] = (((ulong)ctlr->card.ramstart)>>13) & 0x3F;
+ ctlr->card.watch = 0;
+ ctlr->card.irq = 2; /* special */
+ }
+ else
+ ctlr->card.irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];
+
+ /*
+ * Check if 16-bit card.
+ * If Bit16 is read/write, then we have an 8-bit card.
+ * If Bit16 is set, we're in a 16-bit slot.
+ */
+ outb(ctlr->card.io+Icr, ic[Icr]^Bit16);
+ inb(ctlr->card.io+Msr); /* wiggle bus */
+ if((inb(ctlr->card.io+Icr) & Bit16) == (ic[Icr] & Bit16)){
+ ctlr->card.bit16 = 1;
+ ic[Icr] &= ~Bit16;
+ }
+ outb(ctlr->card.io+Icr, ic[Icr]);
- /*
- * Set up the bus-size, RAM address and RAM size
- * from the info in the configuration registers.
- */
- ctlr->card.bit16 = icr & 0x1;
+ ic[Icr] = inb(ctlr->card.io+Icr);
+ if(ctlr->card.bit16 && (ic[Icr] & Bit16) == 0)
+ ctlr->card.bit16 = 0;
+ }
- ctlr->card.ram = 1;
- ctlr->card.ramstart = KZERO|((msr & 0x3F)<<13);
+ ctlr->card.ramstart = KZERO|((ic[Msr] & 0x3F)<<13);
if(ctlr->card.bit16)
- ctlr->card.ramstart |= (laar & 0x1F)<<19;
+ ctlr->card.ramstart |= (ic[Laar] & 0x1F)<<19;
else
ctlr->card.ramstart |= 0x80000;
- if(icr & (1<<3))
+ if(ic[Icr] & (1<<3))
ctlr->card.ramstop = 32*1024;
else
ctlr->card.ramstop = 8*1024;
@@ 133,9 164,9 @@ reset(Ctlr *ctlr)
/*
* Enable interface RAM, set interface width.
*/
- outb(ctlr->card.io+Msr, Menb|msr);
+ outb(ctlr->card.io+Msr, ic[Msr]|Menb);
if(ctlr->card.bit16)
- outb(ctlr->card.io+Laar, laar|L16en|M16en|ZeroWS16);
+ outb(ctlr->card.io+Laar, ic[Laar]|L16en|M16en|ZeroWS16);
/*
* Finally, init the 8390 and set the