~kris/9p

9hist

f90b2249fb5c368c5002206e650bf147efd4b812 — David du Colombier 28 years ago 3910fc3
Plan 9 from Bell Labs 1998-02-19
1 files changed, 67 insertions(+), 29 deletions(-)

M pc/devata.c
M pc/devata.c => pc/devata.c +67 -29
@@ 10,9 10,9 @@
#include	"io.h"
#include	"../port/error.h"


#define DPRINT if(0)print
#define XPRINT if(0)print
#define DEBUG	0
#define DPRINT if(DEBUG)print
#define XPRINT if(DEBUG)print
#define ILOCK(x)
#define IUNLOCK(x)



@@ 69,6 69,7 @@ enum
	Creqsense=	0x03,
	Ccapacity=	0x25,
	Cread2=		0x28,
	Cwrite2=	0x2A,

	/* disk states */
	Sspinning,


@@ 199,7 200,7 @@ static void	atasleep(Controller*, int);
static void	ataclock(void);

static int	isatapi(Drive*);
static long	atapirwio(Chan*, char*, ulong, ulong);
static long	atapirwio(Chan*, uchar*, ulong, ulong, int);
static void	atapipart(Drive*);
static void	atapiintr(Controller*);



@@ 400,7 401,6 @@ atactlrprobe(int ctlrno, int irq, int resetok)

	atapi = 0;
	mask = 0;
	status = inb(port+Pstatus);
	DPRINT("ata%d: ATAPI %uX %uX %uX\n", ctlrno, status,
		inb(port+Pcylmsb), inb(port+Pcyllsb));
	if(status == 0 && inb(port+Pcylmsb) == 0xEB && inb(port+Pcyllsb) == 0x14){


@@ 408,8 408,7 @@ atactlrprobe(int ctlrno, int irq, int resetok)
		intrenable(irq, ataintr, ctlr, ctlr->tbdf);
		atapi |= 0x01;
		mask |= 0x01;
//		goto skipedd;
goto atapislave;
		goto atapislave;
	}
	if(atactlrwait(ctlr, DHmagic, 0, MS2TK(1)) || waserror()){
		DPRINT("ata%d: Cedd status %ux/%ux/%ux\n", ctlrno,


@@ 441,9 440,11 @@ goto atapislave;
	 *	in the cylinder registers after reset. Of course, if the drive
	 *	has been messed about by the BIOS or some other O/S then the
	 *	signature may be gone.
	 * When checking status, mask off the IDX bit.
	 */
	error = inb(port+Perror);
	DPRINT("ata%d: master diag error %ux\n", ctlr->ctlrno, error);
	DPRINT("ata%d: master diag status %uX, error %ux\n",
		ctlr->ctlrno, inb(port+Pstatus), error);
	if((error & ~0x80) == 0x01)
		mask |= 0x01;



@@ 453,7 454,7 @@ atapislave:
	status = inb(port+Pstatus);
	error = inb(port+Perror);
	DPRINT("ata%d: slave diag status %ux, error %ux\n", ctlr->ctlrno, status, error);
	if(status && (status & (Sbusy|Serr)) == 0 && (error & ~0x80) == 0x01)
	if((status & ~0x02) && (status & (Sbusy|Serr)) == 0 && (error & ~0x80) == 0x01)
		mask |= 0x02;
	else if(status == 0){
		msb = inb(port+Pcylmsb);


@@ 658,7 659,7 @@ ataread(Chan* c, void* a, long n, ulong offset)
			atapipart(dp);
		qunlock(dp);
		poperror();
		return atapirwio(c, a, n, offset);
		return atapirwio(c, a, n, offset, Cread2);
	}
	pp = &dp->p[PART(c->qid.path)];



@@ 699,8 700,19 @@ atawrite(Chan *c, void *a, long n, ulong offset)
		error(Eisdir);

	dp = atadrive[DRIVE(c->qid.path)];
	if(dp->atapi)
		error(Eperm);
	if(dp->atapi){
		if(dp->online == 0 || dp->atapi == 1)
			error(Eio);
		if(waserror()){
			qunlock(dp);
			nexterror();
		}
		qlock(dp);
		if(dp->partok == 0)
			atapipart(dp);
		qunlock(dp);
		poperror();
	}
	pp = &dp->p[PART(c->qid.path)];

	buf = smalloc(Maxxfer);


@@ 716,13 728,19 @@ atawrite(Chan *c, void *a, long n, ulong offset)
	 */
	partial = offset % dp->bytes;
	if(partial){
		ataxfer(dp, pp, Cread, offset-partial, dp->bytes, buf);
		if(dp->atapi)
			atapirwio(c, buf, dp->bytes, offset-partial, Cread2);
		else
			ataxfer(dp, pp, Cread, offset-partial, dp->bytes, buf);
		if(partial+n > dp->bytes)
			rv = dp->bytes - partial;
		else
			rv = n;
		memmove(buf+partial, aa, rv);
		ataxfer(dp, pp, Cwrite, offset-partial, dp->bytes, buf);
		if(dp->atapi)
			atapirwio(c, buf, dp->bytes, offset-partial, Cwrite2);
		else
			ataxfer(dp, pp, Cwrite, offset-partial, dp->bytes, buf);
	} else
		rv = 0;



@@ 736,7 754,10 @@ atawrite(Chan *c, void *a, long n, ulong offset)
		if(i > Maxxfer)
			i = Maxxfer;
		memmove(buf, aa+rv, i);
		i = ataxfer(dp, pp, Cwrite, offset+rv, i, buf);
		if(dp->atapi)
			i = atapirwio(c, buf, i, offset+rv, Cwrite2);
		else
			i = ataxfer(dp, pp, Cwrite, offset+rv, i, buf);
		if(i == 0)
			break;
	}


@@ 747,9 768,15 @@ atawrite(Chan *c, void *a, long n, ulong offset)
	 *  it out.
	 */
	if(partial){
		ataxfer(dp, pp, Cread, offset+rv, dp->bytes, buf);
		if(dp->atapi)
			atapirwio(c, buf, dp->bytes, offset+rv, Cread2);
		else
			ataxfer(dp, pp, Cread, offset+rv, dp->bytes, buf);
		memmove(buf, aa+rv, partial);
		ataxfer(dp, pp, Cwrite, offset+rv, dp->bytes, buf);
		if(dp->atapi)
			atapirwio(c, buf, dp->bytes, offset+rv, Cwrite2);
		else
			ataxfer(dp, pp, Cwrite, offset+rv, dp->bytes, buf);
		rv += partial;
	}



@@ 1101,6 1128,8 @@ retryatapi:
		dp->bytes = 2048;
		if((ip->config & 0x0060) == 0x0020)
			dp->drqintr = 1;
		if((ip->config & 0x1F00) == 0x0000)
			dp->atapi = 2;
	}
	if(dp->spindown && (ip->capabilities & (1<<13)))
		dp->spindown /= 5;


