aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2000-10-22 09:21:19 +0000
committerScott Long <scottl@FreeBSD.org>2000-10-22 09:21:19 +0000
commitf38211c796addc33f232c50ac4f75f8ada233928 (patch)
tree327b321dd337f7f67a80e892961427cc9de74bcd /sys/dev
parent869975bf962cad696287e161036bda4ecc5ab962 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/aac/aac.c33
-rw-r--r--sys/dev/aac/aacvar.h1
2 files changed, 34 insertions, 0 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index b89678bc15d4..938db5119f8a 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -60,6 +60,7 @@ static void aac_startup(void *arg);
/* Command Processing */
static void aac_startio(struct aac_softc *sc);
+static void aac_timeout(struct aac_command *cm);
static int aac_start(struct aac_command *cm);
static void aac_complete(void *context, int pending);
static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
@@ -164,6 +165,11 @@ static struct cdevsw aac_cdevsw = {
-1, /* bmaj */
};
+/* Timeout for giving up on a command sent to the controller */
+#ifndef AAC_CMD_TIMEOUT
+#define AAC_CMD_TIMEOUT 15
+#endif
+
/********************************************************************************
********************************************************************************
Device Interface
@@ -522,6 +528,9 @@ aac_startio(struct aac_softc *sc)
if (cm == NULL)
break;
+ /* Set a timeout for this command to be completed by the controller */
+ cm->timeout_handle = timeout((timeout_t*)aac_timeout, cm, AAC_CMD_TIMEOUT * hz);
+
/* try to give the command to the controller */
if (aac_start(cm) == EBUSY) {
/* put it on the ready queue for later */
@@ -531,6 +540,27 @@ aac_startio(struct aac_softc *sc)
}
}
+static void
+aac_timeout(struct aac_command *cm)
+{
+ struct aac_softc *sc;
+ struct bio *bp;
+ struct aac_disk *ad;
+
+ sc = cm->cm_sc;
+ bp = (struct bio*)cm->cm_private;
+ ad = (struct aac_disk *)bp->bio_dev->si_drv1;
+
+ device_printf(sc->aac_dev, "Timeout waiting for controller to respond to command\n");
+
+ /* Should try to requeue the command... is it possible? Bail for now */
+ bp->bio_error = EIO;
+ bp->bio_flags |= BIO_ERROR;
+ devstat_end_transaction_bio(&ad->ad_stats, bp);
+ biodone(bp);
+ aac_release_command(cm);
+}
+
/********************************************************************************
* Deliver a command to the controller; allocate controller resources at the
* last moment when possible.
@@ -759,6 +789,9 @@ aac_bio_complete(struct aac_command *cm)
struct bio *bp;
AAC_FSAStatus status;
+ /* kill the timeout timer */
+ untimeout((timeout_t *)aac_timeout, cm, cm->timeout_handle);
+
/* fetch relevant status and then release the command */
bp = (struct bio *)cm->cm_private;
if (BIO_IS_READ(bp)) {
diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h
index 68d21725c5a4..e65dd66309ec 100644
--- a/sys/dev/aac/aacvar.h
+++ b/sys/dev/aac/aacvar.h
@@ -142,6 +142,7 @@ struct aac_command
void (* cm_complete)(struct aac_command *cm);
void *cm_private;
+ struct callout_handle timeout_handle; /* timeout handle */
};
/*