Skip to content

Commit

Permalink
[SCSI] lpfc 8.3.21: Critical Errors and Bug Fixes
Browse files Browse the repository at this point in the history
Critical Errors:
- Correctly handle non-zero return lpfc_workq_post_event and return ENOMEM
- Save the irq level when locking the host_lock in lpfc_findnode_did

Bug Fixes:
- Adjust payload_length and request_length for sli4_config mailbox commands.
- Add the freed sgl/XRI to the tail of the list rather than to the head.
- Set the FC_VPORT_NEEDS_INIT_VPI on vport deletes and check it before
  issuing a fdisc on an els retry.
- Only call lpfc_hba_init_link() if phba->cfg_suppress_link_up
  is LPFC_INITIALIZE_LINK.
- Add support for SLI-4 Performance Hints

Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
James Smart authored and James Bottomley committed Feb 18, 2011
1 parent 382be66 commit fedd3b7
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 56 deletions.
2 changes: 2 additions & 0 deletions drivers/scsi/lpfc/lpfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,8 @@ struct lpfc_hba {
#define LPFC_SLI3_CRP_ENABLED 0x08
#define LPFC_SLI3_BG_ENABLED 0x20
#define LPFC_SLI3_DSS_ENABLED 0x40
#define LPFC_SLI4_PERFH_ENABLED 0x80
#define LPFC_SLI4_PHWQ_ENABLED 0x100
uint32_t iocb_cmd_size;
uint32_t iocb_rsp_size;

Expand Down
29 changes: 24 additions & 5 deletions drivers/scsi/lpfc/lpfc_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,14 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
int status = 0;
int cnt = 0;
int i;
int rc;

init_completion(&online_compl);
lpfc_workq_post_event(phba, &status, &online_compl,
rc = lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_OFFLINE_PREP);
if (rc == 0)
return -ENOMEM;

wait_for_completion(&online_compl);

if (status != 0)
Expand All @@ -652,7 +656,10 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
}

init_completion(&online_compl);
lpfc_workq_post_event(phba, &status, &online_compl, type);
rc = lpfc_workq_post_event(phba, &status, &online_compl, type);
if (rc == 0)
return -ENOMEM;

wait_for_completion(&online_compl);

if (status != 0)
Expand Down Expand Up @@ -682,6 +689,7 @@ lpfc_selective_reset(struct lpfc_hba *phba)
{
struct completion online_compl;
int status = 0;
int rc;

if (!phba->cfg_enable_hba_reset)
return -EIO;
Expand All @@ -692,8 +700,11 @@ lpfc_selective_reset(struct lpfc_hba *phba)
return status;

init_completion(&online_compl);
lpfc_workq_post_event(phba, &status, &online_compl,
rc = lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_ONLINE);
if (rc == 0)
return -ENOMEM;

wait_for_completion(&online_compl);

if (status != 0)
Expand Down Expand Up @@ -812,14 +823,17 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
struct lpfc_hba *phba = vport->phba;
struct completion online_compl;
int status=0;
int rc;

if (!phba->cfg_enable_hba_reset)
return -EACCES;
init_completion(&online_compl);

if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
lpfc_workq_post_event(phba, &status, &online_compl,
rc = lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_ONLINE);
if (rc == 0)
return -ENOMEM;
wait_for_completion(&online_compl);
} else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
Expand Down Expand Up @@ -1813,6 +1827,7 @@ lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
int stat1=0, stat2=0;
unsigned int i, j, cnt=count;
u8 wwpn[8];
int rc;

if (!phba->cfg_enable_hba_reset)
return -EACCES;
Expand Down Expand Up @@ -1863,7 +1878,11 @@ lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
"0463 lpfc_soft_wwpn attribute set failed to "
"reinit adapter - %d\n", stat1);
init_completion(&online_compl);
lpfc_workq_post_event(phba, &stat2, &online_compl, LPFC_EVT_ONLINE);
rc = lpfc_workq_post_event(phba, &stat2, &online_compl,
LPFC_EVT_ONLINE);
if (rc == 0)
return -ENOMEM;

wait_for_completion(&online_compl);
if (stat2)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/lpfc/lpfc_crtn.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
void lpfc_supported_pages(struct lpfcMboxq *);
void lpfc_sli4_params(struct lpfcMboxq *);
void lpfc_pc_sli4_params(struct lpfcMboxq *);
int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *);

