]> Pileus Git - ~andy/linux/blobdiff - drivers/scsi/lpfc/lpfc_init.c
[SCSI] lpfc 8.3.4: Fix a pair of FCoE issues
[~andy/linux] / drivers / scsi / lpfc / lpfc_init.c
index 2f5907f92eeaee7cac3079615ac035d67c27e1a5..a7f32ed256bdd36588e4d682b118cd07b332ffd5 100644 (file)
@@ -211,7 +211,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
                goto out_free_mbox;
 
        do {
-               lpfc_dump_mem(phba, pmb, offset);
+               lpfc_dump_mem(phba, pmb, offset, DMP_REGION_VPD);
                rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
 
                if (rc != MBX_SUCCESS) {
@@ -425,10 +425,14 @@ lpfc_config_port_post(struct lpfc_hba *phba)
                return -EIO;
        }
 
+       /* Check if the port is disabled */
+       lpfc_sli_read_link_ste(phba);
+
        /* Reset the DFT_HBA_Q_DEPTH to the max xri  */
        if (phba->cfg_hba_queue_depth > (mb->un.varRdConfig.max_xri+1))
                phba->cfg_hba_queue_depth =
-                       mb->un.varRdConfig.max_xri + 1;
+                       (mb->un.varRdConfig.max_xri + 1) -
+                                       lpfc_sli4_get_els_iocb_cnt(phba);
 
        phba->lmt = mb->un.varRdConfig.lmt;
 
@@ -523,27 +527,46 @@ lpfc_config_port_post(struct lpfc_hba *phba)
        /* Set up error attention (ERATT) polling timer */
        mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL);
 
-       lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
-       pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-       lpfc_set_loopback_flag(phba);
-       rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
-       if (rc != MBX_SUCCESS) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+       if (phba->hba_flag & LINK_DISABLED) {
+               lpfc_printf_log(phba,
+                       KERN_ERR, LOG_INIT,
+                       "2598 Adapter Link is disabled.\n");
+               lpfc_down_link(phba, pmb);
+               pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+               rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+               if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) {
+                       lpfc_printf_log(phba,
+                       KERN_ERR, LOG_INIT,
+                       "2599 Adapter failed to issue DOWN_LINK"
+                       " mbox command rc 0x%x\n", rc);
+
+                       mempool_free(pmb, phba->mbox_mem_pool);
+                       return -EIO;
+               }
+       } else {
+               lpfc_init_link(phba, pmb, phba->cfg_topology,
+                       phba->cfg_link_speed);
+               pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+               lpfc_set_loopback_flag(phba);
+               rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+               if (rc != MBX_SUCCESS) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                "0454 Adapter failed to init, mbxCmd x%x "
                                "INIT_LINK, mbxStatus x%x\n",
                                mb->mbxCommand, mb->mbxStatus);
 
-               /* Clear all interrupt enable conditions */
-               writel(0, phba->HCregaddr);
-               readl(phba->HCregaddr); /* flush */
-               /* Clear all pending interrupts */
-               writel(0xffffffff, phba->HAregaddr);
-               readl(phba->HAregaddr); /* flush */
+                       /* Clear all interrupt enable conditions */
+                       writel(0, phba->HCregaddr);
+                       readl(phba->HCregaddr); /* flush */
+                       /* Clear all pending interrupts */
+                       writel(0xffffffff, phba->HAregaddr);
+                       readl(phba->HAregaddr); /* flush */
 
-               phba->link_state = LPFC_HBA_ERROR;
-               if (rc != MBX_BUSY)
-                       mempool_free(pmb, phba->mbox_mem_pool);
-               return -EIO;
+                       phba->link_state = LPFC_HBA_ERROR;
+                       if (rc != MBX_BUSY)
+                               mempool_free(pmb, phba->mbox_mem_pool);
+                       return -EIO;
+               }
        }
        /* MBOX buffer will be freed in mbox compl */
        pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -1646,10 +1669,6 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
                oneConnect = 1;
                m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"};
                break;
-       case PCI_DEVICE_ID_TIGERSHARK_S:
-               oneConnect = 1;
-               m = (typeof(m)) {"OCe10100-F-S", max_speed, "PCIe"};
-               break;
        default:
                m = (typeof(m)){ NULL };
                break;
@@ -2810,6 +2829,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
        att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
        if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP)
                return;