@@ 1672,7 1701,7 @@ atapiexec(Drive *dp)
}

static long
atapiio(Drive *dp, char *a, ulong len, ulong offset)
atapiio(Drive *dp, uchar *a, ulong len, ulong offset, int cmd)
{
	ulong bn, n, o, m;
	Controller *cp;


@@ 1681,7 1710,10 @@ atapiio(Drive *dp, char *a, ulong len, ulong offset)

	cp = dp->cp;

	buf = smalloc(Maxxfer);
	if(cmd == Cread2)
		buf = smalloc(Maxxfer);
	else
		buf = 0;
	qlock(cp->ctlrlock);
	retrycount = 2;
retry:


@@ 1695,12 1727,16 @@ retry:
			}
		}
		cp->dp = 0;
		free(buf);
		if(cmd == Cread2)
			free(buf);
		qunlock(cp->ctlrlock);
		nexterror();
	}

	cp->buf = buf;
	if(cmd == Cread2)
		cp->buf = buf;
	else
		cp->buf = a;
	cp->dp = dp;
	cp->len = dp->bytes;



@@ 1714,7 1750,7 @@ retry:
		if(m > n)
			m = n;
		memset(cp->cmdblk, 0, 12);
		cp->cmdblk[0] = Cread2;
		cp->cmdblk[0] = cmd;
		cp->cmdblk[2] = bn >> 24;
		cp->cmdblk[3] = bn >> 16;
		cp->cmdblk[4] = bn >> 8;


@@ 1732,14 1768,15 @@ retry:
		a += m;
	}
	poperror();
	free(buf);
	if(cmd == Cread2)
		free(buf);
	cp->dp = 0;
	qunlock(cp->ctlrlock);
	return len-n;
}

static long
atapirwio(Chan *c, char *a, ulong len, ulong offset)
atapirwio(Chan *c, uchar *a, ulong len, ulong offset, int cmd)
{
	Drive *dp;
	ulong vers;


@@ 1757,7 1794,7 @@ atapirwio(Chan *c, char *a, ulong len, ulong offset)
	c->qid.vers = dp->vers;
	if(vers && vers != dp->vers)
		error(Eio);
	rv = atapiio(dp, a, len, offset);
	rv = atapiio(dp, a, len, offset, cmd);

	poperror();
	qunlock(dp);


@@ 1860,9 1897,6 @@ atapiintr(Controller *cp)
	DPRINT("%s: atapiintr %uX\n", cp->dp->vol, cause);
	switch(cause){

	case 0:						/* data out */
		cp->status |= Serr;
		/*FALLTHROUGH*/
	case 1:						/* command */
		if(cp->status & Serr){
			cp->lastcmd = cp->cmd;


@@ 1874,6 1908,7 @@ atapiintr(Controller *cp)
		outss(pbase+Pdata, cp->cmdblk, sizeof(cp->cmdblk)/2);
		break;

	case 0:						/* data out */
	case 2:						/* data in */
		addr = cp->buf;
		if(addr == 0){


@@ 1904,7 1939,10 @@ atapiintr(Controller *cp)
		count = inb(pbase+Pcyllsb)|(inb(pbase+Pcylmsb)<<8);
		if (count > Maxxfer) 
			count = Maxxfer;
		inss(pbase+Pdata, addr, count/2);
		if(cause == 0)
			outss(pbase+Pdata, addr, count/2);
		else
			inss(pbase+Pdata, addr, count/2);
		cp->count = count;
		cp->lastcmd = cp->cmd; 
		break;