~kris/9p

9hist

280b8b5c8b1efe7bc9562061d851e50c4e2a2b19 — David du Colombier 35 years ago 5307a1c
Plan 9 from Bell Labs 1990-11-18
9 files changed, 113 insertions(+), 105 deletions(-)

M gnot/devpipe.c
M gnot/stream.c
M port/devcons.c
M port/devdk.c
M port/devpipe.c
M port/stream.c
M power/dat.h
M power/fns.h
M power/main.c
M gnot/devpipe.c => gnot/devpipe.c +20 -27
@@ 178,7 178,7 @@ pipeopen(Chan *c, int omode)
		 *  pointer from the other stream.
		 */
		if(streamenter(local)<0)
			panic("pipeattach");
			panic("pipeopen");
	}
	unlock(p);
	poperror();


@@ 208,43 208,29 @@ pipewstat(Chan *c, char *db)
}

void
pipeexit(Pipe *p)
{
	if(decref(p) < 0)
		panic("pipeexit");
	if(p->ref == 0){
		lock(&pipealloc);
		p->next = pipealloc.free;
		pipealloc.free = p;
		unlock(&pipealloc);
	}
}

void
pipeclose(Chan *c)
{
	Stream *remote;
	Stream *local;
	Pipe *p;

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	lock(p);
	if(waserror()){
		unlock(p);
		nexterror();
	}

	/*
	 *  take care of associated streams
	 */
	if(local = c->stream){
		remote = (Stream *)c->stream->devq->ptr;
	if(c->stream)
		streamclose(c);		/* close this stream */
		streamexit(remote, 0);	/* release stream for other half of pipe */

	/*
	 *  free the structure
	 */
	if(decref(p) == 0){
		lock(&pipealloc);
		p->next = pipealloc.free;
		pipealloc.free = p;
		unlock(&pipealloc);
	}
	unlock(p);
	poperror();
	pipeexit(p);
	if(p->ref < 0)
		panic("pipeexit");
}

long


@@ 315,6 301,7 @@ static void
pipestclose(Queue *q)
{
	Block *bp;
	Stream *remote;

	/*
	 *  point to the bit-bucket and let any in-progress


@@ 330,4 317,10 @@ pipestclose(Queue *q)
	bp = allocb(0);
	bp->type = M_HANGUP;
	PUTNEXT(q, bp);

	/*
	 *  release stream for other half of pipe
	 */
	remote = RD(q)->ptr;
	streamexit(remote, 0);
}

M gnot/stream.c => gnot/stream.c +11 -9
@@ 810,9 810,9 @@ streamclose1(Stream *s)
			if(!waserror()){
				if(q->info->close)
					(*q->info->close)(q->other);
				WR(q)->put = nullput;
				poperror();
			}
			poperror();
			WR(q)->put = nullput;

			/*
			 *  this may be 2 streams joined device end to device end


@@ 820,14 820,14 @@ streamclose1(Stream *s)
			if(q == s->devq->other)
				break;
		}
	}
	
	/*
	 *  ascend the stream flushing the queues
	 */
	for(q = s->devq; q; q = nq){
		nq = q->next;
		flushq(q);
		/*
		 *  ascend the stream flushing the queues
		 */
		for(q = s->devq; q; q = nq){
			nq = q->next;
			flushq(q);
		}
	}
	s->opens--;



@@ 1013,6 1013,8 @@ streamread(Chan *c, void *vbuf, long n)
 *	hangup			-- send an M_HANGUP up the stream
 *	push ldname		-- push the line discipline named ldname
 *	pop			-- pop a line discipline
 *
 *  This routing is entrered with s->wrlock'ed and must unlock.
 */
static long
streamctlwrite(Chan *c, void *a, long n)

M port/devcons.c => port/devcons.c +9 -0
@@ 311,6 311,7 @@ enum{
	Qppid,
	Qtime,
	Quser,
	Qvmereset,
};

Dirtab consdir[]={


@@ 324,6 325,7 @@ Dirtab consdir[]={
	"ppid",		Qppid,		12,	0600,
	"time",		Qtime,		12,	0600,
	"user",		Quser,		0,	0600,
	"vmereset",	Qvmereset,	0,	0600,
};

#define	NCONS	(sizeof consdir/sizeof(Dirtab))


@@ 579,6 581,13 @@ conswrite(Chan *c, void *va, long n)

	case Qnull:
		break;

	case Qvmereset:
		if(strcmp(u->p->pgrp->user, "bootes") != 0)
			error(0, Eperm);
		vmereset();
		break;

	default:
		error(0, Egreg);
	}

M port/devdk.c => port/devdk.c +2 -1
@@ 6,7 6,7 @@
#include	"io.h"
#include	"errno.h"

#define	DPRINT	if(0)	/*kprint*/
#define	DPRINT	if(0) print

#define	NOW	(MACHP(0)->ticks)



@@ 1668,6 1668,7 @@ dktimer(void *a)
		/*
		 * send keep alive
		 */
		DPRINT("keep alive\n");
		dkmesg(c, T_ALIVE, D_CONTINUE, 0, 0);

		/*

M port/devpipe.c => port/devpipe.c +20 -27
@@ 178,7 178,7 @@ pipeopen(Chan *c, int omode)
		 *  pointer from the other stream.
		 */
		if(streamenter(local)<0)
			panic("pipeattach");
			panic("pipeopen");
	}
	unlock(p);
	poperror();


