M gnot/boot.h => gnot/boot.h +5 -5
@@ 4453,8 4453,8 @@ ulong bootcode[]={
0x06e65742c,
0x020286929,
0x0696e636f,
- 0x06e007474,
- 0x079310023,
+ 0x06e006569,
+ 0x061310023,
0x0772f6864,
0x030006e65,
0x07874206e,
@@ 4471,7 4471,7 @@ ulong bootcode[]={
0x02c202865,
0x029746865,
0x0726e6574,
- 0x000747479,
+ 0x000656961,
0x030002377,
0x0312f6864,
0x031006174,
@@ 4485,7 4485,7 @@ ulong bootcode[]={
0x039323030,
0x020736572,
0x069616c00,
- 0x074747930,
+ 0x065696130,
0x00023772f,
0x068643000,
0x061742674,
@@ 4504,7 4504,7 @@ ulong bootcode[]={
0x06c2c2028,
0x06929696e,
0x0636f6e00,
- 0x074747930,
+ 0x065696130,
0x00023772f,
0x068643000,
0x073756e20,
M gnot/devduart.c => gnot/devduart.c +9 -9
@@ 608,13 608,13 @@ loop:
enum{
Qdir= 0,
- Qtty0= STREAMQID(0, Sdataqid),
- Qtty0ctl= STREAMQID(0, Sctlqid),
+ Qeia0= STREAMQID(0, Sdataqid),
+ Qeia0ctl= STREAMQID(0, Sctlqid),
};
Dirtab duartdir[]={
- "tty0", {Qtty0}, 0, 0666,
- "tty0ctl", {Qtty0ctl}, 0, 0666,
+ "eia0", {Qeia0}, 0, 0666,
+ "eia0ctl", {Qeia0ctl}, 0, 0666,
};
#define NDuartport (sizeof duartdir/sizeof(Dirtab))
@@ 658,8 658,8 @@ void
duartstat(Chan *c, char *dp)
{
switch(c->qid.path){
- case Qtty0:
- streamstat(c, dp, "tty0");
+ case Qeia0:
+ streamstat(c, dp, "eia0");
break;
default:
devstat(c, dp, duartdir, NDuartport, devgen);
@@ 673,8 673,8 @@ duartopen(Chan *c, int omode)
Duartport *dp;
switch(c->qid.path){
- case Qtty0:
- case Qtty0ctl:
+ case Qeia0:
+ case Qeia0ctl:
dp = &duartport[0];
break;
default:
@@ 712,7 712,7 @@ duartread(Chan *c, void *buf, long n, ulong offset)
switch(c->qid.path&~CHDIR){
case Qdir:
return devdirread(c, buf, n, duartdir, NDuartport, devgen);
- case Qtty0ctl:
+ case Qeia0ctl:
if(offset)
return 0;
s = splhi();
M gnot/trap.c => gnot/trap.c +0 -2
@@ 137,8 137,6 @@ dumpregs(Ureg *ur)
l = &ur->r0;
for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
-
- dumpstack();
}
/*
M pc/clock.c => pc/clock.c +5 -6
@@ 87,11 87,10 @@ clock(Ureg *ur)
else
sched();
}
- /*
- * notes for processes that might be spinning
- * in user mode.
- */
- if((ur->cs&0xffff) == UESEL)
- notify(ur);
+ if((ur->cs&0xffff) == UESEL){
+ spllo(); /* in case we fault */
+ (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); /* profiling clock */
+ splhi();
+ }
}
}
M pc/devuart.c => pc/devuart.c +18 -18
@@ 557,17 557,17 @@ uartkproc(void *a)
enum{
Qdir= 0,
- Qtty0= STREAMQID(0, Sdataqid),
- Qtty0ctl= STREAMQID(0, Sctlqid),
- Qtty1= STREAMQID(1, Sdataqid),
- Qtty1ctl= STREAMQID(1, Sctlqid),
+ Qeia0= STREAMQID(0, Sdataqid),
+ Qeia0ctl= STREAMQID(0, Sctlqid),
+ Qeia1= STREAMQID(1, Sdataqid),
+ Qeia1ctl= STREAMQID(1, Sctlqid),
};
Dirtab uartdir[]={
- "tty0", {Qtty0}, 0, 0666,
- "tty0ctl", {Qtty0ctl}, 0, 0666,
- "tty1", {Qtty1}, 0, 0666,
- "tty1ctl", {Qtty1ctl}, 0, 0666,
+ "eia0", {Qeia0}, 0, 0666,
+ "eia0ctl", {Qeia0ctl}, 0, 0666,
+ "eia1", {Qeia1}, 0, 0666,
+ "eia1ctl", {Qeia1ctl}, 0, 0666,
};
#define NUart (sizeof uartdir/sizeof(Dirtab))
@@ 618,11 618,11 @@ void
uartstat(Chan *c, char *dp)
{
switch(c->qid.path){
- case Qtty0:
- streamstat(c, dp, "tty0");
+ case Qeia0:
+ streamstat(c, dp, "eia0");
break;
- case Qtty1:
- streamstat(c, dp, "tty1");
+ case Qeia1:
+ streamstat(c, dp, "eia1");
break;
default:
devstat(c, dp, uartdir, NUart, devgen);
@@ 636,12 636,12 @@ uartopen(Chan *c, int omode)
Uart *up;
switch(c->qid.path){
- case Qtty0:
- case Qtty0ctl:
+ case Qeia0:
+ case Qeia0ctl:
up = &uart[0];
break;
- case Qtty1:
- case Qtty1ctl:
+ case Qeia1:
+ case Qeia1ctl:
up = &uart[1];
break;
default:
@@ 676,8 676,8 @@ uartread(Chan *c, void *buf, long n, ulong offset)
switch(c->qid.path&~CHDIR){
case Qdir:
return devdirread(c, buf, n, uartdir, NUart, devgen);
- case Qtty1ctl:
- case Qtty0ctl:
+ case Qeia1ctl:
+ case Qeia0ctl:
return 0;
}
return streamread(c, buf, n);
M port/devarp.c => port/devarp.c +5 -2
@@ 147,18 147,21 @@ arpopen(Chan *c, int omode)
void
arpcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
void
arpremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
arpwstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Eperm);
}
@@ 212,7 215,7 @@ arpread(Chan *c, void *a, long n, ulong offset)
sprint(buf, "hits: %d miss: %d failed: %d\n",
arpstats.hit, arpstats.miss, arpstats.failed);
- return stringread(c, a, n, buf, offset);
+ return stringread(a, n, buf, offset);
default:
n=0;
break;
@@ 255,10 258,10 @@ arpwrite(Chan *c, char *a, long n, ulong offset)
return n;
}
-
void
arpopn(Queue *q, Stream *s)
{
+ USED(q, s);
}
void
M port/devbit.c => port/devbit.c +5 -0
@@ 240,18 240,21 @@ bitopen(Chan *c, int omode)
void
bitcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
void
bitremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
bitwstat(Chan *c, char *db)
{
+ USED(c, db);
error(Eperm);
}
@@ 1246,6 1249,7 @@ mouseputc(IOQ *q, int c)
static int nb;
static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7};
+ USED(q);
if((c&0xF0) == 0x80)
nb=0;
msg[nb] = c;
@@ 1264,5 1268,6 @@ mouseputc(IOQ *q, int c)
int
mousechanged(void *m)
{
+ USED(m);
return mouse.changed;
}
M port/devcons.c => port/devcons.c +4 -0
@@ 273,6 273,7 @@ kbdcr2nl(IOQ *q, int ch)
int
kbdputc(IOQ *q, int ch)
{
+ USED(q);
echo(ch);
kbdq.c = ch;
*kbdq.in++ = ch;
@@ 455,6 456,7 @@ consopen(Chan *c, int omode)
void
conscreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
@@ 770,12 772,14 @@ conswrite(Chan *c, void *va, long n, ulong offset)
void
consremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
conswstat(Chan *c, char *dp)
{
+ USED(c);
error(Eperm);
}
M port/devdk.c => port/devdk.c +24 -4
@@ 14,6 14,10 @@ typedef struct Dkmsg Dkmsg;
typedef struct Line Line;
typedef struct Dk Dk;
+enum {
+ Maxlines = 256,
+};
+
/*
* types of possible dkcalls
*/
@@ 117,6 121,7 @@ struct Dk {
int closeall; /* set when we receive a closeall message */
Rendez closeallr; /* wait here for a closeall */
Network net;
+ Netprot *prot;
Block *alloc;
};
@@ 256,7 261,7 @@ dkalloc(char *name, int ncsc, int lines)
/*
* allocate memory for line structures
*/
- n = sizeof(Line*)*(dp->lines+1);
+ n = sizeof(Line*)*(dp->lines);
bp = allocb(n);
if(bp->lim - bp->base < n){
unlock(&dklock);
@@ 267,7 272,7 @@ dkalloc(char *name, int ncsc, int lines)
bp->wptr += n;
dp->alloc = bp;
n = sizeof(Line)*(dp->lines);
- for(i = 0; i <= dp->lines; i++){
+ for(i = 0; i < dp->lines; i++){
if(bp->lim - bp->wptr < sizeof(Line)){
bp = allocb(sizeof(Line)*n);
memset(bp->base, 0, bp->lim-bp->base);
@@ 284,11 289,12 @@ dkalloc(char *name, int ncsc, int lines)
* fill in the network structure
*/
dp->net.name = dp->name;
- dp->net.nconv = dp->lines+1;
+ dp->net.nconv = dp->lines;
dp->net.devp = &dkinfo;
dp->net.protop = &urpinfo;
dp->net.listen = dklisten;
dp->net.clone = dkcloneline;
+ dp->net.prot = dp->prot;
dp->net.ninfo = 3;
dp->net.info[0].name = "addr";
dp->net.info[0].fill = dkfilladdr;
@@ 530,6 536,7 @@ dkstclose(Queue *q)
out:
qlock(lp);
lp->rq = 0;
+ netdisown(&dp->net, lp->lineno);
qunlock(lp);
}
@@ 695,7 702,10 @@ dkmuxconfig(Queue *q, Block *bp)
void
dkreset(void)
{
+ int i;
dk = (Dk*)ialloc(conf.dkif*sizeof(Dk), 0);
+ for(i = 0; i < conf.dkif; i++)
+ dk[i].prot = (Netprot*)ialloc(conf.nurp*sizeof(Netprot), 0);
newqinfo(&dkmuxinfo);
}
@@ 827,7 837,7 @@ dkremove(Chan *c)
void
dkwstat(Chan *c, char *dp)
{
- error(Eperm);
+ netwstat(c, dp, &dk[c->dev].net);
}
/*
@@ 852,6 862,10 @@ dkcloneline(Chan *c)
continue;
}
lp->state = Lopened;
+
+ /* current user becomes owner */
+ netown(&dp->net, lp->lineno, u->p->user, 0);
+
qunlock(lp);
return lp->lineno;
}
@@ 1125,9 1139,11 @@ dklisten(Chan *c)
Line *lp;
Dk *dp;
int n, lineno, ts, window;
+ int from;
Chan *dc;
dp = &dk[c->dev];
+ from = STREAMID(c->qid.path);
/*
* open the data file
@@ 1270,6 1286,10 @@ dklisten(Chan *c)
lp->timestamp = ts;
lp->state = Lconnected;
+
+ /* listener becomes owner */
+ netown(&dp->net, lp->lineno, dp->prot[from].owner, 0);
+
qunlock(lp);
close(dc);
poperror();
M port/devdup.c => port/devdup.c +5 -0
@@ 84,24 84,28 @@ dupopen(Chan *c, int omode)
void
dupcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
void
dupremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
dupwstat(Chan *c, char *dp)
{
+ USED(c);
error(Egreg);
}
void
dupclose(Chan *c)
{
+ USED(c);
}
long
@@ 117,5 121,6 @@ dupread(Chan *c, void *va, long n, ulong offset)
long
dupwrite(Chan *c, void *va, long n, ulong offset)
{
+ USED(c, va, n, offset);
panic("dupwrite");
}
M port/devenv.c => port/devenv.c +2 -0
@@ 196,12 196,14 @@ envremove(Chan *c)
void
envwstat(Chan *c, char *db)
{
+ USED(c, db);
error(Eperm);
}
void
envclose(Chan * c)
{
+ USED(c);
}
void
M port/devip.c => port/devip.c +20 -4
@@ 48,8 48,11 @@ ipinitifc(Ipifc *ifc, Qinfo *stproto, Ipconv *cp)
{
int j;
- for(j = 0; j < conf.ip; j++, cp++)
+ for(j = 0; j < conf.ip; j++, cp++){
+ cp->index = j;
cp->stproto = stproto;
+ cp->ipinterface = ifc;
+ }
ifc->net.name = stproto->name;
ifc->net.nconv = conf.ip;
ifc->net.devp = &ipinfo;
@@ 57,6 60,7 @@ ipinitifc(Ipifc *ifc, Qinfo *stproto, Ipconv *cp)
if(stproto != &udpinfo)
ifc->net.listen = iplisten;
ifc->net.clone = ipclonecon;
+ ifc->net.prot = (Netprot *)ialloc(sizeof(Netprot) * conf.ip, 0);
ifc->net.ninfo = 3;
ifc->net.info[0].name = "remote";
ifc->net.info[0].fill = ipremotefill;
@@ 136,16 140,17 @@ ipclonecon(Chan *c)
Ipconv *new, *base;
base = ipconv[c->dev];
- new = ipincoming(base);
+ new = ipincoming(base, 0);
if(new == 0)
error(Enodev);
return new - base;
}
Ipconv *
-ipincoming(Ipconv *base)
+ipincoming(Ipconv *base, Ipconv *from)
{
Ipconv *new, *etab;
+ Ipifc *ifc;
etab = &base[conf.ip];
for(new = base; new < etab; new++) {
@@ 156,6 161,13 @@ ipincoming(Ipconv *base)
qunlock(new);
continue;
}
+ ifc = base->ipinterface;
+ if(from)
+ /* copy ownership from listening channel */
+ netown(&ifc->net, new->index, ifc->net.prot[from->index].owner, 0);
+ else
+ /* current user becomes owner */
+ netown(&ifc->net, new->index, u->p->user, 0);
new->ref = 1;
qunlock(new);
return new;
@@ 167,19 179,21 @@ ipincoming(Ipconv *base)
void
ipcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
void
ipremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
ipwstat(Chan *c, char *dp)
{
- error(Eperm);
+ netwstat(c, dp, &ipifc[c->dev].net);
}
void
@@ 432,6 446,7 @@ udpstclose(Queue *q)
ipc->ref = 0;
closeipifc(ipc->ipinterface);
+ netdisown(&ipc->ipinterface->net, ipc->index);
}
void
@@ 654,6 669,7 @@ tcpstclose(Queue *q)
qunlock(tcb);
break;
}
+ netdisown(&s->ipinterface->net, s->index);
}
M port/deviproute.c => port/deviproute.c +4 -0
@@ 244,24 244,28 @@ iprouteopen(Chan *c, int omode)
void
iproutecreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
void
iprouteremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
iproutewstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Eperm);
}
void
iprouteclose(Chan *c)
{
+ USED(c);
}
#define IPR_ENTRYLEN 54
M port/devkprof.c => port/devkprof.c +4 -0
@@ 86,24 86,28 @@ kprofopen(Chan *c, int omode)
void
kprofcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
void
kprofremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
kprofwstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Eperm);
}
void
kprofclose(Chan *c)
{
+ USED(c);
}
long
M port/devlance.c => port/devlance.c +14 -1
@@ 94,6 94,7 @@ typedef struct {
Lance; /* host dependent lance params */
int prom; /* number of promiscuous channels */
Network net;
+ Netprot prot[Ntypes];
int inited;
uchar *lmp; /* location of parity test */
@@ 247,6 248,7 @@ lancestclose(Queue *q)
et->q = 0;
et->prom = 0;
et->inuse = 0;
+ netdisown(&l.net, et - l.e);
qunlock(et);
}
@@ 257,6 259,7 @@ Proc *lanceout;
static int
isobuf(void *x)
{
+ USED(x);
return TSUCC(l.tc) != l.tl;
}
static void
@@ 379,6 382,7 @@ lancereset(void)
l.net.listen = 0;
l.net.clone = lanceclonecon;
l.net.ninfo = 2;
+ l.net.prot = l.prot;
l.net.info[0].name = "stats";
l.net.info[0].fill = lancestatsfill;
l.net.info[1].name = "type";
@@ 549,6 553,7 @@ lanceopen(Chan *c, int omode)
void
lancecreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
@@ 574,13 579,14 @@ lancewrite(Chan *c, void *a, long n, ulong offset)
void
lanceremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
lancewstat(Chan *c, char *dp)
{
- error(Eperm);
+ netwstat(c, dp, &l.net);
}
/*
@@ 591,12 597,14 @@ lancestatsfill(Chan *c, char* p, int n)
{
char buf[256];
+ USED(c);
sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\naddr: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n",
l.inpackets, l.outpackets, l.crcs,
l.overflows, l.frames, l.buffs, l.oerrs,
l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]);
strncpy(p, buf, n);
}
+
static void
lancetypefill(Chan *c, char* p, int n)
{
@@ 613,6 621,7 @@ lanceclonecon(Chan *c)
{
Ethertype *e;
+ USED(c);
for(e = l.e; e < &l.e[Ntypes]; e++){
qlock(e);
if(e->inuse || e->q){
@@ 620,6 629,7 @@ lanceclonecon(Chan *c)
continue;
}
e->inuse = 1;
+ netown(&l.net, e - l.e, u->p->user, 0);
qunlock(e);
return e - l.e;
}
@@ 733,6 743,8 @@ static int
isinput(void *arg)
{
Lancemem *lm = LANCEMEM;
+
+ USED(arg);
return l.self.first || (l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0);
}
@@ 747,6 759,7 @@ lancekproc(void *arg)
Msg *m;
Block *bp;
+ USED(arg);
for(;;){
qlock(&l.rlock);
while(bp = getq(&l.self)){
M port/devmux.c => port/devmux.c +157 -68
@@ 15,13 15,16 @@ typedef struct Dtq Dtq;
enum
{
Qdir = 0,
- Qhead,
+ Qhead = 0,
Qclone,
+ Qoffset,
};
enum
{
Nmux = 20,
+ Maxmsg = (32*1024),
+ Flowctl = Maxmsg/2,
};
struct Dtq
@@ 31,6 34,9 @@ struct Dtq
Lock listlk;
Block *list;
int ndelim;
+ int nb;
+ QLock flow;
+ Rendez flowr;
};
struct Con
@@ 44,6 50,7 @@ struct Con
struct Mux
{
Ref;
+ int type;
char name[NAMELEN];
char user[NAMELEN];
ulong perm;
@@ 56,9 63,12 @@ Mux *muxes;
ulong muxreadq(Mux *m, Dtq*, char*, ulong);
void muxwriteq(Dtq*, char*, long, int, int);
+void muxflow(Dtq*);
+Block *muxclq(Dtq *q);
#define NMUX(c) (((c->qid.path>>8)&0xffff)-1)
-#define NQID(m, c) (Qid){(m)<<8|(c)&0xff, 0}
+#define NQID(m, c) (Qid){(m+1)<<8|(c)&0xff, 0}
+#define DQID(m) (Qid){(m+1)<<8|CHDIR, 0}
#define NCON(c) (c->qid.path&0xff)
int
@@ 68,6 78,7 @@ muxgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
int mux;
Con *cm;
char buf[10];
+ int nq;
if(c->qid.path == CHDIR) {
if(s >= conf.nmux)
@@ 76,7 87,7 @@ muxgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
m = &muxes[s];
if(m->name[0] == '\0')
return 0;
- devdir(c, (Qid){CHDIR|((s+1)<<8), 0}, m->name, 0, m->user, m->perm, dp);
+ devdir(c, DQID(s), m->name, 0, m->user, m->perm, dp);
return 1;
}
@@ 85,19 96,21 @@ muxgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
mux = NMUX(c);
m = &muxes[mux];
+
switch(s) {
case Qhead:
- devdir(c, NQID(mux, Qhead), "head", m->headq.ndelim, m->user, m->perm, dp);
+ devdir(c, NQID(mux, Qhead), "head", m->headq.nb, m->user, m->perm, dp);
break;
case Qclone:
devdir(c, NQID(mux, Qclone), "clone", 0, m->user, m->perm, dp);
break;
default:
- cm = &m->connects[s-Qclone];
+ nq = s-Qoffset;
+ cm = &m->connects[nq];
if(cm->ref == 0)
return 0;
- sprint(buf, "%d", s-Qclone);
- devdir(c, NQID(mux, Qclone+s), buf, cm->conq.ndelim, cm->user, cm->perm, dp);
+ sprint(buf, "%d", nq);
+ devdir(c, NQID(mux, Qoffset+s), buf, cm->conq.nb, cm->user, cm->perm, dp);
break;
}
return 1;
@@ 120,7 133,6 @@ muxattach(char *spec)
Chan *c;
c = devattach('m', spec);
-
c->qid.path = CHDIR|Qdir;
return c;
}
@@ 136,8 148,11 @@ muxclone(Chan *c, Chan *nc)
m = &muxes[NMUX(c)];
ncon = NCON(c);
-
c = devclone(c, nc);
+
+ if((c->flag&COPEN) == 0)
+ return c;
+
switch(ncon) {
case Qhead:
incref(m);
@@ 146,7 161,7 @@ muxclone(Chan *c, Chan *nc)
break;
default:
lock(m);
- m->connects[ncon].ref++;
+ m->connects[ncon-Qoffset].ref++;
m->ref++;
unlock(m);
}
@@ 175,19 190,29 @@ muxopen(Chan *c, int omode)
{
Mux *m;
Con *cm, *e;
+ int mux, ok;
if(c->qid.path & CHDIR)
return devopen(c, omode, 0, 0, muxgen);
- m = &muxes[NMUX(c)];
+ mux = NMUX(c);
+ m = &muxes[mux];
switch(NCON(c)) {
case Qhead:
+ c = devopen(c, omode, 0, 0, muxgen);
+ lock(m);
if(m->headopen)
+ ok = 0;
+ else {
+ ok = 1;
+ m->headopen = 1;
+ m->ref++;
+ }
+ unlock(m);
+ if(!ok) {
+ c->flag &= ~COPEN;
errors("server channel busy");
-
- c = devopen(c, omode, 0, 0,muxgen);
- m->headopen = 1;
- incref(m);
+ }
break;
case Qclone:
if(m->headopen == 0)
@@ 203,18 228,20 @@ muxopen(Chan *c, int omode)
unlock(m);
errors("all cannels busy");
}
- cm->ref++;
+ cm->ref = 1;
m->ref++;
unlock(m);
strncpy(cm->user, u->p->user, NAMELEN);
cm->perm = 0600;
- c->qid = NQID(NMUX(c), cm-m->connects);
+ c->qid = NQID(mux, (cm-m->connects)+Qoffset);
break;
default:
- c = devopen(c, omode, 0, 0,muxgen);
- cm = &m->connects[NCON(c)];
+ c = devopen(c, omode, 0, 0, muxgen);
+ cm = &m->connects[NCON(c)-Qoffset];
+ lock(m);
cm->ref++;
- incref(m);
+ m->ref++;
+ unlock(m);
break;
}
@@ 234,7 261,7 @@ muxcreate(Chan *c, char *name, int omode, ulong perm)
m = muxes;
for(e = &m[conf.nmux]; m < e; m++) {
- if(m->ref == 0 && canlock(m)) {
+ if(m->name[0] == '\0' && m->ref == 0 && canlock(m)) {
if(m->ref != 0) {
unlock(m);
continue;
@@ 291,7 318,6 @@ muxwstat(Chan *c, char *db)
d.mode &= 0777;
if(c->qid.path&CHDIR) {
strcpy(m->name, d.name);
- strcpy(m->user, d.uid);
m->perm = d.mode;
return;
}
@@ 303,7 329,7 @@ muxwstat(Chan *c, char *db)
m->perm = d.mode;
break;
default:
- m->connects[nc].perm = d.mode;
+ m->connects[nc-Qoffset].perm = d.mode;
break;
}
}
@@ 316,7 342,10 @@ muxclose(Chan *c)
Mux *m;
int nc;
- if(c->qid.path == CHDIR)
+ if(c->qid.path&CHDIR)
+ return;
+
+ if((c->flag&COPEN) == 0)
return;
m = &muxes[NMUX(c)];
@@ 331,26 360,19 @@ muxclose(Chan *c)
if(cm->ref)
wakeup(&cm->conq.r);
lock(m);
- if(--m->ref == 0) {
- f1 = m->headq.list;
- m->headq.list = 0;
- }
+ if(--m->ref == 0)
+ f1 = muxclq(&m->headq);
unlock(m);
break;
case Qclone:
- panic("muxclose");
+ break;
default:
lock(m);
- cm = &m->connects[nc];
- if(--cm->ref == 0) {
- f1 = cm->conq.list;
- cm->conq.list = 0;
- }
- if(--m->ref == 0) {
- m->name[0] = '\0';
- f2 = m->headq.list;
- m->headq.list = 0;
- }
+ cm = &m->connects[nc-Qoffset];
+ if(--cm->ref == 0)
+ f1 = muxclq(&cm->conq);
+ if(--m->ref == 0)
+ f1 = muxclq(&m->headq);
unlock(m);
}
if(f1)
@@ 377,7 399,7 @@ muxread(Chan *c, void *va, long n, ulong offset)
case Qclone:
error(Eperm);
default:
- cm = &m->connects[NCON(c)];
+ cm = &m->connects[NCON(c)-Qoffset];
bread = muxreadq(m, &cm->conq, va, n);
break;
}
@@ 390,7 412,7 @@ muxhdr(Mux *m, char *h)
{
Con *c;
- if(h[0] != Tmux)
+ if(h[0] != Tmux || h[2] != 0)
error(Ebadmsg);
c = &m->connects[h[1]];
@@ 410,11 432,14 @@ muxwrite(Chan *c, void *va, long n, ulong offset)
Con *cm;
int muxid;
Block *f, *bp;
- char *a, hdr[2];
+ char *a, hdr[3];
- if(c->qid.path & CHDIR)
+ if(c->qid.path&CHDIR)
error(Eisdir);
+ if(n > Maxmsg)
+ error(Etoobig);
+
m = &muxes[NMUX(c)];
switch(NCON(c)) {
case Qclone:
@@ 435,7 460,7 @@ muxwrite(Chan *c, void *va, long n, ulong offset)
if(m->headopen == 0)
error(Ehungup);
- muxid = NCON(c);
+ muxid = NCON(c)-Qoffset;
muxwriteq(&m->headq, va, n, 1, muxid);
break;
}
@@ 447,7 472,7 @@ void
muxwriteq(Dtq *q, char *va, long n, int addid, int muxid)
{
Block *head, *tail, *bp;
- ulong l;
+ ulong l, bwrite;
head = 0;
SET(tail);
@@ 457,13 482,26 @@ muxwriteq(Dtq *q, char *va, long n, int addid, int muxid)
nexterror();
}
+ bwrite = 0;
while(n) {
- bp = allocb(n);
- bp->type = M_DATA;
+ if(addid) {
+ bp = allocb(n+3);
+ bp->wptr[0] = Tmux;
+ bp->wptr[1] = muxid;
+ bp->wptr[2] = 0;
+ bp->wptr += 3;
+ bwrite += 3;
+ addid = 0;
+ }
+ else
+ bp = allocb(n);
l = bp->lim - bp->wptr;
+ if(l > n)
+ l = n;
memmove(bp->wptr, va, l); /* Interruptable thru fault */
va += l;
bp->wptr += l;
+ bwrite += l;
n -= l;
if(head == 0)
head = bp;
@@ 473,16 511,45 @@ muxwriteq(Dtq *q, char *va, long n, int addid, int muxid)
}
poperror();
tail->flags |= S_DELIM;
+
+ if(q->nb > Flowctl)
+ muxflow(q);
+
lock(&q->listlk);
- for(tail = q->list; tail->next; tail = tail->next)
- ;
- tail->next = head;
+ if(q->list == 0)
+ q->list = head;
+ else {
+ for(tail = q->list; tail->next; tail = tail->next)
+ ;
+ tail->next = head;
+ }
q->ndelim++;
+ q->nb += bwrite;
unlock(&q->listlk);
+ wakeup(&q->r);
}
int
-nodata(Dtq *q)
+muxflw(Dtq *q)
+{
+ return q->nb < Flowctl;
+}
+
+void
+muxflow(Dtq *q)
+{
+ qlock(&q->flow);
+ if(waserror()) {
+ qunlock(&q->flow);
+ nexterror();
+ }
+ sleep(&q->flowr, muxflw, q);
+ poperror();
+ qunlock(&q->flow);
+}
+
+int
+havedata(Dtq *q)
{
int n;
@@ 496,7 563,7 @@ ulong
muxreadq(Mux *m, Dtq *q, char *va, ulong n)
{
int l, nread, gotdelim;
- Block *bp;
+ Block *bp, *f1;
qlock(&q->rd);
bp = 0;
@@ 510,41 577,63 @@ muxreadq(Mux *m, Dtq *q, char *va, ulong n)
unlock(&q->listlk);
nexterror();
}
- while(nodata(q))
- sleep(&q->r, nodata, q);
-
- if(m->headopen == 0)
- errors("server shutdown");
+ while(!havedata(q)) {
+ sleep(&q->r, havedata, q);
+ if(m->headopen == 0)
+ errors("server shutdown");
+ }
nread = 0;
+ f1 = 0;
+ lock(&q->listlk);
while(n) {
- lock(&q->listlk);
bp = q->list;
q->list = bp->next;
bp->next = 0;
unlock(&q->listlk);
-
+ if(f1) {
+ freeb(f1);
+ f1 = 0;
+ }
l = BLEN(bp);
- if(n < l)
- n = l;
+ if(l > n)
+ l = n;
memmove(va, bp->rptr, l); /* Interruptable thru fault */
va += l;
bp->rptr += l;
n -= l;
- gotdelim = bp->flags&S_DELIM;
+ nread += l;
lock(&q->listlk);
- if(bp->rptr != bp->wptr) {
+ if(bp->rptr == bp->wptr)
+ f1 = bp;
+ else {
bp->next = q->list;
q->list = bp;
}
- else if(gotdelim)
+ if(bp->flags&S_DELIM) {
q->ndelim--;
- unlock(&q->listlk);
- if(bp->rptr == bp->wptr)
- freeb(bp);
- if(gotdelim)
break;
+ }
}
+ q->nb -= nread;
+ unlock(&q->listlk);
+ if(f1)
+ freeb(f1);
qunlock(&q->rd);
+ poperror();
+ if(q->nb < Flowctl)
+ wakeup(&q->flowr);
return nread;
}
+
+Block *
+muxclq(Dtq *q)
+{
+ Block *f;
+
+ f = q->list;
+ q->list = 0;
+ q->nb = 0;
+ q->ndelim = 0;
+ return f;
+}
M port/devnonet.c => port/devnonet.c +8 -4
@@ 303,6 303,7 @@ nonetopen(Chan *c, int omode)
void
nonetcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
@@ 345,15 346,15 @@ nonetread(Chan *c, void *a, long n, ulong offset)
cp = &noifc[c->dev].conv[STREAMID(c->qid.path)];
switch(t){
case Nraddrqid:
- return stringread(c, a, n, cp->raddr, offset);
+ return stringread(a, n, cp->raddr, offset);
case Naddrqid:
- return stringread(c, a, n, cp->addr, offset);
+ return stringread(a, n, cp->addr, offset);
case Nruserqid:
- return stringread(c, a, n, cp->ruser, offset);
+ return stringread(a, n, cp->ruser, offset);
case Nstatsqid:
sprint(stats, "sent: %d\nrcved: %d\nrexmit: %d\nbad: %d\n",
cp->sent, cp->rcvd, cp->rexmit, cp->bad);
- return stringread(c, a, n, stats, offset);
+ return stringread(a, n, stats, offset);
}
error(Eperm);
}
@@ 401,12 402,14 @@ nonetwrite(Chan *c, void *a, long n, ulong offset)
void
nonetremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
nonetwstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Eperm);
}
@@ 1418,6 1421,7 @@ nokproc(void *arg)
Noconv *cp, *ep;
Nomsg *mp;
+ USED(arg);
cp = 0;
ifc = 0;
if(waserror()){
M port/devpipe.c => port/devpipe.c +3 -0
@@ 193,18 193,21 @@ pipeopen(Chan *c, int omode)
void
pipecreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Egreg);
}
void
piperemove(Chan *c)
{
+ USED(c);
error(Egreg);
}
void
pipewstat(Chan *c, char *db)
{
+ USED(c, db);
error(Eperm);
}
M port/devproc.c => port/devproc.c +3 -0
@@ 189,12 189,14 @@ procopen(Chan *c, int omode)
void
proccreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
void
procremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
@@ 221,6 223,7 @@ procwstat(Chan *c, char *db)
void
procclose(Chan * c)
{
+ USED(c);
}
long
M port/devroot.c => port/devroot.c +5 -0
@@ 101,6 101,7 @@ rootopen(Chan *c, int omode)
void
rootcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
@@ 110,6 111,7 @@ rootcreate(Chan *c, char *name, int omode, ulong perm)
void
rootclose(Chan *c)
{
+ USED(c);
}
#include "boot.h"
@@ 156,17 158,20 @@ rootread(Chan *c, void *buf, long n, ulong offset)
long
rootwrite(Chan *c, void *buf, long n, ulong offset)
{
+ USED(c, buf, n, offset);
error(Egreg);
}
void
rootremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
rootwstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Eperm);
}
M port/devscc.c => port/devscc.c +21 -18
@@ 524,17 524,17 @@ loop:
enum{
Qdir= 0,
- Qtty0= STREAMQID(0, Sdataqid),
- Qtty0ctl= STREAMQID(0, Sctlqid),
- Qtty1= STREAMQID(1, Sdataqid),
- Qtty1ctl= STREAMQID(1, Sctlqid),
+ Qeia0= STREAMQID(0, Sdataqid),
+ Qeia0ctl= STREAMQID(0, Sctlqid),
+ Qeia1= STREAMQID(1, Sdataqid),
+ Qeia1ctl= STREAMQID(1, Sctlqid),
};
Dirtab sccdir[]={
- "tty0", {Qtty0}, 0, 0666,
- "tty0ctl", {Qtty0ctl}, 0, 0666,
- "tty1", {Qtty1}, 0, 0666,
- "tty1ctl", {Qtty1ctl}, 0, 0666,
+ "eia0", {Qeia0}, 0, 0666,
+ "eia0ctl", {Qeia0ctl}, 0, 0666,
+ "eia1", {Qeia1}, 0, 0666,
+ "eia1ctl", {Qeia1ctl}, 0, 0666,
};
#define NSCC (sizeof sccdir/sizeof(Dirtab))
@@ 585,11 585,11 @@ void
sccstat(Chan *c, char *dp)
{
switch(c->qid.path){
- case Qtty0:
- streamstat(c, dp, "tty0");
+ case Qeia0:
+ streamstat(c, dp, "eia0");
break;
- case Qtty1:
- streamstat(c, dp, "tty1");
+ case Qeia1:
+ streamstat(c, dp, "eia1");
break;
default:
devstat(c, dp, sccdir, NSCC, devgen);
@@ 603,12 603,12 @@ sccopen(Chan *c, int omode)
SCC *sp;
switch(c->qid.path){
- case Qtty0:
- case Qtty0ctl:
+ case Qeia0:
+ case Qeia0ctl:
sp = &scc[0];
break;
- case Qtty1:
- case Qtty1ctl:
+ case Qeia1:
+ case Qeia1ctl:
sp = &scc[1];
break;
default:
@@ 627,6 627,7 @@ sccopen(Chan *c, int omode)
void
scccreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c, name, omode, perm);
error(Eperm);
}
@@ 645,10 646,10 @@ sccread(Chan *c, void *buf, long n, ulong offset)
switch(c->qid.path&~CHDIR){
case Qdir:
return devdirread(c, buf, n, sccdir, NSCC, devgen);
- case Qtty1ctl:
+ case Qeia1ctl:
++sp;
/* fall through */
- case Qtty0ctl:
+ case Qeia0ctl:
if(offset)
return 0;
s = splhi();
@@ 668,11 669,13 @@ sccwrite(Chan *c, void *va, long n, ulong offset)
void
sccremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
sccwstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Eperm);
}
M port/devsrv.c => port/devsrv.c +2 -0
@@ 150,12 150,14 @@ srvremove(Chan *c)
void
srvwstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Egreg);
}
void
srvclose(Chan *c)
{
+ USED(c);
}
long
M port/ipdat.h => port/ipdat.h +2 -1
@@ 264,6 264,7 @@ struct Ipconv
{
QLock; /* Ref count lock */
int ref;
+ int index;
Qinfo *stproto; /* Stream protocol for this device */
Ipaddr dst; /* Destination from connect */
Port psrc; /* Source port */
@@ 450,7 451,7 @@ int seq_gt(int, int);
void appendb(Block **, Block *);
Ipconv *ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto);
void ipmkdir(Qinfo *, Dirtab *, Ipconv *);
-Ipconv *ipincoming(Ipconv*);
+Ipconv *ipincoming(Ipconv*, Ipconv*);
int inb_window(Tcpctl *, int);
Block *htontcp(Tcp *, Block *, Tcphdr *);
void start_timer(Timer *);
M port/net.c => port/net.c +91 -14
@@ 25,6 25,11 @@ netgen(Chan *c, void *vp, int ntab, int i, Dir *dp)
Qid q;
char buf[32];
Network *np = vp;
+ int t;
+ int id;
+ Netprot *p;
+ int perm;
+ char *o;
q.vers = 0;
@@ 34,7 39,7 @@ netgen(Chan *c, void *vp, int ntab, int i, Dir *dp)
case 0:
q.path = CHDIR | Q2nd;
strcpy(buf, np->name);
- devdir(c, q, buf, 0, eve, 0666, dp);
+ devdir(c, q, buf, 0, eve, 0555, dp);
break;
default:
return -1;
@@ 43,41 48,51 @@ netgen(Chan *c, void *vp, int ntab, int i, Dir *dp)
}
/* second level contains clone plus all the conversations */
- if(STREAMTYPE(c->qid.path) == Q2nd){
+ t = STREAMTYPE(c->qid.path);
+ if(t == Q2nd || t == Qclone){
if(i == 0){
q.path = Qclone;
devdir(c, q, "clone", 0, eve, 0666, dp);
}else if(i <= np->nconv){
q.path = CHDIR|STREAMQID(i-1, Q3rd);
sprint(buf, "%d", i-1);
- devdir(c, q, buf, 0, eve, 0666, dp);
+ devdir(c, q, buf, 0, eve, 0555, dp);
}else
return -1;
return 1;
}
/* third level depends on the number of info files */
+ id = STREAMID(c->qid.path);
+ p = &np->prot[id];
+ if(*p->owner){
+ o = p->owner;
+ perm = p->mode;
+ } else {
+ o = eve;
+ perm = 0666;
+ }
switch(i){
case 0:
q.path = STREAMQID(STREAMID(c->qid.path), Sdataqid);
- devdir(c, q, "data", 0, eve, 0666, dp);
+ devdir(c, q, "data", 0, o, perm, dp);
break;
case 1:
q.path = STREAMQID(STREAMID(c->qid.path), Sctlqid);
- devdir(c, q, "ctl", 0, eve, 0666, dp);
+ devdir(c, q, "ctl", 0, o, perm, dp);
break;
case 2:
if(np->listen == 0)
return 0;
q.path = STREAMQID(STREAMID(c->qid.path), Qlisten);
- devdir(c, q, "listen", 0, eve, 0666, dp);
+ devdir(c, q, "listen", 0, o, perm, dp);
break;
default:
i -= 3;
if(i >= np->ninfo)
return -1;
q.path = STREAMQID(STREAMID(c->qid.path), Qinf+i);
- devdir(c, q, np->info[i].name, 0, eve, 0666, dp);
+ devdir(c, q, np->info[i].name, 0, eve, 0444, dp);
break;
}
return 1;
@@ 117,7 132,7 @@ netstat(Chan *c, char *db, Network *np)
* here, which is good because we've lost the name by now.
*/
if(c->qid.path & CHDIR){
- devdir(c, c->qid, ".", 0L, eve, CHDIR|0700, &dir);
+ devdir(c, c->qid, ".", 0L, eve, CHDIR|0555, &dir);
convD2M(&dir, db);
return;
}
@@ 134,10 149,28 @@ netstat(Chan *c, char *db, Network *np)
}
}
+void
+netwstat(Chan *c, char *db, Network *np)
+{
+ Dir dir;
+ Netprot *p;
+
+ p = &np->prot[STREAMID(c->qid.path)];
+ lock(np);
+ if(strncmp(p->owner, u->p->user, NAMELEN)){
+ unlock(np);
+ error(Eperm);
+ }
+ convM2D(db, &dir);
+ strncpy(p->owner, dir.uid, NAMELEN);
+ p->mode = dir.mode;
+ unlock(np);
+}
+
Chan *
netopen(Chan *c, int omode, Network *np)
{
- int conv;
+ int id;
if(c->qid.path & CHDIR){
if(omode != OREAD)
@@ 146,14 179,19 @@ netopen(Chan *c, int omode, Network *np)
switch(STREAMTYPE(c->qid.path)){
case Sdataqid:
case Sctlqid:
+ id = STREAMID(c->qid.path);
+ if(netown(np, id, u->p->user, omode&7) < 0)
+ error(Eperm);
break;
case Qlisten:
- conv = (*np->listen)(c);
- c->qid.path = STREAMQID(conv, Sctlqid);
+ streamopen(c, np->devp);
+ id = (*np->listen)(c);
+ streamclose(c);
+ c->qid.path = STREAMQID(id, Sctlqid);
break;
case Qclone:
- conv = (*np->clone)(c);
- c->qid.path = STREAMQID(conv, Sctlqid);
+ id = (*np->clone)(c);
+ c->qid.path = STREAMQID(id, Sctlqid);
break;
default:
if(omode != OREAD)
@@ 191,5 229,44 @@ netread(Chan *c, void *a, long n, ulong offset, Network *np)
error(Ebadusefd);
(*np->info[t-Qinf].fill)(c, buf, sizeof(buf));
- return stringread(c, a, n, buf, offset);
+ return stringread(a, n, buf, offset);
+}
+
+int
+netown(Network *np, int id, char *o, int omode)
+{
+ static int access[] = { 0400, 0200, 0600, 0100 };
+ Netprot *p;
+ int mode;
+ int t;
+
+ p = &np->prot[id];
+ lock(np);
+ if(*p->owner){
+ if(strncmp(o, p->owner, NAMELEN) == 0) /* User */
+ mode = p->mode;
+ else if(strncmp(o, eve, NAMELEN) == 0) /* Bootes is group */
+ mode = p->mode<<3;
+ else
+ mode = p->mode<<6; /* Other */
+
+ t = access[omode&3];
+ if((t & mode) == t){
+ unlock(np);
+ return 0;
+ } else {
+ unlock(np);
+ return -1;
+ }
+ }
+ strncpy(p->owner, o, NAMELEN);
+ np->prot[id].mode = 0660;
+ unlock(np);
+ return 0;
+}
+
+void
+netdisown(Network *np, int id)
+{
+ *np->prot[id].owner = 0;
}
M port/page.c => port/page.c +1 -0
@@ 223,6 223,7 @@ newpage(int clear, Segment **s, ulong va)
int
ispages(void *p)
{
+ USED(p);
return palloc.freecount >= HIGHWATER;
}
M port/portdat.h => port/portdat.h +11 -3
@@ 10,13 10,14 @@ typedef struct Env Env;
typedef struct Envval Envval;
typedef struct Etherpkt Etherpkt;
typedef struct Fgrp Fgrp;
-typedef struct Ifile Ifile;
typedef struct Image Image;
typedef struct IOQ IOQ;
typedef struct KIOQ KIOQ;
typedef struct List List;
typedef struct Mount Mount;
typedef struct Mhead Mhead;
+typedef struct Netinf Netinf;
+typedef struct Netprot Netprot;
typedef struct Network Network;
typedef struct Note Note;
typedef struct Page Page;
@@ 622,13 623,19 @@ enum {
/*
* a multiplexed network
*/
-struct Ifile
+struct Netprot
+{
+ ulong mode;
+ char owner[NAMELEN];
+};
+struct Netinf
{
char *name;
void (*fill)(Chan*, char*, int);
};
struct Network
{
+ Lock;
char *name;
int nconv; /* max # of conversations */
Qinfo *devp; /* device end line disc */
@@ 636,7 643,8 @@ struct Network
int (*listen)(Chan*);
int (*clone)(Chan*);
int ninfo;
- Ifile info[5];
+ Netinf info[5];
+ Netprot *prot; /* protections */
};
#define MAJOR(q) ((q) >> 8)
#define MINOR(q) ((q) & 0xff)
M port/portfns.h => port/portfns.h +4 -4
@@ 1,7 1,4 @@
-#define SET(x) x = 0
-#define USED(x) if(x)
-
Alarm* alarm(int, void (*)(Alarm*), void*);
void alarminit(void);
Block* allocb(ulong);
@@ 123,11 120,14 @@ void mouseclock(void);
int mouseputc(IOQ*, int);
Chan* namec(char*, int, int, ulong);
void nameok(char*);
+void netdisown(Network*, int);
int netgen(Chan*, void*, int, int, Dir*);
Chan* netopen(Chan*, int, Network*);
+int netown(Network*, int, char*, int);
long netread(Chan*, void*, long, ulong, Network*);
void netstat(Chan*, char*, Network*);
int netwalk(Chan*, char*, Network*);
+void netwstat(Chan*, char*, Network*);
Alarm* newalarm(void);
Chan* newchan(void);
Egrp* newegrp(void);
@@ 224,7 224,7 @@ int streamparse(char*, Block*);
long streamread(Chan*, void*, long);
void streamstat(Chan*, char*, char*);
long streamwrite(Chan*, void*, long, int);
-long stringread(Chan*, void*, long, char*, ulong);
+long stringread(void*, long, char*, ulong);
void swapinit(void);
long syscall(Ureg*);
void tcpinit(void);
M port/print.c => port/print.c +5 -0
@@ 240,6 240,8 @@ dconv(Op *op)
static int
hconv(Op *op)
{
+
+ USED(op);
return -FSHORT;
}
@@ 247,6 249,7 @@ static int
lconv(Op *op)
{
+ USED(op);
return -FLONG;
}
@@ 268,6 271,8 @@ sconv(Op *op)
static int
uconv(Op *op)
{
+
+ USED(op);
return -FUNSIGN;
}
M port/proc.c => port/proc.c +2 -4
@@ 384,9 384,6 @@ postnote(Proc *p, int dolock, char *n, int flag)
Rendez *r;
Proc *d, **l;
- SET(k);
- USED(k);
-
if(dolock)
lock(&p->debug);
@@ 396,10 393,11 @@ postnote(Proc *p, int dolock, char *n, int flag)
errors("noted process disappeared");
}
+ SET(k);
if(u == 0 || p != u->p){
k = kmap(p->upage);
up = (User*)VA(k);
- }else
+ }else
up = u;
M port/segment.c => port/segment.c +1 -0
@@ 418,6 418,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
ulong newtop;
int i, sno;
+ USED(p);
if(va&KZERO) /* BUG: Only ok for now */
errors("bad virtual address");
M port/stil.c => port/stil.c +3 -2
@@ 1,4 1,4 @@
-/*
+
/*
* stil - Internet link protocol
*/
#include "u.h"
@@ 93,6 93,7 @@ ilclose(Queue *q)
ic->state = Ilclosed;
break;
}
+ netdisown(&s->ipinterface->net, s->index);
}
void
@@ 256,7 257,7 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
if(s->ilctl.state == Illistening)
if(s->pdst == 0)
if(s->dst == 0) {
- new = ipincoming(ipc);
+ new = ipincoming(ipc, s);
if(new == 0)
goto reset;
M port/stip.c => port/stip.c +1 -0
@@ 131,6 131,7 @@ newipifc(uchar ptcl, void (*recvfun)(Ipconv *, Block *bp),
static void
ipetherclose(Queue *q)
{
+ USED(q);
}
void
M port/stream.c => port/stream.c +3 -2
@@ 689,6 689,7 @@ prepend(Block *bp, int n)
void
nullput(Queue *q, Block *bp)
{
+ USED(q);
if(bp->type == M_HANGUP)
freeb(bp);
else {
@@ 1065,7 1066,7 @@ stputq(Queue *q, Block *bp)
* read a string. update the offset accordingly.
*/
long
-stringread(Chan *c, uchar *buf, long n, char *str, ulong offset)
+stringread(uchar *buf, long n, char *str, ulong offset)
{
long i;
@@ 1092,7 1093,7 @@ streamctlread(Chan *c, void *vbuf, long n)
s = c->stream;
if(STREAMTYPE(c->qid.path) == Sctlqid){
sprint(num, "%d", s->id);
- return stringread(c, buf, n, num, c->offset);
+ return stringread(buf, n, num, c->offset);
} else {
if(CHDIR & c->qid.path)
return devdirread(c, vbuf, n, 0, 0, streamgen);
M port/sturp.c => port/sturp.c +1 -1
@@ 167,7 167,7 @@ urpopen(Queue *q, Stream *s)
if(up == &urp[conf.nurp]){
q->ptr = 0;
WR(q)->ptr = 0;
- error(Egreg);
+ errors("out of urp structures");
}
q->ptr = q->other->ptr = up;
M port/swap.c => port/swap.c +2 -0
@@ 103,6 103,7 @@ pager(void *junk)
Segment *s;
int i;
+ USED(junk);
p = proctab(0);
ep = &p[conf.nproc];
for(;;) {
@@ 320,6 321,7 @@ executeio(void)
int
needpages(void *p)
{
+ USED(p);
return palloc.freecount < HIGHWATER+MAXHEADROOM;
}
M port/sysproc.c => port/sysproc.c +5 -0
@@ 21,6 21,7 @@ sysr1(ulong *arg)
long
sysfork(ulong *arg)
{
+ USED(arg);
return rfork(Forkfd);
}
@@ 393,6 394,7 @@ shargs(char *s, int n, char **ap)
int
return0(void *a)
{
+ USED(a);
return 0;
}
@@ 443,6 445,7 @@ syswait(ulong *arg)
long
sysdeath(ulong *arg)
{
+ USED(arg);
pprint("deprecated system call");
pexit("Suicide", 0);
}
@@ 500,6 503,7 @@ sysforkpgrp(ulong *arg)
long
sysnotify(ulong *arg)
{
+ USED(arg);
if(arg[0] != 0)
validaddr(arg[0], sizeof(ulong), 0);
u->notify = (int(*)(void*, char*))(arg[0]);
@@ 509,6 513,7 @@ sysnotify(ulong *arg)
long
sysnoted(ulong *arg)
{
+ USED(arg);
if(u->notified == 0)
error(Egreg);
return 0;
M port/tcpinput.c => port/tcpinput.c +1 -1
@@ 81,7 81,7 @@ tcp_input(Ipconv *ipc, Block *bp)
if(s->curlog >= s->backlog)
goto clear;
- new = ipincoming(ipc);
+ new = ipincoming(ipc, s);
if(new == 0)
goto clear;
M port/tcptimer.c => port/tcptimer.c +1 -0
@@ 19,6 19,7 @@ tcpackproc(void *junk)
Timer *t,*tp;
Timer *expired;
+ USED(junk);
for(;;) {
expired = 0;
M power/devduart.c => power/devduart.c +4 -4
@@ 696,8 696,8 @@ duartreset(void)
nduartport = 2*conf.nmach;
duartdir = ialloc(nduartport*2*sizeof(Dirtab), 0);
for(i = 0; i < nduartport; i++){
- sprint(duartdir[2*i].name, "tty%d", i);
- sprint(duartdir[2*i+1].name, "tty%dctl", i);
+ sprint(duartdir[2*i].name, "eia%d", i);
+ sprint(duartdir[2*i+1].name, "eia%dctl", i);
duartdir[2*i].length = duartdir[2*i+1].length = 0;
duartdir[2*i].perm = duartdir[2*i+1].perm = 0666;
duartdir[2*i].qid.path = STREAMQID(i, Sdataqid);
@@ 745,7 745,7 @@ duartstat(Chan *c, char *dp)
{
switch(STREAMTYPE(c->qid.path)){
case Sdataqid:
- streamstat(c, dp, "tty0");
+ streamstat(c, dp, "eia0");
break;
default:
devstat(c, dp, duartdir, 2*nduartport, devgen);
@@ 779,7 779,7 @@ duartopen(Chan *c, int omode)
void
duartcreate(Chan *c, char *name, int omode, ulong perm)
{
- errors("only God can create a tty");
+ errors(Eperm);
}
void
M power/main.c => power/main.c +1 -1
@@ 578,6 578,7 @@ confinit(void)
conf.nnoifc = 1;
conf.nnoconv = 32;
conf.nurp = 25;
+ conf.dkif = 1;
conf.nqueue = 5 * conf.nstream;
conf.nblock = 10 * conf.nstream;
conf.ipif = 8;
@@ 593,7 594,6 @@ confinit(void)
conf.copymode = 1; /* copy on reference */
conf.cntrlp = 1;
- conf.dkif = 2;
}
/*
M ss/clock.c => ss/clock.c +1 -1
@@ 13,7 13,7 @@ delay(int ms)
ulong t, *p;
int i;
- ms *= 2000; /* experimentally determined */
+ ms *= 3000; /* experimentally determined */
for(i=0; i<ms; i++)
;
}
M ss/dat.h => ss/dat.h +1 -0
@@ 52,6 52,7 @@ struct FPsave
{
long fsr;
long fpreg[32];
+ long pad; /* so fsr can be guaranteed at 4 mod 8 */
};
struct Conf
M ss/l.s => ss/l.s +11 -5
@@ 468,10 468,15 @@ TEXT putsegm(SB), $0
MOVW R8, (R7, 3)
RETURN
+/*
+ * in savefpregs and restfpregs, incoming R7 points to doubleword
+ * below where F0 will go; doubleword align in and backfill FSR
+ */
TEXT savefpregs(SB), $0
- MOVW FSR, 0(R7)
- ADD $4, R7 /* assumes R7 is now MOVD-aligned */
+ ADD $8, R7
+ ANDN $7, R7 /* now MOVD-aligned */
+ MOVW FSR, -4(R7)
MOVD F0, (0*4)(R7)
MOVD F2, (2*4)(R7)
@@ 501,10 506,11 @@ TEXT restfpregs(SB), $0
OR $PSREF, R8
MOVW R8, PSR
- NOOP
+ ADD $8, R7
+ ANDN $7, R7 /* now MOVD-aligned */
+ OR R0, R0
- MOVW (R7), FSR
- ADD $4, R7 /* assumes R7 is now MOVD-aligned */
+ MOVW -4(R7), FSR
MOVD (0*4)(R7), F0
MOVD (2*4)(R7), F2
M ss/main.c => ss/main.c +0 -2
@@ 40,8 40,6 @@ main(void)
alarminit();
chandevreset();
streaminit();
-/* serviceinit(); /**/
-/* filsysinit(); /**/
pageinit();
userinit();
clockinit();
M ss/trap.c => ss/trap.c +1 -1
@@ 414,7 414,7 @@ setregisters(Ureg *xp, char *pureg, char *uva, int n)
{
ulong psr;
- status = xp->psr;
+ psr = xp->psr;
memmove(pureg, uva, n);
xp->psr = psr;
}