diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 223 |
1 files changed, 102 insertions, 121 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f0337036c7bb..285479b62d8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -14,9 +14,6 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); | |||
14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); | 14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); |
15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); | 15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); |
16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); | 16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); |
17 | static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *); | ||
18 | |||
19 | static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *); | ||
20 | 17 | ||
21 | /** | 18 | /** |
22 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. | 19 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
@@ -33,7 +30,6 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
33 | scsi_qla_host_t *ha; | 30 | scsi_qla_host_t *ha; |
34 | struct device_reg_2xxx __iomem *reg; | 31 | struct device_reg_2xxx __iomem *reg; |
35 | int status; | 32 | int status; |
36 | unsigned long flags; | ||
37 | unsigned long iter; | 33 | unsigned long iter; |
38 | uint16_t hccr; | 34 | uint16_t hccr; |
39 | uint16_t mb[4]; | 35 | uint16_t mb[4]; |
@@ -48,7 +44,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
48 | reg = &ha->iobase->isp; | 44 | reg = &ha->iobase->isp; |
49 | status = 0; | 45 | status = 0; |
50 | 46 | ||
51 | spin_lock_irqsave(&ha->hardware_lock, flags); | 47 | spin_lock(&ha->hardware_lock); |
52 | for (iter = 50; iter--; ) { | 48 | for (iter = 50; iter--; ) { |
53 | hccr = RD_REG_WORD(®->hccr); | 49 | hccr = RD_REG_WORD(®->hccr); |
54 | if (hccr & HCCR_RISC_PAUSE) { | 50 | if (hccr & HCCR_RISC_PAUSE) { |
@@ -99,7 +95,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
99 | RD_REG_WORD(®->hccr); | 95 | RD_REG_WORD(®->hccr); |
100 | } | 96 | } |
101 | } | 97 | } |
102 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 98 | spin_unlock(&ha->hardware_lock); |
103 | 99 | ||
104 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 100 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
105 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 101 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -125,7 +121,6 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
125 | scsi_qla_host_t *ha; | 121 | scsi_qla_host_t *ha; |
126 | struct device_reg_2xxx __iomem *reg; | 122 | struct device_reg_2xxx __iomem *reg; |
127 | int status; | 123 | int status; |
128 | unsigned long flags; | ||
129 | unsigned long iter; | 124 | unsigned long iter; |
130 | uint32_t stat; | 125 | uint32_t stat; |
131 | uint16_t hccr; | 126 | uint16_t hccr; |
@@ -141,7 +136,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
141 | reg = &ha->iobase->isp; | 136 | reg = &ha->iobase->isp; |
142 | status = 0; | 137 | status = 0; |
143 | 138 | ||
144 | spin_lock_irqsave(&ha->hardware_lock, flags); | 139 | spin_lock(&ha->hardware_lock); |
145 | for (iter = 50; iter--; ) { | 140 | for (iter = 50; iter--; ) { |
146 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 141 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
147 | if (stat & HSR_RISC_PAUSED) { | 142 | if (stat & HSR_RISC_PAUSED) { |
@@ -211,7 +206,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
211 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 206 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
212 | RD_REG_WORD_RELAXED(®->hccr); | 207 | RD_REG_WORD_RELAXED(®->hccr); |
213 | } | 208 | } |
214 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 209 | spin_unlock(&ha->hardware_lock); |
215 | 210 | ||
216 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 211 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
217 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 212 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -276,6 +271,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
276 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 271 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
277 | uint32_t rscn_entry, host_pid; | 272 | uint32_t rscn_entry, host_pid; |
278 | uint8_t rscn_queue_index; | 273 | uint8_t rscn_queue_index; |
274 | unsigned long flags; | ||
275 | scsi_qla_host_t *vha; | ||
276 | int i; | ||
279 | 277 | ||
280 | /* Setup to process RIO completion. */ | 278 | /* Setup to process RIO completion. */ |
281 | handle_cnt = 0; | 279 | handle_cnt = 0; |
@@ -351,6 +349,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
351 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", | 349 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", |
352 | mb[1], mb[2], mb[3]); | 350 | mb[1], mb[2], mb[3]); |
353 | 351 | ||
352 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
354 | ha->isp_ops->fw_dump(ha, 1); | 353 | ha->isp_ops->fw_dump(ha, 1); |
355 | 354 | ||
356 | if (IS_FWI2_CAPABLE(ha)) { | 355 | if (IS_FWI2_CAPABLE(ha)) { |
@@ -375,6 +374,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
375 | ha->host_no)); | 374 | ha->host_no)); |
376 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); | 375 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); |
377 | 376 | ||
377 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
379 | break; | 379 | break; |
380 | 380 | ||
@@ -383,6 +383,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
383 | ha->host_no)); | 383 | ha->host_no)); |
384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); | 384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); |
385 | 385 | ||
386 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
386 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 387 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
387 | break; | 388 | break; |
388 | 389 | ||
@@ -410,6 +411,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
410 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 411 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); |
411 | 412 | ||
412 | ha->flags.management_server_logged_in = 0; | 413 | ha->flags.management_server_logged_in = 0; |
414 | qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]); | ||
413 | break; | 415 | break; |
414 | 416 | ||
415 | case MBA_LOOP_UP: /* Loop Up Event */ | 417 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -429,12 +431,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
429 | link_speed); | 431 | link_speed); |
430 | 432 | ||
431 | ha->flags.management_server_logged_in = 0; | 433 | ha->flags.management_server_logged_in = 0; |
434 | qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate); | ||
432 | break; | 435 | break; |
433 | 436 | ||
434 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 437 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
435 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n", | 438 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " |
436 | ha->host_no, mb[1])); | 439 | "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3])); |
437 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]); | 440 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", |
441 | mb[1], mb[2], mb[3]); | ||
438 | 442 | ||
439 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 443 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { |
440 | atomic_set(&ha->loop_state, LOOP_DOWN); | 444 | atomic_set(&ha->loop_state, LOOP_DOWN); |
@@ -452,6 +456,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
452 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | 456 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
453 | if (ql2xfdmienable) | 457 | if (ql2xfdmienable) |
454 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 458 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
459 | qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0); | ||
455 | break; | 460 | break; |
456 | 461 | ||
457 | case MBA_LIP_RESET: /* LIP reset occurred */ | 462 | case MBA_LIP_RESET: /* LIP reset occurred */ |
@@ -475,6 +480,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
475 | 480 | ||
476 | ha->operating_mode = LOOP; | 481 | ha->operating_mode = LOOP; |
477 | ha->flags.management_server_logged_in = 0; | 482 | ha->flags.management_server_logged_in = 0; |
483 | qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]); | ||
478 | break; | 484 | break; |
479 | 485 | ||
480 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 486 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -538,6 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
538 | break; | 544 | break; |
539 | 545 | ||
540 | case MBA_PORT_UPDATE: /* Port database update */ | 546 | case MBA_PORT_UPDATE: /* Port database update */ |
547 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { | ||
548 | for_each_mapped_vp_idx(ha, i) { | ||
549 | list_for_each_entry(vha, &ha->vp_list, | ||
550 | vp_list) { | ||
551 | if ((mb[3] & 0xff) | ||
552 | == vha->vp_idx) { | ||
553 | ha = vha; | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | } | ||
541 | /* | 559 | /* |
542 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET | 560 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET |
543 | * event etc. earlier indicating loop is down) then process | 561 | * event etc. earlier indicating loop is down) then process |
@@ -572,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
572 | break; | 590 | break; |
573 | 591 | ||
574 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 592 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
575 | /* Check if the Vport has issued a SCR */ | 593 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { |
576 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) | 594 | for_each_mapped_vp_idx(ha, i) { |
577 | break; | 595 | list_for_each_entry(vha, &ha->vp_list, |
578 | /* Only handle SCNs for our Vport index. */ | 596 | vp_list) { |
579 | if (ha->flags.npiv_supported && ha->vp_idx != mb[3]) | 597 | if ((mb[3] & 0xff) |
580 | break; | 598 | == vha->vp_idx) { |
599 | ha = vha; | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | } | ||
581 | 605 | ||
582 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", | 606 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", |
583 | ha->host_no)); | 607 | ha->host_no)); |
@@ -612,6 +636,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
612 | 636 | ||
613 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 637 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
614 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 638 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
639 | qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry); | ||
615 | break; | 640 | break; |
616 | 641 | ||
617 | /* case MBA_RIO_RESPONSE: */ | 642 | /* case MBA_RIO_RESPONSE: */ |
@@ -637,6 +662,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
637 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", | 662 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", |
638 | ha->host_no, mb[1], mb[2])); | 663 | ha->host_no, mb[1], mb[2])); |
639 | break; | 664 | break; |
665 | |||
666 | case MBA_ISP84XX_ALERT: | ||
667 | DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " | ||
668 | "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3])); | ||
669 | |||
670 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
671 | switch (mb[1]) { | ||
672 | case A84_PANIC_RECOVERY: | ||
673 | qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery " | ||
674 | "%04x %04x\n", mb[2], mb[3]); | ||
675 | break; | ||
676 | case A84_OP_LOGIN_COMPLETE: | ||
677 | ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2]; | ||
678 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
679 | "firmware version %x\n", ha->cs84xx->op_fw_version)); | ||
680 | break; | ||
681 | case A84_DIAG_LOGIN_COMPLETE: | ||
682 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
683 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
684 | "diagnostic firmware version %x\n", | ||
685 | ha->cs84xx->diag_fw_version)); | ||
686 | break; | ||
687 | case A84_GOLD_LOGIN_COMPLETE: | ||
688 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
689 | ha->cs84xx->fw_update = 1; | ||
690 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold " | ||
691 | "firmware version %x\n", | ||
692 | ha->cs84xx->gold_fw_version)); | ||
693 | break; | ||
694 | default: | ||
695 | qla_printk(KERN_ERR, ha, | ||
696 | "Alert 84xx: Invalid Alert %04x %04x %04x\n", | ||
697 | mb[1], mb[2], mb[3]); | ||
698 | } | ||
699 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags); | ||
700 | break; | ||
640 | } | 701 | } |
641 | 702 | ||
642 | if (!ha->parent && ha->num_vhosts) | 703 | if (!ha->parent && ha->num_vhosts) |
@@ -803,9 +864,6 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) | |||
803 | case STATUS_CONT_TYPE: | 864 | case STATUS_CONT_TYPE: |
804 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 865 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
805 | break; | 866 | break; |
806 | case MS_IOCB_TYPE: | ||
807 | qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt); | ||
808 | break; | ||
809 | default: | 867 | default: |
810 | /* Type Not Supported. */ | 868 | /* Type Not Supported. */ |
811 | DEBUG4(printk(KERN_WARNING | 869 | DEBUG4(printk(KERN_WARNING |
@@ -1340,44 +1398,6 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | |||
1340 | } | 1398 | } |
1341 | 1399 | ||
1342 | /** | 1400 | /** |
1343 | * qla2x00_ms_entry() - Process a Management Server entry. | ||
1344 | * @ha: SCSI driver HA context | ||
1345 | * @index: Response queue out pointer | ||
1346 | */ | ||
1347 | static void | ||
1348 | qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) | ||
1349 | { | ||
1350 | srb_t *sp; | ||
1351 | |||
1352 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1353 | __func__, ha->host_no, pkt, pkt->handle1)); | ||
1354 | |||
1355 | /* Validate handle. */ | ||
1356 | if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS) | ||
1357 | sp = ha->outstanding_cmds[pkt->handle1]; | ||
1358 | else | ||
1359 | sp = NULL; | ||
1360 | |||
1361 | if (sp == NULL) { | ||
1362 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1363 | ha->host_no)); | ||
1364 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n"); | ||
1365 | |||
1366 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1367 | return; | ||
1368 | } | ||
1369 | |||
1370 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status); | ||
1371 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1372 | |||
1373 | /* Free outstanding command slot. */ | ||
1374 | ha->outstanding_cmds[pkt->handle1] = NULL; | ||
1375 | |||
1376 | qla2x00_sp_compl(ha, sp); | ||
1377 | } | ||
1378 | |||
1379 | |||
1380 | /** | ||
1381 | * qla24xx_mbx_completion() - Process mailbox command completions. | 1401 | * qla24xx_mbx_completion() - Process mailbox command completions. |
1382 | * @ha: SCSI driver HA context | 1402 | * @ha: SCSI driver HA context |
1383 | * @mb0: Mailbox0 register | 1403 | * @mb0: Mailbox0 register |
@@ -1449,9 +1469,6 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1449 | case STATUS_CONT_TYPE: | 1469 | case STATUS_CONT_TYPE: |
1450 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 1470 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
1451 | break; | 1471 | break; |
1452 | case MS_IOCB_TYPE: | ||
1453 | qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt); | ||
1454 | break; | ||
1455 | case VP_RPT_ID_IOCB_TYPE: | 1472 | case VP_RPT_ID_IOCB_TYPE: |
1456 | qla24xx_report_id_acquisition(ha, | 1473 | qla24xx_report_id_acquisition(ha, |
1457 | (struct vp_rpt_id_entry_24xx *)pkt); | 1474 | (struct vp_rpt_id_entry_24xx *)pkt); |
@@ -1533,7 +1550,6 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1533 | scsi_qla_host_t *ha; | 1550 | scsi_qla_host_t *ha; |
1534 | struct device_reg_24xx __iomem *reg; | 1551 | struct device_reg_24xx __iomem *reg; |
1535 | int status; | 1552 | int status; |
1536 | unsigned long flags; | ||
1537 | unsigned long iter; | 1553 | unsigned long iter; |
1538 | uint32_t stat; | 1554 | uint32_t stat; |
1539 | uint32_t hccr; | 1555 | uint32_t hccr; |
@@ -1549,13 +1565,19 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1549 | reg = &ha->iobase->isp24; | 1565 | reg = &ha->iobase->isp24; |
1550 | status = 0; | 1566 | status = 0; |
1551 | 1567 | ||
1552 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1568 | spin_lock(&ha->hardware_lock); |
1553 | for (iter = 50; iter--; ) { | 1569 | for (iter = 50; iter--; ) { |
1554 | stat = RD_REG_DWORD(®->host_status); | 1570 | stat = RD_REG_DWORD(®->host_status); |
1555 | if (stat & HSRX_RISC_PAUSED) { | 1571 | if (stat & HSRX_RISC_PAUSED) { |
1556 | if (pci_channel_offline(ha->pdev)) | 1572 | if (pci_channel_offline(ha->pdev)) |
1557 | break; | 1573 | break; |
1558 | 1574 | ||
1575 | if (ha->hw_event_pause_errors == 0) | ||
1576 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1577 | 0, MSW(stat), LSW(stat)); | ||
1578 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1579 | ha->hw_event_pause_errors++; | ||
1580 | |||
1559 | hccr = RD_REG_DWORD(®->hccr); | 1581 | hccr = RD_REG_DWORD(®->hccr); |
1560 | 1582 | ||
1561 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1583 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1597,7 +1619,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1597 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1619 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1598 | RD_REG_DWORD_RELAXED(®->hccr); | 1620 | RD_REG_DWORD_RELAXED(®->hccr); |
1599 | } | 1621 | } |
1600 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1622 | spin_unlock(&ha->hardware_lock); |
1601 | 1623 | ||
1602 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1624 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1603 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1625 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1608,66 +1630,21 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1608 | return IRQ_HANDLED; | 1630 | return IRQ_HANDLED; |
1609 | } | 1631 | } |
1610 | 1632 | ||
1611 | /** | ||
1612 | * qla24xx_ms_entry() - Process a Management Server entry. | ||
1613 | * @ha: SCSI driver HA context | ||
1614 | * @index: Response queue out pointer | ||
1615 | */ | ||
1616 | static void | ||
1617 | qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | ||
1618 | { | ||
1619 | srb_t *sp; | ||
1620 | |||
1621 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1622 | __func__, ha->host_no, pkt, pkt->handle)); | ||
1623 | |||
1624 | DEBUG9(printk("%s: ct pkt dump:\n", __func__)); | ||
1625 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); | ||
1626 | |||
1627 | /* Validate handle. */ | ||
1628 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | ||
1629 | sp = ha->outstanding_cmds[pkt->handle]; | ||
1630 | else | ||
1631 | sp = NULL; | ||
1632 | |||
1633 | if (sp == NULL) { | ||
1634 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1635 | ha->host_no)); | ||
1636 | DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1637 | ha->host_no)); | ||
1638 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n", | ||
1639 | pkt->handle); | ||
1640 | |||
1641 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1642 | return; | ||
1643 | } | ||
1644 | |||
1645 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status); | ||
1646 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1647 | |||
1648 | /* Free outstanding command slot. */ | ||
1649 | ha->outstanding_cmds[pkt->handle] = NULL; | ||
1650 | |||
1651 | qla2x00_sp_compl(ha, sp); | ||
1652 | } | ||
1653 | |||
1654 | static irqreturn_t | 1633 | static irqreturn_t |
1655 | qla24xx_msix_rsp_q(int irq, void *dev_id) | 1634 | qla24xx_msix_rsp_q(int irq, void *dev_id) |
1656 | { | 1635 | { |
1657 | scsi_qla_host_t *ha; | 1636 | scsi_qla_host_t *ha; |
1658 | struct device_reg_24xx __iomem *reg; | 1637 | struct device_reg_24xx __iomem *reg; |
1659 | unsigned long flags; | ||
1660 | 1638 | ||
1661 | ha = dev_id; | 1639 | ha = dev_id; |
1662 | reg = &ha->iobase->isp24; | 1640 | reg = &ha->iobase->isp24; |
1663 | 1641 | ||
1664 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1642 | spin_lock(&ha->hardware_lock); |
1665 | 1643 | ||
1666 | qla24xx_process_response_queue(ha); | 1644 | qla24xx_process_response_queue(ha); |
1667 | |||
1668 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1645 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1669 | 1646 | ||
1670 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1647 | spin_unlock(&ha->hardware_lock); |
1671 | 1648 | ||
1672 | return IRQ_HANDLED; | 1649 | return IRQ_HANDLED; |
1673 | } | 1650 | } |
@@ -1678,7 +1655,6 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1678 | scsi_qla_host_t *ha; | 1655 | scsi_qla_host_t *ha; |
1679 | struct device_reg_24xx __iomem *reg; | 1656 | struct device_reg_24xx __iomem *reg; |
1680 | int status; | 1657 | int status; |
1681 | unsigned long flags; | ||
1682 | uint32_t stat; | 1658 | uint32_t stat; |
1683 | uint32_t hccr; | 1659 | uint32_t hccr; |
1684 | uint16_t mb[4]; | 1660 | uint16_t mb[4]; |
@@ -1687,13 +1663,19 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1687 | reg = &ha->iobase->isp24; | 1663 | reg = &ha->iobase->isp24; |
1688 | status = 0; | 1664 | status = 0; |
1689 | 1665 | ||
1690 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1666 | spin_lock(&ha->hardware_lock); |
1691 | do { | 1667 | do { |
1692 | stat = RD_REG_DWORD(®->host_status); | 1668 | stat = RD_REG_DWORD(®->host_status); |
1693 | if (stat & HSRX_RISC_PAUSED) { | 1669 | if (stat & HSRX_RISC_PAUSED) { |
1694 | if (pci_channel_offline(ha->pdev)) | 1670 | if (pci_channel_offline(ha->pdev)) |
1695 | break; | 1671 | break; |
1696 | 1672 | ||
1673 | if (ha->hw_event_pause_errors == 0) | ||
1674 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1675 | 0, MSW(stat), LSW(stat)); | ||
1676 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1677 | ha->hw_event_pause_errors++; | ||
1678 | |||
1697 | hccr = RD_REG_DWORD(®->hccr); | 1679 | hccr = RD_REG_DWORD(®->hccr); |
1698 | 1680 | ||
1699 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1681 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1734,7 +1716,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1734 | } | 1716 | } |
1735 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1717 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1736 | } while (0); | 1718 | } while (0); |
1737 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1719 | spin_unlock(&ha->hardware_lock); |
1738 | 1720 | ||
1739 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1721 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1740 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1722 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1821,10 +1803,9 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1821 | { | 1803 | { |
1822 | int ret; | 1804 | int ret; |
1823 | device_reg_t __iomem *reg = ha->iobase; | 1805 | device_reg_t __iomem *reg = ha->iobase; |
1824 | unsigned long flags; | ||
1825 | 1806 | ||
1826 | /* If possible, enable MSI-X. */ | 1807 | /* If possible, enable MSI-X. */ |
1827 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha)) | 1808 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1828 | goto skip_msix; | 1809 | goto skip_msix; |
1829 | 1810 | ||
1830 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || | 1811 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || |
@@ -1859,7 +1840,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1859 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); | 1840 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); |
1860 | skip_msix: | 1841 | skip_msix: |
1861 | 1842 | ||
1862 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha)) | 1843 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1863 | goto skip_msi; | 1844 | goto skip_msi; |
1864 | 1845 | ||
1865 | ret = pci_enable_msi(ha->pdev); | 1846 | ret = pci_enable_msi(ha->pdev); |
@@ -1882,7 +1863,7 @@ skip_msi: | |||
1882 | clear_risc_ints: | 1863 | clear_risc_ints: |
1883 | 1864 | ||
1884 | ha->isp_ops->disable_intrs(ha); | 1865 | ha->isp_ops->disable_intrs(ha); |
1885 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1866 | spin_lock_irq(&ha->hardware_lock); |
1886 | if (IS_FWI2_CAPABLE(ha)) { | 1867 | if (IS_FWI2_CAPABLE(ha)) { |
1887 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); | 1868 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); |
1888 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); | 1869 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); |
@@ -1891,7 +1872,7 @@ clear_risc_ints: | |||
1891 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); | 1872 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); |
1892 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); | 1873 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); |
1893 | } | 1874 | } |
1894 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1875 | spin_unlock_irq(&ha->hardware_lock); |
1895 | ha->isp_ops->enable_intrs(ha); | 1876 | ha->isp_ops->enable_intrs(ha); |
1896 | 1877 | ||
1897 | fail: | 1878 | fail: |