aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_ct.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c301
1 files changed, 196 insertions, 105 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 3d0ccd9b341..da61d8dc044 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2004-2008 Emulex. All rights reserved. *
+ * Copyright (C) 2004-2013 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* *
@@ -25,15 +25,20 @@
#include <linux/blkdev.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/utsname.h>
#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_fc.h>
+#include <scsi/fc/fc_fs.h>
+#include "lpfc_hw4.h"
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_sli4.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -43,14 +48,14 @@
#include "lpfc_vport.h"
#include "lpfc_debugfs.h"
-#define HBA_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver
- * incapable of reporting */
-#define HBA_PORTSPEED_1GBIT 1 /* 1 GBit/sec */
-#define HBA_PORTSPEED_2GBIT 2 /* 2 GBit/sec */
-#define HBA_PORTSPEED_4GBIT 8 /* 4 GBit/sec */
-#define HBA_PORTSPEED_8GBIT 16 /* 8 GBit/sec */
-#define HBA_PORTSPEED_10GBIT 4 /* 10 GBit/sec */
-#define HBA_PORTSPEED_NOT_NEGOTIATED 5 /* Speed not established */
+/* FDMI Port Speed definitions */
+#define HBA_PORTSPEED_1GBIT 0x0001 /* 1 GBit/sec */
+#define HBA_PORTSPEED_2GBIT 0x0002 /* 2 GBit/sec */
+#define HBA_PORTSPEED_4GBIT 0x0008 /* 4 GBit/sec */
+#define HBA_PORTSPEED_10GBIT 0x0004 /* 10 GBit/sec */
+#define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */
+#define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */
+#define HBA_PORTSPEED_UNKNOWN 0x0800 /* Unknown */
#define FOURBYTES 4
@@ -63,7 +68,7 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
{
if (!mp) {
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "0146 Ignoring unsolicted CT No HBQ "
+ "0146 Ignoring unsolicited CT No HBQ "
"status = x%x\n",
piocbq->iocb.ulpStatus);
}
@@ -84,7 +89,6 @@ void
lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *piocbq)
{
-
struct lpfc_dmabuf *mp = NULL;
IOCB_t *icmd = &piocbq->iocb;
int i;
@@ -94,14 +98,18 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct list_head head;
struct lpfc_dmabuf *bdeBuf;
+ if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0)
+ return;
+
if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
} else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
- ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
+ ((icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_RCV_BUFFER_WAITING)) {
/* Not enough posted buffers; Try posting more buffers */
phba->fc_stat.NoRcvBuf++;
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
- lpfc_post_buffer(phba, pring, 2, 1);
+ lpfc_post_buffer(phba, pring, 2);
return;
}
@@ -134,28 +142,48 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
list_del(&head);
} else {
- struct lpfc_iocbq *next;
-
- list_for_each_entry_safe(iocbq, next, &piocbq->list, list) {
+ INIT_LIST_HEAD(&head);
+ list_add_tail(&head, &piocbq->list);
+ list_for_each_entry(iocbq, &head, list) {
icmd = &iocbq->iocb;
if (icmd->ulpBdeCount == 0)
- lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0);
+ lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);
for (i = 0; i < icmd->ulpBdeCount; i++) {
paddr = getPaddr(icmd->un.cont64[i].addrHigh,
icmd->un.cont64[i].addrLow);
mp = lpfc_sli_ringpostbuf_get(phba, pring,
paddr);
size = icmd->un.cont64[i].tus.f.bdeSize;
- lpfc_ct_unsol_buffer(phba, piocbq, mp, size);
+ lpfc_ct_unsol_buffer(phba, iocbq, mp, size);
lpfc_in_buf_free(phba, mp);
}
- list_del(&iocbq->list);
- lpfc_sli_release_iocbq(phba, iocbq);
- lpfc_post_buffer(phba, pring, i, 1);
+ lpfc_post_buffer(phba, pring, i);
}
+ list_del(&head);
}
}
+/**
+ * lpfc_ct_handle_unsol_abort - ct upper level protocol abort handler
+ * @phba: Pointer to HBA context object.
+ * @dmabuf: pointer to a dmabuf that describes the FC sequence
+ *
+ * This function serves as the upper level protocol abort handler for CT
+ * protocol.
+ *
+ * Return 1 if abort has been handled, 0 otherwise.
+ **/
+int
+lpfc_ct_handle_unsol_abort(struct lpfc_hba *phba, struct hbq_dmabuf *dmabuf)
+{
+ int handled;
+
+ /* CT upper level goes through BSG */
+ handled = lpfc_bsg_ct_unsol_abort(phba, dmabuf);
+
+ return handled;
+}
+
static void
lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
{
@@ -212,7 +240,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
else
list_add_tail(&mp->list, &mlist->list);
- bpl->tus.f.bdeFlags = BUFF_USE_RCV;
+ bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
/* build buffer ptr list for IOCB */
bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
@@ -252,7 +280,7 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3;
lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
kfree(buf_ptr);
- ctiocb->context1 = NULL;
+ ctiocb->context3 = NULL;
}
lpfc_sli_release_iocbq(phba, ctiocb);
return 0;
@@ -267,8 +295,6 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
uint32_t tmo, uint8_t retry)
{
struct lpfc_hba *phba = vport->phba;
- struct lpfc_sli *psli = &phba->sli;
- struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
IOCB_t *icmd;
struct lpfc_iocbq *geniocb;
int rc;
@@ -283,7 +309,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
icmd->un.genreq64.bdl.ulpIoTag32 = 0;
icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
- icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
+ icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64));
if (usr_flg)
@@ -302,8 +328,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
/* Fill in rest of iocb */
icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
icmd->un.genreq64.w5.hcsw.Dfctl = 0;
- icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
- icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
+ icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
+ icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
if (!tmo) {
/* FC spec states we need 3 * ratov for CT requests */
@@ -314,6 +340,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
icmd->ulpLe = 1;
icmd->ulpClass = CLASS3;
icmd->ulpContext = ndlp->nlp_rpi;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
/* For GEN_REQUEST64_CR, use the RPI */
@@ -331,7 +359,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
geniocb->vport = vport;
geniocb->retry = retry;
- rc = lpfc_sli_issue_iocb(phba, pring, geniocb, 0);
+ rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
if (rc == IOCB_ERROR) {
lpfc_sli_release_iocbq(phba, geniocb);
@@ -361,9 +389,14 @@ lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
if (!outmp)
return -ENOMEM;
-
+ /*
+ * Form the CT IOCB. The total number of BDEs in this IOCB
+ * is the single command plus response count from
+ * lpfc_alloc_ct_rsp.
+ */
+ cnt += 1;
status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
- cnt+1, 0, retry);
+ cnt, 0, retry);
if (status) {
lpfc_free_ct_rsp(phba, outmp);
return -ENOMEM;
@@ -438,7 +471,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
(!(vport->ct_flags & FC_CT_RFF_ID)) ||
(!vport->cfg_restrict_login)) {
ndlp = lpfc_setup_disc_node(vport, Did);
- if (ndlp) {
+ if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
lpfc_debugfs_disc_trc(vport,
LPFC_DISC_TRC_CT,
"Parse GID_FTrsp: "
@@ -499,6 +532,9 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
SLI_CTNS_GFF_ID,
0, Did) == 0)
vport->num_disc_nodes++;
+ else
+ lpfc_setup_disc_node
+ (vport, Did);
}
else {
lpfc_debugfs_disc_trc(vport,
@@ -543,7 +579,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_dmabuf *outp;
struct lpfc_sli_ct_request *CTrsp;
struct lpfc_nodelist *ndlp;
- int rc, retry;
+ int rc;
/* First save ndlp, before we overwrite it */
ndlp = cmdiocb->context_un.ndlp;
@@ -560,49 +596,43 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
/* Don't bother processing response if vport is being torn down. */
- if (vport->load_flag & FC_UNLOADING)
+ if (vport->load_flag & FC_UNLOADING) {
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
goto out;
+ }
- if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
+ if (lpfc_els_chk_latt(vport)) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0216 Link event during NS query\n");
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
goto out;
}
-
+ if (lpfc_error_lost_link(irsp)) {
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0226 NS query failed due to link event\n");
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
+ goto out;
+ }
if (irsp->ulpStatus) {
/* Check for retry */
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
- retry = 1;
- if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
- switch (irsp->un.ulpWord[4]) {
- case IOERR_NO_RESOURCES:
- /* We don't increment the retry
- * count for this case.
- */
- break;
- case IOERR_LINK_DOWN:
- case IOERR_SLI_ABORTED:
- case IOERR_SLI_DOWN:
- retry = 0;
- break;
- default:
- vport->fc_ns_retry++;
- }
- }
- else
+ if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
+ (irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
+ IOERR_NO_RESOURCES)
vport->fc_ns_retry++;
- if (retry) {
- /* CT command is being retried */
- rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
+ /* CT command is being retried */
+ rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
vport->fc_ns_retry, 0);
- if (rc == 0) {
- /* success */
- goto out;
- }
- }
+ if (rc == 0)
+ goto out;
}
+ if (vport->fc_flag & FC_RSCN_MODE)
+ lpfc_els_flush_rscn(vport);
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"0257 GID_FT Query error: 0x%x 0x%x\n",
@@ -742,7 +772,9 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
retry = 1;
if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
- switch (irsp->un.ulpWord[4]) {
+ switch ((irsp->un.ulpWord[4] &
+ IOERR_PARAM_MASK)) {
+
case IOERR_NO_RESOURCES:
/* We don't increment the retry
* count for this case.
@@ -780,7 +812,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* This is a target port, unregistered port, or the GFF_ID failed */
ndlp = lpfc_setup_disc_node(vport, did);
- if (ndlp) {
+ if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0242 Process x%x GFF "
"NameServer Rsp Data: x%x x%x x%x\n",
@@ -863,12 +895,14 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (irsp->ulpStatus) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
- "0268 NS cmd %x Error (%d %d)\n",
+ "0268 NS cmd x%x Error (x%x x%x)\n",
cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
- ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
- (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED)))
+ (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_SLI_DOWN) ||
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_SLI_ABORTED)))
goto out;
retry = cmdiocb->retry;
@@ -877,7 +911,7 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
retry++;
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
- "0216 Retrying NS cmd %x\n", cmdcode);
+ "0250 Retrying NS cmd %x\n", cmdcode);
rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
if (rc == 0)
goto out;
@@ -1006,7 +1040,7 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return;
}
-static int
+int
lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
size_t size)
{
@@ -1024,8 +1058,10 @@ lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
if (n < size)
n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi);
- if (n < size && vport->vname)
- n += snprintf(symbol + n, size - n, " VName-%s", vport->vname);
+ if (n < size &&
+ strlen(vport->fc_vport->symbolic_name))
+ n += snprintf(symbol + n, size - n, " VName-%s",
+ vport->fc_vport->symbolic_name);
return n;
}
@@ -1033,7 +1069,7 @@ int
lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
size_t size)
{
- char fwrev[16];
+ char fwrev[FW_REV_STR_SIZE];
int n;
lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
@@ -1210,9 +1246,9 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
vport->ct_flags &= ~FC_CT_RFF_ID;
CtReq->CommandResponse.bits.CmdRsp =
be16_to_cpu(SLI_CTNS_RFF_ID);
- CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);;
+ CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
CtReq->un.rff.fbits = FC4_FEATURE_INIT;
- CtReq->un.rff.type_code = FC_FCP_DATA;
+ CtReq->un.rff.type_code = FC_TYPE_FCP;
cmpl = lpfc_cmpl_ct_cmd_rff_id;
break;
}
@@ -1552,8 +1588,10 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
ae->un.SupportSpeed = 0;
+ if (phba->lmt & LMT_16Gb)
+ ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT;
if (phba->lmt & LMT_10Gb)
- ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
+ ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT;
if (phba->lmt & LMT_8Gb)
ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
if (phba->lmt & LMT_4Gb)
@@ -1571,21 +1609,26 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
ae->ad.bits.AttrType = be16_to_cpu(PORT_SPEED);
ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
switch(phba->fc_linkspeed) {
- case LA_1GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
+ case LPFC_LINK_SPEED_1GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
break;
- case LA_2GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
+ case LPFC_LINK_SPEED_2GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
break;
- case LA_4GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
+ case LPFC_LINK_SPEED_4GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
break;
- case LA_8GHZ_LINK:
- ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
+ case LPFC_LINK_SPEED_8GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
break;
- default:
- ae->un.PortSpeed =
- HBA_PORTSPEED_UNKNOWN;
+ case LPFC_LINK_SPEED_10GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
+ break;
+ case LPFC_LINK_SPEED_16GHZ:
+ ae->un.PortSpeed = HBA_PORTSPEED_16GBIT;
+ break;
+ default:
+ ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN;
break;
}
pab->ab.EntryCnt++;
@@ -1690,25 +1733,72 @@ fdmi_cmd_exit:
return 1;
}
+/**
+ * lpfc_delayed_disc_tmo - Timeout handler for delayed discovery timer.
+ * @ptr - Context object of the timer.
+ *
+ * This function set the WORKER_DELAYED_DISC_TMO flag and wake up
+ * the worker thread.
+ **/
+void
+lpfc_delayed_disc_tmo(unsigned long ptr)
+{
+ struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
+ struct lpfc_hba *phba = vport->phba;
+ uint32_t tmo_posted;
+ unsigned long iflag;
+
+ spin_lock_irqsave(&vport->work_port_lock, iflag);
+ tmo_posted = vport->work_port_events & WORKER_DELAYED_DISC_TMO;
+ if (!tmo_posted)
+ vport->work_port_events |= WORKER_DELAYED_DISC_TMO;
+ spin_unlock_irqrestore(&vport->work_port_lock, iflag);
+
+ if (!tmo_posted)
+ lpfc_worker_wake_up(phba);
+ return;
+}
+
+/**
+ * lpfc_delayed_disc_timeout_handler - Function called by worker thread to
+ * handle delayed discovery.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This function start nport discovery of the vport.
+ **/
+void
+lpfc_delayed_disc_timeout_handler(struct lpfc_vport *vport)
+{
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+ spin_lock_irq(shost->host_lock);
+ if (!(vport->fc_flag & FC_DISC_DELAYED)) {
+ spin_unlock_irq(shost->host_lock);
+ return;
+ }
+ vport->fc_flag &= ~FC_DISC_DELAYED;
+ spin_unlock_irq(shost->host_lock);
+
+ lpfc_do_scr_ns_plogi(vport->phba, vport);
+}
+
void
lpfc_fdmi_tmo(unsigned long ptr)
{
struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
struct lpfc_hba *phba = vport->phba;
+ uint32_t tmo_posted;
unsigned long iflag;
spin_lock_irqsave(&vport->work_port_lock, iflag);
- if (!(vport->work_port_events & WORKER_FDMI_TMO)) {
+ tmo_posted = vport->work_port_events & WORKER_FDMI_TMO;
+ if (!tmo_posted)
vport->work_port_events |= WORKER_FDMI_TMO;
- spin_unlock_irqrestore(&vport->work_port_lock, iflag);
+ spin_unlock_irqrestore(&vport->work_port_lock, iflag);
- spin_lock_irqsave(&phba->hbalock, iflag);
- if (phba->work_wait)
- lpfc_worker_wake_up(phba);
- spin_unlock_irqrestore(&phba->hbalock, iflag);
- }
- else
- spin_unlock_irqrestore(&vport->work_port_lock, iflag);
+ if (!tmo_posted)
+ lpfc_worker_wake_up(phba);
+ return;
}
void
@@ -1721,7 +1811,8 @@ lpfc_fdmi_timeout_handler(struct lpfc_vport *vport)
if (init_utsname()->nodename[0] != '\0')
lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
else
- mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
+ mod_timer(&vport->fc_fdmitmo, jiffies +
+ msecs_to_jiffies(1000 * 60));
}
return;
}
@@ -1736,8 +1827,10 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
uint32_t *ptr, str[4];
uint8_t *fwname;
- if (vp->rev.rBit) {
- if (psli->sli_flag & LPFC_SLI2_ACTIVE)
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ snprintf(fwrevision, FW_REV_STR_SIZE, "%s", vp->rev.opFwName);
+ else if (vp->rev.rBit) {
+ if (psli->sli_flag & LPFC_SLI_ACTIVE)
rev = vp->rev.sli2FwRev;
else
rev = vp->rev.sli1FwRev;
@@ -1757,13 +1850,16 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
case 2:
c = 'B';
break;
+ case 3:
+ c = 'X';
+ break;
default:
c = 0;
break;
}
b4 = (rev & 0x0000000f);
- if (psli->sli_flag & LPFC_SLI2_ACTIVE)
+ if (psli->sli_flag & LPFC_SLI_ACTIVE)
fwname = vp->rev.sli2FwName;
else
fwname = vp->rev.sli1FwName;
@@ -1802,12 +1898,7 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
c = (rev & 0x0000ff00) >> 8;
b4 = (rev & 0x000000ff);
- if (flag)
- sprintf(fwrevision, "%d.%d%d%c%d ", b1,
- b2, b3, c, b4);
- else
- sprintf(fwrevision, "%d.%d%d%c%d ", b1,
- b2, b3, c, b4);
+ sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4);
}
return;
}