]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/lpfc/lpfc_hbadisc.c
PCI: implement new suspend/resume callbacks
[linux-2.6-omap-h63xx.git] / drivers / scsi / lpfc / lpfc_hbadisc.c
index 1ee3e62c78a71fbcf302d8214296df0d7ecb7b89..7cb68feb04fd11eb18c9a3e0d487ffe5a3b270a6 100644 (file)
@@ -69,7 +69,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
        rdata = rport->dd_data;
        ndlp = rdata->pnode;
 
-       if (!ndlp) {
+       if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
                if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
                        printk(KERN_ERR "Cannot find remote node"
                        " to terminate I/O Data x%x\n",
@@ -114,7 +114,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 
        rdata = rport->dd_data;
        ndlp = rdata->pnode;
-       if (!ndlp)
+       if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
                return;
 
        vport = ndlp->vport;
@@ -243,8 +243,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
        if (warn_on) {
                lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
                                 "0203 Devloss timeout on "
-                                "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
-                                "NPort x%x Data: x%x x%x x%x\n",
+                                "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
+                                "NPort x%06x Data: x%x x%x x%x\n",
                                 *name, *(name+1), *(name+2), *(name+3),
                                 *(name+4), *(name+5), *(name+6), *(name+7),
                                 ndlp->nlp_DID, ndlp->nlp_flag,
@@ -252,8 +252,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
        } else {
                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
                                 "0204 Devloss timeout on "
-                                "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
-                                "NPort x%x Data: x%x x%x x%x\n",
+                                "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
+                                "NPort x%06x Data: x%x x%x x%x\n",
                                 *name, *(name+1), *(name+2), *(name+3),
                                 *(name+4), *(name+5), *(name+6), *(name+7),
                                 ndlp->nlp_DID, ndlp->nlp_flag,
@@ -399,7 +399,10 @@ lpfc_work_done(struct lpfc_hba *phba)
                                vport = vports[i];
                        if (vport == NULL)
                                break;
+                       spin_lock_irq(&vport->work_port_lock);
                        work_port_events = vport->work_port_events;
+                       vport->work_port_events &= ~work_port_events;
+                       spin_unlock_irq(&vport->work_port_lock);
                        if (work_port_events & WORKER_DISC_TMO)
                                lpfc_disc_timeout_handler(vport);
                        if (work_port_events & WORKER_ELS_TMO)
@@ -416,9 +419,6 @@ lpfc_work_done(struct lpfc_hba *phba)
                                lpfc_ramp_down_queue_handler(phba);
                        if (work_port_events & WORKER_RAMP_UP_QUEUE)
                                lpfc_ramp_up_queue_handler(phba);
-                       spin_lock_irq(&vport->work_port_lock);
-                       vport->work_port_events &= ~work_port_events;
-                       spin_unlock_irq(&vport->work_port_lock);
                }
        lpfc_destroy_vport_work_array(phba, vports);
 
@@ -430,10 +430,10 @@ lpfc_work_done(struct lpfc_hba *phba)
                if (pring->flag & LPFC_STOP_IOCB_EVENT) {
                        pring->flag |= LPFC_DEFERRED_RING_EVENT;
                } else {
+                       pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
                        lpfc_sli_handle_slow_ring_event(phba, pring,
                                                        (status &
                                                         HA_RXMASK));
-                       pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
                }
                /*
                 * Turn on Ring interrupts
@@ -519,7 +519,9 @@ lpfc_do_work(void *p)
                        schedule();
                }
        }
+       spin_lock_irq(&phba->hbalock);
        phba->work_wait = NULL;
+       spin_unlock_irq(&phba->hbalock);
        return 0;
 }
 
@@ -629,9 +631,8 @@ lpfc_linkdown(struct lpfc_hba *phba)
        LPFC_MBOXQ_t          *mb;
        int i;
 
-       if (phba->link_state == LPFC_LINK_DOWN) {
+       if (phba->link_state == LPFC_LINK_DOWN)
                return 0;
-       }
        spin_lock_irq(&phba->hbalock);
        if (phba->link_state > LPFC_LINK_DOWN) {
                phba->link_state = LPFC_LINK_DOWN;
@@ -800,21 +801,9 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        writel(control, phba->HCregaddr);
        readl(phba->HCregaddr); /* flush */
        spin_unlock_irq(&phba->hbalock);
+       mempool_free(pmb, phba->mbox_mem_pool);
        return;
 
-       vport->num_disc_nodes = 0;
-       /* go thru NPR nodes and issue ELS PLOGIs */
-       if (vport->fc_npr_cnt)
-               lpfc_els_disc_plogi(vport);
-
-       if (!vport->num_disc_nodes) {
-               spin_lock_irq(shost->host_lock);
-               vport->fc_flag &= ~FC_NDISC_ACTIVE;
-               spin_unlock_irq(shost->host_lock);
-       }
-
-       vport->port_state = LPFC_VPORT_READY;
-
 out:
        /* Device Discovery completes */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
@@ -822,11 +811,9 @@ out:
        mempool_free(pmb, phba->mbox_mem_pool);
 
        spin_lock_irq(shost->host_lock);
-       vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK);
+       vport->fc_flag &= ~FC_ABORT_DISCOVERY;
        spin_unlock_irq(shost->host_lock);
 
-       del_timer_sync(&phba->fc_estabtmo);
-
        lpfc_can_disctmo(vport);
 
        /* turn on Link Attention interrupts */
@@ -1134,7 +1121,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        if (la->attType == AT_LINK_UP) {
                phba->fc_stat.LinkUp++;
                if (phba->link_flag & LS_LOOPBACK_MODE) {
-                       lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
+                       lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
                                        "1306 Link Up Event in loop back mode "
                                        "x%x received Data: x%x x%x x%x x%x\n",
                                        la->eventTag, phba->fc_eventTag,
@@ -1151,11 +1138,21 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                lpfc_mbx_process_link_up(phba, la);
        } else {
                phba->fc_stat.LinkDown++;
-               lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
+               if (phba->link_flag & LS_LOOPBACK_MODE) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
+                               "1308 Link Down Event in loop back mode "
+                               "x%x received "
+                               "Data: x%x x%x x%x\n",
+                               la->eventTag, phba->fc_eventTag,
+                               phba->pport->port_state, vport->fc_flag);
+               }
+               else {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
                                "1305 Link Down Event x%x received "
                                "Data: x%x x%x x%x\n",
                                la->eventTag, phba->fc_eventTag,
                                phba->pport->port_state, vport->fc_flag);
+               }
                lpfc_mbx_issue_link_down(phba);
        }
 
