M mpc/clock.c => mpc/clock.c +7 -1
@@ 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);
M mpc/devpcmcia.c => mpc/devpcmcia.c +1 -0
@@ 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;
M mpc/etherwavelan.c => mpc/etherwavelan.c +32 -18
@@ 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; j<n; j++)
+ ;
+ }
+}
+
static int
read_ringbuf(Ether *ether, int addr, uchar *buf, int len)
{ Ctlr *ctlr;
@@ 261,7 286,6 @@ read_ringbuf(Ether *ether, int addr, uchar *buf, int len)
uchar *buf_ptr = buf;
ctlr = ether->ctlr;
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 */
M mpc/fns.h => mpc/fns.h +1 -0
@@ 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);
M mpc/main.c => mpc/main.c +4 -2
@@ 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.
M port/devbridge.c => port/devbridge.c +1 -2
@@ 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");
M port/devsdp.c => port/devsdp.c +60 -42
@@ 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);