~kris/9p

9hist

8391cd43606855f9f18c7934d600ec9ca298a2f2 — David du Colombier 33 years ago 1da40af
Plan 9 from Bell Labs 1992-10-03
1 files changed, 50 insertions(+), 24 deletions(-)

M pc/devfloppy.c
M pc/devfloppy.c => pc/devfloppy.c +50 -24
@@ 60,7 60,7 @@ enum
};

/*
 *  floppy types
 *  floppy types (all MFM encoding)
 */
struct Type
{


@@ 72,7 72,7 @@ struct Type
	int	tracks;		/* tracks/disk */
	int	gpl;		/* intersector gap length for read/write */	
	int	fgpl;		/* intersector gap length for format */
	int	ring;		/* ring of compatible floppy types */
	int	rate;		/* rate code */

	/*
	 *  these depend on previous entries and are set filled in


@@ 84,12 84,12 @@ struct Type
};
Type floppytype[] =
{
[0]	{ "MF2HD",	512,	18,	2,	1,	80,	0x1B,	0x54,	1, },
[1]	{ "MF1DD",	512,	9,	2,	1,	80,	0x1B,	0x54,	2, },
[2]	{ "MF4HD",	1024,	18,	2,	1,	80,	0x1B,	0x54,	0, },
[3]	{ "F2HD",	512,	15,	2,	1,	80,	0x2A,	0x50,	4, },
[4]	{ "F2DD",	512,	8,	2,	2,	40,	0x2A,	0x50,	5, },
[5]	{ "F1DD",	512,	8,	1,	2,	40,	0x2A,	0x50,	3, },
 { "3½HD",	512,	18,	2,	1,	80,	0x1B,	0x54,	0, },
 { "3½DD",	512,	9,	2,	1,	80,	0x1B,	0x54,	2, },
 { "5¼HD",	512,	15,	2,	1,	80,	0x2A,	0x50,	0, },
 { "5¼DD2",	512,	9,	2,	2,	40,	0x2A,	0x50,	2, },
 { "5¼DD1",	512,	9,	2,	2,	40,	0x2A,	0x50,	1, },
 { "3½ED",	1024,	18,	2,	1,	80,	0x1B,	0x54,	3, },
};
#define NTYPES (sizeof(floppytype)/sizeof(Type))



@@ 122,7 122,7 @@ struct Drive
	int	dev;

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



@@ 147,6 147,7 @@ struct Controller

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


@@ 230,7 231,7 @@ floppyreset(void)
		dp->dev = dp - fl.d;
		dp->t = &floppytype[0];		/* default type */
		floppydir[NFDIR*dp->dev].length = dp->t->cap;
		dp->cyl = -1;		/* because we don't know */
		dp->arm = -1;		/* because we don't know */
		dp->cache = (uchar*)xspanalloc(dp->t->tsize, BY2PG, 0);
		dp->ccyl = -1;
		dp->vers = 1;


@@ 337,15 338,17 @@ changed(Chan *c, Drive *dp)
	if(inb(Pdir)&Fchange){
		dp->vers++;
		dp->ccyl = -1;
		if(dp->cyl)
		if(dp->arm)
			floppythrice(dp, Fread, dp->cache, 0, dp->t->tsize);
		else
			floppythrice(dp, Fread, dp->cache, dp->t->heads*dp->t->tsize, dp->t->tsize);
			floppythrice(dp, Fread, dp->cache, dp->t->heads*dp->t->tsize,
					dp->t->tsize);
	}
	old = c->qid.vers;
	c->qid.vers = dp->vers;
	if(old && old!=dp->vers)
	if(old && old!=dp->vers){
		error(Eio);
	}
}

long


