From 8391cd43606855f9f18c7934d600ec9ca298a2f2 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 3 Oct 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-10-03 --- pc/devfloppy.c | 74 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 600f10147f4bdc386a0eb1c191e315a4eba17897..803b99c5c7283ed71535c6904cf30901189853a4 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -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); }