int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *);
struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
void lpfc_rcv_seq_check_edtov(struct lpfc_vport *);
Expand Down
3 changes: 2 additions & 1 deletion drivers/scsi/lpfc/lpfc_els.c
Original file line number Diff line number Diff line change
Expand Up @@ -2745,7 +2745,8 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
}
break;
case ELS_CMD_FDISC:
lpfc_issue_els_fdisc(vport, ndlp, retry);
if (!(vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI))
lpfc_issue_els_fdisc(vport, ndlp, retry);
break;
}
return;
Expand Down
5 changes: 3 additions & 2 deletions drivers/scsi/lpfc/lpfc_hbadisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4426,10 +4426,11 @@ lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_nodelist *ndlp;
unsigned long iflags;

spin_lock_irq(shost->host_lock);
spin_lock_irqsave(shost->host_lock, iflags);
ndlp = __lpfc_findnode_did(vport, did);
spin_unlock_irq(shost->host_lock);
spin_unlock_irqrestore(shost->host_lock, iflags);
return ndlp;
}

Expand Down
104 changes: 100 additions & 4 deletions drivers/scsi/lpfc/lpfc_hw4.h
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ struct mbox_header {
#define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A
#define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D
#define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A
#define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5

/* FCoE Opcodes */
#define LPFC_MBOX_OPCODE_FCOE_WQ_CREATE 0x01
Expand Down Expand Up @@ -1852,6 +1853,9 @@ struct lpfc_mbx_request_features {
#define lpfc_mbx_rq_ftr_rq_ifip_SHIFT 7
#define lpfc_mbx_rq_ftr_rq_ifip_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rq_ifip_WORD word2
#define lpfc_mbx_rq_ftr_rq_perfh_SHIFT 11
#define lpfc_mbx_rq_ftr_rq_perfh_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rq_perfh_WORD word2
uint32_t word3;
#define lpfc_mbx_rq_ftr_rsp_iaab_SHIFT 0
#define lpfc_mbx_rq_ftr_rsp_iaab_MASK 0x00000001
Expand All @@ -1877,6 +1881,9 @@ struct lpfc_mbx_request_features {
#define lpfc_mbx_rq_ftr_rsp_ifip_SHIFT 7
#define lpfc_mbx_rq_ftr_rsp_ifip_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rsp_ifip_WORD word3
#define lpfc_mbx_rq_ftr_rsp_perfh_SHIFT 11
#define lpfc_mbx_rq_ftr_rsp_perfh_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rsp_perfh_WORD word3
};

struct lpfc_mbx_supp_pages {
Expand Down Expand Up @@ -1935,7 +1942,7 @@ struct lpfc_mbx_supp_pages {
#define LPFC_SLI4_PARAMETERS 2
};

struct lpfc_mbx_sli4_params {
struct lpfc_mbx_pc_sli4_params {
uint32_t word1;
#define qs_SHIFT 0
#define qs_MASK 0x00000001
Expand Down Expand Up @@ -2051,6 +2058,88 @@ struct lpfc_mbx_sli4_params {
uint32_t rsvd_13_63[51];
};

struct lpfc_sli4_parameters {
uint32_t word0;
#define cfg_prot_type_SHIFT 0
#define cfg_prot_type_MASK 0x000000FF
#define cfg_prot_type_WORD word0
uint32_t word1;
#define cfg_ft_SHIFT 0
#define cfg_ft_MASK 0x00000001
#define cfg_ft_WORD word1
#define cfg_sli_rev_SHIFT 4
#define cfg_sli_rev_MASK 0x0000000f
#define cfg_sli_rev_WORD word1
#define cfg_sli_family_SHIFT 8
#define cfg_sli_family_MASK 0x0000000f
#define cfg_sli_family_WORD word1
#define cfg_if_type_SHIFT 12
#define cfg_if_type_MASK 0x0000000f
#define cfg_if_type_WORD word1
#define cfg_sli_hint_1_SHIFT 16
#define cfg_sli_hint_1_MASK 0x000000ff
#define cfg_sli_hint_1_WORD word1
#define cfg_sli_hint_2_SHIFT 24
#define cfg_sli_hint_2_MASK 0x0000001f
#define cfg_sli_hint_2_WORD word1
uint32_t word2;
uint32_t word3;
uint32_t word4;
#define cfg_cqv_SHIFT 14
#define cfg_cqv_MASK 0x00000003
#define cfg_cqv_WORD word4
uint32_t word5;
uint32_t word6;
#define cfg_mqv_SHIFT 14
#define cfg_mqv_MASK 0x00000003
#define cfg_mqv_WORD word6
uint32_t word7;
uint32_t word8;
#define cfg_wqv_SHIFT 14
#define cfg_wqv_MASK 0x00000003
#define cfg_wqv_WORD word8
uint32_t word9;
uint32_t word10;
#define cfg_rqv_SHIFT 14
#define cfg_rqv_MASK 0x00000003
#define cfg_rqv_WORD word10
uint32_t word11;
#define cfg_rq_db_window_SHIFT 28
#define cfg_rq_db_window_MASK 0x0000000f
#define cfg_rq_db_window_WORD word11
uint32_t word12;
#define cfg_fcoe_SHIFT 0
#define cfg_fcoe_MASK 0x00000001
#define cfg_fcoe_WORD word12
#define cfg_phwq_SHIFT 15
#define cfg_phwq_MASK 0x00000001
#define cfg_phwq_WORD word12
#define cfg_loopbk_scope_SHIFT 28
#define cfg_loopbk_scope_MASK 0x0000000f
#define cfg_loopbk_scope_WORD word12
uint32_t sge_supp_len;
uint32_t word14;
#define cfg_sgl_page_cnt_SHIFT 0
#define cfg_sgl_page_cnt_MASK 0x0000000f
#define cfg_sgl_page_cnt_WORD word14
#define cfg_sgl_page_size_SHIFT 8
#define cfg_sgl_page_size_MASK 0x000000ff
#define cfg_sgl_page_size_WORD word14
#define cfg_sgl_pp_align_SHIFT 16
#define cfg_sgl_pp_align_MASK 0x000000ff
#define cfg_sgl_pp_align_WORD word14
uint32_t word15;
uint32_t word16;
uint32_t word17;
uint32_t word18;
uint32_t word19;
};

struct lpfc_mbx_get_sli4_parameters {
struct mbox_header header;
struct lpfc_sli4_parameters sli4_parameters;
};

/* Mailbox Completion Queue Error Messages */
#define MB_CQE_STATUS_SUCCESS 0x0
#define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES 0x1
Expand Down Expand Up @@ -2103,7 +2192,8 @@ struct lpfc_mqe {
struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
struct lpfc_mbx_query_fw_cfg query_fw_cfg;
struct lpfc_mbx_supp_pages supp_pages;
struct lpfc_mbx_sli4_params sli4_params;
struct lpfc_mbx_pc_sli4_params sli4_params;
struct lpfc_mbx_get_sli4_parameters get_sli4_parameters;
struct lpfc_mbx_nop nop;
} un;
};
Expand Down Expand Up @@ -2381,6 +2471,10 @@ struct wqe_common {
#define wqe_wqes_SHIFT 15
#define wqe_wqes_MASK 0x00000001
#define wqe_wqes_WORD word10
/* Note that this field overlaps above fields */
#define wqe_wqid_SHIFT 1
#define wqe_wqid_MASK 0x0000007f
#define wqe_wqid_WORD word10
#define wqe_pri_SHIFT 16
#define wqe_pri_MASK 0x00000007
#define wqe_pri_WORD word10
Expand Down Expand Up @@ -2599,7 +2693,8 @@ struct fcp_iwrite64_wqe {
uint32_t total_xfer_len;
uint32_t initial_xfer_len;
struct wqe_common wqe_com; /* words 6-11 */
uint32_t rsvd_12_15[4]; /* word 12-15 */
uint32_t rsrvd12;
struct ulp_bde64 ph_bde; /* words 13-15 */
};

struct fcp_iread64_wqe {
Expand All @@ -2608,7 +2703,8 @@ struct fcp_iread64_wqe {
uint32_t total_xfer_len; /* word 4 */
uint32_t rsrvd5; /* word 5 */
struct wqe_common wqe_com; /* words 6-11 */
uint32_t rsvd_12_15[4]; /* word 12-15 */
uint32_t rsrvd12;
struct ulp_bde64 ph_bde; /* words 13-15 */
};

struct fcp_icmnd64_wqe {
Expand Down
Loading

0 comments on commit fedd3b7

Please sign in to comment.