summaryrefslogtreecommitdiffstats
path: root/debian/patches/bugfix/arm64
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:02:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:02:38 +0000
commit08b74a000942a380fe028845f92cd3a0dee827d5 (patch)
treeaa78b4e12607c3e1fcce8d5cc42df4330792f118 /debian/patches/bugfix/arm64
parentAdding upstream version 4.19.249. (diff)
downloadlinux-08b74a000942a380fe028845f92cd3a0dee827d5.tar.xz
linux-08b74a000942a380fe028845f92cd3a0dee827d5.zip
Adding debian version 4.19.249-2.debian/4.19.249-2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches/bugfix/arm64')
-rw-r--r--debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch47
-rw-r--r--debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch46
-rw-r--r--debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch92
-rw-r--r--debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch28
-rw-r--r--debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch42
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch47
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch29
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch308
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch54
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch33
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch40
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch116
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch113
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch150
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch92
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch429
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch187
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch82
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch43
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch29
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch32
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch157
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch144
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch45
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch30
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch39
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch28
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch46
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch43
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch28
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch63
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch70
32 files changed, 2732 insertions, 0 deletions
diff --git a/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch b/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch
new file mode 100644
index 000000000..55fbe10b5
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch
@@ -0,0 +1,47 @@
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Sat, 15 Jun 2019 10:23:56 +1000
+Subject: [PATCH 3/4] arm64: PCI: Allow resource reallocation if necessary
+Origin: https://git.kernel.org/linus/3e8ba9686600e5f77e692126bf0293edf162989a
+
+Call pci_assign_unassigned_root_bus_resources() instead of the simpler:
+
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+
+pci_assign_unassigned_root_bus_resources() calls:
+
+ __pci_bus_size_bridges(bus, add_list);
+ __pci_bus_assign_resources(bus, add_list, &fail_head);
+
+so this should be equivalent as long as we're able to assign everything.
+If we were unable to assign something, previously we did nothing and left
+it unassigned, but after this patch, we will attempt to do some
+reallocation.
+
+Once we start honoring FW resource allocations, this will bring up the
+"reallocation" feature which can help making room for SR-IOV when
+necessary.
+
+Link: https://lore.kernel.org/r/20190615002359.29577-1-benh@kernel.crashing.org
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+---
+ arch/arm64/kernel/pci.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+Index: linux/arch/arm64/kernel/pci.c
+===================================================================
+--- linux.orig/arch/arm64/kernel/pci.c
++++ linux/arch/arm64/kernel/pci.c
+@@ -194,8 +194,7 @@ struct pci_bus *pci_acpi_scan_root(struc
+ if (!bus)
+ return NULL;
+
+- pci_bus_size_bridges(bus);
+- pci_bus_assign_resources(bus);
++ pci_assign_unassigned_root_bus_resources(bus);
+
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
diff --git a/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch b/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch
new file mode 100644
index 000000000..37bc6e0c8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch
@@ -0,0 +1,46 @@
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Sat, 15 Jun 2019 10:23:59 +1000
+Subject: [PATCH 4/4] arm64: PCI: Preserve firmware configuration when desired
+Origin: https://git.kernel.org/linus/85dc04136e86680378546afb808357a58c06061c
+
+If we must preserve the firmware resource assignments, claim the existing
+resources rather than reassigning everything.
+
+Link: https://lore.kernel.org/r/20190615002359.29577-4-benh@kernel.crashing.org
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+---
+ arch/arm64/kernel/pci.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+Index: linux/arch/arm64/kernel/pci.c
+===================================================================
+--- linux.orig/arch/arm64/kernel/pci.c
++++ linux/arch/arm64/kernel/pci.c
+@@ -169,6 +169,7 @@ struct pci_bus *pci_acpi_scan_root(struc
+ struct acpi_pci_generic_root_info *ri;
+ struct pci_bus *bus, *child;
+ struct acpi_pci_root_ops *root_ops;
++ struct pci_host_bridge *host;
+
+ ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
+ if (!ri)
+@@ -194,6 +195,15 @@ struct pci_bus *pci_acpi_scan_root(struc
+ if (!bus)
+ return NULL;
+
++ /* If we must preserve the resource configuration, claim now */
++ host = pci_find_host_bridge(bus);
++ if (host->preserve_config)
++ pci_bus_claim_resources(bus);
++
++ /*
++ * Assign whatever was left unassigned. If we didn't claim above,
++ * this will reassign everything.
++ */
+ pci_assign_unassigned_root_bus_resources(bus);
+
+ list_for_each_entry(child, &bus->children, node)
diff --git a/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch
new file mode 100644
index 000000000..50098d001
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch
@@ -0,0 +1,92 @@
+From: Geoff Levand <geoff@infradead.org>
+Date: Wed, 13 Jun 2018 10:56:08 -0700
+Subject: arm64/acpi: Add fixup for HPE m400 quirks
+Forwarded: https://patchwork.codeaurora.org/patch/547277/
+
+Adds a new ACPI init routine acpi_fixup_m400_quirks that adds
+a work-around for HPE ProLiant m400 APEI firmware problems.
+
+The work-around disables APEI when CONFIG_ACPI_APEI is set and
+m400 firmware is detected. Without this fixup m400 systems
+experience errors like these on startup:
+
+ [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2
+ [Hardware Error]: event severity: fatal
+ [Hardware Error]: Error 0, type: fatal
+ [Hardware Error]: section_type: memory error
+ [Hardware Error]: error_status: 0x0000000000001300
+ [Hardware Error]: error_type: 10, invalid address
+ Kernel panic - not syncing: Fatal hardware error!
+
+Signed-off-by: Geoff Levand <geoff@infradead.org>
+[bwh: Adjust context to apply to Linux 4.19]
+---
+ arch/arm64/kernel/acpi.c | 40 ++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 4 deletions(-)
+
+Index: linux/arch/arm64/kernel/acpi.c
+===================================================================
+--- linux.orig/arch/arm64/kernel/acpi.c
++++ linux/arch/arm64/kernel/acpi.c
+@@ -33,6 +33,8 @@
+ #include <asm/pgtable.h>
+ #include <asm/smp_plat.h>
+
++#include <acpi/apei.h>
++
+ int acpi_noirq = 1; /* skip ACPI IRQ initialization */
+ int acpi_disabled = 1;
+ EXPORT_SYMBOL(acpi_disabled);
+@@ -179,6 +181,33 @@ out:
+ }
+
+ /*
++ * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware
++ * problems.
++ */
++static void __init acpi_fixup_m400_quirks(void)
++{
++ acpi_status status;
++ struct acpi_table_header *header;
++#if !defined(CONFIG_ACPI_APEI)
++ int hest_disable = HEST_DISABLED;
++#endif
++
++ if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED)
++ return;
++
++ status = acpi_get_table(ACPI_SIG_HEST, 0, &header);
++
++ if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE ", 6) &&
++ !strncmp(header->oem_table_id, "ProLiant", 8) &&
++ MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) {
++ hest_disable = HEST_DISABLED;
++ pr_info("Disabled APEI for m400.\n");
++ }
++
++ acpi_put_table(header);
++}
++
++/*
+ * acpi_boot_table_init() called from setup_arch(), always.
+ * 1. find RSDP and get its address, and then find XSDT
+ * 2. extract all tables and checksums them all
+@@ -233,11 +262,14 @@ done:
+ if (acpi_disabled) {
+ if (earlycon_acpi_spcr_enable)
+ early_init_dt_scan_chosen_stdout();
+- } else {
+- acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
+- if (IS_ENABLED(CONFIG_ACPI_BGRT))
+- acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
++ return;
+ }
++
++ acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
++ if (IS_ENABLED(CONFIG_ACPI_BGRT))
++ acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
++
++ acpi_fixup_m400_quirks();
+ }
+
+ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)
diff --git a/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch b/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch
new file mode 100644
index 000000000..543364416
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch
@@ -0,0 +1,28 @@
+From: Samuel Holland <samuel@sholland.org>
+Date: Sat, 12 Jan 2019 20:17:19 -0600
+Subject: arm64: dts: allwinner: a64: Enable A64 timer workaround
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/commit?id=55ec26d6a4241363fa94f15377ebd8f1116fbfd7
+
+As instability in the architectural timer has been observed on multiple
+devices using this SoC, inluding the Pine64 and the Orange Pi Win,
+enable the workaround in the SoC's device tree.
+
+Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: linux/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+===================================================================
+--- linux.orig/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
++++ linux/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+@@ -159,6 +159,7 @@
+
+ timer {
+ compatible = "arm,armv8-timer";
++ allwinner,erratum-unknown1;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14
diff --git a/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch
new file mode 100644
index 000000000..4116ab598
--- /dev/null
+++ b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch
@@ -0,0 +1,42 @@
+From: Heinrich Schuchardt <xypron.glpk@gmx.de>
+Date: Mon, 4 Jun 2018 19:15:23 +0200
+Subject: arm64: dts: rockchip: correct voltage selector on Firefly-RK3399
+Bug-Debian: https://bugs.debian.org/900799
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/patch/?id=710e8c4a54be82ee8a97324e7b4330bf191e08bf
+
+Without this patch the Firefly-RK3399 board boot process hangs after these
+lines:
+
+ fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1] Detected!
+ fan53555-reg: supplied by vcc_sys
+ vcc1v8_s3: supplied by vcc_1v8
+
+Blacklisting driver fan53555 allows booting.
+
+The device tree uses a value of fcs,suspend-voltage-selector different to
+any other board.
+
+Changing this setting to the usual value is sufficient to enable booting
+and also matches the value used in the vendor kernel.
+
+Fixes: 171582e00db1 ("arm64: dts: rockchip: add support for firefly-rk3399 board")
+Cc: stable@vger.kernel.org
+Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
+===================================================================
+--- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
++++ linux/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
+@@ -455,7 +455,7 @@
+ vdd_cpu_b: regulator@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+- fcs,suspend-voltage-selector = <0>;
++ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_b";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1500000>;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch b/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch
new file mode 100644
index 000000000..98b6e734e
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch
@@ -0,0 +1,47 @@
+From bbd24b8bdc501fb5dacb43e847b6eeb9a12829f5 Mon Sep 17 00:00:00 2001
+From: Luo Jiaxing <luojiaxing@huawei.com>
+Date: Mon, 24 Sep 2018 23:06:29 +0800
+Subject: [PATCH 02/31] scsi: hisi_sas: Move evaluation of hisi_hba in
+ hisi_sas_task_prep()
+Origin: https://git.kernel.org/linus/1668e3b6f8f8ed2ce685691c92b90dfadeaa3f2f
+
+In evaluating hisi_hba, the sas_port may be NULL, so for safety relocate
+the the check to value possible NULL deference.
+
+Signed-off-by: Luo Jiaxing <luojiaxing@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -288,13 +288,13 @@ static int hisi_sas_task_prep(struct sas
+ int *pass)
+ {
+ struct domain_device *device = task->dev;
+- struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
++ struct hisi_hba *hisi_hba;
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_sas_port *port;
+ struct hisi_sas_slot *slot;
+ struct hisi_sas_cmd_hdr *cmd_hdr_base;
+ struct asd_sas_port *sas_port = device->port;
+- struct device *dev = hisi_hba->dev;
++ struct device *dev;
+ int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
+ int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
+ struct hisi_sas_dq *dq;
+@@ -315,6 +315,9 @@ static int hisi_sas_task_prep(struct sas
+ return -ECOMM;
+ }
+
++ hisi_hba = dev_to_hisi_hba(device);
++ dev = hisi_hba->dev;
++
+ if (DEV_IS_GONE(sas_dev)) {
+ if (sas_dev)
+ dev_info(dev, "task prep: device %d not ready\n",
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch b/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch
new file mode 100644
index 000000000..a25ca7885
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch
@@ -0,0 +1,29 @@
+From de1d5713a20562acdb3f94466232432c9dd1d95c Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 24 Sep 2018 23:06:32 +0800
+Subject: [PATCH 05/31] scsi: hisi_sas: unmask interrupts ent72 and ent74
+Origin: https://git.kernel.org/linus/6ecf5ba13cd5959eb75f617ff32c93bb67790e48
+
+The interrupts of ent72 and ent74 are not processed by PCIe AER handling,
+so we need to unmask the interrupts and process them first in the driver.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -441,7 +441,7 @@ static void init_reg_v3_hw(struct hisi_h
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe);
+ if (pdev->revision >= 0x21)
+- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7fff);
++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7aff);
+ else
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff);
+ hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch b/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch
new file mode 100644
index 000000000..15a26a35a
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch
@@ -0,0 +1,308 @@
+From d35bf6fccf7d4064065c078d3d369ffeaad6c731 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 24 Sep 2018 23:06:33 +0800
+Subject: [PATCH 06/31] scsi: hisi_sas: Use block layer tag instead for IPTT
+Origin: https://git.kernel.org/linus/784b46b7cba0ae914dd293f23848c5057c6ba017
+
+Currently we use the IPTT defined in LLDD to identify IOs. Actually for
+IOs which are from the block layer, they have tags to identify them. So
+for those IOs, use tag of the block layer directly, and for IOs which is
+not from the block layer (such as internal IOs from libsas/LLDD), reserve
+96 IPTTs for them.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 3 +-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 89 +++++++++++++++++---------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 9 +--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 ++-
+ 5 files changed, 70 insertions(+), 40 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -34,6 +34,7 @@
+ #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
+ #define HISI_SAS_RESET_BIT 0
+ #define HISI_SAS_REJECT_CMD_BIT 1
++#define HISI_SAS_RESERVED_IPTT_CNT 96
+
+ #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
+ #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
+@@ -217,7 +218,7 @@ struct hisi_sas_hw {
+ int (*hw_init)(struct hisi_hba *hisi_hba);
+ void (*setup_itct)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *device);
+- int (*slot_index_alloc)(struct hisi_hba *hisi_hba, int *slot_idx,
++ int (*slot_index_alloc)(struct hisi_hba *hisi_hba,
+ struct domain_device *device);
+ struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
+ void (*sl_notify_ssp)(struct hisi_hba *hisi_hba, int phy_no);
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -184,7 +184,14 @@ static void hisi_sas_slot_index_clear(st
+
+ static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx)
+ {
+- hisi_sas_slot_index_clear(hisi_hba, slot_idx);
++ unsigned long flags;
++
++ if (hisi_hba->hw->slot_index_alloc || (slot_idx >=
++ hisi_hba->hw->max_command_entries - HISI_SAS_RESERVED_IPTT_CNT)) {
++ spin_lock_irqsave(&hisi_hba->lock, flags);
++ hisi_sas_slot_index_clear(hisi_hba, slot_idx);
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ }
+ }
+
+ static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx)
+@@ -194,24 +201,34 @@ static void hisi_sas_slot_index_set(stru
+ set_bit(slot_idx, bitmap);
+ }
+
+-static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx)
++static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba,
++ struct scsi_cmnd *scsi_cmnd)
+ {
+- unsigned int index;
++ int index;
+ void *bitmap = hisi_hba->slot_index_tags;
++ unsigned long flags;
+
++ if (scsi_cmnd)
++ return scsi_cmnd->request->tag;
++
++ spin_lock_irqsave(&hisi_hba->lock, flags);
+ index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
+- hisi_hba->last_slot_index + 1);
++ hisi_hba->last_slot_index + 1);
+ if (index >= hisi_hba->slot_index_count) {
+- index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
+- 0);
+- if (index >= hisi_hba->slot_index_count)
++ index = find_next_zero_bit(bitmap,
++ hisi_hba->slot_index_count,
++ hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT);
++ if (index >= hisi_hba->slot_index_count) {
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ return -SAS_QUEUE_FULL;
++ }
+ }
+ hisi_sas_slot_index_set(hisi_hba, index);
+- *slot_idx = index;
+ hisi_hba->last_slot_index = index;
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
+- return 0;
++ return index;
+ }
+
+ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba)
+@@ -250,9 +267,7 @@ void hisi_sas_slot_task_free(struct hisi
+
+ memset(slot, 0, offsetof(struct hisi_sas_slot, buf));
+
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot->idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free);
+
+@@ -385,16 +400,27 @@ static int hisi_sas_task_prep(struct sas
+ goto err_out_dma_unmap;
+ }
+
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ if (hisi_hba->hw->slot_index_alloc)
+- rc = hisi_hba->hw->slot_index_alloc(hisi_hba, &slot_idx,
+- device);
+- else
+- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- if (rc)
++ rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
++ else {
++ struct scsi_cmnd *scsi_cmnd = NULL;
++
++ if (task->uldd_task) {
++ struct ata_queued_cmd *qc;
++
++ if (dev_is_sata(device)) {
++ qc = task->uldd_task;
++ scsi_cmnd = qc->scsicmd;
++ } else {
++ scsi_cmnd = task->uldd_task;
++ }
++ }
++ rc = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd);
++ }
++ if (rc < 0)
+ goto err_out_dma_unmap;
+
++ slot_idx = rc;
+ slot = &hisi_hba->slot_info[slot_idx];
+
+ spin_lock_irqsave(&dq->lock, flags);
+@@ -455,9 +481,7 @@ static int hisi_sas_task_prep(struct sas
+ return 0;
+
+ err_out_tag:
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ err_out_dma_unmap:
+ if (!sas_protocol_ata(task->task_proto)) {
+ if (task->num_scatter) {
+@@ -1747,14 +1771,11 @@ hisi_sas_internal_abort_task_exec(struct
+ port = to_hisi_sas_port(sas_port);
+
+ /* simply get a slot and send abort command */
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
+- if (rc) {
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ rc = hisi_sas_slot_index_alloc(hisi_hba, NULL);
++ if (rc < 0)
+ goto err_out;
+- }
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
++ slot_idx = rc;
+ slot = &hisi_hba->slot_info[slot_idx];
+
+ spin_lock_irqsave(&dq->lock, flags_dq);
+@@ -1790,7 +1811,6 @@ hisi_sas_internal_abort_task_exec(struct
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+-
+ WRITE_ONCE(slot->ready, 1);
+ /* send abort command to the chip */
+ spin_lock_irqsave(&dq->lock, flags);
+@@ -1801,9 +1821,7 @@ hisi_sas_internal_abort_task_exec(struct
+ return 0;
+
+ err_out_tag:
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ err_out:
+ dev_err(dev, "internal abort task prep: failed[%d]!\n", rc);
+
+@@ -2179,6 +2197,8 @@ int hisi_sas_alloc(struct hisi_hba *hisi
+ hisi_sas_init_mem(hisi_hba);
+
+ hisi_sas_slot_index_init(hisi_hba);
++ hisi_hba->last_slot_index = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
+
+ hisi_hba->wq = create_singlethread_workqueue(dev_name(dev));
+ if (!hisi_hba->wq) {
+@@ -2382,8 +2402,15 @@ int hisi_sas_probe(struct platform_devic
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+ shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+- shost->can_queue = hisi_hba->hw->max_command_entries;
+- shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
++ if (hisi_hba->hw->slot_index_alloc) {
++ shost->can_queue = hisi_hba->hw->max_command_entries;
++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
++ } else {
++ shost->can_queue = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
++ }
+
+ sha->sas_ha_name = DRV_NAME;
+ sha->dev = hisi_hba->dev;
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1807,7 +1807,6 @@ static struct scsi_host_template sht_v1_
+ .scan_start = hisi_sas_scan_start,
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+- .can_queue = 1,
+ .this_id = -1,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -770,7 +770,7 @@ static u32 hisi_sas_phy_read32(struct hi
+
+ /* This function needs to be protected from pre-emption. */
+ static int
+-slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, int *slot_idx,
++slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba,
+ struct domain_device *device)
+ {
+ int sata_dev = dev_is_sata(device);
+@@ -778,6 +778,7 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ int sata_idx = sas_dev->sata_idx;
+ int start, end;
++ unsigned long flags;
+
+ if (!sata_dev) {
+ /*
+@@ -801,6 +802,7 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ end = 64 * (sata_idx + 2);
+ }
+
++ spin_lock_irqsave(&hisi_hba->lock, flags);
+ while (1) {
+ start = find_next_zero_bit(bitmap,
+ hisi_hba->slot_index_count, start);
+@@ -815,8 +817,8 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ }
+
+ set_bit(start, bitmap);
+- *slot_idx = start;
+- return 0;
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ return start;
+ }
+
+ static bool sata_index_alloc_v2_hw(struct hisi_hba *hisi_hba, int *idx)
+@@ -3558,7 +3560,6 @@ static struct scsi_host_template sht_v2_
+ .scan_start = hisi_sas_scan_start,
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+- .can_queue = 1,
+ .this_id = -1,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2108,7 +2108,6 @@ static struct scsi_host_template sht_v3_
+ .scan_start = hisi_sas_scan_start,
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+- .can_queue = 1,
+ .this_id = -1,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+@@ -2118,6 +2117,7 @@ static struct scsi_host_template sht_v3_
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+ .shost_attrs = host_attrs,
++ .tag_alloc_policy = BLK_TAG_ALLOC_RR,
+ };
+
+ static const struct hisi_sas_hw hisi_sas_v3_hw = {
+@@ -2255,8 +2255,10 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+ shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+- shost->can_queue = hisi_hba->hw->max_command_entries;
+- shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
++ shost->can_queue = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
+
+ sha->sas_ha_name = DRV_NAME;
+ sha->dev = dev;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch b/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch
new file mode 100644
index 000000000..440ad1a4a
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch
@@ -0,0 +1,54 @@
+From 4fdcfb8a09d75fbabf4454a60001224b89245c82 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 24 Sep 2018 23:06:34 +0800
+Subject: [PATCH 07/31] scsi: hisi_sas: Update v3 hw AIP_LIMIT and
+ CFG_AGING_TIME register values
+Origin: https://git.kernel.org/linus/3bccfba8312762becfb05b35d698ba8cffd440f2
+
+Update registers as follows:
+- Default value of AIP timer is 1ms, and it is easy for some expanders to
+ cause IO error. Change the value to max value 65ms to avoid IO error for
+ those expanders.
+
+- A CQ completion will be reported by HW when 4 CQs have occurred or the
+ aging timer expires, whichever happens first. Sor serial IO scenario, it
+ will still wait 8us for every IO before it is reported. So in the
+ situation, the performance is poor. So to improve it, change the limit
+ time to the least value.
+ For other scenario, it does little affect to the performance.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -127,6 +127,7 @@
+ #define PHY_CTRL_RESET_OFF 0
+ #define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF)
+ #define SL_CFG (PORT_BASE + 0x84)
++#define AIP_LIMIT (PORT_BASE + 0x90)
+ #define SL_CONTROL (PORT_BASE + 0x94)
+ #define SL_CONTROL_NOTIFY_EN_OFF 0
+ #define SL_CONTROL_NOTIFY_EN_MSK (0x1 << SL_CONTROL_NOTIFY_EN_OFF)
+@@ -431,6 +432,7 @@ static void init_reg_v3_hw(struct hisi_h
+ (u32)((1ULL << hisi_hba->queue_count) - 1));
+ hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400);
+ hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108);
++ hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1);
+ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
+@@ -495,6 +497,7 @@ static void init_reg_v3_hw(struct hisi_h
+ hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32);
+ /* used for 12G negotiate */
+ hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e);
++ hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff);
+ }
+
+ for (i = 0; i < hisi_hba->queue_count; i++) {
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch b/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch
new file mode 100644
index 000000000..1dbe7390b
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch
@@ -0,0 +1,33 @@
+From f27f6edaf4983b00a3c0e2f6ab720cfa3150a147 Mon Sep 17 00:00:00 2001
+From: John Garry <john.garry@huawei.com>
+Date: Tue, 16 Oct 2018 23:00:36 +0800
+Subject: [PATCH 08/31] scsi: hisi_sas: Fix spin lock management in
+ slot_index_alloc_quirk_v2_hw()
+Origin: https://git.kernel.org/linus/fe5fb42de36227c1c2dbb1e7403329ec8a915c20
+
+Currently a spin_unlock_irqrestore() call is missing on the error path,
+so add it.
+
+Reported-by: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -806,8 +806,10 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ while (1) {
+ start = find_next_zero_bit(bitmap,
+ hisi_hba->slot_index_count, start);
+- if (start >= end)
++ if (start >= end) {
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ return -SAS_QUEUE_FULL;
++ }
+ /*
+ * SAS IPTT bit0 should be 1, and SATA IPTT bit0 should be 0.
+ */
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch b/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch
new file mode 100644
index 000000000..9e466ba4c
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch
@@ -0,0 +1,40 @@
+From 59bc5f2f2492ef9949cd723fc98bafa7d8a6c287 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 18 Oct 2018 15:10:17 +0200
+Subject: [PATCH 09/31] scsi: hisi_sas: use dma_set_mask_and_coherent
+Origin: https://git.kernel.org/linus/e4db40e7a1a2cd6af3b6d5f8f3fba15533872398
+
+The driver currently uses pci_set_dma_mask despite otherwise using the
+generic DMA API. Switch it over to the better generic DMA API.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2199,14 +2199,11 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ if (rc)
+ goto err_out_disable_device;
+
+- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) ||
+- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) {
+- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
+- dev_err(dev, "No usable DMA addressing method\n");
+- rc = -EIO;
+- goto err_out_regions;
+- }
++ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
++ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
++ dev_err(dev, "No usable DMA addressing method\n");
++ rc = -EIO;
++ goto err_out_regions;
+ }
+
+ shost = hisi_sas_shost_alloc_pci(pdev);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch b/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch
new file mode 100644
index 000000000..5bbf33aa2
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch
@@ -0,0 +1,116 @@
+From 4e63bca6e8c3a7fac800ee6c27f9afab13774fde Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:32 +0800
+Subject: [PATCH 10/31] scsi: hisi_sas: Create separate host attributes per HBA
+Origin: https://git.kernel.org/linus/c3566f9a617de3288739fd3b8e7539951bf2b04d
+
+Currently all the three HBA (v1/v2/v3 HW) share the same host attributes.
+
+To support each HBA having separate attributes in future, create per-HBA
+attributes.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 7 ++++++-
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 7 ++++++-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 ++++++-
+ 5 files changed, 18 insertions(+), 10 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -468,7 +468,6 @@ extern int hisi_sas_remove(struct platfo
+ extern int hisi_sas_slave_configure(struct scsi_device *sdev);
+ extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time);
+ extern void hisi_sas_scan_start(struct Scsi_Host *shost);
+-extern struct device_attribute *host_attrs[];
+ extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
+ extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
+ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2021,12 +2021,6 @@ EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets
+ struct scsi_transport_template *hisi_sas_stt;
+ EXPORT_SYMBOL_GPL(hisi_sas_stt);
+
+-struct device_attribute *host_attrs[] = {
+- &dev_attr_phy_event_threshold,
+- NULL,
+-};
+-EXPORT_SYMBOL_GPL(host_attrs);
+-
+ static struct sas_domain_function_template hisi_sas_transport_ops = {
+ .lldd_dev_found = hisi_sas_dev_found,
+ .lldd_dev_gone = hisi_sas_dev_gone,
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1797,6 +1797,11 @@ static int hisi_sas_v1_init(struct hisi_
+ return 0;
+ }
+
++static struct device_attribute *host_attrs_v1_hw[] = {
++ &dev_attr_phy_event_threshold,
++ NULL
++};
++
+ static struct scsi_host_template sht_v1_hw = {
+ .name = DRV_NAME,
+ .module = THIS_MODULE,
+@@ -1816,7 +1821,7 @@ static struct scsi_host_template sht_v1_
+ .slave_alloc = sas_slave_alloc,
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+- .shost_attrs = host_attrs,
++ .shost_attrs = host_attrs_v1_hw,
+ };
+
+ static const struct hisi_sas_hw hisi_sas_v1_hw = {
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3552,6 +3552,11 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
++struct device_attribute *host_attrs_v2_hw[] = {
++ &dev_attr_phy_event_threshold,
++ NULL
++};
++
+ static struct scsi_host_template sht_v2_hw = {
+ .name = DRV_NAME,
+ .module = THIS_MODULE,
+@@ -3571,7 +3576,7 @@ static struct scsi_host_template sht_v2_
+ .slave_alloc = sas_slave_alloc,
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+- .shost_attrs = host_attrs,
++ .shost_attrs = host_attrs_v2_hw,
+ };
+
+ static const struct hisi_sas_hw hisi_sas_v2_hw = {
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2101,6 +2101,11 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
++struct device_attribute *host_attrs_v3_hw[] = {
++ &dev_attr_phy_event_threshold,
++ NULL
++};
++
+ static struct scsi_host_template sht_v3_hw = {
+ .name = DRV_NAME,
+ .module = THIS_MODULE,
+@@ -2120,7 +2125,7 @@ static struct scsi_host_template sht_v3_
+ .slave_alloc = sas_slave_alloc,
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+- .shost_attrs = host_attrs,
++ .shost_attrs = host_attrs_v3_hw,
+ .tag_alloc_policy = BLK_TAG_ALLOC_RR,
+ };
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch b/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch
new file mode 100644
index 000000000..ae1b2d718
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch
@@ -0,0 +1,113 @@
+From 7e5e4c2dfd67e156956e46c4d503466726a5359c Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:33 +0800
+Subject: [PATCH 11/31] scsi: hisi_sas: Add support for interrupt converge for
+ v3 hw
+Origin: https://git.kernel.org/linus/488cf558e3d7c95daf737d9cae165019ee3f2840
+
+If CQ_INT_CONVERGE_EN is enabled, the interrupts of all the 16 CQ queues
+will be reported by CQ0.
+
+So we need to change the process of CQ tasklet for this situation.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 29 +++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -42,6 +42,7 @@
+ #define MAX_CON_TIME_LIMIT_TIME 0xa4
+ #define BUS_INACTIVE_LIMIT_TIME 0xa8
+ #define REJECT_TO_OPEN_LIMIT_TIME 0xac
++#define CQ_INT_CONVERGE_EN 0xb0
+ #define CFG_AGING_TIME 0xbc
+ #define HGC_DFX_CFG2 0xc0
+ #define CFG_ABT_SET_QUERY_IPTT 0xd4
+@@ -371,6 +372,9 @@ struct hisi_sas_err_record_v3 {
+ ((fis.command == ATA_CMD_DEV_RESET) && \
+ ((fis.control & ATA_SRST) != 0)))
+
++static bool hisi_sas_intr_conv;
++MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)");
++
+ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
+ {
+ void __iomem *regs = hisi_hba->regs + off;
+@@ -436,6 +440,8 @@ static void init_reg_v3_hw(struct hisi_h
+ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
++ hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN,
++ hisi_sas_intr_conv);
+ hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff);
+@@ -1878,10 +1884,12 @@ static int interrupt_init_v3_hw(struct h
+ for (i = 0; i < hisi_hba->queue_count; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
+ struct tasklet_struct *t = &cq->tasklet;
++ int nr = hisi_sas_intr_conv ? 16 : 16 + i;
++ unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0;
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, i+16),
+- cq_interrupt_v3_hw, 0,
+- DRV_NAME " cq", cq);
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, nr),
++ cq_interrupt_v3_hw, irqflags,
++ DRV_NAME " cq", cq);
+ if (rc) {
+ dev_err(dev,
+ "could not request cq%d interrupt, rc=%d\n",
+@@ -1898,8 +1906,9 @@ static int interrupt_init_v3_hw(struct h
+ free_cq_irqs:
+ for (k = 0; k < i; k++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[k];
++ int nr = hisi_sas_intr_conv ? 16 : 16 + k;
+
+- free_irq(pci_irq_vector(pdev, k+16), cq);
++ free_irq(pci_irq_vector(pdev, nr), cq);
+ }
+ free_irq(pci_irq_vector(pdev, 11), hisi_hba);
+ free_chnl_interrupt:
+@@ -2089,8 +2098,16 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
++static ssize_t intr_conv_v3_hw_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return scnprintf(buf, PAGE_SIZE, "%u\n", hisi_sas_intr_conv);
++}
++static DEVICE_ATTR_RO(intr_conv_v3_hw);
++
+ struct device_attribute *host_attrs_v3_hw[] = {
+ &dev_attr_phy_event_threshold,
++ &dev_attr_intr_conv_v3_hw,
+ NULL
+ };
+
+@@ -2303,8 +2320,9 @@ hisi_sas_v3_destroy_irqs(struct pci_dev
+ free_irq(pci_irq_vector(pdev, 11), hisi_hba);
+ for (i = 0; i < hisi_hba->queue_count; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
++ int nr = hisi_sas_intr_conv ? 16 : 16 + i;
+
+- free_irq(pci_irq_vector(pdev, i+16), cq);
++ free_irq(pci_irq_vector(pdev, nr), cq);
+ }
+ pci_free_irq_vectors(pdev);
+ }
+@@ -2626,6 +2644,7 @@ static struct pci_driver sas_v3_pci_driv
+ };
+
+ module_pci_driver(sas_v3_pci_driver);
++module_param_named(intr_conv, hisi_sas_intr_conv, bool, 0444);
+
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch b/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch
new file mode 100644
index 000000000..4595633a2
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch
@@ -0,0 +1,150 @@
+From 20ca5e4f2c4a2c08340225f074c56f7be1c86f5b Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:34 +0800
+Subject: [PATCH 12/31] scsi: hisi_sas: Add support for interrupt coalescing
+ for v3 hw
+Origin: https://git.kernel.org/linus/37359798ec44ae03fab383a9bef3b7c9df819063
+
+If INT_COAL_EN is enabled, configure time and count of interrupt
+coalescing. Then if CQ collects count of CQ entries in time, it will
+report the interrupt. Or if CQ doesn't collect enough CQ entries in time,
+it will report the interrupt at timeout.
+
+As all the registers are not supported to be changed dynamically, we need
+to config those register between disable and enable PHYs.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 2 +
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 100 +++++++++++++++++++++++++
+ 2 files changed, 102 insertions(+)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas.h
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas.h
++++ linux/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -322,6 +322,8 @@ struct hisi_hba {
+ unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
+ struct work_struct rst_work;
+ u32 phy_state;
++ u32 intr_coal_ticks; /* Time of interrupt coalesce in us */
++ u32 intr_coal_count; /* Interrupt count to coalesce */
+ };
+
+ /* Generic HW DMA host memory structures */
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2105,9 +2105,109 @@ static ssize_t intr_conv_v3_hw_show(stru
+ }
+ static DEVICE_ATTR_RO(intr_conv_v3_hw);
+
++static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba)
++{
++ /* config those registers between enable and disable PHYs */
++ hisi_sas_stop_phys(hisi_hba);
++
++ if (hisi_hba->intr_coal_ticks == 0 ||
++ hisi_hba->intr_coal_count == 0) {
++ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
++ } else {
++ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME,
++ hisi_hba->intr_coal_ticks);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT,
++ hisi_hba->intr_coal_count);
++ }
++ phys_init_v3_hw(hisi_hba);
++}
++
++static ssize_t intr_coal_ticks_v3_hw_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n",
++ hisi_hba->intr_coal_ticks);
++}
++
++static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++ u32 intr_coal_ticks;
++ int ret;
++
++ ret = kstrtou32(buf, 10, &intr_coal_ticks);
++ if (ret) {
++ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
++ return -EINVAL;
++ }
++
++ if (intr_coal_ticks >= BIT(24)) {
++ dev_err(dev, "intr_coal_ticks must be less than 2^24!\n");
++ return -EINVAL;
++ }
++
++ hisi_hba->intr_coal_ticks = intr_coal_ticks;
++
++ config_intr_coal_v3_hw(hisi_hba);
++
++ return count;
++}
++static DEVICE_ATTR_RW(intr_coal_ticks_v3_hw);
++
++static ssize_t intr_coal_count_v3_hw_show(struct device *dev,
++ struct device_attribute
++ *attr, char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n",
++ hisi_hba->intr_coal_count);
++}
++
++static ssize_t intr_coal_count_v3_hw_store(struct device *dev,
++ struct device_attribute
++ *attr, const char *buf, size_t count)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++ u32 intr_coal_count;
++ int ret;
++
++ ret = kstrtou32(buf, 10, &intr_coal_count);
++ if (ret) {
++ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
++ return -EINVAL;
++ }
++
++ if (intr_coal_count >= BIT(8)) {
++ dev_err(dev, "intr_coal_count must be less than 2^8!\n");
++ return -EINVAL;
++ }
++
++ hisi_hba->intr_coal_count = intr_coal_count;
++
++ config_intr_coal_v3_hw(hisi_hba);
++
++ return count;
++}
++static DEVICE_ATTR_RW(intr_coal_count_v3_hw);
++
+ struct device_attribute *host_attrs_v3_hw[] = {
+ &dev_attr_phy_event_threshold,
+ &dev_attr_intr_conv_v3_hw,
++ &dev_attr_intr_coal_ticks_v3_hw,
++ &dev_attr_intr_coal_count_v3_hw,
+ NULL
+ };
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch b/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch
new file mode 100644
index 000000000..060fbcfb8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch
@@ -0,0 +1,92 @@
+From 22834ed6cec2690817120e960d43bbf76ddfda17 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:35 +0800
+Subject: [PATCH 13/31] scsi: hisi_sas: Relocate some codes to avoid an unused
+ check
+Origin: https://git.kernel.org/linus/745b6847634c11dda1079d0290781a443eddb4b7
+
+In function hisi_sas_task_prep(), we check asd_sas_port, but in function
+hisi_sas_task_exec(), we already refer to asd_sas_port by using function
+dev_to_hisi_hba() implicitly. So to avoid this possible invalid
+dereference, relocate the check to function hisi_sas_task_prep().
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 44 ++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 21 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -303,36 +303,19 @@ static int hisi_sas_task_prep(struct sas
+ int *pass)
+ {
+ struct domain_device *device = task->dev;
+- struct hisi_hba *hisi_hba;
++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_sas_port *port;
+ struct hisi_sas_slot *slot;
+ struct hisi_sas_cmd_hdr *cmd_hdr_base;
+ struct asd_sas_port *sas_port = device->port;
+- struct device *dev;
++ struct device *dev = hisi_hba->dev;
+ int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
+ int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
+ struct hisi_sas_dq *dq;
+ unsigned long flags;
+ int wr_q_index;
+
+- if (!sas_port) {
+- struct task_status_struct *ts = &task->task_status;
+-
+- ts->resp = SAS_TASK_UNDELIVERED;
+- ts->stat = SAS_PHY_DOWN;
+- /*
+- * libsas will use dev->port, should
+- * not call task_done for sata
+- */
+- if (device->dev_type != SAS_SATA_DEV)
+- task->task_done(task);
+- return -ECOMM;
+- }
+-
+- hisi_hba = dev_to_hisi_hba(device);
+- dev = hisi_hba->dev;
+-
+ if (DEV_IS_GONE(sas_dev)) {
+ if (sas_dev)
+ dev_info(dev, "task prep: device %d not ready\n",
+@@ -507,10 +490,29 @@ static int hisi_sas_task_exec(struct sas
+ u32 rc;
+ u32 pass = 0;
+ unsigned long flags;
+- struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev);
+- struct device *dev = hisi_hba->dev;
++ struct hisi_hba *hisi_hba;
++ struct device *dev;
++ struct domain_device *device = task->dev;
++ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_dq *dq = NULL;
+
++ if (!sas_port) {
++ struct task_status_struct *ts = &task->task_status;
++
++ ts->resp = SAS_TASK_UNDELIVERED;
++ ts->stat = SAS_PHY_DOWN;
++ /*
++ * libsas will use dev->port, should
++ * not call task_done for sata
++ */
++ if (device->dev_type != SAS_SATA_DEV)
++ task->task_done(task);
++ return -ECOMM;
++ }
++
++ hisi_hba = dev_to_hisi_hba(device);
++ dev = hisi_hba->dev;
++
+ if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) {
+ /*
+ * For IOs from upper layer, it may already disable preempt
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch b/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch
new file mode 100644
index 000000000..1f9ed71c0
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch
@@ -0,0 +1,429 @@
+From 13dda01985003ca1b930b42bb3927f7522f4ce69 Mon Sep 17 00:00:00 2001
+From: John Garry <john.garry@huawei.com>
+Date: Thu, 6 Dec 2018 21:34:40 +0800
+Subject: [PATCH 14/31] scsi: hisi_sas: Fix warnings detected by sparse
+Origin: https://git.kernel.org/linus/735bcc77e6ba83e464665cea9041072190ede37e
+
+This patchset fixes some warnings detected by the sparse tool, like these:
+drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: warning: incorrect type in assignment (different base types)
+drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: expected unsigned short [unsigned] [assigned] [usertype] tag_of_task_to_be_managed
+drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: got restricted __le16 [usertype] <noident>
+drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: warning: incorrect type in assignment (different base types)
+drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: expected unsigned short [unsigned] [assigned] [usertype] tag_of_task_to_be_managed
+drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: got restricted __le16 [usertype] <noident>
+
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 +--
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 15 +++---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 66 +++++++++++++++-----------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 37 +++++++++------
+ 5 files changed, 71 insertions(+), 55 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas.h
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas.h
++++ linux/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -211,7 +211,7 @@ struct hisi_sas_slot {
+ /* Do not reorder/change members after here */
+ void *buf;
+ dma_addr_t buf_dma;
+- int idx;
++ u16 idx;
+ };
+
+ struct hisi_sas_hw {
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1463,12 +1463,12 @@ static int hisi_sas_abort_task(struct sa
+ if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
+ struct scsi_cmnd *cmnd = task->uldd_task;
+ struct hisi_sas_slot *slot = task->lldd_task;
+- u32 tag = slot->idx;
++ u16 tag = slot->idx;
+ int rc2;
+
+ int_to_scsilun(cmnd->device->lun, &lun);
+ tmf_task.tmf = TMF_ABORT_TASK;
+- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
++ tmf_task.tag_of_task_to_be_managed = tag;
+
+ rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun,
+ &tmf_task);
+@@ -1722,7 +1722,7 @@ static int hisi_sas_query_task(struct sa
+
+ int_to_scsilun(cmnd->device->lun, &lun);
+ tmf_task.tmf = TMF_QUERY_TASK;
+- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
++ tmf_task.tag_of_task_to_be_managed = tag;
+
+ rc = hisi_sas_debug_issue_ssp_tmf(device,
+ lun.scsi_lun,
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -510,6 +510,7 @@ static void setup_itct_v1_hw(struct hisi
+ struct hisi_sas_itct *itct = &hisi_hba->itct[device_id];
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ u64 sas_addr;
+
+ memset(itct, 0, sizeof(*itct));
+
+@@ -534,8 +535,8 @@ static void setup_itct_v1_hw(struct hisi
+ itct->qw0 = cpu_to_le64(qw0);
+
+ /* qw1 */
+- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
+- itct->sas_addr = __swab64(itct->sas_addr);
++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
+
+ /* qw2 */
+ itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
+@@ -561,7 +562,7 @@ static void clear_itct_v1_hw(struct hisi
+ reg_val &= ~CFG_AGING_TIME_ITCT_REL_MSK;
+ hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val);
+
+- qw0 = cpu_to_le64(itct->qw0);
++ qw0 = le64_to_cpu(itct->qw0);
+ qw0 &= ~ITCT_HDR_VALID_MSK;
+ itct->qw0 = cpu_to_le64(qw0);
+ }
+@@ -1100,7 +1101,7 @@ static void slot_err_v1_hw(struct hisi_h
+ case SAS_PROTOCOL_SSP:
+ {
+ int error = -1;
+- u32 dma_err_type = cpu_to_le32(err_record->dma_err_type);
++ u32 dma_err_type = le32_to_cpu(err_record->dma_err_type);
+ u32 dma_tx_err_type = ((dma_err_type &
+ ERR_HDR_DMA_TX_ERR_TYPE_MSK)) >>
+ ERR_HDR_DMA_TX_ERR_TYPE_OFF;
+@@ -1108,9 +1109,9 @@ static void slot_err_v1_hw(struct hisi_h
+ ERR_HDR_DMA_RX_ERR_TYPE_MSK)) >>
+ ERR_HDR_DMA_RX_ERR_TYPE_OFF;
+ u32 trans_tx_fail_type =
+- cpu_to_le32(err_record->trans_tx_fail_type);
++ le32_to_cpu(err_record->trans_tx_fail_type);
+ u32 trans_rx_fail_type =
+- cpu_to_le32(err_record->trans_rx_fail_type);
++ le32_to_cpu(err_record->trans_rx_fail_type);
+
+ if (dma_tx_err_type) {
+ /* dma tx err */
+@@ -1558,7 +1559,7 @@ static irqreturn_t cq_interrupt_v1_hw(in
+ u32 cmplt_hdr_data;
+
+ complete_hdr = &complete_queue[rd_point];
+- cmplt_hdr_data = cpu_to_le32(complete_hdr->data);
++ cmplt_hdr_data = le32_to_cpu(complete_hdr->data);
+ idx = (cmplt_hdr_data & CMPLT_HDR_IPTT_MSK) >>
+ CMPLT_HDR_IPTT_OFF;
+ slot = &hisi_hba->slot_info[idx];
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -934,6 +934,7 @@ static void setup_itct_v2_hw(struct hisi
+ struct domain_device *parent_dev = device->parent;
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ u64 sas_addr;
+
+ memset(itct, 0, sizeof(*itct));
+
+@@ -966,8 +967,8 @@ static void setup_itct_v2_hw(struct hisi
+ itct->qw0 = cpu_to_le64(qw0);
+
+ /* qw1 */
+- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
+- itct->sas_addr = __swab64(itct->sas_addr);
++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
+
+ /* qw2 */
+ if (!dev_is_sata(device))
+@@ -2044,11 +2045,11 @@ static void slot_err_v2_hw(struct hisi_h
+ struct task_status_struct *ts = &task->task_status;
+ struct hisi_sas_err_record_v2 *err_record =
+ hisi_sas_status_buf_addr_mem(slot);
+- u32 trans_tx_fail_type = cpu_to_le32(err_record->trans_tx_fail_type);
+- u32 trans_rx_fail_type = cpu_to_le32(err_record->trans_rx_fail_type);
+- u16 dma_tx_err_type = cpu_to_le16(err_record->dma_tx_err_type);
+- u16 sipc_rx_err_type = cpu_to_le16(err_record->sipc_rx_err_type);
+- u32 dma_rx_err_type = cpu_to_le32(err_record->dma_rx_err_type);
++ u32 trans_tx_fail_type = le32_to_cpu(err_record->trans_tx_fail_type);
++ u32 trans_rx_fail_type = le32_to_cpu(err_record->trans_rx_fail_type);
++ u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);
++ u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);
++ u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);
+ int error = -1;
+
+ if (err_phase == 1) {
+@@ -2059,8 +2060,7 @@ static void slot_err_v2_hw(struct hisi_h
+ trans_tx_fail_type);
+ } else if (err_phase == 2) {
+ /* error in RX phase, the priority is: DW1 > DW3 > DW2 */
+- error = parse_trans_rx_err_code_v2_hw(
+- trans_rx_fail_type);
++ error = parse_trans_rx_err_code_v2_hw(trans_rx_fail_type);
+ if (error == -1) {
+ error = parse_dma_rx_err_code_v2_hw(
+ dma_rx_err_type);
+@@ -2358,6 +2358,7 @@ slot_complete_v2_hw(struct hisi_hba *his
+ &complete_queue[slot->cmplt_queue_slot];
+ unsigned long flags;
+ bool is_internal = slot->is_internal;
++ u32 dw0;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+ return -EINVAL;
+@@ -2382,8 +2383,9 @@ slot_complete_v2_hw(struct hisi_hba *his
+ }
+
+ /* Use SAS+TMF status codes */
+- switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK)
+- >> CMPLT_HDR_ABORT_STAT_OFF) {
++ dw0 = le32_to_cpu(complete_hdr->dw0);
++ switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >>
++ CMPLT_HDR_ABORT_STAT_OFF) {
+ case STAT_IO_ABORTED:
+ /* this io has been aborted by abort command */
+ ts->stat = SAS_ABORTED_TASK;
+@@ -2408,9 +2410,8 @@ slot_complete_v2_hw(struct hisi_hba *his
+ break;
+ }
+
+- if ((complete_hdr->dw0 & CMPLT_HDR_ERX_MSK) &&
+- (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {
+- u32 err_phase = (complete_hdr->dw0 & CMPLT_HDR_ERR_PHASE_MSK)
++ if ((dw0 & CMPLT_HDR_ERX_MSK) && (!(dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {
++ u32 err_phase = (dw0 & CMPLT_HDR_ERR_PHASE_MSK)
+ >> CMPLT_HDR_ERR_PHASE_OFF;
+ u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
+
+@@ -2526,22 +2527,23 @@ static void prep_ata_v2_hw(struct hisi_h
+ struct hisi_sas_tmf_task *tmf = slot->tmf;
+ u8 *buf_cmd;
+ int has_data = 0, hdr_tag = 0;
+- u32 dw1 = 0, dw2 = 0;
++ u32 dw0, dw1 = 0, dw2 = 0;
+
+ /* create header */
+ /* dw0 */
+- hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF);
++ dw0 = port->id << CMD_HDR_PORT_OFF;
+ if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
+- hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF);
++ dw0 |= 3 << CMD_HDR_CMD_OFF;
+ else
+- hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF);
++ dw0 |= 4 << CMD_HDR_CMD_OFF;
+
+ if (tmf && tmf->force_phy) {
+- hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK;
+- hdr->dw0 |= cpu_to_le32((1 << tmf->phy_id)
+- << CMD_HDR_PHY_ID_OFF);
++ dw0 |= CMD_HDR_FORCE_PHY_MSK;
++ dw0 |= (1 << tmf->phy_id) << CMD_HDR_PHY_ID_OFF;
+ }
+
++ hdr->dw0 = cpu_to_le32(dw0);
++
+ /* dw1 */
+ switch (task->data_dir) {
+ case DMA_TO_DEVICE:
+@@ -3152,20 +3154,24 @@ static void cq_tasklet_v2_hw(unsigned lo
+
+ /* Check for NCQ completion */
+ if (complete_hdr->act) {
+- u32 act_tmp = complete_hdr->act;
++ u32 act_tmp = le32_to_cpu(complete_hdr->act);
+ int ncq_tag_count = ffs(act_tmp);
++ u32 dw1 = le32_to_cpu(complete_hdr->dw1);
+
+- dev_id = (complete_hdr->dw1 & CMPLT_HDR_DEV_ID_MSK) >>
++ dev_id = (dw1 & CMPLT_HDR_DEV_ID_MSK) >>
+ CMPLT_HDR_DEV_ID_OFF;
+ itct = &hisi_hba->itct[dev_id];
+
+ /* The NCQ tags are held in the itct header */
+ while (ncq_tag_count) {
+- __le64 *ncq_tag = &itct->qw4_15[0];
++ __le64 *_ncq_tag = &itct->qw4_15[0], __ncq_tag;
++ u64 ncq_tag;
+
+- ncq_tag_count -= 1;
+- iptt = (ncq_tag[ncq_tag_count / 5]
+- >> (ncq_tag_count % 5) * 12) & 0xfff;
++ ncq_tag_count--;
++ __ncq_tag = _ncq_tag[ncq_tag_count / 5];
++ ncq_tag = le64_to_cpu(__ncq_tag);
++ iptt = (ncq_tag >> (ncq_tag_count % 5) * 12) &
++ 0xfff;
+
+ slot = &hisi_hba->slot_info[iptt];
+ slot->cmplt_queue_slot = rd_point;
+@@ -3176,7 +3182,9 @@ static void cq_tasklet_v2_hw(unsigned lo
+ ncq_tag_count = ffs(act_tmp);
+ }
+ } else {
+- iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
++ u32 dw1 = le32_to_cpu(complete_hdr->dw1);
++
++ iptt = dw1 & CMPLT_HDR_IPTT_MSK;
+ slot = &hisi_hba->slot_info[iptt];
+ slot->cmplt_queue_slot = rd_point;
+ slot->cmplt_queue = queue;
+@@ -3552,7 +3560,7 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
+-struct device_attribute *host_attrs_v2_hw[] = {
++static struct device_attribute *host_attrs_v2_hw[] = {
+ &dev_attr_phy_event_threshold,
+ NULL
+ };
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -628,6 +628,7 @@ static void setup_itct_v3_hw(struct hisi
+ struct domain_device *parent_dev = device->parent;
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ u64 sas_addr;
+
+ memset(itct, 0, sizeof(*itct));
+
+@@ -660,8 +661,8 @@ static void setup_itct_v3_hw(struct hisi
+ itct->qw0 = cpu_to_le64(qw0);
+
+ /* qw1 */
+- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
+- itct->sas_addr = __swab64(itct->sas_addr);
++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
+
+ /* qw2 */
+ if (!dev_is_sata(device))
+@@ -1590,15 +1591,16 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba
+ &complete_queue[slot->cmplt_queue_slot];
+ struct hisi_sas_err_record_v3 *record =
+ hisi_sas_status_buf_addr_mem(slot);
+- u32 dma_rx_err_type = record->dma_rx_err_type;
+- u32 trans_tx_fail_type = record->trans_tx_fail_type;
++ u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type);
++ u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type);
++ u32 dw3 = le32_to_cpu(complete_hdr->dw3);
+
+ switch (task->task_proto) {
+ case SAS_PROTOCOL_SSP:
+ if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
+ ts->residual = trans_tx_fail_type;
+ ts->stat = SAS_DATA_UNDERRUN;
+- } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
++ } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
+ ts->stat = SAS_QUEUE_FULL;
+ slot->abort = 1;
+ } else {
+@@ -1612,7 +1614,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba
+ if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
+ ts->residual = trans_tx_fail_type;
+ ts->stat = SAS_DATA_UNDERRUN;
+- } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
++ } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
+ ts->stat = SAS_PHY_DOWN;
+ slot->abort = 1;
+ } else {
+@@ -1645,6 +1647,7 @@ slot_complete_v3_hw(struct hisi_hba *his
+ &complete_queue[slot->cmplt_queue_slot];
+ unsigned long flags;
+ bool is_internal = slot->is_internal;
++ u32 dw0, dw1, dw3;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+ return -EINVAL;
+@@ -1668,11 +1671,14 @@ slot_complete_v3_hw(struct hisi_hba *his
+ goto out;
+ }
+
++ dw0 = le32_to_cpu(complete_hdr->dw0);
++ dw1 = le32_to_cpu(complete_hdr->dw1);
++ dw3 = le32_to_cpu(complete_hdr->dw3);
++
+ /*
+ * Use SAS+TMF status codes
+ */
+- switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK)
+- >> CMPLT_HDR_ABORT_STAT_OFF) {
++ switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >> CMPLT_HDR_ABORT_STAT_OFF) {
+ case STAT_IO_ABORTED:
+ /* this IO has been aborted by abort command */
+ ts->stat = SAS_ABORTED_TASK;
+@@ -1695,7 +1701,7 @@ slot_complete_v3_hw(struct hisi_hba *his
+ }
+
+ /* check for erroneous completion */
+- if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
++ if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
+ u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
+
+ slot_err_v3_hw(hisi_hba, task, slot);
+@@ -1704,8 +1710,7 @@ slot_complete_v3_hw(struct hisi_hba *his
+ "CQ hdr: 0x%x 0x%x 0x%x 0x%x "
+ "Error info: 0x%x 0x%x 0x%x 0x%x\n",
+ slot->idx, task, sas_dev->device_id,
+- complete_hdr->dw0, complete_hdr->dw1,
+- complete_hdr->act, complete_hdr->dw3,
++ dw0, dw1, complete_hdr->act, dw3,
+ error_info[0], error_info[1],
+ error_info[2], error_info[3]);
+ if (unlikely(slot->abort))
+@@ -1803,11 +1808,13 @@ static void cq_tasklet_v3_hw(unsigned lo
+ while (rd_point != wr_point) {
+ struct hisi_sas_complete_v3_hdr *complete_hdr;
+ struct device *dev = hisi_hba->dev;
++ u32 dw1;
+ int iptt;
+
+ complete_hdr = &complete_queue[rd_point];
++ dw1 = le32_to_cpu(complete_hdr->dw1);
+
+- iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
++ iptt = dw1 & CMPLT_HDR_IPTT_MSK;
+ if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) {
+ slot = &hisi_hba->slot_info[iptt];
+ slot->cmplt_queue_slot = rd_point;
+@@ -2203,7 +2210,7 @@ static ssize_t intr_coal_count_v3_hw_sto
+ }
+ static DEVICE_ATTR_RW(intr_coal_count_v3_hw);
+
+-struct device_attribute *host_attrs_v3_hw[] = {
++static struct device_attribute *host_attrs_v3_hw[] = {
+ &dev_attr_phy_event_threshold,
+ &dev_attr_intr_conv_v3_hw,
+ &dev_attr_intr_coal_ticks_v3_hw,
+@@ -2649,7 +2656,7 @@ static int hisi_sas_v3_suspend(struct pc
+ struct hisi_hba *hisi_hba = sha->lldd_ha;
+ struct device *dev = hisi_hba->dev;
+ struct Scsi_Host *shost = hisi_hba->shost;
+- u32 device_state;
++ pci_power_t device_state;
+ int rc;
+
+ if (!pdev->pm_cap) {
+@@ -2695,7 +2702,7 @@ static int hisi_sas_v3_resume(struct pci
+ struct Scsi_Host *shost = hisi_hba->shost;
+ struct device *dev = hisi_hba->dev;
+ unsigned int rc;
+- u32 device_state = pdev->current_state;
++ pci_power_t device_state = pdev->current_state;
+
+ dev_warn(dev, "resuming from operating state [D%d]\n",
+ device_state);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch b/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch
new file mode 100644
index 000000000..1e44aa3b8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch
@@ -0,0 +1,187 @@
+From 9e9903e8e143c32498565cb49a7aab6081734782 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Thu, 6 Dec 2018 21:34:41 +0800
+Subject: [PATCH 15/31] scsi: hisi_sas: Relocate some code to reduce complexity
+Origin: https://git.kernel.org/linus/6e1b731b535231e199c7810451c851398afccd33
+
+Relocate the codes related to dma_map/unmap in hisi_sas_task_prep() to
+reduce complexity, with a view to add DIF/DIX support.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 146 ++++++++++++++++----------
+ 1 file changed, 90 insertions(+), 56 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -297,6 +297,90 @@ static void hisi_sas_task_prep_abort(str
+ device_id, abort_flag, tag_to_abort);
+ }
+
++static void hisi_sas_dma_unmap(struct hisi_hba *hisi_hba,
++ struct sas_task *task, int n_elem,
++ int n_elem_req, int n_elem_resp)
++{
++ struct device *dev = hisi_hba->dev;
++
++ if (!sas_protocol_ata(task->task_proto)) {
++ if (task->num_scatter) {
++ if (n_elem)
++ dma_unmap_sg(dev, task->scatter,
++ task->num_scatter,
++ task->data_dir);
++ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
++ if (n_elem_req)
++ dma_unmap_sg(dev, &task->smp_task.smp_req,
++ 1, DMA_TO_DEVICE);
++ if (n_elem_resp)
++ dma_unmap_sg(dev, &task->smp_task.smp_resp,
++ 1, DMA_FROM_DEVICE);
++ }
++ }
++}
++
++static int hisi_sas_dma_map(struct hisi_hba *hisi_hba,
++ struct sas_task *task, int *n_elem,
++ int *n_elem_req, int *n_elem_resp)
++{
++ struct device *dev = hisi_hba->dev;
++ int rc;
++
++ if (sas_protocol_ata(task->task_proto)) {
++ *n_elem = task->num_scatter;
++ } else {
++ unsigned int req_len, resp_len;
++
++ if (task->num_scatter) {
++ *n_elem = dma_map_sg(dev, task->scatter,
++ task->num_scatter, task->data_dir);
++ if (!*n_elem) {
++ rc = -ENOMEM;
++ goto prep_out;
++ }
++ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
++ *n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
++ 1, DMA_TO_DEVICE);
++ if (!*n_elem_req) {
++ rc = -ENOMEM;
++ goto prep_out;
++ }
++ req_len = sg_dma_len(&task->smp_task.smp_req);
++ if (req_len & 0x3) {
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++ *n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
++ 1, DMA_FROM_DEVICE);
++ if (!*n_elem_resp) {
++ rc = -ENOMEM;
++ goto err_out_dma_unmap;
++ }
++ resp_len = sg_dma_len(&task->smp_task.smp_resp);
++ if (resp_len & 0x3) {
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++ }
++ }
++
++ if (*n_elem > HISI_SAS_SGE_PAGE_CNT) {
++ dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
++ *n_elem);
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++ return 0;
++
++err_out_dma_unmap:
++ /* It would be better to call dma_unmap_sg() here, but it's messy */
++ hisi_sas_dma_unmap(hisi_hba, task, *n_elem,
++ *n_elem_req, *n_elem_resp);
++prep_out:
++ return rc;
++}
++
+ static int hisi_sas_task_prep(struct sas_task *task,
+ struct hisi_sas_dq **dq_pointer,
+ bool is_tmf, struct hisi_sas_tmf_task *tmf,
+@@ -339,49 +423,10 @@ static int hisi_sas_task_prep(struct sas
+ return -ECOMM;
+ }
+
+- if (!sas_protocol_ata(task->task_proto)) {
+- unsigned int req_len, resp_len;
+-
+- if (task->num_scatter) {
+- n_elem = dma_map_sg(dev, task->scatter,
+- task->num_scatter, task->data_dir);
+- if (!n_elem) {
+- rc = -ENOMEM;
+- goto prep_out;
+- }
+- } else if (task->task_proto & SAS_PROTOCOL_SMP) {
+- n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
+- 1, DMA_TO_DEVICE);
+- if (!n_elem_req) {
+- rc = -ENOMEM;
+- goto prep_out;
+- }
+- req_len = sg_dma_len(&task->smp_task.smp_req);
+- if (req_len & 0x3) {
+- rc = -EINVAL;
+- goto err_out_dma_unmap;
+- }
+- n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
+- 1, DMA_FROM_DEVICE);
+- if (!n_elem_resp) {
+- rc = -ENOMEM;
+- goto err_out_dma_unmap;
+- }
+- resp_len = sg_dma_len(&task->smp_task.smp_resp);
+- if (resp_len & 0x3) {
+- rc = -EINVAL;
+- goto err_out_dma_unmap;
+- }
+- }
+- } else
+- n_elem = task->num_scatter;
+-
+- if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
+- dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
+- n_elem);
+- rc = -EINVAL;
+- goto err_out_dma_unmap;
+- }
++ rc = hisi_sas_dma_map(hisi_hba, task, &n_elem,
++ &n_elem_req, &n_elem_resp);
++ if (rc < 0)
++ goto prep_out;
+
+ if (hisi_hba->hw->slot_index_alloc)
+ rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
+@@ -466,19 +511,8 @@ static int hisi_sas_task_prep(struct sas
+ err_out_tag:
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+ err_out_dma_unmap:
+- if (!sas_protocol_ata(task->task_proto)) {
+- if (task->num_scatter) {
+- dma_unmap_sg(dev, task->scatter, task->num_scatter,
+- task->data_dir);
+- } else if (task->task_proto & SAS_PROTOCOL_SMP) {
+- if (n_elem_req)
+- dma_unmap_sg(dev, &task->smp_task.smp_req,
+- 1, DMA_TO_DEVICE);
+- if (n_elem_resp)
+- dma_unmap_sg(dev, &task->smp_task.smp_resp,
+- 1, DMA_FROM_DEVICE);
+- }
+- }
++ hisi_sas_dma_unmap(hisi_hba, task, n_elem,
++ n_elem_req, n_elem_resp);
+ prep_out:
+ dev_err(dev, "task prep: failed[%d]!\n", rc);
+ return rc;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch b/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch
new file mode 100644
index 000000000..e025687be
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch
@@ -0,0 +1,82 @@
+From 8baf75dd36d8e311434162c6a2c74a45262dc0d4 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Thu, 6 Dec 2018 21:34:42 +0800
+Subject: [PATCH 16/31] scsi: hisi_sas: Make sg_tablesize consistent value
+Origin: https://git.kernel.org/linus/6db831f4ef764ca19d7300d56ab9455af3cb930d
+
+Sht->sg_tablesize is set in the driver, and it will be assigned to
+shost->sg_tablesize in SCSI mid-layer. So it is not necessary to assign
+shost->sg_table one more time in the driver.
+
+In addition to the change, change each scsi_host_template.sg_tablesize
+to HISI_SAS_SGE_PAGE_CNT instead of SG_ALL.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +--
+ 4 files changed, 3 insertions(+), 5 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2426,7 +2426,6 @@ int hisi_sas_probe(struct platform_devic
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+- shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = hisi_hba->hw->max_command_entries;
+ shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1814,7 +1814,7 @@ static struct scsi_host_template sht_v1_
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+ .this_id = -1,
+- .sg_tablesize = SG_ALL,
++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3576,7 +3576,7 @@ static struct scsi_host_template sht_v2_
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+ .this_id = -1,
+- .sg_tablesize = SG_ALL,
++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2229,7 +2229,7 @@ static struct scsi_host_template sht_v3_
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+ .this_id = -1,
+- .sg_tablesize = SG_ALL,
++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+@@ -2371,7 +2371,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+- shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+ shost->can_queue = hisi_hba->hw->max_command_entries -
+ HISI_SAS_RESERVED_IPTT_CNT;
+ shost->cmd_per_lun = hisi_hba->hw->max_command_entries -
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch
new file mode 100644
index 000000000..377ee58bd
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch
@@ -0,0 +1,43 @@
+From 341487a9b370af5c2566fb0c3fe5384c96bdbda7 Mon Sep 17 00:00:00 2001
+From: Huazhong Tan <tanhuazhong@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:52 +0800
+Subject: [PATCH 17/31] net: hns3: remove unnecessary configuration recapture
+ while resetting
+Origin: https://git.kernel.org/linus/b51c366df70da0100193d13975980f1990a2d47b
+
+When doing reset, it is unnecessary to get the hardware's default
+configuration again, otherwise, the user's configuration will be
+overwritten.
+
+Fixes: 4ed340ab8f49 ("net: hns3: Add reset process in hclge_main")
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -5814,19 +5814,6 @@ static int hclge_reset_ae_dev(struct hna
+ return ret;
+ }
+
+- ret = hclge_get_cap(hdev);
+- if (ret) {
+- dev_err(&pdev->dev, "get hw capability error, ret = %d.\n",
+- ret);
+- return ret;
+- }
+-
+- ret = hclge_configure(hdev);
+- if (ret) {
+- dev_err(&pdev->dev, "Configure dev error, ret = %d.\n", ret);
+- return ret;
+- }
+-
+ ret = hclge_map_tqp(hdev);
+ if (ret) {
+ dev_err(&pdev->dev, "Map tqp error, ret = %d.\n", ret);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch b/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch
new file mode 100644
index 000000000..e5141d719
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch
@@ -0,0 +1,29 @@
+From 7740fe91e657e23f25e750d9e34da059a6f607ac Mon Sep 17 00:00:00 2001
+From: Fuyun Liang <liangfuyun1@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:55 +0800
+Subject: [PATCH 18/31] net: hns3: remove 1000M/half support of phy
+Origin: https://git.kernel.org/linus/8362089d787724bb252f13f942921051943369c7
+
+Our phy does not support 1000M/half, this patch removes 1000M/half from
+PHY_SUPPORTED_FEATURES.
+
+Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+@@ -14,7 +14,7 @@
+ SUPPORTED_Asym_Pause | \
+ PHY_10BT_FEATURES | \
+ PHY_100BT_FEATURES | \
+- PHY_1000BT_FEATURES)
++ SUPPORTED_1000baseT_Full)
+
+ enum hclge_mdio_c22_op_seq {
+ HCLGE_MDIO_C22_WRITE = 1,
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch
new file mode 100644
index 000000000..6769afdcf
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch
@@ -0,0 +1,32 @@
+From 4f28c6b52ffb62eb5a0a5a85af4fa10658fecee5 Mon Sep 17 00:00:00 2001
+From: Peng Li <lipeng321@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:56 +0800
+Subject: [PATCH 19/31] net: hns3: synchronize speed and duplex from phy when
+ phy link up
+Origin: https://git.kernel.org/linus/0ad5ea5dbd6cb1e62bac547db5e61bab15af4f44
+
+Driver calls phy_connect_direct and registers hclge_mac_adjust_link
+to synchronize mac speed and duplex from phy. It is better to
+synchronize mac speed and duplex from phy when phy link up.
+
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+@@ -181,6 +181,10 @@ static void hclge_mac_adjust_link(struct
+ int duplex, speed;
+ int ret;
+
++ /* When phy link down, do nothing */
++ if (netdev->phydev->link == 0)
++ return;
++
+ speed = netdev->phydev->speed;
+ duplex = netdev->phydev->duplex;
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch b/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch
new file mode 100644
index 000000000..de4795be4
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch
@@ -0,0 +1,157 @@
+From caeef6247aa6f5250d14108b33cef5458ba6c58e Mon Sep 17 00:00:00 2001
+From: Yunsheng Lin <linyunsheng@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:57 +0800
+Subject: [PATCH 20/31] net: hns3: getting tx and dv buffer size through
+ firmware
+Origin: https://git.kernel.org/linus/368686be234daf365ef184a6ee1c4a6c18ede3b1
+
+This patch adds support of getting tx and dv buffer size through
+firmware, because different version of hardware requires different
+size of tx and dv buffer.
+
+This patch also add dv_buf_size to tc' private buffer size even if
+pfc is not enable for the tc.
+
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 5 ++-
+ .../hisilicon/hns3/hns3pf/hclge_main.c | 41 ++++++++++++++-----
+ .../hisilicon/hns3/hns3pf/hclge_main.h | 3 ++
+ 3 files changed, 38 insertions(+), 11 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+@@ -365,7 +365,9 @@ struct hclge_pf_res_cmd {
+ #define HCLGE_PF_VEC_NUM_M GENMASK(7, 0)
+ __le16 pf_intr_vector_number;
+ __le16 pf_own_fun_number;
+- __le32 rsv[3];
++ __le16 tx_buf_size;
++ __le16 dv_buf_size;
++ __le32 rsv[2];
+ };
+
+ #define HCLGE_CFG_OFFSET_S 0
+@@ -791,6 +793,7 @@ struct hclge_serdes_lb_cmd {
+ #define HCLGE_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */
+ #define HCLGE_DEFAULT_DV 0xA000 /* 40k byte */
+ #define HCLGE_DEFAULT_NON_DCB_DV 0x7800 /* 30K byte */
++#define HCLGE_NON_DCB_ADDITIONAL_BUF 0x200 /* 512 byte */
+
+ #define HCLGE_TYPE_CRQ 0
+ #define HCLGE_TYPE_CSQ 1
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -931,6 +931,18 @@ static int hclge_query_pf_resource(struc
+ hdev->num_tqps = __le16_to_cpu(req->tqp_num);
+ hdev->pkt_buf_size = __le16_to_cpu(req->buf_size) << HCLGE_BUF_UNIT_S;
+
++ if (req->tx_buf_size)
++ hdev->tx_buf_size =
++ __le16_to_cpu(req->tx_buf_size) << HCLGE_BUF_UNIT_S;
++ else
++ hdev->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
++
++ if (req->dv_buf_size)
++ hdev->dv_buf_size =
++ __le16_to_cpu(req->dv_buf_size) << HCLGE_BUF_UNIT_S;
++ else
++ hdev->dv_buf_size = HCLGE_DEFAULT_DV;
++
+ if (hnae3_dev_roce_supported(hdev)) {
+ hdev->roce_base_msix_offset =
+ hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee),
+@@ -1591,9 +1603,10 @@ static bool hclge_is_rx_buf_ok(struct h
+ pfc_enable_num = hclge_get_pfc_enalbe_num(hdev);
+
+ if (hnae3_dev_dcb_supported(hdev))
+- shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV;
++ shared_buf_min = 2 * hdev->mps + hdev->dv_buf_size;
+ else
+- shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_NON_DCB_DV;
++ shared_buf_min = hdev->mps + HCLGE_NON_DCB_ADDITIONAL_BUF
++ + hdev->dv_buf_size;
+
+ shared_buf_tc = pfc_enable_num * hdev->mps +
+ (tc_num - pfc_enable_num) * hdev->mps / 2 +
+@@ -1606,8 +1619,15 @@ static bool hclge_is_rx_buf_ok(struct h
+
+ shared_buf = rx_all - rx_priv;
+ buf_alloc->s_buf.buf_size = shared_buf;
+- buf_alloc->s_buf.self.high = shared_buf;
+- buf_alloc->s_buf.self.low = 2 * hdev->mps;
++ if (hnae3_dev_dcb_supported(hdev)) {
++ buf_alloc->s_buf.self.high = shared_buf - hdev->dv_buf_size;
++ buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high
++ - hdev->mps / 2;
++ } else {
++ buf_alloc->s_buf.self.high = hdev->mps +
++ HCLGE_NON_DCB_ADDITIONAL_BUF;
++ buf_alloc->s_buf.self.low = hdev->mps / 2;
++ }
+
+ for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+ if ((hdev->hw_tc_map & BIT(i)) &&
+@@ -1634,11 +1654,11 @@ static int hclge_tx_buffer_calc(struct h
+ for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+ struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i];
+
+- if (total_size < HCLGE_DEFAULT_TX_BUF)
++ if (total_size < hdev->tx_buf_size)
+ return -ENOMEM;
+
+ if (hdev->hw_tc_map & BIT(i))
+- priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
++ priv->tx_buf_size = hdev->tx_buf_size;
+ else
+ priv->tx_buf_size = 0;
+
+@@ -1684,11 +1704,12 @@ static int hclge_rx_buffer_calc(struct h
+ priv->wl.low = aligned_mps;
+ priv->wl.high = priv->wl.low + aligned_mps;
+ priv->buf_size = priv->wl.high +
+- HCLGE_DEFAULT_DV;
++ hdev->dv_buf_size;
+ } else {
+ priv->wl.low = 0;
+ priv->wl.high = 2 * aligned_mps;
+- priv->buf_size = priv->wl.high;
++ priv->buf_size = priv->wl.high +
++ hdev->dv_buf_size;
+ }
+ } else {
+ priv->enable = 0;
+@@ -1720,11 +1741,11 @@ static int hclge_rx_buffer_calc(struct h
+ if (hdev->tm_info.hw_pfc_map & BIT(i)) {
+ priv->wl.low = 128;
+ priv->wl.high = priv->wl.low + aligned_mps;
+- priv->buf_size = priv->wl.high + HCLGE_DEFAULT_DV;
++ priv->buf_size = priv->wl.high + hdev->dv_buf_size;
+ } else {
+ priv->wl.low = 0;
+ priv->wl.high = aligned_mps;
+- priv->buf_size = priv->wl.high;
++ priv->buf_size = priv->wl.high + hdev->dv_buf_size;
+ }
+ }
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+@@ -545,6 +545,9 @@ struct hclge_dev {
+ u32 flag;
+
+ u32 pkt_buf_size; /* Total pf buf size for tx/rx */
++ u32 tx_buf_size; /* Tx buffer size for each TC */
++ u32 dv_buf_size; /* Dv buffer size for each TC */
++
+ u32 mps; /* Max packet size */
+
+ enum hclge_mta_dmac_sel_type mta_mac_sel_type;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch b/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch
new file mode 100644
index 000000000..e5c403de9
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch
@@ -0,0 +1,144 @@
+From 234c314e892d40daa37e97e9057e04d3e3a0c285 Mon Sep 17 00:00:00 2001
+From: Yunsheng Lin <linyunsheng@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:58 +0800
+Subject: [PATCH 21/31] net: hns3: aligning buffer size in SSU to 256 bytes
+Origin: https://git.kernel.org/linus/b9a400ac295728b2d47445e09814e1880409b311
+
+The hardware expects the buffer size set to SSU is aligned to
+256 bytes, this patch aligns the buffer size to 256 byte using
+roundup or rounddown function.
+
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../hisilicon/hns3/hns3pf/hclge_main.c | 45 ++++++++++++-------
+ 1 file changed, 28 insertions(+), 17 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -31,6 +31,10 @@ static int hclge_set_mta_filter_mode(str
+ enum hclge_mta_dmac_sel_type mta_mac_sel,
+ bool enable);
+ static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu);
++
++#define HCLGE_BUF_SIZE_UNIT 256
++
++static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps);
+ static int hclge_init_vlan_config(struct hclge_dev *hdev);
+ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev);
+
+@@ -937,12 +941,16 @@ static int hclge_query_pf_resource(struc
+ else
+ hdev->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
+
++ hdev->tx_buf_size = roundup(hdev->tx_buf_size, HCLGE_BUF_SIZE_UNIT);
++
+ if (req->dv_buf_size)
+ hdev->dv_buf_size =
+ __le16_to_cpu(req->dv_buf_size) << HCLGE_BUF_UNIT_S;
+ else
+ hdev->dv_buf_size = HCLGE_DEFAULT_DV;
+
++ hdev->dv_buf_size = roundup(hdev->dv_buf_size, HCLGE_BUF_SIZE_UNIT);
++
+ if (hnae3_dev_roce_supported(hdev)) {
+ hdev->roce_base_msix_offset =
+ hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee),
+@@ -1595,48 +1603,50 @@ static bool hclge_is_rx_buf_ok(struct h
+ {
+ u32 shared_buf_min, shared_buf_tc, shared_std;
+ int tc_num, pfc_enable_num;
+- u32 shared_buf;
++ u32 shared_buf, aligned_mps;
+ u32 rx_priv;
+ int i;
+
+ tc_num = hclge_get_tc_num(hdev);
+ pfc_enable_num = hclge_get_pfc_enalbe_num(hdev);
++ aligned_mps = roundup(hdev->mps, HCLGE_BUF_SIZE_UNIT);
+
+ if (hnae3_dev_dcb_supported(hdev))
+- shared_buf_min = 2 * hdev->mps + hdev->dv_buf_size;
++ shared_buf_min = 2 * aligned_mps + hdev->dv_buf_size;
+ else
+- shared_buf_min = hdev->mps + HCLGE_NON_DCB_ADDITIONAL_BUF
++ shared_buf_min = aligned_mps + HCLGE_NON_DCB_ADDITIONAL_BUF
+ + hdev->dv_buf_size;
+
+- shared_buf_tc = pfc_enable_num * hdev->mps +
+- (tc_num - pfc_enable_num) * hdev->mps / 2 +
+- hdev->mps;
++ shared_buf_tc = pfc_enable_num * aligned_mps +
++ (tc_num - pfc_enable_num) * aligned_mps / 2 +
++ aligned_mps;
+ shared_std = max_t(u32, shared_buf_min, shared_buf_tc);
+
+ rx_priv = hclge_get_rx_priv_buff_alloced(buf_alloc);
+ if (rx_all <= rx_priv + shared_std)
+ return false;
+
+- shared_buf = rx_all - rx_priv;
++ shared_buf = rounddown(rx_all - rx_priv, HCLGE_BUF_SIZE_UNIT);
+ buf_alloc->s_buf.buf_size = shared_buf;
+ if (hnae3_dev_dcb_supported(hdev)) {
+ buf_alloc->s_buf.self.high = shared_buf - hdev->dv_buf_size;
+ buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high
+- - hdev->mps / 2;
++ - roundup(aligned_mps / 2, HCLGE_BUF_SIZE_UNIT);
+ } else {
+- buf_alloc->s_buf.self.high = hdev->mps +
++ buf_alloc->s_buf.self.high = aligned_mps +
+ HCLGE_NON_DCB_ADDITIONAL_BUF;
+- buf_alloc->s_buf.self.low = hdev->mps / 2;
++ buf_alloc->s_buf.self.low =
++ roundup(aligned_mps / 2, HCLGE_BUF_SIZE_UNIT);
+ }
+
+ for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+ if ((hdev->hw_tc_map & BIT(i)) &&
+ (hdev->tm_info.hw_pfc_map & BIT(i))) {
+- buf_alloc->s_buf.tc_thrd[i].low = hdev->mps;
+- buf_alloc->s_buf.tc_thrd[i].high = 2 * hdev->mps;
++ buf_alloc->s_buf.tc_thrd[i].low = aligned_mps;
++ buf_alloc->s_buf.tc_thrd[i].high = 2 * aligned_mps;
+ } else {
+ buf_alloc->s_buf.tc_thrd[i].low = 0;
+- buf_alloc->s_buf.tc_thrd[i].high = hdev->mps;
++ buf_alloc->s_buf.tc_thrd[i].high = aligned_mps;
+ }
+ }
+
+@@ -1676,7 +1686,6 @@ static int hclge_tx_buffer_calc(struct h
+ static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
+ struct hclge_pkt_buf_alloc *buf_alloc)
+ {
+-#define HCLGE_BUF_SIZE_UNIT 128
+ u32 rx_all = hdev->pkt_buf_size, aligned_mps;
+ int no_pfc_priv_num, pfc_priv_num;
+ struct hclge_priv_buf *priv;
+@@ -1702,9 +1711,11 @@ static int hclge_rx_buffer_calc(struct h
+ priv->enable = 1;
+ if (hdev->tm_info.hw_pfc_map & BIT(i)) {
+ priv->wl.low = aligned_mps;
+- priv->wl.high = priv->wl.low + aligned_mps;
++ priv->wl.high =
++ roundup(priv->wl.low + aligned_mps,
++ HCLGE_BUF_SIZE_UNIT);
+ priv->buf_size = priv->wl.high +
+- hdev->dv_buf_size;
++ hdev->dv_buf_size;
+ } else {
+ priv->wl.low = 0;
+ priv->wl.high = 2 * aligned_mps;
+@@ -1739,7 +1750,7 @@ static int hclge_rx_buffer_calc(struct h
+ priv->enable = 1;
+
+ if (hdev->tm_info.hw_pfc_map & BIT(i)) {
+- priv->wl.low = 128;
++ priv->wl.low = 256;
+ priv->wl.high = priv->wl.low + aligned_mps;
+ priv->buf_size = priv->wl.high + hdev->dv_buf_size;
+ } else {
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch b/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch
new file mode 100644
index 000000000..26cee78ea
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch
@@ -0,0 +1,45 @@
+From 4d887b7901d59b472df97bd8a2f8bdeb43be7ced Mon Sep 17 00:00:00 2001
+From: Yunsheng Lin <linyunsheng@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:59 +0800
+Subject: [PATCH 22/31] net: hns3: fix a SSU buffer checking bug
+Origin: https://git.kernel.org/linus/af854724e51e4047f534ac6d19b3ef9fb3c35c49
+
+When caculating the SSU buffer, it first allocate tx and
+rx private buffer, then the remaining buffer is for rx
+shared buffer. The remaining buffer size should be at
+least bigger than or equal to the shared_std, which is the
+minimum shared buffer size required by the driver, but
+currently if the remaining buffer size is equal to the
+shared_std, it returns failure, which causes SSU buffer
+allocation failure problem.
+
+This patch fixes this problem by rounding up shared_std before
+checking the the remaining buffer size bigger than or equal to
+the shared_std.
+
+Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -1620,10 +1620,11 @@ static bool hclge_is_rx_buf_ok(struct h
+ shared_buf_tc = pfc_enable_num * aligned_mps +
+ (tc_num - pfc_enable_num) * aligned_mps / 2 +
+ aligned_mps;
+- shared_std = max_t(u32, shared_buf_min, shared_buf_tc);
++ shared_std = roundup(max_t(u32, shared_buf_min, shared_buf_tc),
++ HCLGE_BUF_SIZE_UNIT);
+
+ rx_priv = hclge_get_rx_priv_buff_alloced(buf_alloc);
+- if (rx_all <= rx_priv + shared_std)
++ if (rx_all < rx_priv + shared_std)
+ return false;
+
+ shared_buf = rounddown(rx_all - rx_priv, HCLGE_BUF_SIZE_UNIT);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch b/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch
new file mode 100644
index 000000000..ad8ccd77f
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch
@@ -0,0 +1,30 @@
+From ea3eff7a2ef69730c8e48715fbf965cb9da8b0bc Mon Sep 17 00:00:00 2001
+From: Jian Shen <shenjian15@huawei.com>
+Date: Thu, 20 Dec 2018 11:51:59 +0800
+Subject: [PATCH 23/31] net: hns3: change default tc state to close
+Origin: https://git.kernel.org/linus/a298797532d9dc244abf349d7c2ed063732c6ba3
+
+In original codes, default tc value is set to the max tc. It's more
+reasonable to close tc by changing default tc value to 1. Users can
+enable it with lldp tool when they want to use tc.
+
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -1200,7 +1200,7 @@ static int hclge_configure(struct hclge_
+ hdev->pfc_max = hdev->tc_max;
+ }
+
+- hdev->tm_info.num_tc = hdev->tc_max;
++ hdev->tm_info.num_tc = 1;
+
+ /* Currently not support uncontiuous tc */
+ for (i = 0; i < hdev->tm_info.num_tc; i++)
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch b/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch
new file mode 100644
index 000000000..b3c3464ca
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch
@@ -0,0 +1,39 @@
+From 0f27af14383edac1efaf140d7cbe2d7dfdab7318 Mon Sep 17 00:00:00 2001
+From: Peng Li <lipeng321@huawei.com>
+Date: Thu, 20 Dec 2018 11:52:00 +0800
+Subject: [PATCH 24/31] net: hns3: fix a bug caused by udelay
+Origin: https://git.kernel.org/linus/1b7d7b0581173219b82abbd81c88cf8aa7d402c2
+
+udelay() in driver may always occupancy processor. If there is only
+one cpu in system, the VF driver may initialize fail when insmod
+PF and VF driver in the same system. This patch use msleep() to free
+cpu when VF wait PF message.
+
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+@@ -26,7 +26,7 @@ static int hclgevf_get_mbx_resp(struct h
+ u8 *resp_data, u16 resp_len)
+ {
+ #define HCLGEVF_MAX_TRY_TIMES 500
+-#define HCLGEVF_SLEEP_USCOEND 1000
++#define HCLGEVF_SLEEP_USECOND 1000
+ struct hclgevf_mbx_resp_status *mbx_resp;
+ u16 r_code0, r_code1;
+ int i = 0;
+@@ -40,7 +40,7 @@ static int hclgevf_get_mbx_resp(struct h
+ }
+
+ while ((!hdev->mbx_resp.received_resp) && (i < HCLGEVF_MAX_TRY_TIMES)) {
+- udelay(HCLGEVF_SLEEP_USCOEND);
++ usleep_range(HCLGEVF_SLEEP_USECOND, HCLGEVF_SLEEP_USECOND * 2);
+ i++;
+ }
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch b/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch
new file mode 100644
index 000000000..2dcf9f2ef
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch
@@ -0,0 +1,28 @@
+From 883a7a53d7f6a6494e3a0df73fb02f76ecc42bc1 Mon Sep 17 00:00:00 2001
+From: Peng Li <lipeng321@huawei.com>
+Date: Thu, 20 Dec 2018 11:52:06 +0800
+Subject: [PATCH 25/31] net: hns3: remove redundant variable initialization
+Origin: https://git.kernel.org/linus/1154bb26c879fea51c20aee167ddce4345caa255
+
+This patch removes the redundant variable initialization,
+as driver will devm_kzalloc to set value to hdev soon.
+
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -1360,7 +1360,7 @@ static int hclgevf_configure(struct hclg
+ static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev)
+ {
+ struct pci_dev *pdev = ae_dev->pdev;
+- struct hclgevf_dev *hdev = ae_dev->priv;
++ struct hclgevf_dev *hdev;
+
+ hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL);
+ if (!hdev)
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch b/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch
new file mode 100644
index 000000000..9eddea483
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch
@@ -0,0 +1,46 @@
+From a4e5945057386872cb9add271aea76ca2413f481 Mon Sep 17 00:00:00 2001
+From: Huazhong Tan <tanhuazhong@huawei.com>
+Date: Mon, 31 Dec 2018 10:58:29 +0800
+Subject: [PATCH 26/31] net: hns3: call hns3_nic_net_open() while doing
+ HNAE3_UP_CLIENT
+Origin: https://git.kernel.org/linus/e888402789b9db5de4fcda361331d66dbf0cd9fd
+
+For HNAE3_DOWN_CLIENT calling hns3_nic_net_stop(), HNAE3_UP_CLIENT
+should call hns3_nic_net_open(), since if the number of queue or
+the map of TC has is changed before HHAE3_UP_CLIENT is called,
+it will cause problem.
+
+Also the HNS3_NIC_STATE_RESETTING flag needs to be cleared before
+hns3_nic_net_open() called, and set it back while hns3_nic_net_open()
+failed.
+
+Fixes: bb6b94a896d4 ("net: hns3: Add reset interface implementation in client")
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -3439,11 +3439,15 @@ static int hns3_reset_notify_down_enet(s
+ static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
+ {
+ struct hnae3_knic_private_info *kinfo = &handle->kinfo;
++ struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev);
+ int ret = 0;
+
++ clear_bit(HNS3_NIC_STATE_RESETTING, &priv->state);
++
+ if (netif_running(kinfo->netdev)) {
+- ret = hns3_nic_net_up(kinfo->netdev);
++ ret = hns3_nic_net_open(kinfo->netdev);
+ if (ret) {
++ set_bit(HNS3_NIC_STATE_RESETTING, &priv->state);
+ netdev_err(kinfo->netdev,
+ "hns net up fail, ret=%d!\n", ret);
+ return ret;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch
new file mode 100644
index 000000000..48e2022bd
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch
@@ -0,0 +1,43 @@
+From 84193e72c505286e4681b3c566c64eea3e25f7fd Mon Sep 17 00:00:00 2001
+From: Lijun Ou <oulijun@huawei.com>
+Date: Wed, 12 Dec 2018 17:49:08 +0800
+Subject: [PATCH 29/31] RDMA/hns: Add constraint on the setting of local ACK
+ timeout
+Origin: https://git.kernel.org/linus/44754b95dd35ee07c462b5425ae9c4cde8c7e7c8
+
+According to IB protocol, local ACK timeout shall be a 5 bit
+value. Currently, hip08 could not support the possible max value 31. Fail
+the request in this case.
+
+Signed-off-by: Yixian Liu <liuyixian@huawei.com>
+Signed-off-by: Lijun Ou <oulijun@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+Index: linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+===================================================================
+--- linux.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -3398,10 +3398,16 @@ static int modify_qp_rtr_to_rts(struct i
+ V2_QPC_BYTE_212_LSN_S, 0);
+
+ if (attr_mask & IB_QP_TIMEOUT) {
+- roce_set_field(context->byte_28_at_fl, V2_QPC_BYTE_28_AT_M,
+- V2_QPC_BYTE_28_AT_S, attr->timeout);
+- roce_set_field(qpc_mask->byte_28_at_fl, V2_QPC_BYTE_28_AT_M,
+- V2_QPC_BYTE_28_AT_S, 0);
++ if (attr->timeout < 31) {
++ roce_set_field(context->byte_28_at_fl,
++ V2_QPC_BYTE_28_AT_M, V2_QPC_BYTE_28_AT_S,
++ attr->timeout);
++ roce_set_field(qpc_mask->byte_28_at_fl,
++ V2_QPC_BYTE_28_AT_M, V2_QPC_BYTE_28_AT_S,
++ 0);
++ } else {
++ dev_warn(dev, "Local ACK timeout shall be 0 to 30.\n");
++ }
+ }
+
+ roce_set_field(context->byte_172_sq_psn, V2_QPC_BYTE_172_SQ_CUR_PSN_M,
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch b/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch
new file mode 100644
index 000000000..612b481ff
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch
@@ -0,0 +1,28 @@
+From 454bc02382f8ed2eb3ebc7db4867ed419e3f0241 Mon Sep 17 00:00:00 2001
+From: Lijun Ou <oulijun@huawei.com>
+Date: Wed, 12 Dec 2018 17:49:09 +0800
+Subject: [PATCH 30/31] RDMA/hns: Modify the pbl ba page size for hip08
+Origin: https://git.kernel.org/linus/91fb4d83b88a7b544ce564c44167aad29d4154f0
+
+Modify the pbl ba page size to 16K for in order to support 4G MR size.
+
+Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
+Signed-off-by: Lijun Ou <oulijun@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+===================================================================
+--- linux.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -1235,7 +1235,7 @@ static int hns_roce_v2_profile(struct hn
+ caps->mpt_ba_pg_sz = 0;
+ caps->mpt_buf_pg_sz = 0;
+ caps->mpt_hop_num = HNS_ROCE_CONTEXT_HOP_NUM;
+- caps->pbl_ba_pg_sz = 0;
++ caps->pbl_ba_pg_sz = 2;
+ caps->pbl_buf_pg_sz = 0;
+ caps->pbl_hop_num = HNS_ROCE_PBL_HOP_NUM;
+ caps->mtt_ba_pg_sz = 0;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch b/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch
new file mode 100644
index 000000000..4f9e5f6be
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch
@@ -0,0 +1,63 @@
+From 07a7830061e657ce352e690dbe0a794ffb10d22e Mon Sep 17 00:00:00 2001
+From: Lijun Ou <oulijun@huawei.com>
+Date: Sat, 12 Jan 2019 18:36:29 +0800
+Subject: [PATCH 31/31] RDMA/hns: RDMA/hns: Assign rq head pointer when enable
+ rq record db
+Origin: https://git.kernel.org/linus/de77503a59403e7045c18c6bb0a10c245a99b648
+
+When flush cqe, it needs to get the pointer of rq and sq from db address
+space of user and update it into qp context by modified qp. if rq does not
+exist, it will not get the value from db address space of user.
+
+Signed-off-by: Lijun Ou <oulijun@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+---
+ drivers/infiniband/hw/hns/hns_roce_qp.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+Index: linux/drivers/infiniband/hw/hns/hns_roce_qp.c
+===================================================================
+--- linux.orig/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ linux/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -652,6 +652,10 @@ static int hns_roce_create_qp_common(str
+ dev_err(dev, "rq record doorbell map failed!\n");
+ goto err_sq_dbmap;
+ }
++
++ /* indicate kernel supports rq record db */
++ resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB;
++ hr_qp->rdb_en = 1;
+ }
+ } else {
+ if (init_attr->create_flags &
+@@ -760,16 +764,11 @@ static int hns_roce_create_qp_common(str
+ else
+ hr_qp->doorbell_qpn = cpu_to_le64(hr_qp->qpn);
+
+- if (ib_pd->uobject && (udata->outlen >= sizeof(resp)) &&
+- (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)) {
+-
+- /* indicate kernel supports rq record db */
+- resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB;
+- ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
++ if (udata) {
++ ret = ib_copy_to_udata(udata, &resp,
++ min(udata->outlen, sizeof(resp)));
+ if (ret)
+ goto err_qp;
+-
+- hr_qp->rdb_en = 1;
+ }
+ hr_qp->event = hns_roce_ib_qp_event;
+
+@@ -946,7 +945,9 @@ int hns_roce_modify_qp(struct ib_qp *ibq
+ (attr_mask & IB_QP_STATE) && new_state == IB_QPS_ERR) {
+ if (hr_qp->sdb_en == 1) {
+ hr_qp->sq.head = *(int *)(hr_qp->sdb.virt_addr);
+- hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr);
++
++ if (hr_qp->rdb_en == 1)
++ hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr);
+ } else {
+ dev_warn(dev, "flush cqe is not supported in userspace!\n");
+ goto out;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch b/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch
new file mode 100644
index 000000000..68374aee8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch
@@ -0,0 +1,70 @@
+From badecc38102204f5297ad6ce1d7c7875e514c6f7 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Mon, 18 Feb 2019 08:34:25 +0100
+Subject: [PATCH] scsi: hisi_sas: fix calls to dma_set_mask_and_coherent()
+Origin: https://git.kernel.org/linus/d9a00459effc30f6de2cdd887b64f15c6c54ae71
+
+The change to use dma_set_mask_and_coherent() incorrectly made a second
+call with the 32 bit DMA mask value when the call with the 64 bit DMA
+mask value succeeded.
+
+[mkp: fixed commit message]
+
+Fixes: e4db40e7a1a2 ("scsi: hisi_sas: use dma_set_mask_and_coherent")
+Cc: <stable@vger.kernel.org>
+Suggested-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 8 ++++++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 +++++---
+ 2 files changed, 11 insertions(+), 5 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2339,6 +2339,7 @@ static struct Scsi_Host *hisi_sas_shost_
+ struct Scsi_Host *shost;
+ struct hisi_hba *hisi_hba;
+ struct device *dev = &pdev->dev;
++ int error;
+
+ shost = scsi_host_alloc(hw->sht, sizeof(*hisi_hba));
+ if (!shost) {
+@@ -2359,8 +2360,11 @@ static struct Scsi_Host *hisi_sas_shost_
+ if (hisi_sas_get_fw_info(hisi_hba) < 0)
+ goto err_out;
+
+- if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) &&
+- dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
++ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
++ if (error)
++ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
++
++ if (error) {
+ dev_err(dev, "No usable DMA addressing method\n");
+ goto err_out;
+ }
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2328,10 +2328,12 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ if (rc)
+ goto err_out_disable_device;
+
+- if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
+- dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
++ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
++ if (rc)
++ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
++ if (rc) {
+ dev_err(dev, "No usable DMA addressing method\n");
+- rc = -EIO;
++ rc = -ENODEV;
+ goto err_out_regions;
+ }
+