diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 301 |
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; } |
