diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-06-17 20:56:39 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-17 23:38:11 -0400 |
commit | 858c9f6c19c6f9bf86cbbc64ce0d17c61d6131b8 (patch) | |
tree | 9591b15b4424066023e375ad0aa33fdd37e1c452 /drivers/scsi/lpfc/lpfc_vport.c | |
parent | 92d7f7b0cde3ad2260e7462b40867b57efd49851 (diff) |
[SCSI] lpfc: bug fixes
Following the NPIV support, the following changes have been accumulated
in the testing and qualification of the driver:
- Fix affinity of ELS ring to slow/deferred event processing
- Fix Ring attention masks
- Defer dev_loss_tmo timeout handling to worker thread
- Consolidate link down error classification for better error checking
- Remove unused/deprecated nlp_initiator_tmr timer
- Fix for async scan - move adapter init code back into pci_probe_one
context. Fix async scan interfaces.
- Expand validation of ability to create vports
- Extract VPI resource cnt from firmware
- Tuning of Login/Reject policies to better deal with overwhelmned targets
- Misc ELS and discovery fixes
- Export the npiv_enable attribute to sysfs
- Mailbox handling fix
- Add debugfs support
- A few other small misc fixes:
- wrong return values, double-frees, bad locking
- Added adapter failure heartbeat
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_vport.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 786125b7ad4..85797dbf547 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -82,7 +82,8 @@ lpfc_alloc_vpi(struct lpfc_hba *phba) | |||
82 | int vpi; | 82 | int vpi; |
83 | 83 | ||
84 | spin_lock_irq(&phba->hbalock); | 84 | spin_lock_irq(&phba->hbalock); |
85 | vpi = find_next_zero_bit(phba->vpi_bmask, phba->max_vpi, 1); | 85 | /* Start at bit 1 because vpi zero is reserved for the physical port */ |
86 | vpi = find_next_zero_bit(phba->vpi_bmask, (phba->max_vpi + 1), 1); | ||
86 | if (vpi > phba->max_vpi) | 87 | if (vpi > phba->max_vpi) |
87 | vpi = 0; | 88 | vpi = 0; |
88 | else | 89 | else |
@@ -131,7 +132,8 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
131 | mb->mbxCommand, mb->mbxStatus, rc); | 132 | mb->mbxCommand, mb->mbxStatus, rc); |
132 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 133 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
133 | kfree(mp); | 134 | kfree(mp); |
134 | mempool_free(pmb, phba->mbox_mem_pool); | 135 | if (rc != MBX_TIMEOUT) |
136 | mempool_free(pmb, phba->mbox_mem_pool); | ||
135 | return -EIO; | 137 | return -EIO; |
136 | } | 138 | } |
137 | 139 | ||
@@ -241,6 +243,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
241 | } | 243 | } |
242 | 244 | ||
243 | vport->vpi = vpi; | 245 | vport->vpi = vpi; |
246 | lpfc_debugfs_initialize(vport); | ||
247 | |||
244 | if (lpfc_vport_sparm(phba, vport)) { | 248 | if (lpfc_vport_sparm(phba, vport)) { |
245 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, | 249 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, |
246 | "%d:1813 Create VPORT failed: vpi:%d " | 250 | "%d:1813 Create VPORT failed: vpi:%d " |
@@ -306,8 +310,16 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
306 | */ | 310 | */ |
307 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 311 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
308 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 312 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
309 | lpfc_set_disctmo(vport); | 313 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { |
310 | lpfc_initial_fdisc(vport); | 314 | lpfc_set_disctmo(vport); |
315 | lpfc_initial_fdisc(vport); | ||
316 | } else { | ||
317 | lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP); | ||
318 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | ||
319 | "%d (%d):0262 No NPIV Fabric " | ||
320 | "support\n", | ||
321 | phba->brd_no, vport->vpi); | ||
322 | } | ||
311 | } else { | 323 | } else { |
312 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 324 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
313 | } | 325 | } |
@@ -383,8 +395,16 @@ enable_vport(struct fc_vport *fc_vport) | |||
383 | */ | 395 | */ |
384 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 396 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
385 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 397 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
386 | lpfc_set_disctmo(vport); | 398 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { |
387 | lpfc_initial_fdisc(vport); | 399 | lpfc_set_disctmo(vport); |
400 | lpfc_initial_fdisc(vport); | ||
401 | } else { | ||
402 | lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP); | ||
403 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | ||
404 | "%d (%d):0264 No NPIV Fabric " | ||
405 | "support\n", | ||
406 | phba->brd_no, vport->vpi); | ||
407 | } | ||
388 | } else { | 408 | } else { |
389 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 409 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
390 | } | 410 | } |
@@ -441,6 +461,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
441 | vport->load_flag |= FC_UNLOADING; | 461 | vport->load_flag |= FC_UNLOADING; |
442 | 462 | ||
443 | kfree(vport->vname); | 463 | kfree(vport->vname); |
464 | lpfc_debugfs_terminate(vport); | ||
444 | fc_remove_host(lpfc_shost_from_vport(vport)); | 465 | fc_remove_host(lpfc_shost_from_vport(vport)); |
445 | scsi_remove_host(lpfc_shost_from_vport(vport)); | 466 | scsi_remove_host(lpfc_shost_from_vport(vport)); |
446 | 467 | ||
@@ -476,12 +497,6 @@ skip_logo: | |||
476 | NLP_EVT_DEVICE_RM); | 497 | NLP_EVT_DEVICE_RM); |
477 | } | 498 | } |
478 | 499 | ||
479 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { | ||
480 | /* free any ndlp's in unused state */ | ||
481 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | ||
482 | lpfc_drop_node(vport, ndlp); | ||
483 | } | ||
484 | |||
485 | lpfc_stop_vport_timers(vport); | 500 | lpfc_stop_vport_timers(vport); |
486 | lpfc_unreg_all_rpis(vport); | 501 | lpfc_unreg_all_rpis(vport); |
487 | lpfc_unreg_default_rpis(vport); | 502 | lpfc_unreg_default_rpis(vport); |