aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJamie Wellnitz <Jamie.Wellnitz@emulex.com>2006-02-28 19:25:38 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-02-28 20:05:42 -0500
commit50eba24f2e0576910a3e23dced769b7be7f3683e (patch)
treee338c335b3b019ebbeb77dc85aad1ea5f29cf1c6 /drivers/scsi/lpfc
parent0c6ac8efa83a465b950fe4dca096cd7ff1937f67 (diff)
[SCSI] lpfc 8.1.2: Modify RSCN handling to unregister rpis on lost FCP_TARGETs immediately
Modify RSCN handling to unregister rpis on lost FCP_TARGETs immediately Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index eab087bf826e..0c982bbc4c77 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -323,6 +323,7 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
323 struct lpfc_sli_ct_request *Response = 323 struct lpfc_sli_ct_request *Response =
324 (struct lpfc_sli_ct_request *) mp->virt; 324 (struct lpfc_sli_ct_request *) mp->virt;
325 struct lpfc_nodelist *ndlp = NULL; 325 struct lpfc_nodelist *ndlp = NULL;
326 struct lpfc_nodelist *next_ndlp;
326 struct lpfc_dmabuf *mlast, *next_mp; 327 struct lpfc_dmabuf *mlast, *next_mp;
327 uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; 328 uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
328 uint32_t Did; 329 uint32_t Did;
@@ -391,8 +392,36 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
391nsout1: 392nsout1:
392 list_del(&head); 393 list_del(&head);
393 394
394 /* Here we are finished in the case RSCN */ 395 /*
396 * The driver has cycled through all Nports in the RSCN payload.
397 * Complete the handling by cleaning up and marking the
398 * current driver state.
399 */
395 if (phba->hba_state == LPFC_HBA_READY) { 400 if (phba->hba_state == LPFC_HBA_READY) {
401
402 /*
403 * Switch ports that connect a loop of multiple targets need
404 * special consideration. The driver wants to unregister the
405 * rpi only on the target that was pulled from the loop. On
406 * RSCN, the driver wants to rediscover an NPort only if the
407 * driver flagged it as NLP_NPR_2B_DISC. Provided adisc is
408 * not enabled and the NPort is not capable of retransmissions
409 * (FC Tape) prevent timing races with the scsi error handler by
410 * unregistering the Nport's RPI. This action causes all
411 * outstanding IO to flush back to the midlayer.
412 */
413 list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
414 nlp_listp) {
415 if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
416 (lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) {
417 if ((phba->cfg_use_adisc == 0) &&
418 !(ndlp->nlp_fcp_info &
419 NLP_FCP_2_DEVICE)) {
420 lpfc_unreg_rpi(phba, ndlp);
421 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
422 }
423 }
424 }
396 lpfc_els_flush_rscn(phba); 425 lpfc_els_flush_rscn(phba);
397 spin_lock_irq(phba->host->host_lock); 426 spin_lock_irq(phba->host->host_lock);
398 phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ 427 phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */