From f7380b25d3de5223060c92121c76044b59dc9567 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 8 Apr 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-04-08 --- pc/ether8390.c | 203 +++++++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 93 deletions(-) diff --git a/pc/ether8390.c b/pc/ether8390.c index 2c7bc7af1b3b36e6917da3ca4719b0c6277d648b..a1c5285ba044fd78dbca6a89629112b2922b1426 100644 --- a/pc/ether8390.c +++ b/pc/ether8390.c @@ -14,9 +14,6 @@ #include "etherif.h" -extern int slowinb(ulong); -extern void slowoutb(ulong, uchar); - enum { Cr = 0x00, /* command register, all pages */ @@ -149,6 +146,26 @@ typedef struct { uchar len1; } Hdr; +/* + * the 8390 register accesses must not be too close together + */ +void +dp8390outb(ulong port, uchar x) +{ + outb(port, x); + microdelay(0); +} + +long +dp8390inb(ulong port) +{ + long x; + + x = inb(port); + microdelay(0); + return x; +} + static void dp8390disable(Dp8390 *dp8390) { @@ -163,10 +180,10 @@ dp8390disable(Dp8390 *dp8390) * chip there if this is called when probing for a device * at boot. */ - slowoutb(port+Cr, Page0|RDMAabort|Stp); - slowoutb(port+Rbcr0, 0); - slowoutb(port+Rbcr1, 0); - for(timo = 10000; (slowinb(port+Isr) & Rst) == 0 && timo; timo--) + dp8390outb(port+Cr, Page0|RDMAabort|Stp); + dp8390outb(port+Rbcr0, 0); + dp8390outb(port+Rbcr1, 0); + for(timo = 10000; (dp8390inb(port+Isr) & Rst) == 0 && timo; timo--) ; } @@ -175,13 +192,13 @@ dp8390ring(Dp8390 *dp8390) { ulong port = dp8390->dp8390; - slowoutb(port+Pstart, dp8390->pstart); - slowoutb(port+Pstop, dp8390->pstop); - slowoutb(port+Bnry, dp8390->pstop-1); + dp8390outb(port+Pstart, dp8390->pstart); + dp8390outb(port+Pstop, dp8390->pstop); + dp8390outb(port+Bnry, dp8390->pstop-1); - slowoutb(port+Cr, Page1|RDMAabort|Stp); - slowoutb(port+Curr, dp8390->pstart); - slowoutb(port+Cr, Page0|RDMAabort|Stp); + dp8390outb(port+Cr, Page1|RDMAabort|Stp); + dp8390outb(port+Curr, dp8390->pstart); + dp8390outb(port+Cr, Page0|RDMAabort|Stp); dp8390->nxtpkt = dp8390->pstart; } @@ -200,11 +217,11 @@ dp8390setea(Ether *ether) * addresses as we never set the multicast * enable. */ - cr = slowinb(port+Cr) & ~Txp; - slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); + cr = dp8390inb(port+Cr) & ~Txp; + dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); for(i = 0; i < sizeof(ether->ea); i++) - slowoutb(port+Par0+i, ether->ea[i]); - slowoutb(port+Cr, cr); + dp8390outb(port+Par0+i, ether->ea[i]); + dp8390outb(port+Cr, cr); } void @@ -221,11 +238,11 @@ dp8390getea(Ether *ether) * addresses as we never set the multicast * enable. */ - cr = slowinb(port+Cr) & ~Txp; - slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); + cr = dp8390inb(port+Cr) & ~Txp; + dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); for(i = 0; i < sizeof(ether->ea); i++) - ether->ea[i] = slowinb(port+Par0+i); - slowoutb(port+Cr, cr); + ether->ea[i] = dp8390inb(port+Par0+i); + dp8390outb(port+Cr, cr); } void* @@ -240,25 +257,25 @@ dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len) * using the DP8390 remote DMA facility, and place it at * 'to' in main memory, via the I/O data port. */ - cr = slowinb(port+Cr) & ~Txp; - slowoutb(port+Cr, Page0|RDMAabort|Sta); - slowoutb(port+Isr, Rdc); + cr = dp8390inb(port+Cr) & ~Txp; + dp8390outb(port+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Isr, Rdc); /* * Set up the remote DMA address and count. */ if(dp8390->bit16) len = ROUNDUP(len, 2); - slowoutb(port+Rbcr0, len & 0xFF); - slowoutb(port+Rbcr1, (len>>8) & 0xFF); - slowoutb(port+Rsar0, from & 0xFF); - slowoutb(port+Rsar1, (from>>8) & 0xFF); + dp8390outb(port+Rbcr0, len & 0xFF); + dp8390outb(port+Rbcr1, (len>>8) & 0xFF); + dp8390outb(port+Rsar0, from & 0xFF); + dp8390outb(port+Rsar1, (from>>8) & 0xFF); /* * Start the remote DMA read and suck the data * out of the I/O port. */ - slowoutb(port+Cr, Page0|RDMAread|Sta); + dp8390outb(port+Cr, Page0|RDMAread|Sta); if(dp8390->bit16) inss(dp8390->data, to, len/2); else @@ -271,11 +288,11 @@ dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len) * to the miracles of the bus, we could get this far * and still be talking to a slot full of nothing. */ - for(timo = 10000; (slowinb(port+Isr) & Rdc) == 0 && timo; timo--) + for(timo = 10000; (dp8390inb(port+Isr) & Rdc) == 0 && timo; timo--) ; - slowoutb(port+Isr, Rdc); - slowoutb(port+Cr, cr); + dp8390outb(port+Isr, Rdc); + dp8390outb(port+Cr, cr); return to; } @@ -298,9 +315,9 @@ dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len) * using the DP8390 remote DMA facility, reading it at * 'from' in main memory, via the I/O data port. */ - cr = slowinb(port+Cr) & ~Txp; - slowoutb(port+Cr, Page0|RDMAabort|Sta); - slowoutb(port+Isr, Rdc); + cr = dp8390inb(port+Cr) & ~Txp; + dp8390outb(port+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Isr, Rdc); if(dp8390->bit16) len = ROUNDUP(len, 2); @@ -311,24 +328,24 @@ dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len) * the initial set up for read. */ crda = to-1-dp8390->bit16; - slowoutb(port+Rbcr0, (len+1+dp8390->bit16) & 0xFF); - slowoutb(port+Rbcr1, ((len+1+dp8390->bit16)>>8) & 0xFF); - slowoutb(port+Rsar0, crda & 0xFF); - slowoutb(port+Rsar1, (crda>>8) & 0xFF); - slowoutb(port+Cr, Page0|RDMAread|Sta); + dp8390outb(port+Rbcr0, (len+1+dp8390->bit16) & 0xFF); + dp8390outb(port+Rbcr1, ((len+1+dp8390->bit16)>>8) & 0xFF); + dp8390outb(port+Rsar0, crda & 0xFF); + dp8390outb(port+Rsar1, (crda>>8) & 0xFF); + dp8390outb(port+Cr, Page0|RDMAread|Sta); for(;;){ - crda = slowinb(port+Crda0); - crda |= slowinb(port+Crda1)<<8; + crda = dp8390inb(port+Crda0); + crda |= dp8390inb(port+Crda1)<<8; if(crda == to){ /* * Start the remote DMA write and make sure * the registers are correct. */ - slowoutb(port+Cr, Page0|RDMAwrite|Sta); + dp8390outb(port+Cr, Page0|RDMAwrite|Sta); - crda = slowinb(port+Crda0); - crda |= slowinb(port+Crda1)<<8; + crda = dp8390inb(port+Crda0); + crda |= dp8390inb(port+Crda1)<<8; if(crda != to) panic("crda write %d to %d\n", crda, to); @@ -349,15 +366,15 @@ dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len) * be almost immediate. */ tries = 0; - while((slowinb(port+Isr) & Rdc) == 0){ + while((dp8390inb(port+Isr) & Rdc) == 0){ if(tries++ >= 100000){ print("dp8390write dma timed out\n"); break; } } - slowoutb(port+Isr, Rdc); - slowoutb(port+Cr, cr); + dp8390outb(port+Isr, Rdc); + dp8390outb(port+Cr, cr); splx(s); return (void*)to; @@ -369,10 +386,10 @@ getcurr(Dp8390 *dp8390) ulong port = dp8390->dp8390; uchar cr, curr; - cr = slowinb(port+Cr) & ~Txp; - slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); - curr = slowinb(port+Curr); - slowoutb(port+Cr, cr); + cr = dp8390inb(port+Cr) & ~Txp; + dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); + curr = dp8390inb(port+Curr); + dp8390outb(port+Cr, cr); return curr; } @@ -416,9 +433,9 @@ receive(Ether *ether) || len < 60 || len > sizeof(Etherpkt)){ print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d\n", hdr.status, hdr.next, hdr.len0, hdr.len1, len); - slowoutb(port+Cr, Page0|RDMAabort|Stp); + dp8390outb(port+Cr, Page0|RDMAabort|Stp); dp8390ring(dp8390); - slowoutb(port+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Cr, Page0|RDMAabort|Sta); return; } @@ -467,7 +484,7 @@ receive(Ether *ether) hdr.next--; if(hdr.next < dp8390->pstart) hdr.next = dp8390->pstop-1; - slowoutb(port+Bnry, hdr.next); + dp8390outb(port+Bnry, hdr.next); } } @@ -519,9 +536,9 @@ write(Ether *ether, void *buf, long len) if(dp8390->ram == 0) dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len); - slowoutb(port+Tbcr0, len & 0xFF); - slowoutb(port+Tbcr1, (len>>8) & 0xFF); - slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); + dp8390outb(port+Tbcr0, len & 0xFF); + dp8390outb(port+Tbcr1, (len>>8) & 0xFF); + dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); return len; } @@ -541,24 +558,24 @@ overflow(Ether *ether) * The following procedure is taken from the DP8390[12D] datasheet, * it seems pretty adamant that this is what has to be done. */ - txp = slowinb(port+Cr) & Txp; - slowoutb(port+Cr, Page0|RDMAabort|Stp); + txp = dp8390inb(port+Cr) & Txp; + dp8390outb(port+Cr, Page0|RDMAabort|Stp); delay(2); - slowoutb(port+Rbcr0, 0); - slowoutb(port+Rbcr1, 0); + dp8390outb(port+Rbcr0, 0); + dp8390outb(port+Rbcr1, 0); resend = 0; - if(txp && (slowinb(port+Isr) & (Txe|Ptx)) == 0) + if(txp && (dp8390inb(port+Isr) & (Txe|Ptx)) == 0) resend = 1; - slowoutb(port+Tcr, Lb); - slowoutb(port+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Tcr, Lb); + dp8390outb(port+Cr, Page0|RDMAabort|Sta); receive(ether); - slowoutb(port+Isr, Ovw); - slowoutb(port+Tcr, 0); + dp8390outb(port+Isr, Ovw); + dp8390outb(port+Tcr, 0); if(resend) - slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); + dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); } static void @@ -579,12 +596,12 @@ interrupt(Ureg *ur, void *arg) * While there is something of interest, * clear all the interrupts and process. */ - slowoutb(port+Imr, 0x00); - while(isr = slowinb(port+Isr)){ + dp8390outb(port+Imr, 0x00); + while(isr = dp8390inb(port+Isr)){ if(isr & Ovw){ overflow(ether); - slowoutb(port+Isr, Ovw); + dp8390outb(port+Isr, Ovw); ether->overflows++; } @@ -594,7 +611,7 @@ interrupt(Ureg *ur, void *arg) */ if(isr & (Rxe|Prx)){ receive(ether); - slowoutb(port+Isr, Rxe|Prx); + dp8390outb(port+Isr, Rxe|Prx); } /* @@ -603,14 +620,14 @@ interrupt(Ureg *ur, void *arg) * and wake the output routine. */ if(isr & (Txe|Ptx)){ - r = slowinb(port+Tsr); + r = dp8390inb(port+Tsr); if(isr & Txe){ if((r & (Cdh|Fu|Crs|Abt))) print("dp8390: Tsr#%2.2ux\n", r); ether->oerrs++; } - slowoutb(port+Isr, Txe|Ptx); + dp8390outb(port+Isr, Txe|Ptx); if(isr & Ptx) ether->outpackets++; @@ -619,13 +636,13 @@ interrupt(Ureg *ur, void *arg) } if(isr & Cnt){ - ether->frames += slowinb(port+Cntr0); - ether->crcs += slowinb(port+Cntr1); - ether->buffs += slowinb(port+Cntr2); - slowoutb(port+Isr, Cnt); + ether->frames += dp8390inb(port+Cntr0); + ether->crcs += dp8390inb(port+Cntr1); + ether->buffs += dp8390inb(port+Cntr2); + dp8390outb(port+Isr, Cnt); } } - slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); + dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); } static void @@ -637,9 +654,9 @@ promiscuous(void *arg, int on) * Set/reset promiscuous mode. */ if(on) - slowoutb(dp8390->dp8390+Rcr, Pro|Ab); + dp8390outb(dp8390->dp8390+Rcr, Pro|Ab); else - slowoutb(dp8390->dp8390+Rcr, Ab); + dp8390outb(dp8390->dp8390+Rcr, Ab); } static void @@ -653,8 +670,8 @@ attach(Ether *ether) * mode. Clear the missed-packet counter, it * increments while in monitor mode. */ - slowoutb(dp8390->dp8390+Rcr, Ab); - slowinb(dp8390->dp8390+Cntr2); + dp8390outb(dp8390->dp8390+Rcr, Ab); + dp8390inb(dp8390->dp8390+Cntr2); } int @@ -673,15 +690,15 @@ dp8390reset(Ether *ether) */ dp8390disable(dp8390); if(dp8390->bit16) - slowoutb(port+Dcr, Ft4|Ls|Wts); + dp8390outb(port+Dcr, Ft4|Ls|Wts); else - slowoutb(port+Dcr, Ft4|Ls); + dp8390outb(port+Dcr, Ft4|Ls); - slowoutb(port+Rbcr0, 0); - slowoutb(port+Rbcr1, 0); + dp8390outb(port+Rbcr0, 0); + dp8390outb(port+Rbcr1, 0); - slowoutb(port+Tcr, 0); - slowoutb(port+Rcr, Mon); + dp8390outb(port+Tcr, 0); + dp8390outb(port+Rcr, Mon); /* * Init the ring hardware and software ring pointers. @@ -689,16 +706,16 @@ dp8390reset(Ether *ether) * it yet. */ dp8390ring(dp8390); - slowoutb(port+Tpsr, dp8390->tstart); + dp8390outb(port+Tpsr, dp8390->tstart); - slowoutb(port+Isr, 0xFF); - slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); + dp8390outb(port+Isr, 0xFF); + dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); /* * Leave the chip initialised, * but in monitor mode. */ - slowoutb(port+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Cr, Page0|RDMAabort|Sta); /* * Set up the software configuration.