etc/conf/ne/Space.c100644 3 3 1320 5570572764 12033 0ustar binbin/* filename : Space.c * purpose : define parameters for ne ethernet device driver * author : Randy Wright * Copyright ((C)) 1993 Randy Wright *** generated by ne installer *** */ /* these are tuneable values for irq */ int ne0_irq = 10; int ne1_irq = 0; int ne2_irq = 0; int ne3_irq = 0; /* these are tuneable values for base of io ports for each board */ int ne0_iobase = 0x300; int ne1_iobase = 0; int ne2_iobase = 0; int ne3_iobase = 0; /* these tunable parameters are not used by the NE1000/2000 * devices. They are present for the day that wd/smc cards * are supported by this driver. */ int ne0_mem = 0; int ne1_mem = 0; int ne2_mem = 0; int ne3_mem = 0; /* end Space.c for ne */ etc/conf/ne/src/ 40755 3 3 0 5575212662 11323 5ustar binbinetc/conf/ne/src/ne.c100644 3 3 141456 5570574001 12232 0ustar binbin/* * Driver Name : ne , NE * filename : ne.c * purpose : Character Special Device Driver * : Supports Polling * : Supports ioctl * : Major device number 19 * Device : NE1000 or NE2000 ethernet card * Copyright : ((C)) Randy Wright 1993 * * $Log: ne.c,v $ * Revision 2.0 94/01/19 16:10:57 root * added buffer useage stats, mulituser control, * all known bugs removed, It now seems robust. * * Revision 1.5 94/01/02 13:41:20 root * added Space.c functionality, cleaned up code. * works with neinstall. * * Revision 1.4 93/12/26 20:59:31 root * fixed last byte bug, upgraded thru-put * to 550 kb /sec on write side. Changed * address print to hex, fixed number of * simultaneuos cards to be 1 - 4. * * Revision 1.3 93/12/16 12:33:15 root * working version. gets 714 kb/sec recv * and 223 kb/sec send on raw speed tests. * * Revision 1.2 93/12/15 16:19:36 root * moved code from neth.c into ne.c * * Revision 1.1 93/12/15 14:09:03 root * Initial revision * */ /* typedef unsigned char u_char; */ /* typedef unsigned short u_short; */ #define NE_NUMBUFFS 16 /* number of static 1536 byte buffers for read side * and for write side of each board. */ #define NNE 4 /* number of ethernet boards */ #define NNE_MAX 4 /* maximum number of ethernet boards */ #define NE_LOWWAT 4 /* must be more than this many empty write * packet slots before we will add more */ /* undefine this if you have moved a finalized copy * of devices.h into /usr/include/sys */ #define NETEST NETEST #include #include #include #ifndef NETEST #include #else #include "devices.h.new" #endif /* NETEST */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ds8390.h" #include /* * External function declarations * H.C.P. replaced these with donone() in mz, I like it. extern int nulldev(); extern int nonedev(); */ /* * Driver function declarations */ static void neload(); static void neunload(); static void neopen(); static void neclose(); static void neread(); static void newrite(); static int neioctl(); static void newatch(); static void neblock(); static int nepoll(); /* * Forward references */ static void neput(); static void nefetch(); static void ne_donone(); static int nerestart(); static void necycle(); /* neintr needs to be externally visible */ void neintr(); static void ne0intr(); static void ne1intr(); static void ne2intr(); static void ne3intr(); /* * Driver Configuration CON struct. */ CON necon = { DFCHR|DFPOL, /* Flags */ NE_MAJOR, /* Major Index */ neopen, /* Open */ neclose, /* Close */ ne_donone, /* Not Blocking */ neread, /* Read */ newrite, /* Write */ neioctl, /* Ioctl */ ne_donone, /* Power fail */ ne_donone, /* Timeout */ neload, /* Load */ neunload, /* Unload */ nepoll /* Poll */ }; /* * Interrupt Entry Points. use them if you support mulitple devices */ void (*neintf[NNE_MAX])() = { ne0intr, ne1intr, ne2intr, ne3intr }; /* * Patchable parameters */ /* these are tuneable values for irq, defined in Space.c */ extern int ne0_irq; extern int ne1_irq; extern int ne2_irq; extern int ne3_irq; /* these are tuneable values for base of io ports for each board, * defined in Space.c */ extern int ne0_iobase; extern int ne1_iobase; extern int ne2_iobase; extern int ne3_iobase; /* these tunable parameters are not used by the NE1000/2000 * devices. They are present for the day that wd/smc cards * are supported by this driver. * defined in Space.c */ extern int ne0_mem; extern int ne1_mem; extern int ne2_mem; extern int ne3_mem; int ne_irq[NNE_MAX]; int ne_iobase[NNE_MAX]; paddr_t ne_mem[NNE_MAX]; /* NE1000/NE2000 do not use dual ported ram, but these mem pararmeters are * here in order to port this driver to ds8390 boards that do need dual * port memory mapped io. */ /* there is an ioctl to change this dynamically */ int ne_lowwater = NE_LOWWAT; /* * Register addresses. Locations that might need to be patched * Registers eg. Read, Write, Status, Control. */ ushort ne_eaddr[NNE_MAX][6]; /* * Control struct */ extern time_t lbolt; /* * data_c struct. */ #define ETHER_MIN_LEN 64 #define ETHER_MAX_LEN 1536 typedef struct ebuf_t { int len; /* get the length here */ char data[PKTSZ]; /* get the data here */ } ebuf_t; /* * Ethernet interface local data. There is an NNE sized array * of these. */ struct nedata_c { struct arpcom nd_ac; /* Ethernet common part, neioctl.h */ #define nd_if nd_ac /* network-visible interface */ #define nd_addrp nd_ac.ac_enaddr /* hardware Ethernet address */ int nd_flags; #define DSF_LOCK 1 /* block re-entering restart */ int nd_mask; /* interrupt reg mask */ int nd_ba; /* byte addr in buffer ram of inc pkt */ int nd_cur; /* current page being filled */ struct prhdr nd_ph; /* hrdwr hdr of inc packet, ds8390.h */ struct ether_header nd_eh; /* eth hdr of inc packet, neioctl.h */ short nd_txstart; /* transmitter buffer start */ u_short nd_rxend; /* recevier buffer end */ short nd_port; /* i/o port base */ short nd_mode; /* word/byte mode */ int nd_filemode; /* Open flags, eg O_WRONLY */ int nd_pad; /* pad */ int nd_refc; /* number of current opens */ int nd_reserved; /* pad */ event_t nd_inevent; /* poll events */ event_t nd_outevent; time_t nd_ipsleep; /* polling input timeout */ time_t nd_opsleep; /* polling output timeout */ /* buffering is accomplished by having * NE_NUMBUFS buffers for outgoing packets and * for incoming packets. * these are operated in a ring buffer method * Race conditions between interrupt code and * read write code is prevented by maintianing * at least one open packet between the head and tail * points. NE_NUMBUFS should be organized into * a tuneable parameter in Space.c * */ ebuf_t nd_rq[NE_NUMBUFFS]; /* read buffers */ int nd_norq; /* next open read side packet, * this is where we put * new arrivals coming * off the wires */ int nd_nrq; /* next received packet * This is the point from * which we copy data to the * user's data space in a read() */ ebuf_t nd_wq[NE_NUMBUFFS]; /* write buffers */ int nd_nowq; /* next open write side packet * This is where we put data * copied from the user's data * space in a write call. */ int nd_swq; /* next packet to send * this is where we will get * the next data to put into * the hardware's transmit * buffer */ int nd_state; /* state */ #define NE_NOBOARD -1 /* no ethernet hardware detected */ #define NE_NORMAL 0 /* normal state */ #define NE_DMAWAIT 1 /* waiting for dma to complete */ #define NE_XMIT 2 /* interrupt due in for xmit */ #define NE_RRUN 3 /* restart is running, no reentry */ TIM nd_tim; /* timeout struct */ int nd_timwait; /* keep timeout running */ /* statistics on data flow through our wires, the list * of stats needs to start at nd_collisions * and needs to be synced with neioctl.h */ int nd_collisions; /* number of collisions */ int nd_oerrors; /* number of xmit errors */ int nd_ierrors; /* number of recv errors */ int nd_opackets; /* xmitted packets */ int nd_ipackets; /* recv'd packets */ int nd_idiscards; /* incoming packets discarded */ int nd_lox; /* lowest num of xmit empties */ int nd_lor; /* lowest num of recv empties */ int nd_reentry; /* true if intr is already executing */ } nedata_c[NNE] ; #define ENBUFSIZE (sizeof(struct ether_header) + ETHERMTU + 2 + ETHER_MIN_LEN) int counter, linenum; #define NEPAUSE counter=1;while(counter--); #define PAT(n) (0xa55a + 37*(n)) u_short boarddata[16]; /* replacement for nondev and nulldev */ void ne_donone() { return; } /* void * neopen( dev, mode ) * dev_t dev; * int mode; * */ void neopen(dev, mode, flags) dev_t dev; int mode, flags; { struct aprcom *ifp; /* we need to mark it as running or not */ struct nedata_c *nd; /* the nedata_c struct corresponding to unit */ register neBase; /* the hardware io ports */ int unit; /* current board */ /* referenced in order to * shut the compiler error messages off */ flags; /* the minor device number is also the board number */ unit = minor( dev ); /* there are 4 nedata_c structs so that the * computer can support up to 4 ethernet boards. * We use the minor number to determine which * board shall be used. */ nd = &nedata_c[unit]; if( unit > ( NNE - 1 ) || unit < 0 ) { /* out of range card number */ set_user_error( ENXIO ); return; } /* if there is no ethernet board present */ if( nd->nd_state < 0 ) { set_user_error(ENODEV); return; } /* exclusive open only * / if( nd->nd_refc > 0) { set_user_error(EBUSY); return; } */ if( nd->nd_refc == 0) { /* first open determines access mode */ nd->nd_filemode = mode; } /* set the buffer pointers */ nd->nd_nrq = nd->nd_norq = nd->nd_nowq = nd->nd_swq = 0; /* initialize buffer supply statistics */ nd->nd_lox = nd->nd_lor = NE_NUMBUFFS; /* set the struct variables for later use */ neBase = nd->nd_port = ne_iobase[unit]; ifp = &nd->nd_ac; /* turn on the interrupts, but only if the output init * routine has turned the runniing flag off */ if (ifp->if_flags & IFF_RUNNING) ; else neoinit(unit); nd->nd_timwait = 1; /* Schedule cycler so we get watchdog timeouts */ necycle(unit); /* refc is available for the time when * we will run the device driver with more than one * concurrent process feeding it. refc allows us to * turn off the interrupts when no other processes * is using this net card. */ nd->nd_refc++; return; } /* * Initialization of interface; set up initialization block * and transmit/receive buffer descriptors. Performed at first open. */ neoinit(unit) int unit; { register struct nedata_c *nd = &nedata_c[unit]; struct aprcom *ifp = &nd->nd_ac; int s; int i; register neBase = nd->nd_port; /***> is this interface already active */ if (ifp->if_flags & IFF_RUNNING) return; /* the older style interrupt disable. This should probably * be updated */ s = sphi(); /* set physical address on ethernet card */ outb (neBase+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP); NEPAUSE for (i=0 ; i < 6 ; i++) outb(neBase+ds1_par0+i,nd->nd_addrp[i]); /* clear logical mulitcast address hash filter for now */ for (i=0 ; i < 8 ; i++) outb(neBase+ds1_mar0+i,0xff); /* init regs */ outb (neBase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP); NEPAUSE outb (neBase+ds0_rbcr0, 0); NEPAUSE outb (neBase+ds0_rbcr1, 0); NEPAUSE outb (neBase+ds0_imr, 0); NEPAUSE outb (neBase+ds0_isr, 0xff); NEPAUSE /* Word Transfer select, Burst Mode Select, Fifo at 8 bytes */ outb(neBase+ds0_dcr, nd->nd_mode); NEPAUSE outb(neBase+ds0_tcr, 0); NEPAUSE outb (neBase+ds0_rcr, DSRC_MON); NEPAUSE outb (neBase+ds0_tpsr, 0); NEPAUSE outb(neBase+ds0_pstart, (nd->nd_txstart+PKTSZ)/DS_PGSIZE); NEPAUSE outb(neBase+ds0_pstop, nd->nd_rxend/DS_PGSIZE); NEPAUSE outb(neBase+ds0_bnry, (nd->nd_txstart+PKTSZ)/DS_PGSIZE); NEPAUSE outb (neBase+ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP); NEPAUSE outb(neBase+ds1_curr, (nd->nd_txstart+PKTSZ)/DS_PGSIZE); NEPAUSE nd->nd_cur = (nd->nd_txstart+PKTSZ)/DS_PGSIZE; outb (neBase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); NEPAUSE /* set non-promiscous mode, for now. */ outb (neBase+ds0_rcr, DSRC_AB); NEPAUSE /* word/byte */ outb(neBase+ds0_dcr, nd->nd_mode); NEPAUSE /* enable interrupts */ nd->nd_mask = DSIM_PRXE | DSIM_PTXE | DSIM_RXEE | DSIM_TXEE; outb (neBase+ds0_imr, (nd->nd_mask & 0xff) ); /* mark as running */ nd->nd_if.if_flags |= (unsigned short) IFF_RUNNING; /* not actively outputing */ nd->nd_flags &= ~DSF_LOCK; nd->nd_state = NE_NORMAL; spl(s); } /* void * neclose(dev) * dev_t dev; * */ void neclose(dev) dev_t dev; { register struct nedata_c *nd; register neBase; struct aprcom *ifp; int unit, oldpri, ne_tries; unit = minor( dev ); if( unit > ( NNE - 1 ) || unit < 0 ) { /* out of range card number */ set_user_error( ENXIO ); } nd = &nedata_c[unit]; neBase = nd->nd_port; /* test if nd_refc is zero * and leave the interrupts on if it is not. */ nd->nd_refc--; if( nd->nd_refc == 0 ) { /* we wait for * output to drain. */ oldpri = sphi(); for( ne_tries = 0; ne_tries < 10; ne_tries++ ) { /* is our data space available? * number of empty slots is: * not wrapped */ if( nd->nd_swq == nd->nd_nowq ) { spl(oldpri); break; } else { /* we want to be awakened */ if( (nd->nd_flags & DSF_LOCK == 0) || nd->nd_state == NE_NORMAL ) { int rcount; rcount = 100000; while( (nerestart(unit)) == 0 && (nd->nd_swq != nd->nd_nowq ) && (--rcount > 0) ) ; if( rcount == 0 ) continue; } } /* snooze: */ if( (x_sleep(nd->nd_rq,pritty,slpriSigCatch, "packetwait" )) ==PROCESS_SIGNALLED ) { /* awakened by signal */ set_user_error( EINTR); spl(oldpri); break; } } /* turn off interrupts at board */ outb (neBase+ds0_imr, 0x0); /* we mark the board info as not running so * the next guy will reinitialize it. */ ifp = &nd->nd_ac; ifp->if_flags &= ~IFF_RUNNING; /* if somebody deallocate the queue memory or * gives it to somebody else, we don't want to * try to use it in some spuroius interrupt. */ nd->nd_timwait = 1; /* turn off cycle. */ timeout ( &nd->nd_tim, HZ / 10, NULL, unit); } return; } /* void * neread(dev,iop) * dev_t dev; * IO * iop; */ void neread(dev, iop) dev_t dev; register IO * iop; { register struct nedata_c *nd; register neBase; int unit, oldpri; /* validate the read paramters * and set up the pointers */ unit = minor( dev ); if( unit > ( NNE - 1 ) || unit < 0 ) { /* out of range card number */ set_user_error( ENXIO ); } nd = &nedata_c[unit]; neBase = nd->nd_port; if( iop->io_ioc < PKTSZ ) { /* we return data to user in chunks * of one packet only. */ set_user_error( EINVAL ); return; } /* see if it is legal to transfer data to user */ if( (nd->nd_filemode & IPR) == IPR ) { /* read is ok, is there data available? */ if( nd->nd_norq != nd->nd_nrq ) { /* yes, there is data */ iowrite( iop, &nd->nd_rq[nd->nd_nrq].data[0], ( nd->nd_rq[nd->nd_nrq].len - 3 ) ); if( nd->nd_nrq > NE_NUMBUFFS - 2 ) nd->nd_nrq = 0; else nd->nd_nrq++; } else { /* no data, shall we block? */ if( iop->io_flag & IONDLY ) { /* don't block */ set_user_error( EWOULDBLOCK ); return; } else { /* do a block, 'til there's data */ oldpri = splhi(); while( 1 ) { /* snooze */ if( (x_sleep(nd->nd_rq, prilo, slpriSigCatch, "pktread" ) ) == PROCESS_SIGNALLED ) { /* were we awakened by * a signal? */ set_user_error( EINTR ); spl(oldpri); return; } /* well, if it wasn't a * signal, was it the arrival * of our data? */ if( nd->nd_norq != nd->nd_nrq ) { /* yes, there is data */ iowrite( iop, &nd->nd_rq[nd->nd_nrq].data[0], (nd->nd_rq[nd->nd_nrq].len - 3) ); /* update the * the index */ if( nd->nd_nrq > NE_NUMBUFFS - 2 ) nd->nd_nrq = 0; else nd->nd_nrq++; spl(oldpri); return; } /* no data, no signal, so * loop again */ } } } } else { set_user_error( EBADFD ); return; } } /* void * newrite(dev,iop) * dev_t dev; * IO * iop; */ void newrite(dev, iop) dev_t dev; register IO * iop; { register struct nedata_c *nd; register neBase; int empty, unit, oldpri, ne_tries; unit = minor( dev ); if( unit > ( NNE - 1 ) || unit < 0 ) { /* out of range card number */ set_user_error( ENXIO ); } nd = &nedata_c[unit]; neBase = nd->nd_port; if( iop->io_ioc < ETHER_MIN_LEN || iop->io_ioc > ETHER_MAX_LEN ) { /* invalid data length */ set_user_error( EINVAL ); return; } /* see if it is legal to transfer data to user */ if( nd->nd_filemode & IPW ) { /* since write is ok, is there data available? */ /* determine number of empty slots. */ if( nd->nd_swq < nd->nd_nowq ) empty = NE_NUMBUFFS - (nd->nd_nowq - nd->nd_swq); else { /* nowq has wrapped, but not swq */ if( nd->nd_swq > nd->nd_nowq ) empty = NE_NUMBUFFS - ((nd->nd_nowq + NE_NUMBUFFS) - nd->nd_swq); else empty = NE_NUMBUFFS; } if( empty < nd->nd_lox ) nd->nd_lox = empty; /****************** NOTES ON RACE CONDITIONS **************** * * At this point in the code, we know a number of empty pakcet * slots. However, by the time we have digested this number and * prepared to act on in it, the interrupt handler can easily * change it. We might fall asleep when no further interrupts * have been scheduled. * * our methods of preventing overwriting our own data * before transmission, is that we allow at least ne_lowwater * empty slots to intervene between the current write slot * ( nd_nowq ) and the posisiton of the current send slot (nd_swq). * * Regarding the possible race condition between the * call to x_sleep and the wakeup issued by the interrupt * handler. We use sphi to avert this, and we also have set * up a safety net with necycle which calls wakeup every * 10 HZ. When we do the sleep loop, if we set * ne_tries. It is incremented each time through the * loop. * ************************************************************/ if( empty > ne_lowwater ) { /* yes, there is room, so copy in the data */ nd->nd_wq[nd->nd_nowq].len = (iop->io_ioc + 1 ); ioread( iop, &nd->nd_wq[nd->nd_nowq].data[0], iop->io_ioc ); /* update index */ if( nd->nd_nowq > NE_NUMBUFFS - 2 ) nd->nd_nowq = 0; else nd->nd_nowq++; if( nd->nd_state == NE_NORMAL ) { oldpri = sphi(); nerestart(unit); spl(oldpri); } } else { /* no room, shall we block? */ if( iop->io_flag & IONDLY ) { /* don't block */ set_user_error(EWOULDBLOCK); return; } else { /* do a block, 'til there's room */ /* there's some possible races * in this block. So, we ask that * interrupts be withheld until * we are asleep. We test for room * after interrupts are disabled, * but before our first sleep. */ oldpri = sphi(); for( ne_tries = 0; ne_tries < 10; ne_tries++ ) { /* is our data space available? */ if( nd->nd_swq < nd->nd_nowq ) empty = NE_NUMBUFFS - (nd->nd_nowq - nd->nd_swq); else { if( nd->nd_swq > nd->nd_nowq ) empty = NE_NUMBUFFS - ((nd->nd_nowq + NE_NUMBUFFS) - nd->nd_swq); else empty = NE_NUMBUFFS; } if( empty < nd->nd_lox ) nd->nd_lox = empty; if( empty > ne_lowwater ) { /* there is room, copy in data */ nd->nd_wq[nd->nd_nowq].len = iop->io_ioc; ioread( iop, &nd->nd_wq[nd->nd_nowq].data[0], iop->io_ioc ); nd->nd_wq[nd->nd_nowq].len++; /* update the index */ if( nd->nd_nowq > NE_NUMBUFFS - 2 ) nd->nd_nowq = 0; else nd->nd_nowq++; /* begin transmission * if we can */ if( nd->nd_state == NE_NORMAL ) { nerestart(unit); } else continue; /* turn interrupts back on */ spl(oldpri); return; } else { /* we want to be awakened */ if( (nd->nd_flags & DSF_LOCK == 0) || nd->nd_state == NE_NORMAL ) { int rcount; /* nerestart is desgined * to return 1 if and only * if it has done something * which will create an * interrupt (which makes * our wakeup call). rcount * prevents lockup on deadnet. */ rcount = 100; /* begin transmission * if we can */ if( nd->nd_state == NE_NORMAL ) { while( (nerestart(unit)) == 0 && (nd->nd_swq != nd->nd_nowq) && (--rcount > 0) ) ; /* <- note semicolon */ } if( rcount == 0) { cmn_err( CE_NOTE, "newrite:restart failure\n" ); continue; } /* net may be down */ } } if( nd->nd_state != NE_NORMAL ) { /* turn on watchdog */ timeout ( &nd->nd_tim, HZ / 10, necycle, unit); /* snooze */ if( (x_sleep(nd->nd_rq,prilo,slpriSigCatch, "pktwrite" )) ==PROCESS_SIGNALLED ) { /* awakened by signal */ set_user_error( EINTR ); spl(oldpri); return; } } } /* if we reach this spot, we have * probably have a broken network, * because it doesn't take a whole * second to clear the backlog. */ set_user_error( ENETDOWN ); spl(oldpri); return; } } } else { set_user_error( EBADFD ); return; } } /* int * neioctl(dev,com,arg) * dev_t dev; * int com; * neattr_t * arg; */ static int neioctl(dev, com, arg) dev_t dev; int com; register char * arg; { register struct nedata_c *nd; register neBase; struct aprcom *ifp; int unit; short *sh; unit = minor( dev ); if( unit > ( NNE - 1 ) || unit < 0 ) { /* out of range card number */ set_user_error( ENXIO ); } nd = &nedata_c[unit]; neBase = nd->nd_port; /* interface data for address resolution */ ifp = &nd->nd_ac; switch( com ) { case NEIOCGFLAGS: kucopy( ifp, arg, (sizeof(ifp->ac_enaddr) + sizeof(ifp->if_flags) ) ); return; break; case NEIOCSFLAGS: /* we don't reset the ethernet address, just the flags */ sh = arg; sh += 6; ifp->if_flags = getusd(sh); /* set the card operation */ if( (ifp->if_flags & IFF_PROMISC)) outb (nd->nd_port+ds0_rcr, DSRC_AB | DSRC_PRO | DSRC_AR | DSRC_SEP); else outb (nd->nd_port+ds0_rcr, DSRC_AB); return; break; /* retreive stats */ case NEIOCGSTATS: kucopy( &nd->nd_collisions, arg, sizeof(struct nestats) ); /* clear buffer supply statistics */ nd->nd_lox = nd->nd_lor = NE_NUMBUFFS; return; break; /* retreive lowwater figure */ case NEIOCGLOWWAT: kucopy( &ne_lowwater, arg, sizeof(ne_lowwater) ); return; break; case NEIOCSLOWWAT: ne_lowwater = getuwd(arg); if( ne_lowwater < 3 ) ne_lowwater = 3; if( ne_lowwater > (NE_NUMBUFFS - 1) ) ne_lowwater=(NE_NUMBUFFS - 1); return; break; default: set_user_error( EINVAL ); return; break; } return; } void newatch() { } /* * neload routine, runs a boot time. * * We try out the card to see if it will run in byte mode * or word mode. * * If neither, no card is present. If byte mode works, its a NE1000 * If word mode works, its a NE2000. If one of the modes * works, then we extract the hardware ethernet address and * make an announcement on the console. * * We allow a small amount of time to elapse between io events * to the registers, and a fair amount of time after a reset * or dma call. * * we don't use the dev_t that accompanies to call to neload. * * void * neload(dev) * dev_t dev; */ void neload() { int val, i, ch, pat, board; register struct nedata_c *nd; register neBase; struct aprcom *ifp; long delay; int bytemode; /* fill in the values from Space.c */ ne_irq[0] = ne0_irq; ne_irq[1] = ne1_irq; ne_irq[2] = ne2_irq; ne_irq[3] = ne3_irq; ne_iobase[0] = ne0_iobase; ne_iobase[1] = ne1_iobase; ne_iobase[2] = ne2_iobase; ne_iobase[3] = ne3_iobase; ne_mem[0] = ne0_mem; ne_mem[0] = ne1_mem; ne_mem[0] = ne2_mem; ne_mem[0] = ne3_mem; /* loop in order to probe all cards */ for( board = 0; board < NNE; board++ ) { /* try byte mode first */ bytemode = 1; /* our private data */ nd = &nedata_c[board]; /* our io port */ neBase = nd->nd_port = ne_iobase[board]; /* interface data for address resolution */ ifp = &nd->nd_ac; /* the param in Space.c is ne_iobase[]. If * the sys admin has set our io port to zero * we do not wish to test for this board */ if( neBase == 0 ) { nd->nd_state = NE_NOBOARD; continue; } if (bytemode) { /* Byte Transfers, Burst Mode Select, Fifo at 8 bytes * DSDC_BMS = burst mode sel, DSDC_FT1 = fifo threshold */ nd->nd_mode = DSDC_BMS|DSDC_FT1; /* statring loc of xmit buffer (8*1024) */ nd->nd_txstart = TBUF8; /* end loc of rcv buffer (16*1024) */ nd->nd_rxend = RBUFEND8; } else { word: /* Word Transfers, Burst Mode Select, Fifo at 8 bytes */ nd->nd_mode = DSDC_WTS|DSDC_BMS|DSDC_FT1; nd->nd_txstart = TBUF16; /* (16*1024) */ nd->nd_rxend = RBUFEND16; /* (32*1024) */ bytemode = 0; } /* Reset the board by reading the reset port and * then writing to it. */ val = inb(neBase + ne_reset); /* delay for ??? */ for( delay = 1000L; delay > 0; delay -- ) ; outb(neBase + ne_reset, val); for( delay = 1000L; delay > 0; delay-- ) ; outb(neBase + ds_cmd, DSCM_STOP|DSCM_NODMA); NEPAUSE /* now check the results of the reset. If it worked, we * have board. Otherwise we don't */ i = 10000; while ((inb(neBase + ds0_isr) & DSIS_RESET) == 0 && i-- > 0); if (i < 0) { nd->nd_state = NE_NOBOARD; return; } outb(neBase + ds0_isr, 0xff); NEPAUSE outb(neBase + ds0_dcr, nd->nd_mode); NEPAUSE outb(neBase + ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP); for( delay = 1000L; delay > 0; delay -- ) ; /* Check cmd reg and fail if not right */ if ((i = inb(neBase + ds_cmd)) != (DSCM_NODMA|DSCM_PG0|DSCM_STOP)) { nd->nd_state = NE_NOBOARD; return; } NEPAUSE /* transmission control */ outb(neBase + ds0_tcr, 0); NEPAUSE /* receiver control */ outb(neBase + ds0_rcr, DSRC_MON); NEPAUSE /* first page of receive buffer */ outb(neBase + ds0_pstart, (nd->nd_txstart+PKTSZ)/DS_PGSIZE); NEPAUSE /* end page of receive buffer */ outb(neBase + ds0_pstop, nd->nd_rxend/DS_PGSIZE); NEPAUSE /* pointer to boundary between last packet * and next one (last page of last packet). * Here we've set it the end of the receive * buffer. */ outb(neBase + ds0_bnry, nd->nd_rxend/DS_PGSIZE); NEPAUSE /* We turn off all interrupts from this * board. */ outb(neBase + ds0_imr, 0); NEPAUSE /* zero out the interrupt status register */ outb(neBase + ds0_isr, 0); NEPAUSE /* flip to page 1 of registers */ outb(neBase + ds_cmd, DSCM_NODMA|DSCM_PG1|DSCM_STOP); NEPAUSE /* The current transmit buffer begining page * is stored in ds1_curr */ outb(neBase + ds1_curr, (nd->nd_txstart+PKTSZ)/DS_PGSIZE); NEPAUSE /* flip back to page 0 */ outb(neBase + ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_STOP); NEPAUSE /* * detect the presence of the card by using card dma * to store the pattern in the transmit buffer * then retrieve it using card dma and check it. * In order for this to work, the byte vs. word * mode must be correct and the hardware must be * present. */ pat = PAT(0); nesput(nd, &pat, nd->nd_txstart, 4); nefetch(nd, &pat, nd->nd_txstart, 4); if (pat != PAT(0)) { if (bytemode) { goto word; } else { nd->nd_state = NE_NOBOARD; return; } } /* set the interrupt vector to point at the correct handler * entry point after validating it. */ if( (ne_irq[board] > 1) && neintf[board] != NULL ) { setivec( ne_irq[board], neintf[board] ); } else { nd->nd_state = NE_NOBOARD; return; } /* Extract ethernet hardware address from board */ nefetch (nd, &boarddata[0], 0, sizeof(boarddata)); /* report to the console */ if( bytemode ) cmn_err( CE_CONT, "ne%d: NE1000 ", board ); else cmn_err( CE_CONT, "ne%d: NE2000 ", board ); cmn_err( CE_CONT, "ethernet address [" ); for(i=0; i < 6; i++) { nd->nd_addrp[i] = ne_eaddr[board][i] = boarddata[i]; ch = (unsigned int) nd->nd_addrp[i]; cmn_err( CE_CONT, "%x", ch ); if( i < 5 ) cmn_err( CE_CONT, ":" ); } cmn_err( CE_CONT, "] IRQ:[%d] io base[0x%x]\n", ne_irq[board], ne_iobase[board] ); nd->nd_norq = nd->nd_nrq = 0; nd->nd_nowq = nd->nd_swq = 0; /* no processes can have us opened yet, so init refc */ nd->nd_refc = 0; nd->nd_state = NE_NORMAL; } return; } /* * Fetch from onboard ROM/RAM. I/O for the NE card uses * an internal dma scheme to move data between our accessible * data port and the card's internal memory buffers. */ static void nefetch (nd, up, ad, len) struct nedata_c *nd; caddr_t up; { u_char cmd; int pport, t; register neBase = nd->nd_port; /* save the old cmd value */ cmd = inb (neBase + ds_cmd); NEPAUSE /* flip to page 0 */ outb (neBase + ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); NEPAUSE /* Setup remote dma */ outb (neBase + ds0_isr, DSIS_RDC); NEPAUSE /* roundup our length to words if needed */ t = len; if ((nd->nd_mode & DSDC_WTS) && (t & 1) ) t++; /* tell the card how much data (in bytes) to expect */ outb (neBase+ds0_rbcr0, t); NEPAUSE outb (neBase+ds0_rbcr1, (t >> 8) ); NEPAUSE /* tell the card where to get the data from */ outb (neBase+ds0_rsar0, ad); NEPAUSE outb (neBase+ds0_rsar1, ad>>8); NEPAUSE /* Execute & extract from card */ outb (neBase+ds_cmd, DSCM_RREAD|DSCM_PG0|DSCM_START); NEPAUSE /* insw and insb are assembler routines defined * locore.s which use insb and insw to move data */ if (nd->nd_mode & DSDC_WTS) { pport = neBase+ne_data; /* ee_insw is defined in wsub.s */ ee_insw (pport, up, (int)t/2 ); } else ee_insb (neBase+ne_data, up, len); counter = 10000; /* Wait till done, then shutdown remote dma */ while ((inb (neBase+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) ; outb (neBase+ds0_isr, DSIS_RDC); NEPAUSE /* restore the old cmd */ outb (neBase+ds_cmd, cmd); NEPAUSE } /* * Put string to onboard RAM. For a description of card io, see * nefecth pre-function comments */ nesput (nd, up, ad, len) struct nedata_c *nd; caddr_t up; { u_char cmd; int pport; register neBase = nd->nd_port; /* save the old cmd */ cmd = inb(neBase+ds_cmd); /* flip to page 0 */ outb (neBase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); NEPAUSE /* Setup for remote dma */ outb (neBase+ds0_isr, DSIS_RDC); NEPAUSE /* roundup to words if needed */ if ((nd->nd_mode & DSDC_WTS) && len&1) len++; /* tell the card how much data and where to put it */ outb (neBase+ds0_rbcr0, len); NEPAUSE outb (neBase+ds0_rbcr1, len>>8); NEPAUSE outb (neBase+ds0_rsar0, ad); NEPAUSE outb (neBase+ds0_rsar1, ad>>8); NEPAUSE /* Execute & stuff to card */ outb (neBase+ds_cmd, DSCM_RWRITE|DSCM_PG0|DSCM_START); NEPAUSE if (nd->nd_mode & DSDC_WTS) { pport = neBase+ne_data, ee_outsw ( pport, up, (int)len/2); if( len & 0x1 ) { unsigned short myword; myword = ( (((char)up[len-1]) << 8) & 0xff00); outw( pport, myword ); } } else ee_outsb (neBase+ne_data, up, len); counter=10000; /* Wait till done, then shutdown dma */ while ((inb (neBase+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) ; outb (neBase+ds0_isr, DSIS_RDC); NEPAUSE /* restore old cmd */ outb (neBase+ds_cmd, cmd); NEPAUSE } /*void * neunload(dev) * dev_t dev; */ void neunload() { /** none **/ } /* * int * nepoll(dev,ev,msec) * dev_t dev; * int ev; * int msec; */ static int nepoll(dev, ev, msec) dev_t dev; int ev; int msec; { register struct nedata_c *nd; int unit, empty; unit = minor( dev ); if( unit > ( NNE - 1 ) || unit < 0 ) { /* out of range card number */ set_user_error( ENXIO ); } nd = &nedata_c[unit]; /* * We accept polls for POLLIN and POLLOUT. POLLIN gets a defered * pollwake in the interrupt code when data arrives. * POLLOUT gets a defered wakeup from the interrupt code when * the is more than ne_lowwater empty packet slots available. * * In addition, there is a pollwake call available in necycle * that tests to see if the timeout time has elapsed. It runs * in a 10 HZ granularity. */ ev &= (POLLIN | POLLOUT); if( (ev & POLLIN) != 0) { if(nd->nd_norq == nd->nd_nrq ) { /* block for input */ if( msec != 0 ) { /* if there is already a poll that will * timeout sooner than ours, we don't * bump our own watchdog timer. */ if( nd->nd_inevent.e_procp && ((lbolt + (msec/10)) < nd->nd_ipsleep) ) nd->nd_ipsleep = lbolt + (msec / 10 ) ; pollopen( &nd->nd_inevent ); } /* 2nd look */ if( nd->nd_norq != nd->nd_nrq ) { ev &= POLLIN; } else ev &= ~POLLIN; } } /** calculate the number of empty slots **/ if( nd->nd_swq < nd->nd_nowq ) empty = NE_NUMBUFFS - (nd->nd_nowq - nd->nd_swq); else { if( nd->nd_swq > nd->nd_nowq ) empty = NE_NUMBUFFS - ((nd->nd_nowq + NE_NUMBUFFS) - nd->nd_swq); else empty = NE_NUMBUFFS; } if( ((ev & POLLOUT) != 0) && ( empty < (ne_lowwater + 2 )) ) { /* block for input */ if( msec != 0 ) { /* if there is already a poll that will * timeout sooner than ours, we don't * bump our own watchdog timer. */ if( nd->nd_outevent.e_procp && ((lbolt + (msec/10)) < nd->nd_opsleep) ) nd->nd_opsleep = lbolt + (msec / 10 ) ; pollopen( &nd->nd_outevent ); } /* 2nd look */ if( nd->nd_swq < nd->nd_nowq ) empty = NE_NUMBUFFS - (nd->nd_nowq - nd->nd_swq); else { if( nd->nd_swq > nd->nd_nowq ) empty = NE_NUMBUFFS - ((nd->nd_nowq + NE_NUMBUFFS) - nd->nd_swq); else empty = NE_NUMBUFFS; } if( empty > ne_lowwater ) ev &= POLLOUT; else ev &= ~POLLOUT; } return ev; } /* the interrupt vectoring functions */ static void ne0intr() { neintr(0); } static void ne1intr() { neintr(1); } static void ne2intr() { neintr(2); } static void ne3intr() { neintr(3); } /* buffer successor/predecessor in ring? */ #define succ(n) (((n)+1 >= nd->nd_rxend/DS_PGSIZE) ? (nd->nd_txstart+PKTSZ)/DS_PGSIZE : (n)+1) #define pred(n) (((n)-1 < (nd->nd_txstart+PKTSZ)/DS_PGSIZE) ? nd->nd_rxend/DS_PGSIZE-1 : (n)-1) /* * Controller interrupt. */ void neintr(unit) { register struct nedata_c *nd; register neBase; unsigned char cmd, isr, pend, lastfree, nxt; int len, /* lenth of incoming packet */ i, /* generic iteration counter */ rqf, /* wakeup read side flag */ wqf, /* wakeup write side flag */ oldstate, /* previous state */ pri, /* previous interrupt priority */ rempty, /* number of empty slots in the read buffer array */ empty, /* number of empty slots in write buffer array */ oldpri, /* retained interrupt priority */ vector; /* same as unit */ /* let's see what this value is */ oldpri = pri = sphi(); /* set up a pointer to our private data */ nd = &nedata_c[unit]; /* bad pointer ?? */ if( nd == NULL) return; /* check re-entrancy */ if( nd->nd_reentry ) { cmn_err( CE_CONT, "reentering neintr\n" ); return; } nd->nd_reentry = 1; /* get our io port base */ neBase = nd->nd_port; /* stop any further card interrupts */ outb (neBase+ds0_imr, (nd->nd_mask & 0x00) ); /* flag to enable wakeups */ wqf = rqf = 0; /* save interrupt vector */ i = vector = unit; /* store the current command */ cmd = inb( neBase+ds_cmd ); loop: /* get the interrupt status */ isr = inb( neBase + ds0_isr ); /* clear the interrupt */ outb(neBase + ds_cmd, DSCM_NODMA | DSCM_START ); NEPAUSE outb(neBase + ds0_isr, isr ); NEPAUSE /* if received with error, clear the error */ if( isr & DSIS_RXE ) { nd->nd_ierrors++; NEPAUSE inb( neBase + ds0_rsr); NEPAUSE inb( neBase + 0xD ); NEPAUSE inb( neBase + 0xE ); NEPAUSE inb( neBase + 0xF ); } /* if received, get it out of the board memory */ if( isr & (DSIS_RXE | DSIS_RX | DSIS_ROVRN )) { nd->nd_ipackets++; /* flip to page 1 */ outb( neBase + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG1 ); NEPAUSE /* store the current buffer page num */ pend = inb( neBase + ds1_curr ); NEPAUSE /* flip to page 0 */ outb( neBase + ds_cmd, DSCM_START | DSCM_NODMA | DSCM_PG0 ); NEPAUSE /* get the boundry pointer */ lastfree = inb( neBase + ds0_bnry ); /* if we have looped around the recv. ring buffer, * adjust the pointers */ if( lastfree >= nd->nd_rxend / DS_PGSIZE ) lastfree = ( nd->nd_txstart+PKTSZ) / DS_PGSIZE ; if( pend < lastfree && nd->nd_cur < pend ) lastfree = nd->nd_cur; else if( nd->nd_cur > lastfree ) lastfree = nd->nd_cur; while( pend != lastfree ) { if( nd->nd_state == NE_DMAWAIT ) { /* This should not happen. We have * locked off card interrupts, so there * should not be another copy of neintr * happening in the dma loop. nerestart * should have turned off card interrupts * before starting a dma and they shouldn't * be turned back on until the dma is complete * This is an error, so we are going to clear * it, by taking the card out of dma mode. */ outb (neBase+ds0_isr, DSIS_RDC); } /* save state and then change it */ oldstate = nd->nd_state; nd->nd_state = NE_DMAWAIT; /* get the ethernet packet header */ nefetch( nd , &nd->nd_ph, lastfree * DS_PGSIZE, sizeof( nd->nd_ph ) ); /* set up the byte address of the packet */ nd->nd_ba = lastfree * DS_PGSIZE + sizeof( nd->nd_ph); /* check to be sure the receive is complete */ if( nd->nd_ph.pr_status == DSRS_RPC || nd->nd_ph.pr_status == 0x21 ) { /* get the data length */ len = nd->nd_ph.pr_sz0 + (nd->nd_ph.pr_sz1 << 8 ); /* check for sane len */ if( len < ETHER_MIN_LEN || len > ETHER_MAX_LEN ) goto brr; /* vaidate a slot to hold * the data */ if( nd->nd_nrq < nd->nd_norq ) rempty = NE_NUMBUFFS - (nd->nd_norq - nd->nd_nrq); else { if( nd->nd_nrq > nd->nd_norq ) rempty = NE_NUMBUFFS - ((nd->nd_norq + NE_NUMBUFFS) - nd->nd_nrq); else rempty = NE_NUMBUFFS; } /* update buffer supply statistic */ if( rempty < nd->nd_lor ) nd->nd_lor = rempty; /* if we have less than two buffers remaining * in our array, we need to stop buffering * input from the wire and return * so that some of the build up can * be cleared. */ if( rempty < 2 ) { rqf++; /* flag wakeup */ goto brr; } /* get the packet */ nefetch( nd, &nd->nd_rq[nd->nd_norq].data[0], nd->nd_ba, len - sizeof( nd->nd_ph) ); nd->nd_rq[nd->nd_norq].len = len; rqf++; /* flag wakeup */ /* increment buffer index */ nd->nd_norq++; /* wrap buffer index if needed */ if( nd->nd_norq > NE_NUMBUFFS - 1) nd->nd_norq = 0; /* restore previous state */ nd->nd_state = oldstate; } brr: /* adjust pointer to next packet */ nxt = nd->nd_ph.pr_nxtpg; /* validate pointer, re-adj if needed */ if( nxt >= (nd->nd_txstart+PKTSZ)/DS_PGSIZE && nxt <= nd->nd_rxend/DS_PGSIZE && nxt <= pend ) nd->nd_cur = nxt; else nd->nd_cur = nxt = pend; lastfree = nxt; /* reset the card's boundary pointer */ outb( neBase + ds0_bnry, pred(nxt) ); NEPAUSE /* flip to page 1 */ outb(neBase+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG1); NEPAUSE /* get a new pointer for next read */ pend = inb(neBase+ds1_curr); NEPAUSE /* flip back to page 0 */ outb(neBase+ds_cmd, DSCM_START|DSCM_NODMA|DSCM_PG0); NEPAUSE } /* while more incoming packets */ /* turn off card dma */ outb(neBase+ds_cmd, DSCM_START|DSCM_NODMA); NEPAUSE } /* if recd something */ /* Transmit error */ if (isr & DSIS_TXE) { /* Need to read these registers to clear error status */ inb( neBase + 0xD ); NEPAUSE inb( neBase + 0xE ); NEPAUSE inb( neBase + 0xF ); NEPAUSE /* update statistics */ nd->nd_collisions += inb(neBase+ds0_tbcr0); nd->nd_oerrors++; /* set wakeups */ wqf++; } /* Packet Transmitted */ if (isr & DSIS_TX) { /* update statistics */ ++nd->nd_opackets; nd->nd_collisions += inb(neBase+ds0_tbcr0); NEPAUSE /* set wakeups */ wqf++; } /* Receiver ovverun? */ if (isr & DSIS_ROVRN) { /* in case of receive buffer overrun * we have to go through this ritual * in order to restore sanity to the board: * * Set the recv'd byte count to zero. */ outb(neBase+ds0_rbcr0, 0); NEPAUSE outb(neBase+ds0_rbcr1, 0); NEPAUSE /* set the transmission control register * to loop back 0 mode. */ outb(neBase+ds0_tcr, DSTC_LB0); NEPAUSE /* set the recv control register to * monitor mode */ outb(neBase+ds0_rcr, DSRC_MON); NEPAUSE /* start up the card listening to itself */ outb(neBase+ds_cmd, DSCM_START|DSCM_NODMA); NEPAUSE /* Set the recv control register back * back to normal */ outb(neBase+ds0_rcr, DSRC_AB); NEPAUSE /* turn off the tranmission control * loop back mode. */ outb(neBase+ds0_tcr, 0); NEPAUSE } /* restore old cmd and interrupt mask */ outb (neBase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); NEPAUSE outb (neBase+ds_cmd, cmd); NEPAUSE outb (neBase+ds0_imr, (nd->nd_mask & 0xff) ); NEPAUSE /* Any more to send? */ if( nd->nd_swq != nd->nd_nowq ) { nerestart(unit); wqf++; } else { /* unlock the xmiter and q */ nd->nd_flags &= ~DSF_LOCK; nd->nd_state = NE_NORMAL; } /* Still more to do? */ isr = inb (neBase+ds0_isr); NEPAUSE if(isr) { goto loop; } /* do read side wakeups */ if( rqf ) { defer( wakeup, nd->nd_rq ); rqf = 0; if( nd->nd_inevent.e_procp ) { defer( pollwake, &nd->nd_inevent ); } } /* write side wakeup */ if( wqf ) { defer( wakeup, nd->nd_wq ); wqf = 0; } /* calculate the number of empty slots, for pollwake */ if( nd->nd_swq < nd->nd_nowq ) empty = NE_NUMBUFFS - (nd->nd_nowq - nd->nd_swq); else { if( nd->nd_swq > nd->nd_nowq ) empty = NE_NUMBUFFS - ((nd->nd_nowq + NE_NUMBUFFS) - nd->nd_swq); else empty = NE_NUMBUFFS; } if( empty > ( ne_lowwater + 2 ) && nd->nd_outevent.e_procp ) { defer( pollwake, &nd->nd_outevent ); } nd->nd_reentry = 0; spl(oldpri); return; } /* * Setup output on interface. * Get a datagram to send from nd_wq buffers, * and copy it to the xmit buffer before starting the output. * return true if an interrupt can be expected from what we are doing here */ static int nerestart(unit) int unit; { register struct nedata_c *nd; int len, i, total,t, oldstate; register neBase; u_short word; u_char cmd; char n_cmd, n_isr, n_tsr; nd = &nedata_c[unit]; /* lock things up right away */ oldstate = nd->nd_state; nd->nd_state = NE_RRUN; if( oldstate == NE_RRUN ) return(1); /* our io port base */ neBase = nd->nd_port; /* nothin to do ?? */ if( nd->nd_swq == nd->nd_nowq ) { nd->nd_state = oldstate; return(0); } /* if the board or structs haven't been initialized */ if ((nd->nd_if.if_flags & IFF_RUNNING ) == 0) { nd->nd_state = oldstate; return(0); } /* if we haven't completed the last transmission * return because we'll soon get an interrupt anyway * if (nd->nd_flags & DSF_LOCK || nd->nd_state > NE_NORMAL ) { return(0); } */ cmd = inb(neBase+ds_cmd); NEPAUSE /* * The DS8390 has only one transmit buffer, if it is busy we * must wait until the transmit interrupt completes. */ outb(neBase+ds_cmd,DSCM_NODMA|DSCM_START); NEPAUSE if (inb(neBase+ds_cmd) & DSCM_TRANS) { nd->nd_state = oldstate; return(0); } /* look at state, if we are already waiting for dma * we do not want to start another, this would indicate * that the receiver is doing dma, so we don't want to * replace the flag in oldstate 'cause that dma flag might * have changed since we copied it. */ if( oldstate == NE_DMAWAIT ) { return(0); } /* go to work loading board. turn off interrupts */ /* store old cmd */ inb(neBase+ds_cmd); NEPAUSE /* flip to page 0 */ outb (neBase+ds_cmd, DSCM_NODMA|DSCM_PG0|DSCM_START); NEPAUSE /* turn off interrupts on card */ outb (neBase+ds0_imr, 0 ); NEPAUSE /* double check . If recieve interrput code is * doing dma wait til later, in case of race */ if( nd->nd_state == NE_DMAWAIT ) { return(0); } /* now, lock things up and we should have sole control * of the card until we turn card interrupts back on. */ nd->nd_state = NE_DMAWAIT; /* don't mess with wq */ nd->nd_flags |= DSF_LOCK; /* prevent re-entry */ /* determine data length */ i = t = nd->nd_wq[nd->nd_swq].len; /* if we are a NE2000 round up dma size to words */ if ((nd->nd_mode & DSDC_WTS) && (t & 1) ) t++; /* Setup for remote dma */ outb (neBase+ds0_isr, DSIS_RDC); NEPAUSE outb (neBase+ds0_rbcr0, t); NEPAUSE outb (neBase+ds0_rbcr1, t>>8); NEPAUSE outb (neBase+ds0_rsar0, nd->nd_txstart); NEPAUSE outb (neBase+ds0_rsar1, nd->nd_txstart>>8); NEPAUSE /* Execute dma & stuff to card */ outb (neBase+ds_cmd, DSCM_RWRITE|DSCM_PG0|DSCM_START); NEPAUSE total = t; counter = 10000; if (nd->nd_mode & DSDC_WTS) { /* Word Mode */ if (i > 1) { /* if the data is odd in len, add a pad for the dma */ if (i & 1) { /* captuer odd byte into a short */ word = (ushort) nd->nd_wq[ nd->nd_swq].data[ (nd->nd_wq[ nd->nd_swq ].len - 1) ] ; word = (ushort) ((word << 8 ) & 0xff00 ); /* put the data into the buffer */ ee_outsw(neBase+ne_data, &nd->nd_wq[ nd->nd_swq].data[0], i / 2); /* now the final word */ /* put the data into the buffer */ ee_outsw(neBase+ne_data, &word, 1); /* Wait till done, then shutdown dma */ while ((inb (neBase+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) ; outb (neBase+ds0_isr, DSIS_RDC); NEPAUSE /* restore cmd */ outb (neBase+ds_cmd, cmd); /* update the index */ if( nd->nd_swq > NE_NUMBUFFS - 2 ) nd->nd_swq = 0; else nd->nd_swq++; } else { /* length is even, * no need for extra word */ n_cmd = inb(neBase+ds_cmd ); NEPAUSE n_isr = inb(neBase+ds0_isr); NEPAUSE n_tsr = inb(neBase+ds0_tsr); NEPAUSE /* put the data into the buffer */ ee_outsw(neBase+ne_data, &nd->nd_wq[ nd->nd_swq].data[0], i / 2); /* Wait till done, then shutdown dma */ counter = 10000; while ((inb (neBase+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) ; if( counter == 0 ) cmn_err( CE_CONT, "\n" ); outb (neBase+ds0_isr, DSIS_RDC); NEPAUSE outb (neBase+ds_cmd, cmd); NEPAUSE /* update the index */ if( nd->nd_swq > NE_NUMBUFFS - 2 ) nd->nd_swq = 0; else nd->nd_swq++; } } } else { /* Byte Mode */ if (i > 0) /* put the data into the buffer */ ee_outsw(neBase+ne_data, &nd->nd_wq[ nd->nd_swq].data[0], i ); /* Wait till done, then shutdown dma */ while ((inb (neBase+ds0_isr) & DSIS_RDC) == 0 && counter-- > 0) ; outb (neBase+ds0_isr, DSIS_RDC); outb (neBase+ds_cmd, cmd); /* update the index */ if( nd->nd_swq > NE_NUMBUFFS - 2 ) nd->nd_swq = 0; else nd->nd_swq++; } len = total = t; if (len < ETHER_MIN_LEN) len = ETHER_MIN_LEN; /* transmit length */ outb(neBase+ds0_tbcr0,len&0xff); NEPAUSE outb(neBase+ds0_tbcr1,(len>>8)&0xff); NEPAUSE /* pointer to begining of transmit packet */ outb(neBase+ds0_tpsr, nd->nd_txstart/DS_PGSIZE); NEPAUSE /* transmit complete interrupt will change * state of nd_state, but this state indicator * will keep from attempting to call * nerestart again */ nd->nd_state = NE_XMIT; /* cmd = transmit */ outb(neBase+ds_cmd, DSCM_TRANS|DSCM_NODMA|DSCM_START); NEPAUSE /* * turn on card interrupts. */ outb (neBase+ds0_imr, (nd->nd_mask & 0xff) ); /* return 1 says we have done something which should * cause a future interrupt which will awaken * sleeping write() call */ return(1); } /*****/ /* * necycle() * * Do a wakeup of any sleeping ne's at regular intervals. */ static void necycle(unit) int unit; { register struct nedata_c *nd; nd = &nedata_c[unit]; if (nd->nd_refc ) { wakeup (nd->nd_wq ); wakeup (nd->nd_rq ); /* restore sanity to polls and do any * overdue pollwakes */ if( (nd->nd_opsleep != 0) && nd->nd_opsleep < lbolt ) { nd->nd_opsleep = 0; if( nd->nd_outevent.e_procp ) pollwake( &nd->nd_outevent ); } if( (nd->nd_ipsleep != 0) && ( nd->nd_ipsleep < lbolt ) ) { nd->nd_ipsleep = 0; if( nd->nd_inevent.e_procp ) pollwake( &nd->nd_inevent ); } } /* Schedule next cycle. */ if ( nd->nd_refc && nd->nd_timwait ) timeout ( &nd->nd_tim, HZ / 10, necycle, unit); } /**** end of ne.c ****/ etc/conf/ne/src/devices.h.new100644 3 3 3763 5570572762 14021 0ustar binbin/* (-lgl * COHERENT Version 4.0.3 * Copyright (c) 1982, 1993 by Mark Williams Company. * All rights reserved. May not be copied without permission. -lgl) */ #ifndef __SYS_DEVICES_H__ #define __SYS_DEVICES_H__ /* Device major numbers. */ #define MEM_MAJOR 0 /* memory */ #define TTY_MAJOR 1 /* tty */ #define KB_MAJOR 2 /* keyboard and video */ #define MM_MAJOR 2 /* keyboard and video, same as KB_MAJOR */ #define LP_MAJOR 3 /* parallel line printer */ #define FL_MAJOR 4 /* floppy disk */ #define ASY_MAJOR 5 /* async devices 0..31 */ #define AL0_MAJOR 5 /* serial line 0, COM[13] */ #define AL1_MAJOR 6 /* serial line 1, COM[24] */ #define HS_MAJOR 7 /* polled multi-port serial card */ #define RM_MAJOR 8 /* dual RAM disk */ #define PTY_MAJOR 9 /* pseudotty */ #define MS_MAJOR 10 /* Microsoft mouse */ #define AT_MAJOR 11 /* AT-type hard disk */ #define ST_MAJOR 12 /* archive streaming tape */ #define SCSI_MAJOR 13 /* SCSI */ /* 14 currently unassigned */ /* 15 may be used for bitmapped device */ /* 16 currently unassigned */ /* 17 currently unassigned */ /* 18 currently unassigned */ #define NE_MAJOR 19 /* NE2000 ethernet card */ #define TN_MAJOR 20 /* Tiac PC-234/6 ARCNET LAN */ #define PE_MAJOR 21 /* Emulex/Persyst fast serial (DCP/MUX) */ #define SBP_MAJOR 21 /* Sound Blaster Pro */ /* 22 currently unassigned */ #define SEM_MAJOR 23 /* S-V compatible semaphores */ #define SHM_MAJOR 24 /* S-V subset shared memory */ #define MSG_MAJOR 25 /* S-V compatible messaging */ /* 26 may be used for socket driver */ /* 27 currently unassigned */ /* 28 currently unassigned */ /* 29 currently unassigned */ #define GR_MAJOR 30 /* IBM Color card 640x200 graphics */ /* 31 currently unassigned */ /* Selected minor numbers. */ #define AT0X_MINOR 128 /* /dev/at0x */ #define AT1X_MINOR 129 /* /dev/at1x */ #define SCSI_minor(s, i, l, p) ((s)*0x80 + (i)*0x10 + (l)*0x04 + (p)) #endif /* end of devices.h */ etc/conf/ne/src/neioctl.h100644 3 3 7416 5570572762 13243 0ustar binbin/* filename : neconioctl.h * purpose : define constants for con ethernet driver * author : Randy Wright * * Copyright ((C)) 1993 Randy Wright * * * * $Log: neioctl.h,v $ * Revision 2.1 94/01/25 22:07:19 root * put in low buffer usage stats. * note that arpcom struct will disappear. * However, that will apply mainly to the * STREAMS version which is under a paralell * development track. * * Revision 2.0 94/01/19 16:16:53 root * initial revision, usder rcs to sync with * ne.c and wsub.c * * * */ #ifndef ne_H #define ne_H ne_H #define ne_data 0x10 /* Data Transfer port */ #define ne_reset 0x1f /* Card Reset port */ #define PKTSZ 3*512 /* Size of transmit buffer */ /* Span of memory on an NE2000 */ #define TBUF16 (16*1024) /* Starting location of Transmit Buffer */ #define RBUFEND16 (32*1024) /* Ending location of Receive Buffer */ /* Span of memory on an NE1000 */ #define TBUF8 (8*1024) /* Starting location of Transmit Buffer */ #define RBUFEND8 (16*1024) /* Ending location of Receive Buffer */ #ifndef ETHER_MIN_LEN #define ETHER_MIN_LEN 64 #endif #ifndef ETHER_MIN_LEN #define ETHER_MAX_LEN 1536 #endif /* NOTE: this structure will be disappearing in the future, * so don't use it for new code. It is a remnant of bsd days. */ struct arpcom { unsigned char ac_enaddr[6]; unsigned short if_flags; char *acc_if; }; struct ether_header { unsigned char ether_dhost[6]; unsigned char ether_shost[6]; unsigned short ether_type; }; struct nestats { /* statistics on data flow through our wires * copied from driver */ int nestat_collisions; /* number of collisions */ int nestat_oerrors; /* number of xmit errors */ int nestat_ierrors; /* number of recv errors */ int nestat_opackets; /* xmitted packets */ int nestat_ipackets; /* recv'd packets */ int nestat_idiscards; /* incoming packets discarded */ int nestat_lox; /* lowest num of xmit buffs * -- cleared on ioctl */ int nestat_lor; /* lowest num of recv buffs * -- cleared on ioctl */ }; /* change the definition to whatever is correct */ typedef int neattr_t; /* ioctl commands */ #define NEIOCGFLAGS 0x01 /* get flags, arg is pointer to * an arpcom. acc_if is not returned */ #define NEIOCSFLAGS 0x02 /* set flags, * arg is pointer to arpcom */ /* the following 3 are not supported */ #define NEIOCGMODE 0x03 /* get mode (promiscous/normal) */ #define NEIOCSNORM 0x04 /* set mode to normal */ #define NEIOCSPROM 0x05 /* set mode to promiscous */ /* we support these next ones */ #define NEIOCGSTATS 0x06 /* retreive stats into struct nestats */ #define NEIOCGLOWWAT 0x07 /* get the current low-water figure * this is only significant on the * write side flow control. */ #define NEIOCSLOWWAT 0x08 /* set the low-water figure. */ /* if_flags constants */ #define IFF_UP 0x1 /* interface is up */ #define IFF_BROADCAST 0x2 /* broadcast address valid */ #define IFF_DEBUG 0x4 /* turn on debugging */ #define IFF_LOOPBACK 0x8 /* is a loopback net */ #define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */ #define IFF_NOTRAILERS 0x20 /* avoid use of trailers */ #define IFF_RUNNING 0x40 /* resources allocated */ #define IFF_NOARP 0x80 /* no address resolution protocol */ /* next two not supported now, but reserved: */ #define IFF_PROMISC 0x100 /* receive all packets */ #define IFF_ALLMULTI 0x200 /* receive all multicast packets */ #define IFF_OACTIVE 0x400 /* transmission in progress */ #define IFF_SIMPLEX 0x800 /* can't hear own transmissions */ #define IFF_LLC0 0x1000 /* interface driver control/status */ #define IFF_LLC1 0x2000 /* interface driver control/status */ #define IFF_LLC2 0x4000 /* interface driver control/status */ #endif /* ne_H */ /* end of file neioctl.h */ etc/conf/ne/src/Makefile100644 3 3 577 5570572762 13056 0ustar binbin###### Makefile for ne device driver ###### # # author : Randy Wright # Copyright ((C)) 1993 Randy Wright # # # COHERENT 4.2 CON # # # # ################ all : ne.o wsub.o ar rs ../Driver.a ne.o wsub.o date >> all ne.o: ne.c neioctl.h ds8390.h devices.h.new cc -VPSTR -c ne.c wsub.o : wsub.s as -f wsub.s clean: rm *.o core err ../Driver.a ### end of Makefile #### etc/conf/ne/src/neinstall100755 3 3 235731 5570572763 13420 0ustar binbinL =- y Z @.text .data @ @@.bss@@ZXT@RUP/: P*U조 @~hh@hTPo ˃jÐU조 @~+U조 @~)hh@hTP' 5 @Y @+Ð@EE@ @~EÐU조 @~@ÐUW@}@}  @~+_ÐUE @E @ @~+U조 @~@ÐU조 @~@ÐUW@}@}  @~+_ÐUuh8h@ jh@, @ } hh@hT5 @ }5 @_Y @jhh@hz@ f%~@f ~@ fz@+f@f|@@@ @@f@ @hz@hT5 @ }/5 @Y @ @@ @ @@+Ð @EE @}tYstEÐ @EE @EÐ @EE @}t]stEÐ @EE @}trsEÐW@Ejj5@l =@G}uh9 ElP}`uh9 E8P},uh9 EP}uh8 EP}uh8 EP}uh8EhP}G\uh8E4P}G(uh8uh85@܀(5@tY+_,VWS@Eԋ}EGE܋=@GWtYEE}ek}4}ԋG(uEk}4}kE G(@Pj5@ ku4uk}4~(}P5@y5@tY몋=@G@E@EEE@E@EjjW. pj5@趄*r}+}}EE~Euuu5@)YE t u:5@ujk}4}w,EuuEE=7=t#=t~=tO=Gr85@ujk}4}w,\Euu_EuuEEuk4}ԋG(uuMuk4}ԋG(@=l8;Ea@=l8k4}ԋG(yuu@=l8EPu5@ujk}4}w,tE!EEu Yku4uk}4~(}PY;uE;Etuu-EqE맃= @uo= @uj5@U= @txnuu5@c, E裌@3uuu| E[_^ÐUVW=@GkE @PjW| kE 4EPh#95@| 5@pY=@Gk} 4}kE G(@Pj5@,| ku 4uk} 4~(}P5@v5@WpY_^ÐUVW=@GkE @PjW{ kE 4EPh*95@)| =@Gk} 4}kE G(@Pj5@{ ku 4uk} 4~(}P5@uu5@oY_^ÐUVW} GjuW:{ kE4EPuuh19u {} Gk}4}G(@Puu z ku4uk}4~(}P5@tu &oY_^ÐUVW} GjuWz kE4EPuuh89u z} Gk}4}G(@Puu hz ku4uk}4~(}P5@Qtu nY_^ÐVW@E=@GWonYEE}ek}4}G(uEk}4}kE G(@Pj5@y ku4uk}4~(}P5@s5@mY몋=@G+_^Ð VW@Eu&YEEE}Nku4uk}4~(}PY;Eu)k}4},t!ujk}4}w, E E몸_^8VWS+EEEE}-k}4}G(tkE4EPrYE;E~EEkE EO~}O+kE EPu EPEP oẼ}u/hGh?9h8@ h8@YVwj{YjjuuuoEȃ}u/hXh\9h8@| h8@KY wj.Yjjuw u>lY}GEE;E~Jjuuw 5m@uqE@Puuw 5m@uqEukYEE@;E~JujuUw 5m@uPquE@Pu1w 5m@u,qEjju w 5m@uqE@Pjuv 5m@upjE@Puv 5m@upE@PE@Puv 5m@up}GWjYjjuov ujY}GEE;E}CjPu?v ujYkE4EPuuhy9uvuijYE뵋}GEE;E}Dk}4}w(Puu ku4uk}4~(}Puou jYEEEEjYEj[YEjuz@Eܡ@Eء @~jju$ }EH;E}E}}EHEuuuuuYEc t u5k}4}, uȋE@PE @Pk}4}w,E=N=t=t@=teVhDuuuuEE;E!EuuuuM}EEk=@4},u0uuuuMk=@4}G0EE@;Eu8uȋE@PE @Pk}4}w,Euuuuuuuu@EuPuu1uȋE@PE @Pk}4}w,^]EE;EuYku4uk}4~(}PY;u[E;Et,uuuuDEEuPuuk}4},t uuk}4}G0Egk}4}G0EuuuuEjuw @~uuu " upYupY5@QpY5@fY5@9pY5@fY5@!pY5@qfYE[_^WhjhjhjE@%h@=@u*h6h9h8@ h8@YjYjjjOj5@ i@=@u/h<h9h8@ h8@YRpjwYjjjOj5@h@=@u/hCh9h8@r h8@AYoj$YjjjMjng@=@u/hJh9h8@% h8@YojYjNjjj5@h@=@u/hRh9h8@ h8@Y_ojYjjjMj5@g@=@u/hYh9h8@ h8@NY oj1YjjjOj5@qg}@=@u/h`h9h8@' h8@YnjYEEN}QPj5@o 5m@5@iuj5@`o 5m@5@XiEEE}QjP5@'o 5m@5@ijNu5@o 5m@5@hEjj5@n 5m@5@hjNj5@n 5m@5@h} t\u .Y=p8'+Pj5@kn =@Gu h9Wn =@GWbYjj5@"n j^5@h5@`bYEE}*jP5@m 5m@5@gEjj5@m jv5@g5@aYjj5@m j<5@gEEM}/Pj5@]m 5m@h95@m EjNj5@-m j>5@)g5@kaYjj5@l =@Guh9WQm =@GW'aY5@aY@f@@_Ð W}t} u } EGEEEM}QPj5@Xl 5m@5@Pfuj5@1l 5m@5@)fEuY=p8'+Pj5@k =@Guh9W@l =@GW`Yuuu k u _Y+_ÐUjÐȘW+EE}E} EGE̡@Eԡ@Eء @~@E@EE}S}uM}}EEEN}+}?u}uMEE;E~ EEEE륋E=p8'+ljEE=p8 +ljEuPEPEPaE}u/hh9h8@ h8@YeijYjjuuuaE}u/h!h9h8@ h8@ZYij=YEPE@PjjuyaEjjui }GEE;E}GjuWi 5m@ucE@Puui 5m@u~c}GEPE@PWSi 5m@uNcElEE@;E}GujWi 5m@u cuE@Puh 5m@ub}GE@PEPWh 5m@ubEn}GjjWh 5m@ubE@Pjugh 5m@ubbjE@PuDh 5m@u?bE@PE@Puh 5m@ubEHPE@Pug 5m@uaEPE@Pug 5m@ua}Gjjug }Gh:Wgjju{g }GE}EE;EjPuHg uY;E}BjOj hP uh:u踼Y=p8E=p8+-uh:hP hPuuh:u4gE}}L}GuZY @~jju jYEjJYEjukuMYu(YuY= @uj5@kuZY @~EУ@uu5@ uBdYu9dYu0dYuuu e 5@cY5@ZY5@cY5@YY5@cY5@YY+_ÐȬW+EEE}E} EGE@EС@Eԡ @~@E@EE}S}uM}}EEEN}+}?u}uMEE;E~ EEEEEE=p8'+ljE܋E=p8 +ljEuPEPEP [E}u/hh!:h8@ h8@YScjxYjjuuu[E}u/hh=:h8@y h8@HYcj+YEPujjuh[E}E+PujjuG[Ejjuc }GEE;E}GjuWuc 5m@up]E@PuuQc 5m@uL]}GEPE@PW!c 5m@u]ElEE@;E}GujWb 5m@u\uE@Pub 5m@u\}GE@PEPWb 5m@u\En}GjjWXb 5m@uS\E@Pju5b 5m@u0\jE@Pub 5m@u \E@PE@Pua 5m@u[jjua }GE}EE;EjPua u2Y;E}BjOj TPp uhZ:u Y=p8E=p8+-uh]:TP TPuuh`:uaE}}LEHPuu` 5m@uZEPuu` 5m@uZ}E+HPuu` 5m@uZ}E+ǃPuuk` 5m@ufZ}GjjWC` hg:u`}GGjju` }Ghj:Wk`}Gu_Yu9TYj!YEjYEjYEjueju e@Eԡ@EE @~h YEjju }}tuu: YEĺ&;b &#(#(&&#(&}}Gjju^ }Ghm:W(_u SY}GjjW^ hp:u^}G @~jju Eu}G @~jju jju$^ }Ghs:W|^u]RY}GjjW] hv:uL^}GEuRYjju] uRYuQY6E*uQYuQY:Q @~uu5@ Ẹ@ucYuYu Yut[Yuk[Yub[YuY[Y5@[Y5@QQYuuu \ 5@ZY5@(QY5@ZY5@QYE_ÐȔW+EEEEE}EGEȡ@Eԡ@Eء @~@E@EEEE}S}uM}}EEEN}+}?u}uMEE;E~ EEEEEE=p8'+ljEE=p8 +ljEuPEPEP+RE}u/h hy:h8@ h8@趻YtZjYjjuuuRE}u/hh:h8@蚿 h8@iY'ZjLYE+EPuEHPjuREjjuZ }GEE;E}GjuWZ 5m@uTE@PuuZ 5m@uT}GEPE@PW[Z 5m@uVTElEE@;E}GujWZ 5m@uTuE@PuY 5m@uS}GE@PEPWY 5m@uSEn}GjjWY 5m@uSE@PjuoY 5m@ujSjE@PuLY 5m@uGSE@PE@Pu&Y 5m@u!SjjuY }GE}EE;EjPuX ulY;E}BjOj lP読 uh:uCY=p8E=p8+-uh:lP lPuuh:uXE}}L}GE+EPuWX }GjjuX uTYuKLYuBLYu ubu+LY @~hVYEjjuB @~uu5@$ EУ@uUYuUYuUY5@[UY5@KYuuu@W 5@2UY5@KY5@UY5@jKYu 詬Y_ÐVWjj5@V 5@9KY=@GEE}?EEM}+Pu5@V 5m@5@PEE빋=@GWJY5@JY @~$=@5@w=@> @_^ÐU5@zJY5@nJY+ÐEE}3kE Pu5@U kE Ph:5@>V EjFu5@U h:5@V5@IY+EK~EKEE}PuP5@_U E=t8 th:5@Uuh:5@U E5@oIY+ÐVW+<@DHEEPTX\DžL@@@@@j5 @h@舮 8 @~(=@t8u@DžL볃=@=@qEEj dP5 @ E Ad`EE}`?t?t?t}t M`ڋErw`%\@5@k=@ @@~@@~@\@M`Q@;@t%@%=u@@=@t%@%=u@g=@t%@%=u@9=@t DžLdEEd`}``%=t}t `Mڃ}0`XXtMXtE`G%=u1Ev)``TTtEM DžT`G%=u2Ev*``GPPtMM DžTE; @~ ME++E; @~ EEE; @~ EE++E; @~ ME}u}tNuu)}t+EE}t+EE+EE졌@%=uUM`3f=@ @~ @= @tj5k@UuQYE_^ÐUVW @u nh:h8@訴 @u @ 5@5@5@P @%=@G @%PWI5@:DYE@E @E@=@} @=@} @=@G;@} G@@~ @=@G;@} G@@N~ @N=@5@w=@> @5@5@5@O 5l@5@Hjj +_^ÐVW @u n @u @ 5@5@5@N @%=@G @%PW}HE@E @=@} @=@} @=@G;@} G@@~ @=@G;@} G@@N~ @N=@5@w=@> @5@5@5@M @%E @1EE%=@G @%PWoG5@AY_^ rwwin.c built on Jan 19 1994 %s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s %-8.8s%-8.8s%-*.*s%-*.*srwwin: %d, s_menu is NULL - rwwin: %d, contents is NULL %-*.*srwwin: %drwwin: %drwwin: %drwwin: %drwwin: %drwwin: %drwwin: %d%s%c%-79.79s%srwwin: %d, m_box is NULL - rwwin: %d, contents is NULL OK%s%s%-*.*srwwin: %d, m_box is NULL - rwwin: %d, contents is NULL %s%s%-*.*sNOOKOKNOOKNOrwwin: %d, m_box is NULL - rwwin: %d, contents is NULL %s%s%-*.*s%.2d....|....70....|. -%.2dchmousewin WEK th]9YjݹYjh+^蜣 t?h8^Yha^Yh^Yh^Yh_Yj苹Yh_hD@h_hO@ݮh_hZ@ˮh_he@蹮h!_hp@觮h#_h{@蕮h%_h@胮h'_h@qh)_h@_hB_h@Mh@h@h@hd@}@jjPwI jY5@h@ u5@SYjlY5@h@jjjj5@@@j jj j5@y@@EE}==@GjPWH }@hm_5@I E5@<Y=@GWSYEE};=@GjPWXH kE D@Phs_5@H E5@<Y5@x<Y5@YEHw$=>'>?>+=>>>>+=>>>??(?H?h?u?5@ uH3Ytt$dt9~t'uh@uhp@uh@uh@uh@h l諗Yjh2lh/lh&lh#lhlj茭Yh5lբYØ tjP)Y;tutwhCl茢PaY(uh@hflYjhlhlhlh|lhtldjҬYhlY轗T(uh@jj5@i= =@GWGYhl5@=5@1Yjju'= +_ÐNE1000 - NE2000 Ethernet Device Driver Installer Each card needs two paramters. IRQ is the interrupt number.IOBASE is the card's port address. These parameters are the ones youmust set with jumpers when you install the cards in the computer.The software does not require any other parameters. If you do not have the IRQ and IOBASE information for each card,you can quit now, so that you can jot down the jumpersettings. Then re-run this program later. The TAB key toggles between OK or NO-=-Do you wish to continue...The installer menus offer all the user tune and install options for ne. If needed, change the per-card parameters to suit your situation using the change menus. The default values are for 1 card using IRQ 10 and and IOBASE of 0x300. Since these are for card 0, the card will be accessable through /dev/ne0. A zero in any card's IRQ data field preventsthe device driver from attempting to initalize a card in that slot. Build menu's space subselection will save your current IRQ and IOBASE values. Build menu's Build subselection calls system scripts to generate a new kernel. Once you have created a kernel, quit and reboot to try the new kernel. Your new kernel will be named /coh.ne. This installer can be used at any time to generate a kernel with differing parameters. -=-press to continue...The Three Easy Steps to install the NE device driver: STEP 1. Check listed parameters against hardware jumper settings. Use Change menu as needed. Zero IRQ field on unused cards. STEP 2. Use Build menu's Space subselection to save your parameters. STEP 3. Use Build menu's Build subselection to generate a new kernel. ** Use the elp menus for more detailed help **-=-press to continue...Navigation is done through pull down menus.You can choose a selection by typing the highlighted letter, orby using the arrow keys to move through the selections until youhave highlighted the correct selection -- then press enter.The escape key allows you back out of a menu.The Quit selection is in the Build menu.-=-press to continue...IRQ helpThe IRQ is the number of an interrupt that the ethernet card generates when it has received data or is ready for more data to transmit. There are 15 possible IRQ's for NE2000 cards, and 8 possible IRQ's for the NE1000 card. You need to select an IRQ that is not used by any other device in your system for each ethernet card you install. The hardware jumpers on the card need to be set to indicate your choice, and the IRQ values here need to alsobe set to correspond to the values you choose. The next screen shows some values that may be used by other hardware. If youuse the listed hardware, choose a different value for your ethernet card, toavoid IRQ conflicts -=-press to continue...IRQ 0 - system timer IRQ 8 - real time IRQ 1 - keyboard IRQ 9 - unused IRQ 2 - slave PIC IRQ 10 - unused IRQ 3 - COM 1 IRQ 11 - SCSI hai IRQ 4 - COM 2 IRQ 12 - unused IRQ 5 - SCSI 8bit IRQ 13 - math co-processorIRQ 6 - floppy IRQ 14 - IDE drive IRQ 7 - unused * IRQ 15 - unused IRQ 5 and 7 are used for interrupt driven printer service on somesystems, but not on current COHERENT configurations.Suggested IRQ's for ne include 5, 7, 9, 10, 12 or 15.NE1000 cards can't use IRQ's greater than 7.There may be other hardware on your system that create IRQ conflicts.-=-press to continue...IOBASE helpThe IOBASE is the address of io ports that the ethernet card uses. This address is usually specified as a hex number of the form "0xXXX" where XXX is 3 hex digits. The io ports can be from 0x000 to 0x3ff. You need to select an IOBASE that is not used by any other device in your system for each ethernet card you install. The hardware jumpers on the cardneed to be set to indicate your choice, and the IOBASE values here need to also be set to correspond to the values you choose. The next screen shows values that may be used by other hardware. If you use the listed hardware, choose a different value for your ethernet card, to avoid IOBASE conflicts -=-press to continue...0x278 - lpt3 0x3b0 - mono video 0x278 - lpt2 0x3c0 - ega/color 0x3bc - lpt1 0x3f6 or 0x1f7 - IDE drivebelow 0x100 - system 0x3f0 - floppy 0x1f0 - hard drive 0x330 - hai scsi 0x200 - game port 0x3f2 - 0x3f7 - floppy 0x2f8 - com2 0x3e8 - com3 0x3f8 - com1 0x2e8 - com 4 Suggestions for iobase for ne devices include:0x300, 0x320, 0x340 or 0x360-But don't use 0x320 if you use adaptec type scsi--=-press to continue...please enter the new value for the irq-=- Space not saved. Continue anyway?? -=-TAB key toggles between OK and NOplease enter the new value for the iobasea hexadecmal value in the form of 0x123 is preferablebut a decimal value without the leading 0x will also work-=-IRQ 0IOBASE 0IRQ 1IOBASE 1IRQ 2IOBASE 2IRQ 3IOBASE 3You MUST be the superuser to run the installer /etc/conf/neI cannot access directory /etc/conf/ne. This indicates that the previous installation phases did not copy the necesary files onto your hard drive please check the permissions of /etc/conf and retry the installation 100x300000000NE1000/NE2000 INSTALLLERSet up Parameters -- type h for help menu%8.8s%-10.10sI can't open /etc/conf/ne/Space.c to write the new parameters-=-press enter to continue/etc/conf/ne/Space.cw/* filename : Space.c * purpose : define parameters for ne ethernet device driver * author : Randy Wright * Copyright ((C)) 1993 Randy Wright *** generated by ne installer *** */ /* these are tuneable values for irq */ int ne0_irq = %s; int ne1_irq = %s; int ne2_irq = %s; int ne3_irq = %s; /* these are tuneable values for base of io ports for each board */ int ne0_iobase = %s; int ne1_iobase = %s; int ne2_iobase = %s; int ne3_iobase = %s; /* these tunable parameters are not used by the NE1000/2000 * devices. They are present for the day that wd/smc cards * are supported by this driver. */ int ne0_mem = 0; int ne1_mem = 0; int ne2_mem = 0; int ne3_mem = 0; /* end Space.c for ne */ /etc/conf/ne/Space.c/etc/conf/ne/Space.cI can't open /etc/conf/mdevice to get the existing parameters-=-press enter to continueI can't open /etc/conf/mdevice.new to set the parameters-=-press enter to continueI can't open /etc/conf/sdevice to get the existing parameters-=-press enter to continueI can't open /etc/conf/sdevice.new to set the parameters-=-press enter to continueidenabel failedreporting a confilctyou need to try different paramters-=-press enter to continuecommand failedreporting missing configuration files.-=-press enter to continuemake failed.-=-press enter to continuecommand failedreporting a usage error.This indicates an internal error in this installer-=-press enter to continueidenabel failedreporting an unknown error.-=-press enter to continuekernel /coh.ne has been builtYou can now quit, shutdown and reboot. When boot prompt saysPress to abort bootpress space and at the '?' prompt type coh.ne This will allow you to test your new kernel. If you aresatisfied, link /coh.ne to the name /autoboot card 0 - /dev/ne0 card 2 - /dev/ne2card 1 - /dev/ne1 card 3 - /dev/ne3-=-press enter to continueexec failed.This is usually caused by bad permissions or lack of memory-=-press enter to continuecp /etc/conf/ne/src/neioctl.h /usr/include/sys/dev/ne0mknod /dev/ne0 c 19 0/dev/ne0/dev/ne0/dev/ne1mknod /dev/ne1 c 19 1/dev/ne1/dev/ne1/dev/ne2mknod /dev/ne2 c 19 2/dev/ne2/dev/ne2/dev/ne3mknod /dev/ne3 c 19 3/dev/ne3/dev/ne3/etc/conf/mdevicer/etc/conf/mdevice.newwne%sne - CGHo ne 19 19 0 3 -1 -1 /etc/conf/mdevice.older/etc/conf/mdevice.older/etc/conf/mdevice.old/etc/conf/mdevice.old/etc/conf/mdevice.older/etc/conf/mdevice/etc/conf/mdevice.old/etc/conf/mdevice.new/etc/conf/mdevice/ect/conf/mdevice/ect/conf/mdevice/etc/conf/mdevice.new/etc/conf/sdevicer/etc/conf/sdevice.newwne%sne N 0 6 1 10 0x300 0x31f 0x0 0x0 /etc/conf/sdevice.older/etc/conf/sdevice.older/etc/conf/sdevice.old/etc/conf/sdevice.old/etc/conf/sdevice.older/etc/conf/sdevice.old/etc/conf/sdevice/etc/conf/sdevice.old/etc/conf/sdevice/etc/conf/sdevice.new/etc/conf/sdevice/etc/conf/sdevice.new/ect/conf/sdevice/ect/conf/sdevice/etc/conf/sdevice.newbuilding new kernelpress enter to continue %d /etc/conf/bin/bin/shshidenable-ene idenable OK press enter to continue status %d /etc/conf/bin/bin/shshidmkcoh-o/coh.neidmkcoh OK set parameters -- type h for help menu W}uLhotYE}u8}t}(hphoh8@} j҇Y=o@u Džp@?hvYu%}uh6phph8@| j~YDžh7psY t?u}Ph@pP|P }ou}PhRphIpPj|P }3}t}+uhdph8@{ j訆Y=o@thpsY to@h=o@7ho@l p@E =o@fGo@ PhTu p =o@G %=u+jo@ Po@Pk =o@fg!'t}t }_ÐVWShp?rYE=o@E+ہc}R+ o@?t5 o@:Eu o@EFC[_^Ðlib_setup.c built on Nov 13 1993 TERMTERM environment variable not set. Not enough memory to create terminal structure. TERMINFO%s/%c/%s%s/%c/%s/usr/lib/terminfo'%s': Unknown terminal type. CCCCUWo@PhT=o@GPn _UWo@ PhT=o@GPn _UWo@PhT=o@GPfn _UÐUjjuÐUW=o@G_ÐUW=o@G_ÐUWjhT=o@GPn =@t =@G$_ÐW=o@G E} @_UWh@hT=o@GPm _UWh@hT=o@GP~m _(VWSjumE}} j EPum  }E%fE}E%fE}E%fE}E%fE}E%fE}E%fEf}tu)lYf}}EPjh@ul /@} @f}~jEPuVl f}%}EPj%E .Pupl f}%~jE%Pul EEE%}} G.E}EǙ=v tjEPul  t*E} EPjE TPuk iEf}~E;E~KjEPuk }u}u}} fGT}} uEfGTEf}~jEPuk "EEE}}} fGTE=o@tEPgoY} Gu } G0@f}c}EcEE} Ed~dEPh0"@uj E}m ttEE=v;E]]] u怾0"@uu怾1"@u+#M }1"@}0"@AEEE=v;E~fN }u=o@GX;Eu }ufN  o@yXEE;ufN [_^VWS]CC;|C;| | }+kE %E  * -E % sM d@S%E ~t C%C E S ;E tcK f9uS K$ff1K ;~ K K$;} K$fK(fSF E C;}Y+GC.;}NO{SY:΃+ƉE;u}/j S FSQYN}+fCf[_^UVWS]u >tF%PS9 u+[_^ VWS]C E{{,{EC,C.;~?KG{{ fK({$fCffF빋EE{E+E=;E}E{.{E{.{ fK.K({.{$fCffff;C,~ ff;C.f [_^VWS]C EECE}{CEE}{EEu;us>;Et2uEu}{+=EE}{(f뽋Etr}{ ;E}{ f?u}{ Ef}{E+=ȋ}{$;} }{$MKE+=f[_^ÐVWS]CECE+;u&{ f{$Ef{(fF[_^ÐUVWS]fC u*+C;| {?t{7`YFs(`Ys `Ys$`Ys`YS`Y[_^ÐUVW=@}%=@=@wuGP=@w~FE_^ÐUWj p@HPjjM6=k@G=k@t"thtj=k@G=o@0thtj0 =o@xthtjx =o@|thtj| =o@thtj =@wK`Y_ÐUS]}|/C;E|&C,;E C.;E |EfCE f+[ÐUEPhh"@Nd h"@5k@CÐUE Phh"@"d h"@uUu u5k@T t+)EPhh"@c h"@5k@ÐUuu u t+&EPhh"@c h"@uÐ%r%r%r%rVWS]E{u"fC tfCf;Cuff;Cu+{jj=@?G PW EPj=@?G PW =@7T_Yuj=@?G PW u =@7Va=@3t1u2u :E{t `=@$~ @I$y$G9=@?}=@?=@7?GY=@yAt=@3tZ}R |N{C P;CP5k@? u+ CP5k@/ CPS }t[_^ÐVWSu=@GEjUYEh8jWEPjWuUY$@=@$~ @I$y$G9=@?}=@?=@7?GY=@yA؃t}FÈ}tMy;t }GE}tH}f tujVuUY}G r}Eh8jVjTY}% =$@ujVuTYN;v @y$A$G[_^ÐU$@h8jBVUVW=@}%=@=@wuGP=@w~FE_^ÐUW=o@dtt E =k@G_ÐUWE;k@u E =k@E }G_ÐUWE }G_UWE }G_UWE }G_UWE }G} t=o@thPj"} u$=o@thPj =@Guf_ÐUWE }G} t=o@(thPj("} u$=o@$thPj$4 _ÐUW$@h=o@lPh\=o@7hV=o@phM=o@thU=o@xhJ=o@|hH=o@h=o@hL=o@hO=o@ohN=o@Vh=o@=h =o@$h =o@ h =o@h =o@h =o@h=o@h=o@h=o@uh=o@\h=o@Ch=o@*hK=o@hI=o@h=o@h[=o@hR=o@hS=o@h=o@{hP=o@bhQ=o@IhT=o@0h=o@$@=@G_ÐUVWS] =`@=$@tU5$@F:t ~tvF:uCˀ9>tO6j VTYF u `@gFj 5TY$@ t+FCFfF ;t(j TY6 u`@ t>VTYE fF [_^ÐUWu8Y}G_ÐVWS]u =@G0EG3EG1EG2E^itEEu=@?}=@?=@7?GY=@yA > :E;uvN{C P;CP5k@ u+h5k@hS =@wh[V=@wzTY> | >!{C P;CP5k@ u+h5k@h S=@whU=@wSY:E;uN{C P;CP5k@| u+h5k@hS=@whQU=@wpSY> | >w{C P;CP5k@ u+h 5k@h$S=@wh(T=@wRY{C P;CP5k@ u+>d@5k@>d@S=@w>d@GT=@wfRYF=k@G=@G,}u!}t}t}ut>u+[_^Ð            Wj} G Pu t+j`OY@ tE =(@u=@G(@@E =@GE o@=@GG(G,GG0G1G2G3G4G\=o@GX p@GTp@h LYE tPLY=o@fGX p@h&^LYE tPKY=o@fGTp@=o@t 3Yjj=o@GTPGXPk@ jj=o@GTPGXPk@ k@=@Gk@G =k@G=k@GhjJ=k@u)jj=o@GTPGXPAk@ 4@_ÐLINESCOLUMNSUWS+m@m@m@m@+m@m@m@m@m@-m@|m@+m@_l@<l@>=o@Ȗ;Cbd+,-.0`afghijklmnoqstuvwx~h4Ǚޙȗd̘0J~NC% m@_C% m@EC% m@+C% m@C% m@C% m@C% m@C% m@C% m@C% m@uC% m@[C% m@AC% m@'C% |m@ C% m@C% m@C% m@C% m@C% l@C% l@tC% l@]C% l@FC% m@/C% m@C% l@C;t C?[_Ð$VWS]IEE =o@0t 0E;;$t PUYC;p?EC;@u;.uj>S/@ uj$UYjEC뉀;.u=C;@t0;0X=h$@j;u>>EC;*uE (=u>h>EC=o@f^G^;EBuzE<UEE<h$@j ;uu<h@@j:=E+EP<UE<uul:} EPUYFҀ;tC[_^ÐUW (@}(@h(@u0@P=,@,@E_ÐUS]hPjS [Ð^@^A^B^C^D^E^F^G^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^~^_ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?UVWSE#d@t(=o@(tu j( t(=o@@tu j@ t(=o@<tu j< t$=o@,tu j, +ۋ#Et"=o@tu j] t"=o@tu j3 t"=o@tu j @t"=o@tu j t"=o@tu j t"=o@tu j t"=o@tu ja t"=o@tu j7 t"=o@ tu j  =n@=d@~E%~;u =k@}~fm@tpu j}~m@P=o@Hx*P u j}~|n@P=o@L@*PS Ed@[_^ÐUhPuÐUVW=@}%=@=@wuGP=@w~FE_^ÐVWSjj8?E=k@tWY=k@G=k@tWY=k@G=k@tx9+ۋ=o@GX;~-5k@~ f~$f~(fCŋ=k@fG=k@fG=k@f=k@fGPP=@w,w(=k@=@G(=k@G=@G,wCYuj!>[_^ÐVWS] k@A E;k@th k@q+ o@AX;ATHE}tSM ;EuMރ}uF뻋 o@ATH;Eu+E}t o@AXH;uM+;}=S ;Et$WV @q,q( @q(y,G;} k@AES %;Eu k@u7S % k@AhPk@ @I }? @I @qS %P @IAP-@JAAES %MG o@y/t}t@ @A(A,k @y,];k@tH+;5 p@}>+;=p@}1k@JES MGF[_^UVWS+ۋ=o@GX;~5k@~(f?tSYC[_^ VWSE+ۋ=o@GX;GT=ȋ5k@~(;~/=o@GT=E~ ~$+;E=EtHEPu_E5k@~ f?tS8Y Eu]CPEt=o@GXHPu [_^UW=o@`u t"8t=o@t uuY_ÐVWSk@MJ9k@MJE+ۋ o@AT;~Uϋ;uCڋ o@AT;ATH;}Uϋ;uNSu @q,q(6E @A(Y,];u? o@y/t@AXH;B(uATH;B,k@Mϋ%;Bu k@u0Mϋ% k@AhPGk@ @I }8 @I @qMϋ%P @IAP @AP@Mϋ% @A,@ o@AT;B,!y/t @A,A( @I,UUMϋE[_^VWS5k@}~E5k@}~EE=o@GT;E~MM}};uEԋ=o@GT;E=GTHEE;E~}} uM=o@GTHEE;E~}} uMMM}};uMME;E~EEuu=@w,w(E=@G(EG,];(=o@/t @GXH;A(uGTH;A, k@}%;Au k@u0}%=k@GhPk@=@}8=@=@w}%P=@GP =@WJB}%=@G, @=o@GT;A,!/t=@G,G( =@O,CE;E}E+EPEPE;E~ +EP Y]=o@GT;~M}C[_^ÐUVWSE +E@Pu+ۋE +E@;|+fi@fi@C׋E +E@PE +E@P++E +E@ ~,fi@uF tu EPVi +K tu uVQ E +E@;|9i@tu!EHP!Yu EHP C[_^$VWS=o@GTdtd-/Y'E=o@t/Y'E;] iʼn k@}Oy7Yʼn k@}Oy7XYCf%@;] c- ȋH- %@Ef%@- fLJG@O%@Ef%@fLJG@C똻;] };u i- lj͋;u+ =o@GTIH- %@f%@- fLJG@I- %@EE- %@;E~3- Ef%@- fLJG@H- %@EE- %@;E~3- Ef%@- fLJG@FCz=o@OTGT- %@[_^ÐUVWS+;]{+;u@- G@P- %@Ph$: F (@}(@h(@j 0@P=,@,@ Ch(@j6Y[_^VWS];] +=o@GT;~d (@}/(@h(@=k@O970@P*,@,@Ek@J9}F (@}(@h(@j 0@P=,@,@ CL[_^ÐVWS];] +=o@GT;~d (@}/(@h(@=k@O970@P*,@,@Ek@J9}F (@}(@h(@j 0@P=,@,@ CL[_^ÐVWS]+E=o@GT;~ uF܋ o@yT@;}AˋEыE[_^ÐUVWS]u u t}- G@t t#t:UHPSfLJi@9fLJi@VHPHPHPfLJi@[_^ÐUVWhj=o@t(hj +=@G,G(=o@tU=@G,G(jjw,P=@G(G,hj=o@Q =o@=@G,G(5@=o@GX;F(~Ij=@w(w,w(=@G(G(G,hj=o@ jj=@w,w(=@G(G,_^ÐUVWS]u =o@ O8Bhj V =o@/t @GXH;A(uGTH;A,=k@%;Gu k@u(%=k@GhPk@=@}*=@=@w%PGP=@OyA%=@G, @=o@GT;A,!/t=@G,G( =@O,Nhj=o@8. g=o@@,hjV@P -=o@/t @GXH;A(uGTH;A,=k@%;Gu k@u(%=k@GhP3k@=@}*=@=@w%PGP=@OyA%=@G, @=o@GT;A,!/t=@G,G( =@O,N  hj=o@` =o@/t @GXH;A(uGTH;A,=k@%;Gu k@u(%=k@GhP k@=@}*=@=@w%PGP=@OyA%=@G, @=o@GT;A,!/t=@G,G( =@O,N[_^ÐUWS]=o@4t!hjS4rP $K thj=o@a [_ VWSk@MJEju @q,q(/E @A(A,hj o@d +ۋ o@AT;"y/t@AXH;B(uATH;B,k@M%;Bu k@u0M% k@AhPk@ @I }8 @I @qM%P @IAP @AP@M% @A,@ o@AT;B,!y/t @A,A( @I,Ck@M JE} ;}~* k@AEk@IJMOыk@JE+ o@AT;~6k@JEk@P MF[_^VWSju =@w,w(E =@G(G,=o@8t#hju8P 'EM thj=o@ ًu E;E= k@yEQ}y}yEF;u1+ۋ=o@GT;~k@J9 CF[_^Ð %5d/%d$VW% }|} } j@'j@5o@~XEU~TE U 5o@~XEU~TEU2Yuuj =j@trYuu uu I ;~$PYujP =L=j@tE;E | E;EFYjj uj P.;~$=j@tE;E | E;EYjjM u=o@GXHPh P;~$Y_^Ð$VWE;E I;E }DžDžDž DžYuj S =j@tlYE +EP"YP ;~$=j@tlYE +EP"YP ;~$u_^Ð VWE;E ;E } Dž Dž HYuj  =j@tE;E }oYjj uj- ;~$=j@YE +EP YP4 ;~$0Yuu V ;~$u_^8VW=j@u}LJE ;EE ;EDž=o@fV~a@=}U5o@~VE ~VE+=o@OV~VE@鉅t~V+ljE DžDžDžDž=o@fV~k@=}_5o@~VE~VE +=o@OV~VEH鉅t=o@GVE DžDžDžP0YP Y|O=o@GT;~=j +EPYPm LJYE+E PYP- ;~$=}Pu8u'_^UWE}LJ_ÐVWS]u =} =| ǃ4uE;t}Eۋ[_^4VWS]=;EЋ}l@؉E؃}~eEE;E}M̓AEhjuuuuuuuuuuYP(P /E̋EM thjuYP ۃ<[_^ÐUVWS=@th=@G,v@\u#h@@8PY=@G\+ۃ }=@G8l@Cߋ=@4tH%,v@(@=h@uh@hl@)Yj jYP t p@[_^ÐUWS+ۃ }NSY t2j@hjSYP }j@}C[_ÐUj@ÐU5,v@u Ð,VW} l@؉EuE E=t u Y u}LJ})Em})uEEEԋEE؋EE܋EEE EE$EE(EE,EE0EEE;E}"M}GԉEj@hju0u,u(u$u uuuuu %YPB(PU j@}_^UWS]Ã<$>O`q %=o@=o@=o@=o@=o@=o@=o@=o@r=o@d=o@V=o@H=o@<:=o@L,=o@P=o@X=o@+[_ÐVWS]C EC,C.;E{ECEEEEE;Ew@};Et0EEEuE+E=\EE}{(fE븋Etk{ ;E { f?u { Ef{E+=\ȋ{$;}{$KE+=\fF +ffC[_^ÐUVW=@}%=@=@wuGP=@w~FE_^ÐUW jjhj该fh`j=o@. 5k@Y_ VWS]E $k@ j@(k@$j@; ;%t (k@(k@ Ck; bx!%&'*+-/023;<=>?P^cdegimpst{|~_c#V<rt^3sTd. (k@(k@%= j@~ j@ j@0v@jh45(k@ 5(k@Y(k@@CE}2t }3*Cˀ9d}2u)= j@~ j@ j@0v@jh7늃= j@~ j@ j@0v@jh<^C;d= j@~ j@ j@0v@jhA(C;d= j@~ j@ j@0v@jhE(k@(k@= j@~ j@ j@0v@+"= j@~ j@ j@0v@j5(k@0 C;1;9 j@ j@ 1 $k@0v@ j@C;a;za= j@~ j@ j@0v@+,k@XC;aN;zE j@7 j@ a,k@hC j@} j@0v@ j@CEC;0|;9 kE 0E j@ j@E0v@= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@S j@됃= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@ j@+(= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@ j@= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@ j@ƙW= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@ j@ƙ0v@= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@F j@#= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@ j@ = j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@v j@3= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@ j@;u C+<= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@ j@;~늃= j@~ j@ j@0v@+= j@~ j@ j@0v@+ j@5 j@;-= j@~ j@ j@0v@u+ j@ j@0v@%= j@~ j@ j@0v@+붋 $k@A= j@~ j@ j@0v@+ usCE;tf;%u C;?u E;tC;;u }~EM;eu}u3CE;t&;%u C;?u E;tC;;u}~M;tC$ (k@$j@[_^ÐUu uuÐ%d%02d%03d%2d%3dT$D$UVWSQu }ށʁ;}ً+˃63ޜځ'y M |+xAց |Et&ꝃ  Y[_^]Ç++9+ttك+++tƃ~ك4 ;wr;s벐\$ $L$Vu+ y u+ y ^Y[;wr;wt y萇T$D$UVWSQu }3ށS΁ځ + ++r ;rw;r tCꝃ u ~2}E Y Y[_^]8u u( u$Z++݁u ut ZZS+ȋsIs t [@;rֹ+NjЋrՐQ+ҋȁt: t#% ѝyYú++YÐ yyÐUVWSQu }ށʁ3UʋR旋ᖇÃ_ tE u  ~/} Y Y[_^]ELJZZ++ڐt Q*ʁ  Y+QʁtL Ҝ~=}.s@t 3A} y Yø+YÐQZQQQLRPD$уYVWt$|$ L$sfs_^WL$|$D$ %@sfsD$_ÐVt$d$ :t u+N^ËL$ u+ùVWt$|$ +u wBJ_^ÐL$ $+VWt$|$ u_^D$ÐW|$*+_U5@E PuÐUuu us u%v@uuu u v@Ð VWSjju hP Yq#d!WƁj Pl 1; t; uC;;t ; t; tC;u Dž CDžu >t tZYPY Džϋ  t u Cˊွ't "uCƅωC tKu t9 t0t͊:u+CCurt CϋEE >tϋውuWl WoY[_^ø!ZÐFÐ 2ÐÐ ÐÐ>ÐÐ6Ð%Ð ÐzÐfÐWRÐ>Ð$*Ð Ð;v@ Ð t3 ÐL$/L$"L$L$L$0 ÃX%;PYL$X P8L$ tÐU}}EEÐVWS]+EC @u-u E+uC@tk 0}t[_^ÐUVWS=@ t0σ t#uC:u>tF>uڀ{=uԋ+[_^ÐVWShE }{}u$juhkhhh`{jYjjjjqEPY;Et } }]VjHWj=E[_^Ð/bin/shsh-cUW}@tEE_ÐVS] eEe;]t+SmY t SjV [^VWS=@t+8jYE t +EPmYu @EH%E;EsEE@@u-Y؃uT=@ujYEtE;EvEE@E=mEsE뜃=@u@Ë@@1;@uE{@@~^@EE@~[_^VWS}u+EHE;Er+@@EEM t" uF+ t ǃC;@tjh@j @u$Y u{ tދǃ @;}s뜋E+ǃsEE@EE@ @9@C[_^ÐUVWS}tME؋3sjh@j  ;@t=@u@[_^ÐVWS]CECuSSUYC PhYt MqTYMytqYMq6Y+CC [_^ÐVWS] u8+@=@r! tCtSYuھӋ~C umCEMC+A ~VUr C P ;u$ |MC;AuACCMA +v@u v@K [_^ÐUVW}} WGY u~F_^ÐUVWS] }K~4M } QAY UJBtGƈ uɃu;}t MA t+E[_^ÐUWS@@s(;t;Guj3u u+[_UVW} }WuGPu ~FE_^ÐUVWS]u ;t;}VCPFPNFCuF tǸ[_^ÐUVWSu @}@h@ @Y=@@؃t t FÈ뿃u;ut=$@ t+E[_^ÐUuYÐ(0jÐUVS] sEtC t*C uFKc EFE[^ÐUVS]sCH$0pFR{u FtF C+F ؉ }(F+CF@sYC tF cF[^ÐUVWS]u ~VY}VSFP NFÈ[_^EEPu u EÐE EPuh(@| EEEPu u,WSEԉEEPju uu EP0 M}EEPjEP }E[_ÐPVWS] +C%t?u6GM }QAPËUJB+Dž Cv;uWb #+-0Dž0늋*u4EMA }Dž؉C>Dž0|)9$k 0C̋.C*u1EMA} DžCHDž0|39.k 0CDžlt htLuC Dž+a;b@EGXcdefginoprsux@@u@@@MBYDž lEMAhuf}؉~Dž Dž lEMAhuft+t t u u t Dž V2++ FDž7PuVzEEFEMAEMA u DžF9t|+;~NDžDžDžXDžThuEMIfLlEMI95EMAAQPuf +t)tu t tot++ } Džui~`t0u> ~.M }QAPՋUJBƒtxu%M }Qj-APVUJB-HtM }Qj+ЋUJB+#tM }Qj 뫋UJB tUM }Qj0AP UJB0ot'M }QPAPUJB ~M }Qj0ƋUJB0ԋ+ ~CM }!QPMAPȋEP@뭃 M }Qj APՋUJB [_^VWS]Exu@@EuE w(EN΋E+u}E+uE u#N΋E +u}E +uE u݀>t CF[_^Ð{NULL}Uhh8@6jÐ You must compile with the -f flag to include printf() floating point. UVWS]{uY=v@C PYY u+(@u@hVjSt tjjjSa=v@[_^ÐUS]SYSCY[UVS]u VgYVSFP[^ÐU졈v@ v@ ~-v@v@ u ÐUS@=@r;t3;Y[Ð?ÐÐ @L$D$@ øxD$@3EPhtu |+ÐUVS];,jjjVhS Y[^ÐUVWS] }oSY ux=4@@t h(@YsF+F Pv C Ps u4v@u v@K  F {C;uK [_^ÐVWS]=4@@t h(@%YjEPC P uE) uK v@u v@K [_^ÐUW}O _ÐUWS] }K  {C[_ÐVWS]uEE+EEErM E ErEEwM E tl}buEE M E}+uEE M EE:EuEE M E}buEE M E}> }}uuun }A}u}t5hu |EtVYuu) }t jjV u j,rY u VaYCCCC ƈC CC{G+GGG GG}tK}u K G Eu K , EuK }wuEX}auEJ+[_^ÐUVWS]u ~}VY tG+G HNF[_^VS]u F u=ÈEjEPF P uEv@u v@N [^UW} O _ÐUVWS] E{C;Gu SY uKCE uSY t[_^ÐUVS]sECF+FFF C+FC CC } }K F,K E F @[^ÐUWS] {CE[_ÐUVS]{t Et} uuYE t؀KsE t tU@t<뾋C CFtuSqE CF E FEE F)K @CF E πK CFC t,C tF +[^UVWS]u jjC P t u++[_^ÐÐÐUVS]sCtSYF ;Cw SY0jC+F PC P# uCF +[^Ðx8 IRQIOBASEQuitSpaceBuildIRQ 0IRQ 1IRQ 2IRQ 3IOBASE 0 IOBASE 1 IOBASE 2 IOBASE 3 NavigationGeneralVariables @3 StepsBuild @Change@Help`@HHHITIIII JCJmJoJJJJJKJKKK(LrLtLLMRMTMMM2N6NSNVNNNNOObOdOOOOOOP.PnPPPQBQFQcQfQoQQ RVRXRRR?SSSS(TuTyTTTTT/UaUUUU)V+VmVVVWKWOWlWoW{WWX_XaXXXEYYY)Z-ZJZMZZZZ%[[[[[[[.\K\~\\\\\\\\\]]H]~]]]]]]]]]]]|___cCcGc_cbcccccccddPdTdldoddddddd ee(e+e8e@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~ĝƝ ((((( H Bad pointer in malloc. Bad pointer in free. 0123456789ABCDEF0123456789abcdefH@ d@ @  ,,@(@8@v@.text.data @.bss@.text.data @.bss@.text:.data @.bss@.textl.data@.bss@.textp.data @.bss@.textq.data`@.bss@.textv.data`@.bss"@.text0y.data`@.bss"@.textz.data`@.bss"@.text|.data`@.bss"@.textH|.data`@.bss"@.text.data`@.bss"@.textl.data`@.bss"@.text.data`@.bss"@.text.data`@.bss"@.text.data`@.bss"@.text.data`@.bss"@.textt.data`@.bss"@.text.data`@.bss"@.text.data`@.bss"@.text.data`@.bss$@.textP.data`@.bss$@.textL.datad@.bss%@.textd.datad@.bss%@.text,.datad@.bss%@.text0.datad@.bss%@.text$.datad@.bss%@.text.datad@.bss%@.text̝.datad@.bss%@.text.datah@.bss%@.text,.datah@.bssj@.text<.data@.bss j@.text`.data@.bss j@.text.data@.bss j@.textL.data@.bssk@.text.data@.bssk@.text.data@.bssk@.texth.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text`.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text0.data@.bssk@.text`.data@.bssk@.textx.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text .data@.bssk@.text .data@.bssk@.text4.data@.bssk@.textH.data@.bssk@.text`.data@.bssk@.textt.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text(.data@.bssk@.text8.data@.bssk@.textT.data@.bssk@.text.data@.bssk@done.text.data@.bssk@.text.data@.bssk@.text|.data@.bssk@.text.data@.bssk@.textp.data@.bssk@.textp.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text\.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text(.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text$.data@.bssk@.textD.data@.bssk@.textd.data@.bssk@.text|.data@.bssk@.text.data@.bssk@.text.data@.bssk@.textD.data@.bssk@.textD.data@.bssk@.text.data@.bssk@.text$.data@.bssk@.textL.data@.bssk@.text`.data@.bssk@.textt.data@.bssk@landsend@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text,.data@.bssk@.text@.data@.bssk@.textl.data@.bssk@.textt.data@.bssk@.text.data@.bssk@.text .data@.bssk@.text .data@.bssk@.textt.data@.bssk@.text.data@.bssk@.text.data@.bssk@.text,.data@.bssk@.text@.data@.bssk@environ@_start_exit.-< NdZ/l ~$T5mstab @4h  (09KY i)v4 /0,0k@08 6 `X%@makspace?1@A@M@Y0@d@@oP@z`@@main:builditA$@@p@_tracingk@k@COLORSk@newscrk@curscrk@stdscrk@acs_mapk@m@n@o@o@SP@ttytypeo@lCOLSp@LINES p@p@settermqbaudrate|qkillchar0qresettyqsavettyqgettmodeqpsavetermpflushinpDqqfixtermp&v0qnocbreakTxrawvnocrmodexnlwechoXwnorawwcbreak wnonlxcrmodeLwnoechoxflashybeepywrefreshz;Dzinitscr|subwinD}newwinH|waddchwaddstrlscrollHtouchwindelwinendwinĄwmovemvprintwTwprintw,printwRwgetchidlokclearok̊metaleaveok\lscrolloknodelaykeypad$wclearLwgetstrdnewterm,g0tputs$putp_outcP_unctrld@vidputs̝vidattrDelCharldoupdateHDelLineInsStrq`}InsLine̷HashFn$outcout_file,v@mvcur,werase<tstpstack0v@tparmtgoto _dsubT_daddZ_drsubL_dcmp_ddiv_drdiv_dfcvth_dicvt_dmul_ducvt_fdcvt_fdivh_fadd`_fmulp_fsubx_memcpymemcpymemsetindexstrchrstrcmpstrncmpstrcpy:strncpy0strlen`execlxexecveaccessalarmchdirchmodchown close fcntl4geteuidHioctl`killtlinklseekopenpollreadsyncunlink_execveerrnov@.cerror(fork8signalsigholdTsigrelseasigpause{sigsetnwaitpidwaitabsatoigetenv|system_ctype@toupperpcalloc__a_top@@free @@malloc$fclosefflushfgetcfgetsfopen\fputcfputsgets(removerenameungetcfprintf$printfDsprintfdvsprintf|vfprintf_dtefg_iob2H@_iob@_fp@_fginit_fpinitv@_atexitnv@exit_finish$ulimitLwrite`sbrktbrkisattyabort_fgetb_fgetc_fgete,_fgetstr@_fopenl_fputbt_fputc_fpute _fputt _stropentsetvbufcreatgetpid,_fpseek@__endv@sigreturnrwwin_workfillrwwin_getdclickrwwin_newtitlerwwin_unhisubitemrwwin_toponrwwin_workrefreshrwwin_unhitopitemrwwin_setcbmoderwwin_endrwwin_chmswinrwwin_getsclickrwwin_setrawmoderwwin_mousecloserwwin_sigrwwin_topbarrwwin_hisubitemrwwin_setkpmoderwwin_topoffrwwin_creatrwwin_getbuttonsrwwin_setechomoderwwin_getmsyxrwwin_hitopitemrwwin_getstrrwwin_topsubrwwin_setrezrwwin_getmsintrrwwin_xrulerrwwin_geteventrwwin_mouseisonrwwin_yrulerasc_parmsrwwin_messagerwwin_getynrwwin_updmsrwwin_mouserwwin_setmsintrmakemessagenoparamsmessageexecmessagegoodmessagedb1messagedb2messagedb3messagedb4messagenofilemessagespacemessageunknownmessageconflictmessage__pair_changed____pairs____color__COLOR_PAIRS__cur_termsetupterm__first_termresettermerasecharmust_swapread_entrywnoutrefreshwclrtoeolmvwprintwadd_to_trysetup_acs_DumpCurscr_DumpNewscr_PrintCostssigignore__a_scanp__a_first__a_count_atexitfpetc/conf/ne/src/ds8390.h100644 3 3 14716 5570572763 12562 0ustar binbin/*- * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)ds8390.h 7.1 (Berkeley) 5/9/91 * ds8390.h,v 1.2 1993/05/22 08:01:54 cgd Exp */ /* * Nominal Semidestructor DS8390 Ethernet Chip * Register and bit definitions */ /* * Page register offset values */ #define ds_cmd 0x00 /* Command register: */ #define DSCM_STOP 0x01 /* Stop controller */ #define DSCM_START 0x02 /* Start controller */ #define DSCM_TRANS 0x04 /* Transmit packet */ #define DSCM_RREAD 0x08 /* Remote read */ #define DSCM_RWRITE 0x10 /* Remote write */ #define DSCM_NODMA 0x20 /* No Remote DMA present */ #define DSCM_PG0 0x00 /* Select Page 0 */ #define DSCM_PG1 0x40 /* Select Page 1 */ #define DSCM_PG2 0x80 /* Select Page 2? */ #define ds0_pstart 0x01 /* Page Start register */ #define ds0_pstop 0x02 /* Page Stop register */ #define ds0_bnry 0x03 /* Boundary Pointer */ #define ds0_tsr 0x04 /* Transmit Status (read-only) */ #define DSTS_PTX 0x01 /* Successful packet transmit */ #define DSTS_COLL 0x04 /* Packet transmit w/ collision*/ #define DSTS_COLL16 0x04 /* Packet had >16 collisions & fail */ #define DSTS_UND 0x20 /* FIFO Underrun on transmission*/ #define ds0_tpsr ds0_tsr /* Transmit Page (write-only) */ #define ds0_tbcr0 0x05 /* Transmit Byte count, low WO */ #define ds0_tbcr1 0x06 /* Transmit Byte count, high WO */ #define ds0_isr 0x07 /* Interrupt status register */ #define DSIS_RX 0x01 /* Successful packet reception */ #define DSIS_TX 0x02 /* Successful packet transmission */ #define DSIS_RXE 0x04 /* Packet reception w/error */ #define DSIS_TXE 0x08 /* Packet transmission w/error*/ #define DSIS_ROVRN 0x10 /* Receiver overrun in the ring*/ #define DSIS_CTRS 0x20 /* Diagnostic counters need attn */ #define DSIS_RDC 0x40 /* Remote DMA Complete */ #define DSIS_RESET 0x80 /* Reset Complete */ #define ds0_rsar0 0x08 /* Remote start address low WO */ #define ds0_rsar1 0x09 /* Remote start address high WO */ #define ds0_rbcr0 0x0A /* Remote byte count low WO */ #define ds0_rbcr1 0x0B /* Remote byte count high WO */ #define ds0_rsr 0x0C /* Receive status RO */ #define DSRS_RPC 0x01 /* Received Packet Complete */ #define ds0_rcr ds0_rsr /* Receive configuration WO */ #define DSRC_SEP 0x01 /* Save error packets */ #define DSRC_AR 0x02 /* Accept Runt packets */ #define DSRC_AB 0x04 /* Accept Broadcast packets */ #define DSRC_AM 0x08 /* Accept Multicast packets */ #define DSRC_PRO 0x10 /* Promiscuous physical */ #define DSRC_MON 0x20 /* Monitor mode */ #define ds0_tcr 0x0D /* Transmit configuration WO */ #define DSTC_CRC 0x01 /* Inhibit CRC */ #define DSTC_LB0 0x02 /* Encoded Loopback Control */ #define DSTC_LB1 0x04 /* Encoded Loopback Control */ #define DSTC_ATD 0x08 /* Auto Transmit Disable */ #define DSTC_OFST 0x10 /* Collision Offset Enable */ #define ds0_rcvalctr ds0_tcr /* Receive alignment err ctr RO */ #define ds0_dcr 0x0E /* Data configuration WO */ #define DSDC_WTS 0x01 /* Word Transfer Select */ #define DSDC_BOS 0x02 /* Byte Order Select */ #define DSDC_LAS 0x04 /* Long Address Select */ #define DSDC_BMS 0x08 /* Burst Mode Select */ #define DSDC_AR 0x10 /* Autoinitialize Remote */ #define DSDC_FT0 0x20 /* Fifo Threshold Select */ #define DSDC_FT1 0x40 /* Fifo Threshold Select */ #define ds0_rcvcrcctr ds0_dcr /* Receive CRC error counter RO */ #define ds0_imr 0x0F /* Interrupt mask register WO */ #define DSIM_PRXE 0x01 /* Packet received enable */ #define DSIM_PTXE 0x02 /* Packet transmitted enable */ #define DSIM_RXEE 0x04 /* Receive error enable */ #define DSIM_TXEE 0x08 /* Transmit error enable */ #define DSIM_OVWE 0x10 /* Overwrite warning enable */ #define DSIM_CNTE 0x20 /* Counter overflow enable */ #define DSIM_RDCE 0x40 /* Dma complete enable */ #define ds0_rcvfrmctr ds0_imr /* Receive Frame error cntr RO */ #define ds1_par0 ds0_pstart /* Physical address register 0 */ /* Physical address registers 1-4 */ #define ds1_par5 ds0_tbcr1 /* Physical address register 5 */ #define ds1_curr ds0_isr /* Current page (receive unit) */ #define ds1_mar0 ds0_rsar0 /* Multicast address register 0 */ /* Multicast address registers 1-6 */ #define ds1_mar7 ds0_imr /* Multicast address register 7 */ #define ds1_curr ds0_isr /* Current page (receive unit) */ #define DS_PGSIZE 256 /* Size of RAM pages in bytes */ /* * Packet receive header, 1 per each buffer page used in receive packet */ struct prhdr { u_char pr_status; /* is this a good packet, same as ds0_rsr */ u_char pr_nxtpg; /* next page of packet or next packet */ u_char pr_sz0; u_char pr_sz1; }; etc/conf/ne/src/wsub.s100644 3 3 7704 5570572763 12602 0ustar binbin/ filename : wsub.s / purpose : ethernet in/out [s] b|w functions / author : Randy Wright / Copyright ((C)) 1993 Randy Wright / /$Log: wsub.s,v $ /Revision 2.1 94/01/25 22:00:47 root /cleaned up comments and rmd oub,inb. /ready for beta. / /Revision 2.0 94/01/19 16:13:47 root /*** empty log message *** / /Revision 1.1 93/11/14 00:17:05 root /Initial revision / / / module name wsub .alignoff .intelorder .text //// ee_insw( port, data, len ) int port; short *data; / / / .globl ee_insw ee_insw: push %ebp movl %ebp, %esp push %es / just in case it needs to be preserved push %edi / save this, it must be preserved push %ds / put ds into es so that ed:di point to data pop %es / loads es with data seg movl %eax, 16(%ebp) / grab len movl %ecx, %eax / put len into %ecx movl %edi, 12(%ebp) / put data pointer in edi, must point to word / aligned variable cld / clear direction movl %edx, 8(%ebp) / put the port number into edx ///////////////////////////////////////////////////// /////// this loop is used instead of rep insw to try /////// to avoid some chip bug eel: insw / get the word from the port, repeat ecx times / jmp eej / this adds some bus settling time / eej: loop eel / ///////////////////////////////////////////////////// pop %edi / restore pop %es / restore leave / restore %ebp ret .align 4 //// ee_insb( port, data, len ) int port; short *data; / / / .globl ee_insb ee_insb: push %ebp movl %ebp, %esp push %es / just in case it needs to be preserved push %edi / save this, it must be preserved push %ds / put ds into es so that ed:di point to data pop %es / loads es with data seg movl %eax, 16(%ebp) / could be used movl %ecx, %eax / put a 1 into %ecx movl %edi, 12(%ebp) / put data pointer in edi, must point to word / aligned variable movl %edx, 8(%ebp) / put the port number into edx eek: insb / get the word from the port, repeat ecx times jmp eeh / this adds some bus settling time eeh: loop eek / pop %edi / restore pop %es / restore leave / restore %ebp ret .align 4 //// ee_outsw( port, data, len ) int port; short *data; / / / .globl ee_outsw ee_outsw: push %ebp movl %ebp, %esp push %esi / save this, it must be preserved movl %eax, 16(%ebp) / could be used to make a real insw movl %ecx, %eax / put a 1 into %ecx movl %esi, 12(%ebp) / put data pointer in esi, must point to word / aligned variable cld / make sure we're going the right direction movl %edx, 8(%ebp) / put the port number into edx ///////////////////////////////////////////////////// eeo: outsw / get the word from the port, repeat ecx times / jmp eep / bus timing / eep: loop eeo ///////////////////////////////////////////////////// pop %esi / restore leave / restore %ebp ret .align 4 //// ee_outsb( port, data, len ) int port; short *data; / / / .globl ee_outsb ee_outsb: push %ebp movl %ebp, %esp push %esi / save this, it must be preserved movl %eax, 16(%ebp) / could be used to make a real insw movl %ecx, %eax / put a 1 into %ecx movl %esi, 12(%ebp) / put data pointer in esi, must point to word / aligned variable movl %edx, 8(%ebp) / put the port number into edx rep outsb / get the byte from the port, repeat ecx times pop %esi / restore leave / restore %ebp ret .align 4 //// e_outw( port, dat[i] ) int port, dat; / / / .align 4 .globl e_outw e_outw: push %ebp movl %ebp, %esp movl %edx, $0 / clear %edx movl %edx, 8(%ebp) / load edx movl %eax, 12(%ebp) / load eax outw (%dx) //, %ax / send the word leave / an after thought to retreive %ebp ret .align 4 //// e_inw( port ) int port; / / / .align 4 .globl e_inw e_inw: push %ebp movl %ebp, %esp movl %edx, $0 / clear %edx movl %edx, 8(%ebp) / load edx / movl %eax, $0 / clear %eax inw (%dx) //, %ax / get the word into ax leave / an after thought to retreive %ebp ret .align 4 .align 4 /// end wsub.s //// etc/conf/ne/src/all100644 0 0 127 5570574050 12510 0ustar rootrootTue Feb 1 16:10:31 1994 PST Fri Mar 4 15:35:15 1994 PST Tue May 24 23:03:04 1994 PST etc/conf/ne/src/README100644 3 3 22074 5570572764 12334 0ustar binbinne device driver This document applies to r2.0 of the ne device driver. QUICK START (using defaults for one card only): --- note --- type the exact keystrokes listed. 1. Install one NE2000 compatible ethernet card with jumpers set to IRQ 10 and IO Base 0x300. 2. While logged in as superuser, change directory to /etc/conf/ne/src and command: neinstall 3. When installer screen comes up, hit twice to speed past the opening installer screens, then type: bsbb (DO NOT HIT ENTER YET. Let the installer build some files, and build a new kernel first.) 4. When kernel is built, read the message box, then hit to quit. -------- The ne device driver is a traditional Coherent CON style driver for NE1000 and NE2000 compatible ethernet boards. The driver is both simple and very fast. The NE style board is characterized by port rather than memory based io and jumpers to configure hardware parameters. The driver has a major number of 19 and minor numbers of 0 and 1 are available as supplied. In the distribution, only one card has default hardware parameters. This will be generally be accessed by character special file /dev/ne0 with major number 19 and minor number 0. The default IRQ is 10 and the default io base is 0x300. Of course, the device driver IRQ and io base MUST match the jumper settings on your ethernet card. The driver does not care which physical medium you use (eg: 10baseT, 10base2, 10base5). These are dependant on the type of hardware you have purchased. In addition, the driver works only with regular "Blue book" ethernet packets and does not handle IEEE 802.3 ---- A full screen installation program binary has been developed and included with the driver. It reduces the installation process to 3 steps and includes help screens to guide the installer. Every attempt has been made to make the ne installation as close to 'plug and play' as is possible. The program is called neinstall. To do the installation, the installer must know the IRQ and IOBASE numbers that correspond to the jumper (or switch) settings on the ethernet hardware. Each card must have a unique IRQ and IOBASE that do not conflict with any other hardware on the system. The default installation is for one ethernet card using IRQ 10, and IOBASE of 0x300. Use of these default settings on hardware jumpers will allow the user complete installation by invoking the Build menu's Space selection, followed by the Build menu's Build selection. This will allow a complete software installation with only 8 keystrokes and will require less than 5 minutes. neinstall creates /etc/conf/ne/Space.c and calls the system scripts to enable the driver and build a kernel. It also creates the device special files. A successful installation of hardware and software will result in a boot time banner that tells the ethernet address of the hardware. ---- Technical stuff: Upon boot up, the driver tests for the existance of an NE compatible ethernet card at 0x300. The driver is able to automatically determine whether the card is an 8 bit NE1000 compatible or a 16 bit NE2000 compatible board. If a working card is found the ethernet address will be extracted and announced in the boot up messages. However, interrupts on the card will remain disabled until the card is 'opened'. read(), write() and poll(): The ne device driver deals with data in complete ethernet packets only. That is, the sending software must supply a packet suitable for sending on ethernet, complete with a source and destination address and protocol descriptor. The sent packet must be at least 64 bytes long and no more than 1500 bytes long, including all headers. It must be contiguous .. that is, it cannot be scattered about memory in various mbufs or similar fragments. The fragments must be gathered into a single buffer for the call to write(). The following is an ethernet header as defined in neioctl.h: struct ether_header { unsigned char ether_dhost[6]; unsigned char ether_shost[6]; unsigned short ether_type; }; ether_dhost is a 6 byte ethernet address for the destination machine. ether_shost is a 6 byte ethernet address for the source machine. ether_type is the protocol descriptor that tells the protocol software how to process the packet. A packet is transmited by using write() and received packets are collected by read(). Poll is supported for data recieved and space available for outgoing data. No priority polls are available. There is a watchdog timeout mechanism, so be sure to check the return values of both read and write because it is quite possible for a timeout to occur on a loaded network. The user buffer into which a received packet is collected should be no less than 1536 bytes and the read should always ask for 1536 bytes. read() will return the actual number of bytes transfered to the user buffer which will always be the contents of 1 full packet including the ethernet header. ne does not demultiplex packets, therefore, it should be used with only one protocol suite at a time unless arrangements are made to demulitplex packets based on protocol descriptors. ioctl() calls: The constants and structs for ioctls for ne are listed in neioctl.h. /* ioctl commands */ struct arpcom { unsigned char ac_enaddr[6]; unsigned short if_flags; char *acc_if; }; NEIOCGFLAGS is used to get the flags and NEIOCSFLAGS is used to set the flags. These flags control "promiscous" mode for the ethernet driver. If you set it to promiscous mode, it will receive all ethernet packets on the network no matter who they are addressed to. This is useful for network monitoring and gateway systems. In non-promiscous mode, only packets addressed to this ethernet controller and broadcast packets are received. The following code fragment illustrates turning off promiscous mode. struct arpcom myaprcom; /* get flags */ ioctl( fd, NEIOCGFLAGS, &myarpcom ); /* turn off promiscous bit */ myarpcom.if_flags &= ~IFF_PROMISC; /* set flags */ ioctl( fd, NEIOCSFLAGS, &myarpcom ); The NEIOCGSTATS command is used to retreive a copy of the statistics kept by the driver for each board. The struct nestats is used as the third argument to the ioctl(). The following code fragment illustrates the method for getting statistics from the device driver: struct nestats mynestats; /* download the stats */ ioctl( fd, NEIOCGSTATS, &mynestats ); /* display them */ printf( "number of collisions : %d\n", mynestats.nestat_collisions ); printf( "number of xmit errors : %d\n", mynestats.nestat_oerrors ); printf( "number of recv errors : %d\n", mynestats.nestat_ierrors ); printf( "xmitted packets : %d\n", mynestats.nestat_opackets ); printf( "recv'd packets : %d\n", mynestats.nestat_ipackets ); printf( "incoming packets discarded : %d\n", mynestats.nestat_idiscards ); printf( "xmit buffer supply : %d\n", mystats.nestat_lox); printf( "recv buffer supply : %d\n", mystats.nestat_lor); Note: "nestat_lox" and "nestat_lor" are used to determine how well the buffering is working. These values are the lowest number available packet buffers since the last call to this ioctl. If the value is equal to the number of buffers (default is 16), then the device driver has not had to dip into its buffer cache in order to handle the traffic. If the value is equal to low-water as returned by the next ioctl() the driver is in danger of buffer starvation. "nestat_lox" and "nestat_lor" are both reset to the number of buffer in the cache when this ioctl() is called, so the value returned is a reflection of what has occured since the last call to this ioctl(). NEIOCGLOWWAT and NEIOCSLOWWAT are used to get and set the low water figure used in send buffer flow control. The third argument in the ioctl is a neattr_t which is currently defined as an int. To understand how ne performs flow control, you need to realize that ne uses fixed length, static buffers and avoids turning off interrupts while transfering data from the user area into the transmit queue. This is because the hardware has only a single transmit buffer. The low water maker is in terms of packets, not bytes. It should be no less than 2, in order to keep from overwriting the buffer that is currently being loaded into the tranmitter, however, in some circumstances, the protocol software can queue up a number of packets for tranmission faster than the hardware can send packets. In this case, the low water mark can be set to a greater level. It represents the minimum number of available transmission buffers before more packets will be accepted via a write() call. Most users will never need to use this feature. ------- Modifying the source code: A competent device driver programmer will be able to easily alter the ne.c source code file to do such things as increase or decrease the number of static packet buffers or the number of cards supported. A device driver on a gateway between networks of radically different speeds or loads may benefit from substantially increased numbers of packet buffers. Since static buffers use ram whther a card is present or not, it is wise to change the source code to reflect the real number of cards present if a large amount of buffering is to be used. -------