From 26d34b178484d99243173b6ec800cc0ac3d3be69 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 30 Sep 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-09-30 --- mpc/clock.c | 8 +++- mpc/devpcmcia.c | 1 + mpc/etherwavelan.c | 50 ++++++++++++++-------- mpc/fns.h | 1 + mpc/main.c | 6 ++- port/devbridge.c | 3 +- port/devsdp.c | 102 ++++++++++++++++++++++++++------------------- 7 files changed, 106 insertions(+), 65 deletions(-) diff --git a/mpc/clock.c b/mpc/clock.c index 8dc254f0c37079edbcf9260e57d38585940b0ebc..7d7264956a0032b6c94216e8032c2d787d3bd275 100644 --- a/mpc/clock.c +++ b/mpc/clock.c @@ -68,7 +68,7 @@ enum { static ulong clkreload; void -clockinit(void) +delayloopinit(void) { long x, est; @@ -86,6 +86,12 @@ clockinit(void) m->delayloop = (m->delayloop*est/Timebase)/(x); if(m->delayloop == 0) m->delayloop = 1; +} + +void +clockinit(void) +{ + delayloopinit(); clkreload = (m->clockgen/Timebase)/HZ-1; putdec(clkreload); diff --git a/mpc/devpcmcia.c b/mpc/devpcmcia.c index 3849eeae6579f5398c65a5eb94259503ad1e500c..269c1598179726fb91d91211b52fb5aca432a7d1 100644 --- a/mpc/devpcmcia.c +++ b/mpc/devpcmcia.c @@ -601,6 +601,7 @@ pcmio(int slotno, ISAConf *isa) // setup io space - this could be better io->pcmr[1].base = ISAMEM+isa->port; x = (0x6<<27) | (2<<16) | (4<<12) | (8<<7) | Rio | Rvalid; +// x = (0x6<<27) | (8<<16) | (6<<12) | (24<<7) | Rio | Rvalid; /* 16-bit data path */ if(ct->bit16) x |= Rport16; diff --git a/mpc/etherwavelan.c b/mpc/etherwavelan.c index 2a8954fbde2ece98af73da3c86ed1c0c95d720dd..03b2d9dafc4e515e8c080c774a9e2af924cea724 100644 --- a/mpc/etherwavelan.c +++ b/mpc/etherwavelan.c @@ -252,6 +252,31 @@ mmc_in(int base, uchar o) return((uchar) (inb(MMD(base)))); } +/* + * a standard insb causes the wavelan card to not be able + * to simultanisouly receive a packet out of the ether. + * It appears that the card runs out of bandwidth to it's + * internal memory + */ +void +slowinsb(int port, void *buf, int len) +{ + int i, j, n; + uchar *p, *q; + + p = (uchar*)(port + ISAMEM); + q = buf; + n = m->delayloop/2000; + if(n == 0) + n = 1; + for(i = 0; i < len; i++){ + *q++ = *p; + // a small delay of about .5micro seconds + for(j=0; jctlr; base = ctlr->port; -print("read_ringbuf\n"); /* If buf is NULL, just increment the ring buffer pointer */ if (buf == 0) @@ -270,16 +294,13 @@ print("read_ringbuf\n"); /* Position the Program I/O Register at the ring buffer pointer */ outb(PIORL(base), ring_ptr & 0xff); outb(PIORH(base), ((ring_ptr >> 8) & PIORH_MASK)); - delay(1); /* First, determine how much we can read without wrapping around the ring buffer */ if ((ring_ptr + len) < (RX_BASE + RX_SIZE)) chunk_len = len; else chunk_len = RX_BASE + RX_SIZE - ring_ptr; - if(chunk_len > 256) - chunk_len = 256; - insb(PIOP(base), buf_ptr, chunk_len); + slowinsb(PIOP(base), buf_ptr, chunk_len); buf_ptr += chunk_len; len -= chunk_len; ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE; @@ -296,8 +317,6 @@ wavelan_hardware_send_packet(Ether *ether, void *buf, short length) ctlr = ether->ctlr; base = ctlr->port; -print("%ld: send packet %d\n", m->ticks, length); - outb(PIORL(base), xmtdata_base & 0xff); outb(PIORH(base), ((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX); outb(PIOP(base), length & 0xff); /* lsb */ @@ -408,8 +427,6 @@ static void wavelan_read(Ether *ether, int fd_p, int sksize) ctlr->rx_dropped++; return; } else { -//print("%d+%d = %d\n", fd_p, sksize, fd_p+sksize); -//delay(100); fd_p = read_ringbuf(ether, fd_p, ctlr->rbp->rp, sksize); ctlr->rbp->wp = ctlr->rbp->rp + sksize; /* read signal level, silence level and signal quality bytes */ @@ -476,8 +493,7 @@ if(0) print("before wavelan_cs: i593_rfp %d stop %d newrfp %d ctlr->rfp %d\n", i status = c[0] | (c[1] << 8); len = c[2] | (c[3] << 8); -print("%ld: len = %d status = %ux %ux %ux\n", m->ticks, len, status, newrfp, rp); -//delay(100); +if(0) print("%ld: len = %d status = %ux %ux %ux\n", m->ticks, len, status, newrfp, rp); if(!(status & RX_RCV_OK)) { if(status & RX_NO_SFD) ctlr->rx_no_sfd++; @@ -496,19 +512,19 @@ print("%ld: len = %d status = %ux %ux %ux\n", m->ticks, len, status, newrfp, rp) * per packet. */ ctlr->stop = (i593_rfp + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE; -//print("ctlr->stop = %ux\n", ctlr->stop); outb(LCCR(base), OP0_SWIT_TO_PORT_1 | CR0_CHNL); outb(LCCR(base), CR1_STOP_REG_UPDATE | (ctlr->stop >> RX_SIZE_SHIFT)); outb(LCCR(base), OP1_SWIT_TO_PORT_0); -//delay(100); - +if(0){ newrfp = inb(RPLL(base)); newrfp |= inb(RPLH(base)) << 8; newrfp %= RX_SIZE; -if(newrfp != ctlr->rfp) -print("after wavelan_cs: left over = %d\n", (newrfp - ctlr->rfp + RX_SIZE) % RX_SIZE); + if(newrfp != ctlr->rfp) + print("after wavelan_cs: left over = %d\n", (newrfp - ctlr->rfp + RX_SIZE) % RX_SIZE); +} + return 1; } /* wavelan_receive */ @@ -529,8 +545,6 @@ interrupt(Ureg*, void* arg) outb(LCCR(base), CR0_STATUS_0 | OP0_NOP); interrupt_handler(ether, inb(LCSR(base))); -outb(LCCR(base), CR0_STATUS_0 | OP0_NOP); -print("status = %ux\n", inb(LCSR(base))); iunlock(&ctlr->wlock); }; /* wavelan interrupt */ diff --git a/mpc/fns.h b/mpc/fns.h index 48becbc79a6f2a6d48a2387cd537ba090746c841..528b66705be777dce38d5c8ff94dcd3cac08f858 100644 --- a/mpc/fns.h +++ b/mpc/fns.h @@ -19,6 +19,7 @@ void delay(int); ulong draminit(ulong*); void dtlbmiss(void); void dumpregs(Ureg*); +void delayloopinit(void); void eieio(void); //#define eieio() void evenaddr(ulong); diff --git a/mpc/main.c b/mpc/main.c index 8d55bcf762031f8f73d6dac9addbc830b87c70e0..fc75d5a7e6c0383aad78d7e7cf574b5acf79fe25 100644 --- a/mpc/main.c +++ b/mpc/main.c @@ -43,6 +43,10 @@ main(void) // turn on pcmcia *(uchar*)(NVRAMMEM+0x100001) |= 0x60; +print("m->delayloop = %ld\n", m->delayloop); + delayloopinit(); +print("m->delayloop = %ld\n", m->delayloop); + pageinit(); procinit0(); initseg(); @@ -95,8 +99,6 @@ init0(void) up->nerrlab = 0; -print("spllo = %ux\n", spllo()); - /* * These are o.k. because rootinit is null. * Then early kproc's will have a root and dot. diff --git a/port/devbridge.c b/port/devbridge.c index 0c1324382e7e4dd88bf8c6a177d5ebdfc8b82595..248f1bb494e8fc55bc8b62c05d4861fce2bb7c92 100644 --- a/port/devbridge.c +++ b/port/devbridge.c @@ -981,8 +981,7 @@ if(0)print("devbridge: etherread: reading\n"); if(0)print("devbridge: etherread: blocklen = %d\n", blocklen(bp)); poperror(); qlock(b); - - if(port->closed) + if(bp == nil || port->closed) break; if(waserror()) { print("etherread bridge error\n"); diff --git a/port/devsdp.c b/port/devsdp.c index 8bdaf5d83f30ba146df38e4bda3baee5b924e3c2..56a8a078f527551c7605014533ec51259bf1ef65 100644 --- a/port/devsdp.c +++ b/port/devsdp.c @@ -489,7 +489,6 @@ print("readcontrol asked %ld got %ld\n", n, BLEN(b)); freeb(b); return n; case Qdata: -print("readdata\n"); b = readdata(sdp->conv[CONV(ch->qid)], n); if(b == nil) return 0; @@ -916,7 +915,6 @@ convstats(Conv *c, int local, char *buf, int n) Stats *stats; char *p, *ep; - qlock(c); if(local) { stats = &c->lstats; } else { @@ -926,6 +924,8 @@ convstats(Conv *c, int local, char *buf, int n) } stats = &c->rstats; } + + qlock(c); p = buf; ep = buf + n; p += snprint(p, ep-p, "outPackets: %ld\n", stats->outPackets); @@ -934,6 +934,7 @@ convstats(Conv *c, int local, char *buf, int n) p += snprint(p, ep-p, "outCompDataBytes: %ld\n", stats->outCompDataBytes); p += snprint(p, ep-p, "inPackets: %ld\n", stats->inPackets); p += snprint(p, ep-p, "inDataPackets: %ld\n", stats->inDataPackets); + p += snprint(p, ep-p, "inDataBytes: %ld\n", stats->inDataBytes); p += snprint(p, ep-p, "inCompDataBytes: %ld\n", stats->inCompDataBytes); p += snprint(p, ep-p, "inMissing: %ld\n", stats->inMissing); p += snprint(p, ep-p, "inDup: %ld\n", stats->inDup); @@ -953,7 +954,7 @@ convack(Conv *c) Stats *s; b = allocb(sizeof(AckPkt)); - ack = (Ack)b->wp; + ack = (AckPkt*)b->wp; b->wp += sizeof(AckPkt); s = &c->lstats; hnputl(ack->cseq, c->in.controlseq); @@ -982,7 +983,7 @@ conviput(Conv *c, Block *b, int control) ulong seq, cseq; AckPkt *ack; - c->lstat.inPackets++; + c->lstats.inPackets++; if(BLEN(b) < 4) { freeb(b); @@ -999,7 +1000,7 @@ conviput(Conv *c, Block *b, int control) b->rp += 4; USED(seq); -print("coniput seq=%ulx\n", seq); +if(0) print("coniput seq=%ulx\n", seq); // auth // decrypt @@ -1029,7 +1030,7 @@ print("duplicate control packet: %ulx\n", cseq); convack(c); } else { c->in.controlpkt = b; -print("recv %ld size=%ld\n", cseq, BLEN(b)); +if(0) print("recv %ld size=%ld\n", cseq, BLEN(b)); wakeup(&c->in.controlready); } return nil; @@ -1038,22 +1039,23 @@ print("recv %ld size=%ld\n", cseq, BLEN(b)); break; ack = (AckPkt*)(b->rp); cseq = nhgetl(ack->cseq); + if(cseq != c->out.controlseq) { print("ControlAck expected %ulx got %ulx\n", c->out.controlseq, cseq); - if(cseq != c->out.controlseq) break; - c->rstat.outPackets = nhgetl(ack->outPackets); - c->rstat.outDataPackets = nhgetl(ack->outDataPackets); - c->rstat.outDataBytes = nhgetl(ack->outDataBytes); - c->rstat.outCompDataBytes = nhgetl(ack->outCompDataBytes); - c->rstat.inPackets = nhgetl(ack->inPackets); - c->rstat.inDataPackets = nhgetl(ack->inDataPackets); - c->rstat.inDataBytes = nhgetl(ack->inDataBytes); - c->rstat.inCompDataBytes = nhgetl(ack->inCompDataBytes); - c->rstat.inMissing = nhgetl(ack->inMissing); - c->rstat.inDup = nhgetl(ack->inDup); - c->rstat.inReorder = nhgetl(ack->inReorder); - c->rstat.inBadAuth = nhgetl(ack->inBadAuth); - c->rstat.inBadSeq = nhgetl(ack->inBadSeq); + } + c->rstats.outPackets = nhgetl(ack->outPackets); + c->rstats.outDataPackets = nhgetl(ack->outDataPackets); + c->rstats.outDataBytes = nhgetl(ack->outDataBytes); + c->rstats.outCompDataBytes = nhgetl(ack->outCompDataBytes); + c->rstats.inPackets = nhgetl(ack->inPackets); + c->rstats.inDataPackets = nhgetl(ack->inDataPackets); + c->rstats.inDataBytes = nhgetl(ack->inDataBytes); + c->rstats.inCompDataBytes = nhgetl(ack->inCompDataBytes); + c->rstats.inMissing = nhgetl(ack->inMissing); + c->rstats.inDup = nhgetl(ack->inDup); + c->rstats.inReorder = nhgetl(ack->inReorder); + c->rstats.inBadAuth = nhgetl(ack->inBadAuth); + c->rstats.inBadSeq = nhgetl(ack->inBadSeq); freeb(b); freeb(c->out.controlpkt); c->out.controlpkt = nil; @@ -1182,6 +1184,23 @@ print("invalid conviput2 - sending reset\n"); convoput2(c, ConReset, dialid, acceptid); } +// c is locked +static void +convwriteblock(Conv *c, Block *b) +{ + // simulated errors + if(c->drop && c->drop > nrand(c->drop)) + return; + + if(waserror()) { + convsetstate(c, CClosed); + nexterror(); + } + devtab[c->chan->type]->bwrite(c->chan, b, 0); + poperror(); +} + + // assume hold conv lock static void convoput(Conv *c, int type, Block *b) @@ -1202,35 +1221,31 @@ convoput(Conv *c, int type, Block *b) // encrypt // auth - - // simulated errors - if(c->drop && c->drop > nrand(c->drop)) - return; -print("convoput\n"); - devtab[c->chan->type]->bwrite(c->chan, b, 0); + + convwriteblock(c, b); } // assume hold conv lock static void convoput2(Conv *c, int op, ulong dialid, ulong acceptid) { - ConnectPkt con; + Block *b; + ConnectPkt *con; c->lstats.outPackets++; if(c->chan == nil) { print("chan = nil\n"); error("no channel attached"); } - memset(&con, 0, sizeof(con)); - con.type = TConnect; - con.op = op; - hnputl(con.dialid, dialid); - hnputl(con.acceptid, acceptid); - - // simulated errors - if(c->drop && c->drop > nrand(c->drop)) - return; - devtab[c->chan->type]->write(c->chan, &con, sizeof(con), 0); + b = allocb(sizeof(ConnectPkt)); + con = (ConnectPkt*)b->wp; + b->wp += sizeof(ConnectPkt); + con->type = TConnect; + con->op = op; + hnputl(con->dialid, dialid); + hnputl(con->acceptid, acceptid); + + convwriteblock(c, b); } static Block * @@ -1375,8 +1390,10 @@ writecontrol(Conv *c, void *p, int n, int wait) convretryinit(c); print("send %ld size=%ld\n", c->out.controlseq, BLEN(b)); convoput(c, TControl, copyblock(b, blocklen(b))); - if(wait) + if(wait) { +print("writecontrol wait!\n"); writewait(c); + } poperror(); qunlock(c); qunlock(&c->out.controllk); @@ -1389,6 +1406,8 @@ readdata(Conv *c, int n) for(;;) { b = convreadblock(c, n); + if(b == nil) + return nil; qlock(c); if(waserror()) { qunlock(c); @@ -1408,7 +1427,6 @@ writedata(Conv *c, Block *b) int n; qlock(c); -print("writedata %ulx state=%s\n", b, convstatename[c->state]); if(waserror()) { qunlock(c); nexterror(); @@ -1420,9 +1438,9 @@ print("writedata %ulx state=%s\n", b, convstatename[c->state]); } n = BLEN(b); - c->outDataPackets++; - c->outDataBytes += n; - c->outCompDataBytes += n; + c->lstats.outDataPackets++; + c->lstats.outDataBytes += n; + c->lstats.outCompDataBytes += n; convoput(c, TData, b); poperror(); qunlock(c);