aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-02-08 18:49:39 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-11 18:52:57 -0500
commit1b32f6aa9935ab88eac0d608a4b06369f5d9064a (patch)
treedfca777d4fcd442d33643536963c259a15d67662 /drivers
parente47c9093531d3406a8ae38acca4ce207ef70cc0e (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.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c13
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c16
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c4
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
818out: 806out:
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)
461int 461int
462lpfc_hba_down_prep(struct lpfc_hba *phba) 462lpfc_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
2411do_prep_failed: 2409do_prep_failed:
2412 mempool_free(pmb, phba->mbox_mem_pool); 2410 mempool_free(pmb, phba->mbox_mem_pool);