~kris/9p

9hist

a43fe95feb77c6d64be5ea88e0338777eeb4067d — David du Colombier 34 years ago 39e8ef7
Plan 9 from Bell Labs 1992-08-26
M boot/local.c => boot/local.c +4 -1
@@ 7,7 7,10 @@ static char *disk;
void
configlocal(Method *mp)
{
	disk = *sys ? sys : mp->arg;
	if(*sys == '/' || *sys == '#')
		disk = sys;
	else
		disk = mp->arg;
	USED(mp);
}


M gnot/devduart.c => gnot/devduart.c +1 -1
@@ 675,7 675,7 @@ duartstat(Chan *c, char *dp)
{
	switch(c->qid.path){
	case Qeia0:
		streamstat(c, dp, "eia0");
		streamstat(c, dp, duartdir[0].name, duartdir[0].perm);
		break;
	default:
		devstat(c, dp, duartdir, NDuartport, devgen);

M pc/devhard.c => pc/devhard.c +17 -23
@@ 42,8 42,7 @@ enum
	/* file types */
	Qdir=		0,

	Maxxfer=	512,		/* maximum transfer size/cmd */
	Maxread=	512,		/* maximum transfer size/read */
	Maxxfer=	32*512,		/* maximum transfer size/cmd */
	Npart=		8+2,		/* 8 sub partitions, disk, and partition */
	Nrepl=		64,		/* maximum replacement blocks */
};


@@ 158,7 157,7 @@ Drive		*hard;
static void	hardintr(Ureg*);
static long	hardxfer(Drive*, Partition*, int, long, long, char*);
static void	hardident(Drive*);
static void	hardsetbuf(Drive*, int);
static void	hardsetbuf(Drive*);
static void	hardpart(Drive*);

static int


@@ 239,14 238,13 @@ hardattach(char *spec)
	for(dp = hard; dp < &hard[conf.nhard]; dp++){
		if(!waserror()){
			dp->bytes = 512;
			hardsetbuf(dp, 0);
			hardident(dp);
			switch(dp->id.magic){
			case 0xA5A:	/* conner drive on the AT&T NSX (safari) */
				dp->cyl = dp->id.lcyls;
				dp->heads = dp->id.lheads;
				dp->sectors = dp->id.ls2t;
				hardsetbuf(dp, 1);
				hardsetbuf(dp);
				break;
			case 0x324A:	/* hard drive on the AT&T 6386 */
				dp->cyl = dp->id.lcyls - 4;


@@ 500,8 498,6 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
	start = start / dp->bytes;
	if(len > Maxxfer)
		len = Maxxfer;
	if(cmd == Cread && len > Maxread)
		len = Maxread;
	len = (len + dp->bytes - 1) / dp->bytes;
	if(len == 0)
		return 0;


@@ 578,10 574,10 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
}

/*
 *  set read ahead mode (1 == on, 0 == off)
 *  set read ahead mode
 */
static void
hardsetbuf(Drive *dp, int on)
hardsetbuf(Drive *dp)
{
	Controller *cp = dp->cp;



@@ 594,12 590,16 @@ hardsetbuf(Drive *dp, int on)
	cmdreadywait(cp);

	cp->cmd = Csetbuf;
	outb(cp->pbase+Pprecomp, on ? 0xAA : 0xFF);
	outb(cp->pbase+Pprecomp, 0xAA);
	outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4));
	outb(cp->pbase+Pcmd, Csetbuf);

	sleep(&cp->r, cmddone, cp);

	if(cp->status & Serr)
		print("hd%d setbuf err: status %lux, err %lux\n",
			dp-hard, cp->status, cp->error);

	poperror();
	qunlock(cp);
}


@@ 638,7 638,7 @@ hardident(Drive *dp)
	memmove(&dp->id, buf, dp->bytes);
	/*
	 * this function appears to respond with an extra interrupt after
	 * the indent information is read, except on the safari.  The following
	 * the ident information is read, except on the safari.  The following
	 * delay gives this extra interrupt a chance to happen while we are quiet.
	 * Otherwise, the interrupt may come during a subsequent read or write,
	 * causing a panic and much confusion.


@@ 647,6 647,7 @@ hardident(Drive *dp)
		tsleep(&cp->r, return0, 0, 10);
	cp->cmd = 0;
	cp->buf = 0;
	free(buf);
	poperror();
	qunlock(cp);
}


@@ 786,7 787,6 @@ hardintr(Ureg *ur)
	char *addr;

	USED(ur);
	spllo();	/* let in other interrupts */

	/*
 	 *  BUG!! if there is ever more than one controller, we need a way to


@@ 796,12 796,13 @@ hardintr(Ureg *ur)
	dp = cp->dp;

	loop = 0;
	while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy)
		if(++loop > 10000) {
	while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy){
		if(++loop > 100) {
			print("cmd=%lux status=%lux\n",
				cp->cmd, inb(cp->pbase+Pstatus));
			panic("hardintr: wait busy");
		}
	}
	switch(cp->cmd){
	case Cwrite:
		if(cp->status & Serr){


@@ 814,8 815,8 @@ hardintr(Ureg *ur)
		cp->sofar++;
		if(cp->sofar < cp->nsecs){
			loop = 0;
			while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
				if(++loop > 10000) {
			while(((cp->status = inb(cp->pbase+Pstatus)) & Sdrq) == 0)
				if(++loop > 100) {
					print("cmd=%lux status=%lux\n",
						cp->cmd, inb(cp->pbase+Pstatus));
					panic("hardintr: write");


@@ 834,13 835,6 @@ hardintr(Ureg *ur)
	case Cread:
	case Cident:
		loop = 0;
		while((inb(cp->pbase+Pstatus) & Sbusy) != 0)
			if(++loop > 10000) {
				print("cmd=%lux status=%lux\n",
					cp->cmd, inb(cp->pbase+Pstatus));
				panic("hardintr: wait busy");
			}
		loop = 0;
		while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
			if(++loop > 10000) {
				print("cmd=%lux status=%lux\n",

M pc/devrtc.c => pc/devrtc.c +3 -3
@@ 92,9 92,9 @@ rtcopen(Chan *c, int omode)
	omode = openmode(omode);
	switch(c->qid.path){
	case Qrtc:
		if(omode == OREAD)
			break;
		/* fall through */
		if(omode != OREAD && strcmp(u->p->user, eve)!=0)
			error(Eperm);
		break;
	case Qnvram:
		if(strcmp(u->p->user, eve)!=0 || !cpuserver)
			error(Eperm);

M pc/devuart.c => pc/devuart.c +2 -2
@@ 614,10 614,10 @@ uartstat(Chan *c, char *dp)
{
	switch(c->qid.path){
	case Qeia0:
		streamstat(c, dp, "eia0");
		streamstat(c, dp, uartdir[0].name, uartdir[0].perm);
		break;
	case Qeia1:
		streamstat(c, dp, "eia1");
		streamstat(c, dp, uartdir[2].name, uartdir[2].perm);
		break;
	default:
		devstat(c, dp, uartdir, NUart, devgen);

M port/devcons.c => port/devcons.c +17 -18
@@ 475,7 475,7 @@ consclose(Chan *c)
		unlock(&ctl);
	}
	if(c->qid.path == Qcrypt && c->aux)
		freeb(c->aux);
		free(c->aux);
	c->aux = 0;
}



@@ 485,8 485,7 @@ consread(Chan *c, void *buf, long n, ulong offset)
	int ch, i, k, id;
	ulong l;
	char *cbuf = buf;
	char *chal, *b, *bp;
	Block *cb;
	char *chal, *b, *bp, *cb;
	char tmp[128];	/* must be >= 6*NUMSIZE */
	Mach *mp;



@@ 591,9 590,9 @@ consread(Chan *c, void *buf, long n, ulong offset)
		cb = c->aux;
		if(!cb)
			return 0;
		if(n > cb->wptr - cb->base)
			n = cb->wptr - cb->base;
		memmove(buf, cb->base, n);
		if(n > MAXCRYPT)
			n = MAXCRYPT;
		memmove(buf, &cb[1], n);
		return n;

	case Qchal:


@@ 738,8 737,7 @@ conswrite(Chan *c, void *va, long n, ulong offset)
	char cbuf[64];
	char buf[256];
	long l, bp;
	char *a = va;
	Block *cb;
	char *a = va, *cb;
	Mach *mp;
	int id, fd, ch;
	Chan *swc;


@@ 801,23 799,24 @@ conswrite(Chan *c, void *va, long n, ulong offset)
	case Qcrypt:
		cb = c->aux;
		if(!cb){
			cb = c->aux = allocb(128);
			cb->type = 'E';
			/* first byte determines whether encrypting or decrypting */
			cb = c->aux = smalloc(MAXCRYPT+1);
			cb[0] = 'E';
		}
		if(n < 8){
			if(n != 1 || a[0] != 'E' && a[0] != 'D')
				error(Ebadarg);
			cb->type = a[0];
			cb[0] = a[0];
			return 1;
		}
		if(n > cb->lim - cb->base)
			n = cb->lim - cb->base;
		memmove(cb->base, a, n);
		cb->wptr = cb->base + n;
		if(cb->type == 'E')
			encrypt(u->p->pgrp->crypt->key, cb->base, n);
		if(n > MAXCRYPT)
			n = MAXCRYPT;
		memset(&cb[1], 0, MAXCRYPT);
		memmove(&cb[1], a, n);
		if(cb[0] == 'E')
			encrypt(u->p->pgrp->crypt->key, &cb[1], n);
		else
			decrypt(u->p->pgrp->crypt->key, cb->base, n);
			decrypt(u->p->pgrp->crypt->key, &cb[1], n);
		break;

	case Qkey:

M port/devip.c => port/devip.c +2 -2
@@ 835,14 835,14 @@ tcpstclose(Queue *q)
		qunlock(s);

		qlock(tcb);
		close_self(s, 0);
		localclose(s, 0);
		qunlock(tcb);
		break;

	case Closed:
	case Syn_sent:
		qlock(tcb);
		close_self(s, 0);
		localclose(s, 0);
		qunlock(tcb);
		break;


M port/devpipe.c => port/devpipe.c +1 -1
@@ 117,7 117,7 @@ pipewalk(Chan *c, char *name)
void
pipestat(Chan *c, char *db)
{
	streamstat(c, db, "pipe");
	streamstat(c, db, "pipe", 0666);
}

/*

M port/devscc.c => port/devscc.c +1 -1
@@ 718,7 718,7 @@ sccstat(Chan *c, char *dp)
	i = STREAMID(c->qid.path);
	switch(STREAMTYPE(c->qid.path)){
	case Sdataqid:
		streamstat(c, dp, sccdir[2*i].name);
		streamstat(c, dp, sccdir[2*i].name, sccdir[2*i].perm);
		break;
	default:
		devstat(c, dp, sccdir, 2*nscc, devgen);

M port/ipdat.h => port/ipdat.h +1 -1
@@ 429,7 429,7 @@ void	add_reseq(Tcpctl *, char, Tcp *, Block *, ushort);
int	arp_lookup(uchar*, uchar*);
int	backoff(int);
Block*	btrim(Block*, int, int);
void	close_self(Ipconv *, char []);
void	localclose(Ipconv *, char []);
int	dupb(Block **, Block *, int, int);
void	extract_oob(Block **, Block **, Tcp *);
void	get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *);

M port/lib.h => port/lib.h +2 -0
@@ 33,6 33,8 @@ extern	int	countrune(char*);
extern	char*	utfrune(char*, long);
extern	int	utflen(char*);

extern	int	abs(int);

/*
 * print routines
 */

M port/portdat.h => port/portdat.h +1 -0
@@ 721,6 721,7 @@ struct Network
enum
{
	PRINTSIZE =	256,
	MAXCRYPT = 	127,
	NUMSIZE	=	12,		/* size of formatted number */
	MB =		(1024*1024),
};

M port/portfns.h => port/portfns.h +1 -1
@@ 235,7 235,7 @@ Stream*		streamnew(ushort, ushort, ushort, Qinfo*, int);
void		streamopen(Chan*, Qinfo*);
int		streamparse(char*, Block*);
long		streamread(Chan*, void*, long);
void		streamstat(Chan*, char*, char*);
void		streamstat(Chan*, char*, char*, long);
long		streamwrite(Chan*, void*, long, int);
void		naildownstream(Stream*);
void		swapinit(void);

M port/stream.c => port/stream.c +2 -2
@@ 1232,7 1232,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
 *  first delimiter.
 */
void
streamstat(Chan *c, char *db, char *name)
streamstat(Chan *c, char *db, char *name, long perm)
{
	Dir dir;
	Stream *s;


@@ 1254,7 1254,7 @@ streamstat(Chan *c, char *db, char *name)
		unlock(q);
	}

	devdir(c, c->qid, name, n, eve, 0, &dir);
	devdir(c, c->qid, name, n, eve, perm, &dir);
	convD2M(&dir, db);
}


