diff options
| author | James Smart <James.Smart@Emulex.Com> | 2009-06-10 17:22:44 -0400 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-15 11:09:32 -0400 |
| commit | f1126688805d77a4798b694439fa48bba6629388 (patch) | |
| tree | 8a6169f70dba7e8644f07c8ca654ebad1786281d | |
| parent | 43fac4d97a1a30085f1cae61aa565e5e7e5e5d7d (diff) | |
[SCSI] lpfc 8.3.3 : Fix various SLI-3 vs SLI-4 differences
Contains the following changes
- Set the CT field of FDISC to 3
- Fixed over allocation of SCSI buffers on SLI4
- Removed unused jump table entries
- Increase LPFC_WQE_DEF_COUNT to 256
- Updated FDISC context to VPI
- Fixed immediate SCSI command for LUN reset translation to WQE
- Extended mailbox handling to allow MBX_POLL commands in between async
MBQ commands
- Fixed SID used for FDISC
- Fix crash when accessing ctlregs from sysfs for SLI4 HBAs
- Fix SLI4 firmware version not being saved or displayed correctly
- Expand CQID field in WQE structure to 16 bits
- Fix post header template mailbox command timing out
- Removed FCoE PCI device ID 0x0705
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
| -rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 4 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 6 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 14 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 4 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 33 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 177 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 198 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 2 |
10 files changed, 224 insertions, 219 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 540569849099..1877d9811831 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
| @@ -457,10 +457,6 @@ struct lpfc_hba { | |||
| 457 | void (*lpfc_scsi_prep_cmnd) | 457 | void (*lpfc_scsi_prep_cmnd) |
| 458 | (struct lpfc_vport *, struct lpfc_scsi_buf *, | 458 | (struct lpfc_vport *, struct lpfc_scsi_buf *, |
| 459 | struct lpfc_nodelist *); | 459 | struct lpfc_nodelist *); |
| 460 | int (*lpfc_scsi_prep_task_mgmt_cmd) | ||
| 461 | (struct lpfc_vport *, struct lpfc_scsi_buf *, | ||
| 462 | unsigned int, uint8_t); | ||
| 463 | |||
| 464 | /* IOCB interface function jump table entries */ | 460 | /* IOCB interface function jump table entries */ |
| 465 | int (*__lpfc_sli_issue_iocb) | 461 | int (*__lpfc_sli_issue_iocb) |
| 466 | (struct lpfc_hba *, uint32_t, | 462 | (struct lpfc_hba *, uint32_t, |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index d73e677201f8..fc07be5fbce9 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
| @@ -3113,6 +3113,9 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
| 3113 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 3113 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
| 3114 | struct lpfc_hba *phba = vport->phba; | 3114 | struct lpfc_hba *phba = vport->phba; |
| 3115 | 3115 | ||
| 3116 | if (phba->sli_rev >= LPFC_SLI_REV4) | ||
| 3117 | return -EPERM; | ||
| 3118 | |||
| 3116 | if ((off + count) > FF_REG_AREA_SIZE) | 3119 | if ((off + count) > FF_REG_AREA_SIZE) |
| 3117 | return -ERANGE; | 3120 | return -ERANGE; |
| 3118 | 3121 | ||
| @@ -3163,6 +3166,9 @@ sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
| 3163 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 3166 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
| 3164 | struct lpfc_hba *phba = vport->phba; | 3167 | struct lpfc_hba *phba = vport->phba; |
| 3165 | 3168 | ||
| 3169 | if (phba->sli_rev >= LPFC_SLI_REV4) | ||
| 3170 | return -EPERM; | ||
| 3171 | |||
| 3166 | if (off > FF_REG_AREA_SIZE) | 3172 | if (off > FF_REG_AREA_SIZE) |
| 3167 | return -ERANGE; | 3173 | return -ERANGE; |
| 3168 | 3174 | ||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 1dbccfd3d022..0e532f072eb3 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
| @@ -1732,7 +1732,9 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag) | |||
| 1732 | uint32_t *ptr, str[4]; | 1732 | uint32_t *ptr, str[4]; |
| 1733 | uint8_t *fwname; | 1733 | uint8_t *fwname; |
| 1734 | 1734 | ||
| 1735 | if (vp->rev.rBit) { | 1735 | if (phba->sli_rev == LPFC_SLI_REV4) |
| 1736 | sprintf(fwrevision, "%s", vp->rev.opFwName); | ||
| 1737 | else if (vp->rev.rBit) { | ||
| 1736 | if (psli->sli_flag & LPFC_SLI_ACTIVE) | 1738 | if (psli->sli_flag & LPFC_SLI_ACTIVE) |
| 1737 | rev = vp->rev.sli2FwRev; | 1739 | rev = vp->rev.sli2FwRev; |
| 1738 | else | 1740 | else |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 6bdeb14878a2..2aabaf9c4053 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
| @@ -6108,9 +6108,17 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
| 6108 | icmd->un.elsreq64.myID = 0; | 6108 | icmd->un.elsreq64.myID = 0; |
| 6109 | icmd->un.elsreq64.fl = 1; | 6109 | icmd->un.elsreq64.fl = 1; |
| 6110 | 6110 | ||
| 6111 | /* For FDISC, Let FDISC rsp set the NPortID for this VPI */ | 6111 | if (phba->sli_rev == LPFC_SLI_REV4) { |
| 6112 | icmd->ulpCt_h = 1; | 6112 | /* FDISC needs to be 1 for WQE VPI */ |
| 6113 | icmd->ulpCt_l = 0; | 6113 | elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1; |
| 6114 | elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ; | ||
| 6115 | /* Set the ulpContext to the vpi */ | ||
| 6116 | elsiocb->iocb.ulpContext = vport->vpi + phba->vpi_base; | ||
| 6117 | } else { | ||
| 6118 | /* For FDISC, Let FDISC rsp set the NPortID for this VPI */ | ||
| 6119 | icmd->ulpCt_h = 1; | ||
| 6120 | icmd->ulpCt_l = 0; | ||
| 6121 | } | ||
| 6114 | 6122 | ||
| 6115 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 6123 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
| 6116 | *((uint32_t *) (pcmd)) = ELS_CMD_FDISC; | 6124 | *((uint32_t *) (pcmd)) = ELS_CMD_FDISC; |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 02aa016b93e9..8a3a026667e4 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
| @@ -1183,7 +1183,6 @@ typedef struct { | |||
| 1183 | #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 | 1183 | #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 |
| 1184 | #define PCI_VENDOR_ID_SERVERENGINE 0x19a2 | 1184 | #define PCI_VENDOR_ID_SERVERENGINE 0x19a2 |
| 1185 | #define PCI_DEVICE_ID_TIGERSHARK 0x0704 | 1185 | #define PCI_DEVICE_ID_TIGERSHARK 0x0704 |
| 1186 | #define PCI_DEVICE_ID_TIGERSHARK_S 0x0705 | ||
| 1187 | 1186 | ||
| 1188 | #define JEDEC_ID_ADDRESS 0x0080001c | 1187 | #define JEDEC_ID_ADDRESS 0x0080001c |
| 1189 | #define FIREFLY_JEDEC_ID 0x1ACC | 1188 | #define FIREFLY_JEDEC_ID 0x1ACC |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 39c34b3ad29d..749811a1627b 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
| @@ -422,9 +422,9 @@ struct lpfc_wqe_generic{ | |||
| 422 | #define lpfc_wqe_gen_pri_WORD word10 | 422 | #define lpfc_wqe_gen_pri_WORD word10 |
| 423 | uint32_t word11; | 423 | uint32_t word11; |
| 424 | #define lpfc_wqe_gen_cq_id_SHIFT 16 | 424 | #define lpfc_wqe_gen_cq_id_SHIFT 16 |
| 425 | #define lpfc_wqe_gen_cq_id_MASK 0x000003FF | 425 | #define lpfc_wqe_gen_cq_id_MASK 0x0000FFFF |
| 426 | #define lpfc_wqe_gen_cq_id_WORD word11 | 426 | #define lpfc_wqe_gen_cq_id_WORD word11 |
| 427 | #define LPFC_WQE_CQ_ID_DEFAULT 0x3ff | 427 | #define LPFC_WQE_CQ_ID_DEFAULT 0xffff |
| 428 | #define lpfc_wqe_gen_wqec_SHIFT 7 | 428 | #define lpfc_wqe_gen_wqec_SHIFT 7 |
| 429 | #define lpfc_wqe_gen_wqec_MASK 0x00000001 | 429 | #define lpfc_wqe_gen_wqec_MASK 0x00000001 |
| 430 | #define lpfc_wqe_gen_wqec_WORD word11 | 430 | #define lpfc_wqe_gen_wqec_WORD word11 |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 2f5907f92eea..4363331aba77 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
| @@ -428,7 +428,8 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
| 428 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ | 428 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ |
| 429 | if (phba->cfg_hba_queue_depth > (mb->un.varRdConfig.max_xri+1)) | 429 | if (phba->cfg_hba_queue_depth > (mb->un.varRdConfig.max_xri+1)) |
| 430 | phba->cfg_hba_queue_depth = | 430 | phba->cfg_hba_queue_depth = |
| 431 | mb->un.varRdConfig.max_xri + 1; | 431 | (mb->un.varRdConfig.max_xri + 1) - |
| 432 | lpfc_sli4_get_els_iocb_cnt(phba); | ||
| 432 | 433 | ||
| 433 | phba->lmt = mb->un.varRdConfig.lmt; | 434 | phba->lmt = mb->un.varRdConfig.lmt; |
| 434 | 435 | ||
| @@ -1646,10 +1647,6 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
| 1646 | oneConnect = 1; | 1647 | oneConnect = 1; |
| 1647 | m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"}; | 1648 | m = (typeof(m)) {"OCe10100-F", max_speed, "PCIe"}; |
| 1648 | break; | 1649 | break; |
| 1649 | case PCI_DEVICE_ID_TIGERSHARK_S: | ||
| 1650 | oneConnect = 1; | ||
| 1651 | m = (typeof(m)) {"OCe10100-F-S", max_speed, "PCIe"}; | ||
| 1652 | break; | ||
| 1653 | default: | 1650 | default: |
| 1654 | m = (typeof(m)){ NULL }; | 1651 | m = (typeof(m)){ NULL }; |
| 1655 | break; | 1652 | break; |
| @@ -7184,16 +7181,19 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) | |||
| 7184 | { | 7181 | { |
| 7185 | int max_xri = phba->sli4_hba.max_cfg_param.max_xri; | 7182 | int max_xri = phba->sli4_hba.max_cfg_param.max_xri; |
| 7186 | 7183 | ||
| 7187 | if (max_xri <= 100) | 7184 | if (phba->sli_rev == LPFC_SLI_REV4) { |
| 7188 | return 4; | 7185 | if (max_xri <= 100) |
| 7189 | else if (max_xri <= 256) | 7186 | return 4; |
| 7190 | return 8; | 7187 | else if (max_xri <= 256) |
| 7191 | else if (max_xri <= 512) | 7188 | return 8; |
| 7192 | return 16; | 7189 | else if (max_xri <= 512) |
| 7193 | else if (max_xri <= 1024) | 7190 | return 16; |
| 7194 | return 32; | 7191 | else if (max_xri <= 1024) |
| 7195 | else | 7192 | return 32; |
| 7196 | return 48; | 7193 | else |
| 7194 | return 48; | ||
| 7195 | } else | ||
| 7196 | return 0; | ||
| 7197 | } | 7197 | } |
| 7198 | 7198 | ||
| 7199 | /** | 7199 | /** |
| @@ -7642,7 +7642,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
| 7642 | 7642 | ||
| 7643 | switch (dev_id) { | 7643 | switch (dev_id) { |
| 7644 | case PCI_DEVICE_ID_TIGERSHARK: | 7644 | case PCI_DEVICE_ID_TIGERSHARK: |
| 7645 | case PCI_DEVICE_ID_TIGERSHARK_S: | ||
| 7646 | rc = lpfc_pci_probe_one_s4(pdev, pid); | 7645 | rc = lpfc_pci_probe_one_s4(pdev, pid); |
| 7647 | break; | 7646 | break; |
| 7648 | default: | 7647 | default: |
| @@ -7941,8 +7940,6 @@ static struct pci_device_id lpfc_id_table[] = { | |||
| 7941 | PCI_ANY_ID, PCI_ANY_ID, }, | 7940 | PCI_ANY_ID, PCI_ANY_ID, }, |
| 7942 | {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK, | 7941 | {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK, |
| 7943 | PCI_ANY_ID, PCI_ANY_ID, }, | 7942 | PCI_ANY_ID, PCI_ANY_ID, }, |
| 7944 | {PCI_VENDOR_ID_SERVERENGINE, PCI_DEVICE_ID_TIGERSHARK_S, | ||
| 7945 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
| 7946 | { 0 } | 7943 | { 0 } |
| 7947 | }; | 7944 | }; |
| 7948 | 7945 | ||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index e9fa6762044a..32f8dac6abfe 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
| @@ -116,6 +116,27 @@ lpfc_debug_save_dif(struct scsi_cmnd *cmnd) | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge. | ||
| 120 | * @phba: Pointer to HBA object. | ||
| 121 | * @lpfc_cmd: lpfc scsi command object pointer. | ||
| 122 | * | ||
| 123 | * This function is called from the lpfc_prep_task_mgmt_cmd function to | ||
| 124 | * set the last bit in the response sge entry. | ||
| 125 | **/ | ||
| 126 | static void | ||
| 127 | lpfc_sli4_set_rsp_sgl_last(struct lpfc_hba *phba, | ||
| 128 | struct lpfc_scsi_buf *lpfc_cmd) | ||
| 129 | { | ||
| 130 | struct sli4_sge *sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; | ||
| 131 | if (sgl) { | ||
| 132 | sgl += 1; | ||
| 133 | sgl->word2 = le32_to_cpu(sgl->word2); | ||
| 134 | bf_set(lpfc_sli4_sge_last, sgl, 1); | ||
| 135 | sgl->word2 = cpu_to_le32(sgl->word2); | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 119 | * lpfc_update_stats - Update statistical data for the command completion | 140 | * lpfc_update_stats - Update statistical data for the command completion |
| 120 | * @phba: Pointer to HBA object. | 141 | * @phba: Pointer to HBA object. |
| 121 | * @lpfc_cmd: lpfc scsi command object pointer. | 142 | * @lpfc_cmd: lpfc scsi command object pointer. |
| @@ -1978,7 +1999,7 @@ lpfc_send_scsi_error_event(struct lpfc_hba *phba, struct lpfc_vport *vport, | |||
| 1978 | } | 1999 | } |
| 1979 | 2000 | ||
| 1980 | /** | 2001 | /** |
| 1981 | * lpfc_scsi_unprep_dma_buf_s3 - Un-map DMA mapping of SG-list for SLI3 dev | 2002 | * lpfc_scsi_unprep_dma_buf - Un-map DMA mapping of SG-list for dev |
| 1982 | * @phba: The HBA for which this call is being executed. | 2003 | * @phba: The HBA for which this call is being executed. |
| 1983 | * @psb: The scsi buffer which is going to be un-mapped. | 2004 | * @psb: The scsi buffer which is going to be un-mapped. |
| 1984 | * | 2005 | * |
| @@ -1986,7 +2007,7 @@ lpfc_send_scsi_error_event(struct lpfc_hba *phba, struct lpfc_vport *vport, | |||
| 1986 | * field of @lpfc_cmd for device with SLI-3 interface spec. | 2007 | * field of @lpfc_cmd for device with SLI-3 interface spec. |
| 1987 | **/ | 2008 | **/ |
| 1988 | static void | 2009 | static void |
| 1989 | lpfc_scsi_unprep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) | 2010 | lpfc_scsi_unprep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) |
| 1990 | { | 2011 | { |
| 1991 | /* | 2012 | /* |
| 1992 | * There are only two special cases to consider. (1) the scsi command | 2013 | * There are only two special cases to consider. (1) the scsi command |
| @@ -2003,36 +2024,6 @@ lpfc_scsi_unprep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) | |||
| 2003 | } | 2024 | } |
| 2004 | 2025 | ||
| 2005 | /** | 2026 | /** |
| 2006 | * lpfc_scsi_unprep_dma_buf_s4 - Un-map DMA mapping of SG-list for SLI4 dev | ||
| 2007 | * @phba: The Hba for which this call is being executed. | ||
| 2008 | * @psb: The scsi buffer which is going to be un-mapped. | ||
| 2009 | * | ||
| 2010 | * This routine does DMA un-mapping of scatter gather list of scsi command | ||
| 2011 | * field of @lpfc_cmd for device with SLI-4 interface spec. If we have to | ||
| 2012 | * remove the sgl for this scsi buffer then we will do it here. For now | ||
| 2013 | * we should be able to just call the sli3 unprep routine. | ||
| 2014 | **/ | ||
| 2015 | static void | ||
| 2016 | lpfc_scsi_unprep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) | ||
| 2017 | { | ||
| 2018 | lpfc_scsi_unprep_dma_buf_s3(phba, psb); | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | /** | ||
| 2022 | * lpfc_scsi_unprep_dma_buf - Wrapper function for unmap DMA mapping of SG-list | ||
| 2023 | * @phba: The Hba for which this call is being executed. | ||
| 2024 | * @psb: The scsi buffer which is going to be un-mapped. | ||
| 2025 | * | ||
| 2026 | * This routine does DMA un-mapping of scatter gather list of scsi command | ||
| 2027 | * field of @lpfc_cmd for device with SLI-4 interface spec. | ||
| 2028 | **/ | ||
| 2029 | static void | ||
| 2030 | lpfc_scsi_unprep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) | ||
| 2031 | { | ||
| 2032 | phba->lpfc_scsi_unprep_dma_buf(phba, psb); | ||
| 2033 | } | ||
| 2034 | |||
| 2035 | /** | ||
| 2036 | * lpfc_handler_fcp_err - FCP response handler | 2027 | * lpfc_handler_fcp_err - FCP response handler |
| 2037 | * @vport: The virtual port for which this call is being executed. | 2028 | * @vport: The virtual port for which this call is being executed. |
| 2038 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. | 2029 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. |
| @@ -2461,7 +2452,7 @@ lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd) | |||
| 2461 | } | 2452 | } |
| 2462 | 2453 | ||
| 2463 | /** | 2454 | /** |
| 2464 | * lpfc_scsi_prep_cmnd_s3 - Convert scsi cmnd to FCP infor unit for SLI3 dev | 2455 | * lpfc_scsi_prep_cmnd - Wrapper func for convert scsi cmnd to FCP info unit |
| 2465 | * @vport: The virtual port for which this call is being executed. | 2456 | * @vport: The virtual port for which this call is being executed. |
| 2466 | * @lpfc_cmd: The scsi command which needs to send. | 2457 | * @lpfc_cmd: The scsi command which needs to send. |
| 2467 | * @pnode: Pointer to lpfc_nodelist. | 2458 | * @pnode: Pointer to lpfc_nodelist. |
| @@ -2470,7 +2461,7 @@ lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd) | |||
| 2470 | * to transfer for device with SLI3 interface spec. | 2461 | * to transfer for device with SLI3 interface spec. |
| 2471 | **/ | 2462 | **/ |
| 2472 | static void | 2463 | static void |
| 2473 | lpfc_scsi_prep_cmnd_s3(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | 2464 | lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, |
| 2474 | struct lpfc_nodelist *pnode) | 2465 | struct lpfc_nodelist *pnode) |
| 2475 | { | 2466 | { |
| 2476 | struct lpfc_hba *phba = vport->phba; | 2467 | struct lpfc_hba *phba = vport->phba; |
| @@ -2558,46 +2549,7 @@ lpfc_scsi_prep_cmnd_s3(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
| 2558 | } | 2549 | } |
| 2559 | 2550 | ||
| 2560 | /** | 2551 | /** |
| 2561 | * lpfc_scsi_prep_cmnd_s4 - Convert scsi cmnd to FCP infor unit for SLI4 dev | 2552 | * lpfc_scsi_prep_task_mgmt_cmnd - Convert SLI3 scsi TM cmd to FCP info unit |
| 2562 | * @vport: The virtual port for which this call is being executed. | ||
| 2563 | * @lpfc_cmd: The scsi command which needs to send. | ||
| 2564 | * @pnode: Pointer to lpfc_nodelist. | ||
| 2565 | * | ||
| 2566 | * This routine initializes fcp_cmnd and iocb data structure from scsi command | ||
| 2567 | * to transfer for device with SLI4 interface spec. | ||
| 2568 | **/ | ||
| 2569 | static void | ||
| 2570 | lpfc_scsi_prep_cmnd_s4(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | ||
| 2571 | struct lpfc_nodelist *pnode) | ||
| 2572 | { | ||
| 2573 | /* | ||
| 2574 | * The prep cmnd routines do not touch the sgl or its | ||
| 2575 | * entries. We may not have to do anything different. | ||
| 2576 | * I will leave this function in place until we can | ||
| 2577 | * run some IO through the driver and determine if changes | ||
| 2578 | * are needed. | ||
| 2579 | */ | ||
| 2580 | return lpfc_scsi_prep_cmnd_s3(vport, lpfc_cmd, pnode); | ||
| 2581 | } | ||
| 2582 | |||
| 2583 | /** | ||
| 2584 | * lpfc_scsi_prep_cmnd - Wrapper func for convert scsi cmnd to FCP info unit | ||
| 2585 | * @vport: The virtual port for which this call is being executed. | ||
| 2586 | * @lpfc_cmd: The scsi command which needs to send. | ||
| 2587 | * @pnode: Pointer to lpfc_nodelist. | ||
| 2588 | * | ||
| 2589 | * This routine wraps the actual convert SCSI cmnd function pointer from | ||
| 2590 | * the lpfc_hba struct. | ||
| 2591 | **/ | ||
| 2592 | static inline void | ||
| 2593 | lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | ||
| 2594 | struct lpfc_nodelist *pnode) | ||
| 2595 | { | ||
| 2596 | vport->phba->lpfc_scsi_prep_cmnd(vport, lpfc_cmd, pnode); | ||
| 2597 | } | ||
| 2598 | |||
| 2599 | /** | ||
| 2600 | * lpfc_scsi_prep_task_mgmt_cmnd_s3 - Convert SLI3 scsi TM cmd to FCP info unit | ||
| 2601 | * @vport: The virtual port for which this call is being executed. | 2553 | * @vport: The virtual port for which this call is being executed. |
| 2602 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. | 2554 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. |
| 2603 | * @lun: Logical unit number. | 2555 | * @lun: Logical unit number. |
| @@ -2611,7 +2563,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
| 2611 | * 1 - Success | 2563 | * 1 - Success |
| 2612 | **/ | 2564 | **/ |
| 2613 | static int | 2565 | static int |
| 2614 | lpfc_scsi_prep_task_mgmt_cmd_s3(struct lpfc_vport *vport, | 2566 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, |
| 2615 | struct lpfc_scsi_buf *lpfc_cmd, | 2567 | struct lpfc_scsi_buf *lpfc_cmd, |
| 2616 | unsigned int lun, | 2568 | unsigned int lun, |
| 2617 | uint8_t task_mgmt_cmd) | 2569 | uint8_t task_mgmt_cmd) |
| @@ -2653,68 +2605,13 @@ lpfc_scsi_prep_task_mgmt_cmd_s3(struct lpfc_vport *vport, | |||
| 2653 | * The driver will provide the timeout mechanism. | 2605 | * The driver will provide the timeout mechanism. |
| 2654 | */ | 2606 | */ |
| 2655 | piocb->ulpTimeout = 0; | 2607 | piocb->ulpTimeout = 0; |
| 2656 | } else { | 2608 | } else |
| 2657 | piocb->ulpTimeout = lpfc_cmd->timeout; | 2609 | piocb->ulpTimeout = lpfc_cmd->timeout; |
| 2658 | } | ||
| 2659 | |||
| 2660 | return 1; | ||
| 2661 | } | ||
| 2662 | |||
| 2663 | /** | ||
| 2664 | * lpfc_scsi_prep_task_mgmt_cmnd_s4 - Convert SLI4 scsi TM cmd to FCP info unit | ||
| 2665 | * @vport: The virtual port for which this call is being executed. | ||
| 2666 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. | ||
| 2667 | * @lun: Logical unit number. | ||
| 2668 | * @task_mgmt_cmd: SCSI task management command. | ||
| 2669 | * | ||
| 2670 | * This routine creates FCP information unit corresponding to @task_mgmt_cmd | ||
| 2671 | * for device with SLI-4 interface spec. | ||
| 2672 | * | ||
| 2673 | * Return codes: | ||
| 2674 | * 0 - Error | ||
| 2675 | * 1 - Success | ||
| 2676 | **/ | ||
| 2677 | static int | ||
| 2678 | lpfc_scsi_prep_task_mgmt_cmd_s4(struct lpfc_vport *vport, | ||
| 2679 | struct lpfc_scsi_buf *lpfc_cmd, | ||
| 2680 | unsigned int lun, | ||
| 2681 | uint8_t task_mgmt_cmd) | ||
| 2682 | { | ||
| 2683 | /* | ||
| 2684 | * The prep cmnd routines do not touch the sgl or its | ||
| 2685 | * entries. We may not have to do anything different. | ||
| 2686 | * I will leave this function in place until we can | ||
| 2687 | * run some IO through the driver and determine if changes | ||
| 2688 | * are needed. | ||
| 2689 | */ | ||
| 2690 | return lpfc_scsi_prep_task_mgmt_cmd_s3(vport, lpfc_cmd, lun, | ||
| 2691 | task_mgmt_cmd); | ||
| 2692 | } | ||
| 2693 | 2610 | ||
| 2694 | /** | 2611 | if (vport->phba->sli_rev == LPFC_SLI_REV4) |
| 2695 | * lpfc_scsi_prep_task_mgmt_cmnd - Wrapper func convert scsi TM cmd to FCP info | 2612 | lpfc_sli4_set_rsp_sgl_last(vport->phba, lpfc_cmd); |
| 2696 | * @vport: The virtual port for which this call is being executed. | ||
| 2697 | * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure. | ||
| 2698 | * @lun: Logical unit number. | ||
| 2699 | * @task_mgmt_cmd: SCSI task management command. | ||
| 2700 | * | ||
| 2701 | * This routine wraps the actual convert SCSI TM to FCP information unit | ||
| 2702 | * function pointer from the lpfc_hba struct. | ||
| 2703 | * | ||
| 2704 | * Return codes: | ||
| 2705 | * 0 - Error | ||
| 2706 | * 1 - Success | ||
| 2707 | **/ | ||
| 2708 | static inline int | ||
| 2709 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, | ||
| 2710 | struct lpfc_scsi_buf *lpfc_cmd, | ||
| 2711 | unsigned int lun, | ||
| 2712 | uint8_t task_mgmt_cmd) | ||
| 2713 | { | ||
| 2714 | struct lpfc_hba *phba = vport->phba; | ||
| 2715 | 2613 | ||
| 2716 | return phba->lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun, | 2614 | return 1; |
| 2717 | task_mgmt_cmd); | ||
| 2718 | } | 2615 | } |
| 2719 | 2616 | ||
| 2720 | /** | 2617 | /** |
| @@ -2730,23 +2627,19 @@ int | |||
| 2730 | lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) | 2627 | lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) |
| 2731 | { | 2628 | { |
| 2732 | 2629 | ||
| 2630 | phba->lpfc_scsi_unprep_dma_buf = lpfc_scsi_unprep_dma_buf; | ||
| 2631 | phba->lpfc_scsi_prep_cmnd = lpfc_scsi_prep_cmnd; | ||
| 2632 | phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf; | ||
| 2633 | |||
| 2733 | switch (dev_grp) { | 2634 | switch (dev_grp) { |
| 2734 | case LPFC_PCI_DEV_LP: | 2635 | case LPFC_PCI_DEV_LP: |
| 2735 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3; | 2636 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3; |
| 2736 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3; | 2637 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3; |
| 2737 | phba->lpfc_scsi_prep_cmnd = lpfc_scsi_prep_cmnd_s3; | ||
| 2738 | phba->lpfc_scsi_unprep_dma_buf = lpfc_scsi_unprep_dma_buf_s3; | ||
| 2739 | phba->lpfc_scsi_prep_task_mgmt_cmd = | ||
| 2740 | lpfc_scsi_prep_task_mgmt_cmd_s3; | ||
| 2741 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3; | 2638 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3; |
| 2742 | break; | 2639 | break; |
| 2743 | case LPFC_PCI_DEV_OC: | 2640 | case LPFC_PCI_DEV_OC: |
| 2744 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4; | 2641 | phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4; |
| 2745 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4; | 2642 | phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4; |
| 2746 | phba->lpfc_scsi_prep_cmnd = lpfc_scsi_prep_cmnd_s4; | ||
| 2747 | phba->lpfc_scsi_unprep_dma_buf = lpfc_scsi_unprep_dma_buf_s4; | ||
| 2748 | phba->lpfc_scsi_prep_task_mgmt_cmd = | ||
| 2749 | lpfc_scsi_prep_task_mgmt_cmd_s4; | ||
| 2750 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4; | 2643 | phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4; |
| 2751 | break; | 2644 | break; |
| 2752 | default: | 2645 | default: |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ff04daf18f48..b8cf0a1b1382 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
| @@ -4211,27 +4211,6 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
| 4211 | return -EIO; | 4211 | return -EIO; |
| 4212 | } | 4212 | } |
| 4213 | 4213 | ||
| 4214 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, | ||
| 4215 | "(%d):0380 Mailbox cmd x%x Status x%x " | ||
| 4216 | "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x " | ||
| 4217 | "x%x x%x x%x x%x x%x x%x x%x x%x x%x " | ||
| 4218 | "CQ: x%x x%x x%x x%x\n", | ||
| 4219 | mboxq->vport ? mboxq->vport->vpi : 0, | ||
| 4220 | bf_get(lpfc_mqe_command, mqe), | ||
| 4221 | bf_get(lpfc_mqe_status, mqe), | ||
| 4222 | mqe->un.mb_words[0], mqe->un.mb_words[1], | ||
| 4223 | mqe->un.mb_words[2], mqe->un.mb_words[3], | ||
| 4224 | mqe->un.mb_words[4], mqe->un.mb_words[5], | ||
| 4225 | mqe->un.mb_words[6], mqe->un.mb_words[7], | ||
| 4226 | mqe->un.mb_words[8], mqe->un.mb_words[9], | ||
| 4227 | mqe->un.mb_words[10], mqe->un.mb_words[11], | ||
| 4228 | mqe->un.mb_words[12], mqe->un.mb_words[13], | ||
| 4229 | mqe->un.mb_words[14], mqe->un.mb_words[15], | ||
| 4230 | mqe->un.mb_words[16], mqe->un.mb_words[50], | ||
| 4231 | mboxq->mcqe.word0, | ||
| 4232 | mboxq->mcqe.mcqe_tag0, mboxq->mcqe.mcqe_tag1, | ||
| 4233 | mboxq->mcqe.trailer); | ||
| 4234 | |||
| 4235 | /* | 4214 | /* |
| 4236 | * The available vpd length cannot be bigger than the | 4215 | * The available vpd length cannot be bigger than the |
| 4237 | * DMA buffer passed to the port. Catch the less than | 4216 | * DMA buffer passed to the port. Catch the less than |
| @@ -4337,21 +4316,18 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
| 4337 | goto out_free_vpd; | 4316 | goto out_free_vpd; |
| 4338 | 4317 | ||
| 4339 | mqe = &mboxq->u.mqe; | 4318 | mqe = &mboxq->u.mqe; |
| 4340 | if ((bf_get(lpfc_mbx_rd_rev_sli_lvl, | 4319 | phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev); |
| 4341 | &mqe->un.read_rev) != LPFC_SLI_REV4) || | 4320 | if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)) |
| 4342 | (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev) == 0)) { | 4321 | phba->hba_flag |= HBA_FCOE_SUPPORT; |
| 4322 | if (phba->sli_rev != LPFC_SLI_REV4 || | ||
| 4323 | !(phba->hba_flag & HBA_FCOE_SUPPORT)) { | ||
| 4343 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 4324 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
| 4344 | "0376 READ_REV Error. SLI Level %d " | 4325 | "0376 READ_REV Error. SLI Level %d " |
| 4345 | "FCoE enabled %d\n", | 4326 | "FCoE enabled %d\n", |
| 4346 | bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev), | 4327 | phba->sli_rev, phba->hba_flag & HBA_FCOE_SUPPORT); |
| 4347 | bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)); | ||
| 4348 | rc = -EIO; | 4328 | rc = -EIO; |
| 4349 | goto out_free_vpd; | 4329 | goto out_free_vpd; |
| 4350 | } | 4330 | } |
| 4351 | /* Single threaded at this point, no need for lock */ | ||
| 4352 | spin_lock_irq(&phba->hbalock); | ||
| 4353 | phba->hba_flag |= HBA_FCOE_SUPPORT; | ||
| 4354 | spin_unlock_irq(&phba->hbalock); | ||
| 4355 | /* | 4331 | /* |
| 4356 | * Evaluate the read rev and vpd data. Populate the driver | 4332 | * Evaluate the read rev and vpd data. Populate the driver |
| 4357 | * state with the results. If this routine fails, the failure | 4333 | * state with the results. If this routine fails, the failure |
| @@ -4365,8 +4341,32 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
| 4365 | rc = 0; | 4341 | rc = 0; |
| 4366 | } | 4342 | } |
| 4367 | 4343 | ||
| 4368 | /* By now, we should determine the SLI revision, hard code for now */ | 4344 | /* Save information as VPD data */ |
| 4369 | phba->sli_rev = LPFC_SLI_REV4; | 4345 | phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev; |
| 4346 | phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev; | ||
| 4347 | phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev; | ||
| 4348 | phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high, | ||
| 4349 | &mqe->un.read_rev); | ||
| 4350 | phba->vpd.rev.fcphLow = bf_get(lpfc_mbx_rd_rev_fcph_low, | ||
| 4351 | &mqe->un.read_rev); | ||
| 4352 | phba->vpd.rev.feaLevelHigh = bf_get(lpfc_mbx_rd_rev_ftr_lvl_high, | ||
| 4353 | &mqe->un.read_rev); | ||
| 4354 | phba->vpd.rev.feaLevelLow = bf_get(lpfc_mbx_rd_rev_ftr_lvl_low, | ||
| 4355 | &mqe->un.read_rev); | ||
| 4356 | phba->vpd.rev.sli1FwRev = mqe->un.read_rev.fw_id_rev; | ||
| 4357 | memcpy(phba->vpd.rev.sli1FwName, mqe->un.read_rev.fw_name, 16); | ||
| 4358 | phba->vpd.rev.sli2FwRev = mqe->un.read_rev.ulp_fw_id_rev; | ||
| 4359 | memcpy(phba->vpd.rev.sli2FwName, mqe->un.read_rev.ulp_fw_name, 16); | ||
| 4360 | phba->vpd.rev.opFwRev = mqe->un.read_rev.fw_id_rev; | ||
| 4361 | memcpy(phba->vpd.rev.opFwName, mqe->un.read_rev.fw_name, 16); | ||
| 4362 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, | ||
| 4363 | "(%d):0380 READ_REV Status x%x " | ||
| 4364 | "fw_rev:%s fcphHi:%x fcphLo:%x flHi:%x flLo:%x\n", | ||
| 4365 | mboxq->vport ? mboxq->vport->vpi : 0, | ||
| 4366 | bf_get(lpfc_mqe_status, mqe), | ||
| 4367 | phba->vpd.rev.opFwName, | ||
| 4368 | phba->vpd.rev.fcphHigh, phba->vpd.rev.fcphLow, | ||
| 4369 | phba->vpd.rev.feaLevelHigh, phba->vpd.rev.feaLevelLow); | ||
| 4370 | 4370 | ||
| 4371 | /* | 4371 | /* |
| 4372 | * Discover the port's supported feature set and match it against the | 4372 | * Discover the port's supported feature set and match it against the |
| @@ -5030,6 +5030,92 @@ out_not_finished: | |||
| 5030 | } | 5030 | } |
| 5031 | 5031 | ||
| 5032 | /** | 5032 | /** |
| 5033 | * lpfc_sli4_async_mbox_block - Block posting SLI4 asynchronous mailbox command | ||
| 5034 | * @phba: Pointer to HBA context object. | ||
| 5035 | * | ||
| 5036 | * The function blocks the posting of SLI4 asynchronous mailbox commands from | ||
| 5037 | * the driver internal pending mailbox queue. It will then try to wait out the | ||
| 5038 | * possible outstanding mailbox command before return. | ||
| 5039 | * | ||
| 5040 | * Returns: | ||
| 5041 | * 0 - the outstanding mailbox command completed; otherwise, the wait for | ||
| 5042 | * the outstanding mailbox command timed out. | ||
| 5043 | **/ | ||
| 5044 | static int | ||
| 5045 | lpfc_sli4_async_mbox_block(struct lpfc_hba *phba) | ||
| 5046 | { | ||
| 5047 | struct lpfc_sli *psli = &phba->sli; | ||
| 5048 | uint8_t actcmd = MBX_HEARTBEAT; | ||
| 5049 | int rc = 0; | ||
| 5050 | unsigned long timeout; | ||
| 5051 | |||
| 5052 | /* Mark the asynchronous mailbox command posting as blocked */ | ||
| 5053 | spin_lock_irq(&phba->hbalock); | ||
| 5054 | psli->sli_flag |= LPFC_SLI_ASYNC_MBX_BLK; | ||
| 5055 | if (phba->sli.mbox_active) | ||
| 5056 | actcmd = phba->sli.mbox_active->u.mb.mbxCommand; | ||
| 5057 | spin_unlock_irq(&phba->hbalock); | ||
| 5058 | /* Determine how long we might wait for the active mailbox | ||
| 5059 | * command to be gracefully completed by firmware. | ||
| 5060 | */ | ||
| 5061 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, actcmd) * 1000) + | ||
| 5062 | jiffies; | ||
| 5063 | /* Wait for the outstnading mailbox command to complete */ | ||
| 5064 | while (phba->sli.mbox_active) { | ||
| 5065 | /* Check active mailbox complete status every 2ms */ | ||
| 5066 | msleep(2); | ||
| 5067 | if (time_after(jiffies, timeout)) { | ||
| 5068 | /* Timeout, marked the outstanding cmd not complete */ | ||
| 5069 | rc = 1; | ||
| 5070 | break; | ||
| 5071 | } | ||
| 5072 | } | ||
| 5073 | |||
| 5074 | /* Can not cleanly block async mailbox command, fails it */ | ||
| 5075 | if (rc) { | ||
| 5076 | spin_lock_irq(&phba->hbalock); | ||
| 5077 | psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; | ||
| 5078 | spin_unlock_irq(&phba->hbalock); | ||
| 5079 | } | ||
| 5080 | return rc; | ||
| 5081 | } | ||
| 5082 | |||
| 5083 | /** | ||
| 5084 | * lpfc_sli4_async_mbox_unblock - Block posting SLI4 async mailbox command | ||
| 5085 | * @phba: Pointer to HBA context object. | ||
| 5086 | * | ||
| 5087 | * The function unblocks and resume posting of SLI4 asynchronous mailbox | ||
| 5088 | * commands from the driver internal pending mailbox queue. It makes sure | ||
| 5089 | * that there is no outstanding mailbox command before resuming posting | ||
| 5090 | * asynchronous mailbox commands. If, for any reason, there is outstanding | ||
| 5091 | * mailbox command, it will try to wait it out before resuming asynchronous | ||
| 5092 | * mailbox command posting. | ||
| 5093 | **/ | ||
| 5094 | static void | ||
| 5095 | lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba) | ||
| 5096 | { | ||
| 5097 | struct lpfc_sli *psli = &phba->sli; | ||
| 5098 | |||
| 5099 | spin_lock_irq(&phba->hbalock); | ||
| 5100 | if (!(psli->sli_flag & LPFC_SLI_ASYNC_MBX_BLK)) { | ||
| 5101 | /* Asynchronous mailbox posting is not blocked, do nothing */ | ||
| 5102 | spin_unlock_irq(&phba->hbalock); | ||
| 5103 | return; | ||
| 5104 | } | ||
| 5105 | |||
| 5106 | /* Outstanding synchronous mailbox command is guaranteed to be done, | ||
| 5107 | * successful or timeout, after timing-out the outstanding mailbox | ||
| 5108 | * command shall always be removed, so just unblock posting async | ||
| 5109 | * mailbox command and resume | ||
| 5110 | */ | ||
| 5111 | psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; | ||
| 5112 | spin_unlock_irq(&phba->hbalock); | ||
| 5113 | |||
| 5114 | /* wake up worker thread to post asynchronlous mailbox command */ | ||
| 5115 | lpfc_worker_wake_up(phba); | ||
| 5116 | } | ||
| 5117 | |||
| 5118 | /** | ||
| 5033 | * lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox | 5119 | * lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox |
| 5034 | * @phba: Pointer to HBA context object. | 5120 | * @phba: Pointer to HBA context object. |
| 5035 | * @mboxq: Pointer to mailbox object. | 5121 | * @mboxq: Pointer to mailbox object. |
| @@ -5204,14 +5290,35 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
| 5204 | psli->sli_flag, flag); | 5290 | psli->sli_flag, flag); |
| 5205 | return rc; | 5291 | return rc; |
| 5206 | } else if (flag == MBX_POLL) { | 5292 | } else if (flag == MBX_POLL) { |
| 5207 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 5293 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, |
| 5208 | "(%d):2542 Mailbox command x%x (x%x) " | 5294 | "(%d):2542 Try to issue mailbox command " |
| 5209 | "cannot issue Data: x%x x%x\n", | 5295 | "x%x (x%x) synchronously ahead of async" |
| 5296 | "mailbox command queue: x%x x%x\n", | ||
| 5210 | mboxq->vport ? mboxq->vport->vpi : 0, | 5297 | mboxq->vport ? mboxq->vport->vpi : 0, |
| 5211 | mboxq->u.mb.mbxCommand, | 5298 | mboxq->u.mb.mbxCommand, |
| 5212 | lpfc_sli4_mbox_opcode_get(phba, mboxq), | 5299 | lpfc_sli4_mbox_opcode_get(phba, mboxq), |
| 5213 | psli->sli_flag, flag); | 5300 | psli->sli_flag, flag); |
| 5214 | return -EIO; | 5301 | /* Try to block the asynchronous mailbox posting */ |
| 5302 | rc = lpfc_sli4_async_mbox_block(phba); | ||
| 5303 | if (!rc) { | ||
| 5304 | /* Successfully blocked, now issue sync mbox cmd */ | ||
| 5305 | rc = lpfc_sli4_post_sync_mbox(phba, mboxq); | ||
| 5306 | if (rc != MBX_SUCCESS) | ||
| 5307 | lpfc_printf_log(phba, KERN_ERR, | ||
| 5308 | LOG_MBOX | LOG_SLI, | ||
| 5309 | "(%d):2597 Mailbox command " | ||
| 5310 | "x%x (x%x) cannot issue " | ||
| 5311 | "Data: x%x x%x\n", | ||
| 5312 | mboxq->vport ? | ||
| 5313 | mboxq->vport->vpi : 0, | ||
| 5314 | mboxq->u.mb.mbxCommand, | ||
| 5315 | lpfc_sli4_mbox_opcode_get(phba, | ||
| 5316 | mboxq), | ||
| 5317 | psli->sli_flag, flag); | ||
| 5318 | /* Unblock the async mailbox posting afterward */ | ||
| 5319 | lpfc_sli4_async_mbox_unblock(phba); | ||
| 5320 | } | ||
| 5321 | return rc; | ||
| 5215 | } | 5322 | } |
| 5216 | 5323 | ||
| 5217 | /* Now, interrupt mode asynchrous mailbox command */ | 5324 | /* Now, interrupt mode asynchrous mailbox command */ |
| @@ -5814,11 +5921,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 5814 | bf_set(lpfc_wqe_gen_context, &wqe->generic, | 5921 | bf_set(lpfc_wqe_gen_context, &wqe->generic, |
| 5815 | iocbq->iocb.ulpContext); | 5922 | iocbq->iocb.ulpContext); |
| 5816 | 5923 | ||
| 5817 | if (iocbq->vport->fc_myDID != 0) { | ||
| 5818 | bf_set(els_req64_sid, &wqe->els_req, | ||
| 5819 | iocbq->vport->fc_myDID); | ||
| 5820 | bf_set(els_req64_sp, &wqe->els_req, 1); | ||
| 5821 | } | ||
| 5822 | bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct); | 5924 | bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct); |
| 5823 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); | 5925 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); |
| 5824 | /* CCP CCPE PV PRI in word10 were set in the memcpy */ | 5926 | /* CCP CCPE PV PRI in word10 were set in the memcpy */ |
| @@ -5877,14 +5979,19 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 5877 | * is set and we are sending our 2nd or greater command on | 5979 | * is set and we are sending our 2nd or greater command on |
| 5878 | * this exchange. | 5980 | * this exchange. |
| 5879 | */ | 5981 | */ |
| 5982 | /* Always open the exchange */ | ||
| 5983 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); | ||
| 5880 | 5984 | ||
| 5881 | /* ALLOW read & write to fall through to ICMD64 */ | 5985 | wqe->words[10] &= 0xffff0000; /* zero out ebde count */ |
| 5986 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU); | ||
| 5987 | break; | ||
| 5882 | case CMD_FCP_ICMND64_CR: | 5988 | case CMD_FCP_ICMND64_CR: |
| 5883 | /* Always open the exchange */ | 5989 | /* Always open the exchange */ |
| 5884 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); | 5990 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); |
| 5885 | 5991 | ||
| 5992 | wqe->words[4] = 0; | ||
| 5886 | wqe->words[10] &= 0xffff0000; /* zero out ebde count */ | 5993 | wqe->words[10] &= 0xffff0000; /* zero out ebde count */ |
| 5887 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU); | 5994 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); |
| 5888 | break; | 5995 | break; |
| 5889 | case CMD_GEN_REQUEST64_CR: | 5996 | case CMD_GEN_REQUEST64_CR: |
| 5890 | /* word3 command length is described as byte offset to the | 5997 | /* word3 command length is described as byte offset to the |
| @@ -11020,10 +11127,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) | |||
| 11020 | rpi_page->start_rpi); | 11127 | rpi_page->start_rpi); |
| 11021 | hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys); | 11128 | hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys); |
| 11022 | hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys); | 11129 | hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys); |
| 11023 | if (!phba->sli4_hba.intr_enable) | 11130 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); |
| 11024 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
| 11025 | else | ||
| 11026 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | ||
| 11027 | shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; | 11131 | shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; |
| 11028 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 11132 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
| 11029 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | 11133 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 5196b46608d7..3b276b47d18f 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
| @@ -229,7 +229,7 @@ struct lpfc_bmbx { | |||
| 229 | 229 | ||
| 230 | #define LPFC_EQE_DEF_COUNT 1024 | 230 | #define LPFC_EQE_DEF_COUNT 1024 |
| 231 | #define LPFC_CQE_DEF_COUNT 256 | 231 | #define LPFC_CQE_DEF_COUNT 256 |
| 232 | #define LPFC_WQE_DEF_COUNT 64 | 232 | #define LPFC_WQE_DEF_COUNT 256 |
| 233 | #define LPFC_MQE_DEF_COUNT 16 | 233 | #define LPFC_MQE_DEF_COUNT 16 |
| 234 | #define LPFC_RQE_DEF_COUNT 512 | 234 | #define LPFC_RQE_DEF_COUNT 512 |
| 235 | 235 | ||
