]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/scsi/qla2xxx/qla_isr.c
[SCSI] qla2xxx: Check to make sure multique and CPU affinity support is not enabled...
[mirror_ubuntu-bionic-kernel.git] / drivers / scsi / qla2xxx / qla_isr.c
CommitLineData
1da177e4 1/*
fa90c54f 2 * QLogic Fibre Channel HBA Driver
01e58d8e 3 * Copyright (c) 2003-2008 QLogic Corporation
1da177e4 4 *
fa90c54f 5 * See LICENSE.qla2xxx for copyright and licensing details.
1da177e4
LT
6 */
7#include "qla_def.h"
8
05236a05 9#include <linux/delay.h>
df7baa50 10#include <scsi/scsi_tcq.h>
9a069e19 11#include <scsi/scsi_bsg_fc.h>
df7baa50 12
1da177e4 13static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
73208dfd
AC
14static void qla2x00_process_completed_request(struct scsi_qla_host *,
15 struct req_que *, uint32_t);
16static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
2afa19a9 17static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
73208dfd
AC
18static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
19 sts_entry_t *);
9a853f71 20
1da177e4
LT
21/**
22 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
23 * @irq:
24 * @dev_id: SCSI driver HA context
1da177e4
LT
25 *
26 * Called by system whenever the host adapter generates an interrupt.
27 *
28 * Returns handled flag.
29 */
30irqreturn_t
7d12e780 31qla2100_intr_handler(int irq, void *dev_id)
1da177e4 32{
e315cd28
AC
33 scsi_qla_host_t *vha;
34 struct qla_hw_data *ha;
3d71644c 35 struct device_reg_2xxx __iomem *reg;
1da177e4 36 int status;
1da177e4 37 unsigned long iter;
14e660e6 38 uint16_t hccr;
9a853f71 39 uint16_t mb[4];
e315cd28 40 struct rsp_que *rsp;
43fac4d9 41 unsigned long flags;
1da177e4 42
e315cd28
AC
43 rsp = (struct rsp_que *) dev_id;
44 if (!rsp) {
1da177e4 45 printk(KERN_INFO
e315cd28 46 "%s(): NULL response queue pointer\n", __func__);
1da177e4
LT
47 return (IRQ_NONE);
48 }
49
e315cd28 50 ha = rsp->hw;
3d71644c 51 reg = &ha->iobase->isp;
1da177e4
LT
52 status = 0;
53
43fac4d9 54 spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a9 55 vha = pci_get_drvdata(ha->pdev);
1da177e4 56 for (iter = 50; iter--; ) {
14e660e6
SJ
57 hccr = RD_REG_WORD(&reg->hccr);
58 if (hccr & HCCR_RISC_PAUSE) {
59 if (pci_channel_offline(ha->pdev))
60 break;
61
62 /*
63 * Issue a "HARD" reset in order for the RISC interrupt
64 * bit to be cleared. Schedule a big hammmer to get
65 * out of the RISC PAUSED state.
66 */
67 WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
68 RD_REG_WORD(&reg->hccr);
69
e315cd28
AC
70 ha->isp_ops->fw_dump(vha, 1);
71 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
14e660e6
SJ
72 break;
73 } else if ((RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) == 0)
1da177e4
LT
74 break;
75
76 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
77 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
78 RD_REG_WORD(&reg->hccr);
79
80 /* Get mailbox data. */
9a853f71
AV
81 mb[0] = RD_MAILBOX_REG(ha, reg, 0);
82 if (mb[0] > 0x3fff && mb[0] < 0x8000) {
e315cd28 83 qla2x00_mbx_completion(vha, mb[0]);
1da177e4 84 status |= MBX_INTERRUPT;
9a853f71
AV
85 } else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
86 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
87 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
88 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
73208dfd 89 qla2x00_async_event(vha, rsp, mb);
1da177e4
LT
90 } else {
91 /*EMPTY*/
92 DEBUG2(printk("scsi(%ld): Unrecognized "
9a853f71 93 "interrupt type (%d).\n",
e315cd28 94 vha->host_no, mb[0]));
1da177e4
LT
95 }
96 /* Release mailbox registers. */
97 WRT_REG_WORD(&reg->semaphore, 0);
98 RD_REG_WORD(&reg->semaphore);
99 } else {
73208dfd 100 qla2x00_process_response_queue(rsp);
1da177e4
LT
101
102 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
103 RD_REG_WORD(&reg->hccr);
104 }
105 }
43fac4d9 106 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1da177e4 107
1da177e4
LT
108 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
109 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1da177e4 110 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0 111 complete(&ha->mbx_intr_comp);
1da177e4
LT
112 }
113
1da177e4
LT
114 return (IRQ_HANDLED);
115}
116
117/**
118 * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
119 * @irq:
120 * @dev_id: SCSI driver HA context
1da177e4
LT
121 *
122 * Called by system whenever the host adapter generates an interrupt.
123 *
124 * Returns handled flag.
125 */
126irqreturn_t
7d12e780 127qla2300_intr_handler(int irq, void *dev_id)
1da177e4 128{
e315cd28 129 scsi_qla_host_t *vha;
3d71644c 130 struct device_reg_2xxx __iomem *reg;
1da177e4 131 int status;
1da177e4
LT
132 unsigned long iter;
133 uint32_t stat;
1da177e4 134 uint16_t hccr;
9a853f71 135 uint16_t mb[4];
e315cd28
AC
136 struct rsp_que *rsp;
137 struct qla_hw_data *ha;
43fac4d9 138 unsigned long flags;
1da177e4 139
e315cd28
AC
140 rsp = (struct rsp_que *) dev_id;
141 if (!rsp) {
1da177e4 142 printk(KERN_INFO
e315cd28 143 "%s(): NULL response queue pointer\n", __func__);
1da177e4
LT
144 return (IRQ_NONE);
145 }
146
e315cd28 147 ha = rsp->hw;
3d71644c 148 reg = &ha->iobase->isp;
1da177e4
LT
149 status = 0;
150
43fac4d9 151 spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a9 152 vha = pci_get_drvdata(ha->pdev);
1da177e4
LT
153 for (iter = 50; iter--; ) {
154 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
155 if (stat & HSR_RISC_PAUSED) {
85880801 156 if (unlikely(pci_channel_offline(ha->pdev)))
14e660e6
SJ
157 break;
158
1da177e4
LT
159 hccr = RD_REG_WORD(&reg->hccr);
160 if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
07f31805
AV
161 qla_printk(KERN_INFO, ha, "Parity error -- "
162 "HCCR=%x, Dumping firmware!\n", hccr);
1da177e4 163 else
07f31805
AV
164 qla_printk(KERN_INFO, ha, "RISC paused -- "
165 "HCCR=%x, Dumping firmware!\n", hccr);
1da177e4
LT
166
167 /*
168 * Issue a "HARD" reset in order for the RISC
169 * interrupt bit to be cleared. Schedule a big
170 * hammmer to get out of the RISC PAUSED state.
171 */
172 WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
173 RD_REG_WORD(&reg->hccr);
07f31805 174
e315cd28
AC
175 ha->isp_ops->fw_dump(vha, 1);
176 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4
LT
177 break;
178 } else if ((stat & HSR_RISC_INT) == 0)
179 break;
180
1da177e4 181 switch (stat & 0xff) {
1da177e4
LT
182 case 0x1:
183 case 0x2:
184 case 0x10:
185 case 0x11:
e315cd28 186 qla2x00_mbx_completion(vha, MSW(stat));
1da177e4
LT
187 status |= MBX_INTERRUPT;
188
189 /* Release mailbox registers. */
190 WRT_REG_WORD(&reg->semaphore, 0);
191 break;
192 case 0x12:
9a853f71
AV
193 mb[0] = MSW(stat);
194 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
195 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
196 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
73208dfd 197 qla2x00_async_event(vha, rsp, mb);
9a853f71
AV
198 break;
199 case 0x13:
73208dfd 200 qla2x00_process_response_queue(rsp);
1da177e4
LT
201 break;
202 case 0x15:
9a853f71
AV
203 mb[0] = MBA_CMPLT_1_16BIT;
204 mb[1] = MSW(stat);
73208dfd 205 qla2x00_async_event(vha, rsp, mb);
1da177e4
LT
206 break;
207 case 0x16:
9a853f71
AV
208 mb[0] = MBA_SCSI_COMPLETION;
209 mb[1] = MSW(stat);
210 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
73208dfd 211 qla2x00_async_event(vha, rsp, mb);
1da177e4
LT
212 break;
213 default:
214 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
9a853f71 215 "(%d).\n",
e315cd28 216 vha->host_no, stat & 0xff));
1da177e4
LT
217 break;
218 }
219 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
220 RD_REG_WORD_RELAXED(&reg->hccr);
221 }
43fac4d9 222 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1da177e4 223
1da177e4
LT
224 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
225 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1da177e4 226 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0 227 complete(&ha->mbx_intr_comp);
1da177e4
LT
228 }
229
1da177e4
LT
230 return (IRQ_HANDLED);
231}
232
233/**
234 * qla2x00_mbx_completion() - Process mailbox command completions.
235 * @ha: SCSI driver HA context
236 * @mb0: Mailbox0 register
237 */
238static void
e315cd28 239qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
1da177e4
LT
240{
241 uint16_t cnt;
242 uint16_t __iomem *wptr;
e315cd28 243 struct qla_hw_data *ha = vha->hw;
3d71644c 244 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1da177e4
LT
245
246 /* Load return mailbox registers. */
247 ha->flags.mbox_int = 1;
248 ha->mailbox_out[0] = mb0;
249 wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1);
250
251 for (cnt = 1; cnt < ha->mbx_count; cnt++) {
fa2a1ce5 252 if (IS_QLA2200(ha) && cnt == 8)
1da177e4
LT
253 wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
254 if (cnt == 4 || cnt == 5)
255 ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr);
256 else
257 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
fa2a1ce5 258
1da177e4
LT
259 wptr++;
260 }
261
262 if (ha->mcp) {
263 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
e315cd28 264 __func__, vha->host_no, ha->mcp->mb[0]));
1da177e4
LT
265 } else {
266 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
e315cd28 267 __func__, vha->host_no));
1da177e4
LT
268 }
269}
270
8a659571
AV
271static void
272qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
273{
274 static char *event[] =
275 { "Complete", "Request Notification", "Time Extension" };
276 int rval;
277 struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24;
278 uint16_t __iomem *wptr;
279 uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS];
280
281 /* Seed data -- mailbox1 -> mailbox7. */
282 wptr = (uint16_t __iomem *)&reg24->mailbox1;
283 for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++)
284 mb[cnt] = RD_REG_WORD(wptr);
285
286 DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- "
287 "%04x %04x %04x %04x %04x %04x %04x.\n", vha->host_no,
288 event[aen & 0xff],
289 mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6]));
290
291 /* Acknowledgement needed? [Notify && non-zero timeout]. */
292 timeout = (descr >> 8) & 0xf;
293 if (aen != MBA_IDC_NOTIFY || !timeout)
294 return;
295
296 DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- "
297 "ACK timeout=%d.\n", vha->host_no, event[aen & 0xff], timeout));
298
299 rval = qla2x00_post_idc_ack_work(vha, mb);
300 if (rval != QLA_SUCCESS)
301 qla_printk(KERN_WARNING, vha->hw,
302 "IDC failed to post ACK.\n");
303}
304
1da177e4
LT
305/**
306 * qla2x00_async_event() - Process aynchronous events.
307 * @ha: SCSI driver HA context
9a853f71 308 * @mb: Mailbox registers (0 - 3)
1da177e4 309 */
2c3dfe3f 310void
73208dfd 311qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
1da177e4 312{
9a853f71 313#define LS_UNKNOWN 2
3a03eb79 314 static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" };
1da177e4 315 char *link_speed;
1da177e4 316 uint16_t handle_cnt;
bdab23da 317 uint16_t cnt, mbx;
1da177e4 318 uint32_t handles[5];
e315cd28 319 struct qla_hw_data *ha = vha->hw;
3d71644c 320 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
bdab23da 321 struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
1da177e4
LT
322 uint32_t rscn_entry, host_pid;
323 uint8_t rscn_queue_index;
4d4df193 324 unsigned long flags;
1da177e4
LT
325
326 /* Setup to process RIO completion. */
327 handle_cnt = 0;
3a03eb79
AV
328 if (IS_QLA81XX(ha))
329 goto skip_rio;
1da177e4
LT
330 switch (mb[0]) {
331 case MBA_SCSI_COMPLETION:
9a853f71 332 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
1da177e4
LT
333 handle_cnt = 1;
334 break;
335 case MBA_CMPLT_1_16BIT:
9a853f71 336 handles[0] = mb[1];
1da177e4
LT
337 handle_cnt = 1;
338 mb[0] = MBA_SCSI_COMPLETION;
339 break;
340 case MBA_CMPLT_2_16BIT:
9a853f71
AV
341 handles[0] = mb[1];
342 handles[1] = mb[2];
1da177e4
LT
343 handle_cnt = 2;
344 mb[0] = MBA_SCSI_COMPLETION;
345 break;
346 case MBA_CMPLT_3_16BIT:
9a853f71
AV
347 handles[0] = mb[1];
348 handles[1] = mb[2];
349 handles[2] = mb[3];
1da177e4
LT
350 handle_cnt = 3;
351 mb[0] = MBA_SCSI_COMPLETION;
352 break;
353 case MBA_CMPLT_4_16BIT:
9a853f71
AV
354 handles[0] = mb[1];
355 handles[1] = mb[2];
356 handles[2] = mb[3];
1da177e4
LT
357 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
358 handle_cnt = 4;
359 mb[0] = MBA_SCSI_COMPLETION;
360 break;
361 case MBA_CMPLT_5_16BIT:
9a853f71
AV
362 handles[0] = mb[1];
363 handles[1] = mb[2];
364 handles[2] = mb[3];
1da177e4
LT
365 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
366 handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
367 handle_cnt = 5;
368 mb[0] = MBA_SCSI_COMPLETION;
369 break;
370 case MBA_CMPLT_2_32BIT:
9a853f71 371 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
1da177e4
LT
372 handles[1] = le32_to_cpu(
373 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
374 RD_MAILBOX_REG(ha, reg, 6));
375 handle_cnt = 2;
376 mb[0] = MBA_SCSI_COMPLETION;
377 break;
378 default:
379 break;
380 }
3a03eb79 381skip_rio:
1da177e4
LT
382 switch (mb[0]) {
383 case MBA_SCSI_COMPLETION: /* Fast Post */
e315cd28 384 if (!vha->flags.online)
1da177e4
LT
385 break;
386
387 for (cnt = 0; cnt < handle_cnt; cnt++)
73208dfd
AC
388 qla2x00_process_completed_request(vha, rsp->req,
389 handles[cnt]);
1da177e4
LT
390 break;
391
392 case MBA_RESET: /* Reset */
e315cd28
AC
393 DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n",
394 vha->host_no));
1da177e4 395
e315cd28 396 set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
1da177e4
LT
397 break;
398
399 case MBA_SYSTEM_ERR: /* System Error */
bdab23da 400 mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox7) : 0;
1da177e4 401 qla_printk(KERN_INFO, ha,
bdab23da
AV
402 "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
403 "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
1da177e4 404
e315cd28 405 ha->isp_ops->fw_dump(vha, 1);
1da177e4 406
e428924c 407 if (IS_FWI2_CAPABLE(ha)) {
9a853f71
AV
408 if (mb[1] == 0 && mb[2] == 0) {
409 qla_printk(KERN_ERR, ha,
410 "Unrecoverable Hardware Error: adapter "
411 "marked OFFLINE!\n");
e315cd28 412 vha->flags.online = 0;
9a853f71 413 } else
e315cd28 414 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
9a853f71 415 } else if (mb[1] == 0) {
1da177e4
LT
416 qla_printk(KERN_INFO, ha,
417 "Unrecoverable Hardware Error: adapter marked "
418 "OFFLINE!\n");
e315cd28 419 vha->flags.online = 0;
1da177e4 420 } else
e315cd28 421 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4
LT
422 break;
423
424 case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
bdab23da
AV
425 DEBUG2(printk("scsi(%ld): ISP Request Transfer Error (%x).\n",
426 vha->host_no, mb[1]));
427 qla_printk(KERN_WARNING, ha,
428 "ISP Request Transfer Error (%x).\n", mb[1]);
1da177e4 429
e315cd28 430 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4
LT
431 break;
432
433 case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */
434 DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n",
e315cd28 435 vha->host_no));
1da177e4
LT
436 qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
437
e315cd28 438 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4
LT
439 break;
440
441 case MBA_WAKEUP_THRES: /* Request Queue Wake-up */
442 DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n",
e315cd28 443 vha->host_no));
1da177e4
LT
444 break;
445
446 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
e315cd28 447 DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", vha->host_no,
1da177e4 448 mb[1]));
cc3ef7bc 449 qla_printk(KERN_INFO, ha, "LIP occurred (%x).\n", mb[1]);
1da177e4 450
e315cd28
AC
451 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
452 atomic_set(&vha->loop_state, LOOP_DOWN);
453 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
454 qla2x00_mark_all_devices_lost(vha, 1);
1da177e4
LT
455 }
456
e315cd28
AC
457 if (vha->vp_idx) {
458 atomic_set(&vha->vp_state, VP_FAILED);
459 fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f
SJ
460 }
461
e315cd28
AC
462 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
463 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
1da177e4 464
e315cd28
AC
465 vha->flags.management_server_logged_in = 0;
466 qla2x00_post_aen_work(vha, FCH_EVT_LIP, mb[1]);
1da177e4
LT
467 break;
468
469 case MBA_LOOP_UP: /* Loop Up Event */
1da177e4
LT
470 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
471 link_speed = link_speeds[0];
d8b45213 472 ha->link_data_rate = PORT_SPEED_1GB;
1da177e4 473 } else {
9a853f71 474 link_speed = link_speeds[LS_UNKNOWN];
1da177e4
LT
475 if (mb[1] < 5)
476 link_speed = link_speeds[mb[1]];
3a03eb79
AV
477 else if (mb[1] == 0x13)
478 link_speed = link_speeds[5];
1da177e4
LT
479 ha->link_data_rate = mb[1];
480 }
481
482 DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n",
e315cd28 483 vha->host_no, link_speed));
1da177e4
LT
484 qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n",
485 link_speed);
486
e315cd28
AC
487 vha->flags.management_server_logged_in = 0;
488 qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate);
1da177e4
LT
489 break;
490
491 case MBA_LOOP_DOWN: /* Loop Down Event */
bdab23da 492 mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox4) : 0;
4d4df193 493 DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
bdab23da
AV
494 "(%x %x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3],
495 mbx));
496 qla_printk(KERN_INFO, ha,
497 "LOOP DOWN detected (%x %x %x %x).\n", mb[1], mb[2], mb[3],
498 mbx);
1da177e4 499
e315cd28
AC
500 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
501 atomic_set(&vha->loop_state, LOOP_DOWN);
502 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
503 vha->device_flags |= DFLG_NO_CABLE;
504 qla2x00_mark_all_devices_lost(vha, 1);
1da177e4
LT
505 }
506
e315cd28
AC
507 if (vha->vp_idx) {
508 atomic_set(&vha->vp_state, VP_FAILED);
509 fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f
SJ
510 }
511
e315cd28 512 vha->flags.management_server_logged_in = 0;
d8b45213 513 ha->link_data_rate = PORT_SPEED_UNKNOWN;
e315cd28 514 qla2x00_post_aen_work(vha, FCH_EVT_LINKDOWN, 0);
1da177e4
LT
515 break;
516
517 case MBA_LIP_RESET: /* LIP reset occurred */
1da177e4 518 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
e315cd28 519 vha->host_no, mb[1]));
1da177e4 520 qla_printk(KERN_INFO, ha,
cc3ef7bc 521 "LIP reset occurred (%x).\n", mb[1]);
1da177e4 522
e315cd28
AC
523 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
524 atomic_set(&vha->loop_state, LOOP_DOWN);
525 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
526 qla2x00_mark_all_devices_lost(vha, 1);
1da177e4
LT
527 }
528
e315cd28
AC
529 if (vha->vp_idx) {
530 atomic_set(&vha->vp_state, VP_FAILED);
531 fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f
SJ
532 }
533
e315cd28 534 set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
1da177e4
LT
535
536 ha->operating_mode = LOOP;
e315cd28
AC
537 vha->flags.management_server_logged_in = 0;
538 qla2x00_post_aen_work(vha, FCH_EVT_LIPRESET, mb[1]);
1da177e4
LT
539 break;
540
3a03eb79 541 /* case MBA_DCBX_COMPLETE: */
1da177e4
LT
542 case MBA_POINT_TO_POINT: /* Point-to-Point */
543 if (IS_QLA2100(ha))
544 break;
545
3a03eb79
AV
546 if (IS_QLA81XX(ha))
547 DEBUG2(printk("scsi(%ld): DCBX Completed -- %04x %04x "
548 "%04x\n", vha->host_no, mb[1], mb[2], mb[3]));
549 else
550 DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE "
551 "received.\n", vha->host_no));
1da177e4
LT
552
553 /*
554 * Until there's a transition from loop down to loop up, treat
555 * this as loop down only.
556 */
e315cd28
AC
557 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
558 atomic_set(&vha->loop_state, LOOP_DOWN);
559 if (!atomic_read(&vha->loop_down_timer))
560 atomic_set(&vha->loop_down_timer,
1da177e4 561 LOOP_DOWN_TIME);
e315cd28 562 qla2x00_mark_all_devices_lost(vha, 1);
1da177e4
LT
563 }
564
e315cd28
AC
565 if (vha->vp_idx) {
566 atomic_set(&vha->vp_state, VP_FAILED);
567 fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f
SJ
568 }
569
e315cd28
AC
570 if (!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)))
571 set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
572
573 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
574 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
4346b149
AV
575
576 ha->flags.gpsc_supported = 1;
e315cd28 577 vha->flags.management_server_logged_in = 0;
1da177e4
LT
578 break;
579
580 case MBA_CHG_IN_CONNECTION: /* Change in connection mode */
581 if (IS_QLA2100(ha))
582 break;
583
1da177e4
LT
584 DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
585 "received.\n",
e315cd28 586 vha->host_no));
1da177e4
LT
587 qla_printk(KERN_INFO, ha,
588 "Configuration change detected: value=%x.\n", mb[1]);
589
e315cd28
AC
590 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
591 atomic_set(&vha->loop_state, LOOP_DOWN);
592 if (!atomic_read(&vha->loop_down_timer))
593 atomic_set(&vha->loop_down_timer,
1da177e4 594 LOOP_DOWN_TIME);
e315cd28 595 qla2x00_mark_all_devices_lost(vha, 1);
1da177e4
LT
596 }
597
e315cd28
AC
598 if (vha->vp_idx) {
599 atomic_set(&vha->vp_state, VP_FAILED);
600 fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f
SJ
601 }
602
e315cd28
AC
603 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
604 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
1da177e4
LT
605 break;
606
607 case MBA_PORT_UPDATE: /* Port database update */
55903b9d
SV
608 /*
609 * Handle only global and vn-port update events
610 *
611 * Relevant inputs:
612 * mb[1] = N_Port handle of changed port
613 * OR 0xffff for global event
614 * mb[2] = New login state
615 * 7 = Port logged out
616 * mb[3] = LSB is vp_idx, 0xff = all vps
617 *
618 * Skip processing if:
619 * Event is global, vp_idx is NOT all vps,
620 * vp_idx does not match
621 * Event is not global, vp_idx does not match
622 */
12cec63e
AV
623 if (IS_QLA2XXX_MIDTYPE(ha) &&
624 ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff) ||
625 (mb[1] != 0xffff)) && vha->vp_idx != (mb[3] & 0xff))
626 break;
73208dfd 627
9764ff88
AV
628 /* Global event -- port logout or port unavailable. */
629 if (mb[1] == 0xffff && mb[2] == 0x7) {
630 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
631 vha->host_no));
632 DEBUG(printk(KERN_INFO
633 "scsi(%ld): Port unavailable %04x %04x %04x.\n",
634 vha->host_no, mb[1], mb[2], mb[3]));
635
636 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
637 atomic_set(&vha->loop_state, LOOP_DOWN);
638 atomic_set(&vha->loop_down_timer,
639 LOOP_DOWN_TIME);
640 vha->device_flags |= DFLG_NO_CABLE;
641 qla2x00_mark_all_devices_lost(vha, 1);
642 }
643
644 if (vha->vp_idx) {
645 atomic_set(&vha->vp_state, VP_FAILED);
646 fc_vport_set_state(vha->fc_vport,
647 FC_VPORT_FAILED);
faadc5e7 648 qla2x00_mark_all_devices_lost(vha, 1);
9764ff88
AV
649 }
650
651 vha->flags.management_server_logged_in = 0;
652 ha->link_data_rate = PORT_SPEED_UNKNOWN;
653 break;
654 }
655
1da177e4 656 /*
cc3ef7bc 657 * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
1da177e4
LT
658 * event etc. earlier indicating loop is down) then process
659 * it. Otherwise ignore it and Wait for RSCN to come in.
660 */
e315cd28
AC
661 atomic_set(&vha->loop_down_timer, 0);
662 if (atomic_read(&vha->loop_state) != LOOP_DOWN &&
663 atomic_read(&vha->loop_state) != LOOP_DEAD) {
1da177e4 664 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
e315cd28 665 "ignored %04x/%04x/%04x.\n", vha->host_no, mb[1],
9a853f71 666 mb[2], mb[3]));
1da177e4
LT
667 break;
668 }
669
670 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
e315cd28 671 vha->host_no));
1da177e4 672 DEBUG(printk(KERN_INFO
9a853f71 673 "scsi(%ld): Port database changed %04x %04x %04x.\n",
e315cd28 674 vha->host_no, mb[1], mb[2], mb[3]));
1da177e4
LT
675
676 /*
677 * Mark all devices as missing so we will login again.
678 */
e315cd28 679 atomic_set(&vha->loop_state, LOOP_UP);
1da177e4 680
e315cd28 681 qla2x00_mark_all_devices_lost(vha, 1);
1da177e4 682
e315cd28 683 vha->flags.rscn_queue_overflow = 1;
1da177e4 684
e315cd28
AC
685 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
686 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
1da177e4
LT
687 break;
688
689 case MBA_RSCN_UPDATE: /* State Change Registration */
3c397400 690 /* Check if the Vport has issued a SCR */
e315cd28 691 if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags))
3c397400
SJ
692 break;
693 /* Only handle SCNs for our Vport index. */
0d6e61bc 694 if (ha->flags.npiv_supported && vha->vp_idx != (mb[3] & 0xff))
3c397400 695 break;
0d6e61bc 696
1da177e4 697 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
e315cd28 698 vha->host_no));
1da177e4 699 DEBUG(printk(KERN_INFO
f4a8dbc7 700 "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n",
e315cd28 701 vha->host_no, mb[1], mb[2], mb[3]));
1da177e4 702
59d72d87 703 rscn_entry = ((mb[1] & 0xff) << 16) | mb[2];
e315cd28
AC
704 host_pid = (vha->d_id.b.domain << 16) | (vha->d_id.b.area << 8)
705 | vha->d_id.b.al_pa;
1da177e4
LT
706 if (rscn_entry == host_pid) {
707 DEBUG(printk(KERN_INFO
708 "scsi(%ld): Ignoring RSCN update to local host "
709 "port ID (%06x)\n",
e315cd28 710 vha->host_no, host_pid));
1da177e4
LT
711 break;
712 }
713
59d72d87
RA
714 /* Ignore reserved bits from RSCN-payload. */
715 rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
e315cd28 716 rscn_queue_index = vha->rscn_in_ptr + 1;
1da177e4
LT
717 if (rscn_queue_index == MAX_RSCN_COUNT)
718 rscn_queue_index = 0;
e315cd28
AC
719 if (rscn_queue_index != vha->rscn_out_ptr) {
720 vha->rscn_queue[vha->rscn_in_ptr] = rscn_entry;
721 vha->rscn_in_ptr = rscn_queue_index;
1da177e4 722 } else {
e315cd28 723 vha->flags.rscn_queue_overflow = 1;
1da177e4
LT
724 }
725
e315cd28
AC
726 atomic_set(&vha->loop_state, LOOP_UPDATE);
727 atomic_set(&vha->loop_down_timer, 0);
728 vha->flags.management_server_logged_in = 0;
1da177e4 729
e315cd28
AC
730 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
731 set_bit(RSCN_UPDATE, &vha->dpc_flags);
732 qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry);
1da177e4
LT
733 break;
734
735 /* case MBA_RIO_RESPONSE: */
736 case MBA_ZIO_RESPONSE:
3fd67cdf 737 DEBUG3(printk("scsi(%ld): [R|Z]IO update completion.\n",
e315cd28 738 vha->host_no));
1da177e4 739
e428924c 740 if (IS_FWI2_CAPABLE(ha))
2afa19a9 741 qla24xx_process_response_queue(vha, rsp);
4fdfefe5 742 else
73208dfd 743 qla2x00_process_response_queue(rsp);
1da177e4 744 break;
9a853f71
AV
745
746 case MBA_DISCARD_RND_FRAME:
747 DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
e315cd28 748 "%04x.\n", vha->host_no, mb[1], mb[2], mb[3]));
9a853f71 749 break;
45ebeb56
AV
750
751 case MBA_TRACE_NOTIFICATION:
752 DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n",
e315cd28 753 vha->host_no, mb[1], mb[2]));
45ebeb56 754 break;
4d4df193
HK
755
756 case MBA_ISP84XX_ALERT:
757 DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- "
e315cd28 758 "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3]));
4d4df193
HK
759
760 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
761 switch (mb[1]) {
762 case A84_PANIC_RECOVERY:
763 qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery "
764 "%04x %04x\n", mb[2], mb[3]);
765 break;
766 case A84_OP_LOGIN_COMPLETE:
767 ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2];
768 DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:"
769 "firmware version %x\n", ha->cs84xx->op_fw_version));
770 break;
771 case A84_DIAG_LOGIN_COMPLETE:
772 ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
773 DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:"
774 "diagnostic firmware version %x\n",
775 ha->cs84xx->diag_fw_version));
776 break;
777 case A84_GOLD_LOGIN_COMPLETE:
778 ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
779 ha->cs84xx->fw_update = 1;
780 DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold "
781 "firmware version %x\n",
782 ha->cs84xx->gold_fw_version));
783 break;
784 default:
785 qla_printk(KERN_ERR, ha,
786 "Alert 84xx: Invalid Alert %04x %04x %04x\n",
787 mb[1], mb[2], mb[3]);
788 }
789 spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags);
790 break;
3a03eb79
AV
791 case MBA_DCBX_START:
792 DEBUG2(printk("scsi(%ld): DCBX Started -- %04x %04x %04x\n",
793 vha->host_no, mb[1], mb[2], mb[3]));
794 break;
795 case MBA_DCBX_PARAM_UPDATE:
796 DEBUG2(printk("scsi(%ld): DCBX Parameters Updated -- "
797 "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3]));
798 break;
799 case MBA_FCF_CONF_ERR:
800 DEBUG2(printk("scsi(%ld): FCF Configuration Error -- "
801 "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3]));
802 break;
803 case MBA_IDC_COMPLETE:
3a03eb79 804 case MBA_IDC_NOTIFY:
3a03eb79 805 case MBA_IDC_TIME_EXT:
8a659571 806 qla81xx_idc_event(vha, mb[0], mb[1]);
3a03eb79 807 break;
1da177e4 808 }
2c3dfe3f 809
e315cd28 810 if (!vha->vp_idx && ha->num_vhosts)
73208dfd 811 qla2x00_alert_all_vps(rsp, mb);
1da177e4
LT
812}
813
814/**
815 * qla2x00_process_completed_request() - Process a Fast Post response.
816 * @ha: SCSI driver HA context
817 * @index: SRB index
818 */
819static void
73208dfd
AC
820qla2x00_process_completed_request(struct scsi_qla_host *vha,
821 struct req_que *req, uint32_t index)
1da177e4
LT
822{
823 srb_t *sp;
e315cd28 824 struct qla_hw_data *ha = vha->hw;
1da177e4
LT
825
826 /* Validate handle. */
827 if (index >= MAX_OUTSTANDING_COMMANDS) {
828 DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n",
e315cd28 829 vha->host_no, index));
1da177e4
LT
830 qla_printk(KERN_WARNING, ha,
831 "Invalid SCSI completion handle %d.\n", index);
832
e315cd28 833 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4
LT
834 return;
835 }
836
e315cd28 837 sp = req->outstanding_cmds[index];
1da177e4
LT
838 if (sp) {
839 /* Free outstanding command slot. */
e315cd28 840 req->outstanding_cmds[index] = NULL;
1da177e4 841
1da177e4
LT
842 /* Save ISP completion status */
843 sp->cmd->result = DID_OK << 16;
73208dfd 844 qla2x00_sp_compl(ha, sp);
1da177e4 845 } else {
2afa19a9
AC
846 DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion"
847 " handle(%d)\n", vha->host_no, req->id, index));
1da177e4
LT
848 qla_printk(KERN_WARNING, ha,
849 "Invalid ISP SCSI completion handle\n");
850
e315cd28 851 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4
LT
852 }
853}
854
ac280b67
AV
855static srb_t *
856qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
857 struct req_que *req, void *iocb)
858{
859 struct qla_hw_data *ha = vha->hw;
860 sts_entry_t *pkt = iocb;
861 srb_t *sp = NULL;
862 uint16_t index;
863
864 index = LSW(pkt->handle);
865 if (index >= MAX_OUTSTANDING_COMMANDS) {
866 qla_printk(KERN_WARNING, ha,
867 "%s: Invalid completion handle (%x).\n", func, index);
868 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
869 goto done;
870 }
871 sp = req->outstanding_cmds[index];
872 if (!sp) {
873 qla_printk(KERN_WARNING, ha,
874 "%s: Invalid completion handle (%x) -- timed-out.\n", func,
875 index);
876 return sp;
877 }
878 if (sp->handle != index) {
879 qla_printk(KERN_WARNING, ha,
880 "%s: SRB handle (%x) mismatch %x.\n", func, sp->handle,
881 index);
882 return NULL;
883 }
9a069e19 884
ac280b67 885 req->outstanding_cmds[index] = NULL;
9a069e19 886
ac280b67
AV
887done:
888 return sp;
889}
890
891static void
892qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
893 struct mbx_entry *mbx)
894{
895 const char func[] = "MBX-IOCB";
896 const char *type;
897 struct qla_hw_data *ha = vha->hw;
898 fc_port_t *fcport;
899 srb_t *sp;
900 struct srb_logio *lio;
901 uint16_t data[2];
902
903 sp = qla2x00_get_sp_from_handle(vha, func, req, mbx);
904 if (!sp)
905 return;
906
907 type = NULL;
908 lio = sp->ctx;
909 switch (lio->ctx.type) {
910 case SRB_LOGIN_CMD:
911 type = "login";
912 break;
913 case SRB_LOGOUT_CMD:
914 type = "logout";
915 break;
916 default:
917 qla_printk(KERN_WARNING, ha,
918 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
919 lio->ctx.type);
920 return;
921 }
922
923 del_timer(&lio->ctx.timer);
924 fcport = sp->fcport;
925
926 data[0] = data[1] = 0;
927 if (mbx->entry_status) {
928 DEBUG2(printk(KERN_WARNING
929 "scsi(%ld:%x): Async-%s error entry - entry-status=%x "
930 "status=%x state-flag=%x status-flags=%x.\n",
931 fcport->vha->host_no, sp->handle, type,
932 mbx->entry_status, le16_to_cpu(mbx->status),
933 le16_to_cpu(mbx->state_flags),
934 le16_to_cpu(mbx->status_flags)));
935 DEBUG2(qla2x00_dump_buffer((uint8_t *)mbx, sizeof(*mbx)));
936
937 data[0] = MBS_COMMAND_ERROR;
938 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
939 QLA_LOGIO_LOGIN_RETRIED: 0;
940 goto done_post_logio_done_work;
941 }
942
943 if (!mbx->status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
944 DEBUG2(printk(KERN_DEBUG
945 "scsi(%ld:%x): Async-%s complete - mbx1=%x.\n",
946 fcport->vha->host_no, sp->handle, type,
947 le16_to_cpu(mbx->mb1)));
948
949 data[0] = MBS_COMMAND_COMPLETE;
950 if (lio->ctx.type == SRB_LOGIN_CMD && le16_to_cpu(mbx->mb1) & BIT_1)
8474f3a0 951 fcport->flags |= FCF_FCP2_DEVICE;
ac280b67
AV
952
953 goto done_post_logio_done_work;
954 }
955
956 data[0] = le16_to_cpu(mbx->mb0);
957 switch (data[0]) {
958 case MBS_PORT_ID_USED:
959 data[1] = le16_to_cpu(mbx->mb1);
960 break;
961 case MBS_LOOP_ID_USED:
962 break;
963 default:
964 data[0] = MBS_COMMAND_ERROR;
965 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
966 QLA_LOGIO_LOGIN_RETRIED: 0;
967 break;
968 }
969
970 DEBUG2(printk(KERN_WARNING
971 "scsi(%ld:%x): Async-%s failed - status=%x mb0=%x mb1=%x mb2=%x "
972 "mb6=%x mb7=%x.\n",
973 fcport->vha->host_no, sp->handle, type, le16_to_cpu(mbx->status),
974 le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1),
975 le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6),
976 le16_to_cpu(mbx->mb7)));
977
978done_post_logio_done_work:
979 lio->ctx.type == SRB_LOGIN_CMD ?
980 qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
981 qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
982
983 lio->ctx.free(sp);
984}
985
9a069e19
GM
986static void
987qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
988 struct sts_entry_24xx *pkt, int iocb_type)
989{
990 const char func[] = "ELS_CT_IOCB";
991 const char *type;
992 struct qla_hw_data *ha = vha->hw;
993 srb_t *sp;
994 struct srb_bsg *sp_bsg;
995 struct fc_bsg_job *bsg_job;
996 uint16_t comp_status;
997 uint32_t fw_status[3];
998 uint8_t* fw_sts_ptr;
999
1000 sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
1001 if (!sp)
1002 return;
1003 sp_bsg = (struct srb_bsg*)sp->ctx;
1004 bsg_job = sp_bsg->bsg_job;
1005
1006 type = NULL;
1007 switch (sp_bsg->ctx.type) {
1008 case SRB_ELS_CMD_RPT:
1009 case SRB_ELS_CMD_HST:
1010 type = "els";
1011 break;
1012 case SRB_CT_CMD:
1013 type = "ct pass-through";
1014 break;
1015 default:
1016 qla_printk(KERN_WARNING, ha,
1017 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
1018 sp_bsg->ctx.type);
1019 return;
1020 }
1021
1022 comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status);
1023 fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1);
1024 fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2);
1025
1026 /* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
1027 * fc payload to the caller
1028 */
1029 bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
1030 bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status);
1031
1032 if (comp_status != CS_COMPLETE) {
1033 if (comp_status == CS_DATA_UNDERRUN) {
1034 bsg_job->reply->result = DID_OK << 16;
1035 bsg_job->reply->reply_payload_rcv_len =
1036 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
1037
1038 DEBUG2(qla_printk(KERN_WARNING, ha,
1039 "scsi(%ld:0x%x): ELS-CT pass-through-%s error comp_status-status=0x%x "
1040 "error subcode 1=0x%x error subcode 2=0x%x total_byte = 0x%x.\n",
1041 vha->host_no, sp->handle, type, comp_status, fw_status[1], fw_status[2],
1042 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count)));
1043 fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
1044 memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
1045 }
1046 else {
1047 DEBUG2(qla_printk(KERN_WARNING, ha,
1048 "scsi(%ld:0x%x): ELS-CT pass-through-%s error comp_status-status=0x%x "
1049 "error subcode 1=0x%x error subcode 2=0x%x.\n",
1050 vha->host_no, sp->handle, type, comp_status,
1051 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1),
1052 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2)));
1053 bsg_job->reply->result = DID_ERROR << 16;
1054 bsg_job->reply->reply_payload_rcv_len = 0;
1055 fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
1056 memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
1057 }
1058 DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
1059 }
1060 else {
1061 bsg_job->reply->result = DID_OK << 16;;
1062 bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
1063 bsg_job->reply_len = 0;
1064 }
1065
1066 dma_unmap_sg(&ha->pdev->dev,
1067 bsg_job->request_payload.sg_list,
1068 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1069 dma_unmap_sg(&ha->pdev->dev,
1070 bsg_job->reply_payload.sg_list,
1071 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1072 if ((sp_bsg->ctx.type == SRB_ELS_CMD_HST) ||
1073 (sp_bsg->ctx.type == SRB_CT_CMD))
1074 kfree(sp->fcport);
1075 kfree(sp->ctx);
1076 mempool_free(sp, ha->srb_mempool);
1077 bsg_job->job_done(bsg_job);
1078}
1079
ac280b67
AV
1080static void
1081qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
1082 struct logio_entry_24xx *logio)
1083{
1084 const char func[] = "LOGIO-IOCB";
1085 const char *type;
1086 struct qla_hw_data *ha = vha->hw;
1087 fc_port_t *fcport;
1088 srb_t *sp;
1089 struct srb_logio *lio;
1090 uint16_t data[2];
1091 uint32_t iop[2];
1092
1093 sp = qla2x00_get_sp_from_handle(vha, func, req, logio);
1094 if (!sp)
1095 return;
1096
1097 type = NULL;
1098 lio = sp->ctx;
1099 switch (lio->ctx.type) {
1100 case SRB_LOGIN_CMD:
1101 type = "login";
1102 break;
1103 case SRB_LOGOUT_CMD:
1104 type = "logout";
1105 break;
1106 default:
1107 qla_printk(KERN_WARNING, ha,
1108 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
1109 lio->ctx.type);
1110 return;
1111 }
1112
1113 del_timer(&lio->ctx.timer);
1114 fcport = sp->fcport;
1115
1116 data[0] = data[1] = 0;
1117 if (logio->entry_status) {
1118 DEBUG2(printk(KERN_WARNING
1119 "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n",
1120 fcport->vha->host_no, sp->handle, type,
1121 logio->entry_status));
1122 DEBUG2(qla2x00_dump_buffer((uint8_t *)logio, sizeof(*logio)));
1123
1124 data[0] = MBS_COMMAND_ERROR;
1125 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1126 QLA_LOGIO_LOGIN_RETRIED: 0;
1127 goto done_post_logio_done_work;
1128 }
1129
1130 if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
1131 DEBUG2(printk(KERN_DEBUG
1132 "scsi(%ld:%x): Async-%s complete - iop0=%x.\n",
1133 fcport->vha->host_no, sp->handle, type,
1134 le32_to_cpu(logio->io_parameter[0])));
1135
1136 data[0] = MBS_COMMAND_COMPLETE;
1137 if (lio->ctx.type == SRB_LOGOUT_CMD)
1138 goto done_post_logio_done_work;
1139
1140 iop[0] = le32_to_cpu(logio->io_parameter[0]);
1141 if (iop[0] & BIT_4) {
1142 fcport->port_type = FCT_TARGET;
1143 if (iop[0] & BIT_8)
8474f3a0 1144 fcport->flags |= FCF_FCP2_DEVICE;
ac280b67
AV
1145 }
1146 if (iop[0] & BIT_5)
1147 fcport->port_type = FCT_INITIATOR;
1148 if (logio->io_parameter[7] || logio->io_parameter[8])
1149 fcport->supported_classes |= FC_COS_CLASS2;
1150 if (logio->io_parameter[9] || logio->io_parameter[10])
1151 fcport->supported_classes |= FC_COS_CLASS3;
1152
1153 goto done_post_logio_done_work;
1154 }
1155
1156 iop[0] = le32_to_cpu(logio->io_parameter[0]);
1157 iop[1] = le32_to_cpu(logio->io_parameter[1]);
1158 switch (iop[0]) {
1159 case LSC_SCODE_PORTID_USED:
1160 data[0] = MBS_PORT_ID_USED;
1161 data[1] = LSW(iop[1]);
1162 break;
1163 case LSC_SCODE_NPORT_USED:
1164 data[0] = MBS_LOOP_ID_USED;
1165 break;
1166 case LSC_SCODE_CMD_FAILED:
1167 if ((iop[1] & 0xff) == 0x05) {
1168 data[0] = MBS_NOT_LOGGED_IN;
1169 break;
1170 }
1171 /* Fall through. */
1172 default:
1173 data[0] = MBS_COMMAND_ERROR;
1174 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1175 QLA_LOGIO_LOGIN_RETRIED: 0;
1176 break;
1177 }
1178
1179 DEBUG2(printk(KERN_WARNING
1180 "scsi(%ld:%x): Async-%s failed - comp=%x iop0=%x iop1=%x.\n",
1181 fcport->vha->host_no, sp->handle, type,
1182 le16_to_cpu(logio->comp_status),
1183 le32_to_cpu(logio->io_parameter[0]),
1184 le32_to_cpu(logio->io_parameter[1])));
1185
1186done_post_logio_done_work:
1187 lio->ctx.type == SRB_LOGIN_CMD ?
1188 qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
1189 qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
1190
1191 lio->ctx.free(sp);
1192}
1193
1da177e4
LT
1194/**
1195 * qla2x00_process_response_queue() - Process response queue entries.
1196 * @ha: SCSI driver HA context
1197 */
1198void
73208dfd 1199qla2x00_process_response_queue(struct rsp_que *rsp)
1da177e4 1200{
73208dfd
AC
1201 struct scsi_qla_host *vha;
1202 struct qla_hw_data *ha = rsp->hw;
3d71644c 1203 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1da177e4
LT
1204 sts_entry_t *pkt;
1205 uint16_t handle_cnt;
1206 uint16_t cnt;
73208dfd 1207
2afa19a9 1208 vha = pci_get_drvdata(ha->pdev);
1da177e4 1209
e315cd28 1210 if (!vha->flags.online)
1da177e4
LT
1211 return;
1212
e315cd28
AC
1213 while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
1214 pkt = (sts_entry_t *)rsp->ring_ptr;
1da177e4 1215
e315cd28
AC
1216 rsp->ring_index++;
1217 if (rsp->ring_index == rsp->length) {
1218 rsp->ring_index = 0;
1219 rsp->ring_ptr = rsp->ring;
1da177e4 1220 } else {
e315cd28 1221 rsp->ring_ptr++;
1da177e4
LT
1222 }
1223
1224 if (pkt->entry_status != 0) {
1225 DEBUG3(printk(KERN_INFO
e315cd28 1226 "scsi(%ld): Process error entry.\n", vha->host_no));
1da177e4 1227
73208dfd 1228 qla2x00_error_entry(vha, rsp, pkt);
1da177e4
LT
1229 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1230 wmb();
1231 continue;
1232 }
1233
1234 switch (pkt->entry_type) {
1235 case STATUS_TYPE:
73208dfd 1236 qla2x00_status_entry(vha, rsp, pkt);
1da177e4
LT
1237 break;
1238 case STATUS_TYPE_21:
1239 handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
1240 for (cnt = 0; cnt < handle_cnt; cnt++) {
73208dfd 1241 qla2x00_process_completed_request(vha, rsp->req,
1da177e4
LT
1242 ((sts21_entry_t *)pkt)->handle[cnt]);
1243 }
1244 break;
1245 case STATUS_TYPE_22:
1246 handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
1247 for (cnt = 0; cnt < handle_cnt; cnt++) {
73208dfd 1248 qla2x00_process_completed_request(vha, rsp->req,
1da177e4
LT
1249 ((sts22_entry_t *)pkt)->handle[cnt]);
1250 }
1251 break;
1252 case STATUS_CONT_TYPE:
2afa19a9 1253 qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
1da177e4 1254 break;
ac280b67
AV
1255 case MBX_IOCB_TYPE:
1256 qla2x00_mbx_iocb_entry(vha, rsp->req,
1257 (struct mbx_entry *)pkt);
1da177e4
LT
1258 default:
1259 /* Type Not Supported. */
1260 DEBUG4(printk(KERN_WARNING
1261 "scsi(%ld): Received unknown response pkt type %x "
1262 "entry status=%x.\n",
e315cd28 1263 vha->host_no, pkt->entry_type, pkt->entry_status));
1da177e4
LT
1264 break;
1265 }
1266 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1267 wmb();
1268 }
1269
1270 /* Adjust ring index */
e315cd28 1271 WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), rsp->ring_index);
1da177e4
LT
1272}
1273
4733fcb1 1274static inline void
2afa19a9
AC
1275qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len,
1276 struct rsp_que *rsp)
4733fcb1
AV
1277{
1278 struct scsi_cmnd *cp = sp->cmd;
1279
1280 if (sense_len >= SCSI_SENSE_BUFFERSIZE)
1281 sense_len = SCSI_SENSE_BUFFERSIZE;
1282
4733fcb1
AV
1283 sp->request_sense_length = sense_len;
1284 sp->request_sense_ptr = cp->sense_buffer;
1285 if (sp->request_sense_length > 32)
1286 sense_len = 32;
1287
1288 memcpy(cp->sense_buffer, sense_data, sense_len);
1289
1290 sp->request_sense_ptr += sense_len;
1291 sp->request_sense_length -= sense_len;
1292 if (sp->request_sense_length != 0)
2afa19a9 1293 rsp->status_srb = sp;
4733fcb1
AV
1294
1295 DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) "
e315cd28 1296 "cmd=%p pid=%ld\n", __func__, sp->fcport->vha->host_no,
19851f13
AV
1297 cp->device->channel, cp->device->id, cp->device->lun, cp,
1298 cp->serial_number));
4733fcb1 1299 if (sense_len)
ddb9b126 1300 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, sense_len));
4733fcb1
AV
1301}
1302
1da177e4
LT
1303/**
1304 * qla2x00_status_entry() - Process a Status IOCB entry.
1305 * @ha: SCSI driver HA context
1306 * @pkt: Entry pointer
1307 */
1308static void
73208dfd 1309qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1da177e4 1310{
1da177e4 1311 srb_t *sp;
1da177e4
LT
1312 fc_port_t *fcport;
1313 struct scsi_cmnd *cp;
9a853f71
AV
1314 sts_entry_t *sts;
1315 struct sts_entry_24xx *sts24;
1da177e4
LT
1316 uint16_t comp_status;
1317 uint16_t scsi_status;
1318 uint8_t lscsi_status;
1319 int32_t resid;
ed17c71b 1320 uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len;
9a853f71 1321 uint8_t *rsp_info, *sense_data;
e315cd28 1322 struct qla_hw_data *ha = vha->hw;
2afa19a9
AC
1323 uint32_t handle;
1324 uint16_t que;
1325 struct req_que *req;
9a853f71
AV
1326
1327 sts = (sts_entry_t *) pkt;
1328 sts24 = (struct sts_entry_24xx *) pkt;
e428924c 1329 if (IS_FWI2_CAPABLE(ha)) {
9a853f71
AV
1330 comp_status = le16_to_cpu(sts24->comp_status);
1331 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
1332 } else {
1333 comp_status = le16_to_cpu(sts->comp_status);
1334 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
1335 }
2afa19a9
AC
1336 handle = (uint32_t) LSW(sts->handle);
1337 que = MSW(sts->handle);
1338 req = ha->req_q_map[que];
1da177e4 1339 /* Fast path completion. */
9a853f71 1340 if (comp_status == CS_COMPLETE && scsi_status == 0) {
2afa19a9 1341 qla2x00_process_completed_request(vha, req, handle);
1da177e4
LT
1342
1343 return;
1344 }
1345
1346 /* Validate handle. */
2afa19a9
AC
1347 if (handle < MAX_OUTSTANDING_COMMANDS) {
1348 sp = req->outstanding_cmds[handle];
1349 req->outstanding_cmds[handle] = NULL;
1da177e4
LT
1350 } else
1351 sp = NULL;
1352
1353 if (sp == NULL) {
1354 DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
e315cd28 1355 vha->host_no));
1da177e4
LT
1356 qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
1357
e315cd28
AC
1358 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1359 qla2xxx_wake_dpc(vha);
1da177e4
LT
1360 return;
1361 }
1362 cp = sp->cmd;
1363 if (cp == NULL) {
1364 DEBUG2(printk("scsi(%ld): Command already returned back to OS "
2afa19a9 1365 "pkt->handle=%d sp=%p.\n", vha->host_no, handle, sp));
1da177e4
LT
1366 qla_printk(KERN_WARNING, ha,
1367 "Command is NULL: already returned to OS (sp=%p)\n", sp);
1368
1369 return;
1370 }
1371
9a853f71 1372 lscsi_status = scsi_status & STATUS_MASK;
1da177e4 1373
bdf79621 1374 fcport = sp->fcport;
1da177e4 1375
ed17c71b 1376 sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
e428924c 1377 if (IS_FWI2_CAPABLE(ha)) {
0f00a206
LC
1378 if (scsi_status & SS_SENSE_LEN_VALID)
1379 sense_len = le32_to_cpu(sts24->sense_len);
1380 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
1381 rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
1382 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER))
1383 resid_len = le32_to_cpu(sts24->rsp_residual_count);
1384 if (comp_status == CS_DATA_UNDERRUN)
1385 fw_resid_len = le32_to_cpu(sts24->residual_len);
9a853f71
AV
1386 rsp_info = sts24->data;
1387 sense_data = sts24->data;
1388 host_to_fcp_swap(sts24->data, sizeof(sts24->data));
1389 } else {
0f00a206
LC
1390 if (scsi_status & SS_SENSE_LEN_VALID)
1391 sense_len = le16_to_cpu(sts->req_sense_length);
1392 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
1393 rsp_info_len = le16_to_cpu(sts->rsp_info_len);
9a853f71
AV
1394 resid_len = le32_to_cpu(sts->residual_length);
1395 rsp_info = sts->rsp_info;
1396 sense_data = sts->req_sense_data;
1397 }
1398
1da177e4
LT
1399 /* Check for any FCP transport errors. */
1400 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
9a853f71 1401 /* Sense data lies beyond any FCP RESPONSE data. */
e428924c 1402 if (IS_FWI2_CAPABLE(ha))
9a853f71
AV
1403 sense_data += rsp_info_len;
1404 if (rsp_info_len > 3 && rsp_info[3]) {
1da177e4
LT
1405 DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
1406 "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
e315cd28 1407 "retrying command\n", vha->host_no,
9a853f71
AV
1408 cp->device->channel, cp->device->id,
1409 cp->device->lun, rsp_info_len, rsp_info[0],
1410 rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
1411 rsp_info[5], rsp_info[6], rsp_info[7]));
1da177e4
LT
1412
1413 cp->result = DID_BUS_BUSY << 16;
73208dfd 1414 qla2x00_sp_compl(ha, sp);
1da177e4
LT
1415 return;
1416 }
1417 }
1418
3e8ce320
AV
1419 /* Check for overrun. */
1420 if (IS_FWI2_CAPABLE(ha) && comp_status == CS_COMPLETE &&
1421 scsi_status & SS_RESIDUAL_OVER)
1422 comp_status = CS_DATA_OVERRUN;
1423
1da177e4
LT
1424 /*
1425 * Based on Host and scsi status generate status code for Linux
1426 */
1427 switch (comp_status) {
1428 case CS_COMPLETE:
df7baa50 1429 case CS_QUEUE_FULL:
1da177e4
LT
1430 if (scsi_status == 0) {
1431 cp->result = DID_OK << 16;
1432 break;
1433 }
1434 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
9a853f71 1435 resid = resid_len;
385d70b4 1436 scsi_set_resid(cp, resid);
0da69df1
AV
1437
1438 if (!lscsi_status &&
385d70b4 1439 ((unsigned)(scsi_bufflen(cp) - resid) <
0da69df1
AV
1440 cp->underflow)) {
1441 qla_printk(KERN_INFO, ha,
385d70b4
FT
1442 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1443 "detected (%x of %x bytes)...returning "
e315cd28 1444 "error status.\n", vha->host_no,
385d70b4
FT
1445 cp->device->channel, cp->device->id,
1446 cp->device->lun, resid,
1447 scsi_bufflen(cp));
0da69df1
AV
1448
1449 cp->result = DID_ERROR << 16;
1450 break;
1451 }
1da177e4 1452 }
1da177e4
LT
1453 cp->result = DID_OK << 16 | lscsi_status;
1454
df7baa50
AV
1455 if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
1456 DEBUG2(printk(KERN_INFO
1457 "scsi(%ld): QUEUE FULL status detected "
e315cd28 1458 "0x%x-0x%x.\n", vha->host_no, comp_status,
df7baa50 1459 scsi_status));
df7baa50
AV
1460 break;
1461 }
1da177e4
LT
1462 if (lscsi_status != SS_CHECK_CONDITION)
1463 break;
1464
b80ca4f7 1465 memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1da177e4
LT
1466 if (!(scsi_status & SS_SENSE_LEN_VALID))
1467 break;
1468
2afa19a9 1469 qla2x00_handle_sense(sp, sense_data, sense_len, rsp);
1da177e4
LT
1470 break;
1471
1472 case CS_DATA_UNDERRUN:
0f00a206
LC
1473 DEBUG2(printk(KERN_INFO
1474 "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x. "
1475 "resid=0x%x fw_resid=0x%x cdb=0x%x os_underflow=0x%x\n",
1476 vha->host_no, cp->device->id, cp->device->lun, comp_status,
1477 scsi_status, resid_len, fw_resid_len, cp->cmnd[0],
1478 cp->underflow));
1479
ed17c71b 1480 /* Use F/W calculated residual length. */
0f00a206
LC
1481 resid = IS_FWI2_CAPABLE(ha) ? fw_resid_len : resid_len;
1482 scsi_set_resid(cp, resid);
1483 if (scsi_status & SS_RESIDUAL_UNDER) {
1484 if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) {
1485 DEBUG2(printk(
1486 "scsi(%ld:%d:%d:%d) Dropped frame(s) "
1487 "detected (%x of %x bytes)...residual "
1488 "length mismatch...retrying command.\n",
1489 vha->host_no, cp->device->channel,
1490 cp->device->id, cp->device->lun, resid,
1491 scsi_bufflen(cp)));
1492
1493 cp->result = DID_ERROR << 16 | lscsi_status;
1494 break;
6acf8190 1495 }
ed17c71b 1496
0f00a206
LC
1497 if (!lscsi_status &&
1498 ((unsigned)(scsi_bufflen(cp) - resid) <
1499 cp->underflow)) {
1500 qla_printk(KERN_INFO, ha,
1501 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1502 "detected (%x of %x bytes)...returning "
1503 "error status.\n", vha->host_no,
1504 cp->device->channel, cp->device->id,
1505 cp->device->lun, resid, scsi_bufflen(cp));
e038a1be 1506
0f00a206
LC
1507 cp->result = DID_ERROR << 16;
1508 break;
1509 }
1510 } else if (!lscsi_status) {
1511 DEBUG2(printk(
1512 "scsi(%ld:%d:%d:%d) Dropped frame(s) detected "
1513 "(%x of %x bytes)...firmware reported underrun..."
1514 "retrying command.\n", vha->host_no,
1515 cp->device->channel, cp->device->id,
1516 cp->device->lun, resid, scsi_bufflen(cp)));
1517
1518 cp->result = DID_ERROR << 16;
1519 break;
1da177e4
LT
1520 }
1521
0f00a206
LC
1522 cp->result = DID_OK << 16 | lscsi_status;
1523
1da177e4 1524 /*
fa2a1ce5 1525 * Check to see if SCSI Status is non zero. If so report SCSI
1da177e4
LT
1526 * Status.
1527 */
1528 if (lscsi_status != 0) {
ffec28a3
AV
1529 if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
1530 DEBUG2(printk(KERN_INFO
1531 "scsi(%ld): QUEUE FULL status detected "
e315cd28 1532 "0x%x-0x%x.\n", vha->host_no, comp_status,
ffec28a3 1533 scsi_status));
ffec28a3
AV
1534 break;
1535 }
1da177e4
LT
1536 if (lscsi_status != SS_CHECK_CONDITION)
1537 break;
1538
b80ca4f7 1539 memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1da177e4
LT
1540 if (!(scsi_status & SS_SENSE_LEN_VALID))
1541 break;
1542
2afa19a9 1543 qla2x00_handle_sense(sp, sense_data, sense_len, rsp);
1da177e4
LT
1544 }
1545 break;
1546
1547 case CS_DATA_OVERRUN:
1548 DEBUG2(printk(KERN_INFO
1549 "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
e315cd28 1550 vha->host_no, cp->device->id, cp->device->lun, comp_status,
9a853f71 1551 scsi_status));
1da177e4
LT
1552 DEBUG2(printk(KERN_INFO
1553 "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1554 cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
1555 cp->cmnd[4], cp->cmnd[5]));
1556 DEBUG2(printk(KERN_INFO
1557 "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
1558 "status!\n",
385d70b4 1559 cp->serial_number, scsi_bufflen(cp), resid_len));
1da177e4
LT
1560
1561 cp->result = DID_ERROR << 16;
1562 break;
1563
1564 case CS_PORT_LOGGED_OUT:
1565 case CS_PORT_CONFIG_CHG:
1566 case CS_PORT_BUSY:
1567 case CS_INCOMPLETE:
1568 case CS_PORT_UNAVAILABLE:
1569 /*
1570 * If the port is in Target Down state, return all IOs for this
1571 * Target with DID_NO_CONNECT ELSE Queue the IOs in the
1572 * retry_queue.
1573 */
1da177e4
LT
1574 DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
1575 "pid=%ld, compl status=0x%x, port state=0x%x\n",
e315cd28 1576 vha->host_no, cp->device->id, cp->device->lun,
9a853f71 1577 cp->serial_number, comp_status,
1da177e4
LT
1578 atomic_read(&fcport->state)));
1579
056a4483
MC
1580 /*
1581 * We are going to have the fc class block the rport
1582 * while we try to recover so instruct the mid layer
1583 * to requeue until the class decides how to handle this.
1584 */
1585 cp->result = DID_TRANSPORT_DISRUPTED << 16;
a7a28504 1586 if (atomic_read(&fcport->state) == FCS_ONLINE)
e315cd28 1587 qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
1da177e4
LT
1588 break;
1589
1590 case CS_RESET:
1591 DEBUG2(printk(KERN_INFO
1592 "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
e315cd28 1593 vha->host_no, comp_status, scsi_status));
1da177e4 1594
f4f051eb 1595 cp->result = DID_RESET << 16;
1da177e4
LT
1596 break;
1597
1598 case CS_ABORTED:
fa2a1ce5 1599 /*
1da177e4
LT
1600 * hv2.19.12 - DID_ABORT does not retry the request if we
1601 * aborted this request then abort otherwise it must be a
1602 * reset.
1603 */
1604 DEBUG2(printk(KERN_INFO
1605 "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
e315cd28 1606 vha->host_no, comp_status, scsi_status));
1da177e4
LT
1607
1608 cp->result = DID_RESET << 16;
1609 break;
1610
1611 case CS_TIMEOUT:
056a4483
MC
1612 /*
1613 * We are going to have the fc class block the rport
1614 * while we try to recover so instruct the mid layer
1615 * to requeue until the class decides how to handle this.
1616 */
1617 cp->result = DID_TRANSPORT_DISRUPTED << 16;
9a853f71 1618
e428924c 1619 if (IS_FWI2_CAPABLE(ha)) {
9a853f71
AV
1620 DEBUG2(printk(KERN_INFO
1621 "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
e315cd28 1622 "0x%x-0x%x\n", vha->host_no, cp->device->channel,
9a853f71
AV
1623 cp->device->id, cp->device->lun, comp_status,
1624 scsi_status));
1625 break;
1626 }
1da177e4
LT
1627 DEBUG2(printk(KERN_INFO
1628 "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
e315cd28 1629 "sflags=%x.\n", vha->host_no, cp->device->channel,
9a853f71
AV
1630 cp->device->id, cp->device->lun, comp_status, scsi_status,
1631 le16_to_cpu(sts->status_flags)));
1da177e4 1632
9a853f71
AV
1633 /* Check to see if logout occurred. */
1634 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
e315cd28 1635 qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
1da177e4
LT
1636 break;
1637
1da177e4
LT
1638 default:
1639 DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
e315cd28 1640 "0x%x-0x%x.\n", vha->host_no, comp_status, scsi_status));
1da177e4
LT
1641 qla_printk(KERN_INFO, ha,
1642 "Unknown status detected 0x%x-0x%x.\n",
1643 comp_status, scsi_status);
1644
1645 cp->result = DID_ERROR << 16;
1646 break;
1647 }
1648
1649 /* Place command on done queue. */
2afa19a9 1650 if (rsp->status_srb == NULL)
73208dfd 1651 qla2x00_sp_compl(ha, sp);
1da177e4
LT
1652}
1653
1654/**
1655 * qla2x00_status_cont_entry() - Process a Status Continuations entry.
1656 * @ha: SCSI driver HA context
1657 * @pkt: Entry pointer
1658 *
1659 * Extended sense data.
1660 */
1661static void
2afa19a9 1662qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
1da177e4
LT
1663{
1664 uint8_t sense_sz = 0;
2afa19a9
AC
1665 struct qla_hw_data *ha = rsp->hw;
1666 srb_t *sp = rsp->status_srb;
1da177e4
LT
1667 struct scsi_cmnd *cp;
1668
1669 if (sp != NULL && sp->request_sense_length != 0) {
1670 cp = sp->cmd;
1671 if (cp == NULL) {
1672 DEBUG2(printk("%s(): Cmd already returned back to OS "
75bc4190 1673 "sp=%p.\n", __func__, sp));
1da177e4
LT
1674 qla_printk(KERN_INFO, ha,
1675 "cmd is NULL: already returned to OS (sp=%p)\n",
fa2a1ce5 1676 sp);
1da177e4 1677
2afa19a9 1678 rsp->status_srb = NULL;
1da177e4
LT
1679 return;
1680 }
1681
1682 if (sp->request_sense_length > sizeof(pkt->data)) {
1683 sense_sz = sizeof(pkt->data);
1684 } else {
1685 sense_sz = sp->request_sense_length;
1686 }
1687
1688 /* Move sense data. */
e428924c 1689 if (IS_FWI2_CAPABLE(ha))
9a853f71 1690 host_to_fcp_swap(pkt->data, sizeof(pkt->data));
1da177e4
LT
1691 memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
1692 DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
1693
1694 sp->request_sense_ptr += sense_sz;
1695 sp->request_sense_length -= sense_sz;
1696
1697 /* Place command on done queue. */
1698 if (sp->request_sense_length == 0) {
2afa19a9 1699 rsp->status_srb = NULL;
73208dfd 1700 qla2x00_sp_compl(ha, sp);
1da177e4
LT
1701 }
1702 }
1703}
1704
1705/**
1706 * qla2x00_error_entry() - Process an error entry.
1707 * @ha: SCSI driver HA context
1708 * @pkt: Entry pointer
1709 */
1710static void
73208dfd 1711qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
1da177e4
LT
1712{
1713 srb_t *sp;
e315cd28 1714 struct qla_hw_data *ha = vha->hw;
2afa19a9
AC
1715 uint32_t handle = LSW(pkt->handle);
1716 uint16_t que = MSW(pkt->handle);
1717 struct req_que *req = ha->req_q_map[que];
1da177e4
LT
1718#if defined(QL_DEBUG_LEVEL_2)
1719 if (pkt->entry_status & RF_INV_E_ORDER)
1720 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
1721 else if (pkt->entry_status & RF_INV_E_COUNT)
1722 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
1723 else if (pkt->entry_status & RF_INV_E_PARAM)
fa2a1ce5 1724 qla_printk(KERN_ERR, ha,
1da177e4
LT
1725 "%s: Invalid Entry Parameter\n", __func__);
1726 else if (pkt->entry_status & RF_INV_E_TYPE)
1727 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);
1728 else if (pkt->entry_status & RF_BUSY)
1729 qla_printk(KERN_ERR, ha, "%s: Busy\n", __func__);
1730 else
1731 qla_printk(KERN_ERR, ha, "%s: UNKNOWN flag error\n", __func__);
1732#endif
1733
1734 /* Validate handle. */
2afa19a9
AC
1735 if (handle < MAX_OUTSTANDING_COMMANDS)
1736 sp = req->outstanding_cmds[handle];
1da177e4
LT
1737 else
1738 sp = NULL;
1739
1740 if (sp) {
1741 /* Free outstanding command slot. */
2afa19a9 1742 req->outstanding_cmds[handle] = NULL;
354d6b21 1743
1da177e4
LT
1744 /* Bad payload or header */
1745 if (pkt->entry_status &
1746 (RF_INV_E_ORDER | RF_INV_E_COUNT |
1747 RF_INV_E_PARAM | RF_INV_E_TYPE)) {
1748 sp->cmd->result = DID_ERROR << 16;
1749 } else if (pkt->entry_status & RF_BUSY) {
1750 sp->cmd->result = DID_BUS_BUSY << 16;
1751 } else {
1752 sp->cmd->result = DID_ERROR << 16;
1753 }
73208dfd 1754 qla2x00_sp_compl(ha, sp);
1da177e4 1755
9a853f71
AV
1756 } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
1757 COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
1da177e4 1758 DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
e315cd28 1759 vha->host_no));
1da177e4
LT
1760 qla_printk(KERN_WARNING, ha,
1761 "Error entry - invalid handle\n");
1762
e315cd28
AC
1763 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1764 qla2xxx_wake_dpc(vha);
1da177e4
LT
1765 }
1766}
1767
9a853f71
AV
1768/**
1769 * qla24xx_mbx_completion() - Process mailbox command completions.
1770 * @ha: SCSI driver HA context
1771 * @mb0: Mailbox0 register
1772 */
1773static void
e315cd28 1774qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
9a853f71
AV
1775{
1776 uint16_t cnt;
1777 uint16_t __iomem *wptr;
e315cd28 1778 struct qla_hw_data *ha = vha->hw;
9a853f71
AV
1779 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1780
1781 /* Load return mailbox registers. */
1782 ha->flags.mbox_int = 1;
1783 ha->mailbox_out[0] = mb0;
1784 wptr = (uint16_t __iomem *)&reg->mailbox1;
1785
1786 for (cnt = 1; cnt < ha->mbx_count; cnt++) {
1787 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
1788 wptr++;
1789 }
1790
1791 if (ha->mcp) {
1792 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
e315cd28 1793 __func__, vha->host_no, ha->mcp->mb[0]));
9a853f71
AV
1794 } else {
1795 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
e315cd28 1796 __func__, vha->host_no));
9a853f71
AV
1797 }
1798}
1799
1800/**
1801 * qla24xx_process_response_queue() - Process response queue entries.
1802 * @ha: SCSI driver HA context
1803 */
2afa19a9
AC
1804void qla24xx_process_response_queue(struct scsi_qla_host *vha,
1805 struct rsp_que *rsp)
9a853f71 1806{
9a853f71
AV
1807 struct sts_entry_24xx *pkt;
1808
e315cd28 1809 if (!vha->flags.online)
9a853f71
AV
1810 return;
1811
e315cd28
AC
1812 while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
1813 pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
9a853f71 1814
e315cd28
AC
1815 rsp->ring_index++;
1816 if (rsp->ring_index == rsp->length) {
1817 rsp->ring_index = 0;
1818 rsp->ring_ptr = rsp->ring;
9a853f71 1819 } else {
e315cd28 1820 rsp->ring_ptr++;
9a853f71
AV
1821 }
1822
1823 if (pkt->entry_status != 0) {
1824 DEBUG3(printk(KERN_INFO
e315cd28 1825 "scsi(%ld): Process error entry.\n", vha->host_no));
9a853f71 1826
73208dfd 1827 qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt);
9a853f71
AV
1828 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1829 wmb();
1830 continue;
1831 }
1832
1833 switch (pkt->entry_type) {
1834 case STATUS_TYPE:
73208dfd 1835 qla2x00_status_entry(vha, rsp, pkt);
9a853f71
AV
1836 break;
1837 case STATUS_CONT_TYPE:
2afa19a9 1838 qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
9a853f71 1839 break;
2c3dfe3f 1840 case VP_RPT_ID_IOCB_TYPE:
e315cd28 1841 qla24xx_report_id_acquisition(vha,
2c3dfe3f
SJ
1842 (struct vp_rpt_id_entry_24xx *)pkt);
1843 break;
ac280b67
AV
1844 case LOGINOUT_PORT_IOCB_TYPE:
1845 qla24xx_logio_entry(vha, rsp->req,
1846 (struct logio_entry_24xx *)pkt);
1847 break;
9a069e19
GM
1848 case CT_IOCB_TYPE:
1849 qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
1850 clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
1851 break;
1852 case ELS_IOCB_TYPE:
1853 qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
1854 break;
9a853f71
AV
1855 default:
1856 /* Type Not Supported. */
1857 DEBUG4(printk(KERN_WARNING
1858 "scsi(%ld): Received unknown response pkt type %x "
1859 "entry status=%x.\n",
e315cd28 1860 vha->host_no, pkt->entry_type, pkt->entry_status));
9a853f71
AV
1861 break;
1862 }
1863 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1864 wmb();
1865 }
1866
1867 /* Adjust ring index */
08029990 1868 WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
9a853f71
AV
1869}
1870
05236a05 1871static void
e315cd28 1872qla2xxx_check_risc_status(scsi_qla_host_t *vha)
05236a05
AV
1873{
1874 int rval;
1875 uint32_t cnt;
e315cd28 1876 struct qla_hw_data *ha = vha->hw;
05236a05
AV
1877 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1878
3a03eb79 1879 if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))
05236a05
AV
1880 return;
1881
1882 rval = QLA_SUCCESS;
1883 WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
1884 RD_REG_DWORD(&reg->iobase_addr);
1885 WRT_REG_DWORD(&reg->iobase_window, 0x0001);
1886 for (cnt = 10000; (RD_REG_DWORD(&reg->iobase_window) & BIT_0) == 0 &&
1887 rval == QLA_SUCCESS; cnt--) {
1888 if (cnt) {
1889 WRT_REG_DWORD(&reg->iobase_window, 0x0001);
1890 udelay(10);
1891 } else
1892 rval = QLA_FUNCTION_TIMEOUT;
1893 }
1894 if (rval == QLA_SUCCESS)
1895 goto next_test;
1896
1897 WRT_REG_DWORD(&reg->iobase_window, 0x0003);
1898 for (cnt = 100; (RD_REG_DWORD(&reg->iobase_window) & BIT_0) == 0 &&
1899 rval == QLA_SUCCESS; cnt--) {
1900 if (cnt) {
1901 WRT_REG_DWORD(&reg->iobase_window, 0x0003);
1902 udelay(10);
1903 } else
1904 rval = QLA_FUNCTION_TIMEOUT;
1905 }
1906 if (rval != QLA_SUCCESS)
1907 goto done;
1908
1909next_test:
1910 if (RD_REG_DWORD(&reg->iobase_c8) & BIT_3)
1911 qla_printk(KERN_INFO, ha, "Additional code -- 0x55AA.\n");
1912
1913done:
1914 WRT_REG_DWORD(&reg->iobase_window, 0x0000);
1915 RD_REG_DWORD(&reg->iobase_window);
1916}
1917
9a853f71
AV
1918/**
1919 * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
1920 * @irq:
1921 * @dev_id: SCSI driver HA context
9a853f71
AV
1922 *
1923 * Called by system whenever the host adapter generates an interrupt.
1924 *
1925 * Returns handled flag.
1926 */
1927irqreturn_t
7d12e780 1928qla24xx_intr_handler(int irq, void *dev_id)
9a853f71 1929{
e315cd28
AC
1930 scsi_qla_host_t *vha;
1931 struct qla_hw_data *ha;
9a853f71
AV
1932 struct device_reg_24xx __iomem *reg;
1933 int status;
9a853f71
AV
1934 unsigned long iter;
1935 uint32_t stat;
1936 uint32_t hccr;
1937 uint16_t mb[4];
e315cd28 1938 struct rsp_que *rsp;
43fac4d9 1939 unsigned long flags;
9a853f71 1940
e315cd28
AC
1941 rsp = (struct rsp_que *) dev_id;
1942 if (!rsp) {
9a853f71 1943 printk(KERN_INFO
e315cd28 1944 "%s(): NULL response queue pointer\n", __func__);
9a853f71
AV
1945 return IRQ_NONE;
1946 }
1947
e315cd28 1948 ha = rsp->hw;
9a853f71
AV
1949 reg = &ha->iobase->isp24;
1950 status = 0;
1951
85880801
AV
1952 if (unlikely(pci_channel_offline(ha->pdev)))
1953 return IRQ_HANDLED;
1954
43fac4d9 1955 spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a9 1956 vha = pci_get_drvdata(ha->pdev);
9a853f71
AV
1957 for (iter = 50; iter--; ) {
1958 stat = RD_REG_DWORD(&reg->host_status);
1959 if (stat & HSRX_RISC_PAUSED) {
85880801 1960 if (unlikely(pci_channel_offline(ha->pdev)))
14e660e6
SJ
1961 break;
1962
9a853f71
AV
1963 hccr = RD_REG_DWORD(&reg->hccr);
1964
1965 qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1966 "Dumping firmware!\n", hccr);
05236a05 1967
e315cd28 1968 qla2xxx_check_risc_status(vha);
05236a05 1969
e315cd28
AC
1970 ha->isp_ops->fw_dump(vha, 1);
1971 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
9a853f71
AV
1972 break;
1973 } else if ((stat & HSRX_RISC_INT) == 0)
1974 break;
1975
1976 switch (stat & 0xff) {
1977 case 0x1:
1978 case 0x2:
1979 case 0x10:
1980 case 0x11:
e315cd28 1981 qla24xx_mbx_completion(vha, MSW(stat));
9a853f71
AV
1982 status |= MBX_INTERRUPT;
1983
1984 break;
1985 case 0x12:
1986 mb[0] = MSW(stat);
1987 mb[1] = RD_REG_WORD(&reg->mailbox1);
1988 mb[2] = RD_REG_WORD(&reg->mailbox2);
1989 mb[3] = RD_REG_WORD(&reg->mailbox3);
73208dfd 1990 qla2x00_async_event(vha, rsp, mb);
9a853f71
AV
1991 break;
1992 case 0x13:
73208dfd 1993 case 0x14:
2afa19a9 1994 qla24xx_process_response_queue(vha, rsp);
9a853f71
AV
1995 break;
1996 default:
1997 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1998 "(%d).\n",
e315cd28 1999 vha->host_no, stat & 0xff));
9a853f71
AV
2000 break;
2001 }
2002 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
2003 RD_REG_DWORD_RELAXED(&reg->hccr);
2004 }
43fac4d9 2005 spin_unlock_irqrestore(&ha->hardware_lock, flags);
9a853f71
AV
2006
2007 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
2008 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
9a853f71 2009 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0 2010 complete(&ha->mbx_intr_comp);
9a853f71
AV
2011 }
2012
2013 return IRQ_HANDLED;
2014}
2015
a8488abe
AV
2016static irqreturn_t
2017qla24xx_msix_rsp_q(int irq, void *dev_id)
2018{
e315cd28
AC
2019 struct qla_hw_data *ha;
2020 struct rsp_que *rsp;
a8488abe 2021 struct device_reg_24xx __iomem *reg;
2afa19a9 2022 struct scsi_qla_host *vha;
0f19bc68 2023 unsigned long flags;
a8488abe 2024
e315cd28
AC
2025 rsp = (struct rsp_que *) dev_id;
2026 if (!rsp) {
2027 printk(KERN_INFO
2028 "%s(): NULL response queue pointer\n", __func__);
2029 return IRQ_NONE;
2030 }
2031 ha = rsp->hw;
a8488abe
AV
2032 reg = &ha->iobase->isp24;
2033
0f19bc68 2034 spin_lock_irqsave(&ha->hardware_lock, flags);
a8488abe 2035
a67093d4 2036 vha = pci_get_drvdata(ha->pdev);
2afa19a9 2037 qla24xx_process_response_queue(vha, rsp);
3155754a 2038 if (!ha->flags.disable_msix_handshake) {
eb94114b
AC
2039 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
2040 RD_REG_DWORD_RELAXED(&reg->hccr);
2041 }
0f19bc68 2042 spin_unlock_irqrestore(&ha->hardware_lock, flags);
a8488abe
AV
2043
2044 return IRQ_HANDLED;
2045}
2046
68ca949c
AC
2047static irqreturn_t
2048qla25xx_msix_rsp_q(int irq, void *dev_id)
2049{
2050 struct qla_hw_data *ha;
2051 struct rsp_que *rsp;
3155754a 2052 struct device_reg_24xx __iomem *reg;
0f19bc68 2053 unsigned long flags;
68ca949c
AC
2054
2055 rsp = (struct rsp_que *) dev_id;
2056 if (!rsp) {
2057 printk(KERN_INFO
2058 "%s(): NULL response queue pointer\n", __func__);
2059 return IRQ_NONE;
2060 }
2061 ha = rsp->hw;
2062
3155754a
AC
2063 /* Clear the interrupt, if enabled, for this response queue */
2064 if (rsp->options & ~BIT_6) {
2065 reg = &ha->iobase->isp24;
0f19bc68 2066 spin_lock_irqsave(&ha->hardware_lock, flags);
3155754a
AC
2067 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
2068 RD_REG_DWORD_RELAXED(&reg->hccr);
0f19bc68 2069 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3155754a 2070 }
68ca949c
AC
2071 queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
2072
2073 return IRQ_HANDLED;
2074}
2075
a8488abe
AV
2076static irqreturn_t
2077qla24xx_msix_default(int irq, void *dev_id)
2078{
e315cd28
AC
2079 scsi_qla_host_t *vha;
2080 struct qla_hw_data *ha;
2081 struct rsp_que *rsp;
a8488abe
AV
2082 struct device_reg_24xx __iomem *reg;
2083 int status;
a8488abe
AV
2084 uint32_t stat;
2085 uint32_t hccr;
2086 uint16_t mb[4];
0f19bc68 2087 unsigned long flags;
a8488abe 2088
e315cd28
AC
2089 rsp = (struct rsp_que *) dev_id;
2090 if (!rsp) {
2091 DEBUG(printk(
2092 "%s(): NULL response queue pointer\n", __func__));
2093 return IRQ_NONE;
2094 }
2095 ha = rsp->hw;
a8488abe
AV
2096 reg = &ha->iobase->isp24;
2097 status = 0;
2098
0f19bc68 2099 spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a9 2100 vha = pci_get_drvdata(ha->pdev);
87f27015 2101 do {
a8488abe
AV
2102 stat = RD_REG_DWORD(&reg->host_status);
2103 if (stat & HSRX_RISC_PAUSED) {
85880801 2104 if (unlikely(pci_channel_offline(ha->pdev)))
14e660e6
SJ
2105 break;
2106
a8488abe
AV
2107 hccr = RD_REG_DWORD(&reg->hccr);
2108
2109 qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
2110 "Dumping firmware!\n", hccr);
05236a05 2111
e315cd28 2112 qla2xxx_check_risc_status(vha);
05236a05 2113
e315cd28
AC
2114 ha->isp_ops->fw_dump(vha, 1);
2115 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
a8488abe
AV
2116 break;
2117 } else if ((stat & HSRX_RISC_INT) == 0)
2118 break;
2119
2120 switch (stat & 0xff) {
2121 case 0x1:
2122 case 0x2:
2123 case 0x10:
2124 case 0x11:
e315cd28 2125 qla24xx_mbx_completion(vha, MSW(stat));
a8488abe
AV
2126 status |= MBX_INTERRUPT;
2127
2128 break;
2129 case 0x12:
2130 mb[0] = MSW(stat);
2131 mb[1] = RD_REG_WORD(&reg->mailbox1);
2132 mb[2] = RD_REG_WORD(&reg->mailbox2);
2133 mb[3] = RD_REG_WORD(&reg->mailbox3);
73208dfd 2134 qla2x00_async_event(vha, rsp, mb);
a8488abe
AV
2135 break;
2136 case 0x13:
73208dfd 2137 case 0x14:
2afa19a9 2138 qla24xx_process_response_queue(vha, rsp);
a8488abe
AV
2139 break;
2140 default:
2141 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
2142 "(%d).\n",
e315cd28 2143 vha->host_no, stat & 0xff));
a8488abe
AV
2144 break;
2145 }
2146 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
87f27015 2147 } while (0);
0f19bc68 2148 spin_unlock_irqrestore(&ha->hardware_lock, flags);
a8488abe
AV
2149
2150 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
2151 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
a8488abe 2152 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0 2153 complete(&ha->mbx_intr_comp);
a8488abe 2154 }
a8488abe
AV
2155 return IRQ_HANDLED;
2156}
2157
2158/* Interrupt handling helpers. */
2159
2160struct qla_init_msix_entry {
a8488abe 2161 const char *name;
476834c2 2162 irq_handler_t handler;
a8488abe
AV
2163};
2164
68ca949c 2165static struct qla_init_msix_entry msix_entries[3] = {
2afa19a9
AC
2166 { "qla2xxx (default)", qla24xx_msix_default },
2167 { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
68ca949c 2168 { "qla2xxx (multiq)", qla25xx_msix_rsp_q },
a8488abe
AV
2169};
2170
2171static void
e315cd28 2172qla24xx_disable_msix(struct qla_hw_data *ha)
a8488abe
AV
2173{
2174 int i;
2175 struct qla_msix_entry *qentry;
2176
73208dfd
AC
2177 for (i = 0; i < ha->msix_count; i++) {
2178 qentry = &ha->msix_entries[i];
a8488abe 2179 if (qentry->have_irq)
73208dfd 2180 free_irq(qentry->vector, qentry->rsp);
a8488abe
AV
2181 }
2182 pci_disable_msix(ha->pdev);
73208dfd
AC
2183 kfree(ha->msix_entries);
2184 ha->msix_entries = NULL;
2185 ha->flags.msix_enabled = 0;
a8488abe
AV
2186}
2187
2188static int
73208dfd 2189qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
a8488abe 2190{
ad038fa8 2191#define MIN_MSIX_COUNT 2
a8488abe 2192 int i, ret;
73208dfd 2193 struct msix_entry *entries;
a8488abe 2194 struct qla_msix_entry *qentry;
73208dfd
AC
2195
2196 entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count,
2197 GFP_KERNEL);
2198 if (!entries)
2199 return -ENOMEM;
a8488abe 2200
73208dfd
AC
2201 for (i = 0; i < ha->msix_count; i++)
2202 entries[i].entry = i;
a8488abe 2203
73208dfd 2204 ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
a8488abe 2205 if (ret) {
ad038fa8
LC
2206 if (ret < MIN_MSIX_COUNT)
2207 goto msix_failed;
2208
a8488abe 2209 qla_printk(KERN_WARNING, ha,
73208dfd
AC
2210 "MSI-X: Failed to enable support -- %d/%d\n"
2211 " Retry with %d vectors\n", ha->msix_count, ret, ret);
2212 ha->msix_count = ret;
2213 ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
2214 if (ret) {
ad038fa8 2215msix_failed:
73208dfd
AC
2216 qla_printk(KERN_WARNING, ha, "MSI-X: Failed to enable"
2217 " support, giving up -- %d/%d\n",
2218 ha->msix_count, ret);
2219 goto msix_out;
2220 }
2afa19a9 2221 ha->max_rsp_queues = ha->msix_count - 1;
73208dfd
AC
2222 }
2223 ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
2224 ha->msix_count, GFP_KERNEL);
2225 if (!ha->msix_entries) {
2226 ret = -ENOMEM;
a8488abe
AV
2227 goto msix_out;
2228 }
2229 ha->flags.msix_enabled = 1;
2230
73208dfd
AC
2231 for (i = 0; i < ha->msix_count; i++) {
2232 qentry = &ha->msix_entries[i];
2233 qentry->vector = entries[i].vector;
2234 qentry->entry = entries[i].entry;
a8488abe 2235 qentry->have_irq = 0;
73208dfd 2236 qentry->rsp = NULL;
a8488abe
AV
2237 }
2238
2afa19a9
AC
2239 /* Enable MSI-X vectors for the base queue */
2240 for (i = 0; i < 2; i++) {
2241 qentry = &ha->msix_entries[i];
2242 ret = request_irq(qentry->vector, msix_entries[i].handler,
2243 0, msix_entries[i].name, rsp);
2244 if (ret) {
2245 qla_printk(KERN_WARNING, ha,
73208dfd
AC
2246 "MSI-X: Unable to register handler -- %x/%d.\n",
2247 qentry->vector, ret);
2afa19a9
AC
2248 qla24xx_disable_msix(ha);
2249 ha->mqenable = 0;
2250 goto msix_out;
2251 }
2252 qentry->have_irq = 1;
2253 qentry->rsp = rsp;
2254 rsp->msix = qentry;
73208dfd 2255 }
73208dfd
AC
2256
2257 /* Enable MSI-X vector for response queue update for queue 0 */
2afa19a9 2258 if (ha->mqiobase && (ha->max_rsp_queues > 1 || ha->max_req_queues > 1))
73208dfd 2259 ha->mqenable = 1;
73208dfd 2260
a8488abe 2261msix_out:
73208dfd 2262 kfree(entries);
a8488abe
AV
2263 return ret;
2264}
2265
2266int
73208dfd 2267qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
a8488abe
AV
2268{
2269 int ret;
963b0fdd 2270 device_reg_t __iomem *reg = ha->iobase;
a8488abe
AV
2271
2272 /* If possible, enable MSI-X. */
3a03eb79
AV
2273 if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
2274 !IS_QLA8432(ha) && !IS_QLA8001(ha))
a8488abe
AV
2275 goto skip_msix;
2276
e315cd28
AC
2277 if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX ||
2278 !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
a8488abe 2279 DEBUG2(qla_printk(KERN_WARNING, ha,
e315cd28
AC
2280 "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
2281 ha->pdev->revision, ha->fw_attributes));
a8488abe
AV
2282
2283 goto skip_msix;
2284 }
2285
da7429f9
AV
2286 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
2287 (ha->pdev->subsystem_device == 0x7040 ||
2288 ha->pdev->subsystem_device == 0x7041 ||
2289 ha->pdev->subsystem_device == 0x1705)) {
2290 DEBUG2(qla_printk(KERN_WARNING, ha,
2291 "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X, 0x%X).\n",
2292 ha->pdev->subsystem_vendor,
2293 ha->pdev->subsystem_device));
2294
2295 goto skip_msi;
2296 }
2297
73208dfd 2298 ret = qla24xx_enable_msix(ha, rsp);
a8488abe
AV
2299 if (!ret) {
2300 DEBUG2(qla_printk(KERN_INFO, ha,
2301 "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision,
2302 ha->fw_attributes));
963b0fdd 2303 goto clear_risc_ints;
a8488abe
AV
2304 }
2305 qla_printk(KERN_WARNING, ha,
2306 "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
2307skip_msix:
cbedb601 2308
3a03eb79
AV
2309 if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
2310 !IS_QLA8001(ha))
cbedb601
AV
2311 goto skip_msi;
2312
2313 ret = pci_enable_msi(ha->pdev);
2314 if (!ret) {
2315 DEBUG2(qla_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
2316 ha->flags.msi_enabled = 1;
2317 }
2318skip_msi:
2319
fd34f556 2320 ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
d1b1bef4 2321 IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
963b0fdd 2322 if (ret) {
a8488abe
AV
2323 qla_printk(KERN_WARNING, ha,
2324 "Failed to reserve interrupt %d already in use.\n",
2325 ha->pdev->irq);
963b0fdd
AV
2326 goto fail;
2327 }
2328 ha->flags.inta_enabled = 1;
963b0fdd
AV
2329clear_risc_ints:
2330
3a03eb79
AV
2331 /*
2332 * FIXME: Noted that 8014s were being dropped during NK testing.
2333 * Timing deltas during MSI-X/INTa transitions?
2334 */
2335 if (IS_QLA81XX(ha))
2336 goto fail;
c6952483 2337 spin_lock_irq(&ha->hardware_lock);
963b0fdd
AV
2338 if (IS_FWI2_CAPABLE(ha)) {
2339 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
2340 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
2341 } else {
2342 WRT_REG_WORD(&reg->isp.semaphore, 0);
2343 WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
2344 WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
a8488abe 2345 }
c6952483 2346 spin_unlock_irq(&ha->hardware_lock);
a8488abe 2347
963b0fdd 2348fail:
a8488abe
AV
2349 return ret;
2350}
2351
2352void
e315cd28 2353qla2x00_free_irqs(scsi_qla_host_t *vha)
a8488abe 2354{
e315cd28 2355 struct qla_hw_data *ha = vha->hw;
73208dfd 2356 struct rsp_que *rsp = ha->rsp_q_map[0];
a8488abe
AV
2357
2358 if (ha->flags.msix_enabled)
2359 qla24xx_disable_msix(ha);
90a86fc0 2360 else if (ha->flags.msi_enabled) {
e315cd28 2361 free_irq(ha->pdev->irq, rsp);
cbedb601 2362 pci_disable_msi(ha->pdev);
90a86fc0
JC
2363 } else
2364 free_irq(ha->pdev->irq, rsp);
a8488abe 2365}
e315cd28 2366
73208dfd
AC
2367
2368int qla25xx_request_irq(struct rsp_que *rsp)
2369{
2370 struct qla_hw_data *ha = rsp->hw;
2afa19a9 2371 struct qla_init_msix_entry *intr = &msix_entries[2];
73208dfd
AC
2372 struct qla_msix_entry *msix = rsp->msix;
2373 int ret;
2374
2375 ret = request_irq(msix->vector, intr->handler, 0, intr->name, rsp);
2376 if (ret) {
2377 qla_printk(KERN_WARNING, ha,
2378 "MSI-X: Unable to register handler -- %x/%d.\n",
2379 msix->vector, ret);
2380 return ret;
2381 }
2382 msix->have_irq = 1;
2383 msix->rsp = rsp;
2384 return ret;
2385}