@@ 208,43 208,29 @@ pipewstat(Chan *c, char *db)
}

void
pipeexit(Pipe *p)
{
	if(decref(p) < 0)
		panic("pipeexit");
	if(p->ref == 0){
		lock(&pipealloc);
		p->next = pipealloc.free;
		pipealloc.free = p;
		unlock(&pipealloc);
	}
}

void
pipeclose(Chan *c)
{
	Stream *remote;
	Stream *local;
	Pipe *p;

	p = &pipealloc.pipe[STREAMID(c->qid)/2];
	lock(p);
	if(waserror()){
		unlock(p);
		nexterror();
	}

	/*
	 *  take care of associated streams
	 */
	if(local = c->stream){
		remote = (Stream *)c->stream->devq->ptr;
	if(c->stream)
		streamclose(c);		/* close this stream */
		streamexit(remote, 0);	/* release stream for other half of pipe */

	/*
	 *  free the structure
	 */
	if(decref(p) == 0){
		lock(&pipealloc);
		p->next = pipealloc.free;
		pipealloc.free = p;
		unlock(&pipealloc);
	}
	unlock(p);
	poperror();
	pipeexit(p);
	if(p->ref < 0)
		panic("pipeexit");
}

long


@@ 315,6 301,7 @@ static void
pipestclose(Queue *q)
{
	Block *bp;
	Stream *remote;

	/*
	 *  point to the bit-bucket and let any in-progress


@@ 330,4 317,10 @@ pipestclose(Queue *q)
	bp = allocb(0);
	bp->type = M_HANGUP;
	PUTNEXT(q, bp);

	/*
	 *  release stream for other half of pipe
	 */
	remote = RD(q)->ptr;
	streamexit(remote, 0);
}

M port/stream.c => port/stream.c +27 -27
@@ 652,10 652,10 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
	 */
	for(s = slist; s < &slist[conf.nstream]; s++) {
		if(s->inuse == 0){
			if(canlock(s)){
			if(canqlock(s)){
				if(s->inuse == 0)
					break;
				unlock(s);
				qunlock(s);
			}
		}
	}


@@ 664,7 664,7 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
		error(0, Enostream);
	}
	if(waserror()){
		unlock(s);
		qunlock(s);
		streamclose1(s);
		nexterror();
	}


@@ 697,7 697,7 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
	if(qi->open)
		(*qi->open)(RD(s->devq), s);

	unlock(s);
	qunlock(s);
	poperror();
	return s;
}


@@ 717,17 717,17 @@ streamopen(Chan *c, Qinfo *qi)
	for(s = slist; s < &slist[conf.nstream]; s++) {
		if(s->inuse && s->type == c->type && s->dev == c->dev
		   && s->id == STREAMID(c->qid)){
			lock(s);
			qlock(s);
			if(s->inuse && s->type == c->type
			&& s->dev == c->dev
		 	&& s->id == STREAMID(c->qid)){
				s->inuse++;
				s->opens++;
				c->stream = s;
				unlock(s);
				qunlock(s);
				return;
			}
			unlock(s);
			qunlock(s);
		}
	}



