diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-01-11 01:52:54 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-23 12:29:22 -0500 |
commit | 0937282036d9ae798e02c9c69a8b2ef044048855 (patch) | |
tree | 55c8ef65c9c55e74e8985b58396516b3d3b925ad /drivers/scsi/lpfc/lpfc_hbadisc.c | |
parent | 13815c8344a238c204e4f4339b22dc4833c6df0f (diff) |
[SCSI] lpfc 8.2.4 : Miscellaneous Fixes
Miscellaneous Fixes:
- Fix a couple of sparse complaints
- Reset the FCP recovery flag when the node is not a FCP2 device.
- Speed up offline prep delays
- Fixed a memory leak in lpfc_mem_alloc failure path
- Fixed external loopback test.
- Fixed error code returned from the driver when HBA is over heated.
- Correct Max NPIV vport to limits read from adapter
- Add missing locks around fc_flag and FC_NEEDS_REG_VPI
- Add missing hba ids for device identification
- Added support for SET_VARIABLE and MBX_WRITE_WWN mailbox commands
- Changed all temperature event messages from warning to error
- Fix reporting of link speed when link is down
- Added support for MBX_WRITE_WWN mailbox command
- Change del_timer_sync() in ISR to del_timer() in interrupt handler
- Correct instances of beXX_to_cpu() that should be cpu_to_beXX()
- Perform target flush before releasing node references on module unload
- Avoid bogus devloss_tmo messages when driver unloads
- Fix panic when HBA generates ERATT interupt
- Fix mbox race condition and a workaround on back-to-back mailbox commands
- Force NPIV off for pt2pt mode between 2 NPorts
- Stop worker thread before removing fc_host.
- Fix up discovery timeout error case due to missing clear_la
- Tighten mailbox polling code to speed up detection of fast completions
- Only allow DUMP_MEMORY if adapter offline due to overtemp errors
- Added extended error information to the log messages in chip init.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f2b8bc49fe5..644d96012d5 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -114,15 +114,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
114 | 114 | ||
115 | rdata = rport->dd_data; | 115 | rdata = rport->dd_data; |
116 | ndlp = rdata->pnode; | 116 | ndlp = rdata->pnode; |
117 | 117 | if (!ndlp) | |
118 | if (!ndlp) { | ||
119 | if (rport->scsi_target_id != -1) { | ||
120 | printk(KERN_ERR "Cannot find remote node" | ||
121 | " for rport in dev_loss_tmo_callbk x%x\n", | ||
122 | rport->port_id); | ||
123 | } | ||
124 | return; | 118 | return; |
125 | } | ||
126 | 119 | ||
127 | vport = ndlp->vport; | 120 | vport = ndlp->vport; |
128 | phba = vport->phba; | 121 | phba = vport->phba; |
@@ -202,6 +195,12 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
202 | * appropriately we just need to cleanup the ndlp rport info here. | 195 | * appropriately we just need to cleanup the ndlp rport info here. |
203 | */ | 196 | */ |
204 | if (vport->load_flag & FC_UNLOADING) { | 197 | if (vport->load_flag & FC_UNLOADING) { |
198 | if (ndlp->nlp_sid != NLP_NO_SID) { | ||
199 | /* flush the target */ | ||
200 | lpfc_sli_abort_iocb(vport, | ||
201 | &phba->sli.ring[phba->sli.fcp_ring], | ||
202 | ndlp->nlp_sid, 0, LPFC_CTX_TGT); | ||
203 | } | ||
205 | put_node = rdata->pnode != NULL; | 204 | put_node = rdata->pnode != NULL; |
206 | put_rport = ndlp->rport != NULL; | 205 | put_rport = ndlp->rport != NULL; |
207 | rdata->pnode = NULL; | 206 | rdata->pnode = NULL; |
@@ -381,7 +380,7 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
381 | lpfc_handle_latt(phba); | 380 | lpfc_handle_latt(phba); |
382 | vports = lpfc_create_vport_work_array(phba); | 381 | vports = lpfc_create_vport_work_array(phba); |
383 | if (vports != NULL) | 382 | if (vports != NULL) |
384 | for(i = 0; i < LPFC_MAX_VPORTS; i++) { | 383 | for(i = 0; i <= phba->max_vpi; i++) { |
385 | /* | 384 | /* |
386 | * We could have no vports in array if unloading, so if | 385 | * We could have no vports in array if unloading, so if |
387 | * this happens then just use the pport | 386 | * this happens then just use the pport |
@@ -413,7 +412,7 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
413 | vport->work_port_events &= ~work_port_events; | 412 | vport->work_port_events &= ~work_port_events; |
414 | spin_unlock_irq(&vport->work_port_lock); | 413 | spin_unlock_irq(&vport->work_port_lock); |
415 | } | 414 | } |
416 | lpfc_destroy_vport_work_array(vports); | 415 | lpfc_destroy_vport_work_array(phba, vports); |
417 | 416 | ||
418 | pring = &phba->sli.ring[LPFC_ELS_RING]; | 417 | pring = &phba->sli.ring[LPFC_ELS_RING]; |
419 | status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); | 418 | status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); |
@@ -552,6 +551,7 @@ lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2, | |||
552 | void | 551 | void |
553 | lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | 552 | lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) |
554 | { | 553 | { |
554 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
555 | struct lpfc_hba *phba = vport->phba; | 555 | struct lpfc_hba *phba = vport->phba; |
556 | struct lpfc_nodelist *ndlp, *next_ndlp; | 556 | struct lpfc_nodelist *ndlp, *next_ndlp; |
557 | int rc; | 557 | int rc; |
@@ -575,7 +575,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | |||
575 | } | 575 | } |
576 | if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) { | 576 | if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) { |
577 | lpfc_mbx_unreg_vpi(vport); | 577 | lpfc_mbx_unreg_vpi(vport); |
578 | spin_lock_irq(shost->host_lock); | ||
578 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 579 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
580 | spin_unlock_irq(shost->host_lock); | ||
579 | } | 581 | } |
580 | } | 582 | } |
581 | 583 | ||
@@ -629,11 +631,11 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
629 | spin_unlock_irq(&phba->hbalock); | 631 | spin_unlock_irq(&phba->hbalock); |
630 | vports = lpfc_create_vport_work_array(phba); | 632 | vports = lpfc_create_vport_work_array(phba); |
631 | if (vports != NULL) | 633 | if (vports != NULL) |
632 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 634 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
633 | /* Issue a LINK DOWN event to all nodes */ | 635 | /* Issue a LINK DOWN event to all nodes */ |
634 | lpfc_linkdown_port(vports[i]); | 636 | lpfc_linkdown_port(vports[i]); |
635 | } | 637 | } |
636 | lpfc_destroy_vport_work_array(vports); | 638 | lpfc_destroy_vport_work_array(phba, vports); |
637 | /* Clean up any firmware default rpi's */ | 639 | /* Clean up any firmware default rpi's */ |
638 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 640 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
639 | if (mb) { | 641 | if (mb) { |
@@ -738,9 +740,9 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
738 | 740 | ||
739 | vports = lpfc_create_vport_work_array(phba); | 741 | vports = lpfc_create_vport_work_array(phba); |
740 | if (vports != NULL) | 742 | if (vports != NULL) |
741 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) | 743 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) |
742 | lpfc_linkup_port(vports[i]); | 744 | lpfc_linkup_port(vports[i]); |
743 | lpfc_destroy_vport_work_array(vports); | 745 | lpfc_destroy_vport_work_array(phba, vports); |
744 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 746 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) |
745 | lpfc_issue_clear_la(phba, phba->pport); | 747 | lpfc_issue_clear_la(phba, phba->pport); |
746 | 748 | ||
@@ -1319,7 +1321,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1319 | vports = lpfc_create_vport_work_array(phba); | 1321 | vports = lpfc_create_vport_work_array(phba); |
1320 | if (vports != NULL) | 1322 | if (vports != NULL) |
1321 | for(i = 0; | 1323 | for(i = 0; |
1322 | i < LPFC_MAX_VPORTS && vports[i] != NULL; | 1324 | i <= phba->max_vpi && vports[i] != NULL; |
1323 | i++) { | 1325 | i++) { |
1324 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | 1326 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) |
1325 | continue; | 1327 | continue; |
@@ -1335,7 +1337,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1335 | "Fabric support\n"); | 1337 | "Fabric support\n"); |
1336 | } | 1338 | } |
1337 | } | 1339 | } |
1338 | lpfc_destroy_vport_work_array(vports); | 1340 | lpfc_destroy_vport_work_array(phba, vports); |
1339 | lpfc_do_scr_ns_plogi(phba, vport); | 1341 | lpfc_do_scr_ns_plogi(phba, vport); |
1340 | } | 1342 | } |
1341 | 1343 | ||
@@ -1902,7 +1904,8 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport) | |||
1902 | lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox); | 1904 | lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox); |
1903 | mbox->vport = vport; | 1905 | mbox->vport = vport; |
1904 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1906 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1905 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 1907 | mbox->context1 = NULL; |
1908 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | ||
1906 | if (rc == MBX_NOT_FINISHED) { | 1909 | if (rc == MBX_NOT_FINISHED) { |
1907 | mempool_free(mbox, phba->mbox_mem_pool); | 1910 | mempool_free(mbox, phba->mbox_mem_pool); |
1908 | } | 1911 | } |
@@ -1921,7 +1924,8 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) | |||
1921 | lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox); | 1924 | lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox); |
1922 | mbox->vport = vport; | 1925 | mbox->vport = vport; |
1923 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 1926 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
1924 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 1927 | mbox->context1 = NULL; |
1928 | rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); | ||
1925 | if (rc == MBX_NOT_FINISHED) { | 1929 | if (rc == MBX_NOT_FINISHED) { |
1926 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, | 1930 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT, |
1927 | "1815 Could not issue " | 1931 | "1815 Could not issue " |
@@ -2026,7 +2030,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2026 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; | 2030 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; |
2027 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | 2031 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; |
2028 | mbox->vport = vport; | 2032 | mbox->vport = vport; |
2029 | mbox->context2 = 0; | 2033 | mbox->context2 = NULL; |
2030 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 2034 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
2031 | if (rc == MBX_NOT_FINISHED) { | 2035 | if (rc == MBX_NOT_FINISHED) { |
2032 | mempool_free(mbox, phba->mbox_mem_pool); | 2036 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -2702,12 +2706,14 @@ restart_disc: | |||
2702 | clrlaerr = 1; | 2706 | clrlaerr = 1; |
2703 | break; | 2707 | break; |
2704 | 2708 | ||
2709 | case LPFC_LINK_UP: | ||
2710 | lpfc_issue_clear_la(phba, vport); | ||
2711 | /* Drop thru */ | ||
2705 | case LPFC_LINK_UNKNOWN: | 2712 | case LPFC_LINK_UNKNOWN: |
2706 | case LPFC_WARM_START: | 2713 | case LPFC_WARM_START: |
2707 | case LPFC_INIT_START: | 2714 | case LPFC_INIT_START: |
2708 | case LPFC_INIT_MBX_CMDS: | 2715 | case LPFC_INIT_MBX_CMDS: |
2709 | case LPFC_LINK_DOWN: | 2716 | case LPFC_LINK_DOWN: |
2710 | case LPFC_LINK_UP: | ||
2711 | case LPFC_HBA_ERROR: | 2717 | case LPFC_HBA_ERROR: |
2712 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 2718 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
2713 | "0230 Unexpected timeout, hba link " | 2719 | "0230 Unexpected timeout, hba link " |