M port/tcpinput.c => port/tcpinput.c +36 -41
@@ 19,7 19,7 @@ char *tcpstate[] =
};

void
reset(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg)
sndrst(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg)
{
	Block *hbp;
	Port tmp;


@@ 85,8 85,8 @@ tcpflushincoming(Ipconv *s)
	seg.seq = tcb->snd.ptr;
	seg.ack = tcb->last_ack = tcb->rcv.nxt;

	reset(s->dst, Myip[Myself], 0, 0, &seg);
	close_self(s, 0);
	sndrst(s->dst, Myip[Myself], 0, 0, &seg);
	localclose(s, 0);
}

static void


@@ 159,7 159,7 @@ tcp_input(Ipifc *ifc, Block *bp)
	if((hdrlen = ntohtcp(&seg, &bp)) < 0)
		return;

	/* Adjust the data length */
	/* trim the packet to the size claimed by the datagram */
	length -= (hdrlen+TCP_IPLEN+TCP_PHDRSIZE);
	bp = btrim(bp, hdrlen+TCP_PKT, length);
	if(bp == 0)


@@ 198,7 198,7 @@ tcp_input(Ipifc *ifc, Block *bp)
		}
		if(s == 0){
			freeb(bp);   
			reset(source, dest, tos, length, &seg);
			sndrst(source, dest, tos, length, &seg);
			return;
		}
	}


