]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/lpfc/lpfc_ct.c
[SCSI] lpfc 8.1.7 : Short bug fixes
[linux-2.6-omap-h63xx.git] / drivers / scsi / lpfc / lpfc_ct.c
index 98b94c0eb59728d95bd49fddf94db07f332e9d49..cab2d9dec0885a5e404ae53b25886f213cd3a9ef 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2006 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -131,6 +131,7 @@ lpfc_ct_unsol_event(struct lpfc_hba * phba,
        }
 
 ct_unsol_event_exit_piocbq:
+       list_del(&head);
        if (pmbuf) {
                list_for_each_entry_safe(matp, next_matp, &pmbuf->list, list) {
                        lpfc_mbuf_free(phba, matp->virt, matp->phys);
@@ -323,6 +324,7 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
        struct lpfc_sli_ct_request *Response =
                (struct lpfc_sli_ct_request *) mp->virt;
        struct lpfc_nodelist *ndlp = NULL;
+       struct lpfc_nodelist *next_ndlp;
        struct lpfc_dmabuf *mlast, *next_mp;
        uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
        uint32_t Did;
@@ -391,8 +393,36 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
 nsout1:
        list_del(&head);
 
-       /* Here we are finished in the case RSCN */
+       /*
+        * The driver has cycled through all Nports in the RSCN payload.
+        * Complete the handling by cleaning up and marking the
+        * current driver state.
+        */
        if (phba->hba_state == LPFC_HBA_READY) {
+
+               /*
+                * Switch ports that connect a loop of multiple targets need
+                * special consideration.  The driver wants to unregister the
+                * rpi only on the target that was pulled from the loop.  On
+                * RSCN, the driver wants to rediscover an NPort only if the
+                * driver flagged it as NLP_NPR_2B_DISC.  Provided adisc is
+                * not enabled and the NPort is not capable of retransmissions
+                * (FC Tape) prevent timing races with the scsi error handler by
+                * unregistering the Nport's RPI.  This action causes all
+                * outstanding IO to flush back to the midlayer.
+                */
+               list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
+                                        nlp_listp) {
+                       if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
+                           (lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) {
+                               if ((phba->cfg_use_adisc == 0) &&
+                                   !(ndlp->nlp_fcp_info &
+                                     NLP_FCP_2_DEVICE)) {
+                                       lpfc_unreg_rpi(phba, ndlp);
+                                       ndlp->nlp_flag &= ~NLP_NPR_ADISC;
+                               }
+                       }
+               }
                lpfc_els_flush_rscn(phba);
                spin_lock_irq(phba->host->host_lock);
                phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */
@@ -985,19 +1015,19 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
                        ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
                        ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED);
                        ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
-                       if (FC_JEDEC_ID(vp->rev.biuRev) == VIPER_JEDEC_ID)
+
+                       ae->un.SupportSpeed = 0;
+                       if (phba->lmt & LMT_10Gb)
                                ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
-                       else if (FC_JEDEC_ID(vp->rev.biuRev) == HELIOS_JEDEC_ID)
-                               ae->un.SupportSpeed = HBA_PORTSPEED_4GBIT;
-                       else if ((FC_JEDEC_ID(vp->rev.biuRev) ==
-                                 CENTAUR_2G_JEDEC_ID)
-                                || (FC_JEDEC_ID(vp->rev.biuRev) ==
-                                    PEGASUS_JEDEC_ID)
-                                || (FC_JEDEC_ID(vp->rev.biuRev) ==
-                                    THOR_JEDEC_ID))
-                               ae->un.SupportSpeed = HBA_PORTSPEED_2GBIT;
-                       else
-                               ae->un.SupportSpeed = HBA_PORTSPEED_1GBIT;
+                       if (phba->lmt & LMT_8Gb)
+                               ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
+                       if (phba->lmt & LMT_4Gb)
+                               ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT;
+                       if (phba->lmt & LMT_2Gb)
+                               ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT;
+                       if (phba->lmt & LMT_1Gb)
+                               ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT;
+
                        pab->ab.EntryCnt++;
                        size += FOURBYTES + 4;
 
@@ -1137,11 +1167,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
 {
        struct lpfc_nodelist *ndlp;
 
-       spin_lock_irq(phba->host->host_lock);
-       if (!(phba->work_hba_events & WORKER_FDMI_TMO)) {
-               spin_unlock_irq(phba->host->host_lock);
-               return;
-       }
        ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
        if (ndlp) {
                if (system_utsname.nodename[0] != '\0') {
@@ -1150,7 +1175,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
                        mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
                }
        }
-       spin_unlock_irq(phba->host->host_lock);
        return;
 }