+++ /dev/null
-From 517614ffd4e2408c731ad62bcbe169b0d0c49a0d Mon Sep 17 00:00:00 2001
-From: Karen Higgins <karen.higgins@qlogic.com>
-Date: Thu, 23 Apr 2009 21:48:36 -0700
-Subject: Correct Extended Sense Data Errors
-References: bnc#483706
-
-Fixed sense data errors occurring above the first 32 bytes,
-as required by some third party applications. Sense data
-in the first 32 bytes has always been correct.
-
-Also, corrected debug print alignment bug in dump_buffer routine.
-Removed KERN_DEBUG from printk statements in this routine,
-as loglevel #defines only get interpreted if the previous
-print statement ends with a newline character. This prevents
-<7> from being diplayed throughout the buffer.
-
-Changed version number to 5.01.00-k9
-
-Signed-off-by: Karen Higgins <karen.higgins@qlogic.com>
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-
----
- drivers/scsi/qla4xxx/ql4_dbg.c | 15 ++--
- drivers/scsi/qla4xxx/ql4_def.h | 2 +
- drivers/scsi/qla4xxx/ql4_fw.h | 7 ++
- drivers/scsi/qla4xxx/ql4_isr.c | 147 +++++++++++++++++++++++++-----------
- drivers/scsi/qla4xxx/ql4_version.h | 2 +-
- 5 files changed, 119 insertions(+), 54 deletions(-)
-
-diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
-index 7ea69a6..0f6b6b0 100644
---- a/drivers/scsi/qla4xxx/ql4_dbg.c
-+++ b/drivers/scsi/qla4xxx/ql4_dbg.c
-@@ -138,13 +138,13 @@ void qla4xxx_dump_buffer(void *b, uint32_t size)
- "Fh\n");
- printk("------------------------------------------------------------"
- "--\n");
-- for (cnt = 0; cnt < size; cnt++, c++) {
-- printk(KERN_DEBUG "%02x", *c);
-- if (!(cnt % 16))
-- printk(KERN_DEBUG "\n");
-+ for (cnt = 0; cnt < size; c++) {
-+ printk("%02x", *c);
-+ if (!(++cnt % 16))
-+ printk("\n");
-
- else
-- printk(KERN_DEBUG " ");
-+ printk(" ");
- }
-- printk(KERN_DEBUG "\n");
-+ printk("\n");
- }
-diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
-index 2b5af89..f8ea527 100644
---- a/drivers/scsi/qla4xxx/ql4_def.h
-+++ b/drivers/scsi/qla4xxx/ql4_def.h
-@@ -465,6 +465,9 @@ struct scsi_qla_host {
- #define QL_INDICES_PER_ENTRY 32
- #define QL_OSINDEX_ENTRIES (MAX_DDB_ENTRIES/QL_INDICES_PER_ENTRY)
- volatile unsigned long os_map[QL_OSINDEX_ENTRIES];
-+
-+ /* Saved srb for status continuation entry processing */
-+ struct srb *status_srb;
- };
-
- static inline int is_qla4010(struct scsi_qla_host *ha)
-diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
-index 3fb3658..083089e 100644
---- a/drivers/scsi/qla4xxx/ql4_fw.h
-+++ b/drivers/scsi/qla4xxx/ql4_fw.h
-@@ -581,6 +581,7 @@ struct conn_event_log_entry {
- *************************************************************************/
- #define IOCB_MAX_CDB_LEN 16 /* Bytes in a CBD */
- #define IOCB_MAX_SENSEDATA_LEN 32 /* Bytes of sense data */
-+#define IOCB_MAX_EXT_SENSEDATA_LEN 60 /* Bytes of extended sense data */
-
- /* IOCB header structure */
- struct qla4_header {
-@@ -750,6 +751,12 @@ struct pdu_entry {
- dma_addr_t DmaBuff;
- };
-
-+/* Status Continuation entry */
-+struct status_cont_entry {
-+ struct qla4_header hdr; /* 00-03 */
-+ uint8_t extSenseData[IOCB_MAX_EXT_SENSEDATA_LEN]; /* 04-63 */
-+};
-+
- struct passthru0 {
- struct qla4_header hdr; /* 00-03 */
- uint32_t handle; /* 04-07 */
-diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
-index 5c36ce6..c3354b8 100644
---- a/drivers/scsi/qla4xxx/ql4_isr.c
-+++ b/drivers/scsi/qla4xxx/ql4_isr.c
-@@ -13,6 +13,100 @@
- #include "ql4_os.h"
-
- /**
-+ * qla4xxx_copy_sense - copy sense data into cmd sense buffer
-+ * @ha: Pointer to host adapter structure.
-+ * @sts_entry: Pointer to status entry structure.
-+ * @srb: Pointer to srb structure.
-+ **/
-+static void qla4xxx_copy_sense(struct scsi_qla_host *ha,
-+ struct status_entry *sts_entry,
-+ struct srb *srb)
-+{
-+ struct scsi_cmnd *cmd = srb->cmd;
-+ uint16_t sense_len;
-+
-+ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
-+ sense_len = le16_to_cpu(sts_entry->senseDataByteCnt);
-+ if (sense_len == 0)
-+ return;
-+
-+ /* Save total available sense length,
-+ * not to exceed cmd's sense buffer size */
-+ sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE);
-+ cmd->SCp.ptr = cmd->sense_buffer;
-+ cmd->SCp.this_residual = sense_len;
-+
-+ /* Copy sense from sts_entry pkt */
-+ sense_len = min_t(uint16_t, sense_len, IOCB_MAX_SENSEDATA_LEN);
-+ memcpy(cmd->sense_buffer, sts_entry->senseData, sense_len);
-+
-+ DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
-+ "Addl.SenseLen - %02x, "
-+ "ASC/ASCQ = %02x/%02x\n", ha->host_no,
-+ cmd->device->channel, cmd->device->id,
-+ cmd->device->lun, __func__,
-+ sts_entry->senseData[2] & 0x0f,
-+ sts_entry->senseData[7],
-+ sts_entry->senseData[12],
-+ sts_entry->senseData[13]));
-+
-+ DEBUG5(qla4xxx_dump_buffer(cmd->SCp.ptr, sense_len));
-+ srb->flags |= SRB_GOT_SENSE;
-+
-+ /* Update srb, in case a sts_cont pkt follows */
-+ cmd->SCp.ptr += sense_len;
-+ cmd->SCp.this_residual -= sense_len;
-+ if (cmd->SCp.this_residual != 0)
-+ ha->status_srb = srb;
-+ else
-+ ha->status_srb = NULL;
-+}
-+
-+/**
-+ * qla4xxx_status_cont_entry() - Process a Status Continuations entry.
-+ * @ha: SCSI driver HA context
-+ * @sts_cont: Entry pointer
-+ *
-+ * Extended sense data.
-+ */
-+static void
-+qla4xxx_status_cont_entry(struct scsi_qla_host *ha,
-+ struct status_cont_entry *sts_cont)
-+{
-+ struct srb *srb = ha->status_srb;
-+ struct scsi_cmnd *cmd;
-+ uint8_t sense_len;
-+
-+ if (srb == NULL) {
-+ DEBUG2(printk("scsi%ld: %s: Throw away extra STATUS CONTINUATION\n",
-+ ha->host_no, __func__));
-+ return;
-+ }
-+
-+ cmd = srb->cmd;
-+ if (cmd == NULL) {
-+ DEBUG2(printk("scsi%ld: %s: Cmd already returned back to OS "
-+ "srb=%p srb->state:%d\n", ha->host_no, __func__, srb, srb->state));
-+ ha->status_srb = NULL;
-+ return;
-+ }
-+
-+ /* Copy sense data. */
-+ sense_len = min(cmd->SCp.this_residual, IOCB_MAX_EXT_SENSEDATA_LEN);
-+ memcpy(cmd->SCp.ptr, sts_cont->extSenseData, sense_len);
-+ DEBUG5(qla4xxx_dump_buffer(cmd->SCp.ptr, sense_len));
-+
-+ cmd->SCp.ptr += sense_len;
-+ cmd->SCp.this_residual -= sense_len;
-+
-+ /* Place command on done queue. */
-+ if (cmd->SCp.this_residual == 0) {
-+ qla4xxx_srb_compl(ha, srb);
-+ ha->status_srb = NULL;
-+ }
-+}
-+
-+/**
- * qla4xxx_status_entry - processes status IOCBs
- * @ha: Pointer to host adapter structure.
- * @sts_entry: Pointer to status entry structure.
-@@ -25,7 +119,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
- struct srb *srb;
- struct ddb_entry *ddb_entry;
- uint32_t residual;
-- uint16_t sensebytecnt;
-
- srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle));
- if (!srb) {
-@@ -74,24 +167,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
- break;
-
- /* Copy Sense Data into sense buffer. */
-- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
--
-- sensebytecnt = le16_to_cpu(sts_entry->senseDataByteCnt);
-- if (sensebytecnt == 0)
-- break;
--
-- memcpy(cmd->sense_buffer, sts_entry->senseData,
-- min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE));
--
-- DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
-- "ASC/ASCQ = %02x/%02x\n", ha->host_no,
-- cmd->device->channel, cmd->device->id,
-- cmd->device->lun, __func__,
-- sts_entry->senseData[2] & 0x0f,
-- sts_entry->senseData[12],
-- sts_entry->senseData[13]));
--
-- srb->flags |= SRB_GOT_SENSE;
-+ qla4xxx_copy_sense(ha, sts_entry, srb);
- break;
-
- case SCS_INCOMPLETE:
-@@ -158,23 +234,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
- break;
-
- /* Copy Sense Data into sense buffer. */
-- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
--
-- sensebytecnt =
-- le16_to_cpu(sts_entry->senseDataByteCnt);
-- if (sensebytecnt == 0)
-- break;
--
-- memcpy(cmd->sense_buffer, sts_entry->senseData,
-- min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE));
--
-- DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
-- "ASC/ASCQ = %02x/%02x\n", ha->host_no,
-- cmd->device->channel, cmd->device->id,
-- cmd->device->lun, __func__,
-- sts_entry->senseData[2] & 0x0f,
-- sts_entry->senseData[12],
-- sts_entry->senseData[13]));
-+ qla4xxx_copy_sense(ha, sts_entry, srb);
- } else {
- /*
- * If RISC reports underrun and target does not
-@@ -250,9 +310,10 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
-
- status_entry_exit:
-
-- /* complete the request */
-+ /* complete the request, if not waiting for status_continuation pkt */
- srb->cc_stat = sts_entry->completionStatus;
-- qla4xxx_srb_compl(ha, srb);
-+ if (ha->status_srb == NULL)
-+ qla4xxx_srb_compl(ha, srb);
- }
-
- /**
-@@ -287,10 +348,7 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
- /* process entry */
- switch (sts_entry->hdr.entryType) {
- case ET_STATUS:
-- /*
-- * Common status - Single completion posted in single
-- * IOSB.
-- */
-+ /* Common status */
- qla4xxx_status_entry(ha, sts_entry);
- break;
-
-@@ -298,9 +356,8 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
- break;
-
- case ET_STATUS_CONTINUATION:
-- /* Just throw away the status continuation entries */
-- DEBUG2(printk("scsi%ld: %s: Status Continuation entry "
-- "- ignoring\n", ha->host_no, __func__));
-+ qla4xxx_status_cont_entry(ha,
-+ (struct status_cont_entry *) sts_entry);
- break;
-
- case ET_COMMAND:
-diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
-index 073e401..5de8e5f 100644
---- a/drivers/scsi/qla4xxx/ql4_version.h
-+++ b/drivers/scsi/qla4xxx/ql4_version.h
-@@ -5,5 +5,5 @@
- * See LICENSE.qla4xxx for copyright and licensing details.
- */
-
--#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-04"
-+#define QLA4XXX_DRIVER_VERSION "5.01.00-k9_sles11-04"
-