~kris/9p

9hist

23672e4936061d634094d2153f3fd088e2f823ed — David du Colombier 35 years ago 762e05f
Plan 9 from Bell Labs 1991-09-25
5 files changed, 113 insertions(+), 99 deletions(-)

M pc/devfloppy.c
M pc/dma.c
M port/devlance.c
M port/devmnt.c
M port/devnonet.c
M pc/devfloppy.c => pc/devfloppy.c +85 -61
@@ 39,7 39,8 @@ enum
	Fdumpreg=	0x0e,	/* dump internal registers */

	/* digital input register */
	Pdir=		0x3F7,	/* disk changed port */
	Pdir=		0x3F7,	/* disk changed port (read only) */
	Pdsr=		0x3F7,	/* data rate select port (write only) */
	Fchange=	0x80,	/* disk has changed */

	/* status 0 byte */


@@ 114,14 115,13 @@ static int c2b[] =
 */
struct Drive
{
	QLock;			/* exclusive access to the drive */

	Type	*t;
	int	dev;

	ulong	lasttouched;	/* time last touched */
	int	cyl;		/* current cylinder */
	int	confused;	/* needs to be recalibrated */
	int	vers;

	int	tcyl;		/* target cylinder */
	int	thead;		/* target head */


@@ 143,6 143,7 @@ struct Controller
	QLock;			/* exclusive access to the contoller */

	Drive	*d;		/* the floppy drives */
	Drive	*selected;
	uchar	cmd[14];	/* command */
	int	ncmd;		  /* # command bytes */
	uchar	stat[14];	/* command status */


@@ 162,6 163,7 @@ Controller	fl;
 */
static int	floppycmd(void);
static void	floppyeject(Drive*);
static void	floppyintr(Ureg*);
static void	floppykproc(void*);
static void	floppyon(Drive*);
static void	floppyoff(Drive*);


@@ 210,6 212,7 @@ floppyreset(void)
	 *  allocate the drive storage
	 */
	fl.d = ialloc(conf.nfloppy*sizeof(Drive), 0);
	fl.selected = fl.d;

	/*
	 *  stop the motors


@@ 229,12 232,14 @@ floppyreset(void)
		dp->cyl = -1;		/* because we don't know */
		dp->cache = (uchar*)ialloc(dp->t->tsize, 1);
		dp->ccyl = -1;
		dp->vers = 1;
	}

	/*
	 *  first operation will recalibrate
	 */
	fl.confused = 1;
	setvec(Floppyvec, floppyintr);
}

void


@@ 278,7 283,7 @@ floppystat(Chan *c, char *dp)
Chan*
floppyopen(Chan *c, int omode)
{
	return devopen(c, omode, floppydir, conf.nfloppy*NFDIR, devgen);
	devopen(c, omode, floppydir, conf.nfloppy*NFDIR, devgen);
}

void


@@ 304,6 309,40 @@ floppywstat(Chan *c, char *dp)
	error(Eperm);
}

static void
islegal(Chan *c, long n, Drive *dp)
{
	if(c->offset % dp->t->bytes)
		errors("bad offset");
	if(n % dp->t->bytes)
		errors("bad len");
}

/*
 *  check if the floppy has been replaced under foot
 *
 *  a seek and a read clears the condition.  this was determined experimentally,
 *  there has to be a better way.
 */
static void
changed(Chan *c, Drive *dp)
{
	ulong old;

	if(inb(Pdir)&Fchange)
		dp->vers++;
	old = c->qid.vers;
	c->qid.vers = dp->vers;
	if(old && old!=dp->vers){
		dp->ccyl = -1;
		if(dp->cyl)
			floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize);
		else
			floppyxfer(dp, Fread, dp->cache, dp->t->heads*dp->t->tsize, dp->t->tsize);
		errors("disk changed");
	}
}

long
floppyread(Chan *c, void *a, long n)
{


@@ 319,15 358,19 @@ floppyread(Chan *c, void *a, long n)

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];

	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		if(c->offset % dp->t->bytes)
			errors("bad offset");
		if(n % dp->t->bytes)
			errors("bad len");
		islegal(c, n, dp);
		aa = a;
		nn = dp->t->tsize;

		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += len){
			/*
			 *  truncate xfer at track boundary


@@ 356,6 399,9 @@ floppyread(Chan *c, void *a, long n)
			}
			memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
		}
		qunlock(&fl);
		poperror();

		break;
	case Qctl:
		break;


@@ 377,13 423,16 @@ floppywrite(Chan *c, void *a, long n)

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];

	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		if(c->offset % dp->t->bytes)
			errors("bad offset");
		if(n % dp->t->bytes)
			errors("bad len");
		islegal(c, n, dp);
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += i){
			floppypos(dp, c->offset+rv);
			if(dp->tcyl == dp->ccyl)


@@ 393,22 442,18 @@ floppywrite(Chan *c, void *a, long n)
			if(i <= 0)
				break;
		}
		qunlock(&fl);
		poperror();
		break;
	case Qctl:
		qlock(&fl);
		if(SNCMP(aa, "eject") == 0){
			floppyeject(dp);
		} else if(SNCMP(aa, "seek") == 0){
			aa += 5;
			floppyseek(dp, strtoul(aa, 0, 0));
		} else if(SNCMP(aa, "den") == 0){
			aa += 4;
			i = strtoul(aa, 0, 0);
			USED(i);
/*			devp->dsr = i;
			devp->ccr = i;/**/
		} else if(SNCMP(aa, "reset") == 0){
			fl.confused = 1;
			floppyon(dp);
		}
		qunlock(&fl);
		break;
	default:
		panic("floppywrite: bad qid");


