plan 9 kernel history: overview | file list | diff list

1992/1217/pc/devfloppy.c (diff list | history)

1992/1216/sys/src/9/pc/devfloppy.c:13,241992/1217/sys/src/9/pc/devfloppy.c:13,28 (short | long | prev | next)
1991/0727    
typedef	struct Controller	Controller; 
1991/0802    
typedef struct Type		Type; 
1991/0727    
 
1992/1016    
#define DPRINT if(floppydebug)print 
1992/1217    
#define DPRINT if(floppydebug)kprint 
1992/1016    
int floppydebug; 
1992/0901    
 
1991/0924    
/* bits in the registers */ 
1991/0727    
enum 
{ 
1992/1217    
	/* status registers a & b */ 
	Psra=		0x3f0, 
	Psrb=		0x3f1, 
 
1991/0924    
	/* digital output register */ 
	Pdor=		0x3f2, 
	Fintena=	0x8,	/* enable floppy interrupt */ 
1992/1216/sys/src/9/pc/devfloppy.c:212,2171992/1217/sys/src/9/pc/devfloppy.c:216,228
1991/0802    
}; 
1991/0811    
#define NFDIR	2	/* directory entries/drive */ 
1991/0731    
 
1992/1217    
static void 
fldump(void) 
{ 
	DPRINT("sra %ux srb %ux dor %ux msr %ux dir %ux\n", inb(Psra), inb(Psrb), 
		inb(Pdor), inb(Pmsr), inb(Pdir)); 
} 
 
1992/1006    
/* 
 *  set floppy drive to its default type 
 */ 
1992/1216/sys/src/9/pc/devfloppy.c:380,3861992/1217/sys/src/9/pc/devfloppy.c:391,397
1992/1013    
 * 
 *  if the read fails, cycle through the possible floppy 
 *  density till one works or we've cycled through all 
 *  possibilities. 
1992/1217    
 *  possibilities for this drive. 
1991/0925    
 */ 
static void 
changed(Chan *c, Drive *dp) 
1992/1216/sys/src/9/pc/devfloppy.c:392,3981992/1217/sys/src/9/pc/devfloppy.c:403,410
1992/1013    
	 *  if floppy has changed or first time through 
	 */ 
	if((inb(Pdir)&Fchange) || dp->vers == 0){ 
1992/1216    
DPRINT("changed: msr %ux dir %ux\n", inb(Pmsr), inb(Pdir)); 
1992/1217    
		DPRINT("changed\n"); 
		fldump(); 
1991/0925    
		dp->vers++; 
1992/1013    
		setdef(dp); 
		start = dp->t; 
1992/1216/sys/src/9/pc/devfloppy.c:408,4161992/1217/sys/src/9/pc/devfloppy.c:420,429
1992/1013    
			} 
			floppydir[NFDIR*dp->dev].length = dp->t->cap; 
1992/1216    
			floppyon(dp); 
1992/1217    
			DPRINT("changed: trying %s\n", dp->t->name); 
			fldump(); 
1992/1013    
			if(dp->t == start) 
				nexterror(); 
1992/1016    
			DPRINT("changed: trying %s\n", dp->t->name); 
1992/1013    
		} 
		floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize); 
		poperror(); 
1992/1216/sys/src/9/pc/devfloppy.c:594,6021992/1217/sys/src/9/pc/devfloppy.c:607,620
1991/0924    
	alreadyon = fl.motor & MOTORBIT(dp->dev); 
	fl.motor |= MOTORBIT(dp->dev); 
	outb(Pdor, fl.motor | Fintena | Fena | dp->dev); 
1991/0921    
	if(!alreadyon) 
1992/1217    
	if(!alreadyon){ 
		/* wait for drive to spin up */ 
1991/0921    
		tsleep(&dp->r, return0, 0, 750); 
1991/0924    
 
1992/1217    
		/* clear any pending interrupts */ 
		floppysense(); 
	} 
 
