]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Fri, 23 Sep 2011 23:35:40 +0000 (16:35 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 23 Sep 2011 23:35:40 +0000 (16:35 -0700)
13 files changed:
queue-3.0/ahci-raid-mode-sata-patch-for-intel-panther-point-deviceids.patch [new file with mode: 0644]
queue-3.0/bluetooth-fix-timeout-on-scanning-for-the-second-time.patch [new file with mode: 0644]
queue-3.0/cnic-fix-port_mode-setting.patch [new file with mode: 0644]
queue-3.0/isci-change-sas-phy-timeouts-from-54us-to-59us.patch [new file with mode: 0644]
queue-3.0/isci-fix-event-get-pointer-increment.patch [new file with mode: 0644]
queue-3.0/isci-leave-requests-alone-if-already-terminating.patch [new file with mode: 0644]
queue-3.0/libiscsi_tcp-fix-lld-data-allocation.patch [new file with mode: 0644]
queue-3.0/lpfc-8.3.25-adapter-interface-fixes-and-changes.patch [new file with mode: 0644]
queue-3.0/lpfc-8.3.25-fabric-and-target-discovery-fixes.patch [new file with mode: 0644]
queue-3.0/lpfc-8.3.25-miscellaneous-bug-fixes-and-code-cleanup.patch [new file with mode: 0644]
queue-3.0/lpfc-8.3.25-pci-and-sr-iov-fixes.patch [new file with mode: 0644]
queue-3.0/lpfc-8.3.25-t10-dif-fixes.patch [new file with mode: 0644]
queue-3.0/series

diff --git a/queue-3.0/ahci-raid-mode-sata-patch-for-intel-panther-point-deviceids.patch b/queue-3.0/ahci-raid-mode-sata-patch-for-intel-panther-point-deviceids.patch
new file mode 100644 (file)
index 0000000..bfde3aa
--- /dev/null
@@ -0,0 +1,29 @@
+From 2cab7a4c5ccf96e0954e767af490ba9aee2c9b6f Mon Sep 17 00:00:00 2001
+From: Seth Heasley <seth.heasley@intel.com>
+Date: Thu, 14 Jul 2011 16:50:49 -0700
+Subject: ahci: RAID-mode SATA patch for Intel Panther Point DeviceIDs
+
+From: Seth Heasley <seth.heasley@intel.com>
+
+commit 2cab7a4c5ccf96e0954e767af490ba9aee2c9b6f upstream.
+
+This patch adds an additional SATA RAID controller DeviceID for the Intel Panther Point PCH.
+
+Signed-off-by: Seth Heasley <seth.heasley@intel.com>
+Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/ahci.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -267,6 +267,7 @@ static const struct pci_device_id ahci_p
+       { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
++      { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
+       /* JMicron 360/1/3/5/6, match class to avoid IDE function */
+       { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/queue-3.0/bluetooth-fix-timeout-on-scanning-for-the-second-time.patch b/queue-3.0/bluetooth-fix-timeout-on-scanning-for-the-second-time.patch
new file mode 100644 (file)
index 0000000..3763c9a
--- /dev/null
@@ -0,0 +1,67 @@
+From 2d20a26a92f72e3bb658fe8ce99c3663756e9e7a Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Tue, 30 Aug 2011 15:52:18 +0200
+Subject: Bluetooth: Fix timeout on scanning for the second time
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit 2d20a26a92f72e3bb658fe8ce99c3663756e9e7a upstream.
+
+The checks for HCI_INQUIRY and HCI_MGMT were in the wrong order,
+so that second scans always failed.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/bluetooth/hci_event.c |   17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -56,8 +56,8 @@ static void hci_cc_inquiry_cancel(struct
+       if (status)
+               return;
+-      if (test_bit(HCI_MGMT, &hdev->flags) &&
+-                              test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
++      if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
++                      test_bit(HCI_MGMT, &hdev->flags))
+               mgmt_discovering(hdev->id, 0);
+       hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
+@@ -74,8 +74,8 @@ static void hci_cc_exit_periodic_inq(str
+       if (status)
+               return;
+-      if (test_bit(HCI_MGMT, &hdev->flags) &&
+-                              test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
++      if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
++                              test_bit(HCI_MGMT, &hdev->flags))
+               mgmt_discovering(hdev->id, 0);
+       hci_conn_check_pending(hdev);
+@@ -851,9 +851,8 @@ static inline void hci_cs_inquiry(struct
+               return;
+       }
+-      if (test_bit(HCI_MGMT, &hdev->flags) &&
+-                                      !test_and_set_bit(HCI_INQUIRY,
+-                                                      &hdev->flags))
++      if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags) &&
++                              test_bit(HCI_MGMT, &hdev->flags))
+               mgmt_discovering(hdev->id, 1);
+ }
+@@ -1225,8 +1224,8 @@ static inline void hci_inquiry_complete_
+       BT_DBG("%s status %d", hdev->name, status);
+-      if (test_bit(HCI_MGMT, &hdev->flags) &&
+-                              test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
++      if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) &&
++                              test_bit(HCI_MGMT, &hdev->flags))
+               mgmt_discovering(hdev->id, 0);
+       hci_req_complete(hdev, HCI_OP_INQUIRY, status);
diff --git a/queue-3.0/cnic-fix-port_mode-setting.patch b/queue-3.0/cnic-fix-port_mode-setting.patch
new file mode 100644 (file)
index 0000000..209d738
--- /dev/null
@@ -0,0 +1,27 @@
+From b7d40315c9643034ac4b5c9dda480d0124416f89 Mon Sep 17 00:00:00 2001
+From: Michael Chan <mchan@broadcom.com>
+Date: Wed, 13 Jul 2011 17:24:18 +0000
+Subject: cnic: Fix port_mode setting
+
+From: Michael Chan <mchan@broadcom.com>
+
+commit b7d40315c9643034ac4b5c9dda480d0124416f89 upstream.
+
+CHIP_2_PORT_MODE was not set correctly.
+
+Signed-off-by: Michael Chan <mchan@broadcom.com>
+Reviewed-by: Matt Carlson <mcarlson@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+--- a/drivers/net/cnic.c
++++ b/drivers/net/cnic.c
+@@ -4834,7 +4834,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
+                       cp->port_mode = CHIP_4_PORT_MODE;
+                       cp->pfid = func >> 1;
+               } else {
+-                      cp->port_mode = CHIP_4_PORT_MODE;
++                      cp->port_mode = CHIP_2_PORT_MODE;
+                       cp->pfid = func & 0x6;
+               }
+       } else {
diff --git a/queue-3.0/isci-change-sas-phy-timeouts-from-54us-to-59us.patch b/queue-3.0/isci-change-sas-phy-timeouts-from-54us-to-59us.patch
new file mode 100644 (file)
index 0000000..fc5de02
--- /dev/null
@@ -0,0 +1,76 @@
+From 985af6f70dbb8a33b3af8a7c7df508d924650e37 Mon Sep 17 00:00:00 2001
+From: Marcin Tomczak <marcin.tomczak@intel.com>
+Date: Fri, 29 Jul 2011 17:16:50 -0700
+Subject: [SCSI] isci: change sas phy timeouts from 54us to 59us
+
+From: Marcin Tomczak <marcin.tomczak@intel.com>
+
+commit 985af6f70dbb8a33b3af8a7c7df508d924650e37 upstream.
+
+Need the following workaround in the driver for interoperability with
+the older Intel SSD drives and any other SATA drive that may exhibit the
+same behavior. This is a corner case where SCU speed is limited to
+either 3G or 1.5G and the drive has a period of DC idle when it switches
+speed during SATA speed negotiation. Workaround :change PHYTOV[31:24]
+from 0x36 to 0x3B.
+
+Signed-off-by: Marcin Tomczak <marcin.tomczak@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/isci/phy.c       |   13 +++++++++++++
+ drivers/scsi/isci/registers.h |   12 ++++++++++++
+ 2 files changed, 25 insertions(+)
+
+--- a/drivers/scsi/isci/phy.c
++++ b/drivers/scsi/isci/phy.c
+@@ -104,6 +104,7 @@ sci_phy_link_layer_initialization(struct
+       u32 parity_count = 0;
+       u32 llctl, link_rate;
+       u32 clksm_value = 0;
++      u32 sp_timeouts = 0;
+       iphy->link_layer_registers = reg;
+@@ -211,6 +212,18 @@ sci_phy_link_layer_initialization(struct
+       llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
+       writel(llctl, &iphy->link_layer_registers->link_layer_control);
++      sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts);
++
++      /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
++      sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
++
++      /* Set RATE_CHANGE timeout value to 0x3B (59us).  This ensures SCU can
++       * lock with 3Gb drive when SCU max rate is set to 1.5Gb.
++       */
++      sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
++
++      writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts);
++
+       if (is_a2(ihost->pdev)) {
+               /* Program the max ARB time for the PHY to 700us so we inter-operate with
+                * the PMC expander which shuts down PHYs if the expander PHY generates too
+--- a/drivers/scsi/isci/registers.h
++++ b/drivers/scsi/isci/registers.h
+@@ -1299,6 +1299,18 @@ struct scu_transport_layer_registers {
+ #define SCU_AFE_XCVRCR_OFFSET       0x00DC
+ #define SCU_AFE_LUTCR_OFFSET        0x00E0
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_SHIFT          (0UL)
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_MASK           (0x000000FFUL)
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_SHIFT                 (8UL)
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_MASK                  (0x0000FF00UL)
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_SHIFT         (16UL)
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_MASK          (0x00FF0000UL)
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_SHIFT              (24UL)
++#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_MASK               (0xFF000000UL)
++
++#define SCU_SAS_PHYTOV_GEN_VAL(name, value) \
++      SCU_GEN_VALUE(SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_##name, value)
++
+ #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT                  (0)
+ #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK                   (0x00000003)
+ #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1                   (0)
diff --git a/queue-3.0/isci-fix-event-get-pointer-increment.patch b/queue-3.0/isci-fix-event-get-pointer-increment.patch
new file mode 100644 (file)
index 0000000..0e28e86
--- /dev/null
@@ -0,0 +1,33 @@
+From 77cd72a53f6426f81b7f56a862402849ee903bda Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Fri, 29 Jul 2011 17:17:16 -0700
+Subject: [SCSI] isci: fix event-get pointer increment
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 77cd72a53f6426f81b7f56a862402849ee903bda upstream.
+
+Hardware only increments the put pointer on event types >= 4.  Do not
+increment the get pointer for event type 3.
+
+Reported-by: Kapil Karkra <kapil.karkra@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/isci/host.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/scsi/isci/host.c
++++ b/drivers/scsi/isci/host.c
+@@ -531,6 +531,9 @@ static void sci_controller_process_compl
+                       break;
+               case SCU_COMPLETION_TYPE_EVENT:
++                      sci_controller_event_completion(ihost, ent);
++                      break;
++
+               case SCU_COMPLETION_TYPE_NOTIFY: {
+                       event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) <<
+                                      (SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT);
diff --git a/queue-3.0/isci-leave-requests-alone-if-already-terminating.patch b/queue-3.0/isci-leave-requests-alone-if-already-terminating.patch
new file mode 100644 (file)
index 0000000..e3134a3
--- /dev/null
@@ -0,0 +1,46 @@
+From 39ea2c5b5ffaa344467da53e885cfa4ac0105050 Mon Sep 17 00:00:00 2001
+From: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
+Date: Fri, 29 Jul 2011 17:17:05 -0700
+Subject: [SCSI] isci: Leave requests alone if already terminating.
+
+From: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
+
+commit 39ea2c5b5ffaa344467da53e885cfa4ac0105050 upstream.
+
+Instead of immediately completing any request that has a second
+termination call made on it, wait for the TC done/abort HW event.
+
+Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/isci/request.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/isci/request.c
++++ b/drivers/scsi/isci/request.c
+@@ -732,12 +732,20 @@ sci_io_request_terminate(struct isci_req
+               sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
+               return SCI_SUCCESS;
+       case SCI_REQ_TASK_WAIT_TC_RESP:
++              /* The task frame was already confirmed to have been
++               * sent by the SCU HW.  Since the state machine is
++               * now only waiting for the task response itself,
++               * abort the request and complete it immediately
++               * and don't wait for the task response.
++               */
+               sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
+               sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+               return SCI_SUCCESS;
+       case SCI_REQ_ABORTING:
+-              sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+-              return SCI_SUCCESS;
++              /* If a request has a termination requested twice, return
++               * a failure indication, since HW confirmation of the first
++               * abort is still outstanding.
++               */
+       case SCI_REQ_COMPLETED:
+       default:
+               dev_warn(&ireq->owning_controller->pdev->dev,
diff --git a/queue-3.0/libiscsi_tcp-fix-lld-data-allocation.patch b/queue-3.0/libiscsi_tcp-fix-lld-data-allocation.patch
new file mode 100644 (file)
index 0000000..d50ea3b
--- /dev/null
@@ -0,0 +1,56 @@
+From 74dcd0ec735ba9c5bef254b2f6e53068cf3f9ff0 Mon Sep 17 00:00:00 2001
+From: Mike Christie <michaelc@cs.wisc.edu>
+Date: Fri, 24 Jun 2011 15:11:55 -0500
+Subject: [SCSI] libiscsi_tcp: fix LLD data allocation
+
+From: Mike Christie <michaelc@cs.wisc.edu>
+
+commit 74dcd0ec735ba9c5bef254b2f6e53068cf3f9ff0 upstream.
+
+Have libiscsi_tcp have upper layers allocate the LLD data
+along with the iscsi_cls_conn struct, so it is refcounted.
+
+Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/libiscsi_tcp.c |   14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+--- a/drivers/scsi/libiscsi_tcp.c
++++ b/drivers/scsi/libiscsi_tcp.c
+@@ -1084,7 +1084,8 @@ iscsi_tcp_conn_setup(struct iscsi_cls_se
+       struct iscsi_cls_conn *cls_conn;
+       struct iscsi_tcp_conn *tcp_conn;
+-      cls_conn = iscsi_conn_setup(cls_session, sizeof(*tcp_conn), conn_idx);
++      cls_conn = iscsi_conn_setup(cls_session,
++                                  sizeof(*tcp_conn) + dd_data_size, conn_idx);
+       if (!cls_conn)
+               return NULL;
+       conn = cls_conn->dd_data;
+@@ -1096,22 +1097,13 @@ iscsi_tcp_conn_setup(struct iscsi_cls_se
+       tcp_conn = conn->dd_data;
+       tcp_conn->iscsi_conn = conn;
+-
+-      tcp_conn->dd_data = kzalloc(dd_data_size, GFP_KERNEL);
+-      if (!tcp_conn->dd_data) {
+-              iscsi_conn_teardown(cls_conn);
+-              return NULL;
+-      }
++      tcp_conn->dd_data = conn->dd_data + sizeof(*tcp_conn);
+       return cls_conn;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_tcp_conn_setup);
+ void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn)
+ {
+-      struct iscsi_conn *conn = cls_conn->dd_data;
+-      struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+-
+-      kfree(tcp_conn->dd_data);
+       iscsi_conn_teardown(cls_conn);
+ }
+ EXPORT_SYMBOL_GPL(iscsi_tcp_conn_teardown);
diff --git a/queue-3.0/lpfc-8.3.25-adapter-interface-fixes-and-changes.patch b/queue-3.0/lpfc-8.3.25-adapter-interface-fixes-and-changes.patch
new file mode 100644 (file)
index 0000000..28f8ffe
--- /dev/null
@@ -0,0 +1,661 @@
+From 7851fe2c7f294d0beccf4c3d6af52e8247b89f00 Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@emulex.com>
+Date: Fri, 22 Jul 2011 18:36:52 -0400
+Subject: [SCSI] lpfc 8.3.25: Adapter Interface fixes and changes
+
+From: James Smart <james.smart@emulex.com>
+
+commit 7851fe2c7f294d0beccf4c3d6af52e8247b89f00 upstream.
+
+Adapter Interface fixes and changes
+
+- Modify the macro field from lpfc_init_vpi_vpi to lpfc_init_vfi_vpi
+- Add the new CQE_CODE_RECEIVE_V1 CQE Code, add code in the driver to handle
+  the new Code the same as the CQE_CODE_RECEIVE code except that there are
+  two new checks for this code that will cause the driver to use the new V1
+  macros for rq_id and fcf_id.
+- Fix a bug in lpfc_prep_seq() where the size out of the first CQE was
+  ONLY being used, even though multiple dmabufs make up the sequence,
+  each have their own CQE with potentially different sizes.
+- Fix bug in lpfc_bsg_ct_unsol_event() where the ulpContext and ulpWord[3]
+  fields of the XMIT_SEQUENCE64_CX IOCB were being calculated incorrectly.
+- Do physical to logical translation before indexing into the active
+  XRI array.
+- Populate physical vpi in the iocb data structure.
+- Put the current accumulated total in each IOCB in the chain as we are
+  walking thru then. The last IOCB in the chain should have the total
+  length of the sequence.
+
+Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
+Signed-off-by: James Smart <james.smart@emulex.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/lpfc/lpfc.h      |    3 -
+ drivers/scsi/lpfc/lpfc_bsg.c  |   15 +++----
+ drivers/scsi/lpfc/lpfc_crtn.h |    1 
+ drivers/scsi/lpfc/lpfc_els.c  |   70 +++++++++++++++++++++++----------
+ drivers/scsi/lpfc/lpfc_hw.h   |    7 ++-
+ drivers/scsi/lpfc/lpfc_hw4.h  |    9 +++-
+ drivers/scsi/lpfc/lpfc_mbox.c |    2 
+ drivers/scsi/lpfc/lpfc_sli.c  |   88 +++++++++++++++++++++++++++---------------
+ 8 files changed, 133 insertions(+), 62 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -470,9 +470,10 @@ enum intr_type_t {
+ struct unsol_rcv_ct_ctx {
+       uint32_t ctxt_id;
+       uint32_t SID;
+-      uint32_t oxid;
+       uint32_t flags;
+ #define UNSOL_VALID   0x00000001
++      uint16_t oxid;
++      uint16_t rxid;
+ };
+ #define LPFC_USER_LINK_SPEED_AUTO     0       /* auto select (default)*/
+--- a/drivers/scsi/lpfc/lpfc_bsg.c
++++ b/drivers/scsi/lpfc/lpfc_bsg.c
+@@ -960,8 +960,10 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba
+                                                   evt_dat->immed_dat].oxid,
+                                               phba->ct_ctx[
+                                                   evt_dat->immed_dat].SID);
++                      phba->ct_ctx[evt_dat->immed_dat].rxid =
++                              piocbq->iocb.ulpContext;
+                       phba->ct_ctx[evt_dat->immed_dat].oxid =
+-                                              piocbq->iocb.ulpContext;
++                              piocbq->iocb.unsli3.rcvsli3.ox_id;
+                       phba->ct_ctx[evt_dat->immed_dat].SID =
+                               piocbq->iocb.un.rcvels.remoteID;
+                       phba->ct_ctx[evt_dat->immed_dat].flags = UNSOL_VALID;
+@@ -1312,7 +1314,8 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba,
+                       rc = IOCB_ERROR;
+                       goto issue_ct_rsp_exit;
+               }
+-              icmd->ulpContext = phba->ct_ctx[tag].oxid;
++              icmd->ulpContext = phba->ct_ctx[tag].rxid;
++              icmd->unsli3.rcvsli3.ox_id = phba->ct_ctx[tag].oxid;
+               ndlp = lpfc_findnode_did(phba->pport, phba->ct_ctx[tag].SID);
+               if (!ndlp) {
+                       lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
+@@ -1337,9 +1340,7 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba,
+                       goto issue_ct_rsp_exit;
+               }
+-              icmd->un.ulpWord[3] = ndlp->nlp_rpi;
+-              if (phba->sli_rev == LPFC_SLI_REV4)
+-                      icmd->ulpContext =
++              icmd->un.ulpWord[3] =
+                               phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+               /* The exchange is done, mark the entry as invalid */
+@@ -1351,8 +1352,8 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba,
+       /* Xmit CT response on exchange <xid> */
+       lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
+-                      "2722 Xmit CT response on exchange x%x Data: x%x x%x\n",
+-                      icmd->ulpContext, icmd->ulpIoTag, phba->link_state);
++              "2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n",
++              icmd->ulpContext, icmd->ulpIoTag, tag, phba->link_state);
+       ctiocb->iocb_cmpl = NULL;
+       ctiocb->iocb_flag |= LPFC_IO_LIBDFC;
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -432,6 +432,7 @@ void lpfc_handle_rrq_active(struct lpfc_
+ int lpfc_send_rrq(struct lpfc_hba *, struct lpfc_node_rrq *);
+ int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *,
+       uint16_t, uint16_t, uint16_t);
++uint16_t lpfc_sli4_xri_inrange(struct lpfc_hba *, uint16_t);
+ void lpfc_cleanup_wt_rrqs(struct lpfc_hba *);
+ void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *);
+ struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t,
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -3656,7 +3656,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
+               }
+               icmd = &elsiocb->iocb;
+-              icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
++              icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++              icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+               pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+               *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
+               pcmd += sizeof(uint32_t);
+@@ -3673,7 +3674,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
+                       return 1;
+               icmd = &elsiocb->iocb;
+-              icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
++              icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++              icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+               pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+               if (mbox)
+@@ -3695,7 +3697,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vpor
+                       return 1;
+               icmd = &elsiocb->iocb;
+-              icmd->ulpContext = oldcmd->ulpContext; /* Xri */
++              icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++              icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+               pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+               memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
+@@ -3781,7 +3784,8 @@ lpfc_els_rsp_reject(struct lpfc_vport *v
+       icmd = &elsiocb->iocb;
+       oldcmd = &oldiocb->iocb;
+-      icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
++      icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++      icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+       *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
+@@ -3853,7 +3857,8 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport
+       icmd = &elsiocb->iocb;
+       oldcmd = &oldiocb->iocb;
+-      icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
++      icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++      icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+       /* Xmit ADISC ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+@@ -3931,7 +3936,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport
+       icmd = &elsiocb->iocb;
+       oldcmd = &oldiocb->iocb;
+-      icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
++      icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++      icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
++
+       /* Xmit PRLI ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "0131 Xmit PRLI ACC response tag x%x xri x%x, "
+@@ -4035,7 +4042,9 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport
+       icmd = &elsiocb->iocb;
+       oldcmd = &oldiocb->iocb;
+-      icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
++      icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++      icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
++
+       /* Xmit RNID ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "0132 Xmit RNID ACC response tag x%x xri x%x\n",
+@@ -4163,7 +4172,9 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport
+       if (!elsiocb)
+               return 1;
+-      elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext;    /* Xri */
++      elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext;  /* Xri / rx_id */
++      elsiocb->iocb.unsli3.rcvsli3.ox_id = oldiocb->iocb.unsli3.rcvsli3.ox_id;
++
+       /* Xmit ECHO ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
+@@ -5054,13 +5065,15 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *ph
+       uint8_t *pcmd;
+       struct lpfc_iocbq *elsiocb;
+       struct lpfc_nodelist *ndlp;
+-      uint16_t xri;
++      uint16_t oxid;
++      uint16_t rxid;
+       uint32_t cmdsize;
+       mb = &pmb->u.mb;
+       ndlp = (struct lpfc_nodelist *) pmb->context2;
+-      xri = (uint16_t) ((unsigned long)(pmb->context1));
++      rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
++      oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
+       pmb->context1 = NULL;
+       pmb->context2 = NULL;
+@@ -5082,7 +5095,8 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *ph
+               return;
+       icmd = &elsiocb->iocb;
+-      icmd->ulpContext = xri;
++      icmd->ulpContext = rxid;
++      icmd->unsli3.rcvsli3.ox_id = oxid;
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+       *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
+@@ -5137,13 +5151,16 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *ph
+       uint8_t *pcmd;
+       struct lpfc_iocbq *elsiocb;
+       struct lpfc_nodelist *ndlp;
+-      uint16_t xri, status;
++      uint16_t status;
++      uint16_t oxid;
++      uint16_t rxid;
+       uint32_t cmdsize;
+       mb = &pmb->u.mb;
+       ndlp = (struct lpfc_nodelist *) pmb->context2;
+-      xri = (uint16_t) ((unsigned long)(pmb->context1));
++      rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
++      oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
+       pmb->context1 = NULL;
+       pmb->context2 = NULL;
+@@ -5165,7 +5182,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *ph
+               return;
+       icmd = &elsiocb->iocb;
+-      icmd->ulpContext = xri;
++      icmd->ulpContext = rxid;
++      icmd->unsli3.rcvsli3.ox_id = oxid;
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+       *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
+@@ -5238,8 +5256,9 @@ lpfc_els_rcv_rls(struct lpfc_vport *vpor
+       mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
+       if (mbox) {
+               lpfc_read_lnk_stat(phba, mbox);
+-              mbox->context1 =
+-                  (void *)((unsigned long) cmdiocb->iocb.ulpContext);
++              mbox->context1 = (void *)((unsigned long)
++                      ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
++                      cmdiocb->iocb.ulpContext)); /* rx_id */
+               mbox->context2 = lpfc_nlp_get(ndlp);
+               mbox->vport = vport;
+               mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
+@@ -5314,7 +5333,8 @@ lpfc_els_rcv_rtv(struct lpfc_vport *vpor
+       pcmd += sizeof(uint32_t); /* Skip past command */
+       /* use the command's xri in the response */
+-      elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;
++      elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;  /* Xri / rx_id */
++      elsiocb->iocb.unsli3.rcvsli3.ox_id = cmdiocb->iocb.unsli3.rcvsli3.ox_id;
+       rtv_rsp = (struct RTV_RSP *)pcmd;
+@@ -5399,8 +5419,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vpor
+               mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
+               if (mbox) {
+                       lpfc_read_lnk_stat(phba, mbox);
+-                      mbox->context1 =
+-                          (void *)((unsigned long) cmdiocb->iocb.ulpContext);
++                      mbox->context1 = (void *)((unsigned long)
++                              ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
++                              cmdiocb->iocb.ulpContext)); /* rx_id */
+                       mbox->context2 = lpfc_nlp_get(ndlp);
+                       mbox->vport = vport;
+                       mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
+@@ -5554,7 +5575,8 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *
+       icmd = &elsiocb->iocb;
+       oldcmd = &oldiocb->iocb;
+-      icmd->ulpContext = oldcmd->ulpContext;  /* Xri */
++      icmd->ulpContext = oldcmd->ulpContext;  /* Xri / rx_id */
++      icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
+       pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+       *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
+@@ -7787,6 +7809,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hb
+ {
+       uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
+       uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
++      uint16_t lxri = 0;
+       struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
+       unsigned long iflag = 0;
+@@ -7815,7 +7838,12 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hb
+               }
+       }
+       spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
+-      sglq_entry = __lpfc_get_active_sglq(phba, xri);
++      lxri = lpfc_sli4_xri_inrange(phba, xri);
++      if (lxri == NO_XRI) {
++              spin_unlock_irqrestore(&phba->hbalock, iflag);
++              return;
++      }
++      sglq_entry = __lpfc_get_active_sglq(phba, lxri);
+       if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
+               spin_unlock_irqrestore(&phba->hbalock, iflag);
+               return;
+--- a/drivers/scsi/lpfc/lpfc_hw.h
++++ b/drivers/scsi/lpfc/lpfc_hw.h
+@@ -3470,11 +3470,16 @@ typedef struct {
+    or CMD_IOCB_RCV_SEQ64_CX (0xB5) */
+ struct rcv_sli3 {
+-      uint32_t word8Rsvd;
+ #ifdef __BIG_ENDIAN_BITFIELD
++      uint16_t ox_id;
++      uint16_t seq_cnt;
++
+       uint16_t vpi;
+       uint16_t word9Rsvd;
+ #else  /*  __LITTLE_ENDIAN */
++      uint16_t seq_cnt;
++      uint16_t ox_id;
++
+       uint16_t word9Rsvd;
+       uint16_t vpi;
+ #endif
+--- a/drivers/scsi/lpfc/lpfc_hw4.h
++++ b/drivers/scsi/lpfc/lpfc_hw4.h
+@@ -330,6 +330,7 @@ struct lpfc_cqe {
+ #define CQE_CODE_RELEASE_WQE          0x2
+ #define CQE_CODE_RECEIVE              0x4
+ #define CQE_CODE_XRI_ABORTED          0x5
++#define CQE_CODE_RECEIVE_V1           0x9
+ /* completion queue entry for wqe completions */
+ struct lpfc_wcqe_complete {
+@@ -433,7 +434,10 @@ struct lpfc_rcqe {
+ #define FC_STATUS_RQ_BUF_LEN_EXCEEDED         0x11 /* payload truncated */
+ #define FC_STATUS_INSUFF_BUF_NEED_BUF         0x12 /* Insufficient buffers */
+ #define FC_STATUS_INSUFF_BUF_FRM_DISC         0x13 /* Frame Discard */
+-      uint32_t reserved1;
++      uint32_t word1;
++#define lpfc_rcqe_fcf_id_v1_SHIFT     0
++#define lpfc_rcqe_fcf_id_v1_MASK      0x0000003F
++#define lpfc_rcqe_fcf_id_v1_WORD      word1
+       uint32_t word2;
+ #define lpfc_rcqe_length_SHIFT                16
+ #define lpfc_rcqe_length_MASK         0x0000FFFF
+@@ -444,6 +448,9 @@ struct lpfc_rcqe {
+ #define lpfc_rcqe_fcf_id_SHIFT                0
+ #define lpfc_rcqe_fcf_id_MASK         0x0000003F
+ #define lpfc_rcqe_fcf_id_WORD         word2
++#define lpfc_rcqe_rq_id_v1_SHIFT      0
++#define lpfc_rcqe_rq_id_v1_MASK               0x0000FFFF
++#define lpfc_rcqe_rq_id_v1_WORD               word2
+       uint32_t word3;
+ #define lpfc_rcqe_valid_SHIFT         lpfc_cqe_valid_SHIFT
+ #define lpfc_rcqe_valid_MASK          lpfc_cqe_valid_MASK
+--- a/drivers/scsi/lpfc/lpfc_mbox.c
++++ b/drivers/scsi/lpfc/lpfc_mbox.c
+@@ -2031,7 +2031,7 @@ lpfc_init_vfi(struct lpfcMboxq *mbox, st
+       bf_set(lpfc_init_vfi_vp, init_vfi, 1);
+       bf_set(lpfc_init_vfi_vfi, init_vfi,
+              vport->phba->sli4_hba.vfi_ids[vport->vfi]);
+-      bf_set(lpfc_init_vpi_vpi, init_vfi,
++      bf_set(lpfc_init_vfi_vpi, init_vfi,
+              vport->phba->vpi_ids[vport->vpi]);
+       bf_set(lpfc_init_vfi_fcfi, init_vfi,
+              vport->phba->fcf.fcfi);
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -560,7 +560,7 @@ __lpfc_set_rrq_active(struct lpfc_hba *p
+       rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
+       if (rrq) {
+               rrq->send_rrq = send_rrq;
+-              rrq->xritag = phba->sli4_hba.xri_ids[xritag];
++              rrq->xritag = xritag;
+               rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1);
+               rrq->ndlp = ndlp;
+               rrq->nlp_DID = ndlp->nlp_DID;
+@@ -2452,7 +2452,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_
+               /* search continue save q for same XRI */
+               list_for_each_entry(iocbq, &pring->iocb_continue_saveq, clist) {
+-                      if (iocbq->iocb.ulpContext == saveq->iocb.ulpContext) {
++                      if (iocbq->iocb.unsli3.rcvsli3.ox_id ==
++                              saveq->iocb.unsli3.rcvsli3.ox_id) {
+                               list_add_tail(&saveq->list, &iocbq->list);
+                               found = 1;
+                               break;
+@@ -3355,6 +3356,7 @@ lpfc_sli_handle_slow_ring_event_s4(struc
+                                                          irspiocbq);
+                       break;
+               case CQE_CODE_RECEIVE:
++              case CQE_CODE_RECEIVE_V1:
+                       dmabuf = container_of(cq_event, struct hbq_dmabuf,
+                                             cq_event);
+                       lpfc_sli4_handle_received_buffer(phba, dmabuf);
+@@ -7318,12 +7320,12 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+               bf_set(wqe_qosd, &wqe->els_req.wqe_com, 1);
+               bf_set(wqe_lenloc, &wqe->els_req.wqe_com, LPFC_WQE_LENLOC_NONE);
+               bf_set(wqe_ebde_cnt, &wqe->els_req.wqe_com, 0);
+-      break;
++              break;
+       case CMD_XMIT_SEQUENCE64_CX:
+               bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com,
+                      iocbq->iocb.un.ulpWord[3]);
+               bf_set(wqe_rcvoxid, &wqe->xmit_sequence.wqe_com,
+-                     iocbq->iocb.ulpContext);
++                     iocbq->iocb.unsli3.rcvsli3.ox_id);
+               /* The entire sequence is transmitted for this IOCB */
+               xmit_len = total_len;
+               cmnd = CMD_XMIT_SEQUENCE64_CR;
+@@ -7341,7 +7343,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+               bf_set(wqe_ebde_cnt, &wqe->xmit_sequence.wqe_com, 0);
+               wqe->xmit_sequence.xmit_len = xmit_len;
+               command_type = OTHER_COMMAND;
+-      break;
++              break;
+       case CMD_XMIT_BCAST64_CN:
+               /* word3 iocb=iotag32 wqe=seq_payload_len */
+               wqe->xmit_bcast64.seq_payload_len = xmit_len;
+@@ -7355,7 +7357,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+               bf_set(wqe_lenloc, &wqe->xmit_bcast64.wqe_com,
+                      LPFC_WQE_LENLOC_WORD3);
+               bf_set(wqe_ebde_cnt, &wqe->xmit_bcast64.wqe_com, 0);
+-      break;
++              break;
+       case CMD_FCP_IWRITE64_CR:
+               command_type = FCP_COMMAND_DATA_OUT;
+               /* word3 iocb=iotag wqe=payload_offset_len */
+@@ -7375,7 +7377,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+                      LPFC_WQE_LENLOC_WORD4);
+               bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0);
+               bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU);
+-      break;
++              break;
+       case CMD_FCP_IREAD64_CR:
+               /* word3 iocb=iotag wqe=payload_offset_len */
+               /* Add the FCP_CMD and FCP_RSP sizes to get the offset */
+@@ -7394,7 +7396,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+                      LPFC_WQE_LENLOC_WORD4);
+               bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0);
+               bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU);
+-      break;
++              break;
+       case CMD_FCP_ICMND64_CR:
+               /* word3 iocb=IO_TAG wqe=reserved */
+               wqe->fcp_icmd.rsrvd3 = 0;
+@@ -7407,7 +7409,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+               bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com,
+                      LPFC_WQE_LENLOC_NONE);
+               bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0);
+-      break;
++              break;
+       case CMD_GEN_REQUEST64_CR:
+               /* For this command calculate the xmit length of the
+                * request bde.
+@@ -7442,7 +7444,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+               bf_set(wqe_lenloc, &wqe->gen_req.wqe_com, LPFC_WQE_LENLOC_NONE);
+               bf_set(wqe_ebde_cnt, &wqe->gen_req.wqe_com, 0);
+               command_type = OTHER_COMMAND;
+-      break;
++              break;
+       case CMD_XMIT_ELS_RSP64_CX:
+               ndlp = (struct lpfc_nodelist *)iocbq->context1;
+               /* words0-2 BDE memcpy */
+@@ -7457,7 +7459,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+                      ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
+               bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU);
+               bf_set(wqe_rcvoxid, &wqe->xmit_els_rsp.wqe_com,
+-                     iocbq->iocb.ulpContext);
++                     iocbq->iocb.unsli3.rcvsli3.ox_id);
+               if (!iocbq->iocb.ulpCt_h && iocbq->iocb.ulpCt_l)
+                       bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
+                              phba->vpi_ids[iocbq->vport->vpi]);
+@@ -7470,7 +7472,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+               bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp,
+                      phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
+               command_type = OTHER_COMMAND;
+-      break;
++              break;
+       case CMD_CLOSE_XRI_CN:
+       case CMD_ABORT_XRI_CN:
+       case CMD_ABORT_XRI_CX:
+@@ -7509,7 +7511,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+               cmnd = CMD_ABORT_XRI_CX;
+               command_type = OTHER_COMMAND;
+               xritag = 0;
+-      break;
++              break;
+       case CMD_XMIT_BLS_RSP64_CX:
+               /* As BLS ABTS RSP WQE is very different from other WQEs,
+                * we re-construct this WQE here based on information in
+@@ -7553,7 +7555,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+                              bf_get(lpfc_rsn_code, &iocbq->iocb.un.bls_rsp));
+               }
+-      break;
++              break;
+       case CMD_XRI_ABORTED_CX:
+       case CMD_CREATE_XRI_CR: /* Do we expect to use this? */
+       case CMD_IOCB_FCP_IBIDIR64_CR: /* bidirectional xfer */
+@@ -7565,7 +7567,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba
+                               "2014 Invalid command 0x%x\n",
+                               iocbq->iocb.ulpCommand);
+               return IOCB_ERROR;
+-      break;
++              break;
+       }
+       bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag);
+@@ -10481,10 +10483,14 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba
+       struct lpfc_queue *hrq = phba->sli4_hba.hdr_rq;
+       struct lpfc_queue *drq = phba->sli4_hba.dat_rq;
+       struct hbq_dmabuf *dma_buf;
+-      uint32_t status;
++      uint32_t status, rq_id;
+       unsigned long iflags;
+-      if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id)
++      if (bf_get(lpfc_cqe_code, rcqe) == CQE_CODE_RECEIVE_V1)
++              rq_id = bf_get(lpfc_rcqe_rq_id_v1, rcqe);
++      else
++              rq_id = bf_get(lpfc_rcqe_rq_id, rcqe);
++      if (rq_id != hrq->queue_id)
+               goto out;
+       status = bf_get(lpfc_rcqe_status, rcqe);
+@@ -10563,6 +10569,7 @@ lpfc_sli4_sp_handle_cqe(struct lpfc_hba
+                               (struct sli4_wcqe_xri_aborted *)&cqevt);
+               break;
+       case CQE_CODE_RECEIVE:
++      case CQE_CODE_RECEIVE_V1:
+               /* Process the RQ event */
+               phba->last_completion_time = jiffies;
+               workposted = lpfc_sli4_sp_handle_rcqe(phba,
+@@ -13405,7 +13412,7 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc
+  * This function validates the xri maps to the known range of XRIs allocated an
+  * used by the driver.
+  **/
+-static uint16_t
++uint16_t
+ lpfc_sli4_xri_inrange(struct lpfc_hba *phba,
+                     uint16_t xri)
+ {
+@@ -13642,10 +13649,12 @@ lpfc_seq_complete(struct hbq_dmabuf *dma
+ static struct lpfc_iocbq *
+ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
+ {
++      struct hbq_dmabuf *hbq_buf;
+       struct lpfc_dmabuf *d_buf, *n_buf;
+       struct lpfc_iocbq *first_iocbq, *iocbq;
+       struct fc_frame_header *fc_hdr;
+       uint32_t sid;
++      uint32_t len, tot_len;
+       struct ulp_bde64 *pbde;
+       fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt;
+@@ -13654,6 +13663,7 @@ lpfc_prep_seq(struct lpfc_vport *vport,
+       lpfc_update_rcv_time_stamp(vport);
+       /* get the Remote Port's SID */
+       sid = sli4_sid_from_fc_hdr(fc_hdr);
++      tot_len = 0;
+       /* Get an iocbq struct to fill in. */
+       first_iocbq = lpfc_sli_get_iocbq(vport->phba);
+       if (first_iocbq) {
+@@ -13661,9 +13671,12 @@ lpfc_prep_seq(struct lpfc_vport *vport,
+               first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
+               first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
+               first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
+-              first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id);
+-              /* iocbq is prepped for internal consumption.  Logical vpi. */
+-              first_iocbq->iocb.unsli3.rcvsli3.vpi = vport->vpi;
++              first_iocbq->iocb.ulpContext = NO_XRI;
++              first_iocbq->iocb.unsli3.rcvsli3.ox_id =
++                      be16_to_cpu(fc_hdr->fh_ox_id);
++              /* iocbq is prepped for internal consumption.  Physical vpi. */
++              first_iocbq->iocb.unsli3.rcvsli3.vpi =
++                      vport->phba->vpi_ids[vport->vpi];
+               /* put the first buffer into the first IOCBq */
+               first_iocbq->context2 = &seq_dmabuf->dbuf;
+               first_iocbq->context3 = NULL;
+@@ -13671,9 +13684,9 @@ lpfc_prep_seq(struct lpfc_vport *vport,
+               first_iocbq->iocb.un.cont64[0].tus.f.bdeSize =
+                                                       LPFC_DATA_BUF_SIZE;
+               first_iocbq->iocb.un.rcvels.remoteID = sid;
+-              first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
+-                              bf_get(lpfc_rcqe_length,
++              tot_len = bf_get(lpfc_rcqe_length,
+                                      &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
++              first_iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
+       }
+       iocbq = first_iocbq;
+       /*
+@@ -13691,9 +13704,13 @@ lpfc_prep_seq(struct lpfc_vport *vport,
+                       pbde = (struct ulp_bde64 *)
+                                       &iocbq->iocb.unsli3.sli3Words[4];
+                       pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE;
+-                      first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
+-                              bf_get(lpfc_rcqe_length,
+-                                     &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
++
++                      /* We need to get the size out of the right CQE */
++                      hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
++                      len = bf_get(lpfc_rcqe_length,
++                                     &hbq_buf->cq_event.cqe.rcqe_cmpl);
++                      iocbq->iocb.unsli3.rcvsli3.acc_len += len;
++                      tot_len += len;
+               } else {
+                       iocbq = lpfc_sli_get_iocbq(vport->phba);
+                       if (!iocbq) {
+@@ -13711,9 +13728,14 @@ lpfc_prep_seq(struct lpfc_vport *vport,
+                       iocbq->iocb.ulpBdeCount = 1;
+                       iocbq->iocb.un.cont64[0].tus.f.bdeSize =
+                                                       LPFC_DATA_BUF_SIZE;
+-                      first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
+-                              bf_get(lpfc_rcqe_length,
+-                                     &seq_dmabuf->cq_event.cqe.rcqe_cmpl);
++
++                      /* We need to get the size out of the right CQE */
++                      hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
++                      len = bf_get(lpfc_rcqe_length,
++                                     &hbq_buf->cq_event.cqe.rcqe_cmpl);
++                      tot_len += len;
++                      iocbq->iocb.unsli3.rcvsli3.acc_len = tot_len;
++
+                       iocbq->iocb.un.rcvels.remoteID = sid;
+                       list_add_tail(&iocbq->list, &first_iocbq->list);
+               }
+@@ -13786,7 +13808,13 @@ lpfc_sli4_handle_received_buffer(struct
+               lpfc_in_buf_free(phba, &dmabuf->dbuf);
+               return;
+       }
+-      fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl);
++      if ((bf_get(lpfc_cqe_code,
++                  &dmabuf->cq_event.cqe.rcqe_cmpl) == CQE_CODE_RECEIVE_V1))
++              fcfi = bf_get(lpfc_rcqe_fcf_id_v1,
++                            &dmabuf->cq_event.cqe.rcqe_cmpl);
++      else
++              fcfi = bf_get(lpfc_rcqe_fcf_id,
++                            &dmabuf->cq_event.cqe.rcqe_cmpl);
+       vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
+       if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) {
+               /* throw out the frame */
diff --git a/queue-3.0/lpfc-8.3.25-fabric-and-target-discovery-fixes.patch b/queue-3.0/lpfc-8.3.25-fabric-and-target-discovery-fixes.patch
new file mode 100644 (file)
index 0000000..c86308b
--- /dev/null
@@ -0,0 +1,138 @@
+From 5248a7498e5f6f3d6d276080466946f82f0ea56a Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@emulex.com>
+Date: Fri, 22 Jul 2011 18:37:06 -0400
+Subject: [SCSI] lpfc 8.3.25: Fabric and Target Discovery Fixes
+
+From: James Smart <james.smart@emulex.com>
+
+commit 5248a7498e5f6f3d6d276080466946f82f0ea56a upstream.
+
+Fabric and Target Discovery Fixes
+
+- Clear FC_VPORT_NEEDS_INIT_VPI flag during completion of REG_VFI mailbox
+  command.
+- Prevent SLI3 Code from unregistering the physical VPI.
+- Add an else clause to the code that checks and sets
+  sp->cmn.request_multiple_Nport to clear the bit.
+- Remove a redundant mbox free.
+- Modified lpfc_sli4_async_fip_evt to pass in physical VPI toi
+  lpfc_find_vport_by_vpid function.
+- Modified lpfc_find_vport_by_vpid to translate physical VPI to logical VPI
+  before comparing with vport VPI.
+
+Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
+Signed-off-by: James Smart <james.smart@emulex.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/lpfc/lpfc_els.c     |   33 +++++++++++++++------------------
+ drivers/scsi/lpfc/lpfc_hbadisc.c |    2 +-
+ drivers/scsi/lpfc/lpfc_init.c    |    4 ++--
+ 3 files changed, 18 insertions(+), 21 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -647,21 +647,15 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_v
+               }
+               lpfc_cleanup_pending_mbox(vport);
+-              if (phba->sli_rev == LPFC_SLI_REV4)
++              if (phba->sli_rev == LPFC_SLI_REV4) {
+                       lpfc_sli4_unreg_all_rpis(vport);
+-
+-              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);
+-              }
+-              /*
+-               * If VPI is unreged, driver need to do INIT_VPI
+-               * before re-registering
+-               */
+-              if (phba->sli_rev == LPFC_SLI_REV4) {
+-                      spin_lock_irq(shost->host_lock);
++                      /*
++                      * If VPI is unreged, driver need to do INIT_VPI
++                      * before re-registering
++                      */
+                       vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
+                       spin_unlock_irq(shost->host_lock);
+               }
+@@ -1096,11 +1090,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *
+                       /* Set the fcfi to the fcfi we registered with */
+                       elsiocb->iocb.ulpContext = phba->fcf.fcfi;
+               }
+-      } else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
+-              sp->cmn.request_multiple_Nport = 1;
+-              /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
+-              icmd->ulpCt_h = 1;
+-              icmd->ulpCt_l = 0;
++      } else {
++              if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
++                      sp->cmn.request_multiple_Nport = 1;
++                      /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
++                      icmd->ulpCt_h = 1;
++                      icmd->ulpCt_l = 0;
++              } else
++                      sp->cmn.request_multiple_Nport = 0;
+       }
+       if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
+@@ -6608,7 +6605,7 @@ lpfc_find_vport_by_vpid(struct lpfc_hba
+ {
+       struct lpfc_vport *vport;
+       unsigned long flags;
+-      int i;
++      int i = 0;
+       /* The physical ports are always vpi 0 - translate is unnecessary. */
+       if (vpi > 0) {
+@@ -6631,7 +6628,7 @@ lpfc_find_vport_by_vpid(struct lpfc_hba
+       spin_lock_irqsave(&phba->hbalock, flags);
+       list_for_each_entry(vport, &phba->port_list, listentry) {
+-              if (vport->vpi == vpi) {
++              if (vport->vpi == i) {
+                       spin_unlock_irqrestore(&phba->hbalock, flags);
+                       return vport;
+               }
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -2247,7 +2247,6 @@ read_next_fcf:
+                               spin_lock_irq(&phba->hbalock);
+                               phba->fcf.fcf_flag |= FCF_REDISC_FOV;
+                               spin_unlock_irq(&phba->hbalock);
+-                              lpfc_sli4_mbox_cmd_free(phba, mboxq);
+                               lpfc_sli4_fcf_scan_read_fcf_rec(phba,
+                                               LPFC_FCOE_FCF_GET_FIRST);
+                               return;
+@@ -2645,6 +2644,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *p
+       vport->vpi_state |= LPFC_VPI_REGISTERED;
+       vport->fc_flag |= FC_VFI_REGISTERED;
+       vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
++      vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
+       spin_unlock_irq(shost->host_lock);
+       if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -3649,7 +3649,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba
+                       " tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag);
+               vport = lpfc_find_vport_by_vpid(phba,
+-                              acqe_fip->index - phba->vpi_base);
++                                              acqe_fip->index);
+               ndlp = lpfc_sli4_perform_vport_cvl(vport);
+               if (!ndlp)
+                       break;
+@@ -4518,7 +4518,7 @@ lpfc_sli4_driver_resource_setup(struct l
+               }
+       }
+-      return rc;
++      return 0;
+ out_free_fcp_eq_hdl:
+       kfree(phba->sli4_hba.fcp_eq_hdl);
diff --git a/queue-3.0/lpfc-8.3.25-miscellaneous-bug-fixes-and-code-cleanup.patch b/queue-3.0/lpfc-8.3.25-miscellaneous-bug-fixes-and-code-cleanup.patch
new file mode 100644 (file)
index 0000000..56008fb
--- /dev/null
@@ -0,0 +1,529 @@
+From 88a2cfbb8bf3802ca5a90c7d1567a1e542e6ef0c Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@emulex.com>
+Date: Fri, 22 Jul 2011 18:36:33 -0400
+Subject: [SCSI] lpfc 8.3.25: Miscellaneous Bug fixes and code cleanup
+
+From: James Smart <james.smart@emulex.com>
+
+commit 88a2cfbb8bf3802ca5a90c7d1567a1e542e6ef0c upstream.
+
+Miscellaneous Bug fixes and code cleanup
+
+- Fix 16G link speed reporting by adding check for 16G check.
+- Change the check and enforcement of MAILBOX_EXT_SIZE (2048B)
+  to the check and enforcement of BSG_MBOX_SIZE - sizeof(MAILBOX_t) (3840B).
+- Instead of waiting for a fixed amount of time after performing firmware
+  reset, the driver shall wait for the Lancer SLIPORT_STATUS register for the
+  readiness of the firmware for bring up.
+- Add logging to indicate when dynamic parameters are changed.
+- Add revision and date to the firmware image format.
+- Use revision instead of rev_name to check firmware image version.
+- Update temporary offset after memcopy is complete for firmware update.
+- Consolidated the use of the macros to get rid of duplicated register
+  offset definitions.
+- Removed the unused second parameter in routine lpfc_bsg_diag_mode_enter()
+- Enable debugfs when debugfs is enabled.
+- Update function comments for lpfc_sli4_alloc_xri and lpfc_sli4_init_rpi_hdrs.
+
+Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
+Signed-off-by: James Smart <james.smart@emulex.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/lpfc/lpfc.h      |    5 +++
+ drivers/scsi/lpfc/lpfc_attr.c |   67 +++++++++++++++++++++++++++++++++++++++++-
+ drivers/scsi/lpfc/lpfc_bsg.c  |   37 +++++++++++++----------
+ drivers/scsi/lpfc/lpfc_hw4.h  |   21 +++++--------
+ drivers/scsi/lpfc/lpfc_init.c |   34 +++++++++++----------
+ drivers/scsi/lpfc/lpfc_sli.c  |   17 +++++-----
+ drivers/scsi/lpfc/lpfc_sli4.h |    2 +
+ 7 files changed, 129 insertions(+), 54 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -20,6 +20,11 @@
+  *******************************************************************/
+ #include <scsi/scsi_host.h>
++
++#if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_SCSI_LPFC_DEBUG_FS)
++#define CONFIG_SCSI_LPFC_DEBUG_FS
++#endif
++
+ struct lpfc_sli2_slim;
+ #define LPFC_PCI_DEV_LP               0x1
+--- a/drivers/scsi/lpfc/lpfc_attr.c
++++ b/drivers/scsi/lpfc/lpfc_attr.c
+@@ -755,6 +755,47 @@ lpfc_issue_reset(struct device *dev, str
+ }
+ /**
++ * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness
++ * @phba: lpfc_hba pointer.
++ *
++ * Description:
++ * SLI4 interface type-2 device to wait on the sliport status register for
++ * the readyness after performing a firmware reset.
++ *
++ * Returns:
++ * zero for success
++ **/
++static int
++lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
++{
++      struct lpfc_register portstat_reg;
++      int i;
++
++
++      lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
++                 &portstat_reg.word0);
++
++      /* wait for the SLI port firmware ready after firmware reset */
++      for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) {
++              msleep(10);
++              lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
++                         &portstat_reg.word0);
++              if (!bf_get(lpfc_sliport_status_err, &portstat_reg))
++                      continue;
++              if (!bf_get(lpfc_sliport_status_rn, &portstat_reg))
++                      continue;
++              if (!bf_get(lpfc_sliport_status_rdy, &portstat_reg))
++                      continue;
++              break;
++      }
++
++      if (i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT)
++              return 0;
++      else
++              return -EIO;
++}
++
++/**
+  * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc
+  * @phba: lpfc_hba pointer.
+  *
+@@ -805,7 +846,10 @@ lpfc_sli4_pdev_reg_request(struct lpfc_h
+       readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
+       /* delay driver action following IF_TYPE_2 reset */
+-      msleep(100);
++      rc = lpfc_sli4_pdev_status_reg_wait(phba);
++
++      if (rc)
++              return -EIO;
+       init_completion(&online_compl);
+       rc = lpfc_workq_post_event(phba, &status, &online_compl,
+@@ -895,6 +939,10 @@ lpfc_board_mode_store(struct device *dev
+       if (!phba->cfg_enable_hba_reset)
+               return -EACCES;
++
++      lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
++              "3050 lpfc_board_mode set to %s\n", buf);
++
+       init_completion(&online_compl);
+       if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
+@@ -1290,6 +1338,10 @@ lpfc_poll_store(struct device *dev, stru
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               val = 0;
++      lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
++              "3051 lpfc_poll changed from %d to %d\n",
++              phba->cfg_poll, val);
++
+       spin_lock_irq(&phba->hbalock);
+       old_val = phba->cfg_poll;
+@@ -1605,6 +1657,9 @@ static int \
+ lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \
+ { \
+       if (val >= minval && val <= maxval) {\
++              lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
++                      "3052 lpfc_" #attr " changed from %d to %d\n", \
++                      phba->cfg_##attr, val); \
+               phba->cfg_##attr = val;\
+               return 0;\
+       }\
+@@ -1762,6 +1817,9 @@ static int \
+ lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \
+ { \
+       if (val >= minval && val <= maxval) {\
++              lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
++                      "3053 lpfc_" #attr " changed from %d to %d\n", \
++                      vport->cfg_##attr, val); \
+               vport->cfg_##attr = val;\
+               return 0;\
+       }\
+@@ -2678,6 +2736,9 @@ lpfc_topology_store(struct device *dev,
+               if (nolip)
+                       return strlen(buf);
++              lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
++                      "3054 lpfc_topology changed from %d to %d\n",
++                      prev_val, val);
+               err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
+               if (err) {
+                       phba->cfg_topology = prev_val;
+@@ -3101,6 +3162,10 @@ lpfc_link_speed_store(struct device *dev
+       if (sscanf(val_buf, "%i", &val) != 1)
+               return -EINVAL;
++      lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
++              "3055 lpfc_link_speed changed from %d to %d %s\n",
++              phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
++
+       if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
+           ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
+           ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
+--- a/drivers/scsi/lpfc/lpfc_bsg.c
++++ b/drivers/scsi/lpfc/lpfc_bsg.c
+@@ -1471,13 +1471,12 @@ send_mgmt_rsp_exit:
+ /**
+  * lpfc_bsg_diag_mode_enter - process preparing into device diag loopback mode
+  * @phba: Pointer to HBA context object.
+- * @job: LPFC_BSG_VENDOR_DIAG_MODE
+  *
+  * This function is responsible for preparing driver for diag loopback
+  * on device.
+  */
+ static int
+-lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba, struct fc_bsg_job *job)
++lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba)
+ {
+       struct lpfc_vport **vports;
+       struct Scsi_Host *shost;
+@@ -1521,7 +1520,6 @@ lpfc_bsg_diag_mode_enter(struct lpfc_hba
+ /**
+  * lpfc_bsg_diag_mode_exit - exit process from device diag loopback mode
+  * @phba: Pointer to HBA context object.
+- * @job: LPFC_BSG_VENDOR_DIAG_MODE
+  *
+  * This function is responsible for driver exit processing of setting up
+  * diag loopback mode on device.
+@@ -1586,7 +1584,7 @@ lpfc_sli3_bsg_diag_loopback_mode(struct
+               goto job_error;
+       }
+-      rc = lpfc_bsg_diag_mode_enter(phba, job);
++      rc = lpfc_bsg_diag_mode_enter(phba);
+       if (rc)
+               goto job_error;
+@@ -1758,7 +1756,7 @@ lpfc_sli4_bsg_diag_loopback_mode(struct
+               goto job_error;
+       }
+-      rc = lpfc_bsg_diag_mode_enter(phba, job);
++      rc = lpfc_bsg_diag_mode_enter(phba);
+       if (rc)
+               goto job_error;
+@@ -1982,7 +1980,7 @@ lpfc_sli4_bsg_link_diag_test(struct fc_b
+               goto job_error;
+       }
+-      rc = lpfc_bsg_diag_mode_enter(phba, job);
++      rc = lpfc_bsg_diag_mode_enter(phba);
+       if (rc)
+               goto job_error;
+@@ -3511,7 +3509,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpf
+               lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+                               "2947 Issued SLI_CONFIG ext-buffer "
+                               "maibox command, rc:x%x\n", rc);
+-              return 1;
++              return SLI_CONFIG_HANDLED;
+       }
+       lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+                       "2948 Failed to issue SLI_CONFIG ext-buffer "
+@@ -3549,7 +3547,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lp
+       LPFC_MBOXQ_t *pmboxq = NULL;
+       MAILBOX_t *pmb;
+       uint8_t *mbx;
+-      int rc = 0, i;
++      int rc = SLI_CONFIG_NOT_HANDLED, i;
+       mbox_req =
+          (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+@@ -3660,7 +3658,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lp
+                       lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+                                       "2955 Issued SLI_CONFIG ext-buffer "
+                                       "maibox command, rc:x%x\n", rc);
+-                      return 1;
++                      return SLI_CONFIG_HANDLED;
+               }
+               lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+                               "2956 Failed to issue SLI_CONFIG ext-buffer "
+@@ -3668,6 +3666,11 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lp
+               rc = -EPIPE;
+       }
++      /* wait for additoinal external buffers */
++      job->reply->result = 0;
++      job->job_done(job);
++      return SLI_CONFIG_HANDLED;
++
+ job_error:
+       if (pmboxq)
+               mempool_free(pmboxq, phba->mbox_mem_pool);
+@@ -3959,7 +3962,7 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba
+                       lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+                                       "2969 Issued SLI_CONFIG ext-buffer "
+                                       "maibox command, rc:x%x\n", rc);
+-                      return 1;
++                      return SLI_CONFIG_HANDLED;
+               }
+               lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+                               "2970 Failed to issue SLI_CONFIG ext-buffer "
+@@ -4039,14 +4042,14 @@ lpfc_bsg_handle_sli_cfg_ext(struct lpfc_
+                           struct lpfc_dmabuf *dmabuf)
+ {
+       struct dfc_mbox_req *mbox_req;
+-      int rc;
++      int rc = SLI_CONFIG_NOT_HANDLED;
+       mbox_req =
+          (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+       /* mbox command with/without single external buffer */
+       if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0)
+-              return SLI_CONFIG_NOT_HANDLED;
++              return rc;
+       /* mbox command and first external buffer */
+       if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE) {
+@@ -4249,7 +4252,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phb
+                * mailbox extension size
+                */
+               if ((transmit_length > receive_length) ||
+-                      (transmit_length > MAILBOX_EXT_SIZE)) {
++                      (transmit_length > BSG_MBOX_SIZE - sizeof(MAILBOX_t))) {
+                       rc = -ERANGE;
+                       goto job_done;
+               }
+@@ -4272,7 +4275,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phb
+               /* receive length cannot be greater than mailbox
+                * extension size
+                */
+-              if (receive_length > MAILBOX_EXT_SIZE) {
++              if (receive_length > BSG_MBOX_SIZE - sizeof(MAILBOX_t)) {
+                       rc = -ERANGE;
+                       goto job_done;
+               }
+@@ -4306,7 +4309,8 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phb
+                       bde = (struct ulp_bde64 *)&pmb->un.varWords[4];
+                       /* bde size cannot be greater than mailbox ext size */
+-                      if (bde->tus.f.bdeSize > MAILBOX_EXT_SIZE) {
++                      if (bde->tus.f.bdeSize >
++                          BSG_MBOX_SIZE - sizeof(MAILBOX_t)) {
+                               rc = -ERANGE;
+                               goto job_done;
+                       }
+@@ -4332,7 +4336,8 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phb
+                                * mailbox extension size
+                                */
+                               if ((receive_length == 0) ||
+-                                  (receive_length > MAILBOX_EXT_SIZE)) {
++                                  (receive_length >
++                                   BSG_MBOX_SIZE - sizeof(MAILBOX_t))) {
+                                       rc = -ERANGE;
+                                       goto job_done;
+                               }
+--- a/drivers/scsi/lpfc/lpfc_hw4.h
++++ b/drivers/scsi/lpfc/lpfc_hw4.h
+@@ -170,15 +170,8 @@ struct lpfc_sli_intf {
+ #define LPFC_PCI_FUNC3                3
+ #define LPFC_PCI_FUNC4                4
+-/* SLI4 interface type-2 control register offsets */
+-#define LPFC_CTL_PORT_SEM_OFFSET      0x400
+-#define LPFC_CTL_PORT_STA_OFFSET      0x404
+-#define LPFC_CTL_PORT_CTL_OFFSET      0x408
+-#define LPFC_CTL_PORT_ER1_OFFSET      0x40C
+-#define LPFC_CTL_PORT_ER2_OFFSET      0x410
++/* SLI4 interface type-2 PDEV_CTL register */
+ #define LPFC_CTL_PDEV_CTL_OFFSET      0x414
+-
+-/* Some SLI4 interface type-2 PDEV_CTL register bits */
+ #define LPFC_CTL_PDEV_CTL_DRST                0x00000001
+ #define LPFC_CTL_PDEV_CTL_FRST                0x00000002
+ #define LPFC_CTL_PDEV_CTL_DD          0x00000004
+@@ -515,7 +508,7 @@ struct lpfc_register {
+ /* The following BAR0 register sets are defined for if_type 0 and 2 UCNAs. */
+ #define LPFC_SLI_INTF                 0x0058
+-#define LPFC_SLIPORT_IF2_SMPHR                0x0400
++#define LPFC_CTL_PORT_SEM_OFFSET      0x400
+ #define lpfc_port_smphr_perr_SHIFT    31
+ #define lpfc_port_smphr_perr_MASK     0x1
+ #define lpfc_port_smphr_perr_WORD     word0
+@@ -575,7 +568,7 @@ struct lpfc_register {
+ #define LPFC_POST_STAGE_PORT_READY                    0xC000
+ #define LPFC_POST_STAGE_PORT_UE                       0xF000
+-#define LPFC_SLIPORT_STATUS           0x0404
++#define LPFC_CTL_PORT_STA_OFFSET      0x404
+ #define lpfc_sliport_status_err_SHIFT 31
+ #define lpfc_sliport_status_err_MASK  0x1
+ #define lpfc_sliport_status_err_WORD  word0
+@@ -593,7 +586,7 @@ struct lpfc_register {
+ #define lpfc_sliport_status_rdy_WORD  word0
+ #define MAX_IF_TYPE_2_RESETS  1000
+-#define LPFC_SLIPORT_CNTRL            0x0408
++#define LPFC_CTL_PORT_CTL_OFFSET      0x408
+ #define lpfc_sliport_ctrl_end_SHIFT   30
+ #define lpfc_sliport_ctrl_end_MASK    0x1
+ #define lpfc_sliport_ctrl_end_WORD    word0
+@@ -604,8 +597,8 @@ struct lpfc_register {
+ #define lpfc_sliport_ctrl_ip_WORD     word0
+ #define LPFC_SLIPORT_INIT_PORT        1
+-#define LPFC_SLIPORT_ERR_1            0x040C
+-#define LPFC_SLIPORT_ERR_2            0x0410
++#define LPFC_CTL_PORT_ER1_OFFSET      0x40C
++#define LPFC_CTL_PORT_ER2_OFFSET      0x410
+ /* The following Registers apply to SLI4 if_type 0 UCNAs. They typically
+  * reside in BAR 2.
+@@ -3198,6 +3191,8 @@ struct lpfc_grp_hdr {
+ #define lpfc_grp_hdr_id_MASK          0x000000FF
+ #define lpfc_grp_hdr_id_WORD          word2
+       uint8_t rev_name[128];
++      uint8_t date[12];
++      uint8_t revision[32];
+ };
+ #define FCP_COMMAND 0x0
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -2927,6 +2927,8 @@ void lpfc_host_attrib_init(struct Scsi_H
+                                sizeof fc_host_symbolic_name(shost));
+       fc_host_supported_speeds(shost) = 0;
++      if (phba->lmt & LMT_16Gb)
++              fc_host_supported_speeds(shost) |= FC_PORTSPEED_16GBIT;
+       if (phba->lmt & LMT_10Gb)
+               fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
+       if (phba->lmt & LMT_8Gb)
+@@ -4966,17 +4968,14 @@ out_free_mem:
+  * @phba: pointer to lpfc hba data structure.
+  *
+  * This routine is invoked to post rpi header templates to the
+- * HBA consistent with the SLI-4 interface spec.  This routine
++ * port for those SLI4 ports that do not support extents.  This routine
+  * posts a PAGE_SIZE memory region to the port to hold up to
+- * PAGE_SIZE modulo 64 rpi context headers.
+- * No locks are held here because this is an initialization routine
+- * called only from probe or lpfc_online when interrupts are not
+- * enabled and the driver is reinitializing the device.
++ * PAGE_SIZE modulo 64 rpi context headers.  This is an initialization routine
++ * and should be called only when interrupts are disabled.
+  *
+  * Return codes
+  *    0 - successful
+- *    -ENOMEM - No available memory
+- *      -EIO - The mailbox failed to complete successfully.
++ *    -ERROR - otherwise.
+  **/
+ int
+ lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba)
+@@ -5687,17 +5686,22 @@ lpfc_sli4_bar0_register_memmap(struct lp
+               break;
+       case LPFC_SLI_INTF_IF_TYPE_2:
+               phba->sli4_hba.u.if_type2.ERR1regaddr =
+-                      phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_1;
++                      phba->sli4_hba.conf_regs_memmap_p +
++                                              LPFC_CTL_PORT_ER1_OFFSET;
+               phba->sli4_hba.u.if_type2.ERR2regaddr =
+-                      phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_ERR_2;
++                      phba->sli4_hba.conf_regs_memmap_p +
++                                              LPFC_CTL_PORT_ER2_OFFSET;
+               phba->sli4_hba.u.if_type2.CTRLregaddr =
+-                      phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_CNTRL;
++                      phba->sli4_hba.conf_regs_memmap_p +
++                                              LPFC_CTL_PORT_CTL_OFFSET;
+               phba->sli4_hba.u.if_type2.STATUSregaddr =
+-                      phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_STATUS;
++                      phba->sli4_hba.conf_regs_memmap_p +
++                                              LPFC_CTL_PORT_STA_OFFSET;
+               phba->sli4_hba.SLIINTFregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_SLI_INTF;
+               phba->sli4_hba.PSMPHRregaddr =
+-                   phba->sli4_hba.conf_regs_memmap_p + LPFC_SLIPORT_IF2_SMPHR;
++                      phba->sli4_hba.conf_regs_memmap_p +
++                                              LPFC_CTL_PORT_SEM_OFFSET;
+               phba->sli4_hba.RQDBregaddr =
+                       phba->sli4_hba.conf_regs_memmap_p + LPFC_RQ_DOORBELL;
+               phba->sli4_hba.WQDBregaddr =
+@@ -8859,11 +8863,11 @@ lpfc_write_firmware(struct lpfc_hba *phb
+               return -EINVAL;
+       }
+       lpfc_decode_firmware_rev(phba, fwrev, 1);
+-      if (strncmp(fwrev, image->rev_name, strnlen(fwrev, 16))) {
++      if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "3023 Updating Firmware. Current Version:%s "
+                               "New Version:%s\n",
+-                              fwrev, image->rev_name);
++                              fwrev, image->revision);
+               for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) {
+                       dmabuf = kzalloc(sizeof(struct lpfc_dmabuf),
+                                        GFP_KERNEL);
+@@ -8892,9 +8896,9 @@ lpfc_write_firmware(struct lpfc_hba *phb
+                                              fw->size - offset);
+                                       break;
+                               }
+-                              temp_offset += SLI4_PAGE_SIZE;
+                               memcpy(dmabuf->virt, fw->data + temp_offset,
+                                      SLI4_PAGE_SIZE);
++                              temp_offset += SLI4_PAGE_SIZE;
+                       }
+                       rc = lpfc_wr_object(phba, &dma_buffer_list,
+                                   (fw->size - offset), &offset);
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -12345,19 +12345,18 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba
+ }
+ /**
+- * lpfc_sli4_init_rpi_hdrs - Post the rpi header memory region to the port
++ * lpfc_sli4_alloc_xri - Get an available rpi in the device's range
+  * @phba: pointer to lpfc hba data structure.
+  *
+  * This routine is invoked to post rpi header templates to the
+- * port for those SLI4 ports that do not support extents.  This routine
+- * posts a PAGE_SIZE memory region to the port to hold up to
+- * PAGE_SIZE modulo 64 rpi context headers.  This is an initialization routine
+- * and should be called only when interrupts are disabled.
++ * HBA consistent with the SLI-4 interface spec.  This routine
++ * posts a SLI4_PAGE_SIZE memory region to the port to hold up to
++ * SLI4_PAGE_SIZE modulo 64 rpi context headers.
+  *
+- * Return codes
+- *    0 - successful
+- *    -ERROR - otherwise.
+- */
++ * Returns
++ *    A nonzero rpi defined as rpi_base <= rpi < max_rpi if successful
++ *    LPFC_RPI_ALLOC_ERROR if no rpis are available.
++ **/
+ uint16_t
+ lpfc_sli4_alloc_xri(struct lpfc_hba *phba)
+ {
+--- a/drivers/scsi/lpfc/lpfc_sli4.h
++++ b/drivers/scsi/lpfc/lpfc_sli4.h
+@@ -81,6 +81,8 @@
+        (fc_hdr)->fh_f_ctl[1] <<  8 | \
+        (fc_hdr)->fh_f_ctl[2])
++#define LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT 12000
++
+ enum lpfc_sli4_queue_type {
+       LPFC_EQ,
+       LPFC_GCQ,
diff --git a/queue-3.0/lpfc-8.3.25-pci-and-sr-iov-fixes.patch b/queue-3.0/lpfc-8.3.25-pci-and-sr-iov-fixes.patch
new file mode 100644 (file)
index 0000000..7c0b8dd
--- /dev/null
@@ -0,0 +1,206 @@
+From 0a96e9754d6c4a2a31e50ee6c6e36ec13f80bc25 Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@emulex.com>
+Date: Fri, 22 Jul 2011 18:37:28 -0400
+Subject: [SCSI] lpfc 8.3.25: PCI and SR-IOV Fixes
+
+From: James Smart <james.smart@emulex.com>
+
+commit 0a96e9754d6c4a2a31e50ee6c6e36ec13f80bc25 upstream.
+
+PCI and SR-IOV Fixes
+
+- Call pci_save_state after the pci_restore_state completes.
+- After calling pci_enable_pcie_error_reporting() and checking the return
+  value for logging messages from rc, reset rc to 0 to it will not later be
+  interpreted for error.
+- Read PCI config space SR-IOV capability to get the number of VFs supported.
+- Check for the PF's supported number of VFs before invoking PCI enable sriov
+  API call and log error message that user requested number of VFs is beyond
+  the PF capability if such request is passed in.
+- Added check for Physical function with Virtual Functions attached. If so,
+  first disable all the VFs before proceeding to device reset.
+
+Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
+Signed-off-by: James Smart <james.smart@emulex.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/lpfc/lpfc_attr.c |   76 +-----------------------------------------
+ drivers/scsi/lpfc/lpfc_crtn.h |    1 
+ drivers/scsi/lpfc/lpfc_init.c |   44 ++++++++++++++++++++++++
+ drivers/scsi/lpfc/lpfc_sli.c  |    1 
+ 4 files changed, 49 insertions(+), 73 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc_attr.c
++++ b/drivers/scsi/lpfc/lpfc_attr.c
+@@ -1466,80 +1466,10 @@ lpfc_sriov_hw_max_virtfn_show(struct dev
+       struct Scsi_Host *shost = class_to_shost(dev);
+       struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+       struct lpfc_hba *phba = vport->phba;
+-      struct pci_dev *pdev = phba->pcidev;
+-      union  lpfc_sli4_cfg_shdr *shdr;
+-      uint32_t shdr_status, shdr_add_status;
+-      LPFC_MBOXQ_t *mboxq;
+-      struct lpfc_mbx_get_prof_cfg *get_prof_cfg;
+-      struct lpfc_rsrc_desc_pcie *desc;
+-      uint32_t max_nr_virtfn;
+-      uint32_t desc_count;
+-      int length, rc, i;
++      uint16_t max_nr_virtfn;
+-      if ((phba->sli_rev < LPFC_SLI_REV4) ||
+-          (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+-           LPFC_SLI_INTF_IF_TYPE_2))
+-              return -EPERM;
+-
+-      if (!pdev->is_physfn)
+-              return snprintf(buf, PAGE_SIZE, "%d\n", 0);
+-
+-      mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+-      if (!mboxq)
+-              return -ENOMEM;
+-
+-      /* get the maximum number of virtfn support by physfn */
+-      length = (sizeof(struct lpfc_mbx_get_prof_cfg) -
+-                sizeof(struct lpfc_sli4_cfg_mhdr));
+-      lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+-                       LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG,
+-                       length, LPFC_SLI4_MBX_EMBED);
+-      shdr = (union lpfc_sli4_cfg_shdr *)
+-              &mboxq->u.mqe.un.sli4_config.header.cfg_shdr;
+-      bf_set(lpfc_mbox_hdr_pf_num, &shdr->request,
+-             phba->sli4_hba.iov.pf_number + 1);
+-
+-      get_prof_cfg = &mboxq->u.mqe.un.get_prof_cfg;
+-      bf_set(lpfc_mbx_get_prof_cfg_prof_tp, &get_prof_cfg->u.request,
+-             LPFC_CFG_TYPE_CURRENT_ACTIVE);
+-
+-      rc = lpfc_sli_issue_mbox_wait(phba, mboxq,
+-                              lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG));
+-
+-      if (rc != MBX_TIMEOUT) {
+-              /* check return status */
+-              shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+-              shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+-                                       &shdr->response);
+-              if (shdr_status || shdr_add_status || rc)
+-                      goto error_out;
+-
+-      } else
+-              goto error_out;
+-
+-      desc_count = get_prof_cfg->u.response.prof_cfg.rsrc_desc_count;
+-
+-      for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) {
+-              desc = (struct lpfc_rsrc_desc_pcie *)
+-                      &get_prof_cfg->u.response.prof_cfg.desc[i];
+-              if (LPFC_RSRC_DESC_TYPE_PCIE ==
+-                  bf_get(lpfc_rsrc_desc_pcie_type, desc)) {
+-                      max_nr_virtfn = bf_get(lpfc_rsrc_desc_pcie_nr_virtfn,
+-                                             desc);
+-                      break;
+-              }
+-      }
+-
+-      if (i < LPFC_RSRC_DESC_MAX_NUM) {
+-              if (rc != MBX_TIMEOUT)
+-                      mempool_free(mboxq, phba->mbox_mem_pool);
+-              return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
+-      }
+-
+-error_out:
+-      if (rc != MBX_TIMEOUT)
+-              mempool_free(mboxq, phba->mbox_mem_pool);
+-      return -EIO;
++      max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba);
++      return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
+ }
+ /**
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -440,3 +440,4 @@ struct lpfc_node_rrq *lpfc_get_active_rr
+ int lpfc_wr_object(struct lpfc_hba *, struct list_head *, uint32_t, uint32_t *);
+ /* functions to support SR-IOV */
+ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int);
++uint16_t lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *);
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -4037,6 +4037,34 @@ lpfc_reset_hba(struct lpfc_hba *phba)
+ }
+ /**
++ * lpfc_sli_sriov_nr_virtfn_get - Get the number of sr-iov virtual functions
++ * @phba: pointer to lpfc hba data structure.
++ *
++ * This function enables the PCI SR-IOV virtual functions to a physical
++ * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to
++ * enable the number of virtual functions to the physical function. As
++ * not all devices support SR-IOV, the return code from the pci_enable_sriov()
++ * API call does not considered as an error condition for most of the device.
++ **/
++uint16_t
++lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *phba)
++{
++      struct pci_dev *pdev = phba->pcidev;
++      uint16_t nr_virtfn;
++      int pos;
++
++      if (!pdev->is_physfn)
++              return 0;
++
++      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
++      if (pos == 0)
++              return 0;
++
++      pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF, &nr_virtfn);
++      return nr_virtfn;
++}
++
++/**
+  * lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions
+  * @phba: pointer to lpfc hba data structure.
+  * @nr_vfn: number of virtual functions to be enabled.
+@@ -4051,8 +4079,17 @@ int
+ lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn)
+ {
+       struct pci_dev *pdev = phba->pcidev;
++      uint16_t max_nr_vfn;
+       int rc;
++      max_nr_vfn = lpfc_sli_sriov_nr_virtfn_get(phba);
++      if (nr_vfn > max_nr_vfn) {
++              lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
++                              "3057 Requested vfs (%d) greater than "
++                              "supported vfs (%d)", nr_vfn, max_nr_vfn);
++              return -EINVAL;
++      }
++
+       rc = pci_enable_sriov(pdev, nr_vfn);
+       if (rc) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+@@ -9487,6 +9524,13 @@ lpfc_io_slot_reset_s4(struct pci_dev *pd
+       }
+       pci_restore_state(pdev);
++
++      /*
++       * As the new kernel behavior of pci_restore_state() API call clears
++       * device saved_state flag, need to save the restored state again.
++       */
++      pci_save_state(pdev);
++
+       if (pdev->is_busmaster)
+               pci_set_master(pdev);
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -5839,6 +5839,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phb
+                                       "Advanced Error Reporting (AER)\n");
+                       phba->cfg_aer_support = 0;
+               }
++              rc = 0;
+       }
+       if (!(phba->hba_flag & HBA_FCOE_MODE)) {
diff --git a/queue-3.0/lpfc-8.3.25-t10-dif-fixes.patch b/queue-3.0/lpfc-8.3.25-t10-dif-fixes.patch
new file mode 100644 (file)
index 0000000..10f0023
--- /dev/null
@@ -0,0 +1,264 @@
+From 7c56b9fd3b6d2d933075d12abee67ceb7c90d04a Mon Sep 17 00:00:00 2001
+From: James Smart <james.smart@emulex.com>
+Date: Fri, 22 Jul 2011 18:36:25 -0400
+Subject: [SCSI] lpfc 8.3.25: T10 DIF Fixes
+
+From: James Smart <james.smart@emulex.com>
+
+commit 7c56b9fd3b6d2d933075d12abee67ceb7c90d04a upstream.
+
+T10 DIF Fixes
+
+- Fix the case where the SCSI Host supplies the CRC and driver to controller
+  protection is on.
+- Only support T10 DIF type 1. LBA always goes in ref tag and app tag is not
+  checked.
+- Change the format of the sense data passed up to the SCSI layer to match the
+  Descriptor Format Sense Data found in SPC-4 sections 4.5.2.1 and 4.5.2.2.
+- Fix Slip PDE implementation.
+- Remove BUG() in else casein lpfc_sc_to_bg_opcodes.
+
+Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
+Signed-off-by: James Smart <james.smart@emulex.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/lpfc/lpfc_attr.c |    4 +
+ drivers/scsi/lpfc/lpfc_scsi.c |   97 ++++++++++++------------------------------
+ 2 files changed, 33 insertions(+), 68 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc_attr.c
++++ b/drivers/scsi/lpfc/lpfc_attr.c
+@@ -3678,7 +3678,9 @@ LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable
+ #     - Default will result in registering capabilities for all profiles.
+ #
+ */
+-unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION;
++unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION |
++                            SHOST_DIX_TYPE0_PROTECTION |
++                            SHOST_DIX_TYPE1_PROTECTION;
+ module_param(lpfc_prot_mask, uint, S_IRUGO);
+ MODULE_PARM_DESC(lpfc_prot_mask, "host protection mask");
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -1302,13 +1302,13 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *p
+               case SCSI_PROT_NORMAL:
+               default:
+                       lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+-                              "9063 BLKGRD: Bad op/guard:%d/%d combination\n",
+-                                      scsi_get_prot_op(sc), guard_type);
++                              "9063 BLKGRD: Bad op/guard:%d/IP combination\n",
++                                      scsi_get_prot_op(sc));
+                       ret = 1;
+                       break;
+               }
+-      } else if (guard_type == SHOST_DIX_GUARD_CRC) {
++      } else {
+               switch (scsi_get_prot_op(sc)) {
+               case SCSI_PROT_READ_STRIP:
+               case SCSI_PROT_WRITE_INSERT:
+@@ -1324,17 +1324,18 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *p
+               case SCSI_PROT_READ_INSERT:
+               case SCSI_PROT_WRITE_STRIP:
++                      *txop = BG_OP_IN_CRC_OUT_NODIF;
++                      *rxop = BG_OP_IN_NODIF_OUT_CRC;
++                      break;
++
+               case SCSI_PROT_NORMAL:
+               default:
+                       lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+-                              "9075 BLKGRD: Bad op/guard:%d/%d combination\n",
+-                                      scsi_get_prot_op(sc), guard_type);
++                              "9075 BLKGRD: Bad op/guard:%d/CRC combination\n",
++                                      scsi_get_prot_op(sc));
+                       ret = 1;
+                       break;
+               }
+-      } else {
+-              /* unsupported format */
+-              BUG();
+       }
+       return ret;
+@@ -1352,45 +1353,6 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)
+       return sc->device->sector_size;
+ }
+-/**
+- * lpfc_get_cmd_dif_parms - Extract DIF parameters from SCSI command
+- * @sc:             in: SCSI command
+- * @apptagmask:     out: app tag mask
+- * @apptagval:      out: app tag value
+- * @reftag:         out: ref tag (reference tag)
+- *
+- * Description:
+- *   Extract DIF parameters from the command if possible.  Otherwise,
+- *   use default parameters.
+- *
+- **/
+-static inline void
+-lpfc_get_cmd_dif_parms(struct scsi_cmnd *sc, uint16_t *apptagmask,
+-              uint16_t *apptagval, uint32_t *reftag)
+-{
+-      struct  scsi_dif_tuple *spt;
+-      unsigned char op = scsi_get_prot_op(sc);
+-      unsigned int protcnt = scsi_prot_sg_count(sc);
+-      static int cnt;
+-
+-      if (protcnt && (op == SCSI_PROT_WRITE_STRIP ||
+-                              op == SCSI_PROT_WRITE_PASS)) {
+-
+-              cnt++;
+-              spt = page_address(sg_page(scsi_prot_sglist(sc))) +
+-                      scsi_prot_sglist(sc)[0].offset;
+-              *apptagmask = 0;
+-              *apptagval = 0;
+-              *reftag = cpu_to_be32(spt->ref_tag);
+-
+-      } else {
+-              /* SBC defines ref tag to be lower 32bits of LBA */
+-              *reftag = (uint32_t) (0xffffffff & scsi_get_lba(sc));
+-              *apptagmask = 0;
+-              *apptagval = 0;
+-      }
+-}
+-
+ /*
+  * This function sets up buffer list for protection groups of
+  * type LPFC_PG_TYPE_NO_DIF
+@@ -1427,9 +1389,8 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba,
+       dma_addr_t physaddr;
+       int i = 0, num_bde = 0, status;
+       int datadir = sc->sc_data_direction;
+-      unsigned blksize;
+       uint32_t reftag;
+-      uint16_t apptagmask, apptagval;
++      unsigned blksize;
+       uint8_t txop, rxop;
+       status  = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
+@@ -1438,17 +1399,16 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba,
+       /* extract some info from the scsi command for pde*/
+       blksize = lpfc_cmd_blksize(sc);
+-      lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag);
++      reftag = scsi_get_lba(sc) & 0xffffffff;
+       /* setup PDE5 with what we have */
+       pde5 = (struct lpfc_pde5 *) bpl;
+       memset(pde5, 0, sizeof(struct lpfc_pde5));
+       bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
+-      pde5->reftag = reftag;
+       /* Endianness conversion if necessary for PDE5 */
+       pde5->word0 = cpu_to_le32(pde5->word0);
+-      pde5->reftag = cpu_to_le32(pde5->reftag);
++      pde5->reftag = cpu_to_le32(reftag);
+       /* advance bpl and increment bde count */
+       num_bde++;
+@@ -1463,10 +1423,10 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba,
+       if (datadir == DMA_FROM_DEVICE) {
+               bf_set(pde6_ce, pde6, 1);
+               bf_set(pde6_re, pde6, 1);
+-              bf_set(pde6_ae, pde6, 1);
+       }
+       bf_set(pde6_ai, pde6, 1);
+-      bf_set(pde6_apptagval, pde6, apptagval);
++      bf_set(pde6_ae, pde6, 0);
++      bf_set(pde6_apptagval, pde6, 0);
+       /* Endianness conversion if necessary for PDE6 */
+       pde6->word0 = cpu_to_le32(pde6->word0);
+@@ -1551,7 +1511,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
+       unsigned char pgdone = 0, alldone = 0;
+       unsigned blksize;
+       uint32_t reftag;
+-      uint16_t apptagmask, apptagval;
+       uint8_t txop, rxop;
+       int num_bde = 0;
+@@ -1571,7 +1530,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
+       /* extract some info from the scsi command */
+       blksize = lpfc_cmd_blksize(sc);
+-      lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag);
++      reftag = scsi_get_lba(sc) & 0xffffffff;
+       split_offset = 0;
+       do {
+@@ -1579,11 +1538,10 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
+               pde5 = (struct lpfc_pde5 *) bpl;
+               memset(pde5, 0, sizeof(struct lpfc_pde5));
+               bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
+-              pde5->reftag = reftag;
+               /* Endianness conversion if necessary for PDE5 */
+               pde5->word0 = cpu_to_le32(pde5->word0);
+-              pde5->reftag = cpu_to_le32(pde5->reftag);
++              pde5->reftag = cpu_to_le32(reftag);
+               /* advance bpl and increment bde count */
+               num_bde++;
+@@ -1597,9 +1555,9 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
+               bf_set(pde6_oprx, pde6, rxop);
+               bf_set(pde6_ce, pde6, 1);
+               bf_set(pde6_re, pde6, 1);
+-              bf_set(pde6_ae, pde6, 1);
+               bf_set(pde6_ai, pde6, 1);
+-              bf_set(pde6_apptagval, pde6, apptagval);
++              bf_set(pde6_ae, pde6, 0);
++              bf_set(pde6_apptagval, pde6, 0);
+               /* Endianness conversion if necessary for PDE6 */
+               pde6->word0 = cpu_to_le32(pde6->word0);
+@@ -1621,8 +1579,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
+               memset(pde7, 0, sizeof(struct lpfc_pde7));
+               bf_set(pde7_type, pde7, LPFC_PDE7_DESCRIPTOR);
+-              pde7->addrHigh = le32_to_cpu(putPaddrLow(protphysaddr));
+-              pde7->addrLow = le32_to_cpu(putPaddrHigh(protphysaddr));
++              pde7->addrHigh = le32_to_cpu(putPaddrHigh(protphysaddr));
++              pde7->addrLow = le32_to_cpu(putPaddrLow(protphysaddr));
+               protgrp_blks = protgroup_len / 8;
+               protgrp_bytes = protgrp_blks * blksize;
+@@ -1632,7 +1590,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
+                       protgroup_remainder = 0x1000 - (pde7->addrLow & 0xfff);
+                       protgroup_offset += protgroup_remainder;
+                       protgrp_blks = protgroup_remainder / 8;
+-                      protgrp_bytes = protgroup_remainder * blksize;
++                      protgrp_bytes = protgrp_blks * blksize;
+               } else {
+                       protgroup_offset = 0;
+                       curr_prot++;
+@@ -2006,16 +1964,21 @@ lpfc_parse_bg_err(struct lpfc_hba *phba,
+       if (lpfc_bgs_get_hi_water_mark_present(bgstat)) {
+               /*
+                * setup sense data descriptor 0 per SPC-4 as an information
+-               * field, and put the failing LBA in it
++               * field, and put the failing LBA in it.
++               * This code assumes there was also a guard/app/ref tag error
++               * indication.
+                */
+-              cmd->sense_buffer[8] = 0;     /* Information */
+-              cmd->sense_buffer[9] = 0xa;   /* Add. length */
++              cmd->sense_buffer[7] = 0xc;   /* Additional sense length */
++              cmd->sense_buffer[8] = 0;     /* Information descriptor type */
++              cmd->sense_buffer[9] = 0xa;   /* Additional descriptor length */
++              cmd->sense_buffer[10] = 0x80; /* Validity bit */
+               bghm /= cmd->device->sector_size;
+               failing_sector = scsi_get_lba(cmd);
+               failing_sector += bghm;
+-              put_unaligned_be64(failing_sector, &cmd->sense_buffer[10]);
++              /* Descriptor Information */
++              put_unaligned_be64(failing_sector, &cmd->sense_buffer[12]);
+       }
+       if (!ret) {
index 492484cf2f3195862518a8c90212bdd08d2d6232..6639b47f09e9e87d3e3ed5cfde919b55e611fc3a 100644 (file)
@@ -192,3 +192,15 @@ bridge-fix-a-possible-use-after-free.patch
 zorro-defer-device_register-until-all-devices-have-been-identified.patch
 tpm-call-tpm_transmit-with-correct-size.patch
 tpm-zero-buffer-after-copying-to-userspace.patch
+lpfc-8.3.25-t10-dif-fixes.patch
+lpfc-8.3.25-miscellaneous-bug-fixes-and-code-cleanup.patch
+lpfc-8.3.25-adapter-interface-fixes-and-changes.patch
+lpfc-8.3.25-fabric-and-target-discovery-fixes.patch
+lpfc-8.3.25-pci-and-sr-iov-fixes.patch
+isci-change-sas-phy-timeouts-from-54us-to-59us.patch
+isci-leave-requests-alone-if-already-terminating.patch
+isci-fix-event-get-pointer-increment.patch
+ahci-raid-mode-sata-patch-for-intel-panther-point-deviceids.patch
+bluetooth-fix-timeout-on-scanning-for-the-second-time.patch
+libiscsi_tcp-fix-lld-data-allocation.patch
+cnic-fix-port_mode-setting.patch