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

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

1992/1007/sys/src/9/pc/devfloppy.c:5,101992/1009/sys/src/9/pc/devfloppy.c:5,11 (short | long | prev | next)
1991/0727    
#include	"fns.h" 
#include	"io.h" 
1992/0111    
#include	"../port/error.h" 
1992/1009    
#include	"devtab.h" 
1991/0727    
 
1991/0924    
/* Intel 82077A (8272A compatible) floppy controller */ 
1991/0920    
 
1992/1007/sys/src/9/pc/devfloppy.c:194,2001992/1009/sys/src/9/pc/devfloppy.c:195,201
1991/0924    
static int	floppysense(void); 
static void	floppywait(void); 
1991/0802    
static long	floppyxfer(Drive*, int, void*, long, long); 
1992/1007    
static int	floppyformat(Drive*, ulong, ulong); 
1992/1009    
static void	floppyformat(Drive*, char*); 
1991/1006    
static long	floppythrice(Drive*, int, void*, long, long); 
1991/0924    
static int	cmddone(void*); 
void Xdelay(int); 
1992/1007/sys/src/9/pc/devfloppy.c:362,3701992/1009/sys/src/9/pc/devfloppy.c:363,371
1991/0802    
} 
 
1991/0925    
static void 
islegal(Chan *c, long n, Drive *dp) 
1992/1009    
islegal(ulong offset, long n, Drive *dp) 
1991/0925    
{ 
	if(c->offset % dp->t->bytes) 
1992/1009    
	if(offset % dp->t->bytes) 
1992/0114    
		error(Ebadarg); 
1991/0925    
	if(n % dp->t->bytes) 
1992/0114    
		error(Ebadarg); 
1992/1007/sys/src/9/pc/devfloppy.c:400,4061992/1009/sys/src/9/pc/devfloppy.c:401,407
1991/0925    
} 
 
