From 0d469f507f78ea64ef3e035ad23cbbd440fc868c Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 13 Aug 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-08-13 --- pc/devfloppy.c | 51 ++++++++++++++++++++++++++++++++++++-------------- pc/devlpt.c | 14 ++++++++------ pc/floppy.h | 3 ++- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/pc/devfloppy.c b/pc/devfloppy.c index f5290791e6be9c0da604d1cf7c831b46e668aace..132deaa5f53eebbd5d9bc64f543a47c2b4cb955e 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -100,7 +100,7 @@ static int floppyresult(void); static void floppyrevive(void); static long floppyseek(FDrive*, long); static int floppysense(void); -static void floppywait(void); +static void floppywait(int); static long floppyxfer(FDrive*, int, void*, long, long); Dirtab floppydir[]={ @@ -272,12 +272,24 @@ changed(Chan *c, FDrive *dp) DPRINT("changed\n"); fldump(); dp->vers++; - floppysetdef(dp); start = dp->t; + dp->maxtries = 3; /* limit it when we're probing */ + + /* floppyon will fail if there's a controller but no drive */ dp->confused = 1; /* make floppyon recal */ - floppyon(dp); + if(floppyon(dp) < 0) + error(Eio); + + /* seek to the first track */ floppyseek(dp, dp->t->heads*dp->t->tsize); while(waserror()){ + /* + * if first attempt doesn't reset changed bit, there's + * no floppy there + */ + if(inb(Pdir)&Fchange) + nexterror(); + while(++dp->t){ if(dp->t == &floppytype[nelem(floppytype)]) dp->t = floppytype; @@ -285,14 +297,21 @@ changed(Chan *c, FDrive *dp) break; } floppydir[NFDIR*dp->dev].length = dp->t->cap; - floppyon(dp); + + /* floppyon will fail if there's a controller but no drive */ + if(floppyon(dp) < 0) + error(Eio); + DPRINT("changed: trying %s\n", dp->t->name); fldump(); if(dp->t == start) nexterror(); } + + /* if the read succeeds, we've got the density right */ floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize); poperror(); + dp->maxtries = 20; } old = c->qid.vers; @@ -467,7 +486,7 @@ floppykproc(void *) /* * start a floppy drive's motor. */ -static void +static int floppyon(FDrive *dp) { int alreadyon; @@ -501,6 +520,11 @@ floppyon(FDrive *dp) break; dp->lasttouched = m->ticks; fl.selected = dp; + + /* return -1 if this didn't work */ + if(dp->confused) + return -1; + return 0; } /* @@ -639,9 +663,9 @@ cmddone(void *) * routine to try to clear any conditions. */ static void -floppywait(void) +floppywait(int slow) { - tsleep(&fl.r, cmddone, 0, 5000); + tsleep(&fl.r, cmddone, 0, slow ? 5000 : 1000); if(!cmddone(0)){ floppyintr(0); fl.confused = 1; @@ -662,7 +686,7 @@ floppyrecal(FDrive *dp) fl.cmd[fl.ncmd++] = dp->dev; if(floppycmd() < 0) return -1; - floppywait(); + floppywait(1); if(fl.nstat < 2){ DPRINT("recalibrate: confused %ux\n", inb(Pmsr)); fl.confused = 1; @@ -712,7 +736,7 @@ floppyrevive(void) spllo(); fl.motor = 0; fl.confused = 0; - floppywait(); + floppywait(0); /* mark all drives in an unknown state */ for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++) @@ -746,7 +770,7 @@ floppyseek(FDrive *dp, long off) fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps; if(floppycmd() < 0) return -1; - floppywait(); + floppywait(1); if(fl.nstat < 2){ DPRINT("seek: confused\n"); fl.confused = 1; @@ -779,10 +803,9 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n) /* retry on error (until it gets ridiculous) */ tries = 0; while(waserror()){ - if(tries++ > 20) + if(tries++ >= dp->maxtries) nexterror(); DPRINT("floppyxfer: retrying\n"); - /*floppyon(dp);*/ } dp->len = n; @@ -825,7 +848,7 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n) /* * give bus to DMA, floppyintr() will read result */ - floppywait(); + floppywait(0); dmaend(DMAchan); poperror(); @@ -961,7 +984,7 @@ floppyformat(FDrive *dp, char *params) /* * give bus to DMA, floppyintr() will read result */ - floppywait(); + floppywait(1); dmaend(DMAchan); poperror(); diff --git a/pc/devlpt.c b/pc/devlpt.c index 23a0e3e854a24699d56fb21776ef8aecc6e2ac85..72ab3a6e62a6b4416f8a6dc528c2b4a9331b4914 100644 --- a/pc/devlpt.c +++ b/pc/devlpt.c @@ -178,15 +178,17 @@ outch(int base, int c) { int status, tries; - for(tries = 0;; tries++){ + for(tries=0;; tries++) { status = inb(base+Qpsr); - if(!(status & Fselect) || !(status & Fnoerror)) - error(Eio); - if(status & Fnotbusy) + if(status&Fnotbusy) break; - if(tries > 1000){ + if((status&Fpe)==0 && (status&(Fselect|Fnoerror)) != (Fselect|Fnoerror)) + error(Eio); + if(tries < 10) + tsleep(&lptrendez, return0, nil, 1); + else { outb(base+Qpcr, Finitbar|Fie); - tsleep(&lptrendez, lptready, (void *)base, MS2HZ); + tsleep(&lptrendez, lptready, (void *)base, 100); } } outb(base+Qdlr, c); diff --git a/pc/floppy.h b/pc/floppy.h index a897b5223b986e732a530857c28818a542518a2f..86c4c4dd12ffb76db5858d6424e3a531a51fd3d1 100644 --- a/pc/floppy.h +++ b/pc/floppy.h @@ -3,7 +3,7 @@ typedef struct FDrive FDrive; typedef struct FType FType; static void floppyintr(Ureg*); -static void floppyon(FDrive*); +static int floppyon(FDrive*); static void floppyoff(FDrive*); static void floppysetdef(FDrive*); @@ -20,6 +20,7 @@ struct FDrive int cyl; /* current arm position */ int confused; /* needs to be recalibrated */ int vers; + int maxtries; /* max read attempts before Eio */ int tcyl; /* target cylinder */ int thead; /* target head */