| plan 9 kernel history: overview | file list | diff list |
1992/0407/pc/devether.c (diff list | history)
| 1992/0406/sys/src/9/pc/devether.c:7,12 – 1992/0407/sys/src/9/pc/devether.c:7,13 (short | long | prev | next) | ||
| 1992/0406 | * output * deal with stalling and restarting output on input overflow * fix magic ring constants | |
| 1992/0407 | * rewrite per SMC doc | |
| 1992/0403 | */ #include "u.h" #include "../port/lib.h" | |
| 1992/0406/sys/src/9/pc/devether.c:79,85 – 1992/0407/sys/src/9/pc/devether.c:80,87 | ||
| 1992/0404 | struct Ring { uchar status; uchar next; | |
| 1992/0407 | uchar len0; uchar len1; | |
| 1992/0404 | uchar data[BUFsize-4]; | |
| 1992/0403 | }; | |
| 1992/0406/sys/src/9/pc/devether.c:101,114 – 1992/0407/sys/src/9/pc/devether.c:103,119 | ||
| 1992/0403 | struct Ctlr { QLock; | |
| 1992/0407 | Ring *ring; | |
| 1992/0403 | Rendez rr; /* rendezvous for an input buffer */ | |
| 1992/0407 | Queue rq; | |
| 1992/0404 | uchar bnry; uchar curr; uchar ovw; | |
| 1992/0403 |
| |
| 1992/0407 | Etherpkt *xpkt; | |
| 1992/0404 | QLock xl; | |
| 1992/0403 | Rendez xr; | |
| 1992/0407 | uchar xbusy; | |
| 1992/0403 | int iobase; /* I/O base address */ | |
| 1992/0406/sys/src/9/pc/devether.c:132,137 – 1992/0407/sys/src/9/pc/devether.c:137,150 | ||
| 1992/0403 | }; static Ctlr ctlr[Nctlr]; | |
| 1992/0407 | static int isxfree(void *arg) { Ctlr *cp = arg; return cp->xbusy == 0 && cp->ovw == 0; } | |
| 1992/0403 | static void etheroput(Queue *q, Block *bp) { | |
| 1992/0406/sys/src/9/pc/devether.c:184,205 – 1992/0407/sys/src/9/pc/devether.c:197,216 | ||
| 1992/0403 | } } | |
| 1992/0406 |
| |
| 1992/0403 | /* * only one transmitter at a time */ | |
| 1992/0407 | qlock(&cp->xl); | |
| 1992/0403 | if(waserror()){ | |
| 1992/0407 | qunlock(&cp->xl); | |
| 1992/0403 | nexterror(); } /* | |
| 1992/0407 | * Wait till we get an output buffer | |
| 1992/0403 | */ | |
| 1992/0407 | sleep(&cp->xr, isxfree, cp); p = cp->xpkt; | |
| 1992/0403 | /* * copy message into buffer | |
| 1992/0406/sys/src/9/pc/devether.c:216,253 – 1992/0407/sys/src/9/pc/devether.c:227,255 | ||
| 1992/0403 | } /* | |
| 1992/0407 | * pad the packet (zero the pad) | |
| 1992/0403 | */ if(len < ETHERMINTU){ memset(((char*)p)+len, 0, ETHERMINTU-len); len = ETHERMINTU; } | |
| 1992/0407 | * give packet a local address | |
| 1992/0403 | */ | |
| 1992/0407 | memmove(p->s, cp->ea, sizeof(cp->ea)); | |
| 1992/0403 | /* | |
| 1992/0407 | * start the transmission | |
| 1992/0403 | */ | |
| 1992/0407 | outb(cp->iobase+Tbcr0, len & 0xFF); outb(cp->iobase+Tbcr1, (len>>8) & 0xFF); outb(cp->iobase+Cr, 0x26); /* Page0|TXP|STA */ cp->xbusy = 1; | |
| 1992/0403 |
| |
| 1992/0407 | qunlock(&cp->xl); | |
| 1992/0403 | poperror(); | |
| 1992/0404 |
| |
| 1992/0403 | } /* | |
| 1992/0406/sys/src/9/pc/devether.c:370,376 – 1992/0407/sys/src/9/pc/devether.c:372,379 | ||
| 1992/0404 | if(isr & Ptx) cp->outpackets++; if(isr & (Txe|Ptx)){ | |
| 1992/0407 | cp->xbusy = 0; wakeup(&cp->xr); | |
| 1992/0404 | } /* * the receive ring is full. | |
| 1992/0406/sys/src/9/pc/devether.c:422,427 – 1992/0407/sys/src/9/pc/devether.c:425,431 | ||
| 1992/0404 | outb(cp->iobase+Tcr, 0x20); /* LB0 */ outb(cp->iobase+Bnry, 6); cp->bnry = 6; | |
| 1992/0407 | cp->ring = (Ring*)(KZERO|RAMbase); | |
| 1992/0404 | outb(cp->iobase+Pstart, 6); /* 6*256 */ outb(cp->iobase+Pstop, 32); /* 8*1024/256 */ outb(cp->iobase+Isr, 0xFF); | |
| 1992/0406/sys/src/9/pc/devether.c:435,440 – 1992/0407/sys/src/9/pc/devether.c:439,445 | ||
| 1992/0404 | outb(cp->iobase+Cr, 0x22); /* Page0, RD2|STA */ outb(cp->iobase+Tpsr, 0); | |
| 1992/0407 | cp->xpkt = (Etherpkt*)(KZERO|RAMbase); | |
| 1992/0403 | } void | |
| 1992/0406/sys/src/9/pc/devether.c:556,569 – 1992/0407/sys/src/9/pc/devether.c:561,573 | ||
| 1992/0406 | /* * process any received packets */ | |
| 1992/0407 | cp->bnry = inb(cp->iobase+Bnry); while(cp->bnry != cp->curr){ rp = &cp->ring[cp->bnry]; | |
| 1992/0406 | cp->inpackets++; | |
| 1992/0407 | etherup(cp, (Etherpkt*)rp->data, ((rp->len1<<8)+rp->len0)-4); cp->bnry = rp->next; outb(cp->iobase+Bnry, cp->bnry); | |
| 1992/0406 | } /* * if we idled input because of overflow, | |
| 1992/0406/sys/src/9/pc/devether.c:572,577 – 1992/0407/sys/src/9/pc/devether.c:576,582 | ||
| 1992/0406 | if(cp->ovw){ cp->ovw = 0; outb(cp->iobase+Tcr, 0); | |
| 1992/0407 | wakeup(&cp->xr); | |
| 1992/0406 | } | |
| 1992/0403 | } } | |