M pc/devfloppy.c => pc/devfloppy.c +48 -36
@@ 110,7 110,6 @@ struct Drive
int dev;
ulong lasttouched; /* time last touched */
- int motoron; /* motor is on */
int cyl; /* current cylinder */
int confused; /* needs to be recalibrated (or worse) */
@@ 137,12 136,15 @@ struct Controller
int confused;
int intr; /* true if interrupt occured */
Rendez r; /* wait here for command termination */
+ int motor;
Rendez kr; /* for motor watcher */
};
Controller floppy;
+#define MOTORBIT(i) (1<<((i)+4))
+
/*
* predeclared
*/
@@ 201,7 203,7 @@ floppyreset(void)
dp->dev = dp - floppy.d;
dp->t = &floppytype[0]; /* default type */
floppydir[NFDIR*dp->dev].length = dp->t->cap;
- dp->motoron = 1;
+ floppy.motor |= MOTORBIT(dp->dev);
dp->cyl = -1; /* because we don't know */
motoroff(dp);
}
@@ 376,36 378,6 @@ floppywrite(Chan *c, void *a, long n)
return rv;
}
-/*
- * start a floppy drive's motor. set an alarm for .75 second later to
- * mark it as started (we get no interrupt to tell us).
- *
- * assume the caller qlocked the drive.
- */
-static void
-motoron(Drive *dp)
-{
- int cmd;
-
- cmd = (1<<(dp->dev+4)) | Fintena | Fena | dp->dev;
- outb(Fmotor, cmd);
- tsleep(&dp->r, return0, 0, 750);
- dp->motoron = 1;
- dp->lasttouched = m->ticks;
-}
-
-/*
- * stop the floppy if it hasn't been used in 5 seconds
- */
-static void
-motoroff(Drive *dp)
-{
- int cmd;
-
- cmd = Fintena | Fena | dp->dev;
- outb(Fmotor, cmd);
- dp->motoron = 0;
-}
static void
floppykproc(void *a)
{
@@ 416,7 388,8 @@ floppykproc(void *a)
;
for(;;){
for(dp = floppy.d; dp < &floppy.d[conf.nfloppy]; dp++){
- if(dp->motoron && TK2SEC(m->ticks - dp->lasttouched) > 5
+ if((floppy.motor&MOTORBIT(dp->dev))
+ && TK2SEC(m->ticks - dp->lasttouched) > 5
&& canqlock(dp)){
if(TK2SEC(m->ticks - dp->lasttouched) > 5)
motoroff(dp);
@@ 429,6 402,46 @@ floppykproc(void *a)
}
}
+static void
+driveselect(Drive *dp)
+{
+ int cmd;
+
+ cmd = floppy.motor | Fintena | Fena | dp->dev;
+ outb(Fmotor, cmd);
+}
+
+/*
+ * start a floppy drive's motor. set an alarm for .75 second later to
+ * mark it as started (we get no interrupt to tell us).
+ *
+ * assume the caller qlocked the drive.
+ *
+ * this also selects the drive for subsequent operations
+ */
+static void
+motoron(Drive *dp)
+{
+ int alreadyon;
+
+ alreadyon = floppy.motor & MOTORBIT(dp->dev);
+ floppy.motor |= MOTORBIT(dp->dev);
+ driveselect(dp);
+ if(!alreadyon)
+ tsleep(&dp->r, return0, 0, 750);
+ dp->lasttouched = m->ticks;
+}
+
+/*
+ * stop the floppy if it hasn't been used in 5 seconds
+ */
+static void
+motoroff(Drive *dp)
+{
+ floppy.motor &= ~MOTORBIT(dp->dev);
+ driveselect(dp);
+}
+
/*
* send a byte to the floppy
*/
@@ 633,9 646,9 @@ floppyrevive(void)
outb(Fmotor, Fintena|Fena);
spllo();
for(dp = floppy.d; dp < &floppy.d[conf.nfloppy]; dp++){
- dp->motoron = 0;
dp->confused = 1;
}
+ floppy.motor = 0;
sleep(&floppy.r, interrupted, 0);
floppy.confused = 0;
}
@@ 716,8 729,7 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n)
*/
if(floppy.confused || dp->confused)
floppyrevive();
- if(!dp->motoron)
- motoron(dp);
+ motoron(dp);
/*
* calculate new position and seek to it (dp->len may be trimmed)
M pc/devhard.c => pc/devhard.c +1 -1
@@ 238,7 238,7 @@ hardattach(char *spec)
dp->online = 0;
}
- return devattach('h', spec);
+ return devattach('w', spec);
}
Chan*
M pc/vga.c => pc/vga.c +2 -1
@@ 165,7 165,8 @@ screeninit(void)
/*
* swizzle the font longs.
- * we do it here since the font is initialized with big endian longs.
+ * we do it here since the font is initialized with big
+ * endian longs.
*/
defont = &defont0;
l = defont->bits->base;
M port/devsrv.c => port/devsrv.c +1 -1
@@ 181,6 181,6 @@ srvwrite(Chan *c, void *va, long n, ulong offset)
fd = strtoul(buf, 0, 0);
fdtochan(fd, -1); /* error check only */
srv.chan[i] = u->p->fgrp->fd[fd];
- incref(u->p->fgrp->fd[fd]);
+ incref(srv.chan[i]);
return n;
}
M port/devwren.c => port/devwren.c +1 -1
@@ 125,7 125,7 @@ wrenattach(char *param)
drive = wrendev(param);
wrenpart(drive);
- c = devattach('r', param);
+ c = devattach('w', param);
c->dev = drive;
return c;
}
M power/devhs.c => power/devhs.c +4 -1
@@ 45,6 45,7 @@ struct Hsvme {
uchar buf[1024]; /* bytes being collected */
uchar *wptr; /* pointer into buf */
int kstarted; /* true if kernel process started */
+ int started;
/* statistics */
@@ 124,6 125,7 @@ hsvmerestart(Hsvme *hp)
addr->csr = NORESET|IPL(Intlevel)|FORCEW|IENABLE|ALIVE;
wbflush();
delay(1);
+ hp->started = 1;
}
/*
@@ 164,7 166,8 @@ hsvmeattach(char *spec)
if(i >= Nhsvme)
error(Ebadarg);
hp = &hsvme[i];
- hsvmerestart(hp);
+ if(!hp->started)
+ hsvmerestart(hp);
c = devattach('h', spec);
c->dev = i;