diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 157 |
1 files changed, 112 insertions, 45 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 091f68e5cb70..678a4b11059c 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1074,6 +1074,12 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1074 | 1074 | ||
1075 | mempool_free(pmb, phba->mbox_mem_pool); | 1075 | mempool_free(pmb, phba->mbox_mem_pool); |
1076 | 1076 | ||
1077 | /* don't perform discovery for SLI4 loopback diagnostic test */ | ||
1078 | if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
1079 | !(phba->hba_flag & HBA_FCOE_MODE) && | ||
1080 | (phba->link_flag & LS_LOOPBACK_MODE)) | ||
1081 | return; | ||
1082 | |||
1077 | if (phba->fc_topology == LPFC_TOPOLOGY_LOOP && | 1083 | if (phba->fc_topology == LPFC_TOPOLOGY_LOOP && |
1078 | vport->fc_flag & FC_PUBLIC_LOOP && | 1084 | vport->fc_flag & FC_PUBLIC_LOOP && |
1079 | !(vport->fc_flag & FC_LBIT)) { | 1085 | !(vport->fc_flag & FC_LBIT)) { |
@@ -2646,9 +2652,14 @@ lpfc_init_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2646 | { | 2652 | { |
2647 | struct lpfc_vport *vport = mboxq->vport; | 2653 | struct lpfc_vport *vport = mboxq->vport; |
2648 | 2654 | ||
2649 | /* VFI not supported on interface type 0, just do the flogi */ | 2655 | /* |
2650 | if (mboxq->u.mb.mbxStatus && (bf_get(lpfc_sli_intf_if_type, | 2656 | * VFI not supported on interface type 0, just do the flogi |
2651 | &phba->sli4_hba.sli_intf) != LPFC_SLI_INTF_IF_TYPE_0)) { | 2657 | * Also continue if the VFI is in use - just use the same one. |
2658 | */ | ||
2659 | if (mboxq->u.mb.mbxStatus && | ||
2660 | (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | ||
2661 | LPFC_SLI_INTF_IF_TYPE_0) && | ||
2662 | mboxq->u.mb.mbxStatus != MBX_VFI_IN_USE) { | ||
2652 | lpfc_printf_vlog(vport, KERN_ERR, | 2663 | lpfc_printf_vlog(vport, KERN_ERR, |
2653 | LOG_MBOX, | 2664 | LOG_MBOX, |
2654 | "2891 Init VFI mailbox failed 0x%x\n", | 2665 | "2891 Init VFI mailbox failed 0x%x\n", |
@@ -2842,10 +2853,10 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2842 | lpfc_disc_list_loopmap(vport); | 2853 | lpfc_disc_list_loopmap(vport); |
2843 | /* Start discovery */ | 2854 | /* Start discovery */ |
2844 | lpfc_disc_start(vport); | 2855 | lpfc_disc_start(vport); |
2845 | goto fail_free_mem; | 2856 | goto out_free_mem; |
2846 | } | 2857 | } |
2847 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 2858 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
2848 | goto fail_free_mem; | 2859 | goto out_free_mem; |
2849 | } | 2860 | } |
2850 | /* The VPI is implicitly registered when the VFI is registered */ | 2861 | /* The VPI is implicitly registered when the VFI is registered */ |
2851 | spin_lock_irq(shost->host_lock); | 2862 | spin_lock_irq(shost->host_lock); |
@@ -2855,10 +2866,16 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2855 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; | 2866 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; |
2856 | spin_unlock_irq(shost->host_lock); | 2867 | spin_unlock_irq(shost->host_lock); |
2857 | 2868 | ||
2869 | /* In case SLI4 FC loopback test, we are ready */ | ||
2870 | if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
2871 | (phba->link_flag & LS_LOOPBACK_MODE)) { | ||
2872 | phba->link_state = LPFC_HBA_READY; | ||
2873 | goto out_free_mem; | ||
2874 | } | ||
2875 | |||
2858 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | 2876 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
2859 | /* For private loop just start discovery and we are done. */ | 2877 | /* For private loop just start discovery and we are done. */ |
2860 | if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && | 2878 | if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && |
2861 | (phba->alpa_map[0] == 0) && | ||
2862 | !(vport->fc_flag & FC_PUBLIC_LOOP)) { | 2879 | !(vport->fc_flag & FC_PUBLIC_LOOP)) { |
2863 | /* Use loop map to make discovery list */ | 2880 | /* Use loop map to make discovery list */ |
2864 | lpfc_disc_list_loopmap(vport); | 2881 | lpfc_disc_list_loopmap(vport); |
@@ -2870,7 +2887,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2870 | } | 2887 | } |
2871 | } | 2888 | } |
2872 | 2889 | ||
2873 | fail_free_mem: | 2890 | out_free_mem: |
2874 | mempool_free(mboxq, phba->mbox_mem_pool); | 2891 | mempool_free(mboxq, phba->mbox_mem_pool); |
2875 | lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); | 2892 | lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); |
2876 | kfree(dmabuf); | 2893 | kfree(dmabuf); |
@@ -2923,6 +2940,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) | |||
2923 | { | 2940 | { |
2924 | struct lpfc_vport *vport = phba->pport; | 2941 | struct lpfc_vport *vport = phba->pport; |
2925 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL; | 2942 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL; |
2943 | struct Scsi_Host *shost; | ||
2926 | int i; | 2944 | int i; |
2927 | struct lpfc_dmabuf *mp; | 2945 | struct lpfc_dmabuf *mp; |
2928 | int rc; | 2946 | int rc; |
@@ -2946,6 +2964,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) | |||
2946 | phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la); | 2964 | phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la); |
2947 | phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; | 2965 | phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; |
2948 | 2966 | ||
2967 | shost = lpfc_shost_from_vport(vport); | ||
2949 | if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { | 2968 | if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { |
2950 | phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; | 2969 | phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; |
2951 | 2970 | ||
@@ -2957,8 +2976,11 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) | |||
2957 | "1309 Link Up Event npiv not supported in loop " | 2976 | "1309 Link Up Event npiv not supported in loop " |
2958 | "topology\n"); | 2977 | "topology\n"); |
2959 | /* Get Loop Map information */ | 2978 | /* Get Loop Map information */ |
2960 | if (bf_get(lpfc_mbx_read_top_il, la)) | 2979 | if (bf_get(lpfc_mbx_read_top_il, la)) { |
2980 | spin_lock_irq(shost->host_lock); | ||
2961 | vport->fc_flag |= FC_LBIT; | 2981 | vport->fc_flag |= FC_LBIT; |
2982 | spin_unlock_irq(shost->host_lock); | ||
2983 | } | ||
2962 | 2984 | ||
2963 | vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la); | 2985 | vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la); |
2964 | i = la->lilpBde64.tus.f.bdeSize; | 2986 | i = la->lilpBde64.tus.f.bdeSize; |
@@ -3003,11 +3025,13 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) | |||
3003 | } else { | 3025 | } else { |
3004 | if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { | 3026 | if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { |
3005 | if (phba->max_vpi && phba->cfg_enable_npiv && | 3027 | if (phba->max_vpi && phba->cfg_enable_npiv && |
3006 | (phba->sli_rev == 3)) | 3028 | (phba->sli_rev >= LPFC_SLI_REV3)) |
3007 | phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; | 3029 | phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; |
3008 | } | 3030 | } |
3009 | vport->fc_myDID = phba->fc_pref_DID; | 3031 | vport->fc_myDID = phba->fc_pref_DID; |
3032 | spin_lock_irq(shost->host_lock); | ||
3010 | vport->fc_flag |= FC_LBIT; | 3033 | vport->fc_flag |= FC_LBIT; |
3034 | spin_unlock_irq(shost->host_lock); | ||
3011 | } | 3035 | } |
3012 | spin_unlock_irq(&phba->hbalock); | 3036 | spin_unlock_irq(&phba->hbalock); |
3013 | 3037 | ||
@@ -3224,15 +3248,14 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3224 | } else if (bf_get(lpfc_mbx_read_top_att_type, la) == | 3248 | } else if (bf_get(lpfc_mbx_read_top_att_type, la) == |
3225 | LPFC_ATT_LINK_DOWN) { | 3249 | LPFC_ATT_LINK_DOWN) { |
3226 | phba->fc_stat.LinkDown++; | 3250 | phba->fc_stat.LinkDown++; |
3227 | if (phba->link_flag & LS_LOOPBACK_MODE) { | 3251 | if (phba->link_flag & LS_LOOPBACK_MODE) |
3228 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 3252 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
3229 | "1308 Link Down Event in loop back mode " | 3253 | "1308 Link Down Event in loop back mode " |
3230 | "x%x received " | 3254 | "x%x received " |
3231 | "Data: x%x x%x x%x\n", | 3255 | "Data: x%x x%x x%x\n", |
3232 | la->eventTag, phba->fc_eventTag, | 3256 | la->eventTag, phba->fc_eventTag, |
3233 | phba->pport->port_state, vport->fc_flag); | 3257 | phba->pport->port_state, vport->fc_flag); |
3234 | } | 3258 | else |
3235 | else { | ||
3236 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 3259 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
3237 | "1305 Link Down Event x%x received " | 3260 | "1305 Link Down Event x%x received " |
3238 | "Data: x%x x%x x%x x%x x%x\n", | 3261 | "Data: x%x x%x x%x x%x x%x\n", |
@@ -3240,7 +3263,6 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3240 | phba->pport->port_state, vport->fc_flag, | 3263 | phba->pport->port_state, vport->fc_flag, |
3241 | bf_get(lpfc_mbx_read_top_mm, la), | 3264 | bf_get(lpfc_mbx_read_top_mm, la), |
3242 | bf_get(lpfc_mbx_read_top_fa, la)); | 3265 | bf_get(lpfc_mbx_read_top_fa, la)); |
3243 | } | ||
3244 | lpfc_mbx_issue_link_down(phba); | 3266 | lpfc_mbx_issue_link_down(phba); |
3245 | } | 3267 | } |
3246 | if ((bf_get(lpfc_mbx_read_top_mm, la)) && | 3268 | if ((bf_get(lpfc_mbx_read_top_mm, la)) && |
@@ -3594,6 +3616,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3594 | MAILBOX_t *mb = &pmb->u.mb; | 3616 | MAILBOX_t *mb = &pmb->u.mb; |
3595 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 3617 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
3596 | struct lpfc_nodelist *ndlp; | 3618 | struct lpfc_nodelist *ndlp; |
3619 | struct Scsi_Host *shost; | ||
3597 | 3620 | ||
3598 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 3621 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
3599 | pmb->context1 = NULL; | 3622 | pmb->context1 = NULL; |
@@ -3639,8 +3662,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3639 | * vport discovery */ | 3662 | * vport discovery */ |
3640 | if (!(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) | 3663 | if (!(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) |
3641 | lpfc_start_fdiscs(phba); | 3664 | lpfc_start_fdiscs(phba); |
3642 | else | 3665 | else { |
3666 | shost = lpfc_shost_from_vport(vport); | ||
3667 | spin_lock_irq(shost->host_lock); | ||
3643 | vport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG ; | 3668 | vport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG ; |
3669 | spin_unlock_irq(shost->host_lock); | ||
3670 | } | ||
3644 | lpfc_do_scr_ns_plogi(phba, vport); | 3671 | lpfc_do_scr_ns_plogi(phba, vport); |
3645 | } | 3672 | } |
3646 | 3673 | ||
@@ -5353,6 +5380,73 @@ lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn) | |||
5353 | return ndlp; | 5380 | return ndlp; |
5354 | } | 5381 | } |
5355 | 5382 | ||
5383 | /* | ||
5384 | * This routine looks up the ndlp lists for the given RPI. If the rpi | ||
5385 | * is found, the routine returns the node element list pointer else | ||
5386 | * return NULL. | ||
5387 | */ | ||
5388 | struct lpfc_nodelist * | ||
5389 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | ||
5390 | { | ||
5391 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
5392 | struct lpfc_nodelist *ndlp; | ||
5393 | |||
5394 | spin_lock_irq(shost->host_lock); | ||
5395 | ndlp = __lpfc_findnode_rpi(vport, rpi); | ||
5396 | spin_unlock_irq(shost->host_lock); | ||
5397 | return ndlp; | ||
5398 | } | ||
5399 | |||
5400 | /** | ||
5401 | * lpfc_find_vport_by_vpid - Find a vport on a HBA through vport identifier | ||
5402 | * @phba: pointer to lpfc hba data structure. | ||
5403 | * @vpi: the physical host virtual N_Port identifier. | ||
5404 | * | ||
5405 | * This routine finds a vport on a HBA (referred by @phba) through a | ||
5406 | * @vpi. The function walks the HBA's vport list and returns the address | ||
5407 | * of the vport with the matching @vpi. | ||
5408 | * | ||
5409 | * Return code | ||
5410 | * NULL - No vport with the matching @vpi found | ||
5411 | * Otherwise - Address to the vport with the matching @vpi. | ||
5412 | **/ | ||
5413 | struct lpfc_vport * | ||
5414 | lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) | ||
5415 | { | ||
5416 | struct lpfc_vport *vport; | ||
5417 | unsigned long flags; | ||
5418 | int i = 0; | ||
5419 | |||
5420 | /* The physical ports are always vpi 0 - translate is unnecessary. */ | ||
5421 | if (vpi > 0) { | ||
5422 | /* | ||
5423 | * Translate the physical vpi to the logical vpi. The | ||
5424 | * vport stores the logical vpi. | ||
5425 | */ | ||
5426 | for (i = 0; i < phba->max_vpi; i++) { | ||
5427 | if (vpi == phba->vpi_ids[i]) | ||
5428 | break; | ||
5429 | } | ||
5430 | |||
5431 | if (i >= phba->max_vpi) { | ||
5432 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | ||
5433 | "2936 Could not find Vport mapped " | ||
5434 | "to vpi %d\n", vpi); | ||
5435 | return NULL; | ||
5436 | } | ||
5437 | } | ||
5438 | |||
5439 | spin_lock_irqsave(&phba->hbalock, flags); | ||
5440 | list_for_each_entry(vport, &phba->port_list, listentry) { | ||
5441 | if (vport->vpi == i) { | ||
5442 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
5443 | return vport; | ||
5444 | } | ||
5445 | } | ||
5446 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
5447 | return NULL; | ||
5448 | } | ||
5449 | |||
5356 | void | 5450 | void |
5357 | lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 5451 | lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
5358 | uint32_t did) | 5452 | uint32_t did) |
@@ -5599,7 +5693,7 @@ out: | |||
5599 | * | 5693 | * |
5600 | * This function frees memory associated with the mailbox command. | 5694 | * This function frees memory associated with the mailbox command. |
5601 | */ | 5695 | */ |
5602 | static void | 5696 | void |
5603 | lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 5697 | lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) |
5604 | { | 5698 | { |
5605 | struct lpfc_vport *vport = mboxq->vport; | 5699 | struct lpfc_vport *vport = mboxq->vport; |
@@ -5651,7 +5745,6 @@ lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
5651 | int | 5745 | int |
5652 | lpfc_unregister_fcf_prep(struct lpfc_hba *phba) | 5746 | lpfc_unregister_fcf_prep(struct lpfc_hba *phba) |
5653 | { | 5747 | { |
5654 | LPFC_MBOXQ_t *mbox; | ||
5655 | struct lpfc_vport **vports; | 5748 | struct lpfc_vport **vports; |
5656 | struct lpfc_nodelist *ndlp; | 5749 | struct lpfc_nodelist *ndlp; |
5657 | struct Scsi_Host *shost; | 5750 | struct Scsi_Host *shost; |
@@ -5687,35 +5780,9 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba) | |||
5687 | /* Cleanup any outstanding ELS commands */ | 5780 | /* Cleanup any outstanding ELS commands */ |
5688 | lpfc_els_flush_all_cmd(phba); | 5781 | lpfc_els_flush_all_cmd(phba); |
5689 | 5782 | ||
5690 | /* Unregister VFI */ | 5783 | /* Unregister the physical port VFI */ |
5691 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 5784 | rc = lpfc_issue_unreg_vfi(phba->pport); |
5692 | if (!mbox) { | 5785 | return rc; |
5693 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
5694 | "2556 UNREG_VFI mbox allocation failed" | ||
5695 | "HBA state x%x\n", phba->pport->port_state); | ||
5696 | return -ENOMEM; | ||
5697 | } | ||
5698 | |||
5699 | lpfc_unreg_vfi(mbox, phba->pport); | ||
5700 | mbox->vport = phba->pport; | ||
5701 | mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl; | ||
5702 | |||
5703 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
5704 | if (rc == MBX_NOT_FINISHED) { | ||
5705 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
5706 | "2557 UNREG_VFI issue mbox failed rc x%x " | ||
5707 | "HBA state x%x\n", | ||
5708 | rc, phba->pport->port_state); | ||
5709 | mempool_free(mbox, phba->mbox_mem_pool); | ||
5710 | return -EIO; | ||
5711 | } | ||
5712 | |||
5713 | shost = lpfc_shost_from_vport(phba->pport); | ||
5714 | spin_lock_irq(shost->host_lock); | ||
5715 | phba->pport->fc_flag &= ~FC_VFI_REGISTERED; | ||
5716 | spin_unlock_irq(shost->host_lock); | ||
5717 | |||
5718 | return 0; | ||
5719 | } | 5786 | } |
5720 | 5787 | ||
5721 | /** | 5788 | /** |