aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c160
1 files changed, 124 insertions, 36 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 630bd28fb997..a8f30bdaff69 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -221,7 +221,11 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
221 /* For ELS_REQUEST64_CR, use the VPI by default */ 221 /* For ELS_REQUEST64_CR, use the VPI by default */
222 icmd->ulpContext = vport->vpi; 222 icmd->ulpContext = vport->vpi;
223 icmd->ulpCt_h = 0; 223 icmd->ulpCt_h = 0;
224 icmd->ulpCt_l = 1; 224 /* The CT field must be 0=INVALID_RPI for the ECHO cmd */
225 if (elscmd == ELS_CMD_ECHO)
226 icmd->ulpCt_l = 0; /* context = invalid RPI */
227 else
228 icmd->ulpCt_l = 1; /* context = VPI */
225 } 229 }
226 230
227 bpl = (struct ulp_bde64 *) pbuflist->virt; 231 bpl = (struct ulp_bde64 *) pbuflist->virt;
@@ -271,7 +275,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
271 return elsiocb; 275 return elsiocb;
272 276
273els_iocb_free_pbuf_exit: 277els_iocb_free_pbuf_exit:
274 lpfc_mbuf_free(phba, prsp->virt, prsp->phys); 278 if (expectRsp)
279 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
275 kfree(pbuflist); 280 kfree(pbuflist);
276 281
277els_iocb_free_prsp_exit: 282els_iocb_free_prsp_exit:
@@ -2468,6 +2473,15 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2468 case IOSTAT_LOCAL_REJECT: 2473 case IOSTAT_LOCAL_REJECT:
2469 switch ((irsp->un.ulpWord[4] & 0xff)) { 2474 switch ((irsp->un.ulpWord[4] & 0xff)) {
2470 case IOERR_LOOP_OPEN_FAILURE: 2475 case IOERR_LOOP_OPEN_FAILURE:
2476 if (cmd == ELS_CMD_FLOGI) {
2477 if (PCI_DEVICE_ID_HORNET ==
2478 phba->pcidev->device) {
2479 phba->fc_topology = TOPOLOGY_LOOP;
2480 phba->pport->fc_myDID = 0;
2481 phba->alpa_map[0] = 0;
2482 phba->alpa_map[1] = 0;
2483 }
2484 }
2471 if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0) 2485 if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
2472 delay = 1000; 2486 delay = 1000;
2473 retry = 1; 2487 retry = 1;
@@ -3823,27 +3837,21 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
3823 while (payload_len) { 3837 while (payload_len) {
3824 rscn_did.un.word = be32_to_cpu(*lp++); 3838 rscn_did.un.word = be32_to_cpu(*lp++);
3825 payload_len -= sizeof(uint32_t); 3839 payload_len -= sizeof(uint32_t);
3826 switch (rscn_did.un.b.resv) { 3840 switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) {
3827 case 0: /* Single N_Port ID effected */ 3841 case RSCN_ADDRESS_FORMAT_PORT:
3828 if (ns_did.un.word == rscn_did.un.word) 3842 if (ns_did.un.word == rscn_did.un.word)
3829 goto return_did_out; 3843 goto return_did_out;
3830 break; 3844 break;
3831 case 1: /* Whole N_Port Area effected */ 3845 case RSCN_ADDRESS_FORMAT_AREA:
3832 if ((ns_did.un.b.domain == rscn_did.un.b.domain) 3846 if ((ns_did.un.b.domain == rscn_did.un.b.domain)
3833 && (ns_did.un.b.area == rscn_did.un.b.area)) 3847 && (ns_did.un.b.area == rscn_did.un.b.area))
3834 goto return_did_out; 3848 goto return_did_out;
3835 break; 3849 break;
3836 case 2: /* Whole N_Port Domain effected */ 3850 case RSCN_ADDRESS_FORMAT_DOMAIN:
3837 if (ns_did.un.b.domain == rscn_did.un.b.domain) 3851 if (ns_did.un.b.domain == rscn_did.un.b.domain)
3838 goto return_did_out; 3852 goto return_did_out;
3839 break; 3853 break;
3840 default: 3854 case RSCN_ADDRESS_FORMAT_FABRIC:
3841 /* Unknown Identifier in RSCN node */
3842 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
3843 "0217 Unknown Identifier in "
3844 "RSCN payload Data: x%x\n",
3845 rscn_did.un.word);
3846 case 3: /* Whole Fabric effected */
3847 goto return_did_out; 3855 goto return_did_out;
3848 } 3856 }
3849 } 3857 }
@@ -3887,6 +3895,49 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
3887} 3895}
3888 3896
3889/** 3897/**
3898 * lpfc_send_rscn_event: Send an RSCN event to management application.
3899 * @vport: pointer to a host virtual N_Port data structure.
3900 * @cmdiocb: pointer to lpfc command iocb data structure.
3901 *
3902 * lpfc_send_rscn_event sends an RSCN netlink event to management
3903 * applications.
3904 */
3905static void
3906lpfc_send_rscn_event(struct lpfc_vport *vport,
3907 struct lpfc_iocbq *cmdiocb)
3908{
3909 struct lpfc_dmabuf *pcmd;
3910 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3911 uint32_t *payload_ptr;
3912 uint32_t payload_len;
3913 struct lpfc_rscn_event_header *rscn_event_data;
3914
3915 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3916 payload_ptr = (uint32_t *) pcmd->virt;
3917 payload_len = be32_to_cpu(*payload_ptr & ~ELS_CMD_MASK);
3918
3919 rscn_event_data = kmalloc(sizeof(struct lpfc_rscn_event_header) +
3920 payload_len, GFP_KERNEL);
3921 if (!rscn_event_data) {
3922 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
3923 "0147 Failed to allocate memory for RSCN event\n");
3924 return;
3925 }
3926 rscn_event_data->event_type = FC_REG_RSCN_EVENT;
3927 rscn_event_data->payload_length = payload_len;
3928 memcpy(rscn_event_data->rscn_payload, payload_ptr,
3929 payload_len);
3930
3931 fc_host_post_vendor_event(shost,
3932 fc_get_event_number(),
3933 sizeof(struct lpfc_els_event_header) + payload_len,
3934 (char *)rscn_event_data,
3935 LPFC_NL_VENDOR_ID);
3936
3937 kfree(rscn_event_data);
3938}
3939
3940/**
3890 * lpfc_els_rcv_rscn: Process an unsolicited rscn iocb. 3941 * lpfc_els_rcv_rscn: Process an unsolicited rscn iocb.
3891 * @vport: pointer to a host virtual N_Port data structure. 3942 * @vport: pointer to a host virtual N_Port data structure.
3892 * @cmdiocb: pointer to lpfc command iocb data structure. 3943 * @cmdiocb: pointer to lpfc command iocb data structure.
@@ -3933,6 +3984,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", 3984 "0214 RSCN received Data: x%x x%x x%x x%x\n",
3934 vport->fc_flag, payload_len, *lp, 3985 vport->fc_flag, payload_len, *lp,
3935 vport->fc_rscn_id_cnt); 3986 vport->fc_rscn_id_cnt);
3987
3988 /* Send an RSCN event to the management application */
3989 lpfc_send_rscn_event(vport, cmdiocb);
3990
3936 for (i = 0; i < payload_len/sizeof(uint32_t); i++) 3991 for (i = 0; i < payload_len/sizeof(uint32_t); i++)
3937 fc_host_post_event(shost, fc_get_event_number(), 3992 fc_host_post_event(shost, fc_get_event_number(),
3938 FCH_EVT_RSCN, lp[i]); 3993 FCH_EVT_RSCN, lp[i]);
@@ -4884,10 +4939,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
4884 uint32_t timeout; 4939 uint32_t timeout;
4885 uint32_t remote_ID = 0xffffffff; 4940 uint32_t remote_ID = 0xffffffff;
4886 4941
4887 /* If the timer is already canceled do nothing */
4888 if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
4889 return;
4890 }
4891 spin_lock_irq(&phba->hbalock); 4942 spin_lock_irq(&phba->hbalock);
4892 timeout = (uint32_t)(phba->fc_ratov << 1); 4943 timeout = (uint32_t)(phba->fc_ratov << 1);
4893 4944
@@ -5128,7 +5179,7 @@ lpfc_send_els_failure_event(struct lpfc_hba *phba,
5128 fc_get_event_number(), 5179 fc_get_event_number(),
5129 sizeof(lsrjt_event), 5180 sizeof(lsrjt_event),
5130 (char *)&lsrjt_event, 5181 (char *)&lsrjt_event,
5131 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); 5182 LPFC_NL_VENDOR_ID);
5132 return; 5183 return;
5133 } 5184 }
5134 if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) || 5185 if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) ||
@@ -5146,7 +5197,7 @@ lpfc_send_els_failure_event(struct lpfc_hba *phba,
5146 fc_get_event_number(), 5197 fc_get_event_number(),
5147 sizeof(fabric_event), 5198 sizeof(fabric_event),
5148 (char *)&fabric_event, 5199 (char *)&fabric_event,
5149 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); 5200 LPFC_NL_VENDOR_ID);
5150 return; 5201 return;
5151 } 5202 }
5152 5203
@@ -5164,32 +5215,68 @@ lpfc_send_els_failure_event(struct lpfc_hba *phba,
5164static void 5215static void
5165lpfc_send_els_event(struct lpfc_vport *vport, 5216lpfc_send_els_event(struct lpfc_vport *vport,
5166 struct lpfc_nodelist *ndlp, 5217 struct lpfc_nodelist *ndlp,
5167 uint32_t cmd) 5218 uint32_t *payload)
5168{ 5219{
5169 struct lpfc_els_event_header els_data; 5220 struct lpfc_els_event_header *els_data = NULL;
5221 struct lpfc_logo_event *logo_data = NULL;
5170 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 5222 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5171 5223
5172 els_data.event_type = FC_REG_ELS_EVENT; 5224 if (*payload == ELS_CMD_LOGO) {
5173 switch (cmd) { 5225 logo_data = kmalloc(sizeof(struct lpfc_logo_event), GFP_KERNEL);
5226 if (!logo_data) {
5227 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5228 "0148 Failed to allocate memory "
5229 "for LOGO event\n");
5230 return;
5231 }
5232 els_data = &logo_data->header;
5233 } else {
5234 els_data = kmalloc(sizeof(struct lpfc_els_event_header),
5235 GFP_KERNEL);
5236 if (!els_data) {
5237 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5238 "0149 Failed to allocate memory "
5239 "for ELS event\n");
5240 return;
5241 }
5242 }
5243 els_data->event_type = FC_REG_ELS_EVENT;
5244 switch (*payload) {
5174 case ELS_CMD_PLOGI: 5245 case ELS_CMD_PLOGI:
5175 els_data.subcategory = LPFC_EVENT_PLOGI_RCV; 5246 els_data->subcategory = LPFC_EVENT_PLOGI_RCV;
5176 break; 5247 break;
5177 case ELS_CMD_PRLO: 5248 case ELS_CMD_PRLO:
5178 els_data.subcategory = LPFC_EVENT_PRLO_RCV; 5249 els_data->subcategory = LPFC_EVENT_PRLO_RCV;
5179 break; 5250 break;
5180 case ELS_CMD_ADISC: 5251 case ELS_CMD_ADISC:
5181 els_data.subcategory = LPFC_EVENT_ADISC_RCV; 5252 els_data->subcategory = LPFC_EVENT_ADISC_RCV;
5253 break;
5254 case ELS_CMD_LOGO:
5255 els_data->subcategory = LPFC_EVENT_LOGO_RCV;
5256 /* Copy the WWPN in the LOGO payload */
5257 memcpy(logo_data->logo_wwpn, &payload[2],
5258 sizeof(struct lpfc_name));
5182 break; 5259 break;
5183 default: 5260 default:
5184 return; 5261 return;
5185 } 5262 }
5186 memcpy(els_data.wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name)); 5263 memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name));
5187 memcpy(els_data.wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name)); 5264 memcpy(els_data->wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name));
5188 fc_host_post_vendor_event(shost, 5265 if (*payload == ELS_CMD_LOGO) {
5189 fc_get_event_number(), 5266 fc_host_post_vendor_event(shost,
5190 sizeof(els_data), 5267 fc_get_event_number(),
5191 (char *)&els_data, 5268 sizeof(struct lpfc_logo_event),
5192 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); 5269 (char *)logo_data,
5270 LPFC_NL_VENDOR_ID);
5271 kfree(logo_data);
5272 } else {
5273 fc_host_post_vendor_event(shost,
5274 fc_get_event_number(),
5275 sizeof(struct lpfc_els_event_header),
5276 (char *)els_data,
5277 LPFC_NL_VENDOR_ID);
5278 kfree(els_data);
5279 }
5193 5280
5194 return; 5281 return;
5195} 5282}
@@ -5296,7 +5383,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5296 phba->fc_stat.elsRcvPLOGI++; 5383 phba->fc_stat.elsRcvPLOGI++;
5297 ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); 5384 ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
5298 5385
5299 lpfc_send_els_event(vport, ndlp, cmd); 5386 lpfc_send_els_event(vport, ndlp, payload);
5300 if (vport->port_state < LPFC_DISC_AUTH) { 5387 if (vport->port_state < LPFC_DISC_AUTH) {
5301 if (!(phba->pport->fc_flag & FC_PT2PT) || 5388 if (!(phba->pport->fc_flag & FC_PT2PT) ||
5302 (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { 5389 (phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
@@ -5334,6 +5421,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5334 did, vport->port_state, ndlp->nlp_flag); 5421 did, vport->port_state, ndlp->nlp_flag);
5335 5422
5336 phba->fc_stat.elsRcvLOGO++; 5423 phba->fc_stat.elsRcvLOGO++;
5424 lpfc_send_els_event(vport, ndlp, payload);
5337 if (vport->port_state < LPFC_DISC_AUTH) { 5425 if (vport->port_state < LPFC_DISC_AUTH) {
5338 rjt_err = LSRJT_UNABLE_TPC; 5426 rjt_err = LSRJT_UNABLE_TPC;
5339 break; 5427 break;
@@ -5346,7 +5434,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5346 did, vport->port_state, ndlp->nlp_flag); 5434 did, vport->port_state, ndlp->nlp_flag);
5347 5435
5348 phba->fc_stat.elsRcvPRLO++; 5436 phba->fc_stat.elsRcvPRLO++;
5349 lpfc_send_els_event(vport, ndlp, cmd); 5437 lpfc_send_els_event(vport, ndlp, payload);
5350 if (vport->port_state < LPFC_DISC_AUTH) { 5438 if (vport->port_state < LPFC_DISC_AUTH) {
5351 rjt_err = LSRJT_UNABLE_TPC; 5439 rjt_err = LSRJT_UNABLE_TPC;
5352 break; 5440 break;
@@ -5364,7 +5452,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", 5452 "RCV ADISC: did:x%x/ste:x%x flg:x%x",
5365 did, vport->port_state, ndlp->nlp_flag); 5453 did, vport->port_state, ndlp->nlp_flag);
5366 5454
5367 lpfc_send_els_event(vport, ndlp, cmd); 5455 lpfc_send_els_event(vport, ndlp, payload);
5368 phba->fc_stat.elsRcvADISC++; 5456 phba->fc_stat.elsRcvADISC++;
5369 if (vport->port_state < LPFC_DISC_AUTH) { 5457 if (vport->port_state < LPFC_DISC_AUTH) {
5370 rjt_err = LSRJT_UNABLE_TPC; 5458 rjt_err = LSRJT_UNABLE_TPC;