diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-02-08 18:49:39 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-11 18:52:57 -0500 |
commit | 1b32f6aa9935ab88eac0d608a4b06369f5d9064a (patch) | |
tree | dfca777d4fcd442d33643536963c259a15d67662 /drivers | |
parent | e47c9093531d3406a8ae38acca4ce207ef70cc0e (diff) |
[SCSI] lpfc 8.2.5 : Miscellaneous Fixes
Miscellaneous fixes:
- Fix ERRATT flag which was overlapping
- Allow RESTART mbx commands through when stopped.
- Accept incoming PLOGI when connected to an N_Port.
- Fix NPort to NPort pt2pt problems: ADISC and reg_vpi issues
- Fix vport unloading error that erroneously cleaned up RSCN buffers
- Fix memory leak during repeated unloads - in mbox handling
- Fix link bounce vs FLOGI race conditions
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 8 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 14 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 15 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 16 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 4 |
7 files changed, 41 insertions, 33 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 572c525ad2b5..cbe07d79bd12 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -409,7 +409,7 @@ struct lpfc_hba { | |||
409 | /* This flag is set while issuing */ | 409 | /* This flag is set while issuing */ |
410 | /* INIT_LINK mailbox command */ | 410 | /* INIT_LINK mailbox command */ |
411 | #define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */ | 411 | #define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */ |
412 | #define LS_IGNORE_ERATT 0x3 /* intr handler should ignore ERATT */ | 412 | #define LS_IGNORE_ERATT 0x4 /* intr handler should ignore ERATT */ |
413 | 413 | ||
414 | struct lpfc_sli2_slim *slim2p; | 414 | struct lpfc_sli2_slim *slim2p; |
415 | struct lpfc_dmabuf hbqslimp; | 415 | struct lpfc_dmabuf hbqslimp; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index ef061d97a222..fc48e40c4d29 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1946,11 +1946,13 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1946 | } | 1946 | } |
1947 | 1947 | ||
1948 | /* If HBA encountered an error attention, allow only DUMP | 1948 | /* If HBA encountered an error attention, allow only DUMP |
1949 | * mailbox command until the HBA is restarted. | 1949 | * or RESTART mailbox commands until the HBA is restarted. |
1950 | */ | 1950 | */ |
1951 | if ((phba->pport->stopped) && | 1951 | if ((phba->pport->stopped) && |
1952 | (phba->sysfs_mbox.mbox->mb.mbxCommand | 1952 | (phba->sysfs_mbox.mbox->mb.mbxCommand != |
1953 | != MBX_DUMP_MEMORY)) { | 1953 | MBX_DUMP_MEMORY && |
1954 | phba->sysfs_mbox.mbox->mb.mbxCommand != | ||
1955 | MBX_RESTART)) { | ||
1954 | sysfs_mbox_idle(phba); | 1956 | sysfs_mbox_idle(phba); |
1955 | spin_unlock_irq(&phba->hbalock); | 1957 | spin_unlock_irq(&phba->hbalock); |
1956 | return -EPERM; | 1958 | return -EPERM; |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 39268e6a1a05..60afc8028ff5 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -2046,7 +2046,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2046 | retry = 1; | 2046 | retry = 1; |
2047 | 2047 | ||
2048 | if ((cmd == ELS_CMD_FLOGI) && | 2048 | if ((cmd == ELS_CMD_FLOGI) && |
2049 | (phba->fc_topology != TOPOLOGY_LOOP)) { | 2049 | (phba->fc_topology != TOPOLOGY_LOOP) && |
2050 | !lpfc_error_lost_link(irsp)) { | ||
2050 | /* FLOGI retry policy */ | 2051 | /* FLOGI retry policy */ |
2051 | retry = 1; | 2052 | retry = 1; |
2052 | maxretry = 48; | 2053 | maxretry = 48; |
@@ -4091,8 +4092,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
4091 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); | 4092 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); |
4092 | 4093 | ||
4093 | if (vport->port_state < LPFC_DISC_AUTH) { | 4094 | if (vport->port_state < LPFC_DISC_AUTH) { |
4094 | rjt_err = LSRJT_UNABLE_TPC; | 4095 | if (!(phba->pport->fc_flag & FC_PT2PT) || |
4095 | break; | 4096 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { |
4097 | rjt_err = LSRJT_UNABLE_TPC; | ||
4098 | break; | ||
4099 | } | ||
4100 | /* We get here, and drop thru, if we are PT2PT with | ||
4101 | * another NPort and the other side has initiated | ||
4102 | * the PLOGI before responding to our FLOGI. | ||
4103 | */ | ||
4096 | } | 4104 | } |
4097 | 4105 | ||
4098 | shost = lpfc_shost_from_vport(vport); | 4106 | shost = lpfc_shost_from_vport(vport); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1ee3e62c78a7..25892671bfb0 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -800,21 +800,9 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
800 | writel(control, phba->HCregaddr); | 800 | writel(control, phba->HCregaddr); |
801 | readl(phba->HCregaddr); /* flush */ | 801 | readl(phba->HCregaddr); /* flush */ |
802 | spin_unlock_irq(&phba->hbalock); | 802 | spin_unlock_irq(&phba->hbalock); |
803 | mempool_free(pmb, phba->mbox_mem_pool); | ||
803 | return; | 804 | return; |
804 | 805 | ||
805 | vport->num_disc_nodes = 0; | ||
806 | /* go thru NPR nodes and issue ELS PLOGIs */ | ||
807 | if (vport->fc_npr_cnt) | ||
808 | lpfc_els_disc_plogi(vport); | ||
809 | |||
810 | if (!vport->num_disc_nodes) { | ||
811 | spin_lock_irq(shost->host_lock); | ||
812 | vport->fc_flag &= ~FC_NDISC_ACTIVE; | ||
813 | spin_unlock_irq(shost->host_lock); | ||
814 | } | ||
815 | |||
816 | vport->port_state = LPFC_VPORT_READY; | ||
817 | |||
818 | out: | 806 | out: |
819 | /* Device Discovery completes */ | 807 | /* Device Discovery completes */ |
820 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 808 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
@@ -2484,6 +2472,7 @@ lpfc_disc_start(struct lpfc_vport *vport) | |||
2484 | * continue discovery. | 2472 | * continue discovery. |
2485 | */ | 2473 | */ |
2486 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && | 2474 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
2475 | !(vport->fc_flag & FC_PT2PT) && | ||
2487 | !(vport->fc_flag & FC_RSCN_MODE)) { | 2476 | !(vport->fc_flag & FC_RSCN_MODE)) { |
2488 | lpfc_issue_reg_vpi(phba, vport); | 2477 | lpfc_issue_reg_vpi(phba, vport); |
2489 | return; | 2478 | return; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index e0363bef6d29..99141545c25e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -461,12 +461,21 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
461 | int | 461 | int |
462 | lpfc_hba_down_prep(struct lpfc_hba *phba) | 462 | lpfc_hba_down_prep(struct lpfc_hba *phba) |
463 | { | 463 | { |
464 | struct lpfc_vport **vports; | ||
465 | int i; | ||
464 | /* Disable interrupts */ | 466 | /* Disable interrupts */ |
465 | writel(0, phba->HCregaddr); | 467 | writel(0, phba->HCregaddr); |
466 | readl(phba->HCregaddr); /* flush */ | 468 | readl(phba->HCregaddr); /* flush */ |
467 | 469 | ||
468 | lpfc_cleanup_discovery_resources(phba->pport); | 470 | if (phba->pport->load_flag & FC_UNLOADING) |
469 | return 0; | 471 | lpfc_cleanup_discovery_resources(phba->pport); |
472 | else { | ||
473 | vports = lpfc_create_vport_work_array(phba); | ||
474 | if (vports != NULL) | ||
475 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) | ||
476 | lpfc_cleanup_discovery_resources(vports[i]); | ||
477 | lpfc_destroy_vport_work_array(phba, vports); | ||
478 | } return 0; | ||
470 | } | 479 | } |
471 | 480 | ||
472 | /************************************************************************/ | 481 | /************************************************************************/ |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 01d548375811..d513813f6697 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -645,13 +645,15 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
645 | return 0; | 645 | return 0; |
646 | } | 646 | } |
647 | 647 | ||
648 | /* Check config parameter use-adisc or FCP-2 */ | 648 | if (!(vport->fc_flag & FC_PT2PT)) { |
649 | if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || | 649 | /* Check config parameter use-adisc or FCP-2 */ |
650 | ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { | 650 | if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || |
651 | spin_lock_irq(shost->host_lock); | 651 | ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { |
652 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 652 | spin_lock_irq(shost->host_lock); |
653 | spin_unlock_irq(shost->host_lock); | 653 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
654 | return 1; | 654 | spin_unlock_irq(shost->host_lock); |
655 | return 1; | ||
656 | } | ||
655 | } | 657 | } |
656 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 658 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
657 | lpfc_unreg_rpi(vport, ndlp); | 659 | lpfc_unreg_rpi(vport, ndlp); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fdd01e384e36..456b8ec7753b 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -2404,9 +2404,7 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode) | |||
2404 | if ((pmb->mb.un.varCfgPort.sli_mode == 3) && | 2404 | if ((pmb->mb.un.varCfgPort.sli_mode == 3) && |
2405 | (!pmb->mb.un.varCfgPort.cMA)) { | 2405 | (!pmb->mb.un.varCfgPort.cMA)) { |
2406 | rc = -ENXIO; | 2406 | rc = -ENXIO; |
2407 | goto do_prep_failed; | ||
2408 | } | 2407 | } |
2409 | return rc; | ||
2410 | 2408 | ||
2411 | do_prep_failed: | 2409 | do_prep_failed: |
2412 | mempool_free(pmb, phba->mbox_mem_pool); | 2410 | mempool_free(pmb, phba->mbox_mem_pool); |