diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-09-07 11:52:10 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-13 09:28:57 -0400 |
commit | ea2151b4e142fa2de0319d9dd80413a997bf435a (patch) | |
tree | 1daa395a0b8584431c1b739af2761a840d013985 /drivers/scsi/lpfc/lpfc_els.c | |
parent | 977b5a0af6d22a1a0170057c19cde37eeac68acd (diff) |
[SCSI] lpfc 8.2.8 v2 : Add statistical reporting control and additional fc vendor events
Added support for new sysfs attributes: lpfc_stat_data_ctrl and
lpfc_max_scsicmpl_time. The attributes control statistical reporting
of io load.
Added support for new fc vendor events for error reporting.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index d0730e79c1a7..630bd28fb997 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include "lpfc_hw.h" | 31 | #include "lpfc_hw.h" |
32 | #include "lpfc_sli.h" | 32 | #include "lpfc_sli.h" |
33 | #include "lpfc_nl.h" | ||
33 | #include "lpfc_disc.h" | 34 | #include "lpfc_disc.h" |
34 | #include "lpfc_scsi.h" | 35 | #include "lpfc_scsi.h" |
35 | #include "lpfc.h" | 36 | #include "lpfc.h" |
@@ -5085,6 +5086,116 @@ lpfc_els_flush_all_cmd(struct lpfc_hba *phba) | |||
5085 | } | 5086 | } |
5086 | 5087 | ||
5087 | /** | 5088 | /** |
5089 | * lpfc_send_els_failure_event: Posts an ELS command failure event. | ||
5090 | * @phba: Pointer to hba context object. | ||
5091 | * @cmdiocbp: Pointer to command iocb which reported error. | ||
5092 | * @rspiocbp: Pointer to response iocb which reported error. | ||
5093 | * | ||
5094 | * This function sends an event when there is an ELS command | ||
5095 | * failure. | ||
5096 | **/ | ||
5097 | void | ||
5098 | lpfc_send_els_failure_event(struct lpfc_hba *phba, | ||
5099 | struct lpfc_iocbq *cmdiocbp, | ||
5100 | struct lpfc_iocbq *rspiocbp) | ||
5101 | { | ||
5102 | struct lpfc_vport *vport = cmdiocbp->vport; | ||
5103 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
5104 | struct lpfc_lsrjt_event lsrjt_event; | ||
5105 | struct lpfc_fabric_event_header fabric_event; | ||
5106 | struct ls_rjt stat; | ||
5107 | struct lpfc_nodelist *ndlp; | ||
5108 | uint32_t *pcmd; | ||
5109 | |||
5110 | ndlp = cmdiocbp->context1; | ||
5111 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) | ||
5112 | return; | ||
5113 | |||
5114 | if (rspiocbp->iocb.ulpStatus == IOSTAT_LS_RJT) { | ||
5115 | lsrjt_event.header.event_type = FC_REG_ELS_EVENT; | ||
5116 | lsrjt_event.header.subcategory = LPFC_EVENT_LSRJT_RCV; | ||
5117 | memcpy(lsrjt_event.header.wwpn, &ndlp->nlp_portname, | ||
5118 | sizeof(struct lpfc_name)); | ||
5119 | memcpy(lsrjt_event.header.wwnn, &ndlp->nlp_nodename, | ||
5120 | sizeof(struct lpfc_name)); | ||
5121 | pcmd = (uint32_t *) (((struct lpfc_dmabuf *) | ||
5122 | cmdiocbp->context2)->virt); | ||
5123 | lsrjt_event.command = *pcmd; | ||
5124 | stat.un.lsRjtError = be32_to_cpu(rspiocbp->iocb.un.ulpWord[4]); | ||
5125 | lsrjt_event.reason_code = stat.un.b.lsRjtRsnCode; | ||
5126 | lsrjt_event.explanation = stat.un.b.lsRjtRsnCodeExp; | ||
5127 | fc_host_post_vendor_event(shost, | ||
5128 | fc_get_event_number(), | ||
5129 | sizeof(lsrjt_event), | ||
5130 | (char *)&lsrjt_event, | ||
5131 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | ||
5132 | return; | ||
5133 | } | ||
5134 | if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) || | ||
5135 | (rspiocbp->iocb.ulpStatus == IOSTAT_FABRIC_BSY)) { | ||
5136 | fabric_event.event_type = FC_REG_FABRIC_EVENT; | ||
5137 | if (rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) | ||
5138 | fabric_event.subcategory = LPFC_EVENT_PORT_BUSY; | ||
5139 | else | ||
5140 | fabric_event.subcategory = LPFC_EVENT_FABRIC_BUSY; | ||
5141 | memcpy(fabric_event.wwpn, &ndlp->nlp_portname, | ||
5142 | sizeof(struct lpfc_name)); | ||
5143 | memcpy(fabric_event.wwnn, &ndlp->nlp_nodename, | ||
5144 | sizeof(struct lpfc_name)); | ||
5145 | fc_host_post_vendor_event(shost, | ||
5146 | fc_get_event_number(), | ||
5147 | sizeof(fabric_event), | ||
5148 | (char *)&fabric_event, | ||
5149 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | ||
5150 | return; | ||
5151 | } | ||
5152 | |||
5153 | } | ||
5154 | |||
5155 | /** | ||
5156 | * lpfc_send_els_event: Posts unsolicited els event. | ||
5157 | * @vport: Pointer to vport object. | ||
5158 | * @ndlp: Pointer FC node object. | ||
5159 | * @cmd: ELS command code. | ||
5160 | * | ||
5161 | * This function posts an event when there is an incoming | ||
5162 | * unsolicited ELS command. | ||
5163 | **/ | ||
5164 | static void | ||
5165 | lpfc_send_els_event(struct lpfc_vport *vport, | ||
5166 | struct lpfc_nodelist *ndlp, | ||
5167 | uint32_t cmd) | ||
5168 | { | ||
5169 | struct lpfc_els_event_header els_data; | ||
5170 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
5171 | |||
5172 | els_data.event_type = FC_REG_ELS_EVENT; | ||
5173 | switch (cmd) { | ||
5174 | case ELS_CMD_PLOGI: | ||
5175 | els_data.subcategory = LPFC_EVENT_PLOGI_RCV; | ||
5176 | break; | ||
5177 | case ELS_CMD_PRLO: | ||
5178 | els_data.subcategory = LPFC_EVENT_PRLO_RCV; | ||
5179 | break; | ||
5180 | case ELS_CMD_ADISC: | ||
5181 | els_data.subcategory = LPFC_EVENT_ADISC_RCV; | ||
5182 | break; | ||
5183 | default: | ||
5184 | return; | ||
5185 | } | ||
5186 | memcpy(els_data.wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name)); | ||
5187 | memcpy(els_data.wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name)); | ||
5188 | fc_host_post_vendor_event(shost, | ||
5189 | fc_get_event_number(), | ||
5190 | sizeof(els_data), | ||
5191 | (char *)&els_data, | ||
5192 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | ||
5193 | |||
5194 | return; | ||
5195 | } | ||
5196 | |||
5197 | |||
5198 | /** | ||
5088 | * lpfc_els_unsol_buffer: Process an unsolicited event data buffer. | 5199 | * lpfc_els_unsol_buffer: Process an unsolicited event data buffer. |
5089 | * @phba: pointer to lpfc hba data structure. | 5200 | * @phba: pointer to lpfc hba data structure. |
5090 | * @pring: pointer to a SLI ring. | 5201 | * @pring: pointer to a SLI ring. |
@@ -5185,6 +5296,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5185 | phba->fc_stat.elsRcvPLOGI++; | 5296 | phba->fc_stat.elsRcvPLOGI++; |
5186 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); | 5297 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); |
5187 | 5298 | ||
5299 | lpfc_send_els_event(vport, ndlp, cmd); | ||
5188 | if (vport->port_state < LPFC_DISC_AUTH) { | 5300 | if (vport->port_state < LPFC_DISC_AUTH) { |
5189 | if (!(phba->pport->fc_flag & FC_PT2PT) || | 5301 | if (!(phba->pport->fc_flag & FC_PT2PT) || |
5190 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { | 5302 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { |
@@ -5234,6 +5346,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5234 | did, vport->port_state, ndlp->nlp_flag); | 5346 | did, vport->port_state, ndlp->nlp_flag); |
5235 | 5347 | ||
5236 | phba->fc_stat.elsRcvPRLO++; | 5348 | phba->fc_stat.elsRcvPRLO++; |
5349 | lpfc_send_els_event(vport, ndlp, cmd); | ||
5237 | if (vport->port_state < LPFC_DISC_AUTH) { | 5350 | if (vport->port_state < LPFC_DISC_AUTH) { |
5238 | rjt_err = LSRJT_UNABLE_TPC; | 5351 | rjt_err = LSRJT_UNABLE_TPC; |
5239 | break; | 5352 | break; |
@@ -5251,6 +5364,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5251 | "RCV ADISC: did:x%x/ste:x%x flg:x%x", | 5364 | "RCV ADISC: did:x%x/ste:x%x flg:x%x", |
5252 | did, vport->port_state, ndlp->nlp_flag); | 5365 | did, vport->port_state, ndlp->nlp_flag); |
5253 | 5366 | ||
5367 | lpfc_send_els_event(vport, ndlp, cmd); | ||
5254 | phba->fc_stat.elsRcvADISC++; | 5368 | phba->fc_stat.elsRcvADISC++; |
5255 | if (vport->port_state < LPFC_DISC_AUTH) { | 5369 | if (vport->port_state < LPFC_DISC_AUTH) { |
5256 | rjt_err = LSRJT_UNABLE_TPC; | 5370 | rjt_err = LSRJT_UNABLE_TPC; |