]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.25/patches.drivers/lpfc-8.2.8.7-update
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / lpfc-8.2.8.7-update
diff --git a/src/patches/suse-2.6.27.25/patches.drivers/lpfc-8.2.8.7-update b/src/patches/suse-2.6.27.25/patches.drivers/lpfc-8.2.8.7-update
deleted file mode 100644 (file)
index 9914a87..0000000
+++ /dev/null
@@ -1,1676 +0,0 @@
-From: Jamie Wellnitz <jamie.wellnitz@emulex.com>
-Subject: Update lpfc to 8.2.8.7
-References: bnc#420767
-
-This patch updates the SLES 11 inbox lpfc driver 8.2.8.7, which fixes several
-issues we've found in testing on SLES 11 Beta.
-
-* Changed version number to 8.2.8.7
-* Fixed system lockup problem when HBA is in MSI-X mode (CR 85802, 85441)
-* Fixed slow vport deletes
-* Fixed locking issue when lpfc_ioctl_send_mgmt_cmd fails to allocate buffer
-* Changed mdelay to msleep in the ioctl path (CR 85606)
-* Fixed a discovery issue (CR 85714)
-* Extended Error Handling (EEH) support on IBM PowerPC P6 platform (CR 85671)
-* Fix allocation of HBQs should not be done in interrupt context (CR 84717)
-* Fixed loopback tests not working if auth enabled but auth service not
-  available (CR 85334)
-* Changed version number to 8.2.8.6
-* Fix memory leaks in netlink send code
-* Fixed fail-to-enable INTx when auth is enabled but auth service is not
-  running (CR 85162)
-* Fix build warning of uninitialized variable in lpfc_enable_intr
-* Fix crash when running latency test (CR 85257)
-* Fixed missing CNA attribute for sysfs (CR 85265)
-* Fixed false overrun failure for menlo commands that are less than the command
-  header size (CR 85168)
-* Fixed mbuf leak when lpfc_pci_probe_one hit an error exit in SLI-2 mode
-* Fix memory leak with dump mailbox completion
-* Fix bpl size to reflect the correct buffer's size
-* Fixed lpfc install problem for SLES 11 Beta2 (CR 84623)
-* Fix driver online notification to come after port is added to auth list
-* Added active interrupt test and automatic fallback for enabling
-  MSI/MSI-X/INTx (CR 84266)
-* Fixed NULL pointer dereference in lpfc_prep_els_iocb (CR 84470)
-* Fixed time out handling in the worker thread (CR 84540)
-* Changed version number to 8.2.8.5
-* Small cleanup to match upstream 8.2.8 changes
-* Fix bug with Interrupt Enable Block support (CR 84106)
-* Applied pci_max_read fix from 8.2.0.x driver series (CR 84414)
-* Added support for hps bit (CR 84425 84428)
-
-Signed-off-by: Jamie Wellnitz <jamie.wellnitz@emulex.com>
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-
-diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
-index 7508dea..7bb7971 100644
---- a/drivers/scsi/lpfc/lpfc.h
-+++ b/drivers/scsi/lpfc/lpfc.h
-@@ -73,6 +73,9 @@ struct lpfc_sli2_slim;
- /* Number of MSI-X vectors the driver uses */
- #define LPFC_MSIX_VECTORS     2
-+/* Active interrupt test threshold */
-+#define LPFC_INTR_THRESHOLD   1
-+
- /* lpfc wait event data ready flag */
- #define LPFC_DATA_READY               (1<<0)
-@@ -629,6 +632,7 @@ struct lpfc_hba {
-       uint32_t cfg_hba_queue_depth;
-       uint32_t cfg_enable_hba_reset;
-       uint32_t cfg_enable_hba_heartbeat;
-+      uint32_t cfg_pci_max_read;
-       lpfc_vpd_t vpd;         /* vital product data */
-@@ -718,6 +722,8 @@ struct lpfc_hba {
-       struct fc_host_statistics link_stats;
-       enum intr_type_t intr_type;
-+      uint32_t intr_mode;
-+#define LPFC_INTR_ERROR       0xFFFFFFFF
-       struct msix_entry msix_entries[LPFC_MSIX_VECTORS];
-       struct lpfcdfc_host *dfc_host;
-diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
-index 1069491..2140408 100644
---- a/drivers/scsi/lpfc/lpfc_attr.c
-+++ b/drivers/scsi/lpfc/lpfc_attr.c
-@@ -42,6 +42,7 @@
- #include "lpfc_crtn.h"
- #include "lpfc_vport.h"
- #include "lpfc_auth_access.h"
-+#include "lpfc_security.h"
- #define LPFC_DEF_DEVLOSS_TMO 30
- #define LPFC_MIN_DEVLOSS_TMO 1
-@@ -3100,6 +3101,27 @@ LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat.");
-  */
- LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT,
-           LPFC_MAX_SG_SEG_CNT, "Max Scatter Gather Segment Count");
-+/*
-+ * lpfc_pci_max_read:  Maximum DMA read byte count. This parameter can have
-+ * values 512, 1024, 2048, 4096. Default value is 2048.
-+ */
-+static int lpfc_pci_max_read = 2048;
-+module_param(lpfc_pci_max_read, int, 0);
-+MODULE_PARM_DESC(lpfc_pci_max_read,
-+      "Maximum DMA read byte count. Allowed values:"
-+      " 512,1024,2048,4096.");
-+static int
-+lpfc_pci_max_read_init(struct lpfc_hba *phba, int val)
-+{
-+      phba->cfg_pci_max_read = 2048;
-+      if ((val == 512) || (val == 1024) || (val == 2048) || (val == 4096))
-+              phba->cfg_pci_max_read = val;
-+      return 0;
-+}
-+
-+lpfc_param_show(pci_max_read)
-+static DEVICE_ATTR(lpfc_pci_max_read, S_IRUGO,
-+                      lpfc_pci_max_read_show, NULL);
- struct device_attribute *lpfc_hba_attrs[] = {
-       &dev_attr_info,
-@@ -3136,6 +3158,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
-       &dev_attr_lpfc_fdmi_on,
-       &dev_attr_lpfc_max_luns,
-       &dev_attr_lpfc_enable_npiv,
-+      &dev_attr_lpfc_pci_max_read,
-       &dev_attr_nport_evt_cnt,
-       &dev_attr_board_mode,
-       &dev_attr_max_vpi,
-@@ -4176,12 +4199,22 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
-       if (error)
-               goto out_remove_ctlreg_attr;
-+       error = sysfs_create_bin_file(&shost->shost_dev.kobj,
-+                                      &sysfs_menlo_attr);
-+      if (error)
-+              goto out_remove_menlo_attr;
-+
-+
-       return 0;
- out_remove_ctlreg_attr:
-       sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
- out_remove_stat_attr:
-       sysfs_remove_bin_file(&shost->shost_dev.kobj,
-                       &sysfs_drvr_stat_data_attr);
-+out_remove_menlo_attr:
-+      sysfs_remove_bin_file(&shost->shost_dev.kobj,
-+                      &sysfs_menlo_attr);
-+
- out:
-       return error;
- }
-@@ -4269,6 +4302,13 @@ lpfc_get_host_port_state(struct Scsi_Host *shost)
-       if (vport->fc_flag & FC_OFFLINE_MODE)
-               fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
-       else {
-+              if ((vport->cfg_enable_auth) &&
-+                  (lpfc_security_service_state == SECURITY_OFFLINE)) {
-+                      fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
-+                      spin_unlock_irq(shost->host_lock);
-+                      return;
-+              }
-+
-               switch (phba->link_state) {
-               case LPFC_LINK_UNKNOWN:
-               case LPFC_LINK_DOWN:
-@@ -4837,6 +4877,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
-       lpfc_link_speed_init(phba, lpfc_link_speed);
-       lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
-       lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
-+      lpfc_pci_max_read_init(phba, lpfc_pci_max_read);
-       lpfc_use_msi_init(phba, lpfc_use_msi);
-       lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
-       lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
-diff --git a/drivers/scsi/lpfc/lpfc_auth_access.c b/drivers/scsi/lpfc/lpfc_auth_access.c
-index 7481eb0..9f48c59 100644
---- a/drivers/scsi/lpfc/lpfc_auth_access.c
-+++ b/drivers/scsi/lpfc/lpfc_auth_access.c
-@@ -1,7 +1,7 @@
- /*******************************************************************
-  * This file is part of the Emulex Linux Device Driver for         *
-  * Fibre Channel Host Bus Adapters.                                *
-- * Copyright (C) 2006-2007 Emulex.  All rights reserved.           *
-+ * Copyright (C) 2006-2008 Emulex.  All rights reserved.           *
-  * EMULEX and SLI are trademarks of Emulex.                        *
-  * www.emulex.com                                                  *
-  *                                                                 *
-@@ -213,10 +213,11 @@ lpfc_fc_sc_request(struct lpfc_vport *vport,
-       fc_sc_req->tran_id = seq;
-       len = sizeof(struct fc_nl_sc_message) + auth_req_len;
--      fc_nl_sc_msg = kzalloc(sizeof(struct fc_nl_sc_message) + auth_req_len,
--                             GFP_KERNEL);
--      if (!fc_nl_sc_msg)
-+      fc_nl_sc_msg = kzalloc(len, GFP_KERNEL);
-+      if (!fc_nl_sc_msg) {
-+              kfree(fc_sc_req);
-               return -ENOMEM;
-+      }
-       fc_nl_sc_msg->msgtype = msg_type;
-       fc_nl_sc_msg->data_len = auth_req_len;
-       memcpy(fc_nl_sc_msg->data, auth_req, auth_req_len);
-@@ -228,6 +229,7 @@ lpfc_fc_sc_request(struct lpfc_vport *vport,
-       scsi_nl_send_vendor_msg(fc_service_pid, shost->host_no,
-                               (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX),
-                               (char *) fc_nl_sc_msg, len);
-+      kfree(fc_nl_sc_msg);
-       lpfc_fc_sc_add_timer(fc_sc_req, FC_SC_REQ_TIMEOUT,
-                            lpfc_fc_sc_req_times_out);
-       return 0;
-diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
-index 380acef..cedbfea 100644
---- a/drivers/scsi/lpfc/lpfc_crtn.h
-+++ b/drivers/scsi/lpfc/lpfc_crtn.h
-@@ -43,6 +43,7 @@ void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
- void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
- int lpfc_reg_login(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
-                  LPFC_MBOXQ_t *, uint32_t);
-+void lpfc_set_var(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
- void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
- void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
- void lpfc_reg_vpi(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
-@@ -166,6 +167,8 @@ void lpfc_offline(struct lpfc_hba *);
- int lpfc_sli_setup(struct lpfc_hba *);
- int lpfc_sli_queue_setup(struct lpfc_hba *);
-+int  lpfc_sli_set_dma_length(struct lpfc_hba *, uint32_t);
-+
- void lpfc_handle_eratt(struct lpfc_hba *);
- void lpfc_handle_latt(struct lpfc_hba *);
-diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
-index 7fecdbb..896c7b0 100644
---- a/drivers/scsi/lpfc/lpfc_ct.c
-+++ b/drivers/scsi/lpfc/lpfc_ct.c
-@@ -560,18 +560,25 @@ 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_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) {
-@@ -587,6 +594,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
-                       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",
-diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
-index 3f58a4b..69f92e8 100644
---- a/drivers/scsi/lpfc/lpfc_els.c
-+++ b/drivers/scsi/lpfc/lpfc_els.c
-@@ -278,7 +278,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
-       return elsiocb;
- els_iocb_free_pbuf_exit:
--      lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
-+      if (expectRsp)
-+              lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
-       kfree(pbuflist);
- els_iocb_free_prsp_exit:
-@@ -943,6 +944,10 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
-       struct lpfc_hba *phba = vport->phba;
-       struct lpfc_nodelist *ndlp;
-+      if ((vport->cfg_enable_auth) &&
-+          (lpfc_security_service_state == SECURITY_OFFLINE))
-+              return 1;
-+
-       vport->port_state = LPFC_FLOGI;
-       lpfc_set_disctmo(vport);
-@@ -4985,10 +4990,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
-       uint32_t timeout;
-       uint32_t remote_ID = 0xffffffff;
--      /* If the timer is already canceled do nothing */
--      if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
--              return;
--      }
-       spin_lock_irq(&phba->hbalock);
-       timeout = (uint32_t)(phba->fc_ratov << 1);
-diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
-index 358e9de..f02c2bb 100644
---- a/drivers/scsi/lpfc/lpfc_hbadisc.c
-+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
-@@ -39,6 +39,7 @@
- #include "lpfc_crtn.h"
- #include "lpfc_vport.h"
- #include "lpfc_debugfs.h"
-+#include "lpfc_security.h"
- /* AlpaArray for assignment of scsid for scan-down and bind_method */
- static uint8_t lpfcAlpaArray[] = {
-@@ -1008,9 +1009,12 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
-       /* Start discovery by sending a FLOGI. port_state is identically
-        * LPFC_FLOGI while waiting for FLOGI cmpl
-        */
--      if (vport->port_state != LPFC_FLOGI) {
-+      if ((vport->cfg_enable_auth) &&
-+          (lpfc_security_service_state == SECURITY_OFFLINE))
-+              lpfc_issue_clear_la(phba, vport);
-+      else if (vport->port_state != LPFC_FLOGI)
-               lpfc_initial_flogi(vport);
--      }
-+
-       return;
- out:
-diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
-index c77d49e..f9a42f6 100644
---- a/drivers/scsi/lpfc/lpfc_hw.h
-+++ b/drivers/scsi/lpfc/lpfc_hw.h
-@@ -2370,6 +2370,14 @@ typedef struct {
-       uint32_t rsvd1;
- } CLEAR_LA_VAR;
-+/* Structure for MB Command SET_SLIM (33) */
-+/* Values needed to set MAX_DMA_LENGTH parameter */
-+#define SLIM_VAR_MAX_DMA_LENGTH 0x100506
-+#define SLIM_VAL_MAX_DMA_512    0x0
-+#define SLIM_VAL_MAX_DMA_1024   0x1
-+#define SLIM_VAL_MAX_DMA_2048   0x2
-+#define SLIM_VAL_MAX_DMA_4096   0x3
-+
- /* Structure for MB Command DUMP */
- typedef struct {
-@@ -2621,10 +2629,17 @@ typedef struct {
-       uint32_t pcbLow;       /* bit 31:0  of memory based port config block */
-       uint32_t pcbHigh;      /* bit 63:32 of memory based port config block */
--      uint32_t hbainit[6];
-+      uint32_t hbainit[5];
-+#ifdef __BIG_ENDIAN_BITFIELD
-+      uint32_t hps       :  1; /* bit 31 word9 Host Pointer in slim */
-+      uint32_t rsvd      : 31; /* least significant 31 bits of word 9 */
-+#else   /*  __LITTLE_ENDIAN */
-+      uint32_t rsvd      : 31; /* least significant 31 bits of word 9 */
-+      uint32_t hps       :  1; /* bit 31 word9 Host Pointer in slim */
-+#endif
- #ifdef __BIG_ENDIAN_BITFIELD
--      uint32_t rsvd      : 24;  /* Reserved                             */
-+      uint32_t rsvd1     : 24;  /* Reserved                             */
-       uint32_t cmv       :  1;  /* Configure Max VPIs                   */
-       uint32_t ccrp      :  1;  /* Config Command Ring Polling          */
-       uint32_t csah      :  1;  /* Configure Synchronous Abort Handling */
-@@ -2642,7 +2657,7 @@ typedef struct {
-       uint32_t csah      :  1;  /* Configure Synchronous Abort Handling */
-       uint32_t ccrp      :  1;  /* Config Command Ring Polling          */
-       uint32_t cmv       :  1;  /* Configure Max VPIs                   */
--      uint32_t rsvd      : 24;  /* Reserved                             */
-+      uint32_t rsvd1     : 24;  /* Reserved                             */
- #endif
- #ifdef __BIG_ENDIAN_BITFIELD
-       uint32_t rsvd2     : 24;  /* Reserved                             */
-diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
-index c151651..4032bda 100644
---- a/drivers/scsi/lpfc/lpfc_init.c
-+++ b/drivers/scsi/lpfc/lpfc_init.c
-@@ -290,8 +290,10 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
-       /* character array used for decoding dist type. */
-       char dist_char[] = "nabx";
--      if (pmboxq->mb.mbxStatus != MBX_SUCCESS)
-+      if (pmboxq->mb.mbxStatus != MBX_SUCCESS) {
-+              mempool_free(pmboxq, phba->mbox_mem_pool);
-               return;
-+      }
-       prg = (struct prog_id *) &prog_id_word;
-@@ -309,6 +311,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
-               sprintf(phba->OptionROMVersion, "%d.%d%d%c%d",
-                       prg->ver, prg->rev, prg->lev,
-                       dist, prg->num);
-+      mempool_free(pmboxq, phba->mbox_mem_pool);
-       return;
- }
-@@ -521,22 +524,46 @@ lpfc_config_port_post(struct lpfc_hba *phba)
-       /* Set up error attention (ERATT) polling timer */
-       mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL);
-+      /* Use the existing MBOX buffer, it will be freed in mbox compl */
-+      lpfc_config_async(phba, pmb, LPFC_ELS_RING);
-+      pmb->mbox_cmpl = lpfc_config_async_cmpl;
-+      pmb->vport = phba->pport;
-+      rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
-+      if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
-+              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+                              "0456 Adapter failed to issue "
-+                              "ASYNCEVT_ENABLE mbox status x%x \n.", rc);
-+              mempool_free(pmb, phba->mbox_mem_pool);
-+      }
-+
-+      /* Allocate new MBOX buffer, it will be freed in mbox compl */
-+      pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-+      lpfc_dump_wakeup_param(phba, pmb);
-+      pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
-+      pmb->vport = phba->pport;
-+      rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
-+      if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
-+              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+                              "0435 Adapter failed to get Option "
-+                              "ROM version status x%x\n.", rc);
-+              mempool_free(pmb, phba->mbox_mem_pool);
-+      }
-+
-       if (vport->cfg_enable_auth) {
-               if (lpfc_security_service_state == SECURITY_OFFLINE) {
-                       lpfc_printf_log(vport->phba, KERN_ERR, LOG_SECURITY,
-                               "1000 Authentication is enabled but "
-                               "authentication service is not running\n");
-                       vport->auth.auth_mode = FC_AUTHMODE_UNKNOWN;
--                      phba->link_state = LPFC_HBA_ERROR;
--                      mempool_free(pmb, phba->mbox_mem_pool);
--                      return 0;
-               }
-       }
-+      /* Allocate new MBOX buffer, will be freed in mbox compl */
-+      pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-       lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
-       pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-       rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
--      if (rc != MBX_SUCCESS) {
-+      if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "0454 Adapter failed to init, mbxCmd x%x "
-                               "INIT_LINK, mbxStatus x%x\n",
-@@ -550,40 +577,9 @@ lpfc_config_port_post(struct lpfc_hba *phba)
-               readl(phba->HAregaddr); /* flush */
-               phba->link_state = LPFC_HBA_ERROR;
--              if (rc != MBX_BUSY)
--                      mempool_free(pmb, phba->mbox_mem_pool);
--              return -EIO;
--      }
--      /* MBOX buffer will be freed in mbox compl */
--      pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
--      lpfc_config_async(phba, pmb, LPFC_ELS_RING);
--      pmb->mbox_cmpl = lpfc_config_async_cmpl;
--      pmb->vport = phba->pport;
--      rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
--
--      if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
--              lpfc_printf_log(phba,
--                              KERN_ERR,
--                              LOG_INIT,
--                              "0456 Adapter failed to issue "
--                              "ASYNCEVT_ENABLE mbox status x%x \n.",
--                              rc);
--              mempool_free(pmb, phba->mbox_mem_pool);
--      }
--
--      /* Get Option rom version */
--      pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
--      lpfc_dump_wakeup_param(phba, pmb);
--      pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
--      pmb->vport = phba->pport;
--      rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
--
--      if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
--              lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0435 Adapter failed "
--                              "to get Option ROM version status x%x\n.", rc);
-               mempool_free(pmb, phba->mbox_mem_pool);
-+              return -EIO;
-       }
--
-       return 0;
- }
-@@ -788,11 +784,6 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
-               return;
-       spin_lock_irq(&phba->pport->work_port_lock);
--      /* If the timer is already canceled do nothing */
--      if (!(phba->pport->work_port_events & WORKER_HB_TMO)) {
--              spin_unlock_irq(&phba->pport->work_port_lock);
--              return;
--      }
-       if (time_after(phba->last_completion_time + LPFC_HB_MBOX_INTERVAL * HZ,
-               jiffies)) {
-@@ -2307,6 +2298,51 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
- }
- /**
-+ * lpfc_setup_max_dma_length: Check the host's chipset and adjust HBA's
-+ * max DMA length.
-+ * @phba: pointer to lpfc hba data structure.
-+ *
-+ * This routine is invoked to test the machines chipsets. Some of Emulex's
-+ * HBA models expose bugs in these chipsets. To work around these bugs we
-+ * tell the HBA to use a smaller maxium DMA length.
-+ * This routine is only called during module init. The DMA length is passed
-+ * to the driver as a module parameter(lpfc_pci_max_read).
-+ *
-+ * return: NONE.
-+ **/
-+void
-+lpfc_setup_max_dma_length(struct lpfc_hba *phba)
-+{
-+      struct pci_dev *pdev = phba->pcidev;
-+      struct pci_bus *bus = pdev->bus;
-+      uint8_t rev;
-+
-+      while (bus) {
-+              /*
-+               * 0x7450 == PCI_DEVICE_ID_AMD_8131_BRIDGE for 2.6 kernels
-+               * 0x7450 == PCI_DEVICE_ID_AMD_8131_APIC   for 2.4 kernels
-+               */
-+              if (bus->self &&
-+                      (bus->self->vendor == PCI_VENDOR_ID_AMD) &&
-+                      (bus->self->device == 0x7450)) {
-+                      pci_read_config_byte(bus->self, 0x08, &rev);
-+                      if (rev == 0x13) {
-+                              /*
-+                               * If set a value in module paramter,
-+                               * use that value.
-+                               */
-+                              if (phba->cfg_pci_max_read == 2048)
-+                                      phba->cfg_pci_max_read = 1024;
-+                              return;
-+                      }
-+              }
-+              bus = bus->parent;
-+      }
-+      return;
-+}
-+
-+
-+/**
-  * lpfc_enable_msix: Enable MSI-X interrupt mode.
-  * @phba: pointer to lpfc hba data structure.
-  *
-@@ -2340,8 +2376,7 @@ lpfc_enable_msix(struct lpfc_hba *phba)
-                               ARRAY_SIZE(phba->msix_entries));
-       if (rc) {
-               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
--                              "0420 Enable MSI-X failed (%d), continuing "
--                              "with MSI\n", rc);
-+                              "0420 PCI enable MSI-X failed (%d)\n", rc);
-               goto msi_fail_out;
-       } else
-               for (i = 0; i < LPFC_MSIX_VECTORS; i++)
-@@ -2358,9 +2393,9 @@ lpfc_enable_msix(struct lpfc_hba *phba)
-       rc = request_irq(phba->msix_entries[0].vector, &lpfc_sp_intr_handler,
-                        IRQF_SHARED, LPFC_SP_DRIVER_HANDLER_NAME, phba);
-       if (rc) {
--              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+              lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-                               "0421 MSI-X slow-path request_irq failed "
--                              "(%d), continuing with MSI\n", rc);
-+                              "(%d)\n", rc);
-               goto msi_fail_out;
-       }
-@@ -2369,9 +2404,9 @@ lpfc_enable_msix(struct lpfc_hba *phba)
-                        IRQF_SHARED, LPFC_FP_DRIVER_HANDLER_NAME, phba);
-       if (rc) {
--              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+              lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-                               "0429 MSI-X fast-path request_irq failed "
--                              "(%d), continuing with MSI\n", rc);
-+                              "(%d)\n", rc);
-               goto irq_fail_out;
-       }
-@@ -2392,7 +2427,7 @@ lpfc_enable_msix(struct lpfc_hba *phba)
-               goto mbx_fail_out;
-       rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
-       if (rc != MBX_SUCCESS) {
--              lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
-+              lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
-                               "0351 Config MSI mailbox command failed, "
-                               "mbxCmd x%x, mbxStatus x%x\n",
-                               pmb->mb.mbxCommand, pmb->mb.mbxStatus);
-@@ -2441,6 +2476,111 @@ lpfc_disable_msix(struct lpfc_hba *phba)
- }
- /**
-+ * lpfc_enable_msi: Enable MSI interrupt mode.
-+ * @phba: pointer to lpfc hba data structure.
-+ *
-+ * This routine is invoked to enable the MSI interrupt mode. The kernel
-+ * function pci_enable_msi() is called to enable the MSI vector. The
-+ * device driver is responsible for calling the request_irq() to register
-+ * MSI vector with a interrupt the handler, which is done in this function.
-+ *
-+ * Return codes
-+ *    0 - sucessful
-+ *    other values - error
-+ */
-+static int
-+lpfc_enable_msi(struct lpfc_hba *phba)
-+{
-+      int rc;
-+
-+      rc = pci_enable_msi(phba->pcidev);
-+      if (!rc)
-+              lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-+                              "0462 PCI enable MSI mode success.\n");
-+      else {
-+              lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-+                              "0471 PCI enable MSI mode failed (%d)\n", rc);
-+              return rc;
-+      }
-+
-+      rc = request_irq(phba->pcidev->irq, lpfc_intr_handler,
-+                       IRQF_SHARED, LPFC_DRIVER_NAME, phba);
-+      if (rc) {
-+              pci_disable_msi(phba->pcidev);
-+              lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-+                              "0478 MSI request_irq failed (%d)\n", rc);
-+      }
-+      return rc;
-+}
-+
-+/**
-+ * lpfc_disable_msi: Disable MSI interrupt mode.
-+ * @phba: pointer to lpfc hba data structure.
-+ *
-+ * This routine is invoked to disable the MSI interrupt mode. The driver
-+ * calls free_irq() on MSI vector it has done request_irq() on before
-+ * calling pci_disable_msi(). Failure to do so results in a BUG_ON() and
-+ * a device will be left with MSI enabled and leaks its vector.
-+ */
-+
-+static void
-+lpfc_disable_msi(struct lpfc_hba *phba)
-+{
-+      free_irq(phba->pcidev->irq, phba);
-+      pci_disable_msi(phba->pcidev);
-+      return;
-+}
-+
-+/**
-+ * lpfc_log_intr_mode: Log the active interrupt mode
-+ * @phba: pointer to lpfc hba data structure.
-+ * @intr_mode: active interrupt mode adopted.
-+ *
-+ * This routine it invoked to log the currently used active interrupt mode
-+ * to the device.
-+ */
-+static void
-+lpfc_log_intr_mode(struct lpfc_hba *phba, uint32_t intr_mode)
-+{
-+      switch (intr_mode) {
-+      case 0:
-+              lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-+                              "0470 Enable INTx interrupt mode.\n");
-+              break;
-+      case 1:
-+              lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-+                              "0481 Enabled MSI interrupt mode.\n");
-+              break;
-+      case 2:
-+              lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-+                              "0480 Enabled MSI-X interrupt mode.\n");
-+              break;
-+      default:
-+              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+                              "0482 Illegal interrupt mode.\n");
-+              break;
-+      }
-+      return;
-+}
-+
-+static void
-+lpfc_stop_port(struct lpfc_hba *phba)
-+{
-+      /* Clear all interrupt enable conditions */
-+      writel(0, phba->HCregaddr);
-+      readl(phba->HCregaddr); /* flush */
-+      /* Clear all pending interrupts */
-+      writel(0xffffffff, phba->HAregaddr);
-+      readl(phba->HAregaddr); /* flush */
-+
-+      /* Reset some HBA SLI setup states */
-+      lpfc_stop_phba_timers(phba);
-+      phba->pport->work_port_events = 0;
-+
-+      return;
-+}
-+
-+/**
-  * lpfc_enable_intr: Enable device interrupt.
-  * @phba: pointer to lpfc hba data structure.
-  *
-@@ -2454,60 +2594,47 @@ lpfc_disable_msix(struct lpfc_hba *phba)
-  *   0 - sucessful
-  *   other values - error
-  **/
--static int
--lpfc_enable_intr(struct lpfc_hba *phba)
-+static uint32_t
-+lpfc_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
- {
--      int retval = 0;
--
--      /* Starting point of configuring interrupt method */
--      phba->intr_type = NONE;
-+      uint32_t intr_mode = LPFC_INTR_ERROR;
-+      int retval;
--      if (phba->cfg_use_msi == 2) {
-+      if (cfg_mode == 2) {
-               /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
-               retval = lpfc_sli_config_port(phba, 3);
--              if (retval)
--                      lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
--                              "0478 Firmware not capable of SLI 3 mode.\n");
--              else {
--                      lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
--                              "0479 Firmware capable of SLI 3 mode.\n");
-+              if (!retval) {
-                       /* Now, try to enable MSI-X interrupt mode */
-                       retval = lpfc_enable_msix(phba);
-                       if (!retval) {
-+                              /* Indicate initialization to MSI-X mode */
-                               phba->intr_type = MSIX;
--                              lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
--                                              "0480 enable MSI-X mode.\n");
-+                              intr_mode = 2;
-                       }
-               }
-       }
-       /* Fallback to MSI if MSI-X initialization failed */
--      if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
--              retval = pci_enable_msi(phba->pcidev);
-+      if (cfg_mode >= 1 && phba->intr_type == NONE) {
-+              retval = lpfc_enable_msi(phba);
-               if (!retval) {
-+                      /* Indicate initialization to MSI mode */
-                       phba->intr_type = MSI;
--                      lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
--                                      "0481 enable MSI mode.\n");
--              } else
--                      lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
--                                      "0470 enable IRQ mode.\n");
-+                      intr_mode = 1;
-+              }
-       }
--      /* MSI-X is the only case the doesn't need to call request_irq */
--      if (phba->intr_type != MSIX) {
-+      /* Fallback to INTx if both MSI-X/MSI initalization failed */
-+      if (phba->intr_type == NONE) {
-               retval = request_irq(phba->pcidev->irq, lpfc_intr_handler,
-                                    IRQF_SHARED, LPFC_DRIVER_NAME, phba);
--              if (retval) {
--                      if (phba->intr_type == MSI)
--                              pci_disable_msi(phba->pcidev);
--                      lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
--                                      "0471 Enable interrupt handler "
--                                      "failed\n");
--              } else if (phba->intr_type != MSI)
-+              if (!retval) {
-+                      /* Indicate initialization to INTx mode */
-                       phba->intr_type = INTx;
-+                      intr_mode = 0;
-+              }
-       }
--
--      return retval;
-+      return intr_mode;
- }
- /**
-@@ -2522,13 +2649,18 @@ lpfc_enable_intr(struct lpfc_hba *phba)
- static void
- lpfc_disable_intr(struct lpfc_hba *phba)
- {
-+      /* Disable the currently initialized interrupt mode */
-       if (phba->intr_type == MSIX)
-               lpfc_disable_msix(phba);
--      else {
-+      else if (phba->intr_type == MSI)
-+              lpfc_disable_msi(phba);
-+      else if (phba->intr_type == INTx)
-               free_irq(phba->pcidev->irq, phba);
--              if (phba->intr_type == MSI)
--                      pci_disable_msi(phba->pcidev);
--      }
-+
-+      /* Reset interrupt management states */
-+      phba->intr_type = NONE;
-+      phba->sli.slistat.sli_intr = 0;
-+
-       return;
- }
-@@ -2562,6 +2694,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
-       int error = -ENODEV, retval;
-       int  i, hbq_count;
-       uint16_t iotag;
-+      uint32_t cfg_mode, intr_mode;
-       int bars = pci_select_bars(pdev, IORESOURCE_MEM);
-       struct lpfc_adapter_event_header adapter_event;
-@@ -2593,6 +2726,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
-        * establish the host.
-        */
-       lpfc_get_cfgparam(phba);
-+      /* Check if we need to change the DMA length */
-+      lpfc_setup_max_dma_length(phba);
-+
-       phba->max_vpi = lpfc_hba_max_vpi(phba->pcidev->device);
-       /* Initialize timers used by driver */
-@@ -2615,6 +2751,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
-       phba->eratt_poll.data = (unsigned long) phba;
-       pci_set_master(pdev);
-+      pci_save_state(pdev);
-       pci_try_set_mwi(pdev);
-       if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0)
-@@ -2769,9 +2906,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
-       if ((lpfc_get_security_enabled)(shost)) {
-               unsigned long flags;
--              /* Triggers fcauthd to register if it is running */
--              fc_host_post_event(shost, fc_get_event_number(),
--                                 FCH_EVT_PORT_ONLINE, shost->host_no);
-               spin_lock_irqsave(&fc_security_user_lock, flags);
-               list_add_tail(&vport->sc_users, &fc_security_user_list);
-               spin_unlock_irqrestore(&fc_security_user_lock, flags);
-@@ -2779,6 +2913,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
-                       lpfc_fc_queue_security_work(vport,
-                               &vport->sc_online_work);
-               }
-+              /* Triggers fcauthd to register if it is running */
-+              fc_host_post_event(shost, fc_get_event_number(),
-+                                 FCH_EVT_PORT_ONLINE, shost->host_no);
-       }
-       phba->pport = vport;
-       lpfc_debugfs_initialize(vport);
-@@ -2791,34 +2928,66 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
-       phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
-       phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
--      /* Configure and enable interrupt */
--      error = lpfc_enable_intr(phba);
--      if (error) {
--              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
--                              "0426 Failed to enable interrupt.\n");
--              goto out_destroy_port;
--      }
--
-+      /* Confiugre sysfs attributes */
-       phba->dfc_host = lpfcdfc_host_add(pdev, shost, phba);
-       if (!phba->dfc_host) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
-                               "1201 Failed to allocate dfc_host \n");
-               error = -ENOMEM;
--              goto out_free_irq;
-+              goto out_destroy_port;
-       }
-       if (lpfc_alloc_sysfs_attr(vport)) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "1476 Failed to allocate sysfs attr\n");
-               error = -ENOMEM;
--              goto out_free_irq;
-+              goto out_del_dfc_host;
-       }
--      if (lpfc_sli_hba_setup(phba)) {
--              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
--                              "1477 Failed to set up hba\n");
--              error = -ENODEV;
--              goto out_remove_device;
-+      cfg_mode = phba->cfg_use_msi;
-+      while (true) {
-+              /* Configure and enable interrupt */
-+              intr_mode = lpfc_enable_intr(phba, cfg_mode);
-+              if (intr_mode == LPFC_INTR_ERROR) {
-+                      lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+                                      "0426 Failed to enable interrupt.\n");
-+                      goto out_free_sysfs_attr;
-+              }
-+              /* HBA SLI setup */
-+              if (lpfc_sli_hba_setup(phba)) {
-+                      lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+                                      "1477 Failed to set up hba\n");
-+                      error = -ENODEV;
-+                      goto out_remove_device;
-+              }
-+
-+              /* Wait 50ms for the interrupts of previous mailbox commands */
-+              msleep(50);
-+              /* Check active interrupts received */
-+              if (phba->sli.slistat.sli_intr > LPFC_INTR_THRESHOLD) {
-+                      /* Log the current active interrupt mode */
-+                      phba->intr_mode = intr_mode;
-+                      lpfc_log_intr_mode(phba, intr_mode);
-+                      break;
-+              } else {
-+                      lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-+                                      "0451 Configure interrupt mode (%d) "
-+                                      "failed active interrupt test.\n",
-+                                      intr_mode);
-+                      if (intr_mode == 0) {
-+                              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+                                              "0479 Failed to enable "
-+                                              "interrupt.\n");
-+                              error = -ENODEV;
-+                              goto out_remove_device;
-+                      }
-+                      /* Stop HBA SLI setups */
-+                      lpfc_stop_port(phba);
-+                      /* Disable the current interrupt mode */
-+                      lpfc_disable_intr(phba);
-+                      /* Try next level of interrupt mode */
-+                      cfg_mode = --intr_mode;
-+              }
-       }
-       /*
-@@ -2850,16 +3019,19 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
-       return 0;
- out_remove_device:
--      lpfc_free_sysfs_attr(vport);
-       spin_lock_irq(shost->host_lock);
-       vport->load_flag |= FC_UNLOADING;
-       spin_unlock_irq(shost->host_lock);
--out_free_irq:
--      if (phba->dfc_host)
--              lpfcdfc_host_del(phba->dfc_host);
-       lpfc_stop_phba_timers(phba);
-       phba->pport->work_port_events = 0;
-       lpfc_disable_intr(phba);
-+      lpfc_sli_hba_down(phba);
-+      lpfc_sli_brdrestart(phba);
-+out_free_sysfs_attr:
-+      lpfc_free_sysfs_attr(vport);
-+out_del_dfc_host:
-+      if (phba->dfc_host)
-+              lpfcdfc_host_del(phba->dfc_host);
- out_destroy_port:
-       destroy_port(vport);
- out_kthread_stop:
-@@ -3051,6 +3223,7 @@ lpfc_pci_resume_one(struct pci_dev *pdev)
- {
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
-+      uint32_t intr_mode;
-       int error;
-       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-@@ -3073,19 +3246,22 @@ lpfc_pci_resume_one(struct pci_dev *pdev)
-               return error;
-       }
--      /* Enable interrupt from device */
--      error = lpfc_enable_intr(phba);
--      if (error) {
-+      /* Configure and enable interrupt */
-+      intr_mode = lpfc_enable_intr(phba, phba->intr_mode);
-+      if (intr_mode == LPFC_INTR_ERROR) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
--                              "0430 PM resume Failed to enable interrupt: "
--                              "error=x%x.\n", error);
--              return error;
--      }
-+                              "0430 PM resume Failed to enable interrupt\n");
-+              return -EIO;
-+      } else
-+              phba->intr_mode = intr_mode;
-       /* Restart HBA and bring it online */
-       lpfc_sli_brdrestart(phba);
-       lpfc_online(phba);
-+      /* Log the current active interrupt mode */
-+      lpfc_log_intr_mode(phba, phba->intr_mode);
-+
-       return 0;
- }
-@@ -3161,7 +3337,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
-       struct Scsi_Host *shost = pci_get_drvdata(pdev);
-       struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
-       struct lpfc_sli *psli = &phba->sli;
--      int error;
-+      uint32_t intr_mode;
-       dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
-       if (pci_enable_device_mem(pdev)) {
-@@ -3170,25 +3346,31 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
-               return PCI_ERS_RESULT_DISCONNECT;
-       }
--      pci_set_master(pdev);
-+      pci_restore_state(pdev);
-+      if (pdev->is_busmaster)
-+              pci_set_master(pdev);
-       spin_lock_irq(&phba->hbalock);
-       psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
-       spin_unlock_irq(&phba->hbalock);
--      /* Enable configured interrupt method */
--      error = lpfc_enable_intr(phba);
--      if (error) {
-+      /* Configure and enable interrupt */
-+      intr_mode = lpfc_enable_intr(phba, phba->intr_mode);
-+      if (intr_mode == LPFC_INTR_ERROR) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-                               "0427 Cannot re-enable interrupt after "
-                               "slot reset.\n");
-               return PCI_ERS_RESULT_DISCONNECT;
--      }
-+      } else
-+              phba->intr_mode = intr_mode;
-       /* Take device offline; this will perform cleanup */
-       lpfc_offline(phba);
-       lpfc_sli_brdrestart(phba);
-+      /* Log the current active interrupt mode */
-+      lpfc_log_intr_mode(phba, phba->intr_mode);
-+
-       return PCI_ERS_RESULT_RECOVERED;
- }
-diff --git a/drivers/scsi/lpfc/lpfc_ioctl.c b/drivers/scsi/lpfc/lpfc_ioctl.c
-index e80d157..127b47b 100644
---- a/drivers/scsi/lpfc/lpfc_ioctl.c
-+++ b/drivers/scsi/lpfc/lpfc_ioctl.c
-@@ -162,7 +162,7 @@ lpfc_ioctl_hba_rnid(struct lpfc_hba * phba,
-       for (i0 = 0;
-            i0 < 10 && (pndl->nlp_flag & NLP_ELS_SND_MASK) == NLP_RNID_SND;
-            i0++) {
--              mdelay(1000);
-+              msleep(1000);
-       }
-       if (i0 == 10) {
-@@ -731,7 +731,6 @@ lpfc_ioctl_send_mgmt_cmd(struct lpfc_hba * phba,
-       outdmp = dfc_cmd_data_alloc(phba, NULL, bpl, snsbfrcnt);
-       if (!outdmp) {
-               rc = ENOMEM;
--              spin_lock_irq(shost->host_lock);
-               goto send_mgmt_cmd_free_indmp;
-       }
-@@ -1104,7 +1103,7 @@ lpfc_ioctl_loopback_mode(struct lpfc_hba *phba,
-               if (i++ > 500)  /* wait up to 5 seconds */
-                       break;
--              mdelay(10);
-+              msleep(10);
-       }
-       memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
-diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
-index f0ab456..84619ed 100644
---- a/drivers/scsi/lpfc/lpfc_mbox.c
-+++ b/drivers/scsi/lpfc/lpfc_mbox.c
-@@ -835,6 +835,40 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
- }
- /**
-+ * lpfc_set_var: Prepare a mailbox command to write slim.
-+ * @phba: pointer to lpfc hba data structure.
-+ * @pmb: pointer to the driver internal queue element for mailbox command.
-+ * @addr: This the set variable number that identifies the variable.
-+ * @value:The value that we are setting the parameter to.
-+ *
-+ * The routine just sets the addr and value in the set variable mailbox
-+ * command structure.
-+ * returns: NONE.
-+ **/
-+void
-+lpfc_set_var(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, uint32_t addr,
-+            uint32_t value)
-+{
-+      MAILBOX_t *mb;
-+
-+      mb = &pmb->mb;
-+      memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
-+
-+      /*
-+       * Always turn on DELAYED ABTS for ELS timeouts
-+       */
-+      if ((addr == 0x052198) && (value == 0))
-+              value = 1;
-+
-+      mb->un.varWords[0] = addr;
-+      mb->un.varWords[1] = value;
-+
-+      mb->mbxCommand = MBX_SET_VARIABLE;
-+      mb->mbxOwner = OWN_HOST;
-+      return;
-+}
-+
-+/**
-  * lpfc_read_rev: Prepare a mailbox command for reading HBA revision.
-  * @phba: pointer to lpfc hba data structure.
-  * @pmb: pointer to the driver internal queue element for mailbox command.
-@@ -1093,6 +1127,9 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
-       mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
-       mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
-+      /* Always Host Group Pointer is in SLIM */
-+      mb->un.varCfgPort.hps = 1;
-+
-       /* If HBA supports SLI=3 ask for it */
-       if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
-@@ -1195,16 +1232,11 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
-                                   sizeof(*phba->host_gp));
-       }
--      /* Setup Port Group ring pointer */
--      if (phba->sli3_options & LPFC_SLI3_INB_ENABLED) {
--              pgp_offset = offsetof(struct lpfc_sli2_slim,
--                                    mbx.us.s3_inb_pgp.port);
--              phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get;
--      } else if (phba->sli_rev == 3) {
-+      /* Setup Port Group offset */
-+      if (phba->sli_rev == 3)
-               pgp_offset = offsetof(struct lpfc_sli2_slim,
-                                     mbx.us.s3_pgp.port);
--              phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get;
--      } else
-+      else
-               pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port);
-       pdma_addr = phba->slim2p.phys + pgp_offset;
-       phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr);
-diff --git a/drivers/scsi/lpfc/lpfc_menlo.c b/drivers/scsi/lpfc/lpfc_menlo.c
-index aa36c16..4f3b332 100644
---- a/drivers/scsi/lpfc/lpfc_menlo.c
-+++ b/drivers/scsi/lpfc/lpfc_menlo.c
-@@ -289,19 +289,16 @@ static void
- sysfs_menlo_idle(struct lpfc_hba *phba,
-               struct lpfc_sysfs_menlo *sysfs_menlo)
- {
--      struct Scsi_Host *shost = lpfc_shost_from_vport(phba->pport);
-       spin_lock_irq(&phba->hbalock);
-       list_del_init(&sysfs_menlo->list);
-       spin_unlock_irq(&phba->hbalock);
--      spin_lock_irq(shost->host_lock);
-       if (sysfs_menlo->cr.cmdiocbq)
-               sysfs_menlo_genreq_free(phba, &sysfs_menlo->cr);
-       if (sysfs_menlo->cx.cmdiocbq)
-               sysfs_menlo_genreq_free(phba, &sysfs_menlo->cx);
--      spin_unlock_irq(shost->host_lock);
-       kfree(sysfs_menlo);
- }
-@@ -543,14 +540,15 @@ lpfc_menlo_write(struct lpfc_hba *phba,
-       }
-       if ((count + sysfs_menlo->cr.offset) > sysfs_menlo->cmdhdr.cmdsize) {
--              if ( sysfs_menlo->cmdhdr.cmdsize != 4) {
--              lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
-+              if (sysfs_menlo->cmdhdr.cmdsize >=
-+                      sizeof(struct lpfc_sysfs_menlo_hdr)) {
-+                      lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
-                       "1213 FCoE cmd overflow: off %d + cnt %d > cmdsz %d\n",
--                      (int)sysfs_menlo->cr.offset,
--                      (int)count,
--                      (int)sysfs_menlo->cmdhdr.cmdsize);
--              sysfs_menlo_idle(phba, sysfs_menlo);
--              return -ERANGE;
-+                              (int)sysfs_menlo->cr.offset,
-+                              (int)count,
-+                              (int)sysfs_menlo->cmdhdr.cmdsize);
-+                      sysfs_menlo_idle(phba, sysfs_menlo);
-+                      return -ERANGE;
-               }
-       }
-diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
-index 0c25d97..8f548ad 100644
---- a/drivers/scsi/lpfc/lpfc_nportdisc.c
-+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
-@@ -1929,10 +1929,10 @@ lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
-       if (vport->fc_flag & FC_RSCN_DEFERRED)
-               return ndlp->nlp_state;
-+      lpfc_cancel_retry_delay_tmo(vport, ndlp);
-       spin_lock_irq(shost->host_lock);
-       ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
-       spin_unlock_irq(shost->host_lock);
--      lpfc_cancel_retry_delay_tmo(vport, ndlp);
-       return ndlp->nlp_state;
- }
-diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
-index daf400e..38a7faf 100644
---- a/drivers/scsi/lpfc/lpfc_scsi.c
-+++ b/drivers/scsi/lpfc/lpfc_scsi.c
-@@ -65,6 +65,8 @@ lpfc_update_stats(struct lpfc_hba *phba, struct  lpfc_scsi_buf *lpfc_cmd)
-       if (cmd->result)
-               return;
-+      latency = jiffies_to_msecs((long)jiffies - (long)lpfc_cmd->start_time);
-+
-       spin_lock_irqsave(shost->host_lock, flags);
-       if (!vport->stat_data_enabled ||
-               vport->stat_data_blocked ||
-@@ -73,13 +75,15 @@ lpfc_update_stats(struct lpfc_hba *phba, struct  lpfc_scsi_buf *lpfc_cmd)
-               spin_unlock_irqrestore(shost->host_lock, flags);
-               return;
-       }
--      latency = jiffies_to_msecs(jiffies - lpfc_cmd->start_time);
-       if (phba->bucket_type == LPFC_LINEAR_BUCKET) {
-               i = (latency + phba->bucket_step - 1 - phba->bucket_base)/
-                       phba->bucket_step;
--              if (i >= LPFC_MAX_BUCKET_COUNT)
--                      i = LPFC_MAX_BUCKET_COUNT;
-+              /* check array subscript bounds */
-+              if (i < 0)
-+                      i = 0;
-+              else if (i >= LPFC_MAX_BUCKET_COUNT)
-+                      i = LPFC_MAX_BUCKET_COUNT - 1;
-       } else {
-               for (i = 0; i < LPFC_MAX_BUCKET_COUNT-1; i++)
-                       if (latency <= (phba->bucket_base +
-@@ -413,14 +417,14 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport)
-       bpl[0].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_cmd));
-       bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd);
-       bpl[0].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
--      bpl[0].tus.w = le32_to_cpu(bpl->tus.w);
-+      bpl[0].tus.w = le32_to_cpu(bpl[0].tus.w);
-       /* Setup the physical region for the FCP RSP */
-       bpl[1].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_rsp));
-       bpl[1].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_rsp));
-       bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp);
-       bpl[1].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
--      bpl[1].tus.w = le32_to_cpu(bpl->tus.w);
-+      bpl[1].tus.w = le32_to_cpu(bpl[1].tus.w);
-       /*
-        * Since the IOCB for the FCP I/O is built into this lpfc_scsi_buf,
-@@ -920,7 +924,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
-               if (!pnode || !NLP_CHK_NODE_ACT(pnode)
-                   || (pnode->nlp_state != NLP_STE_MAPPED_NODE))
-                       cmd->result = ScsiResult(DID_TRANSPORT_DISRUPTED,
--                      SAM_STAT_BUSY);
-+                                               SAM_STAT_BUSY);
-       } else {
-               cmd->result = ScsiResult(DID_OK, 0);
-       }
-diff --git a/drivers/scsi/lpfc/lpfc_security.c b/drivers/scsi/lpfc/lpfc_security.c
-index c0fbe56..3d2a8c8 100644
---- a/drivers/scsi/lpfc/lpfc_security.c
-+++ b/drivers/scsi/lpfc/lpfc_security.c
-@@ -45,8 +45,7 @@ lpfc_security_service_online(struct Scsi_Host *shost)
-       lpfc_security_service_state = SECURITY_ONLINE;
-       if (vport->cfg_enable_auth &&
--          vport->auth.auth_mode == FC_AUTHMODE_UNKNOWN &&
--          vport->phba->link_state == LPFC_HBA_ERROR)
-+          vport->auth.auth_mode == FC_AUTHMODE_UNKNOWN)
-               lpfc_selective_reset(vport->phba);
- }
-diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
-index ac78493..5838e41 100644
---- a/drivers/scsi/lpfc/lpfc_sli.c
-+++ b/drivers/scsi/lpfc/lpfc_sli.c
-@@ -1262,68 +1262,6 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba)
- }
- /**
-- * lpfc_sli_replace_hbqbuff: Replace the HBQ buffer with a new buffer.
-- * @phba: Pointer to HBA context object.
-- * @tag: Tag for the HBQ buffer.
-- *
-- * This function is called from unsolicited event handler code path to get the
-- * HBQ buffer associated with an unsolicited iocb. This function is called with
-- * no lock held. It returns the buffer associated with the given tag and posts
-- * another buffer to the firmware. Note that the new buffer must be allocated
-- * before taking the hbalock and that the hba lock must be held until it is
-- * finished with the hbq entry swap.
-- **/
--static struct lpfc_dmabuf *
--lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
--{
--      struct hbq_dmabuf *hbq_entry, *new_hbq_entry;
--      uint32_t hbqno;
--      void *virt;             /* virtual address ptr */
--      dma_addr_t phys;        /* mapped address */
--      unsigned long flags;
--
--      hbqno = tag >> 16;
--      new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
--      /* Check whether HBQ is still in use */
--      spin_lock_irqsave(&phba->hbalock, flags);
--      if (!phba->hbq_in_use) {
--              if (new_hbq_entry)
--                      (phba->hbqs[hbqno].hbq_free_buffer)(phba,
--                                                          new_hbq_entry);
--              spin_unlock_irqrestore(&phba->hbalock, flags);
--              return NULL;
--      }
--
--      hbq_entry = lpfc_sli_hbqbuf_find(phba, tag);
--      if (hbq_entry == NULL) {
--              if (new_hbq_entry)
--                      (phba->hbqs[hbqno].hbq_free_buffer)(phba,
--                                                          new_hbq_entry);
--              spin_unlock_irqrestore(&phba->hbalock, flags);
--              return NULL;
--      }
--      list_del(&hbq_entry->dbuf.list);
--
--      if (new_hbq_entry == NULL) {
--              list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list);
--              spin_unlock_irqrestore(&phba->hbalock, flags);
--              return &hbq_entry->dbuf;
--      }
--      new_hbq_entry->tag = -1;
--      phys = new_hbq_entry->dbuf.phys;
--      virt = new_hbq_entry->dbuf.virt;
--      new_hbq_entry->dbuf.phys = hbq_entry->dbuf.phys;
--      new_hbq_entry->dbuf.virt = hbq_entry->dbuf.virt;
--      hbq_entry->dbuf.phys = phys;
--      hbq_entry->dbuf.virt = virt;
--      lpfc_sli_free_hbq(phba, hbq_entry);
--      list_add_tail(&new_hbq_entry->dbuf.list, &phba->hbqbuf_in_list);
--      spin_unlock_irqrestore(&phba->hbalock, flags);
--
--      return &new_hbq_entry->dbuf;
--}
--
--/**
-  * lpfc_sli_get_buff: Get the buffer associated with the buffer tag.
-  * @phba: Pointer to HBA context object.
-  * @pring: Pointer to driver SLI ring object.
-@@ -1337,13 +1275,17 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
-  **/
- static struct lpfc_dmabuf *
- lpfc_sli_get_buff(struct lpfc_hba *phba,
--                      struct lpfc_sli_ring *pring,
--                      uint32_t tag)
-+                struct lpfc_sli_ring *pring,
-+                uint32_t tag)
- {
-+      struct hbq_dmabuf *hbq_entry;
-+
-       if (tag & QUE_BUFTAG_BIT)
-               return lpfc_sli_ring_taggedbuf_get(phba, pring, tag);
--      else
--              return lpfc_sli_replace_hbqbuff(phba, tag);
-+      hbq_entry = lpfc_sli_hbqbuf_find(phba, tag);
-+      if (!hbq_entry)
-+              return NULL;
-+      return &hbq_entry->dbuf;
- }
-@@ -1375,8 +1317,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
-       match = 0;
-       irsp = &(saveq->iocb);
--      if (irsp->ulpStatus == IOSTAT_NEED_BUFFER)
--              return 1;
-       if (irsp->ulpCommand == CMD_ASYNC_STATUS) {
-               if (pring->lpfc_sli_rcv_async_status)
-                       pring->lpfc_sli_rcv_async_status(phba, pring, saveq);
-@@ -2776,6 +2716,86 @@ lpfc_sli_brdreset(struct lpfc_hba *phba)
- }
- /**
-+ * lpfc_sli_set_dma_length: Set the HBA's max DMA length.
-+ * @phba: Pointer to HBA context object.
-+ * @polling: flag that indicates if interrupts are enabled.
-+ *
-+ * This function sets the HBA's max dma length by issuing a set variable
-+ * mailbox command. The dma length is taking from the cfg_pci_max_read
-+ * configuration parameter. This parameter is passed as a module parameter
-+ * during the driver load. If the HBA does not support this set variable
-+ * mbox command the failure status will reset the cfg_pci_max_read to the
-+ * default(2048).
-+ * If interrupts are not enabled yet then the polling flag = 1  should be
-+ * be used so that the right mailbox routine is called.
-+ * This function returns 0 for success, non 0 returned for failure.
-+ **/
-+int
-+lpfc_sli_set_dma_length(struct lpfc_hba *phba, uint32_t polling)
-+{
-+      uint32_t dma_length;
-+      LPFC_MBOXQ_t *mbox;
-+      int ret = 0;
-+
-+      switch (phba->cfg_pci_max_read) {
-+      case 512:
-+              dma_length = SLIM_VAL_MAX_DMA_512;
-+              break;
-+      case 1024:
-+              dma_length = SLIM_VAL_MAX_DMA_1024;
-+              break;
-+      case 2048:
-+              dma_length = SLIM_VAL_MAX_DMA_2048;
-+              break;
-+      case 4096:
-+              dma_length = SLIM_VAL_MAX_DMA_4096;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-+      if (!mbox)
-+              goto failed;
-+
-+      lpfc_set_var(phba, mbox, SLIM_VAR_MAX_DMA_LENGTH, dma_length);
-+
-+      if (polling)
-+              ret = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
-+      else
-+              ret = lpfc_sli_issue_mbox_wait(phba, mbox,
-+                      LPFC_MBOX_TMO * 2);
-+
-+      if (ret != MBX_SUCCESS) {
-+              if (mbox->mb.mbxStatus != MBXERR_UNKNOWN_CMD)
-+                      lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-+                              "%d:0443 Adapter failed to set maximum"
-+                              " DMA length mbxStatus x%x \n",
-+                              phba->brd_no, mbox->mb.mbxStatus);
-+              else
-+                      lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-+                              "%d:0447 Adapter failed to set maximum"
-+                              " DMA length mbxStatus x%x \n",
-+                              phba->brd_no, mbox->mb.mbxStatus);
-+              goto failed;
-+      }
-+
-+      mempool_free(mbox, phba->mbox_mem_pool);
-+      return 0;
-+
-+failed:
-+      /* If mailbox command failed, reset the value to default value */
-+      phba->cfg_pci_max_read = 2048;
-+      if (ret == MBX_TIMEOUT) {
-+              mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-+              return -EPERM;
-+      } else if (mbox) {
-+              mempool_free(mbox, phba->mbox_mem_pool);
-+              return -EPERM;
-+      } else
-+              return -ENOMEM;
-+}
-+/**
-  * lpfc_sli_brdrestart: Restart the HBA.
-  * @phba: Pointer to HBA context object.
-  *
-@@ -3140,17 +3160,20 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode)
-                       phba->sli3_options |= LPFC_SLI3_CRP_ENABLED;
-               if (pmb->mb.un.varCfgPort.ginb) {
-                       phba->sli3_options |= LPFC_SLI3_INB_ENABLED;
-+                      phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get;
-                       phba->port_gp = phba->mbox->us.s3_inb_pgp.port;
-                       phba->inb_ha_copy = &phba->mbox->us.s3_inb_pgp.ha_copy;
-                       phba->inb_counter = &phba->mbox->us.s3_inb_pgp.counter;
-                       phba->inb_last_counter =
-                                       phba->mbox->us.s3_inb_pgp.counter;
-               } else {
-+                      phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get;
-                       phba->port_gp = phba->mbox->us.s3_pgp.port;
-                       phba->inb_ha_copy = NULL;
-                       phba->inb_counter = NULL;
-               }
-       } else {
-+              phba->hbq_get = NULL;
-               phba->port_gp = phba->mbox->us.s2.port;
-               phba->inb_ha_copy = NULL;
-               phba->inb_counter = NULL;
-@@ -3226,6 +3249,9 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
-       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
-                       "0444 Firmware in SLI %x mode. Max_vpi %d\n",
-                       phba->sli_rev, phba->max_vpi);
-+
-+      lpfc_sli_set_dma_length(phba, 1);
-+
-       rc = lpfc_sli_ring_map(phba);
-       if (rc)
-@@ -3301,10 +3327,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
-       struct lpfc_sli *psli = &phba->sli;
-       struct lpfc_sli_ring *pring;
--      if (!(phba->pport->work_port_events & WORKER_MBOX_TMO)) {
--              return;
--      }
--
-       /* Mbox cmd <mbxCommand> timeout */
-       lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
-                       "0310 Mailbox command x%x timeout Data: x%x x%x x%p\n",
-@@ -5275,6 +5297,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-       uint32_t ha_copy;
-       uint32_t work_ha_copy;
-       unsigned long status;
-+      unsigned long iflag;
-       uint32_t control;
-       MAILBOX_t *mbox, *pmbox;
-@@ -5307,7 +5330,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-               if (unlikely(phba->link_state < LPFC_LINK_DOWN))
-                       return IRQ_NONE;
-               /* Need to read HA REG for slow-path events */
--              spin_lock(&phba->hbalock);
-+              spin_lock_irqsave(&phba->hbalock, iflag);
-               ha_copy = readl(phba->HAregaddr);
-               /* If somebody is waiting to handle an eratt don't process it
-                * here. The brdkill function will do this.
-@@ -5327,7 +5350,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-               writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)),
-                       phba->HAregaddr);
-               readl(phba->HAregaddr); /* flush */
--              spin_unlock(&phba->hbalock);
-+              spin_unlock_irqrestore(&phba->hbalock, iflag);
-       } else
-               ha_copy = phba->ha_copy;
-@@ -5340,13 +5363,13 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-                                * Turn off Link Attention interrupts
-                                * until CLEAR_LA done
-                                */
--                              spin_lock(&phba->hbalock);
-+                              spin_lock_irqsave(&phba->hbalock, iflag);
-                               phba->sli.sli_flag &= ~LPFC_PROCESS_LA;
-                               control = readl(phba->HCregaddr);
-                               control &= ~HC_LAINT_ENA;
-                               writel(control, phba->HCregaddr);
-                               readl(phba->HCregaddr); /* flush */
--                              spin_unlock(&phba->hbalock);
-+                              spin_unlock_irqrestore(&phba->hbalock, iflag);
-                       }
-                       else
-                               work_ha_copy &= ~HA_LATT;
-@@ -5361,7 +5384,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-                               (HA_RXMASK  << (4*LPFC_ELS_RING)));
-                       status >>= (4*LPFC_ELS_RING);
-                       if (status & HA_RXMASK) {
--                              spin_lock(&phba->hbalock);
-+                              spin_lock_irqsave(&phba->hbalock, iflag);
-                               control = readl(phba->HCregaddr);
-                               lpfc_debugfs_slow_ring_trc(phba,
-@@ -5390,10 +5413,10 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-                                               (uint32_t)((unsigned long)
-                                               &phba->work_waitq));
-                               }
--                              spin_unlock(&phba->hbalock);
-+                              spin_unlock_irqrestore(&phba->hbalock, iflag);
-                       }
-               }
--              spin_lock(&phba->hbalock);
-+              spin_lock_irqsave(&phba->hbalock, iflag);
-               if (work_ha_copy & HA_ERATT)
-                       lpfc_sli_read_hs(phba);
-               if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) {
-@@ -5405,7 +5428,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-                       /* First check out the status word */
-                       lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t));
-                       if (pmbox->mbxOwner != OWN_HOST) {
--                              spin_unlock(&phba->hbalock);
-+                              spin_unlock_irqrestore(&phba->hbalock, iflag);
-                               /*
-                                * Stray Mailbox Interrupt, mbxCommand <cmd>
-                                * mbxStatus <status>
-@@ -5422,7 +5445,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-                               work_ha_copy &= ~HA_MBATT;
-                       } else {
-                               phba->sli.mbox_active = NULL;
--                              spin_unlock(&phba->hbalock);
-+                              spin_unlock_irqrestore(&phba->hbalock, iflag);
-                               phba->last_completion_time = jiffies;
-                               del_timer(&phba->sli.mbox_tmo);
-                               if (pmb->mbox_cmpl) {
-@@ -5480,14 +5503,18 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
-                                               goto send_current_mbox;
-                                       }
-                               }
--                              spin_lock(&phba->pport->work_port_lock);
-+                              spin_lock_irqsave(
-+                                              &phba->pport->work_port_lock,
-+                                              iflag);
-                               phba->pport->work_port_events &=
-                                       ~WORKER_MBOX_TMO;
--                              spin_unlock(&phba->pport->work_port_lock);
-+                              spin_unlock_irqrestore(
-+                                              &phba->pport->work_port_lock,
-+                                              iflag);
-                               lpfc_mbox_cmpl_put(phba, pmb);
-                       }
-               } else
--                      spin_unlock(&phba->hbalock);
-+                      spin_unlock_irqrestore(&phba->hbalock, iflag);
-               if ((work_ha_copy & HA_MBATT) &&
-                   (phba->sli.mbox_active == NULL)) {
-@@ -5503,9 +5530,9 @@ send_current_mbox:
-                                               "MBX_SUCCESS");
-               }
--              spin_lock(&phba->hbalock);
-+              spin_lock_irqsave(&phba->hbalock, iflag);
-               phba->work_ha |= work_ha_copy;
--              spin_unlock(&phba->hbalock);
-+              spin_unlock_irqrestore(&phba->hbalock, iflag);
-               lpfc_worker_wake_up(phba);
-       }
-       return IRQ_HANDLED;
-@@ -5537,6 +5564,7 @@ lpfc_fp_intr_handler(int irq, void *dev_id)
-       struct lpfc_hba  *phba;
-       uint32_t ha_copy;
-       unsigned long status;
-+      unsigned long iflag;
-       /* Get the driver's phba structure from the dev_id and
-        * assume the HBA is not interrupting.
-@@ -5562,11 +5590,11 @@ lpfc_fp_intr_handler(int irq, void *dev_id)
-               /* Need to read HA REG for FCP ring and other ring events */
-               ha_copy = readl(phba->HAregaddr);
-               /* Clear up only attention source related to fast-path */
--              spin_lock(&phba->hbalock);
-+              spin_lock_irqsave(&phba->hbalock, iflag);
-               writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)),
-                       phba->HAregaddr);
-               readl(phba->HAregaddr); /* flush */
--              spin_unlock(&phba->hbalock);
-+              spin_unlock_irqrestore(&phba->hbalock, iflag);
-       } else
-               ha_copy = phba->ha_copy;
-diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
-index 57b559a..16626a5 100644
---- a/drivers/scsi/lpfc/lpfc_version.h
-+++ b/drivers/scsi/lpfc/lpfc_version.h
-@@ -18,7 +18,7 @@
-  * included with this package.                                     *
-  *******************************************************************/
--#define LPFC_DRIVER_VERSION "8.2.8.4"
-+#define LPFC_DRIVER_VERSION "8.2.8.7"
- #define LPFC_DRIVER_NAME              "lpfc"
- #define LPFC_SP_DRIVER_HANDLER_NAME   "lpfc:sp"