+       phba->fcoe_eventtag = acqe_link->event_tag;
        pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!pmb) {
                lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -2897,6 +2917,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
        uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
        int rc;
 
+       phba->fcoe_eventtag = acqe_fcoe->event_tag;
        switch (event_type) {
        case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
                lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
@@ -2904,11 +2925,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                        acqe_fcoe->fcf_index,
                        acqe_fcoe->event_tag);
                /*
-                * If the current FCF is in discovered state,
-                * do nothing.
+                * If the current FCF is in discovered state, or
+                * FCF discovery is in progress do nothing.
                 */
                spin_lock_irq(&phba->hbalock);
-               if (phba->fcf.fcf_flag & FCF_DISCOVERED) {
+               if ((phba->fcf.fcf_flag & FCF_DISCOVERED) ||
+                  (phba->hba_flag & FCF_DISC_INPROGRESS)) {
                        spin_unlock_irq(&phba->hbalock);
                        break;
                }
@@ -3543,6 +3565,7 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba)
 
        /* Free the allocated rpi headers. */
        lpfc_sli4_remove_rpi_hdrs(phba);
+       lpfc_sli4_remove_rpis(phba);
 
        /* Free the ELS sgl list */
        lpfc_free_active_sgl(phba);
@@ -4132,8 +4155,7 @@ lpfc_hba_alloc(struct pci_dev *pdev)
        /* Allocate memory for HBA structure */
        phba = kzalloc(sizeof(struct lpfc_hba), GFP_KERNEL);
        if (!phba) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "1417 Failed to allocate hba struct.\n");
+               dev_err(&pdev->dev, "failed to allocate hba struct\n");
                return NULL;
        }
 
@@ -4491,23 +4513,6 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
        if (!phba->sli4_hba.STAregaddr)
                return -ENODEV;
 
-       /* With uncoverable error, log the error message and return error */
-       onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
-       onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
-       if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
-               uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
-               uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
-               if (uerrlo_reg.word0 || uerrhi_reg.word0) {
-                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                                       "1422 HBA Unrecoverable error: "
-                                       "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-                                       "online0_reg=0x%x, online1_reg=0x%x\n",
-                                       uerrlo_reg.word0, uerrhi_reg.word0,
-                                       onlnreg0, onlnreg1);
-               }
-               return -ENODEV;
-       }
-
        /* Wait up to 30 seconds for the SLI Port POST done and ready */
        for (i = 0; i < 3000; i++) {
                sta_reg.word0 = readl(phba->sli4_hba.STAregaddr);
@@ -4547,6 +4552,23 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
                        bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
                        bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));
 
+       /* With uncoverable error, log the error message and return error */
+       onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
+       onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
+       if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
+               uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
+               uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
+               if (uerrlo_reg.word0 || uerrhi_reg.word0) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                       "1422 HBA Unrecoverable error: "
+                                       "uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+                                       "online0_reg=0x%x, online1_reg=0x%x\n",
+                                       uerrlo_reg.word0, uerrhi_reg.word0,
+                                       onlnreg0, onlnreg1);
+               }
+               return -ENODEV;
+       }
+
        return port_error;
 }
 
@@ -7184,16 +7206,19 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba)
 {
        int max_xri = phba->sli4_hba.max_cfg_param.max_xri;
 
-       if (max_xri <= 100)
-               return 4;
-       else if (max_xri <= 256)
-               return 8;
-       else if (max_xri <= 512)
-               return 16;
-       else if (max_xri <= 1024)
-               return 32;
-       else
-               return 48;
+       if (phba->sli_rev == LPFC_SLI_REV4) {
+               if (max_xri <= 100)
+                       return 4;
+               else if (max_xri <= 256)
+                       return 8;
+               else if (max_xri <= 512)
+                       return 16;
+               else if (max_xri <= 1024)
+                       return 32;
+               else
+                       return 48;
+       } else
+               return 0;
 }
 
 /**
@@ -7635,20 +7660,17 @@ static int __devinit
 lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 {
        int rc;
-       uint16_t dev_id;
+       struct lpfc_sli_intf intf;
 
-       if (pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id))
+       if (pci_read_config_dword(pdev, LPFC_SLIREV_CONF_WORD, &intf.word0))
                return -ENODEV;
 
-       switch (dev_id) {
-       case PCI_DEVICE_ID_TIGERSHARK:
-       case PCI_DEVICE_ID_TIGERSHARK_S:
+       if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) &&
+               (bf_get(lpfc_sli_intf_rev, &intf) == LPFC_SLIREV_CONF_SLI4))
                rc = lpfc_pci_probe_one_s4(pdev, pid);
-               break;
-       default:
+       else
                rc = lpfc_pci_probe_one_s3(pdev, pid);
-               break;
-       }
+
        return rc;
 }
 
@@ -7941,8 +7963,6 @@ static struct pci_device_id lpfc_id_table[] = {
                PCI_ANY_ID, PCI_ANY_ID, },
        {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK,
                PCI_ANY_ID, PCI_ANY_ID, },
-       {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK_S,
-               PCI_ANY_ID, PCI_ANY_ID, },
        { 0 }
 };