@@ 421,26 466,20 @@ static void
floppykproc(void *a)
{
	Drive *dp;
int i;
static int last;

	while(waserror())
		;
	for(;;){
i = inb(Pdir) & 0x80;
if(i != last)
	print("fromn %d to %d\n", last, i);
last = i;
		for(dp = fl.d; dp < &fl.d[conf.nfloppy]; dp++){
			if((fl.motor&MOTORBIT(dp->dev))
			&& TK2SEC(m->ticks - dp->lasttouched) > 5
			&& canqlock(dp)){
			&& canqlock(&fl)){
				if(TK2SEC(m->ticks - dp->lasttouched) > 5)
					floppyoff(dp);
				qunlock(dp);
				qunlock(&fl);
			}
		}
		tsleep(&fl.kr, return0, 0, 5*100);
		tsleep(&fl.kr, return0, 0, 1000);
	}
}



@@ 469,6 508,7 @@ floppyon(Drive *dp)
			if(floppyrecal(dp) >= 0)
				break;
	dp->lasttouched = m->ticks;
	fl.selected = dp;
}

/*


@@ 479,6 519,7 @@ floppyoff(Drive *dp)
{
	fl.motor &= ~MOTORBIT(dp->dev);
	outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
	fl.selected = dp;
}

/*


@@ 488,6 529,7 @@ static void
floppyeject(Drive *dp)
{
	floppyon(dp);
	dp->vers++;
	floppyoff(dp);
}



@@ 670,8 712,7 @@ floppyrevive(void)
		fl.motor = 0;
		floppywait();
		fl.confused = 0;
/*		devp->dsr = 0;
		devp->ccr = 0; /**/
		outb(Pdsr, 0);
	}
}



@@ 683,7 724,6 @@ floppyrevive(void)
static long
floppyseek(Drive *dp, long off)
{
	floppyon(dp);
	floppypos(dp, off);
	if(dp->cyl == dp->tcyl)
		return dp->cyl;


@@ 723,23 763,13 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n)
	if(off + n > dp->t->cap)
		n = dp->t->cap - off;

	qlock(&fl);
	qlock(dp);
	if(waserror()){
		dmaend(DMAchan);
		qunlock(&fl);
		qunlock(dp);
		fl.confused = 1;
		nexterror();
	}

	/*
	 *  calculate new position and seek to it (dp->len may be trimmed)
	 */
	dp->len = n;
	if(floppyseek(dp, off) < 0)
		errors("seeking floppy");
	

/*print("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n",
	dp->tcyl, dp->thead, dp->tsec, a, dp->len);/**/



@@ 751,7 781,7 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n)
	/*
	 *  start operation
	 */
/*	cmd = cmd | (dp->t->heads > 1 ? Fmulti : 0);/**/
	cmd = cmd | (dp->t->heads > 1 ? Fmulti : 0);
	fl.ncmd = 0;
	fl.cmd[fl.ncmd++] = cmd;
	fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;


@@ 783,14 813,11 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n)
		errors("floppy result failed");
	}
	if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){
		if(fl.stat[1] != 0x80){
			print("xfer failed %lux %lux %lux\n", fl.stat[0],
				fl.stat[1], fl.stat[2]);
			print("offset %lud len %d\n", off, dp->len);
			dp->confused = 1;
			errors("floppy drive lost");
		} else
			fl.stat[5]++;
		print("xfer failed %lux %lux %lux\n", fl.stat[0],
			fl.stat[1], fl.stat[2]);
		print("offset %lud len %d\n", off, dp->len);
		dp->confused = 1;
		errors("floppy drive lost");
	}

	/*


@@ 801,20 828,17 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n)
	offset = offset * c2b[fl.stat[6]];
	if(offset != off+dp->len){
		print("new offset %d instead of %d\n", offset, off+dp->len);
		print("	%d %d %d\n", fl.stat[3], fl.stat[4], fl.stat[5]);
		dp->confused = 1;
		errors("floppy drive lost");
	}

	dp->lasttouched = m->ticks;
	qunlock(&fl);
	qunlock(dp);
	poperror();

	return dp->len;
}

void
floppyintr(void)
static void
floppyintr(Ureg *ur)
{
	switch(fl.cmd[0]&~Fmulti){
	case Fread:

M pc/dma.c => pc/dma.c +6 -5
@@ 106,7 106,8 @@ dmasetup(int chan, void *va, long len, int isread)
	 */
	pa = ((ulong)va) & ~KZERO;
	if(!isphys(va) || (pa&0xFFFF0000)!=((pa+len)&0xFFFF0000)){
		xp->pg = newpage(1, 0, 0);
		if(xp->pg == 0)
			xp->pg = newpage(1, 0, 0);
		if(len > BY2PG)
			len = BY2PG;
		if(!isread)


@@ 115,7 116,8 @@ dmasetup(int chan, void *va, long len, int isread)
		xp->len = len;
		xp->isread = isread;
		pa = xp->pg->pa;
	}
	} else
		xp->len = 0;

	/*
	 * this setup must be atomic


@@ 161,13 163,12 @@ dmaend(int chan)
	unlock(dp);

	xp = &dp->x[chan];
	if(xp->pg == 0)
	if(xp->len == 0)
		return;

	/*
	 *  copy out of temporary page
	 */
	memmove(xp->va, (void*)(KZERO|xp->pg->pa), xp->len);
	putpage(xp->pg);
	xp->pg = 0;
	xp->len = 0;
}