@@ 212,7 212,7 @@ tcp_input(Ipifc *ifc, Block *bp)
	switch(tcb->state) {
	case Closed:
		freeb(bp);
		reset(source, dest, tos, length, &seg);
		sndrst(source, dest, tos, length, &seg);
		goto done;
	case Listen:
		if(seg.flags & RST) {


@@ 221,7 221,7 @@ tcp_input(Ipifc *ifc, Block *bp)
		} 
		if(seg.flags & ACK) {
			freeb(bp);
			reset(source, dest, tos, length, &seg);
			sndrst(source, dest, tos, length, &seg);
			goto done;
		}
		if(seg.flags & SYN) {


@@ 239,13 239,13 @@ tcp_input(Ipifc *ifc, Block *bp)
		if(seg.flags & ACK) {
			if(!seq_within(seg.ack, tcb->iss+1, tcb->snd.nxt)) {
				freeb(bp);
				reset(source, dest, tos, length, &seg);
				sndrst(source, dest, tos, length, &seg);
				goto done;
			}
		}
		if(seg.flags & RST) {
			if(seg.flags & ACK)
				close_self(s, Econrefused);
				localclose(s, Econrefused);
			freeb(bp);
			goto done;
		}


@@ 253,7 253,7 @@ tcp_input(Ipifc *ifc, Block *bp)
		if(seg.flags & ACK)
		if(PREC(tos) != PREC(tcb->tos)){
			freeb(bp);
			reset(source, dest, tos, length, &seg);
			sndrst(source, dest, tos, length, &seg);
			goto done;
		}



@@ 277,7 277,7 @@ tcp_input(Ipifc *ifc, Block *bp)
		goto done;
	}

	/* Trim segment to fit receive window. */
	/* Cut the data to fit the receive window */
	if(trim(tcb, &seg, &bp, &length) == -1) {
		if(!(seg.flags & RST)) {
			tcb->flags |= FORCE;


@@ 286,15 286,18 @@ tcp_input(Ipifc *ifc, Block *bp)
		goto done;
	}

	/* If we dont understand answer with a rst */
	/* Cannot accept so answer with a rst */
	if(length)
	if(s->readq == 0)
	if(tcb->state == Closed) {
		freeb(bp);
		reset(source, dest, tos, length, &seg);
		sndrst(source, dest, tos, length, &seg);
		goto done;
	}

	/* The segment is beyond the current receive pointer so
	 * queue the data in the resequence queue
	 */
	if(seg.seq != tcb->rcv.nxt)
	if(length != 0 || (seg.flags & (SYN|FIN))) {
		add_reseq(tcb, tos, &seg, bp, length);


@@ 308,7 311,7 @@ tcp_input(Ipifc *ifc, Block *bp)
			   && !(tcb->flags & (CLONE|ACTIVE))) 
				setstate(s, Listen);
			else
				close_self(s, Econrefused);
				localclose(s, Econrefused);

			freeb(bp);
			goto done;


@@ 316,7 319,7 @@ tcp_input(Ipifc *ifc, Block *bp)

		if(PREC(tos) != PREC(tcb->tos) || (seg.flags & SYN)){
			freeb(bp);
			reset(source, dest, tos, length, &seg);
			sndrst(source, dest, tos, length, &seg);
			goto done;
		}



@@ 333,7 336,7 @@ tcp_input(Ipifc *ifc, Block *bp)
			}
			else {
				freeb(bp);
				reset(source, dest, tos, length, &seg);
				sndrst(source, dest, tos, length, &seg);
				goto done;
			}
			break;


@@ 361,7 364,7 @@ tcp_input(Ipifc *ifc, Block *bp)
			update(s, &seg);
			if(tcb->sndcnt == 0) {
				freeb(bp);
				close_self(s, Enoerror);
				localclose(s, Enoerror);
				goto done;
			}			
		case Time_wait:


@@ 393,7 396,7 @@ tcp_input(Ipifc *ifc, Block *bp)
			case Syn_received:
			case Established:
			case Finwait1:
				/* Place on receive queue */
				/* If we still have some data place on receive queue */
				tcb->rcvcnt += blen(bp);
				if(bp){
					if(s->readq)


@@ 415,7 418,7 @@ tcp_input(Ipifc *ifc, Block *bp)
				/* no process to read the data, send a reset */
				if(bp)
					freeb(bp);
				reset(source, dest, tos, length, &seg);
				sndrst(source, dest, tos, length, &seg);
				goto done;
			}
		}


