aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-11-18 15:39:44 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:51 -0500
commit5ffc266ee7a62741ebee89ede15049ec0f02fa75 (patch)
tree1ffd531c5b95d3e0c2bf0d905d34f497827ff0ee /drivers/scsi/lpfc/lpfc_els.c
parentc868595d5686e97183bc1ad85502835d81d7a457 (diff)
[SCSI] lpfc 8.3.6 : FC Protocol Fixes
FC protocol fixes. - Fix send sequence logic to handle multi SGL IOCBs. - Fix FDISC completion always setting VPORT state to failed. - Ported the fix on reporting of max_vpi to uppper layer. - Fix incorrect number of Vports allowed to be created. - Fixed Dead FCoE port after creating vports. - Added handling of ELS request for Reinstate Recovery Qualifier (RRQ) - Handle unsolicited CT exchange initiator receiving CT exchange ABTS - Migrate LUN queue depth ramp up code to scsi mid-layer. - Made ABTS WQE go to the same WQ as the WQE to be aborted. - Fix Vport does not rediscover after FCF goes away. - Fixed lpfc_unreg_vfi failure after devloss timeout. - Fixed RPI bit leak. - Fix hbq pointer corruption during target discovery. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index e9e423f28f8a..a079bbc03cf8 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -4521,6 +4521,29 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4521} 4521}
4522 4522
4523/** 4523/**
4524 * lpfc_els_rcv_rrq - Process an unsolicited rrq iocb
4525 * @vport: pointer to a host virtual N_Port data structure.
4526 * @cmdiocb: pointer to lpfc command iocb data structure.
4527 * @ndlp: pointer to a node-list data structure.
4528 *
4529 * This routine processes a Reinstate Recovery Qualifier (RRQ) IOCB
4530 * received as an ELS unsolicited event. A request to RRQ shall only
4531 * be accepted if the Originator Nx_Port N_Port_ID or the Responder
4532 * Nx_Port N_Port_ID of the target Exchange is the same as the
4533 * N_Port_ID of the Nx_Port that makes the request. If the RRQ is
4534 * not accepted, an LS_RJT with reason code "Unable to perform
4535 * command request" and reason code explanation "Invalid Originator
4536 * S_ID" shall be returned. For now, we just unconditionally accept
4537 * RRQ from the target.
4538 **/
4539static void
4540lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4541 struct lpfc_nodelist *ndlp)
4542{
4543 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4544}
4545
4546/**
4524 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd 4547 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4525 * @phba: pointer to lpfc hba data structure. 4548 * @phba: pointer to lpfc hba data structure.
4526 * @pmb: pointer to the driver internal queue element for mailbox command. 4549 * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -5636,6 +5659,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5636 if (newnode) 5659 if (newnode)
5637 lpfc_nlp_put(ndlp); 5660 lpfc_nlp_put(ndlp);
5638 break; 5661 break;
5662 case ELS_CMD_RRQ:
5663 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5664 "RCV RRQ: did:x%x/ste:x%x flg:x%x",
5665 did, vport->port_state, ndlp->nlp_flag);
5666
5667 phba->fc_stat.elsRcvRRQ++;
5668 lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
5669 if (newnode)
5670 lpfc_nlp_put(ndlp);
5671 break;
5639 default: 5672 default:
5640 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 5673 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5641 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", 5674 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
@@ -6042,11 +6075,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6042 irsp->ulpStatus, irsp->un.ulpWord[4]); 6075 irsp->ulpStatus, irsp->un.ulpWord[4]);
6043 goto fdisc_failed; 6076 goto fdisc_failed;
6044 } 6077 }
6045 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
6046 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
6047 lpfc_nlp_put(ndlp);
6048 /* giving up on FDISC. Cancel discovery timer */
6049 lpfc_can_disctmo(vport);
6050 spin_lock_irq(shost->host_lock); 6078 spin_lock_irq(shost->host_lock);
6051 vport->fc_flag |= FC_FABRIC; 6079 vport->fc_flag |= FC_FABRIC;
6052 if (vport->phba->fc_topology == TOPOLOGY_LOOP) 6080 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
@@ -6125,6 +6153,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6125 int did = ndlp->nlp_DID; 6153 int did = ndlp->nlp_DID;
6126 int rc; 6154 int rc;
6127 6155
6156 vport->port_state = LPFC_FDISC;
6128 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); 6157 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
6129 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, 6158 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
6130 ELS_CMD_FDISC); 6159 ELS_CMD_FDISC);
@@ -6190,7 +6219,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6190 return 1; 6219 return 1;
6191 } 6220 }
6192 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING); 6221 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
6193 vport->port_state = LPFC_FDISC;
6194 return 0; 6222 return 0;
6195} 6223}
6196 6224