]> Pileus Git - ~andy/linux/blobdiff - drivers/scsi/lpfc/lpfc_hbadisc.c
Merge branch 'linux-next' of git://git.open-osd.org/linux-open-osd
[~andy/linux] / drivers / scsi / lpfc / lpfc_hbadisc.c
index 9b4f92941dce585aaddbfaa401d9e3ae5d7f7312..e9845d2ecf10db6f6fd9eca8681aba1febee305a 100644 (file)
@@ -123,6 +123,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
                "rport devlosscb: sid:x%x did:x%x flg:x%x",
                ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3181 dev_loss_callbk x%06x, rport %p flg x%x\n",
+                        ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag);
+
        /* Don't defer this if we are in the process of deleting the vport
         * or unloading the driver. The unload will cleanup the node
         * appropriately we just need to cleanup the ndlp rport info here.
@@ -142,6 +146,15 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
        if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
                return;
 
+       if (ndlp->nlp_type & NLP_FABRIC) {
+
+               /* If the WWPN of the rport and ndlp don't match, ignore it */
+               if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn)) {
+                       put_device(&rport->dev);
+                       return;
+               }
+       }
+
        evtp = &ndlp->dev_loss_evt;
 
        if (!list_empty(&evtp->evt_listp))
@@ -202,6 +215,10 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
                "rport devlosstmo:did:x%x type:x%x id:x%x",
                ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3182 dev_loss_tmo_handler x%06x, rport %p flg x%x\n",
+                        ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag);
+
        /* Don't defer this if we are in the process of deleting the vport
         * or unloading the driver. The unload will cleanup the node
         * appropriately we just need to cleanup the ndlp rport info here.
@@ -3492,7 +3509,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
        LPFC_MBOXQ_t *pmb = NULL;
        MAILBOX_t *mb;
        struct static_vport_info *vport_info;
-       int rc = 0, i;
+       int mbx_wait_rc = 0, i;
        struct fc_vport_identifiers vport_id;
        struct fc_vport *new_fc_vport;
        struct Scsi_Host *shost;
@@ -3509,7 +3526,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
                                " allocate mailbox memory\n");
                return;
        }
-
+       memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
        mb = &pmb->u.mb;
 
        vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL);
@@ -3523,24 +3540,31 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
 
        vport_buff = (uint8_t *) vport_info;
        do {
+               /* free dma buffer from previous round */
+               if (pmb->context1) {
+                       mp = (struct lpfc_dmabuf *)pmb->context1;
+                       lpfc_mbuf_free(phba, mp->virt, mp->phys);
+                       kfree(mp);
+               }
                if (lpfc_dump_static_vport(phba, pmb, offset))
                        goto out;
 
                pmb->vport = phba->pport;
-               rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO);
+               mbx_wait_rc = lpfc_sli_issue_mbox_wait(phba, pmb,
+                                                       LPFC_MBOX_TMO);
 