@@ -1343,10 +1340,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                            i++) {
                                if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
                                        continue;
+                               if (phba->fc_topology == TOPOLOGY_LOOP) {
+                                       lpfc_vport_set_state(vports[i],
+                                                       FC_VPORT_LINKDOWN);
+                                       continue;
+                               }
                                if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
                                        lpfc_initial_fdisc(vports[i]);
-                               else if (phba->sli3_options &
-                                               LPFC_SLI3_NPIV_ENABLED) {
+                               else {
                                        lpfc_vport_set_state(vports[i],
                                                FC_VPORT_NO_FABRIC_SUPP);
                                        lpfc_printf_vlog(vport, KERN_ERR,
@@ -1697,7 +1698,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
                                NLP_STE_UNUSED_NODE);
 }
 
-void
+static void
 lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
        if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
@@ -2193,10 +2194,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        if (did == Bcast_DID)
                return 0;
 
-       if (ndlp->nlp_DID == 0) {
-               return 0;
-       }
-
        /* First check for Direct match */
        if (ndlp->nlp_DID == did)
                return 1;
@@ -2304,7 +2301,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
                return ndlp;
        }
 
-       if (vport->fc_flag & FC_RSCN_MODE) {
+       if ((vport->fc_flag & FC_RSCN_MODE) &&
+           !(vport->fc_flag & FC_NDISC_ACTIVE)) {
                if (lpfc_rscn_payload_check(vport, did)) {
                        /* If we've already recieved a PLOGI from this NPort
                         * we don't need to try to discover it again.
@@ -2484,6 +2482,7 @@ lpfc_disc_start(struct lpfc_vport *vport)
         * continue discovery.
         */
        if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
+           !(vport->fc_flag & FC_PT2PT) &&
            !(vport->fc_flag & FC_RSCN_MODE)) {
                lpfc_issue_reg_vpi(phba, vport);
                return;
@@ -2949,24 +2948,6 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
        return NULL;
 }
 
-#if 0
-/*
- * Search node lists for a remote port matching filter criteria
- * Caller needs to hold host_lock before calling this routine.
- */
-struct lpfc_nodelist *
-lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
-{
-       struct Scsi_Host     *shost = lpfc_shost_from_vport(vport);
-       struct lpfc_nodelist *ndlp;
-
-       spin_lock_irq(shost->host_lock);
-       ndlp = __lpfc_find_node(vport, filter, param);
-       spin_unlock_irq(shost->host_lock);
-       return ndlp;
-}
-#endif  /*  0  */
-
 /*
  * This routine looks up the ndlp lists for the given RPI. If rpi found it
  * returns the node list element pointer else return NULL.
@@ -2977,20 +2958,6 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
        return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi);
 }
 
-#if 0
-struct lpfc_nodelist *
-lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
-{
-       struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-       struct lpfc_nodelist *ndlp;
-
-       spin_lock_irq(shost->host_lock);
-       ndlp = __lpfc_findnode_rpi(vport, rpi);
-       spin_unlock_irq(shost->host_lock);
-       return ndlp;
-}
-#endif  /*  0  */
-
 /*
  * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
  * returns the node element list pointer else return NULL.