diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d670b1c410ec..f3ad7349f5d1 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -1475,8 +1475,12 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1475 | phba->sli4_hba.u.if_type2.STATUSregaddr, | 1475 | phba->sli4_hba.u.if_type2.STATUSregaddr, |
1476 | &portstat_reg.word0); | 1476 | &portstat_reg.word0); |
1477 | /* consider PCI bus read error as pci_channel_offline */ | 1477 | /* consider PCI bus read error as pci_channel_offline */ |
1478 | if (pci_rd_rc1 == -EIO) | 1478 | if (pci_rd_rc1 == -EIO) { |
1479 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1480 | "3151 PCI bus read access failure: x%x\n", | ||
1481 | readl(phba->sli4_hba.u.if_type2.STATUSregaddr)); | ||
1479 | return; | 1482 | return; |
1483 | } | ||
1480 | reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr); | 1484 | reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr); |
1481 | reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr); | 1485 | reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr); |
1482 | if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) { | 1486 | if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) { |
@@ -1526,6 +1530,9 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1526 | } | 1530 | } |
1527 | /* fall through for not able to recover */ | 1531 | /* fall through for not able to recover */ |
1528 | } | 1532 | } |
1533 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1534 | "3152 Unrecoverable error, bring the port " | ||
1535 | "offline\n"); | ||
1529 | lpfc_sli4_offline_eratt(phba); | 1536 | lpfc_sli4_offline_eratt(phba); |
1530 | break; | 1537 | break; |
1531 | case LPFC_SLI_INTF_IF_TYPE_1: | 1538 | case LPFC_SLI_INTF_IF_TYPE_1: |
@@ -2514,6 +2521,42 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba) | |||
2514 | } | 2521 | } |
2515 | 2522 | ||
2516 | /** | 2523 | /** |
2524 | * lpfc_sli4_node_prep - Assign RPIs for active nodes. | ||
2525 | * @phba: pointer to lpfc hba data structure. | ||
2526 | * | ||
2527 | * Allocate RPIs for all active remote nodes. This is needed whenever | ||
2528 | * an SLI4 adapter is reset and the driver is not unloading. Its purpose | ||
2529 | * is to fixup the temporary rpi assignments. | ||
2530 | **/ | ||
2531 | void | ||
2532 | lpfc_sli4_node_prep(struct lpfc_hba *phba) | ||
2533 | { | ||
2534 | struct lpfc_nodelist *ndlp, *next_ndlp; | ||
2535 | struct lpfc_vport **vports; | ||
2536 | int i; | ||
2537 | |||
2538 | if (phba->sli_rev != LPFC_SLI_REV4) | ||
2539 | return; | ||
2540 | |||
2541 | vports = lpfc_create_vport_work_array(phba); | ||
2542 | if (vports != NULL) { | ||
2543 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
2544 | if (vports[i]->load_flag & FC_UNLOADING) | ||
2545 | continue; | ||
2546 | |||
2547 | list_for_each_entry_safe(ndlp, next_ndlp, | ||
2548 | &vports[i]->fc_nodes, | ||
2549 | nlp_listp) { | ||
2550 | if (NLP_CHK_NODE_ACT(ndlp)) | ||
2551 | ndlp->nlp_rpi = | ||
2552 | lpfc_sli4_alloc_rpi(phba); | ||
2553 | } | ||
2554 | } | ||
2555 | } | ||
2556 | lpfc_destroy_vport_work_array(phba, vports); | ||
2557 | } | ||
2558 | |||
2559 | /** | ||
2517 | * lpfc_online - Initialize and bring a HBA online | 2560 | * lpfc_online - Initialize and bring a HBA online |
2518 | * @phba: pointer to lpfc hba data structure. | 2561 | * @phba: pointer to lpfc hba data structure. |
2519 | * | 2562 | * |
@@ -2654,6 +2697,15 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
2654 | } | 2697 | } |
2655 | spin_lock_irq(shost->host_lock); | 2698 | spin_lock_irq(shost->host_lock); |
2656 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 2699 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
2700 | |||
2701 | /* | ||
2702 | * Whenever an SLI4 port goes offline, free the | ||
2703 | * RPI. A new RPI when the adapter port comes | ||
2704 | * back online. | ||
2705 | */ | ||
2706 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
2707 | lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); | ||
2708 | |||
2657 | spin_unlock_irq(shost->host_lock); | 2709 | spin_unlock_irq(shost->host_lock); |
2658 | lpfc_unreg_rpi(vports[i], ndlp); | 2710 | lpfc_unreg_rpi(vports[i], ndlp); |
2659 | } | 2711 | } |
@@ -7224,19 +7276,17 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) | |||
7224 | rc = -ENODEV; | 7276 | rc = -ENODEV; |
7225 | goto out; | 7277 | goto out; |
7226 | } | 7278 | } |
7227 | if (bf_get(lpfc_sliport_status_rdy, ®_data)) | 7279 | if (bf_get(lpfc_sliport_status_rn, ®_data)) |
7228 | break; | ||
7229 | if (bf_get(lpfc_sliport_status_rn, ®_data)) { | ||
7230 | reset_again++; | 7280 | reset_again++; |
7281 | if (bf_get(lpfc_sliport_status_rdy, ®_data)) | ||
7231 | break; | 7282 | break; |
7232 | } | ||
7233 | } | 7283 | } |
7234 | 7284 | ||
7235 | /* | 7285 | /* |
7236 | * If the port responds to the init request with | 7286 | * If the port responds to the init request with |
7237 | * reset needed, delay for a bit and restart the loop. | 7287 | * reset needed, delay for a bit and restart the loop. |
7238 | */ | 7288 | */ |
7239 | if (reset_again) { | 7289 | if (reset_again && (rdy_chk < 1000)) { |
7240 | msleep(10); | 7290 | msleep(10); |
7241 | reset_again = 0; | 7291 | reset_again = 0; |
7242 | continue; | 7292 | continue; |
@@ -9059,7 +9109,7 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) | |||
9059 | int | 9109 | int |
9060 | lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | 9110 | lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) |
9061 | { | 9111 | { |
9062 | char fwrev[32]; | 9112 | char fwrev[FW_REV_STR_SIZE]; |
9063 | struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data; | 9113 | struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data; |
9064 | struct list_head dma_buffer_list; | 9114 | struct list_head dma_buffer_list; |
9065 | int i, rc = 0; | 9115 | int i, rc = 0; |