summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua M. Clulow <jmc@joyent.com>2016-03-04 11:32:07 +0000
committerJoshua M. Clulow <jmc@joyent.com>2016-07-06 16:25:28 +0000
commitad2c07638e56f3d636b2e94258bbfcec387c34b8 (patch)
tree758c62225b2e7bf30c00e8d4ea0940f56b5c2b2c
parent931639d8f0cf57f6328750c97540c11d71d26a89 (diff)
downloadillumos-joyent-ad2c07638e56f3d636b2e94258bbfcec387c34b8.tar.gz
XXX fix some typos, allow re-use of SCSA packets
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3.c3
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3.h4
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_ciss.c2
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_ciss.h6
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_commands.c13
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_hba.c61
-rw-r--r--usr/src/uts/common/io/cpqary3/cpqary3_logvol.c37
7 files changed, 88 insertions, 38 deletions
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3.c b/usr/src/uts/common/io/cpqary3/cpqary3.c
index 363520b758..f37d02b371 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3.c
@@ -324,9 +324,10 @@ cpqary3_attach(dev_info_t *dip, ddi_attach_cmd_t attach_cmd)
/*
* Register a periodic function to be called every 15 seconds.
+ * XXX (1 second at the moment)
*/
cpq->cpq_periodic = ddi_periodic_add(cpqary3_periodic, cpq,
- 15 * NANOSEC, DDI_IPL_0);
+ 1 * NANOSEC, DDI_IPL_0);
cpq->cpq_init_level |= CPQARY3_INITLEVEL_PERIODIC;
/* Report that an Instance of the Driver is Attached Successfully */
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3.h b/usr/src/uts/common/io/cpqary3/cpqary3.h
index 93520bd493..3b3ad208a9 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3.h
+++ b/usr/src/uts/common/io/cpqary3/cpqary3.h
@@ -397,6 +397,9 @@ typedef enum cpqary3_command_status {
CPQARY3_CMD_STATUS_POLLED = (0x1 << 6),
CPQARY3_CMD_STATUS_POLL_COMPLETE = (0x1 << 7),
CPQARY3_CMD_STATUS_ABORT_SENT = (0x1 << 8),
+ CPQARY3_CMD_STATUS_TRAN_START = (0x1 << 9),
+ CPQARY3_CMD_STATUS_TRAN_IGNORED = (0x1 << 10),
+ CPQARY3_CMD_STATUS_REUSED = (0x1 << 11),
} cpqary3_command_status_t;
typedef enum cpqary3_command_type {
@@ -456,7 +459,6 @@ struct cpqary3_command_internal {
*/
struct cpqary3_command_scsa {
struct scsi_pkt *cpcms_pkt;
- int cpcms_flags;
cpqary3_command_t *cpcms_command;
};
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.c b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.c
index 0f601cc605..a95a5f2866 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.c
@@ -151,7 +151,7 @@ cpqary3_submit(cpqary3_t *cpq, cpqary3_command_t *cpcm)
* Ensure that this command is not re-used without issuing a new
* tag number and performing any appropriate cleanup.
*/
- VERIFY(!(cpcm->cpcm_status & ~CPQARY3_CMD_STATUS_USED));
+ VERIFY(!(cpcm->cpcm_status & CPQARY3_CMD_STATUS_USED));
cpcm->cpcm_status |= CPQARY3_CMD_STATUS_USED;
/*
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h
index 26e68d7de6..855a0a03da 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h
@@ -81,9 +81,9 @@ extern "C" {
* at offset 34h.
*
* This ill-fated attempt to increase the proprietary complexity of (and
- * presumably, thus, the gross margin on) computer systems folded at the turn
- * of the century. The transport layer of this storage controller is all
- * that's left of their religion.
+ * presumably, thus, the gross margin on) computer systems is all but extinct.
+ * The transport layer of this storage controller is all that's left of their
+ * religion.
*/
#define CISS_I2O_INBOUND_DOORBELL 0x20
#define CISS_I2O_INTERRUPT_STATUS 0x30
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_commands.c b/usr/src/uts/common/io/cpqary3/cpqary3_commands.c
index a8f5390f9e..bf8376fa04 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_commands.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_commands.c
@@ -144,18 +144,11 @@ cpqary3_command_reuse(cpqary3_command_t *cpcm)
mutex_enter(&cpq->cpq_mutex);
/*
- * Make sure the command is not currently inflight.
+ * Make sure the command is not currently inflight, then
+ * reset the command status.
*/
VERIFY(!(cpcm->cpcm_status & CPQARY3_CMD_STATUS_INFLIGHT));
- if (!(cpcm->cpcm_status & CPQARY3_CMD_STATUS_USED)) {
- /*
- * If the command has not yet been issued to the controller,
- * this is a no-op.
- */
- mutex_exit(&cpq->cpq_mutex);
- return;
- }
- cpcm->cpcm_status &= ~CPQARY3_CMD_STATUS_USED;
+ cpcm->cpcm_status = CPQARY3_CMD_STATUS_REUSED;
cpqary3_set_new_tag(cpq, cpcm);
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_hba.c b/usr/src/uts/common/io/cpqary3/cpqary3_hba.c
index 2e216c7cc0..39c5526eee 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_hba.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_hba.c
@@ -157,8 +157,9 @@ cpqary3_tran_setup_pkt(struct scsi_pkt *pkt, int (*callback)(caddr_t),
}
cpcm->cpcm_scsa = cpcms;
cpcms->cpcms_command = cpcm;
+ cpcms->cpcms_pkt = pkt;
- pkt->pkt_cdbp = &cpcm->cpcm_va_cmd->Request.CDB[16];
+ pkt->pkt_cdbp = cpcm->cpcm_va_cmd->Request.CDB;
cpcm->cpcm_va_cmd->Request.CDBLen = pkt->pkt_cdblen;
pkt->pkt_scbp = (uchar_t *)&cpcm->cpcm_va_err->SenseInfo;
@@ -194,6 +195,24 @@ cpqary3_tran_teardown_pkt(struct scsi_pkt *pkt)
pkt->pkt_scbp = NULL;
}
+static void
+cpqary3_set_arq_data(struct scsi_pkt *pkt, uchar_t key)
+{
+ struct scsi_arq_status *arqstat;
+
+ arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp);
+
+ arqstat->sts_status.sts_chk = 1; /* CHECK CONDITION */
+ arqstat->sts_rqpkt_reason = CMD_CMPLT;
+ arqstat->sts_rqpkt_resid = 0;
+ arqstat->sts_rqpkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
+ STATE_SENT_CMD | STATE_XFERRED_DATA;
+ arqstat->sts_rqpkt_statistics = 0;
+ arqstat->sts_sensedata.es_valid = 1;
+ arqstat->sts_sensedata.es_class = CLASS_EXTENDED_SENSE;
+ arqstat->sts_sensedata.es_key = key;
+}
+
static int
cpqary3_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
{
@@ -204,6 +223,37 @@ cpqary3_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
cpqary3_command_t *cpcm = cpcms->cpcms_command;
int r;
+ if (cpcm->cpcm_status & CPQARY3_CMD_STATUS_TRAN_START) {
+ /*
+ * This is a retry of a command that has already been
+ * used once. Assign it a new tag number.
+ */
+ cpqary3_command_reuse(cpcm);
+ }
+ cpcm->cpcm_status |= CPQARY3_CMD_STATUS_TRAN_START;
+
+ /*
+ * The sophisticated firmware in this controller cannot possibly bear
+ * the following SCSI commands. It appears to return a response with
+ * the status STATUS_ACA_ACTIVE (0x30), which is not something we
+ * expect. Instead, fake up a failure response.
+ */
+ switch (pkt->pkt_cdbp[0]) {
+ case SCMD_FORMAT:
+ case SCMD_LOG_SENSE_G1:
+ case SCMD_MODE_SELECT:
+ case SCMD_PERSISTENT_RESERVE_IN:
+ cpcm->cpcm_status |= CPQARY3_CMD_STATUS_TRAN_IGNORED;
+ dev_err(cpq->dip, CE_WARN, "ignored SCSI cmd %02x",
+ (unsigned)pkt->pkt_cdbp[0]); /* XXX */
+ cpqary3_set_arq_data(pkt, KEY_ILLEGAL_REQUEST);
+ pkt->pkt_reason = CMD_BADMSG;
+ pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
+ STATE_SENT_CMD | STATE_XFERRED_DATA;
+ scsi_hba_pkt_comp(pkt);
+ return (TRAN_ACCEPT);
+ }
+
if (pkt->pkt_flags & FLAG_NOINTR) {
/*
* We must sleep and wait for the completion of this command.
@@ -220,6 +270,8 @@ cpqary3_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
/*
* More DMA cookies than we are prepared to handle.
*/
+ dev_err(cpq->dip, CE_WARN, "too many DMA cookies (got %u;"
+ " expected %u)", pkt->pkt_numcookies, cpq->cpq_sg_cnt);
return (TRAN_BADPKT);
}
cpcm->cpcm_va_cmd->Header.SGList = pkt->pkt_numcookies;
@@ -301,6 +353,8 @@ cpqary3_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
if ((r = cpqary3_submit(cpq, cpcm)) != 0) {
mutex_exit(&cpq->cpq_mutex);
+ dev_err(cpq->dip, CE_WARN, "cpqary3_submit failed %d", r);
+
/*
* Inform the SCSI framework that we could not submit
* the command.
@@ -308,6 +362,11 @@ cpqary3_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
return (r == EAGAIN ? TRAN_BUSY : TRAN_FATAL_ERROR);
}
+ dev_err(cpq->dip, CE_WARN, "SCSI OUT targ %3x opcode %x len %u",
+ cpcm->cpcm_target->cptg_scsi_dev->sd_address.a_target,
+ (unsigned)cpcm->cpcm_va_cmd->Request.CDB[0],
+ pkt->pkt_cdblen);
+
/*
* Update the SCSI packet to reflect submission of the command.
*/
diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c b/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c
index e2654a6fa1..6c008d6a10 100644
--- a/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c
+++ b/usr/src/uts/common/io/cpqary3/cpqary3_logvol.c
@@ -86,16 +86,16 @@ cpqary3_read_logvols(cpqary3_t *cpq, cpqary3_report_logical_lun_t *cprll)
if ((cplv = kmem_zalloc(sizeof (*cplv), KM_NOSLEEP)) ==
NULL) {
return (ENOMEM);
+ }
- cplv->cplv_addr = ents[i].cprle_addr;
+ cplv->cplv_addr = ents[i].cprle_addr;
- list_create(&cplv->cplv_targets,
- sizeof (cpqary3_target_t),
- offsetof(cpqary3_target_t, cptg_link_volume));
+ list_create(&cplv->cplv_targets,
+ sizeof (cpqary3_target_t),
+ offsetof(cpqary3_target_t, cptg_link_volume));
- cplv->cplv_ctlr = cpq;
- list_insert_tail(&cpq->cpq_volumes, cplv);
- }
+ cplv->cplv_ctlr = cpq;
+ list_insert_tail(&cpq->cpq_volumes, cplv);
}
return (0);
@@ -155,19 +155,19 @@ cpqary3_read_logvols_ext(cpqary3_t *cpq, cpqary3_report_logical_lun_t *cprll)
if ((cplv = kmem_zalloc(sizeof (*cplv), KM_NOSLEEP)) ==
NULL) {
return (ENOMEM);
+ }
- cplv->cplv_addr = extents[i].cprle_addr;
+ cplv->cplv_addr = extents[i].cprle_addr;
- bcopy(extents[i].cprle_wwn, cplv->cplv_wwn, 16);
- cplv->cplv_flags |= CPQARY3_VOL_FLAG_WWN;
+ bcopy(extents[i].cprle_wwn, cplv->cplv_wwn, 16);
+ cplv->cplv_flags |= CPQARY3_VOL_FLAG_WWN;
- list_create(&cplv->cplv_targets,
- sizeof (cpqary3_target_t),
- offsetof(cpqary3_target_t, cptg_link_volume));
+ list_create(&cplv->cplv_targets,
+ sizeof (cpqary3_target_t),
+ offsetof(cpqary3_target_t, cptg_link_volume));
- cplv->cplv_ctlr = cpq;
- list_insert_tail(&cpq->cpq_volumes, cplv);
- }
+ cplv->cplv_ctlr = cpq;
+ list_insert_tail(&cpq->cpq_volumes, cplv);
}
return (0);
@@ -220,7 +220,6 @@ cpqary3_discover_logical_volumes(cpqary3_t *cpq, int timeout)
cprllr.cprllr_datasize = htonl(sizeof (cpqary3_report_logical_lun_t));
bcopy(&cprllr, cl->Request.CDB, 16);
- dev_err(cpq->dip, CE_WARN, "send: REPORT LOGICAL LUNs");
if (cpqary3_synccmd_send(cpq, cpcm, timeout * 1000,
CPQARY3_SYNCCMD_SEND_WAITSIG) != 0) {
cpqary3_synccmd_free(cpq, cpcm);
@@ -242,12 +241,8 @@ cpqary3_discover_logical_volumes(cpqary3_t *cpq, int timeout)
mutex_enter(&cpq->cpq_mutex);
if ((cprll->cprll_extflag & 0x1) != 0) {
- dev_err(cpq->dip, CE_WARN, "LOG LUNS: EXT RESPONSE!");
-
r = cpqary3_read_logvols_ext(cpq, cprll);
} else {
- dev_err(cpq->dip, CE_WARN, "LOG LUNS: NORMAL RESPONSE!");
-
r = cpqary3_read_logvols(cpq, cprll);
}
mutex_exit(&cpq->cpq_mutex);