1991/0731    
long 
floppyread(Chan *c, void *a, long n) 
1992/1009    
floppyread(Chan *c, void *a, long n, ulong offset) 
1991/0731    
{ 
	Drive *dp; 
1991/0924    
	long rv, i; 
1992/1007/sys/src/9/pc/devfloppy.c:415,4211992/1009/sys/src/9/pc/devfloppy.c:416,422
1991/0924    
	dp = &fl.d[c->qid.path & ~Qmask]; 
1991/0802    
	switch ((int)(c->qid.path & Qmask)) { 
	case Qdata: 
1991/0925    
		islegal(c, n, dp); 
1992/1009    
		islegal(offset, n, dp); 
1991/0924    
		aa = a; 
1991/0925    
 
		qlock(&fl); 
1992/1007/sys/src/9/pc/devfloppy.c:430,4361992/1009/sys/src/9/pc/devfloppy.c:431,437
1991/0924    
			 *  truncate xfer at track boundary 
1991/0809    
			 */ 
			dp->len = n - rv; 
			floppypos(dp, c->offset+rv); 
1992/1009    
			floppypos(dp, offset+rv); 
1991/0809    
			cyl = dp->tcyl; 
1991/0924    
			head = dp->thead; 
1991/0809    
			len = dp->len; 
1992/1007/sys/src/9/pc/devfloppy.c:470,4811992/1009/sys/src/9/pc/devfloppy.c:471,481
1991/0731    
 
1991/0924    
#define SNCMP(a, b) strncmp(a, b, sizeof(b)-1) 
1991/0731    
long 
floppywrite(Chan *c, void *a, long n) 
1992/1009    
floppywrite(Chan *c, void *a, long n, ulong offset) 
1991/0731    
{ 
	Drive *dp; 
	long rv, i; 
1991/0924    
	char *aa = a; 
1992/1006    
	char *f[3]; 
	char ctlmsg[64]; 
1991/0731    
 
1991/0802    
	rv = 0; 
1992/1007/sys/src/9/pc/devfloppy.c:482,4881992/1009/sys/src/9/pc/devfloppy.c:482,488
1991/0924    
	dp = &fl.d[c->qid.path & ~Qmask]; 
1991/0802    
	switch ((int)(c->qid.path & Qmask)) { 
	case Qdata: 
1991/0925    
		islegal(c, n, dp); 
1992/1009    
		islegal(offset, n, dp); 
1991/0925    
		qlock(&fl); 
		if(waserror()){ 
			qunlock(&fl); 
1992/1007/sys/src/9/pc/devfloppy.c:491,5001992/1009/sys/src/9/pc/devfloppy.c:491,500
1991/0925    
		floppyon(dp); 
		changed(c, dp); 
1991/0802    
		for(rv = 0; rv < n; rv += i){ 
1991/0924    
			floppypos(dp, c->offset+rv); 
1992/1009    
			floppypos(dp, offset+rv); 
1991/0924    
			if(dp->tcyl == dp->ccyl) 
				dp->ccyl = -1; 
1992/1006    
			i = floppythrice(dp, Fwrite, aa+rv, c->offset+rv, n-rv); 
1992/1009    
			i = floppythrice(dp, Fwrite, aa+rv, offset+rv, n-rv); 
1991/1006    
			if(i < 0) 
1991/0802    
				break; 
1991/1006    
			if(i == 0) 
1992/1007/sys/src/9/pc/devfloppy.c:504,5091992/1009/sys/src/9/pc/devfloppy.c:504,510
1991/0925    
		poperror(); 
1991/0802    
		break; 
1991/0924    
	case Qctl: 
1992/1009    
		rv = n; 
1991/0925    
		qlock(&fl); 
1992/1007    
		if(waserror()){ 
			qunlock(&fl); 
1992/1007/sys/src/9/pc/devfloppy.c:519,5271992/1009/sys/src/9/pc/devfloppy.c:520,526
1991/0925    
			fl.confused = 1; 
1991/0924    
			floppyon(dp); 
1992/1006    
		} else if(SNCMP(ctlmsg, "format") == 0){ 
			if(getfields(ctlmsg, f, 3, ' ') != 3) 
				error(Ebadarg); 
1992/1007    
			rv = n*floppyformat(dp, strtoul(f[1], 0, 0), strtoul(f[2], 0, 0)); 
1992/1009    
			floppyformat(dp, ctlmsg); 
1991/0924    
		} 
1992/1007    
		poperror(); 
1991/0925    
		qunlock(&fl); 
1992/1007/sys/src/9/pc/devfloppy.c:956,10371992/1009/sys/src/9/pc/devfloppy.c:955,1061
1992/1006    
/* 
 *  format a track 
 */ 
static int 
1992/1007    
floppyformat(Drive *dp, ulong track, ulong filler) 
1992/1009    
static void 
floppyformat(Drive *dp, char *params) 
1992/1006    
{ 
 	int cyl, h, sec; 
1992/1009    
	ulong track; 
1992/1006    
	uchar *buf, *bp; 
	Type *t; 
1992/1009    
	char *f[3]; 
1992/1006    
 
	t = dp->t; 
	cyl = track/t->heads; 
	h = track % t->heads; 
	if(track >= t->tracks * t->heads) 
		return 0; 
1992/1007    
	setdef(dp); 
1992/1006    
	buf = smalloc(t->sectors*4); 
	if(waserror()){ 
		free(buf); 
		nexterror(); 
	} 
1992/1007    
	if(!waserror()){ 
		floppyon(dp); 
		poperror(); 
	} 
	floppyseek(dp, track*t->tsize); 
	dp->cyl = cyl; 
	dp->confused = 0; 
1992/1006    
                 
	/* 
	 *  set up the dma (dp->len may be trimmed) 
1992/1009    
	 *  set the type 
1992/1006    
	 */ 
	bp = buf; 
	for(sec = 1; sec <= t->sectors; sec++){ 
		*bp++ = cyl; 
		*bp++ = h; 
		*bp++ = sec; 
		*bp++ = t->bcode; 
1992/1009    
	if(getfields(params, f, 3, ' ') > 1){ 
		for(t = floppytype; t < &floppytype[NTYPES]; t++) 
			if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){ 
				dp->t = t; 
				floppydir[NFDIR*dp->dev].length = dp->t->cap; 
				break; 
			} 
	} else { 
		setdef(dp); 
		t = dp->t; 
1992/1006    
	} 
	dmasetup(DMAchan, buf, bp-buf, 0); 
 
	/* 
	 *  start operation 
1992/1009    
	 *  buffer for per track info 
1992/1006    
	 */ 
	fl.ncmd = 0; 
	fl.cmd[fl.ncmd++] = Fformat; 
	fl.cmd[fl.ncmd++] = (h<<2) | dp->dev; 
	fl.cmd[fl.ncmd++] = t->bcode; 
	fl.cmd[fl.ncmd++] = t->sectors; 
	fl.cmd[fl.ncmd++] = t->fgpl; 
	fl.cmd[fl.ncmd++] = filler; 
	if(floppycmd() < 0){ 
		DPRINT("xfer cmd failed\n"); 
		error(Eio); 
1992/1009    
	buf = smalloc(t->sectors*4); 
	if(waserror()){ 
		free(buf); 
		nexterror(); 
1992/1006    
	} 
 
	/* 
	 *  give bus to DMA, floppyintr() will read result 
1992/1009    
	 *  format a track at time 
1992/1006    
	 */ 
	floppywait(); 
	dmaend(DMAchan); 
1992/1009    
	for(track = 0; track < t->tracks*t->heads; track++){ 
		cyl = track/t->heads; 
		h = track % t->heads; 
1992/1006    
 
	/* 
	 *  check for errors 
	 */ 
	if(fl.nstat < 7){ 
		DPRINT("format result failed %lux\n", inb(Pmsr)); 
		fl.confused = 1; 
		error(Eio); 
1992/1009    
		/* 
		 *  seek to track, ignore errors 
		 */ 
		if(!waserror()){ 
			floppyon(dp); 
			poperror(); 
		} 
		floppyseek(dp, track*t->tsize); 
		dp->cyl = cyl; 
		dp->confused = 0; 
 
		/* 
		 *  set up the dma (dp->len may be trimmed) 
		 */ 
		bp = buf; 
		for(sec = 1; sec <= t->sectors; sec++){ 
			*bp++ = cyl; 
			*bp++ = h; 
			*bp++ = sec; 
			*bp++ = t->bcode; 
		} 
		dmasetup(DMAchan, buf, bp-buf, 0); 
 
		/* 
		 *  start operation 
		 */ 
		fl.ncmd = 0; 
		fl.cmd[fl.ncmd++] = Fformat; 
		fl.cmd[fl.ncmd++] = (h<<2) | dp->dev; 
		fl.cmd[fl.ncmd++] = t->bcode; 
		fl.cmd[fl.ncmd++] = t->sectors; 
		fl.cmd[fl.ncmd++] = t->fgpl; 
		fl.cmd[fl.ncmd++] = 0x5a; 
		if(floppycmd() < 0){ 
			DPRINT("xfer cmd failed\n"); 
			error(Eio); 
		} 
 
		/* 
		 *  give bus to DMA, floppyintr() will read result 
		 */ 
		floppywait(); 
		dmaend(DMAchan); 
 
		/* 
		 *  check for errors 
		 */ 
		if(fl.nstat < 7){ 
			DPRINT("format result failed %lux\n",inb(Pmsr)); 
			fl.confused = 1; 
			error(Eio); 
		} 
		if((fl.stat[0]&Codemask)!=0 || fl.stat[1]|| fl.stat[2]){ 
			DPRINT("format failed %lux %lux %lux\n", 
				fl.stat[0], fl.stat[1], fl.stat[2]); 
			dp->confused = 1; 
			error(Eio); 
		} 
1992/1006    
	} 
	if((fl.stat[0]&Codemask)!=0 || fl.stat[1] || fl.stat[2]){ 
		DPRINT("format failed %lux %lux %lux\n", 
			fl.stat[0], fl.stat[1], fl.stat[2]); 
		dp->confused = 1; 
		error(Eio); 
	} 
	free(buf); 
1992/1007    
	poperror(); 
1992/1006    
	return 1; 
} 
 
1991/0925    
static void 


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