From 409231a272633b8b76fe53c6a1e26252adb1a097 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 18 Sep 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-09-18 --- ip/rudp.c | 4 +-- pc/devusb.c | 63 ++++++++++++++++++----------------- port/devbridge.c | 85 ++++++++++++++++++++++++------------------------ port/devmnt.c | 5 ++- port/devsdp.c | 50 ++++++++++++++-------------- 5 files changed, 108 insertions(+), 99 deletions(-) diff --git a/ip/rudp.c b/ip/rudp.c index 86f1b42e0965d226e6b3f5bf77c76495b315cb3c..f6daa50f2bceb9814f7277cb87d3bcbfef325519 100644 --- a/ip/rudp.c +++ b/ip/rudp.c @@ -197,7 +197,7 @@ static void rudpstartackproc(Proto *rudp) { Rudppriv *rpriv; - char kpname[NAMELEN]; + char kpname[KNAMELEN]; rpriv = rudp->priv; if(rpriv->ackprocstarted == 0){ @@ -1032,7 +1032,7 @@ relhangup(Conv *c, Reliable *r) { int n; Block *bp; - char hup[ERRLEN]; + char hup[ERRMAX]; n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port); qproduce(c->eq, hup, n); diff --git a/pc/devusb.c b/pc/devusb.c index d9201ee36751e51d7fe993f7612df2d8a3a6507f..5e2060f344695b251d726d948f10f94ce95ee759 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -204,6 +204,7 @@ struct Endpt { int data01; /* 0=DATA0, 1=DATA1 */ byte eof; ulong csp; + byte isopen; /* ep operations forbidde on open endpoints */ byte mode; /* OREAD, OWRITE, ORDWR */ byte nbuf; /* number of buffers allowed */ byte iso; @@ -724,7 +725,7 @@ isorecv(Endpt *e, Block *b, int pid) td = e->etd; if (td == nil) - panic("usb: isoxmit"); + panic("usb: isorecv"); while(td->status & Active){ XPRINT("isorecv: sleep %lux\n", &e->wr); sleep(&e->wr, tdisready, e->etd); @@ -741,13 +742,9 @@ isorecv(Endpt *e, Block *b, int pid) ob->wp = ob->rp + n; td->buffer = PADDR(b->rp); td->bp = b; - n = BLEN(b); id = (e->x<<7)|(e->dev->x&0x7F); - td->dev = ((n-1)<<21) | ((id&0x7FF)<<8) | pid; - if ((ioc++ & 0xff) == 0) - td->status = ErrLimit3 | Active | IsoSelect | IOC; - else - td->status = ErrLimit3 | Active | IsoSelect; + td->dev = ((e->maxpkt-1)<<21) | ((id&0x7FF)<<8) | pid; + td->status = ErrLimit3 | Active | IsoSelect | IOC; e->etd = td->next; return ob; } @@ -876,15 +873,20 @@ schedendpt(Endpt *e) if(!e->iso || e->sched >= 0) return 0; ub = &ubus; - + + if (e->isopen){ + return -1; + } + e->curblock = allocb(e->maxpkt); if (e->curblock == nil) panic("schedept: allocb"); e->curbytes = 0; - ilock(ub); e->sched = usbsched(ub, e->pollms, e->maxpkt); - if(e->sched < 0) + if(e->sched < 0){ + qunlock(&usbstate); return -1; + } /* Allocate TDs from the NISOTD entries on each of the * frames. Link them circularly so they can be walked easily @@ -902,12 +904,20 @@ schedendpt(Endpt *e) if(j == NISOTD) panic("usb: no td entries despite schedulability test"); td->ep = e; - if (td->bp) + if(td->bp) panic("usb: schedendpt: block not empty"); td->bp = allocb(e->maxpkt); - if (td->bp == nil) + if(td->bp == nil) panic("schedept: allocb"); - if (i == e->sched){ + if (e->mode == OREAD){ + int id; + /* enable receive on this entry */ + td->buffer = PADDR(td->bp->rp); + id = (e->x<<7)|(e->dev->x&0x7F); + td->dev = ((e->maxpkt-1)<<21) | ((id&0x7FF)<<8) | TokIN; + td->status = ErrLimit3 | Active | IsoSelect | IOC; + } + if(i == e->sched){ first = td; e->etd = td; }else{ @@ -917,7 +927,6 @@ schedendpt(Endpt *e) ub->frameld[i] += e->maxpkt; } *prev = first; /* complete circular link */ - iunlock(ub); return 0; } @@ -931,8 +940,7 @@ unschedendpt(Endpt *e) ub = &ubus; if(!e->iso || (q = e->sched) < 0) return; - ilock(ub); - + for (td = e->etd; q < NFRAME; q += e->pollms){ ub->frameld[q] -= e->maxpkt; next = td->next; @@ -944,8 +952,6 @@ unschedendpt(Endpt *e) } freeb(e->curblock); e->sched = -1; - - iunlock(ub); } static Endpt * @@ -999,6 +1005,7 @@ freept(Endpt *e) { if(e != nil && decref(e) == 0){ XPRINT("freept(%d,%d)\n", e->dev->x, e->x); + e->isopen = 0; unschedendpt(e); e->dev->ep[e->x] = nil; eptdeactivate(e); @@ -1555,6 +1562,7 @@ usbopen(Chan *c, int omode) if(schedendpt(e) < 0) error("can't schedule USB endpoint"); eptactivate(e); + e->isopen = 1; } incref(d); break; @@ -1643,12 +1651,6 @@ readusb(Endpt *e, void *a, long n) if (e->iso){ if (e->curbytes == 0){ /* calculate size of next receive buffer */ - e->psize = (e->hz + e->remain)*e->pollms/1000; - e->remain = (e->hz + e->remain)*e->pollms%1000; - e->psize *= e->samplesz; - if (e->psize > e->maxpkt) - panic("packet size > maximum"); - e->curblock->wp = e->curblock->rp + e->psize; /* put empty buffer on receive queue and get next full one */ b = isorecv(e, e->curblock, TokIN); /* bytes to consume in b: */ @@ -1965,17 +1967,18 @@ usbwrite(Chan *c, void *a, long n, vlong) } if((e = d->ep[i]) == nil) e = devendpt(d, i, 1); + qlock(&usbstate); if(waserror()){ freept(e); + qunlock(&usbstate); nexterror(); } - if (e->iso && e->sched >= 0){ - unschedendpt(e); - } - e->iso = 0; + if (e->isopen) + error(Eperm); if(strcmp(fields[2], "bulk") == 0){ Ctlr *ub; + e->iso = 0; /* ep n `bulk' mode maxpkt nbuf */ ub = &ubus; /* Each bulk device gets a queue head hanging off the @@ -2018,7 +2021,8 @@ usbwrite(Chan *c, void *a, long n, vlong) if(i >= 1 && i <= 100000){ /* Hz */ e->hz = i; - e->remain = 999/e->pollms; + // e->remain = 999/e->pollms; + e->remain = 0; }else { XPRINT("field 5: 1 < %d <= 100000 Hz\n", i); error(Ebadarg); @@ -2027,6 +2031,7 @@ usbwrite(Chan *c, void *a, long n, vlong) e->iso = 1; } poperror(); + qunlock(&usbstate); }else { XPRINT("command %s, fields %d\n", fields[0], nf); error(Ebadarg); diff --git a/port/devbridge.c b/port/devbridge.c index 0fce23ac56286a4089d1b0960ad29eb43de18d0e..91176800f06d381c0a5b1c54a30cd58de4a13bd4 100644 --- a/port/devbridge.c +++ b/port/devbridge.c @@ -30,7 +30,7 @@ enum MaxQ, Maxbridge= 4, - Maxport= 64, // power of 2 + Maxport= 128, // power of 2 CacheHash= 257, // prime CacheLook= 5, // how many cache entries to examine CacheSize= (CacheHash+CacheLook-1), @@ -74,8 +74,8 @@ static Logflag logflags[] = static Dirtab *dirtab[MaxQ]; -#define TYPE(x) ((x).path & 0xff) -#define PORT(x) (((x).path >> 8)&(Maxport-1)) +#define TYPE(x) (((ulong)(x).path) & 0xff) +#define PORT(x) ((((ulong)(x).path) >> 8)&(Maxport-1)) #define QID(x, y) (((x)<<8) | (y)) struct Centry @@ -118,7 +118,7 @@ struct Port // the following uniquely identifies the port int type; - char name[NAMELEN]; + char name[KNAMELEN]; // owner hash - avoids bind/unbind races ulong ownhash; @@ -183,7 +183,7 @@ static int m2p[] = { [ORDWR] 6 }; -static int bridgegen(Chan *c, Dirtab*, int, int s, Dir *dp); +static int bridgegen(Chan *c, char*, Dirtab*, int, int s, Dir *dp); static void portbind(Bridge *b, int argc, char *argv[]); static void portunbind(Bridge *b, int argc, char *argv[]); static void etherread(void *a); @@ -222,22 +222,22 @@ bridgeattach(char* spec) error("bad specification"); c = devattach('B', spec); - c->qid = (Qid){QID(0, Qtopdir)|CHDIR, 0}; + mkqid(&c->qid, QID(0, Qtopdir), 0, QTDIR); c->dev = dev; return c; } -static int -bridgewalk(Chan *c, char *name) +static Walkqid* +bridgewalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, 0, 0, bridgegen); + return devwalk(c, nc, name, nname, (Dirtab*)0, 0, bridgegen); } -static void -bridgestat(Chan* c, char* db) +static int +bridgestat(Chan* c, uchar* db, int n) { - devstat(c, db, nil, 0, bridgegen); + return devstat(c, db, n, (Dirtab *)0, 0L, bridgegen); } static Chan* @@ -416,11 +416,10 @@ bridgewrite(Chan *c, void *a, long n, vlong off) } static int -bridgegen(Chan *c, Dirtab*, int, int s, Dir *dp) +bridgegen(Chan *c, char *, Dirtab*, int, int s, Dir *dp) { Bridge *b = bridgetab + c->dev; int type = TYPE(c->qid); - char buf[32]; Dirtab *dt; Qid qid; @@ -428,12 +427,14 @@ bridgegen(Chan *c, Dirtab*, int, int s, Dir *dp) switch(TYPE(c->qid)){ case Qtopdir: case Qbridgedir: - snprint(buf, sizeof(buf), "#B%ld", c->dev); - devdir(c, (Qid){CHDIR|Qtopdir, 0}, buf, 0, eve, 0555, dp); + snprint(up->genbuf, sizeof(up->genbuf), "#B%ld", c->dev); + mkqid(&qid, Qtopdir, 0, QTDIR); + devdir(c, qid, up->genbuf, 0, eve, 0555, dp); break; case Qportdir: - sprint(buf, "bridge%ld", c->dev); - devdir(c, (Qid){CHDIR|Qbridgedir, 0}, buf, 0, eve, 0555, dp); + snprint(up->genbuf, sizeof(up->genbuf), "bridge%ld", c->dev); + mkqid(&qid, Qbridgedir, 0, QTDIR); + devdir(c, qid, up->genbuf, 0, eve, 0555, dp); break; default: panic("bridgewalk %lux", c->qid.path); @@ -444,7 +445,7 @@ bridgegen(Chan *c, Dirtab*, int, int s, Dir *dp) switch(type) { default: // non directory entries end up here - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) panic("bridgegen: unexpected directory"); if(s != 0) return -1; @@ -456,8 +457,9 @@ bridgegen(Chan *c, Dirtab*, int, int s, Dir *dp) case Qtopdir: if(s != 0) return -1; - sprint(buf, "bridge%ld", c->dev); - devdir(c, (Qid){QID(0,Qbridgedir)|CHDIR,0}, buf, 0, eve, 0555, dp); + snprint(up->genbuf, sizeof(up->genbuf), "bridge%ld", c->dev); + mkqid(&qid, QID(0, Qbridgedir), 0, QTDIR); + devdir(c, qid, up->genbuf, 0, eve, 0555, dp); return 1; case Qbridgedir: if(s= b->nport) return -1; - qid = (Qid){QID(s,Qportdir)|CHDIR, 0}; - snprint(buf, sizeof(buf), "%d", s); - devdir(c, qid, buf, 0, eve, 0555, dp); + mkqid(&qid, QID(s, Qportdir), 0, QTDIR); + snprint(up->genbuf, sizeof(up->genbuf), "%d", s); + devdir(c, qid, up->genbuf, 0, eve, 0555, dp); return 1; case Qportdir: if(s>=nelem(portdirtab)) return -1; dt = portdirtab+s; - qid = (Qid){QID(PORT(c->qid),TYPE(dt->qid)),0}; + mkqid(&qid, QID(PORT(c->qid),TYPE(dt->qid)), 0, QTFILE); devdir(c, qid, dt->name, dt->length, eve, dt->perm, dp); return 1; } @@ -511,31 +513,31 @@ static void portbind(Bridge *b, int argc, char *argv[]) { Port *port; - char path[8*NAMELEN]; + char path[8*KNAMELEN]; char buf[100]; char *dev, *dev2=nil, *p; Chan *ctl; int type=0, i, n; char *usage = "usage: bind ether|tunnel name ownhash dev [dev2]"; - char name[NAMELEN]; + char name[KNAMELEN]; ulong ownhash; - memset(name, 0, NAMELEN); + memset(name, 0, KNAMELEN); if(argc < 4) error(usage); if(strcmp(argv[0], "ether") == 0) { if(argc != 4) error(usage); type = Tether; - strncpy(name, argv[1], NAMELEN); - name[NAMELEN-1] = 0; + strncpy(name, argv[1], KNAMELEN); + name[KNAMELEN-1] = 0; // parseaddr(addr, argv[1], Eaddrlen); } else if(strcmp(argv[0], "tunnel") == 0) { if(argc != 5) error(usage); type = Ttun; - strncpy(name, argv[1], NAMELEN); - name[NAMELEN-1] = 0; + strncpy(name, argv[1], KNAMELEN); + name[KNAMELEN-1] = 0; // parseip(addr, argv[1]); dev2 = argv[4]; } else @@ -546,7 +548,7 @@ portbind(Bridge *b, int argc, char *argv[]) port = b->port[i]; if(port != nil) if(port->type == type) - if(memcmp(port->name, name, NAMELEN) == 0) + if(memcmp(port->name, name, KNAMELEN) == 0) error("port in use"); } for(i=0; itype = type; - memmove(port->name, name, NAMELEN); + memmove(port->name, name, KNAMELEN); switch(port->type) { default: panic("portbind: unknown port type: %d", type); case Tether: @@ -627,21 +629,21 @@ portunbind(Bridge *b, int argc, char *argv[]) Port *port=nil; int type=0, i; char *usage = "usage: unbind ether|tunnel addr [ownhash]"; - char name[NAMELEN]; + char name[KNAMELEN]; ulong ownhash; - memset(name, 0, NAMELEN); + memset(name, 0, KNAMELEN); if(argc < 2 || argc > 3) error(usage); if(strcmp(argv[0], "ether") == 0) { type = Tether; - strncpy(name, argv[1], NAMELEN); - name[NAMELEN-1] = 0; + strncpy(name, argv[1], KNAMELEN); + name[KNAMELEN-1] = 0; // parseaddr(addr, argv[1], Eaddrlen); } else if(strcmp(argv[0], "tunnel") == 0) { type = Ttun; - strncpy(name, argv[1], NAMELEN); - name[NAMELEN-1] = 0; + strncpy(name, argv[1], KNAMELEN); + name[KNAMELEN-1] = 0; // parseip(addr, argv[1]); } else error(usage); @@ -653,7 +655,7 @@ portunbind(Bridge *b, int argc, char *argv[]) port = b->port[i]; if(port != nil) if(port->type == type) - if(memcmp(port->name, name, NAMELEN) == 0) + if(memcmp(port->name, name, KNAMELEN) == 0) break; } if(i == b->nport) @@ -1189,7 +1191,6 @@ Dev bridgedevtab = { devreset, bridgeinit, bridgeattach, - devclone, bridgewalk, bridgestat, bridgeopen, diff --git a/port/devmnt.c b/port/devmnt.c index 6548b7a0f89d0169ffcda42f2f656ec21707f71c..ed91cf6226d0bdd3434eb2039ba0680dadfbdb92 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -184,8 +184,11 @@ mntversion(Chan *c, char *version, int msize, int returnlen) l = convM2S(msg, k, &f); if(l != k) error("bad fversion conversion on reply"); - if(f.type != Rversion) + if(f.type != Rversion){ + if(f.type == Rerror) + error(f.ename); error("unexpected reply type in fversion"); + } if(f.msize > msize) error("server tries to increase msize in fversion"); if(f.msize<256 || f.msize>1024*1024) diff --git a/port/devsdp.c b/port/devsdp.c index f966136e2ff5d1412115515a315397bb251f97a6..2efbb6a54cd300c097025ccf6f28bdced66d9180 100644 --- a/port/devsdp.c +++ b/port/devsdp.c @@ -49,8 +49,8 @@ enum NCompStats = 8, }; -#define TYPE(x) ((x).path & 0xff) -#define CONV(x) (((x).path >> 8)&(Maxconv-1)) +#define TYPE(x) (((ulong)(x).path) & 0xff) +#define CONV(x) ((((ulong)(x).path) >> 8)&(Maxconv-1)) #define QID(x, y) (((x)<<8) | (y)) struct Stats @@ -144,7 +144,7 @@ struct Conv { Chan *chan; // packet channel char *channame; - char owner[NAMELEN]; /* protections */ + char owner[KNAMELEN]; /* protections */ int perm; Algorithm *auth; @@ -283,7 +283,7 @@ static char *convstatename[] = { [CClosed] "Closed", }; -static int sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp); +static int sdpgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp); static Conv *sdpclone(Sdp *sdp); static void sdpackproc(void *a); static void onewaycleanup(OneWay *ow); @@ -375,7 +375,7 @@ sdpattach(char* spec) error("bad specification"); c = devattach('E', spec); - c->qid = (Qid){QID(0, Qtopdir)|CHDIR, 0}; + c->qid = (Qid){QID(0, Qtopdir), 0, QTDIR}; c->dev = dev; sdp = sdptab + dev; @@ -392,19 +392,18 @@ sdpattach(char* spec) return c; } -static int -sdpwalk(Chan *c, char *name) +static Walkqid* +sdpwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, 0, 0, sdpgen); + return devwalk(c, nc, name, nname, 0, 0, sdpgen); } -static void -sdpstat(Chan* c, char* db) +static int +sdpstat(Chan* c, uchar* db, int n) { - devstat(c, db, nil, 0, sdpgen); + return devstat(c, db, n, nil, 0, sdpgen); } - static Chan* sdpopen(Chan* ch, int omode) { @@ -703,11 +702,10 @@ sdpbwrite(Chan *ch, Block *bp, ulong offset) } static int -sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp) +sdpgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) { Sdp *sdp = sdptab + c->dev; int type = TYPE(c->qid); - char buf[32]; Dirtab *dt; Qid qid; @@ -715,12 +713,14 @@ sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp) switch(TYPE(c->qid)){ case Qtopdir: case Qsdpdir: - snprint(buf, sizeof(buf), "#E%ld", c->dev); - devdir(c, (Qid){CHDIR|Qtopdir, 0}, buf, 0, eve, 0555, dp); + snprint(up->genbuf, sizeof(up->genbuf), "#E%ld", c->dev); + mkqid(&qid, Qtopdir, 0, QTDIR); + devdir(c, qid, up->genbuf, 0, eve, 0555, dp); break; case Qconvdir: - snprint(buf, sizeof(buf), "%d", s); - devdir(c, (Qid){CHDIR|Qsdpdir, 0}, buf, 0, eve, 0555, dp); + snprint(up->genbuf, sizeof(up->genbuf), "%d", s); + mkqid(&qid, Qsdpdir, 0, QTDIR); + devdir(c, qid, up->genbuf, 0, eve, 0555, dp); break; default: panic("sdpwalk %lux", c->qid.path); @@ -731,7 +731,7 @@ sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp) switch(type) { default: // non directory entries end up here - if(c->qid.path & CHDIR) + if(c->qid.type & QTDIR) panic("sdpgen: unexpected directory"); if(s != 0) return -1; @@ -743,7 +743,8 @@ sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp) case Qtopdir: if(s != 0) return -1; - devdir(c, (Qid){QID(0,Qsdpdir)|CHDIR,0}, "sdp", 0, eve, 0555, dp); + mkqid(&qid, QID(0, Qsdpdir), 0, QTDIR); + devdir(c, qid, "sdp", 0, eve, 0555, dp); return 1; case Qsdpdir: if(s= sdp->nconv) return -1; - qid = (Qid){QID(s,Qconvdir)|CHDIR, 0}; - snprint(buf, sizeof(buf), "%d", s); - devdir(c, qid, buf, 0, eve, 0555, dp); + mkqid(&qid, QID(s, Qconvdir), 0, QTDIR); + snprint(up->genbuf, sizeof(up->genbuf), "%d", s); + devdir(c, qid, up->genbuf, 0, eve, 0555, dp); return 1; case Qconvdir: if(s>=nelem(convdirtab)) return -1; dt = convdirtab+s; - qid = (Qid){QID(CONV(c->qid),TYPE(dt->qid)),0}; + mkqid(&qid, QID(CONV(c->qid),TYPE(dt->qid)), 0, QTFILE); devdir(c, qid, dt->name, dt->length, eve, dt->perm, dp); return 1; } @@ -935,7 +936,6 @@ Dev sdpdevtab = { devreset, sdpinit, sdpattach, - devclone, sdpwalk, sdpstat, sdpopen,