aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_isr.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2005-07-06 13:31:27 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-07-14 11:00:27 -0400
commit9a853f71804d80e862362f6d0743d06955305752 (patch)
tree311136d6956994e6ac2d6479e0d0b1fbbffe8564 /drivers/scsi/qla2xxx/qla_isr.c
parent2b6c0cee90cecbce35fb6d65fed94f22e5063be0 (diff)
[SCSI] qla2xxx: Add ISP24xx ISR routines.
Add ISP24xx ISR routines. Add appropriate glue-code for ISP24xx support -- this included generalizing some of the core handling routines (qla2x00_async_event() [pull-up retrieval of mailbox values] and qla2x00_status_entry()]. Fixup 2100/2300 ISRs to handle the new conventions. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c582
1 files changed, 418 insertions, 164 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f38d13628f43..b960bdfe91e9 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -19,14 +19,17 @@
19#include "qla_def.h" 19#include "qla_def.h"
20 20
21static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); 21static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
22static void qla2x00_async_event(scsi_qla_host_t *, uint32_t); 22static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
23static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); 23static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
24void qla2x00_process_response_queue(struct scsi_qla_host *); 24void qla2x00_process_response_queue(struct scsi_qla_host *);
25static void qla2x00_status_entry(scsi_qla_host_t *, sts_entry_t *); 25static void qla2x00_status_entry(scsi_qla_host_t *, void *);
26static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); 26static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
27static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); 27static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
28static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *); 28static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
29 29
30void qla24xx_process_response_queue(scsi_qla_host_t *);
31static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
32
30/** 33/**
31 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. 34 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
32 * @irq: 35 * @irq:
@@ -45,7 +48,7 @@ qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
45 int status; 48 int status;
46 unsigned long flags; 49 unsigned long flags;
47 unsigned long iter; 50 unsigned long iter;
48 uint32_t mbx; 51 uint16_t mb[4];
49 52
50 ha = (scsi_qla_host_t *) dev_id; 53 ha = (scsi_qla_host_t *) dev_id;
51 if (!ha) { 54 if (!ha) {
@@ -67,17 +70,20 @@ qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
67 RD_REG_WORD(&reg->hccr); 70 RD_REG_WORD(&reg->hccr);
68 71
69 /* Get mailbox data. */ 72 /* Get mailbox data. */
70 mbx = RD_MAILBOX_REG(ha, reg, 0); 73 mb[0] = RD_MAILBOX_REG(ha, reg, 0);
71 if (mbx > 0x3fff && mbx < 0x8000) { 74 if (mb[0] > 0x3fff && mb[0] < 0x8000) {
72 qla2x00_mbx_completion(ha, (uint16_t)mbx); 75 qla2x00_mbx_completion(ha, mb[0]);
73 status |= MBX_INTERRUPT; 76 status |= MBX_INTERRUPT;
74 } else if (mbx > 0x7fff && mbx < 0xc000) { 77 } else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
75 qla2x00_async_event(ha, mbx); 78 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
79 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
80 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
81 qla2x00_async_event(ha, mb);
76 } else { 82 } else {
77 /*EMPTY*/ 83 /*EMPTY*/
78 DEBUG2(printk("scsi(%ld): Unrecognized " 84 DEBUG2(printk("scsi(%ld): Unrecognized "
79 "interrupt type (%d)\n", 85 "interrupt type (%d).\n",
80 ha->host_no, mbx)); 86 ha->host_no, mb[0]));
81 } 87 }
82 /* Release mailbox registers. */ 88 /* Release mailbox registers. */
83 WRT_REG_WORD(&reg->semaphore, 0); 89 WRT_REG_WORD(&reg->semaphore, 0);
@@ -123,8 +129,8 @@ qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
123 unsigned long flags; 129 unsigned long flags;
124 unsigned long iter; 130 unsigned long iter;
125 uint32_t stat; 131 uint32_t stat;
126 uint32_t mbx;
127 uint16_t hccr; 132 uint16_t hccr;
133 uint16_t mb[4];
128 134
129 ha = (scsi_qla_host_t *) dev_id; 135 ha = (scsi_qla_host_t *) dev_id;
130 if (!ha) { 136 if (!ha) {
@@ -146,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
146 "Parity error -- HCCR=%x.\n", hccr); 152 "Parity error -- HCCR=%x.\n", hccr);
147 else 153 else
148 qla_printk(KERN_INFO, ha, 154 qla_printk(KERN_INFO, ha,
149 "RISC paused -- HCCR=%x\n", hccr); 155 "RISC paused -- HCCR=%x.\n", hccr);
150 156
151 /* 157 /*
152 * Issue a "HARD" reset in order for the RISC 158 * Issue a "HARD" reset in order for the RISC
@@ -160,35 +166,41 @@ qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
160 } else if ((stat & HSR_RISC_INT) == 0) 166 } else if ((stat & HSR_RISC_INT) == 0)
161 break; 167 break;
162 168
163 mbx = MSW(stat);
164 switch (stat & 0xff) { 169 switch (stat & 0xff) {
165 case 0x13:
166 qla2x00_process_response_queue(ha);
167 break;
168 case 0x1: 170 case 0x1:
169 case 0x2: 171 case 0x2:
170 case 0x10: 172 case 0x10:
171 case 0x11: 173 case 0x11:
172 qla2x00_mbx_completion(ha, (uint16_t)mbx); 174 qla2x00_mbx_completion(ha, MSW(stat));
173 status |= MBX_INTERRUPT; 175 status |= MBX_INTERRUPT;
174 176
175 /* Release mailbox registers. */ 177 /* Release mailbox registers. */
176 WRT_REG_WORD(&reg->semaphore, 0); 178 WRT_REG_WORD(&reg->semaphore, 0);
177 break; 179 break;
178 case 0x12: 180 case 0x12:
179 qla2x00_async_event(ha, mbx); 181 mb[0] = MSW(stat);
182 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
183 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
184 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
185 qla2x00_async_event(ha, mb);
186 break;
187 case 0x13:
188 qla2x00_process_response_queue(ha);
180 break; 189 break;
181 case 0x15: 190 case 0x15:
182 mbx = mbx << 16 | MBA_CMPLT_1_16BIT; 191 mb[0] = MBA_CMPLT_1_16BIT;
183 qla2x00_async_event(ha, mbx); 192 mb[1] = MSW(stat);
193 qla2x00_async_event(ha, mb);
184 break; 194 break;
185 case 0x16: 195 case 0x16:
186 mbx = mbx << 16 | MBA_SCSI_COMPLETION; 196 mb[0] = MBA_SCSI_COMPLETION;
187 qla2x00_async_event(ha, mbx); 197 mb[1] = MSW(stat);
198 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
199 qla2x00_async_event(ha, mb);
188 break; 200 break;
189 default: 201 default:
190 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " 202 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
191 "(%d)\n", 203 "(%d).\n",
192 ha->host_no, stat & 0xff)); 204 ha->host_no, stat & 0xff));
193 break; 205 break;
194 } 206 }
@@ -250,14 +262,14 @@ qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
250/** 262/**
251 * qla2x00_async_event() - Process aynchronous events. 263 * qla2x00_async_event() - Process aynchronous events.
252 * @ha: SCSI driver HA context 264 * @ha: SCSI driver HA context
253 * @mb0: Mailbox0 register 265 * @mb: Mailbox registers (0 - 3)
254 */ 266 */
255static void 267static void
256qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx) 268qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
257{ 269{
258 static char *link_speeds[5] = { "1", "2", "4", "?", "10" }; 270#define LS_UNKNOWN 2
271 static char *link_speeds[5] = { "1", "2", "?", "4", "10" };
259 char *link_speed; 272 char *link_speed;
260 uint16_t mb[4];
261 uint16_t handle_cnt; 273 uint16_t handle_cnt;
262 uint16_t cnt; 274 uint16_t cnt;
263 uint32_t handles[5]; 275 uint32_t handles[5];
@@ -267,61 +279,48 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
267 279
268 /* Setup to process RIO completion. */ 280 /* Setup to process RIO completion. */
269 handle_cnt = 0; 281 handle_cnt = 0;
270 mb[0] = LSW(mbx);
271 switch (mb[0]) { 282 switch (mb[0]) {
272 case MBA_SCSI_COMPLETION: 283 case MBA_SCSI_COMPLETION:
273 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 284 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
274 handles[0] = le32_to_cpu(
275 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
276 RD_MAILBOX_REG(ha, reg, 1));
277 else
278 handles[0] = le32_to_cpu(
279 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
280 MSW(mbx));
281 handle_cnt = 1; 285 handle_cnt = 1;
282 break; 286 break;
283 case MBA_CMPLT_1_16BIT: 287 case MBA_CMPLT_1_16BIT:
284 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 288 handles[0] = mb[1];
285 handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
286 else
287 handles[0] = MSW(mbx);
288 handle_cnt = 1; 289 handle_cnt = 1;
289 mb[0] = MBA_SCSI_COMPLETION; 290 mb[0] = MBA_SCSI_COMPLETION;
290 break; 291 break;
291 case MBA_CMPLT_2_16BIT: 292 case MBA_CMPLT_2_16BIT:
292 handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1); 293 handles[0] = mb[1];
293 handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2); 294 handles[1] = mb[2];
294 handle_cnt = 2; 295 handle_cnt = 2;
295 mb[0] = MBA_SCSI_COMPLETION; 296 mb[0] = MBA_SCSI_COMPLETION;
296 break; 297 break;
297 case MBA_CMPLT_3_16BIT: 298 case MBA_CMPLT_3_16BIT:
298 handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1); 299 handles[0] = mb[1];
299 handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2); 300 handles[1] = mb[2];
300 handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3); 301 handles[2] = mb[3];
301 handle_cnt = 3; 302 handle_cnt = 3;
302 mb[0] = MBA_SCSI_COMPLETION; 303 mb[0] = MBA_SCSI_COMPLETION;
303 break; 304 break;
304 case MBA_CMPLT_4_16BIT: 305 case MBA_CMPLT_4_16BIT:
305 handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1); 306 handles[0] = mb[1];
306 handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2); 307 handles[1] = mb[2];
307 handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3); 308 handles[2] = mb[3];
308 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6); 309 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
309 handle_cnt = 4; 310 handle_cnt = 4;
310 mb[0] = MBA_SCSI_COMPLETION; 311 mb[0] = MBA_SCSI_COMPLETION;
311 break; 312 break;
312 case MBA_CMPLT_5_16BIT: 313 case MBA_CMPLT_5_16BIT:
313 handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1); 314 handles[0] = mb[1];
314 handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2); 315 handles[1] = mb[2];
315 handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3); 316 handles[2] = mb[3];
316 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6); 317 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
317 handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7); 318 handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
318 handle_cnt = 5; 319 handle_cnt = 5;
319 mb[0] = MBA_SCSI_COMPLETION; 320 mb[0] = MBA_SCSI_COMPLETION;
320 break; 321 break;
321 case MBA_CMPLT_2_32BIT: 322 case MBA_CMPLT_2_32BIT:
322 handles[0] = le32_to_cpu( 323 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
323 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
324 RD_MAILBOX_REG(ha, reg, 1));
325 handles[1] = le32_to_cpu( 324 handles[1] = le32_to_cpu(
326 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) | 325 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
327 RD_MAILBOX_REG(ha, reg, 6)); 326 RD_MAILBOX_REG(ha, reg, 6));
@@ -358,7 +357,15 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
358 357
359 ha->isp_ops.fw_dump(ha, 1); 358 ha->isp_ops.fw_dump(ha, 1);
360 359
361 if (mb[1] == 0) { 360 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
361 if (mb[1] == 0 && mb[2] == 0) {
362 qla_printk(KERN_ERR, ha,
363 "Unrecoverable Hardware Error: adapter "
364 "marked OFFLINE!\n");
365 ha->flags.online = 0;
366 } else
367 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
368 } else if (mb[1] == 0) {
362 qla_printk(KERN_INFO, ha, 369 qla_printk(KERN_INFO, ha,
363 "Unrecoverable Hardware Error: adapter marked " 370 "Unrecoverable Hardware Error: adapter marked "
364 "OFFLINE!\n"); 371 "OFFLINE!\n");
@@ -389,8 +396,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
389 break; 396 break;
390 397
391 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ 398 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
392 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
393
394 DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no, 399 DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
395 mb[1])); 400 mb[1]));
396 qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]); 401 qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
@@ -411,13 +416,11 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
411 break; 416 break;
412 417
413 case MBA_LOOP_UP: /* Loop Up Event */ 418 case MBA_LOOP_UP: /* Loop Up Event */
414 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
415
416 ha->link_data_rate = 0; 419 ha->link_data_rate = 0;
417 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 420 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
418 link_speed = link_speeds[0]; 421 link_speed = link_speeds[0];
419 } else { 422 } else {
420 link_speed = link_speeds[3]; 423 link_speed = link_speeds[LS_UNKNOWN];
421 if (mb[1] < 5) 424 if (mb[1] < 5)
422 link_speed = link_speeds[mb[1]]; 425 link_speed = link_speeds[mb[1]];
423 ha->link_data_rate = mb[1]; 426 ha->link_data_rate = mb[1];
@@ -435,9 +438,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
435 break; 438 break;
436 439
437 case MBA_LOOP_DOWN: /* Loop Down Event */ 440 case MBA_LOOP_DOWN: /* Loop Down Event */
438 DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN.\n", 441 DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n",
439 ha->host_no)); 442 ha->host_no, mb[1]));
440 qla_printk(KERN_INFO, ha, "LOOP DOWN detected.\n"); 443 qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]);
441 444
442 if (atomic_read(&ha->loop_state) != LOOP_DOWN) { 445 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
443 atomic_set(&ha->loop_state, LOOP_DOWN); 446 atomic_set(&ha->loop_state, LOOP_DOWN);
@@ -454,8 +457,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
454 break; 457 break;
455 458
456 case MBA_LIP_RESET: /* LIP reset occurred */ 459 case MBA_LIP_RESET: /* LIP reset occurred */
457 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
458
459 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n", 460 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
460 ha->host_no, mb[1])); 461 ha->host_no, mb[1]));
461 qla_printk(KERN_INFO, ha, 462 qla_printk(KERN_INFO, ha,
@@ -506,8 +507,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
506 if (IS_QLA2100(ha)) 507 if (IS_QLA2100(ha))
507 break; 508 break;
508 509
509 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
510
511 DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection " 510 DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
512 "received.\n", 511 "received.\n",
513 ha->host_no)); 512 ha->host_no));
@@ -527,16 +526,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
527 break; 526 break;
528 527
529 case MBA_PORT_UPDATE: /* Port database update */ 528 case MBA_PORT_UPDATE: /* Port database update */
530 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
531 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
532
533 /* 529 /*
534 * If a single remote port just logged into (or logged out of) 530 * If a single remote port just logged into (or logged out of)
535 * us, create a new entry in our rscn fcports list and handle 531 * us, create a new entry in our rscn fcports list and handle
536 * the event like an RSCN. 532 * the event like an RSCN.
537 */ 533 */
538 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) && 534 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
539 !IS_QLA6322(ha) && ha->flags.init_done && mb[1] != 0xffff && 535 !IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
536 ha->flags.init_done && mb[1] != 0xffff &&
540 ((ha->operating_mode == P2P && mb[1] != 0) || 537 ((ha->operating_mode == P2P && mb[1] != 0) ||
541 (ha->operating_mode != P2P && mb[1] != 538 (ha->operating_mode != P2P && mb[1] !=
542 SNS_FIRST_LOOP_ID)) && (mb[2] == 6 || mb[2] == 7)) { 539 SNS_FIRST_LOOP_ID)) && (mb[2] == 6 || mb[2] == 7)) {
@@ -547,8 +544,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
547 rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC); 544 rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC);
548 if (rscn_fcport) { 545 if (rscn_fcport) {
549 DEBUG14(printk("scsi(%ld): Port Update -- " 546 DEBUG14(printk("scsi(%ld): Port Update -- "
550 "creating RSCN fcport %p for %x/%x.\n", 547 "creating RSCN fcport %p for %x/%x/%x.\n",
551 ha->host_no, rscn_fcport, mb[1], mb[2])); 548 ha->host_no, rscn_fcport, mb[1], mb[2],
549 mb[3]));
552 550
553 rscn_fcport->loop_id = mb[1]; 551 rscn_fcport->loop_id = mb[1];
554 rscn_fcport->d_id.b24 = INVALID_PORT_ID; 552 rscn_fcport->d_id.b24 = INVALID_PORT_ID;
@@ -577,15 +575,16 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
577 if (atomic_read(&ha->loop_state) != LOOP_DOWN && 575 if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
578 atomic_read(&ha->loop_state) != LOOP_DEAD) { 576 atomic_read(&ha->loop_state) != LOOP_DEAD) {
579 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE " 577 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
580 "ignored.\n", ha->host_no)); 578 "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
579 mb[2], mb[3]));
581 break; 580 break;
582 } 581 }
583 582
584 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n", 583 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
585 ha->host_no)); 584 ha->host_no));
586 DEBUG(printk(KERN_INFO 585 DEBUG(printk(KERN_INFO
587 "scsi(%ld): Port database changed %04x %04x.\n", 586 "scsi(%ld): Port database changed %04x %04x %04x.\n",
588 ha->host_no, mb[1], mb[2])); 587 ha->host_no, mb[1], mb[2], mb[3]));
589 588
590 /* 589 /*
591 * Mark all devices as missing so we will login again. 590 * Mark all devices as missing so we will login again.
@@ -604,9 +603,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
604 break; 603 break;
605 604
606 case MBA_RSCN_UPDATE: /* State Change Registration */ 605 case MBA_RSCN_UPDATE: /* State Change Registration */
607 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
608 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
609
610 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", 606 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
611 ha->host_no)); 607 ha->host_no));
612 DEBUG(printk(KERN_INFO 608 DEBUG(printk(KERN_INFO
@@ -655,6 +651,11 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
655 651
656 qla2x00_process_response_queue(ha); 652 qla2x00_process_response_queue(ha);
657 break; 653 break;
654
655 case MBA_DISCARD_RND_FRAME:
656 DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
657 "%04x.\n", ha->host_no, mb[1], mb[2], mb[3]));
658 break;
658 } 659 }
659} 660}
660 661
@@ -801,31 +802,41 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
801 * @pkt: Entry pointer 802 * @pkt: Entry pointer
802 */ 803 */
803static void 804static void
804qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) 805qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
805{ 806{
806 unsigned b, t, l;
807 srb_t *sp; 807 srb_t *sp;
808 fc_port_t *fcport; 808 fc_port_t *fcport;
809 struct scsi_cmnd *cp; 809 struct scsi_cmnd *cp;
810 sts_entry_t *sts;
811 struct sts_entry_24xx *sts24;
810 uint16_t comp_status; 812 uint16_t comp_status;
811 uint16_t scsi_status; 813 uint16_t scsi_status;
812 uint8_t lscsi_status; 814 uint8_t lscsi_status;
813 int32_t resid; 815 int32_t resid;
814 uint8_t sense_sz = 0; 816 uint32_t sense_len, rsp_info_len, resid_len;
815 uint16_t rsp_info_len; 817 uint8_t *rsp_info, *sense_data;
818
819 sts = (sts_entry_t *) pkt;
820 sts24 = (struct sts_entry_24xx *) pkt;
821 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
822 comp_status = le16_to_cpu(sts24->comp_status);
823 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
824 } else {
825 comp_status = le16_to_cpu(sts->comp_status);
826 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
827 }
816 828
817 /* Fast path completion. */ 829 /* Fast path completion. */
818 if (le16_to_cpu(pkt->comp_status) == CS_COMPLETE && 830 if (comp_status == CS_COMPLETE && scsi_status == 0) {
819 (le16_to_cpu(pkt->scsi_status) & SS_MASK) == 0) { 831 qla2x00_process_completed_request(ha, sts->handle);
820 qla2x00_process_completed_request(ha, pkt->handle);
821 832
822 return; 833 return;
823 } 834 }
824 835
825 /* Validate handle. */ 836 /* Validate handle. */
826 if (pkt->handle < MAX_OUTSTANDING_COMMANDS) { 837 if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
827 sp = ha->outstanding_cmds[pkt->handle]; 838 sp = ha->outstanding_cmds[sts->handle];
828 ha->outstanding_cmds[pkt->handle] = NULL; 839 ha->outstanding_cmds[sts->handle] = NULL;
829 } else 840 } else
830 sp = NULL; 841 sp = NULL;
831 842
@@ -844,40 +855,49 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
844 if (cp == NULL) { 855 if (cp == NULL) {
845 DEBUG2(printk("scsi(%ld): Command already returned back to OS " 856 DEBUG2(printk("scsi(%ld): Command already returned back to OS "
846 "pkt->handle=%d sp=%p sp->state:%d\n", 857 "pkt->handle=%d sp=%p sp->state:%d\n",
847 ha->host_no, pkt->handle, sp, sp->state)); 858 ha->host_no, sts->handle, sp, sp->state));
848 qla_printk(KERN_WARNING, ha, 859 qla_printk(KERN_WARNING, ha,
849 "Command is NULL: already returned to OS (sp=%p)\n", sp); 860 "Command is NULL: already returned to OS (sp=%p)\n", sp);
850 861
851 return; 862 return;
852 } 863 }
853 864
854 comp_status = le16_to_cpu(pkt->comp_status); 865 lscsi_status = scsi_status & STATUS_MASK;
855 /* Mask of reserved bits 12-15, before we examine the scsi status */ 866 CMD_ENTRY_STATUS(cp) = sts->entry_status;
856 scsi_status = le16_to_cpu(pkt->scsi_status) & SS_MASK;
857 lscsi_status = scsi_status & STATUS_MASK;
858
859 CMD_ENTRY_STATUS(cp) = pkt->entry_status;
860 CMD_COMPL_STATUS(cp) = comp_status; 867 CMD_COMPL_STATUS(cp) = comp_status;
861 CMD_SCSI_STATUS(cp) = scsi_status; 868 CMD_SCSI_STATUS(cp) = scsi_status;
862 869
863 /* Generate LU queue on cntrl, target, LUN */
864 b = cp->device->channel;
865 t = cp->device->id;
866 l = cp->device->lun,
867
868 fcport = sp->fcport; 870 fcport = sp->fcport;
869 871
872 sense_len = rsp_info_len = resid_len = 0;
873 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
874 sense_len = le32_to_cpu(sts24->sense_len);
875 rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
876 resid_len = le32_to_cpu(sts24->rsp_residual_count);
877 rsp_info = sts24->data;
878 sense_data = sts24->data;
879 host_to_fcp_swap(sts24->data, sizeof(sts24->data));
880 } else {
881 sense_len = le16_to_cpu(sts->req_sense_length);
882 rsp_info_len = le16_to_cpu(sts->rsp_info_len);
883 resid_len = le32_to_cpu(sts->residual_length);
884 rsp_info = sts->rsp_info;
885 sense_data = sts->req_sense_data;
886 }
887
870 /* Check for any FCP transport errors. */ 888 /* Check for any FCP transport errors. */
871 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) { 889 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
872 rsp_info_len = le16_to_cpu(pkt->rsp_info_len); 890 /* Sense data lies beyond any FCP RESPONSE data. */
873 if (rsp_info_len > 3 && pkt->rsp_info[3]) { 891 if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
892 sense_data += rsp_info_len;
893 if (rsp_info_len > 3 && rsp_info[3]) {
874 DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol " 894 DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
875 "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..." 895 "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
876 "retrying command\n", ha->host_no, b, t, l, 896 "retrying command\n", ha->host_no,
877 rsp_info_len, pkt->rsp_info[0], pkt->rsp_info[1], 897 cp->device->channel, cp->device->id,
878 pkt->rsp_info[2], pkt->rsp_info[3], 898 cp->device->lun, rsp_info_len, rsp_info[0],
879 pkt->rsp_info[4], pkt->rsp_info[5], 899 rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
880 pkt->rsp_info[6], pkt->rsp_info[7])); 900 rsp_info[5], rsp_info[6], rsp_info[7]));
881 901
882 cp->result = DID_BUS_BUSY << 16; 902 cp->result = DID_BUS_BUSY << 16;
883 qla2x00_sp_compl(ha, sp); 903 qla2x00_sp_compl(ha, sp);
@@ -895,7 +915,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
895 break; 915 break;
896 } 916 }
897 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) { 917 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
898 resid = le32_to_cpu(pkt->residual_length); 918 resid = resid_len;
899 cp->resid = resid; 919 cp->resid = resid;
900 CMD_RESID_LEN(cp) = resid; 920 CMD_RESID_LEN(cp) = resid;
901 } 921 }
@@ -904,39 +924,34 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
904 if (lscsi_status != SS_CHECK_CONDITION) 924 if (lscsi_status != SS_CHECK_CONDITION)
905 break; 925 break;
906 926
907 /* 927 /* Copy Sense Data into sense buffer. */
908 * Copy Sense Data into sense buffer
909 */
910 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer)); 928 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
911 929
912 if (!(scsi_status & SS_SENSE_LEN_VALID)) 930 if (!(scsi_status & SS_SENSE_LEN_VALID))
913 break; 931 break;
914 932
915 if (le16_to_cpu(pkt->req_sense_length) < 933 if (sense_len >= sizeof(cp->sense_buffer))
916 sizeof(cp->sense_buffer)) 934 sense_len = sizeof(cp->sense_buffer);
917 sense_sz = le16_to_cpu(pkt->req_sense_length);
918 else
919 sense_sz = sizeof(cp->sense_buffer);
920 935
921 CMD_ACTUAL_SNSLEN(cp) = sense_sz; 936 CMD_ACTUAL_SNSLEN(cp) = sense_len;
922 sp->request_sense_length = sense_sz; 937 sp->request_sense_length = sense_len;
923 sp->request_sense_ptr = cp->sense_buffer; 938 sp->request_sense_ptr = cp->sense_buffer;
924 939
925 if (sp->request_sense_length > 32) 940 if (sp->request_sense_length > 32)
926 sense_sz = 32; 941 sense_len = 32;
927 942
928 memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz); 943 memcpy(cp->sense_buffer, sense_data, sense_len);
929 944
930 sp->request_sense_ptr += sense_sz; 945 sp->request_sense_ptr += sense_len;
931 sp->request_sense_length -= sense_sz; 946 sp->request_sense_length -= sense_len;
932 if (sp->request_sense_length != 0) 947 if (sp->request_sense_length != 0)
933 ha->status_srb = sp; 948 ha->status_srb = sp;
934 949
935 DEBUG5(printk("%s(): Check condition Sense data, " 950 DEBUG5(printk("%s(): Check condition Sense data, "
936 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", 951 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", __func__,
937 __func__, ha->host_no, b, t, l, cp, 952 ha->host_no, cp->device->channel, cp->device->id,
938 cp->serial_number)); 953 cp->device->lun, cp, cp->serial_number));
939 if (sense_sz) 954 if (sense_len)
940 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, 955 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
941 CMD_ACTUAL_SNSLEN(cp))); 956 CMD_ACTUAL_SNSLEN(cp)));
942 break; 957 break;
@@ -944,9 +959,10 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
944 case CS_DATA_UNDERRUN: 959 case CS_DATA_UNDERRUN:
945 DEBUG2(printk(KERN_INFO 960 DEBUG2(printk(KERN_INFO
946 "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n", 961 "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n",
947 ha->host_no, t, l, comp_status, scsi_status)); 962 ha->host_no, cp->device->id, cp->device->lun, comp_status,
963 scsi_status));
948 964
949 resid = le32_to_cpu(pkt->residual_length); 965 resid = resid_len;
950 if (scsi_status & SS_RESIDUAL_UNDER) { 966 if (scsi_status & SS_RESIDUAL_UNDER) {
951 cp->resid = resid; 967 cp->resid = resid;
952 CMD_RESID_LEN(cp) = resid; 968 CMD_RESID_LEN(cp) = resid;
@@ -968,31 +984,30 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
968 if (!(scsi_status & SS_SENSE_LEN_VALID)) 984 if (!(scsi_status & SS_SENSE_LEN_VALID))
969 break; 985 break;
970 986
971 if (le16_to_cpu(pkt->req_sense_length) < 987 if (sense_len >= sizeof(cp->sense_buffer))
972 sizeof(cp->sense_buffer)) 988 sense_len = sizeof(cp->sense_buffer);
973 sense_sz = le16_to_cpu(pkt->req_sense_length);
974 else
975 sense_sz = sizeof(cp->sense_buffer);
976 989
977 CMD_ACTUAL_SNSLEN(cp) = sense_sz; 990 CMD_ACTUAL_SNSLEN(cp) = sense_len;
978 sp->request_sense_length = sense_sz; 991 sp->request_sense_length = sense_len;
979 sp->request_sense_ptr = cp->sense_buffer; 992 sp->request_sense_ptr = cp->sense_buffer;
980 993
981 if (sp->request_sense_length > 32) 994 if (sp->request_sense_length > 32)
982 sense_sz = 32; 995 sense_len = 32;
983 996
984 memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz); 997 memcpy(cp->sense_buffer, sense_data, sense_len);
985 998
986 sp->request_sense_ptr += sense_sz; 999 sp->request_sense_ptr += sense_len;
987 sp->request_sense_length -= sense_sz; 1000 sp->request_sense_length -= sense_len;
988 if (sp->request_sense_length != 0) 1001 if (sp->request_sense_length != 0)
989 ha->status_srb = sp; 1002 ha->status_srb = sp;
990 1003
991 DEBUG5(printk("%s(): Check condition Sense data, " 1004 DEBUG5(printk("%s(): Check condition Sense data, "
992 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", 1005 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
993 __func__, ha->host_no, b, t, l, cp, 1006 __func__, ha->host_no, cp->device->channel,
1007 cp->device->id, cp->device->lun, cp,
994 cp->serial_number)); 1008 cp->serial_number));
995 if (sense_sz) 1009
1010 if (sense_len)
996 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, 1011 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
997 CMD_ACTUAL_SNSLEN(cp))); 1012 CMD_ACTUAL_SNSLEN(cp)));
998 } else { 1013 } else {
@@ -1004,8 +1019,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1004 if (!(scsi_status & SS_RESIDUAL_UNDER)) { 1019 if (!(scsi_status & SS_RESIDUAL_UNDER)) {
1005 DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped " 1020 DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
1006 "frame(s) detected (%x of %x bytes)..." 1021 "frame(s) detected (%x of %x bytes)..."
1007 "retrying command.\n", 1022 "retrying command.\n", ha->host_no,
1008 ha->host_no, b, t, l, resid, 1023 cp->device->channel, cp->device->id,
1024 cp->device->lun, resid,
1009 cp->request_bufflen)); 1025 cp->request_bufflen));
1010 1026
1011 cp->result = DID_BUS_BUSY << 16; 1027 cp->result = DID_BUS_BUSY << 16;
@@ -1018,8 +1034,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1018 qla_printk(KERN_INFO, ha, 1034 qla_printk(KERN_INFO, ha,
1019 "scsi(%ld:%d:%d:%d): Mid-layer underflow " 1035 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1020 "detected (%x of %x bytes)...returning " 1036 "detected (%x of %x bytes)...returning "
1021 "error status.\n", 1037 "error status.\n", ha->host_no,
1022 ha->host_no, b, t, l, resid, 1038 cp->device->channel, cp->device->id,
1039 cp->device->lun, resid,
1023 cp->request_bufflen); 1040 cp->request_bufflen);
1024 1041
1025 cp->result = DID_ERROR << 16; 1042 cp->result = DID_ERROR << 16;
@@ -1034,7 +1051,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1034 case CS_DATA_OVERRUN: 1051 case CS_DATA_OVERRUN:
1035 DEBUG2(printk(KERN_INFO 1052 DEBUG2(printk(KERN_INFO
1036 "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n", 1053 "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
1037 ha->host_no, t, l, comp_status, scsi_status)); 1054 ha->host_no, cp->device->id, cp->device->lun, comp_status,
1055 scsi_status));
1038 DEBUG2(printk(KERN_INFO 1056 DEBUG2(printk(KERN_INFO
1039 "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 1057 "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1040 cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3], 1058 cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
@@ -1042,8 +1060,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1042 DEBUG2(printk(KERN_INFO 1060 DEBUG2(printk(KERN_INFO
1043 "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR " 1061 "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
1044 "status!\n", 1062 "status!\n",
1045 cp->serial_number, cp->request_bufflen, 1063 cp->serial_number, cp->request_bufflen, resid_len));
1046 le32_to_cpu(pkt->residual_length)));
1047 1064
1048 cp->result = DID_ERROR << 16; 1065 cp->result = DID_ERROR << 16;
1049 break; 1066 break;
@@ -1060,7 +1077,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1060 */ 1077 */
1061 DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down " 1078 DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
1062 "pid=%ld, compl status=0x%x, port state=0x%x\n", 1079 "pid=%ld, compl status=0x%x, port state=0x%x\n",
1063 ha->host_no, t, l, cp->serial_number, comp_status, 1080 ha->host_no, cp->device->id, cp->device->lun,
1081 cp->serial_number, comp_status,
1064 atomic_read(&fcport->state))); 1082 atomic_read(&fcport->state)));
1065 1083
1066 cp->result = DID_BUS_BUSY << 16; 1084 cp->result = DID_BUS_BUSY << 16;
@@ -1091,17 +1109,25 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1091 break; 1109 break;
1092 1110
1093 case CS_TIMEOUT: 1111 case CS_TIMEOUT:
1112 cp->result = DID_BUS_BUSY << 16;
1113
1114 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
1115 DEBUG2(printk(KERN_INFO
1116 "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
1117 "0x%x-0x%x\n", ha->host_no, cp->device->channel,
1118 cp->device->id, cp->device->lun, comp_status,
1119 scsi_status));
1120 break;
1121 }
1094 DEBUG2(printk(KERN_INFO 1122 DEBUG2(printk(KERN_INFO
1095 "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x " 1123 "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
1096 "sflags=%x.\n", ha->host_no, b, t, l, comp_status, 1124 "sflags=%x.\n", ha->host_no, cp->device->channel,
1097 scsi_status, le16_to_cpu(pkt->status_flags))); 1125 cp->device->id, cp->device->lun, comp_status, scsi_status,
1098 1126 le16_to_cpu(sts->status_flags)));
1099 cp->result = DID_BUS_BUSY << 16;
1100 1127
1101 /* Check to see if logout occurred */ 1128 /* Check to see if logout occurred. */
1102 if ((le16_to_cpu(pkt->status_flags) & SF_LOGOUT_SENT)) { 1129 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
1103 qla2x00_mark_device_lost(ha, fcport, 1); 1130 qla2x00_mark_device_lost(ha, fcport, 1);
1104 }
1105 break; 1131 break;
1106 1132
1107 case CS_QUEUE_FULL: 1133 case CS_QUEUE_FULL:
@@ -1117,8 +1143,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1117 1143
1118 default: 1144 default:
1119 DEBUG3(printk("scsi(%ld): Error detected (unknown status) " 1145 DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
1120 "0x%x-0x%x.\n", 1146 "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
1121 ha->host_no, comp_status, scsi_status));
1122 qla_printk(KERN_INFO, ha, 1147 qla_printk(KERN_INFO, ha,
1123 "Unknown status detected 0x%x-0x%x.\n", 1148 "Unknown status detected 0x%x-0x%x.\n",
1124 comp_status, scsi_status); 1149 comp_status, scsi_status);
@@ -1166,6 +1191,8 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
1166 } 1191 }
1167 1192
1168 /* Move sense data. */ 1193 /* Move sense data. */
1194 if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
1195 host_to_fcp_swap(pkt->data, sizeof(pkt->data));
1169 memcpy(sp->request_sense_ptr, pkt->data, sense_sz); 1196 memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
1170 DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz)); 1197 DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
1171 1198
@@ -1186,7 +1213,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
1186 * @pkt: Entry pointer 1213 * @pkt: Entry pointer
1187 */ 1214 */
1188static void 1215static void
1189qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) 1216qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1190{ 1217{
1191 srb_t *sp; 1218 srb_t *sp;
1192 1219
@@ -1228,15 +1255,15 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1228 } 1255 }
1229 qla2x00_sp_compl(ha, sp); 1256 qla2x00_sp_compl(ha, sp);
1230 1257
1231 } else if (pkt->entry_type == COMMAND_A64_TYPE || 1258 } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
1232 pkt->entry_type == COMMAND_TYPE) { 1259 COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
1233 DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n", 1260 DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
1234 ha->host_no)); 1261 ha->host_no));
1235 qla_printk(KERN_WARNING, ha, 1262 qla_printk(KERN_WARNING, ha,
1236 "Error entry - invalid handle\n"); 1263 "Error entry - invalid handle\n");
1237 1264
1238 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 1265 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1239 if (ha->dpc_wait && !ha->dpc_active) 1266 if (ha->dpc_wait && !ha->dpc_active)
1240 up(ha->dpc_wait); 1267 up(ha->dpc_wait);
1241 } 1268 }
1242} 1269}
@@ -1247,7 +1274,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1247 * @index: Response queue out pointer 1274 * @index: Response queue out pointer
1248 */ 1275 */
1249static void 1276static void
1250qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) 1277qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
1251{ 1278{
1252 srb_t *sp; 1279 srb_t *sp;
1253 1280
@@ -1277,3 +1304,230 @@ qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
1277 1304
1278 qla2x00_sp_compl(ha, sp); 1305 qla2x00_sp_compl(ha, sp);
1279} 1306}
1307
1308
1309/**
1310 * qla24xx_mbx_completion() - Process mailbox command completions.
1311 * @ha: SCSI driver HA context
1312 * @mb0: Mailbox0 register
1313 */
1314static void
1315qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
1316{
1317 uint16_t cnt;
1318 uint16_t __iomem *wptr;
1319 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1320
1321 /* Load return mailbox registers. */
1322 ha->flags.mbox_int = 1;
1323 ha->mailbox_out[0] = mb0;
1324 wptr = (uint16_t __iomem *)&reg->mailbox1;
1325
1326 for (cnt = 1; cnt < ha->mbx_count; cnt++) {
1327 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
1328 wptr++;
1329 }
1330
1331 if (ha->mcp) {
1332 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
1333 __func__, ha->host_no, ha->mcp->mb[0]));
1334 } else {
1335 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
1336 __func__, ha->host_no));
1337 }
1338}
1339
1340/**
1341 * qla24xx_process_response_queue() - Process response queue entries.
1342 * @ha: SCSI driver HA context
1343 */
1344void
1345qla24xx_process_response_queue(struct scsi_qla_host *ha)
1346{
1347 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1348 struct sts_entry_24xx *pkt;
1349
1350 if (!ha->flags.online)
1351 return;
1352
1353 while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
1354 pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
1355
1356 ha->rsp_ring_index++;
1357 if (ha->rsp_ring_index == ha->response_q_length) {
1358 ha->rsp_ring_index = 0;
1359 ha->response_ring_ptr = ha->response_ring;
1360 } else {
1361 ha->response_ring_ptr++;
1362 }
1363
1364 if (pkt->entry_status != 0) {
1365 DEBUG3(printk(KERN_INFO
1366 "scsi(%ld): Process error entry.\n", ha->host_no));
1367
1368 //FIXME
1369 qla2x00_error_entry(ha, (sts_entry_t *) pkt);
1370 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1371 wmb();
1372 continue;
1373 }
1374
1375 switch (pkt->entry_type) {
1376 case STATUS_TYPE:
1377 qla2x00_status_entry(ha, pkt);
1378 break;
1379 case STATUS_CONT_TYPE:
1380 qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
1381 break;
1382 case MS_IOCB_TYPE:
1383 qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
1384 break;
1385 default:
1386 /* Type Not Supported. */
1387 DEBUG4(printk(KERN_WARNING
1388 "scsi(%ld): Received unknown response pkt type %x "
1389 "entry status=%x.\n",
1390 ha->host_no, pkt->entry_type, pkt->entry_status));
1391 break;
1392 }
1393 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1394 wmb();
1395 }
1396
1397 /* Adjust ring index */
1398 WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);
1399}
1400
1401/**
1402 * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
1403 * @irq:
1404 * @dev_id: SCSI driver HA context
1405 * @regs:
1406 *
1407 * Called by system whenever the host adapter generates an interrupt.
1408 *
1409 * Returns handled flag.
1410 */
1411irqreturn_t
1412qla24xx_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
1413{
1414 scsi_qla_host_t *ha;
1415 struct device_reg_24xx __iomem *reg;
1416 int status;
1417 unsigned long flags;
1418 unsigned long iter;
1419 uint32_t stat;
1420 uint32_t hccr;
1421 uint16_t mb[4];
1422
1423 ha = (scsi_qla_host_t *) dev_id;
1424 if (!ha) {
1425 printk(KERN_INFO
1426 "%s(): NULL host pointer\n", __func__);
1427 return IRQ_NONE;
1428 }
1429
1430 reg = &ha->iobase->isp24;
1431 status = 0;
1432
1433 spin_lock_irqsave(&ha->hardware_lock, flags);
1434 for (iter = 50; iter--; ) {
1435 stat = RD_REG_DWORD(&reg->host_status);
1436 if (stat & HSRX_RISC_PAUSED) {
1437 hccr = RD_REG_DWORD(&reg->hccr);
1438
1439 qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1440 "Dumping firmware!\n", hccr);
1441 qla24xx_fw_dump(ha, 1);
1442
1443 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1444 break;
1445 } else if ((stat & HSRX_RISC_INT) == 0)
1446 break;
1447
1448 switch (stat & 0xff) {
1449 case 0x1:
1450 case 0x2:
1451 case 0x10:
1452 case 0x11:
1453 qla24xx_mbx_completion(ha, MSW(stat));
1454 status |= MBX_INTERRUPT;
1455
1456 break;
1457 case 0x12:
1458 mb[0] = MSW(stat);
1459 mb[1] = RD_REG_WORD(&reg->mailbox1);
1460 mb[2] = RD_REG_WORD(&reg->mailbox2);
1461 mb[3] = RD_REG_WORD(&reg->mailbox3);
1462 qla2x00_async_event(ha, mb);
1463 break;
1464 case 0x13:
1465 qla24xx_process_response_queue(ha);
1466 break;
1467 default:
1468 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1469 "(%d).\n",
1470 ha->host_no, stat & 0xff));
1471 break;
1472 }
1473 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1474 RD_REG_DWORD_RELAXED(&reg->hccr);
1475 }
1476 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1477
1478 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
1479 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1480 spin_lock_irqsave(&ha->mbx_reg_lock, flags);
1481
1482 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1483 up(&ha->mbx_intr_sem);
1484
1485 spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
1486 }
1487
1488 return IRQ_HANDLED;
1489}
1490
1491/**
1492 * qla24xx_ms_entry() - Process a Management Server entry.
1493 * @ha: SCSI driver HA context
1494 * @index: Response queue out pointer
1495 */
1496static void
1497qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
1498{
1499 srb_t *sp;
1500
1501 DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1502 __func__, ha->host_no, pkt, pkt->handle));
1503
1504 DEBUG9(printk("%s: ct pkt dump:\n", __func__);)
1505 DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));)
1506
1507 /* Validate handle. */
1508 if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1509 sp = ha->outstanding_cmds[pkt->handle];
1510 else
1511 sp = NULL;
1512
1513 if (sp == NULL) {
1514 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1515 ha->host_no));
1516 DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
1517 ha->host_no));
1518 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
1519 pkt->handle);
1520
1521 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1522 return;
1523 }
1524
1525 CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
1526 CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1527
1528 /* Free outstanding command slot. */
1529 ha->outstanding_cmds[pkt->handle] = NULL;
1530
1531 qla2x00_sp_compl(ha, sp);
1532}
1533