.. | .. |
---|
879 | 879 | goto qc24_fail_command; |
---|
880 | 880 | } |
---|
881 | 881 | |
---|
882 | | - if (!fcport) { |
---|
883 | | - cmd->result = DID_NO_CONNECT << 16; |
---|
| 882 | + if (!fcport || fcport->deleted) { |
---|
| 883 | + cmd->result = DID_IMM_RETRY << 16; |
---|
884 | 884 | goto qc24_fail_command; |
---|
885 | 885 | } |
---|
886 | 886 | |
---|
.. | .. |
---|
961 | 961 | goto qc24_fail_command; |
---|
962 | 962 | } |
---|
963 | 963 | |
---|
964 | | - if (!fcport) { |
---|
| 964 | + if (!qpair->online) { |
---|
| 965 | + ql_dbg(ql_dbg_io, vha, 0x3077, |
---|
| 966 | + "qpair not online. eeh_busy=%d.\n", ha->flags.eeh_busy); |
---|
965 | 967 | cmd->result = DID_NO_CONNECT << 16; |
---|
| 968 | + goto qc24_fail_command; |
---|
| 969 | + } |
---|
| 970 | + |
---|
| 971 | + if (!fcport || fcport->deleted) { |
---|
| 972 | + cmd->result = DID_IMM_RETRY << 16; |
---|
966 | 973 | goto qc24_fail_command; |
---|
967 | 974 | } |
---|
968 | 975 | |
---|
.. | .. |
---|
1190 | 1197 | return return_status; |
---|
1191 | 1198 | } |
---|
1192 | 1199 | |
---|
1193 | | -#define ISP_REG_DISCONNECT 0xffffffffU |
---|
1194 | | -/************************************************************************** |
---|
1195 | | -* qla2x00_isp_reg_stat |
---|
1196 | | -* |
---|
1197 | | -* Description: |
---|
1198 | | -* Read the host status register of ISP before aborting the command. |
---|
1199 | | -* |
---|
1200 | | -* Input: |
---|
1201 | | -* ha = pointer to host adapter structure. |
---|
1202 | | -* |
---|
1203 | | -* |
---|
1204 | | -* Returns: |
---|
1205 | | -* Either true or false. |
---|
1206 | | -* |
---|
1207 | | -* Note: Return true if there is register disconnect. |
---|
1208 | | -**************************************************************************/ |
---|
1209 | | -static inline |
---|
1210 | | -uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha) |
---|
1211 | | -{ |
---|
1212 | | - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
---|
1213 | | - struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; |
---|
1214 | | - |
---|
1215 | | - if (IS_P3P_TYPE(ha)) |
---|
1216 | | - return ((rd_reg_dword(®82->host_int)) == ISP_REG_DISCONNECT); |
---|
1217 | | - else |
---|
1218 | | - return ((rd_reg_dword(®->host_status)) == |
---|
1219 | | - ISP_REG_DISCONNECT); |
---|
1220 | | -} |
---|
1221 | | - |
---|
1222 | 1200 | /************************************************************************** |
---|
1223 | 1201 | * qla2xxx_eh_abort |
---|
1224 | 1202 | * |
---|
.. | .. |
---|
1253 | 1231 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1254 | 1232 | ql_log(ql_log_info, vha, 0x8042, |
---|
1255 | 1233 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1234 | + qla_pci_set_eeh_busy(vha); |
---|
1256 | 1235 | return FAILED; |
---|
1257 | 1236 | } |
---|
1258 | 1237 | |
---|
.. | .. |
---|
1444 | 1423 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1445 | 1424 | ql_log(ql_log_info, vha, 0x803e, |
---|
1446 | 1425 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1426 | + qla_pci_set_eeh_busy(vha); |
---|
1447 | 1427 | return FAILED; |
---|
1448 | 1428 | } |
---|
1449 | 1429 | |
---|
.. | .. |
---|
1460 | 1440 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1461 | 1441 | ql_log(ql_log_info, vha, 0x803f, |
---|
1462 | 1442 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1443 | + qla_pci_set_eeh_busy(vha); |
---|
1463 | 1444 | return FAILED; |
---|
1464 | 1445 | } |
---|
1465 | 1446 | |
---|
.. | .. |
---|
1495 | 1476 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1496 | 1477 | ql_log(ql_log_info, vha, 0x8040, |
---|
1497 | 1478 | "PCI/Register disconnect, exiting.\n"); |
---|
| 1479 | + qla_pci_set_eeh_busy(vha); |
---|
1498 | 1480 | return FAILED; |
---|
1499 | 1481 | } |
---|
1500 | 1482 | |
---|
.. | .. |
---|
1572 | 1554 | if (qla2x00_isp_reg_stat(ha)) { |
---|
1573 | 1555 | ql_log(ql_log_info, vha, 0x8041, |
---|
1574 | 1556 | "PCI/Register disconnect, exiting.\n"); |
---|
1575 | | - schedule_work(&ha->board_disable); |
---|
| 1557 | + qla_pci_set_eeh_busy(vha); |
---|
1576 | 1558 | return SUCCESS; |
---|
1577 | 1559 | } |
---|
1578 | 1560 | |
---|
.. | .. |
---|
1762 | 1744 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { |
---|
1763 | 1745 | sp = req->outstanding_cmds[cnt]; |
---|
1764 | 1746 | if (sp) { |
---|
| 1747 | + /* |
---|
| 1748 | + * perform lockless completion during driver unload |
---|
| 1749 | + */ |
---|
| 1750 | + if (qla2x00_chip_is_down(vha)) { |
---|
| 1751 | + req->outstanding_cmds[cnt] = NULL; |
---|
| 1752 | + spin_unlock_irqrestore(qp->qp_lock_ptr, flags); |
---|
| 1753 | + sp->done(sp, res); |
---|
| 1754 | + spin_lock_irqsave(qp->qp_lock_ptr, flags); |
---|
| 1755 | + continue; |
---|
| 1756 | + } |
---|
| 1757 | + |
---|
1765 | 1758 | switch (sp->cmd_type) { |
---|
1766 | 1759 | case TYPE_SRB: |
---|
1767 | 1760 | qla2x00_abort_srb(qp, sp, res, &flags); |
---|
.. | .. |
---|
2855 | 2848 | ha->max_exchg = FW_MAX_EXCHANGES_CNT; |
---|
2856 | 2849 | atomic_set(&ha->num_pend_mbx_stage1, 0); |
---|
2857 | 2850 | atomic_set(&ha->num_pend_mbx_stage2, 0); |
---|
2858 | | - atomic_set(&ha->num_pend_mbx_stage3, 0); |
---|
2859 | 2851 | atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD); |
---|
2860 | 2852 | ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD; |
---|
2861 | 2853 | |
---|
.. | .. |
---|
3130 | 3122 | host->max_id = ha->max_fibre_devices; |
---|
3131 | 3123 | host->cmd_per_lun = 3; |
---|
3132 | 3124 | host->unique_id = host->host_no; |
---|
| 3125 | + |
---|
| 3126 | + if (ql2xenabledif && ql2xenabledif != 2) { |
---|
| 3127 | + ql_log(ql_log_warn, base_vha, 0x302d, |
---|
| 3128 | + "Invalid value for ql2xenabledif, resetting it to default (2)\n"); |
---|
| 3129 | + ql2xenabledif = 2; |
---|
| 3130 | + } |
---|
| 3131 | + |
---|
3133 | 3132 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) |
---|
3134 | 3133 | host->max_cmd_len = 32; |
---|
3135 | 3134 | else |
---|
.. | .. |
---|
3362 | 3361 | base_vha->flags.difdix_supported = 1; |
---|
3363 | 3362 | ql_dbg(ql_dbg_init, base_vha, 0x00f1, |
---|
3364 | 3363 | "Registering for DIF/DIX type 1 and 3 protection.\n"); |
---|
3365 | | - if (ql2xenabledif == 1) |
---|
3366 | | - prot = SHOST_DIX_TYPE0_PROTECTION; |
---|
3367 | 3364 | if (ql2xprotmask) |
---|
3368 | 3365 | scsi_host_set_prot(host, ql2xprotmask); |
---|
3369 | 3366 | else |
---|
.. | .. |
---|
4866 | 4863 | } |
---|
4867 | 4864 | INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); |
---|
4868 | 4865 | |
---|
4869 | | - sprintf(vha->host_str, "%s_%lu", QLA2XXX_DRIVER_NAME, vha->host_no); |
---|
| 4866 | + snprintf(vha->host_str, sizeof(vha->host_str), "%s_%lu", |
---|
| 4867 | + QLA2XXX_DRIVER_NAME, vha->host_no); |
---|
4870 | 4868 | ql_dbg(ql_dbg_init, vha, 0x0041, |
---|
4871 | 4869 | "Allocated the host=%p hw=%p vha=%p dev_name=%s", |
---|
4872 | 4870 | vha->host, vha->hw, vha, |
---|
.. | .. |
---|
6660 | 6658 | |
---|
6661 | 6659 | schedule(); |
---|
6662 | 6660 | |
---|
| 6661 | + if (test_and_clear_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags)) |
---|
| 6662 | + qla_pci_set_eeh_busy(base_vha); |
---|
| 6663 | + |
---|
6663 | 6664 | if (!base_vha->flags.init_done || ha->flags.mbox_busy) |
---|
6664 | 6665 | goto end_loop; |
---|
6665 | 6666 | |
---|
.. | .. |
---|
6899 | 6900 | } |
---|
6900 | 6901 | } |
---|
6901 | 6902 | loop_resync_check: |
---|
6902 | | - if (test_and_clear_bit(LOOP_RESYNC_NEEDED, |
---|
| 6903 | + if (!qla2x00_reset_active(base_vha) && |
---|
| 6904 | + test_and_clear_bit(LOOP_RESYNC_NEEDED, |
---|
6903 | 6905 | &base_vha->dpc_flags)) { |
---|
6904 | | - |
---|
| 6906 | + /* |
---|
| 6907 | + * Allow abort_isp to complete before moving on to scanning. |
---|
| 6908 | + */ |
---|
6905 | 6909 | ql_dbg(ql_dbg_dpc, base_vha, 0x400f, |
---|
6906 | 6910 | "Loop resync scheduled.\n"); |
---|
6907 | 6911 | |
---|
.. | .. |
---|
6953 | 6957 | mutex_unlock(&ha->mq_lock); |
---|
6954 | 6958 | } |
---|
6955 | 6959 | |
---|
6956 | | - if (test_and_clear_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, |
---|
6957 | | - &base_vha->dpc_flags)) { |
---|
6958 | | - ql_log(ql_log_info, base_vha, 0xffffff, |
---|
6959 | | - "nvme: SET ZIO Activity exchange threshold to %d.\n", |
---|
6960 | | - ha->nvme_last_rptd_aen); |
---|
6961 | | - if (qla27xx_set_zio_threshold(base_vha, |
---|
6962 | | - ha->nvme_last_rptd_aen)) { |
---|
6963 | | - ql_log(ql_log_info, base_vha, 0xffffff, |
---|
6964 | | - "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n", |
---|
6965 | | - ha->nvme_last_rptd_aen); |
---|
6966 | | - } |
---|
6967 | | - } |
---|
6968 | | - |
---|
6969 | 6960 | if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, |
---|
6970 | | - &base_vha->dpc_flags)) { |
---|
| 6961 | + &base_vha->dpc_flags)) { |
---|
| 6962 | + u16 threshold = ha->nvme_last_rptd_aen + ha->last_zio_threshold; |
---|
| 6963 | + |
---|
| 6964 | + if (threshold > ha->orig_fw_xcb_count) |
---|
| 6965 | + threshold = ha->orig_fw_xcb_count; |
---|
| 6966 | + |
---|
6971 | 6967 | ql_log(ql_log_info, base_vha, 0xffffff, |
---|
6972 | | - "SET ZIO Activity exchange threshold to %d.\n", |
---|
6973 | | - ha->last_zio_threshold); |
---|
6974 | | - qla27xx_set_zio_threshold(base_vha, |
---|
6975 | | - ha->last_zio_threshold); |
---|
| 6968 | + "SET ZIO Activity exchange threshold to %d.\n", |
---|
| 6969 | + threshold); |
---|
| 6970 | + if (qla27xx_set_zio_threshold(base_vha, threshold)) { |
---|
| 6971 | + ql_log(ql_log_info, base_vha, 0xffffff, |
---|
| 6972 | + "Unable to SET ZIO Activity exchange threshold to %d.\n", |
---|
| 6973 | + threshold); |
---|
| 6974 | + } |
---|
6976 | 6975 | } |
---|
6977 | 6976 | |
---|
6978 | 6977 | if (!IS_QLAFX00(ha)) |
---|
.. | .. |
---|
7145 | 7144 | |
---|
7146 | 7145 | /* if the loop has been down for 4 minutes, reinit adapter */ |
---|
7147 | 7146 | if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { |
---|
7148 | | - if (!(vha->device_flags & DFLG_NO_CABLE)) { |
---|
| 7147 | + if (!(vha->device_flags & DFLG_NO_CABLE) && !vha->vp_idx) { |
---|
7149 | 7148 | ql_log(ql_log_warn, vha, 0x6009, |
---|
7150 | 7149 | "Loop down - aborting ISP.\n"); |
---|
7151 | 7150 | |
---|
.. | .. |
---|
7190 | 7189 | index = atomic_read(&ha->nvme_active_aen_cnt); |
---|
7191 | 7190 | if (!vha->vp_idx && |
---|
7192 | 7191 | (index != ha->nvme_last_rptd_aen) && |
---|
7193 | | - (index >= DEFAULT_ZIO_THRESHOLD) && |
---|
7194 | 7192 | ha->zio_mode == QLA_ZIO_MODE_6 && |
---|
7195 | 7193 | !ha->flags.host_shutting_down) { |
---|
| 7194 | + ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); |
---|
7196 | 7195 | ql_log(ql_log_info, vha, 0x3002, |
---|
7197 | 7196 | "nvme: Sched: Set ZIO exchange threshold to %d.\n", |
---|
7198 | 7197 | ha->nvme_last_rptd_aen); |
---|
7199 | | - ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); |
---|
7200 | | - set_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); |
---|
| 7198 | + set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); |
---|
7201 | 7199 | start_dpc++; |
---|
7202 | 7200 | } |
---|
7203 | 7201 | |
---|
.. | .. |
---|
7370 | 7368 | int i; |
---|
7371 | 7369 | unsigned long flags; |
---|
7372 | 7370 | |
---|
| 7371 | + ql_dbg(ql_dbg_aer, vha, 0x9000, |
---|
| 7372 | + "%s\n", __func__); |
---|
7373 | 7373 | ha->chip_reset++; |
---|
7374 | 7374 | |
---|
7375 | 7375 | ha->base_qpair->chip_reset = ha->chip_reset; |
---|
.. | .. |
---|
7379 | 7379 | ha->base_qpair->chip_reset; |
---|
7380 | 7380 | } |
---|
7381 | 7381 | |
---|
7382 | | - /* purge MBox commands */ |
---|
7383 | | - if (atomic_read(&ha->num_pend_mbx_stage3)) { |
---|
7384 | | - clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
---|
7385 | | - complete(&ha->mbx_intr_comp); |
---|
7386 | | - } |
---|
7387 | | - |
---|
7388 | | - i = 0; |
---|
7389 | | - |
---|
7390 | | - while (atomic_read(&ha->num_pend_mbx_stage3) || |
---|
7391 | | - atomic_read(&ha->num_pend_mbx_stage2) || |
---|
7392 | | - atomic_read(&ha->num_pend_mbx_stage1)) { |
---|
7393 | | - msleep(20); |
---|
7394 | | - i++; |
---|
7395 | | - if (i > 50) |
---|
7396 | | - break; |
---|
7397 | | - } |
---|
7398 | | - |
---|
7399 | | - ha->flags.purge_mbox = 0; |
---|
| 7382 | + /* |
---|
| 7383 | + * purge mailbox might take a while. Slot Reset/chip reset |
---|
| 7384 | + * will take care of the purge |
---|
| 7385 | + */ |
---|
7400 | 7386 | |
---|
7401 | 7387 | mutex_lock(&ha->mq_lock); |
---|
| 7388 | + ha->base_qpair->online = 0; |
---|
7402 | 7389 | list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) |
---|
7403 | 7390 | qpair->online = 0; |
---|
| 7391 | + wmb(); |
---|
7404 | 7392 | mutex_unlock(&ha->mq_lock); |
---|
7405 | 7393 | |
---|
7406 | 7394 | qla2x00_mark_all_devices_lost(vha); |
---|
.. | .. |
---|
7437 | 7425 | { |
---|
7438 | 7426 | scsi_qla_host_t *vha = pci_get_drvdata(pdev); |
---|
7439 | 7427 | struct qla_hw_data *ha = vha->hw; |
---|
| 7428 | + pci_ers_result_t ret = PCI_ERS_RESULT_NEED_RESET; |
---|
7440 | 7429 | |
---|
7441 | | - ql_dbg(ql_dbg_aer, vha, 0x9000, |
---|
7442 | | - "PCI error detected, state %x.\n", state); |
---|
| 7430 | + ql_log(ql_log_warn, vha, 0x9000, |
---|
| 7431 | + "PCI error detected, state %x.\n", state); |
---|
| 7432 | + ha->pci_error_state = QLA_PCI_ERR_DETECTED; |
---|
7443 | 7433 | |
---|
7444 | 7434 | if (!atomic_read(&pdev->enable_cnt)) { |
---|
7445 | 7435 | ql_log(ql_log_info, vha, 0xffff, |
---|
7446 | 7436 | "PCI device is disabled,state %x\n", state); |
---|
7447 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
| 7437 | + ret = PCI_ERS_RESULT_NEED_RESET; |
---|
| 7438 | + goto out; |
---|
7448 | 7439 | } |
---|
7449 | 7440 | |
---|
7450 | 7441 | switch (state) { |
---|
.. | .. |
---|
7454 | 7445 | set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); |
---|
7455 | 7446 | qla2xxx_wake_dpc(vha); |
---|
7456 | 7447 | } |
---|
7457 | | - return PCI_ERS_RESULT_CAN_RECOVER; |
---|
| 7448 | + ret = PCI_ERS_RESULT_CAN_RECOVER; |
---|
| 7449 | + break; |
---|
7458 | 7450 | case pci_channel_io_frozen: |
---|
7459 | | - ha->flags.eeh_busy = 1; |
---|
7460 | | - qla_pci_error_cleanup(vha); |
---|
7461 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
| 7451 | + qla_pci_set_eeh_busy(vha); |
---|
| 7452 | + ret = PCI_ERS_RESULT_NEED_RESET; |
---|
| 7453 | + break; |
---|
7462 | 7454 | case pci_channel_io_perm_failure: |
---|
7463 | 7455 | ha->flags.pci_channel_io_perm_failure = 1; |
---|
7464 | 7456 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); |
---|
.. | .. |
---|
7466 | 7458 | set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); |
---|
7467 | 7459 | qla2xxx_wake_dpc(vha); |
---|
7468 | 7460 | } |
---|
7469 | | - return PCI_ERS_RESULT_DISCONNECT; |
---|
| 7461 | + ret = PCI_ERS_RESULT_DISCONNECT; |
---|
7470 | 7462 | } |
---|
7471 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
| 7463 | +out: |
---|
| 7464 | + ql_dbg(ql_dbg_aer, vha, 0x600d, |
---|
| 7465 | + "PCI error detected returning [%x].\n", ret); |
---|
| 7466 | + return ret; |
---|
7472 | 7467 | } |
---|
7473 | 7468 | |
---|
7474 | 7469 | static pci_ers_result_t |
---|
.. | .. |
---|
7482 | 7477 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
---|
7483 | 7478 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; |
---|
7484 | 7479 | |
---|
| 7480 | + ql_log(ql_log_warn, base_vha, 0x9000, |
---|
| 7481 | + "mmio enabled\n"); |
---|
| 7482 | + |
---|
| 7483 | + ha->pci_error_state = QLA_PCI_MMIO_ENABLED; |
---|
7485 | 7484 | if (IS_QLA82XX(ha)) |
---|
7486 | 7485 | return PCI_ERS_RESULT_RECOVERED; |
---|
7487 | 7486 | |
---|
.. | .. |
---|
7505 | 7504 | ql_log(ql_log_info, base_vha, 0x9003, |
---|
7506 | 7505 | "RISC paused -- mmio_enabled, Dumping firmware.\n"); |
---|
7507 | 7506 | qla2xxx_dump_fw(base_vha); |
---|
7508 | | - |
---|
7509 | | - return PCI_ERS_RESULT_NEED_RESET; |
---|
7510 | | - } else |
---|
7511 | | - return PCI_ERS_RESULT_RECOVERED; |
---|
| 7507 | + } |
---|
| 7508 | + /* set PCI_ERS_RESULT_NEED_RESET to trigger call to qla2xxx_pci_slot_reset */ |
---|
| 7509 | + ql_dbg(ql_dbg_aer, base_vha, 0x600d, |
---|
| 7510 | + "mmio enabled returning.\n"); |
---|
| 7511 | + return PCI_ERS_RESULT_NEED_RESET; |
---|
7512 | 7512 | } |
---|
7513 | 7513 | |
---|
7514 | 7514 | static pci_ers_result_t |
---|
.. | .. |
---|
7520 | 7520 | int rc; |
---|
7521 | 7521 | struct qla_qpair *qpair = NULL; |
---|
7522 | 7522 | |
---|
7523 | | - ql_dbg(ql_dbg_aer, base_vha, 0x9004, |
---|
7524 | | - "Slot Reset.\n"); |
---|
| 7523 | + ql_log(ql_log_warn, base_vha, 0x9004, |
---|
| 7524 | + "Slot Reset.\n"); |
---|
7525 | 7525 | |
---|
| 7526 | + ha->pci_error_state = QLA_PCI_SLOT_RESET; |
---|
7526 | 7527 | /* Workaround: qla2xxx driver which access hardware earlier |
---|
7527 | 7528 | * needs error state to be pci_channel_io_online. |
---|
7528 | 7529 | * Otherwise mailbox command timesout. |
---|
.. | .. |
---|
7556 | 7557 | qpair->online = 1; |
---|
7557 | 7558 | mutex_unlock(&ha->mq_lock); |
---|
7558 | 7559 | |
---|
| 7560 | + ha->flags.eeh_busy = 0; |
---|
7559 | 7561 | base_vha->flags.online = 1; |
---|
7560 | 7562 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
---|
7561 | | - if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS) |
---|
7562 | | - ret = PCI_ERS_RESULT_RECOVERED; |
---|
| 7563 | + ha->isp_ops->abort_isp(base_vha); |
---|
7563 | 7564 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
---|
7564 | 7565 | |
---|
| 7566 | + if (qla2x00_isp_reg_stat(ha)) { |
---|
| 7567 | + ha->flags.eeh_busy = 1; |
---|
| 7568 | + qla_pci_error_cleanup(base_vha); |
---|
| 7569 | + ql_log(ql_log_warn, base_vha, 0x9005, |
---|
| 7570 | + "Device unable to recover from PCI error.\n"); |
---|
| 7571 | + } else { |
---|
| 7572 | + ret = PCI_ERS_RESULT_RECOVERED; |
---|
| 7573 | + } |
---|
7565 | 7574 | |
---|
7566 | 7575 | exit_slot_reset: |
---|
7567 | 7576 | ql_dbg(ql_dbg_aer, base_vha, 0x900e, |
---|
7568 | | - "slot_reset return %x.\n", ret); |
---|
| 7577 | + "Slot Reset returning %x.\n", ret); |
---|
7569 | 7578 | |
---|
7570 | 7579 | return ret; |
---|
7571 | 7580 | } |
---|
.. | .. |
---|
7577 | 7586 | struct qla_hw_data *ha = base_vha->hw; |
---|
7578 | 7587 | int ret; |
---|
7579 | 7588 | |
---|
7580 | | - ql_dbg(ql_dbg_aer, base_vha, 0x900f, |
---|
7581 | | - "pci_resume.\n"); |
---|
| 7589 | + ql_log(ql_log_warn, base_vha, 0x900f, |
---|
| 7590 | + "Pci Resume.\n"); |
---|
7582 | 7591 | |
---|
7583 | | - ha->flags.eeh_busy = 0; |
---|
7584 | 7592 | |
---|
7585 | 7593 | ret = qla2x00_wait_for_hba_online(base_vha); |
---|
7586 | 7594 | if (ret != QLA_SUCCESS) { |
---|
7587 | 7595 | ql_log(ql_log_fatal, base_vha, 0x9002, |
---|
7588 | 7596 | "The device failed to resume I/O from slot/link_reset.\n"); |
---|
7589 | 7597 | } |
---|
| 7598 | + ha->pci_error_state = QLA_PCI_RESUME; |
---|
| 7599 | + ql_dbg(ql_dbg_aer, base_vha, 0x600d, |
---|
| 7600 | + "Pci Resume returning.\n"); |
---|
| 7601 | +} |
---|
| 7602 | + |
---|
| 7603 | +void qla_pci_set_eeh_busy(struct scsi_qla_host *vha) |
---|
| 7604 | +{ |
---|
| 7605 | + struct qla_hw_data *ha = vha->hw; |
---|
| 7606 | + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
---|
| 7607 | + bool do_cleanup = false; |
---|
| 7608 | + unsigned long flags; |
---|
| 7609 | + |
---|
| 7610 | + if (ha->flags.eeh_busy) |
---|
| 7611 | + return; |
---|
| 7612 | + |
---|
| 7613 | + spin_lock_irqsave(&base_vha->work_lock, flags); |
---|
| 7614 | + if (!ha->flags.eeh_busy) { |
---|
| 7615 | + ha->flags.eeh_busy = 1; |
---|
| 7616 | + do_cleanup = true; |
---|
| 7617 | + } |
---|
| 7618 | + spin_unlock_irqrestore(&base_vha->work_lock, flags); |
---|
| 7619 | + |
---|
| 7620 | + if (do_cleanup) |
---|
| 7621 | + qla_pci_error_cleanup(base_vha); |
---|
| 7622 | +} |
---|
| 7623 | + |
---|
| 7624 | +/* |
---|
| 7625 | + * this routine will schedule a task to pause IO from interrupt context |
---|
| 7626 | + * if caller sees a PCIE error event (register read = 0xf's) |
---|
| 7627 | + */ |
---|
| 7628 | +void qla_schedule_eeh_work(struct scsi_qla_host *vha) |
---|
| 7629 | +{ |
---|
| 7630 | + struct qla_hw_data *ha = vha->hw; |
---|
| 7631 | + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
---|
| 7632 | + |
---|
| 7633 | + if (ha->flags.eeh_busy) |
---|
| 7634 | + return; |
---|
| 7635 | + |
---|
| 7636 | + set_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags); |
---|
| 7637 | + qla2xxx_wake_dpc(base_vha); |
---|
7590 | 7638 | } |
---|
7591 | 7639 | |
---|
7592 | 7640 | static void |
---|