diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index c48cd0be1a59..b9edfebf5091 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -4692,6 +4692,175 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
4692 | } | 4692 | } |
4693 | 4693 | ||
4694 | /** | 4694 | /** |
4695 | * lpfc_sli4_retrieve_pport_name - Retrieve SLI4 device physical port name | ||
4696 | * @phba: pointer to lpfc hba data structure. | ||
4697 | * | ||
4698 | * This routine retrieves SLI4 device physical port name this PCI function | ||
4699 | * is attached to. | ||
4700 | * | ||
4701 | * Return codes | ||
4702 | * 0 - sucessful | ||
4703 | * otherwise - failed to retrieve physical port name | ||
4704 | **/ | ||
4705 | static int | ||
4706 | lpfc_sli4_retrieve_pport_name(struct lpfc_hba *phba) | ||
4707 | { | ||
4708 | LPFC_MBOXQ_t *mboxq; | ||
4709 | struct lpfc_mbx_read_config *rd_config; | ||
4710 | struct lpfc_mbx_get_cntl_attributes *mbx_cntl_attr; | ||
4711 | struct lpfc_controller_attribute *cntl_attr; | ||
4712 | struct lpfc_mbx_get_port_name *get_port_name; | ||
4713 | void *virtaddr = NULL; | ||
4714 | uint32_t alloclen, reqlen; | ||
4715 | uint32_t shdr_status, shdr_add_status; | ||
4716 | union lpfc_sli4_cfg_shdr *shdr; | ||
4717 | char cport_name = 0; | ||
4718 | int rc; | ||
4719 | |||
4720 | /* We assume nothing at this point */ | ||
4721 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_INVAL; | ||
4722 | phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_NON; | ||
4723 | |||
4724 | mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4725 | if (!mboxq) | ||
4726 | return -ENOMEM; | ||
4727 | |||
4728 | /* obtain link type and link number via READ_CONFIG */ | ||
4729 | lpfc_read_config(phba, mboxq); | ||
4730 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
4731 | if (rc == MBX_SUCCESS) { | ||
4732 | rd_config = &mboxq->u.mqe.un.rd_config; | ||
4733 | if (bf_get(lpfc_mbx_rd_conf_lnk_ldv, rd_config)) { | ||
4734 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL; | ||
4735 | phba->sli4_hba.lnk_info.lnk_tp = | ||
4736 | bf_get(lpfc_mbx_rd_conf_lnk_type, rd_config); | ||
4737 | phba->sli4_hba.lnk_info.lnk_no = | ||
4738 | bf_get(lpfc_mbx_rd_conf_lnk_numb, rd_config); | ||
4739 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
4740 | "3081 lnk_type:%d, lnk_numb:%d\n", | ||
4741 | phba->sli4_hba.lnk_info.lnk_tp, | ||
4742 | phba->sli4_hba.lnk_info.lnk_no); | ||
4743 | goto retrieve_ppname; | ||
4744 | } else | ||
4745 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
4746 | "3082 Mailbox (x%x) returned ldv:x0\n", | ||
4747 | bf_get(lpfc_mqe_command, | ||
4748 | &mboxq->u.mqe)); | ||
4749 | } else | ||
4750 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
4751 | "3083 Mailbox (x%x) failed, status:x%x\n", | ||
4752 | bf_get(lpfc_mqe_command, &mboxq->u.mqe), | ||
4753 | bf_get(lpfc_mqe_status, &mboxq->u.mqe)); | ||
4754 | |||
4755 | /* obtain link type and link number via COMMON_GET_CNTL_ATTRIBUTES */ | ||
4756 | reqlen = sizeof(struct lpfc_mbx_get_cntl_attributes); | ||
4757 | alloclen = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
4758 | LPFC_MBOX_OPCODE_GET_CNTL_ATTRIBUTES, reqlen, | ||
4759 | LPFC_SLI4_MBX_NEMBED); | ||
4760 | if (alloclen < reqlen) { | ||
4761 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
4762 | "3084 Allocated DMA memory size (%d) is " | ||
4763 | "less than the requested DMA memory size " | ||
4764 | "(%d)\n", alloclen, reqlen); | ||
4765 | rc = -ENOMEM; | ||
4766 | goto out_free_mboxq; | ||
4767 | } | ||
4768 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
4769 | virtaddr = mboxq->sge_array->addr[0]; | ||
4770 | mbx_cntl_attr = (struct lpfc_mbx_get_cntl_attributes *)virtaddr; | ||
4771 | shdr = &mbx_cntl_attr->cfg_shdr; | ||
4772 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
4773 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
4774 | if (shdr_status || shdr_add_status || rc) { | ||
4775 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
4776 | "3085 Mailbox x%x (x%x/x%x) failed, " | ||
4777 | "rc:x%x, status:x%x, add_status:x%x\n", | ||
4778 | bf_get(lpfc_mqe_command, &mboxq->u.mqe), | ||
4779 | lpfc_sli_config_mbox_subsys_get(phba, mboxq), | ||
4780 | lpfc_sli_config_mbox_opcode_get(phba, mboxq), | ||
4781 | rc, shdr_status, shdr_add_status); | ||
4782 | rc = -ENXIO; | ||
4783 | goto out_free_mboxq; | ||
4784 | } | ||
4785 | cntl_attr = &mbx_cntl_attr->cntl_attr; | ||
4786 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL; | ||
4787 | phba->sli4_hba.lnk_info.lnk_tp = | ||
4788 | bf_get(lpfc_cntl_attr_lnk_type, cntl_attr); | ||
4789 | phba->sli4_hba.lnk_info.lnk_no = | ||
4790 | bf_get(lpfc_cntl_attr_lnk_numb, cntl_attr); | ||
4791 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
4792 | "3086 lnk_type:%d, lnk_numb:%d\n", | ||
4793 | phba->sli4_hba.lnk_info.lnk_tp, | ||
4794 | phba->sli4_hba.lnk_info.lnk_no); | ||
4795 | |||
4796 | retrieve_ppname: | ||
4797 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | ||
4798 | LPFC_MBOX_OPCODE_GET_PORT_NAME, | ||
4799 | sizeof(struct lpfc_mbx_get_port_name) - | ||
4800 | sizeof(struct lpfc_sli4_cfg_mhdr), | ||
4801 | LPFC_SLI4_MBX_EMBED); | ||
4802 | get_port_name = &mboxq->u.mqe.un.get_port_name; | ||
4803 | shdr = (union lpfc_sli4_cfg_shdr *)&get_port_name->header.cfg_shdr; | ||
4804 | bf_set(lpfc_mbox_hdr_version, &shdr->request, LPFC_OPCODE_VERSION_1); | ||
4805 | bf_set(lpfc_mbx_get_port_name_lnk_type, &get_port_name->u.request, | ||
4806 | phba->sli4_hba.lnk_info.lnk_tp); | ||
4807 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
4808 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
4809 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
4810 | if (shdr_status || shdr_add_status || rc) { | ||
4811 | lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, | ||
4812 | "3087 Mailbox x%x (x%x/x%x) failed: " | ||
4813 | "rc:x%x, status:x%x, add_status:x%x\n", | ||
4814 | bf_get(lpfc_mqe_command, &mboxq->u.mqe), | ||
4815 | lpfc_sli_config_mbox_subsys_get(phba, mboxq), | ||
4816 | lpfc_sli_config_mbox_opcode_get(phba, mboxq), | ||
4817 | rc, shdr_status, shdr_add_status); | ||
4818 | rc = -ENXIO; | ||
4819 | goto out_free_mboxq; | ||
4820 | } | ||
4821 | switch (phba->sli4_hba.lnk_info.lnk_no) { | ||
4822 | case LPFC_LINK_NUMBER_0: | ||
4823 | cport_name = bf_get(lpfc_mbx_get_port_name_name0, | ||
4824 | &get_port_name->u.response); | ||
4825 | phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET; | ||
4826 | break; | ||
4827 | case LPFC_LINK_NUMBER_1: | ||
4828 | cport_name = bf_get(lpfc_mbx_get_port_name_name1, | ||
4829 | &get_port_name->u.response); | ||
4830 | phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET; | ||
4831 | break; | ||
4832 | case LPFC_LINK_NUMBER_2: | ||
4833 | cport_name = bf_get(lpfc_mbx_get_port_name_name2, | ||
4834 | &get_port_name->u.response); | ||
4835 | phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET; | ||
4836 | break; | ||
4837 | case LPFC_LINK_NUMBER_3: | ||
4838 | cport_name = bf_get(lpfc_mbx_get_port_name_name3, | ||
4839 | &get_port_name->u.response); | ||
4840 | phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_GET; | ||
4841 | break; | ||
4842 | default: | ||
4843 | break; | ||
4844 | } | ||
4845 | |||
4846 | if (phba->sli4_hba.pport_name_sta == LPFC_SLI4_PPNAME_GET) { | ||
4847 | phba->Port[0] = cport_name; | ||
4848 | phba->Port[1] = '\0'; | ||
4849 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
4850 | "3091 SLI get port name: %s\n", phba->Port); | ||
4851 | } | ||
4852 | |||
4853 | out_free_mboxq: | ||
4854 | if (rc != MBX_TIMEOUT) { | ||
4855 | if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) | ||
4856 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
4857 | else | ||
4858 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
4859 | } | ||
4860 | return rc; | ||
4861 | } | ||
4862 | |||
4863 | /** | ||
4695 | * lpfc_sli4_arm_cqeq_intr - Arm sli-4 device completion and event queues | 4864 | * lpfc_sli4_arm_cqeq_intr - Arm sli-4 device completion and event queues |
4696 | * @phba: pointer to lpfc hba data structure. | 4865 | * @phba: pointer to lpfc hba data structure. |
4697 | * | 4866 | * |
@@ -5754,6 +5923,17 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
5754 | kfree(vpd); | 5923 | kfree(vpd); |
5755 | goto out_free_mbox; | 5924 | goto out_free_mbox; |
5756 | } | 5925 | } |
5926 | |||
5927 | /* | ||
5928 | * Retrieve sli4 device physical port name, failure of doing it | ||
5929 | * is considered as non-fatal. | ||
5930 | */ | ||
5931 | rc = lpfc_sli4_retrieve_pport_name(phba); | ||
5932 | if (!rc) | ||
5933 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, | ||
5934 | "3080 Successful retrieving SLI4 device " | ||
5935 | "physical port name: %s.\n", phba->Port); | ||
5936 | |||
5757 | /* | 5937 | /* |
5758 | * Evaluate the read rev and vpd data. Populate the driver | 5938 | * Evaluate the read rev and vpd data. Populate the driver |
5759 | * state with the results. If this routine fails, the failure | 5939 | * state with the results. If this routine fails, the failure |