Home Home > GIT Browse > SLE12-SP5-UPDATE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Kirjanov <dkirjanov@suse.com>2019-10-18 10:49:18 +0300
committerDenis Kirjanov <dkirjanov@suse.com>2019-10-18 10:49:18 +0300
commit8934b05a0ba76e493277f91b1419ff69805599b2 (patch)
tree015b39c6737d20f1a0e472a10079ea549bf43cb6
parentd5085de81355bfb72eda1a4f7b25f585c098ed25 (diff)
parentef585f185ad90b7d4402c9429fcfb211aaf51f92 (diff)
Merge remote-tracking branch 'origin/SLE15-SP1' into SLE12-SP5-UPDATESLE12-SP5-UPDATE
Conflicts: series.conf
-rw-r--r--blacklist.conf1
-rw-r--r--patches.kabi/qla2xxx-kABI-fixes-for-v10.01.00.18-k.patch4
-rw-r--r--patches.suse/0001-drm-i915-gvt-update-vgpu-workload-head-pointer-corre.patch83
-rw-r--r--patches.suse/0002-drm-nouveau-kms-nv50-Don-t-create-MSTMs-for-eDP-conn.patch52
-rw-r--r--patches.suse/0003-drm-amd-display-Restore-backlight-brightness-after-s.patch43
-rw-r--r--patches.suse/RDMA-cxgb4-Do-not-dma-memory-off-of-the-stack.patch109
-rw-r--r--patches.suse/bnxt_en-Add-PCI-IDs-for-57500-series-NPAR-devices.patch55
-rw-r--r--patches.suse/efi-arm-Show-SMBIOS-bank-device-location-in-CPER-and.patch45
-rw-r--r--patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm.patch (renamed from patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm_meta_-get-set.patch)21
-rw-r--r--patches.suse/s390-crypto-fix-gcm-aes-s390-selftest-failures255
-rw-r--r--patches.suse/scsi-qla2xxx-Add-error-handling-for-PLOGI-ELS-passth.patch138
-rw-r--r--patches.suse/scsi-qla2xxx-Capture-FW-dump-on-MPI-heartbeat-stop-e.patch98
-rw-r--r--patches.suse/scsi-qla2xxx-Check-for-MB-timeout-while-capturing-IS.patch100
-rw-r--r--patches.suse/scsi-qla2xxx-Dual-FCP-NVMe-target-port-support.patch457
-rw-r--r--patches.suse/scsi-qla2xxx-Fix-N2N-link-reset.patch298
-rw-r--r--patches.suse/scsi-qla2xxx-Fix-N2N-link-up-fail.patch55
-rw-r--r--patches.suse/scsi-qla2xxx-Fix-stale-mem-access-on-driver-unload.patch89
-rw-r--r--patches.suse/scsi-qla2xxx-Fix-unbound-sleep-in-fcport-delete-path.patch40
-rw-r--r--patches.suse/scsi-qla2xxx-Improve-logging-for-scan-thread.patch97
-rw-r--r--patches.suse/scsi-qla2xxx-Optimize-NPIV-tear-down-process.patch156
-rw-r--r--patches.suse/scsi-qla2xxx-Remove-WARN_ON_ONCE-in-qla2x00_status_c.patch33
-rw-r--r--patches.suse/scsi-qla2xxx-Set-remove-flag-for-all-VP.patch74
-rw-r--r--patches.suse/scsi-qla2xxx-Silence-fwdump-template-message.patch29
-rw-r--r--patches.suse/scsi-qla2xxx-Update-driver-version-to-10.01.00.20-k.patch27
-rw-r--r--patches.suse/scsi-qla2xxx-fix-wait-condition-in-loop.patch61
-rw-r--r--patches.suse/scsi-qla2xxx-remove-redundant-assignment-to-pointer-.patch32
-rw-r--r--series.conf32
27 files changed, 2455 insertions, 29 deletions
diff --git a/blacklist.conf b/blacklist.conf
index 4a599ff6fe..e87234d4cc 100644
--- a/blacklist.conf
+++ b/blacklist.conf
@@ -1357,3 +1357,4 @@ b636fd38dc40113f853337a7d2a6885ad23b8811 # non-functional prereq for c03cd7738a8
813af51f5d30a2da6a2523c08465f9726e51772e # clang not supported
aea447141c7e7824b81b49acd1bc785506fba46e # clang not supported
a521c44c3ded9fe184c5de3eed3a442af2d26f00 # book3e not supported
+7101949f36fc77b530b73e4c6bd0066a2740d75b # misattributed. Bug does not existed in our kernels.
diff --git a/patches.kabi/qla2xxx-kABI-fixes-for-v10.01.00.18-k.patch b/patches.kabi/qla2xxx-kABI-fixes-for-v10.01.00.18-k.patch
index fe0e7b476f..bcd319a269 100644
--- a/patches.kabi/qla2xxx-kABI-fixes-for-v10.01.00.18-k.patch
+++ b/patches.kabi/qla2xxx-kABI-fixes-for-v10.01.00.18-k.patch
@@ -78,9 +78,9 @@ Signed-off-by: Daniel Wagner <dwagner@suse.de>
} fc_port_type_t;
enum qla_sess_deletion {
-@@ -2372,6 +2382,9 @@ typedef struct fc_port {
- unsigned int id_changed:1;
+@@ -2398,6 +2398,9 @@ typedef struct fc_port {
unsigned int scan_needed:1;
+ unsigned int n2n_flag:1;
+#ifdef __GENKSYMS__
+ struct work_struct nvme_del_work;
diff --git a/patches.suse/0001-drm-i915-gvt-update-vgpu-workload-head-pointer-corre.patch b/patches.suse/0001-drm-i915-gvt-update-vgpu-workload-head-pointer-corre.patch
new file mode 100644
index 0000000000..926ed6f78c
--- /dev/null
+++ b/patches.suse/0001-drm-i915-gvt-update-vgpu-workload-head-pointer-corre.patch
@@ -0,0 +1,83 @@
+From 0a3242bdb47713e09cb004a0ba4947d3edf82d8a Mon Sep 17 00:00:00 2001
+From: Xiaolin Zhang <xiaolin.zhang@intel.com>
+Date: Tue, 27 Aug 2019 16:39:23 +0800
+Subject: drm/i915/gvt: update vgpu workload head pointer correctly
+Git-commit: 0a3242bdb47713e09cb004a0ba4947d3edf82d8a
+Patch-mainline: v5.4-rc1
+References: bsc#1112178
+
+when creating a vGPU workload, the guest context head pointer should
+be updated correctly by comparing with the exsiting workload in the
+guest worklod queue including the current running context.
+
+in some situation, there is a running context A and then received 2 new
+vGPU workload context B and A. in the new workload context A, it's head
+pointer should be updated with the running context A's tail.
+
+v2: walk through guest workload list in backward way.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Xiaolin Zhang <xiaolin.zhang@intel.com>
+Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+---
+ drivers/gpu/drm/i915/gvt/scheduler.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
+index 7c99bbc3e2b8..affd38238725 100644
+--- a/drivers/gpu/drm/i915/gvt/scheduler.c
++++ b/drivers/gpu/drm/i915/gvt/scheduler.c
+@@ -1371,9 +1371,6 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
+ #define same_context(a, b) (((a)->context_id == (b)->context_id) && \
+ ((a)->lrca == (b)->lrca))
+
+-#define get_last_workload(q) \
+- (list_empty(q) ? NULL : container_of(q->prev, \
+- struct intel_vgpu_workload, list))
+ /**
+ * intel_vgpu_create_workload - create a vGPU workload
+ * @vgpu: a vGPU
+@@ -1393,7 +1390,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
+ {
+ struct intel_vgpu_submission *s = &vgpu->submission;
+ struct list_head *q = workload_q_head(vgpu, ring_id);
+- struct intel_vgpu_workload *last_workload = get_last_workload(q);
++ struct intel_vgpu_workload *last_workload = NULL;
+ struct intel_vgpu_workload *workload = NULL;
+ struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+ u64 ring_context_gpa;
+@@ -1416,15 +1413,20 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
+ head &= RB_HEAD_OFF_MASK;
+ tail &= RB_TAIL_OFF_MASK;
+
+- if (last_workload && same_context(&last_workload->ctx_desc, desc)) {
+- gvt_dbg_el("ring id %d cur workload == last\n", ring_id);
+- gvt_dbg_el("ctx head %x real head %lx\n", head,
+- last_workload->rb_tail);
+- /*
+- * cannot use guest context head pointer here,
+- * as it might not be updated at this time
+- */
+- head = last_workload->rb_tail;
++ list_for_each_entry_reverse(last_workload, q, list) {
++
++ if (same_context(&last_workload->ctx_desc, desc)) {
++ gvt_dbg_el("ring id %d cur workload == last\n",
++ ring_id);
++ gvt_dbg_el("ctx head %x real head %lx\n", head,
++ last_workload->rb_tail);
++ /*
++ * cannot use guest context head pointer here,
++ * as it might not be updated at this time
++ */
++ head = last_workload->rb_tail;
++ break;
++ }
+ }
+
+ gvt_dbg_el("ring id %d begin a new workload\n", ring_id);
+--
+2.23.0
+
diff --git a/patches.suse/0002-drm-nouveau-kms-nv50-Don-t-create-MSTMs-for-eDP-conn.patch b/patches.suse/0002-drm-nouveau-kms-nv50-Don-t-create-MSTMs-for-eDP-conn.patch
new file mode 100644
index 0000000000..a68f8795f7
--- /dev/null
+++ b/patches.suse/0002-drm-nouveau-kms-nv50-Don-t-create-MSTMs-for-eDP-conn.patch
@@ -0,0 +1,52 @@
+From 698c1aa9f83b618de79e9e5e19a58f70a4a6ae0f Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+Date: Fri, 13 Sep 2019 18:03:50 -0400
+Subject: drm/nouveau/kms/nv50-: Don't create MSTMs for eDP connectors
+Git-commit: 698c1aa9f83b618de79e9e5e19a58f70a4a6ae0f
+Patch-mainline: v5.4-rc1
+References: bsc#1112178
+
+On the ThinkPad P71, we have one eDP connector exposed along with 5 DP
+connectors, resulting in a total of 11 TMDS encoders. Since the GPU on
+this system is also capable of MST, we create an additional 4 fake MST
+encoders for each DP port. Unfortunately, we also do this for the eDP
+port as well, resulting in:
+
+ 1 eDP port: +1 TMDS encoder
+ +4 DPMST encoders
+ 5 DP ports: +2 TMDS encoders
+ +4 DPMST encoders
+ *5 ports
+ == 35 encoders
+
+Which breaks things, since DRM has a hard coded limit of 32 encoders.
+So, fix this by not creating MSTMs for any eDP connectors. This brings
+us down to 31 encoders, although we can do better.
+
+This fixes driver probing for nouveau on the ThinkPad P71.
+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+---
+ drivers/gpu/drm/nouveau/dispnv50/disp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
+index f1dbc7852414..064a69d161e3 100644
+--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
+@@ -1599,7 +1599,8 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
+ nv_encoder->aux = aux;
+ }
+
+- if ((data = nvbios_dp_table(bios, &ver, &hdr, &cnt, &len)) &&
++ if (nv_connector->type != DCB_CONNECTOR_eDP &&
++ (data = nvbios_dp_table(bios, &ver, &hdr, &cnt, &len)) &&
+ ver >= 0x40 && (nvbios_rd08(bios, data + 0x08) & 0x04)) {
+ ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16,
+ nv_connector->base.base.id,
+--
+2.23.0
+
diff --git a/patches.suse/0003-drm-amd-display-Restore-backlight-brightness-after-s.patch b/patches.suse/0003-drm-amd-display-Restore-backlight-brightness-after-s.patch
new file mode 100644
index 0000000000..2bcaa32864
--- /dev/null
+++ b/patches.suse/0003-drm-amd-display-Restore-backlight-brightness-after-s.patch
@@ -0,0 +1,43 @@
+From bb264220d9316f6bd7c1fd84b8da398c93912931 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Mon, 2 Sep 2019 16:33:42 +0800
+Subject: drm/amd/display: Restore backlight brightness after system resume
+Git-commit: bb264220d9316f6bd7c1fd84b8da398c93912931
+Patch-mainline: v5.4-rc1
+References: bsc#1112178
+
+Laptops with AMD APU doesn't restore display backlight brightness after
+system resume.
+
+This issue started when DC was introduced.
+
+Let's use BL_CORE_SUSPENDRESUME so the backlight core calls
+update_status callback after system resume to restore the backlight
+level.
+
+Tested on Dell Inspiron 3180 (Stoney Ridge) and Dell Latitude 5495
+(Raven Ridge).
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 9590ca552a28..d3f404f097eb 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2113,6 +2113,7 @@ static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
+ }
+
+ static const struct backlight_ops amdgpu_dm_backlight_ops = {
++ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = amdgpu_dm_backlight_get_brightness,
+ .update_status = amdgpu_dm_backlight_update_status,
+ };
+--
+2.23.0
+
diff --git a/patches.suse/RDMA-cxgb4-Do-not-dma-memory-off-of-the-stack.patch b/patches.suse/RDMA-cxgb4-Do-not-dma-memory-off-of-the-stack.patch
new file mode 100644
index 0000000000..dae24ada3e
--- /dev/null
+++ b/patches.suse/RDMA-cxgb4-Do-not-dma-memory-off-of-the-stack.patch
@@ -0,0 +1,109 @@
+From 3840c5b78803b2b6cc1ff820100a74a092c40cbb Mon Sep 17 00:00:00 2001
+From: Greg KH <gregkh@linuxfoundation.org>
+Date: Tue, 1 Oct 2019 18:56:11 +0200
+Subject: [PATCH] RDMA/cxgb4: Do not dma memory off of the stack
+
+References: bsc#1152790
+Patch-mainline: v5.4-rc3
+Git-commit: 3840c5b78803b2b6cc1ff820100a74a092c40cbb
+
+Nicolas pointed out that the cxgb4 driver is doing dma off of the stack,
+which is generally considered a very bad thing. On some architectures it
+could be a security problem, but odds are none of them actually run this
+driver, so it's just a "normal" bug.
+
+Resolve this by allocating the memory for a message off of the heap
+instead of the stack. kmalloc() always will give us a proper memory
+location that DMA will work correctly from.
+
+Link: https://lore.kernel.org/r/20191001165611.GA3542072@kroah.com
+Reported-by: Nicolas Waisman <nico@semmle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Tested-by: Potnuri Bharat Teja <bharat@chelsio.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Acked-by: Denis Kirjanov <denis.kirjanov@suse.com>
+---
+ drivers/infiniband/hw/cxgb4/mem.c | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
+index aa772ee0706f..35c284af574d 100644
+--- a/drivers/infiniband/hw/cxgb4/mem.c
++++ b/drivers/infiniband/hw/cxgb4/mem.c
+@@ -275,13 +275,17 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
+ struct sk_buff *skb, struct c4iw_wr_wait *wr_waitp)
+ {
+ int err;
+- struct fw_ri_tpte tpt;
++ struct fw_ri_tpte *tpt;
+ u32 stag_idx;
+ static atomic_t key;
+
+ if (c4iw_fatal_error(rdev))
+ return -EIO;
+
++ tpt = kmalloc(sizeof(*tpt), GFP_KERNEL);
++ if (!tpt)
++ return -ENOMEM;
++
+ stag_state = stag_state > 0;
+ stag_idx = (*stag) >> 8;
+
+@@ -291,6 +295,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
+ mutex_lock(&rdev->stats.lock);
+ rdev->stats.stag.fail++;
+ mutex_unlock(&rdev->stats.lock);
++ kfree(tpt);
+ return -ENOMEM;
+ }
+ mutex_lock(&rdev->stats.lock);
+@@ -305,28 +310,28 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
+
+ /* write TPT entry */
+ if (reset_tpt_entry)
+- memset(&tpt, 0, sizeof(tpt));
++ memset(tpt, 0, sizeof(*tpt));
+ else {
+- tpt.valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
++ tpt->valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
+ FW_RI_TPTE_STAGKEY_V((*stag & FW_RI_TPTE_STAGKEY_M)) |
+ FW_RI_TPTE_STAGSTATE_V(stag_state) |
+ FW_RI_TPTE_STAGTYPE_V(type) | FW_RI_TPTE_PDID_V(pdid));
+- tpt.locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) |
++ tpt->locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) |
+ (bind_enabled ? FW_RI_TPTE_MWBINDEN_F : 0) |
+ FW_RI_TPTE_ADDRTYPE_V((zbva ? FW_RI_ZERO_BASED_TO :
+ FW_RI_VA_BASED_TO))|
+ FW_RI_TPTE_PS_V(page_size));
+- tpt.nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
++ tpt->nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
+ FW_RI_TPTE_PBLADDR_V(PBL_OFF(rdev, pbl_addr)>>3));
+- tpt.len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
+- tpt.va_hi = cpu_to_be32((u32)(to >> 32));
+- tpt.va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
+- tpt.dca_mwbcnt_pstag = cpu_to_be32(0);
+- tpt.len_hi = cpu_to_be32((u32)(len >> 32));
++ tpt->len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
++ tpt->va_hi = cpu_to_be32((u32)(to >> 32));
++ tpt->va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
++ tpt->dca_mwbcnt_pstag = cpu_to_be32(0);
++ tpt->len_hi = cpu_to_be32((u32)(len >> 32));
+ }
+ err = write_adapter_mem(rdev, stag_idx +
+ (rdev->lldi.vr->stag.start >> 5),
+- sizeof(tpt), &tpt, skb, wr_waitp);
++ sizeof(*tpt), tpt, skb, wr_waitp);
+
+ if (reset_tpt_entry) {
+ c4iw_put_resource(&rdev->resource.tpt_table, stag_idx);
+@@ -334,6 +339,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
+ rdev->stats.stag.cur -= 32;
+ mutex_unlock(&rdev->stats.lock);
+ }
++ kfree(tpt);
+ return err;
+ }
+
+--
+2.23.0
+
diff --git a/patches.suse/bnxt_en-Add-PCI-IDs-for-57500-series-NPAR-devices.patch b/patches.suse/bnxt_en-Add-PCI-IDs-for-57500-series-NPAR-devices.patch
new file mode 100644
index 0000000000..9e31bffee7
--- /dev/null
+++ b/patches.suse/bnxt_en-Add-PCI-IDs-for-57500-series-NPAR-devices.patch
@@ -0,0 +1,55 @@
+From 49c98421e6ab33665e8ee7901218a712f5b0db2e Mon Sep 17 00:00:00 2001
+From: Michael Chan <michael.chan@broadcom.com>
+Date: Mon, 29 Jul 2019 06:10:33 -0400
+Subject: [PATCH] bnxt_en: Add PCI IDs for 57500 series NPAR devices.
+References: bsc#1153607
+Git-commit: 49c98421e6ab33665e8ee7901218a712f5b0db2e
+Patch-mainline: v5.4-rc1
+
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Thomas Abraham <tabraham@suse.com>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 90d20052f113..ac61c9352535 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -116,6 +116,9 @@ enum board_idx {
+ BCM57508,
+ BCM57504,
+ BCM57502,
++ BCM57508_NPAR,
++ BCM57504_NPAR,
++ BCM57502_NPAR,
+ BCM58802,
+ BCM58804,
+ BCM58808,
+@@ -161,6 +164,9 @@ static const struct {
+ [BCM57508] = { "Broadcom BCM57508 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet" },
+ [BCM57504] = { "Broadcom BCM57504 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet" },
+ [BCM57502] = { "Broadcom BCM57502 NetXtreme-E 10Gb/25Gb/50Gb Ethernet" },
++ [BCM57508_NPAR] = { "Broadcom BCM57508 NetXtreme-E Ethernet Partition" },
++ [BCM57504_NPAR] = { "Broadcom BCM57504 NetXtreme-E Ethernet Partition" },
++ [BCM57502_NPAR] = { "Broadcom BCM57502 NetXtreme-E Ethernet Partition" },
+ [BCM58802] = { "Broadcom BCM58802 NetXtreme-S 10Gb/25Gb/40Gb/50Gb Ethernet" },
+ [BCM58804] = { "Broadcom BCM58804 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
+ [BCM58808] = { "Broadcom BCM58808 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
+@@ -209,6 +215,12 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
+ { PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 },
+ { PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 },
+ { PCI_VDEVICE(BROADCOM, 0x1752), .driver_data = BCM57502 },
++ { PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57508_NPAR },
++ { PCI_VDEVICE(BROADCOM, 0x1801), .driver_data = BCM57504_NPAR },
++ { PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57502_NPAR },
++ { PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57508_NPAR },
++ { PCI_VDEVICE(BROADCOM, 0x1804), .driver_data = BCM57504_NPAR },
++ { PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57502_NPAR },
+ { PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 },
+ { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
+ #ifdef CONFIG_BNXT_SRIOV
+--
+2.16.4
+
diff --git a/patches.suse/efi-arm-Show-SMBIOS-bank-device-location-in-CPER-and.patch b/patches.suse/efi-arm-Show-SMBIOS-bank-device-location-in-CPER-and.patch
new file mode 100644
index 0000000000..777ef7debf
--- /dev/null
+++ b/patches.suse/efi-arm-Show-SMBIOS-bank-device-location-in-CPER-and.patch
@@ -0,0 +1,45 @@
+From: Marcin Benka <mbenka@marvell.com>
+Date: Thu, 28 Mar 2019 20:34:27 +0100
+Subject: efi/arm: Show SMBIOS bank/device location in CPER and GHES error logs
+
+Git-commit: 5e83cfe947444c7f201f8c39ce0189922ec9f578
+Patch-mainline: v5.2-rc1
+References: bsc#1152033
+
+Run dmi_memdev_walk() for arch arm* as other architectures do.
+This improves error logging as the memory device handle is
+translated now to the DIMM entry's name provided by the DMI handle.
+
+Before:
+
+ {1}[Hardware Error]: DIMM location: not present. DMI handle: 0x0038
+
+After:
+
+ {1}[Hardware Error]: DIMM location: N0 DIMM_A0
+
+Signed-off-by: Marcin Benka <mbenka@marvell.com>
+Signed-off-by: Robert Richter <rrichter@marvell.com>
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Matt Fleming <matt@codeblueprint.co.uk>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-efi@vger.kernel.org
+Link: http://lkml.kernel.org/r/20190328193429.21373-4-ard.biesheuvel@linaro.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Mian Yousaf Kaukab <ykaukab@suse.de>
+---
+ arch/arm64/kernel/efi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/kernel/efi.c
++++ b/arch/arm64/kernel/efi.c
+@@ -125,6 +125,7 @@ static int __init arm64_dmi_init(void)
+ * itself, depends on dmi_scan_machine() having been called already.
+ */
+ dmi_scan_machine();
++ dmi_memdev_walk();
+ if (dmi_available)
+ dmi_set_dump_stack_arch_desc();
+ return 0;
diff --git a/patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm_meta_-get-set.patch b/patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm.patch
index 1d2c857471..940edd7c12 100644
--- a/patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm_meta_-get-set.patch
+++ b/patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm.patch
@@ -1,13 +1,13 @@
-From patchwork Fri Sep 27 06:20:02 2019
-X-Patchwork-Id: 1168278
-Date: Fri, 27 Sep 2019 11:50:02 +0530
-Message-Id: <20190927062002.3169-1-vaibhav@linux.ibm.com>
+From 612ee81b9461475b5a5612c2e8d71559dd3c7920 Mon Sep 17 00:00:00 2001
From: Vaibhav Jain <vaibhav@linux.ibm.com>
+Date: Fri, 27 Sep 2019 11:50:02 +0530
Subject: [PATCH] powerpc/papr_scm: Fix an off-by-one check in
papr_scm_meta_{get, set}
References: bsc#1152243 ltc#181472
-Patch-mainline: submitted https://patchwork.ozlabs.org/patch/1168278/
+Patch-mainline: queued
+Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
+Git-commit: 612ee81b9461475b5a5612c2e8d71559dd3c7920
A validation check to prevent out of bounds read/write inside
functions papr_scm_meta_{get,set}() is off-by-one that prevent reads
@@ -28,16 +28,18 @@ access the entire config-area.
Fixes: 53e80bd042773('powerpc/nvdimm: Add support for multibyte read/write for metadata')
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20190927062002.3169-1-vaibhav@linux.ibm.com
Acked-by: Michal Suchanek <msuchanek@suse.de>
---
arch/powerpc/platforms/pseries/papr_scm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
-index a5ac371a3f06..0d0f4974a301 100644
+index 61883291defc..ee07d0718bf1 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
-@@ -124,7 +124,7 @@ static int papr_scm_meta_get(struct papr_scm_priv *p,
+@@ -152,7 +152,7 @@ static int papr_scm_meta_get(struct papr_scm_priv *p,
int len, read;
int64_t ret;
@@ -46,7 +48,7 @@ index a5ac371a3f06..0d0f4974a301 100644
return -EINVAL;
for (len = hdr->in_length; len; len -= read) {
-@@ -178,7 +178,7 @@ static int papr_scm_meta_set(struct papr_scm_priv *p,
+@@ -206,7 +206,7 @@ static int papr_scm_meta_set(struct papr_scm_priv *p,
__be64 data_be;
int64_t ret;
@@ -55,3 +57,6 @@ index a5ac371a3f06..0d0f4974a301 100644
return -EINVAL;
for (len = hdr->in_length; len; len -= wrote) {
+--
+2.23.0
+
diff --git a/patches.suse/s390-crypto-fix-gcm-aes-s390-selftest-failures b/patches.suse/s390-crypto-fix-gcm-aes-s390-selftest-failures
new file mode 100644
index 0000000000..0e21377d05
--- /dev/null
+++ b/patches.suse/s390-crypto-fix-gcm-aes-s390-selftest-failures
@@ -0,0 +1,255 @@
+From: Harald Freudenberger <freude@linux.ibm.com>
+Date: Thu, 23 May 2019 16:18:25 +0200
+Subject: s390/crypto: fix gcm-aes-s390 selftest failures
+Git-commit: bef9f0ba300a55d79a69aa172156072182176515
+Patch-mainline: v5.2-rc1
+References: bsc#1137861 LTC#178091
+
+The current kernel uses improved crypto selftests. These
+tests showed that the current implementation of gcm-aes-s390
+is not able to deal with chunks of output buffers which are
+not a multiple of 16 bytes. This patch introduces a rework
+of the gcm aes s390 scatter walk handling which now is able
+to handle any input and output scatter list chunk sizes
+correctly.
+
+Code has been verified by the crypto selftests, the tcrypt
+kernel module and additional tests ran via the af_alg interface.
+
+Cc: <stable@vger.kernel.org>
+Reported-by: Julian Wiedmann <jwi@linux.ibm.com>
+Reviewed-by: Patrick Steuer <steuer@linux.ibm.com>
+Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Acked-by: Petr Tesarik <ptesarik@suse.com>
+---
+ arch/s390/crypto/aes_s390.c | 148 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 107 insertions(+), 41 deletions(-)
+
+--- a/arch/s390/crypto/aes_s390.c
++++ b/arch/s390/crypto/aes_s390.c
+@@ -831,19 +831,45 @@ static int gcm_aes_setauthsize(struct cr
+ return 0;
+ }
+
+-static void gcm_sg_walk_start(struct gcm_sg_walk *gw, struct scatterlist *sg,
+- unsigned int len)
++static void gcm_walk_start(struct gcm_sg_walk *gw, struct scatterlist *sg,
++ unsigned int len)
+ {
+ memset(gw, 0, sizeof(*gw));
+ gw->walk_bytes_remain = len;
+ scatterwalk_start(&gw->walk, sg);
+ }
+
+-static int gcm_sg_walk_go(struct gcm_sg_walk *gw, unsigned int minbytesneeded)
++static inline unsigned int _gcm_sg_clamp_and_map(struct gcm_sg_walk *gw)
++{
++ struct scatterlist *nextsg;
++
++ gw->walk_bytes = scatterwalk_clamp(&gw->walk, gw->walk_bytes_remain);
++ while (!gw->walk_bytes) {
++ nextsg = sg_next(gw->walk.sg);
++ if (!nextsg)
++ return 0;
++ scatterwalk_start(&gw->walk, nextsg);
++ gw->walk_bytes = scatterwalk_clamp(&gw->walk,
++ gw->walk_bytes_remain);
++ }
++ gw->walk_ptr = scatterwalk_map(&gw->walk);
++ return gw->walk_bytes;
++}
++
++static inline void _gcm_sg_unmap_and_advance(struct gcm_sg_walk *gw,
++ unsigned int nbytes)
++{
++ gw->walk_bytes_remain -= nbytes;
++ scatterwalk_unmap(&gw->walk);
++ scatterwalk_advance(&gw->walk, nbytes);
++ scatterwalk_done(&gw->walk, 0, gw->walk_bytes_remain);
++ gw->walk_ptr = NULL;
++}
++
++static int gcm_in_walk_go(struct gcm_sg_walk *gw, unsigned int minbytesneeded)
+ {
+ int n;
+
+- /* minbytesneeded <= AES_BLOCK_SIZE */
+ if (gw->buf_bytes && gw->buf_bytes >= minbytesneeded) {
+ gw->ptr = gw->buf;
+ gw->nbytes = gw->buf_bytes;
+@@ -856,13 +882,11 @@ static int gcm_sg_walk_go(struct gcm_sg_
+ goto out;
+ }
+
+- gw->walk_bytes = scatterwalk_clamp(&gw->walk, gw->walk_bytes_remain);
+- if (!gw->walk_bytes) {
+- scatterwalk_start(&gw->walk, sg_next(gw->walk.sg));
+- gw->walk_bytes = scatterwalk_clamp(&gw->walk,
+- gw->walk_bytes_remain);
++ if (!_gcm_sg_clamp_and_map(gw)) {
++ gw->ptr = NULL;
++ gw->nbytes = 0;
++ goto out;
+ }
+- gw->walk_ptr = scatterwalk_map(&gw->walk);
+
+ if (!gw->buf_bytes && gw->walk_bytes >= minbytesneeded) {
+ gw->ptr = gw->walk_ptr;
+@@ -874,51 +898,90 @@ static int gcm_sg_walk_go(struct gcm_sg_
+ n = min(gw->walk_bytes, AES_BLOCK_SIZE - gw->buf_bytes);
+ memcpy(gw->buf + gw->buf_bytes, gw->walk_ptr, n);
+ gw->buf_bytes += n;
+- gw->walk_bytes_remain -= n;
+- scatterwalk_unmap(&gw->walk);
+- scatterwalk_advance(&gw->walk, n);
+- scatterwalk_done(&gw->walk, 0, gw->walk_bytes_remain);
+-
++ _gcm_sg_unmap_and_advance(gw, n);
+ if (gw->buf_bytes >= minbytesneeded) {
+ gw->ptr = gw->buf;
+ gw->nbytes = gw->buf_bytes;
+ goto out;
+ }
+-
+- gw->walk_bytes = scatterwalk_clamp(&gw->walk,
+- gw->walk_bytes_remain);
+- if (!gw->walk_bytes) {
+- scatterwalk_start(&gw->walk, sg_next(gw->walk.sg));
+- gw->walk_bytes = scatterwalk_clamp(&gw->walk,
+- gw->walk_bytes_remain);
++ if (!_gcm_sg_clamp_and_map(gw)) {
++ gw->ptr = NULL;
++ gw->nbytes = 0;
++ goto out;
+ }
+- gw->walk_ptr = scatterwalk_map(&gw->walk);
+ }
+
+ out:
+ return gw->nbytes;
+ }
+
+-static void gcm_sg_walk_done(struct gcm_sg_walk *gw, unsigned int bytesdone)
++static int gcm_out_walk_go(struct gcm_sg_walk *gw, unsigned int minbytesneeded)
+ {
+- int n;
++ if (gw->walk_bytes_remain == 0) {
++ gw->ptr = NULL;
++ gw->nbytes = 0;
++ goto out;
++ }
++
++ if (!_gcm_sg_clamp_and_map(gw)) {
++ gw->ptr = NULL;
++ gw->nbytes = 0;
++ goto out;
++ }
+
++ if (gw->walk_bytes >= minbytesneeded) {
++ gw->ptr = gw->walk_ptr;
++ gw->nbytes = gw->walk_bytes;
++ goto out;
++ }
++
++ scatterwalk_unmap(&gw->walk);
++ gw->walk_ptr = NULL;
++
++ gw->ptr = gw->buf;
++ gw->nbytes = sizeof(gw->buf);
++
++out:
++ return gw->nbytes;
++}
++
++static int gcm_in_walk_done(struct gcm_sg_walk *gw, unsigned int bytesdone)
++{
+ if (gw->ptr == NULL)
+- return;
++ return 0;
+
+ if (gw->ptr == gw->buf) {
+- n = gw->buf_bytes - bytesdone;
++ int n = gw->buf_bytes - bytesdone;
+ if (n > 0) {
+ memmove(gw->buf, gw->buf + bytesdone, n);
+- gw->buf_bytes -= n;
++ gw->buf_bytes = n;
+ } else
+ gw->buf_bytes = 0;
+- } else {
+- gw->walk_bytes_remain -= bytesdone;
+- scatterwalk_unmap(&gw->walk);
+- scatterwalk_advance(&gw->walk, bytesdone);
+- scatterwalk_done(&gw->walk, 0, gw->walk_bytes_remain);
+- }
++ } else
++ _gcm_sg_unmap_and_advance(gw, bytesdone);
++
++ return bytesdone;
++}
++
++static int gcm_out_walk_done(struct gcm_sg_walk *gw, unsigned int bytesdone)
++{
++ int i, n;
++
++ if (gw->ptr == NULL)
++ return 0;
++
++ if (gw->ptr == gw->buf) {
++ for (i = 0; i < bytesdone; i += n) {
++ if (!_gcm_sg_clamp_and_map(gw))
++ return i;
++ n = min(gw->walk_bytes, bytesdone - i);
++ memcpy(gw->walk_ptr, gw->buf + i, n);
++ _gcm_sg_unmap_and_advance(gw, n);
++ }
++ } else
++ _gcm_sg_unmap_and_advance(gw, bytesdone);
++
++ return bytesdone;
+ }
+
+ static int gcm_aes_crypt(struct aead_request *req, unsigned int flags)
+@@ -931,7 +994,7 @@ static int gcm_aes_crypt(struct aead_req
+ unsigned int pclen = req->cryptlen;
+ int ret = 0;
+
+- unsigned int len, in_bytes, out_bytes,
++ unsigned int n, len, in_bytes, out_bytes,
+ min_bytes, bytes, aad_bytes, pc_bytes;
+ struct gcm_sg_walk gw_in, gw_out;
+ u8 tag[GHASH_DIGEST_SIZE];
+@@ -968,14 +1031,14 @@ static int gcm_aes_crypt(struct aead_req
+ *(u32 *)(param.j0 + ivsize) = 1;
+ memcpy(param.k, ctx->key, ctx->key_len);
+
+- gcm_sg_walk_start(&gw_in, req->src, len);
+- gcm_sg_walk_start(&gw_out, req->dst, len);
++ gcm_walk_start(&gw_in, req->src, len);
++ gcm_walk_start(&gw_out, req->dst, len);
+
+ do {
+ min_bytes = min_t(unsigned int,
+ aadlen > 0 ? aadlen : pclen, AES_BLOCK_SIZE);
+- in_bytes = gcm_sg_walk_go(&gw_in, min_bytes);
+- out_bytes = gcm_sg_walk_go(&gw_out, min_bytes);
++ in_bytes = gcm_in_walk_go(&gw_in, min_bytes);
++ out_bytes = gcm_out_walk_go(&gw_out, min_bytes);
+ bytes = min(in_bytes, out_bytes);
+
+ if (aadlen + pclen <= bytes) {
+@@ -1002,8 +1065,11 @@ static int gcm_aes_crypt(struct aead_req
+ gw_in.ptr + aad_bytes, pc_bytes,
+ gw_in.ptr, aad_bytes);
+
+- gcm_sg_walk_done(&gw_in, aad_bytes + pc_bytes);
+- gcm_sg_walk_done(&gw_out, aad_bytes + pc_bytes);
++ n = aad_bytes + pc_bytes;
++ if (gcm_in_walk_done(&gw_in, n) != n)
++ return -ENOMEM;
++ if (gcm_out_walk_done(&gw_out, n) != n)
++ return -ENOMEM;
+ aadlen -= aad_bytes;
+ pclen -= pc_bytes;
+ } while (aadlen + pclen > 0);
diff --git a/patches.suse/scsi-qla2xxx-Add-error-handling-for-PLOGI-ELS-passth.patch b/patches.suse/scsi-qla2xxx-Add-error-handling-for-PLOGI-ELS-passth.patch
new file mode 100644
index 0000000000..e38b31c9c1
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Add-error-handling-for-PLOGI-ELS-passth.patch
@@ -0,0 +1,138 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:13 -0700
+Subject: scsi: qla2xxx: Add error handling for PLOGI ELS passthrough
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+Git-commit: c76ae845ea836d6128982dcbd41ac35c81e2de63
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Add error handling logic to ELS Passthrough relating to NVME devices.
+Current code does not parse error code to take proper recovery action,
+instead it re-logins with the same login parameters that encountered the
+error. Ex: nport handle collision.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-10-hmadhani@marvell.com
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_iocb.c | 95 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 92 insertions(+), 3 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2742,6 +2742,10 @@ static void qla2x00_els_dcmd2_sp_done(sr
+ struct scsi_qla_host *vha = sp->vha;
+ struct event_arg ea;
+ struct qla_work_evt *e;
++ struct fc_port *conflict_fcport;
++ port_id_t cid; /* conflict Nport id */
++ u32 *fw_status = sp->u.iocb_cmd.u.els_plogi.fw_status;
++ u16 lid;
+
+ ql_dbg(ql_dbg_disc, vha, 0x3072,
+ "%s ELS done rc %d hdl=%x, portid=%06x %8phC\n",
+@@ -2753,14 +2757,99 @@ static void qla2x00_els_dcmd2_sp_done(sr
+ if (sp->flags & SRB_WAKEUP_ON_COMP)
+ complete(&lio->u.els_plogi.comp);
+ else {
+- if (res) {
+- set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+- } else {
++ switch (fw_status[0]) {
++ case CS_DATA_UNDERRUN:
++ case CS_COMPLETE:
+ memset(&ea, 0, sizeof(ea));
+ ea.fcport = fcport;
+ ea.data[0] = MBS_COMMAND_COMPLETE;
+ ea.sp = sp;
+ qla24xx_handle_plogi_done_event(vha, &ea);
++ break;
++ case CS_IOCB_ERROR:
++ switch (fw_status[1]) {
++ case LSC_SCODE_PORTID_USED:
++ lid = fw_status[2] & 0xffff;
++ qlt_find_sess_invalidate_other(vha,
++ wwn_to_u64(fcport->port_name),
++ fcport->d_id, lid, &conflict_fcport);
++ if (conflict_fcport) {
++ /*
++ * Another fcport shares the same
++ * loop_id & nport id; conflict
++ * fcport needs to finish cleanup
++ * before this fcport can proceed
++ * to login.
++ */
++ conflict_fcport->conflict = fcport;
++ fcport->login_pause = 1;
++ ql_dbg(ql_dbg_disc, vha, 0x20ed,
++ "%s %d %8phC pid %06x inuse with lid %#x post gidpn\n",
++ __func__, __LINE__,
++ fcport->port_name,
++ fcport->d_id.b24, lid);
++ } else {
++ ql_dbg(ql_dbg_disc, vha, 0x20ed,
++ "%s %d %8phC pid %06x inuse with lid %#x sched del\n",
++ __func__, __LINE__,
++ fcport->port_name,
++ fcport->d_id.b24, lid);
++ qla2x00_clear_loop_id(fcport);
++ set_bit(lid, vha->hw->loop_id_map);
++ fcport->loop_id = lid;
++ fcport->keep_nport_handle = 0;
++ qlt_schedule_sess_for_deletion(fcport);
++ }
++ break;
++
++ case LSC_SCODE_NPORT_USED:
++ cid.b.domain = (fw_status[2] >> 16) & 0xff;
++ cid.b.area = (fw_status[2] >> 8) & 0xff;
++ cid.b.al_pa = fw_status[2] & 0xff;
++ cid.b.rsvd_1 = 0;
++
++ ql_dbg(ql_dbg_disc, vha, 0x20ec,
++ "%s %d %8phC lid %#x in use with pid %06x post gnl\n",
++ __func__, __LINE__, fcport->port_name,
++ fcport->loop_id, cid.b24);
++ set_bit(fcport->loop_id,
++ vha->hw->loop_id_map);
++ fcport->loop_id = FC_NO_LOOP_ID;
++ qla24xx_post_gnl_work(vha, fcport);
++ break;
++
++ case LSC_SCODE_NOXCB:
++ vha->hw->exch_starvation++;
++ if (vha->hw->exch_starvation > 5) {
++ ql_log(ql_log_warn, vha, 0xd046,
++ "Exchange starvation. Resetting RISC\n");
++ vha->hw->exch_starvation = 0;
++ set_bit(ISP_ABORT_NEEDED,
++ &vha->dpc_flags);
++ qla2xxx_wake_dpc(vha);
++ }
++ /* fall through */
++ default:
++ ql_dbg(ql_dbg_disc, vha, 0x20eb,
++ "%s %8phC cmd error fw_status 0x%x 0x%x 0x%x\n",
++ __func__, sp->fcport->port_name,
++ fw_status[0], fw_status[1], fw_status[2]);
++
++ fcport->flags &= ~FCF_ASYNC_SENT;
++ set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
++ break;
++ }
++ break;
++
++ default:
++ ql_dbg(ql_dbg_disc, vha, 0x20eb,
++ "%s %8phC cmd error 2 fw_status 0x%x 0x%x 0x%x\n",
++ __func__, sp->fcport->port_name,
++ fw_status[0], fw_status[1], fw_status[2]);
++
++ sp->fcport->flags &= ~FCF_ASYNC_SENT;
++ set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
++ break;
+ }
+
+ e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
diff --git a/patches.suse/scsi-qla2xxx-Capture-FW-dump-on-MPI-heartbeat-stop-e.patch b/patches.suse/scsi-qla2xxx-Capture-FW-dump-on-MPI-heartbeat-stop-e.patch
new file mode 100644
index 0000000000..d79608c8ad
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Capture-FW-dump-on-MPI-heartbeat-stop-e.patch
@@ -0,0 +1,98 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:16 -0700
+Subject: scsi: qla2xxx: Capture FW dump on MPI heartbeat stop event
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+Git-commit: d52cd7747d905f5b2a6ec07d5f6abe8720969dc5
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+For MPI heartbeat stop Async Event, this patch would capture MPI FW dump
+and chip reset. FW will tell which function to capture FW dump for.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-13-hmadhani@marvell.com
+Reviewed-by: Laurence Oberman <loberman@redhat.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_attr.c | 4 +++-
+ drivers/scsi/qla2xxx/qla_isr.c | 31 ++++++++++++++++++++++++++-----
+ drivers/scsi/qla2xxx/qla_tmpl.c | 4 +++-
+ 3 files changed, 32 insertions(+), 7 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -102,8 +102,10 @@ qla2x00_sysfs_write_fw_dump(struct file
+ qla8044_idc_lock(ha);
+ qla82xx_set_reset_owner(vha);
+ qla8044_idc_unlock(ha);
+- } else
++ } else {
++ ha->fw_dump_mpi = 1;
+ qla2x00_system_error(vha);
++ }
+ break;
+ case 4:
+ if (IS_P3P_TYPE(ha)) {
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -1227,11 +1227,32 @@ global_port_update:
+ break;
+
+ case MBA_IDC_AEN:
+- mb[4] = RD_REG_WORD(&reg24->mailbox4);
+- mb[5] = RD_REG_WORD(&reg24->mailbox5);
+- mb[6] = RD_REG_WORD(&reg24->mailbox6);
+- mb[7] = RD_REG_WORD(&reg24->mailbox7);
+- qla83xx_handle_8200_aen(vha, mb);
++ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
++ ha->flags.fw_init_done = 0;
++ ql_log(ql_log_warn, vha, 0xffff,
++ "MPI Heartbeat stop. Chip reset needed. MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n",
++ mb[0], mb[1], mb[2], mb[3]);
++
++ if ((mb[1] & BIT_8) ||
++ (mb[2] & BIT_8)) {
++ ql_log(ql_log_warn, vha, 0xd013,
++ "MPI Heartbeat stop. FW dump needed\n");
++ ha->fw_dump_mpi = 1;
++ ha->isp_ops->fw_dump(vha, 1);
++ }
++ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
++ qla2xxx_wake_dpc(vha);
++ } else if (IS_QLA83XX(ha)) {
++ mb[4] = RD_REG_WORD(&reg24->mailbox4);
++ mb[5] = RD_REG_WORD(&reg24->mailbox5);
++ mb[6] = RD_REG_WORD(&reg24->mailbox6);
++ mb[7] = RD_REG_WORD(&reg24->mailbox7);
++ qla83xx_handle_8200_aen(vha, mb);
++ } else {
++ ql_dbg(ql_dbg_async, vha, 0x5052,
++ "skip Heartbeat processing mb0-3=[0x%04x] [0x%04x] [0x%04x] [0x%04x]\n",
++ mb[0], mb[1], mb[2], mb[3]);
++ }
+ break;
+
+ case MBA_DPORT_DIAGNOSTICS:
+--- a/drivers/scsi/qla2xxx/qla_tmpl.c
++++ b/drivers/scsi/qla2xxx/qla_tmpl.c
+@@ -1017,8 +1017,9 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int
+ uint j;
+ ulong len;
+ void *buf = vha->hw->fw_dump;
++ uint count = vha->hw->fw_dump_mpi ? 2 : 1;
+
+- for (j = 0; j < 2; j++, fwdt++, buf += len) {
++ for (j = 0; j < count; j++, fwdt++, buf += len) {
+ ql_log(ql_log_warn, vha, 0xd011,
+ "-> fwdt%u running...\n", j);
+ if (!fwdt->template) {
+@@ -1046,6 +1047,7 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int
+ }
+
+ bailout:
++ vha->hw->fw_dump_mpi = 0;
+ #ifndef __CHECKER__
+ if (!hardware_locked)
+ spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
diff --git a/patches.suse/scsi-qla2xxx-Check-for-MB-timeout-while-capturing-IS.patch b/patches.suse/scsi-qla2xxx-Check-for-MB-timeout-while-capturing-IS.patch
new file mode 100644
index 0000000000..f10c7c27eb
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Check-for-MB-timeout-while-capturing-IS.patch
@@ -0,0 +1,100 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:15 -0700
+Subject: scsi: qla2xxx: Check for MB timeout while capturing ISP27/28xx FW
+ dump
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+Git-commit: c55474197a2e29fd0858fb9678db1628f4a39861
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Add mailbox timeout checkout for ISP 27xx/28xx during FW dump procedure.
+Without the timeout check, hardware lock can be held for long period. This
+patch would shorten the dump procedure if a timeout condition is
+encountered.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-12-hmadhani@marvell.com
+Reviewed-by: Laurence Oberman <loberman@redhat.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_tmpl.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_tmpl.c
++++ b/drivers/scsi/qla2xxx/qla_tmpl.c
+@@ -10,6 +10,7 @@
+ #define ISPREG(vha) (&(vha)->hw->iobase->isp24)
+ #define IOBAR(reg) offsetof(typeof(*(reg)), iobase_addr)
+ #define IOBASE(vha) IOBAR(ISPREG(vha))
++#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
+
+ static inline void
+ qla27xx_insert16(uint16_t value, void *buf, ulong *len)
+@@ -261,6 +262,7 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_
+ ulong start = le32_to_cpu(ent->t262.start_addr);
+ ulong end = le32_to_cpu(ent->t262.end_addr);
+ ulong dwords;
++ int rc;
+
+ ql_dbg(ql_dbg_misc, vha, 0xd206,
+ "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len);
+@@ -308,7 +310,13 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_
+ dwords = end - start + 1;
+ if (buf) {
+ buf += *len;
+- qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
++ rc = qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
++ if (rc != QLA_SUCCESS) {
++ ql_dbg(ql_dbg_async, vha, 0xffff,
++ "%s: dump ram MB failed. Area %xh start %lxh end %lxh\n",
++ __func__, area, start, end);
++ return INVALID_ENTRY;
++ }
+ }
+ *len += dwords * sizeof(uint32_t);
+ done:
+@@ -838,6 +846,13 @@ qla27xx_walk_template(struct scsi_qla_ho
+ ent = qla27xx_find_entry(type)(vha, ent, buf, len);
+ if (!ent)
+ break;
++
++ if (ent == INVALID_ENTRY) {
++ *len = 0;
++ ql_dbg(ql_dbg_async, vha, 0xffff,
++ "Unable to capture FW dump");
++ goto bailout;
++ }
+ }
+
+ if (tmp->count)
+@@ -847,6 +862,9 @@ qla27xx_walk_template(struct scsi_qla_ho
+ if (ent)
+ ql_dbg(ql_dbg_misc, vha, 0xd019,
+ "%s: missing end entry\n", __func__);
++
++bailout:
++ cpu_to_le32s(&tmp->count); /* endianize residual count */
+ }
+
+ static void
+@@ -1010,7 +1028,9 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int
+ }
+ len = qla27xx_execute_fwdt_template(vha,
+ fwdt->template, buf);
+- if (len != fwdt->dump_size) {
++ if (len == 0) {
++ goto bailout;
++ } else if (len != fwdt->dump_size) {
+ ql_log(ql_log_warn, vha, 0xd013,
+ "-> fwdt%u fwdump residual=%+ld\n",
+ j, fwdt->dump_size - len);
+@@ -1025,6 +1045,7 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int
+ qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
+ }
+
++bailout:
+ #ifndef __CHECKER__
+ if (!hardware_locked)
+ spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
diff --git a/patches.suse/scsi-qla2xxx-Dual-FCP-NVMe-target-port-support.patch b/patches.suse/scsi-qla2xxx-Dual-FCP-NVMe-target-port-support.patch
new file mode 100644
index 0000000000..9da34b6527
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Dual-FCP-NVMe-target-port-support.patch
@@ -0,0 +1,457 @@
+From: Michael Hernandez <mhernandez@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:12 -0700
+Subject: scsi: qla2xxx: Dual FCP-NVMe target port support
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+Git-commit: 84ed362ac40ca44dbbbebf767301463aa72bc797
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Some storage arrays advertise FCP LUNs and NVMe namespaces behind the same
+WWN. The driver now offers a user option by way of NVRAM parameter to
+allow users to choose, on a per port basis, the kind of FC-4 type they
+would like to prioritize for login.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-9-hmadhani@marvell.com
+Signed-off-by: Michael Hernandez <mhernandez@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 26 ++++++++++++++-
+ drivers/scsi/qla2xxx/qla_fw.h | 2 +
+ drivers/scsi/qla2xxx/qla_gs.c | 42 ++++++++++++++----------
+ drivers/scsi/qla2xxx/qla_init.c | 64 +++++++++++++++++++++-----------------
+ drivers/scsi/qla2xxx/qla_inline.h | 12 +++++++
+ drivers/scsi/qla2xxx/qla_mbx.c | 11 +++---
+ drivers/scsi/qla2xxx/qla_os.c | 17 ++++------
+ 7 files changed, 114 insertions(+), 60 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2277,7 +2277,7 @@ typedef struct {
+ uint8_t fabric_port_name[WWN_SIZE];
+ uint16_t fp_speed;
+ uint8_t fc4_type;
+- uint8_t fc4f_nvme; /* nvme fc4 feature bits */
++ uint8_t fc4_features;
+ } sw_info_t;
+
+ /* FCP-4 types */
+@@ -2445,7 +2445,7 @@ typedef struct fc_port {
+ u32 supported_classes;
+
+ uint8_t fc4_type;
+- uint8_t fc4f_nvme;
++ uint8_t fc4_features;
+ uint8_t scan_state;
+
+ unsigned long last_queue_full;
+@@ -2476,6 +2476,9 @@ typedef struct fc_port {
+ u16 n2n_chip_reset;
+ } fc_port_t;
+
++#define FC4_PRIORITY_NVME 0
++#define FC4_PRIORITY_FCP 1
++
+ #define QLA_FCPORT_SCAN 1
+ #define QLA_FCPORT_FOUND 2
+
+@@ -4291,6 +4294,8 @@ struct qla_hw_data {
+ atomic_t nvme_active_aen_cnt;
+ uint16_t nvme_last_rptd_aen; /* Last recorded aen count */
+
++ uint8_t fc4_type_priority;
++
+ atomic_t zio_threshold;
+ uint16_t last_zio_threshold;
+
+@@ -4814,6 +4819,23 @@ struct sff_8247_a0 {
+ ha->current_topology == ISP_CFG_N || \
+ !ha->current_topology)
+
++#define NVME_TYPE(fcport) \
++ (fcport->fc4_type & FS_FC4TYPE_NVME) \
++
++#define FCP_TYPE(fcport) \
++ (fcport->fc4_type & FS_FC4TYPE_FCP) \
++
++#define NVME_ONLY_TARGET(fcport) \
++ (NVME_TYPE(fcport) && !FCP_TYPE(fcport)) \
++
++#define NVME_FCP_TARGET(fcport) \
++ (FCP_TYPE(fcport) && NVME_TYPE(fcport)) \
++
++#define NVME_TARGET(ha, fcport) \
++ ((NVME_FCP_TARGET(fcport) && \
++ (ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \
++ NVME_ONLY_TARGET(fcport)) \
++
+ #include "qla_target.h"
+ #include "qla_gbl.h"
+ #include "qla_dbg.h"
+--- a/drivers/scsi/qla2xxx/qla_fw.h
++++ b/drivers/scsi/qla2xxx/qla_fw.h
+@@ -2101,4 +2101,6 @@ struct qla_fcp_prio_cfg {
+ #define FA_FLASH_LAYOUT_ADDR_83 (0x3F1000/4)
+ #define FA_FLASH_LAYOUT_ADDR_28 (0x11000/4)
+
++#define NVRAM_DUAL_FCP_NVME_FLAG_OFFSET 0x196
++
+ #endif
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -248,7 +248,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_
+ WWN_SIZE);
+
+ fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
+- FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
++ FS_FC4TYPE_FCP : FC4_TYPE_OTHER;
+
+ if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
+ ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
+@@ -2887,7 +2887,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_
+ struct ct_sns_req *ct_req;
+ struct ct_sns_rsp *ct_rsp;
+ struct qla_hw_data *ha = vha->hw;
+- uint8_t fcp_scsi_features = 0;
++ uint8_t fcp_scsi_features = 0, nvme_features = 0;
+ struct ct_arg arg;
+
+ for (i = 0; i < ha->max_fibre_devices; i++) {
+@@ -2933,14 +2933,19 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_
+ ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
+ fcp_scsi_features &= 0x0f;
+
+- if (fcp_scsi_features)
+- list[i].fc4_type = FC4_TYPE_FCP_SCSI;
+- else
+- list[i].fc4_type = FC4_TYPE_OTHER;
++ if (fcp_scsi_features) {
++ list[i].fc4_type = FS_FC4TYPE_FCP;
++ list[i].fc4_features = fcp_scsi_features;
++ }
+
+- list[i].fc4f_nvme =
++ nvme_features =
+ ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
+- list[i].fc4f_nvme &= 0xf;
++ nvme_features &= 0xf;
++
++ if (nvme_features) {
++ list[i].fc4_type |= FS_FC4TYPE_NVME;
++ list[i].fc4_features = nvme_features;
++ }
+ }
+
+ /* Last device exit. */
+@@ -3435,6 +3440,8 @@ void qla24xx_async_gffid_sp_done(srb_t *
+ fc_port_t *fcport = sp->fcport;
+ struct ct_sns_rsp *ct_rsp;
+ struct event_arg ea;
++ uint8_t fc4_scsi_feat;
++ uint8_t fc4_nvme_feat;
+
+ ql_dbg(ql_dbg_disc, vha, 0x2133,
+ "Async done-%s res %x ID %x. %8phC\n",
+@@ -3442,24 +3449,25 @@ void qla24xx_async_gffid_sp_done(srb_t *
+
+ fcport->flags &= ~FCF_ASYNC_SENT;
+ ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
++ fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
++ fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
++
+ /*
+ * FC-GS-7, 5.2.3.12 FC-4 Features - format
+ * The format of the FC-4 Features object, as defined by the FC-4,
+ * Shall be an array of 4-bit values, one for each type code value
+ */
+ if (!res) {
+- if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
++ if (fc4_scsi_feat & 0xf) {
+ /* w1 b00:03 */
+- fcport->fc4_type =
+- ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
+- fcport->fc4_type &= 0xf;
+- }
++ fcport->fc4_type = FS_FC4TYPE_FCP;
++ fcport->fc4_features = fc4_scsi_feat & 0xf;
++ }
+
+- if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
++ if (fc4_nvme_feat & 0xf) {
+ /* w5 [00:03]/28h */
+- fcport->fc4f_nvme =
+- ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
+- fcport->fc4f_nvme &= 0xf;
++ fcport->fc4_type |= FS_FC4TYPE_NVME;
++ fcport->fc4_features = fc4_nvme_feat & 0xf;
+ }
+ }
+
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -328,7 +328,7 @@ qla2x00_async_login(struct scsi_qla_host
+ else
+ lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
+
+- if (fcport->fc4f_nvme)
++ if (NVME_TARGET(vha->hw, fcport))
+ lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
+
+ ql_dbg(ql_dbg_disc, vha, 0x2072,
+@@ -726,19 +726,17 @@ static void qla24xx_handle_gnl_done_even
+
+ loop_id = le16_to_cpu(e->nport_handle);
+ loop_id = (loop_id & 0x7fff);
+- if (fcport->fc4f_nvme)
++ if (NVME_TARGET(vha->hw, fcport))
+ current_login_state = e->current_login_state >> 4;
+ else
+ current_login_state = e->current_login_state & 0xf;
+
+-
+ ql_dbg(ql_dbg_disc, vha, 0x20e2,
+- "%s found %8phC CLS [%x|%x] nvme %d ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
++ "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n",
+ __func__, fcport->port_name,
+ e->current_login_state, fcport->fw_login_state,
+- fcport->fc4f_nvme, id.b.domain, id.b.area, id.b.al_pa,
+- fcport->d_id.b.domain, fcport->d_id.b.area,
+- fcport->d_id.b.al_pa, loop_id, fcport->loop_id);
++ fcport->fc4_type, id.b24, fcport->d_id.b24,
++ loop_id, fcport->loop_id);
+
+ switch (fcport->disc_state) {
+ case DSC_DELETE_PEND:
+@@ -1227,13 +1225,13 @@ qla24xx_async_prli(struct scsi_qla_host
+ sp->done = qla2x00_async_prli_sp_done;
+ lio->u.logio.flags = 0;
+
+- if (fcport->fc4f_nvme)
++ if (NVME_TARGET(vha->hw, fcport))
+ lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
+
+ ql_dbg(ql_dbg_disc, vha, 0x211b,
+ "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
+ fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
+- fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc");
++ fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc");
+
+ rval = qla2x00_start_sp(sp);
+ if (rval != QLA_SUCCESS) {
+@@ -1384,14 +1382,14 @@ void qla24xx_handle_gpdb_event(scsi_qla_
+ fcport->flags &= ~FCF_ASYNC_SENT;
+
+ ql_dbg(ql_dbg_disc, vha, 0x20d2,
+- "%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name,
+- fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme,
+- ea->rc);
++ "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__,
++ fcport->port_name, fcport->disc_state, pd->current_login_state,
++ fcport->fc4_type, ea->rc);
+
+ if (fcport->disc_state == DSC_DELETE_PEND)
+ return;
+
+- if (fcport->fc4f_nvme)
++ if (NVME_TARGET(vha->hw, fcport))
+ ls = pd->current_login_state >> 4;
+ else
+ ls = pd->current_login_state & 0xf;
+@@ -1580,7 +1578,8 @@ int qla24xx_fcport_handle_login(struct s
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
+ "%s %d %8phC post %s PRLI\n",
+ __func__, __LINE__, fcport->port_name,
+- fcport->fc4f_nvme ? "NVME" : "FC");
++ NVME_TARGET(vha->hw, fcport) ? "NVME" :
++ "FC");
+ qla24xx_post_prli_work(vha, fcport);
+ }
+ break;
+@@ -1862,13 +1861,22 @@ qla24xx_handle_prli_done_event(struct sc
+ break;
+ }
+
+- if (ea->fcport->fc4f_nvme) {
++ /*
++ * Retry PRLI with other FC-4 type if failure occurred on dual
++ * FCP/NVMe port
++ */
++ if (NVME_FCP_TARGET(ea->fcport)) {
++ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
++ ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
++ else
++ ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
+- "%s %d %8phC post fc4 prli\n",
+- __func__, __LINE__, ea->fcport->port_name);
+- ea->fcport->fc4f_nvme = 0;
++ "%s %d %8phC post %s prli\n",
++ __func__, __LINE__, ea->fcport->port_name,
++ (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ?
++ "NVMe" : "FCP");
+ qla24xx_post_prli_work(vha, ea->fcport);
+- return;
++ break;
+ }
+
+ /* at this point both PRLI NVME & PRLI FCP failed */
+@@ -1954,7 +1962,7 @@ qla24xx_handle_plogi_done_event(struct s
+ * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
+ * requests.
+ */
+- if (ea->fcport->fc4f_nvme) {
++ if (NVME_TARGET(vha->hw, ea->fcport)) {
+ ql_dbg(ql_dbg_disc, vha, 0x2117,
+ "%s %d %8phC post prli\n",
+ __func__, __LINE__, ea->fcport->port_name);
+@@ -5382,7 +5390,7 @@ qla2x00_update_fcport(scsi_qla_host_t *v
+
+ qla2x00_iidma_fcport(vha, fcport);
+
+- if (fcport->fc4f_nvme) {
++ if (NVME_TARGET(vha->hw, fcport)) {
+ qla_nvme_register_remote(vha, fcport);
+ fcport->disc_state = DSC_LOGIN_COMPLETE;
+ qla2x00_set_fcport_state(fcport, FCS_ONLINE);
+@@ -5710,11 +5718,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
+ new_fcport->fc4_type = swl[swl_idx].fc4_type;
+
+ new_fcport->nvme_flag = 0;
+- new_fcport->fc4f_nvme = 0;
+ if (vha->flags.nvme_enabled &&
+- swl[swl_idx].fc4f_nvme) {
+- new_fcport->fc4f_nvme =
+- swl[swl_idx].fc4f_nvme;
++ swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) {
+ ql_log(ql_log_info, vha, 0x2131,
+ "FOUND: NVME port %8phC as FC Type 28h\n",
+ new_fcport->port_name);
+@@ -5770,7 +5775,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
+
+ /* Bypass ports whose FCP-4 type is not FCP_SCSI */
+ if (ql2xgffidenable &&
+- (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
++ (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) &&
+ new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
+ continue;
+
+@@ -5839,7 +5844,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
+ break;
+ }
+
+- if (fcport->fc4f_nvme) {
++ if (NVME_TARGET(vha->hw, fcport)) {
+ if (fcport->disc_state == DSC_DELETE_PEND) {
+ fcport->disc_state = DSC_GNL;
+ vha->fcport_count--;
+@@ -8514,6 +8519,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vh
+ /* N2N: driver will initiate Login instead of FW */
+ icb->firmware_options_3 |= BIT_8;
+
++ /* Determine NVMe/FCP priority for target ports */
++ ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha);
++ ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n",
++ ha->fc4_type_priority & BIT_0 ? "FCP" : "NVMe");
++
+ if (rval) {
+ ql_log(ql_log_warn, vha, 0x0076,
+ "NVRAM configuration failed.\n");
+--- a/drivers/scsi/qla2xxx/qla_inline.h
++++ b/drivers/scsi/qla2xxx/qla_inline.h
+@@ -307,3 +307,15 @@ qla_83xx_start_iocbs(struct qla_qpair *q
+
+ WRT_REG_DWORD(req->req_q_in, req->ring_index);
+ }
++
++static inline int
++qla2xxx_get_fc4_priority(struct scsi_qla_host *vha)
++{
++ uint32_t data;
++
++ data =
++ ((uint8_t *)vha->hw->nvram)[NVRAM_DUAL_FCP_NVME_FLAG_OFFSET];
++
++
++ return ((data >> 6) & BIT_0);
++}
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -1931,7 +1931,7 @@ qla2x00_get_port_database(scsi_qla_host_
+ pd24 = (struct port_database_24xx *) pd;
+
+ /* Check for logged in state. */
+- if (fcport->fc4f_nvme) {
++ if (NVME_TARGET(ha, fcport)) {
+ current_login_state = pd24->current_login_state >> 4;
+ last_login_state = pd24->last_login_state >> 4;
+ } else {
+@@ -3898,8 +3898,9 @@ qla24xx_report_id_acquisition(scsi_qla_h
+ fcport->scan_state = QLA_FCPORT_FOUND;
+ fcport->n2n_flag = 1;
+ fcport->keep_nport_handle = 1;
++ fcport->fc4_type = FS_FC4TYPE_FCP;
+ if (vha->flags.nvme_enabled)
+- fcport->fc4f_nvme = 1;
++ fcport->fc4_type |= FS_FC4TYPE_NVME;
+
+ switch (fcport->disc_state) {
+ case DSC_DELETED:
+@@ -6361,7 +6362,7 @@ int __qla24xx_parse_gpdb(struct scsi_qla
+ uint64_t zero = 0;
+ u8 current_login_state, last_login_state;
+
+- if (fcport->fc4f_nvme) {
++ if (NVME_TARGET(vha->hw, fcport)) {
+ current_login_state = pd->current_login_state >> 4;
+ last_login_state = pd->last_login_state >> 4;
+ } else {
+@@ -6396,8 +6397,8 @@ int __qla24xx_parse_gpdb(struct scsi_qla
+ fcport->d_id.b.al_pa = pd->port_id[2];
+ fcport->d_id.b.rsvd_1 = 0;
+
+- if (fcport->fc4f_nvme) {
+- fcport->port_type = 0;
++ if (NVME_TARGET(vha->hw, fcport)) {
++ fcport->port_type = FCT_NVME;
+ if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0)
+ fcport->port_type |= FCT_NVME_INITIATOR;
+ if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5045,19 +5045,17 @@ void qla24xx_create_new_sess(struct scsi
+ fcport->d_id = e->u.new_sess.id;
+ fcport->flags |= FCF_FABRIC_DEVICE;
+ fcport->fw_login_state = DSC_LS_PLOGI_PEND;
+- if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP)
+- fcport->fc4_type = FC4_TYPE_FCP_SCSI;
+-
+- if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) {
+- fcport->fc4_type = FC4_TYPE_OTHER;
+- fcport->fc4f_nvme = FC4_TYPE_NVME;
+- }
+
+ memcpy(fcport->port_name, e->u.new_sess.port_name,
+ WWN_SIZE);
+
+- if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N)
++ fcport->fc4_type = e->u.new_sess.fc4_type;
++ if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) {
++ fcport->fc4_type = FS_FC4TYPE_FCP;
+ fcport->n2n_flag = 1;
++ if (vha->flags.nvme_enabled)
++ fcport->fc4_type |= FS_FC4TYPE_NVME;
++ }
+
+ } else {
+ ql_dbg(ql_dbg_disc, vha, 0xffff,
+@@ -5161,7 +5159,8 @@ void qla24xx_create_new_sess(struct scsi
+ fcport->flags &= ~FCF_FABRIC_DEVICE;
+ fcport->keep_nport_handle = 1;
+ if (vha->flags.nvme_enabled) {
+- fcport->fc4f_nvme = 1;
++ fcport->fc4_type =
++ (FS_FC4TYPE_NVME | FS_FC4TYPE_FCP);
+ fcport->n2n_flag = 1;
+ }
+ fcport->fw_login_state = 0;
diff --git a/patches.suse/scsi-qla2xxx-Fix-N2N-link-reset.patch b/patches.suse/scsi-qla2xxx-Fix-N2N-link-reset.patch
new file mode 100644
index 0000000000..1fd7f69fb3
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Fix-N2N-link-reset.patch
@@ -0,0 +1,298 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:09 -0700
+Subject: scsi: qla2xxx: Fix N2N link reset
+Patch-mainline: v5.4-rc2
+Git-commit: 7f2a398d59d658818f3d219645164676fbbc88e8
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Fix stalled link recovery for N2N with FC-NVMe connection.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-6-hmadhani@marvell.com
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 3 -
+ drivers/scsi/qla2xxx/qla_init.c | 107 ++++++++++++++++++++++++++++------------
+ drivers/scsi/qla2xxx/qla_mbx.c | 23 +++++++-
+ drivers/scsi/qla2xxx/qla_os.c | 4 +
+ 4 files changed, 103 insertions(+), 34 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2396,6 +2396,7 @@ typedef struct fc_port {
+ unsigned int query:1;
+ unsigned int id_changed:1;
+ unsigned int scan_needed:1;
++ unsigned int n2n_flag:1;
+
+ struct completion nvme_del_done;
+ uint32_t nvme_prli_service_param;
+@@ -2446,7 +2447,6 @@ typedef struct fc_port {
+ uint8_t fc4_type;
+ uint8_t fc4f_nvme;
+ uint8_t scan_state;
+- uint8_t n2n_flag;
+
+ unsigned long last_queue_full;
+ unsigned long last_ramp_up;
+@@ -3036,6 +3036,7 @@ enum scan_flags_t {
+ enum fc4type_t {
+ FS_FC4TYPE_FCP = BIT_0,
+ FS_FC4TYPE_NVME = BIT_1,
++ FS_FCP_IS_N2N = BIT_7,
+ };
+
+ struct fab_scan_rp {
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -746,12 +746,15 @@ static void qla24xx_handle_gnl_done_even
+ break;
+ default:
+ if ((id.b24 != fcport->d_id.b24 &&
+- fcport->d_id.b24) ||
++ fcport->d_id.b24 &&
++ fcport->loop_id != FC_NO_LOOP_ID) ||
+ (fcport->loop_id != FC_NO_LOOP_ID &&
+ fcport->loop_id != loop_id)) {
+ ql_dbg(ql_dbg_disc, vha, 0x20e3,
+ "%s %d %8phC post del sess\n",
+ __func__, __LINE__, fcport->port_name);
++ if (fcport->n2n_flag)
++ fcport->d_id.b24 = 0;
+ qlt_schedule_sess_for_deletion(fcport);
+ return;
+ }
+@@ -759,6 +762,8 @@ static void qla24xx_handle_gnl_done_even
+ }
+
+ fcport->loop_id = loop_id;
++ if (fcport->n2n_flag)
++ fcport->d_id.b24 = id.b24;
+
+ wwn = wwn_to_u64(fcport->port_name);
+ qlt_find_sess_invalidate_other(vha, wwn,
+@@ -974,7 +979,7 @@ static void qla24xx_async_gnl_sp_done(sr
+ wwn = wwn_to_u64(e->port_name);
+
+ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8,
+- "%s %8phC %02x:%02x:%02x state %d/%d lid %x \n",
++ "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n",
+ __func__, (void *)&wwn, e->port_id[2], e->port_id[1],
+ e->port_id[0], e->current_login_state, e->last_login_state,
+ (loop_id & 0x7fff));
+@@ -1501,7 +1506,8 @@ int qla24xx_fcport_handle_login(struct s
+ (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
+ return 0;
+
+- if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
++ if (fcport->fw_login_state == DSC_LS_PLOGI_COMP &&
++ !N2N_TOPO(vha->hw)) {
+ if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
+ set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+ return 0;
+@@ -1572,8 +1578,9 @@ int qla24xx_fcport_handle_login(struct s
+ qla24xx_post_gpdb_work(vha, fcport, 0);
+ } else {
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
+- "%s %d %8phC post NVMe PRLI\n",
+- __func__, __LINE__, fcport->port_name);
++ "%s %d %8phC post %s PRLI\n",
++ __func__, __LINE__, fcport->port_name,
++ fcport->fc4f_nvme ? "NVME" : "FC");
+ qla24xx_post_prli_work(vha, fcport);
+ }
+ break;
+@@ -1855,17 +1862,38 @@ qla24xx_handle_prli_done_event(struct sc
+ break;
+ }
+
+- if (ea->fcport->n2n_flag) {
++ if (ea->fcport->fc4f_nvme) {
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
+ "%s %d %8phC post fc4 prli\n",
+ __func__, __LINE__, ea->fcport->port_name);
+ ea->fcport->fc4f_nvme = 0;
+- ea->fcport->n2n_flag = 0;
+ qla24xx_post_prli_work(vha, ea->fcport);
++ return;
++ }
++
++ /* at this point both PRLI NVME & PRLI FCP failed */
++ if (N2N_TOPO(vha->hw)) {
++ if (ea->fcport->n2n_link_reset_cnt < 3) {
++ ea->fcport->n2n_link_reset_cnt++;
++ /*
++ * remote port is not sending Plogi. Reset
++ * link to kick start his state machine
++ */
++ set_bit(N2N_LINK_RESET, &vha->dpc_flags);
++ } else {
++ ql_log(ql_log_warn, vha, 0x2119,
++ "%s %d %8phC Unable to reconnect\n",
++ __func__, __LINE__, ea->fcport->port_name);
++ }
++ } else {
++ /*
++ * switch connect. login failed. Take connection
++ * down and allow relogin to retrigger
++ */
++ ea->fcport->flags &= ~FCF_ASYNC_SENT;
++ ea->fcport->keep_nport_handle = 0;
++ qlt_schedule_sess_for_deletion(ea->fcport);
+ }
+- ql_dbg(ql_dbg_disc, vha, 0x2119,
+- "%s %d %8phC unhandle event of %x\n",
+- __func__, __LINE__, ea->fcport->port_name, ea->data[0]);
+ break;
+ }
+ }
+@@ -4986,28 +5014,47 @@ qla2x00_configure_local_loop(scsi_qla_ho
+ unsigned long flags;
+
+ /* Inititae N2N login. */
+- if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
+- /* borrowing */
+- u32 *bp, i, sz;
+-
+- memset(ha->init_cb, 0, ha->init_cb_size);
+- sz = min_t(int, sizeof(struct els_plogi_payload),
+- ha->init_cb_size);
+- rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
+- (void *)ha->init_cb, sz);
+- if (rval == QLA_SUCCESS) {
+- bp = (uint32_t *)ha->init_cb;
+- for (i = 0; i < sz/4 ; i++, bp++)
+- *bp = cpu_to_be32(*bp);
++ if (N2N_TOPO(ha)) {
++ if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
++ /* borrowing */
++ u32 *bp, i, sz;
++
++ memset(ha->init_cb, 0, ha->init_cb_size);
++ sz = min_t(int, sizeof(struct els_plogi_payload),
++ ha->init_cb_size);
++ rval = qla24xx_get_port_login_templ(vha,
++ ha->init_cb_dma, (void *)ha->init_cb, sz);
++ if (rval == QLA_SUCCESS) {
++ bp = (uint32_t *)ha->init_cb;
++ for (i = 0; i < sz/4 ; i++, bp++)
++ *bp = cpu_to_be32(*bp);
++
++ memcpy(&ha->plogi_els_payld.data,
++ (void *)ha->init_cb,
++ sizeof(ha->plogi_els_payld.data));
++ set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
++ } else {
++ ql_dbg(ql_dbg_init, vha, 0x00d1,
++ "PLOGI ELS param read fail.\n");
++ goto skip_login;
++ }
++ }
+
+- memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb,
+- sizeof(ha->plogi_els_payld.data));
+- set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+- } else {
+- ql_dbg(ql_dbg_init, vha, 0x00d1,
+- "PLOGI ELS param read fail.\n");
++ list_for_each_entry(fcport, &vha->vp_fcports, list) {
++ if (fcport->n2n_flag) {
++ qla24xx_fcport_handle_login(vha, fcport);
++ return QLA_SUCCESS;
++ }
++ }
++skip_login:
++ spin_lock_irqsave(&vha->work_lock, flags);
++ vha->scan.scan_retry++;
++ spin_unlock_irqrestore(&vha->work_lock, flags);
++
++ if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
++ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
++ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+ }
+- return QLA_SUCCESS;
+ }
+
+ found_devs = 0;
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -2249,7 +2249,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha)
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+- ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
++ ql_dbg(ql_dbg_disc, vha, 0x105a,
+ "Entered %s.\n", __func__);
+
+ if (IS_CNA_CAPABLE(vha->hw)) {
+@@ -3883,14 +3883,23 @@ qla24xx_report_id_acquisition(scsi_qla_h
+ case TOPO_N2N:
+ ha->current_topology = ISP_CFG_N;
+ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
++ list_for_each_entry(fcport, &vha->vp_fcports, list) {
++ fcport->scan_state = QLA_FCPORT_SCAN;
++ fcport->n2n_flag = 0;
++ }
++
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ rptid_entry->u.f1.port_name, 1);
+ spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+
+ if (fcport) {
+ fcport->plogi_nack_done_deadline = jiffies + HZ;
+- fcport->dm_login_expire = jiffies + 3*HZ;
++ fcport->dm_login_expire = jiffies + 2*HZ;
+ fcport->scan_state = QLA_FCPORT_FOUND;
++ fcport->n2n_flag = 1;
++ if (vha->flags.nvme_enabled)
++ fcport->fc4f_nvme = 1;
++
+ switch (fcport->disc_state) {
+ case DSC_DELETED:
+ set_bit(RELOGIN_NEEDED,
+@@ -3924,7 +3933,7 @@ qla24xx_report_id_acquisition(scsi_qla_h
+ rptid_entry->u.f1.port_name,
+ rptid_entry->u.f1.node_name,
+ NULL,
+- FC4_TYPE_UNKNOWN);
++ FS_FCP_IS_N2N);
+ }
+
+ /* if our portname is higher then initiate N2N login */
+@@ -4023,6 +4032,7 @@ qla24xx_report_id_acquisition(scsi_qla_h
+
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
+ fcport->scan_state = QLA_FCPORT_SCAN;
++ fcport->n2n_flag = 0;
+ }
+
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+@@ -4032,6 +4042,13 @@ qla24xx_report_id_acquisition(scsi_qla_h
+ fcport->login_retry = vha->hw->login_retry_count;
+ fcport->plogi_nack_done_deadline = jiffies + HZ;
+ fcport->scan_state = QLA_FCPORT_FOUND;
++ fcport->n2n_flag = 1;
++ fcport->d_id.b.domain =
++ rptid_entry->u.f2.remote_nport_id[2];
++ fcport->d_id.b.area =
++ rptid_entry->u.f2.remote_nport_id[1];
++ fcport->d_id.b.al_pa =
++ rptid_entry->u.f2.remote_nport_id[0];
+ }
+ }
+ }
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5055,6 +5055,10 @@ void qla24xx_create_new_sess(struct scsi
+
+ memcpy(fcport->port_name, e->u.new_sess.port_name,
+ WWN_SIZE);
++
++ if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N)
++ fcport->n2n_flag = 1;
++
+ } else {
+ ql_dbg(ql_dbg_disc, vha, 0xffff,
+ "%s %8phC mem alloc fail.\n",
diff --git a/patches.suse/scsi-qla2xxx-Fix-N2N-link-up-fail.patch b/patches.suse/scsi-qla2xxx-Fix-N2N-link-up-fail.patch
new file mode 100644
index 0000000000..18e2a22890
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Fix-N2N-link-up-fail.patch
@@ -0,0 +1,55 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:10 -0700
+Subject: scsi: qla2xxx: Fix N2N link up fail
+Patch-mainline: v5.4-rc2
+Git-commit: f3f1938bb673b1b5ad182c4608f5f8a24921eea3
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+During link up/bounce, qla driver would do command flush as part of
+cleanup. In this case, the flush can intefere with FW state. This patch
+allows FW to be in control of link up.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-7-hmadhani@marvell.com
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_mbx.c | 2 ++
+ drivers/scsi/qla2xxx/qla_os.c | 6 ++----
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -3897,6 +3897,7 @@ qla24xx_report_id_acquisition(scsi_qla_h
+ fcport->dm_login_expire = jiffies + 2*HZ;
+ fcport->scan_state = QLA_FCPORT_FOUND;
+ fcport->n2n_flag = 1;
++ fcport->keep_nport_handle = 1;
+ if (vha->flags.nvme_enabled)
+ fcport->fc4f_nvme = 1;
+
+@@ -4042,6 +4043,7 @@ qla24xx_report_id_acquisition(scsi_qla_h
+ fcport->login_retry = vha->hw->login_retry_count;
+ fcport->plogi_nack_done_deadline = jiffies + HZ;
+ fcport->scan_state = QLA_FCPORT_FOUND;
++ fcport->keep_nport_handle = 1;
+ fcport->n2n_flag = 1;
+ fcport->d_id.b.domain =
+ rptid_entry->u.f2.remote_nport_id[2];
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5157,11 +5157,9 @@ void qla24xx_create_new_sess(struct scsi
+ if (dfcp)
+ qlt_schedule_sess_for_deletion(tfcp);
+
+-
+- if (N2N_TOPO(vha->hw))
+- fcport->flags &= ~FCF_FABRIC_DEVICE;
+-
+ if (N2N_TOPO(vha->hw)) {
++ fcport->flags &= ~FCF_FABRIC_DEVICE;
++ fcport->keep_nport_handle = 1;
+ if (vha->flags.nvme_enabled) {
+ fcport->fc4f_nvme = 1;
+ fcport->n2n_flag = 1;
diff --git a/patches.suse/scsi-qla2xxx-Fix-stale-mem-access-on-driver-unload.patch b/patches.suse/scsi-qla2xxx-Fix-stale-mem-access-on-driver-unload.patch
new file mode 100644
index 0000000000..4432ab274e
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Fix-stale-mem-access-on-driver-unload.patch
@@ -0,0 +1,89 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:07 -0700
+Subject: scsi: qla2xxx: Fix stale mem access on driver unload
+Patch-mainline: v5.4-rc2
+Git-commit: fd5564ba54e0d8a9e3e823d311b764232e09eb5f
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+On driver unload, 'remove_one' thread was allowed to advance, while session
+cleanup still lag behind. This patch ensures session deletion will finish
+before remove_one can advance.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-4-hmadhani@marvell.com
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_os.c | 1 +
+ drivers/scsi/qla2xxx/qla_target.c | 21 ++++++++-------------
+ 2 files changed, 9 insertions(+), 13 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1124,6 +1124,7 @@ qla2x00_wait_for_sess_deletion(scsi_qla_
+ qla2x00_mark_all_devices_lost(vha, 0);
+
+ wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ);
++ flush_workqueue(vha->hw->wq);
+ }
+
+ /*
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -962,7 +962,7 @@ void qlt_free_session_done(struct work_s
+ struct qla_hw_data *ha = vha->hw;
+ unsigned long flags;
+ bool logout_started = false;
+- scsi_qla_host_t *base_vha;
++ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ struct qlt_plogi_ack_t *own =
+ sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
+
+@@ -1114,6 +1114,7 @@ void qlt_free_session_done(struct work_s
+ }
+
+ spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
++ sess->free_pending = 0;
+
+ ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
+ "Unregistration of sess %p %8phC finished fcp_cnt %d\n",
+@@ -1122,17 +1123,8 @@ void qlt_free_session_done(struct work_s
+ if (tgt && (tgt->sess_count == 0))
+ wake_up_all(&tgt->waitQ);
+
+- if (vha->fcport_count == 0)
+- wake_up_all(&vha->fcport_waitQ);
+-
+- base_vha = pci_get_drvdata(ha->pdev);
+-
+- sess->free_pending = 0;
+-
+- if (test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags))
+- return;
+-
+- if ((!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
++ if (!test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags) &&
++ (!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
+ switch (vha->host->active_mode) {
+ case MODE_INITIATOR:
+ case MODE_DUAL:
+@@ -1145,6 +1137,9 @@ void qlt_free_session_done(struct work_s
+ break;
+ }
+ }
++
++ if (vha->fcport_count == 0)
++ wake_up_all(&vha->fcport_waitQ);
+ }
+
+ /* ha->tgt.sess_lock supposed to be held on entry */
+@@ -1174,7 +1169,7 @@ void qlt_unreg_sess(struct fc_port *sess
+ sess->last_login_gen = sess->login_gen;
+
+ INIT_WORK(&sess->free_work, qlt_free_session_done);
+- schedule_work(&sess->free_work);
++ queue_work(sess->vha->hw->wq, &sess->free_work);
+ }
+ EXPORT_SYMBOL(qlt_unreg_sess);
+
diff --git a/patches.suse/scsi-qla2xxx-Fix-unbound-sleep-in-fcport-delete-path.patch b/patches.suse/scsi-qla2xxx-Fix-unbound-sleep-in-fcport-delete-path.patch
new file mode 100644
index 0000000000..af1a8e908e
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Fix-unbound-sleep-in-fcport-delete-path.patch
@@ -0,0 +1,40 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:06 -0700
+Subject: scsi: qla2xxx: Fix unbound sleep in fcport delete path.
+Patch-mainline: v5.4-rc2
+Git-commit: c3b6a1d397420a0fdd97af2f06abfb78adc370df
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+There are instances, though rare, where a LOGO request cannot be sent out
+and the thread in free session done can wait indefinitely. Fix this by
+putting an upper bound to sleep.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-3-hmadhani@marvell.com
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_target.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -1029,6 +1029,7 @@ void qlt_free_session_done(struct work_s
+
+ if (logout_started) {
+ bool traced = false;
++ u16 cnt = 0;
+
+ while (!READ_ONCE(sess->logout_completed)) {
+ if (!traced) {
+@@ -1038,6 +1039,9 @@ void qlt_free_session_done(struct work_s
+ traced = true;
+ }
+ msleep(100);
++ cnt++;
++ if (cnt > 200)
++ break;
+ }
+
+ ql_dbg(ql_dbg_disc, vha, 0xf087,
diff --git a/patches.suse/scsi-qla2xxx-Improve-logging-for-scan-thread.patch b/patches.suse/scsi-qla2xxx-Improve-logging-for-scan-thread.patch
new file mode 100644
index 0000000000..8ac5831c73
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Improve-logging-for-scan-thread.patch
@@ -0,0 +1,97 @@
+From: Himanshu Madhani <hmadhani@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:17 -0700
+Subject: scsi: qla2xxx: Improve logging for scan thread
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+Git-commit: 45c96e442f52c4890f7fceeda9496a5900909aa5
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Move messages to verbose logging for scan thread.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-14-hmadhani@marvell.com
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3571,7 +3571,7 @@ void qla24xx_async_gnnft_done(scsi_qla_h
+ u8 recheck = 0;
+ u16 dup = 0, dup_cnt = 0;
+
+- ql_dbg(ql_dbg_disc, vha, 0xffff,
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
+ "%s enter\n", __func__);
+
+ if (sp->gen1 != vha->hw->base_qpair->chip_reset) {
+@@ -3588,8 +3588,9 @@ void qla24xx_async_gnnft_done(scsi_qla_h
+ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+ } else {
+- ql_dbg(ql_dbg_disc, vha, 0xffff,
+- "Fabric scan failed on all retries.\n");
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
++ "%s: Fabric scan failed for %d retries.\n",
++ __func__, vha->scan.scan_retry);
+ }
+ goto out;
+ }
+@@ -4055,7 +4056,7 @@ done_free_sp:
+
+ void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
+ {
+- ql_dbg(ql_dbg_disc, vha, 0xffff,
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
+ "%s enter\n", __func__);
+ qla24xx_async_gnnft(vha, sp, sp->gen2);
+ }
+@@ -4069,7 +4070,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t
+ u32 rspsz;
+ unsigned long flags;
+
+- ql_dbg(ql_dbg_disc, vha, 0xffff,
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
+ "%s enter\n", __func__);
+
+ if (!vha->flags.online)
+@@ -4078,14 +4079,15 @@ int qla24xx_async_gpnft(scsi_qla_host_t
+ spin_lock_irqsave(&vha->work_lock, flags);
+ if (vha->scan.scan_flags & SF_SCANNING) {
+ spin_unlock_irqrestore(&vha->work_lock, flags);
+- ql_dbg(ql_dbg_disc, vha, 0xffff, "scan active\n");
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
++ "%s: scan active\n", __func__);
+ return rval;
+ }
+ vha->scan.scan_flags |= SF_SCANNING;
+ spin_unlock_irqrestore(&vha->work_lock, flags);
+
+ if (fc4_type == FC4_TYPE_FCP_SCSI) {
+- ql_dbg(ql_dbg_disc, vha, 0xffff,
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
+ "%s: Performing FCP Scan\n", __func__);
+
+ if (sp)
+@@ -4138,7 +4140,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t
+ }
+ sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
+
+- ql_dbg(ql_dbg_disc, vha, 0xffff,
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
+ "%s scan list size %d\n", __func__, vha->scan.size);
+
+ memset(vha->scan.l, 0, vha->scan.size);
+@@ -4203,8 +4205,8 @@ done_free_sp:
+ spin_lock_irqsave(&vha->work_lock, flags);
+ vha->scan.scan_flags &= ~SF_SCANNING;
+ if (vha->scan.scan_flags == 0) {
+- ql_dbg(ql_dbg_disc, vha, 0xffff,
+- "%s: schedule\n", __func__);
++ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
++ "%s: Scan scheduled.\n", __func__);
+ vha->scan.scan_flags |= SF_QUEUED;
+ schedule_delayed_work(&vha->scan.scan_work, 5);
+ }
diff --git a/patches.suse/scsi-qla2xxx-Optimize-NPIV-tear-down-process.patch b/patches.suse/scsi-qla2xxx-Optimize-NPIV-tear-down-process.patch
new file mode 100644
index 0000000000..9befd83c32
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Optimize-NPIV-tear-down-process.patch
@@ -0,0 +1,156 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:08 -0700
+Subject: scsi: qla2xxx: Optimize NPIV tear down process
+Patch-mainline: v5.4-rc2
+Git-commit: f5187b7d1ac66b61676f896751d3af9fcf8dd592
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+In the case of NPIV port is being torn down, this patch will set a flag to
+indicate VPORT_DELETE. This would prevent relogin to be triggered.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-5-hmadhani@marvell.com
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_attr.c | 2 ++
+ drivers/scsi/qla2xxx/qla_def.h | 1 +
+ drivers/scsi/qla2xxx/qla_gs.c | 3 ++-
+ drivers/scsi/qla2xxx/qla_mid.c | 32 ++++++++++++++++++++++----------
+ drivers/scsi/qla2xxx/qla_os.c | 7 ++++++-
+ drivers/scsi/qla2xxx/qla_target.c | 1 +
+ 6 files changed, 34 insertions(+), 12 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -2919,6 +2919,8 @@ qla24xx_vport_delete(struct fc_vport *fc
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t id = vha->vp_idx;
+
++ set_bit(VPORT_DELETE, &vha->dpc_flags);
++
+ while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
+ test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
+ msleep(1000);
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -4394,6 +4394,7 @@ typedef struct scsi_qla_host {
+ #define IOCB_WORK_ACTIVE 31
+ #define SET_ZIO_THRESHOLD_NEEDED 32
+ #define ISP_ABORT_TO_ROM 33
++#define VPORT_DELETE 34
+
+ unsigned long pci_flags;
+ #define PFLG_DISCONNECTED 0 /* PCI device removed */
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3102,7 +3102,8 @@ int qla24xx_post_gpnid_work(struct scsi_
+ {
+ struct qla_work_evt *e;
+
+- if (test_bit(UNLOADING, &vha->dpc_flags))
++ if (test_bit(UNLOADING, &vha->dpc_flags) ||
++ (vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)))
+ return 0;
+
+ e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -66,6 +66,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t
+ uint16_t vp_id;
+ struct qla_hw_data *ha = vha->hw;
+ unsigned long flags = 0;
++ u8 i;
+
+ mutex_lock(&ha->vport_lock);
+ /*
+@@ -75,8 +76,9 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t
+ * ensures no active vp_list traversal while the vport is removed
+ * from the queue)
+ */
+- wait_event_timeout(vha->vref_waitq, !atomic_read(&vha->vref_count),
+- 10*HZ);
++ for (i = 0; i < 10 && atomic_read(&vha->vref_count); i++)
++ wait_event_timeout(vha->vref_waitq,
++ atomic_read(&vha->vref_count), HZ);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ if (atomic_read(&vha->vref_count)) {
+@@ -262,6 +264,9 @@ qla2x00_alert_all_vps(struct rsp_que *rs
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vha, &ha->vp_list, list) {
+ if (vha->vp_idx) {
++ if (test_bit(VPORT_DELETE, &vha->dpc_flags))
++ continue;
++
+ atomic_inc(&vha->vref_count);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
+@@ -300,6 +305,20 @@ qla2x00_alert_all_vps(struct rsp_que *rs
+ int
+ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
+ {
++ fc_port_t *fcport;
++
++ /*
++ * To exclusively reset vport, we need to log it out first.
++ * Note: This control_vp can fail if ISP reset is already
++ * issued, this is expected, as the vp would be already
++ * logged out due to ISP reset.
++ */
++ if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
++ qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
++ list_for_each_entry(fcport, &vha->vp_fcports, list)
++ fcport->logout_on_delete = 0;
++ }
++
+ /*
+ * Physical port will do most of the abort and recovery work. We can
+ * just treat it as a loop down
+@@ -312,16 +331,9 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vh
+ atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
+ }
+
+- /*
+- * To exclusively reset vport, we need to log it out first. Note: this
+- * control_vp can fail if ISP reset is already issued, this is
+- * expected, as the vp would be already logged out due to ISP reset.
+- */
+- if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
+- qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
+-
+ ql_dbg(ql_dbg_taskm, vha, 0x801d,
+ "Scheduling enable of Vport %d.\n", vha->vp_idx);
++
+ return qla24xx_enable_vp(vha);
+ }
+
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1121,9 +1121,14 @@ static inline int test_fcport_count(scsi
+ void
+ qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
+ {
++ u8 i;
++
+ qla2x00_mark_all_devices_lost(vha, 0);
+
+- wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha), 10*HZ);
++ for (i = 0; i < 10; i++)
++ wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha),
++ HZ);
++
+ flush_workqueue(vha->hw->wq);
+ }
+
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -1124,6 +1124,7 @@ void qlt_free_session_done(struct work_s
+ wake_up_all(&tgt->waitQ);
+
+ if (!test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags) &&
++ !(vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)) &&
+ (!tgt || !tgt->tgt_stop) && !LOOP_TRANSITION(vha)) {
+ switch (vha->host->active_mode) {
+ case MODE_INITIATOR:
diff --git a/patches.suse/scsi-qla2xxx-Remove-WARN_ON_ONCE-in-qla2x00_status_c.patch b/patches.suse/scsi-qla2xxx-Remove-WARN_ON_ONCE-in-qla2x00_status_c.patch
index 4ab563ca3c..a37f3c9a3a 100644
--- a/patches.suse/scsi-qla2xxx-Remove-WARN_ON_ONCE-in-qla2x00_status_c.patch
+++ b/patches.suse/scsi-qla2xxx-Remove-WARN_ON_ONCE-in-qla2x00_status_c.patch
@@ -1,28 +1,30 @@
From: Daniel Wagner <dwagner@suse.de>
-Date: Thu, 26 Sep 2019 09:36:43 +0200
-Subject: [PATCH] scsi: qla2xxx: Remove WARN_ON_ONCE in
- qla2x00_status_cont_entry()
-Patch-Mainline: Not yet, submitted linux-scsi 2019/09/26
-References: bsc#1123034 bsc#1131304 bsc#1127988
+Date: Fri, 27 Sep 2019 09:30:31 +0200
+Subject: scsi: qla2xxx: Remove WARN_ON_ONCE in qla2x00_status_cont_entry()
+Patch-mainline: v5.4 or v5.4-rc4 (next release)
+Git-commit: 9bc6157f5fd0e898c94f3018d088a3419bde0d8f
+References: bsc#1143706 bsc#1082635 bsc#1123034
-Commit 88263208dd23 ("scsi: qla2xxx: Complain if sp->done() is not
-called from the completion path") introduced the WARN_ON_ONCE in
+Commit 88263208dd23 ("scsi: qla2xxx: Complain if sp->done() is not called
+from the completion path") introduced the WARN_ON_ONCE in
qla2x00_status_cont_entry(). The assumption was that there is only one
-status continuations element. According to the firmware documentation
-it is possible that multiple status continuations are emitted by the
-firmware.
+status continuations element. According to the firmware documentation it is
+possible that multiple status continuations are emitted by the firmware.
+Fixes: 88263208dd23 ("scsi: qla2xxx: Complain if sp->done() is not called from the completion path")
+Link: https://lore.kernel.org/r/20190927073031.62296-1-dwagner@suse.de
Cc: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Daniel Wagner <dwagner@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
- drivers/scsi/qla2xxx/qla_isr.c | 2 --
+ drivers/scsi/qla2xxx/qla_isr.c | 2 --
1 file changed, 2 deletions(-)
-diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
-index 4c26630c1c3e..009fd5a33fcd 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
-@@ -2837,8 +2837,6 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
+@@ -2837,8 +2837,6 @@ qla2x00_status_cont_entry(struct rsp_que
if (sense_len == 0) {
rsp->status_srb = NULL;
sp->done(sp, cp->result);
@@ -31,6 +33,3 @@ index 4c26630c1c3e..009fd5a33fcd 100644
}
}
---
-2.16.4
-
diff --git a/patches.suse/scsi-qla2xxx-Set-remove-flag-for-all-VP.patch b/patches.suse/scsi-qla2xxx-Set-remove-flag-for-all-VP.patch
new file mode 100644
index 0000000000..7775af3b35
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Set-remove-flag-for-all-VP.patch
@@ -0,0 +1,74 @@
+From: Quinn Tran <qutran@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:14 -0700
+Subject: scsi: qla2xxx: Set remove flag for all VP
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+Git-commit: 6997db98d00a659d05cda23bd33c34aff546635b
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+During driver unload, the remove flag will be set for all
+scsi_qla_host/NPIV. This allows each NPIV to see the flag instead of
+reaching for base_vha to search for it.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-11-hmadhani@marvell.com
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_os.c | 30 +++++++++++++++++++++++++-----
+ 1 file changed, 25 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -3500,6 +3500,29 @@ disable_device:
+ return ret;
+ }
+
++static void __qla_set_remove_flag(scsi_qla_host_t *base_vha)
++{
++ scsi_qla_host_t *vp;
++ unsigned long flags;
++ struct qla_hw_data *ha;
++
++ if (!base_vha)
++ return;
++
++ ha = base_vha->hw;
++
++ spin_lock_irqsave(&ha->vport_slock, flags);
++ list_for_each_entry(vp, &ha->vp_list, list)
++ set_bit(PFLG_DRIVER_REMOVING, &vp->pci_flags);
++
++ /*
++ * Indicate device removal to prevent future board_disable
++ * and wait until any pending board_disable has completed.
++ */
++ set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags);
++ spin_unlock_irqrestore(&ha->vport_slock, flags);
++}
++
+ static void
+ qla2x00_shutdown(struct pci_dev *pdev)
+ {
+@@ -3516,7 +3539,7 @@ qla2x00_shutdown(struct pci_dev *pdev)
+ * Prevent future board_disable and wait
+ * until any pending board_disable has completed.
+ */
+- set_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags);
++ __qla_set_remove_flag(vha);
+ cancel_work_sync(&ha->board_disable);
+
+ if (!atomic_read(&pdev->enable_cnt))
+@@ -3672,10 +3695,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
+ ha = base_vha->hw;
+ ql_log(ql_log_info, base_vha, 0xb079,
+ "Removing driver\n");
+-
+- /* Indicate device removal to prevent future board_disable and wait
+- * until any pending board_disable has completed. */
+- set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags);
++ __qla_set_remove_flag(base_vha);
+ cancel_work_sync(&ha->board_disable);
+
+ /*
diff --git a/patches.suse/scsi-qla2xxx-Silence-fwdump-template-message.patch b/patches.suse/scsi-qla2xxx-Silence-fwdump-template-message.patch
new file mode 100644
index 0000000000..03e63fa239
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Silence-fwdump-template-message.patch
@@ -0,0 +1,29 @@
+From: Himanshu Madhani <hmadhani@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:05 -0700
+Subject: scsi: qla2xxx: Silence fwdump template message
+Patch-mainline: v5.4-rc2
+Git-commit: 248a445adfc8c33ffd67cf1f2e336578e34f9e21
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Print if fwdt template is present or not, only when
+ql2xextended_error_logging is enabled.
+
+Link: https://lore.kernel.org/r/20190912180918.6436-2-hmadhani@marvell.com
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -3192,7 +3192,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *v
+
+ for (j = 0; j < 2; j++, fwdt++) {
+ if (!fwdt->template) {
+- ql_log(ql_log_warn, vha, 0x00ba,
++ ql_dbg(ql_dbg_init, vha, 0x00ba,
+ "-> fwdt%u no template\n", j);
+ continue;
+ }
diff --git a/patches.suse/scsi-qla2xxx-Update-driver-version-to-10.01.00.20-k.patch b/patches.suse/scsi-qla2xxx-Update-driver-version-to-10.01.00.20-k.patch
new file mode 100644
index 0000000000..e171213605
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-Update-driver-version-to-10.01.00.20-k.patch
@@ -0,0 +1,27 @@
+From: Himanshu Madhani <hmadhani@marvell.com>
+Date: Thu, 12 Sep 2019 11:09:18 -0700
+Subject: scsi: qla2xxx: Update driver version to 10.01.00.20-k
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
+Git-commit: 8ae15a460b1471622f85bad6caebe56fd91f4f83
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Link: https://lore.kernel.org/r/20190912180918.6436-15-hmadhani@marvell.com
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_version.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/qla2xxx/qla_version.h
++++ b/drivers/scsi/qla2xxx/qla_version.h
+@@ -7,7 +7,7 @@
+ /*
+ * Driver version
+ */
+-#define QLA2XXX_VERSION "10.01.00.19-k"
++#define QLA2XXX_VERSION "10.01.00.20-k"
+
+ #define QLA_DRIVER_MAJOR_VER 10
+ #define QLA_DRIVER_MINOR_VER 1
diff --git a/patches.suse/scsi-qla2xxx-fix-wait-condition-in-loop.patch b/patches.suse/scsi-qla2xxx-fix-wait-condition-in-loop.patch
new file mode 100644
index 0000000000..b935413aa6
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-fix-wait-condition-in-loop.patch
@@ -0,0 +1,61 @@
+From 5287c30d4f4e1873d1fda35b3f48a4a13eea7305 Mon Sep 17 00:00:00 2001
+From: Martin Wilck <mwilck@suse.com>
+Date: Wed, 2 Oct 2019 15:41:56 +0000
+Subject: [PATCH] scsi: qla2xxx: Fix wait condition in loop
+Patch-mainline: Submitted, 2019-10-02 linux-scsi
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+Fix two issues with the previously submitted patch
+"qla2xxx: Optimize NPIV tear down process": a missing negation
+in a wait_event_timeout() condition, and a missing loop end
+condition.
+
+Signed-off-by: Martin Wilck <mwilck@suse.com>
+Fixes: f5187b7d1ac6 ("scsi: qla2xxx: Optimize NPIV tear down process")
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_mid.c | 8 +++++---
+ drivers/scsi/qla2xxx/qla_os.c | 8 +++++---
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
+index 6afad68e5ba2..238240984bc1 100644
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -76,9 +76,11 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
+ * ensures no active vp_list traversal while the vport is removed
+ * from the queue)
+ */
+- for (i = 0; i < 10 && atomic_read(&vha->vref_count); i++)
+- wait_event_timeout(vha->vref_waitq,
+- atomic_read(&vha->vref_count), HZ);
++ for (i = 0; i < 10; i++) {
++ if (wait_event_timeout(vha->vref_waitq,
++ !atomic_read(&vha->vref_count), HZ) > 0)
++ break;
++ }
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ if (atomic_read(&vha->vref_count)) {
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 16f9b6ed574a..fec8410456ef 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -1119,9 +1119,11 @@ qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
+
+ qla2x00_mark_all_devices_lost(vha, 0);
+
+- for (i = 0; i < 10; i++)
+- wait_event_timeout(vha->fcport_waitQ, test_fcport_count(vha),
+- HZ);
++ for (i = 0; i < 10; i++) {
++ if (wait_event_timeout(vha->fcport_waitQ,
++ test_fcport_count(vha), HZ) > 0)
++ break;
++ }
+
+ flush_workqueue(vha->hw->wq);
+ }
+--
+2.16.4
+
diff --git a/patches.suse/scsi-qla2xxx-remove-redundant-assignment-to-pointer-.patch b/patches.suse/scsi-qla2xxx-remove-redundant-assignment-to-pointer-.patch
new file mode 100644
index 0000000000..62bc967dfa
--- /dev/null
+++ b/patches.suse/scsi-qla2xxx-remove-redundant-assignment-to-pointer-.patch
@@ -0,0 +1,32 @@
+From: Colin Ian King <colin.king@canonical.com>
+Date: Thu, 5 Sep 2019 14:42:29 +0100
+Subject: scsi: qla2xxx: remove redundant assignment to pointer host
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+Git-commit: da6d2965dbdb480f091c42f54a09abe8056282e5
+References: bsc#1143706 bsc#1082635 bsc#1123034
+
+The pointer host is being initialized with a value that is never read and
+is being re-assigned a little later on. The assignment is redundant and
+hence can be removed.
+
+Link: https://lore.kernel.org/r/20190905134229.21194-1-colin.king@canonical.com
+Addresses-Coverity: ("Unused value")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Daniel Wagner <dwagner@suse.de>
+---
+ drivers/scsi/qla2xxx/qla_target.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -472,7 +472,7 @@ void qlt_response_pkt_all_vps(struct scs
+
+ case IMMED_NOTIFY_TYPE:
+ {
+- struct scsi_qla_host *host = vha;
++ struct scsi_qla_host *host;
+ struct imm_ntfy_from_isp *entry =
+ (struct imm_ntfy_from_isp *)pkt;
+
diff --git a/series.conf b/series.conf
index 28c55a7b55..e0c09a7470 100644
--- a/series.conf
+++ b/series.conf
@@ -47491,6 +47491,7 @@
patches.suse/x86-speculation-support-mitigations-cmdline-option.patch
patches.suse/powerpc-speculation-support-mitigations-cmdline-option.patch
patches.suse/s390-speculation-support-mitigations-cmdline-option.patch
+ patches.suse/efi-arm-Show-SMBIOS-bank-device-location-in-CPER-and.patch
patches.suse/genirq-Prevent-use-after-free-and-work-list-corrupti.patch
patches.suse/perf-x86-remove-perf_x86_event_committed.patch
patches.suse/perf-x86-add-get-pmu.patch
@@ -48737,6 +48738,7 @@
patches.suse/s390-pci-fix-struct-definition-for-set-pci-function
patches.suse/s390-pci-fix-assignment-of-bus-resources
patches.suse/s390-zcrypt-fix-wrong-dispatching-for-control-domain-cprbs
+ patches.suse/s390-crypto-fix-gcm-aes-s390-selftest-failures
patches.suse/cifs-fix-memory-leak-of-pneg_inbuf-on-EOPNOTSUPP-ioctl-case.patch
patches.suse/fs-cifs-smb2pdu-c-fix-buffer-free-in-SMB2_ioctl_free.patch
patches.suse/dfs_cache-fix-a-wrong-use-of-kfree-in-flush_cache_ent-.patch
@@ -50139,6 +50141,7 @@
patches.suse/crypto-caam-free-resources-in-case-caam_rng-registra.patch
patches.suse/crypto-skcipher-Unmap-pages-after-an-external-error.patch
patches.suse/crypto-cavium-zip-Add-missing-single_release.patch
+ patches.suse/bnxt_en-Add-PCI-IDs-for-57500-series-NPAR-devices.patch
patches.suse/libertas_tf-Use-correct-channel-range-in-lbtf_geo_in.patch
patches.suse/Revert-mwifiex-fix-system-hang-problem-after-resume.patch
patches.suse/mac80211-minstrel_ht-fix-per-group-max-throughput-ra.patch
@@ -50157,6 +50160,8 @@
patches.suse/0001-video-ssd1307fb-Start-page-range-at-page_offset.patch
patches.suse/dma-buf-sw_sync-Synchronize-signal-vs-syncpt-free.patch
patches.suse/0001-drm-imx-Drop-unused-imx-ipuv3-crtc.o-build.patch
+ patches.suse/0001-drm-i915-gvt-update-vgpu-workload-head-pointer-corre.patch
+ patches.suse/0002-drm-nouveau-kms-nv50-Don-t-create-MSTMs-for-eDP-conn.patch
patches.suse/powerpc-powernv-Restrict-OPAL-symbol-map-to-only-be-.patch
patches.suse/powerpc-pseries-Fix-cpu_hotplug_lock-acquisition-in-.patch
patches.suse/powerpc-powernv-ioda-Fix-race-in-TCE-level-allocatio.patch
@@ -50333,6 +50338,7 @@
patches.suse/PCI-VPD-Prevent-VPD-access-for-Amazon-s-Annapurna-La.patch
patches.suse/PCI-Add-quirk-to-disable-MSI-X-support-for-Amazon-s-.patch
patches.suse/suse-hv-PCI-hv-Detect-and-fix-Hyper-V-PCI-domain-number-coll.patch
+ patches.suse/0003-drm-amd-display-Restore-backlight-brightness-after-s.patch
patches.suse/nfsd-handle-drc-over-allocation-gracefully.patch
patches.suse/nfsd-degraded-slot-count-more-gracefully-as-allocati.patch
patches.suse/powerpc-pseries-Read-TLB-Block-Invalidate-Characteri.patch
@@ -50352,7 +50358,21 @@
patches.suse/0002-btrfs-qgroup-Fix-reserved-data-space-leak-if-we-have.patch
patches.suse/0001-xen-xenbus-fix-self-deadlock-after-killing-user-proc.patch
patches.suse/0001-xen-netfront-do-not-use-0U-as-error-return-value-for.patch
+ patches.suse/scsi-qla2xxx-Silence-fwdump-template-message.patch
+ patches.suse/scsi-qla2xxx-Fix-unbound-sleep-in-fcport-delete-path.patch
+ patches.suse/scsi-qla2xxx-Fix-stale-mem-access-on-driver-unload.patch
+ patches.suse/scsi-qla2xxx-Optimize-NPIV-tear-down-process.patch
+ patches.suse/scsi-qla2xxx-Fix-N2N-link-reset.patch
+ patches.suse/scsi-qla2xxx-Fix-N2N-link-up-fail.patch
patches.suse/scsi-qla2xxx-Fix-Nport-ID-display-value.patch
+ patches.suse/RDMA-cxgb4-Do-not-dma-memory-off-of-the-stack.patch
+ patches.suse/scsi-qla2xxx-Remove-WARN_ON_ONCE-in-qla2x00_status_c.patch
+
+ # jejb/scsi for-next
+ patches.suse/scsi-qla2xxx-remove-redundant-assignment-to-pointer-.patch
+
+ # powerpc/linux next
+ patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm.patch
# dhowells/linux-fs keys-uefi
patches.suse/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch
@@ -50362,6 +50382,15 @@
patches.suse/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch
patches.suse/0006-modsign-Use-secondary-trust-keyring-for-module-signi.patch
+ # mkp/scsi queue
+ patches.suse/scsi-qla2xxx-Dual-FCP-NVMe-target-port-support.patch
+ patches.suse/scsi-qla2xxx-Add-error-handling-for-PLOGI-ELS-passth.patch
+ patches.suse/scsi-qla2xxx-Set-remove-flag-for-all-VP.patch
+ patches.suse/scsi-qla2xxx-Check-for-MB-timeout-while-capturing-IS.patch
+ patches.suse/scsi-qla2xxx-Capture-FW-dump-on-MPI-heartbeat-stop-e.patch
+ patches.suse/scsi-qla2xxx-Improve-logging-for-scan-thread.patch
+ patches.suse/scsi-qla2xxx-Update-driver-version-to-10.01.00.20-k.patch
+
# out-of-tree patches
patches.suse/firmware-arm_sdei-fix-wrong-of_node_put-in-init-function.patch
patches.suse/net-mvpp2-fix-condition-for-setting-up-link-interrup.patch
@@ -50398,9 +50427,8 @@
patches.suse/0001-ACPICA-Increase-total-number-of-possible-Owner-IDs.patch
patches.suse/powerpc-fadump-when-fadump-is-supported-register-the.patch
patches.suse/cifs-handle-netapp-error-codes.patch
- patches.suse/scsi-qla2xxx-Remove-WARN_ON_ONCE-in-qla2x00_status_c.patch
patches.suse/0001-b2c2-flexcop-usb-add-sanity-checking.patch
- patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm_meta_-get-set.patch
+ patches.suse/scsi-qla2xxx-fix-wait-condition-in-loop.patch
########################################################
# end of sorted patches