diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-11-18 15:39:44 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:01:51 -0500 |
commit | 5ffc266ee7a62741ebee89ede15049ec0f02fa75 (patch) | |
tree | 1ffd531c5b95d3e0c2bf0d905d34f497827ff0ee /drivers/scsi/lpfc/lpfc_els.c | |
parent | c868595d5686e97183bc1ad85502835d81d7a457 (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.c | 40 |
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 | **/ | ||
4539 | static void | ||
4540 | lpfc_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 | ||