예제 #1
0
파일: devfloppy.c 프로젝트: biddyweb/plan9
/*
 *  seek to the target cylinder
 *
 *	interrupt, no results
 */
static vlong
pcfloppyseek(FDrive *dp, vlong off)
{
    floppypos(dp, off);
    if(dp->cyl == dp->tcyl) {
        dp->offset = off;
        return off;
    }
    dp->cyl = -1;

    fl.ncmd = 0;
    fl.cmd[fl.ncmd++] = Fseek;
    fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
    fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
    if(floppycmd() < 0)
        return -1;
    floppywait(1);
    if(fl.nstat < 2) {
        DPRINT("seek: confused\n");
        fl.confused = 1;
        return -1;
    }
    if((fl.stat[0] & (Codemask|Seekend)) != Seekend) {
        DPRINT("seek: failed\n");
        dp->confused = 1;
        return -1;
    }

    dp->cyl = dp->tcyl;
    dp->offset = off;
    DPRINT("seek to %d succeeded\n", dp->offset);

    return dp->offset;
}
예제 #2
0
파일: devfloppy.c 프로젝트: biddyweb/plan9
long
floppyread(Fs *fs, void *a, long n)
{
    FDrive *dp;
    long rv, offset;
    int sec, head, cyl;
    long len;
    uchar *aa;

    aa = a;
    dp = &fl.d[fs->dev];

    offset = dp->offset;
    floppyon(dp);
    if(changed(dp))
        return -1;

    for(rv = 0; rv < n; rv += len) {
        /*
         *  all xfers come out of the track cache
         */
        dp->len = n - rv;
        floppypos(dp, offset+rv);
        cyl = dp->tcyl;
        head = dp->thead;
        len = dp->len;
        sec = dp->tsec;
        if(readtrack(dp, cyl, head) < 0)
            break;
        memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
    }
    dp->offset = offset+rv;

    return rv;
}
예제 #3
0
/*
 *  seek to the target cylinder
 *
 *	interrupt, no results
 */
static long
floppyseek(FDrive *dp, long off)
{
	floppypos(dp, off);
	if(dp->cyl == dp->tcyl)
		return dp->tcyl;
	dp->cyl = -1;

	fl.ncmd = 0;
	fl.cmd[fl.ncmd++] = Fseek;
	fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
	fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
	if(floppycmd() < 0)
		return -1;
	floppywait(1);
	if(fl.nstat < 2){
		DPRINT("seek: confused\n");
		fl.confused = 1;
		return -1;
	}
	if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
		DPRINT("seek: failed\n");
		dp->confused = 1;
		return -1;
	}

	dp->cyl = dp->tcyl;
	return dp->tcyl;
}
예제 #4
0
static long
floppyread(Chan *c, void *a, long n, vlong off)
{
	FDrive *dp;
	long rv;
	int sec, head, cyl;
	long len;
	uchar *aa;
	ulong offset = off;

	if(c->qid.type & QTDIR)
		return devdirread(c, a, n, floppydir, 1+fl.ndrive*NFDIR, devgen);

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];
	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		islegal(offset, n, dp);
		aa = a;

		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += len){
			/*
			 *  all xfers come out of the track cache
			 */
			dp->len = n - rv;
			floppypos(dp, offset+rv);
			cyl = dp->tcyl;
			head = dp->thead;
			len = dp->len;
			sec = dp->tsec;
			if(readtrack(dp, cyl, head) < 0)
				break;
			memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
		}
		qunlock(&fl);
		poperror();

		break;
	case Qctl:
		return readstr(offset, a, n, dp->t->name);
	default:
		panic("floppyread: bad qid");
	}

	return rv;
}
예제 #5
0
static long
floppywrite(Chan *c, void *a, long n, vlong off)
{
	FDrive *dp;
	long rv, i;
	char *aa = a;
	Cmdbuf *cb;
	Cmdtab *ct;
	ulong offset = off;

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];
	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		islegal(offset, n, dp);
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += i){
			floppypos(dp, offset+rv);
			if(dp->tcyl == dp->ccyl)
				dp->ccyl = -1;
			i = floppyxfer(dp, Fwrite, aa+rv, offset+rv, n-rv);
			if(i < 0)
				break;
			if(i == 0)
				error(Eio);
		}
		qunlock(&fl);
		poperror();
		break;
	case Qctl:
		rv = n;
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		ct = lookupcmd(cb, floppyctlmsg, nelem(floppyctlmsg));
		switch(ct->index){
		case CMeject:
			floppyeject(dp);
			break;
		case CMformat:
			floppyformat(dp, cb);
			break;
		case CMreset:
			fl.confused = 1;
			floppyon(dp);
			break;
		case CMdebug:
			floppydebug = 1;
			break;
		case CMnodebug:
			floppydebug = 0;
			break;
		}
		poperror();
		qunlock(&fl);
		poperror();
		free(cb);
		break;
	default:
		panic("floppywrite: bad qid");
	}

	return rv;
}