summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/arc.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/sys/dev/pci/arc.c b/sys/dev/pci/arc.c
index 3688206166a..ec5fca70437 100644
--- a/sys/dev/pci/arc.c
+++ b/sys/dev/pci/arc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arc.c,v 1.18 2006/08/14 15:22:27 dlg Exp $ */
+/* $OpenBSD: arc.c,v 1.19 2006/08/15 02:09:02 dlg Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -153,11 +153,12 @@ struct arc_msg_scsicmd {
#define ARC_MSG_CDBLEN 16
u_int8_t cdb[ARC_MSG_CDBLEN];
-#define ARC_MSG_SENSELEN 16
+ u_int8_t status;
+#define ARC_MSG_STATUS_SELTIMEOUT 0xf0
+#define ARC_MSG_STATUS_ABORTED 0xf1
+#define ARC_MSG_STATUS_INIT_FAIL 0xf2
+#define ARC_MSG_SENSELEN 15
u_int8_t sense_data[ARC_MSG_SENSELEN];
-#define ARC_MSG_SENSE_TIMEOUT 0xf0
-#define ARC_MSG_SENSE_ABORTED 0xf1
-#define ARC_MSG_SENSE_INIT_FAIL 0xf2
/* followed by an sgl */
} __packed;
@@ -509,6 +510,7 @@ void
arc_scsi_cmd_done(struct arc_softc *sc, struct arc_ccb *ccb, u_int32_t reg)
{
struct scsi_xfer *xs = ccb->ccb_xs;
+ struct arc_msg_scsicmd *cmd;
if (xs->datalen != 0) {
bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
@@ -521,8 +523,31 @@ arc_scsi_cmd_done(struct arc_softc *sc, struct arc_ccb *ccb, u_int32_t reg)
xs->flags |= ITSDONE;
if (reg & ARC_REG_REPLY_QUEUE_ERR) {
- // printf("%s: something went wrong\n", DEVNAME(sc));
- xs->error = XS_DRIVER_STUFFUP;
+ cmd = &ccb->ccb_cmd->cmd;
+
+ switch (cmd->status) {
+ case ARC_MSG_STATUS_SELTIMEOUT:
+ case ARC_MSG_STATUS_ABORTED:
+ case ARC_MSG_STATUS_INIT_FAIL:
+ xs->status = SCSI_OK;
+ xs->error = XS_SELTIMEOUT;
+ break;
+
+ case SCSI_CHECK:
+ bzero(&xs->sense, sizeof(xs->sense));
+ bcopy(cmd->sense_data, &xs->sense,
+ min(ARC_MSG_SENSELEN, sizeof(xs->sense)));
+ xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
+ xs->status = SCSI_CHECK;
+ xs->error = XS_SENSE;
+ break;
+
+ default:
+ /* unknown device status */
+ xs->error = XS_BUSY; /* try again later? */
+ xs->status = SCSI_BUSY;
+ break;
+ }
} else {
xs->status = SCSI_OK;
xs->error = XS_NOERROR;