M port/devlance.c => port/devlance.c +7 -13
@@ 258,6 258,7 @@ lanceoput(Queue *q, Block *bp )
	Etherpkt *p;
	Ethertype *e;
	Msg *m;
	Block *nbp;

	if(bp->type == M_CTL){
		e = q->ptr;


@@ 276,16 277,11 @@ lanceoput(Queue *q, Block *bp )
	}

	/*
	 *  save up to a delim
	 */
	if(!putq(q, bp))
		return;

	/*
	 *  only one transmitter at a time
	 */
	qlock(&l.tlock);
	if(waserror()){
		freeb(bp);
		qunlock(&l.tlock);
		nexterror();
	}


@@ 300,17 296,14 @@ lanceoput(Queue *q, Block *bp )
	 *  copy message into lance RAM
	 */
	len = 0;
	while(bp = getq(q)){
		if(sizeof(Etherpkt) - len >= (n = BLEN(bp))){
			memmove(((uchar *)p)+len, bp->rptr, n);
	for(nbp = bp; nbp; nbp = nbp->next){
		if(sizeof(Etherpkt) - len >= (n = BLEN(nbp))){
			memmove(((uchar *)p)+len, nbp->rptr, n);
			len += n;
		} else
			print("no room damn it\n");
		if(bp->flags & S_DELIM){
			freeb(bp);
		if(bp->flags & S_DELIM)
			break;
		} else
			freeb(bp);
	}

	/*


@@ 338,6 331,7 @@ lanceoput(Queue *q, Block *bp )
	l.tc = TSUCC(l.tc);
	*l.rdp = INEA|TDMD; /**/
	wbflush();
	freeb(bp);
	qunlock(&l.tlock);
	poperror();
}

M port/devmnt.c => port/devmnt.c +12 -9
@@ 351,8 351,11 @@ mntclunk(Chan *c, int t)
	m = mntchk(c);
	r = mntralloc();
	if(waserror()){
		mntfree(r);
		if(decref(m) == 0) {
			for(q = m->queue; q; q = r) {
if(q->flushed == 0)
print("mail philw: %lux: not flushed\n", q);
				r = q->list;
				q->flushed = 0;
				mntfree(q);


@@ 364,7 367,6 @@ mntclunk(Chan *c, int t)
			mntalloc.mntfree = m;
			unlock(&mntalloc);
		}
		mntfree(r);
		return;
	}



@@ 493,15 495,16 @@ mountio(Mnt *m, Mntrpc *r)
	n = convS2M(&r->request, r->rpc);
	if(waserror()) {
		qunlock(&m->c->wrl);
		mntqrm(m, r);
		nexterror();
		if(mntflush(m, r) == 0)
			nexterror();
	}
	else {
		qlock(&m->c->wrl);
		if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n)
			error(Eshortmsg);
		qunlock(&m->c->wrl);
		poperror();
	}
	qlock(&m->c->wrl);
	if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n)
		error(Eshortmsg);
	qunlock(&m->c->wrl);
	poperror();

	if(m->mux) {
		mntqrm(m, r);
		mntrpcread(m, r);

M port/devnonet.c => port/devnonet.c +3 -11
@@ 623,19 623,11 @@ nooput(Queue *q, Block *bp)
	/*
	 *  send the message, the kproc will retry
	 */
	if(waserror()){
		/* throw out the message */
		freeb(mp->first);
		mp->first = 0;
		mp->acked = 0;
		if(MSUCC(cp->first) == cp->next)
			cp->first = cp->next;
		qunlock(cp);
		nexterror();
	if(!waserror()){
		nosend(cp, mp);
		poperror();
	}
	nosend(cp, mp);
	qunlock(cp);
	poperror();
}

/*