@@ 744,13 744,13 @@ streamopen(Chan *c, Qinfo *qi)
int
streamenter(Stream *s)
{
	lock(s);
	qlock(s);
	if(s->opens == 0){
		unlock(s);
		qunlock(s);
		return -1;
	}
	s->inuse++;
	unlock(s);
	qunlock(s);
	return 0;
}



@@ 767,7 767,7 @@ streamexit(Stream *s, int locked)
	char *name;

	if(!locked)
		lock(s);
		qlock(s);
	if(s->inuse == 1){
		if(s->opens != 0)
			panic("streamexit %d %s\n", s->opens, s->devq->info->name);


@@ 784,7 784,7 @@ streamexit(Stream *s, int locked)
	s->inuse--;
	rv = s->inuse;
	if(!locked)
		unlock(s);
		qunlock(s);
	return rv;
}



@@ 801,24 801,24 @@ streamclose1(Stream *s)
	/*
	 *  decrement the reference count
	 */
	lock(s);
	qlock(s);
	if(s->opens == 1){
		if(!waserror()){
			/*
			 *  descend the stream closing the queues
			 */
			for(q = s->procq; q; q = q->next){
		/*
		 *  descend the stream closing the queues
		 */
		for(q = s->procq; q; q = q->next){
			if(!waserror()){
				if(q->info->close)
					(*q->info->close)(q->other);
				WR(q)->put = nullput;

				/*
				 *  this may be 2 streams joined device end to device end
				 */
				if(q == s->devq->other)
					break;
				poperror();
			}
			poperror();
			WR(q)->put = nullput;

			/*
			 *  this may be 2 streams joined device end to device end
			 */
			if(q == s->devq->other)
				break;
		}
	
		/*


@@ 835,7 835,7 @@ streamclose1(Stream *s)
	 *  leave it and free it
	 */
	streamexit(s, 1);
	unlock(s);
	qunlock(s);
}
void
streamclose(Chan *c)

M power/dat.h => power/dat.h +1 -1
@@ 454,7 454,7 @@ struct Queue {
 *  a stream head
 */
struct Stream {
	Lock;			/* structure lock */
	QLock;			/* structure lock */
	short	inuse;		/* number of processes in stream */
	short	opens;		/* number of processes with stream open */
	ushort	hread;		/* number of reads after hangup */

M power/fns.h => power/fns.h +1 -0
@@ 198,6 198,7 @@ void	validaddr(ulong, ulong, int);
void	vecinit(void);
void	vector80(void);
void*	vmemchr(void*, int, int);
void	vmereset(void);
void	wakeme(Alarm*);
void	wakeup(Rendez*);
void	wbflush(void);

M power/main.c => power/main.c +22 -13
@@ 103,6 103,25 @@ vecinit(void)
}

/*
 *  reset the vme bus
 */
void
vmereset(void)
{
	long i;
	int noforce;

	if(ioid >= IO3R1)
		noforce = 1;
	else
		noforce = 0;
	MODEREG->resetforce = (1<<1) | noforce;
	for(i=0; i<1000000; i++)
		;
	MODEREG->resetforce = noforce;
}

/*
 *  We have to program both the IO2 board to generate interrupts
 *  and the SBCC on CPU 0 to accept them.
 */


@@ 110,25 129,15 @@ void
ioboardinit(void)
{
	long i;
	int noforce;
	int maxlevel;

	ioid = *IOID;
	if(ioid >= IO3R1){
	if(ioid >= IO3R1)
		maxlevel = 11;
		noforce = 1;
	} else {
	else
		maxlevel = 8;
		noforce = 0;
	}

	/*
	 *  reset VME bus (MODEREG is on the IO2)
	 */
	MODEREG->resetforce = (1<<1) | noforce;
	for(i=0; i<1000000; i++)
		;
	MODEREG->resetforce = noforce;
	vmereset();
	MODEREG->masterslave = (SLAVE<<4) | MASTER;

	/*