1 From 517614ffd4e2408c731ad62bcbe169b0d0c49a0d Mon Sep 17 00:00:00 2001
2 From: Karen Higgins <karen.higgins@qlogic.com>
3 Date: Thu, 23 Apr 2009 21:48:36 -0700
4 Subject: Correct Extended Sense Data Errors
7 Fixed sense data errors occurring above the first 32 bytes,
8 as required by some third party applications. Sense data
9 in the first 32 bytes has always been correct.
11 Also, corrected debug print alignment bug in dump_buffer routine.
12 Removed KERN_DEBUG from printk statements in this routine,
13 as loglevel #defines only get interpreted if the previous
14 print statement ends with a newline character. This prevents
15 <7> from being diplayed throughout the buffer.
17 Changed version number to 5.01.00-k9
19 Signed-off-by: Karen Higgins <karen.higgins@qlogic.com>
20 Signed-off-by: Hannes Reinecke <hare@suse.de>
23 drivers/scsi/qla4xxx/ql4_dbg.c | 15 ++--
24 drivers/scsi/qla4xxx/ql4_def.h | 2 +
25 drivers/scsi/qla4xxx/ql4_fw.h | 7 ++
26 drivers/scsi/qla4xxx/ql4_isr.c | 147 +++++++++++++++++++++++++-----------
27 drivers/scsi/qla4xxx/ql4_version.h | 2 +-
28 5 files changed, 119 insertions(+), 54 deletions(-)
30 diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
31 index 7ea69a6..0f6b6b0 100644
32 --- a/drivers/scsi/qla4xxx/ql4_dbg.c
33 +++ b/drivers/scsi/qla4xxx/ql4_dbg.c
34 @@ -138,13 +138,13 @@ void qla4xxx_dump_buffer(void *b, uint32_t size)
36 printk("------------------------------------------------------------"
38 - for (cnt = 0; cnt < size; cnt++, c++) {
39 - printk(KERN_DEBUG "%02x", *c);
41 - printk(KERN_DEBUG "\n");
42 + for (cnt = 0; cnt < size; c++) {
48 - printk(KERN_DEBUG " ");
51 - printk(KERN_DEBUG "\n");
54 diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
55 index 2b5af89..f8ea527 100644
56 --- a/drivers/scsi/qla4xxx/ql4_def.h
57 +++ b/drivers/scsi/qla4xxx/ql4_def.h
58 @@ -465,6 +465,9 @@ struct scsi_qla_host {
59 #define QL_INDICES_PER_ENTRY 32
60 #define QL_OSINDEX_ENTRIES (MAX_DDB_ENTRIES/QL_INDICES_PER_ENTRY)
61 volatile unsigned long os_map[QL_OSINDEX_ENTRIES];
63 + /* Saved srb for status continuation entry processing */
64 + struct srb *status_srb;
67 static inline int is_qla4010(struct scsi_qla_host *ha)
68 diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
69 index 3fb3658..083089e 100644
70 --- a/drivers/scsi/qla4xxx/ql4_fw.h
71 +++ b/drivers/scsi/qla4xxx/ql4_fw.h
72 @@ -581,6 +581,7 @@ struct conn_event_log_entry {
73 *************************************************************************/
74 #define IOCB_MAX_CDB_LEN 16 /* Bytes in a CBD */
75 #define IOCB_MAX_SENSEDATA_LEN 32 /* Bytes of sense data */
76 +#define IOCB_MAX_EXT_SENSEDATA_LEN 60 /* Bytes of extended sense data */
78 /* IOCB header structure */
80 @@ -750,6 +751,12 @@ struct pdu_entry {
84 +/* Status Continuation entry */
85 +struct status_cont_entry {
86 + struct qla4_header hdr; /* 00-03 */
87 + uint8_t extSenseData[IOCB_MAX_EXT_SENSEDATA_LEN]; /* 04-63 */
91 struct qla4_header hdr; /* 00-03 */
92 uint32_t handle; /* 04-07 */
93 diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
94 index 5c36ce6..c3354b8 100644
95 --- a/drivers/scsi/qla4xxx/ql4_isr.c
96 +++ b/drivers/scsi/qla4xxx/ql4_isr.c
101 + * qla4xxx_copy_sense - copy sense data into cmd sense buffer
102 + * @ha: Pointer to host adapter structure.
103 + * @sts_entry: Pointer to status entry structure.
104 + * @srb: Pointer to srb structure.
106 +static void qla4xxx_copy_sense(struct scsi_qla_host *ha,
107 + struct status_entry *sts_entry,
110 + struct scsi_cmnd *cmd = srb->cmd;
111 + uint16_t sense_len;
113 + memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
114 + sense_len = le16_to_cpu(sts_entry->senseDataByteCnt);
115 + if (sense_len == 0)
118 + /* Save total available sense length,
119 + * not to exceed cmd's sense buffer size */
120 + sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE);
121 + cmd->SCp.ptr = cmd->sense_buffer;
122 + cmd->SCp.this_residual = sense_len;
124 + /* Copy sense from sts_entry pkt */
125 + sense_len = min_t(uint16_t, sense_len, IOCB_MAX_SENSEDATA_LEN);
126 + memcpy(cmd->sense_buffer, sts_entry->senseData, sense_len);
128 + DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
129 + "Addl.SenseLen - %02x, "
130 + "ASC/ASCQ = %02x/%02x\n", ha->host_no,
131 + cmd->device->channel, cmd->device->id,
132 + cmd->device->lun, __func__,
133 + sts_entry->senseData[2] & 0x0f,
134 + sts_entry->senseData[7],
135 + sts_entry->senseData[12],
136 + sts_entry->senseData[13]));
138 + DEBUG5(qla4xxx_dump_buffer(cmd->SCp.ptr, sense_len));
139 + srb->flags |= SRB_GOT_SENSE;
141 + /* Update srb, in case a sts_cont pkt follows */
142 + cmd->SCp.ptr += sense_len;
143 + cmd->SCp.this_residual -= sense_len;
144 + if (cmd->SCp.this_residual != 0)
145 + ha->status_srb = srb;
147 + ha->status_srb = NULL;
151 + * qla4xxx_status_cont_entry() - Process a Status Continuations entry.
152 + * @ha: SCSI driver HA context
153 + * @sts_cont: Entry pointer
155 + * Extended sense data.
158 +qla4xxx_status_cont_entry(struct scsi_qla_host *ha,
159 + struct status_cont_entry *sts_cont)
161 + struct srb *srb = ha->status_srb;
162 + struct scsi_cmnd *cmd;
166 + DEBUG2(printk("scsi%ld: %s: Throw away extra STATUS CONTINUATION\n",
167 + ha->host_no, __func__));
173 + DEBUG2(printk("scsi%ld: %s: Cmd already returned back to OS "
174 + "srb=%p srb->state:%d\n", ha->host_no, __func__, srb, srb->state));
175 + ha->status_srb = NULL;
179 + /* Copy sense data. */
180 + sense_len = min(cmd->SCp.this_residual, IOCB_MAX_EXT_SENSEDATA_LEN);
181 + memcpy(cmd->SCp.ptr, sts_cont->extSenseData, sense_len);
182 + DEBUG5(qla4xxx_dump_buffer(cmd->SCp.ptr, sense_len));
184 + cmd->SCp.ptr += sense_len;
185 + cmd->SCp.this_residual -= sense_len;
187 + /* Place command on done queue. */
188 + if (cmd->SCp.this_residual == 0) {
189 + qla4xxx_srb_compl(ha, srb);
190 + ha->status_srb = NULL;
195 * qla4xxx_status_entry - processes status IOCBs
196 * @ha: Pointer to host adapter structure.
197 * @sts_entry: Pointer to status entry structure.
198 @@ -25,7 +119,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
200 struct ddb_entry *ddb_entry;
202 - uint16_t sensebytecnt;
204 srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle));
206 @@ -74,24 +167,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
209 /* Copy Sense Data into sense buffer. */
210 - memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
212 - sensebytecnt = le16_to_cpu(sts_entry->senseDataByteCnt);
213 - if (sensebytecnt == 0)
216 - memcpy(cmd->sense_buffer, sts_entry->senseData,
217 - min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE));
219 - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
220 - "ASC/ASCQ = %02x/%02x\n", ha->host_no,
221 - cmd->device->channel, cmd->device->id,
222 - cmd->device->lun, __func__,
223 - sts_entry->senseData[2] & 0x0f,
224 - sts_entry->senseData[12],
225 - sts_entry->senseData[13]));
227 - srb->flags |= SRB_GOT_SENSE;
228 + qla4xxx_copy_sense(ha, sts_entry, srb);
232 @@ -158,23 +234,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
235 /* Copy Sense Data into sense buffer. */
236 - memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
239 - le16_to_cpu(sts_entry->senseDataByteCnt);
240 - if (sensebytecnt == 0)
243 - memcpy(cmd->sense_buffer, sts_entry->senseData,
244 - min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE));
246 - DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
247 - "ASC/ASCQ = %02x/%02x\n", ha->host_no,
248 - cmd->device->channel, cmd->device->id,
249 - cmd->device->lun, __func__,
250 - sts_entry->senseData[2] & 0x0f,
251 - sts_entry->senseData[12],
252 - sts_entry->senseData[13]));
253 + qla4xxx_copy_sense(ha, sts_entry, srb);
256 * If RISC reports underrun and target does not
257 @@ -250,9 +310,10 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
261 - /* complete the request */
262 + /* complete the request, if not waiting for status_continuation pkt */
263 srb->cc_stat = sts_entry->completionStatus;
264 - qla4xxx_srb_compl(ha, srb);
265 + if (ha->status_srb == NULL)
266 + qla4xxx_srb_compl(ha, srb);
270 @@ -287,10 +348,7 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
272 switch (sts_entry->hdr.entryType) {
275 - * Common status - Single completion posted in single
278 + /* Common status */
279 qla4xxx_status_entry(ha, sts_entry);
282 @@ -298,9 +356,8 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
285 case ET_STATUS_CONTINUATION:
286 - /* Just throw away the status continuation entries */
287 - DEBUG2(printk("scsi%ld: %s: Status Continuation entry "
288 - "- ignoring\n", ha->host_no, __func__));
289 + qla4xxx_status_cont_entry(ha,
290 + (struct status_cont_entry *) sts_entry);
294 diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
295 index 073e401..5de8e5f 100644
296 --- a/drivers/scsi/qla4xxx/ql4_version.h
297 +++ b/drivers/scsi/qla4xxx/ql4_version.h
299 * See LICENSE.qla4xxx for copyright and licensing details.
302 -#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-04"
303 +#define QLA4XXX_DRIVER_VERSION "5.01.00-k9_sles11-04"