~kris/9p

9hist

f4556d99e243df58fb887d67b389d5b0a8767c57 — David du Colombier 34 years ago 2c89fa4
Plan 9 from Bell Labs 1992-03-06
5 files changed, 12 insertions(+), 295 deletions(-)

M port/devip.c
M port/tcpinput.c
M power/boot.c
D power/devbit3.c
M power/devhotrod.c
M port/devip.c => port/devip.c +3 -0
@@ 173,6 173,7 @@ ipincoming(Ipconv *base, Ipconv *from)
				/* current user becomes owner */
				netown(new->net, new->index, u->p->user, 0);
			new->ref = 1;
			new->newcon = 0;
			qunlock(new);
			return new;
		}	


@@ 643,7 644,9 @@ iplisten(Chan *c)
		new = base;
 		for(etab = &base[conf.ip]; new < etab; new++) {
			if(new->newcon) {
				qlock(s);
				s->curlog--;
				qunlock(s);
				new->newcon = 0;
				qunlock(&s->listenq);
				return new - base;

M port/tcpinput.c => port/tcpinput.c +2 -0
@@ 85,7 85,9 @@ tcp_input(Ipconv *ipc, Block *bp)
				if(new == 0)
					goto clear;

				qlock(s);
				s->curlog++;
				qunlock(s);
				new->psrc = seg.dest;
				new->pdst = seg.source;
				new->dst = source;

M power/boot.c => power/boot.c +3 -43
@@ 2,7 2,7 @@
#include <libc.h>
#include <fcall.h>

#define DEFSYS "bit!bootes"
#define DEFSYS "cyc!bootes"
#define DEFFILE "/mips/9"

Fcall	hdr;


@@ 153,47 153,7 @@ dkdial(char *arg)
int
hotdial(char *arg)
{
	int fd;
	char srvdir[100];
	Waitmsg m;

	return open("#H/hotrod", ORDWR);

	/*
	 * The killer: gotta get a hotrodboot running, so dial up
	 * on datakit and load it.
	 */
	fd = dkdial(arg);
	if(fd < 0)
		return -1;
	if(!preamble(fd)){
		close(fd);
		return -1;
	}
	/*
	 * use /dev; it's local
	 */
	if(mount(fd, "/dev", MREPL, "", "") < 0)
		error("mount");
	switch(fork()){
	case 0:
		/*
		 * child: get hotrodboot running
		 */
		execl("/dev/mips/bin/hotrodboot", "hotrodboot", "/dev/hobbit/hot", 0);
		error("execl hotrodboot");
	case -1:
		error("fork");
	}
	/*
	 * parent: wait, then sleep a while
	 */
	wait(&m);
	if(m.msg[0])
		error(m.msg);
	fprint(2, "sleep 3 seconds\n");
	sleep(3*1000);
	fprint(2, "go for it....\n");
	USED(arg);
	return open("#H/hotrod", ORDWR);
}



@@ 278,7 238,7 @@ boot(int ask)
		fd = -1;
		if(strncmp(sys, "bit!", 4) == 0)
			fd = bitdial(&sys[4]);
		else if(strncmp(sys, "hot!", 4) == 0)
		else if(strncmp(sys, "cyc!", 4) == 0)
			fd = hotdial(&sys[4]);
		else if(strncmp(sys, "dk!", 3) == 0)
			fd = dkdial(&sys[3]);

D power/devbit3.c => power/devbit3.c +0 -244
@@ 1,244 0,0 @@
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"
#include	"devtab.h"

#include	"io.h"

static struct
{
	QLock;
	QLock	buflock;
	int	open;
	char	buf[10*1024];
}bit3;

#define	BIT3ADDR	((Bit3msg**)(KZERO+0x7C))
#define	BIT3HOLD	((ulong*)(KZERO+0x78))
#define	BIT3INTR	((char*)(UNCACHED|0x17c12001))

enum
{
	RESET,
	READ,
	WRITE,
};

void
bit3send(Bit3msg *bp, ulong cmd, void *addr, ulong count)
{
	do; while(*BIT3ADDR);
	bp->cmd = cmd;
	bp->addr = (ulong)addr;
	bp->count = count;
	*BIT3ADDR = bp;
	wbflush();
	do; while(*BIT3HOLD);
	*BIT3INTR = 0x20;

}

void
bit3reset(void)
{
	*BIT3HOLD = 0;
	*BIT3ADDR = 0;
	qlock(&bit3);
	qunlock(&bit3);
}

void
bit3init(void)
{
}

Chan*
bit3attach(char *spec)
{
	return devattach('3', spec);
}

Chan*
bit3clone(Chan *c, Chan *nc)
{
	return devclone(c, nc);
}

int	 
bit3walk(Chan *c, char *name)
{
	if(c->qid.path != CHDIR)
		return 0;
	if(strcmp(name, "bit3") == 0){
		c->qid.path = 1;
		return 1;
	}
	return 0;
}

void	 
bit3stat(Chan *c, char *dp)
{
	USED(c, dp);
	print("bit3stat\n");
	error(Egreg);
}

Chan*
bit3open(Chan *c, int omode)
{
	Bit3msg *bp;

	bp = &((User*)(u->p->upage->pa|KZERO))->kbit3;
	if(c->qid.path!=1 || omode!=ORDWR)
		error(Eperm);
	qlock(&bit3);
	if(bit3.open){
		qunlock(&bit3);
		error(Einuse);
	}
	bit3send(bp, RESET, 0, 0);
	bit3.open = 1;
	qunlock(&bit3);
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void	 
bit3create(Chan *c, char *name, int omode, ulong perm)
{
	USED(c, name, omode, perm);
	error(Eperm);
}

void	 
bit3close(Chan *c)
{
	USED(c);
	qlock(&bit3);
	bit3.open = 0;
	qunlock(&bit3);
}

/*
 * Read and write use physical addresses if they can, which they usually can.
 * Most I/O is from devmnt, which has local buffers.  Therefore just check
 * that buf is in KSEG0 and is at an even address.  The only killer is that
 * DMA counts from the bit3 device are mod 256, so devmnt must use oversize
 * buffers.
 */

long	 
bit3read(Chan *c, void *buf, long n, ulong offset)
{
	Bit3msg *bp;
	int docpy;
	long i;

	switch(c->qid.path){
	case 1:
		if(n > sizeof bit3.buf)
			error(Egreg);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){
			/*
			 *  use supplied buffer, no need to lock for reply
			 */
			bp = &((User*)(u->p->upage->pa|KZERO))->kbit3;
			bp->rcount = 0;
			qlock(&bit3);
			bit3send(bp, READ, buf, n);
			qunlock(&bit3);
			for(i=0; i<10*1000*1000; i++){
				n = bp->rcount;
				if(n != 0)
					return n;
				if(i > 5*1000*1000){
					u->p->psstate = "Bit3wait";
					while(waserror())
						;
					tsleep(&u->p->sleep, return0, 0, 1000);
					poperror();
				}
			}
			pexit("Suicide", 0);
		}else{
			/*
			 *  use bit3 buffer.  lock the buffer till the reply
			 */
			bp = &((User*)(u->p->upage->pa|KZERO))->ubit3;
			bp->rcount = 0;
			qlock(&bit3.buflock);
			qlock(&bit3);
			bit3send(bp, READ, bit3.buf, n);
			qunlock(&bit3);
			for(i=0; i<10*1000*1000; i++){
				n = bp->rcount;
				if(n != 0){
					memmove(buf, bit3.buf, n);
					qunlock(&bit3.buflock);
					return n;
				}
				if(i > 5*1000*1000){
					u->p->psstate = "Bit3wait";
					while(waserror())
						;
					tsleep(&u->p->sleep, return0, 0, 1000);
					poperror();
				}
			}
			qunlock(&bit3.buflock);
			pexit("Suicide", 0);
		}
	}
	error(Egreg);
	return 0;
}

long	 
bit3write(Chan *c, void *buf, long n, ulong offset)
{
	Bit3msg *bp;

	switch(c->qid.path){
	case 1:
		if(n > sizeof bit3.buf)
			error(Egreg);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){
			bp = &((User*)(u->p->upage->pa|KZERO))->kbit3;
			qlock(&bit3);
			bit3send(bp, WRITE, buf, n);
			qunlock(&bit3);
		}else{
			bp = &((User*)(u->p->upage->pa|KZERO))->ubit3;
			qlock(&bit3.buflock);
			qlock(&bit3);
			memmove(bit3.buf, buf, n);
			bit3send(bp, WRITE, bit3.buf, n);
			do; while(*BIT3ADDR);
			qunlock(&bit3);
			qunlock(&bit3.buflock);
		}
		return n;
	}
	error(Egreg);
	return 0;
}

void	 
bit3remove(Chan *c)
{
	USED(c);
	error(Eperm);
}

void	 
bit3wstat(Chan *c, char *dp)
{
	USED(c, dp);
	error(Eperm);
}

M power/devhotrod.c => power/devhotrod.c +4 -8
@@ 12,14 12,10 @@
#include	"../../fs/cyc/comm.h"


/*
 * If 1, ENABCKSUM causes data transfers to have checksums
 */
#define	ENABCKSUM	0

typedef struct Commrod	Commrod;

enum{
enum
{
	Vmevec=		0xd2,		/* vme vector for interrupts */
	Intlevel=	5,		/* level to interrupt on */
	Qdir=		0,		/* Qid's */


@@ 368,7 364,7 @@ hotrodwrite(Chan *c, void *buf, long n, ulong offset)
			mp->cmd = Uwrite;
			mp->param[0] = MP2VME(buf);
			mp->param[1] = n;
			mp->param[2] = hotsum(buf, n, ENABCKSUM);
			mp->param[2] = 0;
			hmp = hotsend(hp, mp);
			hotwait(hmp);
		}else{


@@ 382,7 378,7 @@ hotrodwrite(Chan *c, void *buf, long n, ulong offset)
			mp->cmd = Uwrite;
			mp->param[0] = MP2VME(hp->buf);
			mp->param[1] = n;
			mp->param[2] = hotsum((ulong*)hp->buf, n, ENABCKSUM);
			mp->param[2] = 0;
			hmp = hotsend(hp, mp);
			hotwait(hmp);
			qunlock(&hp->buflock);