aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-08-02 11:10:31 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-08-01 13:24:10 -0400
commit51ef4c26891a734bc8416b639ad460a8162926bc (patch)
tree8279e11bf1a0a3200e8aa9bb3d956345ef73533c /drivers/scsi/lpfc/lpfc_hbadisc.c
parent78b2d852a88cd2a55e3ab632109de045d58b83e3 (diff)
[SCSI] lpfc 8.2.2 : Miscellaneous Bug Fixes
- Fix vport ndlp ref counting errors - Fix use after free of ndlp structure - Use the correct flag to check for LOADING setting. - Fix driver unload bugs (related to shost references) after link down or rscn - Fix up HBQ initialization - Fix port_list locking around driver unload. - Fix references to hostdata as a phba - Fix GFFID type offset to work correctly with big endian structure. - Only call pci_disable_msi if the pci_enable_msi succeeded - Fix vport_delete wait/fail if in discovery - Put a reference on the nameservers ndlp when performing CT traffic. - Remove unbalanced hba unlock. - Fix up HBQ processing - Fix lpfc debugfs discovery trace output for ELS rsp cmpl - Send ADISC when rpi is 0 - Stop FDISC retrying forever - Unable to retrieve correct config parameter for vport - Fix sli_validate_fcp_iocb, sli_sum_iocb, sli_abort_iocb to be vport-aware. - Fix index-out-of-range error in iocb. Spotted by Coverity. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index f96ab75ba637..8788f14b1dec 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -83,10 +83,17 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
83 ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); 83 ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
84 84
85 if (ndlp->nlp_sid != NLP_NO_SID) { 85 if (ndlp->nlp_sid != NLP_NO_SID) {
86 lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], 86 lpfc_sli_abort_iocb(ndlp->vport,
87 ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); 87 &phba->sli.ring[phba->sli.fcp_ring],
88 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
88 } 89 }
89 90
91 /*
92 * A device is normally blocked for rediscovery and unblocked when
93 * devloss timeout happens. In case a vport is removed or driver
94 * unloaded before devloss timeout happens, we need to unblock here.
95 */
96 scsi_target_unblock(&rport->dev);
90 return; 97 return;
91} 98}
92 99
@@ -194,8 +201,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
194 if (ndlp->nlp_sid != NLP_NO_SID) { 201 if (ndlp->nlp_sid != NLP_NO_SID) {
195 warn_on = 1; 202 warn_on = 1;
196 /* flush the target */ 203 /* flush the target */
197 lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], 204 lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
198 ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); 205 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
199 } 206 }
200 if (vport->load_flag & FC_UNLOADING) 207 if (vport->load_flag & FC_UNLOADING)
201 warn_on = 0; 208 warn_on = 0;
@@ -348,6 +355,7 @@ lpfc_work_done(struct lpfc_hba *phba)
348 struct lpfc_sli_ring *pring; 355 struct lpfc_sli_ring *pring;
349 uint32_t ha_copy, status, control, work_port_events; 356 uint32_t ha_copy, status, control, work_port_events;
350 struct lpfc_vport **vports; 357 struct lpfc_vport **vports;
358 struct lpfc_vport *vport;
351 int i; 359 int i;
352 360
353 spin_lock_irq(&phba->hbalock); 361 spin_lock_irq(&phba->hbalock);
@@ -365,12 +373,22 @@ lpfc_work_done(struct lpfc_hba *phba)
365 lpfc_handle_latt(phba); 373 lpfc_handle_latt(phba);
366 vports = lpfc_create_vport_work_array(phba); 374 vports = lpfc_create_vport_work_array(phba);
367 if (vports != NULL) 375 if (vports != NULL)
368 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { 376 for(i = 0; i < LPFC_MAX_VPORTS; i++) {
369 work_port_events = vports[i]->work_port_events; 377 /*
378 * We could have no vports in array if unloading, so if
379 * this happens then just use the pport
380 */
381 if (vports[i] == NULL && i == 0)
382 vport = phba->pport;
383 else
384 vport = vports[i];
385 if (vport == NULL)
386 break;
387 work_port_events = vport->work_port_events;
370 if (work_port_events & WORKER_DISC_TMO) 388 if (work_port_events & WORKER_DISC_TMO)
371 lpfc_disc_timeout_handler(vports[i]); 389 lpfc_disc_timeout_handler(vport);
372 if (work_port_events & WORKER_ELS_TMO) 390 if (work_port_events & WORKER_ELS_TMO)
373 lpfc_els_timeout_handler(vports[i]); 391 lpfc_els_timeout_handler(vport);
374 if (work_port_events & WORKER_HB_TMO) 392 if (work_port_events & WORKER_HB_TMO)
375 lpfc_hb_timeout_handler(phba); 393 lpfc_hb_timeout_handler(phba);
376 if (work_port_events & WORKER_MBOX_TMO) 394 if (work_port_events & WORKER_MBOX_TMO)
@@ -378,14 +396,14 @@ lpfc_work_done(struct lpfc_hba *phba)
378 if (work_port_events & WORKER_FABRIC_BLOCK_TMO) 396 if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
379 lpfc_unblock_fabric_iocbs(phba); 397 lpfc_unblock_fabric_iocbs(phba);
380 if (work_port_events & WORKER_FDMI_TMO) 398 if (work_port_events & WORKER_FDMI_TMO)
381 lpfc_fdmi_timeout_handler(vports[i]); 399 lpfc_fdmi_timeout_handler(vport);
382 if (work_port_events & WORKER_RAMP_DOWN_QUEUE) 400 if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
383 lpfc_ramp_down_queue_handler(phba); 401 lpfc_ramp_down_queue_handler(phba);
384 if (work_port_events & WORKER_RAMP_UP_QUEUE) 402 if (work_port_events & WORKER_RAMP_UP_QUEUE)
385 lpfc_ramp_up_queue_handler(phba); 403 lpfc_ramp_up_queue_handler(phba);
386 spin_lock_irq(&vports[i]->work_port_lock); 404 spin_lock_irq(&vport->work_port_lock);
387 vports[i]->work_port_events &= ~work_port_events; 405 vport->work_port_events &= ~work_port_events;
388 spin_unlock_irq(&vports[i]->work_port_lock); 406 spin_unlock_irq(&vport->work_port_lock);
389 } 407 }
390 lpfc_destroy_vport_work_array(vports); 408 lpfc_destroy_vport_work_array(vports);
391 409
@@ -1638,16 +1656,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1638void 1656void
1639lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) 1657lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1640{ 1658{
1641 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1659 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
1642
1643 if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
1644 lpfc_cancel_retry_delay_tmo(vport, ndlp);
1645 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
1646 lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
1647 spin_lock_irq(shost->host_lock);
1648 list_del_init(&ndlp->nlp_listp);
1649 ndlp->nlp_flag &= ~NLP_TARGET_REMOVE;
1650 spin_unlock_irq(shost->host_lock);
1651 lpfc_nlp_put(ndlp); 1660 lpfc_nlp_put(ndlp);
1652} 1661}
1653 1662