[SCSI] qla2xxx: Add PCI error recovery support.
[linux-2.6-block.git] / drivers / scsi / qla2xxx / qla_isr.c
CommitLineData
1da177e4 1/*
fa90c54f
AV
2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2005 QLogic Corporation
1da177e4 4 *
fa90c54f 5 * See LICENSE.qla2xxx for copyright and licensing details.
1da177e4
LT
6 */
7#include "qla_def.h"
8
df7baa50
AV
9#include <scsi/scsi_tcq.h>
10
1da177e4 11static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
1da177e4 12static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
9a853f71 13static void qla2x00_status_entry(scsi_qla_host_t *, void *);
1da177e4
LT
14static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
15static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
16static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
17
9a853f71
AV
18static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
19
1da177e4
LT
20/**
21 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
22 * @irq:
23 * @dev_id: SCSI driver HA context
1da177e4
LT
24 *
25 * Called by system whenever the host adapter generates an interrupt.
26 *
27 * Returns handled flag.
28 */
29irqreturn_t
7d12e780 30qla2100_intr_handler(int irq, void *dev_id)
1da177e4
LT
31{
32 scsi_qla_host_t *ha;
3d71644c 33 struct device_reg_2xxx __iomem *reg;
1da177e4
LT
34 int status;
35 unsigned long flags;
36 unsigned long iter;
14e660e6 37 uint16_t hccr;
9a853f71 38 uint16_t mb[4];
1da177e4
LT
39
40 ha = (scsi_qla_host_t *) dev_id;
41 if (!ha) {
42 printk(KERN_INFO
43 "%s(): NULL host pointer\n", __func__);
44 return (IRQ_NONE);
45 }
46
3d71644c 47 reg = &ha->iobase->isp;
1da177e4
LT
48 status = 0;
49
50 spin_lock_irqsave(&ha->hardware_lock, flags);
51 for (iter = 50; iter--; ) {
14e660e6
SJ
52 hccr = RD_REG_WORD(&reg->hccr);
53 if (hccr & HCCR_RISC_PAUSE) {
54 if (pci_channel_offline(ha->pdev))
55 break;
56
57 /*
58 * Issue a "HARD" reset in order for the RISC interrupt
59 * bit to be cleared. Schedule a big hammmer to get
60 * out of the RISC PAUSED state.
61 */
62 WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
63 RD_REG_WORD(&reg->hccr);
64
65 ha->isp_ops->fw_dump(ha, 1);
66 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
67 break;
68 } else if ((RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) == 0)
1da177e4
LT
69 break;
70
71 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
72 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
73 RD_REG_WORD(&reg->hccr);
74
75 /* Get mailbox data. */
9a853f71
AV
76 mb[0] = RD_MAILBOX_REG(ha, reg, 0);
77 if (mb[0] > 0x3fff && mb[0] < 0x8000) {
78 qla2x00_mbx_completion(ha, mb[0]);
1da177e4 79 status |= MBX_INTERRUPT;
9a853f71
AV
80 } else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
81 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
82 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
83 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
84 qla2x00_async_event(ha, mb);
1da177e4
LT
85 } else {
86 /*EMPTY*/
87 DEBUG2(printk("scsi(%ld): Unrecognized "
9a853f71
AV
88 "interrupt type (%d).\n",
89 ha->host_no, mb[0]));
1da177e4
LT
90 }
91 /* Release mailbox registers. */
92 WRT_REG_WORD(&reg->semaphore, 0);
93 RD_REG_WORD(&reg->semaphore);
94 } else {
95 qla2x00_process_response_queue(ha);
96
97 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
98 RD_REG_WORD(&reg->hccr);
99 }
100 }
101 spin_unlock_irqrestore(&ha->hardware_lock, flags);
102
1da177e4
LT
103 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
104 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1da177e4
LT
105 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
106 up(&ha->mbx_intr_sem);
1da177e4
LT
107 }
108
1da177e4
LT
109 return (IRQ_HANDLED);
110}
111
112/**
113 * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
114 * @irq:
115 * @dev_id: SCSI driver HA context
1da177e4
LT
116 *
117 * Called by system whenever the host adapter generates an interrupt.
118 *
119 * Returns handled flag.
120 */
121irqreturn_t
7d12e780 122qla2300_intr_handler(int irq, void *dev_id)
1da177e4
LT
123{
124 scsi_qla_host_t *ha;
3d71644c 125 struct device_reg_2xxx __iomem *reg;
1da177e4
LT
126 int status;
127 unsigned long flags;
128 unsigned long iter;
129 uint32_t stat;
1da177e4 130 uint16_t hccr;
9a853f71 131 uint16_t mb[4];
1da177e4
LT
132
133 ha = (scsi_qla_host_t *) dev_id;
134 if (!ha) {
135 printk(KERN_INFO
136 "%s(): NULL host pointer\n", __func__);
137 return (IRQ_NONE);
138 }
139
3d71644c 140 reg = &ha->iobase->isp;
1da177e4
LT
141 status = 0;
142
143 spin_lock_irqsave(&ha->hardware_lock, flags);
144 for (iter = 50; iter--; ) {
145 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
146 if (stat & HSR_RISC_PAUSED) {
14e660e6
SJ
147 if (pci_channel_offline(ha->pdev))
148 break;
149
1da177e4
LT
150 hccr = RD_REG_WORD(&reg->hccr);
151 if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
07f31805
AV
152 qla_printk(KERN_INFO, ha, "Parity error -- "
153 "HCCR=%x, Dumping firmware!\n", hccr);
1da177e4 154 else
07f31805
AV
155 qla_printk(KERN_INFO, ha, "RISC paused -- "
156 "HCCR=%x, Dumping firmware!\n", hccr);
1da177e4
LT
157
158 /*
159 * Issue a "HARD" reset in order for the RISC
160 * interrupt bit to be cleared. Schedule a big
161 * hammmer to get out of the RISC PAUSED state.
162 */
163 WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
164 RD_REG_WORD(&reg->hccr);
07f31805 165
fd34f556 166 ha->isp_ops->fw_dump(ha, 1);
1da177e4
LT
167 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
168 break;
169 } else if ((stat & HSR_RISC_INT) == 0)
170 break;
171
1da177e4 172 switch (stat & 0xff) {
1da177e4
LT
173 case 0x1:
174 case 0x2:
175 case 0x10:
176 case 0x11:
9a853f71 177 qla2x00_mbx_completion(ha, MSW(stat));
1da177e4
LT
178 status |= MBX_INTERRUPT;
179
180 /* Release mailbox registers. */
181 WRT_REG_WORD(&reg->semaphore, 0);
182 break;
183 case 0x12:
9a853f71
AV
184 mb[0] = MSW(stat);
185 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
186 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
187 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
188 qla2x00_async_event(ha, mb);
189 break;
190 case 0x13:
191 qla2x00_process_response_queue(ha);
1da177e4
LT
192 break;
193 case 0x15:
9a853f71
AV
194 mb[0] = MBA_CMPLT_1_16BIT;
195 mb[1] = MSW(stat);
196 qla2x00_async_event(ha, mb);
1da177e4
LT
197 break;
198 case 0x16:
9a853f71
AV
199 mb[0] = MBA_SCSI_COMPLETION;
200 mb[1] = MSW(stat);
201 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
202 qla2x00_async_event(ha, mb);
1da177e4
LT
203 break;
204 default:
205 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
9a853f71 206 "(%d).\n",
1da177e4
LT
207 ha->host_no, stat & 0xff));
208 break;
209 }
210 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
211 RD_REG_WORD_RELAXED(&reg->hccr);
212 }
213 spin_unlock_irqrestore(&ha->hardware_lock, flags);
214
1da177e4
LT
215 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
216 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1da177e4
LT
217 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
218 up(&ha->mbx_intr_sem);
1da177e4
LT
219 }
220
1da177e4
LT
221 return (IRQ_HANDLED);
222}
223
224/**
225 * qla2x00_mbx_completion() - Process mailbox command completions.
226 * @ha: SCSI driver HA context
227 * @mb0: Mailbox0 register
228 */
229static void
230qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
231{
232 uint16_t cnt;
233 uint16_t __iomem *wptr;
3d71644c 234 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1da177e4
LT
235
236 /* Load return mailbox registers. */
237 ha->flags.mbox_int = 1;
238 ha->mailbox_out[0] = mb0;
239 wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1);
240
241 for (cnt = 1; cnt < ha->mbx_count; cnt++) {
fa2a1ce5 242 if (IS_QLA2200(ha) && cnt == 8)
1da177e4
LT
243 wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
244 if (cnt == 4 || cnt == 5)
245 ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr);
246 else
247 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
fa2a1ce5 248
1da177e4
LT
249 wptr++;
250 }
251
252 if (ha->mcp) {
253 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
254 __func__, ha->host_no, ha->mcp->mb[0]));
255 } else {
256 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
257 __func__, ha->host_no));
258 }
259}
260
261/**
262 * qla2x00_async_event() - Process aynchronous events.
263 * @ha: SCSI driver HA context
9a853f71 264 * @mb: Mailbox registers (0 - 3)
1da177e4 265 */
2c3dfe3f 266void
9a853f71 267qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
1da177e4 268{
9a853f71 269#define LS_UNKNOWN 2
c3a2f0df 270 static char *link_speeds[5] = { "1", "2", "?", "4", "8" };
1da177e4 271 char *link_speed;
1da177e4
LT
272 uint16_t handle_cnt;
273 uint16_t cnt;
274 uint32_t handles[5];
3d71644c 275 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1da177e4
LT
276 uint32_t rscn_entry, host_pid;
277 uint8_t rscn_queue_index;
278
279 /* Setup to process RIO completion. */
280 handle_cnt = 0;
1da177e4
LT
281 switch (mb[0]) {
282 case MBA_SCSI_COMPLETION:
9a853f71 283 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
1da177e4
LT
284 handle_cnt = 1;
285 break;
286 case MBA_CMPLT_1_16BIT:
9a853f71 287 handles[0] = mb[1];
1da177e4
LT
288 handle_cnt = 1;
289 mb[0] = MBA_SCSI_COMPLETION;
290 break;
291 case MBA_CMPLT_2_16BIT:
9a853f71
AV
292 handles[0] = mb[1];
293 handles[1] = mb[2];
1da177e4
LT
294 handle_cnt = 2;
295 mb[0] = MBA_SCSI_COMPLETION;
296 break;
297 case MBA_CMPLT_3_16BIT:
9a853f71
AV
298 handles[0] = mb[1];
299 handles[1] = mb[2];
300 handles[2] = mb[3];
1da177e4
LT
301 handle_cnt = 3;
302 mb[0] = MBA_SCSI_COMPLETION;
303 break;
304 case MBA_CMPLT_4_16BIT:
9a853f71
AV
305 handles[0] = mb[1];
306 handles[1] = mb[2];
307 handles[2] = mb[3];
1da177e4
LT
308 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
309 handle_cnt = 4;
310 mb[0] = MBA_SCSI_COMPLETION;
311 break;
312 case MBA_CMPLT_5_16BIT:
9a853f71
AV
313 handles[0] = mb[1];
314 handles[1] = mb[2];
315 handles[2] = mb[3];
1da177e4
LT
316 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
317 handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
318 handle_cnt = 5;
319 mb[0] = MBA_SCSI_COMPLETION;
320 break;
321 case MBA_CMPLT_2_32BIT:
9a853f71 322 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
1da177e4
LT
323 handles[1] = le32_to_cpu(
324 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
325 RD_MAILBOX_REG(ha, reg, 6));
326 handle_cnt = 2;
327 mb[0] = MBA_SCSI_COMPLETION;
328 break;
329 default:
330 break;
331 }
332
333 switch (mb[0]) {
334 case MBA_SCSI_COMPLETION: /* Fast Post */
335 if (!ha->flags.online)
336 break;
337
338 for (cnt = 0; cnt < handle_cnt; cnt++)
339 qla2x00_process_completed_request(ha, handles[cnt]);
340 break;
341
342 case MBA_RESET: /* Reset */
343 DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", ha->host_no));
344
345 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
346 break;
347
348 case MBA_SYSTEM_ERR: /* System Error */
349 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
350 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
351 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
352
353 qla_printk(KERN_INFO, ha,
354 "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
355 mb[1], mb[2], mb[3]);
356
fd34f556 357 ha->isp_ops->fw_dump(ha, 1);
1da177e4 358
e428924c 359 if (IS_FWI2_CAPABLE(ha)) {
9a853f71
AV
360 if (mb[1] == 0 && mb[2] == 0) {
361 qla_printk(KERN_ERR, ha,
362 "Unrecoverable Hardware Error: adapter "
363 "marked OFFLINE!\n");
364 ha->flags.online = 0;
365 } else
366 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
367 } else if (mb[1] == 0) {
1da177e4
LT
368 qla_printk(KERN_INFO, ha,
369 "Unrecoverable Hardware Error: adapter marked "
370 "OFFLINE!\n");
371 ha->flags.online = 0;
372 } else
373 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
374 break;
375
376 case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
377 DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
378 ha->host_no));
379 qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
380
381 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
382 break;
383
384 case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */
385 DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n",
386 ha->host_no));
387 qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
388
389 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
390 break;
391
392 case MBA_WAKEUP_THRES: /* Request Queue Wake-up */
393 DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n",
394 ha->host_no));
395 break;
396
397 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
1da177e4
LT
398 DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
399 mb[1]));
400 qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
401
402 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
403 atomic_set(&ha->loop_state, LOOP_DOWN);
404 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
d97994dc 405 qla2x00_mark_all_devices_lost(ha, 1);
1da177e4
LT
406 }
407
2c3dfe3f
SJ
408 if (ha->parent) {
409 atomic_set(&ha->vp_state, VP_FAILED);
410 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
411 }
412
1da177e4
LT
413 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
414
415 ha->flags.management_server_logged_in = 0;
1da177e4
LT
416 break;
417
418 case MBA_LOOP_UP: /* Loop Up Event */
1da177e4
LT
419 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
420 link_speed = link_speeds[0];
d8b45213 421 ha->link_data_rate = PORT_SPEED_1GB;
1da177e4 422 } else {
9a853f71 423 link_speed = link_speeds[LS_UNKNOWN];
1da177e4
LT
424 if (mb[1] < 5)
425 link_speed = link_speeds[mb[1]];
426 ha->link_data_rate = mb[1];
427 }
428
429 DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n",
430 ha->host_no, link_speed));
431 qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n",
432 link_speed);
433
434 ha->flags.management_server_logged_in = 0;
1da177e4
LT
435 break;
436
437 case MBA_LOOP_DOWN: /* Loop Down Event */
9a853f71
AV
438 DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n",
439 ha->host_no, mb[1]));
440 qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]);
1da177e4
LT
441
442 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
443 atomic_set(&ha->loop_state, LOOP_DOWN);
444 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
445 ha->device_flags |= DFLG_NO_CABLE;
d97994dc 446 qla2x00_mark_all_devices_lost(ha, 1);
1da177e4
LT
447 }
448
2c3dfe3f
SJ
449 if (ha->parent) {
450 atomic_set(&ha->vp_state, VP_FAILED);
451 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
452 }
453
1da177e4 454 ha->flags.management_server_logged_in = 0;
d8b45213 455 ha->link_data_rate = PORT_SPEED_UNKNOWN;
cca5335c
AV
456 if (ql2xfdmienable)
457 set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
1da177e4
LT
458 break;
459
460 case MBA_LIP_RESET: /* LIP reset occurred */
1da177e4
LT
461 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
462 ha->host_no, mb[1]));
463 qla_printk(KERN_INFO, ha,
464 "LIP reset occured (%x).\n", mb[1]);
465
466 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
467 atomic_set(&ha->loop_state, LOOP_DOWN);
468 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
d97994dc 469 qla2x00_mark_all_devices_lost(ha, 1);
1da177e4
LT
470 }
471
2c3dfe3f
SJ
472 if (ha->parent) {
473 atomic_set(&ha->vp_state, VP_FAILED);
474 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
475 }
476
1da177e4
LT
477 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
478
479 ha->operating_mode = LOOP;
480 ha->flags.management_server_logged_in = 0;
1da177e4
LT
481 break;
482
483 case MBA_POINT_TO_POINT: /* Point-to-Point */
484 if (IS_QLA2100(ha))
485 break;
486
487 DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n",
488 ha->host_no));
489
490 /*
491 * Until there's a transition from loop down to loop up, treat
492 * this as loop down only.
493 */
494 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
495 atomic_set(&ha->loop_state, LOOP_DOWN);
496 if (!atomic_read(&ha->loop_down_timer))
497 atomic_set(&ha->loop_down_timer,
498 LOOP_DOWN_TIME);
d97994dc 499 qla2x00_mark_all_devices_lost(ha, 1);
1da177e4
LT
500 }
501
2c3dfe3f
SJ
502 if (ha->parent) {
503 atomic_set(&ha->vp_state, VP_FAILED);
504 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
505 }
506
1da177e4
LT
507 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
508 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
509 }
510 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
4346b149
AV
511
512 ha->flags.gpsc_supported = 1;
02d638b4 513 ha->flags.management_server_logged_in = 0;
1da177e4
LT
514 break;
515
516 case MBA_CHG_IN_CONNECTION: /* Change in connection mode */
517 if (IS_QLA2100(ha))
518 break;
519
1da177e4
LT
520 DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
521 "received.\n",
522 ha->host_no));
523 qla_printk(KERN_INFO, ha,
524 "Configuration change detected: value=%x.\n", mb[1]);
525
526 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
fa2a1ce5 527 atomic_set(&ha->loop_state, LOOP_DOWN);
1da177e4
LT
528 if (!atomic_read(&ha->loop_down_timer))
529 atomic_set(&ha->loop_down_timer,
530 LOOP_DOWN_TIME);
d97994dc 531 qla2x00_mark_all_devices_lost(ha, 1);
1da177e4
LT
532 }
533
2c3dfe3f
SJ
534 if (ha->parent) {
535 atomic_set(&ha->vp_state, VP_FAILED);
536 fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED);
537 }
538
1da177e4
LT
539 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
540 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
541 break;
542
543 case MBA_PORT_UPDATE: /* Port database update */
1da177e4
LT
544 /*
545 * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
546 * event etc. earlier indicating loop is down) then process
547 * it. Otherwise ignore it and Wait for RSCN to come in.
548 */
549 atomic_set(&ha->loop_down_timer, 0);
550 if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
551 atomic_read(&ha->loop_state) != LOOP_DEAD) {
552 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
9a853f71
AV
553 "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
554 mb[2], mb[3]));
1da177e4
LT
555 break;
556 }
557
558 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
559 ha->host_no));
560 DEBUG(printk(KERN_INFO
9a853f71
AV
561 "scsi(%ld): Port database changed %04x %04x %04x.\n",
562 ha->host_no, mb[1], mb[2], mb[3]));
1da177e4
LT
563
564 /*
565 * Mark all devices as missing so we will login again.
566 */
567 atomic_set(&ha->loop_state, LOOP_UP);
568
d97994dc 569 qla2x00_mark_all_devices_lost(ha, 1);
1da177e4
LT
570
571 ha->flags.rscn_queue_overflow = 1;
572
573 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
574 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
1da177e4
LT
575 break;
576
577 case MBA_RSCN_UPDATE: /* State Change Registration */
2c3dfe3f
SJ
578 /* Check if the Vport has issued a SCR */
579 if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags))
580 break;
581
1da177e4
LT
582 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
583 ha->host_no));
584 DEBUG(printk(KERN_INFO
585 "scsi(%ld): RSCN database changed -- %04x %04x.\n",
586 ha->host_no, mb[1], mb[2]));
587
588 rscn_entry = (mb[1] << 16) | mb[2];
589 host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
590 ha->d_id.b.al_pa;
591 if (rscn_entry == host_pid) {
592 DEBUG(printk(KERN_INFO
593 "scsi(%ld): Ignoring RSCN update to local host "
594 "port ID (%06x)\n",
595 ha->host_no, host_pid));
596 break;
597 }
598
599 rscn_queue_index = ha->rscn_in_ptr + 1;
600 if (rscn_queue_index == MAX_RSCN_COUNT)
601 rscn_queue_index = 0;
602 if (rscn_queue_index != ha->rscn_out_ptr) {
603 ha->rscn_queue[ha->rscn_in_ptr] = rscn_entry;
604 ha->rscn_in_ptr = rscn_queue_index;
605 } else {
606 ha->flags.rscn_queue_overflow = 1;
607 }
608
609 atomic_set(&ha->loop_state, LOOP_UPDATE);
610 atomic_set(&ha->loop_down_timer, 0);
611 ha->flags.management_server_logged_in = 0;
612
613 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
614 set_bit(RSCN_UPDATE, &ha->dpc_flags);
1da177e4
LT
615 break;
616
617 /* case MBA_RIO_RESPONSE: */
618 case MBA_ZIO_RESPONSE:
619 DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n",
620 ha->host_no));
621 DEBUG(printk(KERN_INFO
622 "scsi(%ld): [R|Z]IO update completion.\n",
623 ha->host_no));
624
e428924c 625 if (IS_FWI2_CAPABLE(ha))
4fdfefe5
AV
626 qla24xx_process_response_queue(ha);
627 else
628 qla2x00_process_response_queue(ha);
1da177e4 629 break;
9a853f71
AV
630
631 case MBA_DISCARD_RND_FRAME:
632 DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
633 "%04x.\n", ha->host_no, mb[1], mb[2], mb[3]));
634 break;
45ebeb56
AV
635
636 case MBA_TRACE_NOTIFICATION:
637 DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n",
638 ha->host_no, mb[1], mb[2]));
639 break;
1da177e4 640 }
2c3dfe3f
SJ
641
642 if (!ha->parent && ha->num_vhosts)
643 qla2x00_alert_all_vps(ha, mb);
1da177e4
LT
644}
645
df7baa50
AV
646static void
647qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
648{
649 fc_port_t *fcport = data;
650
651 if (fcport->ha->max_q_depth <= sdev->queue_depth)
652 return;
653
654 if (sdev->ordered_tags)
655 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
656 sdev->queue_depth + 1);
657 else
658 scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG,
659 sdev->queue_depth + 1);
660
661 fcport->last_ramp_up = jiffies;
662
663 DEBUG2(qla_printk(KERN_INFO, fcport->ha,
664 "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n",
665 fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
666 sdev->queue_depth));
667}
668
669static void
670qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
671{
672 fc_port_t *fcport = data;
673
674 if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
675 return;
676
677 DEBUG2(qla_printk(KERN_INFO, fcport->ha,
678 "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
679 fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
680 sdev->queue_depth));
681}
682
683static inline void
684qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp)
685{
686 fc_port_t *fcport;
687 struct scsi_device *sdev;
688
689 sdev = sp->cmd->device;
690 if (sdev->queue_depth >= ha->max_q_depth)
691 return;
692
693 fcport = sp->fcport;
694 if (time_before(jiffies,
695 fcport->last_ramp_up + ql2xqfullrampup * HZ))
696 return;
697 if (time_before(jiffies,
698 fcport->last_queue_full + ql2xqfullrampup * HZ))
699 return;
700
df7baa50
AV
701 starget_for_each_device(sdev->sdev_target, fcport,
702 qla2x00_adjust_sdev_qdepth_up);
df7baa50
AV
703}
704
1da177e4
LT
705/**
706 * qla2x00_process_completed_request() - Process a Fast Post response.
707 * @ha: SCSI driver HA context
708 * @index: SRB index
709 */
710static void
711qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
712{
713 srb_t *sp;
714
715 /* Validate handle. */
716 if (index >= MAX_OUTSTANDING_COMMANDS) {
717 DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n",
718 ha->host_no, index));
719 qla_printk(KERN_WARNING, ha,
720 "Invalid SCSI completion handle %d.\n", index);
721
722 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
723 return;
724 }
725
726 sp = ha->outstanding_cmds[index];
727 if (sp) {
728 /* Free outstanding command slot. */
729 ha->outstanding_cmds[index] = NULL;
730
1da177e4
LT
731 CMD_COMPL_STATUS(sp->cmd) = 0L;
732 CMD_SCSI_STATUS(sp->cmd) = 0L;
733
734 /* Save ISP completion status */
735 sp->cmd->result = DID_OK << 16;
df7baa50
AV
736
737 qla2x00_ramp_up_queue_depth(ha, sp);
f4f051eb 738 qla2x00_sp_compl(ha, sp);
1da177e4
LT
739 } else {
740 DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
741 ha->host_no));
742 qla_printk(KERN_WARNING, ha,
743 "Invalid ISP SCSI completion handle\n");
744
745 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
746 }
747}
748
749/**
750 * qla2x00_process_response_queue() - Process response queue entries.
751 * @ha: SCSI driver HA context
752 */
753void
754qla2x00_process_response_queue(struct scsi_qla_host *ha)
755{
3d71644c 756 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1da177e4
LT
757 sts_entry_t *pkt;
758 uint16_t handle_cnt;
759 uint16_t cnt;
760
761 if (!ha->flags.online)
762 return;
763
764 while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
765 pkt = (sts_entry_t *)ha->response_ring_ptr;
766
767 ha->rsp_ring_index++;
768 if (ha->rsp_ring_index == ha->response_q_length) {
769 ha->rsp_ring_index = 0;
770 ha->response_ring_ptr = ha->response_ring;
771 } else {
772 ha->response_ring_ptr++;
773 }
774
775 if (pkt->entry_status != 0) {
776 DEBUG3(printk(KERN_INFO
777 "scsi(%ld): Process error entry.\n", ha->host_no));
778
779 qla2x00_error_entry(ha, pkt);
780 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
781 wmb();
782 continue;
783 }
784
785 switch (pkt->entry_type) {
786 case STATUS_TYPE:
787 qla2x00_status_entry(ha, pkt);
788 break;
789 case STATUS_TYPE_21:
790 handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
791 for (cnt = 0; cnt < handle_cnt; cnt++) {
792 qla2x00_process_completed_request(ha,
793 ((sts21_entry_t *)pkt)->handle[cnt]);
794 }
795 break;
796 case STATUS_TYPE_22:
797 handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
798 for (cnt = 0; cnt < handle_cnt; cnt++) {
799 qla2x00_process_completed_request(ha,
800 ((sts22_entry_t *)pkt)->handle[cnt]);
801 }
802 break;
803 case STATUS_CONT_TYPE:
804 qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
805 break;
806 case MS_IOCB_TYPE:
807 qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
808 break;
1da177e4
LT
809 default:
810 /* Type Not Supported. */
811 DEBUG4(printk(KERN_WARNING
812 "scsi(%ld): Received unknown response pkt type %x "
813 "entry status=%x.\n",
814 ha->host_no, pkt->entry_type, pkt->entry_status));
815 break;
816 }
817 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
818 wmb();
819 }
820
821 /* Adjust ring index */
822 WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index);
823}
824
825/**
826 * qla2x00_status_entry() - Process a Status IOCB entry.
827 * @ha: SCSI driver HA context
828 * @pkt: Entry pointer
829 */
830static void
9a853f71 831qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
1da177e4 832{
1da177e4 833 srb_t *sp;
1da177e4
LT
834 fc_port_t *fcport;
835 struct scsi_cmnd *cp;
9a853f71
AV
836 sts_entry_t *sts;
837 struct sts_entry_24xx *sts24;
1da177e4
LT
838 uint16_t comp_status;
839 uint16_t scsi_status;
840 uint8_t lscsi_status;
841 int32_t resid;
ed17c71b 842 uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len;
9a853f71
AV
843 uint8_t *rsp_info, *sense_data;
844
845 sts = (sts_entry_t *) pkt;
846 sts24 = (struct sts_entry_24xx *) pkt;
e428924c 847 if (IS_FWI2_CAPABLE(ha)) {
9a853f71
AV
848 comp_status = le16_to_cpu(sts24->comp_status);
849 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
850 } else {
851 comp_status = le16_to_cpu(sts->comp_status);
852 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
853 }
1da177e4
LT
854
855 /* Fast path completion. */
9a853f71
AV
856 if (comp_status == CS_COMPLETE && scsi_status == 0) {
857 qla2x00_process_completed_request(ha, sts->handle);
1da177e4
LT
858
859 return;
860 }
861
862 /* Validate handle. */
9a853f71
AV
863 if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
864 sp = ha->outstanding_cmds[sts->handle];
865 ha->outstanding_cmds[sts->handle] = NULL;
1da177e4
LT
866 } else
867 sp = NULL;
868
869 if (sp == NULL) {
870 DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
871 ha->host_no));
872 qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
873
874 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
39a11240 875 qla2xxx_wake_dpc(ha);
1da177e4
LT
876 return;
877 }
878 cp = sp->cmd;
879 if (cp == NULL) {
880 DEBUG2(printk("scsi(%ld): Command already returned back to OS "
75bc4190 881 "pkt->handle=%d sp=%p.\n", ha->host_no, sts->handle, sp));
1da177e4
LT
882 qla_printk(KERN_WARNING, ha,
883 "Command is NULL: already returned to OS (sp=%p)\n", sp);
884
885 return;
886 }
887
9a853f71
AV
888 lscsi_status = scsi_status & STATUS_MASK;
889 CMD_ENTRY_STATUS(cp) = sts->entry_status;
1da177e4
LT
890 CMD_COMPL_STATUS(cp) = comp_status;
891 CMD_SCSI_STATUS(cp) = scsi_status;
892
bdf79621 893 fcport = sp->fcport;
1da177e4 894
ed17c71b 895 sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
e428924c 896 if (IS_FWI2_CAPABLE(ha)) {
9a853f71
AV
897 sense_len = le32_to_cpu(sts24->sense_len);
898 rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
899 resid_len = le32_to_cpu(sts24->rsp_residual_count);
ed17c71b 900 fw_resid_len = le32_to_cpu(sts24->residual_len);
9a853f71
AV
901 rsp_info = sts24->data;
902 sense_data = sts24->data;
903 host_to_fcp_swap(sts24->data, sizeof(sts24->data));
904 } else {
905 sense_len = le16_to_cpu(sts->req_sense_length);
906 rsp_info_len = le16_to_cpu(sts->rsp_info_len);
907 resid_len = le32_to_cpu(sts->residual_length);
908 rsp_info = sts->rsp_info;
909 sense_data = sts->req_sense_data;
910 }
911
1da177e4
LT
912 /* Check for any FCP transport errors. */
913 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
9a853f71 914 /* Sense data lies beyond any FCP RESPONSE data. */
e428924c 915 if (IS_FWI2_CAPABLE(ha))
9a853f71
AV
916 sense_data += rsp_info_len;
917 if (rsp_info_len > 3 && rsp_info[3]) {
1da177e4
LT
918 DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
919 "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
9a853f71
AV
920 "retrying command\n", ha->host_no,
921 cp->device->channel, cp->device->id,
922 cp->device->lun, rsp_info_len, rsp_info[0],
923 rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
924 rsp_info[5], rsp_info[6], rsp_info[7]));
1da177e4
LT
925
926 cp->result = DID_BUS_BUSY << 16;
f4f051eb 927 qla2x00_sp_compl(ha, sp);
1da177e4
LT
928 return;
929 }
930 }
931
932 /*
933 * Based on Host and scsi status generate status code for Linux
934 */
935 switch (comp_status) {
936 case CS_COMPLETE:
df7baa50 937 case CS_QUEUE_FULL:
1da177e4
LT
938 if (scsi_status == 0) {
939 cp->result = DID_OK << 16;
940 break;
941 }
942 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
9a853f71 943 resid = resid_len;
385d70b4 944 scsi_set_resid(cp, resid);
1da177e4 945 CMD_RESID_LEN(cp) = resid;
0da69df1
AV
946
947 if (!lscsi_status &&
385d70b4 948 ((unsigned)(scsi_bufflen(cp) - resid) <
0da69df1
AV
949 cp->underflow)) {
950 qla_printk(KERN_INFO, ha,
385d70b4
FT
951 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
952 "detected (%x of %x bytes)...returning "
953 "error status.\n", ha->host_no,
954 cp->device->channel, cp->device->id,
955 cp->device->lun, resid,
956 scsi_bufflen(cp));
0da69df1
AV
957
958 cp->result = DID_ERROR << 16;
959 break;
960 }
1da177e4 961 }
1da177e4
LT
962 cp->result = DID_OK << 16 | lscsi_status;
963
df7baa50
AV
964 if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
965 DEBUG2(printk(KERN_INFO
966 "scsi(%ld): QUEUE FULL status detected "
967 "0x%x-0x%x.\n", ha->host_no, comp_status,
968 scsi_status));
969
970 /* Adjust queue depth for all luns on the port. */
971 fcport->last_queue_full = jiffies;
df7baa50
AV
972 starget_for_each_device(cp->device->sdev_target,
973 fcport, qla2x00_adjust_sdev_qdepth_down);
df7baa50
AV
974 break;
975 }
1da177e4
LT
976 if (lscsi_status != SS_CHECK_CONDITION)
977 break;
978
9a853f71 979 /* Copy Sense Data into sense buffer. */
1da177e4
LT
980 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
981
982 if (!(scsi_status & SS_SENSE_LEN_VALID))
983 break;
984
9a853f71
AV
985 if (sense_len >= sizeof(cp->sense_buffer))
986 sense_len = sizeof(cp->sense_buffer);
1da177e4 987
9a853f71
AV
988 CMD_ACTUAL_SNSLEN(cp) = sense_len;
989 sp->request_sense_length = sense_len;
1da177e4
LT
990 sp->request_sense_ptr = cp->sense_buffer;
991
992 if (sp->request_sense_length > 32)
9a853f71 993 sense_len = 32;
1da177e4 994
9a853f71 995 memcpy(cp->sense_buffer, sense_data, sense_len);
1da177e4 996
9a853f71
AV
997 sp->request_sense_ptr += sense_len;
998 sp->request_sense_length -= sense_len;
1da177e4
LT
999 if (sp->request_sense_length != 0)
1000 ha->status_srb = sp;
1001
1da177e4 1002 DEBUG5(printk("%s(): Check condition Sense data, "
9a853f71
AV
1003 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", __func__,
1004 ha->host_no, cp->device->channel, cp->device->id,
1005 cp->device->lun, cp, cp->serial_number));
1006 if (sense_len)
1da177e4
LT
1007 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
1008 CMD_ACTUAL_SNSLEN(cp)));
1009 break;
1010
1011 case CS_DATA_UNDERRUN:
9a853f71 1012 resid = resid_len;
ed17c71b 1013 /* Use F/W calculated residual length. */
e428924c 1014 if (IS_FWI2_CAPABLE(ha))
ed17c71b
RA
1015 resid = fw_resid_len;
1016
1da177e4 1017 if (scsi_status & SS_RESIDUAL_UNDER) {
385d70b4 1018 scsi_set_resid(cp, resid);
1da177e4 1019 CMD_RESID_LEN(cp) = resid;
e038a1be 1020 } else {
1021 DEBUG2(printk(KERN_INFO
1022 "scsi(%ld:%d:%d) UNDERRUN status detected "
ed17c71b
RA
1023 "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x "
1024 "os_underflow=0x%x\n", ha->host_no,
1025 cp->device->id, cp->device->lun, comp_status,
1026 scsi_status, resid_len, resid, cp->cmnd[0],
1027 cp->underflow));
e038a1be 1028
1da177e4
LT
1029 }
1030
1031 /*
fa2a1ce5 1032 * Check to see if SCSI Status is non zero. If so report SCSI
1da177e4
LT
1033 * Status.
1034 */
1035 if (lscsi_status != 0) {
1da177e4
LT
1036 cp->result = DID_OK << 16 | lscsi_status;
1037
ffec28a3
AV
1038 if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
1039 DEBUG2(printk(KERN_INFO
1040 "scsi(%ld): QUEUE FULL status detected "
1041 "0x%x-0x%x.\n", ha->host_no, comp_status,
1042 scsi_status));
1043
1044 /*
1045 * Adjust queue depth for all luns on the
1046 * port.
1047 */
1048 fcport->last_queue_full = jiffies;
1049 starget_for_each_device(
1050 cp->device->sdev_target, fcport,
1051 qla2x00_adjust_sdev_qdepth_down);
1052 break;
1053 }
1da177e4
LT
1054 if (lscsi_status != SS_CHECK_CONDITION)
1055 break;
1056
1057 /* Copy Sense Data into sense buffer */
1058 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
1059
1060 if (!(scsi_status & SS_SENSE_LEN_VALID))
1061 break;
1062
9a853f71
AV
1063 if (sense_len >= sizeof(cp->sense_buffer))
1064 sense_len = sizeof(cp->sense_buffer);
1da177e4 1065
9a853f71
AV
1066 CMD_ACTUAL_SNSLEN(cp) = sense_len;
1067 sp->request_sense_length = sense_len;
1da177e4
LT
1068 sp->request_sense_ptr = cp->sense_buffer;
1069
fa2a1ce5 1070 if (sp->request_sense_length > 32)
9a853f71 1071 sense_len = 32;
1da177e4 1072
9a853f71 1073 memcpy(cp->sense_buffer, sense_data, sense_len);
1da177e4 1074
9a853f71
AV
1075 sp->request_sense_ptr += sense_len;
1076 sp->request_sense_length -= sense_len;
1da177e4
LT
1077 if (sp->request_sense_length != 0)
1078 ha->status_srb = sp;
1079
1da177e4
LT
1080 DEBUG5(printk("%s(): Check condition Sense data, "
1081 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
9a853f71
AV
1082 __func__, ha->host_no, cp->device->channel,
1083 cp->device->id, cp->device->lun, cp,
1da177e4 1084 cp->serial_number));
9a853f71 1085
8084fe16
SS
1086 /*
1087 * In case of a Underrun condition, set both the lscsi
1088 * status and the completion status to appropriate
1089 * values.
1090 */
1091 if (resid &&
4b39c1d9 1092 ((unsigned)(scsi_bufflen(cp) - resid) <
8084fe16
SS
1093 cp->underflow)) {
1094 DEBUG2(qla_printk(KERN_INFO, ha,
1095 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1096 "detected (%x of %x bytes)...returning "
1097 "error status.\n", ha->host_no,
1098 cp->device->channel, cp->device->id,
1099 cp->device->lun, resid,
4b39c1d9 1100 scsi_bufflen(cp)));
8084fe16
SS
1101
1102 cp->result = DID_ERROR << 16 | lscsi_status;
1103 }
1104
9a853f71 1105 if (sense_len)
1da177e4
LT
1106 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
1107 CMD_ACTUAL_SNSLEN(cp)));
1108 } else {
1109 /*
1110 * If RISC reports underrun and target does not report
1111 * it then we must have a lost frame, so tell upper
1112 * layer to retry it by reporting a bus busy.
1113 */
1114 if (!(scsi_status & SS_RESIDUAL_UNDER)) {
1115 DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
385d70b4
FT
1116 "frame(s) detected (%x of %x bytes)..."
1117 "retrying command.\n", ha->host_no,
1118 cp->device->channel, cp->device->id,
1119 cp->device->lun, resid,
1120 scsi_bufflen(cp)));
1da177e4
LT
1121
1122 cp->result = DID_BUS_BUSY << 16;
1da177e4
LT
1123 break;
1124 }
1125
1126 /* Handle mid-layer underflow */
385d70b4 1127 if ((unsigned)(scsi_bufflen(cp) - resid) <
1da177e4
LT
1128 cp->underflow) {
1129 qla_printk(KERN_INFO, ha,
385d70b4
FT
1130 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1131 "detected (%x of %x bytes)...returning "
1132 "error status.\n", ha->host_no,
1133 cp->device->channel, cp->device->id,
1134 cp->device->lun, resid,
1135 scsi_bufflen(cp));
1da177e4
LT
1136
1137 cp->result = DID_ERROR << 16;
1138 break;
1139 }
1140
1141 /* Everybody online, looking good... */
1142 cp->result = DID_OK << 16;
1143 }
1144 break;
1145
1146 case CS_DATA_OVERRUN:
1147 DEBUG2(printk(KERN_INFO
1148 "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
9a853f71
AV
1149 ha->host_no, cp->device->id, cp->device->lun, comp_status,
1150 scsi_status));
1da177e4
LT
1151 DEBUG2(printk(KERN_INFO
1152 "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1153 cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
1154 cp->cmnd[4], cp->cmnd[5]));
1155 DEBUG2(printk(KERN_INFO
1156 "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
1157 "status!\n",
385d70b4 1158 cp->serial_number, scsi_bufflen(cp), resid_len));
1da177e4
LT
1159
1160 cp->result = DID_ERROR << 16;
1161 break;
1162
1163 case CS_PORT_LOGGED_OUT:
1164 case CS_PORT_CONFIG_CHG:
1165 case CS_PORT_BUSY:
1166 case CS_INCOMPLETE:
1167 case CS_PORT_UNAVAILABLE:
1168 /*
1169 * If the port is in Target Down state, return all IOs for this
1170 * Target with DID_NO_CONNECT ELSE Queue the IOs in the
1171 * retry_queue.
1172 */
1da177e4
LT
1173 DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
1174 "pid=%ld, compl status=0x%x, port state=0x%x\n",
9a853f71
AV
1175 ha->host_no, cp->device->id, cp->device->lun,
1176 cp->serial_number, comp_status,
1da177e4
LT
1177 atomic_read(&fcport->state)));
1178
f4f051eb 1179 cp->result = DID_BUS_BUSY << 16;
1da177e4 1180 if (atomic_read(&fcport->state) == FCS_ONLINE) {
d97994dc 1181 qla2x00_mark_device_lost(ha, fcport, 1, 1);
1da177e4 1182 }
1da177e4
LT
1183 break;
1184
1185 case CS_RESET:
1186 DEBUG2(printk(KERN_INFO
1187 "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
1188 ha->host_no, comp_status, scsi_status));
1189
f4f051eb 1190 cp->result = DID_RESET << 16;
1da177e4
LT
1191 break;
1192
1193 case CS_ABORTED:
fa2a1ce5 1194 /*
1da177e4
LT
1195 * hv2.19.12 - DID_ABORT does not retry the request if we
1196 * aborted this request then abort otherwise it must be a
1197 * reset.
1198 */
1199 DEBUG2(printk(KERN_INFO
1200 "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
1201 ha->host_no, comp_status, scsi_status));
1202
1203 cp->result = DID_RESET << 16;
1204 break;
1205
1206 case CS_TIMEOUT:
9a853f71
AV
1207 cp->result = DID_BUS_BUSY << 16;
1208
e428924c 1209 if (IS_FWI2_CAPABLE(ha)) {
9a853f71
AV
1210 DEBUG2(printk(KERN_INFO
1211 "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
1212 "0x%x-0x%x\n", ha->host_no, cp->device->channel,
1213 cp->device->id, cp->device->lun, comp_status,
1214 scsi_status));
1215 break;
1216 }
1da177e4
LT
1217 DEBUG2(printk(KERN_INFO
1218 "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
9a853f71
AV
1219 "sflags=%x.\n", ha->host_no, cp->device->channel,
1220 cp->device->id, cp->device->lun, comp_status, scsi_status,
1221 le16_to_cpu(sts->status_flags)));
1da177e4 1222
9a853f71
AV
1223 /* Check to see if logout occurred. */
1224 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
d97994dc 1225 qla2x00_mark_device_lost(ha, fcport, 1, 1);
1da177e4
LT
1226 break;
1227
1da177e4
LT
1228 default:
1229 DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
9a853f71 1230 "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
1da177e4
LT
1231 qla_printk(KERN_INFO, ha,
1232 "Unknown status detected 0x%x-0x%x.\n",
1233 comp_status, scsi_status);
1234
1235 cp->result = DID_ERROR << 16;
1236 break;
1237 }
1238
1239 /* Place command on done queue. */
1240 if (ha->status_srb == NULL)
f4f051eb 1241 qla2x00_sp_compl(ha, sp);
1da177e4
LT
1242}
1243
1244/**
1245 * qla2x00_status_cont_entry() - Process a Status Continuations entry.
1246 * @ha: SCSI driver HA context
1247 * @pkt: Entry pointer
1248 *
1249 * Extended sense data.
1250 */
1251static void
1252qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
1253{
1254 uint8_t sense_sz = 0;
1255 srb_t *sp = ha->status_srb;
1256 struct scsi_cmnd *cp;
1257
1258 if (sp != NULL && sp->request_sense_length != 0) {
1259 cp = sp->cmd;
1260 if (cp == NULL) {
1261 DEBUG2(printk("%s(): Cmd already returned back to OS "
75bc4190 1262 "sp=%p.\n", __func__, sp));
1da177e4
LT
1263 qla_printk(KERN_INFO, ha,
1264 "cmd is NULL: already returned to OS (sp=%p)\n",
fa2a1ce5 1265 sp);
1da177e4
LT
1266
1267 ha->status_srb = NULL;
1268 return;
1269 }
1270
1271 if (sp->request_sense_length > sizeof(pkt->data)) {
1272 sense_sz = sizeof(pkt->data);
1273 } else {
1274 sense_sz = sp->request_sense_length;
1275 }
1276
1277 /* Move sense data. */
e428924c 1278 if (IS_FWI2_CAPABLE(ha))
9a853f71 1279 host_to_fcp_swap(pkt->data, sizeof(pkt->data));
1da177e4
LT
1280 memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
1281 DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
1282
1283 sp->request_sense_ptr += sense_sz;
1284 sp->request_sense_length -= sense_sz;
1285
1286 /* Place command on done queue. */
1287 if (sp->request_sense_length == 0) {
1da177e4 1288 ha->status_srb = NULL;
f4f051eb 1289 qla2x00_sp_compl(ha, sp);
1da177e4
LT
1290 }
1291 }
1292}
1293
1294/**
1295 * qla2x00_error_entry() - Process an error entry.
1296 * @ha: SCSI driver HA context
1297 * @pkt: Entry pointer
1298 */
1299static void
9a853f71 1300qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1da177e4
LT
1301{
1302 srb_t *sp;
1303
1304#if defined(QL_DEBUG_LEVEL_2)
1305 if (pkt->entry_status & RF_INV_E_ORDER)
1306 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
1307 else if (pkt->entry_status & RF_INV_E_COUNT)
1308 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
1309 else if (pkt->entry_status & RF_INV_E_PARAM)
fa2a1ce5 1310 qla_printk(KERN_ERR, ha,
1da177e4
LT
1311 "%s: Invalid Entry Parameter\n", __func__);
1312 else if (pkt->entry_status & RF_INV_E_TYPE)
1313 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);
1314 else if (pkt->entry_status & RF_BUSY)
1315 qla_printk(KERN_ERR, ha, "%s: Busy\n", __func__);
1316 else
1317 qla_printk(KERN_ERR, ha, "%s: UNKNOWN flag error\n", __func__);
1318#endif
1319
1320 /* Validate handle. */
1321 if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1322 sp = ha->outstanding_cmds[pkt->handle];
1323 else
1324 sp = NULL;
1325
1326 if (sp) {
1327 /* Free outstanding command slot. */
1328 ha->outstanding_cmds[pkt->handle] = NULL;
354d6b21 1329
1da177e4
LT
1330 /* Bad payload or header */
1331 if (pkt->entry_status &
1332 (RF_INV_E_ORDER | RF_INV_E_COUNT |
1333 RF_INV_E_PARAM | RF_INV_E_TYPE)) {
1334 sp->cmd->result = DID_ERROR << 16;
1335 } else if (pkt->entry_status & RF_BUSY) {
1336 sp->cmd->result = DID_BUS_BUSY << 16;
1337 } else {
1338 sp->cmd->result = DID_ERROR << 16;
1339 }
f4f051eb 1340 qla2x00_sp_compl(ha, sp);
1da177e4 1341
9a853f71
AV
1342 } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
1343 COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
1da177e4
LT
1344 DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
1345 ha->host_no));
1346 qla_printk(KERN_WARNING, ha,
1347 "Error entry - invalid handle\n");
1348
1349 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
39a11240 1350 qla2xxx_wake_dpc(ha);
1da177e4
LT
1351 }
1352}
1353
1354/**
1355 * qla2x00_ms_entry() - Process a Management Server entry.
1356 * @ha: SCSI driver HA context
1357 * @index: Response queue out pointer
1358 */
1359static void
9a853f71 1360qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
1da177e4
LT
1361{
1362 srb_t *sp;
1363
1364 DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1365 __func__, ha->host_no, pkt, pkt->handle1));
1366
1367 /* Validate handle. */
1368 if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
1369 sp = ha->outstanding_cmds[pkt->handle1];
1370 else
1371 sp = NULL;
1372
1373 if (sp == NULL) {
1374 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1375 ha->host_no));
1376 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
1377
1378 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1379 return;
1380 }
1381
1382 CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
1383 CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1384
1385 /* Free outstanding command slot. */
1386 ha->outstanding_cmds[pkt->handle1] = NULL;
1387
f4f051eb 1388 qla2x00_sp_compl(ha, sp);
1da177e4 1389}
9a853f71
AV
1390
1391
1392/**
1393 * qla24xx_mbx_completion() - Process mailbox command completions.
1394 * @ha: SCSI driver HA context
1395 * @mb0: Mailbox0 register
1396 */
1397static void
1398qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
1399{
1400 uint16_t cnt;
1401 uint16_t __iomem *wptr;
1402 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1403
1404 /* Load return mailbox registers. */
1405 ha->flags.mbox_int = 1;
1406 ha->mailbox_out[0] = mb0;
1407 wptr = (uint16_t __iomem *)&reg->mailbox1;
1408
1409 for (cnt = 1; cnt < ha->mbx_count; cnt++) {
1410 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
1411 wptr++;
1412 }
1413
1414 if (ha->mcp) {
1415 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
1416 __func__, ha->host_no, ha->mcp->mb[0]));
1417 } else {
1418 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
1419 __func__, ha->host_no));
1420 }
1421}
1422
1423/**
1424 * qla24xx_process_response_queue() - Process response queue entries.
1425 * @ha: SCSI driver HA context
1426 */
1427void
1428qla24xx_process_response_queue(struct scsi_qla_host *ha)
1429{
1430 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1431 struct sts_entry_24xx *pkt;
1432
1433 if (!ha->flags.online)
1434 return;
1435
1436 while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
1437 pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
1438
1439 ha->rsp_ring_index++;
1440 if (ha->rsp_ring_index == ha->response_q_length) {
1441 ha->rsp_ring_index = 0;
1442 ha->response_ring_ptr = ha->response_ring;
1443 } else {
1444 ha->response_ring_ptr++;
1445 }
1446
1447 if (pkt->entry_status != 0) {
1448 DEBUG3(printk(KERN_INFO
1449 "scsi(%ld): Process error entry.\n", ha->host_no));
1450
9a853f71
AV
1451 qla2x00_error_entry(ha, (sts_entry_t *) pkt);
1452 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1453 wmb();
1454 continue;
1455 }
1456
1457 switch (pkt->entry_type) {
1458 case STATUS_TYPE:
1459 qla2x00_status_entry(ha, pkt);
1460 break;
1461 case STATUS_CONT_TYPE:
1462 qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
1463 break;
1464 case MS_IOCB_TYPE:
1465 qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
1466 break;
2c3dfe3f
SJ
1467 case VP_RPT_ID_IOCB_TYPE:
1468 qla24xx_report_id_acquisition(ha,
1469 (struct vp_rpt_id_entry_24xx *)pkt);
1470 break;
9a853f71
AV
1471 default:
1472 /* Type Not Supported. */
1473 DEBUG4(printk(KERN_WARNING
1474 "scsi(%ld): Received unknown response pkt type %x "
1475 "entry status=%x.\n",
1476 ha->host_no, pkt->entry_type, pkt->entry_status));
1477 break;
1478 }
1479 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1480 wmb();
1481 }
1482
1483 /* Adjust ring index */
1484 WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);
1485}
1486
1487/**
1488 * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
1489 * @irq:
1490 * @dev_id: SCSI driver HA context
9a853f71
AV
1491 *
1492 * Called by system whenever the host adapter generates an interrupt.
1493 *
1494 * Returns handled flag.
1495 */
1496irqreturn_t
7d12e780 1497qla24xx_intr_handler(int irq, void *dev_id)
9a853f71
AV
1498{
1499 scsi_qla_host_t *ha;
1500 struct device_reg_24xx __iomem *reg;
1501 int status;
1502 unsigned long flags;
1503 unsigned long iter;
1504 uint32_t stat;
1505 uint32_t hccr;
1506 uint16_t mb[4];
1507
1508 ha = (scsi_qla_host_t *) dev_id;
1509 if (!ha) {
1510 printk(KERN_INFO
1511 "%s(): NULL host pointer\n", __func__);
1512 return IRQ_NONE;
1513 }
1514
1515 reg = &ha->iobase->isp24;
1516 status = 0;
1517
1518 spin_lock_irqsave(&ha->hardware_lock, flags);
1519 for (iter = 50; iter--; ) {
1520 stat = RD_REG_DWORD(&reg->host_status);
1521 if (stat & HSRX_RISC_PAUSED) {
14e660e6
SJ
1522 if (pci_channel_offline(ha->pdev))
1523 break;
1524
9a853f71
AV
1525 hccr = RD_REG_DWORD(&reg->hccr);
1526
1527 qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1528 "Dumping firmware!\n", hccr);
fd34f556 1529 ha->isp_ops->fw_dump(ha, 1);
9a853f71
AV
1530 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1531 break;
1532 } else if ((stat & HSRX_RISC_INT) == 0)
1533 break;
1534
1535 switch (stat & 0xff) {
1536 case 0x1:
1537 case 0x2:
1538 case 0x10:
1539 case 0x11:
1540 qla24xx_mbx_completion(ha, MSW(stat));
1541 status |= MBX_INTERRUPT;
1542
1543 break;
1544 case 0x12:
1545 mb[0] = MSW(stat);
1546 mb[1] = RD_REG_WORD(&reg->mailbox1);
1547 mb[2] = RD_REG_WORD(&reg->mailbox2);
1548 mb[3] = RD_REG_WORD(&reg->mailbox3);
1549 qla2x00_async_event(ha, mb);
1550 break;
1551 case 0x13:
1552 qla24xx_process_response_queue(ha);
1553 break;
1554 default:
1555 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1556 "(%d).\n",
1557 ha->host_no, stat & 0xff));
1558 break;
1559 }
1560 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1561 RD_REG_DWORD_RELAXED(&reg->hccr);
1562 }
1563 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1564
1565 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
1566 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
9a853f71
AV
1567 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1568 up(&ha->mbx_intr_sem);
9a853f71
AV
1569 }
1570
1571 return IRQ_HANDLED;
1572}
1573
1574/**
1575 * qla24xx_ms_entry() - Process a Management Server entry.
1576 * @ha: SCSI driver HA context
1577 * @index: Response queue out pointer
1578 */
1579static void
1580qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
1581{
1582 srb_t *sp;
1583
1584 DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1585 __func__, ha->host_no, pkt, pkt->handle));
1586
744f11fd
AV
1587 DEBUG9(printk("%s: ct pkt dump:\n", __func__));
1588 DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx)));
9a853f71
AV
1589
1590 /* Validate handle. */
1591 if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1592 sp = ha->outstanding_cmds[pkt->handle];
1593 else
1594 sp = NULL;
1595
1596 if (sp == NULL) {
1597 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1598 ha->host_no));
1599 DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
1600 ha->host_no));
1601 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
1602 pkt->handle);
1603
1604 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1605 return;
1606 }
1607
1608 CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
1609 CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1610
1611 /* Free outstanding command slot. */
1612 ha->outstanding_cmds[pkt->handle] = NULL;
1613
1614 qla2x00_sp_compl(ha, sp);
1615}
1616
a8488abe
AV
1617static irqreturn_t
1618qla24xx_msix_rsp_q(int irq, void *dev_id)
1619{
1620 scsi_qla_host_t *ha;
1621 struct device_reg_24xx __iomem *reg;
1622 unsigned long flags;
1623
1624 ha = dev_id;
1625 reg = &ha->iobase->isp24;
1626
1627 spin_lock_irqsave(&ha->hardware_lock, flags);
1628
1629 qla24xx_process_response_queue(ha);
1630
1631 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1632 RD_REG_DWORD_RELAXED(&reg->hccr);
1633
1634 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1635
1636 return IRQ_HANDLED;
1637}
1638
1639static irqreturn_t
1640qla24xx_msix_default(int irq, void *dev_id)
1641{
1642 scsi_qla_host_t *ha;
1643 struct device_reg_24xx __iomem *reg;
1644 int status;
1645 unsigned long flags;
1646 unsigned long iter;
1647 uint32_t stat;
1648 uint32_t hccr;
1649 uint16_t mb[4];
1650
1651 ha = dev_id;
1652 reg = &ha->iobase->isp24;
1653 status = 0;
1654
1655 spin_lock_irqsave(&ha->hardware_lock, flags);
1656 for (iter = 50; iter--; ) {
1657 stat = RD_REG_DWORD(&reg->host_status);
1658 if (stat & HSRX_RISC_PAUSED) {
14e660e6
SJ
1659 if (pci_channel_offline(ha->pdev))
1660 break;
1661
a8488abe
AV
1662 hccr = RD_REG_DWORD(&reg->hccr);
1663
1664 qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1665 "Dumping firmware!\n", hccr);
fd34f556 1666 ha->isp_ops->fw_dump(ha, 1);
a8488abe
AV
1667 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1668 break;
1669 } else if ((stat & HSRX_RISC_INT) == 0)
1670 break;
1671
1672 switch (stat & 0xff) {
1673 case 0x1:
1674 case 0x2:
1675 case 0x10:
1676 case 0x11:
1677 qla24xx_mbx_completion(ha, MSW(stat));
1678 status |= MBX_INTERRUPT;
1679
1680 break;
1681 case 0x12:
1682 mb[0] = MSW(stat);
1683 mb[1] = RD_REG_WORD(&reg->mailbox1);
1684 mb[2] = RD_REG_WORD(&reg->mailbox2);
1685 mb[3] = RD_REG_WORD(&reg->mailbox3);
1686 qla2x00_async_event(ha, mb);
1687 break;
1688 case 0x13:
1689 qla24xx_process_response_queue(ha);
1690 break;
1691 default:
1692 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1693 "(%d).\n",
1694 ha->host_no, stat & 0xff));
1695 break;
1696 }
1697 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1698 RD_REG_DWORD_RELAXED(&reg->hccr);
1699 }
1700 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1701
1702 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
1703 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
a8488abe
AV
1704 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1705 up(&ha->mbx_intr_sem);
a8488abe
AV
1706 }
1707
1708 return IRQ_HANDLED;
1709}
1710
1711/* Interrupt handling helpers. */
1712
1713struct qla_init_msix_entry {
1714 uint16_t entry;
1715 uint16_t index;
1716 const char *name;
476834c2 1717 irq_handler_t handler;
a8488abe
AV
1718};
1719
1720static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = {
1721 { QLA_MSIX_DEFAULT, QLA_MIDX_DEFAULT,
1722 "qla2xxx (default)", qla24xx_msix_default },
1723
1724 { QLA_MSIX_RSP_Q, QLA_MIDX_RSP_Q,
1725 "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
1726};
1727
1728static void
1729qla24xx_disable_msix(scsi_qla_host_t *ha)
1730{
1731 int i;
1732 struct qla_msix_entry *qentry;
1733
1734 for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
1735 qentry = &ha->msix_entries[imsix_entries[i].index];
1736 if (qentry->have_irq)
1737 free_irq(qentry->msix_vector, ha);
1738 }
1739 pci_disable_msix(ha->pdev);
1740}
1741
1742static int
1743qla24xx_enable_msix(scsi_qla_host_t *ha)
1744{
1745 int i, ret;
1746 struct msix_entry entries[QLA_MSIX_ENTRIES];
1747 struct qla_msix_entry *qentry;
1748
1749 for (i = 0; i < QLA_MSIX_ENTRIES; i++)
1750 entries[i].entry = imsix_entries[i].entry;
1751
1752 ret = pci_enable_msix(ha->pdev, entries, ARRAY_SIZE(entries));
1753 if (ret) {
1754 qla_printk(KERN_WARNING, ha,
1755 "MSI-X: Failed to enable support -- %d/%d\n",
1756 QLA_MSIX_ENTRIES, ret);
1757 goto msix_out;
1758 }
1759 ha->flags.msix_enabled = 1;
1760
1761 for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
1762 qentry = &ha->msix_entries[imsix_entries[i].index];
1763 qentry->msix_vector = entries[i].vector;
1764 qentry->msix_entry = entries[i].entry;
1765 qentry->have_irq = 0;
1766 ret = request_irq(qentry->msix_vector,
1767 imsix_entries[i].handler, 0, imsix_entries[i].name, ha);
1768 if (ret) {
1769 qla_printk(KERN_WARNING, ha,
1770 "MSI-X: Unable to register handler -- %x/%d.\n",
1771 imsix_entries[i].index, ret);
1772 qla24xx_disable_msix(ha);
1773 goto msix_out;
1774 }
1775 qentry->have_irq = 1;
1776 }
1777
1778msix_out:
1779 return ret;
1780}
1781
1782int
1783qla2x00_request_irqs(scsi_qla_host_t *ha)
1784{
1785 int ret;
1786
1787 /* If possible, enable MSI-X. */
c3a2f0df 1788 if (!IS_QLA2432(ha) && !IS_QLA2532(ha))
a8488abe
AV
1789 goto skip_msix;
1790
c3a2f0df
AV
1791 if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
1792 !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
a8488abe
AV
1793 DEBUG2(qla_printk(KERN_WARNING, ha,
1794 "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
1795 ha->chip_revision, ha->fw_attributes));
1796
1797 goto skip_msix;
1798 }
1799
1800 ret = qla24xx_enable_msix(ha);
1801 if (!ret) {
1802 DEBUG2(qla_printk(KERN_INFO, ha,
1803 "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision,
1804 ha->fw_attributes));
1805 return ret;
1806 }
1807 qla_printk(KERN_WARNING, ha,
1808 "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
1809skip_msix:
cbedb601 1810
c3a2f0df 1811 if (!IS_QLA24XX(ha) && !IS_QLA2532(ha))
cbedb601
AV
1812 goto skip_msi;
1813
1814 ret = pci_enable_msi(ha->pdev);
1815 if (!ret) {
1816 DEBUG2(qla_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
1817 ha->flags.msi_enabled = 1;
1818 }
1819skip_msi:
1820
fd34f556 1821 ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
a8488abe 1822 IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
d88021a6
AV
1823 if (!ret) {
1824 ha->flags.inta_enabled = 1;
1825 ha->host->irq = ha->pdev->irq;
1826 } else {
a8488abe
AV
1827 qla_printk(KERN_WARNING, ha,
1828 "Failed to reserve interrupt %d already in use.\n",
1829 ha->pdev->irq);
1830 }
a8488abe
AV
1831
1832 return ret;
1833}
1834
1835void
1836qla2x00_free_irqs(scsi_qla_host_t *ha)
1837{
1838
1839 if (ha->flags.msix_enabled)
1840 qla24xx_disable_msix(ha);
cbedb601 1841 else if (ha->flags.inta_enabled) {
a8488abe 1842 free_irq(ha->host->irq, ha);
cbedb601
AV
1843 pci_disable_msi(ha->pdev);
1844 }
a8488abe 1845}