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