diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-12-04 22:38:46 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 12:24:24 -0500 |
commit | ddcc50f0f3538e4771c8ab9e8ec685a22c90d88c (patch) | |
tree | 23dd2dce48b82eca6fdea70425d0e18bdcf4a2ad /drivers/scsi/lpfc/lpfc_els.c | |
parent | 5cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290 (diff) |
[SCSI] lpfc 8.3.0 : Rework RSCN netlink event to send entire RSCN payload
Rework RSCN netlink event to send entire RSCN payload
Also replaces (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX) with
LPFC_NL_VENDOR_ID
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 | 122 |
1 files changed, 103 insertions, 19 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 630bd28fb997..50c2faa50f0c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -3887,6 +3887,49 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) | |||
3887 | } | 3887 | } |
3888 | 3888 | ||
3889 | /** | 3889 | /** |
3890 | * lpfc_send_rscn_event: Send an RSCN event to management application. | ||
3891 | * @vport: pointer to a host virtual N_Port data structure. | ||
3892 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
3893 | * | ||
3894 | * lpfc_send_rscn_event sends an RSCN netlink event to management | ||
3895 | * applications. | ||
3896 | */ | ||
3897 | static void | ||
3898 | lpfc_send_rscn_event(struct lpfc_vport *vport, | ||
3899 | struct lpfc_iocbq *cmdiocb) | ||
3900 | { | ||
3901 | struct lpfc_dmabuf *pcmd; | ||
3902 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
3903 | uint32_t *payload_ptr; | ||
3904 | uint32_t payload_len; | ||
3905 | struct lpfc_rscn_event_header *rscn_event_data; | ||
3906 | |||
3907 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
3908 | payload_ptr = (uint32_t *) pcmd->virt; | ||
3909 | payload_len = be32_to_cpu(*payload_ptr & ~ELS_CMD_MASK); | ||
3910 | |||
3911 | rscn_event_data = kmalloc(sizeof(struct lpfc_rscn_event_header) + | ||
3912 | payload_len, GFP_KERNEL); | ||
3913 | if (!rscn_event_data) { | ||
3914 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
3915 | "0147 Failed to allocate memory for RSCN event\n"); | ||
3916 | return; | ||
3917 | } | ||
3918 | rscn_event_data->event_type = FC_REG_RSCN_EVENT; | ||
3919 | rscn_event_data->payload_length = payload_len; | ||
3920 | memcpy(rscn_event_data->rscn_payload, payload_ptr, | ||
3921 | payload_len); | ||
3922 | |||
3923 | fc_host_post_vendor_event(shost, | ||
3924 | fc_get_event_number(), | ||
3925 | sizeof(struct lpfc_els_event_header) + payload_len, | ||
3926 | (char *)rscn_event_data, | ||
3927 | LPFC_NL_VENDOR_ID); | ||
3928 | |||
3929 | kfree(rscn_event_data); | ||
3930 | } | ||
3931 | |||
3932 | /** | ||
3890 | * lpfc_els_rcv_rscn: Process an unsolicited rscn iocb. | 3933 | * lpfc_els_rcv_rscn: Process an unsolicited rscn iocb. |
3891 | * @vport: pointer to a host virtual N_Port data structure. | 3934 | * @vport: pointer to a host virtual N_Port data structure. |
3892 | * @cmdiocb: pointer to lpfc command iocb data structure. | 3935 | * @cmdiocb: pointer to lpfc command iocb data structure. |
@@ -3933,6 +3976,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3933 | "0214 RSCN received Data: x%x x%x x%x x%x\n", | 3976 | "0214 RSCN received Data: x%x x%x x%x x%x\n", |
3934 | vport->fc_flag, payload_len, *lp, | 3977 | vport->fc_flag, payload_len, *lp, |
3935 | vport->fc_rscn_id_cnt); | 3978 | vport->fc_rscn_id_cnt); |
3979 | |||
3980 | /* Send an RSCN event to the management application */ | ||
3981 | lpfc_send_rscn_event(vport, cmdiocb); | ||
3982 | |||
3936 | for (i = 0; i < payload_len/sizeof(uint32_t); i++) | 3983 | for (i = 0; i < payload_len/sizeof(uint32_t); i++) |
3937 | fc_host_post_event(shost, fc_get_event_number(), | 3984 | fc_host_post_event(shost, fc_get_event_number(), |
3938 | FCH_EVT_RSCN, lp[i]); | 3985 | FCH_EVT_RSCN, lp[i]); |
@@ -5128,7 +5175,7 @@ lpfc_send_els_failure_event(struct lpfc_hba *phba, | |||
5128 | fc_get_event_number(), | 5175 | fc_get_event_number(), |
5129 | sizeof(lsrjt_event), | 5176 | sizeof(lsrjt_event), |
5130 | (char *)&lsrjt_event, | 5177 | (char *)&lsrjt_event, |
5131 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 5178 | LPFC_NL_VENDOR_ID); |
5132 | return; | 5179 | return; |
5133 | } | 5180 | } |
5134 | if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) || | 5181 | if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) || |
@@ -5146,7 +5193,7 @@ lpfc_send_els_failure_event(struct lpfc_hba *phba, | |||
5146 | fc_get_event_number(), | 5193 | fc_get_event_number(), |
5147 | sizeof(fabric_event), | 5194 | sizeof(fabric_event), |
5148 | (char *)&fabric_event, | 5195 | (char *)&fabric_event, |
5149 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 5196 | LPFC_NL_VENDOR_ID); |
5150 | return; | 5197 | return; |
5151 | } | 5198 | } |
5152 | 5199 | ||
@@ -5164,32 +5211,68 @@ lpfc_send_els_failure_event(struct lpfc_hba *phba, | |||
5164 | static void | 5211 | static void |
5165 | lpfc_send_els_event(struct lpfc_vport *vport, | 5212 | lpfc_send_els_event(struct lpfc_vport *vport, |
5166 | struct lpfc_nodelist *ndlp, | 5213 | struct lpfc_nodelist *ndlp, |
5167 | uint32_t cmd) | 5214 | uint32_t *payload) |
5168 | { | 5215 | { |
5169 | struct lpfc_els_event_header els_data; | 5216 | struct lpfc_els_event_header *els_data = NULL; |
5217 | struct lpfc_logo_event *logo_data = NULL; | ||
5170 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 5218 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
5171 | 5219 | ||
5172 | els_data.event_type = FC_REG_ELS_EVENT; | 5220 | if (*payload == ELS_CMD_LOGO) { |
5173 | switch (cmd) { | 5221 | logo_data = kmalloc(sizeof(struct lpfc_logo_event), GFP_KERNEL); |
5222 | if (!logo_data) { | ||
5223 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
5224 | "0148 Failed to allocate memory " | ||
5225 | "for LOGO event\n"); | ||
5226 | return; | ||
5227 | } | ||
5228 | els_data = &logo_data->header; | ||
5229 | } else { | ||
5230 | els_data = kmalloc(sizeof(struct lpfc_els_event_header), | ||
5231 | GFP_KERNEL); | ||
5232 | if (!els_data) { | ||
5233 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
5234 | "0149 Failed to allocate memory " | ||
5235 | "for ELS event\n"); | ||
5236 | return; | ||
5237 | } | ||
5238 | } | ||
5239 | els_data->event_type = FC_REG_ELS_EVENT; | ||
5240 | switch (*payload) { | ||
5174 | case ELS_CMD_PLOGI: | 5241 | case ELS_CMD_PLOGI: |
5175 | els_data.subcategory = LPFC_EVENT_PLOGI_RCV; | 5242 | els_data->subcategory = LPFC_EVENT_PLOGI_RCV; |
5176 | break; | 5243 | break; |
5177 | case ELS_CMD_PRLO: | 5244 | case ELS_CMD_PRLO: |
5178 | els_data.subcategory = LPFC_EVENT_PRLO_RCV; | 5245 | els_data->subcategory = LPFC_EVENT_PRLO_RCV; |
5179 | break; | 5246 | break; |
5180 | case ELS_CMD_ADISC: | 5247 | case ELS_CMD_ADISC: |
5181 | els_data.subcategory = LPFC_EVENT_ADISC_RCV; | 5248 | els_data->subcategory = LPFC_EVENT_ADISC_RCV; |
5249 | break; | ||
5250 | case ELS_CMD_LOGO: | ||
5251 | els_data->subcategory = LPFC_EVENT_LOGO_RCV; | ||
5252 | /* Copy the WWPN in the LOGO payload */ | ||
5253 | memcpy(logo_data->logo_wwpn, &payload[2], | ||
5254 | sizeof(struct lpfc_name)); | ||
5182 | break; | 5255 | break; |
5183 | default: | 5256 | default: |
5184 | return; | 5257 | return; |
5185 | } | 5258 | } |
5186 | memcpy(els_data.wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name)); | 5259 | memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name)); |
5187 | memcpy(els_data.wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name)); | 5260 | memcpy(els_data->wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name)); |
5188 | fc_host_post_vendor_event(shost, | 5261 | if (*payload == ELS_CMD_LOGO) { |
5189 | fc_get_event_number(), | 5262 | fc_host_post_vendor_event(shost, |
5190 | sizeof(els_data), | 5263 | fc_get_event_number(), |
5191 | (char *)&els_data, | 5264 | sizeof(struct lpfc_logo_event), |
5192 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 5265 | (char *)logo_data, |
5266 | LPFC_NL_VENDOR_ID); | ||
5267 | kfree(logo_data); | ||
5268 | } else { | ||
5269 | fc_host_post_vendor_event(shost, | ||
5270 | fc_get_event_number(), | ||
5271 | sizeof(struct lpfc_els_event_header), | ||
5272 | (char *)els_data, | ||
5273 | LPFC_NL_VENDOR_ID); | ||
5274 | kfree(els_data); | ||
5275 | } | ||
5193 | 5276 | ||
5194 | return; | 5277 | return; |
5195 | } | 5278 | } |
@@ -5296,7 +5379,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5296 | phba->fc_stat.elsRcvPLOGI++; | 5379 | phba->fc_stat.elsRcvPLOGI++; |
5297 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); | 5380 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); |
5298 | 5381 | ||
5299 | lpfc_send_els_event(vport, ndlp, cmd); | 5382 | lpfc_send_els_event(vport, ndlp, payload); |
5300 | if (vport->port_state < LPFC_DISC_AUTH) { | 5383 | if (vport->port_state < LPFC_DISC_AUTH) { |
5301 | if (!(phba->pport->fc_flag & FC_PT2PT) || | 5384 | if (!(phba->pport->fc_flag & FC_PT2PT) || |
5302 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { | 5385 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { |
@@ -5334,6 +5417,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5334 | did, vport->port_state, ndlp->nlp_flag); | 5417 | did, vport->port_state, ndlp->nlp_flag); |
5335 | 5418 | ||
5336 | phba->fc_stat.elsRcvLOGO++; | 5419 | phba->fc_stat.elsRcvLOGO++; |
5420 | lpfc_send_els_event(vport, ndlp, payload); | ||
5337 | if (vport->port_state < LPFC_DISC_AUTH) { | 5421 | if (vport->port_state < LPFC_DISC_AUTH) { |
5338 | rjt_err = LSRJT_UNABLE_TPC; | 5422 | rjt_err = LSRJT_UNABLE_TPC; |
5339 | break; | 5423 | break; |
@@ -5346,7 +5430,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5346 | did, vport->port_state, ndlp->nlp_flag); | 5430 | did, vport->port_state, ndlp->nlp_flag); |
5347 | 5431 | ||
5348 | phba->fc_stat.elsRcvPRLO++; | 5432 | phba->fc_stat.elsRcvPRLO++; |
5349 | lpfc_send_els_event(vport, ndlp, cmd); | 5433 | lpfc_send_els_event(vport, ndlp, payload); |
5350 | if (vport->port_state < LPFC_DISC_AUTH) { | 5434 | if (vport->port_state < LPFC_DISC_AUTH) { |
5351 | rjt_err = LSRJT_UNABLE_TPC; | 5435 | rjt_err = LSRJT_UNABLE_TPC; |
5352 | break; | 5436 | break; |
@@ -5364,7 +5448,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5364 | "RCV ADISC: did:x%x/ste:x%x flg:x%x", | 5448 | "RCV ADISC: did:x%x/ste:x%x flg:x%x", |
5365 | did, vport->port_state, ndlp->nlp_flag); | 5449 | did, vport->port_state, ndlp->nlp_flag); |
5366 | 5450 | ||
5367 | lpfc_send_els_event(vport, ndlp, cmd); | 5451 | lpfc_send_els_event(vport, ndlp, payload); |
5368 | phba->fc_stat.elsRcvADISC++; | 5452 | phba->fc_stat.elsRcvADISC++; |
5369 | if (vport->port_state < LPFC_DISC_AUTH) { | 5453 | if (vport->port_state < LPFC_DISC_AUTH) { |
5370 | rjt_err = LSRJT_UNABLE_TPC; | 5454 | rjt_err = LSRJT_UNABLE_TPC; |