~kris/9p

9hist

0d469f507f78ea64ef3e035ad23cbbd440fc868c — David du Colombier 26 years ago 6ad2efd
Plan 9 from Bell Labs 2000-08-13
3 files changed, 47 insertions(+), 21 deletions(-)

M pc/devfloppy.c
M pc/devlpt.c
M pc/floppy.h
M pc/devfloppy.c => pc/devfloppy.c +37 -14
@@ 100,7 100,7 @@ static int	floppyresult(void);
static void	floppyrevive(void);
static long	floppyseek(FDrive*, long);
static int	floppysense(void);
static void	floppywait(void);
static void	floppywait(int);
static long	floppyxfer(FDrive*, int, void*, long, long);

Dirtab floppydir[]={


@@ 272,12 272,24 @@ changed(Chan *c, FDrive *dp)
		DPRINT("changed\n");
		fldump();
		dp->vers++;
		floppysetdef(dp);
		start = dp->t;
		dp->maxtries = 3;	/* limit it when we're probing */

		/* floppyon will fail if there's a controller but no drive */
		dp->confused = 1;	/* make floppyon recal */
		floppyon(dp);
		if(floppyon(dp) < 0)
			error(Eio);

		/* seek to the first track */
		floppyseek(dp, dp->t->heads*dp->t->tsize);
		while(waserror()){
			/*
			 *  if first attempt doesn't reset changed bit, there's
			 *  no floppy there
			 */
			if(inb(Pdir)&Fchange)
				nexterror();

			while(++dp->t){
				if(dp->t == &floppytype[nelem(floppytype)])
					dp->t = floppytype;


@@ 285,14 297,21 @@ changed(Chan *c, FDrive *dp)
					break;
			}
			floppydir[NFDIR*dp->dev].length = dp->t->cap;
			floppyon(dp);

			/* floppyon will fail if there's a controller but no drive */
			if(floppyon(dp) < 0)
				error(Eio);

			DPRINT("changed: trying %s\n", dp->t->name);
			fldump();
			if(dp->t == start)
				nexterror();
		}

		/* if the read succeeds, we've got the density right */
		floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize);
		poperror();
		dp->maxtries = 20;
	}

	old = c->qid.vers;


@@ 467,7 486,7 @@ floppykproc(void *)
/*
 *  start a floppy drive's motor.
 */
static void
static int
floppyon(FDrive *dp)
{
	int alreadyon;


@@ 501,6 520,11 @@ floppyon(FDrive *dp)
				break;
	dp->lasttouched = m->ticks;
	fl.selected = dp;

	/* return -1 if this didn't work */
	if(dp->confused)
		return -1;
	return 0;
}

/*


@@ 639,9 663,9 @@ cmddone(void *)
 *  routine to try to clear any conditions.
 */
static void
floppywait(void)
floppywait(int slow)
{
	tsleep(&fl.r, cmddone, 0, 5000);
	tsleep(&fl.r, cmddone, 0, slow ? 5000 : 1000);
	if(!cmddone(0)){
		floppyintr(0);
		fl.confused = 1;


@@ 662,7 686,7 @@ floppyrecal(FDrive *dp)
	fl.cmd[fl.ncmd++] = dp->dev;
	if(floppycmd() < 0)
		return -1;
	floppywait();
	floppywait(1);
	if(fl.nstat < 2){
		DPRINT("recalibrate: confused %ux\n", inb(Pmsr));
		fl.confused = 1;


@@ 712,7 736,7 @@ floppyrevive(void)
		spllo();
		fl.motor = 0;
		fl.confused = 0;
		floppywait();
		floppywait(0);

		/* mark all drives in an unknown state */
		for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++)


@@ 746,7 770,7 @@ floppyseek(FDrive *dp, long off)
	fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
	if(floppycmd() < 0)
		return -1;
	floppywait();
	floppywait(1);
	if(fl.nstat < 2){
		DPRINT("seek: confused\n");
		fl.confused = 1;


@@ 779,10 803,9 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
	/* retry on error (until it gets ridiculous) */
	tries = 0;
	while(waserror()){
		if(tries++ > 20)
		if(tries++ >= dp->maxtries)
			nexterror();
		DPRINT("floppyxfer: retrying\n");
		/*floppyon(dp);*/
	}

	dp->len = n;


@@ 825,7 848,7 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
	/*
	 *  give bus to DMA, floppyintr() will read result
	 */
	floppywait();
	floppywait(0);
	dmaend(DMAchan);
	poperror();



@@ 961,7 984,7 @@ floppyformat(FDrive *dp, char *params)
		/*
		 *  give bus to DMA, floppyintr() will read result
		 */
		floppywait();
		floppywait(1);
		dmaend(DMAchan);
		poperror();


M pc/devlpt.c => pc/devlpt.c +8 -6
@@ 178,15 178,17 @@ outch(int base, int c)
{
	int status, tries;

	for(tries = 0;; tries++){
	for(tries=0;; tries++) {
		status = inb(base+Qpsr);
		if(!(status & Fselect) || !(status & Fnoerror))
			error(Eio);
		if(status & Fnotbusy)
		if(status&Fnotbusy)
			break;
		if(tries > 1000){
		if((status&Fpe)==0 && (status&(Fselect|Fnoerror)) != (Fselect|Fnoerror))
			error(Eio);
		if(tries < 10)
			tsleep(&lptrendez, return0, nil, 1);
		else {
			outb(base+Qpcr, Finitbar|Fie);
			tsleep(&lptrendez, lptready, (void *)base, MS2HZ);
			tsleep(&lptrendez, lptready, (void *)base, 100);
		}
	}
	outb(base+Qdlr, c);

M pc/floppy.h => pc/floppy.h +2 -1
@@ 3,7 3,7 @@ typedef	struct FDrive FDrive;
typedef struct FType FType;

static void floppyintr(Ureg*);
static void floppyon(FDrive*);
static int floppyon(FDrive*);
static void floppyoff(FDrive*);
static void floppysetdef(FDrive*);



@@ 20,6 20,7 @@ struct FDrive
	int	cyl;		/* current arm position */
	int	confused;	/* needs to be recalibrated */
	int	vers;
	int	maxtries;	/* max read attempts before Eio */

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