~kris/9p

9hist

409231a272633b8b76fe53c6a1e26252adb1a097 — David du Colombier 25 years ago 7bff2ba
Plan 9 from Bell Labs 2001-09-18
5 files changed, 108 insertions(+), 99 deletions(-)

M ip/rudp.c
M pc/devusb.c
M port/devbridge.c
M port/devmnt.c
M port/devsdp.c
M ip/rudp.c => ip/rudp.c +2 -2
@@ 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);

M pc/devusb.c => pc/devusb.c +34 -29
@@ 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);

M port/devbridge.c => port/devbridge.c +43 -42
@@ 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<nelem(bridgedirtab)) {


@@ 468,15 470,15 @@ bridgegen(Chan *c, Dirtab*, int, int s, Dir *dp)
		s -= nelem(bridgedirtab);
		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; i<Maxport; i++)


@@ 564,7 566,7 @@ portbind(Bridge *b, int argc, char *argv[])
		nexterror();
	}
	port->type = 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,

M port/devmnt.c => port/devmnt.c +4 -1
@@ 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)

M port/devsdp.c => port/devsdp.c +25 -25
@@ 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<nelem(sdpdirtab)) {


@@ 754,15 755,15 @@ sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp)
		s -= nelem(sdpdirtab);
		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,