]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.drivers/qla4xxx-correct-extended-sense-data-errors
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / qla4xxx-correct-extended-sense-data-errors
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
5 References: bnc#483706
6
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.
10
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.
16
17 Changed version number to 5.01.00-k9
18
19 Signed-off-by: Karen Higgins <karen.higgins@qlogic.com>
20 Signed-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
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)
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 }
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];
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)
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 */
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 */
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
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:
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
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