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