示例#1
0
int
floppyinit(void)
{
    FDrive *dp;
    FType *t;
    ulong maxtsize;
    int mask;

    dmainit(DMAchan);

    floppysetup0(&fl);

    /*
     *  init dependent parameters
     */
    maxtsize = 0;
    for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++) {
        t->cap = t->bytes * t->heads * t->sectors * t->tracks;
        t->bcode = b2c[t->bytes/128];
        t->tsize = t->bytes * t->sectors;
        if(maxtsize < t->tsize)
            maxtsize = t->tsize;
    }

    fl.selected = fl.d;

    floppydetach = _floppydetach;
    floppydetach();

    /*
     *  init drives
     */
    mask = 0;
    for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++) {
        dp->dev = dp - fl.d;
        if(dp->dt == Tnone)
            continue;
        mask |= 1<<dp->dev;
        floppysetdef(dp);
        dp->cyl = -1;			/* because we don't know */
        dp->cache = (uchar*)xspanalloc(maxtsize, BY2PG, 64*1024);
        dp->ccyl = -1;
        dp->vers = 0;
        dp->maxtries = 5;
    }

    /*
     *  first operation will recalibrate
     */
    fl.confused = 1;

    floppysetup1(&fl);

    /* to turn the motor off when inactive */
    alarm(5*1000, floppyalarm, 0);

    return mask;
}
示例#2
0
/*
 *  check if the floppy has been replaced under foot.  cause
 *  an error if it has.
 *
 *  a seek and a read clears the condition.  this was determined
 *  experimentally, there has to be a better way.
 *
 *  if the read fails, cycle through the possible floppy
 *  density till one works or we've cycled through all
 *  possibilities for this drive.
 */
static int
changed(FDrive *dp)
{
    FType *start;

    /*
     *  if floppy has changed or first time through
     */
    if((inb(Pdir)&Fchange) || dp->vers == 0) {
        DPRINT("changed\n");
        fldump();
        dp->vers++;
        floppysetdef(dp);
        dp->maxtries = 3;
        start = dp->t;

        /* flopppyon fails if there's no drive */
        dp->confused = 1;	/* make floppyon recal */
        if(floppyon(dp) < 0)
            return -1;

        pcfloppyseek(dp, dp->t->heads*dp->t->tsize);

        while(floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize) <= 0) {

            /*
             *  if the xfer attempt doesn't clear the changed bit,
             *  there's no floppy in the drive
             */
            if(inb(Pdir)&Fchange)
                return -1;

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

            /* flopppyon fails if there's no drive */
            if(floppyon(dp) < 0)
                return -1;

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

    return 0;
}
示例#3
0
/*
 *  format a track
 */
static void
floppyformat(FDrive *dp, Cmdbuf *cb)
{
 	int cyl, h, sec;
	ulong track;
	uchar *buf, *bp;
	FType *t;

	/*
	 *  set the type
	 */
	if(cb->nf == 2){
		for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
			if(strcmp(cb->f[1], t->name)==0 && t->dt==dp->dt){
				dp->t = t;
				floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
				break;
			}
		}
		if(t >= &floppytype[nelem(floppytype)])
			error(Ebadarg);
	} else if(cb->nf == 1){
		floppysetdef(dp);
		t = dp->t;
	} else {
		cmderror(cb, "invalid floppy format command");
		SET(t);
	}

	/*
	 *  buffer for per track info
	 */
	buf = smalloc(t->sectors*4);
	if(waserror()){
		free(buf);
		nexterror();
	}

	/* force a recalibrate to cylinder 0 */
	dp->confused = 1;
	if(!waserror()){
		floppyon(dp);
		poperror();
	}

	/*
	 *  format a track at time
	 */
	for(track = 0; track < t->tracks*t->heads; track++){
		cyl = track/t->heads;
		h = track % t->heads;

		/*
		 *  seek to track, ignore errors
		 */
		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;
		}
		if(waserror()){
			dmaend(DMAchan);
			nexterror();
		}
		if(dmasetup(DMAchan, buf, bp-buf, 0) < 0)
			error(Eio);

		/*
		 *  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)
			error(Eio);

		/* Poll ready bits and transfer data */
		floppyexec((char *)buf, bp-buf, 0);

		/*
		 *  give bus to DMA, floppyintr() will read result
		 */
		floppywait(1);
		dmaend(DMAchan);
		poperror();

		/*
		 *  check for errors
		 */
		if(fl.nstat < 7){
			DPRINT("format: confused\n");
			fl.confused = 1;
			error(Eio);
		}
		if((fl.stat[0]&Codemask)!=0 || fl.stat[1]|| fl.stat[2]){
			DPRINT("format: failed %ux %ux %ux\n",
				fl.stat[0], fl.stat[1], fl.stat[2]);
			dp->confused = 1;
			error(Eio);
		}
	}
	free(buf);
	dp->confused = 1;
	poperror();
}
示例#4
0
static void
floppyreset(void)
{
	FDrive *dp;
	FType *t;
	ulong maxtsize;
	
	floppysetup0(&fl);
	if(fl.ndrive == 0)
		return;

	/*
	 *  init dependent parameters
	 */
	maxtsize = 0;
	for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
		t->cap = t->bytes * t->heads * t->sectors * t->tracks;
		t->bcode = b2c[t->bytes/128];
		t->tsize = t->bytes * t->sectors;
		if(maxtsize < t->tsize)
			maxtsize = t->tsize;
	}

	/*
	 * Should check if this fails. Can do so
	 * if there is no space <= 16MB for the DMA
	 * bounce buffer.
	 */
	dmainit(DMAchan, maxtsize);

	/*
	 *  allocate the drive storage
	 */
	fl.d = xalloc(fl.ndrive*sizeof(FDrive));
	fl.selected = fl.d;

	/*
	 *  stop the motors
	 */
	fl.motor = 0;
	delay(10);
	outb(Pdor, fl.motor | Fintena | Fena);
	delay(10);

	/*
	 *  init drives
	 */
	for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
		dp->dev = dp - fl.d;
		dp->dt = T1440kb;
		floppysetdef(dp);
		dp->cyl = -1;			/* because we don't know */
		dp->cache = (uchar*)xspanalloc(maxtsize, BY2PG, 64*1024);
		dp->ccyl = -1;
		dp->vers = 0;
	}

	/*
	 *  first operation will recalibrate
	 */
	fl.confused = 1;

	floppysetup1(&fl);
}