diff options
| author | Scott Long <scottl@FreeBSD.org> | 2000-10-22 09:21:19 +0000 |
|---|---|---|
| committer | Scott Long <scottl@FreeBSD.org> | 2000-10-22 09:21:19 +0000 |
| commit | f38211c796addc33f232c50ac4f75f8ada233928 (patch) | |
| tree | 327b321dd337f7f67a80e892961427cc9de74bcd /sys/dev | |
| parent | 869975bf962cad696287e161036bda4ecc5ab962 (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/aac/aac.c | 33 | ||||
| -rw-r--r-- | sys/dev/aac/aacvar.h | 1 |
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 */ }; /* |
