~kris/9p

9hist

a9d043d20ab911b2ed1331b57f5d96a4735d2396 — David du Colombier 34 years ago 325456e
Plan 9 from Bell Labs 1991-10-19
7 files changed, 160 insertions(+), 56 deletions(-)

M port/devip.c
M port/devwren.c
M port/ipdat.h
M port/stil.c
M port/tcpinput.c
M port/tcpoutput.c
M power/devhotrod.c
M port/devip.c => port/devip.c +9 -6
@@ 17,7 17,7 @@ enum

int udpsum = 1;

Queue	*Tcpoutput;		/* Tcp to lance output channel */
Queue	*Ipoutput;		/* Control message stream for tcp/il */
Ipifc	*ipifc;			/* IP protocol interfaces for stip */
Ipconv	*ipconv[Nrprotocol];	/* Connections for each protocol */
Dirtab  *ipdir[Nrprotocol];	/* Connection directory structures */


@@ 609,14 609,17 @@ void
tcpstopen(Queue *q, Stream *s)
{
	Ipconv *ipc;
	static int tcpkprocs;

	/* Start tcp service processes */
	if(!Tcpoutput) {
		Tcpoutput = WR(q);
		/* This never goes away - we use this queue to send acks/rejects */
	if(!Ipoutput) {
		Ipoutput = WR(q);
		s->opens++;
		s->inuse++;
		/* Flow control and tcp timer processes */
	}

	/* Flow control and tcp timer processes */
	if(tcpkprocs == 0) {
		tcpkprocs = 1;
		kproc("tcpack", tcpackproc, 0);
		kproc("tcpflow", tcpflow, &ipconv[s->dev]);


M port/devwren.c => port/devwren.c +17 -26
@@ 14,7 14,8 @@ typedef struct Drive		Drive;

enum {
	Npart=		8+2,	/* 8 sub partitions, disk, and partition */
	Ndisk=		64,	/* maximum disks; must be power of 2 or change DRIVE */
	Ndisk=		64,	/* maximum disks; if you change it, you must
				   map from dev to disk */

	/* file types */
	Qdir=		0,


@@ 49,30 50,20 @@ static long	wrenio(Drive *, Partition *, int, char *, ulong, ulong);
static int
wrendev(char *p)
{
	int dev = 0;
	int drive, unit;

	if(p == 0 || p[0] == 0)
		goto out;
	if(p == 0 || p[0] == '\0')
		return 0;
	if(p[0] < '0' || p[0] > '7')
		goto cant;
	dev = (p[0] - '0') << 3;
	if(p[1] == 0)
		goto out;
	if(p[1] != '.')
		goto cant;
	if(p[2] == 0)
		goto out;
	if(p[2] < '0' || p[2] > '7')
		goto cant;
	dev |= p[2] - '0';
	if(p[3] != 0)
		goto cant;
out:
	if(dev >= Ndisk)
		error(Ebadarg);
	return dev;
cant:
	error(Ebadarg);
		errors("bad scsi drive specifier");
	drive = p[0] - '0';
	unit = 0;
	if(p[1]){
		if(p[1] != '.' || p[2] < '0' || p[2] > '7' || p[3] != '\0')
			errors("bad scsi unit specifier");
		unit = p[2] - '0';
	}
	return (drive << 3) | unit;
}

static int


@@ 191,7 182,7 @@ wrenread(Chan *c, char *a, long n, ulong offset)

	d = &wren[DRIVE(c->qid.path)];
	if(d->npart == 0)
		errors("bad drive");
		errors("drive repartitioned");
	p = &d->p[PART(c->qid.path)];
	return wrenio(d, p, 0, a, n, offset);
}


@@ 204,7 195,7 @@ wrenwrite(Chan *c, char *a, long n, ulong offset)

	d = &wren[DRIVE(c->qid.path)];
	if(d->npart == 0)
		errors("bad drive");
		errors("drive repartitioned");
	p = &d->p[PART(c->qid.path)];
	return wrenio(d, p, 1, a, n, offset);
}


@@ 216,7 207,7 @@ wrenio(Drive *d, Partition *p, int write, char *a, ulong n, ulong offset)
	ulong block;

	if(n % d->bytes || offset % d->bytes)
		error(Ebadarg);
		errors("io not block aligned");
	block = offset / d->bytes + p->start;
	if(block >= p->end)
		return 0;

M port/ipdat.h => port/ipdat.h +3 -1
@@ 82,7 82,7 @@ struct Ilhdr
	uchar	cksum[2];	/* Header checksum */
	uchar	src[4];		/* Ip source */
	uchar	dst[4];		/* Ip destination */
#define IL_HDRSIZE	16	
#define IL_HDRSIZE	18	
	uchar	ilsum[2];	/* Checksum including header */
	uchar	illen[2];	/* Packet length */
	uchar	iltype;		/* Packet type */


@@ 95,6 95,7 @@ struct Ilhdr

struct Ilcb				/* Control block */
{
	Lock;
	int	state;
	Block	*unacked;
	Block	*unackedtail;


@@ 527,3 528,4 @@ extern Qinfo tcpinfo;
extern Qinfo ipinfo;
extern Qinfo udpinfo;
extern Qinfo ilinfo;
extern Queue *Ipoutput;

M port/stil.c => port/stil.c +124 -16
@@ 13,7 13,7 @@

#define DPRINT if(pip)print
int ilcksum = 1;
Queue	*Iloutput;		/* Il to lance output channel */

static int initseq = 25000;
char *ilstate[] = { "Closed", "Syncer", "Syncee", "Established", "Listening", "Closing" };



@@ 25,13 25,18 @@ void
ilopen(Queue *q, Stream *s)
{
	Ipconv *ipc;
	static int ilkproc;

	/* Start il service processes */
	if(!Iloutput) {
		Iloutput = WR(q);
	if(!Ipoutput) {
		Ipoutput = WR(q);
		/* This never goes away - we use this queue to send acks/rejects */
		s->opens++;
		s->inuse++;
	}

	if(ilkproc == 0) {
		ilkproc = 1;
		kproc("ilack", ilackproc, 0);
	}



@@ 62,11 67,18 @@ iloput(Queue *q, Block *bp)
	int dlen;
	Block *np;

	/* Prepend udp header to packet and pass on to ip layer */
	ipc = (Ipconv *)(q->ptr);
	if(ipc->psrc == 0)
		error(Enoport);

	switch(ipc->ilctl.state) {
	case Ilclosed:
	case Ilsyncee:
	case Illistening:
	case Ilclosing:
		error(Ehungup);
	}

	if(bp->type != M_DATA) {
		freeb(bp);
		error(Ebadctl);


@@ 90,7 102,12 @@ iloput(Queue *q, Block *bp)
	ih = (Ilhdr *)(bp->rptr);
	ic = &ipc->ilctl;

	hnputs(ih->illen, dlen+IL_EHSIZE+IL_HDRSIZE);
	/* Ip fields */
	hnputl(ih->src, Myip);
	hnputl(ih->dst, ipc->dst);
	ih->proto = IP_ILPROTO;
	/* Il fields */
	hnputs(ih->illen, dlen+IL_HDRSIZE);
	hnputs(ih->ilsrc, ipc->psrc);
	hnputs(ih->ildst, ipc->pdst);
	ih->iltype = Ildata;


@@ 104,8 121,20 @@ iloput(Queue *q, Block *bp)
	if(ilcksum)
		hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, dlen+IL_HDRSIZE));

	ilackq(ic, bp);

	PUTNEXT(q, bp);
}

void
ilackq(Ilctl *ic, Block *bp)
{
	Block *np;

	/* Enqueue a copy on the unacked queue in case this one gets lost */
	np = copyb(bp, blen(bp));

	lock(ic);
	if(ic->unacked) {
		ic->unackedtail->next = np;
		ic->unackedtail = np;


@@ 115,8 144,33 @@ iloput(Queue *q, Block *bp)
		ic->unackedtail = np;
	}
	np->next = 0;
	unlock(ic);
}

	PUTNEXT(q, bp);
void
ilackto(Ilctl *ic, ulong ackto)
{
	Ilhdr *h;
	Block *bp;

	for(;;) {
		lock(ic);
		if(ic->unacked) {
			h = (Ilhdr *)ic->unacked->rptr;
			if(ackto < hngetl(h->ilack)) {
				unlock(ic);
				break;	
			}
			bp = ic->unacked;
			ic->unacked = bp->next;
			unlock(ic);
			freeb(bp);
		}
		else {
			unlock(ic);
			break;
		}
	}
}

void


@@ 143,29 197,79 @@ ilrcvmsg(Ipconv *ipc, Block *bp)
		goto drop;
	}

	s = ip_conn(ipc, nhgets(ih->ildst), nhgets(ih->ilsrc), nhgetl(ih->src), IP_ILPROTO);
	if(s == 0) {
		ilsendctl(0, ih, Ilreset);
		goto drop;
	etab = &ipc[conf.ip];
	for(s = ipc; s < etab; s++) {
		if(s->sport == ih->ildst && s->dport == ih->ilsrc) {
			ilprocess(s, ih, bp);
			return;
		}
			
	}

	
drop:
	for(s = ipc; s < etab; s++) {
		if(s->state == 	Illistening && s->sport == 0) {
			/* Do the listener stuff */
			ilprocess(s, ih, bp);
			return;
		}
	}
	ilsendctl(0, ih, Ilreset);
	freeb(bp);
}

void
ilsendctl(Ipconv *ipc, Ilhdr *inih, int type)
ilprocess(Ipconv *s, Ihdr *h, Block *bp)
{
	switch(s->ilctl.state) {
	case Ilclosed:
	case Ilclosing:
	case Illistener:
		error(Ehungup);
	}

	switch(h->type) {
	case Ilsync:
		if(s->ilctl.state == Ilsync)
			s->ilctl.state = Ilestablished;
		freeb(bp);
		break;
	case Ilack:
		ilackto(&s->ilctl, hngetl(g->ilack));
		freeb(bp);
		break;
	case Ilquerey:
		ilsendctl(s, 0, Ilack, 1);
		freeb(bp);
		break;
	case Ildataquery:
	case Ildata:
		ilackto(&s->ilctl, hngetl(h->ilack));
		bp->rptr += IL_EHSIZE+IL_HDRSIZE;
		PUTNEXT(s->readq, bp);
		break;
	case Ilreset:
		s->ilctl.state = Closed;
		freeb(bp);
	}
}

void
ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, int ack)
{
	Ilhdr *ih;
	Ilcb *ic;
	Block *bp;

	bp = allocb(IL_EHSIZE+IL_HDRSIZE);
	bp->wptr += IL_EHSIZE+IL_HDRSIZE;

	ih = (Ilhdr *)(bp->rptr);
	ic = &ipc->ilctl;

	hnputs(ih->illen, IL_EHSIZE+IL_HDRSIZE);
	/* Ip fields */
	hnputl(ih->src, Myip);
	hnputl(ih->dst, ipc->dst);
	ih->proto = IP_ILPROTO;
	hnputs(ih->illen, IL_HDRSIZE);
	if(inih) {
		hnputs(ih->ilsrc, nhgets(inih->ildst));
		hnputs(ih->ildst, nhgets(inih->ilsrc));


@@ 186,7 290,11 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type)
	if(ilcksum)
		hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, IL_HDRSIZE));

	PUTNEXT(Iloutput, bp);
	if(!ack) {
		ic->sent++;			/* Maybe needs locking */
		ilackq(&ipc->ilctl, bp);
	}
	PUTNEXT(Ipoutput, bp);
}

