~kris/9p

9hist

23c90a71403861ded3d26bf888e9eb1529b83e50 — David du Colombier 26 years ago cc7c0a0
Plan 9 from Bell Labs 2000-05-26
4 files changed, 66 insertions(+), 48 deletions(-)

M pc/sdata.c
M port/devbridge.c
M port/devsd.c
M port/sd.h
M pc/sdata.c => pc/sdata.c +42 -15
@@ 91,6 91,7 @@ enum {					/* Command */
	Cidpkt		= 0xA1,		/* Identify Packet Device */
	Crsm		= 0xC4,		/* Read Multiple */
	Cwsm		= 0xC5,		/* Write Multiple */
	Csm		= 0xC6,		/* Set Multiple */
	Crdq		= 0xC7,		/* Read DMA queued */
	Crd		= 0xC8,		/* Read DMA */
	Cwd		= 0xCA,		/* Write DMA */


@@ 225,11 226,12 @@ typedef struct Drive {
	int	s;			/* sector */
	int	sectors;		/* total */
	int	secsize;		/* sector size */

	int	dma;			/* DMA R/W possible */

	int	block;			/* R/W multiple size */
	int	pior;			/* PIO read command */
	int	piow;			/* PIO write command */
	int	dma;			/* DMA R/W possible */
	int	pkt;			/* PACKET device, length of pktcmd */

	uchar	sense[18];
	uchar	inquiry[48];


@@ 244,6 246,7 @@ typedef struct Drive {
	int	status;
	int	error;

	int	pkt;			/* PACKET device, length of pktcmd */
	uchar	pktcmd[16];
	int	pktdma;
} Drive;


@@ 411,6 414,40 @@ atacsfenabled(Drive* drive, vlong csf)
	return 0;
}

static int
atasetrwmode(Drive* drive, int cmdport, int ctlport, int dev)
{
	int as, block;

	drive->block = drive->secsize;
	drive->pior = Crs;
	drive->piow = Cws;
	if((block = drive->info[Imaxrwm] & 0xFF) == 0)
		return 0;

	/*
	 * Prior to ATA-4 there was no way to determine the
	 * current block count (now in Irwm).
	 * Sometimes drives come up with the current count set
	 * to 0, so always set a suitable value.
	 */
	if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 100*1000) < 0)
		return 0;
	outb(cmdport+Sector, block);
	outb(cmdport+Command, Csf);
	microdelay(1);
	as = ataready(cmdport, ctlport, dev, Bsy, Drdy|Df|Err, 1000);
	if(as < 0 || (as & (Df|Err)))
		return -1;

	drive->info[Irwm] = 0x100|block;
	drive->block = block*drive->secsize;
	drive->pior = Crsm;
	drive->piow = Cwsm;

	return block;
}