@@ 366,7 369,6 @@ floppyread(Chan *c, void *a, long n)
	case Qdata:
		islegal(c, n, dp);
		aa = a;
		nn = dp->t->tsize;

		qlock(&fl);
		if(waserror()){


@@ 385,6 387,7 @@ floppyread(Chan *c, void *a, long n)
			head = dp->thead;
			len = dp->len;
			sec = dp->tsec;
			nn = dp->t->tsize;

			/*
			 *  read the track


@@ 396,7 399,8 @@ floppyread(Chan *c, void *a, long n)
				if(i != nn){
					if(i == 0)
						break;
					error(Eio);
					len = 0;
					continue;
				}
				dp->ccyl = cyl;
				dp->chead = head;


@@ 512,6 516,12 @@ floppyon(Drive *dp)
	if(!alreadyon)
		tsleep(&dp->r, return0, 0, 750);

	/* set transfer rate */
	if(fl.rate != dp->t->rate){
		fl.rate = dp->t->rate;
		outb(Pdsr, fl.rate);
	}

	/* get drive to a known cylinder */
	if(dp->confused)
		for(tries = 0; tries < 4; tries++)


@@ 683,9 693,9 @@ floppyrecal(Drive *dp)
		dp->confused = 1;
		return -1;
	}
	dp->cyl = fl.stat[1]/dp->t->steps;
	if(dp->cyl != 0){
		DPRINT("recalibrate went to wrong cylinder %d\n", dp->cyl);
	dp->arm = fl.stat[1];
	if(dp->arm != 0){
		DPRINT("recalibrate went to wrong cylinder %d\n", dp->arm);
		dp->confused = 1;
		return -1;
	}


@@ 720,6 730,7 @@ floppyrevive(void)
		floppywait();
		fl.confused = 0;
		outb(Pdsr, 0);
		fl.rate = 0;
	}
}



@@ 732,8 743,8 @@ static long
floppyseek(Drive *dp, long off)
{
	floppypos(dp, off);
	if(dp->cyl == dp->tcyl)
		return dp->cyl;
	if(dp->arm*dp->t->steps == dp->tcyl)
		return dp->tcyl;

	DPRINT("seeking tcyl %d, thead %d\n", dp->tcyl, dp->thead);
	fl.ncmd = 0;


@@ 746,6 757,7 @@ floppyseek(Drive *dp, long off)
	}
	floppywait();
	if(fl.nstat < 2){
		DPRINT("seek cmd confused\n");
		fl.confused = 1;
		return -1;
	}


@@ 755,8 767,8 @@ floppyseek(Drive *dp, long off)
		return -1;
	}

	dp->cyl = dp->tcyl;
	return dp->cyl;
	dp->arm = dp->tcyl*dp->t->steps;
	return dp->tcyl;
}

/*


@@ 768,11 780,24 @@ floppythrice(Drive *dp, int cmd, void *a, long off, long n)
{
	int tries;
	long rv;
	Type *start;

	start = dp->t;
	for(tries = 0; ; tries++){
		if(waserror()){
			if(strcmp(u->error, Eintr)==0 || tries > 3)
			if(cmd != Fread || strcmp(u->error, Eintr)==0)
				nexterror();

			/* walk through the compatible types */
			if(tries == 3){
				if(++dp->t == &floppytype[NTYPES])
					dp->t = floppytype;
				floppydir[NFDIR*dp->dev].length = dp->t->cap;
				if(dp->t == start)
					nexterror();
				tries = 0;
				floppyon(dp);
			}
		} else {
			rv = floppyxfer(dp, cmd, a, off, n);
			poperror();


@@ 851,10 876,11 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n)
	/*
	 *  check for correct cylinder
	 */
	offset = (fl.stat[3]/dp->t->steps) * dp->t->heads + fl.stat[4];
	offset = ((fl.stat[3]+dp->t->steps-1)/dp->t->steps) * dp->t->heads + fl.stat[4];
	offset = offset*dp->t->sectors + fl.stat[5] - 1;
	offset = offset * c2b[fl.stat[6]];
	if(offset != off+dp->len){
		DPRINT("xfer ends on wrong cyl\n");
		dp->confused = 1;
		error(Eio);
	}