@@ 454,15 457,17 @@ tcp_input(Ipifc *ifc, Block *bp)
				break;
			}
		}

		while(tcb->reseq != 0) {
			if(seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq) == 0)
				break;

			get_reseq(tcb, &tos, &seg, &bp, &length);

			if(trim(tcb, &seg, &bp, &length) == 0)
				goto gotone;
				break;
		}
		break;
		gotone:;
	}
output:
	tcp_output(s);


@@ 473,11 478,10 @@ done:
void
update(Ipconv *s, Tcp *seg)
{
	int rtt;
	ushort acked;
	ushort expand;
	Tcpctl *tcb = &s->tcpctl;
	int rtt;
	int abserr;

	if(seq_gt(seg->ack, tcb->snd.nxt)) {
		tcb->flags |= FORCE;


@@ 498,6 502,7 @@ update(Ipconv *s, Tcp *seg)
	if(!seq_gt(seg->ack, tcb->snd.una))
		return;	

	/* Compute the new send window size */
	acked = seg->ack - tcb->snd.una;
	if(tcb->cwind < tcb->snd.wnd) {
		if(tcb->cwind < tcb->ssthresh)


@@ 513,31 518,25 @@ update(Ipconv *s, Tcp *seg)
			tcb->cwind += expand;
	}

	/* Round trip time estimation */
	/* Adjust the timers acorrding to the round trip time */
	if(run_timer(&tcb->rtt_timer))
	if(seq_ge(seg->ack, tcb->rttseq)) {
		stop_timer(&tcb->rtt_timer);
		if((tcb->flags&RETRAN) == 0) {
			tcb->backoff = 0;
			rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
			rtt *= MSPTICK;	
			rtt *= MSPTICK;
			if(rtt > tcb->srtt &&
			  (tcb->state == Syn_sent || tcb->state == Syn_received))
				tcb->srtt = rtt;
			else {
				if(rtt > tcb->srtt)
					abserr = rtt - tcb->srtt;
				else
					abserr = tcb->srtt - rtt;
				tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt) / AGAIN;
				tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr) / DGAIN;
				DPRINT("tcpout: rtt %d, srtt %d, mdev %d\n", 
					rtt, tcb->srtt, tcb->mdev);
				rtt = abs(rtt - tcb->srtt);
				tcb->mdev = ((DGAIN-1)*tcb->mdev + rtt) / DGAIN;
			}
			tcb->backoff = 0;
		}
	}

	/* If we're waiting for an ack of our SYN, note it and adjust count */
	if((tcb->flags & SYNACK) == 0){
		tcb->flags |= SYNACK;
		acked--;


@@ 548,12 547,9 @@ update(Ipconv *s, Tcp *seg)

	tcb->sndcnt -= acked;
	tcb->snd.una = seg->ack;
	if (seq_gt(seg->ack, tcb->snd.up))
	if(seq_gt(seg->ack, tcb->snd.up))
		tcb->snd.up = seg->ack;

	/* Stop retransmission timer, but restart it if there is still
	 * unacknowledged data.
	 */	
	stop_timer(&tcb->timer);
	if(tcb->snd.una != tcb->snd.nxt)
		start_timer(&tcb->timer);


@@ 561,7 557,6 @@ update(Ipconv *s, Tcp *seg)
	if(seq_lt(tcb->snd.ptr, tcb->snd.una))
		tcb->snd.ptr = tcb->snd.una;

	/* All data is acked now */
	tcb->flags &= ~RETRAN;
	tcb->backoff = 0;
}