static Drive*
ataidentify(int cmdport, int ctlport, int dev)
{


@@ 471,6 508,8 @@ retry:
		*p++ = *sp>>8;
		*p++ = *sp++;
	}

	drive->secsize = 512;
	if((drive->info[Iconfig] & 0xC000) == 0x8000){
		if(drive->info[Iconfig] & 0x01)
			drive->pkt = 16;


@@ 495,20 534,8 @@ retry:
		}
		else
			drive->sectors = drive->c*drive->h*drive->s;
		atasetrwmode(drive, cmdport, ctlport, dev);
	}	
	drive->secsize = 512;

	if((drive->info[Imaxrwm] & 0xFF) && (drive->info[Irwm] & 0x0100)){
		drive->block = drive->info[Imaxrwm] & 0x00FF;
		drive->pior = Crsm;
		drive->piow = Cwsm;
	}
	else{
		drive->block = 1;
		drive->pior = Crs;
		drive->piow = Cws;
	}
	drive->block *= drive->secsize;

	/*
	 * Check if any DMA mode enabled.

M port/devbridge.c => port/devbridge.c +1 -1
@@ 30,7 30,7 @@ enum
	MaxQ,

	Maxbridge=	4,
	Maxport=	32,		// power of 2
	Maxport=	64,		// power of 2
	CacheHash=	257,		// prime
	CacheLook=	5,		// how many cache entries to examine
	CacheSize=	(CacheHash+CacheLook-1),

M port/devsd.c => port/devsd.c +22 -30
@@ 328,7 328,7 @@ sd2gen(Chan* c, int i, Dir* dp)
		return 1;
	case Qraw:
		q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qraw), c->qid.vers};
		devdir(c, q, "raw", 0, eve, 0600, dp);
		devdir(c, q, "raw", 0, eve, CHEXCL|0600, dp);
		return 1;
	case Qpart:
		unit = sdunit[UNIT(c->qid)];


@@ 492,6 492,12 @@ sdopen(Chan* c, int omode)
	switch(TYPE(c->qid)){
	default:
		break;
	case Qraw:
		unit = sdunit[UNIT(c->qid)];
		if(!canlock(&unit->rawinuse))
			error(Einuse);
		unit->state = Rawcmd;
		break;
	case Qpart:
		unit = sdunit[UNIT(c->qid)];
		qlock(&unit->ctl);


@@ 528,11 534,7 @@ sdclose(Chan* c)
		break;
	case Qraw:
		unit = sdunit[UNIT(c->qid)];
		if(canqlock(&unit->raw) || unit->pid == up->pid){
			unit->pid = 0;
			unit->state = Rawcmd;
			qunlock(&unit->raw);
		}
		unlock(&unit->rawinuse);
		break;
	case Qpart:
		unit = sdunit[UNIT(c->qid)];


@@ 744,23 746,15 @@ sdread(Chan *c, void *a, long n, vlong off)
		return l;
	case Qraw:
		unit = sdunit[UNIT(c->qid)];
		if(canqlock(&unit->raw)){
			qunlock(&unit->raw);
			error(Ebadusefd);
		}
		if(unit->pid != up->pid)
			error(Eperm);
		if(unit->state == Rawdata){
			unit->state = Rawstatus;
			return sdrio(unit->req, a, n);
		}
		else if(unit->state == Rawstatus){
			status = unit->req->status;
			unit->pid = 0;
			unit->state = Rawcmd;
			free(unit->req);
			unit->req = nil;
			qunlock(&unit->raw);
			return readnum(0, a, n, status, NUMSIZE);
		}
		break;


@@ 819,21 813,15 @@ sdwrite(Chan *c, void *a, long n, vlong off)
		poperror();
		free(cb);
		break;

	case Qraw:
		unit = sdunit[UNIT(c->qid)];
		if(canqlock(&unit->raw)){
			if(unit->state != Rawcmd){
				qunlock(&unit->raw);
				error(Ebadusefd);
			}
			if(n < 6 || n > sizeof(req->cmd)){
				qunlock(&unit->raw);
		switch(unit->state){
		case Rawcmd:
			if(n < 6 || n > sizeof(req->cmd))
				error(Ebadarg);
			}
			if((req = malloc(sizeof(SDreq))) == nil){
				qunlock(&unit->raw);
			if((req = malloc(sizeof(SDreq))) == nil)
				error(Enomem);
			}
			req->unit = unit;
			memmove(req->cmd, a, n);
			req->clen = n;


@@ 841,12 829,16 @@ sdwrite(Chan *c, void *a, long n, vlong off)
			req->status = ~0;

			unit->req = req;
			unit->pid = up->pid;
			unit->state = Rawdata;
		}
		else{
			if(unit->pid != up->pid)
				error(Eperm);
			break;

		case Rawstatus:
			unit->state = Rawcmd;
			free(unit->req);
			unit->req = nil;
			error(Ebadusefd);

		case Rawdata:
			if(unit->state != Rawdata)
				error(Ebadusefd);
			unit->state = Rawstatus;

M port/sd.h => port/sd.h +1 -2
@@ 32,9 32,8 @@ typedef struct SDunit {
	int	nopen;			/* of partitions on this unit */
	int	changed;

	QLock	raw;
	Lock	rawinuse;
	int	state;
	ulong	pid;
	SDreq*	req;
} SDunit;