aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_init.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-10-02 15:16:45 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:40 -0500
commit6669f9bb902b8c3f5e33cb8c32c8c0eec6ed68ed (patch)
treee143e916abc71ff3c7edb7a5508d480391efc1ee /drivers/scsi/lpfc/lpfc_init.c
parent4d9ab994e214d35107017c342aca42477b137316 (diff)
[SCSI] lpfc 8.3.5: fix VPI registration, error clean up and add support for vlink events
This patch includes the following fixes and new features: - Fix mask size for CT field in WQE - Fix VPI base not used when unregistering VPI on port 1. - Fix UNREG_VPI mailbox command to unreg the correct VPI - Fixed Check for aborted els command - Fix error when trying to load driver with wrong firmware on FCoE HBA. - Fix bug with probe_one routines not putting the Scsi_Host back upon error - Add support for Clear Virtual Link Async Events - Add support for unsolicited CT exchange sequence abort - Add 0x0714 OCeXXXXX PCI ID Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c107
1 files changed, 103 insertions, 4 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index d654c0e3db4d..a7b5566ea0b5 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1669,6 +1669,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
1669 oneConnect = 1; 1669 oneConnect = 1;
1670 m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"}; 1670 m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"};
1671 break; 1671 break;
1672 case PCI_DEVICE_ID_TS_BE3:
1673 oneConnect = 1;
1674 m = (typeof(m)) {"OCeXXXXX-F", max_speed, "PCIe"};
1675 break;
1672 default: 1676 default:
1673 m = (typeof(m)){ NULL }; 1677 m = (typeof(m)){ NULL };
1674 break; 1678 break;
@@ -2699,6 +2703,63 @@ lpfc_sli_remove_dflt_fcf(struct lpfc_hba *phba)
2699} 2703}
2700 2704
2701/** 2705/**
2706 * lpfc_sli4_fw_cfg_check - Read the firmware config and verify FCoE support
2707 * @phba: pointer to lpfc hba data structure.
2708 *
2709 * This function uses the QUERY_FW_CFG mailbox command to determine if the
2710 * firmware loaded supports FCoE. A return of zero indicates that the mailbox
2711 * was successful and the firmware supports FCoE. Any other return indicates
2712 * a error. It is assumed that this function will be called before interrupts
2713 * are enabled.
2714 **/
2715static int
2716lpfc_sli4_fw_cfg_check(struct lpfc_hba *phba)
2717{
2718 int rc = 0;
2719 LPFC_MBOXQ_t *mboxq;
2720 struct lpfc_mbx_query_fw_cfg *query_fw_cfg;
2721 uint32_t length;
2722 uint32_t shdr_status, shdr_add_status;
2723
2724 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2725 if (!mboxq) {
2726 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2727 "2621 Failed to allocate mbox for "
2728 "query firmware config cmd\n");
2729 return -ENOMEM;
2730 }
2731 query_fw_cfg = &mboxq->u.mqe.un.query_fw_cfg;
2732 length = (sizeof(struct lpfc_mbx_query_fw_cfg) -
2733 sizeof(struct lpfc_sli4_cfg_mhdr));
2734 lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
2735 LPFC_MBOX_OPCODE_QUERY_FW_CFG,
2736 length, LPFC_SLI4_MBX_EMBED);
2737 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
2738 /* The IOCTL status is embedded in the mailbox subheader. */
2739 shdr_status = bf_get(lpfc_mbox_hdr_status,
2740 &query_fw_cfg->header.cfg_shdr.response);
2741 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
2742 &query_fw_cfg->header.cfg_shdr.response);
2743 if (shdr_status || shdr_add_status || rc != MBX_SUCCESS) {
2744 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2745 "2622 Query Firmware Config failed "
2746 "mbx status x%x, status x%x add_status x%x\n",
2747 rc, shdr_status, shdr_add_status);
2748 return -EINVAL;
2749 }
2750 if (!bf_get(lpfc_function_mode_fcoe_i, query_fw_cfg)) {
2751 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2752 "2623 FCoE Function not supported by firmware. "
2753 "Function mode = %08x\n",
2754 query_fw_cfg->function_mode);
2755 return -EINVAL;
2756 }
2757 if (rc != MBX_TIMEOUT)
2758 mempool_free(mboxq, phba->mbox_mem_pool);
2759 return 0;
2760}
2761
2762/**
2702 * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code 2763 * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code
2703 * @phba: pointer to lpfc hba data structure. 2764 * @phba: pointer to lpfc hba data structure.
2704 * @acqe_link: pointer to the async link completion queue entry. 2765 * @acqe_link: pointer to the async link completion queue entry.
@@ -2918,6 +2979,9 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
2918{ 2979{
2919 uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe); 2980 uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
2920 int rc; 2981 int rc;
2982 struct lpfc_vport *vport;
2983 struct lpfc_nodelist *ndlp;
2984 struct Scsi_Host *shost;
2921 2985
2922 phba->fc_eventTag = acqe_fcoe->event_tag; 2986 phba->fc_eventTag = acqe_fcoe->event_tag;
2923 phba->fcoe_eventtag = acqe_fcoe->event_tag; 2987 phba->fcoe_eventtag = acqe_fcoe->event_tag;
@@ -2925,7 +2989,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
2925 case LPFC_FCOE_EVENT_TYPE_NEW_FCF: 2989 case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
2926 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 2990 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
2927 "2546 New FCF found index 0x%x tag 0x%x\n", 2991 "2546 New FCF found index 0x%x tag 0x%x\n",
2928 acqe_fcoe->fcf_index, 2992 acqe_fcoe->index,
2929 acqe_fcoe->event_tag); 2993 acqe_fcoe->event_tag);
2930 /* 2994 /*
2931 * If the current FCF is in discovered state, or 2995 * If the current FCF is in discovered state, or
@@ -2958,10 +3022,10 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
2958 case LPFC_FCOE_EVENT_TYPE_FCF_DEAD: 3022 case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
2959 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 3023 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
2960 "2549 FCF disconnected fron network index 0x%x" 3024 "2549 FCF disconnected fron network index 0x%x"
2961 " tag 0x%x\n", acqe_fcoe->fcf_index, 3025 " tag 0x%x\n", acqe_fcoe->index,
2962 acqe_fcoe->event_tag); 3026 acqe_fcoe->event_tag);
2963 /* If the event is not for currently used fcf do nothing */ 3027 /* If the event is not for currently used fcf do nothing */
2964 if (phba->fcf.fcf_indx != acqe_fcoe->fcf_index) 3028 if (phba->fcf.fcf_indx != acqe_fcoe->index)
2965 break; 3029 break;
2966 /* 3030 /*
2967 * Currently, driver support only one FCF - so treat this as 3031 * Currently, driver support only one FCF - so treat this as
@@ -2971,7 +3035,28 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
2971 /* Unregister FCF if no devices connected to it */ 3035 /* Unregister FCF if no devices connected to it */
2972 lpfc_unregister_unused_fcf(phba); 3036 lpfc_unregister_unused_fcf(phba);
2973 break; 3037 break;
2974 3038 case LPFC_FCOE_EVENT_TYPE_CVL:
3039 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
3040 "2718 Clear Virtual Link Received for VPI 0x%x"
3041 " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
3042 vport = lpfc_find_vport_by_vpid(phba,
3043 acqe_fcoe->index /*- phba->vpi_base*/);
3044 if (!vport)
3045 break;
3046 ndlp = lpfc_findnode_did(vport, Fabric_DID);
3047 if (!ndlp)
3048 break;
3049 shost = lpfc_shost_from_vport(vport);
3050 lpfc_linkdown_port(vport);
3051 if (vport->port_type != LPFC_NPIV_PORT) {
3052 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
3053 spin_lock_irq(shost->host_lock);
3054 ndlp->nlp_flag |= NLP_DELAY_TMO;
3055 spin_unlock_irq(shost->host_lock);
3056 ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
3057 vport->port_state = LPFC_FLOGI;
3058 }
3059 break;
2975 default: 3060 default:
2976 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 3061 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
2977 "0288 Unknown FCoE event type 0x%x event tag " 3062 "0288 Unknown FCoE event type 0x%x event tag "
@@ -3463,6 +3548,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
3463 if (unlikely(rc)) 3548 if (unlikely(rc))
3464 goto out_free_bsmbx; 3549 goto out_free_bsmbx;
3465 3550
3551 rc = lpfc_sli4_fw_cfg_check(phba);
3552 if (unlikely(rc))
3553 goto out_free_bsmbx;
3554
3466 /* Set up the hba's configuration parameters. */ 3555 /* Set up the hba's configuration parameters. */
3467 rc = lpfc_sli4_read_config(phba); 3556 rc = lpfc_sli4_read_config(phba);
3468 if (unlikely(rc)) 3557 if (unlikely(rc))
@@ -6687,6 +6776,7 @@ lpfc_pci_probe_one_s3(struct pci_dev *pdev, const struct pci_device_id *pid)
6687{ 6776{
6688 struct lpfc_hba *phba; 6777 struct lpfc_hba *phba;
6689 struct lpfc_vport *vport = NULL; 6778 struct lpfc_vport *vport = NULL;
6779 struct Scsi_Host *shost = NULL;
6690 int error; 6780 int error;
6691 uint32_t cfg_mode, intr_mode; 6781 uint32_t cfg_mode, intr_mode;
6692 6782
@@ -6765,6 +6855,7 @@ lpfc_pci_probe_one_s3(struct pci_dev *pdev, const struct pci_device_id *pid)
6765 goto out_destroy_shost; 6855 goto out_destroy_shost;
6766 } 6856 }
6767 6857
6858 shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */
6768 /* Now, trying to enable interrupt and bring up the device */ 6859 /* Now, trying to enable interrupt and bring up the device */
6769 cfg_mode = phba->cfg_use_msi; 6860 cfg_mode = phba->cfg_use_msi;
6770 while (true) { 6861 while (true) {
@@ -6831,6 +6922,8 @@ out_unset_pci_mem_s3:
6831 lpfc_sli_pci_mem_unset(phba); 6922 lpfc_sli_pci_mem_unset(phba);
6832out_disable_pci_dev: 6923out_disable_pci_dev:
6833 lpfc_disable_pci_dev(phba); 6924 lpfc_disable_pci_dev(phba);
6925 if (shost)
6926 scsi_host_put(shost);
6834out_free_phba: 6927out_free_phba:
6835 lpfc_hba_free(phba); 6928 lpfc_hba_free(phba);
6836 return error; 6929 return error;
@@ -7214,6 +7307,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
7214{ 7307{
7215 struct lpfc_hba *phba; 7308 struct lpfc_hba *phba;
7216 struct lpfc_vport *vport = NULL; 7309 struct lpfc_vport *vport = NULL;
7310 struct Scsi_Host *shost = NULL;
7217 int error; 7311 int error;
7218 uint32_t cfg_mode, intr_mode; 7312 uint32_t cfg_mode, intr_mode;
7219 int mcnt; 7313 int mcnt;
@@ -7294,6 +7388,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
7294 goto out_destroy_shost; 7388 goto out_destroy_shost;
7295 } 7389 }
7296 7390
7391 shost = lpfc_shost_from_vport(vport); /* save shost for error cleanup */
7297 /* Now, trying to enable interrupt and bring up the device */ 7392 /* Now, trying to enable interrupt and bring up the device */
7298 cfg_mode = phba->cfg_use_msi; 7393 cfg_mode = phba->cfg_use_msi;
7299 while (true) { 7394 while (true) {
@@ -7362,6 +7457,8 @@ out_unset_pci_mem_s4:
7362 lpfc_sli4_pci_mem_unset(phba); 7457 lpfc_sli4_pci_mem_unset(phba);
7363out_disable_pci_dev: 7458out_disable_pci_dev:
7364 lpfc_disable_pci_dev(phba); 7459 lpfc_disable_pci_dev(phba);
7460 if (shost)
7461 scsi_host_put(shost);
7365out_free_phba: 7462out_free_phba:
7366 lpfc_hba_free(phba); 7463 lpfc_hba_free(phba);
7367 return error; 7464 return error;
@@ -7936,6 +8033,8 @@ static struct pci_device_id lpfc_id_table[] = {
7936 PCI_ANY_ID, PCI_ANY_ID, }, 8033 PCI_ANY_ID, PCI_ANY_ID, },
7937 {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK, 8034 {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK,
7938 PCI_ANY_ID, PCI_ANY_ID, }, 8035 PCI_ANY_ID, PCI_ANY_ID, },
8036 {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TS_BE3,
8037 PCI_ANY_ID, PCI_ANY_ID, },
7939 { 0 } 8038 { 0 }
7940}; 8039};
7941 8040