summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2005-05-28 00:07:04 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2005-05-28 00:07:04 +0000
commit87d37b46a28075243600b59a10c2293060b612dc (patch)
treeccfc15b2e13aa80dd65ec03ba518edf0ac230cd2
parent6447028262e9d34a7be6625ae13ef7707725742b (diff)
Step 2 in fixing bioctl commands intermixed with regular io.
Add tsleep/wakeup magic to drain IO when a RAID mgmt command wants to run. Issue RAID mgmt command. Resume IO. ok mickey@
-rw-r--r--sys/dev/ic/ami.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/sys/dev/ic/ami.c b/sys/dev/ic/ami.c
index 9508de67b4a..6c739af4792 100644
--- a/sys/dev/ic/ami.c
+++ b/sys/dev/ic/ami.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ami.c,v 1.39 2005/05/27 20:39:29 marco Exp $ */
+/* $OpenBSD: ami.c,v 1.40 2005/05/28 00:07:03 marco Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -54,6 +54,7 @@
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/proc.h>
#include <machine/bus.h>
@@ -932,6 +933,10 @@ ami_schwartz_poll(sc, cmd)
struct ami_iocmd *cmd;
{
/* FIXME add the actual code here */
+
+ if (sc->sc_dis_poll)
+ return 1; /* fail */
+
return 1;
}
@@ -1185,6 +1190,8 @@ ami_done(sc, idx)
xs->flags |= ITSDONE;
AMI_DPRINTF(AMI_D_CMD, ("scsi_done(%d) ", idx));
scsi_done(xs);
+ if (sc->sc_flags & AMI_CMDWAIT && TAILQ_EMPTY(&sc->sc_ccbq))
+ wakeup(&sc->sc_ccbq);
}
AMI_UNLOCK_AMI(sc, lock);
@@ -1248,6 +1255,9 @@ ami_scsi_raw_cmd(xs)
return (COMPLETE);
}
+ while (sc->sc_flags & AMI_CMDWAIT)
+ tsleep(&sc->sc_ccbq, PRIBIO + 1, "ami_raw", 0);
+
xs->error = XS_NOERROR;
if ((ccb = ami_get_ccb(sc)) == NULL) {
@@ -1484,6 +1494,9 @@ ami_scsi_cmd(xs)
}
}
+ while (sc->sc_flags & AMI_CMDWAIT)
+ tsleep(&sc->sc_ccbq, PRIBIO + 1, "ami_cmd", 0);
+
if ((ccb = ami_get_ccb(sc)) == NULL) {
AMI_DPRINTF(AMI_D_CMD, ("no more ccbs "));
xs->error = XS_DRIVER_STUFFUP;
@@ -1598,6 +1611,8 @@ ami_ioctl(dev, cmd, addr)
int lock, error = 0;
struct ami_softc *sc = (struct ami_softc *)dev;
+ /* FIXME do we need to test for sc_dis_poll? */
+
if (sc->sc_flags & AMI_BROKEN)
return ENODEV; /* can't do this to broken device for now */
@@ -1608,6 +1623,19 @@ ami_ioctl(dev, cmd, addr)
}
switch (cmd) {
+ case BIOCALARM:
+ case BIOCBLINK:
+ case BIOCSTARTSTOP:
+ case BIOCSTATUS:
+ case BIOCSCSICMD:
+ sc->sc_flags |= AMI_CMDWAIT;
+ while (!TAILQ_EMPTY(&sc->sc_ccbq))
+ if (tsleep(&sc->sc_ccbq, PRIBIO, "ami_ioctl",
+ 100 * 60) == EWOULDBLOCK)
+ return EWOULDBLOCK;
+ }
+
+ switch (cmd) {
case BIOCPING:
((bioc_ping *)addr)->x++;
@@ -1661,6 +1689,9 @@ ami_ioctl(dev, cmd, addr)
error = EINVAL;
}
+ sc->sc_flags &= ~AMI_CMDWAIT;
+ wakeup(&sc->sc_ccbq);
+
AMI_UNLOCK_AMI(sc, lock);
return (error);