diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2009-12-01 01:50:36 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2009-12-01 01:50:36 +0000 |
commit | 4e2686172affb675337d24909f61d8ba3fbfc083 (patch) | |
tree | 5eed3ac4abf0e7f02bf84edd1dcc98247b7f4c34 /sys/scsi/sd.c | |
parent | 56901e51ebf1db9a1c61f31f83c5b6e63d702f20 (diff) |
properly handle all xs states that can be returned by an adapter in sd.
requested by krw@ after spending a week munging through my code.
Diffstat (limited to 'sys/scsi/sd.c')
-rw-r--r-- | sys/scsi/sd.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index 081733da095..62ca807d63c 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.165 2009/12/01 01:40:02 dlg Exp $ */ +/* $OpenBSD: sd.c,v 1.166 2009/12/01 01:50:35 dlg Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -770,13 +770,27 @@ sd_buf_done(struct scsi_xfer *xs) break; case XS_NO_CCB: - /* The hardware is busy, requeue the buf and try it later. */ + /* The adapter is busy, requeue the buf and try it later. */ sd_buf_requeue(sc, bp); scsi_xs_put(xs); SET(sc->flags, SDF_WAITING); /* break out of sdstart loop */ timeout_add(&sc->sc_timeout, 1); return; + case XS_SENSE: + case XS_SHORTSENSE: + if (scsi_interpret_sense(xs) != ERESTART) + xs->retries = 0; + + /* FALLTHROUGH */ + case XS_BUSY: + case XS_TIMEOUT: + if (xs->retries--) { + scsi_xs_exec(xs); + return; + } + + /* FALLTHROUGH */ default: bp->b_error = EIO; bp->b_flags |= B_ERROR; |