M gnot/dat.h => gnot/dat.h +1 -0
@@ 105,6 105,7 @@ struct Conf
int copymode; /* 0 is copy on write, 1 is copy on reference */
int portispaged; /* ??? */
int cntrlp; /* panic on ^P */
+ int dkif; /* number of datakit interfaces */
};
#include "../port/portdat.h"
M gnot/main.c => gnot/main.c +1 -0
@@ 278,6 278,7 @@ confinit(void)
conf.copymode = 0; /* copy on write */
conf.portispaged = 0;
conf.cntrlp = 0;
+ conf.dkif = 2;
}
/*
M pc/dat.h => pc/dat.h +1 -0
@@ 93,6 93,7 @@ struct Conf
ulong cntrlp; /* panic on ^P */
ulong nfloppy; /* number of floppy drives */
ulong nhard; /* number of hard drives */
+ int dkif; /* number of datakit interfaces */
};
/*
M pc/main.c => pc/main.c +2 -0
@@ 19,6 19,7 @@ main(void)
confinit();
screeninit();
printinit();
+crdump();
print("%ludK bytes of physical memory\n", (conf.base1 + conf.npage1*BY2PG)/1024);
mmuinit();
trapinit();
@@ 225,6 226,7 @@ confinit(void)
conf.cntrlp = 0;
conf.nfloppy = 1;
conf.nhard = 1;
+ conf.dkif = 1;
}
char *mathmsg[] =
M pc/vga.c => pc/vga.c +11 -0
@@ 89,6 89,17 @@ crout(int reg, int val)
outb(CRX, reg);
outb(CR, val);
}
+crdump(void)
+{
+ uchar x;
+ int i;
+
+ for(i = 0; i < 0x16; i++){
+ outb(CRX, i);
+ x = inb(CR);
+ print("cr[0x%lux] = %ux\n", i, x);
+ }
+}
/*
* m is a bit mask of planes to be affected by CPU writes
M port/chan.c => port/chan.c +5 -0
@@ 647,10 647,15 @@ char isfrog[]={
void
nameok(char *elem)
{
+ char *eelem;
+
+ eelem = elem+NAMELEN;
while(*elem) {
if((*elem&0x80) || isfrog[*elem])
error(Ebadchar);
elem++;
+ if(elem >= eelem)
+ error(Efilename);
}
}
M port/devdk.c => port/devdk.c +73 -47
@@ 12,11 12,6 @@
enum {
/*
- * configuration parameters
- */
- Ndk = 2, /* max dks */
-
- /*
* relative or immutable
*/
Nline = 256, /* max lines per dk */
@@ 97,6 92,7 @@ struct Dkmsg {
*/
struct Line {
QLock;
+ int lineno;
Rendez r; /* wait here for dial */
int state; /* dial state */
int err; /* dialing error (if non zero) */
@@ 107,7 103,6 @@ struct Line {
char addr[64];
char raddr[64];
char ruser[32];
- char other[64];
Dk *dp; /* interface contianing this line */
};
@@ 124,14 119,16 @@ struct Dk {
int lines; /* number of lines */
int ncsc; /* csc line number */
Chan *csc;
- Line line[Nline];
+ Line **linep;
int restart;
int urpwindow;
Rendez timer;
int closeall; /* set when we receive a closeall message */
Rendez closeallr; /* wait here for a closeall */
+
+ Block *alloc;
};
-static Dk dk[Ndk];
+static Dk *dk;
static Lock dklock;
/*
@@ 217,14 214,16 @@ Qinfo dkmuxinfo =
* Look for a dk struct with a name. If none exists, create one.
*/
static Dk *
-dkalloc(char *name)
+dkalloc(char *name, int ncsc, int lines)
{
Dk *dp;
Dk *freep;
+ Block *bp;
+ int i, n;
lock(&dklock);
freep = 0;
- for(dp = dk; dp < &dk[Ndk]; dp++){
+ for(dp = dk; dp < &dk[conf.dkif]; dp++){
if(strcmp(name, dp->name) == 0){
unlock(&dklock);
return dp;
@@ 236,11 235,42 @@ dkalloc(char *name)
unlock(&dklock);
error(Enoifc);
}
+ if(lines == 0)
+ errors("unknown dk interface");
+
+ /*
+ * init the structures
+ */
dp = freep;
dp->opened = 0;
dp->s = 0;
- dp->ncsc = 1;
+ dp->ncsc = ncsc;
+ dp->lines = lines;
strncpy(dp->name, name, sizeof(freep->name));
+
+ /*
+ * allocate memory for line structures
+ */
+ n = sizeof(Line*)*dp->lines;
+ bp = allocb(n);
+ if(bp->lim - bp->base < n){
+ unlock(&dklock);
+ errors("too many lines");
+ }
+ dp->linep = (Line **)bp->base;
+ bp->wptr += n;
+ dp->alloc = bp;
+ for(i = 0; i < n; i++){
+ if(bp->lim - bp->wptr < sizeof(Line)){
+ bp = allocb(sizeof(Line)*n);
+ bp->next = dp->alloc;
+ dp->alloc = bp;
+ }
+ dp->linep[i] = (Line*)bp->wptr;
+ dp->linep[i]->lineno = i;
+ bp->wptr += sizeof(Line);
+ }
+
unlock(&dklock);
return dp;
}
@@ 281,7 311,7 @@ dkmuxclose(Queue *q)
* hang up all datakit connections
*/
for(i=dp->ncsc; i < dp->lines; i++)
- dkhangup(&dp->line[i]);
+ dkhangup(dp->linep[i]);
/*
* wakeup the timer so it can die
@@ 344,7 374,7 @@ dkmuxiput(Queue *q, Block *bp)
return;
}
- lp = &dp->line[line];
+ lp = dp->linep[line];
if(canqlock(lp)){
if(lp->rq)
PUTNEXT(lp->rq, bp);
@@ 385,7 415,7 @@ dkstopen(Queue *q, Stream *s)
Line *lp;
dp = &dk[s->dev];
- q->other->ptr = q->ptr = lp = &dp->line[s->id];
+ q->other->ptr = q->ptr = lp = dp->linep[s->id];
lp->dp = dp;
lock(dp);
if(dp->opened==0 || streamenter(dp->s)<0){
@@ 449,22 479,22 @@ dkstclose(Queue *q)
*/
switch(lp->state){
case Lrclose:
- dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0);
+ dkmesg(c, T_CHG, D_CLOSE, lp->lineno, 0);
lp->state = Lclosed;
break;
case Lackwait:
- dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0);
+ dkmesg(c, T_CHG, D_CLOSE, lp->lineno, 0);
lp->state = Llclose;
break;
case Llistening:
- dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0);
+ dkmesg(c, T_CHG, D_CLOSE, lp->lineno, 0);
lp->state = Llclose;
break;
case Lconnected:
- dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0);
+ dkmesg(c, T_CHG, D_CLOSE, lp->lineno, 0);
lp->state = Llclose;
break;
}
@@ 506,7 536,7 @@ dkoput(Queue *q, Block *bp)
lp = (Line *)q->ptr;
dp = lp->dp;
- line = lp - dp->line;
+ line = lp->lineno;
bp = padb(bp, 2);
bp->rptr[0] = line;
@@ 590,14 620,12 @@ dkmuxconfig(Queue *q, Block *bp)
/*
* set up
*/
- dp = dkalloc(name);
+ dp = dkalloc(name, ncsc, lines);
lock(dp);
if(dp->opened){
unlock(dp);
error(Ebadarg);
}
- dp->ncsc = ncsc;
- dp->lines = lines;
dp->restart = restart;
dp->urpwindow = window;
dp->s = RD(q)->ptr;
@@ 649,7 677,6 @@ enum {
Dlistenqid,
Draddrqid,
Duserqid,
- Dotherqid,
Dlineqid,
/*
@@ 669,7 696,6 @@ Dirtab dkdir[Ndir];
Dirtab dksubdir[]={
"addr", {Daddrqid}, 0, 0600,
"listen", {Dlistenqid}, 0, 0600,
- "other", {Dotherqid}, 0, 0600,
"raddr", {Draddrqid}, 0, 0600,
"ruser", {Duserqid}, 0, 0600,
};
@@ 681,6 707,7 @@ Dirtab dksubdir[]={
void
dkreset(void)
{
+ dk = (Dk*)ialloc(conf.dkif*sizeof(Dk), 0);
newqinfo(&dkmuxinfo);
}
@@ 728,7 755,7 @@ dkattach(char *spec)
*/
if(*spec == 0)
spec = "dk";
- dp = dkalloc(spec);
+ dp = dkalloc(spec, 0, 0);
/*
* return the new channel
@@ 778,7 805,7 @@ dkopen(Chan *c, int omode)
{
extern Qinfo dkinfo;
Stream *s;
- Line *lp, *end;
+ Line *lp;
Dk *dp;
int line;
@@ 794,21 821,21 @@ dkopen(Chan *c, int omode)
/*
* get an unused device and open its control file
*/
- end = &dp->line[dp->lines];
- for(lp = &dp->line[dp->ncsc+1]; lp < end; lp++){
+ for(line = dp->ncsc+1; line < dp->lines; line++){
+ lp = dp->linep[line];
if(lp->state == Lclosed && canqlock(lp)){
if(lp->state != Lclosed){
qunlock(lp);
continue;
}
- c->qid.path = STREAMQID(lp-dp->line, Sctlqid);
+ c->qid.path = STREAMQID(line, Sctlqid);
+ lp->state = Lopened;
+ qunlock(lp);
break;
}
}
- if(lp == end)
+ if(line == dp->lines)
error(Enodev);
- lp->state = Lopened;
- qunlock(lp);
streamopen(c, &dkinfo);
pushq(c->stream, &urpinfo);
break;
@@ 826,7 853,6 @@ dkopen(Chan *c, int omode)
case Daddrqid:
case Draddrqid:
case Duserqid:
- case Dotherqid:
/*
* read only files
*/
@@ 877,7 903,7 @@ dkread(Chan *c, void *a, long n, ulong offset)
return devdirread(c, a, n, dksubdir, Nsubdir, streamgen);
}
- lp = &dk[c->dev].line[STREAMID(c->qid.path)];
+ lp = dk[c->dev].linep[STREAMID(c->qid.path)];
switch(STREAMTYPE(c->qid.path)){
case Daddrqid:
return stringread(c, a, n, lp->addr, offset);
@@ 1028,7 1054,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
line = STREAMID(c->qid.path);
dp = &dk[c->dev];
- lp = &dp->line[line];
+ lp = dp->linep[line];
/*
* only dial on virgin lines
@@ 1272,7 1298,7 @@ dklisten(Chan *c)
print("dklisten: illegal line %d\n", lineno);
continue;
}
- lp = &dp->line[lineno];
+ lp = dp->linep[lineno];
ts = strtoul(field[1], 0, 0);
/*
@@ 1338,9 1364,8 @@ dklisten(Chan *c)
error(Ebadarg);
}
- sprint(lp->other, "w(%d)", W_TRAF(lp->window));
- DPRINT("src(%s)user(%s)dest(%s)other(%s)\n", lp->raddr, lp->ruser,
- lp->addr, lp->other);
+ DPRINT("src(%s)user(%s)dest(%s)w(%d)\n", lp->raddr, lp->ruser,
+ lp->addr, W_TRAF(lp->window));
lp->timestamp = ts;
lp->state = Lconnected;
@@ 1365,7 1390,7 @@ dkanswer(Chan *c, int line, int code)
Line *lp;
dp = &dk[c->dev];
- lp = &dp->line[line];
+ lp = dp->linep[line];
/*
* open the data file (c is a control file)
@@ 1398,7 1423,7 @@ dkwindow(Chan *c)
long wins;
Line *lp;
- lp = &dk[c->dev].line[STREAMID(c->qid.path)];
+ lp = dk[c->dev].linep[STREAMID(c->qid.path)];
if(lp->window == 0)
lp->window = 64;
sprint(buf, "init %d %d", lp->window, Streamhi);
@@ 1496,7 1521,7 @@ dkchgmesg(Chan *c, Dk *dp, Dkmsg *dialp, int line)
dkmesg(c, T_CHG, D_CLOSE, line, 0);
return;
}
- lp = &dp->line[line];
+ lp = dp->linep[line];
switch (lp->state) {
case Ldialing:
@@ 1532,7 1557,7 @@ dkchgmesg(Chan *c, Dk *dp, Dkmsg *dialp, int line)
dkmesg(c, T_CHG, D_CLOSE, line, 0);
return;
}
- lp = &dp->line[line];
+ lp = dp->linep[line];
switch (lp->state) {
case Llclose:
case Lclosed:
@@ 1552,7 1577,7 @@ dkchgmesg(Chan *c, Dk *dp, Dkmsg *dialp, int line)
* datakit wants us to close all lines
*/
for(line = dp->ncsc+1; line < dp->lines; line++){
- lp = &dp->line[line];
+ lp = dp->linep[line];
switch (lp->state) {
case Ldialing:
@@ 1601,7 1626,7 @@ dkreplymesg(Dk *dp, Dkmsg *dialp, int line)
if(line < 0 || line >= dp->lines)
return;
- lp=&dp->line[line];
+ lp = dp->linep[line];
if(lp->state != Ldialing)
return;
@@ 1646,7 1671,7 @@ dktimer(void *a)
* hang up any calls waiting for the dk
*/
for (i=dp->ncsc+1; i<dp->lines; i++){
- lp = &dp->line[i];
+ lp = dp->linep[i];
switch(lp->state){
case Llclose:
lp->state = Lclosed;
@@ 1659,6 1684,7 @@ dktimer(void *a)
}
if(c)
close(c);
+ freeb(dp->alloc);
return;
}
@@ 1682,7 1708,7 @@ dktimer(void *a)
* timeout calls that take to long
*/
for (i=dp->ncsc+1; i<dp->lines; i++){
- lp = &dp->line[i];
+ lp = dp->linep[i];
switch(lp->state){
case Llclose:
dkmesg(c, T_CHG, D_CLOSE, i, 0);
M port/devlance.c => port/devlance.c +6 -53
@@ 186,7 186,6 @@ static SoftLance l;
*/
static void lancekproc(void *);
static void lancestart(int, int);
-static void lancedump(void);
static void lanceup(Etherpkt*, int);
/*
@@ 244,45 243,6 @@ lancestclose(Queue *q)
}
/*
- * expand a block list to be one byte, len bytes long
- */
-static Block*
-expandb(Block *bp, int len)
-{
- Block *nbp, *new;
- int i;
-
- new = allocb(len);
- if(new == 0){
- freeb(bp);
- return 0;
- }
-
- /*
- * copy bytes into new block
- */
- for(nbp = bp; len>0 && nbp; nbp = nbp->next){
- i = BLEN(bp);
- if(i > len) {
- memmove(new->wptr, nbp->rptr, len);
- new->wptr += len;
- break;
- } else {
- memmove(new->wptr, nbp->rptr, i);
- new->wptr += i;
- len -= i;
- }
- }
- if(len){
- memset(new->wptr, 0, len);
- new->wptr += len;
- }
- freeb(bp);
- return new;
-
-}
-
-/*
* the ``connect'' control message specifyies the type
*/
Proc *lanceout;
@@ 329,7 289,7 @@ lanceoput(Queue *q, Block *bp )
memmove(p->s, l.ea, sizeof(l.ea));
if(memcmp(l.ea, p->d, sizeof(l.ea)) == 0){
len = blen(bp);
- bp = expandb(bp, len >= 60 ? len : 60);
+ bp = expandb(bp, len >= ETHERMINTU ? len : ETHERMINTU);
if(bp){
putq(&l.self, bp);
wakeup(&l.rr);
@@ 370,9 330,9 @@ lanceoput(Queue *q, Block *bp )
/*
* pad the packet (zero the pad)
*/
- if(len < 60){
- memset(((char*)p)+len, 0, 60-len);
- len = 60;
+ if(len < ETHERMINTU){
+ memset(((char*)p)+len, 0, ETHERMINTU-len);
+ len = ETHERMINTU;
}
/*
@@ 695,9 655,8 @@ lanceintr(void)
* see if an error occurred
*/
if(csr & (BABL|MISS|MERR)){
- print("lance err %ux\n", csr);
- if(csr & MISS)
- lancedump();
+ if(misses++ < 4)
+ print("lance err %ux\n", csr);
}
if(csr & IDON){
@@ 838,9 797,3 @@ stage:
sleep(&l.rr, isinput, 0);
}
}
-
-static void
-lancedump(void)
-{
- print("l.rl %d l.rc %d l.tl %d l.tc %d\n", l.rl, l.rc, l.tl, l.tc);
-}
M port/devproc.c => port/devproc.c +0 -2
@@ 166,9 166,7 @@ procopen(Chan *c, int omode)
if(p->pid != PID(c->qid))
goto Close;
- qlock(&tc->rdl);
tc->offset = 0;
- qunlock(&tc->rdl);
return tc;
case Qctl:
case Qnote:
M port/ipdat.h => port/ipdat.h +1 -1
@@ 101,7 101,7 @@ struct Ilcb /* Control block */
Block *unacked;
Block *unackedtail;
Block *outoforder;
- ulong sent;
+ ulong next;
ulong recvd;
ulong start;
ulong rstart;
A port/net.c => port/net.c +143 -0
@@ 0,0 1,143 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "errno.h"
+
+enum
+{
+ Qlisten= 1,
+ Qclone= 2,
+ Q2nd= 3,
+ Q3rd= 4,
+};
+
+/*
+ * generate a 3 level directory
+ */
+int
+netgen(Chan *c, void *vp, int ntab, int i, Dir *dp)
+{
+ Qid q;
+ char buf[32];
+ Network *np = vp;
+
+ q.vers = 0;
+
+ /* top level directory contains the name of the network */
+ if(c->qid.path == CHDIR){
+ switch(i){
+ case 0:
+ q.path = CHDIR | Q2nd;
+ strcpy(buf, np->name);
+ devdir(c, q, buf, 0, 0666, dp);
+ break;
+ default:
+ return -1;
+ }
+ return 1;
+ }
+
+ /* second level contains clone plus all the conversations */
+ if(c->qid.path == (CHDIR | Q2nd)){
+ if(i == 0){
+ q.path = Qclone;
+ devdir(c, q, "clone", 0, 0666, dp);
+ }else if(i < np->nconv){
+ q.path = CHDIR|STREAMQID(i, Q3rd);
+ sprint(buf, "%d", i);
+ devdir(c, q, buf, 0, 0666, dp);
+ }else
+ return -1;
+ return 1;
+ }
+
+ if((c->qid.path & CHDIR) == 0)
+ return -1;
+
+ /* third level depends on the number of info files */
+ switch(i){
+ case 0:
+ q.path = STREAMQID(STREAMID(c->qid.path), Sdataqid);
+ devdir(c, q, "data", 0, 0666, dp);
+ break;
+ case 1:
+ q.path = STREAMQID(STREAMID(c->qid.path), Sctlqid);
+ devdir(c, q, "ctl", 0, 0666, dp);
+ break;
+ case 2:
+ if(np->listen == 0)
+ return 0;
+ q.path = STREAMQID(STREAMID(c->qid.path), Qlisten);
+ devdir(c, q, "listen", 0, 0666, dp);
+ break;
+ default:
+ if(i >= 3 + np->ninfo)
+ return -1;
+ i -= 3;
+ q.path = Qlisten + i + 1;
+ devdir(c, q, np->info[i].name, 0, 0666, dp);
+ }
+ return 1;
+}
+
+Chan *
+netopen(Chan *c, int omode, Network *np)
+{
+ int conv;
+
+ if(c->qid.path & CHDIR){
+ if(omode != OREAD)
+ error(Eperm);
+ } else {
+ switch(STREAMTYPE(c->qid.path)){
+ case Sdataqid:
+ case Sctlqid:
+ break;
+ case Qlisten:
+ conv = (*np->listen)(c);
+ c->qid.path = STREAMQID(conv, Sctlqid);
+ break;
+ case Qclone:
+ conv = (*np->clone)(c);
+ c->qid.path = STREAMQID(conv, Sctlqid);
+ break;
+ default:
+ if(omode != OREAD)
+ error(Ebadarg);
+ }
+ switch(STREAMTYPE(c->qid.path)){
+ case Sdataqid:
+ case Sctlqid:
+ streamopen(c, np->devp);
+ if(np->protop && c->stream->devq->next->info != np->protop)
+ pushq(c->stream, np->protop);
+ break;
+ }
+ }
+ c->mode = openmode(omode);
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+}
+
+long
+netread(Chan *c, void *a, long n, ulong offset, Network *np)
+{
+ int i;
+ char buf[256];
+
+ if(c->stream)
+ return streamread(c, a, n);
+
+ if(c->qid.path&CHDIR)
+ return devdirread(c, a, n, (Dirtab*)np, 0, netgen);
+
+ if(c->qid.path <= Qlisten || c->qid.path > Qlisten + np->ninfo)
+ error(Ebadusefd);
+
+ i = c->qid.path - Qlisten - 1;
+ (*np->info[i].fill)(c, buf, sizeof(buf));
+ return stringread(c, a, n, buf, offset);
+}
M port/portdat.h => port/portdat.h +0 -3
@@ 624,14 624,11 @@ struct Ifile
struct Network
{
char *name;
- int nif; /* max # of interfaces */
int nconv; /* max # of conversations */
Qinfo *devp; /* device end line disc */
Qinfo *protop; /* protocol line disc */
int (*listen)(Chan*);
int (*clone)(Chan*);
- void (*connect)(Chan*, char*);
- void (*announce)(Chan*, char*);
int ninfo;
Ifile info[5];
};
M port/portfns.h => port/portfns.h +4 -0
@@ 64,6 64,7 @@ void error(int);
void errors(char*);
void execpc(ulong);
void exit(void);
+Block* expandb(Block *, int);
int fault(ulong, int);
void fdclose(int, int);
Chan* fdtochan(int, int, int);
@@ 120,6 121,9 @@ void mouseclock(void);
int mouseputc(IOQ*, int);
Chan* namec(char*, int, int, ulong);
void nameok(char*);
+int netgen(Chan*, void*, int, int, Dir*);
+Chan* netopen(Chan*, int, Network*);
+long netread(Chan*, void*, long, ulong, Network*);
Alarm* newalarm(void);
Chan* newchan(void);
Egrp* newegrp(void);
M port/stil.c => port/stil.c +42 -40
@@ 31,6 31,7 @@ void ilackq(Ilcb*, Block*);
void ilprocess(Ipconv*, Ilhdr*, Block*);
void ilpullup(Ipconv*);
void ilhangup(Ipconv*);
+void ilfreeq(Ilcb*);
void
ilopen(Queue *q, Stream *s)
@@ 83,18 84,8 @@ ilclose(Queue *q)
case Ilsyncer:
case Ilsyncee:
case Ilestablished:
- for(bp = ic->unacked; bp; bp = next) {
- next = bp->list;
- freeb(bp);
- }
- for(bp = ic->outoforder; bp; bp = next) {
- next = bp->list;
- freeb(bp);
- }
- ic->unacked = 0;
- ic->outoforder = 0;
+ ilfreeq(ic);
ic->state = Ilclosing;
- ic->sent++;
ilsendctl(s, 0, Ilclose);
break;
Illistening:
@@ 156,7 147,7 @@ iloput(Queue *q, Block *bp)
hnputs(ih->illen, dlen+IL_HDRSIZE);
hnputs(ih->ilsrc, ipc->psrc);
hnputs(ih->ildst, ipc->pdst);
- hnputl(ih->ilid, ic->sent++);
+ hnputl(ih->ilid, ic->next++);
hnputl(ih->ilack, ic->recvd);
ih->iltype = Ildata;
ih->ilspec = 0;
@@ 275,8 266,8 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
ic = &new->ilctl;
ic->state = Ilsyncee;
initseq += TK2MS(MACHP(0)->ticks);
- ic->sent = initseq;
- ic->start = ic->sent;
+ ic->next = initseq;
+ ic->start = ic->next;
ic->recvd = 0;
ic->rstart = nhgetl(ih->ilid);
ilprocess(new, ih, bp);
@@ 413,22 404,11 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
break;
case Ilclose:
freeb(bp);
- if(ic->start >= ack || ack < ic->sent)
+ if(id != ic->recvd)
break;
- ic->sent++;
- ic->recvd = ack;
ilsendctl(s, 0, Ilclose);
ic->state = Ilclosing;
- for(nb = ic->unacked; nb; nb = next) {
- next = nb->list;
- freeb(nb);
- }
- for(nb = ic->outoforder; nb; nb = next) {
- next = nb->list;
- freeb(nb);
- }
- ic->unacked = 0;
- ic->outoforder = 0;
+ ilfreeq(ic);
break;
}
break;
@@ 438,15 418,16 @@ _ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
case Ilclosing:
switch(h->iltype) {
case Ilclose:
- if(ack == ic->sent) {
+ if(ack == ic->next) {
ic->state = Ilclosed;
ilhangup(s);
}
- ic->recvd = id;
- ilsendctl(s, 0, Ilclose);
+ else {
+ ic->recvd = id;
+ ilsendctl(s, 0, Ilclose);
+ }
break;
default:
- ic->state = Ilclosed;
ilsendctl(s, 0, Ilclose);
ilhangup(s);
break;
@@ 462,14 443,14 @@ ilprocess(Ipconv *s, Ilhdr *h, Block *bp)
{
Ilcb *ic = &s->ilctl;
- print("%s start %d rstart %d recvd %d sent %d\n",
- ilstate[ic->state], ic->start, ic->rstart, ic->recvd, ic->sent);
- print("pkt(%s id %d ack %d)\n", iltype[h->iltype], nhgetl(h->ilid), nhgetl(h->ilack));
+ print("%s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
+ ilstate[ic->state], ic->rstart, ic->recvd, ic->start, ic->next,
+ iltype[h->iltype], nhgetl(h->ilid), nhgetl(h->ilack),
+ nhgets(h->ilsrc), nhgets(h->ildst));
_ilprocess(s, h, bp);
- print("%s start %d rstart %d recvd %d sent %d\n",
- ilstate[ic->state], ic->start, ic->rstart, ic->recvd, ic->sent);
+ print("%s rcv %d snt %d\n", ilstate[ic->state], ic->recvd, ic->next);
}
void
@@ 578,7 559,7 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type)
hnputl(ih->dst, ipc->dst);
hnputs(ih->ilsrc, ipc->psrc);
hnputs(ih->ildst, ipc->pdst);
- id = ic->sent;
+ id = ic->next;
if(type == Ilsync)
id = ic->start;
hnputl(ih->ilid, id);
@@ 592,6 573,10 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type)
if(ilcksum)
hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, IL_HDRSIZE));
+ print("ctl(%s id %d ack %d %d->%d) ",
+ iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack),
+ nhgets(ih->ilsrc), nhgets(ih->ildst));
+
PUTNEXT(Ipoutput, bp);
}
@@ 638,10 623,10 @@ ilstart(Ipconv *ipc, int type, int window)
ic->unacked = 0;
ic->outoforder = 0;
initseq += TK2MS(MACHP(0)->ticks);
- ic->sent = initseq;
- ic->start = ic->sent;
+ ic->next = initseq;
+ ic->start = ic->next;
ic->recvd = 0;
- ic->lastack = ic->sent;
+ ic->lastack = ic->next;
ic->window = window;
switch(type) {
@@ 654,3 639,20 @@ ilstart(Ipconv *ipc, int type, int window)
break;
}
}
+
+void
+ilfreeq(Ilcb *ic)
+{
+ Block *bp, *next;
+
+ for(bp = ic->unacked; bp; bp = next) {
+ next = bp->list;
+ freeb(bp);
+ }
+ for(bp = ic->outoforder; bp; bp = next) {
+ next = bp->list;
+ freeb(bp);
+ }
+ ic->unacked = 0;
+ ic->outoforder = 0;
+}
M port/stnoether.c => port/stnoether.c +12 -5
@@ 196,11 196,18 @@ noetheriput(Queue *q, Block *bp)
*/
ep = &ifc->conv[conf.nnoconv];
for(cp = &ifc->conv[0]; cp < ep; cp++){
- if(circuit==cp->rcvcircuit){
- qlock(cp);
- peh = (Etherpkt*)cp->media->rptr;
- if(circuit == cp->rcvcircuit
- && memcmp(peh->d, eh->s, sizeof(eh->s)) == 0){
+ nbp = cp->media;
+ if(nbp == 0)
+ continue;
+ peh = (Etherpkt*)nbp->rptr;
+ if(circuit==cp->rcvcircuit && memcmp(peh->d, eh->s, sizeof(eh->s))==0){
+ if(!canqlock(cp)){
+ freeb(bp);
+ return;
+ }
+ peh = (Etherpkt*)nbp->rptr;
+ if(circuit==cp->rcvcircuit
+ && memcmp(peh->d, eh->s, sizeof(eh->s))==0){
bp->rptr += ifc->hsize;
nonetrcvmsg(cp, bp);
qunlock(cp);
M port/stream.c => port/stream.c +49 -9
@@ 44,6 44,7 @@ static Lock garbagelock;
typedef struct {
int size;
int made;
+ QLock;
Blist;
} Bclass;
Bclass bclass[Nclass]={
@@ 145,11 146,11 @@ newblock(Bclass *bcp)
* upgrade a level 0 block
*/
bp = allocb(0);
- lock(bclass);
+ qlock(bclass);
bclass->made--;
bcp->made++;
bp->flags = bcp - bclass;
- unlock(bclass);
+ qunlock(bclass);
/*
* tack on the data area
@@ 193,10 194,10 @@ allocb(ulong size)
/*
* look for a free block
*/
- lock(bcp);
+ qlock(bcp);
while(bcp->first == 0){
if(waserror()){
- unlock(bcp);
+ qunlock(bcp);
nexterror();
}
newblock(bcp);
@@ 206,7 207,7 @@ allocb(ulong size)
bcp->first = bp->next;
if(bcp->first == 0)
bcp->last = 0;
- unlock(bcp);
+ qunlock(bcp);
/*
* return an empty block
@@ 240,7 241,7 @@ freeb(Block *bp)
for(; bp; bp = nbp){
bcp = &bclass[bp->flags & S_CLASS];
bp->flags = bp->flags|S_CLASS; /* Check for double free */
- lock(bcp);
+ qlock(bcp);
bp->rptr = bp->wptr = 0;
if(bcp->first)
bcp->last->next = bp;
@@ 249,7 250,7 @@ freeb(Block *bp)
bcp->last = bp;
nbp = bp->next;
bp->next = 0;
- unlock(bcp);
+ qunlock(bcp);
}
}
@@ 617,6 618,45 @@ pullup(Block *bp, int n)
}
/*
+ * expand a block list to be one byte, len bytes long
+ */
+Block*
+expandb(Block *bp, int len)
+{
+ Block *nbp, *new;
+ int i;
+
+ new = allocb(len);
+ if(new == 0){
+ freeb(bp);
+ return 0;
+ }
+
+ /*
+ * copy bytes into new block
+ */
+ for(nbp = bp; len>0 && nbp; nbp = nbp->next){
+ i = BLEN(bp);
+ if(i > len) {
+ memmove(new->wptr, nbp->rptr, len);
+ new->wptr += len;
+ break;
+ } else {
+ memmove(new->wptr, nbp->rptr, i);
+ new->wptr += i;
+ len -= i;
+ }
+ }
+ if(len){
+ memset(new->wptr, 0, len);
+ new->wptr += len;
+ }
+ freeb(bp);
+ return new;
+
+}
+
+/*
* grow the front of a list of blocks by n bytes
*/
Block *
@@ 1414,10 1454,10 @@ dumpqueues(void)
}
print("%d queues\n", qcount);
for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){
- lock(bcp);
+ qlock(bcp);
for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
;
- unlock(bcp);
+ qunlock(bcp);
print("%d byte blocks: %d made %d free\n", bcp->size,
bcp->made, count);
}
M port/sysfile.c => port/sysfile.c +2 -2
@@ 535,7 535,7 @@ syswstat(ulong *arg)
long n;
validaddr(arg[1], DIRLEN, 0);
- evenaddr(arg[1]);
+ nameok((char*)arg[1]);
validaddr(arg[0], 1, 0);
c = namec((char*)arg[0], Aaccess, 0, 0);
if(waserror()){
@@ 555,7 555,7 @@ sysfwstat(ulong *arg)
long n;
validaddr(arg[1], DIRLEN, 0);
- evenaddr(arg[1]);
+ nameok((char*)arg[1]);
c = fdtochan(arg[0], -1, 1);
(*devtab[c->type].wstat)(c, (char*)arg[1]);
return 0;
M power/conf.h => power/conf.h +1 -0
@@ 37,6 37,7 @@ Conftab conftab[] = {
{"arp", &conf.arp },
{"frag", &conf.frag },
{"cntrlp", &conf.cntrlp },
+ {"dkif", &conf.dkif },
{ 0, 0 },
};
M power/dat.h => power/dat.h +1 -0
@@ 74,6 74,7 @@ struct Conf
ulong arp; /* Arp table size */
ulong frag; /* Ip fragment assemble queue size */
ulong cntrlp; /* panic on ^P */
+ ulong dkif; /* number of datakit interfaces */
};
/*
M power/main.c => power/main.c +1 -0
@@ 595,6 595,7 @@ confinit(void)
conf.copymode = 1; /* copy on reference */
conf.cntrlp = 1;
+ conf.dkif = 2;
}
/*
M ss/dat.h => ss/dat.h +1 -0
@@ 99,6 99,7 @@ struct Conf
ulong arp; /* Arp table size */
ulong frag; /* Ip fragment assemble queue size */
int cntrlp; /* panic on ^P */
+ int dkif; /* number of datakit interfaces */
};
/*
M ss/main.c => ss/main.c +1 -0
@@ 243,6 243,7 @@ confinit(void)
conf.arp = 32;
conf.frag = 32;
conf.cntrlp = 0;
+ conf.dkif = 1;
}
/*