diff options
author | James Smart <james.smart@emulex.com> | 2010-02-12 14:42:03 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-17 18:40:48 -0500 |
commit | 28baac7492fa084dbff6a1b9c4b42ed0d014b558 (patch) | |
tree | dcf6dc190d0b85153eb8606b64f83089fae8084f /drivers/scsi/lpfc/lpfc_init.c | |
parent | ecfd03c6a99ad98fea5cb75ec83cd9945adff8d9 (diff) |
[SCSI] lpfc 8.3.9: SLI enhancments to support new hardware.
- Add support for the INTF (Interface) PCI register.
- Add support for greater than 2 page SGLs.
- Add support for up to 32 bit BDE lengths.
- Implement the Port Capabilities Mailbox command.
- Stop checking the Minor Code in the EQE structure.
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.c | 187 |
1 files changed, 148 insertions, 39 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 6e04679167e3..b0b7bb39f054 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -2443,7 +2443,8 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) | |||
2443 | shost->this_id = -1; | 2443 | shost->this_id = -1; |
2444 | shost->max_cmd_len = 16; | 2444 | shost->max_cmd_len = 16; |
2445 | if (phba->sli_rev == LPFC_SLI_REV4) { | 2445 | if (phba->sli_rev == LPFC_SLI_REV4) { |
2446 | shost->dma_boundary = LPFC_SLI4_MAX_SEGMENT_SIZE; | 2446 | shost->dma_boundary = |
2447 | phba->sli4_hba.pc_sli4_params.sge_supp_len; | ||
2447 | shost->sg_tablesize = phba->cfg_sg_seg_cnt; | 2448 | shost->sg_tablesize = phba->cfg_sg_seg_cnt; |
2448 | } | 2449 | } |
2449 | 2450 | ||
@@ -3621,8 +3622,10 @@ static int | |||
3621 | lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | 3622 | lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) |
3622 | { | 3623 | { |
3623 | struct lpfc_sli *psli; | 3624 | struct lpfc_sli *psli; |
3624 | int rc; | 3625 | LPFC_MBOXQ_t *mboxq; |
3625 | int i, hbq_count; | 3626 | int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size; |
3627 | uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; | ||
3628 | struct lpfc_mqe *mqe; | ||
3626 | 3629 | ||
3627 | /* Before proceed, wait for POST done and device ready */ | 3630 | /* Before proceed, wait for POST done and device ready */ |
3628 | rc = lpfc_sli4_post_status_check(phba); | 3631 | rc = lpfc_sli4_post_status_check(phba); |
@@ -3680,31 +3683,26 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
3680 | * used to create the sg_dma_buf_pool must be dynamically calculated. | 3683 | * used to create the sg_dma_buf_pool must be dynamically calculated. |
3681 | * 2 segments are added since the IOCB needs a command and response bde. | 3684 | * 2 segments are added since the IOCB needs a command and response bde. |
3682 | * To insure that the scsi sgl does not cross a 4k page boundary only | 3685 | * To insure that the scsi sgl does not cross a 4k page boundary only |
3683 | * sgl sizes of 1k, 2k, 4k, and 8k are supported. | 3686 | * sgl sizes of must be a power of 2. |
3684 | * Table of sgl sizes and seg_cnt: | ||
3685 | * sgl size, sg_seg_cnt total seg | ||
3686 | * 1k 50 52 | ||
3687 | * 2k 114 116 | ||
3688 | * 4k 242 244 | ||
3689 | * 8k 498 500 | ||
3690 | * cmd(32) + rsp(160) + (52 * sizeof(sli4_sge)) = 1024 | ||
3691 | * cmd(32) + rsp(160) + (116 * sizeof(sli4_sge)) = 2048 | ||
3692 | * cmd(32) + rsp(160) + (244 * sizeof(sli4_sge)) = 4096 | ||
3693 | * cmd(32) + rsp(160) + (500 * sizeof(sli4_sge)) = 8192 | ||
3694 | */ | 3687 | */ |
3695 | if (phba->cfg_sg_seg_cnt <= LPFC_DEFAULT_SG_SEG_CNT) | 3688 | buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) + |
3696 | phba->cfg_sg_seg_cnt = 50; | 3689 | ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge))); |
3697 | else if (phba->cfg_sg_seg_cnt <= 114) | 3690 | /* Feature Level 1 hardware is limited to 2 pages */ |
3698 | phba->cfg_sg_seg_cnt = 114; | 3691 | if ((bf_get(lpfc_sli_intf_featurelevel1, &phba->sli4_hba.sli_intf) == |
3699 | else if (phba->cfg_sg_seg_cnt <= 242) | 3692 | LPFC_SLI_INTF_FEATURELEVEL1_1)) |
3700 | phba->cfg_sg_seg_cnt = 242; | 3693 | max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE; |
3701 | else | 3694 | else |
3702 | phba->cfg_sg_seg_cnt = 498; | 3695 | max_buf_size = LPFC_SLI4_MAX_BUF_SIZE; |
3703 | 3696 | for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE; | |
3704 | phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) | 3697 | dma_buf_size < max_buf_size && buf_size > dma_buf_size; |
3705 | + sizeof(struct fcp_rsp); | 3698 | dma_buf_size = dma_buf_size << 1) |
3706 | phba->cfg_sg_dma_buf_size += | 3699 | ; |
3707 | ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge)); | 3700 | if (dma_buf_size == max_buf_size) |
3701 | phba->cfg_sg_seg_cnt = (dma_buf_size - | ||
3702 | sizeof(struct fcp_cmnd) - sizeof(struct fcp_rsp) - | ||
3703 | (2 * sizeof(struct sli4_sge))) / | ||
3704 | sizeof(struct sli4_sge); | ||
3705 | phba->cfg_sg_dma_buf_size = dma_buf_size; | ||
3708 | 3706 | ||
3709 | /* Initialize buffer queue management fields */ | 3707 | /* Initialize buffer queue management fields */ |
3710 | hbq_count = lpfc_sli_hbq_count(); | 3708 | hbq_count = lpfc_sli_hbq_count(); |
@@ -3822,6 +3820,43 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
3822 | goto out_free_fcp_eq_hdl; | 3820 | goto out_free_fcp_eq_hdl; |
3823 | } | 3821 | } |
3824 | 3822 | ||
3823 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | ||
3824 | GFP_KERNEL); | ||
3825 | if (!mboxq) { | ||
3826 | rc = -ENOMEM; | ||
3827 | goto out_free_fcp_eq_hdl; | ||
3828 | } | ||
3829 | |||
3830 | /* Get the Supported Pages. It is always available. */ | ||
3831 | lpfc_supported_pages(mboxq); | ||
3832 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
3833 | if (unlikely(rc)) { | ||
3834 | rc = -EIO; | ||
3835 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
3836 | goto out_free_fcp_eq_hdl; | ||
3837 | } | ||
3838 | |||
3839 | mqe = &mboxq->u.mqe; | ||
3840 | memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3), | ||
3841 | LPFC_MAX_SUPPORTED_PAGES); | ||
3842 | for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) { | ||
3843 | switch (pn_page[i]) { | ||
3844 | case LPFC_SLI4_PARAMETERS: | ||
3845 | phba->sli4_hba.pc_sli4_params.supported = 1; | ||
3846 | break; | ||
3847 | default: | ||
3848 | break; | ||
3849 | } | ||
3850 | } | ||
3851 | |||
3852 | /* Read the port's SLI4 Parameters capabilities if supported. */ | ||
3853 | if (phba->sli4_hba.pc_sli4_params.supported) | ||
3854 | rc = lpfc_pc_sli4_params_get(phba, mboxq); | ||
3855 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
3856 | if (rc) { | ||
3857 | rc = -EIO; | ||
3858 | goto out_free_fcp_eq_hdl; | ||
3859 | } | ||
3825 | return rc; | 3860 | return rc; |
3826 | 3861 | ||
3827 | out_free_fcp_eq_hdl: | 3862 | out_free_fcp_eq_hdl: |
@@ -4825,7 +4860,7 @@ lpfc_sli_pci_mem_unset(struct lpfc_hba *phba) | |||
4825 | int | 4860 | int |
4826 | lpfc_sli4_post_status_check(struct lpfc_hba *phba) | 4861 | lpfc_sli4_post_status_check(struct lpfc_hba *phba) |
4827 | { | 4862 | { |
4828 | struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg, scratchpad; | 4863 | struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg; |
4829 | int i, port_error = -ENODEV; | 4864 | int i, port_error = -ENODEV; |
4830 | 4865 | ||
4831 | if (!phba->sli4_hba.STAregaddr) | 4866 | if (!phba->sli4_hba.STAregaddr) |
@@ -4861,14 +4896,21 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba) | |||
4861 | bf_get(lpfc_hst_state_port_status, &sta_reg)); | 4896 | bf_get(lpfc_hst_state_port_status, &sta_reg)); |
4862 | 4897 | ||
4863 | /* Log device information */ | 4898 | /* Log device information */ |
4864 | scratchpad.word0 = readl(phba->sli4_hba.SCRATCHPADregaddr); | 4899 | phba->sli4_hba.sli_intf.word0 = readl(phba->sli4_hba.SLIINTFregaddr); |
4865 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 4900 | if (bf_get(lpfc_sli_intf_valid, |
4866 | "2534 Device Info: ChipType=0x%x, SliRev=0x%x, " | 4901 | &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_VALID) { |
4867 | "FeatureL1=0x%x, FeatureL2=0x%x\n", | 4902 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
4868 | bf_get(lpfc_scratchpad_chiptype, &scratchpad), | 4903 | "2534 Device Info: ChipType=0x%x, SliRev=0x%x, " |
4869 | bf_get(lpfc_scratchpad_slirev, &scratchpad), | 4904 | "FeatureL1=0x%x, FeatureL2=0x%x\n", |
4870 | bf_get(lpfc_scratchpad_featurelevel1, &scratchpad), | 4905 | bf_get(lpfc_sli_intf_sli_family, |
4871 | bf_get(lpfc_scratchpad_featurelevel2, &scratchpad)); | 4906 | &phba->sli4_hba.sli_intf), |
4907 | bf_get(lpfc_sli_intf_slirev, | ||
4908 | &phba->sli4_hba.sli_intf), | ||
4909 | bf_get(lpfc_sli_intf_featurelevel1, | ||
4910 | &phba->sli4_hba.sli_intf), | ||
4911 | bf_get(lpfc_sli_intf_featurelevel2, | ||
4912 | &phba->sli4_hba.sli_intf)); | ||
4913 | } | ||
4872 | phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr); | 4914 | phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr); |
4873 | phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr); | 4915 | phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr); |
4874 | /* With uncoverable error, log the error message and return error */ | 4916 | /* With uncoverable error, log the error message and return error */ |
@@ -4907,8 +4949,8 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba) | |||
4907 | LPFC_UE_MASK_LO; | 4949 | LPFC_UE_MASK_LO; |
4908 | phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p + | 4950 | phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p + |
4909 | LPFC_UE_MASK_HI; | 4951 | LPFC_UE_MASK_HI; |
4910 | phba->sli4_hba.SCRATCHPADregaddr = phba->sli4_hba.conf_regs_memmap_p + | 4952 | phba->sli4_hba.SLIINTFregaddr = phba->sli4_hba.conf_regs_memmap_p + |
4911 | LPFC_SCRATCHPAD; | 4953 | LPFC_SLI_INTF; |
4912 | } | 4954 | } |
4913 | 4955 | ||
4914 | /** | 4956 | /** |
@@ -6981,6 +7023,73 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) | |||
6981 | phba->pport->work_port_events = 0; | 7023 | phba->pport->work_port_events = 0; |
6982 | } | 7024 | } |
6983 | 7025 | ||
7026 | /** | ||
7027 | * lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities. | ||
7028 | * @phba: Pointer to HBA context object. | ||
7029 | * @mboxq: Pointer to the mailboxq memory for the mailbox command response. | ||
7030 | * | ||
7031 | * This function is called in the SLI4 code path to read the port's | ||
7032 | * sli4 capabilities. | ||
7033 | * | ||
7034 | * This function may be be called from any context that can block-wait | ||
7035 | * for the completion. The expectation is that this routine is called | ||
7036 | * typically from probe_one or from the online routine. | ||
7037 | **/ | ||
7038 | int | ||
7039 | lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
7040 | { | ||
7041 | int rc; | ||
7042 | struct lpfc_mqe *mqe; | ||
7043 | struct lpfc_pc_sli4_params *sli4_params; | ||
7044 | uint32_t mbox_tmo; | ||
7045 | |||
7046 | rc = 0; | ||
7047 | mqe = &mboxq->u.mqe; | ||
7048 | |||
7049 | /* Read the port's SLI4 Parameters port capabilities */ | ||
7050 | lpfc_sli4_params(mboxq); | ||
7051 | if (!phba->sli4_hba.intr_enable) | ||
7052 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
7053 | else { | ||
7054 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_PORT_CAPABILITIES); | ||
7055 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | ||
7056 | } | ||
7057 | |||
7058 | if (unlikely(rc)) | ||
7059 | return 1; | ||
7060 | |||
7061 | sli4_params = &phba->sli4_hba.pc_sli4_params; | ||
7062 | sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params); | ||
7063 | sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params); | ||
7064 | sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params); | ||
7065 | sli4_params->featurelevel_1 = bf_get(featurelevel_1, | ||
7066 | &mqe->un.sli4_params); | ||
7067 | sli4_params->featurelevel_2 = bf_get(featurelevel_2, | ||
7068 | &mqe->un.sli4_params); | ||
7069 | sli4_params->proto_types = mqe->un.sli4_params.word3; | ||
7070 | sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len; | ||
7071 | sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params); | ||
7072 | sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params); | ||
7073 | sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params); | ||
7074 | sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params); | ||
7075 | sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params); | ||
7076 | sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params); | ||
7077 | sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params); | ||
7078 | sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params); | ||
7079 | sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params); | ||
7080 | sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params); | ||
7081 | sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params); | ||
7082 | sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params); | ||
7083 | sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params); | ||
7084 | sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params); | ||
7085 | sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params); | ||
7086 | sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params); | ||
7087 | sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params); | ||
7088 | sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params); | ||
7089 | sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params); | ||
7090 | return rc; | ||
7091 | } | ||
7092 | |||
6984 | /** | 7093 | /** |
6985 | * lpfc_pci_probe_one_s3 - PCI probe func to reg SLI-3 device to PCI subsystem. | 7094 | * lpfc_pci_probe_one_s3 - PCI probe func to reg SLI-3 device to PCI subsystem. |
6986 | * @pdev: pointer to PCI device | 7095 | * @pdev: pointer to PCI device |
@@ -8053,11 +8162,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
8053 | int rc; | 8162 | int rc; |
8054 | struct lpfc_sli_intf intf; | 8163 | struct lpfc_sli_intf intf; |
8055 | 8164 | ||
8056 | if (pci_read_config_dword(pdev, LPFC_SLIREV_CONF_WORD, &intf.word0)) | 8165 | if (pci_read_config_dword(pdev, LPFC_SLI_INTF, &intf.word0)) |
8057 | return -ENODEV; | 8166 | return -ENODEV; |
8058 | 8167 | ||
8059 | if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) && | 8168 | if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) && |
8060 | (bf_get(lpfc_sli_intf_rev, &intf) == LPFC_SLIREV_CONF_SLI4)) | 8169 | (bf_get(lpfc_sli_intf_slirev, &intf) == LPFC_SLI_INTF_REV_SLI4)) |
8061 | rc = lpfc_pci_probe_one_s4(pdev, pid); | 8170 | rc = lpfc_pci_probe_one_s4(pdev, pid); |
8062 | else | 8171 | else |
8063 | rc = lpfc_pci_probe_one_s3(pdev, pid); | 8172 | rc = lpfc_pci_probe_one_s3(pdev, pid); |