mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 23:51:37 +00:00
[SCSI] lpfc 8.3.25: Enhancements to Debug infrastructure
Enhancements to Debug infrastructure - debugfs additions for new hardware. - Correct stack overflow in lpfc_debugfs_dumpHBASlim_data() - Correct warning on uninitialized reg_val in lpfc_idiag_drbacc_write() - Separated the iDiag command for capturing mailbox commands for generic issue mailbox command entry point and for BSG multi-buffer handling. - Added capturing dumping capabiliy of mailbox command and external buffer for the completion of the mailbox command so that the outcome can be examined. - Changed all the iDiag command structure data array indexing introduced so far with properly defined macros. - Added SLI4 device PCI BAR memory mapped register read/browse, write-by- value, set-bit, and clear-bit methods for both interface type 0 and interface type 2. - Corrected warnings on mbxstatus being uninitialized in error paths in lpfc_bsg.c Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
0a96e9754d
commit
b76f2dc91c
@ -851,9 +851,13 @@ struct lpfc_hba {
|
||||
/* iDiag debugfs sub-directory */
|
||||
struct dentry *idiag_root;
|
||||
struct dentry *idiag_pci_cfg;
|
||||
struct dentry *idiag_bar_acc;
|
||||
struct dentry *idiag_que_info;
|
||||
struct dentry *idiag_que_acc;
|
||||
struct dentry *idiag_drb_acc;
|
||||
struct dentry *idiag_ctl_acc;
|
||||
struct dentry *idiag_mbx_acc;
|
||||
struct dentry *idiag_ext_acc;
|
||||
#endif
|
||||
|
||||
/* Used for deferred freeing of ELS data buffers */
|
||||
|
@ -810,6 +810,7 @@ static ssize_t
|
||||
lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
|
||||
{
|
||||
struct completion online_compl;
|
||||
struct pci_dev *pdev = phba->pcidev;
|
||||
uint32_t reg_val;
|
||||
int status = 0;
|
||||
int rc;
|
||||
@ -822,6 +823,14 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
|
||||
LPFC_SLI_INTF_IF_TYPE_2))
|
||||
return -EPERM;
|
||||
|
||||
if (!pdev->is_physfn)
|
||||
return -EPERM;
|
||||
|
||||
/* Disable SR-IOV virtual functions if enabled */
|
||||
if (phba->cfg_sriov_nr_virtfn) {
|
||||
pci_disable_sriov(pdev);
|
||||
phba->cfg_sriov_nr_virtfn = 0;
|
||||
}
|
||||
status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
|
||||
|
||||
if (status != 0)
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "lpfc.h"
|
||||
#include "lpfc_logmsg.h"
|
||||
#include "lpfc_crtn.h"
|
||||
#include "lpfc_debugfs.h"
|
||||
#include "lpfc_vport.h"
|
||||
#include "lpfc_version.h"
|
||||
|
||||
@ -1566,7 +1567,7 @@ lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
|
||||
uint32_t link_flags;
|
||||
uint32_t timeout;
|
||||
LPFC_MBOXQ_t *pmboxq;
|
||||
int mbxstatus;
|
||||
int mbxstatus = MBX_SUCCESS;
|
||||
int i = 0;
|
||||
int rc = 0;
|
||||
|
||||
@ -1740,7 +1741,7 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
|
||||
uint32_t link_flags, timeout, req_len, alloc_len;
|
||||
struct lpfc_mbx_set_link_diag_loopback *link_diag_loopback;
|
||||
LPFC_MBOXQ_t *pmboxq = NULL;
|
||||
int mbxstatus, i, rc = 0;
|
||||
int mbxstatus = MBX_SUCCESS, i, rc = 0;
|
||||
|
||||
/* no data to return just the return code */
|
||||
job->reply->reply_payload_rcv_len = 0;
|
||||
@ -3177,6 +3178,11 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
|
||||
"(x%x/x%x) complete bsg job done, bsize:%d\n",
|
||||
phba->mbox_ext_buf_ctx.nembType,
|
||||
phba->mbox_ext_buf_ctx.mboxType, size);
|
||||
lpfc_idiag_mbxacc_dump_bsg_mbox(phba,
|
||||
phba->mbox_ext_buf_ctx.nembType,
|
||||
phba->mbox_ext_buf_ctx.mboxType,
|
||||
dma_ebuf, sta_pos_addr,
|
||||
phba->mbox_ext_buf_ctx.mbx_dmabuf, 0);
|
||||
} else
|
||||
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
|
||||
|
||||
@ -3429,6 +3435,10 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
|
||||
"ext_buf_cnt:%d\n", ext_buf_cnt);
|
||||
}
|
||||
|
||||
/* before dma descriptor setup */
|
||||
lpfc_idiag_mbxacc_dump_bsg_mbox(phba, nemb_tp, mbox_rd, dma_mbox,
|
||||
sta_pre_addr, dmabuf, ext_buf_cnt);
|
||||
|
||||
/* reject non-embedded mailbox command with none external buffer */
|
||||
if (ext_buf_cnt == 0) {
|
||||
rc = -EPERM;
|
||||
@ -3476,6 +3486,10 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
|
||||
}
|
||||
}
|
||||
|
||||
/* after dma descriptor setup */
|
||||
lpfc_idiag_mbxacc_dump_bsg_mbox(phba, nemb_tp, mbox_rd, dma_mbox,
|
||||
sta_pos_addr, dmabuf, ext_buf_cnt);
|
||||
|
||||
/* construct base driver mbox command */
|
||||
pmb = &pmboxq->u.mb;
|
||||
pmbx = (uint8_t *)dmabuf->virt;
|
||||
@ -3590,12 +3604,20 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
|
||||
"ext_buf_cnt:%d\n", ext_buf_cnt);
|
||||
}
|
||||
|
||||
/* before dma buffer descriptor setup */
|
||||
lpfc_idiag_mbxacc_dump_bsg_mbox(phba, nemb_tp, mbox_wr, dma_mbox,
|
||||
sta_pre_addr, dmabuf, ext_buf_cnt);
|
||||
|
||||
if (ext_buf_cnt == 0)
|
||||
return -EPERM;
|
||||
|
||||
/* for the first external buffer */
|
||||
lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, 0, dmabuf, dmabuf);
|
||||
|
||||
/* after dma descriptor setup */
|
||||
lpfc_idiag_mbxacc_dump_bsg_mbox(phba, nemb_tp, mbox_wr, dma_mbox,
|
||||
sta_pos_addr, dmabuf, ext_buf_cnt);
|
||||
|
||||
/* log for looking forward */
|
||||
for (i = 1; i < ext_buf_cnt; i++) {
|
||||
if (nemb_tp == nemb_mse)
|
||||
@ -3844,6 +3866,12 @@ lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
|
||||
dmabuf = list_first_entry(&phba->mbox_ext_buf_ctx.ext_dmabuf_list,
|
||||
struct lpfc_dmabuf, list);
|
||||
list_del_init(&dmabuf->list);
|
||||
|
||||
/* after dma buffer descriptor setup */
|
||||
lpfc_idiag_mbxacc_dump_bsg_mbox(phba, phba->mbox_ext_buf_ctx.nembType,
|
||||
mbox_rd, dma_ebuf, sta_pos_addr,
|
||||
dmabuf, index);
|
||||
|
||||
pbuf = (uint8_t *)dmabuf->virt;
|
||||
job->reply->reply_payload_rcv_len =
|
||||
sg_copy_from_buffer(job->reply_payload.sg_list,
|
||||
@ -3926,6 +3954,11 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
|
||||
dmabuf);
|
||||
list_add_tail(&dmabuf->list, &phba->mbox_ext_buf_ctx.ext_dmabuf_list);
|
||||
|
||||
/* after write dma buffer */
|
||||
lpfc_idiag_mbxacc_dump_bsg_mbox(phba, phba->mbox_ext_buf_ctx.nembType,
|
||||
mbox_wr, dma_ebuf, sta_pos_addr,
|
||||
dmabuf, index);
|
||||
|
||||
if (phba->mbox_ext_buf_ctx.seqNum == phba->mbox_ext_buf_ctx.numBuf) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
|
||||
"2968 SLI_CONFIG ext-buffer wr all %d "
|
||||
|
@ -371,6 +371,10 @@ extern struct lpfc_hbq_init *lpfc_hbq_defs[];
|
||||
/* SLI4 if_type 2 externs. */
|
||||
int lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *);
|
||||
int lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *);
|
||||
int lpfc_sli4_get_allocated_extnts(struct lpfc_hba *, uint16_t,
|
||||
uint16_t *, uint16_t *);
|
||||
int lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *, uint16_t,
|
||||
uint16_t *, uint16_t *);
|
||||
|
||||
/* externs BlockGuard */
|
||||
extern char *_dump_buf_data;
|
||||
@ -437,6 +441,10 @@ void lpfc_cleanup_wt_rrqs(struct lpfc_hba *);
|
||||
void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *);
|
||||
struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t,
|
||||
uint32_t);
|
||||
void lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *, enum nemb_type,
|
||||
enum mbox_type, enum dma_type, enum sta_type,
|
||||
struct lpfc_dmabuf *, uint32_t);
|
||||
void lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *, MAILBOX_t *);
|
||||
int lpfc_wr_object(struct lpfc_hba *, struct list_head *, uint32_t, uint32_t *);
|
||||
/* functions to support SR-IOV */
|
||||
int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,14 +39,51 @@
|
||||
/* hbqinfo output buffer size */
|
||||
#define LPFC_HBQINFO_SIZE 8192
|
||||
|
||||
/*
|
||||
* For SLI4 iDiag debugfs diagnostics tool
|
||||
*/
|
||||
|
||||
/* pciConf */
|
||||
#define LPFC_PCI_CFG_BROWSE 0xffff
|
||||
#define LPFC_PCI_CFG_RD_CMD_ARG 2
|
||||
#define LPFC_PCI_CFG_WR_CMD_ARG 3
|
||||
#define LPFC_PCI_CFG_SIZE 4096
|
||||
#define LPFC_PCI_CFG_RD_BUF_SIZE (LPFC_PCI_CFG_SIZE/2)
|
||||
#define LPFC_PCI_CFG_RD_SIZE (LPFC_PCI_CFG_SIZE/4)
|
||||
|
||||
#define IDIAG_PCICFG_WHERE_INDX 0
|
||||
#define IDIAG_PCICFG_COUNT_INDX 1
|
||||
#define IDIAG_PCICFG_VALUE_INDX 2
|
||||
|
||||
/* barAcc */
|
||||
#define LPFC_PCI_BAR_BROWSE 0xffff
|
||||
#define LPFC_PCI_BAR_RD_CMD_ARG 3
|
||||
#define LPFC_PCI_BAR_WR_CMD_ARG 3
|
||||
|
||||
#define LPFC_PCI_IF0_BAR0_SIZE (1024 * 16)
|
||||
#define LPFC_PCI_IF0_BAR1_SIZE (1024 * 128)
|
||||
#define LPFC_PCI_IF0_BAR2_SIZE (1024 * 128)
|
||||
#define LPFC_PCI_IF2_BAR0_SIZE (1024 * 32)
|
||||
|
||||
#define LPFC_PCI_BAR_RD_BUF_SIZE 4096
|
||||
#define LPFC_PCI_BAR_RD_SIZE (LPFC_PCI_BAR_RD_BUF_SIZE/4)
|
||||
|
||||
#define LPFC_PCI_IF0_BAR0_RD_SIZE (LPFC_PCI_IF0_BAR0_SIZE/4)
|
||||
#define LPFC_PCI_IF0_BAR1_RD_SIZE (LPFC_PCI_IF0_BAR1_SIZE/4)
|
||||
#define LPFC_PCI_IF0_BAR2_RD_SIZE (LPFC_PCI_IF0_BAR2_SIZE/4)
|
||||
#define LPFC_PCI_IF2_BAR0_RD_SIZE (LPFC_PCI_IF2_BAR0_SIZE/4)
|
||||
|
||||
#define IDIAG_BARACC_BAR_NUM_INDX 0
|
||||
#define IDIAG_BARACC_OFF_SET_INDX 1
|
||||
#define IDIAG_BARACC_ACC_MOD_INDX 2
|
||||
#define IDIAG_BARACC_REG_VAL_INDX 2
|
||||
#define IDIAG_BARACC_BAR_SZE_INDX 3
|
||||
|
||||
#define IDIAG_BARACC_BAR_0 0
|
||||
#define IDIAG_BARACC_BAR_1 1
|
||||
#define IDIAG_BARACC_BAR_2 2
|
||||
|
||||
#define SINGLE_WORD 1
|
||||
|
||||
/* queue info */
|
||||
#define LPFC_QUE_INFO_GET_BUF_SIZE 4096
|
||||
|
||||
@ -63,7 +100,14 @@
|
||||
#define LPFC_IDIAG_WQ 4
|
||||
#define LPFC_IDIAG_RQ 5
|
||||
|
||||
/* doorbell acc */
|
||||
#define IDIAG_QUEACC_QUETP_INDX 0
|
||||
#define IDIAG_QUEACC_QUEID_INDX 1
|
||||
#define IDIAG_QUEACC_INDEX_INDX 2
|
||||
#define IDIAG_QUEACC_COUNT_INDX 3
|
||||
#define IDIAG_QUEACC_OFFST_INDX 4
|
||||
#define IDIAG_QUEACC_VALUE_INDX 5
|
||||
|
||||
/* doorbell register acc */
|
||||
#define LPFC_DRB_ACC_ALL 0xffff
|
||||
#define LPFC_DRB_ACC_RD_CMD_ARG 1
|
||||
#define LPFC_DRB_ACC_WR_CMD_ARG 2
|
||||
@ -76,6 +120,67 @@
|
||||
|
||||
#define LPFC_DRB_MAX 4
|
||||
|
||||
#define IDIAG_DRBACC_REGID_INDX 0
|
||||
#define IDIAG_DRBACC_VALUE_INDX 1
|
||||
|
||||
/* control register acc */
|
||||
#define LPFC_CTL_ACC_ALL 0xffff
|
||||
#define LPFC_CTL_ACC_RD_CMD_ARG 1
|
||||
#define LPFC_CTL_ACC_WR_CMD_ARG 2
|
||||
#define LPFC_CTL_ACC_BUF_SIZE 256
|
||||
|
||||
#define LPFC_CTL_PORT_SEM 1
|
||||
#define LPFC_CTL_PORT_STA 2
|
||||
#define LPFC_CTL_PORT_CTL 3
|
||||
#define LPFC_CTL_PORT_ER1 4
|
||||
#define LPFC_CTL_PORT_ER2 5
|
||||
#define LPFC_CTL_PDEV_CTL 6
|
||||
|
||||
#define LPFC_CTL_MAX 6
|
||||
|
||||
#define IDIAG_CTLACC_REGID_INDX 0
|
||||
#define IDIAG_CTLACC_VALUE_INDX 1
|
||||
|
||||
/* mailbox access */
|
||||
#define LPFC_MBX_DMP_ARG 4
|
||||
|
||||
#define LPFC_MBX_ACC_BUF_SIZE 512
|
||||
#define LPFC_MBX_ACC_LBUF_SZ 128
|
||||
|
||||
#define LPFC_MBX_DMP_MBX_WORD 0x00000001
|
||||
#define LPFC_MBX_DMP_MBX_BYTE 0x00000002
|
||||
#define LPFC_MBX_DMP_MBX_ALL (LPFC_MBX_DMP_MBX_WORD | LPFC_MBX_DMP_MBX_BYTE)
|
||||
|
||||
#define LPFC_BSG_DMP_MBX_RD_MBX 0x00000001
|
||||
#define LPFC_BSG_DMP_MBX_RD_BUF 0x00000002
|
||||
#define LPFC_BSG_DMP_MBX_WR_MBX 0x00000004
|
||||
#define LPFC_BSG_DMP_MBX_WR_BUF 0x00000008
|
||||
#define LPFC_BSG_DMP_MBX_ALL (LPFC_BSG_DMP_MBX_RD_MBX | \
|
||||
LPFC_BSG_DMP_MBX_RD_BUF | \
|
||||
LPFC_BSG_DMP_MBX_WR_MBX | \
|
||||
LPFC_BSG_DMP_MBX_WR_BUF)
|
||||
|
||||
#define LPFC_MBX_DMP_ALL 0xffff
|
||||
#define LPFC_MBX_ALL_CMD 0xff
|
||||
|
||||
#define IDIAG_MBXACC_MBCMD_INDX 0
|
||||
#define IDIAG_MBXACC_DPMAP_INDX 1
|
||||
#define IDIAG_MBXACC_DPCNT_INDX 2
|
||||
#define IDIAG_MBXACC_WDCNT_INDX 3
|
||||
|
||||
/* extents access */
|
||||
#define LPFC_EXT_ACC_CMD_ARG 1
|
||||
#define LPFC_EXT_ACC_BUF_SIZE 4096
|
||||
|
||||
#define LPFC_EXT_ACC_AVAIL 0x1
|
||||
#define LPFC_EXT_ACC_ALLOC 0x2
|
||||
#define LPFC_EXT_ACC_DRIVR 0x4
|
||||
#define LPFC_EXT_ACC_ALL (LPFC_EXT_ACC_DRIVR | \
|
||||
LPFC_EXT_ACC_AVAIL | \
|
||||
LPFC_EXT_ACC_ALLOC)
|
||||
|
||||
#define IDIAG_EXTACC_EXMAP_INDX 0
|
||||
|
||||
#define SIZE_U8 sizeof(uint8_t)
|
||||
#define SIZE_U16 sizeof(uint16_t)
|
||||
#define SIZE_U32 sizeof(uint32_t)
|
||||
@ -110,6 +215,11 @@ struct lpfc_idiag_cmd {
|
||||
#define LPFC_IDIAG_CMD_PCICFG_ST 0x00000003
|
||||
#define LPFC_IDIAG_CMD_PCICFG_CL 0x00000004
|
||||
|
||||
#define LPFC_IDIAG_CMD_BARACC_RD 0x00000008
|
||||
#define LPFC_IDIAG_CMD_BARACC_WR 0x00000009
|
||||
#define LPFC_IDIAG_CMD_BARACC_ST 0x0000000a
|
||||
#define LPFC_IDIAG_CMD_BARACC_CL 0x0000000b
|
||||
|
||||
#define LPFC_IDIAG_CMD_QUEACC_RD 0x00000011
|
||||
#define LPFC_IDIAG_CMD_QUEACC_WR 0x00000012
|
||||
#define LPFC_IDIAG_CMD_QUEACC_ST 0x00000013
|
||||
@ -119,6 +229,17 @@ struct lpfc_idiag_cmd {
|
||||
#define LPFC_IDIAG_CMD_DRBACC_WR 0x00000022
|
||||
#define LPFC_IDIAG_CMD_DRBACC_ST 0x00000023
|
||||
#define LPFC_IDIAG_CMD_DRBACC_CL 0x00000024
|
||||
|
||||
#define LPFC_IDIAG_CMD_CTLACC_RD 0x00000031
|
||||
#define LPFC_IDIAG_CMD_CTLACC_WR 0x00000032
|
||||
#define LPFC_IDIAG_CMD_CTLACC_ST 0x00000033
|
||||
#define LPFC_IDIAG_CMD_CTLACC_CL 0x00000034
|
||||
|
||||
#define LPFC_IDIAG_CMD_MBXACC_DP 0x00000041
|
||||
#define LPFC_IDIAG_BSG_MBXACC_DP 0x00000042
|
||||
|
||||
#define LPFC_IDIAG_CMD_EXTACC_RD 0x00000051
|
||||
|
||||
uint32_t data[LPFC_IDIAG_CMD_DATA_SIZE];
|
||||
};
|
||||
|
||||
|
@ -9153,7 +9153,6 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||
|
||||
/* Check if there are static vports to be created. */
|
||||
lpfc_create_static_vport(phba);
|
||||
|
||||
return 0;
|
||||
|
||||
out_disable_intr:
|
||||
|
@ -4714,10 +4714,15 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
|
||||
* lpfc_sli4_get_avail_extnt_rsrc - Get available resource extent count.
|
||||
* @phba: Pointer to HBA context object.
|
||||
* @type: The resource extent type.
|
||||
* @extnt_count: buffer to hold port available extent count.
|
||||
* @extnt_size: buffer to hold element count per extent.
|
||||
*
|
||||
* This function allocates all SLI4 resource identifiers.
|
||||
* This function calls the port and retrievs the number of available
|
||||
* extents and their size for a particular extent type.
|
||||
*
|
||||
* Returns: 0 if successful. Nonzero otherwise.
|
||||
**/
|
||||
static int
|
||||
int
|
||||
lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type,
|
||||
uint16_t *extnt_count, uint16_t *extnt_size)
|
||||
{
|
||||
@ -4894,7 +4899,7 @@ lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t *extnt_cnt,
|
||||
req_len, *emb);
|
||||
if (alloc_len < req_len) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"9000 Allocated DMA memory size (x%x) is "
|
||||
"2982 Allocated DMA memory size (x%x) is "
|
||||
"less than the requested DMA memory "
|
||||
"size (x%x)\n", alloc_len, req_len);
|
||||
return -ENOMEM;
|
||||
@ -5507,6 +5512,154 @@ lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *phba)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_get_allocated_extnts - Get the port's allocated extents.
|
||||
* @phba: Pointer to HBA context object.
|
||||
* @type: The resource extent type.
|
||||
* @extnt_count: buffer to hold port extent count response
|
||||
* @extnt_size: buffer to hold port extent size response.
|
||||
*
|
||||
* This function calls the port to read the host allocated extents
|
||||
* for a particular type.
|
||||
**/
|
||||
int
|
||||
lpfc_sli4_get_allocated_extnts(struct lpfc_hba *phba, uint16_t type,
|
||||
uint16_t *extnt_cnt, uint16_t *extnt_size)
|
||||
{
|
||||
bool emb;
|
||||
int rc = 0;
|
||||
uint16_t curr_blks = 0;
|
||||
uint32_t req_len, emb_len;
|
||||
uint32_t alloc_len, mbox_tmo;
|
||||
struct list_head *blk_list_head;
|
||||
struct lpfc_rsrc_blks *rsrc_blk;
|
||||
LPFC_MBOXQ_t *mbox;
|
||||
void *virtaddr = NULL;
|
||||
struct lpfc_mbx_nembed_rsrc_extent *n_rsrc;
|
||||
struct lpfc_mbx_alloc_rsrc_extents *rsrc_ext;
|
||||
union lpfc_sli4_cfg_shdr *shdr;
|
||||
|
||||
switch (type) {
|
||||
case LPFC_RSC_TYPE_FCOE_VPI:
|
||||
blk_list_head = &phba->lpfc_vpi_blk_list;
|
||||
break;
|
||||
case LPFC_RSC_TYPE_FCOE_XRI:
|
||||
blk_list_head = &phba->sli4_hba.lpfc_xri_blk_list;
|
||||
break;
|
||||
case LPFC_RSC_TYPE_FCOE_VFI:
|
||||
blk_list_head = &phba->sli4_hba.lpfc_vfi_blk_list;
|
||||
break;
|
||||
case LPFC_RSC_TYPE_FCOE_RPI:
|
||||
blk_list_head = &phba->sli4_hba.lpfc_rpi_blk_list;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Count the number of extents currently allocatd for this type. */
|
||||
list_for_each_entry(rsrc_blk, blk_list_head, list) {
|
||||
if (curr_blks == 0) {
|
||||
/*
|
||||
* The GET_ALLOCATED mailbox does not return the size,
|
||||
* just the count. The size should be just the size
|
||||
* stored in the current allocated block and all sizes
|
||||
* for an extent type are the same so set the return
|
||||
* value now.
|
||||
*/
|
||||
*extnt_size = rsrc_blk->rsrc_size;
|
||||
}
|
||||
curr_blks++;
|
||||
}
|
||||
|
||||
/* Calculate the total requested length of the dma memory. */
|
||||
req_len = curr_blks * sizeof(uint16_t);
|
||||
|
||||
/*
|
||||
* Calculate the size of an embedded mailbox. The uint32_t
|
||||
* accounts for extents-specific word.
|
||||
*/
|
||||
emb_len = sizeof(MAILBOX_t) - sizeof(struct mbox_header) -
|
||||
sizeof(uint32_t);
|
||||
|
||||
/*
|
||||
* Presume the allocation and response will fit into an embedded
|
||||
* mailbox. If not true, reconfigure to a non-embedded mailbox.
|
||||
*/
|
||||
emb = LPFC_SLI4_MBX_EMBED;
|
||||
req_len = emb_len;
|
||||
if (req_len > emb_len) {
|
||||
req_len = curr_blks * sizeof(uint16_t) +
|
||||
sizeof(union lpfc_sli4_cfg_shdr) +
|
||||
sizeof(uint32_t);
|
||||
emb = LPFC_SLI4_MBX_NEMBED;
|
||||
}
|
||||
|
||||
mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!mbox)
|
||||
return -ENOMEM;
|
||||
memset(mbox, 0, sizeof(LPFC_MBOXQ_t));
|
||||
|
||||
alloc_len = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
|
||||
LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT,
|
||||
req_len, emb);
|
||||
if (alloc_len < req_len) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"2983 Allocated DMA memory size (x%x) is "
|
||||
"less than the requested DMA memory "
|
||||
"size (x%x)\n", alloc_len, req_len);
|
||||
rc = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, curr_blks, type, emb);
|
||||
if (unlikely(rc)) {
|
||||
rc = -EIO;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
if (!phba->sli4_hba.intr_enable)
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
|
||||
else {
|
||||
mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
|
||||
rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
|
||||
}
|
||||
|
||||
if (unlikely(rc)) {
|
||||
rc = -EIO;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out where the response is located. Then get local pointers
|
||||
* to the response data. The port does not guarantee to respond to
|
||||
* all extents counts request so update the local variable with the
|
||||
* allocated count from the port.
|
||||
*/
|
||||
if (emb == LPFC_SLI4_MBX_EMBED) {
|
||||
rsrc_ext = &mbox->u.mqe.un.alloc_rsrc_extents;
|
||||
shdr = &rsrc_ext->header.cfg_shdr;
|
||||
*extnt_cnt = bf_get(lpfc_mbx_rsrc_cnt, &rsrc_ext->u.rsp);
|
||||
} else {
|
||||
virtaddr = mbox->sge_array->addr[0];
|
||||
n_rsrc = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr;
|
||||
shdr = &n_rsrc->cfg_shdr;
|
||||
*extnt_cnt = bf_get(lpfc_mbx_rsrc_cnt, n_rsrc);
|
||||
}
|
||||
|
||||
if (bf_get(lpfc_mbox_hdr_status, &shdr->response)) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT,
|
||||
"2984 Failed to read allocated resources "
|
||||
"for type %d - Status 0x%x Add'l Status 0x%x.\n",
|
||||
type,
|
||||
bf_get(lpfc_mbox_hdr_status, &shdr->response),
|
||||
bf_get(lpfc_mbox_hdr_add_status, &shdr->response));
|
||||
rc = -EIO;
|
||||
goto err_exit;
|
||||
}
|
||||
err_exit:
|
||||
lpfc_sli4_mbox_cmd_free(phba, mbox);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_hba_setup - SLI4 device intialization PCI function
|
||||
* @phba: Pointer to HBA context object.
|
||||
@ -6637,6 +6790,9 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
|
||||
unsigned long iflags;
|
||||
int rc;
|
||||
|
||||
/* dump from issue mailbox command if setup */
|
||||
lpfc_idiag_mbxacc_dump_issue_mbox(phba, &mboxq->u.mb);
|
||||
|
||||
rc = lpfc_mbox_dev_check(phba);
|
||||
if (unlikely(rc)) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
|
||||
|
Loading…
Reference in New Issue
Block a user