summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2009-12-01 01:50:36 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2009-12-01 01:50:36 +0000
commit4e2686172affb675337d24909f61d8ba3fbfc083 (patch)
tree5eed3ac4abf0e7f02bf84edd1dcc98247b7f4c34 /sys
parent56901e51ebf1db9a1c61f31f83c5b6e63d702f20 (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')
-rw-r--r--sys/scsi/scsi_base.c3
-rw-r--r--sys/scsi/scsiconf.h3
-rw-r--r--sys/scsi/sd.c18
3 files changed, 19 insertions, 5 deletions
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c
index f844d955881..97b74b62c0e 100644
--- a/sys/scsi/scsi_base.c
+++ b/sys/scsi/scsi_base.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsi_base.c,v 1.144 2009/12/01 01:40:02 dlg Exp $ */
+/* $OpenBSD: scsi_base.c,v 1.145 2009/12/01 01:50:35 dlg Exp $ */
/* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */
/*
@@ -53,7 +53,6 @@
static __inline void asc2ascii(u_int8_t, u_int8_t ascq, char *result,
size_t len);
int sc_err1(struct scsi_xfer *);
-int scsi_interpret_sense(struct scsi_xfer *);
char *scsi_decode_sense(struct scsi_sense_data *, int);
void scsi_xs_done(struct scsi_xfer *);
diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h
index 8f9619d8fb9..ac9784b7bc8 100644
--- a/sys/scsi/scsiconf.h
+++ b/sys/scsi/scsiconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.h,v 1.112 2009/12/01 01:40:02 dlg Exp $ */
+/* $OpenBSD: scsiconf.h,v 1.113 2009/12/01 01:50:35 dlg Exp $ */
/* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */
/*
@@ -552,6 +552,7 @@ void sc_print_addr(struct scsi_link *);
int scsi_report_luns(struct scsi_link *, int,
struct scsi_report_luns_data *, u_int32_t, int, int);
void scsi_minphys(struct buf *, struct scsi_link *);
+int scsi_interpret_sense(struct scsi_xfer *);
void show_scsi_xs(struct scsi_xfer *);
void scsi_print_sense(struct scsi_xfer *);
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;