aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-12-13 13:21:57 -0500
committerJames Bottomley <JBottomley@Parallels.com>2011-12-15 01:57:44 -0500
commitcb69f7decc3777822b240c46890a209df288c7bb (patch)
tree8ae647f9d3d50452fc0bc684a8b4108a4f94a65e /drivers/scsi
parentff78d8f97c85a568c0799b06137a4171db45b923 (diff)
[SCSI] lpfc 8.3.28: Add support for ABTS failure handling
Add support for ABTS failure handling: - Add asynchronous ABTS notification event feature to driver (CR 124578) - Change driver message 3092 and 3116 to KERN_WARNING (CR 124768) - Alter the SCR ELS command to use the temporary RPI and the Destination DID for SLI4-FC (CR 126070) 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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c50
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c67
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h13
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c214
7 files changed, 263 insertions, 93 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 9237ff154234..bcc021f3c8eb 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -106,7 +106,7 @@ void lpfc_cleanup(struct lpfc_vport *);
106void lpfc_disc_timeout(unsigned long); 106void lpfc_disc_timeout(unsigned long);
107 107
108struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); 108struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
109 109struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
110void lpfc_worker_wake_up(struct lpfc_hba *); 110void lpfc_worker_wake_up(struct lpfc_hba *);
111int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); 111int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
112int lpfc_do_work(void *); 112int lpfc_do_work(void *);
@@ -455,3 +455,5 @@ int lpfc_sli4_queue_create(struct lpfc_hba *);
455void lpfc_sli4_queue_destroy(struct lpfc_hba *); 455void lpfc_sli4_queue_destroy(struct lpfc_hba *);
456int lpfc_sli4_read_config(struct lpfc_hba *phba); 456int lpfc_sli4_read_config(struct lpfc_hba *phba);
457int lpfc_scsi_buf_update(struct lpfc_hba *phba); 457int lpfc_scsi_buf_update(struct lpfc_hba *phba);
458void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *,
459 struct sli4_wcqe_xri_aborted *);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 846ebfd37b5e..46876941bac6 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -6596,56 +6596,6 @@ dropit:
6596} 6596}
6597 6597
6598/** 6598/**
6599 * lpfc_find_vport_by_vpid - Find a vport on a HBA through vport identifier
6600 * @phba: pointer to lpfc hba data structure.
6601 * @vpi: host virtual N_Port identifier.
6602 *
6603 * This routine finds a vport on a HBA (referred by @phba) through a
6604 * @vpi. The function walks the HBA's vport list and returns the address
6605 * of the vport with the matching @vpi.
6606 *
6607 * Return code
6608 * NULL - No vport with the matching @vpi found
6609 * Otherwise - Address to the vport with the matching @vpi.
6610 **/
6611struct lpfc_vport *
6612lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
6613{
6614 struct lpfc_vport *vport;
6615 unsigned long flags;
6616 int i = 0;
6617
6618 /* The physical ports are always vpi 0 - translate is unnecessary. */
6619 if (vpi > 0) {
6620 /*
6621 * Translate the physical vpi to the logical vpi. The
6622 * vport stores the logical vpi.
6623 */
6624 for (i = 0; i < phba->max_vpi; i++) {
6625 if (vpi == phba->vpi_ids[i])
6626 break;
6627 }
6628
6629 if (i >= phba->max_vpi) {
6630 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
6631 "2936 Could not find Vport mapped "
6632 "to vpi %d\n", vpi);
6633 return NULL;
6634 }
6635 }
6636
6637 spin_lock_irqsave(&phba->hbalock, flags);
6638 list_for_each_entry(vport, &phba->port_list, listentry) {
6639 if (vport->vpi == i) {
6640 spin_unlock_irqrestore(&phba->hbalock, flags);
6641 return vport;
6642 }
6643 }
6644 spin_unlock_irqrestore(&phba->hbalock, flags);
6645 return NULL;
6646}
6647
6648/**
6649 * lpfc_els_unsol_event - Process an unsolicited event from an els sli ring 6599 * lpfc_els_unsol_event - Process an unsolicited event from an els sli ring
6650 * @phba: pointer to lpfc hba data structure. 6600 * @phba: pointer to lpfc hba data structure.
6651 * @pring: pointer to a SLI ring. 6601 * @pring: pointer to a SLI ring.
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index cf4408f9a2cb..99c76677e394 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -5352,6 +5352,73 @@ lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn)
5352 return ndlp; 5352 return ndlp;
5353} 5353}
5354 5354
5355/*
5356 * This routine looks up the ndlp lists for the given RPI. If the rpi
5357 * is found, the routine returns the node element list pointer else
5358 * return NULL.
5359 */
5360struct lpfc_nodelist *
5361lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
5362{
5363 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5364 struct lpfc_nodelist *ndlp;
5365
5366 spin_lock_irq(shost->host_lock);
5367 ndlp = __lpfc_findnode_rpi(vport, rpi);
5368 spin_unlock_irq(shost->host_lock);
5369 return ndlp;
5370}
5371
5372/**
5373 * lpfc_find_vport_by_vpid - Find a vport on a HBA through vport identifier
5374 * @phba: pointer to lpfc hba data structure.
5375 * @vpi: the physical host virtual N_Port identifier.
5376 *
5377 * This routine finds a vport on a HBA (referred by @phba) through a
5378 * @vpi. The function walks the HBA's vport list and returns the address
5379 * of the vport with the matching @vpi.
5380 *
5381 * Return code
5382 * NULL - No vport with the matching @vpi found
5383 * Otherwise - Address to the vport with the matching @vpi.
5384 **/
5385struct lpfc_vport *
5386lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
5387{
5388 struct lpfc_vport *vport;
5389 unsigned long flags;
5390 int i = 0;
5391
5392 /* The physical ports are always vpi 0 - translate is unnecessary. */
5393 if (vpi > 0) {
5394 /*
5395 * Translate the physical vpi to the logical vpi. The
5396 * vport stores the logical vpi.
5397 */
5398 for (i = 0; i < phba->max_vpi; i++) {
5399 if (vpi == phba->vpi_ids[i])
5400 break;
5401 }
5402
5403 if (i >= phba->max_vpi) {
5404 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
5405 "2936 Could not find Vport mapped "
5406 "to vpi %d\n", vpi);
5407 return NULL;
5408 }
5409 }
5410
5411 spin_lock_irqsave(&phba->hbalock, flags);
5412 list_for_each_entry(vport, &phba->port_list, listentry) {
5413 if (vport->vpi == i) {
5414 spin_unlock_irqrestore(&phba->hbalock, flags);
5415 return vport;
5416 }
5417 }
5418 spin_unlock_irqrestore(&phba->hbalock, flags);
5419 return NULL;
5420}
5421
5355void 5422void
5356lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 5423lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
5357 uint32_t did) 5424 uint32_t did)
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 046edc4ab35f..2dd464b0f29e 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -2819,7 +2819,8 @@ typedef struct {
2819#ifdef __BIG_ENDIAN_BITFIELD 2819#ifdef __BIG_ENDIAN_BITFIELD
2820 uint32_t rsvd1 : 19; /* Reserved */ 2820 uint32_t rsvd1 : 19; /* Reserved */
2821 uint32_t cdss : 1; /* Configure Data Security SLI */ 2821 uint32_t cdss : 1; /* Configure Data Security SLI */
2822 uint32_t rsvd2 : 3; /* Reserved */ 2822 uint32_t casabt : 1; /* Configure async abts status notice */
2823 uint32_t rsvd2 : 2; /* Reserved */
2823 uint32_t cbg : 1; /* Configure BlockGuard */ 2824 uint32_t cbg : 1; /* Configure BlockGuard */
2824 uint32_t cmv : 1; /* Configure Max VPIs */ 2825 uint32_t cmv : 1; /* Configure Max VPIs */
2825 uint32_t ccrp : 1; /* Config Command Ring Polling */ 2826 uint32_t ccrp : 1; /* Config Command Ring Polling */
@@ -2839,14 +2840,16 @@ typedef struct {
2839 uint32_t ccrp : 1; /* Config Command Ring Polling */ 2840 uint32_t ccrp : 1; /* Config Command Ring Polling */
2840 uint32_t cmv : 1; /* Configure Max VPIs */ 2841 uint32_t cmv : 1; /* Configure Max VPIs */
2841 uint32_t cbg : 1; /* Configure BlockGuard */ 2842 uint32_t cbg : 1; /* Configure BlockGuard */
2842 uint32_t rsvd2 : 3; /* Reserved */ 2843 uint32_t rsvd2 : 2; /* Reserved */
2844 uint32_t casabt : 1; /* Configure async abts status notice */
2843 uint32_t cdss : 1; /* Configure Data Security SLI */ 2845 uint32_t cdss : 1; /* Configure Data Security SLI */
2844 uint32_t rsvd1 : 19; /* Reserved */ 2846 uint32_t rsvd1 : 19; /* Reserved */
2845#endif 2847#endif
2846#ifdef __BIG_ENDIAN_BITFIELD 2848#ifdef __BIG_ENDIAN_BITFIELD
2847 uint32_t rsvd3 : 19; /* Reserved */ 2849 uint32_t rsvd3 : 19; /* Reserved */
2848 uint32_t gdss : 1; /* Configure Data Security SLI */ 2850 uint32_t gdss : 1; /* Configure Data Security SLI */
2849 uint32_t rsvd4 : 3; /* Reserved */ 2851 uint32_t gasabt : 1; /* Grant async abts status notice */
2852 uint32_t rsvd4 : 2; /* Reserved */
2850 uint32_t gbg : 1; /* Grant BlockGuard */ 2853 uint32_t gbg : 1; /* Grant BlockGuard */
2851 uint32_t gmv : 1; /* Grant Max VPIs */ 2854 uint32_t gmv : 1; /* Grant Max VPIs */
2852 uint32_t gcrp : 1; /* Grant Command Ring Polling */ 2855 uint32_t gcrp : 1; /* Grant Command Ring Polling */
@@ -2866,7 +2869,8 @@ typedef struct {
2866 uint32_t gcrp : 1; /* Grant Command Ring Polling */ 2869 uint32_t gcrp : 1; /* Grant Command Ring Polling */
2867 uint32_t gmv : 1; /* Grant Max VPIs */ 2870 uint32_t gmv : 1; /* Grant Max VPIs */
2868 uint32_t gbg : 1; /* Grant BlockGuard */ 2871 uint32_t gbg : 1; /* Grant BlockGuard */
2869 uint32_t rsvd4 : 3; /* Reserved */ 2872 uint32_t rsvd4 : 2; /* Reserved */
2873 uint32_t gasabt : 1; /* Grant async abts status notice */
2870 uint32_t gdss : 1; /* Configure Data Security SLI */ 2874 uint32_t gdss : 1; /* Configure Data Security SLI */
2871 uint32_t rsvd3 : 19; /* Reserved */ 2875 uint32_t rsvd3 : 19; /* Reserved */
2872#endif 2876#endif
@@ -3465,6 +3469,7 @@ typedef struct {
3465} ASYNCSTAT_FIELDS; 3469} ASYNCSTAT_FIELDS;
3466#define ASYNC_TEMP_WARN 0x100 3470#define ASYNC_TEMP_WARN 0x100
3467#define ASYNC_TEMP_SAFE 0x101 3471#define ASYNC_TEMP_SAFE 0x101
3472#define ASYNC_STATUS_CN 0x102
3468 3473
3469/* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7) 3474/* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7)
3470 or CMD_IOCB_RCV_SEQ64_CX (0xB5) */ 3475 or CMD_IOCB_RCV_SEQ64_CX (0xB5) */
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 0228f04061da..328782efc839 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -1293,6 +1293,10 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1293 phba->sli_rev = LPFC_SLI_REV2; 1293 phba->sli_rev = LPFC_SLI_REV2;
1294 mb->un.varCfgPort.sli_mode = phba->sli_rev; 1294 mb->un.varCfgPort.sli_mode = phba->sli_rev;
1295 1295
1296 /* If this is an SLI3 port, configure async status notification. */
1297 if (phba->sli_rev == LPFC_SLI_REV3)
1298 mb->un.varCfgPort.casabt = 1;
1299
1296 /* Now setup pcb */ 1300 /* Now setup pcb */
1297 phba->pcb->type = TYPE_NATIVE_SLI2; 1301 phba->pcb->type = TYPE_NATIVE_SLI2;
1298 phba->pcb->feature = FEATURE_INITIAL_SLI2; 1302 phba->pcb->feature = FEATURE_INITIAL_SLI2;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 2e1e54e5c3ae..f1af3f9dead4 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -681,8 +681,10 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
681 681
682 rrq_empty = list_empty(&phba->active_rrq_list); 682 rrq_empty = list_empty(&phba->active_rrq_list);
683 spin_unlock_irqrestore(&phba->hbalock, iflag); 683 spin_unlock_irqrestore(&phba->hbalock, iflag);
684 if (ndlp) 684 if (ndlp) {
685 lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1); 685 lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1);
686 lpfc_sli4_abts_err_handler(phba, ndlp, axri);
687 }
686 lpfc_release_scsi_buf_s4(phba, psb); 688 lpfc_release_scsi_buf_s4(phba, psb);
687 if (rrq_empty) 689 if (rrq_empty)
688 lpfc_worker_wake_up(phba); 690 lpfc_worker_wake_up(phba);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 4c4d77356bb2..97bbafb21bc2 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4339,6 +4339,11 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode)
4339 phba->sli.sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; 4339 phba->sli.sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK;
4340 spin_unlock_irq(&phba->hbalock); 4340 spin_unlock_irq(&phba->hbalock);
4341 done = 1; 4341 done = 1;
4342
4343 if ((pmb->u.mb.un.varCfgPort.casabt == 1) &&
4344 (pmb->u.mb.un.varCfgPort.gasabt == 0))
4345 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
4346 "3110 Port did not grant ASABT\n");
4342 } 4347 }
4343 } 4348 }
4344 if (!done) { 4349 if (!done) {
@@ -7704,6 +7709,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
7704 iocbq->context2)->virt); 7709 iocbq->context2)->virt);
7705 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { 7710 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
7706 if (pcmd && (*pcmd == ELS_CMD_FLOGI || 7711 if (pcmd && (*pcmd == ELS_CMD_FLOGI ||
7712 *pcmd == ELS_CMD_SCR ||
7707 *pcmd == ELS_CMD_PLOGI)) { 7713 *pcmd == ELS_CMD_PLOGI)) {
7708 bf_set(els_req64_sp, &wqe->els_req, 1); 7714 bf_set(els_req64_sp, &wqe->els_req, 1);
7709 bf_set(els_req64_sid, &wqe->els_req, 7715 bf_set(els_req64_sid, &wqe->els_req,
@@ -8213,6 +8219,137 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
8213 return 0; 8219 return 0;
8214} 8220}
8215 8221
8222/* lpfc_sli_abts_recover_port - Recover a port that failed an ABTS.
8223 * @vport: pointer to virtual port object.
8224 * @ndlp: nodelist pointer for the impacted rport.
8225 *
8226 * The driver calls this routine in response to a XRI ABORT CQE
8227 * event from the port. In this event, the driver is required to
8228 * recover its login to the rport even though its login may be valid
8229 * from the driver's perspective. The failed ABTS notice from the
8230 * port indicates the rport is not responding.
8231 */
8232static void
8233lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
8234 struct lpfc_nodelist *ndlp)
8235{
8236 struct Scsi_Host *shost;
8237 struct lpfc_hba *phba;
8238 unsigned long flags = 0;
8239
8240 shost = lpfc_shost_from_vport(vport);
8241 phba = vport->phba;
8242 if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
8243 lpfc_printf_log(phba, KERN_INFO,
8244 LOG_SLI, "3093 No rport recovery needed. "
8245 "rport in state 0x%x\n",
8246 ndlp->nlp_state);
8247 return;
8248 }
8249 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
8250 "3094 Start rport recovery on shost id 0x%x "
8251 "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x "
8252 "flags 0x%x\n",
8253 shost->host_no, ndlp->nlp_DID,
8254 vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state,
8255 ndlp->nlp_flag);
8256 /*
8257 * The rport is not responding. Don't attempt ADISC recovery.
8258 * Remove the FCP-2 flag to force a PLOGI.
8259 */
8260 spin_lock_irqsave(shost->host_lock, flags);
8261 ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
8262 spin_unlock_irqrestore(shost->host_lock, flags);
8263 lpfc_disc_state_machine(vport, ndlp, NULL,
8264 NLP_EVT_DEVICE_RECOVERY);
8265 lpfc_cancel_retry_delay_tmo(vport, ndlp);
8266 spin_lock_irqsave(shost->host_lock, flags);
8267 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
8268 spin_unlock_irqrestore(shost->host_lock, flags);
8269 lpfc_disc_start(vport);
8270}
8271
8272/* lpfc_sli_abts_err_handler - handle a failed ABTS request from an SLI3 port.
8273 * @phba: Pointer to HBA context object.
8274 * @iocbq: Pointer to iocb object.
8275 *
8276 * The async_event handler calls this routine when it receives
8277 * an ASYNC_STATUS_CN event from the port. The port generates
8278 * this event when an Abort Sequence request to an rport fails
8279 * twice in succession. The abort could be originated by the
8280 * driver or by the port. The ABTS could have been for an ELS
8281 * or FCP IO. The port only generates this event when an ABTS
8282 * fails to complete after one retry.
8283 */
8284static void
8285lpfc_sli_abts_err_handler(struct lpfc_hba *phba,
8286 struct lpfc_iocbq *iocbq)
8287{
8288 struct lpfc_nodelist *ndlp = NULL;
8289 uint16_t rpi = 0, vpi = 0;
8290 struct lpfc_vport *vport = NULL;
8291
8292 /* The rpi in the ulpContext is vport-sensitive. */
8293 vpi = iocbq->iocb.un.asyncstat.sub_ctxt_tag;
8294 rpi = iocbq->iocb.ulpContext;
8295
8296 lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
8297 "3092 Port generated ABTS async event "
8298 "on vpi %d rpi %d status 0x%x\n",
8299 vpi, rpi, iocbq->iocb.ulpStatus);
8300
8301 vport = lpfc_find_vport_by_vpid(phba, vpi);
8302 if (!vport)
8303 goto err_exit;
8304 ndlp = lpfc_findnode_rpi(vport, rpi);
8305 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
8306 goto err_exit;
8307
8308 if (iocbq->iocb.ulpStatus == IOSTAT_LOCAL_REJECT)
8309 lpfc_sli_abts_recover_port(vport, ndlp);
8310 return;
8311
8312 err_exit:
8313 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
8314 "3095 Event Context not found, no "
8315 "action on vpi %d rpi %d status 0x%x, reason 0x%x\n",
8316 iocbq->iocb.ulpContext, iocbq->iocb.ulpStatus,
8317 vpi, rpi);
8318}
8319
8320/* lpfc_sli4_abts_err_handler - handle a failed ABTS request from an SLI4 port.
8321 * @phba: pointer to HBA context object.
8322 * @ndlp: nodelist pointer for the impacted rport.
8323 * @axri: pointer to the wcqe containing the failed exchange.
8324 *
8325 * The driver calls this routine when it receives an ABORT_XRI_FCP CQE from the
8326 * port. The port generates this event when an abort exchange request to an
8327 * rport fails twice in succession with no reply. The abort could be originated
8328 * by the driver or by the port. The ABTS could have been for an ELS or FCP IO.
8329 */
8330void
8331lpfc_sli4_abts_err_handler(struct lpfc_hba *phba,
8332 struct lpfc_nodelist *ndlp,
8333 struct sli4_wcqe_xri_aborted *axri)
8334{
8335 struct lpfc_vport *vport;
8336
8337 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
8338 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
8339 "3115 Node Context not found, driver "
8340 "ignoring abts err event\n");
8341 vport = ndlp->vport;
8342 lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
8343 "3116 Port generated FCP XRI ABORT event on "
8344 "vpi %d rpi %d xri x%x status 0x%x\n",
8345 ndlp->vport->vpi, ndlp->nlp_rpi,
8346 bf_get(lpfc_wcqe_xa_xri, axri),
8347 bf_get(lpfc_wcqe_xa_status, axri));
8348
8349 if (bf_get(lpfc_wcqe_xa_status, axri) == IOSTAT_LOCAL_REJECT)
8350 lpfc_sli_abts_recover_port(vport, ndlp);
8351}
8352
8216/** 8353/**
8217 * lpfc_sli_async_event_handler - ASYNC iocb handler function 8354 * lpfc_sli_async_event_handler - ASYNC iocb handler function
8218 * @phba: Pointer to HBA context object. 8355 * @phba: Pointer to HBA context object.
@@ -8232,63 +8369,58 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
8232{ 8369{
8233 IOCB_t *icmd; 8370 IOCB_t *icmd;
8234 uint16_t evt_code; 8371 uint16_t evt_code;
8235 uint16_t temp;
8236 struct temp_event temp_event_data; 8372 struct temp_event temp_event_data;
8237 struct Scsi_Host *shost; 8373 struct Scsi_Host *shost;
8238 uint32_t *iocb_w; 8374 uint32_t *iocb_w;
8239 8375
8240 icmd = &iocbq->iocb; 8376 icmd = &iocbq->iocb;
8241 evt_code = icmd->un.asyncstat.evt_code; 8377 evt_code = icmd->un.asyncstat.evt_code;
8242 temp = icmd->ulpContext;
8243 8378
8244 if ((evt_code != ASYNC_TEMP_WARN) && 8379 switch (evt_code) {
8245 (evt_code != ASYNC_TEMP_SAFE)) { 8380 case ASYNC_TEMP_WARN:
8381 case ASYNC_TEMP_SAFE:
8382 temp_event_data.data = (uint32_t) icmd->ulpContext;
8383 temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT;
8384 if (evt_code == ASYNC_TEMP_WARN) {
8385 temp_event_data.event_code = LPFC_THRESHOLD_TEMP;
8386 lpfc_printf_log(phba, KERN_ERR, LOG_TEMP,
8387 "0347 Adapter is very hot, please take "
8388 "corrective action. temperature : %d Celsius\n",
8389 (uint32_t) icmd->ulpContext);
8390 } else {
8391 temp_event_data.event_code = LPFC_NORMAL_TEMP;
8392 lpfc_printf_log(phba, KERN_ERR, LOG_TEMP,
8393 "0340 Adapter temperature is OK now. "
8394 "temperature : %d Celsius\n",
8395 (uint32_t) icmd->ulpContext);
8396 }
8397
8398 /* Send temperature change event to applications */
8399 shost = lpfc_shost_from_vport(phba->pport);
8400 fc_host_post_vendor_event(shost, fc_get_event_number(),
8401 sizeof(temp_event_data), (char *) &temp_event_data,
8402 LPFC_NL_VENDOR_ID);
8403 break;
8404 case ASYNC_STATUS_CN:
8405 lpfc_sli_abts_err_handler(phba, iocbq);
8406 break;
8407 default:
8246 iocb_w = (uint32_t *) icmd; 8408 iocb_w = (uint32_t *) icmd;
8247 lpfc_printf_log(phba, 8409 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
8248 KERN_ERR,
8249 LOG_SLI,
8250 "0346 Ring %d handler: unexpected ASYNC_STATUS" 8410 "0346 Ring %d handler: unexpected ASYNC_STATUS"
8251 " evt_code 0x%x\n" 8411 " evt_code 0x%x\n"
8252 "W0 0x%08x W1 0x%08x W2 0x%08x W3 0x%08x\n" 8412 "W0 0x%08x W1 0x%08x W2 0x%08x W3 0x%08x\n"
8253 "W4 0x%08x W5 0x%08x W6 0x%08x W7 0x%08x\n" 8413 "W4 0x%08x W5 0x%08x W6 0x%08x W7 0x%08x\n"
8254 "W8 0x%08x W9 0x%08x W10 0x%08x W11 0x%08x\n" 8414 "W8 0x%08x W9 0x%08x W10 0x%08x W11 0x%08x\n"
8255 "W12 0x%08x W13 0x%08x W14 0x%08x W15 0x%08x\n", 8415 "W12 0x%08x W13 0x%08x W14 0x%08x W15 0x%08x\n",
8256 pring->ringno, 8416 pring->ringno, icmd->un.asyncstat.evt_code,
8257 icmd->un.asyncstat.evt_code,
8258 iocb_w[0], iocb_w[1], iocb_w[2], iocb_w[3], 8417 iocb_w[0], iocb_w[1], iocb_w[2], iocb_w[3],
8259 iocb_w[4], iocb_w[5], iocb_w[6], iocb_w[7], 8418 iocb_w[4], iocb_w[5], iocb_w[6], iocb_w[7],
8260 iocb_w[8], iocb_w[9], iocb_w[10], iocb_w[11], 8419 iocb_w[8], iocb_w[9], iocb_w[10], iocb_w[11],
8261 iocb_w[12], iocb_w[13], iocb_w[14], iocb_w[15]); 8420 iocb_w[12], iocb_w[13], iocb_w[14], iocb_w[15]);
8262 8421
8263 return; 8422 break;
8264 }
8265 temp_event_data.data = (uint32_t)temp;
8266 temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT;
8267 if (evt_code == ASYNC_TEMP_WARN) {
8268 temp_event_data.event_code = LPFC_THRESHOLD_TEMP;
8269 lpfc_printf_log(phba,
8270 KERN_ERR,
8271 LOG_TEMP,
8272 "0347 Adapter is very hot, please take "
8273 "corrective action. temperature : %d Celsius\n",
8274 temp);
8275 }
8276 if (evt_code == ASYNC_TEMP_SAFE) {
8277 temp_event_data.event_code = LPFC_NORMAL_TEMP;
8278 lpfc_printf_log(phba,
8279 KERN_ERR,
8280 LOG_TEMP,
8281 "0340 Adapter temperature is OK now. "
8282 "temperature : %d Celsius\n",
8283 temp);
8284 } 8423 }
8285
8286 /* Send temperature change event to applications */
8287 shost = lpfc_shost_from_vport(phba->pport);
8288 fc_host_post_vendor_event(shost, fc_get_event_number(),
8289 sizeof(temp_event_data), (char *) &temp_event_data,
8290 LPFC_NL_VENDOR_ID);
8291
8292} 8424}
8293 8425
8294 8426
@@ -9247,6 +9379,14 @@ void
9247lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 9379lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
9248 struct lpfc_iocbq *rspiocb) 9380 struct lpfc_iocbq *rspiocb)
9249{ 9381{
9382 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
9383 "3096 ABORT_XRI_CN completing on xri x%x "
9384 "original iotag x%x, abort cmd iotag x%x "
9385 "status 0x%x, reason 0x%x\n",
9386 cmdiocb->iocb.un.acxri.abortContextTag,
9387 cmdiocb->iocb.un.acxri.abortIoTag,
9388 cmdiocb->iotag, rspiocb->iocb.ulpStatus,
9389 rspiocb->iocb.un.ulpWord[4]);
9250 lpfc_sli_release_iocbq(phba, cmdiocb); 9390 lpfc_sli_release_iocbq(phba, cmdiocb);
9251 return; 9391 return;
9252} 9392}