void

M port/tcpinput.c => port/tcpinput.c +1 -2
@@ 11,7 11,6 @@ int tcpdbg = 0;
#define DPRINT	if(tcpdbg) print
#define LPRINT  if(tcpdbg) print

extern Queue *Tcpoutput;
QLock	reseqlock;
Reseq	*reseqfree;



@@ 497,7 496,7 @@ reset(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg)
	DPRINT("Reset: seq = %lux ack = %d flags = %lux\n",
	       seg->seq, seg->ack, seg->flags);

	PUTNEXT(Tcpoutput, hbp);
	PUTNEXT(Ipoutput, hbp);
}

void

M port/tcpoutput.c => port/tcpoutput.c +3 -4
@@ 9,7 9,8 @@

extern int tcpdbg;
extern ushort tcp_mss;
extern Queue *Tcpoutput;
int tcptimertype = 0;


#define DPRINT if(tcpdbg) print



@@ 190,12 191,10 @@ tcp_output(Ipconv *s)
		DPRINT("tcp_output: ip_send s%lux a%lux w%lux u%lux\n",
			seg.seq, seg.ack, seg.wnd, seg.up);

		PUTNEXT(Tcpoutput, hbp);
		PUTNEXT(Ipoutput, hbp);
	}
}

int tcptimertype = 0;

void
tcp_timeout(void *arg)
{

M power/devhotrod.c => power/devhotrod.c +3 -1
@@ 473,7 473,9 @@ hotrodintr(int vec)
		print("bad hotrod vec\n");
		return;
	}
	h->addr->lcsr3 &= ~INT_VME;
	l = h->addr->lcsr3 & ~INT_VME;
	h->addr->lcsr3 = l;
	h->addr->lcsr3 = l;
	while(l = h->addr->replyq[h->ri]){	/* assign = */
		hm = (Hotmsg*)(VME2MP(l));
		h->addr->replyq[h->ri] = 0;