static void txstart(Ether* ether) { int port; Smc91xx* ctlr; Block* bp; int len, npages; int pno; /* assumes ctlr is locked and bank 2 is selected */ /* leaves bank 2 selected on return */ port = ether->port; ctlr = ether->ctlr; if (ctlr->txbp) { bp = ctlr->txbp; ctlr->txbp = 0; } else { bp = qget(ether->oq); if (bp == 0) return; len = BLEN(bp); npages = (len + HdrSize) / PageSize; outs(port + MmuCmd, McAlloc | npages); } pno = inb(port + AllocRes); if (pno & ArFailed) { outb(port + IntrMask, inb(port + IntrMask) | IntAlloc); ctlr->txbp = bp; ctlr->txtime = MACHP(0)->ticks; return; } outb(port + PktNo, pno); outs(port + Pointer, PtrAutoInc); len = BLEN(bp); outs(port + Data1, 0); outb(port + Data1, (len + HdrSize) & 0xFF); outb(port + Data1, (len + HdrSize) >> 8); outss(port + Data1, bp->rp, len / 2); if ((len & 1) == 0) { outs(port + Data1, 0); } else { outb(port + Data1, bp->rp[len - 1]); outb(port + Data1, 0x20); /* no info what 0x20 means */ } outb(port + IntrMask, inb(port + IntrMask) | IntTxError | IntTxEmpty); outs(port + MmuCmd, McEnqueue); freeb(bp); }
static void csr_outss(Ctlr *ctlr, int reg, void *dat, int ndat) { ushort *rp, *wp; if(ctlr->mmb){ rp = dat; wp = &ctlr->mmb[reg]; while(ndat-- > 0) *wp = *rp++; }else outss(ctlr->iob+reg, dat, ndat); }