1992/1003    
	/* set transfer rate */ 
	if(fl.rate != dp->t->rate){ 
		fl.rate = dp->t->rate; 
1992/1216/sys/src/9/pc/devfloppy.c:646,6551992/1217/sys/src/9/pc/devfloppy.c:664,675
1992/1016    
	fl.nstat = 0; 
1991/0924    
	for(i = 0; i < fl.ncmd; i++){ 
		for(tries = 0; ; tries++){ 
1992/1120    
			if(tries > 10000){ 
1992/1016    
				DPRINT("cmd %ux can't be sent (%d %ux)\n", 
					fl.cmd[0], i, inb(Pmsr)); 
1991/0924    
				fl.confused = 1; 
1992/1217    
			if(tries > 1000){ 
				DPRINT("cmd %ux can't be sent (%d)\n", fl.cmd[0], i); 
				fldump(); 
 
				/* empty fifo, might have been a bad command */ 
				floppyresult(); 
1991/0924    
				return -1; 
			} 
			if((inb(Pmsr)&(Ffrom|Fready)) == Fready) 
1992/1216/sys/src/9/pc/devfloppy.c:673,6811992/1217/sys/src/9/pc/devfloppy.c:693,705
1991/0924    
	int i, s; 
	int tries; 
1991/0727    
 
1992/1217    
	/* get the result of the operation */ 
1991/0924    
	for(i = 0; i < sizeof(fl.stat); i++){ 
1992/1217    
		/* wait for status byte */ 
1991/0924    
		for(tries = 0; ; tries++){ 
			if(tries > 1000){ 
1992/1217    
				DPRINT("floppyresult: %d stats\n", i); 
				fldump(); 
1991/0924    
				fl.confused = 1; 
				return -1; 
			} 
1992/1216/sys/src/9/pc/devfloppy.c:682,6881992/1217/sys/src/9/pc/devfloppy.c:706,712
1991/0924    
			s = inb(Pmsr)&(Ffrom|Fready); 
			if(s == Fready){ 
				fl.nstat = i; 
				return i; 
1992/1217    
				return fl.nstat; 
1991/0924    
			} 
			if(s == (Ffrom|Fready)) 
				break; 
1992/1216/sys/src/9/pc/devfloppy.c:689,6961992/1217/sys/src/9/pc/devfloppy.c:713,720
1991/0924    
		} 
		fl.stat[i] = inb(Pdata); 
1991/0727    
	} 
1991/0924    
	fl.nstat = i; 
	return i; 
1992/1217    
	fl.nstat = sizeof(fl.stat); 
	return fl.nstat; 
1991/0727    
} 
 
1991/0731    
/* 
1992/1216/sys/src/9/pc/devfloppy.c:732,7371992/1217/sys/src/9/pc/devfloppy.c:756,762
1991/0727    
		return -1; 
1991/0924    
	if(floppyresult() < 2){ 
1992/0901    
		DPRINT("can't read sense response\n"); 
1992/1217    
		fldump(); 
1991/0924    
		fl.confused = 1; 
1991/0727    
		return -1; 
	} 
1992/1216/sys/src/9/pc/devfloppy.c:746,7571992/1217/sys/src/9/pc/devfloppy.c:771,785
1991/0924    
} 
 
1991/0731    
/* 
1991/0924    
 *  wait for a floppy interrupt 
1992/1217    
 *  Wait for a floppy interrupt.  If none occurs in 5 seconds, we 
 *  may have missed one.  This only happens on some portables which 
 *  do power management behind our backs.  Call the interrupt 
 *  routine to try to clear any conditions. 
1991/0731    
 */ 
1991/0924    
static void 
floppywait(void) 
1991/0731    
{ 
1991/0924    
	tsleep(&fl.r, cmddone, 0, 2000); 
1992/1217    
	tsleep(&fl.r, cmddone, 0, 5000); 
1992/1216    
	if(!cmddone(0)) 
		floppyintr(0); 
1991/0731    
} 
1992/1216/sys/src/9/pc/devfloppy.c:765,7711992/1217/sys/src/9/pc/devfloppy.c:793,798
1991/0924    
	dp->ccyl = -1; 
1992/1016    
	dp->cyl = -1; 
1991/0727    
 
1992/1216    
DPRINT("floppyrecal: msr %ux dir %ux\n", inb(Pmsr), inb(Pdir)); 
1991/0924    
	fl.ncmd = 0; 
	fl.cmd[fl.ncmd++] = Frecal; 
	fl.cmd[fl.ncmd++] = dp->dev; 
1992/1216/sys/src/9/pc/devfloppy.c:807,8281992/1217/sys/src/9/pc/devfloppy.c:834,864
1991/0924    
	 *  reset the controller if it's confused 
1991/0727    
	 */ 
1991/0924    
	if(fl.confused){ 
1992/1216    
DPRINT("floppyrevive: msr %ux dir %ux\n", inb(Pmsr), inb(Pdir)); 
1992/1217    
		DPRINT("floppyrevive in\n"); 
		fldump(); 
 
1991/0727    
		/* reset controller and turn all motors off */ 
		splhi(); 
1992/1217    
		fl.ncmd = 1; 
1991/0924    
		fl.cmd[0] = 0; 
		outb(Pdor, 0); 
1991/0727    
		delay(1); 
1991/0924    
		outb(Pdor, Fintena|Fena); 
1991/0727    
		spllo(); 
1991/0924    
		for(dp = fl.d; dp < &fl.d[conf.nfloppy]; dp++) 
1991/0727    
			dp->confused = 1; 
1991/0924    
		fl.motor = 0; 
		floppywait(); 
		fl.confused = 0; 
1992/1217    
		floppywait(); 
 
		/* mark all drives in an unknown state */ 
		for(dp = fl.d; dp < &fl.d[conf.nfloppy]; dp++) 
			dp->confused = 1; 
 
		/* set rate to a known value */ 
1991/0925    
		outb(Pdsr, 0); 
1992/1216    
		fl.rate = 0; 
DPRINT("floppyrevive: msr %ux dir %ux\n", inb(Pmsr), inb(Pdir)); 
1992/1217    
 
		DPRINT("floppyrevive out\n"); 
		fldump(); 
1991/0727    
	} 
} 
 
1992/1216/sys/src/9/pc/devfloppy.c:839,8451992/1217/sys/src/9/pc/devfloppy.c:875,880
1992/1003    
		return dp->tcyl; 
1992/1016    
	dp->cyl = -1; 
1991/0727    
 
1992/1016    
	DPRINT("seek: tcyl %d, thead %d\n", dp->tcyl, dp->thead); 
1991/0924    
	fl.ncmd = 0; 
	fl.cmd[fl.ncmd++] = Fseek; 
	fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev; 
1992/1216/sys/src/9/pc/devfloppy.c:890,8981992/1217/sys/src/9/pc/devfloppy.c:925,930
1992/1016    
		dp->confused = 1; 
1992/0114    
		error(Eio); 
1992/1016    
	} 
1991/0925    
                 
1992/1016    
	DPRINT("floppyxfer: tcyl %d, thead %d, tsec %d, addr %lux, n %d\n", 
1992/0901    
	dp->tcyl, dp->thead, dp->tsec, a, dp->len); 
1991/0727    
 
	/* 
1991/0731    
	 *  set up the dma (dp->len may be trimmed) 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)