@@ 688,7 683,7 @@ trim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
			return 0;
	}
	else {
		/* Some part of the segment must be in the window */
		/* Some part of the segment should be in the window */
		if(in_window(tcb,seg->seq)) {
			accept++;
		}


@@ 839,7 834,7 @@ init_tcpctl(Ipconv *s)
 *  called with tcb locked
 */
void
close_self(Ipconv *s, char reason[])
localclose(Ipconv *s, char reason[])
{
	Reseq *rp,*rp1;
	Tcpctl *tcb = &s->tcpctl;

M port/tcpoutput.c => port/tcpoutput.c +2 -2
@@ 182,13 182,13 @@ tcp_timeout(void *arg)
	default:
		tcb->backoff++;
		if (tcb->backoff >= MAXBACKOFF)
			close_self(s, Etimedout);
			localclose(s, Etimedout);
		else 
			tcprxmit(s);
		break;

	case Time_wait:
		close_self(s, 0);
		localclose(s, 0);
		break;
	}
}

M power/devduart.c => power/devduart.c +2 -1
@@ 747,7 747,8 @@ duartstat(Chan *c, char *p)
{
	switch(STREAMTYPE(c->qid.path)){
	case Sdataqid:
		streamstat(c, p, duartdir[2*STREAMID(c->qid.path)].name);
		streamstat(c, p, duartdir[2*STREAMID(c->qid.path)].name,
			duartdir[2*STREAMID(c->qid.path)].perm);
		break;
	default:
		devstat(c, p, duartdir, 2*nduartport, devgen);