-               if ((rc != MBX_SUCCESS) || mb->mbxStatus) {
+               if ((mbx_wait_rc != MBX_SUCCESS) || mb->mbxStatus) {
                        lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
                                "0544 lpfc_create_static_vport failed to"
                                " issue dump mailbox command ret 0x%x "
                                "status 0x%x\n",
-                               rc, mb->mbxStatus);
+                               mbx_wait_rc, mb->mbxStatus);
                        goto out;
                }
 
                if (phba->sli_rev == LPFC_SLI_REV4) {
                        byte_count = pmb->u.mqe.un.mb_words[5];
-                       mp = (struct lpfc_dmabuf *) pmb->context2;
+                       mp = (struct lpfc_dmabuf *)pmb->context1;
                        if (byte_count > sizeof(struct static_vport_info) -
                                        offset)
                                byte_count = sizeof(struct static_vport_info)
@@ -3604,9 +3628,9 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
 
 out:
        kfree(vport_info);
-       if (rc != MBX_TIMEOUT) {
-               if (pmb->context2) {
-                       mp = (struct lpfc_dmabuf *) pmb->context2;
+       if (mbx_wait_rc != MBX_TIMEOUT) {
+               if (pmb->context1) {
+                       mp = (struct lpfc_dmabuf *)pmb->context1;
                        lpfc_mbuf_free(phba, mp->virt, mp->phys);
                        kfree(mp);
                }
@@ -3834,6 +3858,10 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
                fc_remote_port_rolechg(rport, rport_ids.roles);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3183 rport register x%06x, rport %p role x%x\n",
+                        ndlp->nlp_DID, rport, rport_ids.roles);
+
        if ((rport->scsi_target_id != -1) &&
            (rport->scsi_target_id < LPFC_MAX_TARGET)) {
                ndlp->nlp_sid = rport->scsi_target_id;
@@ -3850,6 +3878,10 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
                "rport delete:    did:x%x flg:x%x type x%x",
                ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
 
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+                        "3184 rport unregister x%06x, rport %p\n",
+                        ndlp->nlp_DID, rport);
+
        fc_remote_port_delete(rport);
 
        return;
@@ -3964,6 +3996,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state)
                [NLP_STE_ADISC_ISSUE] = "ADISC",
                [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
                [NLP_STE_PRLI_ISSUE] = "PRLI",
+               [NLP_STE_LOGO_ISSUE] = "LOGO",
                [NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
                [NLP_STE_MAPPED_NODE] = "MAPPED",
                [NLP_STE_NPR_NODE] = "NPR",
@@ -4330,6 +4363,26 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
        return 0;
 }
 
+/**
+ * lpfc_nlp_logo_unreg - Unreg mailbox completion handler before LOGO
+ * @phba: Pointer to HBA context object.
+ * @pmb: Pointer to mailbox object.
+ *
+ * This function will issue an ELS LOGO command after completing
+ * the UNREG_RPI.
+ **/
+void
+lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+{
+       struct lpfc_vport  *vport = pmb->vport;
+       struct lpfc_nodelist *ndlp;
+
+       ndlp = (struct lpfc_nodelist *)(pmb->context1);
+       if (!ndlp)
+               return;
+       lpfc_issue_els_logo(vport, ndlp, 0);
+}
+
 /*
  * Free rpi associated with LPFC_NODELIST entry.
  * This routine is called from lpfc_freenode(), when we are removing
@@ -4354,9 +4407,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
                        rpi = ndlp->nlp_rpi;
                        if (phba->sli_rev == LPFC_SLI_REV4)
                                rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+
                        lpfc_unreg_login(phba, vport->vpi, rpi, mbox);
                        mbox->vport = vport;
-                       mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+                       if (ndlp->nlp_flag & NLP_ISSUE_LOGO) {
+                               mbox->context1 = ndlp;
+                               mbox->mbox_cmpl = lpfc_nlp_logo_unreg;
+                       } else {
+                               mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+                       }
+
                        rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
                        if (rc == MBX_NOT_FINISHED)
                                mempool_free(mbox, phba->mbox_mem_pool);
@@ -4499,9 +4559,13 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
                lpfc_disable_node(vport, ndlp);
        }
 
+
+       /* Don't need to clean up REG_LOGIN64 cmds for Default RPI cleanup */
+
        /* cleanup any ndlp on mbox q waiting for reglogin cmpl */
        if ((mb = phba->sli.mbox_active)) {
                if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
+                  !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
                   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
                        mb->context2 = NULL;
                        mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -4512,6 +4576,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        /* Cleanup REG_LOGIN completions which are not yet processed */
        list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
                if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) ||
+                       (mb->mbox_flag & LPFC_MBX_IMED_UNREG) ||
                        (ndlp != (struct lpfc_nodelist *) mb->context2))
                        continue;
 
@@ -4521,6 +4586,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 
        list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
                if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
+                  !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
                    (ndlp == (struct lpfc_nodelist *) mb->context2)) {
                        mp = (struct lpfc_dmabuf *) (mb->context1);
                        if (mp) {
@@ -4585,7 +4651,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
                                mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
                                mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
                                mbox->vport = vport;
-                               mbox->context2 = NULL;
+                               mbox->context2 = ndlp;
                                rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
                                if (rc == MBX_NOT_FINISHED) {
                                        mempool_free(mbox, phba->mbox_mem_pool);
@@ -5365,9 +5431,17 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
        struct lpfc_nodelist *ndlp;
 
        list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
-               if (filter(ndlp, param))
+               if (filter(ndlp, param)) {
+                       lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+                                        "3185 FIND node filter %p DID "
+                                        "Data: x%p x%x x%x\n",
+                                        filter, ndlp, ndlp->nlp_DID,
+                                        ndlp->nlp_flag);
                        return ndlp;
+               }
        }
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+                        "3186 FIND node filter %p NOT FOUND.\n", filter);
        return NULL;
 }