[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>
This commit is contained in:
parent
13815c8344
commit
0937282036
|
@ -559,8 +559,7 @@ struct lpfc_hba {
|
|||
struct list_head port_list;
|
||||
struct lpfc_vport *pport; /* physical lpfc_vport pointer */
|
||||
uint16_t max_vpi; /* Maximum virtual nports */
|
||||
#define LPFC_MAX_VPI 100 /* Max number of VPI supported */
|
||||
#define LPFC_MAX_VPORTS (LPFC_MAX_VPI+1)/* Max number of VPorts supported */
|
||||
#define LPFC_MAX_VPI 0xFFFF /* Max number of VPI supported */
|
||||
unsigned long *vpi_bmask; /* vpi allocation table */
|
||||
|
||||
/* Data structure used by fabric iocb scheduler */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2004-2007 Emulex. All rights reserved. *
|
||||
* Copyright (C) 2004-2008 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
* www.emulex.com *
|
||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||
|
@ -311,12 +311,14 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
|
|||
|
||||
psli = &phba->sli;
|
||||
|
||||
/* Wait a little for things to settle down, but not
|
||||
* long enough for dev loss timeout to expire.
|
||||
*/
|
||||
for (i = 0; i < psli->num_rings; i++) {
|
||||
pring = &psli->ring[i];
|
||||
/* The linkdown event takes 30 seconds to timeout. */
|
||||
while (pring->txcmplq_cnt) {
|
||||
msleep(10);
|
||||
if (cnt++ > 3000) {
|
||||
if (cnt++ > 500) { /* 5 secs */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_WARNING, LOG_INIT,
|
||||
"0466 Outstanding IO when "
|
||||
|
@ -989,7 +991,7 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
|
|||
spin_lock_irq(&phba->hbalock);
|
||||
if (phba->over_temp_state == HBA_OVER_TEMP) {
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
return -EPERM;
|
||||
return -EACCES;
|
||||
}
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
/* count may include a LF at end of string */
|
||||
|
@ -1782,7 +1784,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
|
|||
if (phba->over_temp_state == HBA_OVER_TEMP) {
|
||||
sysfs_mbox_idle(phba);
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
return -EPERM;
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (off == 0 &&
|
||||
|
@ -1801,9 +1803,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
|
|||
case MBX_DUMP_CONTEXT:
|
||||
case MBX_RUN_DIAGS:
|
||||
case MBX_RESTART:
|
||||
case MBX_FLASH_WR_ULA:
|
||||
case MBX_SET_MASK:
|
||||
case MBX_SET_SLIM:
|
||||
case MBX_SET_DEBUG:
|
||||
if (!(vport->fc_flag & FC_OFFLINE_MODE)) {
|
||||
printk(KERN_WARNING "mbox_read:Command 0x%x "
|
||||
|
@ -1831,6 +1831,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
|
|||
case MBX_LOAD_EXP_ROM:
|
||||
case MBX_BEACON:
|
||||
case MBX_DEL_LD_ENTRY:
|
||||
case MBX_SET_VARIABLE:
|
||||
case MBX_WRITE_WWN:
|
||||
break;
|
||||
case MBX_READ_SPARM64:
|
||||
case MBX_READ_LA:
|
||||
|
@ -1852,6 +1854,17 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
/* If HBA encountered an error attention, allow only DUMP
|
||||
* mailbox command until the HBA is restarted.
|
||||
*/
|
||||
if ((phba->pport->stopped) &&
|
||||
(phba->sysfs_mbox.mbox->mb.mbxCommand
|
||||
!= MBX_DUMP_MEMORY)) {
|
||||
sysfs_mbox_idle(phba);
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
phba->sysfs_mbox.mbox->vport = vport;
|
||||
|
||||
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
|
||||
|
@ -2052,7 +2065,8 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
|
|||
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
|
||||
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
|
@ -2072,7 +2086,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
|
|||
node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
|
||||
else
|
||||
/* fabric is local port if there is no F/FL_Port */
|
||||
node_name = wwn_to_u64(vport->fc_nodename.u.wwn);
|
||||
node_name = 0;
|
||||
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*******************************************************************/
|
||||
|
||||
/*
|
||||
* Fibre Channel SCSI LAN Device Driver CT support
|
||||
* Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS
|
||||
*/
|
||||
|
||||
#include <linux/blkdev.h>
|
||||
|
@ -203,7 +203,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
|
|||
struct lpfc_dmabuf *mp;
|
||||
int cnt, i = 0;
|
||||
|
||||
/* We get chucks of FCELSSIZE */
|
||||
/* We get chunks of FCELSSIZE */
|
||||
cnt = size > FCELSSIZE ? FCELSSIZE: size;
|
||||
|
||||
while (size) {
|
||||
|
@ -1175,7 +1175,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
|||
case SLI_CTNS_GFF_ID:
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
be16_to_cpu(SLI_CTNS_GFF_ID);
|
||||
CtReq->un.gff.PortId = be32_to_cpu(context);
|
||||
CtReq->un.gff.PortId = cpu_to_be32(context);
|
||||
cmpl = lpfc_cmpl_ct_cmd_gff_id;
|
||||
break;
|
||||
|
||||
|
@ -1183,7 +1183,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
|||
vport->ct_flags &= ~FC_CT_RFT_ID;
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
be16_to_cpu(SLI_CTNS_RFT_ID);
|
||||
CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID);
|
||||
CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID);
|
||||
CtReq->un.rft.fcpReg = 1;
|
||||
cmpl = lpfc_cmpl_ct_cmd_rft_id;
|
||||
break;
|
||||
|
@ -1192,7 +1192,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
|||
vport->ct_flags &= ~FC_CT_RNN_ID;
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
be16_to_cpu(SLI_CTNS_RNN_ID);
|
||||
CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID);
|
||||
CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);
|
||||
memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename,
|
||||
sizeof (struct lpfc_name));
|
||||
cmpl = lpfc_cmpl_ct_cmd_rnn_id;
|
||||
|
@ -1202,7 +1202,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
|||
vport->ct_flags &= ~FC_CT_RSPN_ID;
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
be16_to_cpu(SLI_CTNS_RSPN_ID);
|
||||
CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID);
|
||||
CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID);
|
||||
size = sizeof(CtReq->un.rspn.symbname);
|
||||
CtReq->un.rspn.len =
|
||||
lpfc_vport_symbolic_port_name(vport,
|
||||
|
@ -1225,14 +1225,14 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
|||
/* Implement DA_ID Nameserver request */
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
be16_to_cpu(SLI_CTNS_DA_ID);
|
||||
CtReq->un.da_id.port_id = be32_to_cpu(vport->fc_myDID);
|
||||
CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID);
|
||||
cmpl = lpfc_cmpl_ct_cmd_da_id;
|
||||
break;
|
||||
case SLI_CTNS_RFF_ID:
|
||||
vport->ct_flags &= ~FC_CT_RFF_ID;
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
be16_to_cpu(SLI_CTNS_RFF_ID);
|
||||
CtReq->un.rff.PortId = be32_to_cpu(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;
|
||||
cmpl = lpfc_cmpl_ct_cmd_rff_id;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* more details, a copy of which can be found in the file COPYING *
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
/* See Fibre Channel protocol T11 FC-LS for details */
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -392,11 +392,12 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
}
|
||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
|
||||
lpfc_mbx_unreg_vpi(vport);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
}
|
||||
|
||||
ndlp->nlp_sid = irsp->un.ulpWord[4] & Mask_DID;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
|
||||
|
||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED &&
|
||||
|
@ -484,6 +485,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
|
||||
/* If we are pt2pt with another NPort, force NPIV off! */
|
||||
phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_PT2PT;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
@ -2068,7 +2072,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
|
||||
{
|
||||
struct lpfc_dmabuf *buf_ptr;
|
||||
|
@ -2086,7 +2090,7 @@ lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr)
|
||||
{
|
||||
lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
|
||||
|
@ -2976,10 +2980,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
"RCV RSCN defer: did:x%x/ste:x%x flg:x%x",
|
||||
ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_RSCN_DEFERRED;
|
||||
if ((rscn_cnt < FC_MAX_HOLD_RSCN) &&
|
||||
!(vport->fc_flag & FC_RSCN_DISCOVERY)) {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_RSCN_MODE;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
if (rscn_cnt) {
|
||||
|
@ -3008,7 +3012,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
vport->fc_rscn_id_cnt, vport->fc_flag,
|
||||
vport->port_state);
|
||||
} else {
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_RSCN_DISCOVERY;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
/* ReDiscovery RSCN */
|
||||
|
@ -3023,7 +3026,9 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
|||
|
||||
/* send RECOVERY event for ALL nodes that match RSCN payload */
|
||||
lpfc_rscn_recovery_check(vport);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_RSCN_DEFERRED;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3307,13 +3312,13 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
status |= 0x4;
|
||||
|
||||
rps_rsp->rsvd1 = 0;
|
||||
rps_rsp->portStatus = be16_to_cpu(status);
|
||||
rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt);
|
||||
rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt);
|
||||
rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt);
|
||||
rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt);
|
||||
rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord);
|
||||
rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt);
|
||||
rps_rsp->portStatus = cpu_to_be16(status);
|
||||
rps_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
|
||||
rps_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
|
||||
rps_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
|
||||
rps_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
|
||||
rps_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
|
||||
rps_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
|
||||
/* Xmit ELS RPS ACC response tag <ulpIoTag> */
|
||||
lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
|
||||
"0118 Xmit ELS RPS ACC response tag x%x xri x%x, "
|
||||
|
@ -4276,7 +4281,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
if (mb->mbxStatus) {
|
||||
|
@ -4297,7 +4304,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
default:
|
||||
/* Try to recover from this error */
|
||||
lpfc_mbx_unreg_vpi(vport);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_initial_fdisc(vport);
|
||||
break;
|
||||
}
|
||||
|
@ -4316,6 +4325,7 @@ static void
|
|||
lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
|
||||
struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
LPFC_MBOXQ_t *mbox;
|
||||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
|
@ -4327,7 +4337,9 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
|
|||
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
|
||||
== MBX_NOT_FINISHED) {
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
||||
|
@ -4339,7 +4351,9 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
|
|||
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
||||
"0254 Register VPI: no memory\n");
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
}
|
||||
|
@ -4412,7 +4426,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
|||
lpfc_unreg_rpi(vport, np);
|
||||
}
|
||||
lpfc_mbx_unreg_vpi(vport);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
|
||||
if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
|
||||
|
|
|
@ -114,15 +114,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
|||
|
||||
rdata = rport->dd_data;
|
||||
ndlp = rdata->pnode;
|
||||
|
||||
if (!ndlp) {
|
||||
if (rport->scsi_target_id != -1) {
|
||||
printk(KERN_ERR "Cannot find remote node"
|
||||
" for rport in dev_loss_tmo_callbk x%x\n",
|
||||
rport->port_id);
|
||||
}
|
||||
if (!ndlp)
|
||||
return;
|
||||
}
|
||||
|
||||
vport = ndlp->vport;
|
||||
phba = vport->phba;
|
||||
|
@ -202,6 +195,12 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
|
|||
* appropriately we just need to cleanup the ndlp rport info here.
|
||||
*/
|
||||
if (vport->load_flag & FC_UNLOADING) {
|
||||
if (ndlp->nlp_sid != NLP_NO_SID) {
|
||||
/* flush the target */
|
||||
lpfc_sli_abort_iocb(vport,
|
||||
&phba->sli.ring[phba->sli.fcp_ring],
|
||||
ndlp->nlp_sid, 0, LPFC_CTX_TGT);
|
||||
}
|
||||
put_node = rdata->pnode != NULL;
|
||||
put_rport = ndlp->rport != NULL;
|
||||
rdata->pnode = NULL;
|
||||
|
@ -381,7 +380,7 @@ lpfc_work_done(struct lpfc_hba *phba)
|
|||
lpfc_handle_latt(phba);
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS; i++) {
|
||||
for(i = 0; i <= phba->max_vpi; i++) {
|
||||
/*
|
||||
* We could have no vports in array if unloading, so if
|
||||
* this happens then just use the pport
|
||||
|
@ -413,7 +412,7 @@ lpfc_work_done(struct lpfc_hba *phba)
|
|||
vport->work_port_events &= ~work_port_events;
|
||||
spin_unlock_irq(&vport->work_port_lock);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
|
||||
pring = &phba->sli.ring[LPFC_ELS_RING];
|
||||
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,
|
|||
void
|
||||
lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_nodelist *ndlp, *next_ndlp;
|
||||
int rc;
|
||||
|
@ -575,7 +575,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
|
|||
}
|
||||
if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) {
|
||||
lpfc_mbx_unreg_vpi(vport);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -629,11 +631,11 @@ lpfc_linkdown(struct lpfc_hba *phba)
|
|||
spin_unlock_irq(&phba->hbalock);
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
/* Issue a LINK DOWN event to all nodes */
|
||||
lpfc_linkdown_port(vports[i]);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
/* Clean up any firmware default rpi's */
|
||||
mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mb) {
|
||||
|
@ -738,9 +740,9 @@ lpfc_linkup(struct lpfc_hba *phba)
|
|||
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++)
|
||||
lpfc_linkup_port(vports[i]);
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
|
||||
lpfc_issue_clear_la(phba, phba->pport);
|
||||
|
||||
|
@ -1319,7 +1321,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0;
|
||||
i < LPFC_MAX_VPORTS && vports[i] != NULL;
|
||||
i <= phba->max_vpi && vports[i] != NULL;
|
||||
i++) {
|
||||
if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
|
||||
continue;
|
||||
|
@ -1335,7 +1337,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
"Fabric support\n");
|
||||
}
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
lpfc_do_scr_ns_plogi(phba, vport);
|
||||
}
|
||||
|
||||
|
@ -1902,7 +1904,8 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport)
|
|||
lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox);
|
||||
mbox->vport = vport;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
|
||||
mbox->context1 = NULL;
|
||||
rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
}
|
||||
|
@ -1921,7 +1924,8 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport)
|
|||
lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox);
|
||||
mbox->vport = vport;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
|
||||
mbox->context1 = NULL;
|
||||
rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
|
||||
"1815 Could not issue "
|
||||
|
@ -2026,7 +2030,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
|
||||
mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
|
||||
mbox->vport = vport;
|
||||
mbox->context2 = 0;
|
||||
mbox->context2 = NULL;
|
||||
rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
|
@ -2702,12 +2706,14 @@ restart_disc:
|
|||
clrlaerr = 1;
|
||||
break;
|
||||
|
||||
case LPFC_LINK_UP:
|
||||
lpfc_issue_clear_la(phba, vport);
|
||||
/* Drop thru */
|
||||
case LPFC_LINK_UNKNOWN:
|
||||
case LPFC_WARM_START:
|
||||
case LPFC_INIT_START:
|
||||
case LPFC_INIT_MBX_CMDS:
|
||||
case LPFC_LINK_DOWN:
|
||||
case LPFC_LINK_UP:
|
||||
case LPFC_HBA_ERROR:
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
|
||||
"0230 Unexpected timeout, hba link "
|
||||
|
|
|
@ -1279,7 +1279,7 @@ typedef struct { /* FireFly BIU registers */
|
|||
#define MBX_DEL_LD_ENTRY 0x1D
|
||||
#define MBX_RUN_PROGRAM 0x1E
|
||||
#define MBX_SET_MASK 0x20
|
||||
#define MBX_SET_SLIM 0x21
|
||||
#define MBX_SET_VARIABLE 0x21
|
||||
#define MBX_UNREG_D_ID 0x23
|
||||
#define MBX_KILL_BOARD 0x24
|
||||
#define MBX_CONFIG_FARP 0x25
|
||||
|
@ -1301,7 +1301,7 @@ typedef struct { /* FireFly BIU registers */
|
|||
#define MBX_REG_VNPID 0x96
|
||||
#define MBX_UNREG_VNPID 0x97
|
||||
|
||||
#define MBX_FLASH_WR_ULA 0x98
|
||||
#define MBX_WRITE_WWN 0x98
|
||||
#define MBX_SET_DEBUG 0x99
|
||||
#define MBX_LOAD_EXP_ROM 0x9C
|
||||
|
||||
|
@ -3227,6 +3227,8 @@ lpfc_is_LC_HBA(unsigned short device)
|
|||
(device == PCI_DEVICE_ID_BSMB) ||
|
||||
(device == PCI_DEVICE_ID_ZMID) ||
|
||||
(device == PCI_DEVICE_ID_ZSMB) ||
|
||||
(device == PCI_DEVICE_ID_SAT_MID) ||
|
||||
(device == PCI_DEVICE_ID_SAT_SMB) ||
|
||||
(device == PCI_DEVICE_ID_RFLY))
|
||||
return 1;
|
||||
else
|
||||
|
|
|
@ -484,6 +484,9 @@ lpfc_hba_down_post(struct lpfc_hba *phba)
|
|||
struct lpfc_sli *psli = &phba->sli;
|
||||
struct lpfc_sli_ring *pring;
|
||||
struct lpfc_dmabuf *mp, *next_mp;
|
||||
struct lpfc_iocbq *iocb;
|
||||
IOCB_t *cmd = NULL;
|
||||
LIST_HEAD(completions);
|
||||
int i;
|
||||
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
|
||||
|
@ -499,10 +502,36 @@ lpfc_hba_down_post(struct lpfc_hba *phba)
|
|||
}
|
||||
}
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
for (i = 0; i < psli->num_rings; i++) {
|
||||
pring = &psli->ring[i];
|
||||
|
||||
/* At this point in time the HBA is either reset or DOA. Either
|
||||
* way, nothing should be on txcmplq as it will NEVER complete.
|
||||
*/
|
||||
list_splice_init(&pring->txcmplq, &completions);
|
||||
pring->txcmplq_cnt = 0;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
while (!list_empty(&completions)) {
|
||||
iocb = list_get_first(&completions, struct lpfc_iocbq,
|
||||
list);
|
||||
cmd = &iocb->iocb;
|
||||
list_del_init(&iocb->list);
|
||||
|
||||
if (!iocb->iocb_cmpl)
|
||||
lpfc_sli_release_iocbq(phba, iocb);
|
||||
else {
|
||||
cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
|
||||
cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
|
||||
(iocb->iocb_cmpl) (phba, iocb, iocb);
|
||||
}
|
||||
}
|
||||
|
||||
lpfc_sli_abort_iocb_ring(phba, pring);
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
}
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -641,6 +670,26 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_offline_eratt(struct lpfc_hba *phba)
|
||||
{
|
||||
struct lpfc_sli *psli = &phba->sli;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
lpfc_offline_prep(phba);
|
||||
|
||||
lpfc_offline(phba);
|
||||
lpfc_reset_barrier(phba);
|
||||
lpfc_sli_brdreset(phba);
|
||||
lpfc_hba_down_post(phba);
|
||||
lpfc_sli_brdready(phba, HS_MBRDY);
|
||||
lpfc_unblock_mgmt_io(phba);
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* lpfc_handle_eratt */
|
||||
|
@ -681,14 +730,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0;
|
||||
i < LPFC_MAX_VPORTS && vports[i] != NULL;
|
||||
i <= phba->max_vpi && vports[i] != NULL;
|
||||
i++){
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vports[i]->fc_flag |= FC_ESTABLISH_LINK;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
@ -737,14 +786,9 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|||
| PCI_VENDOR_ID_EMULEX);
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||
phba->over_temp_state = HBA_OVER_TEMP;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
lpfc_offline_prep(phba);
|
||||
lpfc_offline(phba);
|
||||
lpfc_unblock_mgmt_io(phba);
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
lpfc_hba_down_post(phba);
|
||||
lpfc_offline_eratt(phba);
|
||||
|
||||
} else {
|
||||
/* The if clause above forces this code path when the status
|
||||
|
@ -763,14 +807,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
|
|||
sizeof(event_data), (char *) &event_data,
|
||||
SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
lpfc_offline_prep(phba);
|
||||
lpfc_offline(phba);
|
||||
lpfc_unblock_mgmt_io(phba);
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
lpfc_hba_down_post(phba);
|
||||
lpfc_offline_eratt(phba);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -790,21 +827,25 @@ lpfc_handle_latt(struct lpfc_hba *phba)
|
|||
LPFC_MBOXQ_t *pmb;
|
||||
volatile uint32_t control;
|
||||
struct lpfc_dmabuf *mp;
|
||||
int rc = -ENOMEM;
|
||||
int rc = 0;
|
||||
|
||||
pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!pmb)
|
||||
if (!pmb) {
|
||||
rc = 1;
|
||||
goto lpfc_handle_latt_err_exit;
|
||||
}
|
||||
|
||||
mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
|
||||
if (!mp)
|
||||
if (!mp) {
|
||||
rc = 2;
|
||||
goto lpfc_handle_latt_free_pmb;
|
||||
}
|
||||
|
||||
mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
|
||||
if (!mp->virt)
|
||||
if (!mp->virt) {
|
||||
rc = 3;
|
||||
goto lpfc_handle_latt_free_mp;
|
||||
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
/* Cleanup any outstanding ELS commands */
|
||||
lpfc_els_flush_all_cmd(phba);
|
||||
|
@ -814,8 +855,10 @@ lpfc_handle_latt(struct lpfc_hba *phba)
|
|||
pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
|
||||
pmb->vport = vport;
|
||||
rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT);
|
||||
if (rc == MBX_NOT_FINISHED)
|
||||
if (rc == MBX_NOT_FINISHED) {
|
||||
rc = 4;
|
||||
goto lpfc_handle_latt_free_mbuf;
|
||||
}
|
||||
|
||||
/* Clear Link Attention in HA REG */
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
|
@ -847,10 +890,8 @@ lpfc_handle_latt_err_exit:
|
|||
lpfc_linkdown(phba);
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
|
||||
/* The other case is an error from issue_mbox */
|
||||
if (rc == -ENOMEM)
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
|
||||
"0300 READ_LA: no buffers\n");
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
|
||||
"0300 LATT: Cannot issue READ_LA: Data:%d\n", rc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1421,14 +1462,14 @@ lpfc_establish_link_tmo(unsigned long ptr)
|
|||
phba->pport->fc_flag, phba->pport->port_state);
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
struct Scsi_Host *shost;
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
spin_lock_irqsave(shost->host_lock, iflag);
|
||||
vports[i]->fc_flag &= ~FC_ESTABLISH_LINK;
|
||||
spin_unlock_irqrestore(shost->host_lock, iflag);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1493,7 +1534,7 @@ lpfc_online(struct lpfc_hba *phba)
|
|||
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
struct Scsi_Host *shost;
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
|
@ -1502,7 +1543,7 @@ lpfc_online(struct lpfc_hba *phba)
|
|||
vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
|
||||
lpfc_unblock_mgmt_io(phba);
|
||||
return 0;
|
||||
|
@ -1536,7 +1577,7 @@ lpfc_offline_prep(struct lpfc_hba * phba)
|
|||
/* Issue an unreg_login to all nodes on all vports */
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL) {
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
struct Scsi_Host *shost;
|
||||
|
||||
if (vports[i]->load_flag & FC_UNLOADING)
|
||||
|
@ -1560,7 +1601,7 @@ lpfc_offline_prep(struct lpfc_hba * phba)
|
|||
}
|
||||
}
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
|
||||
lpfc_sli_flush_mbox_queue(phba);
|
||||
}
|
||||
|
@ -1579,9 +1620,9 @@ lpfc_offline(struct lpfc_hba *phba)
|
|||
lpfc_stop_phba_timers(phba);
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++)
|
||||
lpfc_stop_vport_timers(vports[i]);
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"0460 Bring Adapter offline\n");
|
||||
/* Bring down the SLI Layer and cleanup. The HBA is offline
|
||||
|
@ -1592,14 +1633,14 @@ lpfc_offline(struct lpfc_hba *phba)
|
|||
spin_unlock_irq(&phba->hbalock);
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vports[i]->work_port_events = 0;
|
||||
vports[i]->fc_flag |= FC_OFFLINE_MODE;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -2149,6 +2190,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
|
|||
kfree(vport->vname);
|
||||
lpfc_free_sysfs_attr(vport);
|
||||
|
||||
kthread_stop(phba->worker_thread);
|
||||
|
||||
fc_remove_host(shost);
|
||||
scsi_remove_host(shost);
|
||||
lpfc_cleanup(vport);
|
||||
|
@ -2168,8 +2211,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
|
|||
|
||||
lpfc_debugfs_terminate(vport);
|
||||
|
||||
kthread_stop(phba->worker_thread);
|
||||
|
||||
/* Release the irq reservation */
|
||||
free_irq(phba->pcidev->irq, phba);
|
||||
if (phba->using_msi)
|
||||
|
|
|
@ -896,7 +896,7 @@ lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
|
|||
case MBX_DOWN_LOAD: /* 0x1C */
|
||||
case MBX_DEL_LD_ENTRY: /* 0x1D */
|
||||
case MBX_LOAD_AREA: /* 0x81 */
|
||||
case MBX_FLASH_WR_ULA: /* 0x98 */
|
||||
case MBX_WRITE_WWN: /* 0x98 */
|
||||
case MBX_LOAD_EXP_ROM: /* 0x9C */
|
||||
return LPFC_MBOX_TMO_FLASH_CMD;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
|
|||
|
||||
fail_free_hbq_pool:
|
||||
lpfc_sli_hbqbuf_free_all(phba);
|
||||
pci_pool_destroy(phba->lpfc_hbq_pool);
|
||||
fail_free_nlp_mem_pool:
|
||||
mempool_destroy(phba->nlp_mem_pool);
|
||||
phba->nlp_mem_pool = NULL;
|
||||
|
|
|
@ -130,7 +130,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
|
|||
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
shost_for_each_device(sdev, shost) {
|
||||
new_queue_depth =
|
||||
|
@ -151,7 +151,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
|
|||
new_queue_depth);
|
||||
}
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
atomic_set(&phba->num_rsrc_err, 0);
|
||||
atomic_set(&phba->num_cmd_success, 0);
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
|
|||
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL)
|
||||
for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
|
||||
for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
shost = lpfc_shost_from_vport(vports[i]);
|
||||
shost_for_each_device(sdev, shost) {
|
||||
if (sdev->ordered_tags)
|
||||
|
@ -179,7 +179,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
|
|||
sdev->queue_depth+1);
|
||||
}
|
||||
}
|
||||
lpfc_destroy_vport_work_array(vports);
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
atomic_set(&phba->num_rsrc_err, 0);
|
||||
atomic_set(&phba->num_cmd_success, 0);
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
|
|||
(num_bde * sizeof (struct ulp_bde64));
|
||||
iocb_cmd->ulpBdeCount = 1;
|
||||
iocb_cmd->ulpLe = 1;
|
||||
fcp_cmnd->fcpDl = be32_to_cpu(scsi_bufflen(scsi_cmnd));
|
||||
fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -763,6 +763,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
|
|||
piocbq->iocb.ulpContext = pnode->nlp_rpi;
|
||||
if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE)
|
||||
piocbq->iocb.ulpFCP2Rcvy = 1;
|
||||
else
|
||||
piocbq->iocb.ulpFCP2Rcvy = 0;
|
||||
|
||||
piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f);
|
||||
piocbq->context1 = lpfc_cmd;
|
||||
|
|
|
@ -716,7 +716,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
|
|||
case MBX_DEL_LD_ENTRY:
|
||||
case MBX_RUN_PROGRAM:
|
||||
case MBX_SET_MASK:
|
||||
case MBX_SET_SLIM:
|
||||
case MBX_SET_VARIABLE:
|
||||
case MBX_UNREG_D_ID:
|
||||
case MBX_KILL_BOARD:
|
||||
case MBX_CONFIG_FARP:
|
||||
|
@ -728,7 +728,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
|
|||
case MBX_READ_RPI64:
|
||||
case MBX_REG_LOGIN64:
|
||||
case MBX_READ_LA64:
|
||||
case MBX_FLASH_WR_ULA:
|
||||
case MBX_WRITE_WWN:
|
||||
case MBX_SET_DEBUG:
|
||||
case MBX_LOAD_EXP_ROM:
|
||||
case MBX_ASYNCEVT_ENABLE:
|
||||
|
@ -2182,7 +2182,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
|
|||
<status> */
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"0436 Adapter failed to init, "
|
||||
"timeout, status reg x%x\n", status);
|
||||
"timeout, status reg x%x, "
|
||||
"FW Data: A8 x%x AC x%x\n", status,
|
||||
readl(phba->MBslimaddr + 0xa8),
|
||||
readl(phba->MBslimaddr + 0xac));
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -2194,7 +2197,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
|
|||
<status> */
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"0437 Adapter failed to init, "
|
||||
"chipset, status reg x%x\n", status);
|
||||
"chipset, status reg x%x, "
|
||||
"FW Data: A8 x%x AC x%x\n", status,
|
||||
readl(phba->MBslimaddr + 0xa8),
|
||||
readl(phba->MBslimaddr + 0xac));
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -2222,7 +2228,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
|
|||
/* Adapter failed to init, chipset, status reg <status> */
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"0438 Adapter failed to init, chipset, "
|
||||
"status reg x%x\n", status);
|
||||
"status reg x%x, "
|
||||
"FW Data: A8 x%x AC x%x\n", status,
|
||||
readl(phba->MBslimaddr + 0xa8),
|
||||
readl(phba->MBslimaddr + 0xac));
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -2581,6 +2590,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
uint32_t status, evtctr;
|
||||
uint32_t ha_copy;
|
||||
int i;
|
||||
unsigned long timeout;
|
||||
unsigned long drvr_flag = 0;
|
||||
volatile uint32_t word0, ldata;
|
||||
void __iomem *to_slim;
|
||||
|
@ -2756,18 +2766,24 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
}
|
||||
|
||||
wmb();
|
||||
/* interrupt board to doit right away */
|
||||
writel(CA_MBATT, phba->CAregaddr);
|
||||
readl(phba->CAregaddr); /* flush */
|
||||
|
||||
switch (flag) {
|
||||
case MBX_NOWAIT:
|
||||
/* Don't wait for it to finish, just return */
|
||||
/* Set up reference to mailbox command */
|
||||
psli->mbox_active = pmbox;
|
||||
/* Interrupt board to do it */
|
||||
writel(CA_MBATT, phba->CAregaddr);
|
||||
readl(phba->CAregaddr); /* flush */
|
||||
/* Don't wait for it to finish, just return */
|
||||
break;
|
||||
|
||||
case MBX_POLL:
|
||||
/* Set up null reference to mailbox command */
|
||||
psli->mbox_active = NULL;
|
||||
/* Interrupt board to do it */
|
||||
writel(CA_MBATT, phba->CAregaddr);
|
||||
readl(phba->CAregaddr); /* flush */
|
||||
|
||||
if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
|
||||
/* First read mbox status word */
|
||||
word0 = *((volatile uint32_t *)&phba->slim2p->mbx);
|
||||
|
@ -2779,15 +2795,15 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
|
||||
/* Read the HBA Host Attention Register */
|
||||
ha_copy = readl(phba->HAregaddr);
|
||||
|
||||
i = lpfc_mbox_tmo_val(phba, mb->mbxCommand);
|
||||
i *= 1000; /* Convert to ms */
|
||||
|
||||
timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba,
|
||||
mb->mbxCommand) *
|
||||
1000) + jiffies;
|
||||
i = 0;
|
||||
/* Wait for command to complete */
|
||||
while (((word0 & OWN_CHIP) == OWN_CHIP) ||
|
||||
(!(ha_copy & HA_MBATT) &&
|
||||
(phba->link_state > LPFC_WARM_START))) {
|
||||
if (i-- <= 0) {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||
spin_unlock_irqrestore(&phba->hbalock,
|
||||
drvr_flag);
|
||||
|
@ -2800,12 +2816,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
|||
&& (evtctr != psli->slistat.mbox_event))
|
||||
break;
|
||||
|
||||
spin_unlock_irqrestore(&phba->hbalock,
|
||||
drvr_flag);
|
||||
|
||||
msleep(1);
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, drvr_flag);
|
||||
if (i++ > 10) {
|
||||
spin_unlock_irqrestore(&phba->hbalock,
|
||||
drvr_flag);
|
||||
msleep(1);
|
||||
spin_lock_irqsave(&phba->hbalock, drvr_flag);
|
||||
}
|
||||
|
||||
if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
|
||||
/* First copy command data */
|
||||
|
@ -3065,7 +3081,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
|
|||
if (evt_code == ASYNC_TEMP_WARN) {
|
||||
temp_event_data.event_code = LPFC_THRESHOLD_TEMP;
|
||||
lpfc_printf_log(phba,
|
||||
KERN_WARNING,
|
||||
KERN_ERR,
|
||||
LOG_TEMP,
|
||||
"0347 Adapter is very hot, please take "
|
||||
"corrective action. temperature : %d Celsius\n",
|
||||
|
@ -3074,7 +3090,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
|
|||
if (evt_code == ASYNC_TEMP_SAFE) {
|
||||
temp_event_data.event_code = LPFC_NORMAL_TEMP;
|
||||
lpfc_printf_log(phba,
|
||||
KERN_INFO,
|
||||
KERN_ERR,
|
||||
LOG_TEMP,
|
||||
"0340 Adapter temperature is OK now. "
|
||||
"temperature : %d Celsius\n",
|
||||
|
@ -4047,7 +4063,6 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (work_ha_copy & HA_ERATT) {
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
/*
|
||||
* There was a link/board error. Read the
|
||||
* status register to retrieve the error event
|
||||
|
@ -4079,7 +4094,7 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
* Stray Mailbox Interrupt, mbxCommand <cmd>
|
||||
* mbxStatus <status>
|
||||
*/
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX |
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX |
|
||||
LOG_SLI,
|
||||
"(%d):0304 Stray Mailbox "
|
||||
"Interrupt mbxCommand x%x "
|
||||
|
@ -4087,51 +4102,60 @@ lpfc_intr_handler(int irq, void *dev_id)
|
|||
(vport ? vport->vpi : 0),
|
||||
pmbox->mbxCommand,
|
||||
pmbox->mbxStatus);
|
||||
}
|
||||
phba->last_completion_time = jiffies;
|
||||
del_timer_sync(&phba->sli.mbox_tmo);
|
||||
/* clear mailbox attention bit */
|
||||
work_ha_copy &= ~HA_MBATT;
|
||||
} else {
|
||||
phba->last_completion_time = jiffies;
|
||||
del_timer(&phba->sli.mbox_tmo);
|
||||
|
||||
phba->sli.mbox_active = NULL;
|
||||
if (pmb->mbox_cmpl) {
|
||||
lpfc_sli_pcimem_bcopy(mbox, pmbox,
|
||||
MAILBOX_CMD_SIZE);
|
||||
}
|
||||
if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) {
|
||||
pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG;
|
||||
|
||||
lpfc_debugfs_disc_trc(vport,
|
||||
LPFC_DISC_TRC_MBOX_VPORT,
|
||||
"MBOX dflt rpi: : status:x%x rpi:x%x",
|
||||
(uint32_t)pmbox->mbxStatus,
|
||||
pmbox->un.varWords[0], 0);
|
||||
|
||||
if ( !pmbox->mbxStatus) {
|
||||
mp = (struct lpfc_dmabuf *)
|
||||
(pmb->context1);
|
||||
ndlp = (struct lpfc_nodelist *)
|
||||
pmb->context2;
|
||||
|
||||
/* Reg_LOGIN of dflt RPI was successful.
|
||||
* new lets get rid of the RPI using the
|
||||
* same mbox buffer.
|
||||
*/
|
||||
lpfc_unreg_login(phba, vport->vpi,
|
||||
pmbox->un.varWords[0], pmb);
|
||||
pmb->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
|
||||
pmb->context1 = mp;
|
||||
pmb->context2 = ndlp;
|
||||
pmb->vport = vport;
|
||||
spin_lock(&phba->hbalock);
|
||||
phba->sli.sli_flag &=
|
||||
~LPFC_SLI_MBOX_ACTIVE;
|
||||
spin_unlock(&phba->hbalock);
|
||||
goto send_current_mbox;
|
||||
phba->sli.mbox_active = NULL;
|
||||
if (pmb->mbox_cmpl) {
|
||||
lpfc_sli_pcimem_bcopy(mbox, pmbox,
|
||||
MAILBOX_CMD_SIZE);
|
||||
}
|
||||
if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) {
|
||||
pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG;
|
||||
|
||||
lpfc_debugfs_disc_trc(vport,
|
||||
LPFC_DISC_TRC_MBOX_VPORT,
|
||||
"MBOX dflt rpi: : "
|
||||
"status:x%x rpi:x%x",
|
||||
(uint32_t)pmbox->mbxStatus,
|
||||
pmbox->un.varWords[0], 0);
|
||||
|
||||
if (!pmbox->mbxStatus) {
|
||||
mp = (struct lpfc_dmabuf *)
|
||||
(pmb->context1);
|
||||
ndlp = (struct lpfc_nodelist *)
|
||||
pmb->context2;
|
||||
|
||||
/* Reg_LOGIN of dflt RPI was
|
||||
* successful. new lets get
|
||||
* rid of the RPI using the
|
||||
* same mbox buffer.
|
||||
*/
|
||||
lpfc_unreg_login(phba,
|
||||
vport->vpi,
|
||||
pmbox->un.varWords[0],
|
||||
pmb);
|
||||
pmb->mbox_cmpl =
|
||||
lpfc_mbx_cmpl_dflt_rpi;
|
||||
pmb->context1 = mp;
|
||||
pmb->context2 = ndlp;
|
||||
pmb->vport = vport;
|
||||
spin_lock(&phba->hbalock);
|
||||
phba->sli.sli_flag &=
|
||||
~LPFC_SLI_MBOX_ACTIVE;
|
||||
spin_unlock(&phba->hbalock);
|
||||
goto send_current_mbox;
|
||||
}
|
||||
}
|
||||
spin_lock(&phba->pport->work_port_lock);
|
||||
phba->pport->work_port_events &=
|
||||
~WORKER_MBOX_TMO;
|
||||
spin_unlock(&phba->pport->work_port_lock);
|
||||
lpfc_mbox_cmpl_put(phba, pmb);
|
||||
}
|
||||
spin_lock(&phba->pport->work_port_lock);
|
||||
phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
|
||||
spin_unlock(&phba->pport->work_port_lock);
|
||||
lpfc_mbox_cmpl_put(phba, pmb);
|
||||
}
|
||||
if ((work_ha_copy & HA_MBATT) &&
|
||||
(phba->sli.mbox_active == NULL)) {
|
||||
|
|
|
@ -562,7 +562,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba)
|
|||
struct lpfc_vport *port_iterator;
|
||||
struct lpfc_vport **vports;
|
||||
int index = 0;
|
||||
vports = kzalloc(LPFC_MAX_VPORTS * sizeof(struct lpfc_vport *),
|
||||
vports = kzalloc((phba->max_vpi + 1) * sizeof(struct lpfc_vport *),
|
||||
GFP_KERNEL);
|
||||
if (vports == NULL)
|
||||
return NULL;
|
||||
|
@ -581,12 +581,12 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba)
|
|||
}
|
||||
|
||||
void
|
||||
lpfc_destroy_vport_work_array(struct lpfc_vport **vports)
|
||||
lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports)
|
||||
{
|
||||
int i;
|
||||
if (vports == NULL)
|
||||
return;
|
||||
for (i=0; vports[i] != NULL && i < LPFC_MAX_VPORTS; i++)
|
||||
for (i=0; vports[i] != NULL && i <= phba->max_vpi; i++)
|
||||
scsi_host_put(lpfc_shost_from_vport(vports[i]));
|
||||
kfree(vports);
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ int lpfc_vport_delete(struct fc_vport *);
|
|||
int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *);
|
||||
int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint);
|
||||
struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *);
|
||||
void lpfc_destroy_vport_work_array(struct lpfc_vport **);
|
||||
void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **);
|
||||
|
||||
/*
|
||||
* queuecommand VPORT-specific return codes. Specified in the host byte code.
|
||||
|
|
Loading…
Reference in New Issue