diff options
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 10 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 48 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 121 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 73 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 98 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 40 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 34 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 112 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_version.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 3 |
12 files changed, 260 insertions, 288 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 2ab2d24dcc15..ec0b0f6e5e1a 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | struct lpfc_sli2_slim; | 24 | struct lpfc_sli2_slim; |
25 | 25 | ||
26 | #define LPFC_MAX_TARGET 256 /* max number of targets supported */ | 26 | #define LPFC_MAX_TARGET 4096 /* max number of targets supported */ |
27 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els | 27 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els |
28 | requests */ | 28 | requests */ |
29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact | 29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact |
@@ -268,7 +268,6 @@ struct lpfc_vport { | |||
268 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ | 268 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ |
269 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ | 269 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ |
270 | #define FC_FABRIC 0x100 /* We are fabric attached */ | 270 | #define FC_FABRIC 0x100 /* We are fabric attached */ |
271 | #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ | ||
272 | #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ | 271 | #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ |
273 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ | 272 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ |
274 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ | 273 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ |
@@ -433,8 +432,6 @@ struct lpfc_hba { | |||
433 | 432 | ||
434 | uint32_t fc_eventTag; /* event tag for link attention */ | 433 | uint32_t fc_eventTag; /* event tag for link attention */ |
435 | 434 | ||
436 | |||
437 | struct timer_list fc_estabtmo; /* link establishment timer */ | ||
438 | /* These fields used to be binfo */ | 435 | /* These fields used to be binfo */ |
439 | uint32_t fc_pref_DID; /* preferred D_ID */ | 436 | uint32_t fc_pref_DID; /* preferred D_ID */ |
440 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ | 437 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b12a841703ca..74c9fc204211 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1954,7 +1954,9 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1954 | (phba->sysfs_mbox.mbox->mb.mbxCommand != | 1954 | (phba->sysfs_mbox.mbox->mb.mbxCommand != |
1955 | MBX_DUMP_MEMORY && | 1955 | MBX_DUMP_MEMORY && |
1956 | phba->sysfs_mbox.mbox->mb.mbxCommand != | 1956 | phba->sysfs_mbox.mbox->mb.mbxCommand != |
1957 | MBX_RESTART)) { | 1957 | MBX_RESTART && |
1958 | phba->sysfs_mbox.mbox->mb.mbxCommand != | ||
1959 | MBX_WRITE_VPARMS)) { | ||
1958 | sysfs_mbox_idle(phba); | 1960 | sysfs_mbox_idle(phba); |
1959 | spin_unlock_irq(&phba->hbalock); | 1961 | spin_unlock_irq(&phba->hbalock); |
1960 | return -EPERM; | 1962 | return -EPERM; |
@@ -1962,7 +1964,11 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1962 | 1964 | ||
1963 | phba->sysfs_mbox.mbox->vport = vport; | 1965 | phba->sysfs_mbox.mbox->vport = vport; |
1964 | 1966 | ||
1965 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | 1967 | /* Don't allow mailbox commands to be sent when blocked |
1968 | * or when in the middle of discovery | ||
1969 | */ | ||
1970 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO || | ||
1971 | vport->fc_flag & FC_NDISC_ACTIVE) { | ||
1966 | sysfs_mbox_idle(phba); | 1972 | sysfs_mbox_idle(phba); |
1967 | spin_unlock_irq(&phba->hbalock); | 1973 | spin_unlock_irq(&phba->hbalock); |
1968 | return -EAGAIN; | 1974 | return -EAGAIN; |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 3d0ccd9b341d..153afae567b5 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -63,7 +63,7 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
63 | { | 63 | { |
64 | if (!mp) { | 64 | if (!mp) { |
65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
66 | "0146 Ignoring unsolicted CT No HBQ " | 66 | "0146 Ignoring unsolicited CT No HBQ " |
67 | "status = x%x\n", | 67 | "status = x%x\n", |
68 | piocbq->iocb.ulpStatus); | 68 | piocbq->iocb.ulpStatus); |
69 | } | 69 | } |
@@ -438,7 +438,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || | 438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || |
439 | (!vport->cfg_restrict_login)) { | 439 | (!vport->cfg_restrict_login)) { |
440 | ndlp = lpfc_setup_disc_node(vport, Did); | 440 | ndlp = lpfc_setup_disc_node(vport, Did); |
441 | if (ndlp) { | 441 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
442 | lpfc_debugfs_disc_trc(vport, | 442 | lpfc_debugfs_disc_trc(vport, |
443 | LPFC_DISC_TRC_CT, | 443 | LPFC_DISC_TRC_CT, |
444 | "Parse GID_FTrsp: " | 444 | "Parse GID_FTrsp: " |
@@ -543,7 +543,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
543 | struct lpfc_dmabuf *outp; | 543 | struct lpfc_dmabuf *outp; |
544 | struct lpfc_sli_ct_request *CTrsp; | 544 | struct lpfc_sli_ct_request *CTrsp; |
545 | struct lpfc_nodelist *ndlp; | 545 | struct lpfc_nodelist *ndlp; |
546 | int rc, retry; | 546 | int rc; |
547 | 547 | ||
548 | /* First save ndlp, before we overwrite it */ | 548 | /* First save ndlp, before we overwrite it */ |
549 | ndlp = cmdiocb->context_un.ndlp; | 549 | ndlp = cmdiocb->context_un.ndlp; |
@@ -563,45 +563,29 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
563 | if (vport->load_flag & FC_UNLOADING) | 563 | if (vport->load_flag & FC_UNLOADING) |
564 | goto out; | 564 | goto out; |
565 | 565 | ||
566 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { | 566 | if (lpfc_els_chk_latt(vport)) { |
567 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 567 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
568 | "0216 Link event during NS query\n"); | 568 | "0216 Link event during NS query\n"); |
569 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 569 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
570 | goto out; | 570 | goto out; |
571 | } | 571 | } |
572 | 572 | if (lpfc_error_lost_link(irsp)) { | |
573 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | ||
574 | "0226 NS query failed due to link event\n"); | ||
575 | goto out; | ||
576 | } | ||
573 | if (irsp->ulpStatus) { | 577 | if (irsp->ulpStatus) { |
574 | /* Check for retry */ | 578 | /* Check for retry */ |
575 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 579 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
576 | retry = 1; | 580 | if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || |
577 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | 581 | irsp->un.ulpWord[4] != IOERR_NO_RESOURCES) |
578 | switch (irsp->un.ulpWord[4]) { | ||
579 | case IOERR_NO_RESOURCES: | ||
580 | /* We don't increment the retry | ||
581 | * count for this case. | ||
582 | */ | ||
583 | break; | ||
584 | case IOERR_LINK_DOWN: | ||
585 | case IOERR_SLI_ABORTED: | ||
586 | case IOERR_SLI_DOWN: | ||
587 | retry = 0; | ||
588 | break; | ||
589 | default: | ||
590 | vport->fc_ns_retry++; | ||
591 | } | ||
592 | } | ||
593 | else | ||
594 | vport->fc_ns_retry++; | 582 | vport->fc_ns_retry++; |
595 | 583 | ||
596 | if (retry) { | 584 | /* CT command is being retried */ |
597 | /* CT command is being retried */ | 585 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, |
598 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | ||
599 | vport->fc_ns_retry, 0); | 586 | vport->fc_ns_retry, 0); |
600 | if (rc == 0) { | 587 | if (rc == 0) |
601 | /* success */ | 588 | goto out; |
602 | goto out; | ||
603 | } | ||
604 | } | ||
605 | } | 589 | } |
606 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 590 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
607 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 591 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -780,7 +764,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
780 | 764 | ||
781 | /* This is a target port, unregistered port, or the GFF_ID failed */ | 765 | /* This is a target port, unregistered port, or the GFF_ID failed */ |
782 | ndlp = lpfc_setup_disc_node(vport, did); | 766 | ndlp = lpfc_setup_disc_node(vport, did); |
783 | if (ndlp) { | 767 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
784 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 768 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
785 | "0242 Process x%x GFF " | 769 | "0242 Process x%x GFF " |
786 | "NameServer Rsp Data: x%x x%x x%x\n", | 770 | "NameServer Rsp Data: x%x x%x x%x\n", |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 783d1eea13ef..90272e65957a 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -503,6 +503,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
503 | ndlp->nlp_sid); | 503 | ndlp->nlp_sid); |
504 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) | 504 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) |
505 | len += snprintf(buf+len, size-len, "FCP_INITIATOR "); | 505 | len += snprintf(buf+len, size-len, "FCP_INITIATOR "); |
506 | len += snprintf(buf+len, size-len, "usgmap:%x ", | ||
507 | ndlp->nlp_usg_map); | ||
506 | len += snprintf(buf+len, size-len, "refcnt:%x", | 508 | len += snprintf(buf+len, size-len, "refcnt:%x", |
507 | atomic_read(&ndlp->kref.refcount)); | 509 | atomic_read(&ndlp->kref.refcount)); |
508 | len += snprintf(buf+len, size-len, "\n"); | 510 | len += snprintf(buf+len, size-len, "\n"); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cbb68a942255..886c5f1b11d2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -719,9 +719,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) | |||
719 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && | 719 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && |
720 | icmd->un.elsreq64.bdl.ulpIoTag32) { | 720 | icmd->un.elsreq64.bdl.ulpIoTag32) { |
721 | ndlp = (struct lpfc_nodelist *)(iocb->context1); | 721 | ndlp = (struct lpfc_nodelist *)(iocb->context1); |
722 | if (ndlp && (ndlp->nlp_DID == Fabric_DID)) { | 722 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
723 | (ndlp->nlp_DID == Fabric_DID)) | ||
723 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 724 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
724 | } | ||
725 | } | 725 | } |
726 | } | 726 | } |
727 | spin_unlock_irq(&phba->hbalock); | 727 | spin_unlock_irq(&phba->hbalock); |
@@ -829,7 +829,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
829 | struct fc_rport *rport; | 829 | struct fc_rport *rport; |
830 | struct serv_parm *sp; | 830 | struct serv_parm *sp; |
831 | uint8_t name[sizeof(struct lpfc_name)]; | 831 | uint8_t name[sizeof(struct lpfc_name)]; |
832 | uint32_t rc; | 832 | uint32_t rc, keepDID = 0; |
833 | 833 | ||
834 | /* Fabric nodes can have the same WWPN so we don't bother searching | 834 | /* Fabric nodes can have the same WWPN so we don't bother searching |
835 | * by WWPN. Just return the ndlp that was given to us. | 835 | * by WWPN. Just return the ndlp that was given to us. |
@@ -858,11 +858,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
858 | return ndlp; | 858 | return ndlp; |
859 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); | 859 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); |
860 | } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { | 860 | } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { |
861 | rc = memcmp(&ndlp->nlp_portname, name, | ||
862 | sizeof(struct lpfc_name)); | ||
863 | if (!rc) | ||
864 | return ndlp; | ||
861 | new_ndlp = lpfc_enable_node(vport, new_ndlp, | 865 | new_ndlp = lpfc_enable_node(vport, new_ndlp, |
862 | NLP_STE_UNUSED_NODE); | 866 | NLP_STE_UNUSED_NODE); |
863 | if (!new_ndlp) | 867 | if (!new_ndlp) |
864 | return ndlp; | 868 | return ndlp; |
865 | } | 869 | keepDID = new_ndlp->nlp_DID; |
870 | } else | ||
871 | keepDID = new_ndlp->nlp_DID; | ||
866 | 872 | ||
867 | lpfc_unreg_rpi(vport, new_ndlp); | 873 | lpfc_unreg_rpi(vport, new_ndlp); |
868 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 874 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
@@ -893,12 +899,24 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
893 | } | 899 | } |
894 | new_ndlp->nlp_type = ndlp->nlp_type; | 900 | new_ndlp->nlp_type = ndlp->nlp_type; |
895 | } | 901 | } |
902 | /* We shall actually free the ndlp with both nlp_DID and | ||
903 | * nlp_portname fields equals 0 to avoid any ndlp on the | ||
904 | * nodelist never to be used. | ||
905 | */ | ||
906 | if (ndlp->nlp_DID == 0) { | ||
907 | spin_lock_irq(&phba->ndlp_lock); | ||
908 | NLP_SET_FREE_REQ(ndlp); | ||
909 | spin_unlock_irq(&phba->ndlp_lock); | ||
910 | } | ||
896 | 911 | ||
912 | /* Two ndlps cannot have the same did on the nodelist */ | ||
913 | ndlp->nlp_DID = keepDID; | ||
897 | lpfc_drop_node(vport, ndlp); | 914 | lpfc_drop_node(vport, ndlp); |
898 | } | 915 | } |
899 | else { | 916 | else { |
900 | lpfc_unreg_rpi(vport, ndlp); | 917 | lpfc_unreg_rpi(vport, ndlp); |
901 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 918 | /* Two ndlps cannot have the same did */ |
919 | ndlp->nlp_DID = keepDID; | ||
902 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 920 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
903 | } | 921 | } |
904 | return new_ndlp; | 922 | return new_ndlp; |
@@ -2091,7 +2109,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2091 | } | 2109 | } |
2092 | 2110 | ||
2093 | phba->fc_stat.elsXmitRetry++; | 2111 | phba->fc_stat.elsXmitRetry++; |
2094 | if (ndlp && delay) { | 2112 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) { |
2095 | phba->fc_stat.elsDelayRetry++; | 2113 | phba->fc_stat.elsDelayRetry++; |
2096 | ndlp->nlp_retry = cmdiocb->retry; | 2114 | ndlp->nlp_retry = cmdiocb->retry; |
2097 | 2115 | ||
@@ -2121,7 +2139,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2121 | lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); | 2139 | lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); |
2122 | return 1; | 2140 | return 1; |
2123 | case ELS_CMD_PLOGI: | 2141 | case ELS_CMD_PLOGI: |
2124 | if (ndlp) { | 2142 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2125 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2143 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2126 | lpfc_nlp_set_state(vport, ndlp, | 2144 | lpfc_nlp_set_state(vport, ndlp, |
2127 | NLP_STE_PLOGI_ISSUE); | 2145 | NLP_STE_PLOGI_ISSUE); |
@@ -2302,7 +2320,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2302 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2320 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2303 | kfree(mp); | 2321 | kfree(mp); |
2304 | mempool_free(pmb, phba->mbox_mem_pool); | 2322 | mempool_free(pmb, phba->mbox_mem_pool); |
2305 | if (ndlp) { | 2323 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2306 | lpfc_nlp_put(ndlp); | 2324 | lpfc_nlp_put(ndlp); |
2307 | /* This is the end of the default RPI cleanup logic for this | 2325 | /* This is the end of the default RPI cleanup logic for this |
2308 | * ndlp. If no other discovery threads are using this ndlp. | 2326 | * ndlp. If no other discovery threads are using this ndlp. |
@@ -2335,7 +2353,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2335 | * function can have cmdiocb->contest1 (ndlp) field set to NULL. | 2353 | * function can have cmdiocb->contest1 (ndlp) field set to NULL. |
2336 | */ | 2354 | */ |
2337 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); | 2355 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); |
2338 | if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | 2356 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
2357 | (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | ||
2339 | /* A LS_RJT associated with Default RPI cleanup has its own | 2358 | /* A LS_RJT associated with Default RPI cleanup has its own |
2340 | * seperate code path. | 2359 | * seperate code path. |
2341 | */ | 2360 | */ |
@@ -2344,7 +2363,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2344 | } | 2363 | } |
2345 | 2364 | ||
2346 | /* Check to see if link went down during discovery */ | 2365 | /* Check to see if link went down during discovery */ |
2347 | if (!ndlp || lpfc_els_chk_latt(vport)) { | 2366 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) { |
2348 | if (mbox) { | 2367 | if (mbox) { |
2349 | mp = (struct lpfc_dmabuf *) mbox->context1; | 2368 | mp = (struct lpfc_dmabuf *) mbox->context1; |
2350 | if (mp) { | 2369 | if (mp) { |
@@ -2353,7 +2372,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2353 | } | 2372 | } |
2354 | mempool_free(mbox, phba->mbox_mem_pool); | 2373 | mempool_free(mbox, phba->mbox_mem_pool); |
2355 | } | 2374 | } |
2356 | if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | 2375 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
2376 | (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | ||
2357 | if (lpfc_nlp_not_used(ndlp)) { | 2377 | if (lpfc_nlp_not_used(ndlp)) { |
2358 | ndlp = NULL; | 2378 | ndlp = NULL; |
2359 | /* Indicate the node has already released, | 2379 | /* Indicate the node has already released, |
@@ -2443,7 +2463,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2443 | mempool_free(mbox, phba->mbox_mem_pool); | 2463 | mempool_free(mbox, phba->mbox_mem_pool); |
2444 | } | 2464 | } |
2445 | out: | 2465 | out: |
2446 | if (ndlp) { | 2466 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2447 | spin_lock_irq(shost->host_lock); | 2467 | spin_lock_irq(shost->host_lock); |
2448 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); | 2468 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); |
2449 | spin_unlock_irq(shost->host_lock); | 2469 | spin_unlock_irq(shost->host_lock); |
@@ -3139,6 +3159,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3139 | /* Another thread is walking fc_rscn_id_list on this vport */ | 3159 | /* Another thread is walking fc_rscn_id_list on this vport */ |
3140 | spin_unlock_irq(shost->host_lock); | 3160 | spin_unlock_irq(shost->host_lock); |
3141 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 3161 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
3162 | /* Send back ACC */ | ||
3163 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | ||
3142 | return 0; | 3164 | return 0; |
3143 | } | 3165 | } |
3144 | /* Indicate we are walking fc_rscn_id_list on this vport */ | 3166 | /* Indicate we are walking fc_rscn_id_list on this vport */ |
@@ -3928,7 +3950,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) | |||
3928 | else { | 3950 | else { |
3929 | struct lpfc_nodelist *ndlp; | 3951 | struct lpfc_nodelist *ndlp; |
3930 | ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); | 3952 | ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); |
3931 | if (ndlp) | 3953 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) |
3932 | remote_ID = ndlp->nlp_DID; | 3954 | remote_ID = ndlp->nlp_DID; |
3933 | } | 3955 | } |
3934 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 3956 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -4097,21 +4119,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
4097 | newnode = 1; | 4119 | newnode = 1; |
4098 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) | 4120 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
4099 | ndlp->nlp_type |= NLP_FABRIC; | 4121 | ndlp->nlp_type |= NLP_FABRIC; |
4100 | } else { | 4122 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
4101 | if (!NLP_CHK_NODE_ACT(ndlp)) { | 4123 | ndlp = lpfc_enable_node(vport, ndlp, |
4102 | ndlp = lpfc_enable_node(vport, ndlp, | 4124 | NLP_STE_UNUSED_NODE); |
4103 | NLP_STE_UNUSED_NODE); | 4125 | if (!ndlp) |
4104 | if (!ndlp) | 4126 | goto dropit; |
4105 | goto dropit; | 4127 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
4106 | } | 4128 | newnode = 1; |
4107 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { | 4129 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
4108 | /* This is simular to the new node path */ | 4130 | ndlp->nlp_type |= NLP_FABRIC; |
4109 | ndlp = lpfc_nlp_get(ndlp); | 4131 | } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { |
4110 | if (!ndlp) | 4132 | /* This is similar to the new node path */ |
4111 | goto dropit; | 4133 | ndlp = lpfc_nlp_get(ndlp); |
4112 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 4134 | if (!ndlp) |
4113 | newnode = 1; | 4135 | goto dropit; |
4114 | } | 4136 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
4137 | newnode = 1; | ||
4115 | } | 4138 | } |
4116 | 4139 | ||
4117 | phba->fc_stat.elsRcvFrame++; | 4140 | phba->fc_stat.elsRcvFrame++; |
@@ -4451,7 +4474,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4451 | return; | 4474 | return; |
4452 | } | 4475 | } |
4453 | lpfc_nlp_init(vport, ndlp, NameServer_DID); | 4476 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
4454 | ndlp->nlp_type |= NLP_FABRIC; | ||
4455 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | 4477 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
4456 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | 4478 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); |
4457 | if (!ndlp) { | 4479 | if (!ndlp) { |
@@ -4465,6 +4487,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4465 | return; | 4487 | return; |
4466 | } | 4488 | } |
4467 | } | 4489 | } |
4490 | ndlp->nlp_type |= NLP_FABRIC; | ||
4468 | 4491 | ||
4469 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); | 4492 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
4470 | 4493 | ||
@@ -4481,8 +4504,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4481 | if (ndlp_fdmi) { | 4504 | if (ndlp_fdmi) { |
4482 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); | 4505 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); |
4483 | ndlp_fdmi->nlp_type |= NLP_FABRIC; | 4506 | ndlp_fdmi->nlp_type |= NLP_FABRIC; |
4484 | ndlp_fdmi->nlp_state = | 4507 | lpfc_nlp_set_state(vport, ndlp_fdmi, |
4485 | NLP_STE_PLOGI_ISSUE; | 4508 | NLP_STE_PLOGI_ISSUE); |
4486 | lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, | 4509 | lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, |
4487 | 0); | 4510 | 0); |
4488 | } | 4511 | } |
@@ -5074,39 +5097,3 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | |||
5074 | (piocb->iocb_cmpl) (phba, piocb, piocb); | 5097 | (piocb->iocb_cmpl) (phba, piocb, piocb); |
5075 | } | 5098 | } |
5076 | } | 5099 | } |
5077 | |||
5078 | |||
5079 | #if 0 | ||
5080 | void lpfc_fabric_abort_flogi(struct lpfc_hba *phba) | ||
5081 | { | ||
5082 | LIST_HEAD(completions); | ||
5083 | struct lpfc_iocbq *tmp_iocb, *piocb; | ||
5084 | IOCB_t *cmd; | ||
5085 | struct lpfc_nodelist *ndlp; | ||
5086 | |||
5087 | spin_lock_irq(&phba->hbalock); | ||
5088 | list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list, | ||
5089 | list) { | ||
5090 | |||
5091 | cmd = &piocb->iocb; | ||
5092 | ndlp = (struct lpfc_nodelist *) piocb->context1; | ||
5093 | if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR && | ||
5094 | ndlp != NULL && | ||
5095 | ndlp->nlp_DID == Fabric_DID) | ||
5096 | list_move_tail(&piocb->list, &completions); | ||
5097 | } | ||
5098 | spin_unlock_irq(&phba->hbalock); | ||
5099 | |||
5100 | while (!list_empty(&completions)) { | ||
5101 | piocb = list_get_first(&completions, struct lpfc_iocbq, list); | ||
5102 | list_del_init(&piocb->list); | ||
5103 | |||
5104 | cmd = &piocb->iocb; | ||
5105 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
5106 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
5107 | (piocb->iocb_cmpl) (phba, piocb, piocb); | ||
5108 | } | ||
5109 | } | ||
5110 | #endif /* 0 */ | ||
5111 | |||
5112 | |||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 976653440fba..7cb68feb04fd 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -69,7 +69,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport) | |||
69 | rdata = rport->dd_data; | 69 | rdata = rport->dd_data; |
70 | ndlp = rdata->pnode; | 70 | ndlp = rdata->pnode; |
71 | 71 | ||
72 | if (!ndlp) { | 72 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
73 | if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) | 73 | if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) |
74 | printk(KERN_ERR "Cannot find remote node" | 74 | printk(KERN_ERR "Cannot find remote node" |
75 | " to terminate I/O Data x%x\n", | 75 | " to terminate I/O Data x%x\n", |
@@ -114,7 +114,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
114 | 114 | ||
115 | rdata = rport->dd_data; | 115 | rdata = rport->dd_data; |
116 | ndlp = rdata->pnode; | 116 | ndlp = rdata->pnode; |
117 | if (!ndlp) | 117 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) |
118 | return; | 118 | return; |
119 | 119 | ||
120 | vport = ndlp->vport; | 120 | vport = ndlp->vport; |
@@ -243,8 +243,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
243 | if (warn_on) { | 243 | if (warn_on) { |
244 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 244 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
245 | "0203 Devloss timeout on " | 245 | "0203 Devloss timeout on " |
246 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " | 246 | "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " |
247 | "NPort x%x Data: x%x x%x x%x\n", | 247 | "NPort x%06x Data: x%x x%x x%x\n", |
248 | *name, *(name+1), *(name+2), *(name+3), | 248 | *name, *(name+1), *(name+2), *(name+3), |
249 | *(name+4), *(name+5), *(name+6), *(name+7), | 249 | *(name+4), *(name+5), *(name+6), *(name+7), |
250 | ndlp->nlp_DID, ndlp->nlp_flag, | 250 | ndlp->nlp_DID, ndlp->nlp_flag, |
@@ -252,8 +252,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
252 | } else { | 252 | } else { |
253 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 253 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
254 | "0204 Devloss timeout on " | 254 | "0204 Devloss timeout on " |
255 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " | 255 | "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " |
256 | "NPort x%x Data: x%x x%x x%x\n", | 256 | "NPort x%06x Data: x%x x%x x%x\n", |
257 | *name, *(name+1), *(name+2), *(name+3), | 257 | *name, *(name+1), *(name+2), *(name+3), |
258 | *(name+4), *(name+5), *(name+6), *(name+7), | 258 | *(name+4), *(name+5), *(name+6), *(name+7), |
259 | ndlp->nlp_DID, ndlp->nlp_flag, | 259 | ndlp->nlp_DID, ndlp->nlp_flag, |
@@ -399,7 +399,10 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
399 | vport = vports[i]; | 399 | vport = vports[i]; |
400 | if (vport == NULL) | 400 | if (vport == NULL) |
401 | break; | 401 | break; |
402 | spin_lock_irq(&vport->work_port_lock); | ||
402 | work_port_events = vport->work_port_events; | 403 | work_port_events = vport->work_port_events; |
404 | vport->work_port_events &= ~work_port_events; | ||
405 | spin_unlock_irq(&vport->work_port_lock); | ||
403 | if (work_port_events & WORKER_DISC_TMO) | 406 | if (work_port_events & WORKER_DISC_TMO) |
404 | lpfc_disc_timeout_handler(vport); | 407 | lpfc_disc_timeout_handler(vport); |
405 | if (work_port_events & WORKER_ELS_TMO) | 408 | if (work_port_events & WORKER_ELS_TMO) |
@@ -416,9 +419,6 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
416 | lpfc_ramp_down_queue_handler(phba); | 419 | lpfc_ramp_down_queue_handler(phba); |
417 | if (work_port_events & WORKER_RAMP_UP_QUEUE) | 420 | if (work_port_events & WORKER_RAMP_UP_QUEUE) |
418 | lpfc_ramp_up_queue_handler(phba); | 421 | lpfc_ramp_up_queue_handler(phba); |
419 | spin_lock_irq(&vport->work_port_lock); | ||
420 | vport->work_port_events &= ~work_port_events; | ||
421 | spin_unlock_irq(&vport->work_port_lock); | ||
422 | } | 422 | } |
423 | lpfc_destroy_vport_work_array(phba, vports); | 423 | lpfc_destroy_vport_work_array(phba, vports); |
424 | 424 | ||
@@ -430,10 +430,10 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
430 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { | 430 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { |
431 | pring->flag |= LPFC_DEFERRED_RING_EVENT; | 431 | pring->flag |= LPFC_DEFERRED_RING_EVENT; |
432 | } else { | 432 | } else { |
433 | pring->flag &= ~LPFC_DEFERRED_RING_EVENT; | ||
433 | lpfc_sli_handle_slow_ring_event(phba, pring, | 434 | lpfc_sli_handle_slow_ring_event(phba, pring, |
434 | (status & | 435 | (status & |
435 | HA_RXMASK)); | 436 | HA_RXMASK)); |
436 | pring->flag &= ~LPFC_DEFERRED_RING_EVENT; | ||
437 | } | 437 | } |
438 | /* | 438 | /* |
439 | * Turn on Ring interrupts | 439 | * Turn on Ring interrupts |
@@ -519,7 +519,9 @@ lpfc_do_work(void *p) | |||
519 | schedule(); | 519 | schedule(); |
520 | } | 520 | } |
521 | } | 521 | } |
522 | spin_lock_irq(&phba->hbalock); | ||
522 | phba->work_wait = NULL; | 523 | phba->work_wait = NULL; |
524 | spin_unlock_irq(&phba->hbalock); | ||
523 | return 0; | 525 | return 0; |
524 | } | 526 | } |
525 | 527 | ||
@@ -809,11 +811,9 @@ out: | |||
809 | mempool_free(pmb, phba->mbox_mem_pool); | 811 | mempool_free(pmb, phba->mbox_mem_pool); |
810 | 812 | ||
811 | spin_lock_irq(shost->host_lock); | 813 | spin_lock_irq(shost->host_lock); |
812 | vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK); | 814 | vport->fc_flag &= ~FC_ABORT_DISCOVERY; |
813 | spin_unlock_irq(shost->host_lock); | 815 | spin_unlock_irq(shost->host_lock); |
814 | 816 | ||
815 | del_timer_sync(&phba->fc_estabtmo); | ||
816 | |||
817 | lpfc_can_disctmo(vport); | 817 | lpfc_can_disctmo(vport); |
818 | 818 | ||
819 | /* turn on Link Attention interrupts */ | 819 | /* turn on Link Attention interrupts */ |
@@ -1340,10 +1340,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1340 | i++) { | 1340 | i++) { |
1341 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | 1341 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) |
1342 | continue; | 1342 | continue; |
1343 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1344 | lpfc_vport_set_state(vports[i], | ||
1345 | FC_VPORT_LINKDOWN); | ||
1346 | continue; | ||
1347 | } | ||
1343 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1348 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
1344 | lpfc_initial_fdisc(vports[i]); | 1349 | lpfc_initial_fdisc(vports[i]); |
1345 | else if (phba->sli3_options & | 1350 | else { |
1346 | LPFC_SLI3_NPIV_ENABLED) { | ||
1347 | lpfc_vport_set_state(vports[i], | 1351 | lpfc_vport_set_state(vports[i], |
1348 | FC_VPORT_NO_FABRIC_SUPP); | 1352 | FC_VPORT_NO_FABRIC_SUPP); |
1349 | lpfc_printf_vlog(vport, KERN_ERR, | 1353 | lpfc_printf_vlog(vport, KERN_ERR, |
@@ -2190,10 +2194,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2190 | if (did == Bcast_DID) | 2194 | if (did == Bcast_DID) |
2191 | return 0; | 2195 | return 0; |
2192 | 2196 | ||
2193 | if (ndlp->nlp_DID == 0) { | ||
2194 | return 0; | ||
2195 | } | ||
2196 | |||
2197 | /* First check for Direct match */ | 2197 | /* First check for Direct match */ |
2198 | if (ndlp->nlp_DID == did) | 2198 | if (ndlp->nlp_DID == did) |
2199 | return 1; | 2199 | return 1; |
@@ -2301,7 +2301,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
2301 | return ndlp; | 2301 | return ndlp; |
2302 | } | 2302 | } |
2303 | 2303 | ||
2304 | if (vport->fc_flag & FC_RSCN_MODE) { | 2304 | if ((vport->fc_flag & FC_RSCN_MODE) && |
2305 | !(vport->fc_flag & FC_NDISC_ACTIVE)) { | ||
2305 | if (lpfc_rscn_payload_check(vport, did)) { | 2306 | if (lpfc_rscn_payload_check(vport, did)) { |
2306 | /* If we've already recieved a PLOGI from this NPort | 2307 | /* If we've already recieved a PLOGI from this NPort |
2307 | * we don't need to try to discover it again. | 2308 | * we don't need to try to discover it again. |
@@ -2947,24 +2948,6 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | |||
2947 | return NULL; | 2948 | return NULL; |
2948 | } | 2949 | } |
2949 | 2950 | ||
2950 | #if 0 | ||
2951 | /* | ||
2952 | * Search node lists for a remote port matching filter criteria | ||
2953 | * Caller needs to hold host_lock before calling this routine. | ||
2954 | */ | ||
2955 | struct lpfc_nodelist * | ||
2956 | lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | ||
2957 | { | ||
2958 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2959 | struct lpfc_nodelist *ndlp; | ||
2960 | |||
2961 | spin_lock_irq(shost->host_lock); | ||
2962 | ndlp = __lpfc_find_node(vport, filter, param); | ||
2963 | spin_unlock_irq(shost->host_lock); | ||
2964 | return ndlp; | ||
2965 | } | ||
2966 | #endif /* 0 */ | ||
2967 | |||
2968 | /* | 2951 | /* |
2969 | * This routine looks up the ndlp lists for the given RPI. If rpi found it | 2952 | * This routine looks up the ndlp lists for the given RPI. If rpi found it |
2970 | * returns the node list element pointer else return NULL. | 2953 | * returns the node list element pointer else return NULL. |
@@ -2975,20 +2958,6 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | |||
2975 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); | 2958 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); |
2976 | } | 2959 | } |
2977 | 2960 | ||
2978 | #if 0 | ||
2979 | struct lpfc_nodelist * | ||
2980 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | ||
2981 | { | ||
2982 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2983 | struct lpfc_nodelist *ndlp; | ||
2984 | |||
2985 | spin_lock_irq(shost->host_lock); | ||
2986 | ndlp = __lpfc_findnode_rpi(vport, rpi); | ||
2987 | spin_unlock_irq(shost->host_lock); | ||
2988 | return ndlp; | ||
2989 | } | ||
2990 | #endif /* 0 */ | ||
2991 | |||
2992 | /* | 2961 | /* |
2993 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it | 2962 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it |
2994 | * returns the node element list pointer else return NULL. | 2963 | * returns the node element list pointer else return NULL. |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 22843751c2ca..fa757b251f82 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -559,8 +559,10 @@ lpfc_hb_timeout(unsigned long ptr) | |||
559 | phba->pport->work_port_events |= WORKER_HB_TMO; | 559 | phba->pport->work_port_events |= WORKER_HB_TMO; |
560 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); | 560 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); |
561 | 561 | ||
562 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
562 | if (phba->work_wait) | 563 | if (phba->work_wait) |
563 | wake_up(phba->work_wait); | 564 | wake_up(phba->work_wait); |
565 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
564 | return; | 566 | return; |
565 | } | 567 | } |
566 | 568 | ||
@@ -714,12 +716,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
714 | struct lpfc_vport *vport = phba->pport; | 716 | struct lpfc_vport *vport = phba->pport; |
715 | struct lpfc_sli *psli = &phba->sli; | 717 | struct lpfc_sli *psli = &phba->sli; |
716 | struct lpfc_sli_ring *pring; | 718 | struct lpfc_sli_ring *pring; |
717 | struct lpfc_vport **vports; | ||
718 | uint32_t event_data; | 719 | uint32_t event_data; |
719 | unsigned long temperature; | 720 | unsigned long temperature; |
720 | struct temp_event temp_event_data; | 721 | struct temp_event temp_event_data; |
721 | struct Scsi_Host *shost; | 722 | struct Scsi_Host *shost; |
722 | int i; | ||
723 | 723 | ||
724 | /* If the pci channel is offline, ignore possible errors, | 724 | /* If the pci channel is offline, ignore possible errors, |
725 | * since we cannot communicate with the pci card anyway. */ | 725 | * since we cannot communicate with the pci card anyway. */ |
@@ -729,25 +729,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
729 | if (!phba->cfg_enable_hba_reset) | 729 | if (!phba->cfg_enable_hba_reset) |
730 | return; | 730 | return; |
731 | 731 | ||
732 | if (phba->work_hs & HS_FFER6 || | 732 | if (phba->work_hs & HS_FFER6) { |
733 | phba->work_hs & HS_FFER5) { | ||
734 | /* Re-establishing Link */ | 733 | /* Re-establishing Link */ |
735 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 734 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
736 | "1301 Re-establishing Link " | 735 | "1301 Re-establishing Link " |
737 | "Data: x%x x%x x%x\n", | 736 | "Data: x%x x%x x%x\n", |
738 | phba->work_hs, | 737 | phba->work_hs, |
739 | phba->work_status[0], phba->work_status[1]); | 738 | phba->work_status[0], phba->work_status[1]); |
740 | vports = lpfc_create_vport_work_array(phba); | 739 | |
741 | if (vports != NULL) | ||
742 | for(i = 0; | ||
743 | i <= phba->max_vpi && vports[i] != NULL; | ||
744 | i++){ | ||
745 | shost = lpfc_shost_from_vport(vports[i]); | ||
746 | spin_lock_irq(shost->host_lock); | ||
747 | vports[i]->fc_flag |= FC_ESTABLISH_LINK; | ||
748 | spin_unlock_irq(shost->host_lock); | ||
749 | } | ||
750 | lpfc_destroy_vport_work_array(phba, vports); | ||
751 | spin_lock_irq(&phba->hbalock); | 740 | spin_lock_irq(&phba->hbalock); |
752 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 741 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
753 | spin_unlock_irq(&phba->hbalock); | 742 | spin_unlock_irq(&phba->hbalock); |
@@ -761,7 +750,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
761 | pring = &psli->ring[psli->fcp_ring]; | 750 | pring = &psli->ring[psli->fcp_ring]; |
762 | lpfc_sli_abort_iocb_ring(phba, pring); | 751 | lpfc_sli_abort_iocb_ring(phba, pring); |
763 | 752 | ||
764 | |||
765 | /* | 753 | /* |
766 | * There was a firmware error. Take the hba offline and then | 754 | * There was a firmware error. Take the hba offline and then |
767 | * attempt to restart it. | 755 | * attempt to restart it. |
@@ -770,7 +758,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
770 | lpfc_offline(phba); | 758 | lpfc_offline(phba); |
771 | lpfc_sli_brdrestart(phba); | 759 | lpfc_sli_brdrestart(phba); |
772 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ | 760 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ |
773 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
774 | lpfc_unblock_mgmt_io(phba); | 761 | lpfc_unblock_mgmt_io(phba); |
775 | return; | 762 | return; |
776 | } | 763 | } |
@@ -1454,6 +1441,13 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1454 | NLP_SET_FREE_REQ(ndlp); | 1441 | NLP_SET_FREE_REQ(ndlp); |
1455 | spin_unlock_irq(&phba->ndlp_lock); | 1442 | spin_unlock_irq(&phba->ndlp_lock); |
1456 | 1443 | ||
1444 | if (vport->port_type != LPFC_PHYSICAL_PORT && | ||
1445 | ndlp->nlp_DID == Fabric_DID) { | ||
1446 | /* Just free up ndlp with Fabric_DID for vports */ | ||
1447 | lpfc_nlp_put(ndlp); | ||
1448 | continue; | ||
1449 | } | ||
1450 | |||
1457 | if (ndlp->nlp_type & NLP_FABRIC) | 1451 | if (ndlp->nlp_type & NLP_FABRIC) |
1458 | lpfc_disc_state_machine(vport, ndlp, NULL, | 1452 | lpfc_disc_state_machine(vport, ndlp, NULL, |
1459 | NLP_EVT_DEVICE_RECOVERY); | 1453 | NLP_EVT_DEVICE_RECOVERY); |
@@ -1491,31 +1485,6 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1491 | return; | 1485 | return; |
1492 | } | 1486 | } |
1493 | 1487 | ||
1494 | static void | ||
1495 | lpfc_establish_link_tmo(unsigned long ptr) | ||
1496 | { | ||
1497 | struct lpfc_hba *phba = (struct lpfc_hba *) ptr; | ||
1498 | struct lpfc_vport **vports; | ||
1499 | unsigned long iflag; | ||
1500 | int i; | ||
1501 | |||
1502 | /* Re-establishing Link, timer expired */ | ||
1503 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | ||
1504 | "1300 Re-establishing Link, timer expired " | ||
1505 | "Data: x%x x%x\n", | ||
1506 | phba->pport->fc_flag, phba->pport->port_state); | ||
1507 | vports = lpfc_create_vport_work_array(phba); | ||
1508 | if (vports != NULL) | ||
1509 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | ||
1510 | struct Scsi_Host *shost; | ||
1511 | shost = lpfc_shost_from_vport(vports[i]); | ||
1512 | spin_lock_irqsave(shost->host_lock, iflag); | ||
1513 | vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; | ||
1514 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1515 | } | ||
1516 | lpfc_destroy_vport_work_array(phba, vports); | ||
1517 | } | ||
1518 | |||
1519 | void | 1488 | void |
1520 | lpfc_stop_vport_timers(struct lpfc_vport *vport) | 1489 | lpfc_stop_vport_timers(struct lpfc_vport *vport) |
1521 | { | 1490 | { |
@@ -1529,7 +1498,6 @@ static void | |||
1529 | lpfc_stop_phba_timers(struct lpfc_hba *phba) | 1498 | lpfc_stop_phba_timers(struct lpfc_hba *phba) |
1530 | { | 1499 | { |
1531 | del_timer_sync(&phba->fcp_poll_timer); | 1500 | del_timer_sync(&phba->fcp_poll_timer); |
1532 | del_timer_sync(&phba->fc_estabtmo); | ||
1533 | lpfc_stop_vport_timers(phba->pport); | 1501 | lpfc_stop_vport_timers(phba->pport); |
1534 | del_timer_sync(&phba->sli.mbox_tmo); | 1502 | del_timer_sync(&phba->sli.mbox_tmo); |
1535 | del_timer_sync(&phba->fabric_block_timer); | 1503 | del_timer_sync(&phba->fabric_block_timer); |
@@ -2005,10 +1973,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2005 | phba->max_vpi = LPFC_MAX_VPI; | 1973 | phba->max_vpi = LPFC_MAX_VPI; |
2006 | 1974 | ||
2007 | /* Initialize timers used by driver */ | 1975 | /* Initialize timers used by driver */ |
2008 | init_timer(&phba->fc_estabtmo); | ||
2009 | phba->fc_estabtmo.function = lpfc_establish_link_tmo; | ||
2010 | phba->fc_estabtmo.data = (unsigned long)phba; | ||
2011 | |||
2012 | init_timer(&phba->hb_tmofunc); | 1976 | init_timer(&phba->hb_tmofunc); |
2013 | phba->hb_tmofunc.function = lpfc_hb_timeout; | 1977 | phba->hb_tmofunc.function = lpfc_hb_timeout; |
2014 | phba->hb_tmofunc.data = (unsigned long)phba; | 1978 | phba->hb_tmofunc.data = (unsigned long)phba; |
@@ -2406,6 +2370,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
2406 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2370 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
2407 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2371 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2408 | struct lpfc_sli *psli = &phba->sli; | 2372 | struct lpfc_sli *psli = &phba->sli; |
2373 | int error, retval; | ||
2409 | 2374 | ||
2410 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); | 2375 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); |
2411 | if (pci_enable_device_mem(pdev)) { | 2376 | if (pci_enable_device_mem(pdev)) { |
@@ -2416,15 +2381,40 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
2416 | 2381 | ||
2417 | pci_set_master(pdev); | 2382 | pci_set_master(pdev); |
2418 | 2383 | ||
2419 | /* Re-establishing Link */ | ||
2420 | spin_lock_irq(shost->host_lock); | ||
2421 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
2422 | spin_unlock_irq(shost->host_lock); | ||
2423 | |||
2424 | spin_lock_irq(&phba->hbalock); | 2384 | spin_lock_irq(&phba->hbalock); |
2425 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 2385 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2426 | spin_unlock_irq(&phba->hbalock); | 2386 | spin_unlock_irq(&phba->hbalock); |
2427 | 2387 | ||
2388 | /* Enable configured interrupt method */ | ||
2389 | phba->intr_type = NONE; | ||
2390 | if (phba->cfg_use_msi == 2) { | ||
2391 | error = lpfc_enable_msix(phba); | ||
2392 | if (!error) | ||
2393 | phba->intr_type = MSIX; | ||
2394 | } | ||
2395 | |||
2396 | /* Fallback to MSI if MSI-X initialization failed */ | ||
2397 | if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { | ||
2398 | retval = pci_enable_msi(phba->pcidev); | ||
2399 | if (!retval) | ||
2400 | phba->intr_type = MSI; | ||
2401 | else | ||
2402 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
2403 | "0470 Enable MSI failed, continuing " | ||
2404 | "with IRQ\n"); | ||
2405 | } | ||
2406 | |||
2407 | /* MSI-X is the only case the doesn't need to call request_irq */ | ||
2408 | if (phba->intr_type != MSIX) { | ||
2409 | retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, | ||
2410 | IRQF_SHARED, LPFC_DRIVER_NAME, phba); | ||
2411 | if (retval) { | ||
2412 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
2413 | "0471 Enable interrupt handler " | ||
2414 | "failed\n"); | ||
2415 | } else if (phba->intr_type != MSI) | ||
2416 | phba->intr_type = INTx; | ||
2417 | } | ||
2428 | 2418 | ||
2429 | /* Take device offline; this will perform cleanup */ | 2419 | /* Take device offline; this will perform cleanup */ |
2430 | lpfc_offline(phba); | 2420 | lpfc_offline(phba); |
@@ -2445,9 +2435,7 @@ static void lpfc_io_resume(struct pci_dev *pdev) | |||
2445 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2435 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
2446 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2436 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2447 | 2437 | ||
2448 | if (lpfc_online(phba) == 0) { | 2438 | lpfc_online(phba); |
2449 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2450 | } | ||
2451 | } | 2439 | } |
2452 | 2440 | ||
2453 | static struct pci_device_id lpfc_id_table[] = { | 2441 | static struct pci_device_id lpfc_id_table[] = { |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d513813f6697..d08c4c890744 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -451,7 +451,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
451 | spin_unlock_irq(shost->host_lock); | 451 | spin_unlock_irq(shost->host_lock); |
452 | 452 | ||
453 | if ((ndlp->nlp_flag & NLP_ADISC_SND) && | 453 | if ((ndlp->nlp_flag & NLP_ADISC_SND) && |
454 | (vport->num_disc_nodes)) { | 454 | (vport->num_disc_nodes)) { |
455 | /* Check to see if there are more | 455 | /* Check to see if there are more |
456 | * ADISCs to be sent | 456 | * ADISCs to be sent |
457 | */ | 457 | */ |
@@ -469,20 +469,23 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
469 | lpfc_end_rscn(vport); | 469 | lpfc_end_rscn(vport); |
470 | } | 470 | } |
471 | } | 471 | } |
472 | else if (vport->num_disc_nodes) { | 472 | } |
473 | /* Check to see if there are more | 473 | } else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) && |
474 | * PLOGIs to be sent | 474 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
475 | */ | 475 | (vport->num_disc_nodes)) { |
476 | lpfc_more_plogi(vport); | 476 | spin_lock_irq(shost->host_lock); |
477 | 477 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | |
478 | if (vport->num_disc_nodes == 0) { | 478 | spin_unlock_irq(shost->host_lock); |
479 | spin_lock_irq(shost->host_lock); | 479 | /* Check to see if there are more |
480 | vport->fc_flag &= ~FC_NDISC_ACTIVE; | 480 | * PLOGIs to be sent |
481 | spin_unlock_irq(shost->host_lock); | 481 | */ |
482 | lpfc_can_disctmo(vport); | 482 | lpfc_more_plogi(vport); |
483 | lpfc_end_rscn(vport); | 483 | if (vport->num_disc_nodes == 0) { |
484 | } | 484 | spin_lock_irq(shost->host_lock); |
485 | } | 485 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
486 | spin_unlock_irq(shost->host_lock); | ||
487 | lpfc_can_disctmo(vport); | ||
488 | lpfc_end_rscn(vport); | ||
486 | } | 489 | } |
487 | } | 490 | } |
488 | 491 | ||
@@ -869,8 +872,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
869 | 872 | ||
870 | lp = (uint32_t *) prsp->virt; | 873 | lp = (uint32_t *) prsp->virt; |
871 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 874 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
872 | if (wwn_to_u64(sp->portName.u.wwn) == 0 || | 875 | |
873 | wwn_to_u64(sp->nodeName.u.wwn) == 0) { | 876 | /* Some switches have FDMI servers returning 0 for WWN */ |
877 | if ((ndlp->nlp_DID != FDMI_DID) && | ||
878 | (wwn_to_u64(sp->portName.u.wwn) == 0 || | ||
879 | wwn_to_u64(sp->nodeName.u.wwn) == 0)) { | ||
874 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 880 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
875 | "0142 PLOGI RSP: Invalid WWN.\n"); | 881 | "0142 PLOGI RSP: Invalid WWN.\n"); |
876 | goto out; | 882 | goto out; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 70255c11d3ad..0910a9ab76a5 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -169,6 +169,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | 169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
170 | shost = lpfc_shost_from_vport(vports[i]); | 170 | shost = lpfc_shost_from_vport(vports[i]); |
171 | shost_for_each_device(sdev, shost) { | 171 | shost_for_each_device(sdev, shost) { |
172 | if (vports[i]->cfg_lun_queue_depth <= | ||
173 | sdev->queue_depth) | ||
174 | continue; | ||
172 | if (sdev->ordered_tags) | 175 | if (sdev->ordered_tags) |
173 | scsi_adjust_queue_depth(sdev, | 176 | scsi_adjust_queue_depth(sdev, |
174 | MSG_ORDERED_TAG, | 177 | MSG_ORDERED_TAG, |
@@ -578,14 +581,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
578 | lpfc_cmd->result == IOERR_NO_RESOURCES || | 581 | lpfc_cmd->result == IOERR_NO_RESOURCES || |
579 | lpfc_cmd->result == RJT_LOGIN_REQUIRED) { | 582 | lpfc_cmd->result == RJT_LOGIN_REQUIRED) { |
580 | cmd->result = ScsiResult(DID_REQUEUE, 0); | 583 | cmd->result = ScsiResult(DID_REQUEUE, 0); |
581 | break; | 584 | break; |
582 | } /* else: fall through */ | 585 | } /* else: fall through */ |
583 | default: | 586 | default: |
584 | cmd->result = ScsiResult(DID_ERROR, 0); | 587 | cmd->result = ScsiResult(DID_ERROR, 0); |
585 | break; | 588 | break; |
586 | } | 589 | } |
587 | 590 | ||
588 | if ((pnode == NULL ) | 591 | if (!pnode || !NLP_CHK_NODE_ACT(pnode) |
589 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) | 592 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) |
590 | cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); | 593 | cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); |
591 | } else { | 594 | } else { |
@@ -606,6 +609,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
606 | result = cmd->result; | 609 | result = cmd->result; |
607 | sdev = cmd->device; | 610 | sdev = cmd->device; |
608 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | 611 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); |
612 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
613 | lpfc_cmd->pCmd = NULL; /* This must be done before scsi_done */ | ||
614 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
609 | cmd->scsi_done(cmd); | 615 | cmd->scsi_done(cmd); |
610 | 616 | ||
611 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 617 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
@@ -614,7 +620,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
614 | * wake up the thread. | 620 | * wake up the thread. |
615 | */ | 621 | */ |
616 | spin_lock_irqsave(sdev->host->host_lock, flags); | 622 | spin_lock_irqsave(sdev->host->host_lock, flags); |
617 | lpfc_cmd->pCmd = NULL; | ||
618 | if (lpfc_cmd->waitq) | 623 | if (lpfc_cmd->waitq) |
619 | wake_up(lpfc_cmd->waitq); | 624 | wake_up(lpfc_cmd->waitq); |
620 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 625 | spin_unlock_irqrestore(sdev->host->host_lock, flags); |
@@ -626,7 +631,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
626 | if (!result) | 631 | if (!result) |
627 | lpfc_rampup_queue_depth(vport, sdev); | 632 | lpfc_rampup_queue_depth(vport, sdev); |
628 | 633 | ||
629 | if (!result && pnode != NULL && | 634 | if (!result && pnode && NLP_CHK_NODE_ACT(pnode) && |
630 | ((jiffies - pnode->last_ramp_up_time) > | 635 | ((jiffies - pnode->last_ramp_up_time) > |
631 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && | 636 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && |
632 | ((jiffies - pnode->last_q_full_time) > | 637 | ((jiffies - pnode->last_q_full_time) > |
@@ -654,7 +659,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
654 | * Check for queue full. If the lun is reporting queue full, then | 659 | * Check for queue full. If the lun is reporting queue full, then |
655 | * back off the lun queue depth to prevent target overloads. | 660 | * back off the lun queue depth to prevent target overloads. |
656 | */ | 661 | */ |
657 | if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) { | 662 | if (result == SAM_STAT_TASK_SET_FULL && pnode && |
663 | NLP_CHK_NODE_ACT(pnode)) { | ||
658 | pnode->last_q_full_time = jiffies; | 664 | pnode->last_q_full_time = jiffies; |
659 | 665 | ||
660 | shost_for_each_device(tmp_sdev, sdev->host) { | 666 | shost_for_each_device(tmp_sdev, sdev->host) { |
@@ -684,7 +690,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
684 | * wake up the thread. | 690 | * wake up the thread. |
685 | */ | 691 | */ |
686 | spin_lock_irqsave(sdev->host->host_lock, flags); | 692 | spin_lock_irqsave(sdev->host->host_lock, flags); |
687 | lpfc_cmd->pCmd = NULL; | ||
688 | if (lpfc_cmd->waitq) | 693 | if (lpfc_cmd->waitq) |
689 | wake_up(lpfc_cmd->waitq); | 694 | wake_up(lpfc_cmd->waitq); |
690 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 695 | spin_unlock_irqrestore(sdev->host->host_lock, flags); |
@@ -704,6 +709,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
704 | int datadir = scsi_cmnd->sc_data_direction; | 709 | int datadir = scsi_cmnd->sc_data_direction; |
705 | char tag[2]; | 710 | char tag[2]; |
706 | 711 | ||
712 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) | ||
713 | return; | ||
714 | |||
707 | lpfc_cmd->fcp_rsp->rspSnsLen = 0; | 715 | lpfc_cmd->fcp_rsp->rspSnsLen = 0; |
708 | /* clear task management bits */ | 716 | /* clear task management bits */ |
709 | lpfc_cmd->fcp_cmnd->fcpCntl2 = 0; | 717 | lpfc_cmd->fcp_cmnd->fcpCntl2 = 0; |
@@ -785,9 +793,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, | |||
785 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; | 793 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; |
786 | struct lpfc_nodelist *ndlp = rdata->pnode; | 794 | struct lpfc_nodelist *ndlp = rdata->pnode; |
787 | 795 | ||
788 | if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { | 796 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || |
797 | ndlp->nlp_state != NLP_STE_MAPPED_NODE) | ||
789 | return 0; | 798 | return 0; |
790 | } | ||
791 | 799 | ||
792 | piocbq = &(lpfc_cmd->cur_iocbq); | 800 | piocbq = &(lpfc_cmd->cur_iocbq); |
793 | piocbq->vport = vport; | 801 | piocbq->vport = vport; |
@@ -842,7 +850,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, | |||
842 | struct lpfc_iocbq *iocbqrsp; | 850 | struct lpfc_iocbq *iocbqrsp; |
843 | int ret; | 851 | int ret; |
844 | 852 | ||
845 | if (!rdata->pnode) | 853 | if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode)) |
846 | return FAILED; | 854 | return FAILED; |
847 | 855 | ||
848 | lpfc_cmd->rdata = rdata; | 856 | lpfc_cmd->rdata = rdata; |
@@ -959,7 +967,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
959 | * Catch race where our node has transitioned, but the | 967 | * Catch race where our node has transitioned, but the |
960 | * transport is still transitioning. | 968 | * transport is still transitioning. |
961 | */ | 969 | */ |
962 | if (!ndlp) { | 970 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
963 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); | 971 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); |
964 | goto out_fail_command; | 972 | goto out_fail_command; |
965 | } | 973 | } |
@@ -1146,7 +1154,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1146 | * target is rediscovered or devloss timeout expires. | 1154 | * target is rediscovered or devloss timeout expires. |
1147 | */ | 1155 | */ |
1148 | while (1) { | 1156 | while (1) { |
1149 | if (!pnode) | 1157 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) |
1150 | goto out; | 1158 | goto out; |
1151 | 1159 | ||
1152 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { | 1160 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { |
@@ -1162,7 +1170,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1162 | goto out; | 1170 | goto out; |
1163 | } | 1171 | } |
1164 | pnode = rdata->pnode; | 1172 | pnode = rdata->pnode; |
1165 | if (!pnode) | 1173 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) |
1166 | goto out; | 1174 | goto out; |
1167 | } | 1175 | } |
1168 | if (pnode->nlp_state == NLP_STE_MAPPED_NODE) | 1176 | if (pnode->nlp_state == NLP_STE_MAPPED_NODE) |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fc0d9501aba6..70a0a9eab211 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -2648,7 +2648,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2648 | spin_unlock_irq(&phba->pport->work_port_lock); | 2648 | spin_unlock_irq(&phba->pport->work_port_lock); |
2649 | spin_lock_irq(&phba->hbalock); | 2649 | spin_lock_irq(&phba->hbalock); |
2650 | phba->link_state = LPFC_LINK_UNKNOWN; | 2650 | phba->link_state = LPFC_LINK_UNKNOWN; |
2651 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
2652 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 2651 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2653 | spin_unlock_irq(&phba->hbalock); | 2652 | spin_unlock_irq(&phba->hbalock); |
2654 | 2653 | ||
@@ -2669,8 +2668,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2669 | lpfc_offline_prep(phba); | 2668 | lpfc_offline_prep(phba); |
2670 | lpfc_offline(phba); | 2669 | lpfc_offline(phba); |
2671 | lpfc_sli_brdrestart(phba); | 2670 | lpfc_sli_brdrestart(phba); |
2672 | if (lpfc_online(phba) == 0) /* Initialize the HBA */ | 2671 | lpfc_online(phba); |
2673 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2674 | lpfc_unblock_mgmt_io(phba); | 2672 | lpfc_unblock_mgmt_io(phba); |
2675 | return; | 2673 | return; |
2676 | } | 2674 | } |
@@ -2687,28 +2685,41 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2687 | unsigned long drvr_flag = 0; | 2685 | unsigned long drvr_flag = 0; |
2688 | volatile uint32_t word0, ldata; | 2686 | volatile uint32_t word0, ldata; |
2689 | void __iomem *to_slim; | 2687 | void __iomem *to_slim; |
2688 | int processing_queue = 0; | ||
2689 | |||
2690 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | ||
2691 | if (!pmbox) { | ||
2692 | /* processing mbox queue from intr_handler */ | ||
2693 | processing_queue = 1; | ||
2694 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
2695 | pmbox = lpfc_mbox_get(phba); | ||
2696 | if (!pmbox) { | ||
2697 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | ||
2698 | return MBX_SUCCESS; | ||
2699 | } | ||
2700 | } | ||
2690 | 2701 | ||
2691 | if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && | 2702 | if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && |
2692 | pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { | 2703 | pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { |
2693 | if(!pmbox->vport) { | 2704 | if(!pmbox->vport) { |
2705 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | ||
2694 | lpfc_printf_log(phba, KERN_ERR, | 2706 | lpfc_printf_log(phba, KERN_ERR, |
2695 | LOG_MBOX | LOG_VPORT, | 2707 | LOG_MBOX | LOG_VPORT, |
2696 | "1806 Mbox x%x failed. No vport\n", | 2708 | "1806 Mbox x%x failed. No vport\n", |
2697 | pmbox->mb.mbxCommand); | 2709 | pmbox->mb.mbxCommand); |
2698 | dump_stack(); | 2710 | dump_stack(); |
2699 | return MBX_NOT_FINISHED; | 2711 | goto out_not_finished; |
2700 | } | 2712 | } |
2701 | } | 2713 | } |
2702 | 2714 | ||
2703 | |||
2704 | /* If the PCI channel is in offline state, do not post mbox. */ | 2715 | /* If the PCI channel is in offline state, do not post mbox. */ |
2705 | if (unlikely(pci_channel_offline(phba->pcidev))) | 2716 | if (unlikely(pci_channel_offline(phba->pcidev))) { |
2706 | return MBX_NOT_FINISHED; | 2717 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2718 | goto out_not_finished; | ||
2719 | } | ||
2707 | 2720 | ||
2708 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | ||
2709 | psli = &phba->sli; | 2721 | psli = &phba->sli; |
2710 | 2722 | ||
2711 | |||
2712 | mb = &pmbox->mb; | 2723 | mb = &pmbox->mb; |
2713 | status = MBX_SUCCESS; | 2724 | status = MBX_SUCCESS; |
2714 | 2725 | ||
@@ -2717,14 +2728,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2717 | 2728 | ||
2718 | /* Mbox command <mbxCommand> cannot issue */ | 2729 | /* Mbox command <mbxCommand> cannot issue */ |
2719 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2730 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2720 | return MBX_NOT_FINISHED; | 2731 | goto out_not_finished; |
2721 | } | 2732 | } |
2722 | 2733 | ||
2723 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && | 2734 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && |
2724 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { | 2735 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { |
2725 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2736 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2726 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2737 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2727 | return MBX_NOT_FINISHED; | 2738 | goto out_not_finished; |
2728 | } | 2739 | } |
2729 | 2740 | ||
2730 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { | 2741 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { |
@@ -2738,14 +2749,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2738 | 2749 | ||
2739 | /* Mbox command <mbxCommand> cannot issue */ | 2750 | /* Mbox command <mbxCommand> cannot issue */ |
2740 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2751 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2741 | return MBX_NOT_FINISHED; | 2752 | goto out_not_finished; |
2742 | } | 2753 | } |
2743 | 2754 | ||
2744 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { | 2755 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { |
2745 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2756 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2746 | /* Mbox command <mbxCommand> cannot issue */ | 2757 | /* Mbox command <mbxCommand> cannot issue */ |
2747 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2758 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2748 | return MBX_NOT_FINISHED; | 2759 | goto out_not_finished; |
2749 | } | 2760 | } |
2750 | 2761 | ||
2751 | /* Another mailbox command is still being processed, queue this | 2762 | /* Another mailbox command is still being processed, queue this |
@@ -2792,7 +2803,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2792 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2803 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2793 | /* Mbox command <mbxCommand> cannot issue */ | 2804 | /* Mbox command <mbxCommand> cannot issue */ |
2794 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2805 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2795 | return MBX_NOT_FINISHED; | 2806 | goto out_not_finished; |
2796 | } | 2807 | } |
2797 | /* timeout active mbox command */ | 2808 | /* timeout active mbox command */ |
2798 | mod_timer(&psli->mbox_tmo, (jiffies + | 2809 | mod_timer(&psli->mbox_tmo, (jiffies + |
@@ -2900,7 +2911,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2900 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2911 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2901 | spin_unlock_irqrestore(&phba->hbalock, | 2912 | spin_unlock_irqrestore(&phba->hbalock, |
2902 | drvr_flag); | 2913 | drvr_flag); |
2903 | return MBX_NOT_FINISHED; | 2914 | goto out_not_finished; |
2904 | } | 2915 | } |
2905 | 2916 | ||
2906 | /* Check if we took a mbox interrupt while we were | 2917 | /* Check if we took a mbox interrupt while we were |
@@ -2967,6 +2978,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2967 | 2978 | ||
2968 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2979 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2969 | return status; | 2980 | return status; |
2981 | |||
2982 | out_not_finished: | ||
2983 | if (processing_queue) { | ||
2984 | pmbox->mb.mbxStatus = MBX_NOT_FINISHED; | ||
2985 | lpfc_mbox_cmpl_put(phba, pmbox); | ||
2986 | } | ||
2987 | return MBX_NOT_FINISHED; | ||
2970 | } | 2988 | } |
2971 | 2989 | ||
2972 | /* | 2990 | /* |
@@ -3463,26 +3481,21 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3463 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | 3481 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; |
3464 | spin_unlock(&phba->pport->work_port_lock); | 3482 | spin_unlock(&phba->pport->work_port_lock); |
3465 | 3483 | ||
3484 | /* Return any pending or completed mbox cmds */ | ||
3485 | list_splice_init(&phba->sli.mboxq, &completions); | ||
3466 | if (psli->mbox_active) { | 3486 | if (psli->mbox_active) { |
3467 | list_add_tail(&psli->mbox_active->list, &completions); | 3487 | list_add_tail(&psli->mbox_active->list, &completions); |
3468 | psli->mbox_active = NULL; | 3488 | psli->mbox_active = NULL; |
3469 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 3489 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
3470 | } | 3490 | } |
3471 | |||
3472 | /* Return any pending or completed mbox cmds */ | ||
3473 | list_splice_init(&phba->sli.mboxq, &completions); | ||
3474 | list_splice_init(&phba->sli.mboxq_cmpl, &completions); | 3491 | list_splice_init(&phba->sli.mboxq_cmpl, &completions); |
3475 | INIT_LIST_HEAD(&psli->mboxq); | ||
3476 | INIT_LIST_HEAD(&psli->mboxq_cmpl); | ||
3477 | |||
3478 | spin_unlock_irqrestore(&phba->hbalock, flags); | 3492 | spin_unlock_irqrestore(&phba->hbalock, flags); |
3479 | 3493 | ||
3480 | while (!list_empty(&completions)) { | 3494 | while (!list_empty(&completions)) { |
3481 | list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); | 3495 | list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); |
3482 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 3496 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; |
3483 | if (pmb->mbox_cmpl) { | 3497 | if (pmb->mbox_cmpl) |
3484 | pmb->mbox_cmpl(phba,pmb); | 3498 | pmb->mbox_cmpl(phba,pmb); |
3485 | } | ||
3486 | } | 3499 | } |
3487 | return 1; | 3500 | return 1; |
3488 | } | 3501 | } |
@@ -3613,6 +3626,15 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3613 | irsp->ulpStatus, irsp->un.ulpWord[4]); | 3626 | irsp->ulpStatus, irsp->un.ulpWord[4]); |
3614 | 3627 | ||
3615 | /* | 3628 | /* |
3629 | * If the iocb is not found in Firmware queue the iocb | ||
3630 | * might have completed already. Do not free it again. | ||
3631 | */ | ||
3632 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | ||
3633 | spin_unlock_irq(&phba->hbalock); | ||
3634 | lpfc_sli_release_iocbq(phba, cmdiocb); | ||
3635 | return; | ||
3636 | } | ||
3637 | /* | ||
3616 | * make sure we have the right iocbq before taking it | 3638 | * make sure we have the right iocbq before taking it |
3617 | * off the txcmplq and try to call completion routine. | 3639 | * off the txcmplq and try to call completion routine. |
3618 | */ | 3640 | */ |
@@ -4174,6 +4196,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4174 | phba->pport->stopped = 1; | 4196 | phba->pport->stopped = 1; |
4175 | } | 4197 | } |
4176 | 4198 | ||
4199 | spin_lock(&phba->hbalock); | ||
4177 | if ((work_ha_copy & HA_MBATT) && | 4200 | if ((work_ha_copy & HA_MBATT) && |
4178 | (phba->sli.mbox_active)) { | 4201 | (phba->sli.mbox_active)) { |
4179 | pmb = phba->sli.mbox_active; | 4202 | pmb = phba->sli.mbox_active; |
@@ -4184,6 +4207,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4184 | /* First check out the status word */ | 4207 | /* First check out the status word */ |
4185 | lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); | 4208 | lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); |
4186 | if (pmbox->mbxOwner != OWN_HOST) { | 4209 | if (pmbox->mbxOwner != OWN_HOST) { |
4210 | spin_unlock(&phba->hbalock); | ||
4187 | /* | 4211 | /* |
4188 | * Stray Mailbox Interrupt, mbxCommand <cmd> | 4212 | * Stray Mailbox Interrupt, mbxCommand <cmd> |
4189 | * mbxStatus <status> | 4213 | * mbxStatus <status> |
@@ -4199,10 +4223,10 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4199 | /* clear mailbox attention bit */ | 4223 | /* clear mailbox attention bit */ |
4200 | work_ha_copy &= ~HA_MBATT; | 4224 | work_ha_copy &= ~HA_MBATT; |
4201 | } else { | 4225 | } else { |
4226 | phba->sli.mbox_active = NULL; | ||
4227 | spin_unlock(&phba->hbalock); | ||
4202 | phba->last_completion_time = jiffies; | 4228 | phba->last_completion_time = jiffies; |
4203 | del_timer(&phba->sli.mbox_tmo); | 4229 | del_timer(&phba->sli.mbox_tmo); |
4204 | |||
4205 | phba->sli.mbox_active = NULL; | ||
4206 | if (pmb->mbox_cmpl) { | 4230 | if (pmb->mbox_cmpl) { |
4207 | lpfc_sli_pcimem_bcopy(mbox, pmbox, | 4231 | lpfc_sli_pcimem_bcopy(mbox, pmbox, |
4208 | MAILBOX_CMD_SIZE); | 4232 | MAILBOX_CMD_SIZE); |
@@ -4237,10 +4261,15 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4237 | pmb->context1 = mp; | 4261 | pmb->context1 = mp; |
4238 | pmb->context2 = ndlp; | 4262 | pmb->context2 = ndlp; |
4239 | pmb->vport = vport; | 4263 | pmb->vport = vport; |
4240 | spin_lock(&phba->hbalock); | 4264 | rc = lpfc_sli_issue_mbox(phba, |
4241 | phba->sli.sli_flag &= | 4265 | pmb, |
4242 | ~LPFC_SLI_MBOX_ACTIVE; | 4266 | MBX_NOWAIT); |
4243 | spin_unlock(&phba->hbalock); | 4267 | if (rc != MBX_BUSY) |
4268 | lpfc_printf_log(phba, | ||
4269 | KERN_ERR, | ||
4270 | LOG_MBOX | LOG_SLI, | ||
4271 | "0306 rc should have" | ||
4272 | "been MBX_BUSY"); | ||
4244 | goto send_current_mbox; | 4273 | goto send_current_mbox; |
4245 | } | 4274 | } |
4246 | } | 4275 | } |
@@ -4250,25 +4279,20 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4250 | spin_unlock(&phba->pport->work_port_lock); | 4279 | spin_unlock(&phba->pport->work_port_lock); |
4251 | lpfc_mbox_cmpl_put(phba, pmb); | 4280 | lpfc_mbox_cmpl_put(phba, pmb); |
4252 | } | 4281 | } |
4253 | } | 4282 | } else |
4283 | spin_unlock(&phba->hbalock); | ||
4254 | if ((work_ha_copy & HA_MBATT) && | 4284 | if ((work_ha_copy & HA_MBATT) && |
4255 | (phba->sli.mbox_active == NULL)) { | 4285 | (phba->sli.mbox_active == NULL)) { |
4256 | send_next_mbox: | ||
4257 | spin_lock(&phba->hbalock); | ||
4258 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
4259 | pmb = lpfc_mbox_get(phba); | ||
4260 | spin_unlock(&phba->hbalock); | ||
4261 | send_current_mbox: | 4286 | send_current_mbox: |
4262 | /* Process next mailbox command if there is one */ | 4287 | /* Process next mailbox command if there is one */ |
4263 | if (pmb != NULL) { | 4288 | do { |
4264 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 4289 | rc = lpfc_sli_issue_mbox(phba, NULL, |
4265 | if (rc == MBX_NOT_FINISHED) { | 4290 | MBX_NOWAIT); |
4266 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 4291 | } while (rc == MBX_NOT_FINISHED); |
4267 | lpfc_mbox_cmpl_put(phba, pmb); | 4292 | if (rc != MBX_SUCCESS) |
4268 | goto send_next_mbox; | 4293 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | |
4269 | } | 4294 | LOG_SLI, "0349 rc should be " |
4270 | } | 4295 | "MBX_SUCCESS"); |
4271 | |||
4272 | } | 4296 | } |
4273 | 4297 | ||
4274 | spin_lock(&phba->hbalock); | 4298 | spin_lock(&phba->hbalock); |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ca540d1d041e..b22b893019f4 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.2.5" | 21 | #define LPFC_DRIVER_VERSION "8.2.6" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 86d05beb00b8..6feaf59b0b1b 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -538,7 +538,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
538 | /* Otherwise, we will perform fabric logo as needed */ | 538 | /* Otherwise, we will perform fabric logo as needed */ |
539 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && | 539 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
540 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && | 540 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && |
541 | phba->link_state >= LPFC_LINK_UP) { | 541 | phba->link_state >= LPFC_LINK_UP && |
542 | phba->fc_topology != TOPOLOGY_LOOP) { | ||
542 | if (vport->cfg_enable_da_id) { | 543 | if (vport->cfg_enable_da_id) { |
543 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 544 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
544 | if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) | 545 | if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) |