diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-23 16:35:40 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-23 16:35:40 -0700 |
commit | 078b4c60326626ff446ef79bce67ced773ffbf99 (patch) | |
tree | cb1f0e17c4fde95b4ce382a5ef87880b8a42cb75 | |
parent | db533b0d78134d8a04bee68dc5a61e0cab3d093d (diff) | |
download | stable-queue-078b4c60326626ff446ef79bce67ced773ffbf99.tar.gz |
3.0 patches
13 files changed, 2144 insertions, 0 deletions
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 index 0000000000..bfde3aa06b --- /dev/null +++ b/queue-3.0/ahci-raid-mode-sata-patch-for-intel-panther-point-deviceids.patch @@ -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 index 0000000000..3763c9aedc --- /dev/null +++ b/queue-3.0/bluetooth-fix-timeout-on-scanning-for-the-second-time.patch @@ -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 index 0000000000..209d73879d --- /dev/null +++ b/queue-3.0/cnic-fix-port_mode-setting.patch @@ -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 index 0000000000..fc5de022fa --- /dev/null +++ b/queue-3.0/isci-change-sas-phy-timeouts-from-54us-to-59us.patch @@ -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 index 0000000000..0e28e86986 --- /dev/null +++ b/queue-3.0/isci-fix-event-get-pointer-increment.patch @@ -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 index 0000000000..e3134a3317 --- /dev/null +++ b/queue-3.0/isci-leave-requests-alone-if-already-terminating.patch @@ -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 index 0000000000..d50ea3b3f7 --- /dev/null +++ b/queue-3.0/libiscsi_tcp-fix-lld-data-allocation.patch @@ -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 index 0000000000..28f8ffe22b --- /dev/null +++ b/queue-3.0/lpfc-8.3.25-adapter-interface-fixes-and-changes.patch @@ -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 index 0000000000..c86308bd36 --- /dev/null +++ b/queue-3.0/lpfc-8.3.25-fabric-and-target-discovery-fixes.patch @@ -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 index 0000000000..56008fb91c --- /dev/null +++ b/queue-3.0/lpfc-8.3.25-miscellaneous-bug-fixes-and-code-cleanup.patch @@ -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 index 0000000000..7c0b8dd6ac --- /dev/null +++ b/queue-3.0/lpfc-8.3.25-pci-and-sr-iov-fixes.patch @@ -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 index 0000000000..10f0023563 --- /dev/null +++ b/queue-3.0/lpfc-8.3.25-t10-dif-fixes.patch @@ -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) { diff --git a/queue-3.0/series b/queue-3.0/series index 492484cf2f..6639b47f09 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -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 |