]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.drivers/qla4xxx-correct-extended-sense-data-errors
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / qla4xxx-correct-extended-sense-data-errors
CommitLineData
2cb7cef9
BS
1From 517614ffd4e2408c731ad62bcbe169b0d0c49a0d Mon Sep 17 00:00:00 2001
2From: Karen Higgins <karen.higgins@qlogic.com>
3Date: Thu, 23 Apr 2009 21:48:36 -0700
4Subject: Correct Extended Sense Data Errors
5References: bnc#483706
6
7Fixed sense data errors occurring above the first 32 bytes,
8as required by some third party applications. Sense data
9in the first 32 bytes has always been correct.
10
11Also, corrected debug print alignment bug in dump_buffer routine.
12Removed KERN_DEBUG from printk statements in this routine,
13as loglevel #defines only get interpreted if the previous
14print statement ends with a newline character. This prevents
15<7> from being diplayed throughout the buffer.
16
17Changed version number to 5.01.00-k9
18
19Signed-off-by: Karen Higgins <karen.higgins@qlogic.com>
20Signed-off-by: Hannes Reinecke <hare@suse.de>
21
22---
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(-)
29
30diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
31index 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)
35 "Fh\n");
36 printk("------------------------------------------------------------"
37 "--\n");
38- for (cnt = 0; cnt < size; cnt++, c++) {
39- printk(KERN_DEBUG "%02x", *c);
40- if (!(cnt % 16))
41- printk(KERN_DEBUG "\n");
42+ for (cnt = 0; cnt < size; c++) {
43+ printk("%02x", *c);
44+ if (!(++cnt % 16))
45+ printk("\n");
46
47 else
48- printk(KERN_DEBUG " ");
49+ printk(" ");
50 }
51- printk(KERN_DEBUG "\n");
52+ printk("\n");
53 }
54diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
55index 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];
62+
63+ /* Saved srb for status continuation entry processing */
64+ struct srb *status_srb;
65 };
66
67 static inline int is_qla4010(struct scsi_qla_host *ha)
68diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
69index 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 */
77
78 /* IOCB header structure */
79 struct qla4_header {
80@@ -750,6 +751,12 @@ struct pdu_entry {
81 dma_addr_t DmaBuff;
82 };
83
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 */
88+};
89+
90 struct passthru0 {
91 struct qla4_header hdr; /* 00-03 */
92 uint32_t handle; /* 04-07 */
93diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
94index 5c36ce6..c3354b8 100644
95--- a/drivers/scsi/qla4xxx/ql4_isr.c
96+++ b/drivers/scsi/qla4xxx/ql4_isr.c
97@@ -13,6 +13,100 @@
98 #include "ql4_os.h"
99
100 /**
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.
105+ **/
106+static void qla4xxx_copy_sense(struct scsi_qla_host *ha,
107+ struct status_entry *sts_entry,
108+ struct srb *srb)
109+{
110+ struct scsi_cmnd *cmd = srb->cmd;
111+ uint16_t sense_len;
112+
113+ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
114+ sense_len = le16_to_cpu(sts_entry->senseDataByteCnt);
115+ if (sense_len == 0)
116+ return;
117+
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;
123+
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);
127+
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]));
137+
138+ DEBUG5(qla4xxx_dump_buffer(cmd->SCp.ptr, sense_len));
139+ srb->flags |= SRB_GOT_SENSE;
140+
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;
146+ else
147+ ha->status_srb = NULL;
148+}
149+
150+/**
151+ * qla4xxx_status_cont_entry() - Process a Status Continuations entry.
152+ * @ha: SCSI driver HA context
153+ * @sts_cont: Entry pointer
154+ *
155+ * Extended sense data.
156+ */
157+static void
158+qla4xxx_status_cont_entry(struct scsi_qla_host *ha,
159+ struct status_cont_entry *sts_cont)
160+{
161+ struct srb *srb = ha->status_srb;
162+ struct scsi_cmnd *cmd;
163+ uint8_t sense_len;
164+
165+ if (srb == NULL) {
166+ DEBUG2(printk("scsi%ld: %s: Throw away extra STATUS CONTINUATION\n",
167+ ha->host_no, __func__));
168+ return;
169+ }
170+
171+ cmd = srb->cmd;
172+ if (cmd == NULL) {
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;
176+ return;
177+ }
178+
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));
183+
184+ cmd->SCp.ptr += sense_len;
185+ cmd->SCp.this_residual -= sense_len;
186+
187+ /* Place command on done queue. */
188+ if (cmd->SCp.this_residual == 0) {
189+ qla4xxx_srb_compl(ha, srb);
190+ ha->status_srb = NULL;
191+ }
192+}
193+
194+/**
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,
199 struct srb *srb;
200 struct ddb_entry *ddb_entry;
201 uint32_t residual;
202- uint16_t sensebytecnt;
203
204 srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle));
205 if (!srb) {
206@@ -74,24 +167,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
207 break;
208
209 /* Copy Sense Data into sense buffer. */
210- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
211-
212- sensebytecnt = le16_to_cpu(sts_entry->senseDataByteCnt);
213- if (sensebytecnt == 0)
214- break;
215-
216- memcpy(cmd->sense_buffer, sts_entry->senseData,
217- min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE));
218-
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]));
226-
227- srb->flags |= SRB_GOT_SENSE;
228+ qla4xxx_copy_sense(ha, sts_entry, srb);
229 break;
230
231 case SCS_INCOMPLETE:
232@@ -158,23 +234,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
233 break;
234
235 /* Copy Sense Data into sense buffer. */
236- memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
237-
238- sensebytecnt =
239- le16_to_cpu(sts_entry->senseDataByteCnt);
240- if (sensebytecnt == 0)
241- break;
242-
243- memcpy(cmd->sense_buffer, sts_entry->senseData,
244- min_t(uint16_t, sensebytecnt, SCSI_SENSE_BUFFERSIZE));
245-
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);
254 } else {
255 /*
256 * If RISC reports underrun and target does not
257@@ -250,9 +310,10 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
258
259 status_entry_exit:
260
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);
267 }
268
269 /**
270@@ -287,10 +348,7 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
271 /* process entry */
272 switch (sts_entry->hdr.entryType) {
273 case ET_STATUS:
274- /*
275- * Common status - Single completion posted in single
276- * IOSB.
277- */
278+ /* Common status */
279 qla4xxx_status_entry(ha, sts_entry);
280 break;
281
282@@ -298,9 +356,8 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
283 break;
284
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);
291 break;
292
293 case ET_COMMAND:
294diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
295index 073e401..5de8e5f 100644
296--- a/drivers/scsi/qla4xxx/ql4_version.h
297+++ b/drivers/scsi/qla4xxx/ql4_version.h
298@@ -5,5 +5,5 @@
299 * See LICENSE.qla4xxx for copyright and licensing details.
300 */
301
302-#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-04"
303+#define QLA4XXX_DRIVER_VERSION "5.01.00-k9_sles11-04"
304