~kris/9p

9hist

6d9091a694fc54cb78d42e50e2ef05f6904633da — David du Colombier 33 years ago b5339d6
Plan 9 from Bell Labs 1992-10-01
2 files changed, 46 insertions(+), 21 deletions(-)

M pc/devhard.c
M port/fault.c
M pc/devhard.c => pc/devhard.c +45 -21
@@ 45,7 45,7 @@ enum
	/* file types */
	Qdir=		0,

	Maxxfer=	32*512,		/* maximum transfer size/cmd */
	Maxxfer=	BY2PG,		/* maximum transfer size/cmd */
	Npart=		8+2,		/* 8 sub partitions, disk, and partition */
	Nrepl=		64,		/* maximum replacement blocks */
};


@@ 167,7 167,7 @@ hardreset(void)
	int drive;

	hard = xalloc(conf.nhard * sizeof(Drive));
	hardc = xalloc(((conf.nhard+1)/2 + 1) * sizeof(Controller));
	hardc = xalloc(((conf.nhard+1)/2) * sizeof(Controller));
	
	for(drive = 0; drive < conf.nhard; drive++){
		dp = &hard[drive];


@@ 285,10 285,13 @@ hardread(Chan *c, void *a, long n)

	buf = smalloc(Maxxfer);
	if(waserror()){
		print("hard read error\n");
		free(buf);
		nexterror();
	}

if(a&KZERO)print("rd k 0x%lux d 0x%lux\n", a, n);

	dp = &hard[DRIVE(c->qid.path)];
	pp = &dp->p[PART(c->qid.path)];



@@ 326,10 329,13 @@ hardwrite(Chan *c, void *a, long n)
	pp = &dp->p[PART(c->qid.path)];
	buf = smalloc(Maxxfer);
	if(waserror()){
		print("hard write error\n");
		free(buf);
		nexterror();
	}

if(a&KZERO)print("wr k 0x%lux d 0x%lux\n", a, n);

	/*
	 *  if not starting on a sector boundary,
	 *  read in the first sector before writing


@@ 401,7 407,7 @@ cmdreadywait(Controller *cp)

	start = m->ticks;
	while((inb(cp->pbase+Pstatus) & (Sready|Sbusy)) != Sready)
		if(TK2MS(m->ticks - start) > 1){
		if(TK2MS(m->ticks - start) > 5){
			DPRINT("cmdreadywait failed\n");
			error(Eio);
		}


@@ 430,7 436,7 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
	Controller *cp;
	long lblk;
	int cyl, sec, head;
	int loop;
	int loop, s;

	if(dp->online == 0)
		error(Eio);


@@ 451,46 457,38 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
	lblk = start + pp->start;
	if(lblk >= pp->end)
		return 0;
	if(lblk+len > pp->end)
		len = pp->end - lblk;
	cyl = lblk/(dp->sectors*dp->heads);
	sec = (lblk % dp->sectors) + 1;
	head = (dp->drive<<4) | ((lblk/dp->sectors) % dp->heads);

	/*
	 *  go for it
	 */
	cp = dp->cp;
	qlock(cp);
	cp->sofar = 0;
	cp->buf = buf;
	if(waserror()){
		cp->buf = 0;
		qunlock(cp);
		nexterror();
	}

	/*
	 *  can't xfer past end of disk
	 */
	if(lblk+len > pp->end)
		len = pp->end - lblk;
	cp->nsecs = len;

	cmdreadywait(cp);

	/*
	 *  start the transfer
	 *  splhi to make command atomic
	 */
	s = splhi();
	cp->sofar = 0;
	cp->buf = buf;
	cp->nsecs = len;
	cp->cmd = cmd;
	cp->dp = dp;
	cp->status = 0;

	outb(cp->pbase+Pcount, cp->nsecs-cp->sofar);
	outb(cp->pbase+Pcount, cp->nsecs);
	outb(cp->pbase+Psector, sec);
	outb(cp->pbase+Pdh, 0x20 | head);
	outb(cp->pbase+Pcyllsb, cyl);
	outb(cp->pbase+Pcylmsb, cyl>>8);
	outb(cp->pbase+Pcmd, cmd);

	if(cmd == Cwrite){
		loop = 0;
		while((inb(cp->pbase+Pstatus) & Sdrq) == 0)


@@ 498,8 496,25 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
				panic("hardxfer");
		outss(cp->pbase+Pdata, cp->buf, dp->bytes/2);
	}
	splx(s);

	/*
	 *  wait for command to complete.  if we get a note,
	 *  remember it but keep waiting to let the disk finish
	 *  the current command.
	 */
	loop = 0;
	while(waserror()){
		DPRINT("interrupted hardxfer\n");
		if(loop++ > 10){
			print("hard disk error\n");
			nexterror();
		}
	}
	sleep(&cp->r, cmddone, cp);
	poperror();
	if(loop)
		nexterror();

	if(cp->status & Serr){
		DPRINT("hd%d err: lblk %ld status %lux, err %lux\n",


@@ 510,10 525,11 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf)
		error(Eio);
	}
	cp->buf = 0;
	len = cp->sofar*dp->bytes;
	qunlock(cp);
	poperror();

	return cp->sofar*dp->bytes;
	return len;
}

/*


@@ 594,6 610,7 @@ hardident(Drive *dp)
	Controller *cp;
	char *buf;
	Ident *ip;
	int s;

	cp = dp->cp;
	buf = smalloc(Maxxfer);


@@ 605,6 622,7 @@ hardident(Drive *dp)

	cmdreadywait(cp);

	s = splhi();
	cp->nsecs = 1;
	cp->sofar = 0;
	cp->cmd = Cident;


@@ 612,6 630,8 @@ hardident(Drive *dp)
	cp->buf = buf;
	outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4));
	outb(cp->pbase+Pcmd, Cident);
	splx(s);

	sleep(&cp->r, cmddone, cp);
	if(cp->status & Serr){
		DPRINT("bad disk ident status\n");


@@ 654,6 674,7 @@ hardprobe(Drive *dp, int cyl, int sec, int head)
	buf = smalloc(Maxxfer);
	qlock(cp);
	if(waserror()){
		free(buf);
		qunlock(cp);
		nexterror();
	}


@@ 664,6 685,7 @@ hardprobe(Drive *dp, int cyl, int sec, int head)
	cp->dp = dp;
	cp->status = 0;
	cp->nsecs = 1;
	cp->sofar = 0;

	outb(cp->pbase+Pcount, 1);
	outb(cp->pbase+Psector, sec+1);


@@ 932,6 954,8 @@ hardintr(Ureg *ur)
			inss(cp->pbase+Pdata, addr, dp->bytes/2);
		}
		cp->sofar++;
		if(cp->sofar > cp->nsecs)
			print("hardintr %d %d\n", cp->sofar, cp->nsecs);
		if(cp->sofar >= cp->nsecs){
			cp->lastcmd = cp->cmd;
			if (cp->cmd == Cread)

M port/fault.c => port/fault.c +1 -0
@@ 247,6 247,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
void
faulterror(char *s)
{
	print("faulterror %s\n", s);
	if(u->nerrlab) {
		postnote(u->p, 1, s, NDebug);
		error(s);