Kernel
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- 46 participants
- 18686 discussions

[PATCH openEuler-5.10 01/46] Driver for Zhaoxin CPU core temperature monitoring
by Zheng Zengkai 19 Jul '22
by Zheng Zengkai 19 Jul '22
19 Jul '22
From: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52DS7
CVE: NA
--------------------------------------------
Add support for the temperature sensor inside CPU.
Supported are all known variants of the Zhaoxin processors.
v1: Fix some character encoding mistaken.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
---
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/via-cputemp.c | 1 -
drivers/hwmon/zhaoxin-cputemp.c | 292 ++++++++++++++++++++++++++++++++
4 files changed, 302 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwmon/zhaoxin-cputemp.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 45a1a5969d01..f2fe56e6f8bd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1899,6 +1899,15 @@ config SENSORS_VIA_CPUTEMP
sensor inside your CPU. Supported are all known variants of
the VIA C7 and Nano.
+config SENSORS_ZHAOXIN_CPUTEMP
+ tristate "Zhaoxin CPU temperature sensor"
+ depends on X86
+ select HWMON_VID
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Supported are all known variants of
+ the Zhaoxin processors.
+
config SENSORS_VIA686A
tristate "VIA686A"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index c22a5316bd91..95908c478b94 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -184,6 +184,7 @@ obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TMP513) += tmp513.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
+obj-$(CONFIG_SENSORS_ZHAOXIN_CPUTEMP) += zhaoxin-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index e5d18dac8ee7..0a5057dbe51a 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -273,7 +273,6 @@ static const struct x86_cpu_id __initconst cputemp_ids[] = {
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_A, NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_D, NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_NANO, NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
{}
};
MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
diff --git a/drivers/hwmon/zhaoxin-cputemp.c b/drivers/hwmon/zhaoxin-cputemp.c
new file mode 100644
index 000000000000..39e729590eba
--- /dev/null
+++ b/drivers/hwmon/zhaoxin-cputemp.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * zhaoxin-cputemp.c - Driver for Zhaoxin CPU core temperature monitoring
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define DRVNAME "zhaoxin_cputemp"
+
+enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
+
+/* Functions declaration */
+
+struct zhaoxin_cputemp_data {
+ struct device *hwmon_dev;
+ const char *name;
+ u8 vrm;
+ u32 id;
+ u32 msr_temp;
+ u32 msr_vid;
+};
+
+/* Sysfs stuff */
+
+static ssize_t name_show(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ int ret;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+
+ if (attr->index == SHOW_NAME)
+ ret = sprintf(buf, "%s\n", data->name);
+ else /* show label */
+ ret = sprintf(buf, "Core %d\n", data->id);
+ return ret;
+}
+
+static ssize_t temp_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
+}
+
+static ssize_t cpu0_vid_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, SHOW_TEMP);
+static SENSOR_DEVICE_ATTR_RO(temp1_label, name, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR_RO(name, name, SHOW_NAME);
+
+static struct attribute *zhaoxin_cputemp_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group zhaoxin_cputemp_group = {
+ .attrs = zhaoxin_cputemp_attributes,
+};
+
+/* Optional attributes */
+static DEVICE_ATTR_RO(cpu0_vid);
+
+static int zhaoxin_cputemp_probe(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data;
+ int err;
+ u32 eax, edx;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(struct zhaoxin_cputemp_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->id = pdev->id;
+ data->name = "zhaoxin_cputemp";
+ data->msr_temp = 0x1423;
+
+ /* test if we can access the TEMPERATURE MSR */
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving up\n");
+ return err;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ err = sysfs_create_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ if (err)
+ return err;
+
+ if (data->msr_vid)
+ data->vrm = vid_which_vrm();
+
+ if (data->vrm) {
+ err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_remove;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return err;
+}
+
+static int zhaoxin_cputemp_remove(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return 0;
+}
+
+static struct platform_driver zhaoxin_cputemp_driver = {
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = zhaoxin_cputemp_probe,
+ .remove = zhaoxin_cputemp_remove,
+};
+
+struct pdev_entry {
+ struct list_head list;
+ struct platform_device *pdev;
+ unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int zhaoxin_cputemp_online(unsigned int cpu)
+{
+ int err;
+ struct platform_device *pdev;
+ struct pdev_entry *pdev_entry;
+
+ pdev = platform_device_alloc(DRVNAME, cpu);
+ if (!pdev) {
+ err = -ENOMEM;
+ pr_err("Device allocation failed\n");
+ goto exit;
+ }
+
+ pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+ if (!pdev_entry) {
+ err = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ pr_err("Device addition failed (%d)\n", err);
+ goto exit_device_free;
+ }
+
+ pdev_entry->pdev = pdev;
+ pdev_entry->cpu = cpu;
+ mutex_lock(&pdev_list_mutex);
+ list_add_tail(&pdev_entry->list, &pdev_list);
+ mutex_unlock(&pdev_list_mutex);
+
+ return 0;
+
+exit_device_free:
+ kfree(pdev_entry);
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+static int zhaoxin_cputemp_down_prep(unsigned int cpu)
+{
+ struct pdev_entry *p;
+
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry(p, &pdev_list, list) {
+ if (p->cpu == cpu) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
+ kfree(p);
+ return 0;
+ }
+ }
+ mutex_unlock(&pdev_list_mutex);
+ return 0;
+}
+
+static const struct x86_cpu_id __initconst cputemp_ids[] = {
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(ZHAOXIN, 7, X86_MODEL_ANY, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
+
+static enum cpuhp_state zhaoxin_temp_online;
+
+static int __init zhaoxin_cputemp_init(void)
+{
+ int err;
+
+ if (!x86_match_cpu(cputemp_ids))
+ return -ENODEV;
+
+ err = platform_driver_register(&zhaoxin_cputemp_driver);
+ if (err)
+ goto exit;
+
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/zhaoxin:online",
+ zhaoxin_cputemp_online, zhaoxin_cputemp_down_prep);
+ if (err < 0)
+ goto exit_driver_unreg;
+ zhaoxin_temp_online = err;
+
+#ifndef CONFIG_HOTPLUG_CPU
+ if (list_empty(&pdev_list)) {
+ err = -ENODEV;
+ goto exit_hp_unreg;
+ }
+#endif
+ return 0;
+
+#ifndef CONFIG_HOTPLUG_CPU
+exit_hp_unreg:
+ cpuhp_remove_state_nocalls(zhaoxin_temp_online);
+#endif
+exit_driver_unreg:
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+exit:
+ return err;
+}
+
+static void __exit zhaoxin_cputemp_exit(void)
+{
+ cpuhp_remove_state(zhaoxin_temp_online);
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+}
+
+MODULE_DESCRIPTION("Zhaoxin CPU temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(zhaoxin_cputemp_init)
+module_exit(zhaoxin_cputemp_exit)
--
2.20.1
1
45

[PATCH openEuler-5.10-LTS 01/10] Driver for Zhaoxin CPU core temperature monitoring
by Zheng Zengkai 19 Jul '22
by Zheng Zengkai 19 Jul '22
19 Jul '22
From: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52DS7
CVE: NA
--------------------------------------------
Add support for the temperature sensor inside CPU.
Supported are all known variants of the Zhaoxin processors.
v1: Fix some character encoding mistaken.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
---
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/via-cputemp.c | 1 -
drivers/hwmon/zhaoxin-cputemp.c | 292 ++++++++++++++++++++++++++++++++
4 files changed, 302 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwmon/zhaoxin-cputemp.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 45a1a5969d01..f2fe56e6f8bd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1899,6 +1899,15 @@ config SENSORS_VIA_CPUTEMP
sensor inside your CPU. Supported are all known variants of
the VIA C7 and Nano.
+config SENSORS_ZHAOXIN_CPUTEMP
+ tristate "Zhaoxin CPU temperature sensor"
+ depends on X86
+ select HWMON_VID
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Supported are all known variants of
+ the Zhaoxin processors.
+
config SENSORS_VIA686A
tristate "VIA686A"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index c22a5316bd91..95908c478b94 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -184,6 +184,7 @@ obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TMP513) += tmp513.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
+obj-$(CONFIG_SENSORS_ZHAOXIN_CPUTEMP) += zhaoxin-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index e5d18dac8ee7..0a5057dbe51a 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -273,7 +273,6 @@ static const struct x86_cpu_id __initconst cputemp_ids[] = {
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_A, NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_D, NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_NANO, NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
{}
};
MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
diff --git a/drivers/hwmon/zhaoxin-cputemp.c b/drivers/hwmon/zhaoxin-cputemp.c
new file mode 100644
index 000000000000..39e729590eba
--- /dev/null
+++ b/drivers/hwmon/zhaoxin-cputemp.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * zhaoxin-cputemp.c - Driver for Zhaoxin CPU core temperature monitoring
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define DRVNAME "zhaoxin_cputemp"
+
+enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
+
+/* Functions declaration */
+
+struct zhaoxin_cputemp_data {
+ struct device *hwmon_dev;
+ const char *name;
+ u8 vrm;
+ u32 id;
+ u32 msr_temp;
+ u32 msr_vid;
+};
+
+/* Sysfs stuff */
+
+static ssize_t name_show(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ int ret;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+
+ if (attr->index == SHOW_NAME)
+ ret = sprintf(buf, "%s\n", data->name);
+ else /* show label */
+ ret = sprintf(buf, "Core %d\n", data->id);
+ return ret;
+}
+
+static ssize_t temp_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
+}
+
+static ssize_t cpu0_vid_show(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, SHOW_TEMP);
+static SENSOR_DEVICE_ATTR_RO(temp1_label, name, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR_RO(name, name, SHOW_NAME);
+
+static struct attribute *zhaoxin_cputemp_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group zhaoxin_cputemp_group = {
+ .attrs = zhaoxin_cputemp_attributes,
+};
+
+/* Optional attributes */
+static DEVICE_ATTR_RO(cpu0_vid);
+
+static int zhaoxin_cputemp_probe(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data;
+ int err;
+ u32 eax, edx;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(struct zhaoxin_cputemp_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->id = pdev->id;
+ data->name = "zhaoxin_cputemp";
+ data->msr_temp = 0x1423;
+
+ /* test if we can access the TEMPERATURE MSR */
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving up\n");
+ return err;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ err = sysfs_create_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ if (err)
+ return err;
+
+ if (data->msr_vid)
+ data->vrm = vid_which_vrm();
+
+ if (data->vrm) {
+ err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_remove;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return err;
+}
+
+static int zhaoxin_cputemp_remove(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return 0;
+}
+
+static struct platform_driver zhaoxin_cputemp_driver = {
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = zhaoxin_cputemp_probe,
+ .remove = zhaoxin_cputemp_remove,
+};
+
+struct pdev_entry {
+ struct list_head list;
+ struct platform_device *pdev;
+ unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int zhaoxin_cputemp_online(unsigned int cpu)
+{
+ int err;
+ struct platform_device *pdev;
+ struct pdev_entry *pdev_entry;
+
+ pdev = platform_device_alloc(DRVNAME, cpu);
+ if (!pdev) {
+ err = -ENOMEM;
+ pr_err("Device allocation failed\n");
+ goto exit;
+ }
+
+ pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+ if (!pdev_entry) {
+ err = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ pr_err("Device addition failed (%d)\n", err);
+ goto exit_device_free;
+ }
+
+ pdev_entry->pdev = pdev;
+ pdev_entry->cpu = cpu;
+ mutex_lock(&pdev_list_mutex);
+ list_add_tail(&pdev_entry->list, &pdev_list);
+ mutex_unlock(&pdev_list_mutex);
+
+ return 0;
+
+exit_device_free:
+ kfree(pdev_entry);
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+static int zhaoxin_cputemp_down_prep(unsigned int cpu)
+{
+ struct pdev_entry *p;
+
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry(p, &pdev_list, list) {
+ if (p->cpu == cpu) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
+ kfree(p);
+ return 0;
+ }
+ }
+ mutex_unlock(&pdev_list_mutex);
+ return 0;
+}
+
+static const struct x86_cpu_id __initconst cputemp_ids[] = {
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(ZHAOXIN, 7, X86_MODEL_ANY, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
+
+static enum cpuhp_state zhaoxin_temp_online;
+
+static int __init zhaoxin_cputemp_init(void)
+{
+ int err;
+
+ if (!x86_match_cpu(cputemp_ids))
+ return -ENODEV;
+
+ err = platform_driver_register(&zhaoxin_cputemp_driver);
+ if (err)
+ goto exit;
+
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/zhaoxin:online",
+ zhaoxin_cputemp_online, zhaoxin_cputemp_down_prep);
+ if (err < 0)
+ goto exit_driver_unreg;
+ zhaoxin_temp_online = err;
+
+#ifndef CONFIG_HOTPLUG_CPU
+ if (list_empty(&pdev_list)) {
+ err = -ENODEV;
+ goto exit_hp_unreg;
+ }
+#endif
+ return 0;
+
+#ifndef CONFIG_HOTPLUG_CPU
+exit_hp_unreg:
+ cpuhp_remove_state_nocalls(zhaoxin_temp_online);
+#endif
+exit_driver_unreg:
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+exit:
+ return err;
+}
+
+static void __exit zhaoxin_cputemp_exit(void)
+{
+ cpuhp_remove_state(zhaoxin_temp_online);
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+}
+
+MODULE_DESCRIPTION("Zhaoxin CPU temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(zhaoxin_cputemp_init)
+module_exit(zhaoxin_cputemp_exit)
--
2.20.1
1
9
Backport 5.10.112 LTS patches from upstream.
git cherry-pick v5.10.111..v5.10.112~1 -s
Complicts:
Already merged(10):
80a4df14643f7 hamradio: defer 6pack kfree after unregister_netdev
cfa98ffc42f16 hamradio: remove needs_free_netdev to avoid UAF
5ea00fc60676 ax25: add refcount in ax25_dev to avoid UAF bugs
5ddae8d06441 ax25: fix reference count leaks of ax25_dev
57cc15f5fd55 ax25: fix UAF bugs of net_device caused by rebinding operation
b20a5ab0f5fb ax25: Fix refcount leaks caused by ax25_cb_del()
a4942c6fea87 ax25: fix UAF bug in ax25_send_control()
145ea8d213e8 ax25: fix NPD bug in ax25_disconnect
f934fa478dd1 ax25: Fix NULL pointer dereferences in ax25 timers
5c62d3bf1410 ax25: Fix UAF bugs in ax25 timers
Rejected(1, KABI changed and hard to fix):
845f44ce3d9f net/sched: flower: fix parsing of ethertype following VLAN header
KABI fixes(2):
scsi: iscsi: fix kabi broken in struct iscsi_cls_conn
scsi: iscsi: fix kabi broken in struct iscsi_transport
Total patches: 104 - 10 - 1 + 2 = 95
Adrian Hunter (1):
perf tools: Fix misleading add event PMU debug message
Ajish Koshy (2):
scsi: pm80xx: Mask and unmask upper interrupt vectors 32-63
scsi: pm80xx: Enable upper inbound, outbound queues
Alexey Galakhov (1):
scsi: mvsas: Add PCI ID of RocketRaid 2640
Andy Chiu (1):
net: axienet: setup mdio unconditionally
Anna-Maria Behnsen (1):
timers: Fix warning condition in __run_timers()
Athira Rajeev (1):
testing/selftests/mqueue: Fix mq_perf_tests to free the allocated cpu
set
Aurabindo Pillai (1):
drm/amd: Add USBC connector ID
Benedikt Spranger (1):
net/sched: taprio: Check if socket flags are valid
Borislav Petkov (1):
perf/imx_ddr: Fix undefined behavior due to shift overflowing the
constant
Calvin Johnson (1):
net: mdio: Alphabetically sort header inclusion
Chandrakanth patil (1):
scsi: megaraid_sas: Target with invalid LUN ID is deleted during scan
Chao Gao (1):
dma-direct: avoid redundant memory sync for swiotlb
Charlene Liu (1):
drm/amd/display: fix audio format not updated after edid updated
Chiawen Huang (1):
drm/amd/display: FEC check in timing validation
Christian Lamparter (1):
ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs
Chuck Lever (1):
SUNRPC: Fix the svc_deferred_event trace class
Cristian Marussi (1):
firmware: arm_scmi: Fix sorting of retrieved clock rates
Darrick J. Wong (1):
btrfs: fix fallocate to use file_modified to update permissions
consistently
Dinh Nguyen (1):
net: ethernet: stmmac: fix altr_tse_pcs function when using a
fixed-link
Duoming Zhou (1):
drivers: net: slip: fix NPD bug in sl_tx_timeout()
Fabio M. De Francesco (1):
ALSA: pcm: Test for "silence" field in struct "pcm_format_data"
Felix Kuehling (1):
drm/amdkfd: Use drm_priv to pass VM from KFD to amdgpu
Guillaume Nault (1):
veth: Ensure eth header is in skb's linear part
Harshit Mogalapalli (1):
cifs: potential buffer overflow in handling symlinks
James Smart (1):
scsi: lpfc: Fix queue failures when recovering from PCI parity error
Jason A. Donenfeld (1):
gcc-plugins: latent_entropy: use /dev/urandom
Jeremy Linton (1):
net: bcmgenet: Revert "Use stronger register read/writes to assure
ordering"
Jia-Ju Bai (1):
btrfs: fix root ref counts in error handling in btrfs_get_root_ref
Joey Gouly (1):
arm64: alternatives: mark patch_alternative() as `noinstr`
Johan Hovold (1):
memory: renesas-rpc-if: fix platform-device leak in error path
Johannes Berg (1):
nl80211: correctly check NL80211_ATTR_REG_ALPHA2 size
Jonathan Bakker (1):
regulator: wm8994: Add an off-on delay for WM8994 variant
Josef Bacik (1):
btrfs: do not warn for free space inode in cow_file_range
Juergen Gross (1):
mm, page_alloc: fix build_zonerefs_node()
Karsten Graul (1):
net/smc: Fix NULL pointer dereference in smc_pnet_find_ib()
Khazhismel Kumykov (1):
dm mpath: only use ktime_get_ns() in historical selector
Kyle Copperfield (1):
media: rockchip/rga: do proper error checking in probe
Leo (Hanghong) Ma (1):
drm/amd/display: Update VTEM Infopacket definition
Leo Ruan (1):
gpu: ipu-v3: Fix dev_dbg frequency output
Li Nan (1):
scsi: iscsi: fix kabi broken in struct iscsi_transport
Lin Ma (1):
nfc: nci: add flush_workqueue to prevent uaf
Linus Torvalds (1):
gpiolib: acpi: use correct format characters
Marcelo Ricardo Leitner (1):
net/sched: fix initialization order when updating chain 0 head
Marcin Kozlowski (1):
net: usb: aqc111: Fix out-of-bounds accesses in RX fixup
Mario Limonciello (2):
cpuidle: PSCI: Move the `has_lpi` check to the beginning of the
function
ACPI: processor idle: Check for architectural support for LPI
Martin Leung (1):
drm/amd/display: Revert FEC check in validation
Martin Povišer (1):
i2c: pasemi: Wait for write xfers to finish
Melissa Wen (1):
drm/amd/display: don't ignore alpha property on pre-multiplied mode
Miaoqian Lin (1):
memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe
Michael Kelley (1):
Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer
Michael Walle (1):
net: dsa: felix: suppress -EPROBE_DEFER errors
Mike Christie (10):
scsi: iscsi: Stop queueing during ep_disconnect
scsi: iscsi: Force immediate failure during shutdown
scsi: iscsi: Use system_unbound_wq for destroy_work
scsi: iscsi: Rel ref after iscsi_lookup_endpoint()
scsi: iscsi: Fix in-kernel conn failure handling
scsi: iscsi: Move iscsi_ep_disconnect()
scsi: iscsi: Fix offload conn cleanup when iscsid restarts
scsi: iscsi: Fix conn cleanup and stop race during iscsid restart
scsi: iscsi: Fix endpoint reuse regression
scsi: iscsi: Fix unbound endpoint error handling
Mikulas Patocka (1):
dm integrity: fix memory corruption when tag_size is less than digest
size
Minchan Kim (1):
mm: fix unexpected zeroed page mapping with zram swap
Nadav Amit (1):
smp: Fix offline cpu check in flush_smp_call_function_queue()
Naohiro Aota (1):
btrfs: mark resumed async balance as writing
Nathan Chancellor (2):
btrfs: remove unused variable in
btrfs_{start,write}_dirty_block_groups()
ARM: davinci: da850-evm: Avoid NULL pointer dereference
Nicolas Dichtel (1):
ipv6: fix panic when forwarding a pkt with no in6 dev
Patrick Wang (1):
mm: kmemleak: take a full lowmem check in kmemleak_*_phys()
Paul Gortmaker (1):
tick/nohz: Use WARN_ON_ONCE() to prevent console saturation
Petr Malat (1):
sctp: Initialize daddr on peeled off socket
QintaoShen (1):
drm/amdkfd: Check for potential null return of kmalloc_array()
Rameshkumar Sundaram (1):
cfg80211: hold bss_lock while updating nontrans_list
Randy Dunlap (1):
net: micrel: fix KS8851_MLL Kconfig
Rei Yamamoto (1):
genirq/affinity: Consider that CPUs on nodes can be unbalanced
Rob Clark (2):
drm/msm: Add missing put_task_struct() in debugfs path
drm/msm: Fix range size vs end confusion
Roman Li (1):
drm/amd/display: Fix allocate_mst_payload assert on resume
Sean Christopherson (1):
KVM: x86/mmu: Resolve nx_huge_pages when kvm.ko is loaded
Stephen Boyd (1):
drm/msm/dsi: Use connector directly in
msm_dsi_manager_connector_init()
Steve Capper (1):
tlb: hugetlb: Add more sizes to tlb_remove_huge_tlb_entry
Tao Jin (1):
ALSA: hda/realtek: add quirk for Lenovo Thinkpad X12 speakers
Tianci Yin (1):
drm/amdgpu/vcn: improve vcn dpg stop procedure
Tim Crawford (1):
ALSA: hda/realtek: Add quirk for Clevo PD50PNT
Toke Høiland-Jørgensen (2):
ath9k: Properly clear TX status area before reporting to mac80211
ath9k: Fix usage of driver-private space in tx_info
Tomasz Moń (1):
drm/amdgpu: Enable gfxoff quirk on MacBook Pro
Tushar Patel (1):
drm/amdkfd: Fix Incorrect VMIDs passed to HWS
Tyrel Datwyler (1):
scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024
Vadim Pasternak (1):
mlxsw: i2c: Fix initialization error flow
Xiaoguang Wang (1):
scsi: target: tcmu: Fix possible page UAF
Xiaomeng Tong (1):
myri10ge: fix an incorrect free for skb in myri10ge_sw_tso
Zhang Wensheng (1):
scsi: iscsi: fix kabi broken in struct iscsi_cls_conn
arch/arm/mach-davinci/board-da850-evm.c | 4 +-
arch/arm64/kernel/alternative.c | 6 +-
arch/arm64/kernel/cpuidle.c | 6 +-
arch/x86/include/asm/kvm_host.h | 5 +-
arch/x86/kvm/mmu/mmu.c | 20 +-
arch/x86/kvm/x86.c | 20 +-
drivers/acpi/processor_idle.c | 15 +-
drivers/ata/libata-core.c | 3 +
drivers/firmware/arm_scmi/clock.c | 3 +-
drivers/gpio/gpiolib-acpi.c | 4 +-
drivers/gpu/drm/amd/amdgpu/ObjectID.h | 1 +
.../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 10 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 +
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 3 +
drivers/gpu/drm/amd/amdkfd/kfd_device.c | 11 +-
drivers/gpu/drm/amd/amdkfd/kfd_events.c | 2 +
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-
.../gpu/drm/amd/display/dc/core/dc_resource.c | 4 +-
.../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 14 +-
.../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 14 +-
.../display/modules/info_packet/info_packet.c | 5 +-
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +-
drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +-
drivers/gpu/drm/msm/msm_gem.c | 1 +
drivers/gpu/ipu-v3/ipu-di.c | 5 +-
drivers/hv/ring_buffer.c | 11 +-
drivers/i2c/busses/i2c-pasemi.c | 6 +
drivers/infiniband/ulp/iser/iscsi_iser.c | 9 +-
drivers/md/dm-historical-service-time.c | 10 +-
drivers/md/dm-integrity.c | 7 +-
drivers/media/platform/rockchip/rga/rga.c | 2 +-
drivers/memory/atmel-ebi.c | 23 +-
drivers/memory/renesas-rpc-if.c | 10 +-
drivers/net/dsa/ocelot/felix_vsc9959.c | 2 +-
.../net/ethernet/broadcom/genet/bcmgenet.c | 4 +-
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 1 +
drivers/net/ethernet/micrel/Kconfig | 1 +
.../net/ethernet/myricom/myri10ge/myri10ge.c | 6 +-
.../ethernet/stmicro/stmmac/altr_tse_pcs.c | 8 -
.../ethernet/stmicro/stmmac/altr_tse_pcs.h | 4 +
.../ethernet/stmicro/stmmac/dwmac-socfpga.c | 13 +-
.../net/ethernet/xilinx/xilinx_axienet_main.c | 13 +-
drivers/net/mdio/mdio-bcm-unimac.c | 16 +-
drivers/net/mdio/mdio-bitbang.c | 4 +-
drivers/net/mdio/mdio-cavium.c | 2 +-
drivers/net/mdio/mdio-gpio.c | 10 +-
drivers/net/mdio/mdio-ipq4019.c | 4 +-
drivers/net/mdio/mdio-ipq8064.c | 4 +-
drivers/net/mdio/mdio-mscc-miim.c | 8 +-
drivers/net/mdio/mdio-mux-bcm-iproc.c | 10 +-
drivers/net/mdio/mdio-mux-gpio.c | 8 +-
drivers/net/mdio/mdio-mux-mmioreg.c | 6 +-
drivers/net/mdio/mdio-mux-multiplexer.c | 2 +-
drivers/net/mdio/mdio-mux.c | 6 +-
drivers/net/mdio/mdio-octeon.c | 8 +-
drivers/net/mdio/mdio-thunder.c | 10 +-
drivers/net/mdio/mdio-xgene.c | 6 +-
drivers/net/mdio/of_mdio.c | 10 +-
drivers/net/slip/slip.c | 2 +-
drivers/net/usb/aqc111.c | 9 +-
drivers/net/veth.c | 2 +-
drivers/net/wireless/ath/ath9k/main.c | 2 +-
drivers/net/wireless/ath/ath9k/xmit.c | 33 +-
drivers/perf/fsl_imx8_ddr_perf.c | 2 +-
drivers/regulator/wm8994-regulator.c | 42 +-
drivers/scsi/be2iscsi/be_iscsi.c | 19 +-
drivers/scsi/be2iscsi/be_main.c | 8 +-
drivers/scsi/bnx2i/bnx2i_iscsi.c | 31 +-
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 8 +-
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 8 +-
drivers/scsi/cxgbi/libcxgbi.c | 12 +-
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 2 +-
drivers/scsi/libiscsi.c | 70 ++-
drivers/scsi/lpfc/lpfc_init.c | 2 +
drivers/scsi/megaraid/megaraid_sas.h | 3 +
drivers/scsi/megaraid/megaraid_sas_base.c | 7 +
drivers/scsi/mvsas/mv_init.c | 1 +
drivers/scsi/pm8001/pm80xx_hwi.c | 33 +-
drivers/scsi/qedi/qedi_iscsi.c | 32 +-
drivers/scsi/qla4xxx/ql4_os.c | 8 +-
drivers/scsi/scsi_transport_iscsi.c | 587 +++++++++++-------
drivers/target/target_core_user.c | 3 +-
fs/btrfs/block-group.c | 4 -
fs/btrfs/disk-io.c | 5 +-
fs/btrfs/file.c | 13 +-
fs/btrfs/inode.c | 1 -
fs/btrfs/volumes.c | 2 +
fs/cifs/link.c | 3 +
include/asm-generic/tlb.h | 10 +-
include/scsi/iscsi_if.h | 1 +
include/scsi/libiscsi.h | 1 +
include/scsi/scsi_transport_iscsi.h | 39 +-
include/trace/events/sunrpc.h | 7 +-
kernel/dma/direct.h | 3 +-
kernel/irq/affinity.c | 5 +-
kernel/smp.c | 2 +-
kernel/time/tick-sched.c | 2 +-
kernel/time/timer.c | 11 +-
mm/kmemleak.c | 8 +-
mm/page_alloc.c | 2 +-
mm/page_io.c | 54 --
net/ipv6/ip6_output.c | 2 +-
net/nfc/nci/core.c | 4 +
net/sched/cls_api.c | 2 +-
net/sched/sch_taprio.c | 3 +-
net/sctp/socket.c | 2 +-
net/smc/smc_pnet.c | 5 +-
net/wireless/nl80211.c | 3 +-
net/wireless/scan.c | 2 +
scripts/gcc-plugins/latent_entropy_plugin.c | 44 +-
sound/core/pcm_misc.c | 2 +-
sound/pci/hda/patch_realtek.c | 2 +
tools/perf/util/parse-events.c | 5 +-
.../testing/selftests/mqueue/mq_perf_tests.c | 25 +-
115 files changed, 1046 insertions(+), 565 deletions(-)
--
2.20.1
1
95

19 Jul '22
From: Wang Wensheng <wangwensheng4(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5DS9S
CVE: NA
--------------------------------------------------
This is not used for THP but the user page table is just like THP. The
user alloc hugepages via a special driver and its vma is not marked with
VM_HUGETLB. This commit allow to share those vma to kernel.
Signed-off-by: Wang Wensheng <wangwensheng4(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/linux/share_pool.h | 1 +
mm/share_pool.c | 44 +++++++++++++++++++++++++++++++++-----
2 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h
index 6f294911c6af..d95084b8f624 100644
--- a/include/linux/share_pool.h
+++ b/include/linux/share_pool.h
@@ -178,6 +178,7 @@ struct sp_walk_data {
unsigned long uva_aligned;
unsigned long page_size;
bool is_hugepage;
+ bool is_page_type_set;
pmd_t *pmd;
};
diff --git a/mm/share_pool.c b/mm/share_pool.c
index 76088952d0a5..60ad48e238c4 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -2994,9 +2994,40 @@ EXPORT_SYMBOL_GPL(mg_sp_make_share_k2u);
static int sp_pmd_entry(pmd_t *pmd, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
+ struct page *page;
struct sp_walk_data *sp_walk_data = walk->private;
+ /*
+ * There exist a scene in DVPP where the pagetable is huge page but its
+ * vma doesn't record it, something like THP.
+ * So we cannot make out whether it is a hugepage map until we access the
+ * pmd here. If mixed size of pages appear, just return an error.
+ */
+ if (pmd_huge(*pmd)) {
+ if (!sp_walk_data->is_page_type_set) {
+ sp_walk_data->is_page_type_set = true;
+ sp_walk_data->is_hugepage = true;
+ } else if (!sp_walk_data->is_hugepage)
+ return -EFAULT;
+
+ /* To skip pte level walk */
+ walk->action = ACTION_CONTINUE;
+
+ page = pmd_page(*pmd);
+ get_page(page);
+ sp_walk_data->pages[sp_walk_data->page_count++] = page;
+
+ return 0;
+ }
+
+ if (!sp_walk_data->is_page_type_set) {
+ sp_walk_data->is_page_type_set = true;
+ sp_walk_data->is_hugepage = false;
+ } else if (sp_walk_data->is_hugepage)
+ return -EFAULT;
+
sp_walk_data->pmd = pmd;
+
return 0;
}
@@ -3140,6 +3171,8 @@ static int __sp_walk_page_range(unsigned long uva, unsigned long size,
sp_walk.pmd_entry = sp_pmd_entry;
}
+ sp_walk_data->is_page_type_set = false;
+ sp_walk_data->page_count = 0;
sp_walk_data->page_size = page_size;
uva_aligned = ALIGN_DOWN(uva, page_size);
sp_walk_data->uva_aligned = uva_aligned;
@@ -3164,8 +3197,12 @@ static int __sp_walk_page_range(unsigned long uva, unsigned long size,
ret = walk_page_range(mm, uva_aligned, uva_aligned + size_aligned,
&sp_walk, sp_walk_data);
- if (ret)
+ if (ret) {
+ while (sp_walk_data->page_count--)
+ put_page(pages[sp_walk_data->page_count]);
kvfree(pages);
+ sp_walk_data->pages = NULL;
+ }
return ret;
}
@@ -3201,9 +3238,7 @@ void *sp_make_share_u2k(unsigned long uva, unsigned long size, int pid)
int ret = 0;
struct mm_struct *mm = current->mm;
void *p = ERR_PTR(-ESRCH);
- struct sp_walk_data sp_walk_data = {
- .page_count = 0,
- };
+ struct sp_walk_data sp_walk_data;
struct vm_struct *area;
check_interrupt_context();
@@ -3544,7 +3579,6 @@ int sp_walk_page_range(unsigned long uva, unsigned long size,
return -ESRCH;
}
- sp_walk_data->page_count = 0;
down_write(&mm->mmap_lock);
if (likely(!mm->core_state))
ret = __sp_walk_page_range(uva, size, mm, sp_walk_data);
--
2.20.1
1
22
Backport 5.10.112 LTS patches from upstream.
git cherry-pick v5.10.111..v5.10.112~1 -s
Complicts:
Already merged(10):
80a4df14643f7 hamradio: defer 6pack kfree after unregister_netdev
cfa98ffc42f16 hamradio: remove needs_free_netdev to avoid UAF
5ea00fc60676 ax25: add refcount in ax25_dev to avoid UAF bugs
5ddae8d06441 ax25: fix reference count leaks of ax25_dev
57cc15f5fd55 ax25: fix UAF bugs of net_device caused by rebinding operation
b20a5ab0f5fb ax25: Fix refcount leaks caused by ax25_cb_del()
a4942c6fea87 ax25: fix UAF bug in ax25_send_control()
145ea8d213e8 ax25: fix NPD bug in ax25_disconnect
f934fa478dd1 ax25: Fix NULL pointer dereferences in ax25 timers
5c62d3bf1410 ax25: Fix UAF bugs in ax25 timers
Total patches: 104 - 10 = 94
Adrian Hunter (1):
perf tools: Fix misleading add event PMU debug message
Ajish Koshy (2):
scsi: pm80xx: Mask and unmask upper interrupt vectors 32-63
scsi: pm80xx: Enable upper inbound, outbound queues
Alexey Galakhov (1):
scsi: mvsas: Add PCI ID of RocketRaid 2640
Andy Chiu (1):
net: axienet: setup mdio unconditionally
Anna-Maria Behnsen (1):
timers: Fix warning condition in __run_timers()
Athira Rajeev (1):
testing/selftests/mqueue: Fix mq_perf_tests to free the allocated cpu
set
Aurabindo Pillai (1):
drm/amd: Add USBC connector ID
Benedikt Spranger (1):
net/sched: taprio: Check if socket flags are valid
Borislav Petkov (1):
perf/imx_ddr: Fix undefined behavior due to shift overflowing the
constant
Calvin Johnson (1):
net: mdio: Alphabetically sort header inclusion
Chandrakanth patil (1):
scsi: megaraid_sas: Target with invalid LUN ID is deleted during scan
Chao Gao (1):
dma-direct: avoid redundant memory sync for swiotlb
Charlene Liu (1):
drm/amd/display: fix audio format not updated after edid updated
Chiawen Huang (1):
drm/amd/display: FEC check in timing validation
Christian Lamparter (1):
ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs
Chuck Lever (1):
SUNRPC: Fix the svc_deferred_event trace class
Cristian Marussi (1):
firmware: arm_scmi: Fix sorting of retrieved clock rates
Darrick J. Wong (1):
btrfs: fix fallocate to use file_modified to update permissions
consistently
Dinh Nguyen (1):
net: ethernet: stmmac: fix altr_tse_pcs function when using a
fixed-link
Duoming Zhou (1):
drivers: net: slip: fix NPD bug in sl_tx_timeout()
Fabio M. De Francesco (1):
ALSA: pcm: Test for "silence" field in struct "pcm_format_data"
Felix Kuehling (1):
drm/amdkfd: Use drm_priv to pass VM from KFD to amdgpu
Guillaume Nault (1):
veth: Ensure eth header is in skb's linear part
Harshit Mogalapalli (1):
cifs: potential buffer overflow in handling symlinks
James Smart (1):
scsi: lpfc: Fix queue failures when recovering from PCI parity error
Jason A. Donenfeld (1):
gcc-plugins: latent_entropy: use /dev/urandom
Jeremy Linton (1):
net: bcmgenet: Revert "Use stronger register read/writes to assure
ordering"
Jia-Ju Bai (1):
btrfs: fix root ref counts in error handling in btrfs_get_root_ref
Joey Gouly (1):
arm64: alternatives: mark patch_alternative() as `noinstr`
Johan Hovold (1):
memory: renesas-rpc-if: fix platform-device leak in error path
Johannes Berg (1):
nl80211: correctly check NL80211_ATTR_REG_ALPHA2 size
Jonathan Bakker (1):
regulator: wm8994: Add an off-on delay for WM8994 variant
Josef Bacik (1):
btrfs: do not warn for free space inode in cow_file_range
Juergen Gross (1):
mm, page_alloc: fix build_zonerefs_node()
Karsten Graul (1):
net/smc: Fix NULL pointer dereference in smc_pnet_find_ib()
Khazhismel Kumykov (1):
dm mpath: only use ktime_get_ns() in historical selector
Kyle Copperfield (1):
media: rockchip/rga: do proper error checking in probe
Leo (Hanghong) Ma (1):
drm/amd/display: Update VTEM Infopacket definition
Leo Ruan (1):
gpu: ipu-v3: Fix dev_dbg frequency output
Lin Ma (1):
nfc: nci: add flush_workqueue to prevent uaf
Linus Torvalds (1):
gpiolib: acpi: use correct format characters
Marcelo Ricardo Leitner (1):
net/sched: fix initialization order when updating chain 0 head
Marcin Kozlowski (1):
net: usb: aqc111: Fix out-of-bounds accesses in RX fixup
Mario Limonciello (2):
cpuidle: PSCI: Move the `has_lpi` check to the beginning of the
function
ACPI: processor idle: Check for architectural support for LPI
Martin Leung (1):
drm/amd/display: Revert FEC check in validation
Martin Povišer (1):
i2c: pasemi: Wait for write xfers to finish
Melissa Wen (1):
drm/amd/display: don't ignore alpha property on pre-multiplied mode
Miaoqian Lin (1):
memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe
Michael Kelley (1):
Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer
Michael Walle (1):
net: dsa: felix: suppress -EPROBE_DEFER errors
Mike Christie (10):
scsi: iscsi: Stop queueing during ep_disconnect
scsi: iscsi: Force immediate failure during shutdown
scsi: iscsi: Use system_unbound_wq for destroy_work
scsi: iscsi: Rel ref after iscsi_lookup_endpoint()
scsi: iscsi: Fix in-kernel conn failure handling
scsi: iscsi: Move iscsi_ep_disconnect()
scsi: iscsi: Fix offload conn cleanup when iscsid restarts
scsi: iscsi: Fix conn cleanup and stop race during iscsid restart
scsi: iscsi: Fix endpoint reuse regression
scsi: iscsi: Fix unbound endpoint error handling
Mikulas Patocka (1):
dm integrity: fix memory corruption when tag_size is less than digest
size
Minchan Kim (1):
mm: fix unexpected zeroed page mapping with zram swap
Nadav Amit (1):
smp: Fix offline cpu check in flush_smp_call_function_queue()
Naohiro Aota (1):
btrfs: mark resumed async balance as writing
Nathan Chancellor (2):
btrfs: remove unused variable in
btrfs_{start,write}_dirty_block_groups()
ARM: davinci: da850-evm: Avoid NULL pointer dereference
Nicolas Dichtel (1):
ipv6: fix panic when forwarding a pkt with no in6 dev
Patrick Wang (1):
mm: kmemleak: take a full lowmem check in kmemleak_*_phys()
Paul Gortmaker (1):
tick/nohz: Use WARN_ON_ONCE() to prevent console saturation
Petr Malat (1):
sctp: Initialize daddr on peeled off socket
QintaoShen (1):
drm/amdkfd: Check for potential null return of kmalloc_array()
Rameshkumar Sundaram (1):
cfg80211: hold bss_lock while updating nontrans_list
Randy Dunlap (1):
net: micrel: fix KS8851_MLL Kconfig
Rei Yamamoto (1):
genirq/affinity: Consider that CPUs on nodes can be unbalanced
Rob Clark (2):
drm/msm: Add missing put_task_struct() in debugfs path
drm/msm: Fix range size vs end confusion
Roman Li (1):
drm/amd/display: Fix allocate_mst_payload assert on resume
Sean Christopherson (1):
KVM: x86/mmu: Resolve nx_huge_pages when kvm.ko is loaded
Stephen Boyd (1):
drm/msm/dsi: Use connector directly in
msm_dsi_manager_connector_init()
Steve Capper (1):
tlb: hugetlb: Add more sizes to tlb_remove_huge_tlb_entry
Tao Jin (1):
ALSA: hda/realtek: add quirk for Lenovo Thinkpad X12 speakers
Tianci Yin (1):
drm/amdgpu/vcn: improve vcn dpg stop procedure
Tim Crawford (1):
ALSA: hda/realtek: Add quirk for Clevo PD50PNT
Toke Høiland-Jørgensen (2):
ath9k: Properly clear TX status area before reporting to mac80211
ath9k: Fix usage of driver-private space in tx_info
Tomasz Moń (1):
drm/amdgpu: Enable gfxoff quirk on MacBook Pro
Tushar Patel (1):
drm/amdkfd: Fix Incorrect VMIDs passed to HWS
Tyrel Datwyler (1):
scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024
Vadim Pasternak (1):
mlxsw: i2c: Fix initialization error flow
Vlad Buslov (1):
net/sched: flower: fix parsing of ethertype following VLAN header
Xiaoguang Wang (1):
scsi: target: tcmu: Fix possible page UAF
Xiaomeng Tong (1):
myri10ge: fix an incorrect free for skb in myri10ge_sw_tso
arch/arm/mach-davinci/board-da850-evm.c | 4 +-
arch/arm64/kernel/alternative.c | 6 +-
arch/arm64/kernel/cpuidle.c | 6 +-
arch/x86/include/asm/kvm_host.h | 5 +-
arch/x86/kvm/mmu/mmu.c | 20 +-
arch/x86/kvm/x86.c | 20 +-
drivers/acpi/processor_idle.c | 15 +-
drivers/ata/libata-core.c | 3 +
drivers/firmware/arm_scmi/clock.c | 3 +-
drivers/gpio/gpiolib-acpi.c | 4 +-
drivers/gpu/drm/amd/amdgpu/ObjectID.h | 1 +
.../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 10 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 +
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 3 +
drivers/gpu/drm/amd/amdkfd/kfd_device.c | 11 +-
drivers/gpu/drm/amd/amdkfd/kfd_events.c | 2 +
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-
.../gpu/drm/amd/display/dc/core/dc_resource.c | 4 +-
.../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 14 +-
.../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 14 +-
.../display/modules/info_packet/info_packet.c | 5 +-
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +-
drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +-
drivers/gpu/drm/msm/msm_gem.c | 1 +
drivers/gpu/ipu-v3/ipu-di.c | 5 +-
drivers/hv/ring_buffer.c | 11 +-
drivers/i2c/busses/i2c-pasemi.c | 6 +
drivers/infiniband/ulp/iser/iscsi_iser.c | 2 +
drivers/md/dm-historical-service-time.c | 10 +-
drivers/md/dm-integrity.c | 7 +-
drivers/media/platform/rockchip/rga/rga.c | 2 +-
drivers/memory/atmel-ebi.c | 23 +-
drivers/memory/renesas-rpc-if.c | 10 +-
drivers/net/dsa/ocelot/felix_vsc9959.c | 2 +-
.../net/ethernet/broadcom/genet/bcmgenet.c | 4 +-
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 1 +
drivers/net/ethernet/micrel/Kconfig | 1 +
.../net/ethernet/myricom/myri10ge/myri10ge.c | 6 +-
.../ethernet/stmicro/stmmac/altr_tse_pcs.c | 8 -
.../ethernet/stmicro/stmmac/altr_tse_pcs.h | 4 +
.../ethernet/stmicro/stmmac/dwmac-socfpga.c | 13 +-
.../net/ethernet/xilinx/xilinx_axienet_main.c | 13 +-
drivers/net/mdio/mdio-bcm-unimac.c | 16 +-
drivers/net/mdio/mdio-bitbang.c | 4 +-
drivers/net/mdio/mdio-cavium.c | 2 +-
drivers/net/mdio/mdio-gpio.c | 10 +-
drivers/net/mdio/mdio-ipq4019.c | 4 +-
drivers/net/mdio/mdio-ipq8064.c | 4 +-
drivers/net/mdio/mdio-mscc-miim.c | 8 +-
drivers/net/mdio/mdio-mux-bcm-iproc.c | 10 +-
drivers/net/mdio/mdio-mux-gpio.c | 8 +-
drivers/net/mdio/mdio-mux-mmioreg.c | 6 +-
drivers/net/mdio/mdio-mux-multiplexer.c | 2 +-
drivers/net/mdio/mdio-mux.c | 6 +-
drivers/net/mdio/mdio-octeon.c | 8 +-
drivers/net/mdio/mdio-thunder.c | 10 +-
drivers/net/mdio/mdio-xgene.c | 6 +-
drivers/net/mdio/of_mdio.c | 10 +-
drivers/net/slip/slip.c | 2 +-
drivers/net/usb/aqc111.c | 9 +-
drivers/net/veth.c | 2 +-
drivers/net/wireless/ath/ath9k/main.c | 2 +-
drivers/net/wireless/ath/ath9k/xmit.c | 33 +-
drivers/perf/fsl_imx8_ddr_perf.c | 2 +-
drivers/regulator/wm8994-regulator.c | 42 +-
drivers/scsi/be2iscsi/be_iscsi.c | 19 +-
drivers/scsi/be2iscsi/be_main.c | 1 +
drivers/scsi/bnx2i/bnx2i_iscsi.c | 24 +-
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 1 +
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 1 +
drivers/scsi/cxgbi/libcxgbi.c | 12 +-
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 2 +-
drivers/scsi/libiscsi.c | 70 ++-
drivers/scsi/lpfc/lpfc_init.c | 2 +
drivers/scsi/megaraid/megaraid_sas.h | 3 +
drivers/scsi/megaraid/megaraid_sas_base.c | 7 +
drivers/scsi/mvsas/mv_init.c | 1 +
drivers/scsi/pm8001/pm80xx_hwi.c | 33 +-
drivers/scsi/qedi/qedi_iscsi.c | 26 +-
drivers/scsi/qla4xxx/ql4_os.c | 2 +
drivers/scsi/scsi_transport_iscsi.c | 541 +++++++++++-------
drivers/target/target_core_user.c | 3 +-
fs/btrfs/block-group.c | 4 -
fs/btrfs/disk-io.c | 5 +-
fs/btrfs/file.c | 13 +-
fs/btrfs/inode.c | 1 -
fs/btrfs/volumes.c | 2 +
fs/cifs/link.c | 3 +
include/asm-generic/tlb.h | 10 +-
include/net/flow_dissector.h | 2 +
include/scsi/libiscsi.h | 1 +
include/scsi/scsi_transport_iscsi.h | 14 +-
include/trace/events/sunrpc.h | 7 +-
kernel/dma/direct.h | 3 +-
kernel/irq/affinity.c | 5 +-
kernel/smp.c | 2 +-
kernel/time/tick-sched.c | 2 +-
kernel/time/timer.c | 11 +-
mm/kmemleak.c | 8 +-
mm/page_alloc.c | 2 +-
mm/page_io.c | 54 --
net/core/flow_dissector.c | 1 +
net/ipv6/ip6_output.c | 2 +-
net/nfc/nci/core.c | 4 +
net/sched/cls_api.c | 2 +-
net/sched/cls_flower.c | 18 +-
net/sched/sch_taprio.c | 3 +-
net/sctp/socket.c | 2 +-
net/smc/smc_pnet.c | 5 +-
net/wireless/nl80211.c | 3 +-
net/wireless/scan.c | 2 +
scripts/gcc-plugins/latent_entropy_plugin.c | 44 +-
sound/core/pcm_misc.c | 2 +-
sound/pci/hda/patch_realtek.c | 2 +
tools/perf/util/parse-events.c | 5 +-
.../testing/selftests/mqueue/mq_perf_tests.c | 25 +-
117 files changed, 959 insertions(+), 554 deletions(-)
--
2.20.1
1
94
Backport 5.10.111 LTS patches from upstream.
Complicts:
Already merged(4):
2dc49f58a29c ubifs: Rectify space amount budget for mkdir/tmpfile operations
c688705a3978 Revert "NFSv4: Handle the special Linux file open access mode"
2827328e646d io_uring: fix race between timeout flush and removal
4665722d36ad cgroup: Use open-time credentials for process migraton perm checks
Context conflict(3):
4820847e8bc2 usb: ehci: add pci device support for Aspeed platforms
8a7ada4b8f5d scsi: hisi_sas: Free irq vectors in order for v3 HW
9de98470db6e arm64: Add part number for Arm Cortex-A78AE
Rejected(1):
2f2f017ea873 dm: requeue IO if mapping table not yet available
Implement changed(-1+1):
d36febbcd537 powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit
Added(1):
ipv6: fix kabi for mc_forwarding in struct ipv6_devconf
Total patches: 170 - 4 - 1 + 1 - 1 + 1 = 166
Adam Wujek (1):
clk: si5341: fix reported clk_rate when output divider is 2
Adrian Hunter (1):
perf tools: Fix perf's libperf_print callback
Aharon Landau (1):
RDMA/mlx5: Don't remove cache MRs when a delay is needed
Alex Deucher (2):
drm/amdkfd: make CRAT table missing message informational only
drm/amdgpu/smu10: fix SoC/fclk units in auto mode
Alexander Lobakin (1):
MIPS: fix fortify panic when copying asm exception handlers
Amjad Ouled-Ameur (1):
phy: amlogic: meson8b-usb2: Use dev_err_probe()
Anatolii Gerasymenko (2):
ice: Set txq_teid to ICE_INVAL_TEID on ring creation
ice: Do not skip not enabled queues in ice_vc_dis_qs_msg
Andre Przywara (1):
irqchip/gic, gic-v3: Prevent GSI to SGI translations
Andrea Parri (Microsoft) (1):
Drivers: hv: vmbus: Replace smp_store_mb() with virt_store_mb()
Andreas Gruenbacher (2):
gfs2: Check for active reservation in gfs2_release
gfs2: gfs2_setattr_size error path fix
Andy Gospodarek (1):
bnxt_en: reserve space inside receive page for skb_shared_info
Anisse Astier (1):
drm: Add orientation quirk for GPD Win Max
Arnaldo Carvalho de Melo (4):
perf build: Don't use -ffat-lto-objects in the python feature test
when building with clang-13
perf python: Fix probing for some clang command line options
tools build: Filter out options and warnings not supported by clang
tools build: Use $(shell ) instead of `` to get embedded libperl's
ccopts
Avraham Stern (1):
cfg80211: don't add non transmitted BSS to 6GHz scanned channels
Bob Peterson (1):
gfs2: Fix gfs2_release for non-writers regression
Chanho Park (1):
arm64: Add part number for Arm Cortex-A78AE
Chen-Yu Tsai (1):
net: stmmac: Fix unset max_speed difference between DT and non-DT
platforms
Christian Lamparter (1):
ata: sata_dwc_460ex: Fix crash due to OOB write
Christophe JAILLET (1):
scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one()
Dale Zhao (1):
drm/amd/display: Add signal type check when verify stream backends
same
Damien Le Moal (5):
scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
scsi: pm8001: Fix task leak in pm8001_send_abort_all()
scsi: pm8001: Fix tag leaks on error
scsi: pm8001: Fix memory leak in pm8001_chip_fw_flash_update_req()
Dan Carpenter (1):
drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire()
David Ahern (1):
ipv6: Fix stats accounting in ip6_pkt_drop
Denis Nikitin (1):
perf session: Remap buf if there is no space for event
Dongli Zhang (1):
xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32
Douglas Miller (1):
RDMA/hfi1: Fix use-after-free bug for mm struct
Dust Li (1):
net/smc: correct settings of RMB window update limit
Eric Dumazet (2):
ipv6: make mc_forwarding atomic
rxrpc: fix a race in rxrpc_exit_net()
Ethan Lien (1):
btrfs: fix qgroup reserve overflow the qgroup limit
Evgeny Boger (1):
power: supply: axp20x_battery: properly report current when
discharging
Fangrui Song (1):
arm64: module: remove (NOLOAD) from linker script
Guilherme G. Piccoli (1):
Drivers: hv: vmbus: Fix potential crash on module unload
Guo Ren (1):
arm64: patch_text: Fixup last cpu should be master
Guo Xuenan (1):
lz4: fix LZ4_decompress_safe_partial read out of bound
H. Nikolaus Schaller (1):
usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm
Haimin Zhang (1):
jfs: prevent NULL deref in diFree
Hangyu Hua (2):
mips: ralink: fix a refcount leak in ill_acc_of_setup()
powerpc/secvar: fix refcount leak in format_show()
Hans de Goede (1):
power: supply: axp288-charger: Set Vhold to 4.4V
Harold Huang (1):
tuntap: add sanity checks about msg_controllen in sendmsg
Helge Deller (1):
parisc: Fix CPU affinity for Lasi, WAX and Dino chips
Hou Wenlong (1):
KVM: x86/emulator: Emulate RDPID only if it is enabled in guest
Hou Zhiqiang (1):
PCI: endpoint: Fix alignment fault error in copy tests
Ido Schimmel (1):
ipv4: Invalidate neighbour for broadcast address upon address addition
Ilan Peer (1):
iwlwifi: mvm: Correctly set fragmented EBS
Ilya Maximets (2):
net: openvswitch: don't send internal clone attribute to the
userspace.
net: openvswitch: fix leak of nested actions
Ivan Vecera (1):
ice: Clear default forwarding VSI during VSI release
Jakub Kicinski (2):
net: account alternate interface name memory
net: limit altnames to 64k total
Jakub Sitnicki (1):
bpf: Make dst_port field in struct bpf_sock 16-bit wide
James Clark (1):
perf: arm-spe: Fix perf report --mem-mode
Jamie Bainbridge (1):
qede: confirm skb is allocated before using
Jianglei Nie (1):
scsi: libfc: Fix use after free in fc_exch_abts_resp()
Jiasheng Jiang (2):
rtc: wm8350: Handle error for wm8350_register_irq
drm/imx: imx-ldb: Check for null pointer after calling kmemdup
Jim Mattson (1):
KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs
Jiri Slaby (1):
serial: samsung_tty: do not unlock port->lock for uart_write_wakeup()
John David Anglin (1):
parisc: Fix patch code locking and flushing
Jordy Zomer (1):
dm ioctl: prevent potential spectre v1 gadget
José Expósito (1):
drm/imx: Fix memory leak in imx_pd_connector_get_modes
Kaiwen Hu (1):
btrfs: prevent subvol with swapfile from being deleted
Kalle Valo (1):
ath11k: mhi: use mhi_sync_power_up()
Kamal Dasu (1):
spi: bcm-qspi: fix MSPI only access with bcm_qspi_exec_mem_op()
Karol Herbst (1):
drm/nouveau/pmu: Add missing callbacks for Tegra devices
Kees Cook (1):
ubsan: remove CONFIG_UBSAN_OBJECT_SIZE
Kefeng Wang (1):
powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit
Krzysztof Kozlowski (1):
MIPS: ingenic: correct unit node address
Lee Jones (1):
drm/amdkfd: Create file descriptor after client is added to
smi_clients list
Li Chen (1):
PCI: endpoint: Fix misused goto label
Lorenzo Bianconi (1):
mt76: dma: initialize skip_unmap in mt76_dma_rx_fill
Lucas Denefle (1):
w1: w1_therm: fixes w1_seq for ds28ea00 sensors
Luiz Augusto von Dentz (2):
Bluetooth: Fix not checking for valid hdev on
bt_dev_{info,warn,err,dbg}
Bluetooth: Fix use after free in hci_send_acl
Lv Yunlong (1):
drbd: Fix five use after free bugs in get_initial_state
Maciej Fijalkowski (1):
ice: synchronize_rcu() when terminating rings
Manivannan Sadhasivam (1):
PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
Marc Zyngier (1):
irqchip/gic-v3: Fix GICR_CTLR.RWP polling
Martin Habets (1):
sfc: Do not free an empty page_ring
Mauricio Faria de Oliveira (1):
mm: fix race between MADV_FREE reclaim and blkdev direct IO read
Max Filippov (1):
xtensa: fix DTC warning unit_address_format
Maxim Kiselev (1):
powerpc: dts: t104xrdb: fix phy type for FMAN 4/5
Maxim Mikityanskiy (1):
bpf: Support dual-stack sockets in bpf_tcp_check_syncookie
Maxime Ripard (1):
clk: Enforce that disjoints limits are invalid
Miaohe Lin (1):
mm/mempolicy: fix mpol_new leak in shared_policy_replace
Miaoqian Lin (1):
dpaa2-ptp: Fix refcount leak in dpaa2_ptp_probe
Michael Chan (1):
bnxt_en: Eliminate unintended link toggle during FW reset
Michael Walle (2):
net: sfp: add 2500base-X quirk for Lantech SFP module
net: phy: mscc-miim: reject clause 45 register accesses
Minghao Chi (CGEL ZTE) (1):
Bluetooth: use memset avoid memory leaks
Nathan Chancellor (1):
x86/Kconfig: Do not allow CONFIG_X86_X32_ABI=y with llvm-objcopy
Neal Liu (1):
usb: ehci: add pci device support for Aspeed platforms
NeilBrown (5):
SUNRPC/call_alloc: async tasks mustn't block waiting for memory
SUNRPC/xprt: async tasks mustn't block waiting for memory
SUNRPC: remove scheduling boost for "SWAPPER" tasks.
NFS: swap IO handling is slightly different for O_DIRECT IO
NFS: swap-out must always use STABLE writes.
Niels Dossche (1):
IB/rdmavt: add lock to call to rvt_error_qp to prevent a race
condition
Nikolay Aleksandrov (1):
net: ipv4: fix route with nexthop object delete warning
Oliver Hartkopp (1):
can: isotp: set default value for N_As to 50 micro seconds
Pali Rohár (2):
PCI: aardvark: Fix support for MSI interrupts
Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning"
Paolo Bonzini (1):
mmmremap.c: avoid pointless invalidate_range_start/end on
mremap(old_size=0)
Pavel Begunkov (1):
io_uring: don't touch scm_fp_list after queueing skb
Pawan Gupta (2):
x86/pm: Save the MSR validity status at context setup
x86/speculation: Restore speculation related MSRs during S3 resume
Peter Xu (1):
mm: don't skip swap entry even if zap_details specified
Qi Liu (1):
scsi: hisi_sas: Free irq vectors in order for v3 HW
Qinghua Jin (1):
minix: fix bug when opening a file with O_DIRECT
Rajneesh Bhardwaj (1):
drm/amdgpu: Fix recursive locking warning
Randy Dunlap (3):
scsi: aha152x: Fix aha152x_setup() __setup handler return value
init/main.c: return 1 from handled __setup() functions
virtio_console: eliminate anonymous module_init & module_exit
Sachin Sant (1):
selftests/cgroup: Fix build on older distros
Sasha Levin (1):
Revert "hv: utils: add PTP_1588_CLOCK to Kconfig to fix build"
Sebastian Andrzej Siewior (1):
tcp: Don't acquire inet_listen_hashbucket::lock with disabled BH.
Shreeya Patel (1):
gpio: Restrict usage of GPIO chip irq members before initialization
Sourabh Jain (1):
powerpc: Set crashkernel offset to mid of RMA region
Stefan Wahren (1):
staging: vchiq_core: handle NULL result of find_service_by_handle
Sven Eckelmann (1):
macvtap: advertise link netns via netlink
Tejun Heo (3):
selftests: cgroup: Make cg_create() use 0755 for permission instead of
0644
selftests: cgroup: Test open-time credential usage for migration
checks
selftests: cgroup: Test open-time cgroup namespace usage for migration
checks
Tony Lindgren (2):
clk: ti: Preserve node in ti_dt_clocks_register()
iommu/omap: Fix regression in probe for NULL pointer dereference
Trond Myklebust (7):
NFSv4: Protect the state recovery thread against direct reclaim
SUNRPC: Fix socket waits for write buffer space
NFS: nfsiod should not block forever in mempool_alloc()
NFS: Avoid writeback threads getting stuck in mempool_alloc()
SUNRPC: Handle ENOMEM in call_transmit_status()
SUNRPC: Handle low memory situations in call_status()
SUNRPC: svc_tcp_sendmsg() should handle errors from xdr_alloc_bvec()
Venkateswara Naralasetty (1):
ath11k: fix kernel panic during unload/load ath11k modules
Vinod Koul (1):
dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on
error"
Waiman Long (1):
mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning
Wang Yufen (1):
netlabel: fix out-of-bounds memory accesses
Wayne Chang (2):
usb: gadget: tegra-xudc: Do not program SPARAM
usb: gadget: tegra-xudc: Fix control endpoint's definitions
Wolfram Sang (1):
mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is
complete
Xiaoke Wang (1):
staging: wfx: fix an error handling in wfx_init_common()
Xiaomeng Tong (1):
perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator
Xin Xiong (2):
drm/amd/amdgpu/amdgpu_cs: fix refcount leak of a dma_fence obj
NFSv4.2: fix reference count leaks in _nfs42_proc_copy_notify()
Xiubo Li (1):
ceph: fix memory leak in ceph_readdir when note_last_dentry returns
error
Yang Guang (3):
ptp: replace snprintf with sysfs_emit
scsi: mvsas: Replace snprintf() with sysfs_emit()
scsi: bfa: Replace snprintf() with sysfs_emit()
Yang Li (1):
mt76: mt7615: Fix assigning negative values to unsigned variable
Yann Gautier (1):
mmc: mmci: stm32: correctly check all elements of sg list
Yonghong Song (1):
libbpf: Fix build issue with llvm-readelf
Zekun Shen (1):
ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111
Zheng Zengkai (2):
ipv6: fix kabi for mc_forwarding in struct ipv6_devconf
Revert "powerpc: Fix virt_addr_valid() check"
Zhou Guanghui (1):
iommu/arm-smmu-v3: fix event handling soft lockup
Ziyang Xuan (1):
net/tls: fix slab-out-of-bounds bug in decrypt_internal
arch/arm64/include/asm/cputype.h | 2 +
arch/arm64/include/asm/module.lds.h | 6 +-
arch/arm64/kernel/insn.c | 4 +-
arch/arm64/kernel/proton-pack.c | 1 +
arch/mips/boot/dts/ingenic/jz4780.dtsi | 2 +-
arch/mips/include/asm/setup.h | 2 +-
arch/mips/kernel/traps.c | 22 +--
arch/mips/ralink/ill_acc.c | 1 +
arch/parisc/kernel/patch.c | 25 ++-
arch/powerpc/boot/dts/fsl/t104xrdb.dtsi | 4 +-
arch/powerpc/include/asm/page.h | 7 +-
arch/powerpc/kernel/rtas.c | 6 +
arch/powerpc/kernel/secvar-sysfs.c | 9 +-
arch/powerpc/kexec/core.c | 15 +-
arch/x86/Kconfig | 5 +
arch/x86/kvm/emulate.c | 4 +-
arch/x86/kvm/kvm_emulate.h | 1 +
arch/x86/kvm/svm/pmu.c | 8 +-
arch/x86/kvm/x86.c | 6 +
arch/x86/power/cpu.c | 21 ++-
arch/x86/xen/smp_hvm.c | 6 +
arch/x86/xen/time.c | 24 ++-
arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi | 8 +-
arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi | 8 +-
arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi | 4 +-
drivers/ata/sata_dwc_460ex.c | 6 +-
drivers/block/drbd/drbd_int.h | 8 +-
drivers/block/drbd/drbd_nl.c | 41 +++--
drivers/block/drbd/drbd_state.c | 18 +-
drivers/block/drbd/drbd_state_change.h | 8 +-
drivers/char/virtio_console.c | 8 +-
drivers/clk/clk-si5341.c | 16 +-
drivers/clk/clk.c | 24 +++
drivers/clk/ti/clk.c | 13 +-
drivers/dma/sh/shdma-base.c | 4 +-
drivers/gpio/gpiolib.c | 19 ++
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 1 +
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 3 +-
drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 2 +-
drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c | 24 ++-
.../gpu/drm/amd/display/dc/core/dc_resource.c | 3 +
.../drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 8 +-
.../gpu/drm/drm_panel_orientation_quirks.c | 6 +
drivers/gpu/drm/imx/imx-ldb.c | 2 +
drivers/gpu/drm/imx/parallel-display.c | 4 +-
.../gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c | 1 +
.../gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c | 2 +-
.../gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c | 1 +
.../gpu/drm/nouveau/nvkm/subdev/pmu/priv.h | 1 +
drivers/hv/Kconfig | 1 -
drivers/hv/channel_mgmt.c | 6 +-
drivers/hv/vmbus_drv.c | 9 +-
drivers/infiniband/hw/hfi1/mmu_rb.c | 6 +
drivers/infiniband/hw/mlx5/mr.c | 4 +-
drivers/infiniband/sw/rdmavt/qp.c | 6 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 +
drivers/iommu/omap-iommu.c | 2 +-
drivers/irqchip/irq-gic-v3.c | 14 +-
drivers/irqchip/irq-gic.c | 6 +
drivers/md/dm-ioctl.c | 2 +
drivers/mmc/host/mmci_stm32_sdmmc.c | 6 +-
drivers/mmc/host/renesas_sdhi_core.c | 4 +-
drivers/mmc/host/sdhci-xenon.c | 10 --
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 3 +-
.../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 4 +-
.../net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 4 +-
drivers/net/ethernet/intel/ice/ice.h | 2 +-
drivers/net/ethernet/intel/ice/ice_lib.c | 3 +
drivers/net/ethernet/intel/ice/ice_main.c | 4 +-
.../net/ethernet/intel/ice/ice_virtchnl_pf.c | 4 +-
drivers/net/ethernet/intel/ice/ice_xsk.c | 4 +-
drivers/net/ethernet/qlogic/qede/qede_fp.c | 3 +
drivers/net/ethernet/sfc/rx_common.c | 3 +
.../ethernet/stmicro/stmmac/stmmac_platform.c | 3 +-
drivers/net/macvtap.c | 6 +
drivers/net/mdio/mdio-mscc-miim.c | 6 +
drivers/net/phy/sfp-bus.c | 6 +
drivers/net/tap.c | 3 +-
drivers/net/tun.c | 3 +-
drivers/net/wireless/ath/ath11k/ahb.c | 2 +
drivers/net/wireless/ath/ath11k/mhi.c | 2 +-
drivers/net/wireless/ath/ath5k/eeprom.c | 3 +
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 5 +-
drivers/net/wireless/mediatek/mt76/dma.c | 1 +
.../net/wireless/mediatek/mt76/mt7615/mac.c | 2 +-
drivers/parisc/dino.c | 41 ++++-
drivers/parisc/gsc.c | 31 ++++
drivers/parisc/gsc.h | 1 +
drivers/parisc/lasi.c | 7 +-
drivers/parisc/wax.c | 7 +-
drivers/pci/controller/pci-aardvark.c | 16 +-
drivers/pci/endpoint/functions/pci-epf-test.c | 14 +-
drivers/pci/hotplug/pciehp_hpc.c | 2 +
drivers/perf/qcom_l2_pmu.c | 6 +-
drivers/phy/amlogic/phy-meson8b-usb2.c | 5 +-
drivers/power/supply/axp20x_battery.c | 13 +-
drivers/power/supply/axp288_charger.c | 14 +-
drivers/ptp/ptp_sysfs.c | 4 +-
drivers/rtc/rtc-wm8350.c | 11 +-
drivers/scsi/aha152x.c | 6 +-
drivers/scsi/bfa/bfad_attr.c | 26 +--
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 16 +-
drivers/scsi/libfc/fc_exch.c | 1 +
drivers/scsi/mvsas/mv_init.c | 4 +-
drivers/scsi/pm8001/pm8001_hwi.c | 27 ++-
drivers/scsi/pm8001/pm8001_sas.c | 2 +-
drivers/scsi/pm8001/pm80xx_hwi.c | 17 +-
drivers/scsi/zorro7xx.c | 2 +
drivers/spi/spi-bcm-qspi.c | 4 +-
.../interface/vchiq_arm/vchiq_core.c | 6 +
drivers/staging/wfx/main.c | 7 +-
drivers/tty/serial/samsung_tty.c | 5 +-
drivers/usb/dwc3/dwc3-omap.c | 2 +-
drivers/usb/gadget/udc/tegra-xudc.c | 20 +--
drivers/usb/host/ehci-pci.c | 9 +
drivers/vhost/net.c | 1 +
drivers/w1/slaves/w1_therm.c | 8 +-
fs/btrfs/extent_io.h | 2 +-
fs/btrfs/inode.c | 22 +++
fs/ceph/dir.c | 11 +-
fs/gfs2/bmap.c | 2 +-
fs/gfs2/file.c | 3 +-
fs/gfs2/inode.c | 2 +-
fs/gfs2/rgrp.c | 7 +-
fs/gfs2/rgrp.h | 2 +-
fs/gfs2/super.c | 2 +-
fs/io_uring.c | 8 +-
fs/jfs/inode.c | 3 +-
fs/minix/inode.c | 3 +-
fs/nfs/direct.c | 48 +++--
fs/nfs/file.c | 4 +-
fs/nfs/internal.h | 7 +
fs/nfs/nfs42proc.c | 9 +-
fs/nfs/nfs4state.c | 12 ++
fs/nfs/pagelist.c | 10 +-
fs/nfs/pnfs_nfs.c | 8 +-
fs/nfs/write.c | 34 ++--
include/linux/gpio/driver.h | 9 +
include/linux/ipv6.h | 2 +-
include/linux/mmzone.h | 11 +-
include/linux/nfs_fs.h | 10 +-
include/net/arp.h | 1 +
include/net/bluetooth/bluetooth.h | 14 +-
include/uapi/linux/bpf.h | 3 +-
include/uapi/linux/can/isotp.h | 28 ++-
init/main.c | 6 +-
lib/lz4/lz4_decompress.c | 8 +-
lib/test_ubsan.c | 11 --
mm/memory.c | 25 ++-
mm/mempolicy.c | 1 +
mm/mremap.c | 3 +
mm/rmap.c | 25 ++-
net/batman-adv/multicast.c | 2 +-
net/bluetooth/hci_event.c | 3 +-
net/bluetooth/l2cap_core.c | 1 +
net/can/isotp.c | 12 +-
net/core/filter.c | 27 ++-
net/core/rtnetlink.c | 13 +-
net/ipv4/arp.c | 9 +-
net/ipv4/fib_frontend.c | 5 +-
net/ipv4/fib_semantics.c | 7 +-
net/ipv4/inet_hashtables.c | 53 +++---
net/ipv6/addrconf.c | 4 +-
net/ipv6/inet6_hashtables.c | 5 +-
net/ipv6/ip6_input.c | 2 +-
net/ipv6/ip6mr.c | 8 +-
net/ipv6/route.c | 2 +-
net/netlabel/netlabel_kapi.c | 2 +
net/openvswitch/actions.c | 2 +-
net/openvswitch/flow_netlink.c | 99 ++++++++++-
net/rxrpc/net_ns.c | 2 +-
net/smc/smc_core.c | 2 +-
net/sunrpc/clnt.c | 7 +
net/sunrpc/sched.c | 11 +-
net/sunrpc/svcsock.c | 4 +-
net/sunrpc/xprt.c | 16 +-
net/sunrpc/xprtrdma/transport.c | 6 +-
net/sunrpc/xprtsock.c | 54 ++++--
net/tls/tls_sw.c | 2 +-
net/wireless/scan.c | 9 +-
scripts/Makefile.ubsan | 1 -
tools/build/feature/Makefile | 9 +-
tools/lib/bpf/Makefile | 4 +-
tools/perf/Makefile.config | 6 +
tools/perf/arch/arm64/util/arm-spe.c | 6 +
tools/perf/perf.c | 2 +-
tools/perf/util/session.c | 15 +-
tools/perf/util/setup.py | 8 +-
tools/testing/selftests/cgroup/cgroup_util.c | 6 +-
tools/testing/selftests/cgroup/test_core.c | 165 ++++++++++++++++++
191 files changed, 1365 insertions(+), 496 deletions(-)
--
2.20.1
1
165

14 Jul '22
From: Zheng Yejian <zhengyejian1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 187209, https://gitee.com/openeuler/kernel/issues/I5GWFT
CVE: NA
--------------------------------
Syzkaller report a softlockup problem, see following logs:
[ 41.463870] watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [ksoftirqd/0:9]
[ 41.509763] Modules linked in:
[ 41.512295] CPU: 0 PID: 9 Comm: ksoftirqd/0 Not tainted 4.19.90 #13
[ 41.516134] Hardware name: linux,dummy-virt (DT)
[ 41.519182] pstate: 80c00005 (Nzcv daif +PAN +UAO)
[ 41.522415] pc : perf_trace_buf_alloc+0x138/0x238
[ 41.525583] lr : perf_trace_buf_alloc+0x138/0x238
[ 41.528656] sp : ffff8000c137e880
[ 41.531050] x29: ffff8000c137e880 x28: ffff20000850ced0
[ 41.534759] x27: 0000000000000000 x26: ffff8000c137e9c0
[ 41.538456] x25: ffff8000ce5c2ae0 x24: ffff200008358b08
[ 41.542151] x23: 0000000000000000 x22: ffff2000084a50ac
[ 41.545834] x21: ffff8000c137e880 x20: 000000000000001c
[ 41.549516] x19: ffff7dffbfdf88e8 x18: 0000000000000000
[ 41.553202] x17: 0000000000000000 x16: 0000000000000000
[ 41.556892] x15: 1ffff00036e07805 x14: 0000000000000000
[ 41.560592] x13: 0000000000000004 x12: 0000000000000000
[ 41.564315] x11: 1fffefbff7fbf120 x10: ffff0fbff7fbf120
[ 41.568003] x9 : dfff200000000000 x8 : ffff7dffbfdf8904
[ 41.571699] x7 : 0000000000000000 x6 : ffff0fbff7fbf121
[ 41.575398] x5 : ffff0fbff7fbf121 x4 : ffff0fbff7fbf121
[ 41.579086] x3 : ffff20000850cdc8 x2 : 0000000000000008
[ 41.582773] x1 : ffff8000c1376000 x0 : 0000000000000100
[ 41.586495] Call trace:
[ 41.588922] perf_trace_buf_alloc+0x138/0x238
[ 41.591912] perf_ftrace_function_call+0x1ac/0x248
[ 41.595123] ftrace_ops_no_ops+0x3a4/0x488
[ 41.597998] ftrace_graph_call+0x0/0xc
[ 41.600715] rcu_dynticks_curr_cpu_in_eqs+0x14/0x70
[ 41.603962] rcu_is_watching+0xc/0x20
[ 41.606635] ftrace_ops_no_ops+0x240/0x488
[ 41.609530] ftrace_graph_call+0x0/0xc
[ 41.612249] __read_once_size_nocheck.constprop.0+0x1c/0x38
[ 41.615905] unwind_frame+0x140/0x358
[ 41.618597] walk_stackframe+0x34/0x60
[ 41.621359] __save_stack_trace+0x204/0x3b8
[ 41.624328] save_stack_trace+0x2c/0x38
[ 41.627112] __kasan_slab_free+0x120/0x228
[ 41.630018] kasan_slab_free+0x10/0x18
[ 41.632752] kfree+0x84/0x250
[ 41.635107] skb_free_head+0x70/0xb0
[ 41.637772] skb_release_data+0x3f8/0x730
[ 41.640626] skb_release_all+0x50/0x68
[ 41.643350] kfree_skb+0x84/0x278
[ 41.645890] kfree_skb_list+0x4c/0x78
[ 41.648595] __dev_queue_xmit+0x1a4c/0x23a0
[ 41.651541] dev_queue_xmit+0x28/0x38
[ 41.654254] ip6_finish_output2+0xeb0/0x1630
[ 41.657261] ip6_finish_output+0x2d8/0x7f8
[ 41.660174] ip6_output+0x19c/0x348
[ 41.663850] mld_sendpack+0x560/0x9e0
[ 41.666564] mld_ifc_timer_expire+0x484/0x8a8
[ 41.669624] call_timer_fn+0x68/0x4b0
[ 41.672355] expire_timers+0x168/0x498
[ 41.675126] run_timer_softirq+0x230/0x7a8
[ 41.678052] __do_softirq+0x2d0/0xba0
[ 41.680763] run_ksoftirqd+0x110/0x1a0
[ 41.683512] smpboot_thread_fn+0x31c/0x620
[ 41.686429] kthread+0x2c8/0x348
[ 41.688927] ret_from_fork+0x10/0x18
Look into above call stack, we found a recursive call in
'ftrace_graph_call', see a snippet:
__read_once_size_nocheck.constprop.0
ftrace_graph_call
......
rcu_dynticks_curr_cpu_in_eqs
ftrace_graph_call
We analyze that 'rcu_dynticks_curr_cpu_in_eqs' should not be tracable,
and we verify that mark related functions as 'notrace' can avoid the
problem.
Comparing mainline kernel, we find that commit ff5c4f5cad33 ("rcu/tree:
Mark the idle relevant functions noinstr") mark related functions as
'noinstr' which implies notrace, noinline and sticks things in the
.noinstr.text section.
Link: https://lore.kernel.org/all/20200416114706.625340212@infradead.org/
Currently 'noinstr' mechanism has not been introduced, so we would not
directly backport that commit (otherwise more changes may be introduced).
Instead, we mark the functions as 'notrace' where it is 'noinstr' in
that commit.
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Reviewed-by: Zhen Lei <thunder.leizhen(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
kernel/rcu/tree.c | 22 +++++++++++-----------
kernel/rcu/tree_plugin.h | 4 ++--
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 594d6ea99024..ea05c59096a2 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -275,7 +275,7 @@ static DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
* Record entry into an extended quiescent state. This is only to be
* called when not already in an extended quiescent state.
*/
-static void rcu_dynticks_eqs_enter(void)
+static notrace void rcu_dynticks_eqs_enter(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
int seq;
@@ -298,7 +298,7 @@ static void rcu_dynticks_eqs_enter(void)
* Record exit from an extended quiescent state. This is only to be
* called from an extended quiescent state.
*/
-static void rcu_dynticks_eqs_exit(void)
+static notrace void rcu_dynticks_eqs_exit(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
int seq;
@@ -343,7 +343,7 @@ static void rcu_dynticks_eqs_online(void)
*
* No ordering, as we are sampling CPU-local information.
*/
-bool rcu_dynticks_curr_cpu_in_eqs(void)
+static __always_inline bool rcu_dynticks_curr_cpu_in_eqs(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
@@ -706,7 +706,7 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
* the possibility of usermode upcalls having messed up our count
* of interrupt nesting level during the prior busy period.
*/
-static void rcu_eqs_enter(bool user)
+static notrace void rcu_eqs_enter(bool user)
{
struct rcu_state *rsp;
struct rcu_data *rdp;
@@ -763,7 +763,7 @@ void rcu_idle_enter(void)
* If you add or remove a call to rcu_user_enter(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_user_enter(void)
+notrace void rcu_user_enter(void)
{
lockdep_assert_irqs_disabled();
rcu_eqs_enter(true);
@@ -781,7 +781,7 @@ void rcu_user_enter(void)
* If you add or remove a call to rcu_nmi_exit(), be sure to test
* with CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_nmi_exit(void)
+notrace void rcu_nmi_exit(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
@@ -829,7 +829,7 @@ void rcu_nmi_exit(void)
* If you add or remove a call to rcu_irq_exit(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_irq_exit(void)
+notrace void rcu_irq_exit(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
@@ -864,7 +864,7 @@ void rcu_irq_exit_irqson(void)
* allow for the possibility of usermode upcalls messing up our count of
* interrupt nesting level during the busy period that is just now starting.
*/
-static void rcu_eqs_exit(bool user)
+static notrace void rcu_eqs_exit(bool user)
{
struct rcu_dynticks *rdtp;
long oldval;
@@ -914,7 +914,7 @@ void rcu_idle_exit(void)
* If you add or remove a call to rcu_user_exit(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_user_exit(void)
+void notrace rcu_user_exit(void)
{
rcu_eqs_exit(1);
}
@@ -932,7 +932,7 @@ void rcu_user_exit(void)
* If you add or remove a call to rcu_nmi_enter(), be sure to test
* with CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_nmi_enter(void)
+notrace void rcu_nmi_enter(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
long incby = 2;
@@ -982,7 +982,7 @@ void rcu_nmi_enter(void)
* If you add or remove a call to rcu_irq_enter(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_irq_enter(void)
+notrace void rcu_irq_enter(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 5f6de49dc78e..568818bef28f 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -2677,7 +2677,7 @@ static void rcu_bind_gp_kthread(void)
}
/* Record the current task on dyntick-idle entry. */
-static void rcu_dynticks_task_enter(void)
+static notrace void rcu_dynticks_task_enter(void)
{
#if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL)
WRITE_ONCE(current->rcu_tasks_idle_cpu, smp_processor_id());
@@ -2685,7 +2685,7 @@ static void rcu_dynticks_task_enter(void)
}
/* Record no current task on dyntick-idle exit. */
-static void rcu_dynticks_task_exit(void)
+static notrace void rcu_dynticks_task_exit(void)
{
#if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL)
WRITE_ONCE(current->rcu_tasks_idle_cpu, -1);
--
2.25.1
1
4

14 Jul '22
From: Zheng Yejian <zhengyejian1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 187209, https://gitee.com/openeuler/kernel/issues/I5GWFT
CVE: NA
--------------------------------
Syzkaller report a softlockup problem, see following logs:
[ 41.463870] watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [ksoftirqd/0:9]
[ 41.509763] Modules linked in:
[ 41.512295] CPU: 0 PID: 9 Comm: ksoftirqd/0 Not tainted 4.19.90 #13
[ 41.516134] Hardware name: linux,dummy-virt (DT)
[ 41.519182] pstate: 80c00005 (Nzcv daif +PAN +UAO)
[ 41.522415] pc : perf_trace_buf_alloc+0x138/0x238
[ 41.525583] lr : perf_trace_buf_alloc+0x138/0x238
[ 41.528656] sp : ffff8000c137e880
[ 41.531050] x29: ffff8000c137e880 x28: ffff20000850ced0
[ 41.534759] x27: 0000000000000000 x26: ffff8000c137e9c0
[ 41.538456] x25: ffff8000ce5c2ae0 x24: ffff200008358b08
[ 41.542151] x23: 0000000000000000 x22: ffff2000084a50ac
[ 41.545834] x21: ffff8000c137e880 x20: 000000000000001c
[ 41.549516] x19: ffff7dffbfdf88e8 x18: 0000000000000000
[ 41.553202] x17: 0000000000000000 x16: 0000000000000000
[ 41.556892] x15: 1ffff00036e07805 x14: 0000000000000000
[ 41.560592] x13: 0000000000000004 x12: 0000000000000000
[ 41.564315] x11: 1fffefbff7fbf120 x10: ffff0fbff7fbf120
[ 41.568003] x9 : dfff200000000000 x8 : ffff7dffbfdf8904
[ 41.571699] x7 : 0000000000000000 x6 : ffff0fbff7fbf121
[ 41.575398] x5 : ffff0fbff7fbf121 x4 : ffff0fbff7fbf121
[ 41.579086] x3 : ffff20000850cdc8 x2 : 0000000000000008
[ 41.582773] x1 : ffff8000c1376000 x0 : 0000000000000100
[ 41.586495] Call trace:
[ 41.588922] perf_trace_buf_alloc+0x138/0x238
[ 41.591912] perf_ftrace_function_call+0x1ac/0x248
[ 41.595123] ftrace_ops_no_ops+0x3a4/0x488
[ 41.597998] ftrace_graph_call+0x0/0xc
[ 41.600715] rcu_dynticks_curr_cpu_in_eqs+0x14/0x70
[ 41.603962] rcu_is_watching+0xc/0x20
[ 41.606635] ftrace_ops_no_ops+0x240/0x488
[ 41.609530] ftrace_graph_call+0x0/0xc
[ 41.612249] __read_once_size_nocheck.constprop.0+0x1c/0x38
[ 41.615905] unwind_frame+0x140/0x358
[ 41.618597] walk_stackframe+0x34/0x60
[ 41.621359] __save_stack_trace+0x204/0x3b8
[ 41.624328] save_stack_trace+0x2c/0x38
[ 41.627112] __kasan_slab_free+0x120/0x228
[ 41.630018] kasan_slab_free+0x10/0x18
[ 41.632752] kfree+0x84/0x250
[ 41.635107] skb_free_head+0x70/0xb0
[ 41.637772] skb_release_data+0x3f8/0x730
[ 41.640626] skb_release_all+0x50/0x68
[ 41.643350] kfree_skb+0x84/0x278
[ 41.645890] kfree_skb_list+0x4c/0x78
[ 41.648595] __dev_queue_xmit+0x1a4c/0x23a0
[ 41.651541] dev_queue_xmit+0x28/0x38
[ 41.654254] ip6_finish_output2+0xeb0/0x1630
[ 41.657261] ip6_finish_output+0x2d8/0x7f8
[ 41.660174] ip6_output+0x19c/0x348
[ 41.663850] mld_sendpack+0x560/0x9e0
[ 41.666564] mld_ifc_timer_expire+0x484/0x8a8
[ 41.669624] call_timer_fn+0x68/0x4b0
[ 41.672355] expire_timers+0x168/0x498
[ 41.675126] run_timer_softirq+0x230/0x7a8
[ 41.678052] __do_softirq+0x2d0/0xba0
[ 41.680763] run_ksoftirqd+0x110/0x1a0
[ 41.683512] smpboot_thread_fn+0x31c/0x620
[ 41.686429] kthread+0x2c8/0x348
[ 41.688927] ret_from_fork+0x10/0x18
Look into above call stack, we found a recursive call in
'ftrace_graph_call', see a snippet:
__read_once_size_nocheck.constprop.0
ftrace_graph_call
......
rcu_dynticks_curr_cpu_in_eqs
ftrace_graph_call
We analyze that 'rcu_dynticks_curr_cpu_in_eqs' should not be tracable,
and we verify that mark related functions as 'notrace' can avoid the
problem.
Comparing mainline kernel, we find that commit ff5c4f5cad33 ("rcu/tree:
Mark the idle relevant functions noinstr") mark related functions as
'noinstr' which implies notrace, noinline and sticks things in the
.noinstr.text section.
Link: https://lore.kernel.org/all/20200416114706.625340212@infradead.org/
Currently 'noinstr' mechanism has not been introduced, so we would not
directly backport that commit (otherwise more changes may be introduced).
Instead, we mark the functions as 'notrace' where it is 'noinstr' in
that commit.
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Reviewed-by: Zhen Lei <thunder.leizhen(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
kernel/rcu/tree.c | 22 +++++++++++-----------
kernel/rcu/tree_plugin.h | 4 ++--
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 594d6ea99024..ea05c59096a2 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -275,7 +275,7 @@ static DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
* Record entry into an extended quiescent state. This is only to be
* called when not already in an extended quiescent state.
*/
-static void rcu_dynticks_eqs_enter(void)
+static notrace void rcu_dynticks_eqs_enter(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
int seq;
@@ -298,7 +298,7 @@ static void rcu_dynticks_eqs_enter(void)
* Record exit from an extended quiescent state. This is only to be
* called from an extended quiescent state.
*/
-static void rcu_dynticks_eqs_exit(void)
+static notrace void rcu_dynticks_eqs_exit(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
int seq;
@@ -343,7 +343,7 @@ static void rcu_dynticks_eqs_online(void)
*
* No ordering, as we are sampling CPU-local information.
*/
-bool rcu_dynticks_curr_cpu_in_eqs(void)
+static __always_inline bool rcu_dynticks_curr_cpu_in_eqs(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
@@ -706,7 +706,7 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
* the possibility of usermode upcalls having messed up our count
* of interrupt nesting level during the prior busy period.
*/
-static void rcu_eqs_enter(bool user)
+static notrace void rcu_eqs_enter(bool user)
{
struct rcu_state *rsp;
struct rcu_data *rdp;
@@ -763,7 +763,7 @@ void rcu_idle_enter(void)
* If you add or remove a call to rcu_user_enter(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_user_enter(void)
+notrace void rcu_user_enter(void)
{
lockdep_assert_irqs_disabled();
rcu_eqs_enter(true);
@@ -781,7 +781,7 @@ void rcu_user_enter(void)
* If you add or remove a call to rcu_nmi_exit(), be sure to test
* with CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_nmi_exit(void)
+notrace void rcu_nmi_exit(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
@@ -829,7 +829,7 @@ void rcu_nmi_exit(void)
* If you add or remove a call to rcu_irq_exit(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_irq_exit(void)
+notrace void rcu_irq_exit(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
@@ -864,7 +864,7 @@ void rcu_irq_exit_irqson(void)
* allow for the possibility of usermode upcalls messing up our count of
* interrupt nesting level during the busy period that is just now starting.
*/
-static void rcu_eqs_exit(bool user)
+static notrace void rcu_eqs_exit(bool user)
{
struct rcu_dynticks *rdtp;
long oldval;
@@ -914,7 +914,7 @@ void rcu_idle_exit(void)
* If you add or remove a call to rcu_user_exit(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_user_exit(void)
+void notrace rcu_user_exit(void)
{
rcu_eqs_exit(1);
}
@@ -932,7 +932,7 @@ void rcu_user_exit(void)
* If you add or remove a call to rcu_nmi_enter(), be sure to test
* with CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_nmi_enter(void)
+notrace void rcu_nmi_enter(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
long incby = 2;
@@ -982,7 +982,7 @@ void rcu_nmi_enter(void)
* If you add or remove a call to rcu_irq_enter(), be sure to test with
* CONFIG_RCU_EQS_DEBUG=y.
*/
-void rcu_irq_enter(void)
+notrace void rcu_irq_enter(void)
{
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 5f6de49dc78e..568818bef28f 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -2677,7 +2677,7 @@ static void rcu_bind_gp_kthread(void)
}
/* Record the current task on dyntick-idle entry. */
-static void rcu_dynticks_task_enter(void)
+static notrace void rcu_dynticks_task_enter(void)
{
#if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL)
WRITE_ONCE(current->rcu_tasks_idle_cpu, smp_processor_id());
@@ -2685,7 +2685,7 @@ static void rcu_dynticks_task_enter(void)
}
/* Record no current task on dyntick-idle exit. */
-static void rcu_dynticks_task_exit(void)
+static notrace void rcu_dynticks_task_exit(void)
{
#if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL)
WRITE_ONCE(current->rcu_tasks_idle_cpu, -1);
--
2.25.1
1
4
From: Jiri Slaby <jslaby(a)suse.cz>
stable inclusion
from stable-4.19.250
commit b15d5731b708a2190fec836990b8aefbbf36b07a
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5GKVX
CVE: CVE-2021-33656
--------------------------------
commit ff2047fb755d4415ec3c70ac799889371151796d upstream.
Drop support for these ioctls:
* PIO_FONT, PIO_FONTX
* GIO_FONT, GIO_FONTX
* PIO_FONTRESET
As was demonstrated by commit 90bfdeef83f1 (tty: make FONTX ioctl use
the tty pointer they were actually passed), these ioctls are not used
from userspace, as:
1) they used to be broken (set up font on current console, not the open
one) and racy (before the commit above)
2) KDFONTOP ioctl is used for years instead
Note that PIO_FONTRESET is defunct on most systems as VGA_CONSOLE is set
on them for ages. That turns on BROKEN_GRAPHICS_PROGRAMS which makes
PIO_FONTRESET just return an error.
We are removing KD_FONT_FLAG_OLD here as it was used only by these
removed ioctls. kd.h header exists both in kernel and uapi headers, so
we can remove the kernel one completely. Everyone includeing kd.h will
now automatically get the uapi one.
There are now unused definitions of the ioctl numbers and "struct
consolefontdesc" in kd.h, but as it is a uapi header, I am not touching
these.
Signed-off-by: Jiri Slaby <jslaby(a)suse.cz>
Link: https://lore.kernel.org/r/20210105120239.28031-8-jslaby@suse.cz
Cc: guodaxing <guodaxing(a)huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Xie XiuQi <xiexiuqi(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/tty/vt/vt.c | 39 +---------
drivers/tty/vt/vt_ioctl.c | 149 --------------------------------------
include/linux/kd.h | 8 --
3 files changed, 3 insertions(+), 193 deletions(-)
delete mode 100644 include/linux/kd.h
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 72e3989dffa6..dca627ccece5 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4472,16 +4472,8 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
if (op->data && font.charcount > op->charcount)
rc = -ENOSPC;
- if (!(op->flags & KD_FONT_FLAG_OLD)) {
- if (font.width > op->width || font.height > op->height)
- rc = -ENOSPC;
- } else {
- if (font.width != 8)
- rc = -EIO;
- else if ((op->height && font.height > op->height) ||
- font.height > 32)
- rc = -ENOSPC;
- }
+ if (font.width > op->width || font.height > op->height)
+ rc = -ENOSPC;
if (rc)
goto out;
@@ -4509,7 +4501,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
return -EINVAL;
if (op->charcount > 512)
return -EINVAL;
- if (op->width <= 0 || op->width > 32 || op->height > 32)
+ if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32)
return -EINVAL;
size = (op->width+7)/8 * 32 * op->charcount;
if (size > max_font_size)
@@ -4519,31 +4511,6 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
if (IS_ERR(font.data))
return PTR_ERR(font.data);
- if (!op->height) { /* Need to guess font height [compat] */
- int h, i;
- u8 *charmap = font.data;
-
- /*
- * If from KDFONTOP ioctl, don't allow things which can be done
- * in userland,so that we can get rid of this soon
- */
- if (!(op->flags & KD_FONT_FLAG_OLD)) {
- kfree(font.data);
- return -EINVAL;
- }
-
- for (h = 32; h > 0; h--)
- for (i = 0; i < op->charcount; i++)
- if (charmap[32*i+h-1])
- goto nonzero;
-
- kfree(font.data);
- return -EINVAL;
-
- nonzero:
- op->height = h;
- }
-
font.charcount = op->charcount;
font.width = op->width;
font.height = op->height;
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 13675008d1c7..915b0173b4f8 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -241,48 +241,6 @@ int vt_waitactive(int n)
#define GPLAST 0x3df
#define GPNUM (GPLAST - GPFIRST + 1)
-
-
-static inline int
-do_fontx_ioctl(struct vc_data *vc, int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
-{
- struct consolefontdesc cfdarg;
- int i;
-
- if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
- return -EFAULT;
-
- switch (cmd) {
- case PIO_FONTX:
- if (!perm)
- return -EPERM;
- op->op = KD_FONT_OP_SET;
- op->flags = KD_FONT_FLAG_OLD;
- op->width = 8;
- op->height = cfdarg.charheight;
- op->charcount = cfdarg.charcount;
- op->data = cfdarg.chardata;
- return con_font_op(vc, op);
-
- case GIO_FONTX:
- op->op = KD_FONT_OP_GET;
- op->flags = KD_FONT_FLAG_OLD;
- op->width = 8;
- op->height = cfdarg.charheight;
- op->charcount = cfdarg.charcount;
- op->data = cfdarg.chardata;
- i = con_font_op(vc, op);
- if (i)
- return i;
- cfdarg.charheight = op->height;
- cfdarg.charcount = op->charcount;
- if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
- return -EFAULT;
- return 0;
- }
- return -EINVAL;
-}
-
static inline int
do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
{
@@ -918,30 +876,6 @@ int vt_ioctl(struct tty_struct *tty,
break;
}
- case PIO_FONT: {
- if (!perm)
- return -EPERM;
- op.op = KD_FONT_OP_SET;
- op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
- op.width = 8;
- op.height = 0;
- op.charcount = 256;
- op.data = up;
- ret = con_font_op(vc, &op);
- break;
- }
-
- case GIO_FONT: {
- op.op = KD_FONT_OP_GET;
- op.flags = KD_FONT_FLAG_OLD;
- op.width = 8;
- op.height = 32;
- op.charcount = 256;
- op.data = up;
- ret = con_font_op(vc, &op);
- break;
- }
-
case PIO_CMAP:
if (!perm)
ret = -EPERM;
@@ -953,36 +887,6 @@ int vt_ioctl(struct tty_struct *tty,
ret = con_get_cmap(up);
break;
- case PIO_FONTX:
- case GIO_FONTX:
- ret = do_fontx_ioctl(vc, cmd, up, perm, &op);
- break;
-
- case PIO_FONTRESET:
- {
- if (!perm)
- return -EPERM;
-
-#ifdef BROKEN_GRAPHICS_PROGRAMS
- /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
- font is not saved. */
- ret = -ENOSYS;
- break;
-#else
- {
- op.op = KD_FONT_OP_SET_DEFAULT;
- op.data = NULL;
- ret = con_font_op(vc, &op);
- if (ret)
- break;
- console_lock();
- con_set_default_unimap(vc);
- console_unlock();
- break;
- }
-#endif
- }
-
case KDFONTOP: {
if (copy_from_user(&op, up, sizeof(op))) {
ret = -EFAULT;
@@ -1096,54 +1000,6 @@ void vc_SAK(struct work_struct *work)
#ifdef CONFIG_COMPAT
-struct compat_consolefontdesc {
- unsigned short charcount; /* characters in font (256 or 512) */
- unsigned short charheight; /* scan lines per character (1-32) */
- compat_caddr_t chardata; /* font data in expanded form */
-};
-
-static inline int
-compat_fontx_ioctl(struct vc_data *vc, int cmd,
- struct compat_consolefontdesc __user *user_cfd,
- int perm, struct console_font_op *op)
-{
- struct compat_consolefontdesc cfdarg;
- int i;
-
- if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
- return -EFAULT;
-
- switch (cmd) {
- case PIO_FONTX:
- if (!perm)
- return -EPERM;
- op->op = KD_FONT_OP_SET;
- op->flags = KD_FONT_FLAG_OLD;
- op->width = 8;
- op->height = cfdarg.charheight;
- op->charcount = cfdarg.charcount;
- op->data = compat_ptr(cfdarg.chardata);
- return con_font_op(vc, op);
-
- case GIO_FONTX:
- op->op = KD_FONT_OP_GET;
- op->flags = KD_FONT_FLAG_OLD;
- op->width = 8;
- op->height = cfdarg.charheight;
- op->charcount = cfdarg.charcount;
- op->data = compat_ptr(cfdarg.chardata);
- i = con_font_op(vc, op);
- if (i)
- return i;
- cfdarg.charheight = op->height;
- cfdarg.charcount = op->charcount;
- if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
- return -EFAULT;
- return 0;
- }
- return -EINVAL;
-}
-
struct compat_console_font_op {
compat_uint_t op; /* operation code KD_FONT_OP_* */
compat_uint_t flags; /* KD_FONT_FLAG_* */
@@ -1221,11 +1077,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
/*
* these need special handlers for incompatible data structures
*/
- case PIO_FONTX:
- case GIO_FONTX:
- ret = compat_fontx_ioctl(vc, cmd, up, perm, &op);
- break;
-
case KDFONTOP:
ret = compat_kdfontop_ioctl(up, perm, &op, vc);
break;
diff --git a/include/linux/kd.h b/include/linux/kd.h
deleted file mode 100644
index b130a18f860f..000000000000
--- a/include/linux/kd.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _LINUX_KD_H
-#define _LINUX_KD_H
-
-#include <uapi/linux/kd.h>
-
-#define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface [compat] */
-#endif /* _LINUX_KD_H */
--
2.25.1
1
3

[PATCH openEuler-1.0-LTS] dm thin: Fix crash in dm_sm_register_threshold_callback()
by Yongqiang Liu 13 Jul '22
by Yongqiang Liu 13 Jul '22
13 Jul '22
From: Luo Meng <luomeng12(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5GRX6
CVE: NA
--------------------------------
Fault inject on pool metadata device report:
BUG: KASAN: use-after-free in dm_pool_register_metadata_threshold+0x40/0x80
Read of size 8 at addr ffff8881b9d50068 by task dmsetup/950
CPU: 7 PID: 950 Comm: dmsetup Tainted: G W 5.19.0-rc6 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x34/0x44
print_address_description.constprop.0.cold+0xeb/0x3f4
kasan_report.cold+0xe6/0x147
dm_pool_register_metadata_threshold+0x40/0x80
pool_ctr+0xa0a/0x1150
dm_table_add_target+0x2c8/0x640
table_load+0x1fd/0x430
ctl_ioctl+0x2c4/0x5a0
dm_ctl_ioctl+0xa/0x10
__x64_sys_ioctl+0xb3/0xd0
do_syscall_64+0x35/0x80
entry_SYSCALL_64_after_hwframe+0x46/0xb0
This can be easy reproduce:
echo offline > /sys/block/sda/device/state
dd if=/dev/zero of=/dev/mapper/thin bs=4k count=10
dmsetup load pool --table "0 20971520 thin-pool /dev/sda /dev/sdb 128 0 0"
If metadata commit failed, the transaction will be aborted and the metadata
space manager will be destroyed. If load table on this pool, when register the
metadata threshold callback, the UAF will happen on metadata space manager.
So return error when load table if the pool is on FAIL status.
Fixes: ac8c3f3df65e4 ("dm thin: generate event when metadata threshold passed")
Reported-by: Hulk Robot <hulkci(a)huawei.com>
Signed-off-by: Luo Meng <luomeng12(a)huawei.com>
Reviewed-by: Hou Tao <houtao1(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/md/dm-thin-metadata.c | 8 +++++++-
drivers/md/dm-thin.c | 4 +++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index a6a5cee6b943..c3dc171114dc 100644
--- a/drivers/md/dm-thin-metadata.c
+++ b/drivers/md/dm-thin-metadata.c
@@ -1997,9 +1997,15 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
int r;
down_write(&pmd->root_lock);
+ if (pmd->fail_io) {
+ r = -EINVAL;
+ goto out;
+ }
+
r = dm_sm_register_threshold_callback(pmd->metadata_sm, threshold, fn, context);
- up_write(&pmd->root_lock);
+out:
+ up_write(&pmd->root_lock);
return r;
}
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 435a2ee4a392..2b6dd7a275eb 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -3383,8 +3383,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
calc_metadata_threshold(pt),
metadata_low_callback,
pool);
- if (r)
+ if (r) {
+ ti->error = "Error registering metadata threshold";
goto out_flags_changed;
+ }
pt->callbacks.congested_fn = pool_is_congested;
dm_table_add_target_callbacks(ti->table, &pt->callbacks);
--
2.25.1
1
0

13 Jul '22
From: Li Lingfeng <lilingfeng3(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5DI4S
CVE: NA
Reference: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/commit…
---------------------------
We don't really need the field names to be globally unique, it is enough
when they are unique in the given struct. Since structs do not generally
span mutliple files, using the line number is enough to ensure an unique
identifier. It means that we can't use two KABI_RENAME macros on the same
line but that's not happening anyway.
This allows pahole to deduplicate the type info of structs using KABI
macros, lowering the size of vmlinuz from 26M to 8.5
Signed-off-by: Li Lingfeng <lilingfeng3(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/linux/kabi.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/kabi.h b/include/linux/kabi.h
index a52d9fa72cfa..fe3213c0f576 100644
--- a/include/linux/kabi.h
+++ b/include/linux/kabi.h
@@ -393,6 +393,8 @@
# define __KABI_CHECK_SIZE(_item, _size)
#endif
+#define KABI_UNIQUE_ID __PASTE(kabi_hidden_, __LINE__)
+
# define _KABI_DEPRECATE(_type, _orig) _type kabi_reserved_##_orig
# define _KABI_DEPRECATE_FN(_type, _orig, _args...) \
_type (* kabi_reserved_##_orig)(_args)
@@ -402,7 +404,7 @@
_new; \
struct { \
_orig; \
- } __UNIQUE_ID(kabi_hide); \
+ } KABI_UNIQUE_ID; \
__KABI_CHECK_SIZE_ALIGN(_orig, _new); \
}
#else
--
2.20.1
1
20

[PATCH openEuler-1.0-LTS 1/6] xen/blkfront: fix memory allocation flags in blkfront_setup_indirect()
by Yongqiang Liu 13 Jul '22
by Yongqiang Liu 13 Jul '22
13 Jul '22
From: Juergen Gross <jgross(a)suse.com>
stable inclusion
from stable-v4.19.116
commit 5f547e7cbd8435be3aa2a27e2ae594b4fd94865b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5GLXT
CVE: CVE-2022-26365
--------------------------------
commit 3a169c0be75b59dd85d159493634870cdec6d3c4 upstream.
Commit 1d5c76e664333 ("xen-blkfront: switch kcalloc to kvcalloc for
large array allocation") didn't fix the issue it was meant to, as the
flags for allocating the memory are GFP_NOIO, which will lead the
memory allocation falling back to kmalloc().
So instead of GFP_NOIO use GFP_KERNEL and do all the memory allocation
in blkfront_setup_indirect() in a memalloc_noio_{save,restore} section.
Fixes: 1d5c76e664333 ("xen-blkfront: switch kcalloc to kvcalloc for large array allocation")
Cc: stable(a)vger.kernel.org
Signed-off-by: Juergen Gross <jgross(a)suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky(a)oracle.com>
Acked-by: Roger Pau Monné <roger.pau(a)citrix.com>
Link: https://lore.kernel.org/r/20200403090034.8753-1-jgross@suse.com
Signed-off-by: Juergen Gross <jgross(a)suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: ChenXiaoSong <chenxiaosong2(a)huawei.com>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/block/xen-blkfront.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 0e451b17f33a..8059ff5ab4a6 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -47,6 +47,7 @@
#include <linux/bitmap.h>
#include <linux/list.h>
#include <linux/workqueue.h>
+#include <linux/sched/mm.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@@ -2251,10 +2252,12 @@ static void blkfront_setup_discard(struct blkfront_info *info)
static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
{
- unsigned int psegs, grants;
+ unsigned int psegs, grants, memflags;
int err, i;
struct blkfront_info *info = rinfo->dev_info;
+ memflags = memalloc_noio_save();
+
if (info->max_indirect_segments == 0) {
if (!HAS_EXTRA_REQ)
grants = BLKIF_MAX_SEGMENTS_PER_REQUEST;
@@ -2286,7 +2289,7 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
BUG_ON(!list_empty(&rinfo->indirect_pages));
for (i = 0; i < num; i++) {
- struct page *indirect_page = alloc_page(GFP_NOIO);
+ struct page *indirect_page = alloc_page(GFP_KERNEL);
if (!indirect_page)
goto out_of_memory;
list_add(&indirect_page->lru, &rinfo->indirect_pages);
@@ -2297,15 +2300,15 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
rinfo->shadow[i].grants_used =
kvcalloc(grants,
sizeof(rinfo->shadow[i].grants_used[0]),
- GFP_NOIO);
+ GFP_KERNEL);
rinfo->shadow[i].sg = kvcalloc(psegs,
sizeof(rinfo->shadow[i].sg[0]),
- GFP_NOIO);
+ GFP_KERNEL);
if (info->max_indirect_segments)
rinfo->shadow[i].indirect_grants =
kvcalloc(INDIRECT_GREFS(grants),
sizeof(rinfo->shadow[i].indirect_grants[0]),
- GFP_NOIO);
+ GFP_KERNEL);
if ((rinfo->shadow[i].grants_used == NULL) ||
(rinfo->shadow[i].sg == NULL) ||
(info->max_indirect_segments &&
@@ -2314,6 +2317,7 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
sg_init_table(rinfo->shadow[i].sg, psegs);
}
+ memalloc_noio_restore(memflags);
return 0;
@@ -2333,6 +2337,9 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
__free_page(indirect_page);
}
}
+
+ memalloc_noio_restore(memflags);
+
return -ENOMEM;
}
--
2.25.1
1
5

[PATCH openEuler-5.10 01/23] blk-throttle: fix io hung due to configuration updates
by Zheng Zengkai 12 Jul '22
by Zheng Zengkai 12 Jul '22
12 Jul '22
From: Yu Kuai <yukuai3(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I58VE5
CVE: NA
--------------------------------
If new configuration is submitted while a bio is throttled, then new
waiting time is recaculated regardless that the bio might aready wait
for some time:
tg_conf_updated
throtl_start_new_slice
tg_update_disptime
throtl_schedule_next_dispatch
Then io hung can be triggered by always submmiting new configuration
before the throttled bio is dispatched.
Fix the problem by respecting the time that throttled bio aready waited.
In order to do that, instead of start new slice in tg_conf_updated(),
just update 'bytes_disp' and 'io_disp' based on the new configuration.
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
block/blk-throttle.c | 79 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 66 insertions(+), 13 deletions(-)
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 95a13da1f343..0427c9c63e81 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -1421,7 +1421,57 @@ static int tg_print_conf_uint(struct seq_file *sf, void *v)
return 0;
}
-static void tg_conf_updated(struct throtl_grp *tg, bool global)
+static u64 throtl_update_bytes_disp(u64 dispatched, u64 new_limit,
+ u64 old_limit)
+{
+ if (new_limit == old_limit)
+ return dispatched;
+
+ if (!dispatched)
+ return 0;
+
+ /*
+ * In the case that multiply will overflow, just return 0. It will only
+ * let bios to be dispatched earlier.
+ */
+ if (div64_u64(U64_MAX, dispatched) < new_limit)
+ return 0;
+
+ dispatched *= new_limit;
+ return div64_u64(dispatched, old_limit);
+}
+
+static u32 throtl_update_io_disp(u32 dispatched, u32 new_limit, u32 old_limit)
+{
+ if (new_limit == old_limit)
+ return dispatched;
+
+ if (!dispatched)
+ return 0;
+ /*
+ * In the case that multiply will overflow, just return 0. It will only
+ * let bios to be dispatched earlier.
+ */
+ if (UINT_MAX / dispatched < new_limit)
+ return 0;
+
+ dispatched *= new_limit;
+ return dispatched / old_limit;
+}
+
+static void throtl_update_slice(struct throtl_grp *tg, u64 *old_limits)
+{
+ tg->bytes_disp[READ] = throtl_update_bytes_disp(tg->bytes_disp[READ],
+ tg_bps_limit(tg, READ), old_limits[0]);
+ tg->bytes_disp[WRITE] = throtl_update_bytes_disp(tg->bytes_disp[WRITE],
+ tg_bps_limit(tg, WRITE), old_limits[1]);
+ tg->io_disp[READ] = throtl_update_io_disp(tg->io_disp[READ],
+ tg_iops_limit(tg, READ), (u32)old_limits[2]);
+ tg->io_disp[WRITE] = throtl_update_io_disp(tg->io_disp[WRITE],
+ tg_iops_limit(tg, WRITE), (u32)old_limits[3]);
+}
+
+static void tg_conf_updated(struct throtl_grp *tg, u64 *old_limits, bool global)
{
struct throtl_service_queue *sq = &tg->service_queue;
struct cgroup_subsys_state *pos_css;
@@ -1460,16 +1510,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global)
parent_tg->latency_target);
}
- /*
- * We're already holding queue_lock and know @tg is valid. Let's
- * apply the new config directly.
- *
- * Restart the slices for both READ and WRITES. It might happen
- * that a group's limit are dropped suddenly and we don't want to
- * account recently dispatched IO with new low rate.
- */
- throtl_start_new_slice(tg, READ);
- throtl_start_new_slice(tg, WRITE);
+ throtl_update_slice(tg, old_limits);
if (tg->flags & THROTL_TG_PENDING) {
tg_update_disptime(tg);
@@ -1502,6 +1543,14 @@ static inline int throtl_restart_syscall_when_busy(int errno)
return ret;
}
+static void tg_get_limits(struct throtl_grp *tg, u64 *limits)
+{
+ limits[0] = tg_bps_limit(tg, READ);
+ limits[1] = tg_bps_limit(tg, WRITE);
+ limits[2] = tg_iops_limit(tg, READ);
+ limits[3] = tg_iops_limit(tg, WRITE);
+}
+
static ssize_t tg_set_conf(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off, bool is_u64)
{
@@ -1510,6 +1559,7 @@ static ssize_t tg_set_conf(struct kernfs_open_file *of,
struct throtl_grp *tg;
int ret;
u64 v;
+ u64 old_limits[4];
ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, buf, &ctx);
if (ret)
@@ -1526,13 +1576,14 @@ static ssize_t tg_set_conf(struct kernfs_open_file *of,
v = U64_MAX;
tg = blkg_to_tg(ctx.blkg);
+ tg_get_limits(tg, old_limits);
if (is_u64)
*(u64 *)((void *)tg + of_cft(of)->private) = v;
else
*(unsigned int *)((void *)tg + of_cft(of)->private) = v;
- tg_conf_updated(tg, false);
+ tg_conf_updated(tg, old_limits, false);
ret = 0;
out_finish:
blkg_conf_finish(&ctx);
@@ -1703,6 +1754,7 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
struct blkg_conf_ctx ctx;
struct throtl_grp *tg;
u64 v[4];
+ u64 old_limits[4];
unsigned long idle_time;
unsigned long latency_time;
int ret;
@@ -1721,6 +1773,7 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
v[1] = tg->bps_conf[WRITE][index];
v[2] = tg->iops_conf[READ][index];
v[3] = tg->iops_conf[WRITE][index];
+ tg_get_limits(tg, old_limits);
idle_time = tg->idletime_threshold_conf;
latency_time = tg->latency_target_conf;
@@ -1807,7 +1860,7 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,
tg->td->limit_index = LIMIT_LOW;
} else
tg->td->limit_index = LIMIT_MAX;
- tg_conf_updated(tg, index == LIMIT_LOW &&
+ tg_conf_updated(tg, old_limits, index == LIMIT_LOW &&
tg->td->limit_valid[LIMIT_LOW]);
ret = 0;
out_finish:
--
2.20.1
1
22

[PATCH openEuler-1.0-LTS 1/2] tmpfs: fix undefined-behaviour in shmem_reconfigure()
by Yongqiang Liu 12 Jul '22
by Yongqiang Liu 12 Jul '22
12 Jul '22
From: Luo Meng <luomeng12(a)huawei.com>
mainline inclusion
from mainline-v5.19-rc3
commit d14f5efadd846dbde561bd734318de6a9e6b26e6
category: bugfix
bugzilla: 186471 https://gitee.com/openeuler/kernel/issues/I5DRKR
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
----------------------------------------------------------------------
When shmem_reconfigure() calls __percpu_counter_compare(), the second
parameter is unsigned long long. But in the definition of
__percpu_counter_compare(), the second parameter is s64. So when
__percpu_counter_compare() executes abs(count - rhs), UBSAN shows the
following warning:
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
================================================================================
UBSAN: Undefined behaviour in lib/percpu_counter.c:209:6
signed integer overflow:
0 - -9223372036854775808 cannot be represented in type 'long long int'
CPU: 1 PID: 9636 Comm: syz-executor.2 Tainted: G ---------r- - 4.18.0 #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
Call Trace:
__dump_stack home/install/linux-rh-3-10/lib/dump_stack.c:77 [inline]
dump_stack+0x125/0x1ae home/install/linux-rh-3-10/lib/dump_stack.c:117
ubsan_epilogue+0xe/0x81 home/install/linux-rh-3-10/lib/ubsan.c:159
handle_overflow+0x19d/0x1ec home/install/linux-rh-3-10/lib/ubsan.c:190
__percpu_counter_compare+0x124/0x140 home/install/linux-rh-3-10/lib/percpu_counter.c:209
percpu_counter_compare home/install/linux-rh-3-10/./include/linux/percpu_counter.h:50 [inline]
shmem_remount_fs+0x1ce/0x6b0 home/install/linux-rh-3-10/mm/shmem.c:3530
do_remount_sb+0x11b/0x530 home/install/linux-rh-3-10/fs/super.c:888
do_remount home/install/linux-rh-3-10/fs/namespace.c:2344 [inline]
do_mount+0xf8d/0x26b0 home/install/linux-rh-3-10/fs/namespace.c:2844
ksys_mount+0xad/0x120 home/install/linux-rh-3-10/fs/namespace.c:3075
__do_sys_mount home/install/linux-rh-3-10/fs/namespace.c:3089 [inline]
__se_sys_mount home/install/linux-rh-3-10/fs/namespace.c:3086 [inline]
__x64_sys_mount+0xbf/0x160 home/install/linux-rh-3-10/fs/namespace.c:3086
do_syscall_64+0xca/0x5c0 home/install/linux-rh-3-10/arch/x86/entry/common.c:298
entry_SYSCALL_64_after_hwframe+0x6a/0xdf
RIP: 0033:0x46b5e9
Code: 5d db fa ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 2b db fa ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f54d5f22c68 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 000000000077bf60 RCX: 000000000046b5e9
RDX: 0000000000000000 RSI: 0000000020000000 RDI: 0000000000000000
RBP: 000000000077bf60 R08: 0000000020000140 R09: 0000000000000000
R10: 00000000026740a4 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffd1fb1592f R14: 00007f54d5f239c0 R15: 000000000077bf6c
================================================================================
[akpm(a)linux-foundation.org: tweak error message text]
Link: https://lkml.kernel.org/r/20220513025225.2678727-1-luomeng12@huawei.com
Signed-off-by: Luo Meng <luomeng12(a)huawei.com>
Cc: Hugh Dickins <hughd(a)google.com>
Cc: Yu Kuai <yukuai3(a)huawei.com>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Conflicts:
mm/shmem.c
Signed-off-by: ZhaoLong Wang <wangzhaolong1(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/shmem.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/mm/shmem.c b/mm/shmem.c
index 8915a5b9ad0a..be91fb743426 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3605,6 +3605,10 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
spin_lock(&sbinfo->stat_lock);
inodes = sbinfo->max_inodes - sbinfo->free_inodes;
+ if (config.max_blocks > S64_MAX) {
+ pr_err("Number of blocks too large");
+ goto out;
+ }
if (percpu_counter_compare(&sbinfo->used_blocks, config.max_blocks) > 0)
goto out;
if (config.max_inodes < inodes)
--
2.25.1
1
1

[PATCH openEuler-1.0-LTS] mm/sharepool: Check sp_is_enabled() before show spa_stat
by Yongqiang Liu 12 Jul '22
by Yongqiang Liu 12 Jul '22
12 Jul '22
From: Wang Wensheng <wangwensheng4(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5GO4E
CVE: NA
--------------------------------
When we read file /proc/sharepool/spa_stat, we use sp_mapping_normal to
iterator all the normal sp_area. The global pointer sp_mapping_normal is
NULL if the sharepool feature is not enabled via kernel bootarg. This
leads to a null-pointer-dereference issue.
Signed-off-by: Wang Wensheng <wangwensheng4(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/share_pool.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/share_pool.c b/mm/share_pool.c
index 893e5352bf01..661036a7df64 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -4365,6 +4365,9 @@ void spg_overview_show(struct seq_file *seq)
static int spa_stat_show(struct seq_file *seq, void *offset)
{
+ if (!sp_is_enabled())
+ return 0;
+
spg_overview_show(seq);
spa_overview_show(seq);
/* print the file header */
@@ -4425,6 +4428,9 @@ static int idr_proc_stat_cb(int id, void *p, void *data)
static int proc_stat_show(struct seq_file *seq, void *offset)
{
+ if (!sp_is_enabled())
+ return 0;
+
spg_overview_show(seq);
spa_overview_show(seq);
/* print the file header */
@@ -4474,6 +4480,9 @@ static int idr_proc_overview_cb(int id, void *p, void *data)
static int proc_overview_show(struct seq_file *seq, void *offset)
{
+ if (!sp_is_enabled())
+ return 0;
+
seq_printf(seq, "%-8s %-16s %-9s %-9s %-9s %-10s %-10s %-8s\n",
"PID", "COMM", "SP_ALLOC", "SP_K2U", "SP_RES", "Non-SP_RES",
"Non-SP_Shm", "VIRT");
--
2.25.1
1
0

12 Jul '22
From: Zheng Chongzhen <zhengchongzhen(a)wxiat.com>
Sunway inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OSP
--------------------------------
When porting ZX200 chipset driver on SW64 platform, we meet an IOMMU
exception show as follows:
iommu_interrupt, iommu_status = 0xc8014000dffe0000, devid 0xa00, dva 0xdffe0000,
1Unable to handle kernel paging request at virtual address 0000000000000040
CPU 0 swapper/0(0): Oops 0
pc = [<ffffffff81424b80>] ra = [<ffffffff81424b24>] ps = 0001 Not tainted
pc is at iommu_interrupt+0x140/0x3e0
ra is at iommu_interrupt+0xe4/0x3e0
v0 = 0000000000000051 t0 = c8014000dffe0000 t1 = 0000000000000000
t2 = 0000000000000000 t3 = 0000000000000000 t4 = 0000000000000001
t5 = 0000000000000001 t6 = 0000000000000000 t7 = ffffffff82948000
s0 = fff00003ffff0400 s1 = 0000000000000001 s2 = 0000000000000a00
s3 = 0000000000000a00 s4 = 00000000dffe0000 s5 = fff0000100680e80
s6 = ffffffff8294ba70
a0 = 0000000000000001 a1 = 0000000000000001 a2 = ffffffff8294b790
a3 = ffffffff8294b7a8 a4 = 0000000000000000 a5 = ffffffff82c5fb7a
t8 = 0000000000000001 t9 = fffffffffffcac48 t10 = 0000000000000000
t11= 0000000000000000 pv = ffffffff809f4f10 at = ffffffff82bff6c0
gp = ffffffff82c1f510 sp = (____ptrval____)
The root cause is that the device which raises iommu exception is not in the
device list, then reference a null sdev will cause a page fualt. To work
around this problem, we apply this patch by just clearing IOMMUEXCPT_STATUS
and then go on.
BTW, why the device raise IOMMU exception is not a valid device ID, it's a
puzzling problem.
Signed-off-by: Zheng Chongzhen <zhengchongzhen(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
drivers/iommu/sw64/sunway_iommu.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/sw64/sunway_iommu.c b/drivers/iommu/sw64/sunway_iommu.c
index 5797adf8fbc5..b6c8f1272d28 100644
--- a/drivers/iommu/sw64/sunway_iommu.c
+++ b/drivers/iommu/sw64/sunway_iommu.c
@@ -648,10 +648,21 @@ irqreturn_t iommu_interrupt(int irq, void *dev)
type = (iommu_status >> 59) & 0x7;
devid = (iommu_status >> 37) & 0xffff;
dva = iommu_status & 0xffffffff;
- sdev = search_dev_data(devid);
- sdomain = sdev->domain;
pr_info("%s, iommu_status = %#lx, devid %#lx, dva %#lx, ",
__func__, iommu_status, devid, dva);
+
+ sdev = search_dev_data(devid);
+ if (sdev == NULL) {
+ pr_info("no such dev!!!\n");
+
+ iommu_status &= ~(1UL << 62);
+ write_piu_ior0(hose->node, hose->index,
+ IOMMUEXCPT_STATUS, iommu_status);
+
+ return IRQ_HANDLED;
+ }
+
+ sdomain = sdev->domain;
switch (type) {
case DTE_LEVEL1:
pr_info("invalid level1 dte, addr:%#lx, val:%#lx\n",
@@ -674,7 +685,6 @@ irqreturn_t iommu_interrupt(int irq, void *dev)
fetch_pte(sdomain, dva, PTE_LEVEL2_VAL));
iommu_status &= ~(1UL << 62);
- iommu_status = iommu_status | (1UL << 63);
write_piu_ior0(hose->node, hose->index,
IOMMUEXCPT_STATUS, iommu_status);
break;
--
2.17.1
1
20
Gu Zitao (2):
sw64: add ARCH_TRACEHOOK and regset support
sw64: rename CONFIG_HAVE_GENERIC_GUP to CONFIG_HAVE_FAST_GUP
Hang Xiaoqian (2):
sw64: change the value of physical_id in /proc/cpuinfo
sw64: remove unaligned count
He Chuyue (6):
sw64: simplify __phys_addr and __virt_addr_valid
sw64: check integrity for dtb passed by BIOS
sw64: fix some structs related to pt_regs
sw64: perf: add exclude_user and exclude_kernel support
sw64: perf: fix the number of supported raw events
sw64: perf: fix raw event count
He Sheng (36):
sw64: remove unused header files
sw64: uapi: generate some uapi headers from generic ones
sw64: uapi: include generic param.h
sw64: kapi: remove unused header-y from Kbuild
sw64: kapi: generate some kapi headers from generic ones
sw64: move ucontext.h to uapi
sw64: kapi: remove redudant SMP_CACHE_BYTES
sw64: kapi: remove unimplemented IPLs
sw64: kapi: include generic modules.h
sw64: remove VGA_HOSE things
sw64: clean up unused pci iounmap operation
sw64: kapi: use generic vga.h
sw64: remove unused IO_CONCAT
sw64: do not include sw64io.h in io.h
sw64: read host IO registers with rdio64 hmcall
sw64: map logical address with __va()
sw64: access IO space with readX/writeX
sw64: add fpu state save/restore interfaces
sw64: switch to generic fork like system calls
sw64: remove r9_r15 argument of dik_show_regs and die_if_kernel
sw64: remove switch_stack from entMM and entSys
sw64: remove switch_stack from signal handling
sw64: dump callee-saved registers from pt_regs
sw64: get blocked thread's frame pointer from thread_struct
sw64: remove switch_stack and allregs from entUna
sw64: remove switch_stack from __sw64_vcpu_run
sw64: remove other struct switch_stack things
sw64: access pt_regs with regoffsets where appropriate
sw64: move struct pt_regs to kapi ptrace.h
sw64: avoid copying thread_struct twice
sw64: simplify pgtable helpers
sw64: remove discontiguous memory support
sw64: merge user_fpsimd_state into thread_struct
sw64: fix ptrace.h with types.h and NOT __ASSEMBLY__
sw64: rewrite elf core copy interfaces
sw64: rename debugfs dir sw_64 to sw64
Lu Feifei (2):
sw64: add memhotplug support for guest os
sw64: add a misc device to chip_vt.dts for memory-hotplug
Mao Minkai (2):
sw64: fix __csum_and_copy when dest is not 8-byte aligned
sw64: fix simd version of memset
Min Fanlei (1):
sw64: kvm: fix incorrect page_ref_count() call
Wang Yuanheng (1):
sw64: kvm: enable binding_vcpu debug dynamically
Wu Liliu (4):
sw64: perf: add fp based stack trace support
sw64: reimplement show_stack() method
sw64: reimplement get_wchan()
sw64: reimplement save_stack_trace()
Xiong Aifei (2):
sw64: gpu: correct low-level mmio memset/memcpy direct calls
sw64: gpu: replace '_memset_c_io' by 'memset_io'
Xu Chenjiao (2):
sw64: fix compile errors for NOT chip3
sw64: pcie: fix lack of PME and AER interrupt service routines
Yang Qiang (2):
sw64: dtb: check address validity with physical address
sw64: pci: fix maximum bus number for pci scan
Zhao Yihan (1):
sw64: map address by OR operation in __va()
Zheng Chongzhen (2):
sw64: fix dma features for zx200
sw64: iommu: fix iommu interrupt handler
Zhou Qihang (1):
sw64: iommu: work around iova mapping on pci bars
Zhou Xuemei (1):
sw64: fix floating point register corruption
Zhu Donghong (4):
irqchip: add sw64 chip3 builtin LPC interrupt controller driver
sw64: add builtin LPC interrupt controller to chip3.dts
drivers/irqchip: add sw64 interrupt controller support
sw64: deliver a hot reset to Root Complex with plugin JMicron 585 card
arch/sw_64/Kconfig | 28 +-
arch/sw_64/boot/dts/chip3.dts | 16 +-
arch/sw_64/boot/dts/chip_vt.dts | 12 +
arch/sw_64/chip/chip3/Makefile | 1 -
arch/sw_64/chip/chip3/chip.c | 66 ++-
arch/sw_64/chip/chip3/i2c-lib.c | 41 +-
arch/sw_64/include/asm/Kbuild | 26 +-
arch/sw_64/include/asm/agp.h | 19 -
arch/sw_64/include/asm/asm-prototypes.h | 1 -
arch/sw_64/include/asm/cache.h | 4 +-
arch/sw_64/include/asm/compiler.h | 7 -
arch/sw_64/include/asm/console.h | 11 -
arch/sw_64/include/asm/div64.h | 7 -
arch/sw_64/include/asm/elf.h | 40 +-
arch/sw_64/include/asm/emergency-restart.h | 7 -
arch/sw_64/include/asm/exec.h | 7 -
arch/sw_64/include/asm/extable.h | 4 +
arch/sw_64/include/asm/floppy.h | 116 -----
arch/sw_64/include/asm/hcall.h | 1 +
arch/sw_64/include/asm/io.h | 33 --
arch/sw_64/include/asm/irq_impl.h | 3 +
arch/sw_64/include/asm/irq_regs.h | 7 -
arch/sw_64/include/asm/irqflags.h | 8 -
arch/sw_64/include/asm/kmap_types.h | 15 -
arch/sw_64/include/asm/kvm_asm.h | 3 +
arch/sw_64/include/asm/kvm_host.h | 11 +-
arch/sw_64/include/asm/local.h | 125 -----
arch/sw_64/include/asm/local64.h | 7 -
arch/sw_64/include/asm/memory.h | 1 +
arch/sw_64/include/asm/mmu_context.h | 8 +-
arch/sw_64/include/asm/mmzone.h | 30 --
arch/sw_64/include/asm/module.h | 10 +-
arch/sw_64/include/asm/page.h | 5 +-
arch/sw_64/include/asm/param.h | 11 -
arch/sw_64/include/asm/parport.h | 19 -
arch/sw_64/include/asm/pci.h | 4 +-
arch/sw_64/include/asm/pgalloc.h | 2 +-
arch/sw_64/include/asm/pgtable.h | 98 ++--
arch/sw_64/include/asm/preempt.h | 7 -
arch/sw_64/include/asm/processor.h | 49 +-
arch/sw_64/include/asm/ptrace.h | 54 +-
arch/sw_64/include/asm/seccomp.h | 15 -
arch/sw_64/include/asm/sections.h | 8 -
arch/sw_64/include/asm/segment.h | 7 -
arch/sw_64/include/asm/serial.h | 16 -
arch/sw_64/include/asm/shmparam.h | 7 -
arch/sw_64/include/asm/special_insns.h | 20 -
arch/sw_64/include/asm/stacktrace.h | 72 +++
arch/sw_64/include/asm/sw64_init.h | 1 +
arch/sw_64/include/asm/sw64io.h | 89 ++--
arch/sw_64/include/asm/switch_to.h | 37 +-
arch/sw_64/include/asm/thread_info.h | 5 +
arch/sw_64/include/asm/trace_clock.h | 10 -
arch/sw_64/include/asm/types.h | 7 -
arch/sw_64/include/asm/unaligned.h | 12 -
arch/sw_64/include/asm/vga.h | 85 ----
arch/sw_64/include/asm/wrperfmon.h | 8 +-
arch/sw_64/include/uapi/asm/Kbuild | 1 +
arch/sw_64/include/uapi/asm/console.h | 51 --
arch/sw_64/include/uapi/asm/ipcbuf.h | 7 -
arch/sw_64/include/uapi/asm/kvm_para.h | 7 -
arch/sw_64/include/uapi/asm/msgbuf.h | 28 --
arch/sw_64/include/uapi/asm/param.h | 9 +-
arch/sw_64/include/uapi/asm/perf_regs.h | 7 +
arch/sw_64/include/uapi/asm/poll.h | 7 -
arch/sw_64/include/uapi/asm/posix_types.h | 18 -
arch/sw_64/include/uapi/asm/ptrace.h | 76 +--
arch/sw_64/include/uapi/asm/sembuf.h | 23 -
arch/sw_64/include/uapi/asm/shmbuf.h | 39 --
arch/sw_64/include/uapi/asm/statfs.h | 9 -
arch/sw_64/include/uapi/asm/types.h | 28 --
arch/sw_64/include/{ => uapi}/asm/ucontext.h | 8 +-
arch/sw_64/kernel/Makefile | 7 +-
arch/sw_64/kernel/asm-offsets.c | 136 ++---
arch/sw_64/kernel/bindvcpu.c | 29 ++
arch/sw_64/kernel/core.c | 35 --
arch/sw_64/kernel/dup_print.c | 10 +-
arch/sw_64/kernel/entry.S | 467 +++++-------------
arch/sw_64/kernel/fpu.S | 102 ++++
arch/sw_64/kernel/kgdb.c | 14 +-
arch/sw_64/kernel/pci.c | 55 ++-
arch/sw_64/kernel/pci_impl.h | 2 +
arch/sw_64/kernel/perf_event.c | 100 +++-
arch/sw_64/kernel/process.c | 156 ++----
arch/sw_64/kernel/proto.h | 5 +-
arch/sw_64/kernel/ptrace.c | 245 ++++-----
arch/sw_64/kernel/setup.c | 19 +-
arch/sw_64/kernel/signal.c | 51 +-
arch/sw_64/kernel/stacktrace.c | 212 +++++++-
arch/sw_64/kernel/syscalls/syscall.tbl | 6 +-
arch/sw_64/kernel/traps.c | 182 ++-----
arch/sw_64/kernel/unaligned.c | 56 ---
arch/sw_64/kvm/Kconfig | 7 +
arch/sw_64/kvm/entry.S | 97 ++--
arch/sw_64/kvm/handle_exit.c | 5 +
arch/sw_64/kvm/kvm-sw64.c | 137 ++++-
arch/sw_64/lib/csum_partial_copy.c | 15 +-
arch/sw_64/lib/deep-memset.S | 5 +-
arch/sw_64/lib/iomap.c | 40 +-
arch/sw_64/mm/fault.c | 20 +-
arch/sw_64/mm/init.c | 25 +-
arch/sw_64/mm/physaddr.c | 30 +-
arch/sw_64/platform/platform_xuelang.c | 18 +-
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 12 +
drivers/gpu/drm/radeon/radeon_vce.c | 2 +-
drivers/gpu/drm/radeon/vce_v1_0.c | 5 +
drivers/iommu/sw64/sunway_iommu.c | 21 +-
drivers/irqchip/Kconfig | 26 +-
drivers/irqchip/Makefile | 3 +-
drivers/irqchip/irq-intc-v1.c | 104 ----
.../irqchip/irq-sw64-intc-v2.c | 64 ++-
drivers/irqchip/irq-sw64-lpc-intc.c | 137 +++++
drivers/mfd/lpc_sunway_chip3.c | 130 -----
drivers/misc/Kconfig | 8 +
drivers/misc/Makefile | 1 +
drivers/misc/sunway-ged.c | 253 ++++++++++
116 files changed, 2009 insertions(+), 2686 deletions(-)
delete mode 100644 arch/sw_64/include/asm/agp.h
delete mode 100644 arch/sw_64/include/asm/compiler.h
delete mode 100644 arch/sw_64/include/asm/console.h
delete mode 100644 arch/sw_64/include/asm/div64.h
delete mode 100644 arch/sw_64/include/asm/emergency-restart.h
delete mode 100644 arch/sw_64/include/asm/exec.h
delete mode 100644 arch/sw_64/include/asm/floppy.h
delete mode 100644 arch/sw_64/include/asm/irq_regs.h
delete mode 100644 arch/sw_64/include/asm/kmap_types.h
delete mode 100644 arch/sw_64/include/asm/local.h
delete mode 100644 arch/sw_64/include/asm/local64.h
delete mode 100644 arch/sw_64/include/asm/param.h
delete mode 100644 arch/sw_64/include/asm/parport.h
delete mode 100644 arch/sw_64/include/asm/preempt.h
delete mode 100644 arch/sw_64/include/asm/seccomp.h
delete mode 100644 arch/sw_64/include/asm/sections.h
delete mode 100644 arch/sw_64/include/asm/segment.h
delete mode 100644 arch/sw_64/include/asm/serial.h
delete mode 100644 arch/sw_64/include/asm/shmparam.h
delete mode 100644 arch/sw_64/include/asm/special_insns.h
create mode 100644 arch/sw_64/include/asm/stacktrace.h
delete mode 100644 arch/sw_64/include/asm/trace_clock.h
delete mode 100644 arch/sw_64/include/asm/types.h
delete mode 100644 arch/sw_64/include/asm/unaligned.h
delete mode 100644 arch/sw_64/include/asm/vga.h
delete mode 100644 arch/sw_64/include/uapi/asm/console.h
delete mode 100644 arch/sw_64/include/uapi/asm/ipcbuf.h
delete mode 100644 arch/sw_64/include/uapi/asm/kvm_para.h
delete mode 100644 arch/sw_64/include/uapi/asm/msgbuf.h
delete mode 100644 arch/sw_64/include/uapi/asm/poll.h
delete mode 100644 arch/sw_64/include/uapi/asm/posix_types.h
delete mode 100644 arch/sw_64/include/uapi/asm/sembuf.h
delete mode 100644 arch/sw_64/include/uapi/asm/shmbuf.h
delete mode 100644 arch/sw_64/include/uapi/asm/statfs.h
delete mode 100644 arch/sw_64/include/uapi/asm/types.h
rename arch/sw_64/include/{ => uapi}/asm/ucontext.h (56%)
create mode 100644 arch/sw_64/kernel/bindvcpu.c
delete mode 100644 arch/sw_64/kernel/core.c
create mode 100644 arch/sw_64/kernel/fpu.S
delete mode 100644 arch/sw_64/kernel/unaligned.c
delete mode 100644 drivers/irqchip/irq-intc-v1.c
rename arch/sw_64/chip/chip3/irq_chip.c => drivers/irqchip/irq-sw64-intc-v2.c (59%)
create mode 100644 drivers/irqchip/irq-sw64-lpc-intc.c
create mode 100644 drivers/misc/sunway-ged.c
--
2.17.1
1
50

[PATCH openEuler-5.10-LTS 1/7] arm64: Do not defer reserve_crashkernel() for platforms with no DMA memory zones
by Zheng Zengkai 11 Jul '22
by Zheng Zengkai 11 Jul '22
11 Jul '22
From: Vijay Balakrishna <vijayb(a)linux.microsoft.com>
stable inclusion
from stable-v5.10.110
commit a25864c5bc20966cdc5ba5eb65b74b9b1e9ec8d2
bugzilla: https://gitee.com/openeuler/kernel/issues/I574AL
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 031495635b4668f94e964e037ca93d0d38bfde58 upstream.
The following patches resulted in deferring crash kernel reservation to
mem_init(), mainly aimed at platforms with DMA memory zones (no IOMMU),
in particular Raspberry Pi 4.
commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32")
commit 8424ecdde7df ("arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges")
commit 0a30c53573b0 ("arm64: mm: Move reserve_crashkernel() into mem_init()")
commit 2687275a5843 ("arm64: Force NO_BLOCK_MAPPINGS if crashkernel reservation is required")
Above changes introduced boot slowdown due to linear map creation for
all the memory banks with NO_BLOCK_MAPPINGS, see discussion[1]. The proposed
changes restore crash kernel reservation to earlier behavior thus avoids
slow boot, particularly for platforms with IOMMU (no DMA memory zones).
Tested changes to confirm no ~150ms boot slowdown on our SoC with IOMMU
and 8GB memory. Also tested with ZONE_DMA and/or ZONE_DMA32 configs to confirm
no regression to deferring scheme of crash kernel memory reservation.
In both cases successfully collected kernel crash dump.
[1] https://lore.kernel.org/all/9436d033-579b-55fa-9b00-6f4b661c2dd7@linux.micr…
Signed-off-by: Vijay Balakrishna <vijayb(a)linux.microsoft.com>
Cc: stable(a)vger.kernel.org
Reviewed-by: Pasha Tatashin <pasha.tatashin(a)soleen.com>
Link: https://lore.kernel.org/r/1646242689-20744-1-git-send-email-vijayb@linux.mi…
[will: Add #ifdef CONFIG_KEXEC_CORE guards to fix 'crashk_res' references in allnoconfig build]
Signed-off-by: Will Deacon <will(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yu Liao <liaoyu15(a)huawei.com>
Conflicts:
arch/arm64/mm/mmu.c
Reviewed-by: Wei Li <liwei391(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
arch/arm64/mm/init.c | 36 ++++++++++++++++++++++++++++++++----
arch/arm64/mm/mmu.c | 26 ++++++++++++++++----------
2 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f5bd046f9e19..5023c7e1f754 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -63,8 +63,34 @@ EXPORT_SYMBOL(memstart_addr);
* unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4).
* In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory,
* otherwise it is empty.
+ *
+ * Memory reservation for crash kernel either done early or deferred
+ * depending on DMA memory zones configs (ZONE_DMA) --
+ *
+ * In absence of ZONE_DMA configs arm64_dma_phys_limit initialized
+ * here instead of max_zone_phys(). This lets early reservation of
+ * crash kernel memory which has a dependency on arm64_dma_phys_limit.
+ * Reserving memory early for crash kernel allows linear creation of block
+ * mappings (greater than page-granularity) for all the memory bank rangs.
+ * In this scheme a comparatively quicker boot is observed.
+ *
+ * If ZONE_DMA configs are defined, crash kernel memory reservation
+ * is delayed until DMA zone memory range size initilazation performed in
+ * zone_sizes_init(). The defer is necessary to steer clear of DMA zone
+ * memory range to avoid overlap allocation. So crash kernel memory boundaries
+ * are not known when mapping all bank memory ranges, which otherwise means
+ * not possible to exclude crash kernel range from creating block mappings
+ * so page-granularity mappings are created for the entire memory range.
+ * Hence a slightly slower boot is observed.
+ *
+ * Note: Page-granularity mapppings are necessary for crash kernel memory
+ * range for shrinking its size via /sys/kernel/kexec_crash_size interface.
*/
-phys_addr_t arm64_dma_phys_limit __ro_after_init;
+#if IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32)
+phys_addr_t __ro_after_init arm64_dma_phys_limit;
+#else
+phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
+#endif
#ifndef CONFIG_KEXEC_CORE
static void __init reserve_crashkernel(void)
@@ -173,8 +199,6 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
if (!arm64_dma_phys_limit)
arm64_dma_phys_limit = dma32_phys_limit;
#endif
- if (!arm64_dma_phys_limit)
- arm64_dma_phys_limit = PHYS_MASK + 1;
max_zone_pfns[ZONE_NORMAL] = max;
free_area_init(max_zone_pfns);
@@ -498,6 +522,9 @@ void __init arm64_memblock_init(void)
reserve_elfcorehdr();
+ if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32))
+ reserve_crashkernel();
+
high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
}
@@ -553,7 +580,8 @@ void __init bootmem_init(void)
* request_standard_resources() depends on crashkernel's memory being
* reserved, so do it here.
*/
- reserve_crashkernel();
+ if (IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32))
+ reserve_crashkernel();
reserve_quick_kexec();
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 00e89be15ad2..e76765354040 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -562,16 +562,6 @@ static void __init map_mem(pgd_t *pgdp)
PAGE_KERNEL, NO_CONT_MAPPINGS);
memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
-#ifdef CONFIG_KEXEC_CORE
- if (crashk_res.end) {
- __map_memblock(pgdp, crashk_res.start,
- crashk_res.end + 1,
- PAGE_KERNEL,
- NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
- memblock_clear_nomap(crashk_res.start,
- resource_size(&crashk_res));
- }
-#endif
#ifdef CONFIG_KFENCE
/*
* Map the __kfence_pool at page granularity now.
@@ -584,6 +574,22 @@ static void __init map_mem(pgd_t *pgdp)
memblock_clear_nomap(__pa(__kfence_pool), KFENCE_POOL_SIZE);
}
#endif
+
+ /*
+ * Use page-level mappings here so that we can shrink the region
+ * in page granularity and put back unused memory to buddy system
+ * through /sys/kernel/kexec_crash_size interface.
+ */
+#ifdef CONFIG_KEXEC_CORE
+ if (crashk_res.end) {
+ __map_memblock(pgdp, crashk_res.start,
+ crashk_res.end + 1,
+ PAGE_KERNEL,
+ NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
+ memblock_clear_nomap(crashk_res.start,
+ resource_size(&crashk_res));
+ }
+#endif
}
void mark_rodata_ro(void)
--
2.20.1
1
6
From: Ard Biesheuvel <ardb(a)kernel.org>
stable inclusion
from stable-4.19.245
commit 0569702c238290924fc1c7c6954258aa4a5fd649
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5FNPY
CVE: NA
--------------------------------
[ Upstream commit 0dc14aa94ccd8ba35eb17a0f9b123d1566efd39e ]
The Spectre-BHB mitigations were inadvertently left disabled for
Cortex-A15, due to the fact that cpu_v7_bugs_init() is not called in
that case. So fix that.
Fixes: b9baf5c8c5c3 ("ARM: Spectre-BHB workaround")
Signed-off-by: Ard Biesheuvel <ardb(a)kernel.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel(a)armlinux.org.uk>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
arch/arm/mm/proc-v7-bugs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 87a93b76e148..8c7d00cb63ef 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -299,6 +299,7 @@ void cpu_v7_ca15_ibe(void)
{
if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0)))
cpu_v7_spectre_v2_init();
+ cpu_v7_spectre_bhb_init();
}
void cpu_v7_bugs_init(void)
--
2.25.1
1
33
From: Christoph Hellwig <hch(a)lst.de>
mainline inclusion
from mainline-v5.10-rc1
commit f4ad06f2bb8476548b08f89919ee65abc4e40212
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5ETAB
CVE: NA
-------------------------------------------------
Replace bd_invalidate with a new BDEV_NEED_PART_SCAN flag in a bd_flags
variable to better describe the condition.
Signed-off-by: Christoph Hellwig <hch(a)lst.de>
Reviewed-by: Josef Bacik <josef(a)toxicpanda.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn(a)wdc.com>
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
Conflicts:
fs/block_dev.c
include/linux/blk_types.h
Signed-off-by: Luo Meng <luomeng12(a)huawei.com>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
block/genhd.c | 2 +-
block/partition-generic.c | 6 +++---
drivers/block/nbd.c | 8 ++++----
fs/block_dev.c | 12 ++++++------
include/linux/fs.h | 4 +++-
5 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/block/genhd.c b/block/genhd.c
index fc24384e2c85..afa3cf525f43 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -646,7 +646,7 @@ static void register_disk(struct device *parent, struct gendisk *disk)
if (!bdev)
goto exit;
- bdev->bd_invalidated = 1;
+ set_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
err = blkdev_get(bdev, FMODE_READ, NULL);
if (err < 0)
goto exit;
diff --git a/block/partition-generic.c b/block/partition-generic.c
index 2261566741f4..ae3761fed854 100644
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -546,7 +546,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
if (disk->fops->revalidate_disk)
disk->fops->revalidate_disk(disk);
check_disk_size_change(disk, bdev, true);
- bdev->bd_invalidated = 0;
+ clear_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
return 0;
if (IS_ERR(state)) {
@@ -662,7 +662,7 @@ int invalidate_partitions(struct gendisk *disk, struct block_device *bdev)
{
int res;
- if (!bdev->bd_invalidated)
+ if (!test_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags))
return 0;
res = drop_partitions(disk, bdev);
@@ -671,7 +671,7 @@ int invalidate_partitions(struct gendisk *disk, struct block_device *bdev)
set_capacity(disk, 0);
check_disk_size_change(disk, bdev, false);
- bdev->bd_invalidated = 0;
+ clear_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
/* tell userspace that the media / partition table may have changed */
kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index c2e5ba599418..f1986d8bb47c 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -317,7 +317,7 @@ static void nbd_size_update(struct nbd_device *nbd, bool start)
if (start)
set_blocksize(bdev, config->blksize);
} else
- bdev->bd_invalidated = 1;
+ set_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
bdput(bdev);
}
kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
@@ -1343,7 +1343,7 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *b
return ret;
if (max_part)
- bdev->bd_invalidated = 1;
+ set_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
mutex_unlock(&nbd->config_lock);
ret = wait_event_interruptible(config->recv_wq,
atomic_read(&config->recv_threads) == 0);
@@ -1518,9 +1518,9 @@ static int nbd_open(struct block_device *bdev, fmode_t mode)
refcount_set(&nbd->config_refs, 1);
refcount_inc(&nbd->refs);
mutex_unlock(&nbd->config_lock);
- bdev->bd_invalidated = 1;
+ set_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
} else if (nbd_disconnected(nbd->config)) {
- bdev->bd_invalidated = 1;
+ set_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
}
out:
mutex_unlock(&nbd_index_mutex);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9868b21b8ef9..f521b7cf907f 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -922,7 +922,7 @@ struct block_device *bdget(dev_t dev)
bdev->bd_inode = inode;
bdev->bd_block_size = i_blocksize(inode);
bdev->bd_part_count = 0;
- bdev->bd_invalidated = 0;
+ bdev->bd_flags = 0;
inode->i_mode = S_IFBLK;
inode->i_rdev = dev;
inode->i_bdev = bdev;
@@ -1404,7 +1404,7 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty)
"resized disk %s\n",
bdev->bd_disk ? bdev->bd_disk->disk_name : "");
}
- bdev->bd_invalidated = 1;
+ set_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
}
/**
@@ -1457,7 +1457,7 @@ int revalidate_disk(struct gendisk *disk)
mutex_lock(&bdev->bd_mutex);
check_disk_size_change(disk, bdev, ret == 0);
- bdev->bd_invalidated = 0;
+ clear_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
mutex_unlock(&bdev->bd_mutex);
bdput(bdev);
return ret;
@@ -1520,7 +1520,7 @@ static void bdev_disk_changed(struct block_device *bdev, bool invalidate)
up_read(&disk->lookup_sem);
} else {
check_disk_size_change(bdev->bd_disk, bdev, !invalidate);
- bdev->bd_invalidated = 0;
+ clear_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags);
}
}
@@ -1605,7 +1605,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
* The latter is necessary to prevent ghost
* partitions on a removed medium.
*/
- if (bdev->bd_invalidated &&
+ if (test_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags) &&
(!ret || ret == -ENOMEDIUM))
bdev_disk_changed(bdev, ret == -ENOMEDIUM);
@@ -1642,7 +1642,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
if (bdev->bd_disk->fops->open)
ret = bdev->bd_disk->fops->open(bdev, mode);
/* the same as first opener case, read comment there */
- if (bdev->bd_invalidated &&
+ if (test_bit(BDEV_NEED_PART_SCAN, &bdev->bd_flags) &&
(!ret || ret == -ENOMEDIUM))
bdev_disk_changed(bdev, ret == -ENOMEDIUM);
if (ret)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bcd2131ca06c..480936c2d938 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -459,6 +459,8 @@ struct address_space {
*/
struct request_queue;
+#define BDEV_NEED_PART_SCAN 0
+
struct block_device {
dev_t bd_dev; /* not a kdev_t - it's a search key */
int bd_openers;
@@ -479,7 +481,7 @@ struct block_device {
struct hd_struct * bd_part;
/* number of times partitions within this device have been opened. */
unsigned bd_part_count;
- int bd_invalidated;
+ unsigned long bd_flags;
struct gendisk * bd_disk;
struct request_queue * bd_queue;
struct backing_dev_info *bd_bdi;
--
2.25.1
1
3

[PATCH openEuler-1.0-LTS 1/3] scsi: hisi_sas: Change DMA setup lock timeout to 2.5s
by Laibin Qiu 07 Jul '22
by Laibin Qiu 07 Jul '22
07 Jul '22
From: Xingui Yang <yangxingui(a)huawei.com>
driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5BXH1
CVE: NA
-------------------------------------------------------------------
DMA setup lock timeout protection is added when DMA setup frames are
received, it's a function outside the protocol and used to prevent SATA
disk I/Os from being delivered for a long time. The default value is 100ms
, it's too strict and easily triggered timeout when the disk is overloaded
or faulty. Based on the average I/O latency of 300 disks, we adjust the
value to 2.5s.
Signed-off-by: Xingui Yang <yangxingui(a)huawei.com>
Reviewed-by: kang fenglong <kangfenglong(a)huawei.com>
Acked-by: Xie XiuQi <xiexiuqi(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index baae04adc8e4..91f02357d5b4 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -35,6 +35,7 @@
#define SATA_INITI_D2H_STORE_ADDR_HI 0x64
#define CFG_MAX_TAG 0x68
#define SAS_DMAC_OUTSTAND 0x6c
+#define TRANS_LOCK_ICT_TIME 0X70
#define HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL 0x84
#define HGC_SAS_TXFAIL_RETRY_CTRL 0x88
#define HGC_GET_ITV_TIME 0x90
@@ -596,6 +597,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
(u32)((1ULL << hisi_hba->queue_count) - 1));
hisi_sas_write32(hisi_hba, SAS_AXI_USER3, 0);
hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400);
+ /* time / CLK_AHB = 2.5s / 2ns = 0x4A817C80 */
+ hisi_sas_write32(hisi_hba, TRANS_LOCK_ICT_TIME, 0x4A817C80);
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);
@@ -3061,6 +3064,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = {
HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_LO),
HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_HI),
HISI_SAS_DEBUGFS_REG(CFG_MAX_TAG),
+ HISI_SAS_DEBUGFS_REG(TRANS_LOCK_ICT_TIME),
HISI_SAS_DEBUGFS_REG(HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL),
HISI_SAS_DEBUGFS_REG(HGC_SAS_TXFAIL_RETRY_CTRL),
HISI_SAS_DEBUGFS_REG(HGC_GET_ITV_TIME),
--
2.25.1
1
2

[PATCH openEuler-5.10 01/40] mm,hwpoison: drain pcplists before bailing out for non-buddy zero-refcount page
by Zheng Zengkai 06 Jul '22
by Zheng Zengkai 06 Jul '22
06 Jul '22
From: Oscar Salvador <osalvador(a)suse.de>
mainline inclusion
from mainline-v5.11-rc1
commit 17e395b60f5b3dea204fcae60c7b38e84a00d87a
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5E2IG
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
Patch series "HWpoison: further fixes and cleanups", v5.
This patchset includes some more fixes and a cleanup.
Patch#2 and patch#3 are both fixes for taking a HWpoison page off a buddy
freelist, since having them there has proved to be bad (see [1] and
pathch#2's commit log). Patch#3 does the same for hugetlb pages.
[1] https://lkml.org/lkml/2020/9/22/565
This patch (of 4):
A page with 0-refcount and !PageBuddy could perfectly be a pcppage.
Currently, we bail out with an error if we encounter such a page, meaning
that we do not handle pcppages neither from hard-offline nor from
soft-offline path.
Fix this by draining pcplists whenever we find this kind of page and retry
the check again. It might be that pcplists have been spilled into the
buddy allocator and so we can handle it.
Link: https://lkml.kernel.org/r/20201013144447.6706-1-osalvador@suse.de
Link: https://lkml.kernel.org/r/20201013144447.6706-2-osalvador@suse.de
Signed-off-by: Oscar Salvador <osalvador(a)suse.de>
Acked-by: Naoya Horiguchi <naoya.horiguchi(a)nec.com>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
mm/memory-failure.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 63bacfcca122..de36b4aa4b6f 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -947,13 +947,13 @@ static int page_action(struct page_state *ps, struct page *p,
}
/**
- * get_hwpoison_page() - Get refcount for memory error handling:
+ * __get_hwpoison_page() - Get refcount for memory error handling:
* @page: raw error page (hit by memory error)
*
* Return: return 0 if failed to grab the refcount, otherwise true (some
* non-zero value.)
*/
-static int get_hwpoison_page(struct page *page)
+static int __get_hwpoison_page(struct page *page)
{
struct page *head = compound_head(page);
@@ -983,6 +983,26 @@ static int get_hwpoison_page(struct page *page)
return 0;
}
+static int get_hwpoison_page(struct page *p)
+{
+ int ret;
+ bool drained = false;
+
+retry:
+ ret = __get_hwpoison_page(p);
+ if (!ret && !is_free_buddy_page(p) && !page_count(p) && !drained) {
+ /*
+ * The page might be in a pcplist, so try to drain those
+ * and see if we are lucky.
+ */
+ drain_all_pages(page_zone(p));
+ drained = true;
+ goto retry;
+ }
+
+ return ret;
+}
+
/*
* Do all that is necessary to remove user space mappings. Unmap
* the pages and send SIGBUS to the processes if the data was dirty.
--
2.20.1
1
38

[PATCH openEuler-5.10 01/30] Documentation: Add documentation for Processor MMIO Stale Data
by Zheng Zengkai 06 Jul '22
by Zheng Zengkai 06 Jul '22
06 Jul '22
From: Pawan Gupta <pawan.kumar.gupta(a)linux.intel.com>
stable inclusion
from stable-v5.10.123
commit f8a85334a57e7842320476ff27be3a5f151da364
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5D5RS
CVE: CVE-2022-21123,CVE-2022-21125,CVE-2022-21166
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=…
--------------------------------
commit 4419470191386456e0b8ed4eb06a70b0021798a6 upstream
Add the admin guide for Processor MMIO stale data vulnerabilities.
Signed-off-by: Pawan Gupta <pawan.kumar.gupta(a)linux.intel.com>
Signed-off-by: Borislav Petkov <bp(a)suse.de>
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yipeng Zou <zouyipeng(a)huawei.com>
Reviewed-by: Zhang Jianhua <chris.zjh(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Liao Chang <liaochang1(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
Documentation/admin-guide/hw-vuln/index.rst | 1 +
.../hw-vuln/processor_mmio_stale_data.rst | 246 ++++++++++++++++++
2 files changed, 247 insertions(+)
create mode 100644 Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
diff --git a/Documentation/admin-guide/hw-vuln/index.rst b/Documentation/admin-guide/hw-vuln/index.rst
index ca4dbdd9016d..2adec1e6520a 100644
--- a/Documentation/admin-guide/hw-vuln/index.rst
+++ b/Documentation/admin-guide/hw-vuln/index.rst
@@ -15,3 +15,4 @@ are configurable at compile, boot or run time.
tsx_async_abort
multihit.rst
special-register-buffer-data-sampling.rst
+ processor_mmio_stale_data.rst
diff --git a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
new file mode 100644
index 000000000000..9393c50b5afc
--- /dev/null
+++ b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
@@ -0,0 +1,246 @@
+=========================================
+Processor MMIO Stale Data Vulnerabilities
+=========================================
+
+Processor MMIO Stale Data Vulnerabilities are a class of memory-mapped I/O
+(MMIO) vulnerabilities that can expose data. The sequences of operations for
+exposing data range from simple to very complex. Because most of the
+vulnerabilities require the attacker to have access to MMIO, many environments
+are not affected. System environments using virtualization where MMIO access is
+provided to untrusted guests may need mitigation. These vulnerabilities are
+not transient execution attacks. However, these vulnerabilities may propagate
+stale data into core fill buffers where the data can subsequently be inferred
+by an unmitigated transient execution attack. Mitigation for these
+vulnerabilities includes a combination of microcode update and software
+changes, depending on the platform and usage model. Some of these mitigations
+are similar to those used to mitigate Microarchitectural Data Sampling (MDS) or
+those used to mitigate Special Register Buffer Data Sampling (SRBDS).
+
+Data Propagators
+================
+Propagators are operations that result in stale data being copied or moved from
+one microarchitectural buffer or register to another. Processor MMIO Stale Data
+Vulnerabilities are operations that may result in stale data being directly
+read into an architectural, software-visible state or sampled from a buffer or
+register.
+
+Fill Buffer Stale Data Propagator (FBSDP)
+-----------------------------------------
+Stale data may propagate from fill buffers (FB) into the non-coherent portion
+of the uncore on some non-coherent writes. Fill buffer propagation by itself
+does not make stale data architecturally visible. Stale data must be propagated
+to a location where it is subject to reading or sampling.
+
+Sideband Stale Data Propagator (SSDP)
+-------------------------------------
+The sideband stale data propagator (SSDP) is limited to the client (including
+Intel Xeon server E3) uncore implementation. The sideband response buffer is
+shared by all client cores. For non-coherent reads that go to sideband
+destinations, the uncore logic returns 64 bytes of data to the core, including
+both requested data and unrequested stale data, from a transaction buffer and
+the sideband response buffer. As a result, stale data from the sideband
+response and transaction buffers may now reside in a core fill buffer.
+
+Primary Stale Data Propagator (PSDP)
+------------------------------------
+The primary stale data propagator (PSDP) is limited to the client (including
+Intel Xeon server E3) uncore implementation. Similar to the sideband response
+buffer, the primary response buffer is shared by all client cores. For some
+processors, MMIO primary reads will return 64 bytes of data to the core fill
+buffer including both requested data and unrequested stale data. This is
+similar to the sideband stale data propagator.
+
+Vulnerabilities
+===============
+Device Register Partial Write (DRPW) (CVE-2022-21166)
+-----------------------------------------------------
+Some endpoint MMIO registers incorrectly handle writes that are smaller than
+the register size. Instead of aborting the write or only copying the correct
+subset of bytes (for example, 2 bytes for a 2-byte write), more bytes than
+specified by the write transaction may be written to the register. On
+processors affected by FBSDP, this may expose stale data from the fill buffers
+of the core that created the write transaction.
+
+Shared Buffers Data Sampling (SBDS) (CVE-2022-21125)
+----------------------------------------------------
+After propagators may have moved data around the uncore and copied stale data
+into client core fill buffers, processors affected by MFBDS can leak data from
+the fill buffer. It is limited to the client (including Intel Xeon server E3)
+uncore implementation.
+
+Shared Buffers Data Read (SBDR) (CVE-2022-21123)
+------------------------------------------------
+It is similar to Shared Buffer Data Sampling (SBDS) except that the data is
+directly read into the architectural software-visible state. It is limited to
+the client (including Intel Xeon server E3) uncore implementation.
+
+Affected Processors
+===================
+Not all the CPUs are affected by all the variants. For instance, most
+processors for the server market (excluding Intel Xeon E3 processors) are
+impacted by only Device Register Partial Write (DRPW).
+
+Below is the list of affected Intel processors [#f1]_:
+
+ =================== ============ =========
+ Common name Family_Model Steppings
+ =================== ============ =========
+ HASWELL_X 06_3FH 2,4
+ SKYLAKE_L 06_4EH 3
+ BROADWELL_X 06_4FH All
+ SKYLAKE_X 06_55H 3,4,6,7,11
+ BROADWELL_D 06_56H 3,4,5
+ SKYLAKE 06_5EH 3
+ ICELAKE_X 06_6AH 4,5,6
+ ICELAKE_D 06_6CH 1
+ ICELAKE_L 06_7EH 5
+ ATOM_TREMONT_D 06_86H All
+ LAKEFIELD 06_8AH 1
+ KABYLAKE_L 06_8EH 9 to 12
+ ATOM_TREMONT 06_96H 1
+ ATOM_TREMONT_L 06_9CH 0
+ KABYLAKE 06_9EH 9 to 13
+ COMETLAKE 06_A5H 2,3,5
+ COMETLAKE_L 06_A6H 0,1
+ ROCKETLAKE 06_A7H 1
+ =================== ============ =========
+
+If a CPU is in the affected processor list, but not affected by a variant, it
+is indicated by new bits in MSR IA32_ARCH_CAPABILITIES. As described in a later
+section, mitigation largely remains the same for all the variants, i.e. to
+clear the CPU fill buffers via VERW instruction.
+
+New bits in MSRs
+================
+Newer processors and microcode update on existing affected processors added new
+bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate
+specific variants of Processor MMIO Stale Data vulnerabilities and mitigation
+capability.
+
+MSR IA32_ARCH_CAPABILITIES
+--------------------------
+Bit 13 - SBDR_SSDP_NO - When set, processor is not affected by either the
+ Shared Buffers Data Read (SBDR) vulnerability or the sideband stale
+ data propagator (SSDP).
+Bit 14 - FBSDP_NO - When set, processor is not affected by the Fill Buffer
+ Stale Data Propagator (FBSDP).
+Bit 15 - PSDP_NO - When set, processor is not affected by Primary Stale Data
+ Propagator (PSDP).
+Bit 17 - FB_CLEAR - When set, VERW instruction will overwrite CPU fill buffer
+ values as part of MD_CLEAR operations. Processors that do not
+ enumerate MDS_NO (meaning they are affected by MDS) but that do
+ enumerate support for both L1D_FLUSH and MD_CLEAR implicitly enumerate
+ FB_CLEAR as part of their MD_CLEAR support.
+Bit 18 - FB_CLEAR_CTRL - Processor supports read and write to MSR
+ IA32_MCU_OPT_CTRL[FB_CLEAR_DIS]. On such processors, the FB_CLEAR_DIS
+ bit can be set to cause the VERW instruction to not perform the
+ FB_CLEAR action. Not all processors that support FB_CLEAR will support
+ FB_CLEAR_CTRL.
+
+MSR IA32_MCU_OPT_CTRL
+---------------------
+Bit 3 - FB_CLEAR_DIS - When set, VERW instruction does not perform the FB_CLEAR
+action. This may be useful to reduce the performance impact of FB_CLEAR in
+cases where system software deems it warranted (for example, when performance
+is more critical, or the untrusted software has no MMIO access). Note that
+FB_CLEAR_DIS has no impact on enumeration (for example, it does not change
+FB_CLEAR or MD_CLEAR enumeration) and it may not be supported on all processors
+that enumerate FB_CLEAR.
+
+Mitigation
+==========
+Like MDS, all variants of Processor MMIO Stale Data vulnerabilities have the
+same mitigation strategy to force the CPU to clear the affected buffers before
+an attacker can extract the secrets.
+
+This is achieved by using the otherwise unused and obsolete VERW instruction in
+combination with a microcode update. The microcode clears the affected CPU
+buffers when the VERW instruction is executed.
+
+Kernel reuses the MDS function to invoke the buffer clearing:
+
+ mds_clear_cpu_buffers()
+
+On MDS affected CPUs, the kernel already invokes CPU buffer clear on
+kernel/userspace, hypervisor/guest and C-state (idle) transitions. No
+additional mitigation is needed on such CPUs.
+
+For CPUs not affected by MDS or TAA, mitigation is needed only for the attacker
+with MMIO capability. Therefore, VERW is not required for kernel/userspace. For
+virtualization case, VERW is only needed at VMENTER for a guest with MMIO
+capability.
+
+Mitigation points
+-----------------
+Return to user space
+^^^^^^^^^^^^^^^^^^^^
+Same mitigation as MDS when affected by MDS/TAA, otherwise no mitigation
+needed.
+
+C-State transition
+^^^^^^^^^^^^^^^^^^
+Control register writes by CPU during C-state transition can propagate data
+from fill buffer to uncore buffers. Execute VERW before C-state transition to
+clear CPU fill buffers.
+
+Guest entry point
+^^^^^^^^^^^^^^^^^
+Same mitigation as MDS when processor is also affected by MDS/TAA, otherwise
+execute VERW at VMENTER only for MMIO capable guests. On CPUs not affected by
+MDS/TAA, guest without MMIO access cannot extract secrets using Processor MMIO
+Stale Data vulnerabilities, so there is no need to execute VERW for such guests.
+
+Mitigation control on the kernel command line
+---------------------------------------------
+The kernel command line allows to control the Processor MMIO Stale Data
+mitigations at boot time with the option "mmio_stale_data=". The valid
+arguments for this option are:
+
+ ========== =================================================================
+ full If the CPU is vulnerable, enable mitigation; CPU buffer clearing
+ on exit to userspace and when entering a VM. Idle transitions are
+ protected as well. It does not automatically disable SMT.
+ full,nosmt Same as full, with SMT disabled on vulnerable CPUs. This is the
+ complete mitigation.
+ off Disables mitigation completely.
+ ========== =================================================================
+
+If the CPU is affected and mmio_stale_data=off is not supplied on the kernel
+command line, then the kernel selects the appropriate mitigation.
+
+Mitigation status information
+-----------------------------
+The Linux kernel provides a sysfs interface to enumerate the current
+vulnerability status of the system: whether the system is vulnerable, and
+which mitigations are active. The relevant sysfs file is:
+
+ /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
+
+The possible values in this file are:
+
+ .. list-table::
+
+ * - 'Not affected'
+ - The processor is not vulnerable
+ * - 'Vulnerable'
+ - The processor is vulnerable, but no mitigation enabled
+ * - 'Vulnerable: Clear CPU buffers attempted, no microcode'
+ - The processor is vulnerable, but microcode is not updated. The
+ mitigation is enabled on a best effort basis.
+ * - 'Mitigation: Clear CPU buffers'
+ - The processor is vulnerable and the CPU buffer clearing mitigation is
+ enabled.
+
+If the processor is vulnerable then the following information is appended to
+the above information:
+
+ ======================== ===========================================
+ 'SMT vulnerable' SMT is enabled
+ 'SMT disabled' SMT is disabled
+ 'SMT Host state unknown' Kernel runs in a VM, Host SMT state unknown
+ ======================== ===========================================
+
+References
+----------
+.. [#f1] Affected Processors
+ https://www.intel.com/content/www/us/en/developer/topic-technology/software…
--
2.20.1
1
29
Backport 5.10.110 LTS patches from upstream
arm64: Do not defer reserve_crashkernel() for platforms with no DMA memory zones
PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
can: m_can: m_can_tx_handler(): fix use after free of skb
openvswitch: Fixed nd target mask field in the flow dump.
docs: sysctl/kernel: add missing bit to panic_print
um: Fix uml_mconsole stop/go
ARM: dts: spear13xx: Update SPI dma properties
ARM: dts: spear1340: Update serial node properties
ASoC: topology: Allow TLV control to be either read or write
dt-bindings: spi: mxic: The interrupt property is not mandatory
dt-bindings: mtd: nand-controller: Fix a comment in the examples
dt-bindings: mtd: nand-controller: Fix the reg property description
bpf: Fix comment for helper bpf_current_task_under_cgroup()
bpf: Adjust BPF stack helper functions to accommodate skip > 0
mm/usercopy: return 1 from hardened_usercopy __setup() handler
mm/memcontrol: return 1 from cgroup.memory __setup() handler
ARM: 9187/1: JIVE: fix return value of __setup handler
mm/mmap: return 1 from stack_guard_gap __setup() handler
batman-adv: Check ptr for NULL before reducing its refcnt
ASoC: soc-compress: Change the check for codec_dai
staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on ethernet
proc: bootconfig: Add null pointer check
can: isotp: restore accidentally removed MSG_PEEK feature
platform/chrome: cros_ec_typec: Check for EC device
ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
riscv module: remove (NOLOAD)
io_uring: fix memory leak of uid in files registration
ARM: iop32x: offset IRQ numbers by 1
ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
pinctrl: pinconf-generic: Print arguments for bias-pull-*
watch_queue: Free the page array when watch_queue is dismantled
crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
mailbox: imx: fix wakeup failure from freeze mode
rxrpc: Fix call timer start racing with call destruction
gfs2: Make sure FITRIM minlen is rounded up to fs block size
rtc: check if __rtc_read_time was successful
XArray: Update the LRU list in xas_split()
can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error value
can: mcba_usb: properly check endpoint type
XArray: Fix xas_create_range() when multi-order entry present
wireguard: socket: ignore v6 endpoints when ipv6 is disabled
wireguard: socket: free skb in send6 when ipv6 is disabled
wireguard: queueing: use CFI-safe ptr_ring cleanup function
ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
KVM: SVM: fix panic on out-of-bounds guest IRQ
KVM: x86: fix sending PV IPI
KVM: Prevent module exit until all VMs are freed
KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated
platform: chrome: Split trace include file
scsi: qla2xxx: Use correct feature type field during RFF_ID processing
scsi: qla2xxx: Reduce false trigger to login
scsi: qla2xxx: Fix N2N inconsistent PLOGI
scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
scsi: qla2xxx: Fix hang due to session stuck
scsi: qla2xxx: Fix incorrect reporting of task management failure
scsi: qla2xxx: Fix disk failure to rediscover
scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
scsi: qla2xxx: Check for firmware dump already collected
scsi: qla2xxx: Add devids and conditionals for 28xx
scsi: qla2xxx: Fix device reconnect in loop topology
scsi: qla2xxx: Fix warning for missing error code
scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
scsi: qla2xxx: Fix scheduling while atomic
scsi: qla2xxx: Fix stuck session in gpdb
powerpc: Fix build errors with newer binutils
powerpc/lib/sstep: Fix build errors with newer binutils
powerpc/lib/sstep: Fix 'sthcx' instruction
powerpc/kasan: Fix early region not updated correctly
KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP MMU
ALSA: hda/realtek: Add alc256-samsung-headphone fixup
media: atomisp: fix bad usage at error handling logic
mmc: host: Return an error when ->enable_sdio_irq() ops is missing
media: hdpvr: initialize dev->worker at hdpvr_register_videodev
media: Revert "media: em28xx: add missing em28xx_close_extension"
video: fbdev: sm712fb: Fix crash in smtcfb_write()
ARM: mmp: Fix failure to remove sram device
ARM: tegra: tamonten: Fix I2C3 pad setting
lib/test_lockup: fix kernel pointer check for separate address spaces
uaccess: fix type mismatch warnings from access_ok()
media: cx88-mpeg: clear interrupt status register before streaming video
ASoC: soc-core: skip zero num_dai component in searching dai name
ARM: dts: bcm2711: Add the missing L1/L2 cache information
video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit
video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of
snprintf()
video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf()
arm64: defconfig: build imx-sdma as a module
ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
ARM: ftrace: avoid redundant loads or clobbering IP
media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2 regulator off
on some boards
ASoC: madera: Add dependencies on MFD
ARM: dts: bcm2837: Add the missing L1/L2 cache information
ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
video: fbdev: cirrusfb: check pixclock to avoid divide by zero
video: fbdev: w100fb: Reset global state
video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
media: ir_toy: free before error exiting
media: staging: media: zoran: fix various V4L2 compliance errors
media: staging: media: zoran: calculate the right buffer number for
zoran_reap_stat_com
media: staging: media: zoran: move videodev alloc
ntfs: add sanity check on allocation size
f2fs: compress: fix to print raw data size in error path of lz4 decompression
NFSD: Fix nfsd_breaker_owns_lease() return values
f2fs: fix to do sanity check on curseg->alloc_type
ext4: don't BUG if someone dirty pages without asking ext4 first
ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
ext4: correct cluster len and clusters changed accounting in ext4_mb_mark_bb
locking/lockdep: Iterate lock_classes directly when reading lockdep files
spi: tegra20: Use of_device_get_match_data()
nvme-tcp: lockdep: annotate in-kernel sockets
parisc: Fix handling off probe non-access faults
PM: core: keep irq flags in device_pm_check_callbacks()
ACPI/APEI: Limit printable size of BERT table data
Revert "Revert "block, bfq: honor already-setup queue merges""
lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
ACPICA: Avoid walking the ACPI Namespace if it is not there
fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
irqchip/nvic: Release nvic_base upon failure
irqchip/qcom-pdc: Fix broken locking
Fix incorrect type in assignment of ipv6 port for audit
loop: use sysfs_emit() in the sysfs xxx show()
selinux: allow FIOCLEX and FIONCLEX with policy capability
selinux: use correct type for context length
pinctrl: npcm: Fix broken references to chip->parent_device
gcc-plugins/stackleak: Exactly match strings instead of prefixes
regulator: rpi-panel: Handle I2C errors/timing to the Atmel
LSM: general protection fault in legacy_parse_param
fs: fix fd table size alignment properly
lib/test: use after free in register_test_dev_kmod()
fs: fd tables have to be multiples of BITS_PER_LONG
net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
NFSv4/pNFS: Fix another issue with a list iterator pointing to the head
qlcnic: dcb: default to returning -EOPNOTSUPP
selftests: test_vxlan_under_vrf: Fix broken test case
net: phy: broadcom: Fix brcm_fet_config_init()
net: enetc: report software timestamping via SO_TIMESTAMPING
xen: fix is_xen_pmu()
clk: Initialize orphan req_rate
clk: qcom: gcc-msm8994: Fix gpll4 width
kdb: Fix the putarea helper function
NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
jfs: fix divide error in dbNextAG
driver core: dd: fix return value of __setup handler
firmware: google: Properly state IOMEM dependency
kgdbts: fix return value of __setup handler
serial: 8250: fix XOFF/XON sending when DMA is used
kgdboc: fix return value of __setup handler
tty: hvc: fix return value of __setup handler
pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
pinctrl: mediatek: paris: Skip custom extra pin config dump for virtual GPIOs
pinctrl: mediatek: paris: Fix pingroup pin config state readback
pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get()
pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
staging: mt7621-dts: fix GB-PC2 devicetree
staging: mt7621-dts: fix pinctrl properties for ethernet
staging: mt7621-dts: fix formatting
staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
NFS: remove unneeded check in decode_devicenotify_args()
clk: tegra: tegra124-emc: Fix missing put_device() call in emc_ensure_emc_driver
clk: clps711x: Terminate clk_div_table with sentinel element
clk: loongson1: Terminate clk_div_table with sentinel element
clk: actions: Terminate clk_div_table with sentinel element
nvdimm/region: Fix default alignment for small regions
remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
remoteproc: qcom_wcnss: Add missing of_node_put() in wcnss_alloc_memory_region
remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
clk: qcom: clk-rcg2: Update the frac table for pixel clock
clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
clk: at91: sama7g5: fix parents of PDMCs' GCLK
clk: imx7d: Remove audio_mclk_root_clk
dma-debug: fix return value of __setup handlers
NFS: Return valid errors from nfs2/3_decode_dirent()
habanalabs: Add check for pci_enable_device
iio: adc: Add check for devm_request_threaded_irq
serial: 8250: Fix race condition in RTS-after-send handling
NFS: Use of mapping_set_error() results in spurious errors
serial: 8250_lpss: Balance reference count for PCI DMA device
serial: 8250_mid: Balance reference count for PCI DMA device
phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
clk: qcom: ipq8074: Use floor ops for SDCC1 clock
pinctrl: renesas: checker: Fix miscalculation of number of states
pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
iio: mma8452: Fix probe failing when an i2c_device_id is used
clk: qcom: ipq8074: fix PCI-E clock oops
soundwire: intel: fix wrong register name in intel_shim_wake
cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
misc: alcor_pci: Fix an error handling path
fsi: Aspeed: Fix a potential double free
fsi: aspeed: convert to devm_platform_ioremap_resource
pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add()
mxser: fix xmit_buf leak in activate when LSR == 0xff
mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
tipc: fix the timer expires after interval 100ms
openvswitch: always update flow key after nat
tcp: ensure PMTU updates are processed during fastopen
net: bcmgenet: Use stronger register read/writes to assure ordering
PCI: Avoid broken MSI on SB600 USB devices
selftests/bpf/test_lirc_mode2.sh: Exit with proper code
i2c: mux: demux-pinctrl: do not deactivate a master that is not active
i2c: meson: Fix wrong speed use from probe
af_netlink: Fix shift out of bounds in group mask calculation
ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
Bluetooth: call hci_le_conn_failed with hdev lock in hci_le_conn_failed
selftests/bpf: Fix error reporting from sock_fields programs
bareudp: use ipv6_mod_enabled to check if IPv6 enabled
can: isotp: support MSG_TRUNC flag when reading from socket
can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
USB: storage: ums-realtek: fix error code in rts51x_read_mem()
samples/bpf, xdpsock: Fix race when running for fix duration of time
RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
MIPS: pgalloc: fix memory leak caused by pgd_free()
MIPS: RB532: fix return value of __setup handler
mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
ath10k: Fix error handling in ath10k_setup_msa_resources
vxcan: enable local echo for sent CAN frames
powerpc: 8xx: fix a return value error in mpc8xx_pic_init
platform/x86: huawei-wmi: check the return value of device_create_file()
selftests/bpf: Make test_lwt_ip_encap more stable and faster
libbpf: Unmap rings when umem deleted
mfd: mc13xxx: Add check for mc13xxx_irq_request
powerpc/sysdev: fix incorrect use to determine if list is empty
mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
net: axienet: fix RX ring refill allocation failure handling
IB/hfi1: Allow larger MTU without AIP
power: supply: wm8350-power: Add missing free in free_charger_irq
power: supply: wm8350-power: Handle error for wm8350_register_irq
i2c: xiic: Make bus names unique
hv_balloon: rate-limit "Unhandled message" warning
KVM: x86/emulator: Defer not-present segment check in
__load_segment_descriptor()
KVM: x86: Fix emulation in writing cr8
powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
libbpf: Skip forward declaration when counting duplicated type names
gpu: host1x: Fix a memory leak in 'host1x_remove()'
bpf, arm64: Feed byte-offset into bpf line info
bpf, arm64: Call build_prologue() first in first JIT pass
drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
scsi: hisi_sas: Change permission of parameter prot_mask
power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false return
drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
ext2: correct max file size computing
TOMOYO: fix __setup handlers return values
drm/amd/display: Remove vupdate_int_entry definition
RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
scsi: pm8001: Fix abort all task initialization
scsi: pm8001: Fix NCQ NON DATA command completion handling
scsi: pm8001: Fix NCQ NON DATA command task initialization
scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config()
scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
drm/msm/dpu: fix dp audio condition
drm/msm/dpu: add DSPP blocks teardown
drm/msm/dp: populate connector of struct dp_panel
iwlwifi: mvm: Fix an error code in iwl_mvm_up()
iwlwifi: Fix -EIO error code that is never returned
dax: make sure inodes are flushed before destroy cache
IB/cma: Allow XRC INI QPs to set their local ACK timeout
drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
drm/amd/pm: enable pm sysfs write for one VF mode
iommu/ipmmu-vmsa: Check for error num after setting mask
HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
drm/bridge: dw-hdmi: use safe format when first in bridge chain
PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
scripts/dtc: Call pkg-config POSIXly correct
net: dsa: mv88e6xxx: Enable port policy support on 6097
mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in sta mode
powerpc/perf: Don't use perf_hw_context for trace IMC PMU
KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
ray_cs: Check ioremap return value
power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
i40e: respect metadata on XSK Rx to skb
i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
KVM: PPC: Fix vmx/vsx mixup in mmio emulation
RDMA/core: Set MR type in ib_reg_user_mr
ath9k_htc: fix uninit value bugs
drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq function
drm/amd/display: Fix a NULL pointer dereference in
amdgpu_dm_connector_add_common_modes()
drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
ionic: fix type complaint in ionic_dev_cmd_clean()
drm/edid: Don't clear formats if using deep color
mtd: rawnand: gpmi: fix controller timings setting
mtd: onenand: Check for error irq
Bluetooth: hci_serdev: call init_rwsem() before p->open()
udmabuf: validate ubuf->pagecount
libbpf: Fix possible NULL pointer dereference when destroying skeleton
drm/panfrost: Check for error num after setting mask
ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
drm: bridge: adv7511: Fix ADV7535 HPD enablement
drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
ARM: configs: multi_v5_defconfig: re-enable CONFIG_V4L_PLATFORM_DRIVERS
ASoC: codecs: wcd934x: Add missing of_node_put() in wcd934x_codec_parse_data
ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe
ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
ASoC: atmel: sam9x5_wm8731: use devm_snd_soc_register_card()
mmc: davinci_mmc: Handle error for clk_enable
ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in
msm8916_wcd_digital_probe
ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
ASoC: fsl_spdif: Disable TX clock when stop
ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
ASoC: SOF: Add missing of_node_put() in imx8m_probe
ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in rockchip_i2s_probe
ASoC: rockchip: i2s: Use devm_platform_get_and_ioremap_resource()
ivtv: fix incorrect device_caps for ivtvfb
media: saa7134: fix incorrect use to determine if list is empty
media: saa7134: convert list_for_each to entry variant
video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
ASoC: fsi: Add check for clk_enable
ASoC: wm8350: Handle error for wm8350_register_irq
ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
media: vidtv: Check for null return of vzalloc
media: stk1160: If start stream fails, return buffers with VB2_BUF_STATE_QUEUED
m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined
arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly
ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction
memory: emif: check the pointer temp in get_device_details()
memory: emif: Add check for setup_interrupts
ASoC: soc-compress: prevent the potentially use of null pointer
ASoC: dwc-i2s: Handle errors for clk_enable
ASoC: atmel_ssc_dai: Handle errors for clk_enable
ASoC: mxs-saif: Handle errors for clk_enable
printk: fix return value of printk.devkmsg __setup handler
arm64: dts: broadcom: Fix sata nodename
arm64: dts: ns2: Fix spi-cpol and spi-cpha property
ALSA: spi: Add check for clk_enable()
ASoC: ti: davinci-i2s: Add check for clk_enable()
ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp()
uaccess: fix nios2 and microblaze get_user_8()
ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
media: cedrus: h264: Fix neighbour info buffer size
media: cedrus: H265: Fix neighbour info buffer size
media: usb: go7007: s2250-board: fix leak in probe()
media: em28xx: initialize refcount before kref_get
media: video/hdmi: handle short reads of hdmi info frame.
ARM: dts: imx: Add missing LVDS decoder on M53Menlo
ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL is not
defined
arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
arm64: dts: qcom: sdm845: fix microphone bias properties and values
soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
soc: qcom: rpmpd: Check for null return of devm_kcalloc
ARM: dts: qcom: ipq4019: fix sleep clock
firmware: qcom: scm: Remove reassignment to desc following initializer
video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
video: fbdev: controlfb: Fix COMPILE_TEST build
video: fbdev: controlfb: Fix set but not used warnings
video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200 to avoid
black screen
media: aspeed: Correct value for h-total-pixels
media: hantro: Fix overfill bottom register field name
media: meson: vdec: potential dereference of null pointer
media: coda: Fix missing put_device() call in coda_get_vdoa_data
ASoC: generic: simple-card-utils: remove useless assignment
ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
media: bttv: fix WARNING regression on tunerless devices
media: mtk-vcodec: potential dereference of null pointer
media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
media: staging: media: zoran: fix usage of vb2_dma_contig_set_max_seg_size
kunit: make kunit_test_timeout compatible with comment
selftests, x86: fix how check_cc.sh is being invoked
f2fs: fix compressed file start atomic write may cause data corruption
f2fs: compress: remove unneeded read when rewrite whole cluster
btrfs: fix unexpected error path when reflinking an inline extent
f2fs: fix to avoid potential deadlock
nfsd: more robust allocation failure handling in nfsd_file_cache_init
f2fs: fix missing free nid in f2fs_handle_failed_inode
perf/x86/intel/pt: Fix address filter config for 32-bit kernel
perf/core: Fix address filter parser for multiple filters
rseq: Optimise rseq_get_rseq_cs() and clear_rseq_cs()
sched/core: Export pelt_thermal_tp
sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa
f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
watch_queue: Actually free the watch
watch_queue: Fix NULL dereference in error cleanup
io_uring: terminate manual loop iterator loop correctly for non-vecs
clocksource: acpi_pm: fix return value of __setup handler
hwmon: (pmbus) Add Vin unit off handling
hwrng: nomadik - Change clk_disable to clk_disable_unprepare
amba: Make the remove callback return void
vfio: platform: simplify device removal
crypto: ccree - Fix use after free in cc_cipher_exit()
crypto: ccp - ccp_dmaengine_unregister release dma channels
ACPI: APEI: fix return value of __setup handlers
clocksource/drivers/timer-of: Check return value of of_iomap in
timer_of_base_init()
clocksource/drivers/timer-microchip-pit64b: Use notrace
clocksource/drivers/exynos_mct: Handle DTS with higher number of interrupts
clocksource/drivers/exynos_mct: Refactor resources allocation
clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
crypto: vmx - add missing dependencies
crypto: amlogic - call finalize with bh disabled
crypto: sun8i-ce - call finalize with bh disabled
crypto: sun8i-ss - call finalize with bh disabled
hwrng: atmel - disable trng on failure path
spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
PM: suspend: fix return value of __setup handler
PM: hibernate: fix __setup handler error handling
block: don't delete queue kobject before its children
nvme: cleanup __nvme_check_ids
hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
hwmon: (pmbus) Add mutex to regulator ops
spi: pxa2xx-pci: Balance reference count for PCI DMA device
crypto: ccree - don't attempt 0 len DMA mappings
EVM: fix the evm= __setup handler return value
audit: log AUDIT_TIME_* records only from rules
crypto: rockchip - ECB does not need IV
selftests/x86: Add validity check and allow field splitting
arm64/mm: avoid fixmap race condition when create pud mapping
spi: tegra114: Add missing IRQ check in tegra_spi_probe
thermal: int340x: Check for NULL after calling kmemdup()
crypto: mxs-dcp - Fix scatterlist processing
crypto: authenc - Fix sleep in atomic context in decrypt_tail
crypto: sun8i-ss - really disable hash on A80
hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
hwrng: cavium - Check health status while reading random data
selinux: check return value of sel_make_avc_files
regulator: qcom_smd: fix for_each_child.cocci warnings
PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
PCI: pciehp: Clear cmd_busy bit in polling mode
drm/i915/gem: add missing boundary check in vm_access
brcmfmac: pcie: Fix crashes due to early IRQs
brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
brcmfmac: firmware: Allocate space for default boardrev in nvram
xtensa: fix xtensa_wsr always writing 0
xtensa: fix stop_machine_cpuslocked call in patch_text
media: davinci: vpif: fix unbalanced runtime PM enable
media: davinci: vpif: fix unbalanced runtime PM get
media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
DEC: Limit PMAX memory probing to R3k systems
crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete()
crypto: rsa-pkcs1pad - restore signature length check
crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
crypto: rsa-pkcs1pad - only allow with rsa
exec: Force single empty string when argv is empty
lib/raid6/test: fix multiple definition linking error
thermal: int340x: Increase bitmap size
pstore: Don't use semaphores in always-atomic-context code
carl9170: fix missing bit-wise or operator for tx_params
mgag200 fix memmapsl configuration in GCTL6 register
ARM: dts: exynos: add missing HDMI supplies on SMDK5420
ARM: dts: exynos: add missing HDMI supplies on SMDK5250
ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
video: fbdev: sm712fb: Fix crash in smtcfb_read()
drm/edid: check basic audio support on CEA extension block
block: limit request dispatch loop duration
mailbox: tegra-hsp: Flush whole channel
ext4: fix fs corruption when tring to remove a non-empty directory with IO error
ext4: fix ext4_fc_stats trace point
coredump: Also dump first pages of non-executable ELF libraries
ACPI: properties: Consistently return -ENOENT if there are no more references
arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
arm64: signal: nofpsimd: Do not allocate fp/simd context when not available
udp: call udp_encap_enable for v6 sockets when enabling encap
powerpc/kvm: Fix kvm_use_magic_page
can: isotp: sanitize CAN ID checks in isotp_bind()
drbd: fix potential silent data corruption
dm integrity: set journal entry unused when shrinking device
mm/kmemleak: reset tag when compare object pointer
mm,hwpoison: unmap poisoned page before invalidation
Revert "mm: madvise: skip unmapped vma holes passed to process_madvise"
mm: madvise: return correct bytes advised with process_madvise
mm: madvise: skip unmapped vma holes passed to process_madvise
ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
ALSA: hda: Avoid unsol event during RPM suspending
ALSA: cs4236: fix an incorrect NULL check on list iterator
cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
cifs: prevent bad output lengths in smb2_ioctl_query_info()
Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
riscv: Increase stack size under KASAN
riscv: Fix fill_callchain return value
qed: display VF trust config
scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
mempolicy: mbind_range() set_policy() after vma_merge()
mm: invalidate hwpoison page cache page in fault path
mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
mtd: rawnand: protect access to rawnand devices while in suspend
spi: mxic: Fix the transmit path
pinctrl: samsung: drop pin banks references on error paths
remoteproc: Fix count check in rproc_coredump_write()
f2fs: fix to do sanity check on .cp_pack_total_block_count
f2fs: quota: fix loop condition at f2fs_quota_sync()
f2fs: fix to unlock page correctly in error path of is_alive()
NFSD: prevent integer overflow on 32 bit systems
NFSD: prevent underflow in nfssvc_decode_writeargs()
SUNRPC: avoid race between mod_timer() and del_timer_sync()
HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
firmware: stratix10-svc: add missing callback parameter on RSU
Documentation: update stable tree link
Documentation: add link to stable release candidate tree
KEYS: fix length validation in keyctl_pkey_params_get_2()
clk: uniphier: Fix fixed-rate initialization
greybus: svc: fix an error handling bug in gb_svc_hello()
iio: inkern: make a best effort on offset calculation
iio: inkern: apply consumer scale when no channel scale is available
iio: inkern: apply consumer scale on IIO_VAL_INT cases
iio: afe: rescale: use s64 for temporary scale calculations
coresight: Fix TRCCONFIGR.QE sysfs interface
mei: avoid iterator usage outside of list_for_each_entry
mei: me: add Alder Lake N device id.
xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
xhci: make xhci_handshake timeout for xhci_reset() adjustable
xhci: fix runtime PM imbalance in USB2 resume
xhci: fix garbage USBSTS being logged in some cases
USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c
virtio-blk: Use blk_validate_block_size() to validate block size
tpm: fix reference counting for struct tpm_chip
iommu/iova: Improve 32-bit free space estimate
locking/lockdep: Avoid potential access of invalid memory in lock_class
net: dsa: microchip: add spi_device_id tables
Input: zinitix - do not report shadow fingers
spi: Fix erroneous sgs value with min_t()
Revert "gpio: Revert regression in sysfs-gpio (gpiolib.c)"
net:mcf8390: Use platform_get_irq() to get the interrupt
spi: Fix invalid sgs value
gpio: Revert regression in sysfs-gpio (gpiolib.c)
ethernet: sun: Free the coherent when failing in probing
tools/virtio: fix virtio_test execution
vdpa/mlx5: should verify CTRL_VQ feature exists for MQ
virtio_console: break out of buf poll on remove
ARM: mstar: Select HAVE_ARM_ARCH_TIMER
xfrm: fix tunnel model fragmentation behavior
HID: logitech-dj: add new lightspeed receiver id
hv: utils: add PTP_1588_CLOCK to Kconfig to fix build
USB: serial: simple: add Nokia phone driver
USB: serial: pl2303: add IBM device IDs
already merged(32)
can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error path
KVM: x86/mmu: do compare-and-exchange of gPTE via the user address
ubi: fastmap: Return error code if memory allocation fails in add_aeb()
ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl
net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware
can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path
ubifs: rename_whiteout: correct old_dir size computing
ubifs: Fix to add refcount once page is set private
ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock()
ubifs: setflags: Make dirtied_ino_d 8 bytes aligned
ubifs: Add missing iput if do_tmpfile() failed in rename whiteout
ubifs: Fix deadlock in concurrent rename whiteout and inode writeback
ubifs: rename_whiteout: Fix double free for whiteout_ui->data
bfq: fix use-after-free in bfq_dispatch_request
block, bfq: don't move oom_bfqq
net/x25: Fix null-ptr-deref caused by x25_disconnect
net: hns3: fix bug when PF set the duplicate MAC address for VFs
bpf, sockmap: Fix double uncharge the mem of sk_msg
bpf, sockmap: Fix more uncharged while msg has more_data
bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full
livepatch: Fix build failure on 32 bits processors
drm/i915/opregion: check port number bounds for SWSCI display power state
bcache: fixup multiple threads crash
drivers: hamradio: 6pack: fix UAF bug caused by mod_timer()
jffs2: fix memory leak in jffs2_scan_medium
jffs2: fix memory leak in jffs2_do_mount_fs
jffs2: fix use-after-free in jffs2_clear_xattr_subsystem
can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path
ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE
af_key: add __GFP_ZERO flag for compose_sadb_supported in function
pfkey_register
netdevice: add the case if dev is NULL
swiotlb: fix info leak with DMA_FROM_DEVICE
kabi conflict(8)
PCI: Reduce warnings on possible RW1C corruption
qed: validate and restrict untrusted VFs vlan promisc mode
block: don't merge across cgroup boundaries if blkcg is enabled
rseq: Remove broken uapi field layout on 32-bit little endian
coredump: Use the vma snapshot in fill_files_note
coredump/elf: Pass coredump_params into fill_note_info
coredump: Remove the WARN_ON in dump_vma_snapshot
coredump: Snapshot the vmas in do_coredump
Total Patches = 597 - 32 - 8 = 557
Aaron Conole (1):
openvswitch: always update flow key after nat
Aashish Sharma (1):
dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
Abel Vesa (2):
clk: imx7d: Remove audio_mclk_root_clk
ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
Adrian Hunter (2):
perf/core: Fix address filter parser for multiple filters
perf/x86/intel/pt: Fix address filter config for 32-bit kernel
Aharon Landau (1):
RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
Akira Kawata (1):
fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
Alan Stern (1):
USB: usb-storage: Fix use of bitfields for hardware data in
ene_ub6250.c
Alexander Lobakin (2):
i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
i40e: respect metadata on XSK Rx to skb
Alexander Usyskin (2):
mei: me: add Alder Lake N device id.
mei: avoid iterator usage outside of list_for_each_entry
Alexey Khoroshilov (1):
NFS: remove unneeded check in decode_devicenotify_args()
Alistair Delva (1):
remoteproc: Fix count check in rproc_coredump_write()
Alistair Popple (1):
mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
Amadeusz Sławiński (1):
ASoC: topology: Allow TLV control to be either read or write
Amir Goldstein (1):
nfsd: more robust allocation failure handling in nfsd_file_cache_init
Ammar Faizi (1):
ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
Anders Roxell (3):
powerpc/lib/sstep: Fix 'sthcx' instruction
powerpc/lib/sstep: Fix build errors with newer binutils
powerpc: Fix build errors with newer binutils
Andre Przywara (1):
ARM: configs: multi_v5_defconfig: re-enable
CONFIG_V4L_PLATFORM_DRIVERS
Andreas Gruenbacher (1):
powerpc/kvm: Fix kvm_use_magic_page
Andrew Price (1):
gfs2: Make sure FITRIM minlen is rounded up to fs block size
Andy Shevchenko (3):
spi: pxa2xx-pci: Balance reference count for PCI DMA device
serial: 8250_mid: Balance reference count for PCI DMA device
serial: 8250_lpss: Balance reference count for PCI DMA device
Ang Tien Sung (1):
firmware: stratix10-svc: add missing callback parameter on RSU
Anssi Hannula (3):
xhci: fix garbage USBSTS being logged in some cases
xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
hv_balloon: rate-limit "Unhandled message" warning
Anton Ivanov (1):
um: Fix uml_mconsole stop/go
Ard Biesheuvel (1):
ARM: ftrace: avoid redundant loads or clobbering IP
Armin Wolf (1):
hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
Arnd Bergmann (4):
uaccess: fix nios2 and microblaze get_user_8()
uaccess: fix type mismatch warnings from access_ok()
lib/test_lockup: fix kernel pointer check for separate address spaces
ARM: iop32x: offset IRQ numbers by 1
Arun Easi (2):
scsi: qla2xxx: Fix device reconnect in loop topology
scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
Arınç ÜNAL (5):
staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
staging: mt7621-dts: fix formatting
staging: mt7621-dts: fix pinctrl properties for ethernet
staging: mt7621-dts: fix GB-PC2 devicetree
staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on
ethernet
Athira Rajeev (1):
powerpc/perf: Don't use perf_hw_context for trace IMC PMU
Bagas Sanjaya (2):
Documentation: add link to stable release candidate tree
Documentation: update stable tree link
Bartosz Golaszewski (1):
Revert "gpio: Revert regression in sysfs-gpio (gpiolib.c)"
Bharata B Rao (1):
sched/debug: Remove mpol_get/put and task_lock/unlock from
sched_show_numa
Biju Das (2):
spi: Fix invalid sgs value
spi: Fix erroneous sgs value with min_t()
Bikash Hazarika (1):
scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
Bjorn Helgaas (1):
PCI: Avoid broken MSI on SB600 USB devices
Brandon Wyman (1):
hwmon: (pmbus) Add Vin unit off handling
Casey Schaufler (2):
LSM: general protection fault in legacy_parse_param
Fix incorrect type in assignment of ipv6 port for audit
Chaitanya Kulkarni (1):
loop: use sysfs_emit() in the sysfs xxx show()
Chao Yu (6):
f2fs: fix to unlock page correctly in error path of is_alive()
f2fs: fix to do sanity check on .cp_pack_total_block_count
f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
f2fs: fix to avoid potential deadlock
f2fs: fix to do sanity check on curseg->alloc_type
f2fs: compress: fix to print raw data size in error path of lz4
decompression
Charan Teja Kalla (3):
mm: madvise: skip unmapped vma holes passed to process_madvise
mm: madvise: return correct bytes advised with process_madvise
Revert "mm: madvise: skip unmapped vma holes passed to
process_madvise"
Charles Keepax (1):
ASoC: madera: Add dependencies on MFD
Chen Jingwen (1):
powerpc/kasan: Fix early region not updated correctly
Chen-Yu Tsai (7):
media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across
ioctls
media: hantro: Fix overfill bottom register field name
pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
pinctrl: mediatek: paris: Fix "argument" argument type for
mtk_pinconf_get()
pinctrl: mediatek: paris: Fix pingroup pin config state readback
pinctrl: mediatek: paris: Skip custom extra pin config dump for
virtual GPIOs
pinctrl: pinconf-generic: Print arguments for bias-pull-*
Chris Leech (1):
nvme-tcp: lockdep: annotate in-kernel sockets
Christian Göttsche (2):
selinux: check return value of sel_make_avc_files
selinux: use correct type for context length
Christoph Hellwig (1):
nvme: cleanup __nvme_check_ids
Christophe JAILLET (4):
firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL
is not defined
gpu: host1x: Fix a memory leak in 'host1x_remove()'
fsi: Aspeed: Fix a potential double free
misc: alcor_pci: Fix an error handling path
Chuck Lever (1):
NFSD: Fix nfsd_breaker_owns_lease() return values
Claudiu Beznea (3):
net: dsa: microchip: add spi_device_id tables
hwrng: atmel - disable trng on failure path
clocksource/drivers/timer-microchip-pit64b: Use notrace
Codrin Ciubotariu (2):
ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
clk: at91: sama7g5: fix parents of PDMCs' GCLK
Colin Ian King (2):
carl9170: fix missing bit-wise or operator for tx_params
iwlwifi: Fix -EIO error code that is never returned
Cooper Chiou (1):
drm/edid: check basic audio support on CEA extension block
Corentin Labbe (8):
crypto: sun8i-ss - really disable hash on A80
crypto: rockchip - ECB does not need IV
crypto: sun8i-ss - call finalize with bh disabled
crypto: sun8i-ce - call finalize with bh disabled
crypto: amlogic - call finalize with bh disabled
media: staging: media: zoran: fix usage of
vb2_dma_contig_set_max_seg_size
media: staging: media: zoran: move videodev alloc
media: staging: media: zoran: calculate the right buffer number for
zoran_reap_stat_com
Dafna Hirschfeld (1):
media: stk1160: If start stream fails, return buffers with
VB2_BUF_STATE_QUEUED
Damien Le Moal (11):
scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
scsi: pm8001: Fix payload initialization in
pm80xx_set_thermal_config()
scsi: pm8001: Fix le32 values handling in
pm80xx_set_sas_protocol_timer_config()
scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
scsi: pm8001: Fix NCQ NON DATA command task initialization
scsi: pm8001: Fix NCQ NON DATA command completion handling
scsi: pm8001: Fix abort all task initialization
Dan Carpenter (9):
greybus: svc: fix an error handling bug in gb_svc_hello()
NFSD: prevent underflow in nfssvc_decode_writeargs()
NFSD: prevent integer overflow on 32 bit systems
video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
media: usb: go7007: s2250-board: fix leak in probe()
iwlwifi: mvm: Fix an error code in iwl_mvm_up()
USB: storage: ums-realtek: fix error code in rts51x_read_mem()
lib/test: use after free in register_test_dev_kmod()
Dan Williams (1):
nvdimm/region: Fix default alignment for small regions
Daniel González Cabanelas (1):
media: cx88-mpeg: clear interrupt status register before streaming
video
Daniel Henrique Barboza (1):
powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
Daniel Palmer (1):
ARM: mstar: Select HAVE_ARM_ARCH_TIMER
Daniel Thompson (2):
soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
kdb: Fix the putarea helper function
Dario Binacchi (1):
mtd: rawnand: gpmi: fix controller timings setting
Darren Hart (1):
ACPI/APEI: Limit printable size of BERT table data
Dave Stevenson (1):
regulator: rpi-panel: Handle I2C errors/timing to the Atmel
David Engraf (1):
arm64: signal: nofpsimd: Do not allocate fp/simd context when not
available
David Gow (1):
firmware: google: Properly state IOMEM dependency
David Heidelberg (2):
arm64: dts: qcom: sdm845: fix microphone bias properties and values
ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
David Howells (3):
watch_queue: Fix NULL dereference in error cleanup
watch_queue: Actually free the watch
rxrpc: Fix call timer start racing with call destruction
David Matlack (1):
KVM: Prevent module exit until all VMs are freed
Dirk Buchwalder (1):
clk: qcom: ipq8074: Use floor ops for SDCC1 clock
Dirk Müller (1):
lib/raid6/test: fix multiple definition linking error
Dmitry Baryshkov (3):
drm/msm/dpu: add DSPP blocks teardown
drm/msm/dpu: fix dp audio condition
PM: core: keep irq flags in device_pm_check_callbacks()
Dmitry Torokhov (1):
HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
Dmitry Vyukov (1):
riscv: Increase stack size under KASAN
Dongliang Mu (3):
media: em28xx: initialize refcount before kref_get
ntfs: add sanity check on allocation size
media: hdpvr: initialize dev->worker at hdpvr_register_videodev
Drew Fustini (1):
clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
Dāvis Mosāns (1):
crypto: ccp - ccp_dmaengine_unregister release dma channels
Eddie James (1):
USB: serial: pl2303: add IBM device IDs
Eric Biggers (6):
KEYS: fix length validation in keyctl_pkey_params_get_2()
crypto: rsa-pkcs1pad - only allow with rsa
crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
crypto: rsa-pkcs1pad - restore signature length check
crypto: rsa-pkcs1pad - fix buffer overread in
pkcs1pad_verify_complete()
block: don't delete queue kobject before its children
Eric Dumazet (2):
rseq: Optimise rseq_get_rseq_cs() and clear_rseq_cs()
watch_queue: Free the page array when watch_queue is dismantled
Evgeny Novikov (1):
video: fbdev: w100fb: Reset global state
Fabiano Rosas (2):
KVM: PPC: Fix vmx/vsx mixup in mmio emulation
KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
Fangrui Song (1):
riscv module: remove (NOLOAD)
Felix Maurer (1):
selftests/bpf: Make test_lwt_ip_encap more stable and faster
Fengnan Chang (2):
f2fs: compress: remove unneeded read when rewrite whole cluster
f2fs: fix compressed file start atomic write may cause data corruption
Filipe Manana (1):
btrfs: fix unexpected error path when reflinking an inline extent
Florian Fainelli (1):
net: phy: broadcom: Fix brcm_fet_config_init()
Frank Wunderlich (1):
arm64: dts: broadcom: Fix sata nodename
Geert Uytterhoeven (3):
hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
pinctrl: renesas: checker: Fix miscalculation of number of states
George Kennedy (1):
video: fbdev: cirrusfb: check pixclock to avoid divide by zero
Gilad Ben-Yossef (1):
crypto: ccree - don't attempt 0 len DMA mappings
Guilherme G. Piccoli (1):
docs: sysctl/kernel: add missing bit to panic_print
Guillaume Nault (1):
ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
Guillaume Ranquet (1):
clocksource/drivers/timer-of: Check return value of of_iomap in
timer_of_base_init()
Guillaume Tucker (1):
selftests, x86: fix how check_cc.sh is being invoked
Gwendal Grignou (2):
HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
platform: chrome: Split trace include file
Hangbin Liu (2):
bareudp: use ipv6_mod_enabled to check if IPv6 enabled
selftests/bpf/test_lirc_mode2.sh: Exit with proper code
Hangyu Hua (1):
powerpc: 8xx: fix a return value error in mpc8xx_pic_init
Hans Verkuil (2):
ivtv: fix incorrect device_caps for ivtvfb
media: staging: media: zoran: fix various V4L2 compliance errors
Hans de Goede (3):
power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong
false return
iio: mma8452: Fix probe failing when an i2c_device_id is used
media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2
regulator off on some boards
Hector Martin (4):
brcmfmac: firmware: Allocate space for default boardrev in nvram
brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
brcmfmac: pcie: Fix crashes due to early IRQs
Helge Deller (1):
video: fbdev: sm712fb: Fix crash in smtcfb_read()
Hengqi Chen (1):
bpf: Fix comment for helper bpf_current_task_under_cgroup()
Henry Lin (1):
xhci: fix runtime PM imbalance in USB2 resume
Herbert Xu (2):
crypto: authenc - Fix sleep in atomic context in decrypt_tail
crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
Hoang Le (1):
tipc: fix the timer expires after interval 100ms
Hou Tao (2):
bpf, arm64: Call build_prologue() first in first JIT pass
bpf, arm64: Feed byte-offset into bpf line info
Hou Wenlong (1):
KVM: x86/emulator: Defer not-present segment check in
__load_segment_descriptor()
Hugh Dickins (1):
mempolicy: mbind_range() set_policy() after vma_merge()
Håkon Bugge (1):
IB/cma: Allow XRC INI QPs to set their local ACK timeout
Ido Schimmel (1):
selftests: test_vxlan_under_vrf: Fix broken test case
Ilpo Järvinen (1):
serial: 8250: fix XOFF/XON sending when DMA is used
Jaegeuk Kim (1):
f2fs: fix missing free nid in f2fs_handle_failed_inode
Jagan Teki (1):
drm: bridge: adv7511: Fix ADV7535 HPD enablement
Jakob Koschel (2):
media: saa7134: fix incorrect use to determine if list is empty
powerpc/sysdev: fix incorrect use to determine if list is empty
Jakub Kicinski (1):
tcp: ensure PMTU updates are processed during fastopen
Jakub Sitnicki (1):
selftests/bpf: Fix error reporting from sock_fields programs
James Clark (1):
coresight: Fix TRCCONFIGR.QE sysfs interface
Jammy Huang (1):
media: aspeed: Correct value for h-total-pixels
Jann Horn (2):
coredump: Also dump first pages of non-executable ELF libraries
pstore: Don't use semaphores in always-atomic-context code
Jason A. Donenfeld (2):
wireguard: queueing: use CFI-safe ptr_ring cleanup function
wireguard: socket: ignore v6 endpoints when ipv6 is disabled
Jens Axboe (1):
io_uring: terminate manual loop iterator loop correctly for non-vecs
Jeremy Linton (1):
net: bcmgenet: Use stronger register read/writes to assure ordering
Jernej Skrabec (2):
media: cedrus: H265: Fix neighbour info buffer size
media: cedrus: h264: Fix neighbour info buffer size
Jia-Ju Bai (3):
ASoC: rt5663: check the return value of devm_kzalloc() in
rt5663_parse_dp()
memory: emif: check the pointer temp in get_device_details()
platform/x86: huawei-wmi: check the return value of
device_create_file()
Jianglei Nie (1):
crypto: ccree - Fix use after free in cc_cipher_exit()
Jianyong Wu (1):
arm64/mm: avoid fixmap race condition when create pud mapping
Jiasheng Jiang (26):
thermal: int340x: Check for NULL after calling kmemdup()
spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
media: mtk-vcodec: potential dereference of null pointer
media: meson: vdec: potential dereference of null pointer
soc: qcom: rpmpd: Check for null return of devm_kcalloc
ASoC: ti: davinci-i2s: Add check for clk_enable()
ALSA: spi: Add check for clk_enable()
ASoC: mxs-saif: Handle errors for clk_enable
ASoC: atmel_ssc_dai: Handle errors for clk_enable
ASoC: dwc-i2s: Handle errors for clk_enable
ASoC: soc-compress: prevent the potentially use of null pointer
memory: emif: Add check for setup_interrupts
media: vidtv: Check for null return of vzalloc
ASoC: wm8350: Handle error for wm8350_register_irq
ASoC: fsi: Add check for clk_enable
mmc: davinci_mmc: Handle error for clk_enable
drm/panfrost: Check for error num after setting mask
mtd: onenand: Check for error irq
ray_cs: Check ioremap return value
iommu/ipmmu-vmsa: Check for error num after setting mask
power: supply: wm8350-power: Handle error for wm8350_register_irq
power: supply: wm8350-power: Add missing free in free_charger_irq
mfd: mc13xxx: Add check for mc13xxx_irq_request
iio: adc: Add check for devm_request_threaded_irq
habanalabs: Add check for pci_enable_device
ASoC: soc-compress: Change the check for codec_dai
Jiaxin Yu (1):
ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
Jie Hai (1):
dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
Jing Yao (3):
video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of
snprintf()
video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead
of snprintf()
video: fbdev: udlfb: replace snprintf in show functions with
sysfs_emit
Jiri Slaby (1):
mxser: fix xmit_buf leak in activate when LSR == 0xff
Jocelyn Falempe (1):
mgag200 fix memmapsl configuration in GCTL6 register
Joe Carnuccio (2):
scsi: qla2xxx: Add devids and conditionals for 28xx
scsi: qla2xxx: Check for firmware dump already collected
Johan Hovold (3):
USB: serial: simple: add Nokia phone driver
media: davinci: vpif: fix unbalanced runtime PM get
media: davinci: vpif: fix unbalanced runtime PM enable
John David Anglin (1):
parisc: Fix handling off probe non-access faults
Jonathan Cameron (1):
staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
Jonathan Neuschäfer (5):
clk: actions: Terminate clk_div_table with sentinel element
clk: loongson1: Terminate clk_div_table with sentinel element
clk: clps711x: Terminate clk_div_table with sentinel element
pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
José Expósito (1):
Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
Juergen Gross (1):
xen: fix is_xen_pmu()
Juhyung Park (1):
f2fs: quota: fix loop condition at f2fs_quota_sync()
Kai-Heng Feng (1):
ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
Kees Cook (2):
exec: Force single empty string when argv is empty
gcc-plugins/stackleak: Exactly match strings instead of prefixes
Konrad Dybcio (1):
clk: qcom: gcc-msm8994: Fix gpll4 width
Krzysztof Kozlowski (5):
pinctrl: samsung: drop pin banks references on error paths
ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
ARM: dts: exynos: add missing HDMI supplies on SMDK5250
ARM: dts: exynos: add missing HDMI supplies on SMDK5420
clocksource/drivers/exynos_mct: Handle DTS with higher number of
interrupts
Kuan-Ying Lee (1):
mm/kmemleak: reset tag when compare object pointer
Kuldeep Singh (3):
arm64: dts: ns2: Fix spi-cpol and spi-cpha property
ARM: dts: spear1340: Update serial node properties
ARM: dts: spear13xx: Update SPI dma properties
Kunihiko Hayashi (1):
clk: uniphier: Fix fixed-rate initialization
Kuogee Hsieh (1):
drm/msm/dp: populate connector of struct dp_panel
Lars Ellenberg (1):
drbd: fix potential silent data corruption
Li RongQing (1):
KVM: x86: fix sending PV IPI
Liam Beguin (4):
iio: afe: rescale: use s64 for temporary scale calculations
iio: inkern: apply consumer scale on IIO_VAL_INT cases
iio: inkern: apply consumer scale when no channel scale is available
iio: inkern: make a best effort on offset calculation
Libin Yang (1):
soundwire: intel: fix wrong register name in intel_shim_wake
Liguang Zhang (1):
PCI: pciehp: Clear cmd_busy bit in polling mode
Lina Wang (1):
xfrm: fix tunnel model fragmentation behavior
Lino Sanfilippo (1):
tpm: fix reference counting for struct tpm_chip
Linus Torvalds (2):
fs: fd tables have to be multiples of BITS_PER_LONG
fs: fix fd table size alignment properly
Linus Walleij (1):
Input: zinitix - do not report shadow fingers
Liu Ying (1):
phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
Lorenzo Bianconi (4):
mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in
sta mode
mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
Luca Weiss (1):
cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
Lucas Tanure (1):
i2c: meson: Fix wrong speed use from probe
Lucas Zampieri (1):
HID: logitech-dj: add new lightspeed receiver id
Lv Ruyi (1):
proc: bootconfig: Add null pointer check
Maciej W. Rozycki (1):
DEC: Limit PMAX memory probing to R3k systems
Manish Chopra (1):
qed: display VF trust config
Manish Rangankar (1):
scsi: qla2xxx: Use correct feature type field during RFF_ID processing
Maor Gottlieb (1):
RDMA/core: Set MR type in ib_reg_user_mr
Marc Kleine-Budde (1):
can: m_can: m_can_tx_handler(): fix use after free of skb
Marc Zyngier (4):
PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
pinctrl: npcm: Fix broken references to chip->parent_device
irqchip/qcom-pdc: Fix broken locking
PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
Marcel Ziswiler (1):
arm64: defconfig: build imx-sdma as a module
Marcelo Roberto Jimenez (1):
gpio: Revert regression in sysfs-gpio (gpiolib.c)
Marek Szyprowski (1):
clocksource/drivers/exynos_mct: Refactor resources allocation
Marek Vasut (1):
ARM: dts: imx: Add missing LVDS decoder on M53Menlo
Marijn Suijten (1):
firmware: qcom: scm: Remove reassignment to desc following initializer
Martin Blumenstingl (1):
drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
Martin Varghese (1):
openvswitch: Fixed nd target mask field in the flow dump.
Mastan Katragadda (1):
drm/i915/gem: add missing boundary check in vm_access
Mathias Nyman (1):
xhci: make xhci_handshake timeout for xhci_reset() adjustable
Matt Kramer (1):
ALSA: hda/realtek: Add alc256-samsung-headphone fixup
Matthew Wilcox (Oracle) (2):
XArray: Fix xas_create_range() when multi-order entry present
XArray: Update the LRU list in xas_split()
Maulik Shah (1):
arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
Mauro Carvalho Chehab (1):
media: atomisp: fix bad usage at error handling logic
Max Filippov (2):
xtensa: fix stop_machine_cpuslocked call in patch_text
xtensa: fix xtensa_wsr always writing 0
Maxim Kiselev (1):
powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
Maxime Ripard (2):
drm/edid: Don't clear formats if using deep color
clk: Initialize orphan req_rate
Maíra Canal (1):
drm/amd/display: Remove vupdate_int_entry definition
Miaoqian Lin (31):
spi: tegra114: Add missing IRQ check in tegra_spi_probe
hwrng: nomadik - Change clk_disable to clk_disable_unprepare
media: coda: Fix missing put_device() call in coda_get_vdoa_data
soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in
rockchip_i2s_probe
ASoC: SOF: Add missing of_node_put() in imx8m_probe
ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in
msm8916_wcd_digital_probe
ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
ASoC: msm8916-wcd-analog: Fix error handling in
pm8916_wcd_analog_spmi_probe
ASoC: codecs: wcd934x: Add missing of_node_put() in
wcd934x_codec_parse_data
drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
ath10k: Fix error handling in ath10k_setup_msa_resources
mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
remoteproc: qcom_wcnss: Add missing of_node_put() in
wcnss_alloc_memory_region
remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
clk: tegra: tegra124-emc: Fix missing put_device() call in
emc_ensure_emc_driver
pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
Michael Ellerman (1):
powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
Michael S. Tsirkin (1):
virtio_console: break out of buf poll on remove
Michael Schmitz (1):
video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
Mike Marciniszyn (1):
IB/hfi1: Allow larger MTU without AIP
Mikulas Patocka (1):
dm integrity: set journal entry unused when shrinking device
Minghao Chi (1):
spi: tegra20: Use of_device_get_match_data()
Minghao Chi (CGEL ZTE) (1):
net:mcf8390: Use platform_get_irq() to get the interrupt
Miquel Raynal (4):
spi: mxic: Fix the transmit path
dt-bindings: mtd: nand-controller: Fix the reg property description
dt-bindings: mtd: nand-controller: Fix a comment in the examples
dt-bindings: spi: mxic: The interrupt property is not mandatory
Mohan Kumar (1):
ALSA: hda: Avoid unsol event during RPM suspending
Muhammad Usama Anjum (1):
selftests/x86: Add validity check and allow field splitting
Namhyung Kim (1):
bpf: Adjust BPF stack helper functions to accommodate skip > 0
Neil Armstrong (1):
drm/bridge: dw-hdmi: use safe format when first in bridge chain
NeilBrown (1):
SUNRPC: avoid race between mod_timer() and del_timer_sync()
Niels Dossche (1):
Bluetooth: call hci_le_conn_failed with hdev lock in
hci_le_conn_failed
Nikita Shubin (1):
riscv: Fix fill_callchain return value
Niklas Söderlund (1):
samples/bpf, xdpsock: Fix race when running for fix duration of time
Nilesh Javali (1):
scsi: qla2xxx: Fix warning for missing error code
Nishanth Menon (4):
arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
Olga Kornievskaia (1):
NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
Oliver Hartkopp (5):
can: isotp: sanitize CAN ID checks in isotp_bind()
vxcan: enable local echo for sent CAN frames
can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
can: isotp: support MSG_TRUNC flag when reading from socket
can: isotp: restore accidentally removed MSG_PEEK feature
Ondrej Zary (1):
media: bttv: fix WARNING regression on tunerless devices
Pablo Neira Ayuso (1):
netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
Pali Rohár (1):
PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
Paolo Valente (1):
Revert "Revert "block, bfq: honor already-setup queue merges""
Patrick Rudolph (1):
hwmon: (pmbus) Add mutex to regulator ops
Paul Kocialkowski (1):
ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
Paul Menzel (1):
lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
Paulo Alcantara (2):
cifs: prevent bad output lengths in smb2_ioctl_query_info()
cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
Pavel Begunkov (1):
io_uring: fix memory leak of uid in files registration
Pavel Kubelun (1):
ARM: dts: qcom: ipq4019: fix sleep clock
Pavel Skripkin (6):
udmabuf: validate ubuf->pagecount
Bluetooth: hci_serdev: call init_rwsem() before p->open()
ath9k_htc: fix uninit value bugs
jfs: fix divide error in dbNextAG
media: Revert "media: em28xx: add missing em28xx_close_extension"
can: mcba_usb: properly check endpoint type
Peiwei Hu (1):
media: ir_toy: free before error exiting
Pekka Pessi (1):
mailbox: tegra-hsp: Flush whole channel
Peng Liu (1):
kunit: make kunit_test_timeout compatible with comment
Peter Rosin (1):
i2c: mux: demux-pinctrl: do not deactivate a master that is not active
Petr Machata (1):
af_netlink: Fix shift out of bounds in group mask calculation
Petr Vorel (1):
crypto: vmx - add missing dependencies
Pierre-Louis Bossart (1):
ASoC: generic: simple-card-utils: remove useless assignment
Prashant Malani (1):
platform/chrome: cros_ec_typec: Check for EC device
Qais Yousef (1):
sched/core: Export pelt_thermal_tp
Quinn Tran (7):
scsi: qla2xxx: Fix stuck session in gpdb
scsi: qla2xxx: Fix scheduling while atomic
scsi: qla2xxx: Fix disk failure to rediscover
scsi: qla2xxx: Fix incorrect reporting of task management failure
scsi: qla2xxx: Fix hang due to session stuck
scsi: qla2xxx: Fix N2N inconsistent PLOGI
scsi: qla2xxx: Reduce false trigger to login
Rafael J. Wysocki (2):
ACPICA: Avoid walking the ACPI Namespace if it is not there
ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
Randy Dunlap (20):
hv: utils: add PTP_1588_CLOCK to Kconfig to fix build
EVM: fix the evm= __setup handler return value
PM: hibernate: fix __setup handler error handling
PM: suspend: fix return value of __setup handler
ACPI: APEI: fix return value of __setup handlers
clocksource: acpi_pm: fix return value of __setup handler
printk: fix return value of printk.devkmsg __setup handler
m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are
defined
TOMOYO: fix __setup handlers return values
mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
MIPS: RB532: fix return value of __setup handler
dma-debug: fix return value of __setup handlers
tty: hvc: fix return value of __setup handler
kgdboc: fix return value of __setup handler
kgdbts: fix return value of __setup handler
driver core: dd: fix return value of __setup handler
mm/mmap: return 1 from stack_guard_gap __setup() handler
ARM: 9187/1: JIVE: fix return value of __setup handler
mm/memcontrol: return 1 from cgroup.memory __setup() handler
mm/usercopy: return 1 from hardened_usercopy __setup() handler
Richard Guy Briggs (1):
audit: log AUDIT_TIME_* records only from rules
Richard Haines (1):
selinux: allow FIOCLEX and FIONCLEX with policy capability
Richard Leitner (1):
ARM: tegra: tamonten: Fix I2C3 pad setting
Richard Schleich (2):
ARM: dts: bcm2837: Add the missing L1/L2 cache information
ARM: dts: bcm2711: Add the missing L1/L2 cache information
Rik van Riel (2):
mm: invalidate hwpoison page cache page in fault path
mm,hwpoison: unmap poisoned page before invalidation
Ritesh Harjani (3):
ext4: fix ext4_fc_stats trace point
ext4: correct cluster len and clusters changed accounting in
ext4_mb_mark_bb
ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
Rob Herring (1):
arm64: dts: rockchip: Fix SDIO regulator supply properties on
rk3399-firefly
Robert Hancock (3):
ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
i2c: xiic: Make bus names unique
net: axienet: fix RX ring refill allocation failure handling
Robert Marko (1):
clk: qcom: ipq8074: fix PCI-E clock oops
Robin Gong (1):
mailbox: imx: fix wakeup failure from freeze mode
Robin Murphy (1):
iommu/iova: Improve 32-bit free space estimate
Roman Li (1):
drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
Sakari Ailus (1):
ACPI: properties: Consistently return -ENOENT if there are no more
references
Sam Ravnborg (1):
video: fbdev: controlfb: Fix set but not used warnings
Saurav Kashyap (1):
scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
Sean Christopherson (1):
KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP
MMU
Sean Nyekjaer (1):
mtd: rawnand: protect access to rawnand devices while in suspend
Sean Young (1):
media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
Shannon Nelson (1):
ionic: fix type complaint in ionic_dev_cmd_clean()
Shengjiu Wang (2):
ASoC: fsl_spdif: Disable TX clock when stop
ASoC: soc-core: skip zero num_dai component in searching dai name
Shin'ichiro Kawasaki (1):
block: limit request dispatch loop duration
Si-Wei Liu (1):
vdpa/mlx5: should verify CTRL_VQ feature exists for MQ
Souptick Joarder (HPE) (1):
irqchip/nvic: Release nvic_base upon failure
Srinivas Kandagatla (1):
ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
Srinivas Pandruvada (1):
thermal: int340x: Increase bitmap size
Stefano Garzarella (1):
tools/virtio: fix virtio_test execution
Sunil Goutham (1):
hwrng: cavium - Check health status while reading random data
Sven Eckelmann (1):
batman-adv: Check ptr for NULL before reducing its refcnt
Takashi Iwai (1):
ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
Takashi Sakamoto (1):
ALSA: firewire-lib: fix uninitialized flag for AV/C deferred
transaction
Taniya Das (2):
clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
clk: qcom: clk-rcg2: Update the frac table for pixel clock
Theodore Ts'o (1):
ext4: don't BUG if someone dirty pages without asking ext4 first
Thomas Bracht Laumann Jespersen (1):
scripts/dtc: Call pkg-config POSIXly correct
Tim Gardner (1):
video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
Tobias Waldekranz (1):
net: dsa: mv88e6xxx: Enable port policy support on 6097
Tom Rix (5):
media: video/hdmi: handle short reads of hdmi info frame.
drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq
function
qlcnic: dcb: default to returning -EOPNOTSUPP
can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error
value
rtc: check if __rtc_read_time was successful
Tomas Paukrt (1):
crypto: mxs-dcp - Fix scatterlist processing
Tong Zhang (1):
dax: make sure inodes are flushed before destroy cache
Trond Myklebust (3):
NFS: Use of mapping_set_error() results in spurious errors
NFS: Return valid errors from nfs2/3_decode_dirent()
NFSv4/pNFS: Fix another issue with a list iterator pointing to the
head
Tsuchiya Yuto (1):
media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
Tudor Ambarus (1):
ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
Ulf Hansson (1):
mmc: host: Return an error when ->enable_sdio_irq() ops is missing
Uwe Kleine-König (5):
vfio: platform: simplify device removal
amba: Make the remove callback return void
pwm: lpc18xx-sct: Initialize driver data and hardware before
pwmchip_add()
serial: 8250: Fix race condition in RTS-after-send handling
ARM: mmp: Fix failure to remove sram device
Vijay Balakrishna (1):
arm64: Do not defer reserve_crashkernel() for platforms with no DMA
memory zones
Vitaly Kuznetsov (1):
KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't
activated
Vladimir Oltean (1):
net: enetc: report software timestamping via SO_TIMESTAMPING
Waiman Long (2):
locking/lockdep: Avoid potential access of invalid memory in
lock_class
locking/lockdep: Iterate lock_classes directly when reading lockdep
files
Wang Hai (2):
video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
wireguard: socket: free skb in send6 when ipv6 is disabled
Wang Wensheng (1):
ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
Wen Gong (1):
ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
Xiang Chen (1):
scsi: hisi_sas: Change permission of parameter prot_mask
Xiaomeng Tong (2):
ALSA: cs4236: fix an incorrect NULL check on list iterator
net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
Xie Yongji (1):
virtio-blk: Use blk_validate_block_size() to validate block size
Xin Long (1):
udp: call udp_encap_enable for v6 sockets when enabling encap
Xin Xiong (1):
mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
Xu Kuohai (1):
libbpf: Skip forward declaration when counting duplicated type names
Yafang Shao (1):
libbpf: Fix possible NULL pointer dereference when destroying skeleton
Yake Yang (1):
Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
Yaliang Wang (1):
MIPS: pgalloc: fix memory leak caused by pgd_free()
Yang Guang (1):
video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
Yang Yingliang (3):
media: saa7134: convert list_for_each to entry variant
ASoC: rockchip: i2s: Use devm_platform_get_and_ioremap_resource()
ASoC: atmel: sam9x5_wm8731: use devm_snd_soc_register_card()
Yangtao Li (1):
fsi: aspeed: convert to devm_platform_ioremap_resource
Ye Bin (1):
ext4: fix fs corruption when tring to remove a non-empty directory
with IO error
Yi Wang (1):
KVM: SVM: fix panic on out-of-bounds guest IRQ
Yiqing Yao (1):
drm/amd/pm: enable pm sysfs write for one VF mode
Yongzhi Liu (1):
RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
YueHaibing (1):
video: fbdev: controlfb: Fix COMPILE_TEST build
Z. Liu (1):
video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200
to avoid black screen
Zhang Yi (1):
ext2: correct max file size computing
Zhenzhong Duan (1):
KVM: x86: Fix emulation in writing cr8
Zheyu Ma (2):
ethernet: sun: Free the coherent when failing in probing
video: fbdev: sm712fb: Fix crash in smtcfb_write()
Zhou Qingyang (2):
drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
drm/amd/display: Fix a NULL pointer dereference in
amdgpu_dm_connector_add_common_modes()
kernel test robot (1):
regulator: qcom_smd: fix for_each_child.cocci warnings
lic121 (1):
libbpf: Unmap rings when umem deleted
Documentation/admin-guide/sysctl/kernel.rst | 1 +
.../bindings/mtd/nand-controller.yaml | 4 +-
.../devicetree/bindings/spi/spi-mxic.txt | 4 +-
Documentation/process/stable-kernel-rules.rst | 11 +-
Documentation/sound/hd-audio/models.rst | 4 +
arch/arc/kernel/process.c | 2 +-
arch/arm/boot/dts/bcm2711.dtsi | 50 +++++
arch/arm/boot/dts/bcm2837.dtsi | 49 ++++
arch/arm/boot/dts/dra7-l4.dtsi | 5 +-
arch/arm/boot/dts/dra7.dtsi | 8 +-
arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +-
arch/arm/boot/dts/exynos5250-smdk5250.dts | 3 +
arch/arm/boot/dts/exynos5420-smdk5420.dts | 3 +
arch/arm/boot/dts/imx53-m53menlo.dts | 29 ++-
arch/arm/boot/dts/imx7-colibri.dtsi | 4 +-
arch/arm/boot/dts/imx7-mba7.dtsi | 2 +-
arch/arm/boot/dts/imx7d-nitrogen7.dts | 2 +-
arch/arm/boot/dts/imx7d-pico-hobbit.dts | 4 +-
arch/arm/boot/dts/imx7d-pico-pi.dts | 4 +-
arch/arm/boot/dts/imx7d-sdb.dts | 4 +-
arch/arm/boot/dts/imx7s-warp.dts | 4 +-
arch/arm/boot/dts/qcom-ipq4019.dtsi | 3 +-
arch/arm/boot/dts/qcom-msm8960.dtsi | 8 +-
arch/arm/boot/dts/sama5d2.dtsi | 2 +-
arch/arm/boot/dts/spear1340.dtsi | 6 +-
arch/arm/boot/dts/spear13xx.dtsi | 6 +-
arch/arm/boot/dts/sun8i-v3s.dtsi | 22 +-
arch/arm/boot/dts/tegra20-tamonten.dtsi | 6 +-
arch/arm/configs/multi_v5_defconfig | 1 +
arch/arm/crypto/Kconfig | 2 +
arch/arm/kernel/entry-ftrace.S | 51 ++---
arch/arm/kernel/swp_emulate.c | 2 +-
arch/arm/kernel/traps.c | 2 +-
.../mach-iop32x/include/mach/entry-macro.S | 2 +-
arch/arm/mach-iop32x/include/mach/irqs.h | 2 +-
arch/arm/mach-iop32x/irq.c | 6 +-
arch/arm/mach-iop32x/irqs.h | 60 ++---
arch/arm/mach-mmp/sram.c | 22 +-
arch/arm/mach-mstar/Kconfig | 1 +
arch/arm/mach-s3c/mach-jive.c | 6 +-
.../boot/dts/broadcom/northstar2/ns2-svk.dts | 8 +-
.../boot/dts/broadcom/northstar2/ns2.dtsi | 2 +-
arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 +-
arch/arm64/boot/dts/qcom/sm8150.dtsi | 6 +-
.../boot/dts/rockchip/rk3399-firefly.dts | 4 +-
arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 5 +-
arch/arm64/boot/dts/ti/k3-am65.dtsi | 1 +
arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 5 +-
arch/arm64/boot/dts/ti/k3-j7200.dtsi | 1 +
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 5 +-
arch/arm64/boot/dts/ti/k3-j721e.dtsi | 1 +
arch/arm64/configs/defconfig | 2 +-
arch/arm64/kernel/signal.c | 10 +-
arch/arm64/mm/init.c | 36 ++-
arch/arm64/mm/mmu.c | 36 ++-
arch/arm64/net/bpf_jit_comp.c | 18 +-
arch/csky/kernel/perf_callchain.c | 2 +-
arch/csky/kernel/signal.c | 2 +-
arch/m68k/coldfire/device.c | 6 +-
arch/microblaze/include/asm/uaccess.h | 18 +-
arch/mips/dec/int-handler.S | 6 +-
arch/mips/dec/prom/Makefile | 2 +-
arch/mips/dec/setup.c | 3 +-
arch/mips/include/asm/dec/prom.h | 15 +-
arch/mips/include/asm/pgalloc.h | 6 +
arch/mips/rb532/devices.c | 6 +-
arch/nios2/include/asm/uaccess.h | 26 ++-
arch/nios2/kernel/signal.c | 20 +-
arch/parisc/include/asm/traps.h | 1 +
arch/parisc/kernel/traps.c | 2 +
arch/parisc/mm/fault.c | 89 ++++++++
arch/powerpc/Makefile | 2 +-
arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts | 30 +++
arch/powerpc/boot/dts/fsl/t1040rdb.dts | 8 +-
arch/powerpc/include/asm/io.h | 40 +++-
arch/powerpc/include/asm/uaccess.h | 3 +
arch/powerpc/kernel/kvm.c | 2 +-
arch/powerpc/kvm/book3s_hv.c | 5 +-
arch/powerpc/kvm/powerpc.c | 4 +-
arch/powerpc/lib/sstep.c | 12 +-
arch/powerpc/mm/kasan/kasan_init_32.c | 3 +-
arch/powerpc/mm/numa.c | 4 +-
arch/powerpc/perf/imc-pmu.c | 6 +-
arch/powerpc/platforms/8xx/pic.c | 1 +
arch/powerpc/platforms/powernv/rng.c | 6 +-
arch/powerpc/sysdev/fsl_gtm.c | 4 +-
arch/riscv/include/asm/module.lds.h | 6 +-
arch/riscv/include/asm/thread_info.h | 10 +-
arch/riscv/kernel/perf_callchain.c | 6 +-
arch/sparc/kernel/signal_32.c | 2 +-
arch/um/drivers/mconsole_kern.c | 3 +-
arch/x86/events/intel/pt.c | 2 +-
arch/x86/kernel/kvm.c | 2 +-
arch/x86/kvm/emulate.c | 14 +-
arch/x86/kvm/hyperv.c | 9 +-
arch/x86/kvm/lapic.c | 5 +-
arch/x86/kvm/mmu/tdp_mmu.c | 3 +
arch/x86/kvm/svm/avic.c | 10 +-
arch/x86/xen/pmu.c | 10 +-
arch/x86/xen/pmu.h | 3 +-
arch/x86/xen/smp_pv.c | 2 +-
arch/xtensa/include/asm/processor.h | 4 +-
arch/xtensa/kernel/jump_label.c | 2 +-
block/bfq-iosched.c | 16 +-
block/blk-mq-sched.c | 9 +-
block/blk-sysfs.c | 8 +-
crypto/authenc.c | 2 +-
crypto/rsa-pkcs1pad.c | 11 +-
drivers/acpi/acpica/nswalk.c | 3 +
drivers/acpi/apei/bert.c | 10 +-
drivers/acpi/apei/erst.c | 2 +-
drivers/acpi/apei/hest.c | 2 +-
drivers/acpi/cppc_acpi.c | 5 +
drivers/acpi/property.c | 2 +-
drivers/amba/bus.c | 5 +-
drivers/base/dd.c | 2 +-
drivers/base/power/main.c | 6 +-
drivers/block/drbd/drbd_req.c | 3 +-
drivers/block/loop.c | 10 +-
drivers/block/virtio_blk.c | 12 +-
drivers/bluetooth/btmtksdio.c | 4 +-
drivers/bluetooth/hci_serdev.c | 3 +-
drivers/bus/mips_cdmm.c | 1 +
drivers/char/hw_random/Kconfig | 2 +-
drivers/char/hw_random/atmel-rng.c | 1 +
drivers/char/hw_random/cavium-rng-vf.c | 194 +++++++++++++++-
drivers/char/hw_random/cavium-rng.c | 11 +-
drivers/char/hw_random/nomadik-rng.c | 7 +-
drivers/char/tpm/tpm-chip.c | 46 +---
drivers/char/tpm/tpm.h | 2 +
drivers/char/tpm/tpm2-space.c | 65 ++++++
drivers/char/virtio_console.c | 7 +
drivers/clk/actions/owl-s700.c | 1 +
drivers/clk/actions/owl-s900.c | 2 +-
drivers/clk/at91/sama7g5.c | 8 +-
drivers/clk/clk-clps711x.c | 2 +
drivers/clk/clk.c | 13 ++
drivers/clk/imx/clk-imx7d.c | 1 -
drivers/clk/loongson1/clk-loongson1c.c | 1 +
drivers/clk/qcom/clk-rcg2.c | 14 +-
drivers/clk/qcom/gcc-ipq8074.c | 21 +-
drivers/clk/qcom/gcc-msm8994.c | 1 +
drivers/clk/tegra/clk-tegra124-emc.c | 1 +
.../clk/uniphier/clk-uniphier-fixed-rate.c | 1 +
drivers/clocksource/acpi_pm.c | 6 +-
drivers/clocksource/exynos_mct.c | 60 +++--
drivers/clocksource/timer-microchip-pit64b.c | 2 +-
drivers/clocksource/timer-of.c | 6 +-
drivers/clocksource/timer-ti-dm-systimer.c | 4 +-
drivers/cpufreq/qcom-cpufreq-nvmem.c | 2 +-
.../allwinner/sun8i-ce/sun8i-ce-cipher.c | 3 +
.../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 3 +
.../allwinner/sun8i-ss/sun8i-ss-cipher.c | 3 +
.../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 2 +
.../crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 3 +
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 2 +
drivers/crypto/ccp/ccp-dmaengine.c | 16 ++
drivers/crypto/ccree/cc_buffer_mgr.c | 7 +
drivers/crypto/ccree/cc_cipher.c | 2 +-
drivers/crypto/mxs-dcp.c | 2 +-
.../crypto/rockchip/rk3288_crypto_skcipher.c | 1 -
drivers/crypto/vmx/Kconfig | 4 +
drivers/dax/super.c | 1 +
drivers/dma-buf/udmabuf.c | 4 +
drivers/dma/hisi_dma.c | 2 +-
drivers/dma/pl330.c | 3 +-
drivers/firmware/efi/efi-pstore.c | 2 +-
drivers/firmware/google/Kconfig | 2 +-
drivers/firmware/qcom_scm.c | 6 -
drivers/firmware/stratix10-svc.c | 2 +-
drivers/fsi/fsi-master-aspeed.c | 21 +-
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +-
.../display/dc/irq/dcn21/irq_service_dcn21.c | 14 --
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 4 +-
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +-
drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 +
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 29 ++-
drivers/gpu/drm/bridge/cdns-dsi.c | 1 +
drivers/gpu/drm/bridge/nwl-dsi.c | 1 +
drivers/gpu/drm/bridge/sil-sii8620.c | 2 +-
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 5 +-
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 1 +
drivers/gpu/drm/drm_edid.c | 11 +-
drivers/gpu/drm/i915/gem/i915_gem_mman.c | 2 +-
drivers/gpu/drm/meson/meson_drv.c | 6 +-
drivers/gpu/drm/meson/meson_osd_afbcd.c | 41 ++--
drivers/gpu/drm/meson/meson_osd_afbcd.h | 1 +
drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 8 +
drivers/gpu/drm/msm/dp/dp_display.c | 5 +
.../gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c | 9 +-
drivers/gpu/drm/panfrost/panfrost_gpu.c | 5 +-
drivers/gpu/drm/pl111/pl111_drv.c | 4 +-
drivers/gpu/drm/tegra/dsi.c | 4 +-
drivers/gpu/host1x/dev.c | 1 +
drivers/greybus/svc.c | 8 +-
drivers/hid/hid-logitech-dj.c | 1 +
drivers/hid/i2c-hid/i2c-hid-core.c | 32 ++-
drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 29 +--
drivers/hv/Kconfig | 1 +
drivers/hv/hv_balloon.c | 2 +-
drivers/hwmon/pmbus/pmbus.h | 1 +
drivers/hwmon/pmbus/pmbus_core.c | 18 +-
drivers/hwmon/sch56xx-common.c | 2 +-
drivers/hwtracing/coresight/coresight-catu.c | 3 +-
.../hwtracing/coresight/coresight-cpu-debug.c | 4 +-
.../hwtracing/coresight/coresight-cti-core.c | 4 +-
drivers/hwtracing/coresight/coresight-etb10.c | 4 +-
.../coresight/coresight-etm3x-core.c | 4 +-
.../coresight/coresight-etm4x-core.c | 4 +-
.../coresight/coresight-etm4x-sysfs.c | 8 +-
.../hwtracing/coresight/coresight-funnel.c | 4 +-
.../coresight/coresight-replicator.c | 4 +-
drivers/hwtracing/coresight/coresight-stm.c | 4 +-
.../hwtracing/coresight/coresight-tmc-core.c | 4 +-
drivers/hwtracing/coresight/coresight-tpiu.c | 4 +-
drivers/i2c/busses/i2c-meson.c | 12 +-
drivers/i2c/busses/i2c-nomadik.c | 4 +-
drivers/i2c/busses/i2c-xiic.c | 3 +-
drivers/i2c/muxes/i2c-demux-pinctrl.c | 5 +-
drivers/iio/accel/mma8452.c | 29 ++-
drivers/iio/adc/twl6030-gpadc.c | 2 +
drivers/iio/afe/iio-rescale.c | 8 +-
drivers/iio/inkern.c | 40 +++-
drivers/infiniband/core/cma.c | 2 +-
drivers/infiniband/core/verbs.c | 1 +
drivers/infiniband/hw/hfi1/verbs.c | 3 +-
drivers/infiniband/hw/mlx5/devx.c | 4 +-
drivers/infiniband/hw/mlx5/mr.c | 2 +
drivers/input/input.c | 6 -
drivers/input/serio/ambakmi.c | 3 +-
drivers/input/touchscreen/zinitix.c | 44 +++-
drivers/iommu/iova.c | 5 +-
drivers/iommu/ipmmu-vmsa.c | 4 +-
drivers/irqchip/irq-nvic.c | 2 +
drivers/irqchip/qcom-pdc.c | 5 +-
drivers/mailbox/imx-mailbox.c | 9 +
drivers/mailbox/tegra-hsp.c | 5 +
drivers/md/dm-crypt.c | 2 +-
drivers/md/dm-integrity.c | 6 +-
drivers/media/i2c/adv7511-v4l2.c | 2 +-
drivers/media/i2c/adv7604.c | 2 +-
drivers/media/i2c/adv7842.c | 2 +-
drivers/media/pci/bt8xx/bttv-driver.c | 4 +-
drivers/media/pci/cx88/cx88-mpeg.c | 3 +
drivers/media/pci/ivtv/ivtv-driver.h | 1 -
drivers/media/pci/ivtv/ivtv-ioctl.c | 10 +-
drivers/media/pci/ivtv/ivtv-streams.c | 11 +-
drivers/media/pci/saa7134/saa7134-alsa.c | 8 +-
drivers/media/platform/aspeed-video.c | 9 +-
drivers/media/platform/coda/coda-common.c | 1 +
drivers/media/platform/davinci/vpif.c | 12 +-
.../platform/mtk-vcodec/mtk_vcodec_fw_vpu.c | 2 +
drivers/media/rc/gpio-ir-tx.c | 28 ++-
drivers/media/rc/ir_toy.c | 2 +-
.../media/test-drivers/vidtv/vidtv_s302m.c | 17 +-
drivers/media/usb/em28xx/em28xx-cards.c | 13 +-
drivers/media/usb/go7007/s2250-board.c | 10 +-
drivers/media/usb/hdpvr/hdpvr-video.c | 4 +-
drivers/media/usb/stk1160/stk1160-core.c | 2 +-
drivers/media/usb/stk1160/stk1160-v4l.c | 10 +-
drivers/media/usb/stk1160/stk1160.h | 2 +-
drivers/media/v4l2-core/v4l2-mem2mem.c | 53 ++++-
drivers/memory/emif.c | 8 +-
drivers/memory/pl172.c | 4 +-
drivers/memory/pl353-smc.c | 4 +-
drivers/mfd/asic3.c | 10 +-
drivers/mfd/mc13xxx-core.c | 4 +-
drivers/misc/cardreader/alcor_pci.c | 9 +-
drivers/misc/habanalabs/common/debugfs.c | 2 +
drivers/misc/kgdbts.c | 4 +-
drivers/misc/mei/hw-me-regs.h | 1 +
drivers/misc/mei/interrupt.c | 35 ++-
drivers/misc/mei/pci-me.c | 1 +
drivers/mmc/core/host.c | 15 +-
drivers/mmc/host/davinci_mmc.c | 6 +-
drivers/mmc/host/mmci.c | 4 +-
drivers/mtd/nand/onenand/generic.c | 7 +-
drivers/mtd/nand/raw/atmel/nand-controller.c | 14 +-
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 3 +
drivers/mtd/nand/raw/nand_base.c | 44 ++--
drivers/net/bareudp.c | 25 +--
drivers/net/can/m_can/m_can.c | 5 +-
.../net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +-
drivers/net/can/usb/mcba_usb.c | 26 ++-
drivers/net/can/vxcan.c | 2 +-
drivers/net/dsa/bcm_sf2_cfp.c | 6 +-
drivers/net/dsa/microchip/ksz8795_spi.c | 11 +
drivers/net/dsa/microchip/ksz9477_spi.c | 12 +
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
drivers/net/ethernet/8390/mcf8390.c | 10 +-
.../net/ethernet/broadcom/genet/bcmgenet.c | 4 +-
.../ethernet/freescale/enetc/enetc_ethtool.c | 5 +-
drivers/net/ethernet/intel/i40e/i40e_xsk.c | 16 +-
.../net/ethernet/pensando/ionic/ionic_main.c | 6 +-
drivers/net/ethernet/qlogic/qed/qed_sriov.c | 1 +
.../net/ethernet/qlogic/qlcnic/qlcnic_dcb.h | 10 +-
drivers/net/ethernet/sun/sunhme.c | 6 +-
.../net/ethernet/xilinx/xilinx_axienet_main.c | 72 +++---
drivers/net/phy/broadcom.c | 21 ++
drivers/net/wireguard/queueing.c | 3 +-
drivers/net/wireguard/socket.c | 5 +-
drivers/net/wireless/ath/ath10k/snoc.c | 2 +-
drivers/net/wireless/ath/ath10k/wow.c | 7 +-
drivers/net/wireless/ath/ath9k/htc_hst.c | 5 +
drivers/net/wireless/ath/carl9170/main.c | 2 +-
.../broadcom/brcm80211/brcmfmac/firmware.c | 2 +
.../broadcom/brcm80211/brcmfmac/pcie.c | 66 ++----
.../net/wireless/intel/iwlwifi/dvm/mac80211.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 4 +-
.../net/wireless/mediatek/mt76/mt7603/main.c | 3 +
.../net/wireless/mediatek/mt76/mt7615/main.c | 3 +
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 9 +-
drivers/net/wireless/ray_cs.c | 6 +
drivers/nvdimm/region_devs.c | 3 +
drivers/nvme/host/core.c | 9 +-
drivers/nvme/host/tcp.c | 40 ++++
drivers/pci/controller/pci-aardvark.c | 4 +-
drivers/pci/controller/pci-xgene.c | 35 ++-
drivers/pci/hotplug/pciehp_hpc.c | 2 +
drivers/pci/quirks.c | 12 +
drivers/phy/phy-core-mipi-dphy.c | 4 +-
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 2 +
drivers/pinctrl/mediatek/pinctrl-paris.c | 30 ++-
drivers/pinctrl/nomadik/pinctrl-nomadik.c | 4 +-
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 185 ++++++++--------
drivers/pinctrl/pinconf-generic.c | 6 +-
drivers/pinctrl/pinctrl-rockchip.c | 2 +
drivers/pinctrl/renesas/core.c | 5 +-
drivers/pinctrl/renesas/pfc-r8a77470.c | 4 +-
drivers/pinctrl/samsung/pinctrl-samsung.c | 30 ++-
drivers/platform/chrome/Makefile | 3 +-
.../platform/chrome/cros_ec_sensorhub_ring.c | 3 +-
.../platform/chrome/cros_ec_sensorhub_trace.h | 123 +++++++++++
drivers/platform/chrome/cros_ec_trace.h | 95 --------
drivers/platform/chrome/cros_ec_typec.c | 6 +
drivers/platform/x86/huawei-wmi.c | 13 +-
drivers/power/reset/gemini-poweroff.c | 4 +-
drivers/power/supply/ab8500_fg.c | 4 +-
drivers/power/supply/bq24190_charger.c | 7 +-
drivers/power/supply/wm8350_power.c | 97 ++++++--
drivers/pwm/pwm-lpc18xx-sct.c | 20 +-
drivers/regulator/qcom_smd-regulator.c | 4 +-
.../regulator/rpi-panel-attiny-regulator.c | 56 ++++-
drivers/remoteproc/qcom_q6v5_adsp.c | 1 +
drivers/remoteproc/qcom_q6v5_mss.c | 11 +-
drivers/remoteproc/qcom_wcnss.c | 1 +
drivers/remoteproc/remoteproc_debugfs.c | 2 +-
drivers/rtc/interface.c | 7 +-
drivers/rtc/rtc-pl030.c | 4 +-
drivers/rtc/rtc-pl031.c | 4 +-
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
drivers/scsi/libsas/sas_ata.c | 2 +-
drivers/scsi/pm8001/pm8001_hwi.c | 23 +-
drivers/scsi/pm8001/pm80xx_hwi.c | 209 ++++++++++--------
drivers/scsi/qla2xxx/qla_attr.c | 7 +-
drivers/scsi/qla2xxx/qla_def.h | 10 +-
drivers/scsi/qla2xxx/qla_gs.c | 5 +-
drivers/scsi/qla2xxx/qla_init.c | 73 ++++--
drivers/scsi/qla2xxx/qla_iocb.c | 8 +-
drivers/scsi/qla2xxx/qla_isr.c | 1 +
drivers/scsi/qla2xxx/qla_mbx.c | 14 +-
drivers/scsi/qla2xxx/qla_nvme.c | 22 ++
drivers/scsi/qla2xxx/qla_os.c | 8 +-
drivers/scsi/qla2xxx/qla_sup.c | 4 +-
drivers/scsi/qla2xxx/qla_target.c | 4 +-
drivers/soc/qcom/ocmem.c | 1 +
drivers/soc/qcom/qcom_aoss.c | 2 +-
drivers/soc/qcom/rpmpd.c | 3 +
drivers/soc/ti/wkup_m3_ipc.c | 4 +-
drivers/soundwire/intel.c | 4 +-
drivers/spi/spi-mxic.c | 28 +--
drivers/spi/spi-pl022.c | 5 +-
drivers/spi/spi-pxa2xx-pci.c | 17 +-
drivers/spi/spi-tegra114.c | 4 +
drivers/spi/spi-tegra20-slink.c | 8 +-
drivers/spi/spi-zynqmp-gqspi.c | 5 +-
drivers/spi/spi.c | 4 +-
drivers/staging/iio/adc/ad7280a.c | 4 +-
.../staging/media/atomisp/pci/atomisp_acc.c | 28 ++-
.../media/atomisp/pci/atomisp_gmin_platform.c | 18 ++
drivers/staging/media/atomisp/pci/hmm/hmm.c | 7 +-
.../staging/media/hantro/hantro_h1_jpeg_enc.c | 2 +-
drivers/staging/media/hantro/hantro_h1_regs.h | 2 +-
drivers/staging/media/meson/vdec/esparser.c | 7 +-
.../staging/media/meson/vdec/vdec_helpers.c | 8 +-
.../staging/media/meson/vdec/vdec_helpers.h | 4 +-
.../staging/media/sunxi/cedrus/cedrus_h264.c | 2 +-
.../staging/media/sunxi/cedrus/cedrus_h265.c | 2 +-
drivers/staging/media/zoran/zoran.h | 2 +-
drivers/staging/media/zoran/zoran_card.c | 86 ++++---
drivers/staging/media/zoran/zoran_device.c | 7 +-
drivers/staging/media/zoran/zoran_driver.c | 18 +-
drivers/staging/mt7621-dts/gbpc1.dts | 40 ++--
drivers/staging/mt7621-dts/gbpc2.dts | 116 +++++++++-
drivers/staging/mt7621-dts/mt7621.dtsi | 26 ++-
.../intel/int340x_thermal/int3400_thermal.c | 7 +-
drivers/tty/hvc/hvc_iucv.c | 4 +-
drivers/tty/mxser.c | 15 +-
drivers/tty/serial/8250/8250_dma.c | 11 +-
drivers/tty/serial/8250/8250_lpss.c | 28 ++-
drivers/tty/serial/8250/8250_mid.c | 19 +-
drivers/tty/serial/8250/8250_port.c | 16 +-
drivers/tty/serial/amba-pl010.c | 4 +-
drivers/tty/serial/amba-pl011.c | 3 +-
drivers/tty/serial/kgdboc.c | 6 +-
drivers/tty/serial/serial_core.c | 14 ++
drivers/usb/host/xhci-hub.c | 5 +-
drivers/usb/host/xhci-mem.c | 2 +-
drivers/usb/host/xhci.c | 20 +-
drivers/usb/host/xhci.h | 14 +-
drivers/usb/serial/Kconfig | 1 +
drivers/usb/serial/pl2303.c | 1 +
drivers/usb/serial/pl2303.h | 3 +
drivers/usb/serial/usb-serial-simple.c | 7 +
drivers/usb/storage/ene_ub6250.c | 155 +++++++------
drivers/usb/storage/realtek_cr.c | 2 +-
drivers/vdpa/mlx5/net/mlx5_vnet.c | 18 +-
drivers/vfio/platform/vfio_amba.c | 15 +-
drivers/video/fbdev/amba-clcd.c | 4 +-
drivers/video/fbdev/atafb.c | 12 +-
drivers/video/fbdev/atmel_lcdfb.c | 11 +-
drivers/video/fbdev/cirrusfb.c | 16 +-
drivers/video/fbdev/controlfb.c | 6 +-
drivers/video/fbdev/core/fbcvt.c | 53 ++---
drivers/video/fbdev/matrox/matroxfb_base.c | 2 +-
drivers/video/fbdev/nvidia/nv_i2c.c | 2 +-
.../omap2/omapfb/displays/connector-dvi.c | 1 +
.../omap2/omapfb/displays/panel-dsi-cm.c | 8 +-
.../omapfb/displays/panel-sony-acx565akm.c | 2 +-
.../omapfb/displays/panel-tpo-td043mtea1.c | 4 +-
drivers/video/fbdev/sm712fb.c | 46 +---
drivers/video/fbdev/smscufx.c | 3 +-
drivers/video/fbdev/udlfb.c | 8 +-
drivers/video/fbdev/w100fb.c | 15 +-
drivers/watchdog/rti_wdt.c | 1 +
drivers/watchdog/sp805_wdt.c | 4 +-
fs/binfmt_elf.c | 24 +-
fs/btrfs/reflink.c | 7 +-
fs/cifs/smb2ops.c | 130 ++++++-----
fs/coredump.c | 39 +++-
fs/exec.c | 26 ++-
fs/ext2/super.c | 6 +-
fs/ext4/inline.c | 9 +-
fs/ext4/inode.c | 25 +++
fs/ext4/mballoc.c | 126 ++++++-----
fs/ext4/namei.c | 10 +-
fs/f2fs/checkpoint.c | 8 +-
fs/f2fs/compress.c | 5 +-
fs/f2fs/data.c | 9 +-
fs/f2fs/file.c | 5 +-
fs/f2fs/gc.c | 4 +-
fs/f2fs/inode.c | 1 +
fs/f2fs/node.c | 6 +-
fs/f2fs/segment.c | 7 +
fs/f2fs/super.c | 6 +-
fs/f2fs/sysfs.c | 2 +-
fs/file.c | 31 ++-
fs/gfs2/rgrp.c | 3 +-
fs/io_uring.c | 7 +-
fs/jfs/jfs_dmap.c | 7 +
fs/nfs/callback_proc.c | 27 +--
fs/nfs/callback_xdr.c | 4 -
fs/nfs/nfs2xdr.c | 2 +-
fs/nfs/nfs3xdr.c | 21 +-
fs/nfs/nfs4proc.c | 1 +
fs/nfs/pnfs.c | 11 +
fs/nfs/pnfs.h | 2 +
fs/nfs/write.c | 5 +-
fs/nfsd/filecache.c | 6 +-
fs/nfsd/nfs4state.c | 12 +-
fs/nfsd/nfsproc.c | 2 +-
fs/nfsd/xdr.h | 2 +-
fs/ntfs/inode.c | 4 +
fs/proc/bootconfig.c | 2 +
fs/pstore/platform.c | 38 ++--
include/linux/amba/bus.h | 2 +-
include/linux/mtd/rawnand.h | 2 +
include/linux/pstore.h | 6 +-
include/linux/serial_core.h | 2 +
include/linux/soc/ti/ti_sci_protocol.h | 2 +-
include/linux/sunrpc/xdr.h | 2 +
include/net/udp.h | 1 +
include/net/udp_tunnel.h | 3 +-
include/sound/pcm.h | 1 +
include/trace/events/ext4.h | 78 ++++---
include/trace/events/rxrpc.h | 8 +-
include/uapi/linux/bpf.h | 12 +-
kernel/audit.h | 4 +
kernel/auditsc.c | 87 ++++++--
kernel/bpf/stackmap.c | 56 ++---
kernel/debug/kdb/kdb_support.c | 2 +-
kernel/dma/debug.c | 4 +-
kernel/events/core.c | 3 +
kernel/locking/lockdep.c | 38 ++--
kernel/locking/lockdep_internals.h | 6 +-
kernel/locking/lockdep_proc.c | 51 ++++-
kernel/power/hibernate.c | 2 +-
kernel/power/suspend_test.c | 8 +-
kernel/printk/printk.c | 6 +-
kernel/rseq.c | 9 +
kernel/sched/core.c | 1 +
kernel/sched/debug.c | 10 -
kernel/watch_queue.c | 4 +-
lib/kunit/try-catch.c | 2 +-
lib/raid6/test/Makefile | 4 +-
lib/raid6/test/test.c | 1 -
lib/test_kmod.c | 1 +
lib/test_lockup.c | 11 +-
lib/test_xarray.c | 22 ++
lib/xarray.c | 4 +
mm/kmemleak.c | 9 +-
mm/madvise.c | 3 +-
mm/memcontrol.c | 2 +-
mm/memory.c | 17 +-
mm/mempolicy.c | 8 +-
mm/mmap.c | 2 +-
mm/page_alloc.c | 9 +-
mm/usercopy.c | 5 +-
net/batman-adv/bridge_loop_avoidance.c | 6 +
net/batman-adv/distributed-arp-table.c | 3 +
net/batman-adv/gateway_client.c | 12 +-
net/batman-adv/gateway_client.h | 16 +-
net/batman-adv/hard-interface.h | 3 +
net/batman-adv/network-coding.c | 6 +
net/batman-adv/originator.c | 72 +-----
net/batman-adv/originator.h | 96 +++++++-
net/batman-adv/soft-interface.c | 15 +-
net/batman-adv/soft-interface.h | 16 +-
net/batman-adv/tp_meter.c | 3 +
net/batman-adv/translation-table.c | 22 +-
net/batman-adv/translation-table.h | 18 +-
net/batman-adv/tvlv.c | 6 +
net/bluetooth/hci_conn.c | 2 +
net/can/isotp.c | 69 +++---
net/ipv4/route.c | 18 +-
net/ipv4/tcp_output.c | 5 +-
net/ipv4/udp.c | 6 +
net/ipv6/udp.c | 4 +-
net/ipv6/xfrm6_output.c | 16 ++
net/netfilter/nf_conntrack_proto_tcp.c | 17 +-
net/netlink/af_netlink.c | 2 +
net/openvswitch/conntrack.c | 118 +++++-----
net/openvswitch/flow_netlink.c | 4 +-
net/rxrpc/ar-internal.h | 15 +-
net/rxrpc/call_event.c | 2 +-
net/rxrpc/call_object.c | 40 +++-
net/sunrpc/xprt.c | 7 +
net/tipc/socket.c | 3 +-
net/xfrm/xfrm_interface.c | 5 +-
samples/bpf/xdpsock_user.c | 5 +-
scripts/dtc/Makefile | 2 +-
scripts/gcc-plugins/stackleak_plugin.c | 25 ++-
security/integrity/evm/evm_main.c | 2 +-
security/keys/keyctl_pkey.c | 14 +-
security/security.c | 17 +-
security/selinux/hooks.c | 11 +-
security/selinux/include/policycap.h | 1 +
security/selinux/include/policycap_names.h | 3 +-
security/selinux/include/security.h | 7 +
security/selinux/selinuxfs.c | 2 +
security/selinux/xfrm.c | 2 +-
security/smack/smack_lsm.c | 2 +-
security/tomoyo/load_policy.c | 4 +-
sound/arm/aaci.c | 4 +-
sound/core/pcm.c | 1 +
sound/core/pcm_lib.c | 9 +-
sound/core/pcm_native.c | 39 +++-
sound/firewire/fcp.c | 4 +-
sound/isa/cs423x/cs4236.c | 8 +-
sound/pci/hda/patch_hdmi.c | 8 +-
sound/pci/hda/patch_realtek.c | 15 +-
sound/soc/atmel/atmel_ssc_dai.c | 5 +-
sound/soc/atmel/sam9g20_wm8731.c | 1 +
sound/soc/atmel/sam9x5_wm8731.c | 16 +-
sound/soc/codecs/Kconfig | 5 +
sound/soc/codecs/msm8916-wcd-analog.c | 22 +-
sound/soc/codecs/msm8916-wcd-digital.c | 5 +-
sound/soc/codecs/mt6358.c | 4 +
sound/soc/codecs/rt5663.c | 2 +
sound/soc/codecs/wcd934x.c | 6 +-
sound/soc/codecs/wm8350.c | 28 ++-
sound/soc/dwc/dwc-i2s.c | 17 +-
sound/soc/fsl/fsl_spdif.c | 2 +
sound/soc/fsl/imx-es8328.c | 1 +
sound/soc/generic/simple-card-utils.c | 2 +-
sound/soc/mxs/mxs-saif.c | 5 +-
sound/soc/mxs/mxs-sgtl5000.c | 3 +
sound/soc/rockchip/rockchip_i2s.c | 18 +-
sound/soc/sh/fsi.c | 19 +-
sound/soc/soc-compress.c | 5 +
sound/soc/soc-core.c | 2 +-
sound/soc/soc-generic-dmaengine-pcm.c | 6 +-
sound/soc/soc-topology.c | 3 +-
sound/soc/sof/imx/imx8m.c | 1 +
sound/soc/sof/intel/hda-loader.c | 11 +-
sound/soc/ti/davinci-i2s.c | 5 +-
sound/soc/xilinx/xlnx_formatter_pcm.c | 25 +++
sound/spi/at73c213.c | 27 ++-
tools/include/uapi/linux/bpf.h | 4 +-
tools/lib/bpf/btf_dump.c | 5 +
tools/lib/bpf/libbpf.c | 3 +
tools/lib/bpf/xsk.c | 11 +
.../selftests/bpf/progs/test_sock_fields.c | 2 +-
.../testing/selftests/bpf/test_lirc_mode2.sh | 5 +-
.../selftests/bpf/test_lwt_ip_encap.sh | 10 +-
.../selftests/net/test_vxlan_under_vrf.sh | 8 +-
tools/testing/selftests/vm/Makefile | 6 +-
tools/testing/selftests/x86/Makefile | 6 +-
tools/testing/selftests/x86/check_cc.sh | 2 +-
tools/virtio/virtio_test.c | 1 +
virt/kvm/kvm_main.c | 13 ++
613 files changed, 4980 insertions(+), 2512 deletions(-)
create mode 100644 arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts
create mode 100644 drivers/platform/chrome/cros_ec_sensorhub_trace.h
--
2.20.1
1
557
CVE-2022-21123,CVE-2022-21125,CVE-2022-21166
Gayatri Kammela (2):
x86/cpu: Add Elkhart Lake to Intel family
x86/cpu: Add another Alder Lake CPU to the Intel family
Guenter Roeck (1):
cpu/speculation: Add prototype for cpu_show_srbds()
Josh Poimboeuf (1):
x86/speculation/mmio: Print SMT warning
Pawan Gupta (10):
Documentation: Add documentation for Processor MMIO Stale Data
x86/speculation/mmio: Enumerate Processor MMIO Stale Data bug
x86/speculation: Add a common function for MD_CLEAR mitigation update
x86/speculation/mmio: Add mitigation for Processor MMIO Stale Data
x86/bugs: Group MDS, TAA & Processor MMIO Stale Data mitigations
x86/speculation/mmio: Enable CPU Fill buffer clearing on idle
x86/speculation/mmio: Add sysfs reporting for Processor MMIO Stale
Data
x86/speculation/srbds: Update SRBDS mitigation selection
x86/speculation/mmio: Reuse SRBDS mitigation for SBDS
KVM: x86/speculation: Disable Fill buffer clear within guests
Tony Luck (1):
x86/cpu: Add Lakefield, Alder Lake and Rocket Lake models to the to
Intel CPU family
Zhang Rui (1):
x86/cpu: Add Jasper Lake to Intel family
.../ABI/testing/sysfs-devices-system-cpu | 1 +
Documentation/admin-guide/hw-vuln/index.rst | 1 +
.../hw-vuln/processor_mmio_stale_data.rst | 246 ++++++++++++++++++
.../admin-guide/kernel-parameters.txt | 36 +++
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/intel-family.h | 11 +
arch/x86/include/asm/msr-index.h | 25 ++
arch/x86/include/asm/nospec-branch.h | 2 +
arch/x86/kernel/cpu/bugs.c | 235 ++++++++++++++---
arch/x86/kernel/cpu/common.c | 52 +++-
arch/x86/kvm/vmx.c | 76 +++++-
arch/x86/kvm/x86.c | 4 +
drivers/base/cpu.c | 8 +
include/linux/cpu.h | 4 +
14 files changed, 662 insertions(+), 40 deletions(-)
create mode 100644 Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
--
2.25.1
1
16

[PATCH openEuler-1.0-LTS 1/4] fs-writeback: writeback_sb_inodes:Recalculate 'wrote' according skipped pages
by Yongqiang Liu 06 Jul '22
by Yongqiang Liu 06 Jul '22
06 Jul '22
From: Zhihao Cheng <chengzhihao1(a)huawei.com>
mainline inclusion
from mainline-5.19-rc1
commit 68f4c6eba70df70a720188bce95c85570ddfcc87
category: bugfix
bugzilla: 186540, https://gitee.com/openeuler/kernel/issues/I55AKK
CVE: NA
--------------------------------
Commit 505a666ee3fc ("writeback: plug writeback in wb_writeback() and
writeback_inodes_wb()") has us holding a plug during wb_writeback, which
may cause a potential ABBA dead lock:
wb_writeback fat_file_fsync
blk_start_plug(&plug)
for (;;) {
iter i-1: some reqs have been added into plug->mq_list // LOCK A
iter i:
progress = __writeback_inodes_wb(wb, work)
. writeback_sb_inodes // fat's bdev
. __writeback_single_inode
. . generic_writepages
. . __block_write_full_page
. . . . __generic_file_fsync
. . . . sync_inode_metadata
. . . . writeback_single_inode
. . . . __writeback_single_inode
. . . . fat_write_inode
. . . . __fat_write_inode
. . . . sync_dirty_buffer // fat's bdev
. . . . lock_buffer(bh) // LOCK B
. . . . submit_bh
. . . . blk_mq_get_tag // LOCK A
. . . trylock_buffer(bh) // LOCK B
. . . redirty_page_for_writepage
. . . wbc->pages_skipped++
. . --wbc->nr_to_write
. wrote += write_chunk - wbc.nr_to_write // wrote > 0
. requeue_inode
. redirty_tail_locked
if (progress) // progress > 0
continue;
iter i+1:
queue_io
// similar process with iter i, infinite for-loop !
}
blk_finish_plug(&plug) // flush plug won't be called
Above process triggers a hungtask like:
[ 399.044861] INFO: task bb:2607 blocked for more than 30 seconds.
[ 399.046824] Not tainted 5.18.0-rc1-00005-gefae4d9eb6a2-dirty
[ 399.051539] task:bb state:D stack: 0 pid: 2607 ppid:
2426 flags:0x00004000
[ 399.051556] Call Trace:
[ 399.051570] __schedule+0x480/0x1050
[ 399.051592] schedule+0x92/0x1a0
[ 399.051602] io_schedule+0x22/0x50
[ 399.051613] blk_mq_get_tag+0x1d3/0x3c0
[ 399.051640] __blk_mq_alloc_requests+0x21d/0x3f0
[ 399.051657] blk_mq_submit_bio+0x68d/0xca0
[ 399.051674] __submit_bio+0x1b5/0x2d0
[ 399.051708] submit_bio_noacct+0x34e/0x720
[ 399.051718] submit_bio+0x3b/0x150
[ 399.051725] submit_bh_wbc+0x161/0x230
[ 399.051734] __sync_dirty_buffer+0xd1/0x420
[ 399.051744] sync_dirty_buffer+0x17/0x20
[ 399.051750] __fat_write_inode+0x289/0x310
[ 399.051766] fat_write_inode+0x2a/0xa0
[ 399.051783] __writeback_single_inode+0x53c/0x6f0
[ 399.051795] writeback_single_inode+0x145/0x200
[ 399.051803] sync_inode_metadata+0x45/0x70
[ 399.051856] __generic_file_fsync+0xa3/0x150
[ 399.051880] fat_file_fsync+0x1d/0x80
[ 399.051895] vfs_fsync_range+0x40/0xb0
[ 399.051929] __x64_sys_fsync+0x18/0x30
In my test, 'need_resched()' (which is imported by 590dca3a71 "fs-writeback:
unplug before cond_resched in writeback_sb_inodes") in function
'writeback_sb_inodes()' seldom comes true, unless cond_resched() is deleted
from write_cache_pages().
Fix it by correcting wrote number according number of skipped pages
in writeback_sb_inodes().
Goto Link to find a reproducer.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215837
Cc: stable(a)vger.kernel.org # v4.3
Signed-off-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Link: https://lore.kernel.org/r/20220510133805.1988292-1-chengzhihao1@huawei.com
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/fs-writeback.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 5abb71da2b9a..23a632f02839 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1568,11 +1568,12 @@ static long writeback_sb_inodes(struct super_block *sb,
};
unsigned long start_time = jiffies;
long write_chunk;
- long wrote = 0; /* count both pages and inodes */
+ long total_wrote = 0; /* count both pages and inodes */
while (!list_empty(&wb->b_io)) {
struct inode *inode = wb_inode(wb->b_io.prev);
struct bdi_writeback *tmp_wb;
+ long wrote;
if (inode->i_sb != sb) {
if (work->sb) {
@@ -1648,7 +1649,9 @@ static long writeback_sb_inodes(struct super_block *sb,
wbc_detach_inode(&wbc);
work->nr_pages -= write_chunk - wbc.nr_to_write;
- wrote += write_chunk - wbc.nr_to_write;
+ wrote = write_chunk - wbc.nr_to_write - wbc.pages_skipped;
+ wrote = wrote < 0 ? 0 : wrote;
+ total_wrote += wrote;
if (need_resched()) {
/*
@@ -1670,7 +1673,7 @@ static long writeback_sb_inodes(struct super_block *sb,
tmp_wb = inode_to_wb_and_lock_list(inode);
spin_lock(&inode->i_lock);
if (!(inode->i_state & I_DIRTY_ALL))
- wrote++;
+ total_wrote++;
requeue_inode(inode, tmp_wb, &wbc);
inode_sync_complete(inode);
spin_unlock(&inode->i_lock);
@@ -1684,14 +1687,14 @@ static long writeback_sb_inodes(struct super_block *sb,
* bail out to wb_writeback() often enough to check
* background threshold and other termination conditions.
*/
- if (wrote) {
+ if (total_wrote) {
if (time_is_before_jiffies(start_time + HZ / 10UL))
break;
if (work->nr_pages <= 0)
break;
}
}
- return wrote;
+ return total_wrote;
}
static long __writeback_inodes_wb(struct bdi_writeback *wb,
--
2.25.1
1
3

[PATCH openEuler-5.10-LTS 01/30] Documentation: Add documentation for Processor MMIO Stale Data
by Zheng Zengkai 05 Jul '22
by Zheng Zengkai 05 Jul '22
05 Jul '22
From: Pawan Gupta <pawan.kumar.gupta(a)linux.intel.com>
stable inclusion
from stable-v5.10.123
commit f8a85334a57e7842320476ff27be3a5f151da364
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5D5RS
CVE: CVE-2022-21123,CVE-2022-21125,CVE-2022-21166
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=…
--------------------------------
commit 4419470191386456e0b8ed4eb06a70b0021798a6 upstream
Add the admin guide for Processor MMIO stale data vulnerabilities.
Signed-off-by: Pawan Gupta <pawan.kumar.gupta(a)linux.intel.com>
Signed-off-by: Borislav Petkov <bp(a)suse.de>
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yipeng Zou <zouyipeng(a)huawei.com>
Reviewed-by: Zhang Jianhua <chris.zjh(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
Documentation/admin-guide/hw-vuln/index.rst | 1 +
.../hw-vuln/processor_mmio_stale_data.rst | 246 ++++++++++++++++++
2 files changed, 247 insertions(+)
create mode 100644 Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
diff --git a/Documentation/admin-guide/hw-vuln/index.rst b/Documentation/admin-guide/hw-vuln/index.rst
index ca4dbdd9016d..2adec1e6520a 100644
--- a/Documentation/admin-guide/hw-vuln/index.rst
+++ b/Documentation/admin-guide/hw-vuln/index.rst
@@ -15,3 +15,4 @@ are configurable at compile, boot or run time.
tsx_async_abort
multihit.rst
special-register-buffer-data-sampling.rst
+ processor_mmio_stale_data.rst
diff --git a/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
new file mode 100644
index 000000000000..9393c50b5afc
--- /dev/null
+++ b/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst
@@ -0,0 +1,246 @@
+=========================================
+Processor MMIO Stale Data Vulnerabilities
+=========================================
+
+Processor MMIO Stale Data Vulnerabilities are a class of memory-mapped I/O
+(MMIO) vulnerabilities that can expose data. The sequences of operations for
+exposing data range from simple to very complex. Because most of the
+vulnerabilities require the attacker to have access to MMIO, many environments
+are not affected. System environments using virtualization where MMIO access is
+provided to untrusted guests may need mitigation. These vulnerabilities are
+not transient execution attacks. However, these vulnerabilities may propagate
+stale data into core fill buffers where the data can subsequently be inferred
+by an unmitigated transient execution attack. Mitigation for these
+vulnerabilities includes a combination of microcode update and software
+changes, depending on the platform and usage model. Some of these mitigations
+are similar to those used to mitigate Microarchitectural Data Sampling (MDS) or
+those used to mitigate Special Register Buffer Data Sampling (SRBDS).
+
+Data Propagators
+================
+Propagators are operations that result in stale data being copied or moved from
+one microarchitectural buffer or register to another. Processor MMIO Stale Data
+Vulnerabilities are operations that may result in stale data being directly
+read into an architectural, software-visible state or sampled from a buffer or
+register.
+
+Fill Buffer Stale Data Propagator (FBSDP)
+-----------------------------------------
+Stale data may propagate from fill buffers (FB) into the non-coherent portion
+of the uncore on some non-coherent writes. Fill buffer propagation by itself
+does not make stale data architecturally visible. Stale data must be propagated
+to a location where it is subject to reading or sampling.
+
+Sideband Stale Data Propagator (SSDP)
+-------------------------------------
+The sideband stale data propagator (SSDP) is limited to the client (including
+Intel Xeon server E3) uncore implementation. The sideband response buffer is
+shared by all client cores. For non-coherent reads that go to sideband
+destinations, the uncore logic returns 64 bytes of data to the core, including
+both requested data and unrequested stale data, from a transaction buffer and
+the sideband response buffer. As a result, stale data from the sideband
+response and transaction buffers may now reside in a core fill buffer.
+
+Primary Stale Data Propagator (PSDP)
+------------------------------------
+The primary stale data propagator (PSDP) is limited to the client (including
+Intel Xeon server E3) uncore implementation. Similar to the sideband response
+buffer, the primary response buffer is shared by all client cores. For some
+processors, MMIO primary reads will return 64 bytes of data to the core fill
+buffer including both requested data and unrequested stale data. This is
+similar to the sideband stale data propagator.
+
+Vulnerabilities
+===============
+Device Register Partial Write (DRPW) (CVE-2022-21166)
+-----------------------------------------------------
+Some endpoint MMIO registers incorrectly handle writes that are smaller than
+the register size. Instead of aborting the write or only copying the correct
+subset of bytes (for example, 2 bytes for a 2-byte write), more bytes than
+specified by the write transaction may be written to the register. On
+processors affected by FBSDP, this may expose stale data from the fill buffers
+of the core that created the write transaction.
+
+Shared Buffers Data Sampling (SBDS) (CVE-2022-21125)
+----------------------------------------------------
+After propagators may have moved data around the uncore and copied stale data
+into client core fill buffers, processors affected by MFBDS can leak data from
+the fill buffer. It is limited to the client (including Intel Xeon server E3)
+uncore implementation.
+
+Shared Buffers Data Read (SBDR) (CVE-2022-21123)
+------------------------------------------------
+It is similar to Shared Buffer Data Sampling (SBDS) except that the data is
+directly read into the architectural software-visible state. It is limited to
+the client (including Intel Xeon server E3) uncore implementation.
+
+Affected Processors
+===================
+Not all the CPUs are affected by all the variants. For instance, most
+processors for the server market (excluding Intel Xeon E3 processors) are
+impacted by only Device Register Partial Write (DRPW).
+
+Below is the list of affected Intel processors [#f1]_:
+
+ =================== ============ =========
+ Common name Family_Model Steppings
+ =================== ============ =========
+ HASWELL_X 06_3FH 2,4
+ SKYLAKE_L 06_4EH 3
+ BROADWELL_X 06_4FH All
+ SKYLAKE_X 06_55H 3,4,6,7,11
+ BROADWELL_D 06_56H 3,4,5
+ SKYLAKE 06_5EH 3
+ ICELAKE_X 06_6AH 4,5,6
+ ICELAKE_D 06_6CH 1
+ ICELAKE_L 06_7EH 5
+ ATOM_TREMONT_D 06_86H All
+ LAKEFIELD 06_8AH 1
+ KABYLAKE_L 06_8EH 9 to 12
+ ATOM_TREMONT 06_96H 1
+ ATOM_TREMONT_L 06_9CH 0
+ KABYLAKE 06_9EH 9 to 13
+ COMETLAKE 06_A5H 2,3,5
+ COMETLAKE_L 06_A6H 0,1
+ ROCKETLAKE 06_A7H 1
+ =================== ============ =========
+
+If a CPU is in the affected processor list, but not affected by a variant, it
+is indicated by new bits in MSR IA32_ARCH_CAPABILITIES. As described in a later
+section, mitigation largely remains the same for all the variants, i.e. to
+clear the CPU fill buffers via VERW instruction.
+
+New bits in MSRs
+================
+Newer processors and microcode update on existing affected processors added new
+bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate
+specific variants of Processor MMIO Stale Data vulnerabilities and mitigation
+capability.
+
+MSR IA32_ARCH_CAPABILITIES
+--------------------------
+Bit 13 - SBDR_SSDP_NO - When set, processor is not affected by either the
+ Shared Buffers Data Read (SBDR) vulnerability or the sideband stale
+ data propagator (SSDP).
+Bit 14 - FBSDP_NO - When set, processor is not affected by the Fill Buffer
+ Stale Data Propagator (FBSDP).
+Bit 15 - PSDP_NO - When set, processor is not affected by Primary Stale Data
+ Propagator (PSDP).
+Bit 17 - FB_CLEAR - When set, VERW instruction will overwrite CPU fill buffer
+ values as part of MD_CLEAR operations. Processors that do not
+ enumerate MDS_NO (meaning they are affected by MDS) but that do
+ enumerate support for both L1D_FLUSH and MD_CLEAR implicitly enumerate
+ FB_CLEAR as part of their MD_CLEAR support.
+Bit 18 - FB_CLEAR_CTRL - Processor supports read and write to MSR
+ IA32_MCU_OPT_CTRL[FB_CLEAR_DIS]. On such processors, the FB_CLEAR_DIS
+ bit can be set to cause the VERW instruction to not perform the
+ FB_CLEAR action. Not all processors that support FB_CLEAR will support
+ FB_CLEAR_CTRL.
+
+MSR IA32_MCU_OPT_CTRL
+---------------------
+Bit 3 - FB_CLEAR_DIS - When set, VERW instruction does not perform the FB_CLEAR
+action. This may be useful to reduce the performance impact of FB_CLEAR in
+cases where system software deems it warranted (for example, when performance
+is more critical, or the untrusted software has no MMIO access). Note that
+FB_CLEAR_DIS has no impact on enumeration (for example, it does not change
+FB_CLEAR or MD_CLEAR enumeration) and it may not be supported on all processors
+that enumerate FB_CLEAR.
+
+Mitigation
+==========
+Like MDS, all variants of Processor MMIO Stale Data vulnerabilities have the
+same mitigation strategy to force the CPU to clear the affected buffers before
+an attacker can extract the secrets.
+
+This is achieved by using the otherwise unused and obsolete VERW instruction in
+combination with a microcode update. The microcode clears the affected CPU
+buffers when the VERW instruction is executed.
+
+Kernel reuses the MDS function to invoke the buffer clearing:
+
+ mds_clear_cpu_buffers()
+
+On MDS affected CPUs, the kernel already invokes CPU buffer clear on
+kernel/userspace, hypervisor/guest and C-state (idle) transitions. No
+additional mitigation is needed on such CPUs.
+
+For CPUs not affected by MDS or TAA, mitigation is needed only for the attacker
+with MMIO capability. Therefore, VERW is not required for kernel/userspace. For
+virtualization case, VERW is only needed at VMENTER for a guest with MMIO
+capability.
+
+Mitigation points
+-----------------
+Return to user space
+^^^^^^^^^^^^^^^^^^^^
+Same mitigation as MDS when affected by MDS/TAA, otherwise no mitigation
+needed.
+
+C-State transition
+^^^^^^^^^^^^^^^^^^
+Control register writes by CPU during C-state transition can propagate data
+from fill buffer to uncore buffers. Execute VERW before C-state transition to
+clear CPU fill buffers.
+
+Guest entry point
+^^^^^^^^^^^^^^^^^
+Same mitigation as MDS when processor is also affected by MDS/TAA, otherwise
+execute VERW at VMENTER only for MMIO capable guests. On CPUs not affected by
+MDS/TAA, guest without MMIO access cannot extract secrets using Processor MMIO
+Stale Data vulnerabilities, so there is no need to execute VERW for such guests.
+
+Mitigation control on the kernel command line
+---------------------------------------------
+The kernel command line allows to control the Processor MMIO Stale Data
+mitigations at boot time with the option "mmio_stale_data=". The valid
+arguments for this option are:
+
+ ========== =================================================================
+ full If the CPU is vulnerable, enable mitigation; CPU buffer clearing
+ on exit to userspace and when entering a VM. Idle transitions are
+ protected as well. It does not automatically disable SMT.
+ full,nosmt Same as full, with SMT disabled on vulnerable CPUs. This is the
+ complete mitigation.
+ off Disables mitigation completely.
+ ========== =================================================================
+
+If the CPU is affected and mmio_stale_data=off is not supplied on the kernel
+command line, then the kernel selects the appropriate mitigation.
+
+Mitigation status information
+-----------------------------
+The Linux kernel provides a sysfs interface to enumerate the current
+vulnerability status of the system: whether the system is vulnerable, and
+which mitigations are active. The relevant sysfs file is:
+
+ /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
+
+The possible values in this file are:
+
+ .. list-table::
+
+ * - 'Not affected'
+ - The processor is not vulnerable
+ * - 'Vulnerable'
+ - The processor is vulnerable, but no mitigation enabled
+ * - 'Vulnerable: Clear CPU buffers attempted, no microcode'
+ - The processor is vulnerable, but microcode is not updated. The
+ mitigation is enabled on a best effort basis.
+ * - 'Mitigation: Clear CPU buffers'
+ - The processor is vulnerable and the CPU buffer clearing mitigation is
+ enabled.
+
+If the processor is vulnerable then the following information is appended to
+the above information:
+
+ ======================== ===========================================
+ 'SMT vulnerable' SMT is enabled
+ 'SMT disabled' SMT is disabled
+ 'SMT Host state unknown' Kernel runs in a VM, Host SMT state unknown
+ ======================== ===========================================
+
+References
+----------
+.. [#f1] Affected Processors
+ https://www.intel.com/content/www/us/en/developer/topic-technology/software…
--
2.20.1
1
29
Backport 5.10.110 LTS patches from upstream
PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
can: m_can: m_can_tx_handler(): fix use after free of skb
openvswitch: Fixed nd target mask field in the flow dump.
docs: sysctl/kernel: add missing bit to panic_print
um: Fix uml_mconsole stop/go
ARM: dts: spear13xx: Update SPI dma properties
ARM: dts: spear1340: Update serial node properties
ASoC: topology: Allow TLV control to be either read or write
dt-bindings: spi: mxic: The interrupt property is not mandatory
dt-bindings: mtd: nand-controller: Fix a comment in the examples
dt-bindings: mtd: nand-controller: Fix the reg property description
bpf: Fix comment for helper bpf_current_task_under_cgroup()
bpf: Adjust BPF stack helper functions to accommodate skip > 0
mm/usercopy: return 1 from hardened_usercopy __setup() handler
mm/memcontrol: return 1 from cgroup.memory __setup() handler
ARM: 9187/1: JIVE: fix return value of __setup handler
mm/mmap: return 1 from stack_guard_gap __setup() handler
batman-adv: Check ptr for NULL before reducing its refcnt
ASoC: soc-compress: Change the check for codec_dai
staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on ethernet
proc: bootconfig: Add null pointer check
can: isotp: restore accidentally removed MSG_PEEK feature
platform/chrome: cros_ec_typec: Check for EC device
ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
riscv module: remove (NOLOAD)
io_uring: fix memory leak of uid in files registration
ARM: iop32x: offset IRQ numbers by 1
ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
pinctrl: pinconf-generic: Print arguments for bias-pull-*
watch_queue: Free the page array when watch_queue is dismantled
crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
mailbox: imx: fix wakeup failure from freeze mode
rxrpc: Fix call timer start racing with call destruction
gfs2: Make sure FITRIM minlen is rounded up to fs block size
rtc: check if __rtc_read_time was successful
XArray: Update the LRU list in xas_split()
can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error value
can: mcba_usb: properly check endpoint type
XArray: Fix xas_create_range() when multi-order entry present
wireguard: socket: ignore v6 endpoints when ipv6 is disabled
wireguard: socket: free skb in send6 when ipv6 is disabled
wireguard: queueing: use CFI-safe ptr_ring cleanup function
ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
KVM: SVM: fix panic on out-of-bounds guest IRQ
KVM: x86: fix sending PV IPI
KVM: Prevent module exit until all VMs are freed
KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated
platform: chrome: Split trace include file
scsi: qla2xxx: Use correct feature type field during RFF_ID processing
scsi: qla2xxx: Reduce false trigger to login
scsi: qla2xxx: Fix N2N inconsistent PLOGI
scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
scsi: qla2xxx: Fix hang due to session stuck
scsi: qla2xxx: Fix incorrect reporting of task management failure
scsi: qla2xxx: Fix disk failure to rediscover
scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
scsi: qla2xxx: Check for firmware dump already collected
scsi: qla2xxx: Add devids and conditionals for 28xx
scsi: qla2xxx: Fix device reconnect in loop topology
scsi: qla2xxx: Fix warning for missing error code
scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
scsi: qla2xxx: Fix scheduling while atomic
scsi: qla2xxx: Fix stuck session in gpdb
powerpc: Fix build errors with newer binutils
powerpc/lib/sstep: Fix build errors with newer binutils
powerpc/lib/sstep: Fix 'sthcx' instruction
powerpc/kasan: Fix early region not updated correctly
KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP MMU
ALSA: hda/realtek: Add alc256-samsung-headphone fixup
media: atomisp: fix bad usage at error handling logic
mmc: host: Return an error when ->enable_sdio_irq() ops is missing
media: hdpvr: initialize dev->worker at hdpvr_register_videodev
media: Revert "media: em28xx: add missing em28xx_close_extension"
video: fbdev: sm712fb: Fix crash in smtcfb_write()
ARM: mmp: Fix failure to remove sram device
ARM: tegra: tamonten: Fix I2C3 pad setting
lib/test_lockup: fix kernel pointer check for separate address spaces
uaccess: fix type mismatch warnings from access_ok()
media: cx88-mpeg: clear interrupt status register before streaming video
ASoC: soc-core: skip zero num_dai component in searching dai name
ARM: dts: bcm2711: Add the missing L1/L2 cache information
video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit
video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of
snprintf()
video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf()
arm64: defconfig: build imx-sdma as a module
ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
ARM: ftrace: avoid redundant loads or clobbering IP
media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2 regulator off
on some boards
ASoC: madera: Add dependencies on MFD
ARM: dts: bcm2837: Add the missing L1/L2 cache information
ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
video: fbdev: cirrusfb: check pixclock to avoid divide by zero
video: fbdev: w100fb: Reset global state
video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
media: ir_toy: free before error exiting
media: staging: media: zoran: fix various V4L2 compliance errors
media: staging: media: zoran: calculate the right buffer number for
zoran_reap_stat_com
media: staging: media: zoran: move videodev alloc
ntfs: add sanity check on allocation size
f2fs: compress: fix to print raw data size in error path of lz4 decompression
NFSD: Fix nfsd_breaker_owns_lease() return values
f2fs: fix to do sanity check on curseg->alloc_type
ext4: don't BUG if someone dirty pages without asking ext4 first
ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
ext4: correct cluster len and clusters changed accounting in ext4_mb_mark_bb
locking/lockdep: Iterate lock_classes directly when reading lockdep files
spi: tegra20: Use of_device_get_match_data()
nvme-tcp: lockdep: annotate in-kernel sockets
parisc: Fix handling off probe non-access faults
PM: core: keep irq flags in device_pm_check_callbacks()
ACPI/APEI: Limit printable size of BERT table data
Revert "Revert "block, bfq: honor already-setup queue merges""
lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
ACPICA: Avoid walking the ACPI Namespace if it is not there
fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
irqchip/nvic: Release nvic_base upon failure
irqchip/qcom-pdc: Fix broken locking
Fix incorrect type in assignment of ipv6 port for audit
loop: use sysfs_emit() in the sysfs xxx show()
selinux: allow FIOCLEX and FIONCLEX with policy capability
selinux: use correct type for context length
pinctrl: npcm: Fix broken references to chip->parent_device
gcc-plugins/stackleak: Exactly match strings instead of prefixes
regulator: rpi-panel: Handle I2C errors/timing to the Atmel
LSM: general protection fault in legacy_parse_param
fs: fix fd table size alignment properly
lib/test: use after free in register_test_dev_kmod()
fs: fd tables have to be multiples of BITS_PER_LONG
net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
NFSv4/pNFS: Fix another issue with a list iterator pointing to the head
qlcnic: dcb: default to returning -EOPNOTSUPP
selftests: test_vxlan_under_vrf: Fix broken test case
net: phy: broadcom: Fix brcm_fet_config_init()
net: enetc: report software timestamping via SO_TIMESTAMPING
xen: fix is_xen_pmu()
clk: Initialize orphan req_rate
clk: qcom: gcc-msm8994: Fix gpll4 width
kdb: Fix the putarea helper function
NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
jfs: fix divide error in dbNextAG
driver core: dd: fix return value of __setup handler
firmware: google: Properly state IOMEM dependency
kgdbts: fix return value of __setup handler
serial: 8250: fix XOFF/XON sending when DMA is used
kgdboc: fix return value of __setup handler
tty: hvc: fix return value of __setup handler
pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
pinctrl: mediatek: paris: Skip custom extra pin config dump for virtual GPIOs
pinctrl: mediatek: paris: Fix pingroup pin config state readback
pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get()
pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
staging: mt7621-dts: fix GB-PC2 devicetree
staging: mt7621-dts: fix pinctrl properties for ethernet
staging: mt7621-dts: fix formatting
staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
NFS: remove unneeded check in decode_devicenotify_args()
clk: tegra: tegra124-emc: Fix missing put_device() call in emc_ensure_emc_driver
clk: clps711x: Terminate clk_div_table with sentinel element
clk: loongson1: Terminate clk_div_table with sentinel element
clk: actions: Terminate clk_div_table with sentinel element
nvdimm/region: Fix default alignment for small regions
remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
remoteproc: qcom_wcnss: Add missing of_node_put() in wcnss_alloc_memory_region
remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
clk: qcom: clk-rcg2: Update the frac table for pixel clock
clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
clk: at91: sama7g5: fix parents of PDMCs' GCLK
clk: imx7d: Remove audio_mclk_root_clk
dma-debug: fix return value of __setup handlers
NFS: Return valid errors from nfs2/3_decode_dirent()
habanalabs: Add check for pci_enable_device
iio: adc: Add check for devm_request_threaded_irq
serial: 8250: Fix race condition in RTS-after-send handling
NFS: Use of mapping_set_error() results in spurious errors
serial: 8250_lpss: Balance reference count for PCI DMA device
serial: 8250_mid: Balance reference count for PCI DMA device
phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
clk: qcom: ipq8074: Use floor ops for SDCC1 clock
pinctrl: renesas: checker: Fix miscalculation of number of states
pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
iio: mma8452: Fix probe failing when an i2c_device_id is used
clk: qcom: ipq8074: fix PCI-E clock oops
soundwire: intel: fix wrong register name in intel_shim_wake
cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
misc: alcor_pci: Fix an error handling path
fsi: Aspeed: Fix a potential double free
fsi: aspeed: convert to devm_platform_ioremap_resource
pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add()
mxser: fix xmit_buf leak in activate when LSR == 0xff
mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
tipc: fix the timer expires after interval 100ms
openvswitch: always update flow key after nat
tcp: ensure PMTU updates are processed during fastopen
net: bcmgenet: Use stronger register read/writes to assure ordering
PCI: Avoid broken MSI on SB600 USB devices
selftests/bpf/test_lirc_mode2.sh: Exit with proper code
i2c: mux: demux-pinctrl: do not deactivate a master that is not active
i2c: meson: Fix wrong speed use from probe
af_netlink: Fix shift out of bounds in group mask calculation
ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
Bluetooth: call hci_le_conn_failed with hdev lock in hci_le_conn_failed
selftests/bpf: Fix error reporting from sock_fields programs
bareudp: use ipv6_mod_enabled to check if IPv6 enabled
can: isotp: support MSG_TRUNC flag when reading from socket
can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
USB: storage: ums-realtek: fix error code in rts51x_read_mem()
samples/bpf, xdpsock: Fix race when running for fix duration of time
bpf, sockmap: Fix double uncharge the mem of sk_msg
bpf, sockmap: Fix more uncharged while msg has more_data
bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full
RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
MIPS: pgalloc: fix memory leak caused by pgd_free()
MIPS: RB532: fix return value of __setup handler
mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
ath10k: Fix error handling in ath10k_setup_msa_resources
vxcan: enable local echo for sent CAN frames
powerpc: 8xx: fix a return value error in mpc8xx_pic_init
platform/x86: huawei-wmi: check the return value of device_create_file()
selftests/bpf: Make test_lwt_ip_encap more stable and faster
libbpf: Unmap rings when umem deleted
mfd: mc13xxx: Add check for mc13xxx_irq_request
powerpc/sysdev: fix incorrect use to determine if list is empty
mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
net: axienet: fix RX ring refill allocation failure handling
IB/hfi1: Allow larger MTU without AIP
power: supply: wm8350-power: Add missing free in free_charger_irq
power: supply: wm8350-power: Handle error for wm8350_register_irq
i2c: xiic: Make bus names unique
hv_balloon: rate-limit "Unhandled message" warning
KVM: x86/emulator: Defer not-present segment check in
__load_segment_descriptor()
KVM: x86: Fix emulation in writing cr8
powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
libbpf: Skip forward declaration when counting duplicated type names
gpu: host1x: Fix a memory leak in 'host1x_remove()'
bpf, arm64: Feed byte-offset into bpf line info
bpf, arm64: Call build_prologue() first in first JIT pass
drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
scsi: hisi_sas: Change permission of parameter prot_mask
power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false return
drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
ext2: correct max file size computing
TOMOYO: fix __setup handlers return values
drm/amd/display: Remove vupdate_int_entry definition
RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
scsi: pm8001: Fix abort all task initialization
scsi: pm8001: Fix NCQ NON DATA command completion handling
scsi: pm8001: Fix NCQ NON DATA command task initialization
scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config()
scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
drm/msm/dpu: fix dp audio condition
drm/msm/dpu: add DSPP blocks teardown
drm/msm/dp: populate connector of struct dp_panel
iwlwifi: mvm: Fix an error code in iwl_mvm_up()
iwlwifi: Fix -EIO error code that is never returned
dax: make sure inodes are flushed before destroy cache
IB/cma: Allow XRC INI QPs to set their local ACK timeout
drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
drm/amd/pm: enable pm sysfs write for one VF mode
iommu/ipmmu-vmsa: Check for error num after setting mask
HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
drm/bridge: dw-hdmi: use safe format when first in bridge chain
PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
scripts/dtc: Call pkg-config POSIXly correct
net: dsa: mv88e6xxx: Enable port policy support on 6097
mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in sta mode
powerpc/perf: Don't use perf_hw_context for trace IMC PMU
KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
ray_cs: Check ioremap return value
power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
i40e: respect metadata on XSK Rx to skb
i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
KVM: PPC: Fix vmx/vsx mixup in mmio emulation
RDMA/core: Set MR type in ib_reg_user_mr
ath9k_htc: fix uninit value bugs
drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq function
drm/amd/display: Fix a NULL pointer dereference in
amdgpu_dm_connector_add_common_modes()
drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
ionic: fix type complaint in ionic_dev_cmd_clean()
drm/edid: Don't clear formats if using deep color
mtd: rawnand: gpmi: fix controller timings setting
mtd: onenand: Check for error irq
Bluetooth: hci_serdev: call init_rwsem() before p->open()
udmabuf: validate ubuf->pagecount
libbpf: Fix possible NULL pointer dereference when destroying skeleton
drm/panfrost: Check for error num after setting mask
ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
drm: bridge: adv7511: Fix ADV7535 HPD enablement
drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
ARM: configs: multi_v5_defconfig: re-enable CONFIG_V4L_PLATFORM_DRIVERS
ASoC: codecs: wcd934x: Add missing of_node_put() in wcd934x_codec_parse_data
ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe
ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
ASoC: atmel: sam9x5_wm8731: use devm_snd_soc_register_card()
mmc: davinci_mmc: Handle error for clk_enable
ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in
msm8916_wcd_digital_probe
ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
ASoC: fsl_spdif: Disable TX clock when stop
ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
ASoC: SOF: Add missing of_node_put() in imx8m_probe
ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in rockchip_i2s_probe
ASoC: rockchip: i2s: Use devm_platform_get_and_ioremap_resource()
ivtv: fix incorrect device_caps for ivtvfb
media: saa7134: fix incorrect use to determine if list is empty
media: saa7134: convert list_for_each to entry variant
video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
ASoC: fsi: Add check for clk_enable
ASoC: wm8350: Handle error for wm8350_register_irq
ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
media: vidtv: Check for null return of vzalloc
media: stk1160: If start stream fails, return buffers with VB2_BUF_STATE_QUEUED
m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined
arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly
ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction
memory: emif: check the pointer temp in get_device_details()
memory: emif: Add check for setup_interrupts
ASoC: soc-compress: prevent the potentially use of null pointer
ASoC: dwc-i2s: Handle errors for clk_enable
ASoC: atmel_ssc_dai: Handle errors for clk_enable
ASoC: mxs-saif: Handle errors for clk_enable
printk: fix return value of printk.devkmsg __setup handler
arm64: dts: broadcom: Fix sata nodename
arm64: dts: ns2: Fix spi-cpol and spi-cpha property
ALSA: spi: Add check for clk_enable()
ASoC: ti: davinci-i2s: Add check for clk_enable()
ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp()
uaccess: fix nios2 and microblaze get_user_8()
ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
media: cedrus: h264: Fix neighbour info buffer size
media: cedrus: H265: Fix neighbour info buffer size
media: usb: go7007: s2250-board: fix leak in probe()
media: em28xx: initialize refcount before kref_get
media: video/hdmi: handle short reads of hdmi info frame.
ARM: dts: imx: Add missing LVDS decoder on M53Menlo
ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL is not
defined
arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
arm64: dts: qcom: sdm845: fix microphone bias properties and values
soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
soc: qcom: rpmpd: Check for null return of devm_kcalloc
ARM: dts: qcom: ipq4019: fix sleep clock
firmware: qcom: scm: Remove reassignment to desc following initializer
video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
video: fbdev: controlfb: Fix COMPILE_TEST build
video: fbdev: controlfb: Fix set but not used warnings
video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200 to avoid
black screen
media: aspeed: Correct value for h-total-pixels
media: hantro: Fix overfill bottom register field name
media: meson: vdec: potential dereference of null pointer
media: coda: Fix missing put_device() call in coda_get_vdoa_data
ASoC: generic: simple-card-utils: remove useless assignment
ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
media: bttv: fix WARNING regression on tunerless devices
media: mtk-vcodec: potential dereference of null pointer
media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
media: staging: media: zoran: fix usage of vb2_dma_contig_set_max_seg_size
kunit: make kunit_test_timeout compatible with comment
selftests, x86: fix how check_cc.sh is being invoked
f2fs: fix compressed file start atomic write may cause data corruption
f2fs: compress: remove unneeded read when rewrite whole cluster
btrfs: fix unexpected error path when reflinking an inline extent
f2fs: fix to avoid potential deadlock
nfsd: more robust allocation failure handling in nfsd_file_cache_init
f2fs: fix missing free nid in f2fs_handle_failed_inode
perf/x86/intel/pt: Fix address filter config for 32-bit kernel
perf/core: Fix address filter parser for multiple filters
rseq: Optimise rseq_get_rseq_cs() and clear_rseq_cs()
sched/core: Export pelt_thermal_tp
sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa
f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
watch_queue: Actually free the watch
watch_queue: Fix NULL dereference in error cleanup
io_uring: terminate manual loop iterator loop correctly for non-vecs
clocksource: acpi_pm: fix return value of __setup handler
hwmon: (pmbus) Add Vin unit off handling
hwrng: nomadik - Change clk_disable to clk_disable_unprepare
amba: Make the remove callback return void
vfio: platform: simplify device removal
crypto: ccree - Fix use after free in cc_cipher_exit()
crypto: ccp - ccp_dmaengine_unregister release dma channels
ACPI: APEI: fix return value of __setup handlers
clocksource/drivers/timer-of: Check return value of of_iomap in
timer_of_base_init()
clocksource/drivers/timer-microchip-pit64b: Use notrace
clocksource/drivers/exynos_mct: Handle DTS with higher number of interrupts
clocksource/drivers/exynos_mct: Refactor resources allocation
clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
crypto: vmx - add missing dependencies
crypto: amlogic - call finalize with bh disabled
crypto: sun8i-ce - call finalize with bh disabled
crypto: sun8i-ss - call finalize with bh disabled
hwrng: atmel - disable trng on failure path
spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
PM: suspend: fix return value of __setup handler
PM: hibernate: fix __setup handler error handling
block: don't delete queue kobject before its children
nvme: cleanup __nvme_check_ids
hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
hwmon: (pmbus) Add mutex to regulator ops
spi: pxa2xx-pci: Balance reference count for PCI DMA device
crypto: ccree - don't attempt 0 len DMA mappings
EVM: fix the evm= __setup handler return value
audit: log AUDIT_TIME_* records only from rules
crypto: rockchip - ECB does not need IV
selftests/x86: Add validity check and allow field splitting
arm64/mm: avoid fixmap race condition when create pud mapping
spi: tegra114: Add missing IRQ check in tegra_spi_probe
thermal: int340x: Check for NULL after calling kmemdup()
crypto: mxs-dcp - Fix scatterlist processing
crypto: authenc - Fix sleep in atomic context in decrypt_tail
crypto: sun8i-ss - really disable hash on A80
hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
hwrng: cavium - Check health status while reading random data
selinux: check return value of sel_make_avc_files
regulator: qcom_smd: fix for_each_child.cocci warnings
PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
PCI: pciehp: Clear cmd_busy bit in polling mode
drm/i915/gem: add missing boundary check in vm_access
brcmfmac: pcie: Fix crashes due to early IRQs
brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
brcmfmac: firmware: Allocate space for default boardrev in nvram
xtensa: fix xtensa_wsr always writing 0
xtensa: fix stop_machine_cpuslocked call in patch_text
media: davinci: vpif: fix unbalanced runtime PM enable
media: davinci: vpif: fix unbalanced runtime PM get
media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
DEC: Limit PMAX memory probing to R3k systems
crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete()
crypto: rsa-pkcs1pad - restore signature length check
crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
crypto: rsa-pkcs1pad - only allow with rsa
exec: Force single empty string when argv is empty
lib/raid6/test: fix multiple definition linking error
thermal: int340x: Increase bitmap size
pstore: Don't use semaphores in always-atomic-context code
carl9170: fix missing bit-wise or operator for tx_params
mgag200 fix memmapsl configuration in GCTL6 register
ARM: dts: exynos: add missing HDMI supplies on SMDK5420
ARM: dts: exynos: add missing HDMI supplies on SMDK5250
ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
video: fbdev: sm712fb: Fix crash in smtcfb_read()
drm/edid: check basic audio support on CEA extension block
block: limit request dispatch loop duration
mailbox: tegra-hsp: Flush whole channel
ext4: fix fs corruption when tring to remove a non-empty directory with IO error
ext4: fix ext4_fc_stats trace point
coredump: Also dump first pages of non-executable ELF libraries
ACPI: properties: Consistently return -ENOENT if there are no more references
arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
arm64: signal: nofpsimd: Do not allocate fp/simd context when not available
udp: call udp_encap_enable for v6 sockets when enabling encap
powerpc/kvm: Fix kvm_use_magic_page
can: isotp: sanitize CAN ID checks in isotp_bind()
drbd: fix potential silent data corruption
dm integrity: set journal entry unused when shrinking device
mm/kmemleak: reset tag when compare object pointer
mm,hwpoison: unmap poisoned page before invalidation
Revert "mm: madvise: skip unmapped vma holes passed to process_madvise"
mm: madvise: return correct bytes advised with process_madvise
mm: madvise: skip unmapped vma holes passed to process_madvise
ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
ALSA: hda: Avoid unsol event during RPM suspending
ALSA: cs4236: fix an incorrect NULL check on list iterator
cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
cifs: prevent bad output lengths in smb2_ioctl_query_info()
Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
riscv: Increase stack size under KASAN
riscv: Fix fill_callchain return value
qed: display VF trust config
scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
mempolicy: mbind_range() set_policy() after vma_merge()
mm: invalidate hwpoison page cache page in fault path
mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
mtd: rawnand: protect access to rawnand devices while in suspend
spi: mxic: Fix the transmit path
pinctrl: samsung: drop pin banks references on error paths
remoteproc: Fix count check in rproc_coredump_write()
f2fs: fix to do sanity check on .cp_pack_total_block_count
f2fs: quota: fix loop condition at f2fs_quota_sync()
f2fs: fix to unlock page correctly in error path of is_alive()
NFSD: prevent integer overflow on 32 bit systems
NFSD: prevent underflow in nfssvc_decode_writeargs()
SUNRPC: avoid race between mod_timer() and del_timer_sync()
HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
firmware: stratix10-svc: add missing callback parameter on RSU
Documentation: update stable tree link
Documentation: add link to stable release candidate tree
KEYS: fix length validation in keyctl_pkey_params_get_2()
clk: uniphier: Fix fixed-rate initialization
greybus: svc: fix an error handling bug in gb_svc_hello()
iio: inkern: make a best effort on offset calculation
iio: inkern: apply consumer scale when no channel scale is available
iio: inkern: apply consumer scale on IIO_VAL_INT cases
iio: afe: rescale: use s64 for temporary scale calculations
coresight: Fix TRCCONFIGR.QE sysfs interface
mei: avoid iterator usage outside of list_for_each_entry
mei: me: add Alder Lake N device id.
xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
xhci: make xhci_handshake timeout for xhci_reset() adjustable
xhci: fix runtime PM imbalance in USB2 resume
xhci: fix garbage USBSTS being logged in some cases
USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c
virtio-blk: Use blk_validate_block_size() to validate block size
tpm: fix reference counting for struct tpm_chip
iommu/iova: Improve 32-bit free space estimate
locking/lockdep: Avoid potential access of invalid memory in lock_class
net: dsa: microchip: add spi_device_id tables
Input: zinitix - do not report shadow fingers
spi: Fix erroneous sgs value with min_t()
Revert "gpio: Revert regression in sysfs-gpio (gpiolib.c)"
net:mcf8390: Use platform_get_irq() to get the interrupt
spi: Fix invalid sgs value
gpio: Revert regression in sysfs-gpio (gpiolib.c)
ethernet: sun: Free the coherent when failing in probing
tools/virtio: fix virtio_test execution
vdpa/mlx5: should verify CTRL_VQ feature exists for MQ
virtio_console: break out of buf poll on remove
ARM: mstar: Select HAVE_ARM_ARCH_TIMER
xfrm: fix tunnel model fragmentation behavior
HID: logitech-dj: add new lightspeed receiver id
hv: utils: add PTP_1588_CLOCK to Kconfig to fix build
USB: serial: simple: add Nokia phone driver
USB: serial: pl2303: add IBM device IDs
already merged(30)
arm64: Do not defer reserve_crashkernel() for platforms with no DMA memory zones
can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error path
KVM: x86/mmu: do compare-and-exchange of gPTE via the user address
ubi: fastmap: Return error code if memory allocation fails in add_aeb()
ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl
net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware
can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path
ubifs: rename_whiteout: correct old_dir size computing
ubifs: Fix to add refcount once page is set private
ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock()
ubifs: setflags: Make dirtied_ino_d 8 bytes aligned
ubifs: Add missing iput if do_tmpfile() failed in rename whiteout
ubifs: Fix deadlock in concurrent rename whiteout and inode writeback
ubifs: rename_whiteout: Fix double free for whiteout_ui->data
bfq: fix use-after-free in bfq_dispatch_request
net/x25: Fix null-ptr-deref caused by x25_disconnect
net: hns3: fix bug when PF set the duplicate MAC address for VFs
livepatch: Fix build failure on 32 bits processors
bcache: fixup multiple threads crash
drivers: hamradio: 6pack: fix UAF bug caused by mod_timer()
jffs2: fix memory leak in jffs2_scan_medium
jffs2: fix memory leak in jffs2_do_mount_fs
jffs2: fix use-after-free in jffs2_clear_xattr_subsystem
can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path
ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE
af_key: add __GFP_ZERO flag for compose_sadb_supported in function
pfkey_register
netdevice: add the case if dev is NULL
swiotlb: fix info leak with DMA_FROM_DEVICE
block, bfq: don't move oom_bfqq
drm/i915/opregion: check port number bounds for SWSCI display power state
kabi conflict(8)
PCI: Reduce warnings on possible RW1C corruption
qed: validate and restrict untrusted VFs vlan promisc mode
block: don't merge across cgroup boundaries if blkcg is enabled
rseq: Remove broken uapi field layout on 32-bit little endian
coredump: Snapshot the vmas in do_coredump
coredump: Use the vma snapshot in fill_files_note
coredump/elf: Pass coredump_params into fill_note_info
coredump: Remove the WARN_ON in dump_vma_snapshot
all patches: 597 - 30 - 8 = 559
Aaron Conole (1):
openvswitch: always update flow key after nat
Aashish Sharma (1):
dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
Abel Vesa (2):
clk: imx7d: Remove audio_mclk_root_clk
ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
Adrian Hunter (2):
perf/core: Fix address filter parser for multiple filters
perf/x86/intel/pt: Fix address filter config for 32-bit kernel
Aharon Landau (1):
RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
Akira Kawata (1):
fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
Alan Stern (1):
USB: usb-storage: Fix use of bitfields for hardware data in
ene_ub6250.c
Alexander Lobakin (2):
i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
i40e: respect metadata on XSK Rx to skb
Alexander Usyskin (2):
mei: me: add Alder Lake N device id.
mei: avoid iterator usage outside of list_for_each_entry
Alexey Khoroshilov (1):
NFS: remove unneeded check in decode_devicenotify_args()
Alistair Delva (1):
remoteproc: Fix count check in rproc_coredump_write()
Alistair Popple (1):
mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
Amadeusz Sławiński (1):
ASoC: topology: Allow TLV control to be either read or write
Amir Goldstein (1):
nfsd: more robust allocation failure handling in nfsd_file_cache_init
Ammar Faizi (1):
ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
Anders Roxell (3):
powerpc/lib/sstep: Fix 'sthcx' instruction
powerpc/lib/sstep: Fix build errors with newer binutils
powerpc: Fix build errors with newer binutils
Andre Przywara (1):
ARM: configs: multi_v5_defconfig: re-enable
CONFIG_V4L_PLATFORM_DRIVERS
Andreas Gruenbacher (1):
powerpc/kvm: Fix kvm_use_magic_page
Andrew Price (1):
gfs2: Make sure FITRIM minlen is rounded up to fs block size
Andy Shevchenko (3):
spi: pxa2xx-pci: Balance reference count for PCI DMA device
serial: 8250_mid: Balance reference count for PCI DMA device
serial: 8250_lpss: Balance reference count for PCI DMA device
Ang Tien Sung (1):
firmware: stratix10-svc: add missing callback parameter on RSU
Anssi Hannula (3):
xhci: fix garbage USBSTS being logged in some cases
xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
hv_balloon: rate-limit "Unhandled message" warning
Anton Ivanov (1):
um: Fix uml_mconsole stop/go
Ard Biesheuvel (1):
ARM: ftrace: avoid redundant loads or clobbering IP
Armin Wolf (1):
hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
Arnd Bergmann (4):
uaccess: fix nios2 and microblaze get_user_8()
uaccess: fix type mismatch warnings from access_ok()
lib/test_lockup: fix kernel pointer check for separate address spaces
ARM: iop32x: offset IRQ numbers by 1
Arun Easi (2):
scsi: qla2xxx: Fix device reconnect in loop topology
scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
Arınç ÜNAL (5):
staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
staging: mt7621-dts: fix formatting
staging: mt7621-dts: fix pinctrl properties for ethernet
staging: mt7621-dts: fix GB-PC2 devicetree
staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on
ethernet
Athira Rajeev (1):
powerpc/perf: Don't use perf_hw_context for trace IMC PMU
Bagas Sanjaya (2):
Documentation: add link to stable release candidate tree
Documentation: update stable tree link
Bartosz Golaszewski (1):
Revert "gpio: Revert regression in sysfs-gpio (gpiolib.c)"
Bharata B Rao (1):
sched/debug: Remove mpol_get/put and task_lock/unlock from
sched_show_numa
Biju Das (2):
spi: Fix invalid sgs value
spi: Fix erroneous sgs value with min_t()
Bikash Hazarika (1):
scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
Bjorn Helgaas (1):
PCI: Avoid broken MSI on SB600 USB devices
Brandon Wyman (1):
hwmon: (pmbus) Add Vin unit off handling
Casey Schaufler (2):
LSM: general protection fault in legacy_parse_param
Fix incorrect type in assignment of ipv6 port for audit
Chaitanya Kulkarni (1):
loop: use sysfs_emit() in the sysfs xxx show()
Chao Yu (6):
f2fs: fix to unlock page correctly in error path of is_alive()
f2fs: fix to do sanity check on .cp_pack_total_block_count
f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
f2fs: fix to avoid potential deadlock
f2fs: fix to do sanity check on curseg->alloc_type
f2fs: compress: fix to print raw data size in error path of lz4
decompression
Charan Teja Kalla (3):
mm: madvise: skip unmapped vma holes passed to process_madvise
mm: madvise: return correct bytes advised with process_madvise
Revert "mm: madvise: skip unmapped vma holes passed to
process_madvise"
Charles Keepax (1):
ASoC: madera: Add dependencies on MFD
Chen Jingwen (1):
powerpc/kasan: Fix early region not updated correctly
Chen-Yu Tsai (7):
media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across
ioctls
media: hantro: Fix overfill bottom register field name
pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
pinctrl: mediatek: paris: Fix "argument" argument type for
mtk_pinconf_get()
pinctrl: mediatek: paris: Fix pingroup pin config state readback
pinctrl: mediatek: paris: Skip custom extra pin config dump for
virtual GPIOs
pinctrl: pinconf-generic: Print arguments for bias-pull-*
Chris Leech (1):
nvme-tcp: lockdep: annotate in-kernel sockets
Christian Göttsche (2):
selinux: check return value of sel_make_avc_files
selinux: use correct type for context length
Christoph Hellwig (1):
nvme: cleanup __nvme_check_ids
Christophe JAILLET (4):
firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL
is not defined
gpu: host1x: Fix a memory leak in 'host1x_remove()'
fsi: Aspeed: Fix a potential double free
misc: alcor_pci: Fix an error handling path
Chuck Lever (1):
NFSD: Fix nfsd_breaker_owns_lease() return values
Claudiu Beznea (3):
net: dsa: microchip: add spi_device_id tables
hwrng: atmel - disable trng on failure path
clocksource/drivers/timer-microchip-pit64b: Use notrace
Codrin Ciubotariu (2):
ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
clk: at91: sama7g5: fix parents of PDMCs' GCLK
Colin Ian King (2):
carl9170: fix missing bit-wise or operator for tx_params
iwlwifi: Fix -EIO error code that is never returned
Cooper Chiou (1):
drm/edid: check basic audio support on CEA extension block
Corentin Labbe (8):
crypto: sun8i-ss - really disable hash on A80
crypto: rockchip - ECB does not need IV
crypto: sun8i-ss - call finalize with bh disabled
crypto: sun8i-ce - call finalize with bh disabled
crypto: amlogic - call finalize with bh disabled
media: staging: media: zoran: fix usage of
vb2_dma_contig_set_max_seg_size
media: staging: media: zoran: move videodev alloc
media: staging: media: zoran: calculate the right buffer number for
zoran_reap_stat_com
Dafna Hirschfeld (1):
media: stk1160: If start stream fails, return buffers with
VB2_BUF_STATE_QUEUED
Damien Le Moal (11):
scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
scsi: pm8001: Fix payload initialization in
pm80xx_set_thermal_config()
scsi: pm8001: Fix le32 values handling in
pm80xx_set_sas_protocol_timer_config()
scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
scsi: pm8001: Fix NCQ NON DATA command task initialization
scsi: pm8001: Fix NCQ NON DATA command completion handling
scsi: pm8001: Fix abort all task initialization
Dan Carpenter (9):
greybus: svc: fix an error handling bug in gb_svc_hello()
NFSD: prevent underflow in nfssvc_decode_writeargs()
NFSD: prevent integer overflow on 32 bit systems
video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
media: usb: go7007: s2250-board: fix leak in probe()
iwlwifi: mvm: Fix an error code in iwl_mvm_up()
USB: storage: ums-realtek: fix error code in rts51x_read_mem()
lib/test: use after free in register_test_dev_kmod()
Dan Williams (1):
nvdimm/region: Fix default alignment for small regions
Daniel González Cabanelas (1):
media: cx88-mpeg: clear interrupt status register before streaming
video
Daniel Henrique Barboza (1):
powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
Daniel Palmer (1):
ARM: mstar: Select HAVE_ARM_ARCH_TIMER
Daniel Thompson (2):
soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
kdb: Fix the putarea helper function
Dario Binacchi (1):
mtd: rawnand: gpmi: fix controller timings setting
Darren Hart (1):
ACPI/APEI: Limit printable size of BERT table data
Dave Stevenson (1):
regulator: rpi-panel: Handle I2C errors/timing to the Atmel
David Engraf (1):
arm64: signal: nofpsimd: Do not allocate fp/simd context when not
available
David Gow (1):
firmware: google: Properly state IOMEM dependency
David Heidelberg (2):
arm64: dts: qcom: sdm845: fix microphone bias properties and values
ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
David Howells (3):
watch_queue: Fix NULL dereference in error cleanup
watch_queue: Actually free the watch
rxrpc: Fix call timer start racing with call destruction
David Matlack (1):
KVM: Prevent module exit until all VMs are freed
Dirk Buchwalder (1):
clk: qcom: ipq8074: Use floor ops for SDCC1 clock
Dirk Müller (1):
lib/raid6/test: fix multiple definition linking error
Dmitry Baryshkov (3):
drm/msm/dpu: add DSPP blocks teardown
drm/msm/dpu: fix dp audio condition
PM: core: keep irq flags in device_pm_check_callbacks()
Dmitry Torokhov (1):
HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
Dmitry Vyukov (1):
riscv: Increase stack size under KASAN
Dongliang Mu (3):
media: em28xx: initialize refcount before kref_get
ntfs: add sanity check on allocation size
media: hdpvr: initialize dev->worker at hdpvr_register_videodev
Drew Fustini (1):
clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
Dāvis Mosāns (1):
crypto: ccp - ccp_dmaengine_unregister release dma channels
Eddie James (1):
USB: serial: pl2303: add IBM device IDs
Eric Biggers (6):
KEYS: fix length validation in keyctl_pkey_params_get_2()
crypto: rsa-pkcs1pad - only allow with rsa
crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
crypto: rsa-pkcs1pad - restore signature length check
crypto: rsa-pkcs1pad - fix buffer overread in
pkcs1pad_verify_complete()
block: don't delete queue kobject before its children
Eric Dumazet (2):
rseq: Optimise rseq_get_rseq_cs() and clear_rseq_cs()
watch_queue: Free the page array when watch_queue is dismantled
Evgeny Novikov (1):
video: fbdev: w100fb: Reset global state
Fabiano Rosas (2):
KVM: PPC: Fix vmx/vsx mixup in mmio emulation
KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
Fangrui Song (1):
riscv module: remove (NOLOAD)
Felix Maurer (1):
selftests/bpf: Make test_lwt_ip_encap more stable and faster
Fengnan Chang (2):
f2fs: compress: remove unneeded read when rewrite whole cluster
f2fs: fix compressed file start atomic write may cause data corruption
Filipe Manana (1):
btrfs: fix unexpected error path when reflinking an inline extent
Florian Fainelli (1):
net: phy: broadcom: Fix brcm_fet_config_init()
Frank Wunderlich (1):
arm64: dts: broadcom: Fix sata nodename
Geert Uytterhoeven (3):
hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
pinctrl: renesas: checker: Fix miscalculation of number of states
George Kennedy (1):
video: fbdev: cirrusfb: check pixclock to avoid divide by zero
Gilad Ben-Yossef (1):
crypto: ccree - don't attempt 0 len DMA mappings
Guilherme G. Piccoli (1):
docs: sysctl/kernel: add missing bit to panic_print
Guillaume Nault (1):
ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
Guillaume Ranquet (1):
clocksource/drivers/timer-of: Check return value of of_iomap in
timer_of_base_init()
Guillaume Tucker (1):
selftests, x86: fix how check_cc.sh is being invoked
Gwendal Grignou (2):
HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
platform: chrome: Split trace include file
Hangbin Liu (2):
bareudp: use ipv6_mod_enabled to check if IPv6 enabled
selftests/bpf/test_lirc_mode2.sh: Exit with proper code
Hangyu Hua (1):
powerpc: 8xx: fix a return value error in mpc8xx_pic_init
Hans Verkuil (2):
ivtv: fix incorrect device_caps for ivtvfb
media: staging: media: zoran: fix various V4L2 compliance errors
Hans de Goede (3):
power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong
false return
iio: mma8452: Fix probe failing when an i2c_device_id is used
media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2
regulator off on some boards
Hector Martin (4):
brcmfmac: firmware: Allocate space for default boardrev in nvram
brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
brcmfmac: pcie: Fix crashes due to early IRQs
Helge Deller (1):
video: fbdev: sm712fb: Fix crash in smtcfb_read()
Hengqi Chen (1):
bpf: Fix comment for helper bpf_current_task_under_cgroup()
Henry Lin (1):
xhci: fix runtime PM imbalance in USB2 resume
Herbert Xu (2):
crypto: authenc - Fix sleep in atomic context in decrypt_tail
crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
Hoang Le (1):
tipc: fix the timer expires after interval 100ms
Hou Tao (2):
bpf, arm64: Call build_prologue() first in first JIT pass
bpf, arm64: Feed byte-offset into bpf line info
Hou Wenlong (1):
KVM: x86/emulator: Defer not-present segment check in
__load_segment_descriptor()
Hugh Dickins (1):
mempolicy: mbind_range() set_policy() after vma_merge()
Håkon Bugge (1):
IB/cma: Allow XRC INI QPs to set their local ACK timeout
Ido Schimmel (1):
selftests: test_vxlan_under_vrf: Fix broken test case
Ilpo Järvinen (1):
serial: 8250: fix XOFF/XON sending when DMA is used
Jaegeuk Kim (1):
f2fs: fix missing free nid in f2fs_handle_failed_inode
Jagan Teki (1):
drm: bridge: adv7511: Fix ADV7535 HPD enablement
Jakob Koschel (2):
media: saa7134: fix incorrect use to determine if list is empty
powerpc/sysdev: fix incorrect use to determine if list is empty
Jakub Kicinski (1):
tcp: ensure PMTU updates are processed during fastopen
Jakub Sitnicki (1):
selftests/bpf: Fix error reporting from sock_fields programs
James Clark (1):
coresight: Fix TRCCONFIGR.QE sysfs interface
Jammy Huang (1):
media: aspeed: Correct value for h-total-pixels
Jann Horn (2):
coredump: Also dump first pages of non-executable ELF libraries
pstore: Don't use semaphores in always-atomic-context code
Jason A. Donenfeld (2):
wireguard: queueing: use CFI-safe ptr_ring cleanup function
wireguard: socket: ignore v6 endpoints when ipv6 is disabled
Jens Axboe (1):
io_uring: terminate manual loop iterator loop correctly for non-vecs
Jeremy Linton (1):
net: bcmgenet: Use stronger register read/writes to assure ordering
Jernej Skrabec (2):
media: cedrus: H265: Fix neighbour info buffer size
media: cedrus: h264: Fix neighbour info buffer size
Jia-Ju Bai (3):
ASoC: rt5663: check the return value of devm_kzalloc() in
rt5663_parse_dp()
memory: emif: check the pointer temp in get_device_details()
platform/x86: huawei-wmi: check the return value of
device_create_file()
Jianglei Nie (1):
crypto: ccree - Fix use after free in cc_cipher_exit()
Jianyong Wu (1):
arm64/mm: avoid fixmap race condition when create pud mapping
Jiasheng Jiang (26):
thermal: int340x: Check for NULL after calling kmemdup()
spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
media: mtk-vcodec: potential dereference of null pointer
media: meson: vdec: potential dereference of null pointer
soc: qcom: rpmpd: Check for null return of devm_kcalloc
ASoC: ti: davinci-i2s: Add check for clk_enable()
ALSA: spi: Add check for clk_enable()
ASoC: mxs-saif: Handle errors for clk_enable
ASoC: atmel_ssc_dai: Handle errors for clk_enable
ASoC: dwc-i2s: Handle errors for clk_enable
ASoC: soc-compress: prevent the potentially use of null pointer
memory: emif: Add check for setup_interrupts
media: vidtv: Check for null return of vzalloc
ASoC: wm8350: Handle error for wm8350_register_irq
ASoC: fsi: Add check for clk_enable
mmc: davinci_mmc: Handle error for clk_enable
drm/panfrost: Check for error num after setting mask
mtd: onenand: Check for error irq
ray_cs: Check ioremap return value
iommu/ipmmu-vmsa: Check for error num after setting mask
power: supply: wm8350-power: Handle error for wm8350_register_irq
power: supply: wm8350-power: Add missing free in free_charger_irq
mfd: mc13xxx: Add check for mc13xxx_irq_request
iio: adc: Add check for devm_request_threaded_irq
habanalabs: Add check for pci_enable_device
ASoC: soc-compress: Change the check for codec_dai
Jiaxin Yu (1):
ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
Jie Hai (1):
dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
Jing Yao (3):
video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of
snprintf()
video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead
of snprintf()
video: fbdev: udlfb: replace snprintf in show functions with
sysfs_emit
Jiri Slaby (1):
mxser: fix xmit_buf leak in activate when LSR == 0xff
Jocelyn Falempe (1):
mgag200 fix memmapsl configuration in GCTL6 register
Joe Carnuccio (2):
scsi: qla2xxx: Add devids and conditionals for 28xx
scsi: qla2xxx: Check for firmware dump already collected
Johan Hovold (3):
USB: serial: simple: add Nokia phone driver
media: davinci: vpif: fix unbalanced runtime PM get
media: davinci: vpif: fix unbalanced runtime PM enable
John David Anglin (1):
parisc: Fix handling off probe non-access faults
Jonathan Cameron (1):
staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
Jonathan Neuschäfer (5):
clk: actions: Terminate clk_div_table with sentinel element
clk: loongson1: Terminate clk_div_table with sentinel element
clk: clps711x: Terminate clk_div_table with sentinel element
pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
José Expósito (1):
Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
Juergen Gross (1):
xen: fix is_xen_pmu()
Juhyung Park (1):
f2fs: quota: fix loop condition at f2fs_quota_sync()
Kai-Heng Feng (1):
ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
Kees Cook (2):
exec: Force single empty string when argv is empty
gcc-plugins/stackleak: Exactly match strings instead of prefixes
Konrad Dybcio (1):
clk: qcom: gcc-msm8994: Fix gpll4 width
Krzysztof Kozlowski (5):
pinctrl: samsung: drop pin banks references on error paths
ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
ARM: dts: exynos: add missing HDMI supplies on SMDK5250
ARM: dts: exynos: add missing HDMI supplies on SMDK5420
clocksource/drivers/exynos_mct: Handle DTS with higher number of
interrupts
Kuan-Ying Lee (1):
mm/kmemleak: reset tag when compare object pointer
Kuldeep Singh (3):
arm64: dts: ns2: Fix spi-cpol and spi-cpha property
ARM: dts: spear1340: Update serial node properties
ARM: dts: spear13xx: Update SPI dma properties
Kunihiko Hayashi (1):
clk: uniphier: Fix fixed-rate initialization
Kuogee Hsieh (1):
drm/msm/dp: populate connector of struct dp_panel
Lars Ellenberg (1):
drbd: fix potential silent data corruption
Li RongQing (1):
KVM: x86: fix sending PV IPI
Liam Beguin (4):
iio: afe: rescale: use s64 for temporary scale calculations
iio: inkern: apply consumer scale on IIO_VAL_INT cases
iio: inkern: apply consumer scale when no channel scale is available
iio: inkern: make a best effort on offset calculation
Libin Yang (1):
soundwire: intel: fix wrong register name in intel_shim_wake
Liguang Zhang (1):
PCI: pciehp: Clear cmd_busy bit in polling mode
Lina Wang (1):
xfrm: fix tunnel model fragmentation behavior
Lino Sanfilippo (1):
tpm: fix reference counting for struct tpm_chip
Linus Torvalds (2):
fs: fd tables have to be multiples of BITS_PER_LONG
fs: fix fd table size alignment properly
Linus Walleij (1):
Input: zinitix - do not report shadow fingers
Liu Ying (1):
phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
Lorenzo Bianconi (4):
mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in
sta mode
mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
Luca Weiss (1):
cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
Lucas Tanure (1):
i2c: meson: Fix wrong speed use from probe
Lucas Zampieri (1):
HID: logitech-dj: add new lightspeed receiver id
Lv Ruyi (1):
proc: bootconfig: Add null pointer check
Maciej W. Rozycki (1):
DEC: Limit PMAX memory probing to R3k systems
Manish Chopra (1):
qed: display VF trust config
Manish Rangankar (1):
scsi: qla2xxx: Use correct feature type field during RFF_ID processing
Maor Gottlieb (1):
RDMA/core: Set MR type in ib_reg_user_mr
Marc Kleine-Budde (1):
can: m_can: m_can_tx_handler(): fix use after free of skb
Marc Zyngier (4):
PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
pinctrl: npcm: Fix broken references to chip->parent_device
irqchip/qcom-pdc: Fix broken locking
PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
Marcel Ziswiler (1):
arm64: defconfig: build imx-sdma as a module
Marcelo Roberto Jimenez (1):
gpio: Revert regression in sysfs-gpio (gpiolib.c)
Marek Szyprowski (1):
clocksource/drivers/exynos_mct: Refactor resources allocation
Marek Vasut (1):
ARM: dts: imx: Add missing LVDS decoder on M53Menlo
Marijn Suijten (1):
firmware: qcom: scm: Remove reassignment to desc following initializer
Martin Blumenstingl (1):
drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
Martin Varghese (1):
openvswitch: Fixed nd target mask field in the flow dump.
Mastan Katragadda (1):
drm/i915/gem: add missing boundary check in vm_access
Mathias Nyman (1):
xhci: make xhci_handshake timeout for xhci_reset() adjustable
Matt Kramer (1):
ALSA: hda/realtek: Add alc256-samsung-headphone fixup
Matthew Wilcox (Oracle) (2):
XArray: Fix xas_create_range() when multi-order entry present
XArray: Update the LRU list in xas_split()
Maulik Shah (1):
arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
Mauro Carvalho Chehab (1):
media: atomisp: fix bad usage at error handling logic
Max Filippov (2):
xtensa: fix stop_machine_cpuslocked call in patch_text
xtensa: fix xtensa_wsr always writing 0
Maxim Kiselev (1):
powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
Maxime Ripard (2):
drm/edid: Don't clear formats if using deep color
clk: Initialize orphan req_rate
Maíra Canal (1):
drm/amd/display: Remove vupdate_int_entry definition
Miaoqian Lin (31):
spi: tegra114: Add missing IRQ check in tegra_spi_probe
hwrng: nomadik - Change clk_disable to clk_disable_unprepare
media: coda: Fix missing put_device() call in coda_get_vdoa_data
soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in
rockchip_i2s_probe
ASoC: SOF: Add missing of_node_put() in imx8m_probe
ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in
msm8916_wcd_digital_probe
ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
ASoC: msm8916-wcd-analog: Fix error handling in
pm8916_wcd_analog_spmi_probe
ASoC: codecs: wcd934x: Add missing of_node_put() in
wcd934x_codec_parse_data
drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
ath10k: Fix error handling in ath10k_setup_msa_resources
mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
remoteproc: qcom_wcnss: Add missing of_node_put() in
wcnss_alloc_memory_region
remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
clk: tegra: tegra124-emc: Fix missing put_device() call in
emc_ensure_emc_driver
pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
Michael Ellerman (1):
powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
Michael S. Tsirkin (1):
virtio_console: break out of buf poll on remove
Michael Schmitz (1):
video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
Mike Marciniszyn (1):
IB/hfi1: Allow larger MTU without AIP
Mikulas Patocka (1):
dm integrity: set journal entry unused when shrinking device
Minghao Chi (1):
spi: tegra20: Use of_device_get_match_data()
Minghao Chi (CGEL ZTE) (1):
net:mcf8390: Use platform_get_irq() to get the interrupt
Miquel Raynal (4):
spi: mxic: Fix the transmit path
dt-bindings: mtd: nand-controller: Fix the reg property description
dt-bindings: mtd: nand-controller: Fix a comment in the examples
dt-bindings: spi: mxic: The interrupt property is not mandatory
Mohan Kumar (1):
ALSA: hda: Avoid unsol event during RPM suspending
Muhammad Usama Anjum (1):
selftests/x86: Add validity check and allow field splitting
Namhyung Kim (1):
bpf: Adjust BPF stack helper functions to accommodate skip > 0
Neil Armstrong (1):
drm/bridge: dw-hdmi: use safe format when first in bridge chain
NeilBrown (1):
SUNRPC: avoid race between mod_timer() and del_timer_sync()
Niels Dossche (1):
Bluetooth: call hci_le_conn_failed with hdev lock in
hci_le_conn_failed
Nikita Shubin (1):
riscv: Fix fill_callchain return value
Niklas Söderlund (1):
samples/bpf, xdpsock: Fix race when running for fix duration of time
Nilesh Javali (1):
scsi: qla2xxx: Fix warning for missing error code
Nishanth Menon (4):
arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
Olga Kornievskaia (1):
NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
Oliver Hartkopp (5):
can: isotp: sanitize CAN ID checks in isotp_bind()
vxcan: enable local echo for sent CAN frames
can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
can: isotp: support MSG_TRUNC flag when reading from socket
can: isotp: restore accidentally removed MSG_PEEK feature
Ondrej Zary (1):
media: bttv: fix WARNING regression on tunerless devices
Pablo Neira Ayuso (1):
netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
Pali Rohár (1):
PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
Paolo Valente (1):
Revert "Revert "block, bfq: honor already-setup queue merges""
Patrick Rudolph (1):
hwmon: (pmbus) Add mutex to regulator ops
Paul Kocialkowski (1):
ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
Paul Menzel (1):
lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
Paulo Alcantara (2):
cifs: prevent bad output lengths in smb2_ioctl_query_info()
cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
Pavel Begunkov (1):
io_uring: fix memory leak of uid in files registration
Pavel Kubelun (1):
ARM: dts: qcom: ipq4019: fix sleep clock
Pavel Skripkin (6):
udmabuf: validate ubuf->pagecount
Bluetooth: hci_serdev: call init_rwsem() before p->open()
ath9k_htc: fix uninit value bugs
jfs: fix divide error in dbNextAG
media: Revert "media: em28xx: add missing em28xx_close_extension"
can: mcba_usb: properly check endpoint type
Peiwei Hu (1):
media: ir_toy: free before error exiting
Pekka Pessi (1):
mailbox: tegra-hsp: Flush whole channel
Peng Liu (1):
kunit: make kunit_test_timeout compatible with comment
Peter Rosin (1):
i2c: mux: demux-pinctrl: do not deactivate a master that is not active
Petr Machata (1):
af_netlink: Fix shift out of bounds in group mask calculation
Petr Vorel (1):
crypto: vmx - add missing dependencies
Pierre-Louis Bossart (1):
ASoC: generic: simple-card-utils: remove useless assignment
Prashant Malani (1):
platform/chrome: cros_ec_typec: Check for EC device
Qais Yousef (1):
sched/core: Export pelt_thermal_tp
Quinn Tran (7):
scsi: qla2xxx: Fix stuck session in gpdb
scsi: qla2xxx: Fix scheduling while atomic
scsi: qla2xxx: Fix disk failure to rediscover
scsi: qla2xxx: Fix incorrect reporting of task management failure
scsi: qla2xxx: Fix hang due to session stuck
scsi: qla2xxx: Fix N2N inconsistent PLOGI
scsi: qla2xxx: Reduce false trigger to login
Rafael J. Wysocki (2):
ACPICA: Avoid walking the ACPI Namespace if it is not there
ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
Randy Dunlap (20):
hv: utils: add PTP_1588_CLOCK to Kconfig to fix build
EVM: fix the evm= __setup handler return value
PM: hibernate: fix __setup handler error handling
PM: suspend: fix return value of __setup handler
ACPI: APEI: fix return value of __setup handlers
clocksource: acpi_pm: fix return value of __setup handler
printk: fix return value of printk.devkmsg __setup handler
m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are
defined
TOMOYO: fix __setup handlers return values
mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
MIPS: RB532: fix return value of __setup handler
dma-debug: fix return value of __setup handlers
tty: hvc: fix return value of __setup handler
kgdboc: fix return value of __setup handler
kgdbts: fix return value of __setup handler
driver core: dd: fix return value of __setup handler
mm/mmap: return 1 from stack_guard_gap __setup() handler
ARM: 9187/1: JIVE: fix return value of __setup handler
mm/memcontrol: return 1 from cgroup.memory __setup() handler
mm/usercopy: return 1 from hardened_usercopy __setup() handler
Richard Guy Briggs (1):
audit: log AUDIT_TIME_* records only from rules
Richard Haines (1):
selinux: allow FIOCLEX and FIONCLEX with policy capability
Richard Leitner (1):
ARM: tegra: tamonten: Fix I2C3 pad setting
Richard Schleich (2):
ARM: dts: bcm2837: Add the missing L1/L2 cache information
ARM: dts: bcm2711: Add the missing L1/L2 cache information
Rik van Riel (2):
mm: invalidate hwpoison page cache page in fault path
mm,hwpoison: unmap poisoned page before invalidation
Ritesh Harjani (3):
ext4: fix ext4_fc_stats trace point
ext4: correct cluster len and clusters changed accounting in
ext4_mb_mark_bb
ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
Rob Herring (1):
arm64: dts: rockchip: Fix SDIO regulator supply properties on
rk3399-firefly
Robert Hancock (3):
ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
i2c: xiic: Make bus names unique
net: axienet: fix RX ring refill allocation failure handling
Robert Marko (1):
clk: qcom: ipq8074: fix PCI-E clock oops
Robin Gong (1):
mailbox: imx: fix wakeup failure from freeze mode
Robin Murphy (1):
iommu/iova: Improve 32-bit free space estimate
Roman Li (1):
drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
Sakari Ailus (1):
ACPI: properties: Consistently return -ENOENT if there are no more
references
Sam Ravnborg (1):
video: fbdev: controlfb: Fix set but not used warnings
Saurav Kashyap (1):
scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
Sean Christopherson (1):
KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP
MMU
Sean Nyekjaer (1):
mtd: rawnand: protect access to rawnand devices while in suspend
Sean Young (1):
media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
Shannon Nelson (1):
ionic: fix type complaint in ionic_dev_cmd_clean()
Shengjiu Wang (2):
ASoC: fsl_spdif: Disable TX clock when stop
ASoC: soc-core: skip zero num_dai component in searching dai name
Shin'ichiro Kawasaki (1):
block: limit request dispatch loop duration
Si-Wei Liu (1):
vdpa/mlx5: should verify CTRL_VQ feature exists for MQ
Souptick Joarder (HPE) (1):
irqchip/nvic: Release nvic_base upon failure
Srinivas Kandagatla (1):
ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
Srinivas Pandruvada (1):
thermal: int340x: Increase bitmap size
Stefano Garzarella (1):
tools/virtio: fix virtio_test execution
Sunil Goutham (1):
hwrng: cavium - Check health status while reading random data
Sven Eckelmann (1):
batman-adv: Check ptr for NULL before reducing its refcnt
Takashi Iwai (1):
ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
Takashi Sakamoto (1):
ALSA: firewire-lib: fix uninitialized flag for AV/C deferred
transaction
Taniya Das (2):
clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
clk: qcom: clk-rcg2: Update the frac table for pixel clock
Theodore Ts'o (1):
ext4: don't BUG if someone dirty pages without asking ext4 first
Thomas Bracht Laumann Jespersen (1):
scripts/dtc: Call pkg-config POSIXly correct
Tim Gardner (1):
video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
Tobias Waldekranz (1):
net: dsa: mv88e6xxx: Enable port policy support on 6097
Tom Rix (5):
media: video/hdmi: handle short reads of hdmi info frame.
drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq
function
qlcnic: dcb: default to returning -EOPNOTSUPP
can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error
value
rtc: check if __rtc_read_time was successful
Tomas Paukrt (1):
crypto: mxs-dcp - Fix scatterlist processing
Tong Zhang (1):
dax: make sure inodes are flushed before destroy cache
Trond Myklebust (3):
NFS: Use of mapping_set_error() results in spurious errors
NFS: Return valid errors from nfs2/3_decode_dirent()
NFSv4/pNFS: Fix another issue with a list iterator pointing to the
head
Tsuchiya Yuto (1):
media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
Tudor Ambarus (1):
ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
Ulf Hansson (1):
mmc: host: Return an error when ->enable_sdio_irq() ops is missing
Uwe Kleine-König (5):
vfio: platform: simplify device removal
amba: Make the remove callback return void
pwm: lpc18xx-sct: Initialize driver data and hardware before
pwmchip_add()
serial: 8250: Fix race condition in RTS-after-send handling
ARM: mmp: Fix failure to remove sram device
Vitaly Kuznetsov (1):
KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't
activated
Vladimir Oltean (1):
net: enetc: report software timestamping via SO_TIMESTAMPING
Waiman Long (2):
locking/lockdep: Avoid potential access of invalid memory in
lock_class
locking/lockdep: Iterate lock_classes directly when reading lockdep
files
Wang Hai (2):
video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
wireguard: socket: free skb in send6 when ipv6 is disabled
Wang Wensheng (1):
ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
Wang Yufen (3):
bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full
bpf, sockmap: Fix more uncharged while msg has more_data
bpf, sockmap: Fix double uncharge the mem of sk_msg
Wen Gong (1):
ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
Xiang Chen (1):
scsi: hisi_sas: Change permission of parameter prot_mask
Xiaomeng Tong (2):
ALSA: cs4236: fix an incorrect NULL check on list iterator
net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
Xie Yongji (1):
virtio-blk: Use blk_validate_block_size() to validate block size
Xin Long (1):
udp: call udp_encap_enable for v6 sockets when enabling encap
Xin Xiong (1):
mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
Xu Kuohai (1):
libbpf: Skip forward declaration when counting duplicated type names
Yafang Shao (1):
libbpf: Fix possible NULL pointer dereference when destroying skeleton
Yake Yang (1):
Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
Yaliang Wang (1):
MIPS: pgalloc: fix memory leak caused by pgd_free()
Yang Guang (1):
video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
Yang Yingliang (3):
media: saa7134: convert list_for_each to entry variant
ASoC: rockchip: i2s: Use devm_platform_get_and_ioremap_resource()
ASoC: atmel: sam9x5_wm8731: use devm_snd_soc_register_card()
Yangtao Li (1):
fsi: aspeed: convert to devm_platform_ioremap_resource
Ye Bin (1):
ext4: fix fs corruption when tring to remove a non-empty directory
with IO error
Yi Wang (1):
KVM: SVM: fix panic on out-of-bounds guest IRQ
Yiqing Yao (1):
drm/amd/pm: enable pm sysfs write for one VF mode
Yongzhi Liu (1):
RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
YueHaibing (1):
video: fbdev: controlfb: Fix COMPILE_TEST build
Z. Liu (1):
video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200
to avoid black screen
Zhang Yi (1):
ext2: correct max file size computing
Zhenzhong Duan (1):
KVM: x86: Fix emulation in writing cr8
Zheyu Ma (2):
ethernet: sun: Free the coherent when failing in probing
video: fbdev: sm712fb: Fix crash in smtcfb_write()
Zhou Qingyang (2):
drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
drm/amd/display: Fix a NULL pointer dereference in
amdgpu_dm_connector_add_common_modes()
kernel test robot (1):
regulator: qcom_smd: fix for_each_child.cocci warnings
lic121 (1):
libbpf: Unmap rings when umem deleted
Documentation/admin-guide/sysctl/kernel.rst | 1 +
.../bindings/mtd/nand-controller.yaml | 4 +-
.../devicetree/bindings/spi/spi-mxic.txt | 4 +-
Documentation/process/stable-kernel-rules.rst | 11 +-
Documentation/sound/hd-audio/models.rst | 4 +
arch/arc/kernel/process.c | 2 +-
arch/arm/boot/dts/bcm2711.dtsi | 50 +++++
arch/arm/boot/dts/bcm2837.dtsi | 49 ++++
arch/arm/boot/dts/dra7-l4.dtsi | 5 +-
arch/arm/boot/dts/dra7.dtsi | 8 +-
arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +-
arch/arm/boot/dts/exynos5250-smdk5250.dts | 3 +
arch/arm/boot/dts/exynos5420-smdk5420.dts | 3 +
arch/arm/boot/dts/imx53-m53menlo.dts | 29 ++-
arch/arm/boot/dts/imx7-colibri.dtsi | 4 +-
arch/arm/boot/dts/imx7-mba7.dtsi | 2 +-
arch/arm/boot/dts/imx7d-nitrogen7.dts | 2 +-
arch/arm/boot/dts/imx7d-pico-hobbit.dts | 4 +-
arch/arm/boot/dts/imx7d-pico-pi.dts | 4 +-
arch/arm/boot/dts/imx7d-sdb.dts | 4 +-
arch/arm/boot/dts/imx7s-warp.dts | 4 +-
arch/arm/boot/dts/qcom-ipq4019.dtsi | 3 +-
arch/arm/boot/dts/qcom-msm8960.dtsi | 8 +-
arch/arm/boot/dts/sama5d2.dtsi | 2 +-
arch/arm/boot/dts/spear1340.dtsi | 6 +-
arch/arm/boot/dts/spear13xx.dtsi | 6 +-
arch/arm/boot/dts/sun8i-v3s.dtsi | 22 +-
arch/arm/boot/dts/tegra20-tamonten.dtsi | 6 +-
arch/arm/configs/multi_v5_defconfig | 1 +
arch/arm/crypto/Kconfig | 2 +
arch/arm/kernel/entry-ftrace.S | 51 ++---
arch/arm/kernel/swp_emulate.c | 2 +-
arch/arm/kernel/traps.c | 2 +-
.../mach-iop32x/include/mach/entry-macro.S | 2 +-
arch/arm/mach-iop32x/include/mach/irqs.h | 2 +-
arch/arm/mach-iop32x/irq.c | 6 +-
arch/arm/mach-iop32x/irqs.h | 60 ++---
arch/arm/mach-mmp/sram.c | 22 +-
arch/arm/mach-mstar/Kconfig | 1 +
arch/arm/mach-s3c/mach-jive.c | 6 +-
.../boot/dts/broadcom/northstar2/ns2-svk.dts | 8 +-
.../boot/dts/broadcom/northstar2/ns2.dtsi | 2 +-
arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 +-
arch/arm64/boot/dts/qcom/sm8150.dtsi | 6 +-
.../boot/dts/rockchip/rk3399-firefly.dts | 4 +-
arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 5 +-
arch/arm64/boot/dts/ti/k3-am65.dtsi | 1 +
arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 5 +-
arch/arm64/boot/dts/ti/k3-j7200.dtsi | 1 +
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 5 +-
arch/arm64/boot/dts/ti/k3-j721e.dtsi | 1 +
arch/arm64/configs/defconfig | 2 +-
arch/arm64/kernel/signal.c | 10 +-
arch/arm64/mm/mmu.c | 9 +
arch/arm64/net/bpf_jit_comp.c | 18 +-
arch/csky/kernel/perf_callchain.c | 2 +-
arch/csky/kernel/signal.c | 2 +-
arch/m68k/coldfire/device.c | 6 +-
arch/microblaze/include/asm/uaccess.h | 18 +-
arch/mips/dec/int-handler.S | 6 +-
arch/mips/dec/prom/Makefile | 2 +-
arch/mips/dec/setup.c | 3 +-
arch/mips/include/asm/dec/prom.h | 15 +-
arch/mips/include/asm/pgalloc.h | 6 +
arch/mips/rb532/devices.c | 6 +-
arch/nios2/include/asm/uaccess.h | 26 ++-
arch/nios2/kernel/signal.c | 20 +-
arch/parisc/include/asm/traps.h | 1 +
arch/parisc/kernel/traps.c | 2 +
arch/parisc/mm/fault.c | 89 ++++++++
arch/powerpc/Makefile | 2 +-
arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts | 30 +++
arch/powerpc/boot/dts/fsl/t1040rdb.dts | 8 +-
arch/powerpc/include/asm/io.h | 40 +++-
arch/powerpc/include/asm/uaccess.h | 3 +
arch/powerpc/kernel/kvm.c | 2 +-
arch/powerpc/kvm/book3s_hv.c | 5 +-
arch/powerpc/kvm/powerpc.c | 4 +-
arch/powerpc/lib/sstep.c | 12 +-
arch/powerpc/mm/kasan/kasan_init_32.c | 3 +-
arch/powerpc/mm/numa.c | 4 +-
arch/powerpc/perf/imc-pmu.c | 6 +-
arch/powerpc/platforms/8xx/pic.c | 1 +
arch/powerpc/platforms/powernv/rng.c | 6 +-
arch/powerpc/sysdev/fsl_gtm.c | 4 +-
arch/riscv/include/asm/module.lds.h | 6 +-
arch/riscv/include/asm/thread_info.h | 10 +-
arch/riscv/kernel/perf_callchain.c | 6 +-
arch/sparc/kernel/signal_32.c | 2 +-
arch/um/drivers/mconsole_kern.c | 3 +-
arch/x86/events/intel/pt.c | 2 +-
arch/x86/kernel/kvm.c | 2 +-
arch/x86/kvm/emulate.c | 14 +-
arch/x86/kvm/hyperv.c | 9 +-
arch/x86/kvm/lapic.c | 5 +-
arch/x86/kvm/mmu/tdp_mmu.c | 3 +
arch/x86/kvm/svm/avic.c | 10 +-
arch/x86/xen/pmu.c | 10 +-
arch/x86/xen/pmu.h | 3 +-
arch/x86/xen/smp_pv.c | 2 +-
arch/xtensa/include/asm/processor.h | 4 +-
arch/xtensa/kernel/jump_label.c | 2 +-
block/bfq-iosched.c | 16 +-
block/blk-mq-sched.c | 9 +-
block/blk-sysfs.c | 8 +-
crypto/authenc.c | 2 +-
crypto/rsa-pkcs1pad.c | 11 +-
drivers/acpi/acpica/nswalk.c | 3 +
drivers/acpi/apei/bert.c | 10 +-
drivers/acpi/apei/erst.c | 2 +-
drivers/acpi/apei/hest.c | 2 +-
drivers/acpi/cppc_acpi.c | 5 +
drivers/acpi/property.c | 2 +-
drivers/amba/bus.c | 5 +-
drivers/base/dd.c | 2 +-
drivers/base/power/main.c | 6 +-
drivers/block/drbd/drbd_req.c | 3 +-
drivers/block/loop.c | 10 +-
drivers/block/virtio_blk.c | 12 +-
drivers/bluetooth/btmtksdio.c | 4 +-
drivers/bluetooth/hci_serdev.c | 3 +-
drivers/bus/mips_cdmm.c | 1 +
drivers/char/hw_random/Kconfig | 2 +-
drivers/char/hw_random/atmel-rng.c | 1 +
drivers/char/hw_random/cavium-rng-vf.c | 194 +++++++++++++++-
drivers/char/hw_random/cavium-rng.c | 11 +-
drivers/char/hw_random/nomadik-rng.c | 7 +-
drivers/char/tpm/tpm-chip.c | 46 +---
drivers/char/tpm/tpm.h | 2 +
drivers/char/tpm/tpm2-space.c | 65 ++++++
drivers/char/virtio_console.c | 7 +
drivers/clk/actions/owl-s700.c | 1 +
drivers/clk/actions/owl-s900.c | 2 +-
drivers/clk/at91/sama7g5.c | 8 +-
drivers/clk/clk-clps711x.c | 2 +
drivers/clk/clk.c | 13 ++
drivers/clk/imx/clk-imx7d.c | 1 -
drivers/clk/loongson1/clk-loongson1c.c | 1 +
drivers/clk/qcom/clk-rcg2.c | 14 +-
drivers/clk/qcom/gcc-ipq8074.c | 21 +-
drivers/clk/qcom/gcc-msm8994.c | 1 +
drivers/clk/tegra/clk-tegra124-emc.c | 1 +
.../clk/uniphier/clk-uniphier-fixed-rate.c | 1 +
drivers/clocksource/acpi_pm.c | 6 +-
drivers/clocksource/exynos_mct.c | 60 +++--
drivers/clocksource/timer-microchip-pit64b.c | 2 +-
drivers/clocksource/timer-of.c | 6 +-
drivers/clocksource/timer-ti-dm-systimer.c | 4 +-
drivers/cpufreq/qcom-cpufreq-nvmem.c | 2 +-
.../allwinner/sun8i-ce/sun8i-ce-cipher.c | 3 +
.../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 3 +
.../allwinner/sun8i-ss/sun8i-ss-cipher.c | 3 +
.../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 2 +
.../crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 3 +
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 2 +
drivers/crypto/ccp/ccp-dmaengine.c | 16 ++
drivers/crypto/ccree/cc_buffer_mgr.c | 7 +
drivers/crypto/ccree/cc_cipher.c | 2 +-
drivers/crypto/mxs-dcp.c | 2 +-
.../crypto/rockchip/rk3288_crypto_skcipher.c | 1 -
drivers/crypto/vmx/Kconfig | 4 +
drivers/dax/super.c | 1 +
drivers/dma-buf/udmabuf.c | 4 +
drivers/dma/hisi_dma.c | 2 +-
drivers/dma/pl330.c | 3 +-
drivers/firmware/efi/efi-pstore.c | 2 +-
drivers/firmware/google/Kconfig | 2 +-
drivers/firmware/qcom_scm.c | 6 -
drivers/firmware/stratix10-svc.c | 2 +-
drivers/fsi/fsi-master-aspeed.c | 21 +-
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +-
.../display/dc/irq/dcn21/irq_service_dcn21.c | 14 --
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 4 +-
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +-
drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 +
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 29 ++-
drivers/gpu/drm/bridge/cdns-dsi.c | 1 +
drivers/gpu/drm/bridge/nwl-dsi.c | 1 +
drivers/gpu/drm/bridge/sil-sii8620.c | 2 +-
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 5 +-
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 1 +
drivers/gpu/drm/drm_edid.c | 11 +-
drivers/gpu/drm/i915/gem/i915_gem_mman.c | 2 +-
drivers/gpu/drm/meson/meson_drv.c | 6 +-
drivers/gpu/drm/meson/meson_osd_afbcd.c | 41 ++--
drivers/gpu/drm/meson/meson_osd_afbcd.h | 1 +
drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 8 +
drivers/gpu/drm/msm/dp/dp_display.c | 5 +
.../gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c | 9 +-
drivers/gpu/drm/panfrost/panfrost_gpu.c | 5 +-
drivers/gpu/drm/pl111/pl111_drv.c | 4 +-
drivers/gpu/drm/tegra/dsi.c | 4 +-
drivers/gpu/host1x/dev.c | 1 +
drivers/greybus/svc.c | 8 +-
drivers/hid/hid-logitech-dj.c | 1 +
drivers/hid/i2c-hid/i2c-hid-core.c | 32 ++-
drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 29 +--
drivers/hv/Kconfig | 1 +
drivers/hv/hv_balloon.c | 2 +-
drivers/hwmon/pmbus/pmbus.h | 1 +
drivers/hwmon/pmbus/pmbus_core.c | 18 +-
drivers/hwmon/sch56xx-common.c | 2 +-
drivers/hwtracing/coresight/coresight-catu.c | 3 +-
.../hwtracing/coresight/coresight-cpu-debug.c | 4 +-
.../hwtracing/coresight/coresight-cti-core.c | 4 +-
drivers/hwtracing/coresight/coresight-etb10.c | 4 +-
.../coresight/coresight-etm3x-core.c | 4 +-
.../coresight/coresight-etm4x-core.c | 4 +-
.../coresight/coresight-etm4x-sysfs.c | 8 +-
.../hwtracing/coresight/coresight-funnel.c | 4 +-
.../coresight/coresight-replicator.c | 4 +-
drivers/hwtracing/coresight/coresight-stm.c | 4 +-
.../hwtracing/coresight/coresight-tmc-core.c | 4 +-
drivers/hwtracing/coresight/coresight-tpiu.c | 4 +-
drivers/i2c/busses/i2c-meson.c | 12 +-
drivers/i2c/busses/i2c-nomadik.c | 4 +-
drivers/i2c/busses/i2c-xiic.c | 3 +-
drivers/i2c/muxes/i2c-demux-pinctrl.c | 5 +-
drivers/iio/accel/mma8452.c | 29 ++-
drivers/iio/adc/twl6030-gpadc.c | 2 +
drivers/iio/afe/iio-rescale.c | 8 +-
drivers/iio/inkern.c | 40 +++-
drivers/infiniband/core/cma.c | 2 +-
drivers/infiniband/core/verbs.c | 1 +
drivers/infiniband/hw/hfi1/verbs.c | 3 +-
drivers/infiniband/hw/mlx5/devx.c | 4 +-
drivers/infiniband/hw/mlx5/mr.c | 2 +
drivers/input/input.c | 6 -
drivers/input/serio/ambakmi.c | 3 +-
drivers/input/touchscreen/zinitix.c | 44 +++-
drivers/iommu/iova.c | 5 +-
drivers/iommu/ipmmu-vmsa.c | 4 +-
drivers/irqchip/irq-nvic.c | 2 +
drivers/irqchip/qcom-pdc.c | 5 +-
drivers/mailbox/imx-mailbox.c | 9 +
drivers/mailbox/tegra-hsp.c | 5 +
drivers/md/dm-crypt.c | 2 +-
drivers/md/dm-integrity.c | 6 +-
drivers/media/i2c/adv7511-v4l2.c | 2 +-
drivers/media/i2c/adv7604.c | 2 +-
drivers/media/i2c/adv7842.c | 2 +-
drivers/media/pci/bt8xx/bttv-driver.c | 4 +-
drivers/media/pci/cx88/cx88-mpeg.c | 3 +
drivers/media/pci/ivtv/ivtv-driver.h | 1 -
drivers/media/pci/ivtv/ivtv-ioctl.c | 10 +-
drivers/media/pci/ivtv/ivtv-streams.c | 11 +-
drivers/media/pci/saa7134/saa7134-alsa.c | 8 +-
drivers/media/platform/aspeed-video.c | 9 +-
drivers/media/platform/coda/coda-common.c | 1 +
drivers/media/platform/davinci/vpif.c | 12 +-
.../platform/mtk-vcodec/mtk_vcodec_fw_vpu.c | 2 +
drivers/media/rc/gpio-ir-tx.c | 28 ++-
drivers/media/rc/ir_toy.c | 2 +-
.../media/test-drivers/vidtv/vidtv_s302m.c | 17 +-
drivers/media/usb/em28xx/em28xx-cards.c | 13 +-
drivers/media/usb/go7007/s2250-board.c | 10 +-
drivers/media/usb/hdpvr/hdpvr-video.c | 4 +-
drivers/media/usb/stk1160/stk1160-core.c | 2 +-
drivers/media/usb/stk1160/stk1160-v4l.c | 10 +-
drivers/media/usb/stk1160/stk1160.h | 2 +-
drivers/media/v4l2-core/v4l2-mem2mem.c | 53 ++++-
drivers/memory/emif.c | 8 +-
drivers/memory/pl172.c | 4 +-
drivers/memory/pl353-smc.c | 4 +-
drivers/mfd/asic3.c | 10 +-
drivers/mfd/mc13xxx-core.c | 4 +-
drivers/misc/cardreader/alcor_pci.c | 9 +-
drivers/misc/habanalabs/common/debugfs.c | 2 +
drivers/misc/kgdbts.c | 4 +-
drivers/misc/mei/hw-me-regs.h | 1 +
drivers/misc/mei/interrupt.c | 35 ++-
drivers/misc/mei/pci-me.c | 1 +
drivers/mmc/core/host.c | 15 +-
drivers/mmc/host/davinci_mmc.c | 6 +-
drivers/mmc/host/mmci.c | 4 +-
drivers/mtd/nand/onenand/generic.c | 7 +-
drivers/mtd/nand/raw/atmel/nand-controller.c | 14 +-
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 3 +
drivers/mtd/nand/raw/nand_base.c | 44 ++--
drivers/net/bareudp.c | 25 +--
drivers/net/can/m_can/m_can.c | 5 +-
.../net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +-
drivers/net/can/usb/mcba_usb.c | 26 ++-
drivers/net/can/vxcan.c | 2 +-
drivers/net/dsa/bcm_sf2_cfp.c | 6 +-
drivers/net/dsa/microchip/ksz8795_spi.c | 11 +
drivers/net/dsa/microchip/ksz9477_spi.c | 12 +
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
drivers/net/ethernet/8390/mcf8390.c | 10 +-
.../net/ethernet/broadcom/genet/bcmgenet.c | 4 +-
.../ethernet/freescale/enetc/enetc_ethtool.c | 5 +-
drivers/net/ethernet/intel/i40e/i40e_xsk.c | 16 +-
.../net/ethernet/pensando/ionic/ionic_main.c | 6 +-
drivers/net/ethernet/qlogic/qed/qed_sriov.c | 1 +
.../net/ethernet/qlogic/qlcnic/qlcnic_dcb.h | 10 +-
drivers/net/ethernet/sun/sunhme.c | 6 +-
.../net/ethernet/xilinx/xilinx_axienet_main.c | 72 +++---
drivers/net/phy/broadcom.c | 21 ++
drivers/net/wireguard/queueing.c | 3 +-
drivers/net/wireguard/socket.c | 5 +-
drivers/net/wireless/ath/ath10k/snoc.c | 2 +-
drivers/net/wireless/ath/ath10k/wow.c | 7 +-
drivers/net/wireless/ath/ath9k/htc_hst.c | 5 +
drivers/net/wireless/ath/carl9170/main.c | 2 +-
.../broadcom/brcm80211/brcmfmac/firmware.c | 2 +
.../broadcom/brcm80211/brcmfmac/pcie.c | 66 ++----
.../net/wireless/intel/iwlwifi/dvm/mac80211.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 4 +-
.../net/wireless/mediatek/mt76/mt7603/main.c | 3 +
.../net/wireless/mediatek/mt76/mt7615/main.c | 3 +
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 9 +-
drivers/net/wireless/ray_cs.c | 6 +
drivers/nvdimm/region_devs.c | 3 +
drivers/nvme/host/core.c | 9 +-
drivers/nvme/host/tcp.c | 40 ++++
drivers/pci/controller/pci-aardvark.c | 4 +-
drivers/pci/controller/pci-xgene.c | 35 ++-
drivers/pci/hotplug/pciehp_hpc.c | 2 +
drivers/pci/quirks.c | 12 +
drivers/phy/phy-core-mipi-dphy.c | 4 +-
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 2 +
drivers/pinctrl/mediatek/pinctrl-paris.c | 30 ++-
drivers/pinctrl/nomadik/pinctrl-nomadik.c | 4 +-
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 185 ++++++++--------
drivers/pinctrl/pinconf-generic.c | 6 +-
drivers/pinctrl/pinctrl-rockchip.c | 2 +
drivers/pinctrl/renesas/core.c | 5 +-
drivers/pinctrl/renesas/pfc-r8a77470.c | 4 +-
drivers/pinctrl/samsung/pinctrl-samsung.c | 30 ++-
drivers/platform/chrome/Makefile | 3 +-
.../platform/chrome/cros_ec_sensorhub_ring.c | 3 +-
.../platform/chrome/cros_ec_sensorhub_trace.h | 123 +++++++++++
drivers/platform/chrome/cros_ec_trace.h | 95 --------
drivers/platform/chrome/cros_ec_typec.c | 6 +
drivers/platform/x86/huawei-wmi.c | 13 +-
drivers/power/reset/gemini-poweroff.c | 4 +-
drivers/power/supply/ab8500_fg.c | 4 +-
drivers/power/supply/bq24190_charger.c | 7 +-
drivers/power/supply/wm8350_power.c | 97 ++++++--
drivers/pwm/pwm-lpc18xx-sct.c | 20 +-
drivers/regulator/qcom_smd-regulator.c | 4 +-
.../regulator/rpi-panel-attiny-regulator.c | 56 ++++-
drivers/remoteproc/qcom_q6v5_adsp.c | 1 +
drivers/remoteproc/qcom_q6v5_mss.c | 11 +-
drivers/remoteproc/qcom_wcnss.c | 1 +
drivers/remoteproc/remoteproc_debugfs.c | 2 +-
drivers/rtc/interface.c | 7 +-
drivers/rtc/rtc-pl030.c | 4 +-
drivers/rtc/rtc-pl031.c | 4 +-
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
drivers/scsi/libsas/sas_ata.c | 2 +-
drivers/scsi/pm8001/pm8001_hwi.c | 23 +-
drivers/scsi/pm8001/pm80xx_hwi.c | 209 ++++++++++--------
drivers/scsi/qla2xxx/qla_attr.c | 7 +-
drivers/scsi/qla2xxx/qla_def.h | 10 +-
drivers/scsi/qla2xxx/qla_gs.c | 5 +-
drivers/scsi/qla2xxx/qla_init.c | 73 ++++--
drivers/scsi/qla2xxx/qla_iocb.c | 8 +-
drivers/scsi/qla2xxx/qla_isr.c | 1 +
drivers/scsi/qla2xxx/qla_mbx.c | 14 +-
drivers/scsi/qla2xxx/qla_nvme.c | 22 ++
drivers/scsi/qla2xxx/qla_os.c | 8 +-
drivers/scsi/qla2xxx/qla_sup.c | 4 +-
drivers/scsi/qla2xxx/qla_target.c | 4 +-
drivers/soc/qcom/ocmem.c | 1 +
drivers/soc/qcom/qcom_aoss.c | 2 +-
drivers/soc/qcom/rpmpd.c | 3 +
drivers/soc/ti/wkup_m3_ipc.c | 4 +-
drivers/soundwire/intel.c | 4 +-
drivers/spi/spi-mxic.c | 28 +--
drivers/spi/spi-pl022.c | 5 +-
drivers/spi/spi-pxa2xx-pci.c | 17 +-
drivers/spi/spi-tegra114.c | 4 +
drivers/spi/spi-tegra20-slink.c | 8 +-
drivers/spi/spi-zynqmp-gqspi.c | 5 +-
drivers/spi/spi.c | 4 +-
drivers/staging/iio/adc/ad7280a.c | 4 +-
.../staging/media/atomisp/pci/atomisp_acc.c | 28 ++-
.../media/atomisp/pci/atomisp_gmin_platform.c | 18 ++
drivers/staging/media/atomisp/pci/hmm/hmm.c | 7 +-
.../staging/media/hantro/hantro_h1_jpeg_enc.c | 2 +-
drivers/staging/media/hantro/hantro_h1_regs.h | 2 +-
drivers/staging/media/meson/vdec/esparser.c | 7 +-
.../staging/media/meson/vdec/vdec_helpers.c | 8 +-
.../staging/media/meson/vdec/vdec_helpers.h | 4 +-
.../staging/media/sunxi/cedrus/cedrus_h264.c | 2 +-
.../staging/media/sunxi/cedrus/cedrus_h265.c | 2 +-
drivers/staging/media/zoran/zoran.h | 2 +-
drivers/staging/media/zoran/zoran_card.c | 86 ++++---
drivers/staging/media/zoran/zoran_device.c | 7 +-
drivers/staging/media/zoran/zoran_driver.c | 18 +-
drivers/staging/mt7621-dts/gbpc1.dts | 40 ++--
drivers/staging/mt7621-dts/gbpc2.dts | 116 +++++++++-
drivers/staging/mt7621-dts/mt7621.dtsi | 26 ++-
.../intel/int340x_thermal/int3400_thermal.c | 7 +-
drivers/tty/hvc/hvc_iucv.c | 4 +-
drivers/tty/mxser.c | 15 +-
drivers/tty/serial/8250/8250_dma.c | 11 +-
drivers/tty/serial/8250/8250_lpss.c | 28 ++-
drivers/tty/serial/8250/8250_mid.c | 19 +-
drivers/tty/serial/8250/8250_port.c | 16 +-
drivers/tty/serial/amba-pl010.c | 4 +-
drivers/tty/serial/amba-pl011.c | 3 +-
drivers/tty/serial/kgdboc.c | 6 +-
drivers/tty/serial/serial_core.c | 14 ++
drivers/usb/host/xhci-hub.c | 5 +-
drivers/usb/host/xhci-mem.c | 2 +-
drivers/usb/host/xhci.c | 20 +-
drivers/usb/host/xhci.h | 14 +-
drivers/usb/serial/Kconfig | 1 +
drivers/usb/serial/pl2303.c | 1 +
drivers/usb/serial/pl2303.h | 3 +
drivers/usb/serial/usb-serial-simple.c | 7 +
drivers/usb/storage/ene_ub6250.c | 155 +++++++------
drivers/usb/storage/realtek_cr.c | 2 +-
drivers/vdpa/mlx5/net/mlx5_vnet.c | 18 +-
drivers/vfio/platform/vfio_amba.c | 15 +-
drivers/video/fbdev/amba-clcd.c | 4 +-
drivers/video/fbdev/atafb.c | 12 +-
drivers/video/fbdev/atmel_lcdfb.c | 11 +-
drivers/video/fbdev/cirrusfb.c | 16 +-
drivers/video/fbdev/controlfb.c | 6 +-
drivers/video/fbdev/core/fbcvt.c | 53 ++---
drivers/video/fbdev/matrox/matroxfb_base.c | 2 +-
drivers/video/fbdev/nvidia/nv_i2c.c | 2 +-
.../omap2/omapfb/displays/connector-dvi.c | 1 +
.../omap2/omapfb/displays/panel-dsi-cm.c | 8 +-
.../omapfb/displays/panel-sony-acx565akm.c | 2 +-
.../omapfb/displays/panel-tpo-td043mtea1.c | 4 +-
drivers/video/fbdev/sm712fb.c | 46 +---
drivers/video/fbdev/smscufx.c | 3 +-
drivers/video/fbdev/udlfb.c | 8 +-
drivers/video/fbdev/w100fb.c | 15 +-
drivers/watchdog/rti_wdt.c | 1 +
drivers/watchdog/sp805_wdt.c | 4 +-
fs/binfmt_elf.c | 24 +-
fs/btrfs/reflink.c | 7 +-
fs/cifs/smb2ops.c | 130 ++++++-----
fs/coredump.c | 39 +++-
fs/exec.c | 26 ++-
fs/ext2/super.c | 6 +-
fs/ext4/inline.c | 9 +-
fs/ext4/inode.c | 25 +++
fs/ext4/mballoc.c | 126 ++++++-----
fs/ext4/namei.c | 10 +-
fs/f2fs/checkpoint.c | 8 +-
fs/f2fs/compress.c | 5 +-
fs/f2fs/data.c | 9 +-
fs/f2fs/file.c | 5 +-
fs/f2fs/gc.c | 4 +-
fs/f2fs/inode.c | 1 +
fs/f2fs/node.c | 6 +-
fs/f2fs/segment.c | 7 +
fs/f2fs/super.c | 6 +-
fs/f2fs/sysfs.c | 2 +-
fs/file.c | 31 ++-
fs/gfs2/rgrp.c | 3 +-
fs/io_uring.c | 7 +-
fs/jfs/jfs_dmap.c | 7 +
fs/nfs/callback_proc.c | 27 +--
fs/nfs/callback_xdr.c | 4 -
fs/nfs/nfs2xdr.c | 2 +-
fs/nfs/nfs3xdr.c | 21 +-
fs/nfs/nfs4proc.c | 1 +
fs/nfs/pnfs.c | 11 +
fs/nfs/pnfs.h | 2 +
fs/nfs/write.c | 5 +-
fs/nfsd/filecache.c | 6 +-
fs/nfsd/nfs4state.c | 12 +-
fs/nfsd/nfsproc.c | 2 +-
fs/nfsd/xdr.h | 2 +-
fs/ntfs/inode.c | 4 +
fs/proc/bootconfig.c | 2 +
fs/pstore/platform.c | 38 ++--
include/linux/amba/bus.h | 2 +-
include/linux/mtd/rawnand.h | 2 +
include/linux/pstore.h | 6 +-
include/linux/serial_core.h | 2 +
include/linux/soc/ti/ti_sci_protocol.h | 2 +-
include/linux/sunrpc/xdr.h | 2 +
include/net/udp.h | 1 +
include/net/udp_tunnel.h | 3 +-
include/sound/pcm.h | 1 +
include/trace/events/ext4.h | 78 ++++---
include/trace/events/rxrpc.h | 8 +-
include/uapi/linux/bpf.h | 12 +-
kernel/audit.h | 4 +
kernel/auditsc.c | 87 ++++++--
kernel/bpf/stackmap.c | 56 ++---
kernel/debug/kdb/kdb_support.c | 2 +-
kernel/dma/debug.c | 4 +-
kernel/events/core.c | 3 +
kernel/locking/lockdep.c | 38 ++--
kernel/locking/lockdep_internals.h | 6 +-
kernel/locking/lockdep_proc.c | 51 ++++-
kernel/power/hibernate.c | 2 +-
kernel/power/suspend_test.c | 8 +-
kernel/printk/printk.c | 6 +-
kernel/rseq.c | 9 +
kernel/sched/core.c | 1 +
kernel/sched/debug.c | 10 -
kernel/watch_queue.c | 4 +-
lib/kunit/try-catch.c | 2 +-
lib/raid6/test/Makefile | 4 +-
lib/raid6/test/test.c | 1 -
lib/test_kmod.c | 1 +
lib/test_lockup.c | 11 +-
lib/test_xarray.c | 22 ++
lib/xarray.c | 4 +
mm/kmemleak.c | 9 +-
mm/madvise.c | 3 +-
mm/memcontrol.c | 2 +-
mm/memory.c | 17 +-
mm/mempolicy.c | 8 +-
mm/mmap.c | 2 +-
mm/page_alloc.c | 9 +-
mm/usercopy.c | 5 +-
net/batman-adv/bridge_loop_avoidance.c | 6 +
net/batman-adv/distributed-arp-table.c | 3 +
net/batman-adv/gateway_client.c | 12 +-
net/batman-adv/gateway_client.h | 16 +-
net/batman-adv/hard-interface.h | 3 +
net/batman-adv/network-coding.c | 6 +
net/batman-adv/originator.c | 72 +-----
net/batman-adv/originator.h | 96 +++++++-
net/batman-adv/soft-interface.c | 15 +-
net/batman-adv/soft-interface.h | 16 +-
net/batman-adv/tp_meter.c | 3 +
net/batman-adv/translation-table.c | 22 +-
net/batman-adv/translation-table.h | 18 +-
net/batman-adv/tvlv.c | 6 +
net/bluetooth/hci_conn.c | 2 +
net/can/isotp.c | 69 +++---
net/core/skmsg.c | 17 +-
net/ipv4/route.c | 18 +-
net/ipv4/tcp_bpf.c | 14 +-
net/ipv4/tcp_output.c | 5 +-
net/ipv4/udp.c | 6 +
net/ipv6/udp.c | 4 +-
net/ipv6/xfrm6_output.c | 16 ++
net/netfilter/nf_conntrack_proto_tcp.c | 17 +-
net/netlink/af_netlink.c | 2 +
net/openvswitch/conntrack.c | 118 +++++-----
net/openvswitch/flow_netlink.c | 4 +-
net/rxrpc/ar-internal.h | 15 +-
net/rxrpc/call_event.c | 2 +-
net/rxrpc/call_object.c | 40 +++-
net/sunrpc/xprt.c | 7 +
net/tipc/socket.c | 3 +-
net/xfrm/xfrm_interface.c | 5 +-
samples/bpf/xdpsock_user.c | 5 +-
scripts/dtc/Makefile | 2 +-
scripts/gcc-plugins/stackleak_plugin.c | 25 ++-
security/integrity/evm/evm_main.c | 2 +-
security/keys/keyctl_pkey.c | 14 +-
security/security.c | 17 +-
security/selinux/hooks.c | 11 +-
security/selinux/include/policycap.h | 1 +
security/selinux/include/policycap_names.h | 3 +-
security/selinux/include/security.h | 7 +
security/selinux/selinuxfs.c | 2 +
security/selinux/xfrm.c | 2 +-
security/smack/smack_lsm.c | 2 +-
security/tomoyo/load_policy.c | 4 +-
sound/arm/aaci.c | 4 +-
sound/core/pcm.c | 1 +
sound/core/pcm_lib.c | 9 +-
sound/core/pcm_native.c | 39 +++-
sound/firewire/fcp.c | 4 +-
sound/isa/cs423x/cs4236.c | 8 +-
sound/pci/hda/patch_hdmi.c | 8 +-
sound/pci/hda/patch_realtek.c | 15 +-
sound/soc/atmel/atmel_ssc_dai.c | 5 +-
sound/soc/atmel/sam9g20_wm8731.c | 1 +
sound/soc/atmel/sam9x5_wm8731.c | 16 +-
sound/soc/codecs/Kconfig | 5 +
sound/soc/codecs/msm8916-wcd-analog.c | 22 +-
sound/soc/codecs/msm8916-wcd-digital.c | 5 +-
sound/soc/codecs/mt6358.c | 4 +
sound/soc/codecs/rt5663.c | 2 +
sound/soc/codecs/wcd934x.c | 6 +-
sound/soc/codecs/wm8350.c | 28 ++-
sound/soc/dwc/dwc-i2s.c | 17 +-
sound/soc/fsl/fsl_spdif.c | 2 +
sound/soc/fsl/imx-es8328.c | 1 +
sound/soc/generic/simple-card-utils.c | 2 +-
sound/soc/mxs/mxs-saif.c | 5 +-
sound/soc/mxs/mxs-sgtl5000.c | 3 +
sound/soc/rockchip/rockchip_i2s.c | 18 +-
sound/soc/sh/fsi.c | 19 +-
sound/soc/soc-compress.c | 5 +
sound/soc/soc-core.c | 2 +-
sound/soc/soc-generic-dmaengine-pcm.c | 6 +-
sound/soc/soc-topology.c | 3 +-
sound/soc/sof/imx/imx8m.c | 1 +
sound/soc/sof/intel/hda-loader.c | 11 +-
sound/soc/ti/davinci-i2s.c | 5 +-
sound/soc/xilinx/xlnx_formatter_pcm.c | 25 +++
sound/spi/at73c213.c | 27 ++-
tools/include/uapi/linux/bpf.h | 4 +-
tools/lib/bpf/btf_dump.c | 5 +
tools/lib/bpf/libbpf.c | 3 +
tools/lib/bpf/xsk.c | 11 +
.../selftests/bpf/progs/test_sock_fields.c | 2 +-
.../testing/selftests/bpf/test_lirc_mode2.sh | 5 +-
.../selftests/bpf/test_lwt_ip_encap.sh | 10 +-
.../selftests/net/test_vxlan_under_vrf.sh | 8 +-
tools/testing/selftests/vm/Makefile | 6 +-
tools/testing/selftests/x86/Makefile | 6 +-
tools/testing/selftests/x86/check_cc.sh | 2 +-
tools/virtio/virtio_test.c | 1 +
virt/kvm/kvm_main.c | 13 ++
614 files changed, 4953 insertions(+), 2507 deletions(-)
create mode 100644 arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts
create mode 100644 drivers/platform/chrome/cros_ec_sensorhub_trace.h
--
2.20.1
1
559
From: Rong Wang <w_angrong(a)163.com>
kunpeng inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5CO9A
CVE: NA
---------------------------------
As pass through devices, hypervisor can`t control the status of
device, and can`t track dirty memory DMA from device, during
migration.
The goal of this framework is to combine hardware to accomplish
the task above.
qemu
|status control and dirty memory report
vfio
|ops to hardware
hardware
Signed-off-by: Rong Wang <w_angrong(a)163.com>
Signed-off-by: HuHua Li <18245010845(a)163.com>
Signed-off-by: Ripeng Qiu <965412048(a)qq.com>
---
drivers/vfio/pci/Makefile | 2 +-
drivers/vfio/pci/vfio_pci.c | 54 +++
drivers/vfio/pci/vfio_pci_migration.c | 755 ++++++++++++++++++++++++++++++++++
drivers/vfio/pci/vfio_pci_private.h | 14 +-
drivers/vfio/vfio.c | 411 +++++++++++++++++-
include/linux/vfio_pci_migration.h | 136 ++++++
6 files changed, 1367 insertions(+), 5 deletions(-)
create mode 100644 drivers/vfio/pci/vfio_pci_migration.c
create mode 100644 include/linux/vfio_pci_migration.h
diff --git a/drivers/vfio/pci/Makefile b/drivers/vfio/pci/Makefile
index 76d8ec0..80a777d 100644
--- a/drivers/vfio/pci/Makefile
+++ b/drivers/vfio/pci/Makefile
@@ -1,5 +1,5 @@
-vfio-pci-y := vfio_pci.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o
+vfio-pci-y := vfio_pci.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o vfio_pci_migration.o
vfio-pci-$(CONFIG_VFIO_PCI_IGD) += vfio_pci_igd.o
obj-$(CONFIG_VFIO_PCI) += vfio-pci.o
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 51b791c..59d8280 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -30,6 +30,7 @@
#include <linux/vgaarb.h>
#include <linux/nospec.h>
#include <linux/sched/mm.h>
+#include <linux/vfio_pci_migration.h>
#include "vfio_pci_private.h"
@@ -296,6 +297,14 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
vfio_pci_probe_mmaps(vdev);
+ if (vfio_dev_migration_is_supported(pdev)) {
+ ret = vfio_pci_migration_init(vdev);
+ if (ret) {
+ dev_warn(&vdev->pdev->dev, "Failed to init vfio_pci_migration\n");
+ vfio_pci_disable(vdev);
+ return ret;
+ }
+ }
return 0;
}
@@ -392,6 +401,7 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
out:
pci_disable_device(pdev);
+ vfio_pci_migration_exit(vdev);
vfio_pci_try_bus_reset(vdev);
if (!disable_idle_d3)
@@ -642,6 +652,41 @@ struct vfio_devices {
int max_index;
};
+static long vfio_pci_handle_log_buf_ctl(struct vfio_pci_device *vdev,
+ const unsigned long arg)
+{
+ struct vfio_log_buf_ctl *log_buf_ctl = NULL;
+ struct vfio_log_buf_info *log_buf_info = NULL;
+ struct vf_migration_log_info migration_log_info;
+ long ret = 0;
+
+ log_buf_ctl = (struct vfio_log_buf_ctl *)arg;
+ log_buf_info = (struct vfio_log_buf_info *)log_buf_ctl->data;
+
+ switch (log_buf_ctl->flags) {
+ case VFIO_DEVICE_LOG_BUF_FLAG_START:
+ migration_log_info.dom_uuid = log_buf_info->uuid;
+ migration_log_info.buffer_size =
+ log_buf_info->buffer_size;
+ migration_log_info.sge_num = log_buf_info->addrs_size;
+ migration_log_info.sge_len = log_buf_info->frag_size;
+ migration_log_info.sgevec = log_buf_info->sgevec;
+ ret = vfio_pci_device_log_start(vdev,
+ &migration_log_info);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STOP:
+ ret = vfio_pci_device_log_stop(vdev,
+ log_buf_info->uuid);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY:
+ ret = vfio_pci_device_log_status_query(vdev);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
static long vfio_pci_ioctl(void *device_data,
unsigned int cmd, unsigned long arg)
{
@@ -1142,6 +1187,8 @@ static long vfio_pci_ioctl(void *device_data,
return vfio_pci_ioeventfd(vdev, ioeventfd.offset,
ioeventfd.data, count, ioeventfd.fd);
+ } else if (cmd == VFIO_DEVICE_LOG_BUF_CTL) {
+ return vfio_pci_handle_log_buf_ctl(vdev, arg);
}
return -ENOTTY;
@@ -1566,6 +1613,9 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_power_state(pdev, PCI_D3hot);
}
+ if (vfio_dev_migration_is_supported(pdev))
+ ret = vfio_pci_device_init(pdev);
+
return ret;
}
@@ -1591,6 +1641,10 @@ static void vfio_pci_remove(struct pci_dev *pdev)
if (!disable_idle_d3)
pci_set_power_state(pdev, PCI_D0);
+
+ if (vfio_dev_migration_is_supported(pdev)) {
+ vfio_pci_device_uninit(pdev);
+ }
}
static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
diff --git a/drivers/vfio/pci/vfio_pci_migration.c b/drivers/vfio/pci/vfio_pci_migration.c
new file mode 100644
index 0000000..f69cd13
--- /dev/null
+++ b/drivers/vfio/pci/vfio_pci_migration.c
@@ -0,0 +1,755 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/uaccess.h>
+#include <linux/vfio.h>
+#include <linux/vfio_pci_migration.h>
+
+#include "vfio_pci_private.h"
+
+static LIST_HEAD(vfio_pci_mig_drivers_list);
+static DEFINE_MUTEX(vfio_pci_mig_drivers_mutex);
+
+static void vfio_pci_add_mig_drv(struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ atomic_set(&mig_drv->count, 1);
+ list_add_tail(&mig_drv->list, &vfio_pci_mig_drivers_list);
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+}
+
+static void vfio_pci_remove_mig_drv(struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_del(&mig_drv->list);
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+}
+
+static struct vfio_pci_vendor_mig_driver *
+ vfio_pci_find_mig_drv(struct pci_dev *pdev, struct module *module)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = NULL;
+
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_for_each_entry(mig_drv, &vfio_pci_mig_drivers_list, list) {
+ if (mig_drv->owner == module) {
+ if (mig_drv->bus_num == pdev->bus->number)
+ goto out;
+ }
+ }
+ mig_drv = NULL;
+out:
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+ return mig_drv;
+}
+
+static struct vfio_pci_vendor_mig_driver *
+ vfio_pci_get_mig_driver(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = NULL;
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_for_each_entry(mig_drv, &vfio_pci_mig_drivers_list, list) {
+ if (mig_drv->bus_num == pf_dev->bus->number)
+ goto out;
+ }
+ mig_drv = NULL;
+out:
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+ return mig_drv;
+}
+
+bool vfio_dev_migration_is_supported(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ mig_driver = vfio_pci_get_mig_driver(pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_warn(&pdev->dev, "unable to find a mig_drv module\n");
+ return false;
+ }
+
+ return true;
+}
+
+int vfio_pci_device_log_start(struct vfio_pci_device *vdev,
+ struct vf_migration_log_info *log_info)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->log_start ||
+ (mig_driver->dev_mig_ops->log_start(vdev->pdev,
+ log_info) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to set log start\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_log_stop(struct vfio_pci_device *vdev, uint32_t uuid)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->log_stop ||
+ (mig_driver->dev_mig_ops->log_stop(vdev->pdev, uuid) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to set log stop\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_log_status_query(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->get_log_status ||
+ (mig_driver->dev_mig_ops->get_log_status(vdev->pdev) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to get log status\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_init(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv;
+
+ mig_drv = vfio_pci_get_mig_driver(pdev);
+ if (!mig_drv || !mig_drv->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (mig_drv->dev_mig_ops->init)
+ return mig_drv->dev_mig_ops->init(pdev);
+
+ return -EFAULT;
+}
+
+void vfio_pci_device_uninit(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv;
+
+ mig_drv = vfio_pci_get_mig_driver(pdev);
+ if (!mig_drv || !mig_drv->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_drv module\n");
+ return;
+ }
+
+ if (mig_drv->dev_mig_ops->uninit)
+ mig_drv->dev_mig_ops->uninit(pdev);
+}
+
+static void vfio_pci_device_release(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (mig_drv->dev_mig_ops->release)
+ mig_drv->dev_mig_ops->release(pdev);
+}
+
+static int vfio_pci_device_get_info(struct pci_dev *pdev,
+ struct vfio_device_migration_info *mig_info,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (mig_drv->dev_mig_ops->get_info)
+ return mig_drv->dev_mig_ops->get_info(pdev, mig_info);
+ return -EFAULT;
+}
+
+static int vfio_pci_device_enable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->enable ||
+ (mig_drv->dev_mig_ops->enable(pdev) != 0)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vfio_pci_device_disable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->disable ||
+ (mig_drv->dev_mig_ops->disable(pdev) != 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vfio_pci_device_pre_enable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->pre_enable ||
+ (mig_drv->dev_mig_ops->pre_enable(pdev) != 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vfio_pci_device_state_save(struct pci_dev *pdev,
+ struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_info = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ void *base = (void *)mig_info;
+ int ret = 0;
+
+ if ((mig_info->device_state & VFIO_DEVICE_STATE_RUNNING) != 0) {
+ ret = vfio_pci_device_disable(pdev, mig_drv);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to stop VF function!\n");
+ return ret;
+ }
+ mig_info->device_state &= ~VFIO_DEVICE_STATE_RUNNING;
+ }
+
+ if (mig_drv->dev_mig_ops && mig_drv->dev_mig_ops->save) {
+ ret = mig_drv->dev_mig_ops->save(pdev, base,
+ mig_info->data_offset, data->state_size);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to save device state!\n");
+ return -EINVAL;
+ }
+ } else {
+ return -EFAULT;
+ }
+
+ mig_info->data_size = data->state_size;
+ mig_info->pending_bytes = mig_info->data_size;
+ return ret;
+}
+
+static int vfio_pci_device_state_restore(struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_info = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ void *base = (void *)mig_info;
+ int ret;
+
+ if (mig_drv->dev_mig_ops && mig_drv->dev_mig_ops->restore) {
+ ret = mig_drv->dev_mig_ops->restore(pdev, base,
+ mig_info->data_offset, mig_info->data_size);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to restore device state!\n");
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ return -EFAULT;
+}
+
+static int vfio_pci_set_device_state(struct vfio_pci_migration_data *data,
+ u32 state)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ int ret = 0;
+
+ if (state == mig_ctl->device_state)
+ return 0;
+
+ if (!mig_drv->dev_mig_ops)
+ return -EINVAL;
+
+ switch (state) {
+ case VFIO_DEVICE_STATE_RUNNING:
+ if (!(mig_ctl->device_state &
+ VFIO_DEVICE_STATE_RUNNING))
+ ret = vfio_pci_device_enable(pdev, mig_drv);
+ break;
+ case VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RUNNING:
+ /*
+ * (pre-copy) - device should start logging data.
+ */
+ ret = 0;
+ break;
+ case VFIO_DEVICE_STATE_SAVING:
+ /* stop the vf function, save state */
+ ret = vfio_pci_device_state_save(pdev, data);
+ break;
+ case VFIO_DEVICE_STATE_STOP:
+ if (mig_ctl->device_state & VFIO_DEVICE_STATE_RUNNING)
+ ret = vfio_pci_device_disable(pdev, mig_drv);
+ break;
+ case VFIO_DEVICE_STATE_RESUMING:
+ ret = vfio_pci_device_pre_enable(pdev, mig_drv);
+ break;
+ default:
+ ret = -EFAULT;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
+ mig_ctl->device_state = state;
+ return 0;
+}
+
+static ssize_t vfio_pci_handle_mig_dev_state(
+ struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, bool iswrite)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ u32 device_state;
+ int ret;
+
+ if (count != sizeof(device_state))
+ return -EINVAL;
+
+ if (iswrite) {
+ if (copy_from_user(&device_state, buf, count))
+ return -EFAULT;
+
+ ret = vfio_pci_set_device_state(data, device_state);
+ if (ret)
+ return ret;
+ } else {
+ if (copy_to_user(buf, &mig_ctl->device_state, count))
+ return -EFAULT;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_pending_bytes(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 pending_bytes;
+
+ if (count != sizeof(pending_bytes) || iswrite)
+ return -EINVAL;
+
+ if (mig_info->device_state ==
+ (VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RUNNING)) {
+ /* In pre-copy state we have no data to return for now,
+ * return 0 pending bytes
+ */
+ pending_bytes = 0;
+ } else {
+ pending_bytes = mig_info->pending_bytes;
+ }
+
+ if (copy_to_user(buf, &pending_bytes, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_offset(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 data_offset = mig_info->data_offset;
+
+ if (count != sizeof(data_offset) || iswrite)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &data_offset, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_size(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 data_size;
+
+ if (count != sizeof(data_size))
+ return -EINVAL;
+
+ if (iswrite) {
+ /* data_size is writable only during resuming state */
+ if (mig_info->device_state != VFIO_DEVICE_STATE_RESUMING)
+ return -EINVAL;
+
+ if (copy_from_user(&data_size, buf, sizeof(data_size)))
+ return -EFAULT;
+
+ mig_info->data_size = data_size;
+ } else {
+ if (mig_info->device_state != VFIO_DEVICE_STATE_SAVING)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &mig_info->data_size,
+ sizeof(data_size)))
+ return -EFAULT;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_dev_cmd(struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, bool iswrite)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ u32 device_cmd;
+ int ret = -EFAULT;
+
+ if (count != sizeof(device_cmd) || !iswrite || !mig_drv->dev_mig_ops)
+ return -EINVAL;
+
+ if (copy_from_user(&device_cmd, buf, count))
+ return -EFAULT;
+
+ switch (device_cmd) {
+ case VFIO_DEVICE_MIGRATION_CANCEL:
+ if (mig_drv->dev_mig_ops->cancel)
+ ret = mig_drv->dev_mig_ops->cancel(pdev);
+ break;
+ default:
+ dev_err(&pdev->dev, "cmd is invaild\n");
+ return -EINVAL;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_drv_version(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u32 version_id = mig_info->version_id;
+
+ if (count != sizeof(version_id) || iswrite)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &version_id, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_rw(
+ struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, u64 pos, bool iswrite)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ void *data_addr = data->vf_data;
+
+ if (count == 0) {
+ dev_err(&data->vf_dev->dev, "qemu operation data size error!\n");
+ return -EINVAL;
+ }
+
+ data_addr += pos - mig_ctl->data_offset;
+ if (iswrite) {
+ if (copy_from_user(data_addr, buf, count))
+ return -EFAULT;
+
+ mig_ctl->pending_bytes += count;
+ if (mig_ctl->pending_bytes > data->state_size)
+ return -EINVAL;
+ } else {
+ if (copy_to_user(buf, data_addr, count))
+ return -EFAULT;
+
+ if (mig_ctl->pending_bytes < count)
+ return -EINVAL;
+
+ mig_ctl->pending_bytes -= count;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_dev_migrn_rw(struct vfio_pci_device *vdev,
+ char __user *buf, size_t count, loff_t *ppos, bool iswrite)
+{
+ unsigned int index =
+ VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS;
+ struct vfio_pci_migration_data *data =
+ (struct vfio_pci_migration_data *)vdev->region[index].data;
+ loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ int ret;
+
+ if (pos >= vdev->region[index].size)
+ return -EINVAL;
+
+ count = min(count, (size_t)(vdev->region[index].size - pos));
+ if (pos >= VFIO_MIGRATION_REGION_DATA_OFFSET)
+ return vfio_pci_handle_mig_data_rw(data,
+ buf, count, pos, iswrite);
+
+ switch (pos) {
+ case VFIO_DEVICE_MIGRATION_OFFSET(device_state):
+ ret = vfio_pci_handle_mig_dev_state(data,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(pending_bytes):
+ ret = vfio_pci_handle_mig_pending_bytes(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(data_offset):
+ ret = vfio_pci_handle_mig_data_offset(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(data_size):
+ ret = vfio_pci_handle_mig_data_size(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(device_cmd):
+ ret = vfio_pci_handle_mig_dev_cmd(data,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(version_id):
+ ret = vfio_pci_handle_mig_drv_version(mig_ctl,
+ buf, count, iswrite);
+ break;
+ default:
+ dev_err(&vdev->pdev->dev, "invalid pos offset\n");
+ ret = -EFAULT;
+ break;
+ }
+
+ if (mig_ctl->device_state == VFIO_DEVICE_STATE_RESUMING &&
+ mig_ctl->pending_bytes == data->state_size &&
+ mig_ctl->data_size == data->state_size) {
+ if (vfio_pci_device_state_restore(data) != 0) {
+ dev_err(&vdev->pdev->dev, "Failed to restore device state!\n");
+ return -EFAULT;
+ }
+ mig_ctl->pending_bytes = 0;
+ mig_ctl->data_size = 0;
+ }
+
+ return ret;
+}
+
+static void vfio_pci_dev_migrn_release(struct vfio_pci_device *vdev,
+ struct vfio_pci_region *region)
+{
+ struct vfio_pci_migration_data *data = region->data;
+
+ if (data) {
+ kfree(data->mig_ctl);
+ kfree(data);
+ }
+}
+
+static const struct vfio_pci_regops vfio_pci_migration_regops = {
+ .rw = vfio_pci_dev_migrn_rw,
+ .release = vfio_pci_dev_migrn_release,
+};
+
+static int vfio_pci_migration_info_init(struct pci_dev *pdev,
+ struct vfio_device_migration_info *mig_info,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ int ret;
+
+ ret = vfio_pci_device_get_info(pdev, mig_info, mig_drv);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get device info\n");
+ return ret;
+ }
+
+ if (mig_info->data_size > VFIO_MIGRATION_BUFFER_MAX_SIZE) {
+ dev_err(&pdev->dev, "mig_info->data_size %llu is invalid\n",
+ mig_info->data_size);
+ return -EINVAL;
+ }
+
+ mig_info->data_offset = VFIO_MIGRATION_REGION_DATA_OFFSET;
+ return ret;
+}
+
+static int vfio_device_mig_data_init(struct vfio_pci_device *vdev,
+ struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_ctl;
+ u64 mig_offset;
+ int ret;
+
+ mig_ctl = kzalloc(sizeof(*mig_ctl), GFP_KERNEL);
+ if (!mig_ctl)
+ return -ENOMEM;
+
+ ret = vfio_pci_migration_info_init(vdev->pdev, mig_ctl,
+ data->mig_driver);
+ if (ret) {
+ dev_err(&vdev->pdev->dev, "get device info error!\n");
+ goto err;
+ }
+
+ mig_offset = sizeof(struct vfio_device_migration_info);
+ data->state_size = mig_ctl->data_size;
+ data->mig_ctl = krealloc(mig_ctl, mig_offset + data->state_size,
+ GFP_KERNEL);
+ if (!data->mig_ctl) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ data->vf_data = (void *)((char *)data->mig_ctl + mig_offset);
+ memset(data->vf_data, 0, data->state_size);
+ data->mig_ctl->data_size = 0;
+
+ ret = vfio_pci_register_dev_region(vdev, VFIO_REGION_TYPE_MIGRATION,
+ VFIO_REGION_SUBTYPE_MIGRATION,
+ &vfio_pci_migration_regops, mig_offset + data->state_size,
+ VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE, data);
+ if (ret) {
+ kfree(data->mig_ctl);
+ return ret;
+ }
+
+ return 0;
+err:
+ kfree(mig_ctl);
+ return ret;
+}
+
+int vfio_pci_migration_init(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+ struct vfio_pci_migration_data *data = NULL;
+ struct pci_dev *pdev = vdev->pdev;
+ int ret;
+
+ mig_driver = vfio_pci_get_mig_driver(pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_driver module\n");
+ return -EINVAL;
+ }
+
+ if (!try_module_get(mig_driver->owner)) {
+ pr_err("module %s is not live\n", mig_driver->owner->name);
+ return -ENODEV;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ module_put(mig_driver->owner);
+ return -ENOMEM;
+ }
+
+ data->mig_driver = mig_driver;
+ data->vf_dev = pdev;
+
+ ret = vfio_device_mig_data_init(vdev, data);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to init vfio device migration data!\n");
+ goto err;
+ }
+
+ return ret;
+err:
+ kfree(data);
+ module_put(mig_driver->owner);
+ return ret;
+}
+
+void vfio_pci_migration_exit(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_warn(&vdev->pdev->dev, "mig_driver is not found\n");
+ return;
+ }
+
+ if (module_refcount(mig_driver->owner) > 0) {
+ vfio_pci_device_release(vdev->pdev, mig_driver);
+ module_put(mig_driver->owner);
+ }
+}
+
+int vfio_pci_register_migration_ops(struct vfio_device_migration_ops *ops,
+ struct module *mod, struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ if (!ops || !mod || !pdev)
+ return -EINVAL;
+
+ mig_driver = vfio_pci_find_mig_drv(pdev, mod);
+ if (mig_driver) {
+ pr_info("%s migration ops has already been registered\n",
+ mod->name);
+ atomic_add(1, &mig_driver->count);
+ return 0;
+ }
+
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
+ mig_driver = kzalloc(sizeof(*mig_driver), GFP_KERNEL);
+ if (!mig_driver) {
+ module_put(THIS_MODULE);
+ return -ENOMEM;
+ }
+
+ mig_driver->pdev = pdev;
+ mig_driver->bus_num = pdev->bus->number;
+ mig_driver->owner = mod;
+ mig_driver->dev_mig_ops = ops;
+
+ vfio_pci_add_mig_drv(mig_driver);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(vfio_pci_register_migration_ops);
+
+void vfio_pci_unregister_migration_ops(struct module *mod, struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ if (!mod || !pdev)
+ return;
+
+ mig_driver = vfio_pci_find_mig_drv(pdev, mod);
+ if (!mig_driver) {
+ pr_err("mig_driver is not found\n");
+ return;
+ }
+
+ if (atomic_sub_and_test(1, &mig_driver->count)) {
+ vfio_pci_remove_mig_drv(mig_driver);
+ kfree(mig_driver);
+ module_put(THIS_MODULE);
+ pr_info("%s succeed to unregister migration ops\n",
+ THIS_MODULE->name);
+ }
+}
+EXPORT_SYMBOL_GPL(vfio_pci_unregister_migration_ops);
diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h
index 17d2bae..03af269 100644
--- a/drivers/vfio/pci/vfio_pci_private.h
+++ b/drivers/vfio/pci/vfio_pci_private.h
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/irqbypass.h>
#include <linux/types.h>
+#include <linux/vfio_pci_migration.h>
#ifndef VFIO_PCI_PRIVATE_H
#define VFIO_PCI_PRIVATE_H
@@ -55,7 +56,7 @@ struct vfio_pci_irq_ctx {
struct vfio_pci_region;
struct vfio_pci_regops {
- size_t (*rw)(struct vfio_pci_device *vdev, char __user *buf,
+ ssize_t (*rw)(struct vfio_pci_device *vdev, char __user *buf,
size_t count, loff_t *ppos, bool iswrite);
void (*release)(struct vfio_pci_device *vdev,
struct vfio_pci_region *region);
@@ -173,4 +174,15 @@ static inline int vfio_pci_igd_init(struct vfio_pci_device *vdev)
return -ENODEV;
}
#endif
+
+extern bool vfio_dev_migration_is_supported(struct pci_dev *pdev);
+extern int vfio_pci_migration_init(struct vfio_pci_device *vdev);
+extern void vfio_pci_migration_exit(struct vfio_pci_device *vdev);
+extern int vfio_pci_device_log_start(struct vfio_pci_device *vdev,
+ struct vf_migration_log_info *log_info);
+extern int vfio_pci_device_log_stop(struct vfio_pci_device *vdev,
+ uint32_t uuid);
+extern int vfio_pci_device_log_status_query(struct vfio_pci_device *vdev);
+extern int vfio_pci_device_init(struct pci_dev *pdev);
+extern void vfio_pci_device_uninit(struct pci_dev *pdev);
#endif /* VFIO_PCI_PRIVATE_H */
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 7a386fb..35f2a29 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -33,6 +33,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/vfio.h>
+#include <linux/vfio_pci_migration.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
@@ -40,6 +41,9 @@
#define DRIVER_AUTHOR "Alex Williamson <alex.williamson(a)redhat.com>"
#define DRIVER_DESC "VFIO - User Level meta-driver"
+#define LOG_BUF_FRAG_SIZE (2 * 1024 * 1024) // fix to 2M
+#define LOG_BUF_MAX_ADDRS_SIZE 128 // max vm ram size is 1T
+
static struct vfio {
struct class *class;
struct list_head iommu_drivers_list;
@@ -57,6 +61,14 @@ struct vfio_iommu_driver {
struct list_head vfio_next;
};
+struct vfio_log_buf {
+ struct vfio_log_buf_info info;
+ int fd;
+ int buffer_state;
+ int device_state;
+ unsigned long *cpu_addrs;
+};
+
struct vfio_container {
struct kref kref;
struct list_head group_list;
@@ -64,6 +76,7 @@ struct vfio_container {
struct vfio_iommu_driver *iommu_driver;
void *iommu_data;
bool noiommu;
+ struct vfio_log_buf log_buf;
};
struct vfio_unbound_dev {
@@ -1158,8 +1171,398 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
return ret;
}
+static long vfio_dispatch_cmd_to_devices(const struct vfio_container *container,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vfio_group *group = NULL;
+ struct vfio_device *device = NULL;
+ long ret = -ENXIO;
+
+ list_for_each_entry(group, &container->group_list, container_next) {
+ list_for_each_entry(device, &group->device_list, group_next) {
+ ret = device->ops->ioctl(device->device_data, cmd, arg);
+ if (ret) {
+ pr_err("dispatch cmd to devices failed\n");
+ return ret;
+ }
+ }
+ }
+ return ret;
+}
+
+static long vfio_log_buf_start(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret;
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_START;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+ ret = vfio_dispatch_cmd_to_devices(container, VFIO_DEVICE_LOG_BUF_CTL,
+ (unsigned long)&log_buf_ctl);
+ if (ret)
+ return ret;
+
+ container->log_buf.device_state = 1;
+ return 0;
+}
+
+static long vfio_log_buf_stop(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret;
+
+ if (container->log_buf.device_state == 0) {
+ pr_warn("device already stopped\n");
+ return 0;
+ }
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_STOP;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+ ret = vfio_dispatch_cmd_to_devices(container, VFIO_DEVICE_LOG_BUF_CTL,
+ (unsigned long)&log_buf_ctl);
+ if (ret)
+ return ret;
+
+ container->log_buf.device_state = 0;
+ return 0;
+}
+
+static long vfio_log_buf_query(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+
+ return vfio_dispatch_cmd_to_devices(container,
+ VFIO_DEVICE_LOG_BUF_CTL, (unsigned long)&log_buf_ctl);
+}
+
+static int vfio_log_buf_fops_mmap(struct file *filep,
+ struct vm_area_struct *vma)
+{
+ struct vfio_container *container = filep->private_data;
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ unsigned long frag_pg_size;
+ unsigned long frag_offset;
+ phys_addr_t pa;
+ int ret = -EINVAL;
+
+ if (!log_buf->cpu_addrs) {
+ pr_err("mmap before setup, please setup log buf first\n");
+ return ret;
+ }
+
+ if (log_buf->info.frag_size < PAGE_SIZE) {
+ pr_err("mmap frag size should not less than page size!\n");
+ return ret;
+ }
+
+ frag_pg_size = log_buf->info.frag_size / PAGE_SIZE;
+ frag_offset = vma->vm_pgoff / frag_pg_size;
+
+ if (frag_offset >= log_buf->info.addrs_size) {
+ pr_err("mmap offset out of range!\n");
+ return ret;
+ }
+
+ if (vma->vm_end - vma->vm_start != log_buf->info.frag_size) {
+ pr_err("mmap size error, should be aligned with frag size!\n");
+ return ret;
+ }
+
+ pa = virt_to_phys((void *)log_buf->cpu_addrs[frag_offset]);
+ ret = remap_pfn_range(vma, vma->vm_start,
+ pa >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+ if (ret)
+ pr_err("remap_pfn_range error!\n");
+ return ret;
+}
+
+static struct device *vfio_get_dev(struct vfio_container *container)
+{
+ struct vfio_group *group = NULL;
+ struct vfio_device *device = NULL;
+
+ list_for_each_entry(group, &container->group_list, container_next) {
+ list_for_each_entry(device, &group->device_list, group_next) {
+ return device->dev;
+ }
+ }
+ return NULL;
+}
+
+static void vfio_log_buf_release_dma(struct device *dev,
+ struct vfio_log_buf *log_buf)
+{
+ int i;
+
+ for (i = 0; i < log_buf->info.addrs_size; i++) {
+ if ((log_buf->cpu_addrs && log_buf->cpu_addrs[i] != 0) &&
+ (log_buf->info.sgevec &&
+ log_buf->info.sgevec[i].addr != 0)) {
+ dma_free_coherent(dev, log_buf->info.frag_size,
+ (void *)log_buf->cpu_addrs[i],
+ log_buf->info.sgevec[i].addr);
+ log_buf->cpu_addrs[i] = 0;
+ log_buf->info.sgevec[i].addr = 0;
+ }
+ }
+}
+
+static long vfio_log_buf_alloc_dma(struct vfio_log_buf_info *info,
+ struct vfio_log_buf *log_buf, struct device *dev)
+{
+ int i;
+
+ for (i = 0; i < info->addrs_size; i++) {
+ log_buf->cpu_addrs[i] = (unsigned long)dma_alloc_coherent(dev,
+ info->frag_size, &log_buf->info.sgevec[i].addr,
+ GFP_KERNEL);
+ log_buf->info.sgevec[i].len = info->frag_size;
+ if (log_buf->cpu_addrs[i] == 0 ||
+ log_buf->info.sgevec[i].addr == 0) {
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static long vfio_log_buf_alloc_addrs(struct vfio_log_buf_info *info,
+ struct vfio_log_buf *log_buf)
+{
+ log_buf->info.sgevec = kcalloc(info->addrs_size,
+ sizeof(struct vfio_log_buf_sge), GFP_KERNEL);
+ if (!log_buf->info.sgevec)
+ return -ENOMEM;
+
+ log_buf->cpu_addrs = kcalloc(info->addrs_size,
+ sizeof(unsigned long), GFP_KERNEL);
+ if (!log_buf->cpu_addrs) {
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static long vfio_log_buf_info_valid(struct vfio_log_buf_info *info)
+{
+ if (info->addrs_size > LOG_BUF_MAX_ADDRS_SIZE ||
+ info->addrs_size == 0) {
+ pr_err("can`t support vm ram size larger than 1T or equal to 0\n");
+ return -EINVAL;
+ }
+ if (info->frag_size != LOG_BUF_FRAG_SIZE) {
+ pr_err("only support %d frag size\n", LOG_BUF_FRAG_SIZE);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static long vfio_log_buf_setup(struct vfio_container *container,
+ unsigned long data)
+{
+ struct vfio_log_buf_info info;
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ struct device *dev = NULL;
+ long ret;
+
+ if (log_buf->info.sgevec) {
+ pr_warn("log buf already setup\n");
+ return 0;
+ }
+
+ if (copy_from_user(&info, (void __user *)data,
+ sizeof(struct vfio_log_buf_info)))
+ return -EFAULT;
+
+ ret = vfio_log_buf_info_valid(&info);
+ if (ret)
+ return ret;
+
+ ret = vfio_log_buf_alloc_addrs(&info, log_buf);
+ if (ret)
+ goto err_out;
+
+ dev = vfio_get_dev(container);
+ if (!dev) {
+ pr_err("can`t get dev\n");
+ goto err_free_addrs;
+ }
+
+ ret = vfio_log_buf_alloc_dma(&info, log_buf, dev);
+ if (ret)
+ goto err_free_dma_array;
+
+ log_buf->info.uuid = info.uuid;
+ log_buf->info.buffer_size = info.buffer_size;
+ log_buf->info.frag_size = info.frag_size;
+ log_buf->info.addrs_size = info.addrs_size;
+ log_buf->buffer_state = 1;
+ return 0;
+
+err_free_dma_array:
+ vfio_log_buf_release_dma(dev, log_buf);
+err_free_addrs:
+ kfree(log_buf->cpu_addrs);
+ log_buf->cpu_addrs = NULL;
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+err_out:
+ return -ENOMEM;
+}
+
+static long vfio_log_buf_release_buffer(struct vfio_container *container)
+{
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ struct device *dev = NULL;
+
+ if (log_buf->buffer_state == 0) {
+ pr_warn("buffer already released\n");
+ return 0;
+ }
+
+ dev = vfio_get_dev(container);
+ if (!dev) {
+ pr_err("can`t get dev\n");
+ return -EFAULT;
+ }
+
+ vfio_log_buf_release_dma(dev, log_buf);
+
+ kfree(log_buf->cpu_addrs);
+ log_buf->cpu_addrs = NULL;
+
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+
+ log_buf->buffer_state = 0;
+ return 0;
+}
+
+static int vfio_log_buf_release(struct inode *inode, struct file *filep)
+{
+ struct vfio_container *container = filep->private_data;
+
+ vfio_log_buf_stop(container);
+ vfio_log_buf_release_buffer(container);
+ memset(&container->log_buf, 0, sizeof(struct vfio_log_buf));
+ return 0;
+}
+
+static long vfio_ioctl_handle_log_buf_ctl(struct vfio_container *container,
+ unsigned long arg)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret = 0;
+
+ if (copy_from_user(&log_buf_ctl, (void __user *)arg,
+ sizeof(struct vfio_log_buf_ctl)))
+ return -EFAULT;
+
+ switch (log_buf_ctl.flags) {
+ case VFIO_DEVICE_LOG_BUF_FLAG_SETUP:
+ ret = vfio_log_buf_setup(container,
+ (unsigned long)log_buf_ctl.data);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_RELEASE:
+ ret = vfio_log_buf_release_buffer(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_START:
+ ret = vfio_log_buf_start(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STOP:
+ ret = vfio_log_buf_stop(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY:
+ ret = vfio_log_buf_query(container);
+ break;
+ default:
+ pr_err("log buf control flag incorrect\n");
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static long vfio_log_buf_fops_unl_ioctl(struct file *filep,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vfio_container *container = filep->private_data;
+ long ret = -EINVAL;
+
+ switch (cmd) {
+ case VFIO_LOG_BUF_CTL:
+ ret = vfio_ioctl_handle_log_buf_ctl(container, arg);
+ break;
+ default:
+ pr_err("log buf control cmd incorrect\n");
+ break;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long vfio_log_buf_fops_compat_ioctl(struct file *filep,
+ unsigned int cmd, unsigned long arg)
+{
+ arg = (unsigned long)compat_ptr(arg);
+ return vfio_log_buf_fops_unl_ioctl(filep, cmd, arg);
+}
+#endif /* CONFIG_COMPAT */
+
+static const struct file_operations vfio_log_buf_fops = {
+ .owner = THIS_MODULE,
+ .mmap = vfio_log_buf_fops_mmap,
+ .unlocked_ioctl = vfio_log_buf_fops_unl_ioctl,
+ .release = vfio_log_buf_release,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = vfio_log_buf_fops_compat_ioctl,
+#endif
+};
+
+static int vfio_get_log_buf_fd(struct vfio_container *container,
+ unsigned long arg)
+{
+ struct file *filep = NULL;
+ int ret;
+
+ if (container->log_buf.fd > 0)
+ return container->log_buf.fd;
+
+ ret = get_unused_fd_flags(O_CLOEXEC);
+ if (ret < 0) {
+ pr_err("get_unused_fd_flags get fd failed\n");
+ return ret;
+ }
+
+ filep = anon_inode_getfile("[vfio-log-buf]", &vfio_log_buf_fops,
+ container, O_RDWR);
+ if (IS_ERR(filep)) {
+ pr_err("anon_inode_getfile failed\n");
+ put_unused_fd(ret);
+ ret = PTR_ERR(filep);
+ return ret;
+ }
+
+ filep->f_mode |= (FMODE_READ | FMODE_WRITE | FMODE_LSEEK);
+
+ fd_install(ret, filep);
+
+ container->log_buf.fd = ret;
+ return ret;
+}
+
static long vfio_fops_unl_ioctl(struct file *filep,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
struct vfio_container *container = filep->private_data;
struct vfio_iommu_driver *driver;
@@ -1179,6 +1582,9 @@ static long vfio_fops_unl_ioctl(struct file *filep,
case VFIO_SET_IOMMU:
ret = vfio_ioctl_set_iommu(container, arg);
break;
+ case VFIO_GET_LOG_BUF_FD:
+ ret = vfio_get_log_buf_fd(container, arg);
+ break;
default:
driver = container->iommu_driver;
data = container->iommu_data;
@@ -1210,6 +1616,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
INIT_LIST_HEAD(&container->group_list);
init_rwsem(&container->group_lock);
kref_init(&container->kref);
+ memset(&container->log_buf, 0, sizeof(struct vfio_log_buf));
filep->private_data = container;
@@ -1219,9 +1626,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
static int vfio_fops_release(struct inode *inode, struct file *filep)
{
struct vfio_container *container = filep->private_data;
-
filep->private_data = NULL;
-
vfio_container_put(container);
return 0;
diff --git a/include/linux/vfio_pci_migration.h b/include/linux/vfio_pci_migration.h
new file mode 100644
index 0000000..464ffb4
--- /dev/null
+++ b/include/linux/vfio_pci_migration.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ */
+
+#ifndef VFIO_PCI_MIGRATION_H
+#define VFIO_PCI_MIGRATION_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#define VFIO_REGION_TYPE_MIGRATION (3)
+/* sub-types for VFIO_REGION_TYPE_MIGRATION */
+#define VFIO_REGION_SUBTYPE_MIGRATION (1)
+
+#define VFIO_MIGRATION_BUFFER_MAX_SIZE SZ_256K
+#define VFIO_MIGRATION_REGION_DATA_OFFSET \
+ (sizeof(struct vfio_device_migration_info))
+#define VFIO_DEVICE_MIGRATION_OFFSET(x) \
+ offsetof(struct vfio_device_migration_info, x)
+
+struct vfio_device_migration_info {
+ __u32 device_state; /* VFIO device state */
+#define VFIO_DEVICE_STATE_STOP (0)
+#define VFIO_DEVICE_STATE_RUNNING (1 << 0)
+#define VFIO_DEVICE_STATE_SAVING (1 << 1)
+#define VFIO_DEVICE_STATE_RESUMING (1 << 2)
+#define VFIO_DEVICE_STATE_MASK (VFIO_DEVICE_STATE_RUNNING | \
+ VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING)
+ __u32 reserved;
+
+ __u32 device_cmd;
+ __u32 version_id;
+
+ __u64 pending_bytes;
+ __u64 data_offset;
+ __u64 data_size;
+};
+
+enum {
+ VFIO_DEVICE_STOP = 0xffff0001,
+ VFIO_DEVICE_CONTINUE,
+ VFIO_DEVICE_MIGRATION_CANCEL,
+};
+
+struct vfio_log_buf_sge {
+ __u64 len;
+ __u64 addr;
+};
+
+struct vfio_log_buf_info {
+ __u32 uuid;
+ __u64 buffer_size;
+ __u64 addrs_size;
+ __u64 frag_size;
+ struct vfio_log_buf_sge *sgevec;
+};
+
+struct vfio_log_buf_ctl {
+ __u32 argsz;
+ __u32 flags;
+ #define VFIO_DEVICE_LOG_BUF_FLAG_SETUP (1 << 0)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_RELEASE (1 << 1)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_START (1 << 2)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_STOP (1 << 3)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY (1 << 4)
+ void *data;
+};
+#define VFIO_LOG_BUF_CTL _IO(VFIO_TYPE, VFIO_BASE + 21)
+#define VFIO_GET_LOG_BUF_FD _IO(VFIO_TYPE, VFIO_BASE + 22)
+#define VFIO_DEVICE_LOG_BUF_CTL _IO(VFIO_TYPE, VFIO_BASE + 23)
+
+struct vf_migration_log_info {
+ __u32 dom_uuid;
+ __u64 buffer_size;
+ __u64 sge_len;
+ __u64 sge_num;
+ struct vfio_log_buf_sge *sgevec;
+};
+
+struct vfio_device_migration_ops {
+ /* Get device information */
+ int (*get_info)(struct pci_dev *pdev,
+ struct vfio_device_migration_info *info);
+ /* Enable a vf device */
+ int (*enable)(struct pci_dev *pdev);
+ /* Disable a vf device */
+ int (*disable)(struct pci_dev *pdev);
+ /* Save a vf device */
+ int (*save)(struct pci_dev *pdev, void *base,
+ uint64_t off, uint64_t count);
+ /* Resuming a vf device */
+ int (*restore)(struct pci_dev *pdev, void *base,
+ uint64_t off, uint64_t count);
+ /* Log start a vf device */
+ int (*log_start)(struct pci_dev *pdev,
+ struct vf_migration_log_info *log_info);
+ /* Log stop a vf device */
+ int (*log_stop)(struct pci_dev *pdev, uint32_t uuid);
+ /* Get vf device log status */
+ int (*get_log_status)(struct pci_dev *pdev);
+ /* Pre enable a vf device(load_setup, before restore a vf) */
+ int (*pre_enable)(struct pci_dev *pdev);
+ /* Cancel a vf device when live migration failed (rollback) */
+ int (*cancel)(struct pci_dev *pdev);
+ /* Init a vf device */
+ int (*init)(struct pci_dev *pdev);
+ /* Uninit a vf device */
+ void (*uninit)(struct pci_dev *pdev);
+ /* Release a vf device */
+ void (*release)(struct pci_dev *pdev);
+};
+
+struct vfio_pci_vendor_mig_driver {
+ struct pci_dev *pdev;
+ unsigned char bus_num;
+ struct vfio_device_migration_ops *dev_mig_ops;
+ struct module *owner;
+ atomic_t count;
+ struct list_head list;
+};
+
+struct vfio_pci_migration_data {
+ u64 state_size;
+ struct pci_dev *vf_dev;
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+ struct vfio_device_migration_info *mig_ctl;
+ void *vf_data;
+};
+
+int vfio_pci_register_migration_ops(struct vfio_device_migration_ops *ops,
+ struct module *mod, struct pci_dev *pdev);
+void vfio_pci_unregister_migration_ops(struct module *mod,
+ struct pci_dev *pdev);
+
+#endif /* VFIO_PCI_MIGRATION_H */
--
1.8.3.1
3
2

05 Jul '22
From: Gou Hao <gouhao(a)uniontech.com>
Patch series "Add extended attributes support for EulerFS".
I refer to the extended attribute implementation code of ext2 file
system. At first, I implemented it completely according to the extended
attribute of ext file system. But later, I changed the disk layout of
entries.
About layout of entry:
The layout of ext2's extended attribute is that name and value
are stored separately,with name growing from top to bottom and value
growing from bottom to top. I think the layout of ext2 wastes
space, because, Name and value are aligned with 4 bytes, In the worst
case, the name and value of entry need 3 bytes of padding respectively,
and a total of 6 bytes are wasted.
I store the name and value together. In the worst case, only need
3 bytes of padding.Use xattr-test.c selftests, with the same block
size, my method can store 112 entries, while using ext2 layout can
only store 102 entries.
In ext4 file system, value can be stored in different blocks, which
increases the scalability. In my method, it can add a pointer to the
next block in the header to achieve the same function, and it is simpler.
The performance of my method is the same as that of ext2, or even better.
About block share:
In ext2, if the extended attributes of two files are exactly
the same, they can share the same disk block. Its implementation
process is:
1. When accessing the extended attribute of a file, add this
extended attribute block to a specific cache.
2. When setting the extended attribute of a file, if there is
a block with exactly the same content as this extended attribute
in the cache, share that block directly.
There is a problem here. If the block of a file is not added to the
cache, the extended attribute block will not be shared.So in this
patch set, I didn't realize the shared disk block. I'll implement it
later when there is a good method or when there is a need.
At present, only user. prefix xattr is implemented. Trusted, ACL and
security will be implemented later.
Gou Hao (7):
eulerfs: add EULER_FS_XATTR config
eulerfs: add related fields of extended attributes
eulerfs: add alloc xattr block interface
eulerfs: implement extended attribute core functions
eulerfs: add callback interface of extended attribute
eulerfs: add implementation of user. prefix extended attribute
eulerfs: add selftests for eulerfs extended attribute
fs/eulerfs/Kconfig | 9 +
fs/eulerfs/Makefile | 1 +
fs/eulerfs/alloc_interface.h | 4 +
fs/eulerfs/const.h | 1 +
fs/eulerfs/euler.h | 1 +
fs/eulerfs/euler_def.h | 3 +
fs/eulerfs/file.c | 1 +
fs/eulerfs/inode.c | 3 +
fs/eulerfs/namei.c | 2 +
fs/eulerfs/nvalloc.c | 1 +
fs/eulerfs/nvalloc.h | 1 +
fs/eulerfs/nvm_struct.h | 12 +
fs/eulerfs/super.c | 36 +-
fs/eulerfs/symlink.c | 1 +
fs/eulerfs/xattr.c | 422 ++++++++++++++
fs/eulerfs/xattr.h | 99 ++++
fs/eulerfs/xattr_user.c | 43 ++
tools/testing/selftests/eulerfs/Makefile | 6 +
tools/testing/selftests/eulerfs/xattr-test.c | 565 +++++++++++++++++++
19 files changed, 1209 insertions(+), 2 deletions(-)
create mode 100644 fs/eulerfs/xattr.c
create mode 100644 fs/eulerfs/xattr.h
create mode 100644 fs/eulerfs/xattr_user.c
create mode 100644 tools/testing/selftests/eulerfs/Makefile
create mode 100644 tools/testing/selftests/eulerfs/xattr-test.c
--
2.20.1
1
7
您好!
Kernel SIG 邀请您参加 2022-07-08 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler kernel SIG例会
会议内容:
美团贡献富容器隔离及内部自研混部特性到openEuler kernel的讨论
会议链接:https://us06web.zoom.us/j/89123664797?pwd=S1BKR3BHTTBOZUd0TTg2VE9FRUVMQT09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2022-07-08 14:00,
The subject of the conference is openEuler kernel SIG例会,
Summary:
美团贡献富容器隔离及内部自研混部特性到openEuler kernel的讨论
You can join the meeting at https://us06web.zoom.us/j/89123664797?pwd=S1BKR3BHTTBOZUd0TTg2VE9FRUVMQT09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0
我运行咱们的系统在一台分腾d2000的机器上,发现网卡是驱动不起来的。
网卡型号是PHYT0004,走的MDIO的总线,使用stmmac的驱动。
以上是我了解的相关技术,目前网卡驱动不起来,所以没有相关dmesg日志。
正在着手解决该问题,所以提请咨询。
王铭
sireg
firerun(a)qq.com
2
1
我运行咱们的系统在一台飞腾d2000的机器上,发现网卡驱动不起来。
以上是我了解的相关技术,目前网卡驱动不起来,所以没有相关dmesg日志。
网卡型号是PHYT0004,如果驱动起来,应该是走的MDIO的总线,使用stmmac的驱动。
正在着手解决该问题,所以提请咨询。
王铭
sireg
firerun(a)qq.com
1
0

[PATCH openEuler-1.0-LTS 1/4] ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h
by Yongqiang Liu 02 Jul '22
by Yongqiang Liu 02 Jul '22
02 Jul '22
From: Baokun Li <libaokun1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 186866, https://gitee.com/openeuler/kernel/issues/I5DTBL
CVE: NA
--------------------------------
When adding an xattr to an inode, we must ensure that the inode_size is
not less than EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad. Otherwise,
the end position may be greater than the start position, resulting in UAF.
Signed-off-by: Baokun Li <libaokun1(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/ext4/xattr.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index f39cad2abe2a..990084e00374 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -95,6 +95,19 @@ struct ext4_xattr_entry {
#define EXT4_ZERO_XATTR_VALUE ((void *)-1)
+/*
+ * If we want to add an xattr to the inode, we should make sure that
+ * i_extra_isize is not 0 and that the inode size is not less than
+ * EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad.
+ * EXT4_GOOD_OLD_INODE_SIZE extra_isize header entry pad data
+ * |--------------------------|------------|------|---------|---|-------|
+ */
+#define EXT4_INODE_HAS_XATTR_SPACE(inode) \
+ ((EXT4_I(inode)->i_extra_isize != 0) && \
+ (EXT4_GOOD_OLD_INODE_SIZE + EXT4_I(inode)->i_extra_isize + \
+ sizeof(struct ext4_xattr_ibody_header) + EXT4_XATTR_PAD <= \
+ EXT4_INODE_SIZE((inode)->i_sb)))
+
struct ext4_xattr_info {
const char *name;
const void *value;
--
2.25.1
1
3

[PATCH openEuler-1.0-LTS 1/4] mm/sharepool: Fix using uninitialized sp_flag
by Yongqiang Liu 01 Jul '22
by Yongqiang Liu 01 Jul '22
01 Jul '22
From: Wang Wensheng <wangwensheng4(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I578LV
CVE: NA
-------------------------------------------------
Add the missing initialization for kc.sp_flag in
sp_make_share_kva_to_spg(). Or a random value would be used in
sp_remap_kva_to_vma().
Fixes: da51b55eeff9 ("mm/share_pool: Support read-only memory allocation")
Signed-off-by: Wang Wensheng <wangwensheng4(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/share_pool.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/share_pool.c b/mm/share_pool.c
index ec889155b0ff..893e5352bf01 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -3023,7 +3023,7 @@ static void *sp_make_share_kva_to_spg(unsigned long kva, unsigned long size,
}
spa->kva = kva;
-
+ kc.sp_flags = sp_flags;
list_for_each_entry(spg_node, &spg->procs, proc_node) {
mm = spg_node->master->mm;
kc.state = K2U_NORMAL;
--
2.25.1
1
3

[PATCH openEuler-1.0-LTS 1/4] alinux: sched: Defend cfs and rt bandwidth against overflow
by liuzhengyuan@kylinos.cn 30 Jun '22
by liuzhengyuan@kylinos.cn 30 Jun '22
30 Jun '22
From: Huaixin Chang <changhuaixin(a)linux.alibaba.com>
anolis inclusion
from anolis_master
commit 9d168f216486333f24aa1b33706eddf3b13d7228
category: performance
bugzilla: NA
CVE: NA
---------------------------
Kernel limitation on cpu.cfs_quota_us is insufficient. Some large
numbers might cause overflow in to_ratio() calculation and produce
unexpected results.
For example, if we make two cpu cgroups and then write a reasonable
value and a large value into child's and parent's cpu.cfs_quota_us. This
will cause a write error.
cd /sys/fs/cgroup/cpu
mkdir parent; mkdir parent/child
echo 8000 > parent/child/cpu.cfs_quota_us
# 17592186044416 is (1UL << 44)
echo 17592186044416 > parent/cpu.cfs_quota_us
In this case, quota will overflow and thus fail the __cfs_schedulable
check. Similar overflow also affects rt bandwidth.
Burstable CFS bandwidth controller will also benefit from limiting
quota.
Change-Id: I0f89d1f26b168c5cfa041e886395c7f3068114ae
Reviewed-by: Shanpei Chen <shanpeic(a)linux.alibaba.com>
Signed-off-by: Huaixin Chang <changhuaixin(a)linux.alibaba.com>
Signed-off-by: Zhengyuan Liu <liuzhengyuan(a)kylinos.cn>
---
kernel/sched/core.c | 8 ++++++++
kernel/sched/rt.c | 9 +++++++++
kernel/sched/sched.h | 2 ++
3 files changed, 19 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 36d7422da0ac..51fdd30f188a 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6679,6 +6679,8 @@ static DEFINE_MUTEX(cfs_constraints_mutex);
const u64 max_cfs_quota_period = 1 * NSEC_PER_SEC; /* 1s */
const u64 min_cfs_quota_period = 1 * NSEC_PER_MSEC; /* 1ms */
+/* More than 203 days if BW_SHIFT equals 20. */
+const u64 max_cfs_runtime = MAX_BW_USEC * NSEC_PER_USEC;
static int __cfs_schedulable(struct task_group *tg, u64 period, u64 runtime);
@@ -6706,6 +6708,12 @@ static int tg_set_cfs_bandwidth(struct task_group *tg, u64 period, u64 quota)
if (period > max_cfs_quota_period)
return -EINVAL;
+ /*
+ * Bound quota to defend quota against overflow during bandwidth shift.
+ */
+ if (quota != RUNTIME_INF && quota > max_cfs_runtime)
+ return -EINVAL;
+
/*
* Prevent race between setting of cfs_rq->runtime_enabled and
* unthrottle_offline_cfs_rqs().
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 301ba04d9130..f31e0aaf1f43 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -2518,6 +2518,9 @@ static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
return ret;
}
+/* More than 203 days if BW_SHIFT equals 20. */
+static const u64 max_rt_runtime = MAX_BW_USEC * NSEC_PER_USEC;
+
static int tg_set_rt_bandwidth(struct task_group *tg,
u64 rt_period, u64 rt_runtime)
{
@@ -2534,6 +2537,12 @@ static int tg_set_rt_bandwidth(struct task_group *tg,
if (rt_period == 0)
return -EINVAL;
+ /*
+ * Bound quota to defend quota against overflow during bandwidth shift.
+ */
+ if (rt_runtime != RUNTIME_INF && rt_runtime > max_rt_runtime)
+ return -EINVAL;
+
mutex_lock(&rt_constraints_mutex);
read_lock(&tasklist_lock);
err = __rt_schedulable(tg, rt_period, rt_runtime);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index ae3068153093..f3808a49ce48 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1732,6 +1732,8 @@ extern void init_dl_rq_bw_ratio(struct dl_rq *dl_rq);
#define BW_SHIFT 20
#define BW_UNIT (1 << BW_SHIFT)
#define RATIO_SHIFT 8
+#define MAX_BW_BITS (64 - BW_SHIFT)
+#define MAX_BW_USEC ((1UL << MAX_BW_BITS) - 1)
unsigned long to_ratio(u64 period, u64 runtime);
extern void init_entity_runnable_average(struct sched_entity *se);
--
2.25.1
3
6

29 Jun '22
From: Zhou Guanghui <zhouguanghui1(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5EORS
CVE: NA
--------------------------------
The single-group mode has no application scenario. Therefore, the
related branch is deleted.
The boot option "enable_sp_multi_group_mode" does not take effect.
Signed-off-by: Zhou Guanghui <zhouguanghui1(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/share_pool.c | 137 +++++++++---------------------------------------
1 file changed, 25 insertions(+), 112 deletions(-)
diff --git a/mm/share_pool.c b/mm/share_pool.c
index 5ba353ddfabd..48e309e3ddd3 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -65,9 +65,6 @@
#define byte2mb(size) ((size) >> 20)
#define page2kb(page_num) ((page_num) << (PAGE_SHIFT - 10))
-#define SINGLE_GROUP_MODE 1
-#define MULTI_GROUP_MODE 2
-
#define MAX_GROUP_FOR_SYSTEM 50000
#define MAX_GROUP_FOR_TASK 3000
#define MAX_PROC_PER_GROUP 1024
@@ -98,8 +95,6 @@ int sysctl_sp_perf_alloc;
int sysctl_sp_perf_k2u;
-static int share_pool_group_mode = SINGLE_GROUP_MODE;
-
static int system_group_count;
static unsigned int sp_device_number;
@@ -1088,12 +1083,6 @@ static int mm_add_group_init(struct mm_struct *mm, struct sp_group *spg)
struct sp_group_master *master = mm->sp_group_master;
bool exist = false;
- if (share_pool_group_mode == SINGLE_GROUP_MODE && master &&
- master->count == 1) {
- pr_err_ratelimited("at most one sp group for a task is allowed in single mode\n");
- return -EEXIST;
- }
-
master = sp_init_group_master_locked(mm, &exist);
if (IS_ERR(master))
return PTR_ERR(master);
@@ -2235,72 +2224,30 @@ static int sp_alloc_prepare(unsigned long size, unsigned long sp_flags,
if (sp_flags & SP_HUGEPAGE_ONLY)
sp_flags |= SP_HUGEPAGE;
- if (share_pool_group_mode == SINGLE_GROUP_MODE) {
- spg = __sp_find_spg(current->pid, SPG_ID_DEFAULT);
- if (spg) {
- if (spg_id != SPG_ID_DEFAULT && spg->id != spg_id) {
- sp_group_drop(spg);
- return -ENODEV;
- }
-
- /* up_read will be at the end of sp_alloc */
- down_read(&spg->rw_lock);
- if (!spg_valid(spg)) {
- up_read(&spg->rw_lock);
- sp_group_drop(spg);
- pr_err_ratelimited("allocation failed, spg is dead\n");
- return -ENODEV;
- }
- } else { /* alocation pass through scene */
- if (enable_mdc_default_group) {
- int ret = 0;
-
- ret = sp_group_add_task(current->tgid, spg_id);
- if (ret < 0) {
- pr_err_ratelimited("add group failed in pass through\n");
- return ret;
- }
-
- spg = __sp_find_spg(current->pid, SPG_ID_DEFAULT);
-
- /* up_read will be at the end of sp_alloc */
- down_read(&spg->rw_lock);
- if (!spg_valid(spg)) {
- up_read(&spg->rw_lock);
- sp_group_drop(spg);
- pr_err_ratelimited("pass through allocation failed, spg is dead\n");
- return -ENODEV;
- }
- } else {
- spg = spg_none;
- }
+ if (spg_id != SPG_ID_DEFAULT) {
+ spg = __sp_find_spg(current->pid, spg_id);
+ if (!spg) {
+ pr_err_ratelimited("allocation failed, can't find group\n");
+ return -ENODEV;
}
- } else {
- if (spg_id != SPG_ID_DEFAULT) {
- spg = __sp_find_spg(current->pid, spg_id);
- if (!spg) {
- pr_err_ratelimited("allocation failed, can't find group\n");
- return -ENODEV;
- }
- /* up_read will be at the end of sp_alloc */
- down_read(&spg->rw_lock);
- if (!spg_valid(spg)) {
- up_read(&spg->rw_lock);
- sp_group_drop(spg);
- pr_err_ratelimited("allocation failed, spg is dead\n");
- return -ENODEV;
- }
+ /* up_read will be at the end of sp_alloc */
+ down_read(&spg->rw_lock);
+ if (!spg_valid(spg)) {
+ up_read(&spg->rw_lock);
+ sp_group_drop(spg);
+ pr_err_ratelimited("allocation failed, spg is dead\n");
+ return -ENODEV;
+ }
- if (!is_process_in_group(spg, current->mm)) {
- up_read(&spg->rw_lock);
- sp_group_drop(spg);
- pr_err_ratelimited("allocation failed, task not in group\n");
- return -ENODEV;
- }
- } else { /* alocation pass through scene */
- spg = spg_none;
+ if (!is_process_in_group(spg, current->mm)) {
+ up_read(&spg->rw_lock);
+ sp_group_drop(spg);
+ pr_err_ratelimited("allocation failed, task not in group\n");
+ return -ENODEV;
}
+ } else { /* alocation pass through scene */
+ spg = spg_none;
}
if (sp_flags & SP_HUGEPAGE) {
@@ -2914,33 +2861,12 @@ static int sp_k2u_prepare(unsigned long kva, unsigned long size,
kc->size_aligned = size_aligned;
kc->sp_flags = sp_flags;
kc->spg_id = spg_id;
- kc->to_task = false;
- return 0;
-}
-
-static int sp_check_k2task(struct sp_k2u_context *kc)
-{
- int ret = 0;
- int spg_id = kc->spg_id;
-
- if (share_pool_group_mode == SINGLE_GROUP_MODE) {
- struct sp_group *spg = get_first_group(current->mm);
+ if (spg_id == SPG_ID_DEFAULT || spg_id == SPG_ID_NONE)
+ kc->to_task = true;
+ else
+ kc->to_task = false;
- if (!spg) {
- if (spg_id != SPG_ID_NONE && spg_id != SPG_ID_DEFAULT)
- ret = -EINVAL;
- else
- kc->to_task = true;
- } else {
- if (spg_id != SPG_ID_DEFAULT && spg_id != spg->id)
- ret = -EINVAL;
- sp_group_drop(spg);
- }
- } else {
- if (spg_id == SPG_ID_DEFAULT || spg_id == SPG_ID_NONE)
- kc->to_task = true;
- }
- return ret;
+ return 0;
}
static void *sp_k2u_finish(void *uva, struct sp_k2u_context *kc)
@@ -2985,12 +2911,6 @@ void *sp_make_share_k2u(unsigned long kva, unsigned long size,
if (ret)
return ERR_PTR(ret);
- ret = sp_check_k2task(&kc);
- if (ret) {
- uva = ERR_PTR(ret);
- goto out;
- }
-
if (kc.to_task)
uva = sp_make_share_kva_to_task(kc.kva_aligned, kc.size_aligned, kc.sp_flags);
else {
@@ -3738,13 +3658,6 @@ static int __init enable_share_k2u_to_group(char *s)
}
__setup("enable_sp_share_k2u_spg", enable_share_k2u_to_group);
-static int __init enable_sp_multi_group_mode(char *s)
-{
- share_pool_group_mode = MULTI_GROUP_MODE;
- return 1;
-}
-__setup("enable_sp_multi_group_mode", enable_sp_multi_group_mode);
-
/*** Statistical and maintenance functions ***/
static void free_process_spg_proc_stat(struct sp_proc_stat *proc_stat)
--
2.25.1
1
13

[PATCH openEuler-22.03-LTS 1/2] ipmi/watchdog: replace atomic_add() and atomic_sub()
by Miaohe Lin 29 Jun '22
by Miaohe Lin 29 Jun '22
29 Jun '22
From: Yejune Deng <yejune.deng(a)gmail.com>
mainline inclusion
from v5.11-rc1
commit a01a89b1db1066a6af23ae08b9a0c345b7966f0b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5DVR9
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
atomic_inc() and atomic_dec() looks better
Signed-off-by: Yejune Deng <yejune.deng(a)gmail.com>
Message-Id: <1605511807-7135-1-git-send-email-yejune.deng(a)gmail.com>
Signed-off-by: Corey Minyard <cminyard(a)mvista.com>
Signed-off-by: Miaohe Lin <linmiaohe(a)huawei.com>
---
drivers/char/ipmi/ipmi_watchdog.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index f78156d93c3f..32c334e34d55 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -495,7 +495,7 @@ static void panic_halt_ipmi_heartbeat(void)
msg.cmd = IPMI_WDOG_RESET_TIMER;
msg.data = NULL;
msg.data_len = 0;
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = ipmi_request_supply_msgs(watchdog_user,
(struct ipmi_addr *) &addr,
0,
@@ -505,7 +505,7 @@ static void panic_halt_ipmi_heartbeat(void)
&panic_halt_heartbeat_recv_msg,
1);
if (rv)
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
}
static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -529,12 +529,12 @@ static void panic_halt_ipmi_set_timeout(void)
/* Wait for the messages to be free. */
while (atomic_read(&panic_done_count) != 0)
ipmi_poll_interface(watchdog_user);
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = __ipmi_set_timeout(&panic_halt_smi_msg,
&panic_halt_recv_msg,
&send_heartbeat_now);
if (rv) {
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
pr_warn("Unable to extend the watchdog timeout\n");
} else {
if (send_heartbeat_now)
--
2.23.0
1
1

[PATCH openEuler-5.10-LTS 1/8] net: hns3: set port base vlan tbl_sta to false before removing old vlan
by Zheng Zengkai 28 Jun '22
by Zheng Zengkai 28 Jun '22
28 Jun '22
From: Guangbin Huang <huangguangbin2(a)huawei.com>
mainline inclusion
from mainline-v5.19-rc1
commit 9eda7d8bcbdb
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5DGNU
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
----------------------------------------------------------------------
When modify port base vlan, the port base vlan tbl_sta needs to set to
false before removing old vlan, to indicate this operation is not finish.
Fixes: c0f46de30c96 ("net: hns3: fix port base vlan add fail when concurrent with reset")
Signed-off-by: Guangbin Huang <huangguangbin2(a)huawei.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Jiantao Xiao <xiaojiantao1(a)h-partners.com>
Reviewed-by: Jian Shen <shenjian15(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 3e0d8388ad3f..57aaa2f1536f 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -10117,6 +10117,7 @@ static int hclge_modify_port_base_vlan_tag(struct hclge_vport *vport,
if (ret)
return ret;
+ vport->port_base_vlan_cfg.tbl_sta = false;
/* remove old VLAN tag */
if (old_info->vlan_tag == 0)
ret = hclge_set_vf_vlan_common(hdev, vport->vport_id,
--
2.20.1
1
7

[PATCH OLK-5.10 v3 1/2] ipmi/watchdog: replace atomic_add() and atomic_sub()
by Miaohe Lin 28 Jun '22
by Miaohe Lin 28 Jun '22
28 Jun '22
From: Yejune Deng <yejune.deng(a)gmail.com>
mainline inclusion
from v5.11-rc1
commit a01a89b1db1066a6af23ae08b9a0c345b7966f0b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5DVR9
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
atomic_inc() and atomic_dec() looks better
Signed-off-by: Yejune Deng <yejune.deng(a)gmail.com>
Message-Id: <1605511807-7135-1-git-send-email-yejune.deng(a)gmail.com>
Signed-off-by: Corey Minyard <cminyard(a)mvista.com>
Signed-off-by: Miaohe Lin <linmiaohe(a)huawei.com>
---
drivers/char/ipmi/ipmi_watchdog.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index f78156d93c3f..32c334e34d55 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -495,7 +495,7 @@ static void panic_halt_ipmi_heartbeat(void)
msg.cmd = IPMI_WDOG_RESET_TIMER;
msg.data = NULL;
msg.data_len = 0;
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = ipmi_request_supply_msgs(watchdog_user,
(struct ipmi_addr *) &addr,
0,
@@ -505,7 +505,7 @@ static void panic_halt_ipmi_heartbeat(void)
&panic_halt_heartbeat_recv_msg,
1);
if (rv)
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
}
static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -529,12 +529,12 @@ static void panic_halt_ipmi_set_timeout(void)
/* Wait for the messages to be free. */
while (atomic_read(&panic_done_count) != 0)
ipmi_poll_interface(watchdog_user);
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = __ipmi_set_timeout(&panic_halt_smi_msg,
&panic_halt_recv_msg,
&send_heartbeat_now);
if (rv) {
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
pr_warn("Unable to extend the watchdog timeout\n");
} else {
if (send_heartbeat_now)
--
2.23.0
1
1

28 Jun '22
From: Daniel Thompson <daniel.thompson(a)linaro.org>
from stable-v5.10.119
commit a8f4d63142f947cd22fa615b8b3b8921cdaf4991
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5A5YP
CVE: CVE-2022-21499
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
commit eadb2f47a3ced5c64b23b90fd2a3463f63726066 upstream.
KGDB and KDB allow read and write access to kernel memory, and thus
should be restricted during lockdown. An attacker with access to a
serial port (for example, via a hypervisor console, which some cloud
vendors provide over the network) could trigger the debugger so it is
important that the debugger respect the lockdown mode when/if it is
triggered.
Fix this by integrating lockdown into kdb's existing permissions
mechanism. Unfortunately kgdb does not have any permissions mechanism
(although it certainly could be added later) so, for now, kgdb is simply
and brutally disabled by immediately exiting the gdb stub without taking
any action.
For lockdowns established early in the boot (e.g. the normal case) then
this should be fine but on systems where kgdb has set breakpoints before
the lockdown is enacted than "bad things" will happen.
CVE: CVE-2022-21499
Co-developed-by: Stephen Brennan <stephen.s.brennan(a)oracle.com>
Signed-off-by: Stephen Brennan <stephen.s.brennan(a)oracle.com>
Reviewed-by: Douglas Anderson <dianders(a)chromium.org>
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/linux/security.h | 2 ++
kernel/debug/debug_core.c | 24 ++++++++++++++
kernel/debug/kdb/kdb_main.c | 62 +++++++++++++++++++++++++++++++++++--
security/security.c | 2 ++
4 files changed, 87 insertions(+), 3 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
index 35355429648e..330029ef7e89 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -121,10 +121,12 @@ enum lockdown_reason {
LOCKDOWN_DEBUGFS,
LOCKDOWN_XMON_WR,
LOCKDOWN_BPF_WRITE_USER,
+ LOCKDOWN_DBG_WRITE_KERNEL,
LOCKDOWN_INTEGRITY_MAX,
LOCKDOWN_KCORE,
LOCKDOWN_KPROBES,
LOCKDOWN_BPF_READ,
+ LOCKDOWN_DBG_READ_KERNEL,
LOCKDOWN_PERF,
LOCKDOWN_TRACEFS,
LOCKDOWN_XMON_RW,
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index be5b6b97adbf..363f781b56ca 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -56,6 +56,7 @@
#include <linux/vmacache.h>
#include <linux/rcupdate.h>
#include <linux/irq.h>
+#include <linux/security.h>
#include <asm/cacheflush.h>
#include <asm/byteorder.h>
@@ -762,6 +763,29 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
continue;
kgdb_connected = 0;
} else {
+ /*
+ * This is a brutal way to interfere with the debugger
+ * and prevent gdb being used to poke at kernel memory.
+ * This could cause trouble if lockdown is applied when
+ * there is already an active gdb session. For now the
+ * answer is simply "don't do that". Typically lockdown
+ * *will* be applied before the debug core gets started
+ * so only developers using kgdb for fairly advanced
+ * early kernel debug can be biten by this. Hopefully
+ * they are sophisticated enough to take care of
+ * themselves, especially with help from the lockdown
+ * message printed on the console!
+ */
+ if (security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL)) {
+ if (IS_ENABLED(CONFIG_KGDB_KDB)) {
+ /* Switch back to kdb if possible... */
+ dbg_kdb_mode = 1;
+ continue;
+ } else {
+ /* ... otherwise just bail */
+ break;
+ }
+ }
error = gdb_serial_stub(ks);
}
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 930ac1b25ec7..4e09fab52faf 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -45,6 +45,7 @@
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include "kdb_private.h"
#undef MODULE_PARAM_PREFIX
@@ -197,10 +198,62 @@ struct task_struct *kdb_curr_task(int cpu)
}
/*
- * Check whether the flags of the current command and the permissions
- * of the kdb console has allow a command to be run.
+ * Update the permissions flags (kdb_cmd_enabled) to match the
+ * current lockdown state.
+ *
+ * Within this function the calls to security_locked_down() are "lazy". We
+ * avoid calling them if the current value of kdb_cmd_enabled already excludes
+ * flags that might be subject to lockdown. Additionally we deliberately check
+ * the lockdown flags independently (even though read lockdown implies write
+ * lockdown) since that results in both simpler code and clearer messages to
+ * the user on first-time debugger entry.
+ *
+ * The permission masks during a read+write lockdown permits the following
+ * flags: INSPECT, SIGNAL, REBOOT (and ALWAYS_SAFE).
+ *
+ * The INSPECT commands are not blocked during lockdown because they are
+ * not arbitrary memory reads. INSPECT covers the backtrace family (sometimes
+ * forcing them to have no arguments) and lsmod. These commands do expose
+ * some kernel state but do not allow the developer seated at the console to
+ * choose what state is reported. SIGNAL and REBOOT should not be controversial,
+ * given these are allowed for root during lockdown already.
+ */
+static void kdb_check_for_lockdown(void)
+{
+ const int write_flags = KDB_ENABLE_MEM_WRITE |
+ KDB_ENABLE_REG_WRITE |
+ KDB_ENABLE_FLOW_CTRL;
+ const int read_flags = KDB_ENABLE_MEM_READ |
+ KDB_ENABLE_REG_READ;
+
+ bool need_to_lockdown_write = false;
+ bool need_to_lockdown_read = false;
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | write_flags))
+ need_to_lockdown_write =
+ security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL);
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | read_flags))
+ need_to_lockdown_read =
+ security_locked_down(LOCKDOWN_DBG_READ_KERNEL);
+
+ /* De-compose KDB_ENABLE_ALL if required */
+ if (need_to_lockdown_write || need_to_lockdown_read)
+ if (kdb_cmd_enabled & KDB_ENABLE_ALL)
+ kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL;
+
+ if (need_to_lockdown_write)
+ kdb_cmd_enabled &= ~write_flags;
+
+ if (need_to_lockdown_read)
+ kdb_cmd_enabled &= ~read_flags;
+}
+
+/*
+ * Check whether the flags of the current command, the permissions of the kdb
+ * console and the lockdown state allow a command to be run.
*/
-static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,
+static bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,
bool no_args)
{
/* permissions comes from userspace so needs massaging slightly */
@@ -1194,6 +1247,9 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
kdb_curr_task(raw_smp_processor_id());
KDB_DEBUG_STATE("kdb_local 1", reason);
+
+ kdb_check_for_lockdown();
+
kdb_go_count = 0;
if (reason == KDB_REASON_DEBUG) {
/* special case below */
diff --git a/security/security.c b/security/security.c
index 4fb58543eeb9..2fc40217d49d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -59,10 +59,12 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
[LOCKDOWN_DEBUGFS] = "debugfs access",
[LOCKDOWN_XMON_WR] = "xmon write access",
[LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM",
+ [LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM",
[LOCKDOWN_INTEGRITY_MAX] = "integrity",
[LOCKDOWN_KCORE] = "/proc/kcore access",
[LOCKDOWN_KPROBES] = "use of kprobes",
[LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM",
+ [LOCKDOWN_DBG_READ_KERNEL] = "use of kgdb/kdb to read kernel RAM",
[LOCKDOWN_PERF] = "unsafe use of perf",
[LOCKDOWN_TRACEFS] = "use of tracefs",
[LOCKDOWN_XMON_RW] = "xmon read and write access",
--
2.20.1
1
4
Backport 5.10.109 LTS patches from upstream
nds32: fix access_ok() checks in get/put_user
wcn36xx: Differentiate wcn3660 from wcn3620
tpm: use try_get_ops() in tpm-space.c
mac80211: fix potential double free on mesh join
rcu: Don't deboost before reporting expedited quiescent state
Revert "ath: add support for special 0x0 regulatory domain"
crypto: qat - disable registration of algorithms
ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU
ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3
ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board
drivers: net: xgene: Fix regression in CRC stripping
ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
ALSA: cmipci: Restore aux vol on suspend/resume
ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB
ALSA: pcm: Add stream lock during PCM reset ioctl operations
ALSA: pcm: Fix races among concurrent prealloc proc writes
ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
ALSA: pcm: Fix races among concurrent read/write and buffer changes
ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
ALSA: hda/realtek: Add quirk for ASUS GA402
ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671
ALSA: hda/realtek: Add quirk for Clevo NP50PNJ
ALSA: hda/realtek: Add quirk for Clevo NP70PNJ
ALSA: usb-audio: add mapping for new Corsair Virtuoso SE
ALSA: oss: Fix PCM OSS buffer allocation overflow
ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call
staging: fbtft: fb_st7789v: reset display before initialization
tpm: Fix error handling in async work
cgroup-v1: Correct privileges check in release_agent writes
exfat: avoid incorrectly releasing for root inode
net: ipv6: fix skb_over_panic in __ip6_append_data
Already merged:
llc: only change llc->dev when bind() succeeds
netfilter: nf_tables: initialize registers in nft_do_chain()
llc: fix netdevice reference leaks in llc_ui_bind()
cgroup: Use open-time cgroup namespace for process migration perm checks
cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv
nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION
Total patches: 37 - 6 = 31
Arnd Bergmann (1):
nds32: fix access_ok() checks in get/put_user
Brian Norris (1):
Revert "ath: add support for special 0x0 regulatory domain"
Bryan O'Donoghue (1):
wcn36xx: Differentiate wcn3660 from wcn3620
Chen Li (1):
exfat: avoid incorrectly releasing for root inode
Giacomo Guiduzzi (1):
ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
Giovanni Cabiddu (1):
crypto: qat - disable registration of algorithms
James Bottomley (1):
tpm: use try_get_ops() in tpm-space.c
Jason Zheng (1):
ALSA: hda/realtek: Add quirk for ASUS GA402
Jonathan Teh (1):
ALSA: cmipci: Restore aux vol on suspend/resume
Lars-Peter Clausen (1):
ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB
Linus Lüssing (1):
mac80211: fix potential double free on mesh join
Mark Cilissen (1):
ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board
Maximilian Luz (1):
ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3
Michal Koutný (1):
cgroup-v1: Correct privileges check in release_agent writes
Oliver Graute (1):
staging: fbtft: fb_st7789v: reset display before initialization
Paul E. McKenney (1):
rcu: Don't deboost before reporting expedited quiescent state
Reza Jahanbakhshi (1):
ALSA: usb-audio: add mapping for new Corsair Virtuoso SE
Stephane Graber (1):
drivers: net: xgene: Fix regression in CRC stripping
Tadeusz Struk (2):
net: ipv6: fix skb_over_panic in __ip6_append_data
tpm: Fix error handling in async work
Takashi Iwai (7):
ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call
ALSA: oss: Fix PCM OSS buffer allocation overflow
ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
ALSA: pcm: Fix races among concurrent read/write and buffer changes
ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free
calls
ALSA: pcm: Fix races among concurrent prealloc proc writes
ALSA: pcm: Add stream lock during PCM reset ioctl operations
Tim Crawford (2):
ALSA: hda/realtek: Add quirk for Clevo NP70PNJ
ALSA: hda/realtek: Add quirk for Clevo NP50PNJ
Werner Sembach (1):
ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU
huangwenhui (1):
ALSA: hda/realtek - Fix headset mic problem for a HP machine with
alc671
arch/nds32/include/asm/uaccess.h | 22 ++++-
arch/x86/kernel/acpi/boot.c | 24 +++++
drivers/acpi/battery.c | 12 +++
drivers/acpi/video_detect.c | 75 ++++++++++++++
drivers/char/tpm/tpm-dev-common.c | 8 +-
drivers/char/tpm/tpm2-space.c | 8 +-
drivers/crypto/qat/qat_common/qat_crypto.c | 8 ++
.../net/ethernet/apm/xgene/xgene_enet_main.c | 12 ++-
drivers/net/wireless/ath/regd.c | 10 +-
drivers/net/wireless/ath/wcn36xx/main.c | 3 +
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
drivers/staging/fbtft/fb_st7789v.c | 2 +
fs/exfat/super.c | 2 +-
include/sound/pcm.h | 1 +
kernel/cgroup/cgroup-v1.c | 6 +-
kernel/rcu/tree_plugin.h | 9 +-
net/ipv6/ip6_output.c | 4 +-
net/mac80211/cfg.c | 3 -
sound/core/oss/pcm_oss.c | 12 ++-
sound/core/oss/pcm_plugin.c | 5 +-
sound/core/pcm.c | 2 +
sound/core/pcm_lib.c | 4 +
sound/core/pcm_memory.c | 11 ++-
sound/core/pcm_native.c | 97 ++++++++++++-------
sound/pci/ac97/ac97_codec.c | 4 +-
sound/pci/cmipci.c | 3 +-
sound/pci/hda/patch_realtek.c | 4 +
sound/soc/sti/uniperif_player.c | 6 +-
sound/soc/sti/uniperif_reader.c | 2 +-
sound/usb/mixer_maps.c | 10 ++
sound/usb/mixer_quirks.c | 7 +-
31 files changed, 289 insertions(+), 88 deletions(-)
--
2.20.1
1
31

[PATCH openEuler-1.0-LTS] io_uring: io_close: Set owner as current->files if req->work.files uninitialized
by Yongqiang Liu 28 Jun '22
by Yongqiang Liu 28 Jun '22
28 Jun '22
From: Zhihao Cheng <chengzhihao1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 186543, https://gitee.com/openeuler/kernel/issues/I5BGFA
CVE: NA
--------------------------------
Following process will trigger an use-after-free problem:
1. open /proc/sysvipc/msg and lock it by file lock
fcntl_setlk
do_lock_file_wait
vfs_lock_file
posix_lock_file
locks_insert_lock_ctx
locks_insert_global_locks // Added to lock list
2. Close /proc/sysvipc/msg by io_uring
filp_close(close->put_file, req->work.files) // req->work.files equals
NULL,io_grab_files() initialize it, non-async operations
won't invokes the function.
locks_remove_posix(filp, NULL)
lock.fl_owner = NULL
vfs_lock_file
posix_lock_file
posix_same_owner // Return false according to fl_owner.
locks_delete_lock_ctx(fl, &dispose) and locks_dispose_list
won't be executed, flock is not removed from lock list
fput(filp) // release filp
3. Read /proc/locks
seq_read
locks_start // Get flock from lock list
locks_show
lock_get_status
file_inode(f->file) // Access released file, UAF occurs!
Fix it by passing current->files when req->work.files is uninitialized,
because io-sq thread shares same files with uring_fd task, so it still
works in SQPOLL mode.
Signed-off-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/io_uring.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index c104425b2557..7ae8ba98e73b 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -3903,7 +3903,7 @@ static int io_close(struct io_kiocb *req, bool force_nonblock,
}
/* No ->flush() or already async, safely close from here */
- ret = filp_close(close->put_file, req->work.files);
+ ret = filp_close(close->put_file, req->work.files ? : current->files);
if (ret < 0)
req_set_fail_links(req);
fput(close->put_file);
--
2.25.1
1
0

[PATCH openEuler-5.10-LTS 1/5] lockdown: also lock down previous kgdb use
by Zheng Zengkai 27 Jun '22
by Zheng Zengkai 27 Jun '22
27 Jun '22
From: Daniel Thompson <daniel.thompson(a)linaro.org>
from stable-v5.10.119
commit a8f4d63142f947cd22fa615b8b3b8921cdaf4991
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5A5YP
CVE: CVE-2022-21499
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
commit eadb2f47a3ced5c64b23b90fd2a3463f63726066 upstream.
KGDB and KDB allow read and write access to kernel memory, and thus
should be restricted during lockdown. An attacker with access to a
serial port (for example, via a hypervisor console, which some cloud
vendors provide over the network) could trigger the debugger so it is
important that the debugger respect the lockdown mode when/if it is
triggered.
Fix this by integrating lockdown into kdb's existing permissions
mechanism. Unfortunately kgdb does not have any permissions mechanism
(although it certainly could be added later) so, for now, kgdb is simply
and brutally disabled by immediately exiting the gdb stub without taking
any action.
For lockdowns established early in the boot (e.g. the normal case) then
this should be fine but on systems where kgdb has set breakpoints before
the lockdown is enacted than "bad things" will happen.
CVE: CVE-2022-21499
Co-developed-by: Stephen Brennan <stephen.s.brennan(a)oracle.com>
Signed-off-by: Stephen Brennan <stephen.s.brennan(a)oracle.com>
Reviewed-by: Douglas Anderson <dianders(a)chromium.org>
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/linux/security.h | 2 ++
kernel/debug/debug_core.c | 24 ++++++++++++++
kernel/debug/kdb/kdb_main.c | 62 +++++++++++++++++++++++++++++++++++--
security/security.c | 2 ++
4 files changed, 87 insertions(+), 3 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
index 35355429648e..330029ef7e89 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -121,10 +121,12 @@ enum lockdown_reason {
LOCKDOWN_DEBUGFS,
LOCKDOWN_XMON_WR,
LOCKDOWN_BPF_WRITE_USER,
+ LOCKDOWN_DBG_WRITE_KERNEL,
LOCKDOWN_INTEGRITY_MAX,
LOCKDOWN_KCORE,
LOCKDOWN_KPROBES,
LOCKDOWN_BPF_READ,
+ LOCKDOWN_DBG_READ_KERNEL,
LOCKDOWN_PERF,
LOCKDOWN_TRACEFS,
LOCKDOWN_XMON_RW,
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index be5b6b97adbf..363f781b56ca 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -56,6 +56,7 @@
#include <linux/vmacache.h>
#include <linux/rcupdate.h>
#include <linux/irq.h>
+#include <linux/security.h>
#include <asm/cacheflush.h>
#include <asm/byteorder.h>
@@ -762,6 +763,29 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
continue;
kgdb_connected = 0;
} else {
+ /*
+ * This is a brutal way to interfere with the debugger
+ * and prevent gdb being used to poke at kernel memory.
+ * This could cause trouble if lockdown is applied when
+ * there is already an active gdb session. For now the
+ * answer is simply "don't do that". Typically lockdown
+ * *will* be applied before the debug core gets started
+ * so only developers using kgdb for fairly advanced
+ * early kernel debug can be biten by this. Hopefully
+ * they are sophisticated enough to take care of
+ * themselves, especially with help from the lockdown
+ * message printed on the console!
+ */
+ if (security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL)) {
+ if (IS_ENABLED(CONFIG_KGDB_KDB)) {
+ /* Switch back to kdb if possible... */
+ dbg_kdb_mode = 1;
+ continue;
+ } else {
+ /* ... otherwise just bail */
+ break;
+ }
+ }
error = gdb_serial_stub(ks);
}
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 930ac1b25ec7..4e09fab52faf 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -45,6 +45,7 @@
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include "kdb_private.h"
#undef MODULE_PARAM_PREFIX
@@ -197,10 +198,62 @@ struct task_struct *kdb_curr_task(int cpu)
}
/*
- * Check whether the flags of the current command and the permissions
- * of the kdb console has allow a command to be run.
+ * Update the permissions flags (kdb_cmd_enabled) to match the
+ * current lockdown state.
+ *
+ * Within this function the calls to security_locked_down() are "lazy". We
+ * avoid calling them if the current value of kdb_cmd_enabled already excludes
+ * flags that might be subject to lockdown. Additionally we deliberately check
+ * the lockdown flags independently (even though read lockdown implies write
+ * lockdown) since that results in both simpler code and clearer messages to
+ * the user on first-time debugger entry.
+ *
+ * The permission masks during a read+write lockdown permits the following
+ * flags: INSPECT, SIGNAL, REBOOT (and ALWAYS_SAFE).
+ *
+ * The INSPECT commands are not blocked during lockdown because they are
+ * not arbitrary memory reads. INSPECT covers the backtrace family (sometimes
+ * forcing them to have no arguments) and lsmod. These commands do expose
+ * some kernel state but do not allow the developer seated at the console to
+ * choose what state is reported. SIGNAL and REBOOT should not be controversial,
+ * given these are allowed for root during lockdown already.
+ */
+static void kdb_check_for_lockdown(void)
+{
+ const int write_flags = KDB_ENABLE_MEM_WRITE |
+ KDB_ENABLE_REG_WRITE |
+ KDB_ENABLE_FLOW_CTRL;
+ const int read_flags = KDB_ENABLE_MEM_READ |
+ KDB_ENABLE_REG_READ;
+
+ bool need_to_lockdown_write = false;
+ bool need_to_lockdown_read = false;
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | write_flags))
+ need_to_lockdown_write =
+ security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL);
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | read_flags))
+ need_to_lockdown_read =
+ security_locked_down(LOCKDOWN_DBG_READ_KERNEL);
+
+ /* De-compose KDB_ENABLE_ALL if required */
+ if (need_to_lockdown_write || need_to_lockdown_read)
+ if (kdb_cmd_enabled & KDB_ENABLE_ALL)
+ kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL;
+
+ if (need_to_lockdown_write)
+ kdb_cmd_enabled &= ~write_flags;
+
+ if (need_to_lockdown_read)
+ kdb_cmd_enabled &= ~read_flags;
+}
+
+/*
+ * Check whether the flags of the current command, the permissions of the kdb
+ * console and the lockdown state allow a command to be run.
*/
-static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,
+static bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,
bool no_args)
{
/* permissions comes from userspace so needs massaging slightly */
@@ -1194,6 +1247,9 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
kdb_curr_task(raw_smp_processor_id());
KDB_DEBUG_STATE("kdb_local 1", reason);
+
+ kdb_check_for_lockdown();
+
kdb_go_count = 0;
if (reason == KDB_REASON_DEBUG) {
/* special case below */
diff --git a/security/security.c b/security/security.c
index 4fb58543eeb9..2fc40217d49d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -59,10 +59,12 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
[LOCKDOWN_DEBUGFS] = "debugfs access",
[LOCKDOWN_XMON_WR] = "xmon write access",
[LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM",
+ [LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM",
[LOCKDOWN_INTEGRITY_MAX] = "integrity",
[LOCKDOWN_KCORE] = "/proc/kcore access",
[LOCKDOWN_KPROBES] = "use of kprobes",
[LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM",
+ [LOCKDOWN_DBG_READ_KERNEL] = "use of kgdb/kdb to read kernel RAM",
[LOCKDOWN_PERF] = "unsafe use of perf",
[LOCKDOWN_TRACEFS] = "use of tracefs",
[LOCKDOWN_XMON_RW] = "xmon read and write access",
--
2.20.1
1
4
Backport 5.10.109 LTS patches from upstream
nds32: fix access_ok() checks in get/put_user
wcn36xx: Differentiate wcn3660 from wcn3620
tpm: use try_get_ops() in tpm-space.c
mac80211: fix potential double free on mesh join
rcu: Don't deboost before reporting expedited quiescent state
Revert "ath: add support for special 0x0 regulatory domain"
crypto: qat - disable registration of algorithms
ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU
ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3
ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board
drivers: net: xgene: Fix regression in CRC stripping
ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
ALSA: cmipci: Restore aux vol on suspend/resume
ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB
ALSA: pcm: Add stream lock during PCM reset ioctl operations
ALSA: pcm: Fix races among concurrent prealloc proc writes
ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
ALSA: pcm: Fix races among concurrent read/write and buffer changes
ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
ALSA: hda/realtek: Add quirk for ASUS GA402
ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671
ALSA: hda/realtek: Add quirk for Clevo NP50PNJ
ALSA: hda/realtek: Add quirk for Clevo NP70PNJ
ALSA: usb-audio: add mapping for new Corsair Virtuoso SE
ALSA: oss: Fix PCM OSS buffer allocation overflow
ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call
staging: fbtft: fb_st7789v: reset display before initialization
tpm: Fix error handling in async work
cgroup-v1: Correct privileges check in release_agent writes
exfat: avoid incorrectly releasing for root inode
net: ipv6: fix skb_over_panic in __ip6_append_data
Already merged:
llc: only change llc->dev when bind() succeeds
netfilter: nf_tables: initialize registers in nft_do_chain()
llc: fix netdevice reference leaks in llc_ui_bind()
cgroup: Use open-time cgroup namespace for process migration perm checks
cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv
nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION
Total patches: 37 - 6 = 31
Arnd Bergmann (1):
nds32: fix access_ok() checks in get/put_user
Brian Norris (1):
Revert "ath: add support for special 0x0 regulatory domain"
Bryan O'Donoghue (1):
wcn36xx: Differentiate wcn3660 from wcn3620
Chen Li (1):
exfat: avoid incorrectly releasing for root inode
Giacomo Guiduzzi (1):
ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
Giovanni Cabiddu (1):
crypto: qat - disable registration of algorithms
James Bottomley (1):
tpm: use try_get_ops() in tpm-space.c
Jason Zheng (1):
ALSA: hda/realtek: Add quirk for ASUS GA402
Jonathan Teh (1):
ALSA: cmipci: Restore aux vol on suspend/resume
Lars-Peter Clausen (1):
ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB
Linus Lüssing (1):
mac80211: fix potential double free on mesh join
Mark Cilissen (1):
ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board
Maximilian Luz (1):
ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3
Michal Koutný (1):
cgroup-v1: Correct privileges check in release_agent writes
Oliver Graute (1):
staging: fbtft: fb_st7789v: reset display before initialization
Paul E. McKenney (1):
rcu: Don't deboost before reporting expedited quiescent state
Reza Jahanbakhshi (1):
ALSA: usb-audio: add mapping for new Corsair Virtuoso SE
Stephane Graber (1):
drivers: net: xgene: Fix regression in CRC stripping
Tadeusz Struk (2):
net: ipv6: fix skb_over_panic in __ip6_append_data
tpm: Fix error handling in async work
Takashi Iwai (7):
ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call
ALSA: oss: Fix PCM OSS buffer allocation overflow
ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
ALSA: pcm: Fix races among concurrent read/write and buffer changes
ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free
calls
ALSA: pcm: Fix races among concurrent prealloc proc writes
ALSA: pcm: Add stream lock during PCM reset ioctl operations
Tim Crawford (2):
ALSA: hda/realtek: Add quirk for Clevo NP70PNJ
ALSA: hda/realtek: Add quirk for Clevo NP50PNJ
Werner Sembach (1):
ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU
huangwenhui (1):
ALSA: hda/realtek - Fix headset mic problem for a HP machine with
alc671
arch/nds32/include/asm/uaccess.h | 22 ++++-
arch/x86/kernel/acpi/boot.c | 24 +++++
drivers/acpi/battery.c | 12 +++
drivers/acpi/video_detect.c | 75 ++++++++++++++
drivers/char/tpm/tpm-dev-common.c | 8 +-
drivers/char/tpm/tpm2-space.c | 8 +-
drivers/crypto/qat/qat_common/qat_crypto.c | 8 ++
.../net/ethernet/apm/xgene/xgene_enet_main.c | 12 ++-
drivers/net/wireless/ath/regd.c | 10 +-
drivers/net/wireless/ath/wcn36xx/main.c | 3 +
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
drivers/staging/fbtft/fb_st7789v.c | 2 +
fs/exfat/super.c | 2 +-
include/sound/pcm.h | 1 +
kernel/cgroup/cgroup-v1.c | 6 +-
kernel/rcu/tree_plugin.h | 9 +-
net/ipv6/ip6_output.c | 4 +-
net/mac80211/cfg.c | 3 -
sound/core/oss/pcm_oss.c | 12 ++-
sound/core/oss/pcm_plugin.c | 5 +-
sound/core/pcm.c | 2 +
sound/core/pcm_lib.c | 4 +
sound/core/pcm_memory.c | 11 ++-
sound/core/pcm_native.c | 97 ++++++++++++-------
sound/pci/ac97/ac97_codec.c | 4 +-
sound/pci/cmipci.c | 3 +-
sound/pci/hda/patch_realtek.c | 4 +
sound/soc/sti/uniperif_player.c | 6 +-
sound/soc/sti/uniperif_reader.c | 2 +-
sound/usb/mixer_maps.c | 10 ++
sound/usb/mixer_quirks.c | 7 +-
31 files changed, 289 insertions(+), 88 deletions(-)
--
2.20.1
1
31

[PATCH openEuler-1.0-LTS] mm/memcontrol: fix wrong vmstats for dying memcg
by Yongqiang Liu 27 Jun '22
by Yongqiang Liu 27 Jun '22
27 Jun '22
From: Lu Jialin <lujialin4(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5E8LA
CVE: NA
--------------------------------
At present, only when the absolute value of stat_cpu->count exceeds
MEMCG_CHARGE_BATCH will it be updated to stat, so there will always
be a certain lag difference between stat and the correct value.
In addition, since the partially deleted memcg is still referenced, it
will not be freed immediately after it is offline. Although the
remaining memcg has released the page, it and the parent's stat will
still be not 0 or too large due to the update lag, which leads to the
abnormality of the total_<count> parameter in the memory.stat file.
This patch mainly solves the problem of synchronization between
memcg's stat and the correct value during the destruction process
from two aspects:
1) Perform a flush synchronization operation when memcg is offline
2) For memcg in the process of being destroyed, bypass the threshold
judgment when updating vmstats
Signed-off-by: Lu Jialin <lujialin4(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/memcontrol.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 2983baf910f4..345a9d159ad8 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -697,7 +697,8 @@ void __mod_memcg_state(struct mem_cgroup *memcg, int idx, int val)
return;
x = val + __this_cpu_read(memcg->stat_cpu->count[idx]);
- if (unlikely(abs(x) > MEMCG_CHARGE_BATCH)) {
+ if (unlikely(abs(x) > MEMCG_CHARGE_BATCH ||
+ memcg->css.flags & CSS_DYING)) {
struct mem_cgroup *mi;
struct mem_cgroup_extension *memcg_ext;
@@ -3244,8 +3245,10 @@ static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg)
stat[i] = 0;
for_each_online_cpu(cpu)
- for (i = 0; i < MEMCG_NR_STAT; i++)
+ for (i = 0; i < MEMCG_NR_STAT; i++) {
stat[i] += per_cpu(memcg->stat_cpu->count[i], cpu);
+ per_cpu(memcg->stat_cpu->count[i], cpu) = 0;
+ }
for (mi = memcg; mi; mi = parent_mem_cgroup(mi))
for (i = 0; i < MEMCG_NR_STAT; i++)
@@ -3259,9 +3262,11 @@ static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg)
stat[i] = 0;
for_each_online_cpu(cpu)
- for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
+ for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) {
stat[i] += per_cpu(
pn->lruvec_stat_cpu->count[i], cpu);
+ per_cpu(pn->lruvec_stat_cpu->count[i], cpu) = 0;
+ }
for (pi = pn; pi; pi = parent_nodeinfo(pi, node))
for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
@@ -3279,9 +3284,11 @@ static void memcg_flush_percpu_vmevents(struct mem_cgroup *memcg)
events[i] = 0;
for_each_online_cpu(cpu)
- for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
+ for (i = 0; i < NR_VM_EVENT_ITEMS; i++) {
events[i] += per_cpu(memcg->stat_cpu->events[i],
cpu);
+ per_cpu(memcg->stat_cpu->events[i], cpu) = 0;
+ }
for (mi = memcg; mi; mi = parent_mem_cgroup(mi))
for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
@@ -5106,6 +5113,9 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
memcg_offline_kmem(memcg);
wb_memcg_offline(memcg);
+ memcg_flush_percpu_vmstats(memcg);
+ memcg_flush_percpu_vmevents(memcg);
+
mem_cgroup_id_put(memcg);
}
--
2.25.1
1
0
大家好,
本次Intel Arch例会定于本周二6/28 10:00-11:00AM进行, 欢迎大家提出更多需求或议题和参与讨论。
本次初步议题:
Agenda:
*Status update
*SPR feature PRs merge into intel-kernel & OLK-5.10 kernel *Compiler support for new instructions *Support 22.09 release for SPR fundamental features
-----Original Appointment-----
From: openEuler conference <public(a)openeuler.org>
Sent: Monday, June 20, 2022 3:10 PM
To: openEuler conference; jun.j.tian@intel.com,kai.liu@suse.com
Subject: sig-Intel-Arch
When: Tuesday, June 28, 2022 10:00 AM-11:00 AM (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi.
Where:
您好!
sig-Intel-Arch SIG 邀请您参加 2022-06-28 10:00 召开的Zoom会议
会议主题:sig-Intel-Arch
会议链接:https://us06web.zoom.us/j/81976528831?pwd=cVIxUkRhUXFGcldFV0ZtNkpvUFpxZz09
会议纪要:https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler sig-Intel-Arch SIG invites you to attend the Zoom conference will be held at 2022-06-28 10:00,
The subject of the conference is sig-Intel-Arch,
You can join the meeting at https://us06web.zoom.us/j/81976528831?pwd=cVIxUkRhUXFGcldFV0ZtNkpvUFpxZz09.
Add topics at https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0

[PATCH openEuler-1.0-LTS] ext4: recover csum seed of tmp_inode after migrating to extents
by Yongqiang Liu 25 Jun '22
by Yongqiang Liu 25 Jun '22
25 Jun '22
From: Li Lingfeng <lilingfeng3(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 186944, https://gitee.com/openeuler/kernel/issues/I5DAJY
CVE: NA
--------------------------------
When migrating to extents, the checksum seed of temporary inode
need to be replaced by inode's, otherwise the inode checksums
will be incorrect when swapping the inodes data.
However, the temporary inode can not match it's checksum to
itself since it has lost it's own checksum seed.
mkfs.ext4 -F /dev/sdc
mount /dev/sdc /mnt/sdc
xfs_io -fc "pwrite 4k 4k" -c "fsync" /mnt/sdc/testfile
chattr -e /mnt/sdc/testfile
chattr +e /mnt/sdc/testfile
fsck -fn /dev/sdc
========
...
Pass 1: Checking inodes, blocks, and sizes
Inode 13 passes checks, but checksum does not match inode. Fix? no
...
========
The fix is simple, save the checksum seed of temporary inode, and
recover it after migrating to extents.
Fixes: e81c9302a6c3 ("ext4: set csum seed in tmp inode while migrating to extents")
Signed-off-by: Li Lingfeng <lilingfeng3(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/ext4/migrate.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 75a769634b2b..ed9e7816efbb 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -415,7 +415,7 @@ int ext4_ext_migrate(struct inode *inode)
struct inode *tmp_inode = NULL;
struct migrate_struct lb;
unsigned long max_entries;
- __u32 goal;
+ __u32 goal, tmp_csum_seed;
uid_t owner[2];
/*
@@ -463,6 +463,7 @@ int ext4_ext_migrate(struct inode *inode)
* the migration.
*/
ei = EXT4_I(inode);
+ tmp_csum_seed = EXT4_I(tmp_inode)->i_csum_seed;
EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed;
i_size_write(tmp_inode, i_size_read(inode));
/*
@@ -573,6 +574,7 @@ int ext4_ext_migrate(struct inode *inode)
* the inode is not visible to user space.
*/
tmp_inode->i_blocks = 0;
+ EXT4_I(tmp_inode)->i_csum_seed = tmp_csum_seed;
/* Reset the extent details */
ext4_ext_tree_init(handle, tmp_inode);
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS] vfio: framework supporting vfio device hot migration
by RongWang 24 Jun '22
by RongWang 24 Jun '22
24 Jun '22
From: Rong Wang <w_angrong(a)163.com>
kunpeng inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5CO9A
CVE: NA
---------------------------------
As pass through devices, hypervisor can`t control the status of
device, and can`t track dirty memory DMA from device, during
migration.
The goal of this framework is to combine hardware to accomplish
the task above.
qemu
|status control and dirty memory report
vfio
|ops to hardware
hardware
Signed-off-by: Rong Wang <w_angrong(a)163.com>
Signed-off-by: HuHua Li <18245010845(a)163.com>
Signed-off-by: Ripeng Qiu <965412048(a)qq.com>
---
drivers/vfio/pci/Makefile | 2 +-
drivers/vfio/pci/vfio_pci.c | 54 +++
drivers/vfio/pci/vfio_pci_migration.c | 755 ++++++++++++++++++++++++++++++++++
drivers/vfio/pci/vfio_pci_private.h | 14 +-
drivers/vfio/vfio.c | 411 +++++++++++++++++-
include/linux/vfio_pci_migration.h | 136 ++++++
6 files changed, 1367 insertions(+), 5 deletions(-)
create mode 100644 drivers/vfio/pci/vfio_pci_migration.c
create mode 100644 include/linux/vfio_pci_migration.h
diff --git a/drivers/vfio/pci/Makefile b/drivers/vfio/pci/Makefile
index 76d8ec0..80a777d 100644
--- a/drivers/vfio/pci/Makefile
+++ b/drivers/vfio/pci/Makefile
@@ -1,5 +1,5 @@
-vfio-pci-y := vfio_pci.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o
+vfio-pci-y := vfio_pci.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o vfio_pci_migration.o
vfio-pci-$(CONFIG_VFIO_PCI_IGD) += vfio_pci_igd.o
obj-$(CONFIG_VFIO_PCI) += vfio-pci.o
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 51b791c..59d8280 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -30,6 +30,7 @@
#include <linux/vgaarb.h>
#include <linux/nospec.h>
#include <linux/sched/mm.h>
+#include <linux/vfio_pci_migration.h>
#include "vfio_pci_private.h"
@@ -296,6 +297,14 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
vfio_pci_probe_mmaps(vdev);
+ if (vfio_dev_migration_is_supported(pdev)) {
+ ret = vfio_pci_migration_init(vdev);
+ if (ret) {
+ dev_warn(&vdev->pdev->dev, "Failed to init vfio_pci_migration\n");
+ vfio_pci_disable(vdev);
+ return ret;
+ }
+ }
return 0;
}
@@ -392,6 +401,7 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
out:
pci_disable_device(pdev);
+ vfio_pci_migration_exit(vdev);
vfio_pci_try_bus_reset(vdev);
if (!disable_idle_d3)
@@ -642,6 +652,41 @@ struct vfio_devices {
int max_index;
};
+static long vfio_pci_handle_log_buf_ctl(struct vfio_pci_device *vdev,
+ const unsigned long arg)
+{
+ struct vfio_log_buf_ctl *log_buf_ctl = NULL;
+ struct vfio_log_buf_info *log_buf_info = NULL;
+ struct vf_migration_log_info migration_log_info;
+ long ret = 0;
+
+ log_buf_ctl = (struct vfio_log_buf_ctl *)arg;
+ log_buf_info = (struct vfio_log_buf_info *)log_buf_ctl->data;
+
+ switch (log_buf_ctl->flags) {
+ case VFIO_DEVICE_LOG_BUF_FLAG_START:
+ migration_log_info.dom_uuid = log_buf_info->uuid;
+ migration_log_info.buffer_size =
+ log_buf_info->buffer_size;
+ migration_log_info.sge_num = log_buf_info->addrs_size;
+ migration_log_info.sge_len = log_buf_info->frag_size;
+ migration_log_info.sgevec = log_buf_info->sgevec;
+ ret = vfio_pci_device_log_start(vdev,
+ &migration_log_info);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STOP:
+ ret = vfio_pci_device_log_stop(vdev,
+ log_buf_info->uuid);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY:
+ ret = vfio_pci_device_log_status_query(vdev);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
static long vfio_pci_ioctl(void *device_data,
unsigned int cmd, unsigned long arg)
{
@@ -1142,6 +1187,8 @@ static long vfio_pci_ioctl(void *device_data,
return vfio_pci_ioeventfd(vdev, ioeventfd.offset,
ioeventfd.data, count, ioeventfd.fd);
+ } else if (cmd == VFIO_DEVICE_LOG_BUF_CTL) {
+ return vfio_pci_handle_log_buf_ctl(vdev, arg);
}
return -ENOTTY;
@@ -1566,6 +1613,9 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_power_state(pdev, PCI_D3hot);
}
+ if (vfio_dev_migration_is_supported(pdev))
+ ret = vfio_pci_device_init(pdev);
+
return ret;
}
@@ -1591,6 +1641,10 @@ static void vfio_pci_remove(struct pci_dev *pdev)
if (!disable_idle_d3)
pci_set_power_state(pdev, PCI_D0);
+
+ if (vfio_dev_migration_is_supported(pdev)) {
+ vfio_pci_device_uninit(pdev);
+ }
}
static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
diff --git a/drivers/vfio/pci/vfio_pci_migration.c b/drivers/vfio/pci/vfio_pci_migration.c
new file mode 100644
index 0000000..f69cd13
--- /dev/null
+++ b/drivers/vfio/pci/vfio_pci_migration.c
@@ -0,0 +1,755 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/uaccess.h>
+#include <linux/vfio.h>
+#include <linux/vfio_pci_migration.h>
+
+#include "vfio_pci_private.h"
+
+static LIST_HEAD(vfio_pci_mig_drivers_list);
+static DEFINE_MUTEX(vfio_pci_mig_drivers_mutex);
+
+static void vfio_pci_add_mig_drv(struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ atomic_set(&mig_drv->count, 1);
+ list_add_tail(&mig_drv->list, &vfio_pci_mig_drivers_list);
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+}
+
+static void vfio_pci_remove_mig_drv(struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_del(&mig_drv->list);
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+}
+
+static struct vfio_pci_vendor_mig_driver *
+ vfio_pci_find_mig_drv(struct pci_dev *pdev, struct module *module)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = NULL;
+
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_for_each_entry(mig_drv, &vfio_pci_mig_drivers_list, list) {
+ if (mig_drv->owner == module) {
+ if (mig_drv->bus_num == pdev->bus->number)
+ goto out;
+ }
+ }
+ mig_drv = NULL;
+out:
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+ return mig_drv;
+}
+
+static struct vfio_pci_vendor_mig_driver *
+ vfio_pci_get_mig_driver(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = NULL;
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_for_each_entry(mig_drv, &vfio_pci_mig_drivers_list, list) {
+ if (mig_drv->bus_num == pf_dev->bus->number)
+ goto out;
+ }
+ mig_drv = NULL;
+out:
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+ return mig_drv;
+}
+
+bool vfio_dev_migration_is_supported(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ mig_driver = vfio_pci_get_mig_driver(pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_warn(&pdev->dev, "unable to find a mig_drv module\n");
+ return false;
+ }
+
+ return true;
+}
+
+int vfio_pci_device_log_start(struct vfio_pci_device *vdev,
+ struct vf_migration_log_info *log_info)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->log_start ||
+ (mig_driver->dev_mig_ops->log_start(vdev->pdev,
+ log_info) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to set log start\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_log_stop(struct vfio_pci_device *vdev, uint32_t uuid)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->log_stop ||
+ (mig_driver->dev_mig_ops->log_stop(vdev->pdev, uuid) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to set log stop\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_log_status_query(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->get_log_status ||
+ (mig_driver->dev_mig_ops->get_log_status(vdev->pdev) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to get log status\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_init(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv;
+
+ mig_drv = vfio_pci_get_mig_driver(pdev);
+ if (!mig_drv || !mig_drv->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (mig_drv->dev_mig_ops->init)
+ return mig_drv->dev_mig_ops->init(pdev);
+
+ return -EFAULT;
+}
+
+void vfio_pci_device_uninit(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv;
+
+ mig_drv = vfio_pci_get_mig_driver(pdev);
+ if (!mig_drv || !mig_drv->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_drv module\n");
+ return;
+ }
+
+ if (mig_drv->dev_mig_ops->uninit)
+ mig_drv->dev_mig_ops->uninit(pdev);
+}
+
+static void vfio_pci_device_release(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (mig_drv->dev_mig_ops->release)
+ mig_drv->dev_mig_ops->release(pdev);
+}
+
+static int vfio_pci_device_get_info(struct pci_dev *pdev,
+ struct vfio_device_migration_info *mig_info,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (mig_drv->dev_mig_ops->get_info)
+ return mig_drv->dev_mig_ops->get_info(pdev, mig_info);
+ return -EFAULT;
+}
+
+static int vfio_pci_device_enable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->enable ||
+ (mig_drv->dev_mig_ops->enable(pdev) != 0)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vfio_pci_device_disable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->disable ||
+ (mig_drv->dev_mig_ops->disable(pdev) != 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vfio_pci_device_pre_enable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->pre_enable ||
+ (mig_drv->dev_mig_ops->pre_enable(pdev) != 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vfio_pci_device_state_save(struct pci_dev *pdev,
+ struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_info = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ void *base = (void *)mig_info;
+ int ret = 0;
+
+ if ((mig_info->device_state & VFIO_DEVICE_STATE_RUNNING) != 0) {
+ ret = vfio_pci_device_disable(pdev, mig_drv);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to stop VF function!\n");
+ return ret;
+ }
+ mig_info->device_state &= ~VFIO_DEVICE_STATE_RUNNING;
+ }
+
+ if (mig_drv->dev_mig_ops && mig_drv->dev_mig_ops->save) {
+ ret = mig_drv->dev_mig_ops->save(pdev, base,
+ mig_info->data_offset, data->state_size);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to save device state!\n");
+ return -EINVAL;
+ }
+ } else {
+ return -EFAULT;
+ }
+
+ mig_info->data_size = data->state_size;
+ mig_info->pending_bytes = mig_info->data_size;
+ return ret;
+}
+
+static int vfio_pci_device_state_restore(struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_info = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ void *base = (void *)mig_info;
+ int ret;
+
+ if (mig_drv->dev_mig_ops && mig_drv->dev_mig_ops->restore) {
+ ret = mig_drv->dev_mig_ops->restore(pdev, base,
+ mig_info->data_offset, mig_info->data_size);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to restore device state!\n");
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ return -EFAULT;
+}
+
+static int vfio_pci_set_device_state(struct vfio_pci_migration_data *data,
+ u32 state)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ int ret = 0;
+
+ if (state == mig_ctl->device_state)
+ return 0;
+
+ if (!mig_drv->dev_mig_ops)
+ return -EINVAL;
+
+ switch (state) {
+ case VFIO_DEVICE_STATE_RUNNING:
+ if (!(mig_ctl->device_state &
+ VFIO_DEVICE_STATE_RUNNING))
+ ret = vfio_pci_device_enable(pdev, mig_drv);
+ break;
+ case VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RUNNING:
+ /*
+ * (pre-copy) - device should start logging data.
+ */
+ ret = 0;
+ break;
+ case VFIO_DEVICE_STATE_SAVING:
+ /* stop the vf function, save state */
+ ret = vfio_pci_device_state_save(pdev, data);
+ break;
+ case VFIO_DEVICE_STATE_STOP:
+ if (mig_ctl->device_state & VFIO_DEVICE_STATE_RUNNING)
+ ret = vfio_pci_device_disable(pdev, mig_drv);
+ break;
+ case VFIO_DEVICE_STATE_RESUMING:
+ ret = vfio_pci_device_pre_enable(pdev, mig_drv);
+ break;
+ default:
+ ret = -EFAULT;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
+ mig_ctl->device_state = state;
+ return 0;
+}
+
+static ssize_t vfio_pci_handle_mig_dev_state(
+ struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, bool iswrite)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ u32 device_state;
+ int ret;
+
+ if (count != sizeof(device_state))
+ return -EINVAL;
+
+ if (iswrite) {
+ if (copy_from_user(&device_state, buf, count))
+ return -EFAULT;
+
+ ret = vfio_pci_set_device_state(data, device_state);
+ if (ret)
+ return ret;
+ } else {
+ if (copy_to_user(buf, &mig_ctl->device_state, count))
+ return -EFAULT;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_pending_bytes(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 pending_bytes;
+
+ if (count != sizeof(pending_bytes) || iswrite)
+ return -EINVAL;
+
+ if (mig_info->device_state ==
+ (VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RUNNING)) {
+ /* In pre-copy state we have no data to return for now,
+ * return 0 pending bytes
+ */
+ pending_bytes = 0;
+ } else {
+ pending_bytes = mig_info->pending_bytes;
+ }
+
+ if (copy_to_user(buf, &pending_bytes, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_offset(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 data_offset = mig_info->data_offset;
+
+ if (count != sizeof(data_offset) || iswrite)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &data_offset, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_size(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 data_size;
+
+ if (count != sizeof(data_size))
+ return -EINVAL;
+
+ if (iswrite) {
+ /* data_size is writable only during resuming state */
+ if (mig_info->device_state != VFIO_DEVICE_STATE_RESUMING)
+ return -EINVAL;
+
+ if (copy_from_user(&data_size, buf, sizeof(data_size)))
+ return -EFAULT;
+
+ mig_info->data_size = data_size;
+ } else {
+ if (mig_info->device_state != VFIO_DEVICE_STATE_SAVING)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &mig_info->data_size,
+ sizeof(data_size)))
+ return -EFAULT;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_dev_cmd(struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, bool iswrite)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ u32 device_cmd;
+ int ret = -EFAULT;
+
+ if (count != sizeof(device_cmd) || !iswrite || !mig_drv->dev_mig_ops)
+ return -EINVAL;
+
+ if (copy_from_user(&device_cmd, buf, count))
+ return -EFAULT;
+
+ switch (device_cmd) {
+ case VFIO_DEVICE_MIGRATION_CANCEL:
+ if (mig_drv->dev_mig_ops->cancel)
+ ret = mig_drv->dev_mig_ops->cancel(pdev);
+ break;
+ default:
+ dev_err(&pdev->dev, "cmd is invaild\n");
+ return -EINVAL;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_drv_version(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u32 version_id = mig_info->version_id;
+
+ if (count != sizeof(version_id) || iswrite)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &version_id, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_rw(
+ struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, u64 pos, bool iswrite)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ void *data_addr = data->vf_data;
+
+ if (count == 0) {
+ dev_err(&data->vf_dev->dev, "qemu operation data size error!\n");
+ return -EINVAL;
+ }
+
+ data_addr += pos - mig_ctl->data_offset;
+ if (iswrite) {
+ if (copy_from_user(data_addr, buf, count))
+ return -EFAULT;
+
+ mig_ctl->pending_bytes += count;
+ if (mig_ctl->pending_bytes > data->state_size)
+ return -EINVAL;
+ } else {
+ if (copy_to_user(buf, data_addr, count))
+ return -EFAULT;
+
+ if (mig_ctl->pending_bytes < count)
+ return -EINVAL;
+
+ mig_ctl->pending_bytes -= count;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_dev_migrn_rw(struct vfio_pci_device *vdev,
+ char __user *buf, size_t count, loff_t *ppos, bool iswrite)
+{
+ unsigned int index =
+ VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS;
+ struct vfio_pci_migration_data *data =
+ (struct vfio_pci_migration_data *)vdev->region[index].data;
+ loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ int ret;
+
+ if (pos >= vdev->region[index].size)
+ return -EINVAL;
+
+ count = min(count, (size_t)(vdev->region[index].size - pos));
+ if (pos >= VFIO_MIGRATION_REGION_DATA_OFFSET)
+ return vfio_pci_handle_mig_data_rw(data,
+ buf, count, pos, iswrite);
+
+ switch (pos) {
+ case VFIO_DEVICE_MIGRATION_OFFSET(device_state):
+ ret = vfio_pci_handle_mig_dev_state(data,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(pending_bytes):
+ ret = vfio_pci_handle_mig_pending_bytes(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(data_offset):
+ ret = vfio_pci_handle_mig_data_offset(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(data_size):
+ ret = vfio_pci_handle_mig_data_size(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(device_cmd):
+ ret = vfio_pci_handle_mig_dev_cmd(data,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(version_id):
+ ret = vfio_pci_handle_mig_drv_version(mig_ctl,
+ buf, count, iswrite);
+ break;
+ default:
+ dev_err(&vdev->pdev->dev, "invalid pos offset\n");
+ ret = -EFAULT;
+ break;
+ }
+
+ if (mig_ctl->device_state == VFIO_DEVICE_STATE_RESUMING &&
+ mig_ctl->pending_bytes == data->state_size &&
+ mig_ctl->data_size == data->state_size) {
+ if (vfio_pci_device_state_restore(data) != 0) {
+ dev_err(&vdev->pdev->dev, "Failed to restore device state!\n");
+ return -EFAULT;
+ }
+ mig_ctl->pending_bytes = 0;
+ mig_ctl->data_size = 0;
+ }
+
+ return ret;
+}
+
+static void vfio_pci_dev_migrn_release(struct vfio_pci_device *vdev,
+ struct vfio_pci_region *region)
+{
+ struct vfio_pci_migration_data *data = region->data;
+
+ if (data) {
+ kfree(data->mig_ctl);
+ kfree(data);
+ }
+}
+
+static const struct vfio_pci_regops vfio_pci_migration_regops = {
+ .rw = vfio_pci_dev_migrn_rw,
+ .release = vfio_pci_dev_migrn_release,
+};
+
+static int vfio_pci_migration_info_init(struct pci_dev *pdev,
+ struct vfio_device_migration_info *mig_info,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ int ret;
+
+ ret = vfio_pci_device_get_info(pdev, mig_info, mig_drv);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get device info\n");
+ return ret;
+ }
+
+ if (mig_info->data_size > VFIO_MIGRATION_BUFFER_MAX_SIZE) {
+ dev_err(&pdev->dev, "mig_info->data_size %llu is invalid\n",
+ mig_info->data_size);
+ return -EINVAL;
+ }
+
+ mig_info->data_offset = VFIO_MIGRATION_REGION_DATA_OFFSET;
+ return ret;
+}
+
+static int vfio_device_mig_data_init(struct vfio_pci_device *vdev,
+ struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_ctl;
+ u64 mig_offset;
+ int ret;
+
+ mig_ctl = kzalloc(sizeof(*mig_ctl), GFP_KERNEL);
+ if (!mig_ctl)
+ return -ENOMEM;
+
+ ret = vfio_pci_migration_info_init(vdev->pdev, mig_ctl,
+ data->mig_driver);
+ if (ret) {
+ dev_err(&vdev->pdev->dev, "get device info error!\n");
+ goto err;
+ }
+
+ mig_offset = sizeof(struct vfio_device_migration_info);
+ data->state_size = mig_ctl->data_size;
+ data->mig_ctl = krealloc(mig_ctl, mig_offset + data->state_size,
+ GFP_KERNEL);
+ if (!data->mig_ctl) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ data->vf_data = (void *)((char *)data->mig_ctl + mig_offset);
+ memset(data->vf_data, 0, data->state_size);
+ data->mig_ctl->data_size = 0;
+
+ ret = vfio_pci_register_dev_region(vdev, VFIO_REGION_TYPE_MIGRATION,
+ VFIO_REGION_SUBTYPE_MIGRATION,
+ &vfio_pci_migration_regops, mig_offset + data->state_size,
+ VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE, data);
+ if (ret) {
+ kfree(data->mig_ctl);
+ return ret;
+ }
+
+ return 0;
+err:
+ kfree(mig_ctl);
+ return ret;
+}
+
+int vfio_pci_migration_init(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+ struct vfio_pci_migration_data *data = NULL;
+ struct pci_dev *pdev = vdev->pdev;
+ int ret;
+
+ mig_driver = vfio_pci_get_mig_driver(pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_driver module\n");
+ return -EINVAL;
+ }
+
+ if (!try_module_get(mig_driver->owner)) {
+ pr_err("module %s is not live\n", mig_driver->owner->name);
+ return -ENODEV;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ module_put(mig_driver->owner);
+ return -ENOMEM;
+ }
+
+ data->mig_driver = mig_driver;
+ data->vf_dev = pdev;
+
+ ret = vfio_device_mig_data_init(vdev, data);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to init vfio device migration data!\n");
+ goto err;
+ }
+
+ return ret;
+err:
+ kfree(data);
+ module_put(mig_driver->owner);
+ return ret;
+}
+
+void vfio_pci_migration_exit(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_warn(&vdev->pdev->dev, "mig_driver is not found\n");
+ return;
+ }
+
+ if (module_refcount(mig_driver->owner) > 0) {
+ vfio_pci_device_release(vdev->pdev, mig_driver);
+ module_put(mig_driver->owner);
+ }
+}
+
+int vfio_pci_register_migration_ops(struct vfio_device_migration_ops *ops,
+ struct module *mod, struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ if (!ops || !mod || !pdev)
+ return -EINVAL;
+
+ mig_driver = vfio_pci_find_mig_drv(pdev, mod);
+ if (mig_driver) {
+ pr_info("%s migration ops has already been registered\n",
+ mod->name);
+ atomic_add(1, &mig_driver->count);
+ return 0;
+ }
+
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
+ mig_driver = kzalloc(sizeof(*mig_driver), GFP_KERNEL);
+ if (!mig_driver) {
+ module_put(THIS_MODULE);
+ return -ENOMEM;
+ }
+
+ mig_driver->pdev = pdev;
+ mig_driver->bus_num = pdev->bus->number;
+ mig_driver->owner = mod;
+ mig_driver->dev_mig_ops = ops;
+
+ vfio_pci_add_mig_drv(mig_driver);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(vfio_pci_register_migration_ops);
+
+void vfio_pci_unregister_migration_ops(struct module *mod, struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ if (!mod || !pdev)
+ return;
+
+ mig_driver = vfio_pci_find_mig_drv(pdev, mod);
+ if (!mig_driver) {
+ pr_err("mig_driver is not found\n");
+ return;
+ }
+
+ if (atomic_sub_and_test(1, &mig_driver->count)) {
+ vfio_pci_remove_mig_drv(mig_driver);
+ kfree(mig_driver);
+ module_put(THIS_MODULE);
+ pr_info("%s succeed to unregister migration ops\n",
+ THIS_MODULE->name);
+ }
+}
+EXPORT_SYMBOL_GPL(vfio_pci_unregister_migration_ops);
diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h
index 17d2bae..03af269 100644
--- a/drivers/vfio/pci/vfio_pci_private.h
+++ b/drivers/vfio/pci/vfio_pci_private.h
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/irqbypass.h>
#include <linux/types.h>
+#include <linux/vfio_pci_migration.h>
#ifndef VFIO_PCI_PRIVATE_H
#define VFIO_PCI_PRIVATE_H
@@ -55,7 +56,7 @@ struct vfio_pci_irq_ctx {
struct vfio_pci_region;
struct vfio_pci_regops {
- size_t (*rw)(struct vfio_pci_device *vdev, char __user *buf,
+ ssize_t (*rw)(struct vfio_pci_device *vdev, char __user *buf,
size_t count, loff_t *ppos, bool iswrite);
void (*release)(struct vfio_pci_device *vdev,
struct vfio_pci_region *region);
@@ -173,4 +174,15 @@ static inline int vfio_pci_igd_init(struct vfio_pci_device *vdev)
return -ENODEV;
}
#endif
+
+extern bool vfio_dev_migration_is_supported(struct pci_dev *pdev);
+extern int vfio_pci_migration_init(struct vfio_pci_device *vdev);
+extern void vfio_pci_migration_exit(struct vfio_pci_device *vdev);
+extern int vfio_pci_device_log_start(struct vfio_pci_device *vdev,
+ struct vf_migration_log_info *log_info);
+extern int vfio_pci_device_log_stop(struct vfio_pci_device *vdev,
+ uint32_t uuid);
+extern int vfio_pci_device_log_status_query(struct vfio_pci_device *vdev);
+extern int vfio_pci_device_init(struct pci_dev *pdev);
+extern void vfio_pci_device_uninit(struct pci_dev *pdev);
#endif /* VFIO_PCI_PRIVATE_H */
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 7a386fb..35f2a29 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -33,6 +33,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/vfio.h>
+#include <linux/vfio_pci_migration.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
@@ -40,6 +41,9 @@
#define DRIVER_AUTHOR "Alex Williamson <alex.williamson(a)redhat.com>"
#define DRIVER_DESC "VFIO - User Level meta-driver"
+#define LOG_BUF_FRAG_SIZE (2 * 1024 * 1024) // fix to 2M
+#define LOG_BUF_MAX_ADDRS_SIZE 128 // max vm ram size is 1T
+
static struct vfio {
struct class *class;
struct list_head iommu_drivers_list;
@@ -57,6 +61,14 @@ struct vfio_iommu_driver {
struct list_head vfio_next;
};
+struct vfio_log_buf {
+ struct vfio_log_buf_info info;
+ int fd;
+ int buffer_state;
+ int device_state;
+ unsigned long *cpu_addrs;
+};
+
struct vfio_container {
struct kref kref;
struct list_head group_list;
@@ -64,6 +76,7 @@ struct vfio_container {
struct vfio_iommu_driver *iommu_driver;
void *iommu_data;
bool noiommu;
+ struct vfio_log_buf log_buf;
};
struct vfio_unbound_dev {
@@ -1158,8 +1171,398 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
return ret;
}
+static long vfio_dispatch_cmd_to_devices(const struct vfio_container *container,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vfio_group *group = NULL;
+ struct vfio_device *device = NULL;
+ long ret = -ENXIO;
+
+ list_for_each_entry(group, &container->group_list, container_next) {
+ list_for_each_entry(device, &group->device_list, group_next) {
+ ret = device->ops->ioctl(device->device_data, cmd, arg);
+ if (ret) {
+ pr_err("dispatch cmd to devices failed\n");
+ return ret;
+ }
+ }
+ }
+ return ret;
+}
+
+static long vfio_log_buf_start(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret;
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_START;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+ ret = vfio_dispatch_cmd_to_devices(container, VFIO_DEVICE_LOG_BUF_CTL,
+ (unsigned long)&log_buf_ctl);
+ if (ret)
+ return ret;
+
+ container->log_buf.device_state = 1;
+ return 0;
+}
+
+static long vfio_log_buf_stop(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret;
+
+ if (container->log_buf.device_state == 0) {
+ pr_warn("device already stopped\n");
+ return 0;
+ }
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_STOP;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+ ret = vfio_dispatch_cmd_to_devices(container, VFIO_DEVICE_LOG_BUF_CTL,
+ (unsigned long)&log_buf_ctl);
+ if (ret)
+ return ret;
+
+ container->log_buf.device_state = 0;
+ return 0;
+}
+
+static long vfio_log_buf_query(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+
+ return vfio_dispatch_cmd_to_devices(container,
+ VFIO_DEVICE_LOG_BUF_CTL, (unsigned long)&log_buf_ctl);
+}
+
+static int vfio_log_buf_fops_mmap(struct file *filep,
+ struct vm_area_struct *vma)
+{
+ struct vfio_container *container = filep->private_data;
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ unsigned long frag_pg_size;
+ unsigned long frag_offset;
+ phys_addr_t pa;
+ int ret = -EINVAL;
+
+ if (!log_buf->cpu_addrs) {
+ pr_err("mmap before setup, please setup log buf first\n");
+ return ret;
+ }
+
+ if (log_buf->info.frag_size < PAGE_SIZE) {
+ pr_err("mmap frag size should not less than page size!\n");
+ return ret;
+ }
+
+ frag_pg_size = log_buf->info.frag_size / PAGE_SIZE;
+ frag_offset = vma->vm_pgoff / frag_pg_size;
+
+ if (frag_offset >= log_buf->info.addrs_size) {
+ pr_err("mmap offset out of range!\n");
+ return ret;
+ }
+
+ if (vma->vm_end - vma->vm_start != log_buf->info.frag_size) {
+ pr_err("mmap size error, should be aligned with frag size!\n");
+ return ret;
+ }
+
+ pa = virt_to_phys((void *)log_buf->cpu_addrs[frag_offset]);
+ ret = remap_pfn_range(vma, vma->vm_start,
+ pa >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+ if (ret)
+ pr_err("remap_pfn_range error!\n");
+ return ret;
+}
+
+static struct device *vfio_get_dev(struct vfio_container *container)
+{
+ struct vfio_group *group = NULL;
+ struct vfio_device *device = NULL;
+
+ list_for_each_entry(group, &container->group_list, container_next) {
+ list_for_each_entry(device, &group->device_list, group_next) {
+ return device->dev;
+ }
+ }
+ return NULL;
+}
+
+static void vfio_log_buf_release_dma(struct device *dev,
+ struct vfio_log_buf *log_buf)
+{
+ int i;
+
+ for (i = 0; i < log_buf->info.addrs_size; i++) {
+ if ((log_buf->cpu_addrs && log_buf->cpu_addrs[i] != 0) &&
+ (log_buf->info.sgevec &&
+ log_buf->info.sgevec[i].addr != 0)) {
+ dma_free_coherent(dev, log_buf->info.frag_size,
+ (void *)log_buf->cpu_addrs[i],
+ log_buf->info.sgevec[i].addr);
+ log_buf->cpu_addrs[i] = 0;
+ log_buf->info.sgevec[i].addr = 0;
+ }
+ }
+}
+
+static long vfio_log_buf_alloc_dma(struct vfio_log_buf_info *info,
+ struct vfio_log_buf *log_buf, struct device *dev)
+{
+ int i;
+
+ for (i = 0; i < info->addrs_size; i++) {
+ log_buf->cpu_addrs[i] = (unsigned long)dma_alloc_coherent(dev,
+ info->frag_size, &log_buf->info.sgevec[i].addr,
+ GFP_KERNEL);
+ log_buf->info.sgevec[i].len = info->frag_size;
+ if (log_buf->cpu_addrs[i] == 0 ||
+ log_buf->info.sgevec[i].addr == 0) {
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static long vfio_log_buf_alloc_addrs(struct vfio_log_buf_info *info,
+ struct vfio_log_buf *log_buf)
+{
+ log_buf->info.sgevec = kcalloc(info->addrs_size,
+ sizeof(struct vfio_log_buf_sge), GFP_KERNEL);
+ if (!log_buf->info.sgevec)
+ return -ENOMEM;
+
+ log_buf->cpu_addrs = kcalloc(info->addrs_size,
+ sizeof(unsigned long), GFP_KERNEL);
+ if (!log_buf->cpu_addrs) {
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static long vfio_log_buf_info_valid(struct vfio_log_buf_info *info)
+{
+ if (info->addrs_size > LOG_BUF_MAX_ADDRS_SIZE ||
+ info->addrs_size == 0) {
+ pr_err("can`t support vm ram size larger than 1T or equal to 0\n");
+ return -EINVAL;
+ }
+ if (info->frag_size != LOG_BUF_FRAG_SIZE) {
+ pr_err("only support %d frag size\n", LOG_BUF_FRAG_SIZE);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static long vfio_log_buf_setup(struct vfio_container *container,
+ unsigned long data)
+{
+ struct vfio_log_buf_info info;
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ struct device *dev = NULL;
+ long ret;
+
+ if (log_buf->info.sgevec) {
+ pr_warn("log buf already setup\n");
+ return 0;
+ }
+
+ if (copy_from_user(&info, (void __user *)data,
+ sizeof(struct vfio_log_buf_info)))
+ return -EFAULT;
+
+ ret = vfio_log_buf_info_valid(&info);
+ if (ret)
+ return ret;
+
+ ret = vfio_log_buf_alloc_addrs(&info, log_buf);
+ if (ret)
+ goto err_out;
+
+ dev = vfio_get_dev(container);
+ if (!dev) {
+ pr_err("can`t get dev\n");
+ goto err_free_addrs;
+ }
+
+ ret = vfio_log_buf_alloc_dma(&info, log_buf, dev);
+ if (ret)
+ goto err_free_dma_array;
+
+ log_buf->info.uuid = info.uuid;
+ log_buf->info.buffer_size = info.buffer_size;
+ log_buf->info.frag_size = info.frag_size;
+ log_buf->info.addrs_size = info.addrs_size;
+ log_buf->buffer_state = 1;
+ return 0;
+
+err_free_dma_array:
+ vfio_log_buf_release_dma(dev, log_buf);
+err_free_addrs:
+ kfree(log_buf->cpu_addrs);
+ log_buf->cpu_addrs = NULL;
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+err_out:
+ return -ENOMEM;
+}
+
+static long vfio_log_buf_release_buffer(struct vfio_container *container)
+{
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ struct device *dev = NULL;
+
+ if (log_buf->buffer_state == 0) {
+ pr_warn("buffer already released\n");
+ return 0;
+ }
+
+ dev = vfio_get_dev(container);
+ if (!dev) {
+ pr_err("can`t get dev\n");
+ return -EFAULT;
+ }
+
+ vfio_log_buf_release_dma(dev, log_buf);
+
+ kfree(log_buf->cpu_addrs);
+ log_buf->cpu_addrs = NULL;
+
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+
+ log_buf->buffer_state = 0;
+ return 0;
+}
+
+static int vfio_log_buf_release(struct inode *inode, struct file *filep)
+{
+ struct vfio_container *container = filep->private_data;
+
+ vfio_log_buf_stop(container);
+ vfio_log_buf_release_buffer(container);
+ memset(&container->log_buf, 0, sizeof(struct vfio_log_buf));
+ return 0;
+}
+
+static long vfio_ioctl_handle_log_buf_ctl(struct vfio_container *container,
+ unsigned long arg)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret = 0;
+
+ if (copy_from_user(&log_buf_ctl, (void __user *)arg,
+ sizeof(struct vfio_log_buf_ctl)))
+ return -EFAULT;
+
+ switch (log_buf_ctl.flags) {
+ case VFIO_DEVICE_LOG_BUF_FLAG_SETUP:
+ ret = vfio_log_buf_setup(container,
+ (unsigned long)log_buf_ctl.data);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_RELEASE:
+ ret = vfio_log_buf_release_buffer(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_START:
+ ret = vfio_log_buf_start(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STOP:
+ ret = vfio_log_buf_stop(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY:
+ ret = vfio_log_buf_query(container);
+ break;
+ default:
+ pr_err("log buf control flag incorrect\n");
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static long vfio_log_buf_fops_unl_ioctl(struct file *filep,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vfio_container *container = filep->private_data;
+ long ret = -EINVAL;
+
+ switch (cmd) {
+ case VFIO_LOG_BUF_CTL:
+ ret = vfio_ioctl_handle_log_buf_ctl(container, arg);
+ break;
+ default:
+ pr_err("log buf control cmd incorrect\n");
+ break;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long vfio_log_buf_fops_compat_ioctl(struct file *filep,
+ unsigned int cmd, unsigned long arg)
+{
+ arg = (unsigned long)compat_ptr(arg);
+ return vfio_log_buf_fops_unl_ioctl(filep, cmd, arg);
+}
+#endif /* CONFIG_COMPAT */
+
+static const struct file_operations vfio_log_buf_fops = {
+ .owner = THIS_MODULE,
+ .mmap = vfio_log_buf_fops_mmap,
+ .unlocked_ioctl = vfio_log_buf_fops_unl_ioctl,
+ .release = vfio_log_buf_release,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = vfio_log_buf_fops_compat_ioctl,
+#endif
+};
+
+static int vfio_get_log_buf_fd(struct vfio_container *container,
+ unsigned long arg)
+{
+ struct file *filep = NULL;
+ int ret;
+
+ if (container->log_buf.fd > 0)
+ return container->log_buf.fd;
+
+ ret = get_unused_fd_flags(O_CLOEXEC);
+ if (ret < 0) {
+ pr_err("get_unused_fd_flags get fd failed\n");
+ return ret;
+ }
+
+ filep = anon_inode_getfile("[vfio-log-buf]", &vfio_log_buf_fops,
+ container, O_RDWR);
+ if (IS_ERR(filep)) {
+ pr_err("anon_inode_getfile failed\n");
+ put_unused_fd(ret);
+ ret = PTR_ERR(filep);
+ return ret;
+ }
+
+ filep->f_mode |= (FMODE_READ | FMODE_WRITE | FMODE_LSEEK);
+
+ fd_install(ret, filep);
+
+ container->log_buf.fd = ret;
+ return ret;
+}
+
static long vfio_fops_unl_ioctl(struct file *filep,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
struct vfio_container *container = filep->private_data;
struct vfio_iommu_driver *driver;
@@ -1179,6 +1582,9 @@ static long vfio_fops_unl_ioctl(struct file *filep,
case VFIO_SET_IOMMU:
ret = vfio_ioctl_set_iommu(container, arg);
break;
+ case VFIO_GET_LOG_BUF_FD:
+ ret = vfio_get_log_buf_fd(container, arg);
+ break;
default:
driver = container->iommu_driver;
data = container->iommu_data;
@@ -1210,6 +1616,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
INIT_LIST_HEAD(&container->group_list);
init_rwsem(&container->group_lock);
kref_init(&container->kref);
+ memset(&container->log_buf, 0, sizeof(struct vfio_log_buf));
filep->private_data = container;
@@ -1219,9 +1626,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
static int vfio_fops_release(struct inode *inode, struct file *filep)
{
struct vfio_container *container = filep->private_data;
-
filep->private_data = NULL;
-
vfio_container_put(container);
return 0;
diff --git a/include/linux/vfio_pci_migration.h b/include/linux/vfio_pci_migration.h
new file mode 100644
index 0000000..464ffb4
--- /dev/null
+++ b/include/linux/vfio_pci_migration.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ */
+
+#ifndef VFIO_PCI_MIGRATION_H
+#define VFIO_PCI_MIGRATION_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#define VFIO_REGION_TYPE_MIGRATION (3)
+/* sub-types for VFIO_REGION_TYPE_MIGRATION */
+#define VFIO_REGION_SUBTYPE_MIGRATION (1)
+
+#define VFIO_MIGRATION_BUFFER_MAX_SIZE SZ_256K
+#define VFIO_MIGRATION_REGION_DATA_OFFSET \
+ (sizeof(struct vfio_device_migration_info))
+#define VFIO_DEVICE_MIGRATION_OFFSET(x) \
+ offsetof(struct vfio_device_migration_info, x)
+
+struct vfio_device_migration_info {
+ __u32 device_state; /* VFIO device state */
+#define VFIO_DEVICE_STATE_STOP (0)
+#define VFIO_DEVICE_STATE_RUNNING (1 << 0)
+#define VFIO_DEVICE_STATE_SAVING (1 << 1)
+#define VFIO_DEVICE_STATE_RESUMING (1 << 2)
+#define VFIO_DEVICE_STATE_MASK (VFIO_DEVICE_STATE_RUNNING | \
+ VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING)
+ __u32 reserved;
+
+ __u32 device_cmd;
+ __u32 version_id;
+
+ __u64 pending_bytes;
+ __u64 data_offset;
+ __u64 data_size;
+};
+
+enum {
+ VFIO_DEVICE_STOP = 0xffff0001,
+ VFIO_DEVICE_CONTINUE,
+ VFIO_DEVICE_MIGRATION_CANCEL,
+};
+
+struct vfio_log_buf_sge {
+ __u64 len;
+ __u64 addr;
+};
+
+struct vfio_log_buf_info {
+ __u32 uuid;
+ __u64 buffer_size;
+ __u64 addrs_size;
+ __u64 frag_size;
+ struct vfio_log_buf_sge *sgevec;
+};
+
+struct vfio_log_buf_ctl {
+ __u32 argsz;
+ __u32 flags;
+ #define VFIO_DEVICE_LOG_BUF_FLAG_SETUP (1 << 0)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_RELEASE (1 << 1)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_START (1 << 2)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_STOP (1 << 3)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY (1 << 4)
+ void *data;
+};
+#define VFIO_LOG_BUF_CTL _IO(VFIO_TYPE, VFIO_BASE + 21)
+#define VFIO_GET_LOG_BUF_FD _IO(VFIO_TYPE, VFIO_BASE + 22)
+#define VFIO_DEVICE_LOG_BUF_CTL _IO(VFIO_TYPE, VFIO_BASE + 23)
+
+struct vf_migration_log_info {
+ __u32 dom_uuid;
+ __u64 buffer_size;
+ __u64 sge_len;
+ __u64 sge_num;
+ struct vfio_log_buf_sge *sgevec;
+};
+
+struct vfio_device_migration_ops {
+ /* Get device information */
+ int (*get_info)(struct pci_dev *pdev,
+ struct vfio_device_migration_info *info);
+ /* Enable a vf device */
+ int (*enable)(struct pci_dev *pdev);
+ /* Disable a vf device */
+ int (*disable)(struct pci_dev *pdev);
+ /* Save a vf device */
+ int (*save)(struct pci_dev *pdev, void *base,
+ uint64_t off, uint64_t count);
+ /* Resuming a vf device */
+ int (*restore)(struct pci_dev *pdev, void *base,
+ uint64_t off, uint64_t count);
+ /* Log start a vf device */
+ int (*log_start)(struct pci_dev *pdev,
+ struct vf_migration_log_info *log_info);
+ /* Log stop a vf device */
+ int (*log_stop)(struct pci_dev *pdev, uint32_t uuid);
+ /* Get vf device log status */
+ int (*get_log_status)(struct pci_dev *pdev);
+ /* Pre enable a vf device(load_setup, before restore a vf) */
+ int (*pre_enable)(struct pci_dev *pdev);
+ /* Cancel a vf device when live migration failed (rollback) */
+ int (*cancel)(struct pci_dev *pdev);
+ /* Init a vf device */
+ int (*init)(struct pci_dev *pdev);
+ /* Uninit a vf device */
+ void (*uninit)(struct pci_dev *pdev);
+ /* Release a vf device */
+ void (*release)(struct pci_dev *pdev);
+};
+
+struct vfio_pci_vendor_mig_driver {
+ struct pci_dev *pdev;
+ unsigned char bus_num;
+ struct vfio_device_migration_ops *dev_mig_ops;
+ struct module *owner;
+ atomic_t count;
+ struct list_head list;
+};
+
+struct vfio_pci_migration_data {
+ u64 state_size;
+ struct pci_dev *vf_dev;
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+ struct vfio_device_migration_info *mig_ctl;
+ void *vf_data;
+};
+
+int vfio_pci_register_migration_ops(struct vfio_device_migration_ops *ops,
+ struct module *mod, struct pci_dev *pdev);
+void vfio_pci_unregister_migration_ops(struct module *mod,
+ struct pci_dev *pdev);
+
+#endif /* VFIO_PCI_MIGRATION_H */
--
1.8.3.1
2
1
From: Rong Wang <w_angrong(a)163.com>
kunpeng inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5CO9A
CVE: NA
---------------------------------
As pass through devices, hypervisor can`t control the status of
device, and can`t track dirty memory DMA from device, during
migration.
The goal of this framework is to combine hardware to accomplish
the task above.
qemu
|status control and dirty memory report
vfio
|ops to hardware
hardware
Signed-off-by: Rong Wang <w_angrong(a)163.com>
Signed-off-by: HuHua Li <18245010845(a)163.com>
Signed-off-by: Ripeng Qiu <965412048(a)qq.com>
---
drivers/vfio/pci/Makefile | 2 +-
drivers/vfio/pci/vfio_pci.c | 54 +++
drivers/vfio/pci/vfio_pci_migration.c | 755 ++++++++++++++++++++++++++++++++++
drivers/vfio/pci/vfio_pci_private.h | 14 +-
drivers/vfio/vfio.c | 411 +++++++++++++++++-
include/linux/vfio_pci_migration.h | 136 ++++++
6 files changed, 1367 insertions(+), 5 deletions(-)
create mode 100644 drivers/vfio/pci/vfio_pci_migration.c
create mode 100644 include/linux/vfio_pci_migration.h
diff --git a/drivers/vfio/pci/Makefile b/drivers/vfio/pci/Makefile
index 76d8ec0..80a777d 100644
--- a/drivers/vfio/pci/Makefile
+++ b/drivers/vfio/pci/Makefile
@@ -1,5 +1,5 @@
-vfio-pci-y := vfio_pci.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o
+vfio-pci-y := vfio_pci.o vfio_pci_intrs.o vfio_pci_rdwr.o vfio_pci_config.o vfio_pci_migration.o
vfio-pci-$(CONFIG_VFIO_PCI_IGD) += vfio_pci_igd.o
obj-$(CONFIG_VFIO_PCI) += vfio-pci.o
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 51b791c..59d8280 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -30,6 +30,7 @@
#include <linux/vgaarb.h>
#include <linux/nospec.h>
#include <linux/sched/mm.h>
+#include <linux/vfio_pci_migration.h>
#include "vfio_pci_private.h"
@@ -296,6 +297,14 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
vfio_pci_probe_mmaps(vdev);
+ if (vfio_dev_migration_is_supported(pdev)) {
+ ret = vfio_pci_migration_init(vdev);
+ if (ret) {
+ dev_warn(&vdev->pdev->dev, "Failed to init vfio_pci_migration\n");
+ vfio_pci_disable(vdev);
+ return ret;
+ }
+ }
return 0;
}
@@ -392,6 +401,7 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
out:
pci_disable_device(pdev);
+ vfio_pci_migration_exit(vdev);
vfio_pci_try_bus_reset(vdev);
if (!disable_idle_d3)
@@ -642,6 +652,41 @@ struct vfio_devices {
int max_index;
};
+static long vfio_pci_handle_log_buf_ctl(struct vfio_pci_device *vdev,
+ const unsigned long arg)
+{
+ struct vfio_log_buf_ctl *log_buf_ctl = NULL;
+ struct vfio_log_buf_info *log_buf_info = NULL;
+ struct vf_migration_log_info migration_log_info;
+ long ret = 0;
+
+ log_buf_ctl = (struct vfio_log_buf_ctl *)arg;
+ log_buf_info = (struct vfio_log_buf_info *)log_buf_ctl->data;
+
+ switch (log_buf_ctl->flags) {
+ case VFIO_DEVICE_LOG_BUF_FLAG_START:
+ migration_log_info.dom_uuid = log_buf_info->uuid;
+ migration_log_info.buffer_size =
+ log_buf_info->buffer_size;
+ migration_log_info.sge_num = log_buf_info->addrs_size;
+ migration_log_info.sge_len = log_buf_info->frag_size;
+ migration_log_info.sgevec = log_buf_info->sgevec;
+ ret = vfio_pci_device_log_start(vdev,
+ &migration_log_info);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STOP:
+ ret = vfio_pci_device_log_stop(vdev,
+ log_buf_info->uuid);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY:
+ ret = vfio_pci_device_log_status_query(vdev);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
static long vfio_pci_ioctl(void *device_data,
unsigned int cmd, unsigned long arg)
{
@@ -1142,6 +1187,8 @@ static long vfio_pci_ioctl(void *device_data,
return vfio_pci_ioeventfd(vdev, ioeventfd.offset,
ioeventfd.data, count, ioeventfd.fd);
+ } else if (cmd == VFIO_DEVICE_LOG_BUF_CTL) {
+ return vfio_pci_handle_log_buf_ctl(vdev, arg);
}
return -ENOTTY;
@@ -1566,6 +1613,9 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_power_state(pdev, PCI_D3hot);
}
+ if (vfio_dev_migration_is_supported(pdev))
+ ret = vfio_pci_device_init(pdev);
+
return ret;
}
@@ -1591,6 +1641,10 @@ static void vfio_pci_remove(struct pci_dev *pdev)
if (!disable_idle_d3)
pci_set_power_state(pdev, PCI_D0);
+
+ if (vfio_dev_migration_is_supported(pdev)) {
+ vfio_pci_device_uninit(pdev);
+ }
}
static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
diff --git a/drivers/vfio/pci/vfio_pci_migration.c b/drivers/vfio/pci/vfio_pci_migration.c
new file mode 100644
index 0000000..f69cd13
--- /dev/null
+++ b/drivers/vfio/pci/vfio_pci_migration.c
@@ -0,0 +1,755 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/uaccess.h>
+#include <linux/vfio.h>
+#include <linux/vfio_pci_migration.h>
+
+#include "vfio_pci_private.h"
+
+static LIST_HEAD(vfio_pci_mig_drivers_list);
+static DEFINE_MUTEX(vfio_pci_mig_drivers_mutex);
+
+static void vfio_pci_add_mig_drv(struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ atomic_set(&mig_drv->count, 1);
+ list_add_tail(&mig_drv->list, &vfio_pci_mig_drivers_list);
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+}
+
+static void vfio_pci_remove_mig_drv(struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_del(&mig_drv->list);
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+}
+
+static struct vfio_pci_vendor_mig_driver *
+ vfio_pci_find_mig_drv(struct pci_dev *pdev, struct module *module)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = NULL;
+
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_for_each_entry(mig_drv, &vfio_pci_mig_drivers_list, list) {
+ if (mig_drv->owner == module) {
+ if (mig_drv->bus_num == pdev->bus->number)
+ goto out;
+ }
+ }
+ mig_drv = NULL;
+out:
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+ return mig_drv;
+}
+
+static struct vfio_pci_vendor_mig_driver *
+ vfio_pci_get_mig_driver(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = NULL;
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ mutex_lock(&vfio_pci_mig_drivers_mutex);
+ list_for_each_entry(mig_drv, &vfio_pci_mig_drivers_list, list) {
+ if (mig_drv->bus_num == pf_dev->bus->number)
+ goto out;
+ }
+ mig_drv = NULL;
+out:
+ mutex_unlock(&vfio_pci_mig_drivers_mutex);
+ return mig_drv;
+}
+
+bool vfio_dev_migration_is_supported(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ mig_driver = vfio_pci_get_mig_driver(pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_warn(&pdev->dev, "unable to find a mig_drv module\n");
+ return false;
+ }
+
+ return true;
+}
+
+int vfio_pci_device_log_start(struct vfio_pci_device *vdev,
+ struct vf_migration_log_info *log_info)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->log_start ||
+ (mig_driver->dev_mig_ops->log_start(vdev->pdev,
+ log_info) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to set log start\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_log_stop(struct vfio_pci_device *vdev, uint32_t uuid)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->log_stop ||
+ (mig_driver->dev_mig_ops->log_stop(vdev->pdev, uuid) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to set log stop\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_log_status_query(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&vdev->pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (!mig_driver->dev_mig_ops->get_log_status ||
+ (mig_driver->dev_mig_ops->get_log_status(vdev->pdev) != 0)) {
+ dev_err(&vdev->pdev->dev, "failed to get log status\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int vfio_pci_device_init(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv;
+
+ mig_drv = vfio_pci_get_mig_driver(pdev);
+ if (!mig_drv || !mig_drv->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_drv module\n");
+ return -EFAULT;
+ }
+
+ if (mig_drv->dev_mig_ops->init)
+ return mig_drv->dev_mig_ops->init(pdev);
+
+ return -EFAULT;
+}
+
+void vfio_pci_device_uninit(struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv;
+
+ mig_drv = vfio_pci_get_mig_driver(pdev);
+ if (!mig_drv || !mig_drv->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_drv module\n");
+ return;
+ }
+
+ if (mig_drv->dev_mig_ops->uninit)
+ mig_drv->dev_mig_ops->uninit(pdev);
+}
+
+static void vfio_pci_device_release(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (mig_drv->dev_mig_ops->release)
+ mig_drv->dev_mig_ops->release(pdev);
+}
+
+static int vfio_pci_device_get_info(struct pci_dev *pdev,
+ struct vfio_device_migration_info *mig_info,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (mig_drv->dev_mig_ops->get_info)
+ return mig_drv->dev_mig_ops->get_info(pdev, mig_info);
+ return -EFAULT;
+}
+
+static int vfio_pci_device_enable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->enable ||
+ (mig_drv->dev_mig_ops->enable(pdev) != 0)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vfio_pci_device_disable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->disable ||
+ (mig_drv->dev_mig_ops->disable(pdev) != 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vfio_pci_device_pre_enable(struct pci_dev *pdev,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ if (!mig_drv->dev_mig_ops->pre_enable ||
+ (mig_drv->dev_mig_ops->pre_enable(pdev) != 0))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vfio_pci_device_state_save(struct pci_dev *pdev,
+ struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_info = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ void *base = (void *)mig_info;
+ int ret = 0;
+
+ if ((mig_info->device_state & VFIO_DEVICE_STATE_RUNNING) != 0) {
+ ret = vfio_pci_device_disable(pdev, mig_drv);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to stop VF function!\n");
+ return ret;
+ }
+ mig_info->device_state &= ~VFIO_DEVICE_STATE_RUNNING;
+ }
+
+ if (mig_drv->dev_mig_ops && mig_drv->dev_mig_ops->save) {
+ ret = mig_drv->dev_mig_ops->save(pdev, base,
+ mig_info->data_offset, data->state_size);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to save device state!\n");
+ return -EINVAL;
+ }
+ } else {
+ return -EFAULT;
+ }
+
+ mig_info->data_size = data->state_size;
+ mig_info->pending_bytes = mig_info->data_size;
+ return ret;
+}
+
+static int vfio_pci_device_state_restore(struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_info = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ void *base = (void *)mig_info;
+ int ret;
+
+ if (mig_drv->dev_mig_ops && mig_drv->dev_mig_ops->restore) {
+ ret = mig_drv->dev_mig_ops->restore(pdev, base,
+ mig_info->data_offset, mig_info->data_size);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to restore device state!\n");
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ return -EFAULT;
+}
+
+static int vfio_pci_set_device_state(struct vfio_pci_migration_data *data,
+ u32 state)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ int ret = 0;
+
+ if (state == mig_ctl->device_state)
+ return 0;
+
+ if (!mig_drv->dev_mig_ops)
+ return -EINVAL;
+
+ switch (state) {
+ case VFIO_DEVICE_STATE_RUNNING:
+ if (!(mig_ctl->device_state &
+ VFIO_DEVICE_STATE_RUNNING))
+ ret = vfio_pci_device_enable(pdev, mig_drv);
+ break;
+ case VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RUNNING:
+ /*
+ * (pre-copy) - device should start logging data.
+ */
+ ret = 0;
+ break;
+ case VFIO_DEVICE_STATE_SAVING:
+ /* stop the vf function, save state */
+ ret = vfio_pci_device_state_save(pdev, data);
+ break;
+ case VFIO_DEVICE_STATE_STOP:
+ if (mig_ctl->device_state & VFIO_DEVICE_STATE_RUNNING)
+ ret = vfio_pci_device_disable(pdev, mig_drv);
+ break;
+ case VFIO_DEVICE_STATE_RESUMING:
+ ret = vfio_pci_device_pre_enable(pdev, mig_drv);
+ break;
+ default:
+ ret = -EFAULT;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
+ mig_ctl->device_state = state;
+ return 0;
+}
+
+static ssize_t vfio_pci_handle_mig_dev_state(
+ struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, bool iswrite)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ u32 device_state;
+ int ret;
+
+ if (count != sizeof(device_state))
+ return -EINVAL;
+
+ if (iswrite) {
+ if (copy_from_user(&device_state, buf, count))
+ return -EFAULT;
+
+ ret = vfio_pci_set_device_state(data, device_state);
+ if (ret)
+ return ret;
+ } else {
+ if (copy_to_user(buf, &mig_ctl->device_state, count))
+ return -EFAULT;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_pending_bytes(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 pending_bytes;
+
+ if (count != sizeof(pending_bytes) || iswrite)
+ return -EINVAL;
+
+ if (mig_info->device_state ==
+ (VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RUNNING)) {
+ /* In pre-copy state we have no data to return for now,
+ * return 0 pending bytes
+ */
+ pending_bytes = 0;
+ } else {
+ pending_bytes = mig_info->pending_bytes;
+ }
+
+ if (copy_to_user(buf, &pending_bytes, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_offset(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 data_offset = mig_info->data_offset;
+
+ if (count != sizeof(data_offset) || iswrite)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &data_offset, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_size(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u64 data_size;
+
+ if (count != sizeof(data_size))
+ return -EINVAL;
+
+ if (iswrite) {
+ /* data_size is writable only during resuming state */
+ if (mig_info->device_state != VFIO_DEVICE_STATE_RESUMING)
+ return -EINVAL;
+
+ if (copy_from_user(&data_size, buf, sizeof(data_size)))
+ return -EFAULT;
+
+ mig_info->data_size = data_size;
+ } else {
+ if (mig_info->device_state != VFIO_DEVICE_STATE_SAVING)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &mig_info->data_size,
+ sizeof(data_size)))
+ return -EFAULT;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_dev_cmd(struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, bool iswrite)
+{
+ struct vfio_pci_vendor_mig_driver *mig_drv = data->mig_driver;
+ struct pci_dev *pdev = data->vf_dev;
+ u32 device_cmd;
+ int ret = -EFAULT;
+
+ if (count != sizeof(device_cmd) || !iswrite || !mig_drv->dev_mig_ops)
+ return -EINVAL;
+
+ if (copy_from_user(&device_cmd, buf, count))
+ return -EFAULT;
+
+ switch (device_cmd) {
+ case VFIO_DEVICE_MIGRATION_CANCEL:
+ if (mig_drv->dev_mig_ops->cancel)
+ ret = mig_drv->dev_mig_ops->cancel(pdev);
+ break;
+ default:
+ dev_err(&pdev->dev, "cmd is invaild\n");
+ return -EINVAL;
+ }
+
+ if (ret != 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_drv_version(
+ struct vfio_device_migration_info *mig_info,
+ char __user *buf, size_t count, bool iswrite)
+{
+ u32 version_id = mig_info->version_id;
+
+ if (count != sizeof(version_id) || iswrite)
+ return -EINVAL;
+
+ if (copy_to_user(buf, &version_id, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t vfio_pci_handle_mig_data_rw(
+ struct vfio_pci_migration_data *data,
+ char __user *buf, size_t count, u64 pos, bool iswrite)
+{
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ void *data_addr = data->vf_data;
+
+ if (count == 0) {
+ dev_err(&data->vf_dev->dev, "qemu operation data size error!\n");
+ return -EINVAL;
+ }
+
+ data_addr += pos - mig_ctl->data_offset;
+ if (iswrite) {
+ if (copy_from_user(data_addr, buf, count))
+ return -EFAULT;
+
+ mig_ctl->pending_bytes += count;
+ if (mig_ctl->pending_bytes > data->state_size)
+ return -EINVAL;
+ } else {
+ if (copy_to_user(buf, data_addr, count))
+ return -EFAULT;
+
+ if (mig_ctl->pending_bytes < count)
+ return -EINVAL;
+
+ mig_ctl->pending_bytes -= count;
+ }
+
+ return count;
+}
+
+static ssize_t vfio_pci_dev_migrn_rw(struct vfio_pci_device *vdev,
+ char __user *buf, size_t count, loff_t *ppos, bool iswrite)
+{
+ unsigned int index =
+ VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS;
+ struct vfio_pci_migration_data *data =
+ (struct vfio_pci_migration_data *)vdev->region[index].data;
+ loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+ struct vfio_device_migration_info *mig_ctl = data->mig_ctl;
+ int ret;
+
+ if (pos >= vdev->region[index].size)
+ return -EINVAL;
+
+ count = min(count, (size_t)(vdev->region[index].size - pos));
+ if (pos >= VFIO_MIGRATION_REGION_DATA_OFFSET)
+ return vfio_pci_handle_mig_data_rw(data,
+ buf, count, pos, iswrite);
+
+ switch (pos) {
+ case VFIO_DEVICE_MIGRATION_OFFSET(device_state):
+ ret = vfio_pci_handle_mig_dev_state(data,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(pending_bytes):
+ ret = vfio_pci_handle_mig_pending_bytes(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(data_offset):
+ ret = vfio_pci_handle_mig_data_offset(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(data_size):
+ ret = vfio_pci_handle_mig_data_size(mig_ctl,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(device_cmd):
+ ret = vfio_pci_handle_mig_dev_cmd(data,
+ buf, count, iswrite);
+ break;
+ case VFIO_DEVICE_MIGRATION_OFFSET(version_id):
+ ret = vfio_pci_handle_mig_drv_version(mig_ctl,
+ buf, count, iswrite);
+ break;
+ default:
+ dev_err(&vdev->pdev->dev, "invalid pos offset\n");
+ ret = -EFAULT;
+ break;
+ }
+
+ if (mig_ctl->device_state == VFIO_DEVICE_STATE_RESUMING &&
+ mig_ctl->pending_bytes == data->state_size &&
+ mig_ctl->data_size == data->state_size) {
+ if (vfio_pci_device_state_restore(data) != 0) {
+ dev_err(&vdev->pdev->dev, "Failed to restore device state!\n");
+ return -EFAULT;
+ }
+ mig_ctl->pending_bytes = 0;
+ mig_ctl->data_size = 0;
+ }
+
+ return ret;
+}
+
+static void vfio_pci_dev_migrn_release(struct vfio_pci_device *vdev,
+ struct vfio_pci_region *region)
+{
+ struct vfio_pci_migration_data *data = region->data;
+
+ if (data) {
+ kfree(data->mig_ctl);
+ kfree(data);
+ }
+}
+
+static const struct vfio_pci_regops vfio_pci_migration_regops = {
+ .rw = vfio_pci_dev_migrn_rw,
+ .release = vfio_pci_dev_migrn_release,
+};
+
+static int vfio_pci_migration_info_init(struct pci_dev *pdev,
+ struct vfio_device_migration_info *mig_info,
+ struct vfio_pci_vendor_mig_driver *mig_drv)
+{
+ int ret;
+
+ ret = vfio_pci_device_get_info(pdev, mig_info, mig_drv);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get device info\n");
+ return ret;
+ }
+
+ if (mig_info->data_size > VFIO_MIGRATION_BUFFER_MAX_SIZE) {
+ dev_err(&pdev->dev, "mig_info->data_size %llu is invalid\n",
+ mig_info->data_size);
+ return -EINVAL;
+ }
+
+ mig_info->data_offset = VFIO_MIGRATION_REGION_DATA_OFFSET;
+ return ret;
+}
+
+static int vfio_device_mig_data_init(struct vfio_pci_device *vdev,
+ struct vfio_pci_migration_data *data)
+{
+ struct vfio_device_migration_info *mig_ctl;
+ u64 mig_offset;
+ int ret;
+
+ mig_ctl = kzalloc(sizeof(*mig_ctl), GFP_KERNEL);
+ if (!mig_ctl)
+ return -ENOMEM;
+
+ ret = vfio_pci_migration_info_init(vdev->pdev, mig_ctl,
+ data->mig_driver);
+ if (ret) {
+ dev_err(&vdev->pdev->dev, "get device info error!\n");
+ goto err;
+ }
+
+ mig_offset = sizeof(struct vfio_device_migration_info);
+ data->state_size = mig_ctl->data_size;
+ data->mig_ctl = krealloc(mig_ctl, mig_offset + data->state_size,
+ GFP_KERNEL);
+ if (!data->mig_ctl) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ data->vf_data = (void *)((char *)data->mig_ctl + mig_offset);
+ memset(data->vf_data, 0, data->state_size);
+ data->mig_ctl->data_size = 0;
+
+ ret = vfio_pci_register_dev_region(vdev, VFIO_REGION_TYPE_MIGRATION,
+ VFIO_REGION_SUBTYPE_MIGRATION,
+ &vfio_pci_migration_regops, mig_offset + data->state_size,
+ VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE, data);
+ if (ret) {
+ kfree(data->mig_ctl);
+ return ret;
+ }
+
+ return 0;
+err:
+ kfree(mig_ctl);
+ return ret;
+}
+
+int vfio_pci_migration_init(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+ struct vfio_pci_migration_data *data = NULL;
+ struct pci_dev *pdev = vdev->pdev;
+ int ret;
+
+ mig_driver = vfio_pci_get_mig_driver(pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_err(&pdev->dev, "unable to find a mig_driver module\n");
+ return -EINVAL;
+ }
+
+ if (!try_module_get(mig_driver->owner)) {
+ pr_err("module %s is not live\n", mig_driver->owner->name);
+ return -ENODEV;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ module_put(mig_driver->owner);
+ return -ENOMEM;
+ }
+
+ data->mig_driver = mig_driver;
+ data->vf_dev = pdev;
+
+ ret = vfio_device_mig_data_init(vdev, data);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to init vfio device migration data!\n");
+ goto err;
+ }
+
+ return ret;
+err:
+ kfree(data);
+ module_put(mig_driver->owner);
+ return ret;
+}
+
+void vfio_pci_migration_exit(struct vfio_pci_device *vdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ mig_driver = vfio_pci_get_mig_driver(vdev->pdev);
+ if (!mig_driver || !mig_driver->dev_mig_ops) {
+ dev_warn(&vdev->pdev->dev, "mig_driver is not found\n");
+ return;
+ }
+
+ if (module_refcount(mig_driver->owner) > 0) {
+ vfio_pci_device_release(vdev->pdev, mig_driver);
+ module_put(mig_driver->owner);
+ }
+}
+
+int vfio_pci_register_migration_ops(struct vfio_device_migration_ops *ops,
+ struct module *mod, struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ if (!ops || !mod || !pdev)
+ return -EINVAL;
+
+ mig_driver = vfio_pci_find_mig_drv(pdev, mod);
+ if (mig_driver) {
+ pr_info("%s migration ops has already been registered\n",
+ mod->name);
+ atomic_add(1, &mig_driver->count);
+ return 0;
+ }
+
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
+ mig_driver = kzalloc(sizeof(*mig_driver), GFP_KERNEL);
+ if (!mig_driver) {
+ module_put(THIS_MODULE);
+ return -ENOMEM;
+ }
+
+ mig_driver->pdev = pdev;
+ mig_driver->bus_num = pdev->bus->number;
+ mig_driver->owner = mod;
+ mig_driver->dev_mig_ops = ops;
+
+ vfio_pci_add_mig_drv(mig_driver);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(vfio_pci_register_migration_ops);
+
+void vfio_pci_unregister_migration_ops(struct module *mod, struct pci_dev *pdev)
+{
+ struct vfio_pci_vendor_mig_driver *mig_driver = NULL;
+
+ if (!mod || !pdev)
+ return;
+
+ mig_driver = vfio_pci_find_mig_drv(pdev, mod);
+ if (!mig_driver) {
+ pr_err("mig_driver is not found\n");
+ return;
+ }
+
+ if (atomic_sub_and_test(1, &mig_driver->count)) {
+ vfio_pci_remove_mig_drv(mig_driver);
+ kfree(mig_driver);
+ module_put(THIS_MODULE);
+ pr_info("%s succeed to unregister migration ops\n",
+ THIS_MODULE->name);
+ }
+}
+EXPORT_SYMBOL_GPL(vfio_pci_unregister_migration_ops);
diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h
index 17d2bae..03af269 100644
--- a/drivers/vfio/pci/vfio_pci_private.h
+++ b/drivers/vfio/pci/vfio_pci_private.h
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/irqbypass.h>
#include <linux/types.h>
+#include <linux/vfio_pci_migration.h>
#ifndef VFIO_PCI_PRIVATE_H
#define VFIO_PCI_PRIVATE_H
@@ -55,7 +56,7 @@ struct vfio_pci_irq_ctx {
struct vfio_pci_region;
struct vfio_pci_regops {
- size_t (*rw)(struct vfio_pci_device *vdev, char __user *buf,
+ ssize_t (*rw)(struct vfio_pci_device *vdev, char __user *buf,
size_t count, loff_t *ppos, bool iswrite);
void (*release)(struct vfio_pci_device *vdev,
struct vfio_pci_region *region);
@@ -173,4 +174,15 @@ static inline int vfio_pci_igd_init(struct vfio_pci_device *vdev)
return -ENODEV;
}
#endif
+
+extern bool vfio_dev_migration_is_supported(struct pci_dev *pdev);
+extern int vfio_pci_migration_init(struct vfio_pci_device *vdev);
+extern void vfio_pci_migration_exit(struct vfio_pci_device *vdev);
+extern int vfio_pci_device_log_start(struct vfio_pci_device *vdev,
+ struct vf_migration_log_info *log_info);
+extern int vfio_pci_device_log_stop(struct vfio_pci_device *vdev,
+ uint32_t uuid);
+extern int vfio_pci_device_log_status_query(struct vfio_pci_device *vdev);
+extern int vfio_pci_device_init(struct pci_dev *pdev);
+extern void vfio_pci_device_uninit(struct pci_dev *pdev);
#endif /* VFIO_PCI_PRIVATE_H */
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 7a386fb..35f2a29 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -33,6 +33,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/vfio.h>
+#include <linux/vfio_pci_migration.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
@@ -40,6 +41,9 @@
#define DRIVER_AUTHOR "Alex Williamson <alex.williamson(a)redhat.com>"
#define DRIVER_DESC "VFIO - User Level meta-driver"
+#define LOG_BUF_FRAG_SIZE (2 * 1024 * 1024) // fix to 2M
+#define LOG_BUF_MAX_ADDRS_SIZE 128 // max vm ram size is 1T
+
static struct vfio {
struct class *class;
struct list_head iommu_drivers_list;
@@ -57,6 +61,14 @@ struct vfio_iommu_driver {
struct list_head vfio_next;
};
+struct vfio_log_buf {
+ struct vfio_log_buf_info info;
+ int fd;
+ int buffer_state;
+ int device_state;
+ unsigned long *cpu_addrs;
+};
+
struct vfio_container {
struct kref kref;
struct list_head group_list;
@@ -64,6 +76,7 @@ struct vfio_container {
struct vfio_iommu_driver *iommu_driver;
void *iommu_data;
bool noiommu;
+ struct vfio_log_buf log_buf;
};
struct vfio_unbound_dev {
@@ -1158,8 +1171,398 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
return ret;
}
+static long vfio_dispatch_cmd_to_devices(const struct vfio_container *container,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vfio_group *group = NULL;
+ struct vfio_device *device = NULL;
+ long ret = -ENXIO;
+
+ list_for_each_entry(group, &container->group_list, container_next) {
+ list_for_each_entry(device, &group->device_list, group_next) {
+ ret = device->ops->ioctl(device->device_data, cmd, arg);
+ if (ret) {
+ pr_err("dispatch cmd to devices failed\n");
+ return ret;
+ }
+ }
+ }
+ return ret;
+}
+
+static long vfio_log_buf_start(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret;
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_START;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+ ret = vfio_dispatch_cmd_to_devices(container, VFIO_DEVICE_LOG_BUF_CTL,
+ (unsigned long)&log_buf_ctl);
+ if (ret)
+ return ret;
+
+ container->log_buf.device_state = 1;
+ return 0;
+}
+
+static long vfio_log_buf_stop(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret;
+
+ if (container->log_buf.device_state == 0) {
+ pr_warn("device already stopped\n");
+ return 0;
+ }
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_STOP;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+ ret = vfio_dispatch_cmd_to_devices(container, VFIO_DEVICE_LOG_BUF_CTL,
+ (unsigned long)&log_buf_ctl);
+ if (ret)
+ return ret;
+
+ container->log_buf.device_state = 0;
+ return 0;
+}
+
+static long vfio_log_buf_query(struct vfio_container *container)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+
+ log_buf_ctl.argsz = sizeof(struct vfio_log_buf_info);
+ log_buf_ctl.flags = VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY;
+ log_buf_ctl.data = (void *)&container->log_buf.info;
+
+ return vfio_dispatch_cmd_to_devices(container,
+ VFIO_DEVICE_LOG_BUF_CTL, (unsigned long)&log_buf_ctl);
+}
+
+static int vfio_log_buf_fops_mmap(struct file *filep,
+ struct vm_area_struct *vma)
+{
+ struct vfio_container *container = filep->private_data;
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ unsigned long frag_pg_size;
+ unsigned long frag_offset;
+ phys_addr_t pa;
+ int ret = -EINVAL;
+
+ if (!log_buf->cpu_addrs) {
+ pr_err("mmap before setup, please setup log buf first\n");
+ return ret;
+ }
+
+ if (log_buf->info.frag_size < PAGE_SIZE) {
+ pr_err("mmap frag size should not less than page size!\n");
+ return ret;
+ }
+
+ frag_pg_size = log_buf->info.frag_size / PAGE_SIZE;
+ frag_offset = vma->vm_pgoff / frag_pg_size;
+
+ if (frag_offset >= log_buf->info.addrs_size) {
+ pr_err("mmap offset out of range!\n");
+ return ret;
+ }
+
+ if (vma->vm_end - vma->vm_start != log_buf->info.frag_size) {
+ pr_err("mmap size error, should be aligned with frag size!\n");
+ return ret;
+ }
+
+ pa = virt_to_phys((void *)log_buf->cpu_addrs[frag_offset]);
+ ret = remap_pfn_range(vma, vma->vm_start,
+ pa >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+ if (ret)
+ pr_err("remap_pfn_range error!\n");
+ return ret;
+}
+
+static struct device *vfio_get_dev(struct vfio_container *container)
+{
+ struct vfio_group *group = NULL;
+ struct vfio_device *device = NULL;
+
+ list_for_each_entry(group, &container->group_list, container_next) {
+ list_for_each_entry(device, &group->device_list, group_next) {
+ return device->dev;
+ }
+ }
+ return NULL;
+}
+
+static void vfio_log_buf_release_dma(struct device *dev,
+ struct vfio_log_buf *log_buf)
+{
+ int i;
+
+ for (i = 0; i < log_buf->info.addrs_size; i++) {
+ if ((log_buf->cpu_addrs && log_buf->cpu_addrs[i] != 0) &&
+ (log_buf->info.sgevec &&
+ log_buf->info.sgevec[i].addr != 0)) {
+ dma_free_coherent(dev, log_buf->info.frag_size,
+ (void *)log_buf->cpu_addrs[i],
+ log_buf->info.sgevec[i].addr);
+ log_buf->cpu_addrs[i] = 0;
+ log_buf->info.sgevec[i].addr = 0;
+ }
+ }
+}
+
+static long vfio_log_buf_alloc_dma(struct vfio_log_buf_info *info,
+ struct vfio_log_buf *log_buf, struct device *dev)
+{
+ int i;
+
+ for (i = 0; i < info->addrs_size; i++) {
+ log_buf->cpu_addrs[i] = (unsigned long)dma_alloc_coherent(dev,
+ info->frag_size, &log_buf->info.sgevec[i].addr,
+ GFP_KERNEL);
+ log_buf->info.sgevec[i].len = info->frag_size;
+ if (log_buf->cpu_addrs[i] == 0 ||
+ log_buf->info.sgevec[i].addr == 0) {
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static long vfio_log_buf_alloc_addrs(struct vfio_log_buf_info *info,
+ struct vfio_log_buf *log_buf)
+{
+ log_buf->info.sgevec = kcalloc(info->addrs_size,
+ sizeof(struct vfio_log_buf_sge), GFP_KERNEL);
+ if (!log_buf->info.sgevec)
+ return -ENOMEM;
+
+ log_buf->cpu_addrs = kcalloc(info->addrs_size,
+ sizeof(unsigned long), GFP_KERNEL);
+ if (!log_buf->cpu_addrs) {
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static long vfio_log_buf_info_valid(struct vfio_log_buf_info *info)
+{
+ if (info->addrs_size > LOG_BUF_MAX_ADDRS_SIZE ||
+ info->addrs_size == 0) {
+ pr_err("can`t support vm ram size larger than 1T or equal to 0\n");
+ return -EINVAL;
+ }
+ if (info->frag_size != LOG_BUF_FRAG_SIZE) {
+ pr_err("only support %d frag size\n", LOG_BUF_FRAG_SIZE);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static long vfio_log_buf_setup(struct vfio_container *container,
+ unsigned long data)
+{
+ struct vfio_log_buf_info info;
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ struct device *dev = NULL;
+ long ret;
+
+ if (log_buf->info.sgevec) {
+ pr_warn("log buf already setup\n");
+ return 0;
+ }
+
+ if (copy_from_user(&info, (void __user *)data,
+ sizeof(struct vfio_log_buf_info)))
+ return -EFAULT;
+
+ ret = vfio_log_buf_info_valid(&info);
+ if (ret)
+ return ret;
+
+ ret = vfio_log_buf_alloc_addrs(&info, log_buf);
+ if (ret)
+ goto err_out;
+
+ dev = vfio_get_dev(container);
+ if (!dev) {
+ pr_err("can`t get dev\n");
+ goto err_free_addrs;
+ }
+
+ ret = vfio_log_buf_alloc_dma(&info, log_buf, dev);
+ if (ret)
+ goto err_free_dma_array;
+
+ log_buf->info.uuid = info.uuid;
+ log_buf->info.buffer_size = info.buffer_size;
+ log_buf->info.frag_size = info.frag_size;
+ log_buf->info.addrs_size = info.addrs_size;
+ log_buf->buffer_state = 1;
+ return 0;
+
+err_free_dma_array:
+ vfio_log_buf_release_dma(dev, log_buf);
+err_free_addrs:
+ kfree(log_buf->cpu_addrs);
+ log_buf->cpu_addrs = NULL;
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+err_out:
+ return -ENOMEM;
+}
+
+static long vfio_log_buf_release_buffer(struct vfio_container *container)
+{
+ struct vfio_log_buf *log_buf = &container->log_buf;
+ struct device *dev = NULL;
+
+ if (log_buf->buffer_state == 0) {
+ pr_warn("buffer already released\n");
+ return 0;
+ }
+
+ dev = vfio_get_dev(container);
+ if (!dev) {
+ pr_err("can`t get dev\n");
+ return -EFAULT;
+ }
+
+ vfio_log_buf_release_dma(dev, log_buf);
+
+ kfree(log_buf->cpu_addrs);
+ log_buf->cpu_addrs = NULL;
+
+ kfree(log_buf->info.sgevec);
+ log_buf->info.sgevec = NULL;
+
+ log_buf->buffer_state = 0;
+ return 0;
+}
+
+static int vfio_log_buf_release(struct inode *inode, struct file *filep)
+{
+ struct vfio_container *container = filep->private_data;
+
+ vfio_log_buf_stop(container);
+ vfio_log_buf_release_buffer(container);
+ memset(&container->log_buf, 0, sizeof(struct vfio_log_buf));
+ return 0;
+}
+
+static long vfio_ioctl_handle_log_buf_ctl(struct vfio_container *container,
+ unsigned long arg)
+{
+ struct vfio_log_buf_ctl log_buf_ctl;
+ long ret = 0;
+
+ if (copy_from_user(&log_buf_ctl, (void __user *)arg,
+ sizeof(struct vfio_log_buf_ctl)))
+ return -EFAULT;
+
+ switch (log_buf_ctl.flags) {
+ case VFIO_DEVICE_LOG_BUF_FLAG_SETUP:
+ ret = vfio_log_buf_setup(container,
+ (unsigned long)log_buf_ctl.data);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_RELEASE:
+ ret = vfio_log_buf_release_buffer(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_START:
+ ret = vfio_log_buf_start(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STOP:
+ ret = vfio_log_buf_stop(container);
+ break;
+ case VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY:
+ ret = vfio_log_buf_query(container);
+ break;
+ default:
+ pr_err("log buf control flag incorrect\n");
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static long vfio_log_buf_fops_unl_ioctl(struct file *filep,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vfio_container *container = filep->private_data;
+ long ret = -EINVAL;
+
+ switch (cmd) {
+ case VFIO_LOG_BUF_CTL:
+ ret = vfio_ioctl_handle_log_buf_ctl(container, arg);
+ break;
+ default:
+ pr_err("log buf control cmd incorrect\n");
+ break;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long vfio_log_buf_fops_compat_ioctl(struct file *filep,
+ unsigned int cmd, unsigned long arg)
+{
+ arg = (unsigned long)compat_ptr(arg);
+ return vfio_log_buf_fops_unl_ioctl(filep, cmd, arg);
+}
+#endif /* CONFIG_COMPAT */
+
+static const struct file_operations vfio_log_buf_fops = {
+ .owner = THIS_MODULE,
+ .mmap = vfio_log_buf_fops_mmap,
+ .unlocked_ioctl = vfio_log_buf_fops_unl_ioctl,
+ .release = vfio_log_buf_release,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = vfio_log_buf_fops_compat_ioctl,
+#endif
+};
+
+static int vfio_get_log_buf_fd(struct vfio_container *container,
+ unsigned long arg)
+{
+ struct file *filep = NULL;
+ int ret;
+
+ if (container->log_buf.fd > 0)
+ return container->log_buf.fd;
+
+ ret = get_unused_fd_flags(O_CLOEXEC);
+ if (ret < 0) {
+ pr_err("get_unused_fd_flags get fd failed\n");
+ return ret;
+ }
+
+ filep = anon_inode_getfile("[vfio-log-buf]", &vfio_log_buf_fops,
+ container, O_RDWR);
+ if (IS_ERR(filep)) {
+ pr_err("anon_inode_getfile failed\n");
+ put_unused_fd(ret);
+ ret = PTR_ERR(filep);
+ return ret;
+ }
+
+ filep->f_mode |= (FMODE_READ | FMODE_WRITE | FMODE_LSEEK);
+
+ fd_install(ret, filep);
+
+ container->log_buf.fd = ret;
+ return ret;
+}
+
static long vfio_fops_unl_ioctl(struct file *filep,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
struct vfio_container *container = filep->private_data;
struct vfio_iommu_driver *driver;
@@ -1179,6 +1582,9 @@ static long vfio_fops_unl_ioctl(struct file *filep,
case VFIO_SET_IOMMU:
ret = vfio_ioctl_set_iommu(container, arg);
break;
+ case VFIO_GET_LOG_BUF_FD:
+ ret = vfio_get_log_buf_fd(container, arg);
+ break;
default:
driver = container->iommu_driver;
data = container->iommu_data;
@@ -1210,6 +1616,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
INIT_LIST_HEAD(&container->group_list);
init_rwsem(&container->group_lock);
kref_init(&container->kref);
+ memset(&container->log_buf, 0, sizeof(struct vfio_log_buf));
filep->private_data = container;
@@ -1219,9 +1626,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
static int vfio_fops_release(struct inode *inode, struct file *filep)
{
struct vfio_container *container = filep->private_data;
-
filep->private_data = NULL;
-
vfio_container_put(container);
return 0;
diff --git a/include/linux/vfio_pci_migration.h b/include/linux/vfio_pci_migration.h
new file mode 100644
index 0000000..464ffb4
--- /dev/null
+++ b/include/linux/vfio_pci_migration.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 Huawei Technologies Co., Ltd. All rights reserved.
+ */
+
+#ifndef VFIO_PCI_MIGRATION_H
+#define VFIO_PCI_MIGRATION_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#define VFIO_REGION_TYPE_MIGRATION (3)
+/* sub-types for VFIO_REGION_TYPE_MIGRATION */
+#define VFIO_REGION_SUBTYPE_MIGRATION (1)
+
+#define VFIO_MIGRATION_BUFFER_MAX_SIZE SZ_256K
+#define VFIO_MIGRATION_REGION_DATA_OFFSET \
+ (sizeof(struct vfio_device_migration_info))
+#define VFIO_DEVICE_MIGRATION_OFFSET(x) \
+ offsetof(struct vfio_device_migration_info, x)
+
+struct vfio_device_migration_info {
+ __u32 device_state; /* VFIO device state */
+#define VFIO_DEVICE_STATE_STOP (0)
+#define VFIO_DEVICE_STATE_RUNNING (1 << 0)
+#define VFIO_DEVICE_STATE_SAVING (1 << 1)
+#define VFIO_DEVICE_STATE_RESUMING (1 << 2)
+#define VFIO_DEVICE_STATE_MASK (VFIO_DEVICE_STATE_RUNNING | \
+ VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING)
+ __u32 reserved;
+
+ __u32 device_cmd;
+ __u32 version_id;
+
+ __u64 pending_bytes;
+ __u64 data_offset;
+ __u64 data_size;
+};
+
+enum {
+ VFIO_DEVICE_STOP = 0xffff0001,
+ VFIO_DEVICE_CONTINUE,
+ VFIO_DEVICE_MIGRATION_CANCEL,
+};
+
+struct vfio_log_buf_sge {
+ __u64 len;
+ __u64 addr;
+};
+
+struct vfio_log_buf_info {
+ __u32 uuid;
+ __u64 buffer_size;
+ __u64 addrs_size;
+ __u64 frag_size;
+ struct vfio_log_buf_sge *sgevec;
+};
+
+struct vfio_log_buf_ctl {
+ __u32 argsz;
+ __u32 flags;
+ #define VFIO_DEVICE_LOG_BUF_FLAG_SETUP (1 << 0)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_RELEASE (1 << 1)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_START (1 << 2)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_STOP (1 << 3)
+ #define VFIO_DEVICE_LOG_BUF_FLAG_STATUS_QUERY (1 << 4)
+ void *data;
+};
+#define VFIO_LOG_BUF_CTL _IO(VFIO_TYPE, VFIO_BASE + 21)
+#define VFIO_GET_LOG_BUF_FD _IO(VFIO_TYPE, VFIO_BASE + 22)
+#define VFIO_DEVICE_LOG_BUF_CTL _IO(VFIO_TYPE, VFIO_BASE + 23)
+
+struct vf_migration_log_info {
+ __u32 dom_uuid;
+ __u64 buffer_size;
+ __u64 sge_len;
+ __u64 sge_num;
+ struct vfio_log_buf_sge *sgevec;
+};
+
+struct vfio_device_migration_ops {
+ /* Get device information */
+ int (*get_info)(struct pci_dev *pdev,
+ struct vfio_device_migration_info *info);
+ /* Enable a vf device */
+ int (*enable)(struct pci_dev *pdev);
+ /* Disable a vf device */
+ int (*disable)(struct pci_dev *pdev);
+ /* Save a vf device */
+ int (*save)(struct pci_dev *pdev, void *base,
+ uint64_t off, uint64_t count);
+ /* Resuming a vf device */
+ int (*restore)(struct pci_dev *pdev, void *base,
+ uint64_t off, uint64_t count);
+ /* Log start a vf device */
+ int (*log_start)(struct pci_dev *pdev,
+ struct vf_migration_log_info *log_info);
+ /* Log stop a vf device */
+ int (*log_stop)(struct pci_dev *pdev, uint32_t uuid);
+ /* Get vf device log status */
+ int (*get_log_status)(struct pci_dev *pdev);
+ /* Pre enable a vf device(load_setup, before restore a vf) */
+ int (*pre_enable)(struct pci_dev *pdev);
+ /* Cancel a vf device when live migration failed (rollback) */
+ int (*cancel)(struct pci_dev *pdev);
+ /* Init a vf device */
+ int (*init)(struct pci_dev *pdev);
+ /* Uninit a vf device */
+ void (*uninit)(struct pci_dev *pdev);
+ /* Release a vf device */
+ void (*release)(struct pci_dev *pdev);
+};
+
+struct vfio_pci_vendor_mig_driver {
+ struct pci_dev *pdev;
+ unsigned char bus_num;
+ struct vfio_device_migration_ops *dev_mig_ops;
+ struct module *owner;
+ atomic_t count;
+ struct list_head list;
+};
+
+struct vfio_pci_migration_data {
+ u64 state_size;
+ struct pci_dev *vf_dev;
+ struct vfio_pci_vendor_mig_driver *mig_driver;
+ struct vfio_device_migration_info *mig_ctl;
+ void *vf_data;
+};
+
+int vfio_pci_register_migration_ops(struct vfio_device_migration_ops *ops,
+ struct module *mod, struct pci_dev *pdev);
+void vfio_pci_unregister_migration_ops(struct module *mod,
+ struct pci_dev *pdev);
+
+#endif /* VFIO_PCI_MIGRATION_H */
--
1.8.3.1
1
0

[PATCH OLK-5.10 v2 1/2] ipmi/watchdog: replace atomic_add() and atomic_sub()
by Miaohe Lin 24 Jun '22
by Miaohe Lin 24 Jun '22
24 Jun '22
From: Yejune Deng <yejune.deng(a)gmail.com>
mainline inclusion
from v5.11-rc1
commit a01a89b1db1066a6af23ae08b9a0c345b7966f0b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5DVR9
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
atomic_inc() and atomic_dec() looks better
Signed-off-by: Yejune Deng <yejune.deng(a)gmail.com>
Message-Id: <1605511807-7135-1-git-send-email-yejune.deng(a)gmail.com>
Signed-off-by: Corey Minyard <cminyard(a)mvista.com>
---
drivers/char/ipmi/ipmi_watchdog.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index f78156d93c3f..32c334e34d55 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -495,7 +495,7 @@ static void panic_halt_ipmi_heartbeat(void)
msg.cmd = IPMI_WDOG_RESET_TIMER;
msg.data = NULL;
msg.data_len = 0;
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = ipmi_request_supply_msgs(watchdog_user,
(struct ipmi_addr *) &addr,
0,
@@ -505,7 +505,7 @@ static void panic_halt_ipmi_heartbeat(void)
&panic_halt_heartbeat_recv_msg,
1);
if (rv)
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
}
static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -529,12 +529,12 @@ static void panic_halt_ipmi_set_timeout(void)
/* Wait for the messages to be free. */
while (atomic_read(&panic_done_count) != 0)
ipmi_poll_interface(watchdog_user);
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = __ipmi_set_timeout(&panic_halt_smi_msg,
&panic_halt_recv_msg,
&send_heartbeat_now);
if (rv) {
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
pr_warn("Unable to extend the watchdog timeout\n");
} else {
if (send_heartbeat_now)
--
2.23.0
1
1

23 Jun '22
From: Yejune Deng <yejune.deng(a)gmail.com>
mainline inclusion
from v5.11-rc1
commit a01a89b1db1066a6af23ae08b9a0c345b7966f0b
category: bugfix
bugzilla: NA
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
atomic_inc() and atomic_dec() looks better
Signed-off-by: Yejune Deng <yejune.deng(a)gmail.com>
Message-Id: <1605511807-7135-1-git-send-email-yejune.deng(a)gmail.com>
Signed-off-by: Corey Minyard <cminyard(a)mvista.com>
---
drivers/char/ipmi/ipmi_watchdog.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index f78156d93c3f..32c334e34d55 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -495,7 +495,7 @@ static void panic_halt_ipmi_heartbeat(void)
msg.cmd = IPMI_WDOG_RESET_TIMER;
msg.data = NULL;
msg.data_len = 0;
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = ipmi_request_supply_msgs(watchdog_user,
(struct ipmi_addr *) &addr,
0,
@@ -505,7 +505,7 @@ static void panic_halt_ipmi_heartbeat(void)
&panic_halt_heartbeat_recv_msg,
1);
if (rv)
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
}
static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -529,12 +529,12 @@ static void panic_halt_ipmi_set_timeout(void)
/* Wait for the messages to be free. */
while (atomic_read(&panic_done_count) != 0)
ipmi_poll_interface(watchdog_user);
- atomic_add(1, &panic_done_count);
+ atomic_inc(&panic_done_count);
rv = __ipmi_set_timeout(&panic_halt_smi_msg,
&panic_halt_recv_msg,
&send_heartbeat_now);
if (rv) {
- atomic_sub(1, &panic_done_count);
+ atomic_dec(&panic_done_count);
pr_warn("Unable to extend the watchdog timeout\n");
} else {
if (send_heartbeat_now)
--
2.23.0
2
2

[PATCH openEuler-5.10 01/59] bcache: fix race between setting bdev state to none and new write request direct to backing
by Zheng Zengkai 22 Jun '22
by Zheng Zengkai 22 Jun '22
22 Jun '22
From: Dongsheng Yang <dongsheng.yang(a)easystack.cn>
mainline inclusion
from v5.11-rc1
commit df4ad53242158f9f1f97daf4feddbb4f8b77f080
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I59A5L?from=project-issue
CVE: N/A
-----------------------------------------------
There is a race condition in detaching as below:
A. detaching B. Write request
(1) writing back
(2) write back done, set bdev
state to clean.
(3) cached_dev_put() and
schedule_work(&dc->detach);
(4) write data [0 - 4K] directly
into backing and ack to user.
(5) power-failure...
When we restart this bcache device, this bdev is clean but not detached,
and read [0 - 4K], we will get unexpected old data from cache device.
To fix this problem, set the bdev state to none when we writeback done
in detaching, and then if power-failure happened as above, the data in
cache will not be used in next bcache device starting, it's detached, we
will read the correct data from backing derectly.
Signed-off-by: Dongsheng Yang <dongsheng.yang(a)easystack.cn>
Signed-off-by: Coly Li <colyli(a)suse.de>
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/md/bcache/super.c | 9 ---------
drivers/md/bcache/writeback.c | 9 +++++++++
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 81f1cc5b3499..b7d9d1b79ac2 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1151,9 +1151,6 @@ static void cancel_writeback_rate_update_dwork(struct cached_dev *dc)
static void cached_dev_detach_finish(struct work_struct *w)
{
struct cached_dev *dc = container_of(w, struct cached_dev, detach);
- struct closure cl;
-
- closure_init_stack(&cl);
BUG_ON(!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags));
BUG_ON(refcount_read(&dc->count));
@@ -1167,12 +1164,6 @@ static void cached_dev_detach_finish(struct work_struct *w)
dc->writeback_thread = NULL;
}
- memset(&dc->sb.set_uuid, 0, 16);
- SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE);
-
- bch_write_bdev_super(dc, &cl);
- closure_sync(&cl);
-
mutex_lock(&bch_register_lock);
calc_cached_dev_sectors(dc->disk.c);
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index 3c74996978da..a129e4d2707c 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -705,6 +705,15 @@ static int bch_writeback_thread(void *arg)
* bch_cached_dev_detach().
*/
if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) {
+ struct closure cl;
+
+ closure_init_stack(&cl);
+ memset(&dc->sb.set_uuid, 0, 16);
+ SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE);
+
+ bch_write_bdev_super(dc, &cl);
+ closure_sync(&cl);
+
up_write(&dc->writeback_lock);
break;
}
--
2.20.1
1
58
Backport 5.10.108 LTS patches from upstream
Revert "selftests/bpf: Add test for bpf_timer overwriting crash"
smsc95xx: Ignore -ENODEV errors when device is unplugged
net: usb: Correct reset handling of smsc95xx
net: usb: Correct PHY handling of smsc95xx
perf symbols: Fix symbol size calculation condition
Input: aiptek - properly check endpoint type
scsi: mpt3sas: Page fault in reply q processing
usb: usbtmc: Fix bug in pipe direction for control transfers
usb: gadget: Fix use-after-free bug by not setting udc->dev.driver
net: mscc: ocelot: fix backwards compatibility with single-chain tc-flower
offload
net: bcmgenet: skip invalid partial checksums
bnx2x: fix built-in kernel driver load failure
net: phy: mscc: Add MODULE_FIRMWARE macros
net: dsa: Add missing of_node_put() in dsa_port_parse_of
net: handle ARPHRD_PIMREG in dev_is_mac_header_xmit()
drm/panel: simple: Fix Innolux G070Y2-L01 BPP settings
drm/imx: parallel-display: Remove bus flags check in
imx_pd_bridge_atomic_check()
hv_netvsc: Add check for kvmalloc_array
atm: eni: Add check for dma_map_single
net/packet: fix slab-out-of-bounds access in packet_recvmsg()
net: phy: marvell: Fix invalid comparison in the resume and suspend functions
esp6: fix check on ipv6_skip_exthdr's return value
vsock: each transport cycles only on its own sockets
efi: fix return value of __setup handlers
mm: swap: get rid of livelock in swapin readahead
ocfs2: fix crash when initialize filecheck kobj fails
crypto: qcom-rng - ensure buffer for generate is completely filled
already merged (2)
esp: Fix possible buffer overflow in ESP transformation
arm64: fix clang warning about TRAMP_VALIAS
Total patches = 30 - 2 = 28
Alan Stern (2):
usb: gadget: Fix use-after-free bug by not setting udc->dev.driver
usb: usbtmc: Fix bug in pipe direction for control transfers
Brian Masney (1):
crypto: qcom-rng - ensure buffer for generate is completely filled
Christoph Niedermaier (1):
drm/imx: parallel-display: Remove bus flags check in
imx_pd_bridge_atomic_check()
Dan Carpenter (1):
usb: gadget: rndis: prevent integer overflow in rndis_set_response()
Doug Berger (1):
net: bcmgenet: skip invalid partial checksums
Eric Dumazet (1):
net/packet: fix slab-out-of-bounds access in packet_recvmsg()
Fabio Estevam (1):
smsc95xx: Ignore -ENODEV errors when device is unplugged
Greg Kroah-Hartman (1):
Revert "selftests/bpf: Add test for bpf_timer overwriting crash"
Guo Ziliang (1):
mm: swap: get rid of livelock in swapin readahead
Jiasheng Jiang (2):
atm: eni: Add check for dma_map_single
hv_netvsc: Add check for kvmalloc_array
Jiyong Park (1):
vsock: each transport cycles only on its own sockets
Joseph Qi (1):
ocfs2: fix crash when initialize filecheck kobj fails
Juerg Haefliger (1):
net: phy: mscc: Add MODULE_FIRMWARE macros
Kurt Cancemi (1):
net: phy: marvell: Fix invalid comparison in the resume and suspend
functions
Manish Chopra (1):
bnx2x: fix built-in kernel driver load failure
Marek Vasut (1):
drm/panel: simple: Fix Innolux G070Y2-L01 BPP settings
Markus Reichl (1):
net: usb: Correct reset handling of smsc95xx
Martyn Welch (1):
net: usb: Correct PHY handling of smsc95xx
Matt Lupfer (1):
scsi: mpt3sas: Page fault in reply q processing
Miaoqian Lin (1):
net: dsa: Add missing of_node_put() in dsa_port_parse_of
Michael Petlan (1):
perf symbols: Fix symbol size calculation condition
Nicolas Dichtel (1):
net: handle ARPHRD_PIMREG in dev_is_mac_header_xmit()
Pavel Skripkin (1):
Input: aiptek - properly check endpoint type
Randy Dunlap (1):
efi: fix return value of __setup handlers
Sabrina Dubroca (1):
esp6: fix check on ipv6_skip_exthdr's return value
Vladimir Oltean (1):
net: mscc: ocelot: fix backwards compatibility with single-chain
tc-flower offload
drivers/atm/eni.c | 2 +
drivers/crypto/qcom-rng.c | 17 ++--
drivers/firmware/efi/apple-properties.c | 2 +-
drivers/firmware/efi/efi.c | 2 +-
drivers/gpu/drm/imx/parallel-display.c | 8 --
drivers/gpu/drm/panel/panel-simple.c | 2 +-
drivers/input/tablet/aiptek.c | 10 +--
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 -
.../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 28 +++---
.../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 15 +---
.../net/ethernet/broadcom/genet/bcmgenet.c | 6 +-
drivers/net/ethernet/mscc/ocelot_flower.c | 16 +++-
drivers/net/hyperv/netvsc_drv.c | 3 +
drivers/net/phy/marvell.c | 8 +-
drivers/net/phy/mscc/mscc_main.c | 3 +
drivers/net/usb/smsc95xx.c | 86 +++++++++++--------
drivers/scsi/mpt3sas/mpt3sas_base.c | 5 +-
drivers/usb/class/usbtmc.c | 13 ++-
drivers/usb/gadget/function/rndis.c | 1 +
drivers/usb/gadget/udc/core.c | 3 -
drivers/vhost/vsock.c | 3 +-
fs/ocfs2/super.c | 22 ++---
include/linux/if_arp.h | 1 +
include/net/af_vsock.h | 3 +-
mm/swap_state.c | 2 +-
net/dsa/dsa2.c | 1 +
net/ipv6/esp6.c | 3 +-
net/packet/af_packet.c | 11 ++-
net/vmw_vsock/af_vsock.c | 9 +-
net/vmw_vsock/virtio_transport.c | 7 +-
net/vmw_vsock/vmci_transport.c | 5 +-
tools/perf/util/symbol.c | 2 +-
.../selftests/bpf/prog_tests/timer_crash.c | 32 -------
.../testing/selftests/bpf/progs/timer_crash.c | 54 ------------
34 files changed, 175 insertions(+), 212 deletions(-)
delete mode 100644 tools/testing/selftests/bpf/prog_tests/timer_crash.c
delete mode 100644 tools/testing/selftests/bpf/progs/timer_crash.c
--
2.20.1
1
28

22 Jun '22
From: Kaixu Xia <kaixuxia(a)tencent.com>
mainline inclusion
from mainline-v5.11-rc6
commit 237d7887ae723af7d978e8b9a385fdff416f357b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5AG18
CVE: NA
--------------------------------
The quota option 'usrquota' should be shown if both the XFS_UQUOTA_ACCT
and XFS_UQUOTA_ENFD flags are set. The option 'uqnoenforce' should be
shown when only the XFS_UQUOTA_ACCT flag is set. The current code logic
seems wrong, Fix it and show proper options.
Signed-off-by: Kaixu Xia <kaixuxia(a)tencent.com>
Reviewed-by: Darrick J. Wong <darrick.wong(a)oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong(a)oracle.com>
Signed-off-by: tangbin <tangbin(a)cmss.chinamobile.com>
Reviewed-by: Xuenan Guo <guoxuenan(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
fs/xfs/xfs_super.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index e126bc6cdeb8..5d8e3a4d2671 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -505,10 +505,12 @@ xfs_showargs(
seq_printf(m, ",swidth=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
- if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
- seq_puts(m, ",usrquota");
- else if (mp->m_qflags & XFS_UQUOTA_ACCT)
- seq_puts(m, ",uqnoenforce");
+ if (mp->m_qflags & XFS_UQUOTA_ACCT) {
+ if (mp->m_qflags & XFS_UQUOTA_ENFD)
+ seq_puts(m, ",usrquota");
+ else
+ seq_puts(m, ",uqnoenforce");
+ }
if (mp->m_qflags & XFS_PQUOTA_ACCT) {
if (mp->m_qflags & XFS_PQUOTA_ENFD)
--
2.25.1
1
0

[PATCH openEuler-5.10-LTS 01/55] bcache: fix race between setting bdev state to none and new write request direct to backing
by Zheng Zengkai 21 Jun '22
by Zheng Zengkai 21 Jun '22
21 Jun '22
From: Dongsheng Yang <dongsheng.yang(a)easystack.cn>
mainline inclusion
from v5.11-rc1
commit df4ad53242158f9f1f97daf4feddbb4f8b77f080
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I59A5L?from=project-issue
CVE: N/A
-----------------------------------------------
There is a race condition in detaching as below:
A. detaching B. Write request
(1) writing back
(2) write back done, set bdev
state to clean.
(3) cached_dev_put() and
schedule_work(&dc->detach);
(4) write data [0 - 4K] directly
into backing and ack to user.
(5) power-failure...
When we restart this bcache device, this bdev is clean but not detached,
and read [0 - 4K], we will get unexpected old data from cache device.
To fix this problem, set the bdev state to none when we writeback done
in detaching, and then if power-failure happened as above, the data in
cache will not be used in next bcache device starting, it's detached, we
will read the correct data from backing derectly.
Signed-off-by: Dongsheng Yang <dongsheng.yang(a)easystack.cn>
Signed-off-by: Coly Li <colyli(a)suse.de>
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/md/bcache/super.c | 9 ---------
drivers/md/bcache/writeback.c | 9 +++++++++
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 81f1cc5b3499..b7d9d1b79ac2 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1151,9 +1151,6 @@ static void cancel_writeback_rate_update_dwork(struct cached_dev *dc)
static void cached_dev_detach_finish(struct work_struct *w)
{
struct cached_dev *dc = container_of(w, struct cached_dev, detach);
- struct closure cl;
-
- closure_init_stack(&cl);
BUG_ON(!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags));
BUG_ON(refcount_read(&dc->count));
@@ -1167,12 +1164,6 @@ static void cached_dev_detach_finish(struct work_struct *w)
dc->writeback_thread = NULL;
}
- memset(&dc->sb.set_uuid, 0, 16);
- SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE);
-
- bch_write_bdev_super(dc, &cl);
- closure_sync(&cl);
-
mutex_lock(&bch_register_lock);
calc_cached_dev_sectors(dc->disk.c);
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index 3c74996978da..a129e4d2707c 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -705,6 +705,15 @@ static int bch_writeback_thread(void *arg)
* bch_cached_dev_detach().
*/
if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) {
+ struct closure cl;
+
+ closure_init_stack(&cl);
+ memset(&dc->sb.set_uuid, 0, 16);
+ SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE);
+
+ bch_write_bdev_super(dc, &cl);
+ closure_sync(&cl);
+
up_write(&dc->writeback_lock);
break;
}
--
2.20.1
1
54
Backport 5.10.108 LTS patches from upstream
Revert "selftests/bpf: Add test for bpf_timer overwriting crash"
smsc95xx: Ignore -ENODEV errors when device is unplugged
net: usb: Correct reset handling of smsc95xx
net: usb: Correct PHY handling of smsc95xx
perf symbols: Fix symbol size calculation condition
Input: aiptek - properly check endpoint type
scsi: mpt3sas: Page fault in reply q processing
usb: usbtmc: Fix bug in pipe direction for control transfers
usb: gadget: Fix use-after-free bug by not setting udc->dev.driver
net: mscc: ocelot: fix backwards compatibility with single-chain tc-flower
offload
net: bcmgenet: skip invalid partial checksums
bnx2x: fix built-in kernel driver load failure
net: phy: mscc: Add MODULE_FIRMWARE macros
net: dsa: Add missing of_node_put() in dsa_port_parse_of
net: handle ARPHRD_PIMREG in dev_is_mac_header_xmit()
drm/panel: simple: Fix Innolux G070Y2-L01 BPP settings
drm/imx: parallel-display: Remove bus flags check in
imx_pd_bridge_atomic_check()
hv_netvsc: Add check for kvmalloc_array
atm: eni: Add check for dma_map_single
net/packet: fix slab-out-of-bounds access in packet_recvmsg()
net: phy: marvell: Fix invalid comparison in the resume and suspend functions
esp6: fix check on ipv6_skip_exthdr's return value
vsock: each transport cycles only on its own sockets
efi: fix return value of __setup handlers
mm: swap: get rid of livelock in swapin readahead
ocfs2: fix crash when initialize filecheck kobj fails
crypto: qcom-rng - ensure buffer for generate is completely filled
already merged (2)
esp: Fix possible buffer overflow in ESP transformation
arm64: fix clang warning about TRAMP_VALIAS
Total patches = 30 - 2 = 28
Alan Stern (2):
usb: gadget: Fix use-after-free bug by not setting udc->dev.driver
usb: usbtmc: Fix bug in pipe direction for control transfers
Brian Masney (1):
crypto: qcom-rng - ensure buffer for generate is completely filled
Christoph Niedermaier (1):
drm/imx: parallel-display: Remove bus flags check in
imx_pd_bridge_atomic_check()
Dan Carpenter (1):
usb: gadget: rndis: prevent integer overflow in rndis_set_response()
Doug Berger (1):
net: bcmgenet: skip invalid partial checksums
Eric Dumazet (1):
net/packet: fix slab-out-of-bounds access in packet_recvmsg()
Fabio Estevam (1):
smsc95xx: Ignore -ENODEV errors when device is unplugged
Greg Kroah-Hartman (1):
Revert "selftests/bpf: Add test for bpf_timer overwriting crash"
Guo Ziliang (1):
mm: swap: get rid of livelock in swapin readahead
Jiasheng Jiang (2):
atm: eni: Add check for dma_map_single
hv_netvsc: Add check for kvmalloc_array
Jiyong Park (1):
vsock: each transport cycles only on its own sockets
Joseph Qi (1):
ocfs2: fix crash when initialize filecheck kobj fails
Juerg Haefliger (1):
net: phy: mscc: Add MODULE_FIRMWARE macros
Kurt Cancemi (1):
net: phy: marvell: Fix invalid comparison in the resume and suspend
functions
Manish Chopra (1):
bnx2x: fix built-in kernel driver load failure
Marek Vasut (1):
drm/panel: simple: Fix Innolux G070Y2-L01 BPP settings
Markus Reichl (1):
net: usb: Correct reset handling of smsc95xx
Martyn Welch (1):
net: usb: Correct PHY handling of smsc95xx
Matt Lupfer (1):
scsi: mpt3sas: Page fault in reply q processing
Miaoqian Lin (1):
net: dsa: Add missing of_node_put() in dsa_port_parse_of
Michael Petlan (1):
perf symbols: Fix symbol size calculation condition
Nicolas Dichtel (1):
net: handle ARPHRD_PIMREG in dev_is_mac_header_xmit()
Pavel Skripkin (1):
Input: aiptek - properly check endpoint type
Randy Dunlap (1):
efi: fix return value of __setup handlers
Sabrina Dubroca (1):
esp6: fix check on ipv6_skip_exthdr's return value
Vladimir Oltean (1):
net: mscc: ocelot: fix backwards compatibility with single-chain
tc-flower offload
drivers/atm/eni.c | 2 +
drivers/crypto/qcom-rng.c | 17 ++--
drivers/firmware/efi/apple-properties.c | 2 +-
drivers/firmware/efi/efi.c | 2 +-
drivers/gpu/drm/imx/parallel-display.c | 8 --
drivers/gpu/drm/panel/panel-simple.c | 2 +-
drivers/input/tablet/aiptek.c | 10 +--
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 -
.../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 28 +++---
.../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 15 +---
.../net/ethernet/broadcom/genet/bcmgenet.c | 6 +-
drivers/net/ethernet/mscc/ocelot_flower.c | 16 +++-
drivers/net/hyperv/netvsc_drv.c | 3 +
drivers/net/phy/marvell.c | 8 +-
drivers/net/phy/mscc/mscc_main.c | 3 +
drivers/net/usb/smsc95xx.c | 86 +++++++++++--------
drivers/scsi/mpt3sas/mpt3sas_base.c | 5 +-
drivers/usb/class/usbtmc.c | 13 ++-
drivers/usb/gadget/function/rndis.c | 1 +
drivers/usb/gadget/udc/core.c | 3 -
drivers/vhost/vsock.c | 3 +-
fs/ocfs2/super.c | 22 ++---
include/linux/if_arp.h | 1 +
include/net/af_vsock.h | 3 +-
mm/swap_state.c | 2 +-
net/dsa/dsa2.c | 1 +
net/ipv6/esp6.c | 3 +-
net/packet/af_packet.c | 11 ++-
net/vmw_vsock/af_vsock.c | 9 +-
net/vmw_vsock/virtio_transport.c | 7 +-
net/vmw_vsock/vmci_transport.c | 5 +-
tools/perf/util/symbol.c | 2 +-
.../selftests/bpf/prog_tests/timer_crash.c | 32 -------
.../testing/selftests/bpf/progs/timer_crash.c | 54 ------------
34 files changed, 175 insertions(+), 212 deletions(-)
delete mode 100644 tools/testing/selftests/bpf/prog_tests/timer_crash.c
delete mode 100644 tools/testing/selftests/bpf/progs/timer_crash.c
--
2.20.1
1
28

[PATCH openEuler-1.0-LTS 1/4] sched: Introduce qos smt expeller for co-location
by liuzhengyuan@kylinos.cn 21 Jun '22
by liuzhengyuan@kylinos.cn 21 Jun '22
21 Jun '22
From: Guan Jing <guanjing6(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52611
CVE: NA
--------------------------------
We introduce the qos smt expeller, which lets
online tasks to expel offline tasks on the smt sibling cpus,
and exclusively occupy CPU resources.In this way we are
able to improve QOS of online tasks in co-location.
Change-Id: I1860d20d5e78467773e67cc47b4fa2d1f0110783
Signed-off-by: Guan Jing <guanjing6(a)huawei.com>
Reviewed-by: Chen Hui <judy.chenhui(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Signed-off-by: Zhengyuan Liu <liuzhengyuan(a)kylinos.cn>
---
init/Kconfig | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/init/Kconfig b/init/Kconfig
index ac1c864524ac..dd81d19e2fcb 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -794,6 +794,15 @@ config QOS_SCHED
default n
+config QOS_SCHED_SMT_EXPELLER
+ bool "Qos smt expeller"
+ depends on SCHED_SMT
+ depends on QOS_SCHED
+ default n
+ help
+ This feature enable online tasks to expel offline tasks
+ on the smt sibling cpus, and exclusively occupy CPU resources.
+
config FAIR_GROUP_SCHED
bool "Group scheduling for SCHED_OTHER"
depends on CGROUP_SCHED
--
2.25.1
1
3

[PATCH openEuler-1.0-LTS 1/6] drivers core: Use sysfs_emit and sysfs_emit_at for show(device *...) functions
by Yongqiang Liu 21 Jun '22
by Yongqiang Liu 21 Jun '22
21 Jun '22
From: Joe Perches <joe(a)perches.com>
mainline inclusion
from mainline-v5.10-rc1
commit aa838896d87af561a33ecefea1caa4c15a68bc47
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5C32F
CVE: CVE-2022-20166
----------------------------------------------
Convert the various sprintf fmaily calls in sysfs device show functions
to sysfs_emit and sysfs_emit_at for PAGE_SIZE buffer safety.
Done with:
$ spatch -sp-file sysfs_emit_dev.cocci --in-place --max-width=80 .
And cocci script:
$ cat sysfs_emit_dev.cocci
@@
identifier d_show;
identifier dev, attr, buf;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
return
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier d_show;
identifier dev, attr, buf;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
return
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier d_show;
identifier dev, attr, buf;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
return
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
}
@@
identifier d_show;
identifier dev, attr, buf;
expression chr;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
return
- strcpy(buf, chr);
+ sysfs_emit(buf, chr);
...>
}
@@
identifier d_show;
identifier dev, attr, buf;
identifier len;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
len =
- sprintf(buf,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier d_show;
identifier dev, attr, buf;
identifier len;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
len =
- snprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier d_show;
identifier dev, attr, buf;
identifier len;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
len =
- scnprintf(buf, PAGE_SIZE,
+ sysfs_emit(buf,
...);
...>
return len;
}
@@
identifier d_show;
identifier dev, attr, buf;
identifier len;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
<...
- len += scnprintf(buf + len, PAGE_SIZE - len,
+ len += sysfs_emit_at(buf, len,
...);
...>
return len;
}
@@
identifier d_show;
identifier dev, attr, buf;
expression chr;
@@
ssize_t d_show(struct device *dev, struct device_attribute *attr, char *buf)
{
...
- strcpy(buf, chr);
- return strlen(buf);
+ return sysfs_emit(buf, chr);
}
Signed-off-by: Joe Perches <joe(a)perches.com>
Link: https://lore.kernel.org/r/3d033c33056d88bbe34d4ddb62afd05ee166ab9a.16002859…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
drivers/base/node.c
Signed-off-by: Guo Mengqi <guomengqi3(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/base/arch_topology.c | 3 +-
drivers/base/cacheinfo.c | 18 ++++-----
drivers/base/core.c | 8 ++--
drivers/base/cpu.c | 26 ++++++------
drivers/base/firmware_loader/fallback.c | 2 +-
drivers/base/memory.c | 24 +++++------
drivers/base/node.c | 26 ++++++------
drivers/base/platform.c | 2 +-
drivers/base/power/sysfs.c | 53 +++++++++++++------------
drivers/base/soc.c | 8 ++--
10 files changed, 86 insertions(+), 84 deletions(-)
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 7157e4039b4c..729dded51e7b 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -42,7 +42,8 @@ static ssize_t cpu_capacity_show(struct device *dev,
{
struct cpu *cpu = container_of(dev, struct cpu, dev);
- return sprintf(buf, "%lu\n", topology_get_cpu_scale(NULL, cpu->dev.id));
+ return sysfs_emit(buf, "%lu\n",
+ topology_get_cpu_scale(NULL, cpu->dev.id));
}
static DEVICE_ATTR_RO(cpu_capacity);
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
index aee69d78c2e7..f7d107ca1a66 100644
--- a/drivers/base/cacheinfo.c
+++ b/drivers/base/cacheinfo.c
@@ -415,7 +415,7 @@ static ssize_t size_show(struct device *dev,
{
struct cacheinfo *this_leaf = dev_get_drvdata(dev);
- return sprintf(buf, "%uK\n", this_leaf->size >> 10);
+ return sysfs_emit(buf, "%uK\n", this_leaf->size >> 10);
}
static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf)
@@ -445,11 +445,11 @@ static ssize_t type_show(struct device *dev,
switch (this_leaf->type) {
case CACHE_TYPE_DATA:
- return sprintf(buf, "Data\n");
+ return sysfs_emit(buf, "Data\n");
case CACHE_TYPE_INST:
- return sprintf(buf, "Instruction\n");
+ return sysfs_emit(buf, "Instruction\n");
case CACHE_TYPE_UNIFIED:
- return sprintf(buf, "Unified\n");
+ return sysfs_emit(buf, "Unified\n");
default:
return -EINVAL;
}
@@ -463,11 +463,11 @@ static ssize_t allocation_policy_show(struct device *dev,
int n = 0;
if ((ci_attr & CACHE_READ_ALLOCATE) && (ci_attr & CACHE_WRITE_ALLOCATE))
- n = sprintf(buf, "ReadWriteAllocate\n");
+ n = sysfs_emit(buf, "ReadWriteAllocate\n");
else if (ci_attr & CACHE_READ_ALLOCATE)
- n = sprintf(buf, "ReadAllocate\n");
+ n = sysfs_emit(buf, "ReadAllocate\n");
else if (ci_attr & CACHE_WRITE_ALLOCATE)
- n = sprintf(buf, "WriteAllocate\n");
+ n = sysfs_emit(buf, "WriteAllocate\n");
return n;
}
@@ -479,9 +479,9 @@ static ssize_t write_policy_show(struct device *dev,
int n = 0;
if (ci_attr & CACHE_WRITE_THROUGH)
- n = sprintf(buf, "WriteThrough\n");
+ n = sysfs_emit(buf, "WriteThrough\n");
else if (ci_attr & CACHE_WRITE_BACK)
- n = sprintf(buf, "WriteBack\n");
+ n = sysfs_emit(buf, "WriteBack\n");
return n;
}
diff --git a/drivers/base/core.c b/drivers/base/core.c
index f6d8a4246adf..b4f80e82a91f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -994,7 +994,7 @@ ssize_t device_show_ulong(struct device *dev,
char *buf)
{
struct dev_ext_attribute *ea = to_ext_attr(attr);
- return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
+ return sysfs_emit(buf, "%lx\n", *(unsigned long *)(ea->var));
}
EXPORT_SYMBOL_GPL(device_show_ulong);
@@ -1019,7 +1019,7 @@ ssize_t device_show_int(struct device *dev,
{
struct dev_ext_attribute *ea = to_ext_attr(attr);
- return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
+ return sysfs_emit(buf, "%d\n", *(int *)(ea->var));
}
EXPORT_SYMBOL_GPL(device_show_int);
@@ -1040,7 +1040,7 @@ ssize_t device_show_bool(struct device *dev, struct device_attribute *attr,
{
struct dev_ext_attribute *ea = to_ext_attr(attr);
- return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var));
+ return sysfs_emit(buf, "%d\n", *(bool *)(ea->var));
}
EXPORT_SYMBOL_GPL(device_show_bool);
@@ -1273,7 +1273,7 @@ static ssize_t online_show(struct device *dev, struct device_attribute *attr,
device_lock(dev);
val = !dev->offline;
device_unlock(dev);
- return sprintf(buf, "%u\n", val);
+ return sysfs_emit(buf, "%u\n", val);
}
static ssize_t online_store(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 1df057486176..128e5867c35d 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -156,7 +156,7 @@ static ssize_t show_crash_notes(struct device *dev, struct device_attribute *att
* operation should be safe. No locking required.
*/
addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum));
- rc = sprintf(buf, "%Lx\n", addr);
+ rc = sysfs_emit(buf, "%Lx\n", addr);
return rc;
}
static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL);
@@ -167,7 +167,7 @@ static ssize_t show_crash_notes_size(struct device *dev,
{
ssize_t rc;
- rc = sprintf(buf, "%zu\n", sizeof(note_buf_t));
+ rc = sysfs_emit(buf, "%zu\n", sizeof(note_buf_t));
return rc;
}
static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL);
@@ -328,8 +328,8 @@ static ssize_t print_cpu_modalias(struct device *dev,
ssize_t n;
u32 i;
- n = sprintf(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
- CPU_FEATURE_TYPEVAL);
+ n = sysfs_emit(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
+ CPU_FEATURE_TYPEVAL);
for (i = 0; i < MAX_CPU_FEATURES; i++)
if (cpu_have_feature(i)) {
@@ -519,56 +519,56 @@ static void __init cpu_dev_register_generic(void)
ssize_t __weak cpu_show_meltdown(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_spectre_v1(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_spectre_v2(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_spec_store_bypass(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_l1tf(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_mds(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_tsx_async_abort(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_itlb_multihit(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
ssize_t __weak cpu_show_srbds(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "Not affected\n");
+ return sysfs_emit(buf, "Not affected\n");
}
static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index 818d8c37d70a..ab619da92734 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -216,7 +216,7 @@ static ssize_t firmware_loading_show(struct device *dev,
loading = fw_sysfs_loading(fw_sysfs->fw_priv);
mutex_unlock(&fw_lock);
- return sprintf(buf, "%d\n", loading);
+ return sysfs_emit(buf, "%d\n", loading);
}
/* one pages buffer should be mapped/unmapped only once */
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 1b97f305173f..54225b812cd7 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -140,7 +140,7 @@ static ssize_t phys_index_show(struct device *dev,
unsigned long phys_index;
phys_index = mem->start_section_nr / sections_per_block;
- return sprintf(buf, "%08lx\n", phys_index);
+ return sysfs_emit(buf, "%08lx\n", phys_index);
}
/*
@@ -164,7 +164,7 @@ static ssize_t removable_show(struct device *dev, struct device_attribute *attr,
}
out:
- return sprintf(buf, "%d\n", ret);
+ return sysfs_emit(buf, "%d\n", ret);
}
/*
@@ -182,17 +182,17 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
*/
switch (mem->state) {
case MEM_ONLINE:
- len = sprintf(buf, "online\n");
+ len = sysfs_emit(buf, "online\n");
break;
case MEM_OFFLINE:
- len = sprintf(buf, "offline\n");
+ len = sysfs_emit(buf, "offline\n");
break;
case MEM_GOING_OFFLINE:
- len = sprintf(buf, "going-offline\n");
+ len = sysfs_emit(buf, "going-offline\n");
break;
default:
- len = sprintf(buf, "ERROR-UNKNOWN-%ld\n",
- mem->state);
+ len = sysfs_emit(buf, "ERROR-UNKNOWN-%ld\n",
+ mem->state);
WARN_ON(1);
break;
}
@@ -389,7 +389,7 @@ static ssize_t phys_device_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct memory_block *mem = to_memory_block(dev);
- return sprintf(buf, "%d\n", mem->phys_device);
+ return sysfs_emit(buf, "%d\n", mem->phys_device);
}
#ifdef CONFIG_MEMORY_HOTREMOVE
@@ -427,7 +427,7 @@ static ssize_t valid_zones_show(struct device *dev,
*/
if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages,
&valid_start_pfn, &valid_end_pfn))
- return sprintf(buf, "none\n");
+ return sysfs_emit(buf, "none\n");
start_pfn = valid_start_pfn;
strcat(buf, page_zone(pfn_to_page(start_pfn))->name);
goto out;
@@ -461,7 +461,7 @@ static DEVICE_ATTR_RO(removable);
static ssize_t block_size_bytes_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%lx\n", get_memory_block_size());
+ return sysfs_emit(buf, "%lx\n", get_memory_block_size());
}
static DEVICE_ATTR_RO(block_size_bytes);
@@ -473,8 +473,8 @@ static DEVICE_ATTR_RO(block_size_bytes);
static ssize_t auto_online_blocks_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%s\n",
- online_type_to_str[memhp_default_online_type]);
+ return sysfs_emit(buf, "%s\n",
+ online_type_to_str[memhp_default_online_type]);
}
static ssize_t auto_online_blocks_store(struct device *dev,
diff --git a/drivers/base/node.c b/drivers/base/node.c
index ac44db3f63c7..7a807e471fbf 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -457,19 +457,19 @@ static DEVICE_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
static ssize_t node_read_numastat(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf,
- "numa_hit %lu\n"
- "numa_miss %lu\n"
- "numa_foreign %lu\n"
- "interleave_hit %lu\n"
- "local_node %lu\n"
- "other_node %lu\n",
- sum_zone_numa_state(dev->id, NUMA_HIT),
- sum_zone_numa_state(dev->id, NUMA_MISS),
- sum_zone_numa_state(dev->id, NUMA_FOREIGN),
- sum_zone_numa_state(dev->id, NUMA_INTERLEAVE_HIT),
- sum_zone_numa_state(dev->id, NUMA_LOCAL),
- sum_zone_numa_state(dev->id, NUMA_OTHER));
+ return sysfs_emit(buf,
+ "numa_hit %lu\n"
+ "numa_miss %lu\n"
+ "numa_foreign %lu\n"
+ "interleave_hit %lu\n"
+ "local_node %lu\n"
+ "other_node %lu\n",
+ sum_zone_numa_state(dev->id, NUMA_HIT),
+ sum_zone_numa_state(dev->id, NUMA_MISS),
+ sum_zone_numa_state(dev->id, NUMA_FOREIGN),
+ sum_zone_numa_state(dev->id, NUMA_INTERLEAVE_HIT),
+ sum_zone_numa_state(dev->id, NUMA_LOCAL),
+ sum_zone_numa_state(dev->id, NUMA_OTHER));
}
static DEVICE_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 349c2754eed7..fe3f4225d80a 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -907,7 +907,7 @@ static ssize_t driver_override_show(struct device *dev,
ssize_t len;
device_lock(dev);
- len = sprintf(buf, "%s\n", pdev->driver_override);
+ len = sysfs_emit(buf, "%s\n", pdev->driver_override);
device_unlock(dev);
return len;
}
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index d713738ce796..d071d5d1a6d7 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -101,7 +101,7 @@ static const char ctrl_on[] = "on";
static ssize_t control_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "%s\n",
+ return sysfs_emit(buf, "%s\n",
dev->power.runtime_auto ? ctrl_auto : ctrl_on);
}
@@ -127,7 +127,8 @@ static ssize_t runtime_active_time_show(struct device *dev,
int ret;
spin_lock_irq(&dev->power.lock);
update_pm_runtime_accounting(dev);
- ret = sprintf(buf, "%i\n", jiffies_to_msecs(dev->power.active_jiffies));
+ ret = sysfs_emit(buf, "%i\n",
+ jiffies_to_msecs(dev->power.active_jiffies));
spin_unlock_irq(&dev->power.lock);
return ret;
}
@@ -140,8 +141,8 @@ static ssize_t runtime_suspended_time_show(struct device *dev,
int ret;
spin_lock_irq(&dev->power.lock);
update_pm_runtime_accounting(dev);
- ret = sprintf(buf, "%i\n",
- jiffies_to_msecs(dev->power.suspended_jiffies));
+ ret = sysfs_emit(buf, "%i\n",
+ jiffies_to_msecs(dev->power.suspended_jiffies));
spin_unlock_irq(&dev->power.lock);
return ret;
}
@@ -175,7 +176,7 @@ static ssize_t runtime_status_show(struct device *dev,
return -EIO;
}
}
- return sprintf(buf, p);
+ return sysfs_emit(buf, p);
}
static DEVICE_ATTR_RO(runtime_status);
@@ -185,7 +186,7 @@ static ssize_t autosuspend_delay_ms_show(struct device *dev,
{
if (!dev->power.use_autosuspend)
return -EIO;
- return sprintf(buf, "%d\n", dev->power.autosuspend_delay);
+ return sysfs_emit(buf, "%d\n", dev->power.autosuspend_delay);
}
static ssize_t autosuspend_delay_ms_store(struct device *dev,
@@ -214,11 +215,11 @@ static ssize_t pm_qos_resume_latency_us_show(struct device *dev,
s32 value = dev_pm_qos_requested_resume_latency(dev);
if (value == 0)
- return sprintf(buf, "n/a\n");
+ return sysfs_emit(buf, "n/a\n");
if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
value = 0;
- return sprintf(buf, "%d\n", value);
+ return sysfs_emit(buf, "%d\n", value);
}
static ssize_t pm_qos_resume_latency_us_store(struct device *dev,
@@ -258,11 +259,11 @@ static ssize_t pm_qos_latency_tolerance_us_show(struct device *dev,
s32 value = dev_pm_qos_get_user_latency_tolerance(dev);
if (value < 0)
- return sprintf(buf, "auto\n");
+ return sysfs_emit(buf, "auto\n");
if (value == PM_QOS_LATENCY_ANY)
- return sprintf(buf, "any\n");
+ return sysfs_emit(buf, "any\n");
- return sprintf(buf, "%d\n", value);
+ return sysfs_emit(buf, "%d\n", value);
}
static ssize_t pm_qos_latency_tolerance_us_store(struct device *dev,
@@ -294,8 +295,8 @@ static ssize_t pm_qos_no_power_off_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev)
- & PM_QOS_FLAG_NO_POWER_OFF));
+ return sysfs_emit(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev)
+ & PM_QOS_FLAG_NO_POWER_OFF));
}
static ssize_t pm_qos_no_power_off_store(struct device *dev,
@@ -323,9 +324,9 @@ static const char _disabled[] = "disabled";
static ssize_t wakeup_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "%s\n", device_can_wakeup(dev)
- ? (device_may_wakeup(dev) ? _enabled : _disabled)
- : "");
+ return sysfs_emit(buf, "%s\n", device_can_wakeup(dev)
+ ? (device_may_wakeup(dev) ? _enabled : _disabled)
+ : "");
}
static ssize_t wakeup_store(struct device *dev, struct device_attribute *attr,
@@ -511,7 +512,7 @@ static DEVICE_ATTR_RO(wakeup_prevent_sleep_time_ms);
static ssize_t runtime_usage_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", atomic_read(&dev->power.usage_count));
+ return sysfs_emit(buf, "%d\n", atomic_read(&dev->power.usage_count));
}
static DEVICE_ATTR_RO(runtime_usage);
@@ -519,8 +520,8 @@ static ssize_t runtime_active_kids_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "%d\n", dev->power.ignore_children ?
- 0 : atomic_read(&dev->power.child_count));
+ return sysfs_emit(buf, "%d\n", dev->power.ignore_children ?
+ 0 : atomic_read(&dev->power.child_count));
}
static DEVICE_ATTR_RO(runtime_active_kids);
@@ -528,12 +529,12 @@ static ssize_t runtime_enabled_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
if (dev->power.disable_depth && (dev->power.runtime_auto == false))
- return sprintf(buf, "disabled & forbidden\n");
+ return sysfs_emit(buf, "disabled & forbidden\n");
if (dev->power.disable_depth)
- return sprintf(buf, "disabled\n");
+ return sysfs_emit(buf, "disabled\n");
if (dev->power.runtime_auto == false)
- return sprintf(buf, "forbidden\n");
- return sprintf(buf, "enabled\n");
+ return sysfs_emit(buf, "forbidden\n");
+ return sysfs_emit(buf, "enabled\n");
}
static DEVICE_ATTR_RO(runtime_enabled);
@@ -541,9 +542,9 @@ static DEVICE_ATTR_RO(runtime_enabled);
static ssize_t async_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "%s\n",
- device_async_suspend_enabled(dev) ?
- _enabled : _disabled);
+ return sysfs_emit(buf, "%s\n",
+ device_async_suspend_enabled(dev) ?
+ _enabled : _disabled);
}
static ssize_t async_store(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
index 7e91894a380b..23bc9eb794a2 100644
--- a/drivers/base/soc.c
+++ b/drivers/base/soc.c
@@ -72,13 +72,13 @@ static ssize_t soc_info_get(struct device *dev,
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
if (attr == &dev_attr_machine)
- return sprintf(buf, "%s\n", soc_dev->attr->machine);
+ return sysfs_emit(buf, "%s\n", soc_dev->attr->machine);
if (attr == &dev_attr_family)
- return sprintf(buf, "%s\n", soc_dev->attr->family);
+ return sysfs_emit(buf, "%s\n", soc_dev->attr->family);
if (attr == &dev_attr_revision)
- return sprintf(buf, "%s\n", soc_dev->attr->revision);
+ return sysfs_emit(buf, "%s\n", soc_dev->attr->revision);
if (attr == &dev_attr_soc_id)
- return sprintf(buf, "%s\n", soc_dev->attr->soc_id);
+ return sysfs_emit(buf, "%s\n", soc_dev->attr->soc_id);
return -EINVAL;
--
2.25.1
1
5

21 Jun '22
From: jiazhenyuan <jiazhenyuan(a)uniontech.com>
mainline inclusion
from mainline-v5.1.0-rc2
commit b3198c38f02d54a5e964258a2180d502abe6eaf0
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5D0PL
CVE: NA
--------------------------------
The 50 ms default timeout waiting for vblanks is too small
for the first vblank from the ST-Ericsson MCDE display
controller over DSI. Presumably this is because the DSI
display is command-mode only and the state machine will
take some time setting up its state for the first display
update, and we hit a timeout. 100 ms makes it pass without
problems.
Signed-off-by: Linus Walleij <linus.walleij(a)linaro.org>
Reviewed-by: Ville Syrjälä <ville.syrjala(a)linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20190430093746.26485-1-linus.…
Signed-off-by: jiazhenyuan <jiazhenyuan(a)uniontech.com>
---
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index c22062cc9992..f9306c3e9bab 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1380,7 +1380,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
ret = wait_event_timeout(dev->vblank[i].queue,
old_state->crtcs[i].last_vblank_count !=
drm_crtc_vblank_count(crtc),
- msecs_to_jiffies(50));
+ msecs_to_jiffies(100));
WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n",
crtc->base.id, crtc->name);
--
2.27.0
1
0

[PATCH openEuler-1.0-LTS] RDMA/cma: Do not change route.addr.src_addr.ss_family
by tangbin 21 Jun '22
by tangbin 21 Jun '22
21 Jun '22
From: Jason Gunthorpe <jgg(a)nvidia.com>
mainline inclusion
from mainline-v5.15-rc4
commit bc0bdc5afaa740d782fbf936aaeebd65e5c2921d
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I59840
CVE: CVE-2021-4028
--------------------------------
Conflicts:
The conditional statement to verify RDMA_CM_IDLE state is a little bit
different from the upstream to 4.19. The commit 732d41c545bb (RDMA/cma:
Make the locking for automatic state transition more clear) is missing
from 4.19. So, the context has been modified.
If the state is not idle then rdma_bind_addr() will immediately fail and
no change to global state should happen.
For instance if the state is already RDMA_CM_LISTEN then this will corrupt
the src_addr and would cause the test in cma_cancel_operation():
if (cma_any_addr(cma_src_addr(id_priv)) && !id_priv->cma_dev)
To view a mangled src_addr, eg with a IPv6 loopback address but an IPv4
family, failing the test.
This would manifest as this trace from syzkaller:
BUG: KASAN: use-after-free in __list_add_valid+0x93/0xa0 lib/list_debug.c:26
Read of size 8 at addr ffff8881546491e0 by task syz-executor.1/32204
CPU: 1 PID: 32204 Comm: syz-executor.1 Not tainted 5.12.0-rc8-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:79 [inline]
dump_stack+0x141/0x1d7 lib/dump_stack.c:120
print_address_description.constprop.0.cold+0x5b/0x2f8 mm/kasan/report.c:232
__kasan_report mm/kasan/report.c:399 [inline]
kasan_report.cold+0x7c/0xd8 mm/kasan/report.c:416
__list_add_valid+0x93/0xa0 lib/list_debug.c:26
__list_add include/linux/list.h:67 [inline]
list_add_tail include/linux/list.h:100 [inline]
cma_listen_on_all drivers/infiniband/core/cma.c:2557 [inline]
rdma_listen+0x787/0xe00 drivers/infiniband/core/cma.c:3751
ucma_listen+0x16a/0x210 drivers/infiniband/core/ucma.c:1102
ucma_write+0x259/0x350 drivers/infiniband/core/ucma.c:1732
vfs_write+0x28e/0xa30 fs/read_write.c:603
ksys_write+0x1ee/0x250 fs/read_write.c:658
do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
entry_SYSCALL_64_after_hwframe+0x44/0xae
Which is indicating that an rdma_id_private was destroyed without doing
cma_cancel_listens().
Instead of trying to re-use the src_addr memory to indirectly create an
any address build one explicitly on the stack and bind to that as any
other normal flow would do.
Link: https://lore.kernel.org/r/0-v1-9fbb33f5e201+2a-cma_listen_jgg@nvidia.com
Cc: stable(a)vger.kernel.org
Fixes: 732d41c545bb ("RDMA/cma: Make the locking for automatic state transition more clear")
Reported-by: syzbot+6bb0528b13611047209c(a)syzkaller.appspotmail.com
Tested-by: Hao Sun <sunhao.th(a)gmail.com>
Reviewed-by: Leon Romanovsky <leonro(a)nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg(a)nvidia.com>
Signed-off-by: tangbin <tangbin(a)cmss.chinamobile.com>
---
drivers/infiniband/core/cma.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 319bfef00a4a..7444df92e7cf 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -3375,8 +3375,13 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
id_priv = container_of(id, struct rdma_id_private, id);
if (id_priv->state == RDMA_CM_IDLE) {
- id->route.addr.src_addr.ss_family = AF_INET;
- ret = rdma_bind_addr(id, cma_src_addr(id_priv));
+ struct sockaddr_in any_in = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = htonl(INADDR_ANY),
+ };
+
+ /* For a well behaved ULP state will be RDMA_CM_IDLE */
+ ret = rdma_bind_addr(id, (struct sockaddr *)&any_in);
if (ret)
return ret;
}
--
2.18.4
1
0

[PATCH openEuler-1.0-LTS] arm64: fix out-of-range error when adapting for ARM64_SPECTRE_BHB
by Yongqiang Liu 20 Jun '22
by Yongqiang Liu 20 Jun '22
20 Jun '22
From: Chen Jiahao <chenjiahao16(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 186460, https://gitee.com/src-openeuler/kernel/issues/I53MHA
CVE: CVE-2022-23960
--------------------------------
In cpufeature.c, when num is set to ARM64_SPECTRE_BHB, it should
not be passed to cpu_hwcap_keys, otherwise the out-of-range error
would happen as below:
UBSAN: Undefined behaviour in arch/arm64/kernel/cpufeature.c:1742:3
index 40 is out of range for type 'static_key_false [39]'
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.90+ #1
Call trace:
dump_backtrace+0x0/0x390
show_stack+0x24/0x30
dump_stack+0x130/0x188
ubsan_epilogue+0x14/0xa4
__ubsan_handle_out_of_bounds+0x144/0x184
__enable_cpu_capabilities+0x158/0x1d4
setup_cpu_features+0x34/0xc8
smp_cpus_done+0x44/0x13c
smp_init+0x188/0x1a4
kernel_init_freeable+0x454/0x974
kernel_init+0x18/0x150
ret_from_fork+0x10/0x18
Because KABI cpu_hwcap_keys is consistent and defined with length
ARM64_NCAPS, which is smaller than ARM64_SPECTRE_BHB.
Fixes: 2df7cf898c5b ("arm64: fix extra cpucaps setup problem")
Signed-off-by: Chen Jiahao <chenjiahao16(a)huawei.com>
Reviewed-by: Liao Chang <liaochang1(a)huawei.com>
Reviewed-by: Zhang Jianhua <chris.zjh(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
arch/arm64/kernel/cpufeature.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 996d3476f3c8..d7d8a4ab94b4 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1732,8 +1732,10 @@ __enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
for (; caps->matches; caps++) {
unsigned int num = caps->capability;
- if (num == ARM64_SPECTRE_BHB)
+ if (num == ARM64_SPECTRE_BHB) {
set_cap_spectre_bhb = true;
+ continue;
+ }
if (!(caps->type & scope_mask) || !cpus_have_cap(num))
continue;
--
2.25.1
1
0
Sorry! The Zoom meeting will be held at 2022-06-24 14:00 scheduled by openEuler Kernel SIG has been cancelled.
1
0
您好!
Kernel SIG 邀请您参加 2022-06-24 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler kernel SIG例会&技术分享
会议内容:
openEuler kernel 技术分享:执行实体创建与切换
会议链接:https://us06web.zoom.us/j/83567640355?pwd=OHVRQ2VKcFNka0FhVjg2emQybG1Edz09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2022-06-24 14:00,
The subject of the conference is openEuler kernel SIG例会&技术分享,
Summary:
openEuler kernel 技术分享:执行实体创建与切换
You can join the meeting at https://us06web.zoom.us/j/83567640355?pwd=OHVRQ2VKcFNka0FhVjg2emQybG1Edz09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0
您好!
Kernel SIG 邀请您参加 2022-06-24 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler kernel SIG例会&技术分享
会议内容:
openEuler kernel 技术分享:执行实体创建与切换
会议链接:https://us06web.zoom.us/j/81671713618?pwd=eWIxeGowd1hvNTNZQUlRRmplNlZydz09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2022-06-24 14:00,
The subject of the conference is openEuler kernel SIG例会&技术分享,
Summary:
openEuler kernel 技术分享:执行实体创建与切换
You can join the meeting at https://us06web.zoom.us/j/81671713618?pwd=eWIxeGowd1hvNTNZQUlRRmplNlZydz09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0

[PATCH openEuler-1.0-LTS 1/8] xfs: abort xattr scrub if fatal signals are pending
by Laibin Qiu 18 Jun '22
by Laibin Qiu 18 Jun '22
18 Jun '22
From: "Darrick J. Wong" <darrick.wong(a)oracle.com>
mainline inclusion
from mainline-v5.1-rc1
commit 3258cb208caba74258ffdd8bd59972bbda9bfee1
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5BDCU
CVE: NA
--------------------------------
The extended attribute scrubber should abort the "read all attrs" loop
if there's a fatal signal pending on the process.
Signed-off-by: Darrick J. Wong <darrick.wong(a)oracle.com>
Reviewed-by: Brian Foster <bfoster(a)redhat.com>
Signed-off-by: tangbin <tangbin(a)cmss.chinamobile.com>
Reviewed-by: Lihong Kou <koulihong(a)huawei.com>
Reviewed-by: Xuenan Guo <guoxuenan(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
fs/xfs/scrub/attr.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index 81d5e90547a1..9960bc5b5d76 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -82,6 +82,11 @@ xchk_xattr_listent(
sx = container_of(context, struct xchk_xattr, context);
+ if (xchk_should_terminate(sx->sc, &error)) {
+ context->seen_enough = 1;
+ return;
+ }
+
if (flags & XFS_ATTR_INCOMPLETE) {
/* Incomplete attr key, just mark the inode for preening. */
xchk_ino_set_preen(sx->sc, context->dp->i_ino);
--
2.25.1
1
7
Hi all:
These patches are used to resolve the xfs problem when perform
xfstests. For details about how to fix the problem, we can see the
link below:
https://lore.kernel.org/linux-xfs/154697976479.2839.3584921201780682011.stg…
https://lore.kernel.org/linux-xfs/157232182246.593721.4902116478429075171.s…
Thanks
---
Darrick J. Wong (8):
xfs: abort xattr scrub if fatal signals are pending
xfs: scrub should flag dir/attr offsets that aren't mappable with
xfs_dablk_t
xfs: check directory name validity
xfs: check attribute name validity
xfs: check attribute leaf block structure
xfs: namecheck attribute names before listing them
xfs: namecheck directory entry names before listing them
xfs: replace -EIO with -EFSCORRUPTED for corrupt metadata
fs/xfs/libxfs/xfs_attr.c | 17 +++++++++
fs/xfs/libxfs/xfs_attr.h | 2 +-
fs/xfs/libxfs/xfs_attr_leaf.c | 68 +++++++++++++++++++++++++++++++++--
fs/xfs/libxfs/xfs_attr_leaf.h | 4 +--
fs/xfs/libxfs/xfs_bmap.c | 6 ++--
fs/xfs/libxfs/xfs_dir2.c | 17 +++++++++
fs/xfs/libxfs/xfs_dir2.h | 1 +
fs/xfs/libxfs/xfs_types.c | 11 ++++++
fs/xfs/libxfs/xfs_types.h | 1 +
fs/xfs/scrub/attr.c | 11 ++++++
fs/xfs/scrub/bmap.c | 27 ++++++++++++++
fs/xfs/scrub/dir.c | 6 ++++
fs/xfs/xfs_attr_inactive.c | 6 ++--
fs/xfs/xfs_attr_list.c | 60 ++++++++++++++++++++-----------
fs/xfs/xfs_dir2_readdir.c | 27 +++++++++++---
fs/xfs/xfs_dquot.c | 2 +-
16 files changed, 228 insertions(+), 38 deletions(-)
--
2.18.4
2
9
zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52DS7
CVE: NA
--------------------------------
Optimize driver code and add support for Zhaoxin CPU.
Signed-off-by: LeoLiuoc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/hwmon/Makefile | 3 +-
drivers/hwmon/via-cputemp.c | 69 ++++++++++++++++++++-----------------
2 files changed, 39 insertions(+), 33 deletions(-)
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index c22a5316bd91..115c0e002718 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -183,7 +183,8 @@ obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TMP513) += tmp513.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
-obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
+obj-$(CONFIG_SENSORS_VIA_CPUTEMP) += cputemp-hwmon.o
+cputemp-hwmon-objs := via-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index e5d18dac8ee7..1599440cc451 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -26,7 +26,8 @@
#include <asm/processor.h>
#include <asm/cpu_device_id.h>
-#define DRVNAME "via_cputemp"
+#define VIA_DRVNAME "via_cputemp"
+#define ZHAOXIN_DRVNAME "zhaoxin_cputemp"
enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
@@ -114,17 +115,17 @@ static int via_cputemp_probe(struct
platform_device *pdev)
int err;
u32 eax, edx;
- data = devm_kzalloc(&pdev->dev, sizeof(struct via_cputemp_data),
- GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(struct via_cputemp_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
data->id = pdev->id;
- data->name = "via_cputemp";
if (c->x86 == 7) {
+ data->name = ZHAOXIN_DRVNAME;
data->msr_temp = 0x1423;
} else {
+ data->name = VIA_DRVNAME;
switch (c->x86_model) {
case 0xA:
/* C7 A */
@@ -145,8 +146,7 @@ static int via_cputemp_probe(struct platform_device
*pdev)
/* test if we can access the TEMPERATURE MSR */
err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
if (err) {
- dev_err(&pdev->dev,
- "Unable to access TEMPERATURE MSR, giving up\n");
+ dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving up\n");
return err;
}
@@ -165,11 +165,10 @@ static int via_cputemp_probe(struct
platform_device *pdev)
goto exit_remove;
}
- data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ data->hwmon_dev = hwmon_device_register_with_info(&pdev->dev,
data->name, NULL, NULL, NULL);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
- dev_err(&pdev->dev, "Class registration failed (%d)\n",
- err);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
goto exit_remove;
}
@@ -194,13 +193,12 @@ static int via_cputemp_remove(struct
platform_device *pdev)
}
static struct platform_driver via_cputemp_driver = {
- .driver = {
- .name = DRVNAME,
- },
.probe = via_cputemp_probe,
.remove = via_cputemp_remove,
};
+static struct platform_device_info cputemp_device_info;
+
struct pdev_entry {
struct list_head list;
struct platform_device *pdev;
@@ -216,23 +214,20 @@ static int via_cputemp_online(unsigned int cpu)
struct platform_device *pdev;
struct pdev_entry *pdev_entry;
- pdev = platform_device_alloc(DRVNAME, cpu);
- if (!pdev) {
- err = -ENOMEM;
- pr_err("Device allocation failed\n");
+ cputemp_device_info.id = cpu;
+
+ pdev = platform_device_register_full(&cputemp_device_info);
+ if (IS_ERR(pdev)) {
+ err = PTR_ERR(pdev);
+ pr_err("Device registration failed (%d)\n", err);
goto exit;
}
pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
if (!pdev_entry) {
err = -ENOMEM;
- goto exit_device_put;
- }
-
- err = platform_device_add(pdev);
- if (err) {
- pr_err("Device addition failed (%d)\n", err);
- goto exit_device_free;
+ pr_err("Pdev_entry alloc failed (%d)\n", err);
+ goto exit_device_unregister;
}
pdev_entry->pdev = pdev;
@@ -243,10 +238,8 @@ static int via_cputemp_online(unsigned int cpu)
return 0;
-exit_device_free:
- kfree(pdev_entry);
-exit_device_put:
- platform_device_put(pdev);
+exit_device_unregister:
+ platform_device_unregister(pdev);
exit:
return err;
}
@@ -270,10 +263,11 @@ static int via_cputemp_down_prep(unsigned int cpu)
}
static const struct x86_cpu_id __initconst cputemp_ids[] = {
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_A, NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_D, NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_NANO, NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_A, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_D, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_NANO, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(ZHAOXIN, 7, X86_MODEL_ANY, NULL),
{}
};
MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
@@ -283,15 +277,26 @@ static enum cpuhp_state via_temp_online;
static int __init via_cputemp_init(void)
{
int err;
+ char *cpuhp_name;
if (!x86_match_cpu(cputemp_ids))
return -ENODEV;
+ if (boot_cpu_data.x86 == 0x7) {
+ via_cputemp_driver.driver.name = ZHAOXIN_DRVNAME;
+ cputemp_device_info.name = ZHAOXIN_DRVNAME;
+ cpuhp_name = "hwmon/zhaoxin:online";
+ } else {
+ via_cputemp_driver.driver.name = VIA_DRVNAME;
+ cputemp_device_info.name = VIA_DRVNAME;
+ cpuhp_name = "hwmon/via:online";
+ }
+
err = platform_driver_register(&via_cputemp_driver);
if (err)
goto exit;
- err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/via:online",
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, cpuhp_name,
via_cputemp_online, via_cputemp_down_prep);
if (err < 0)
goto exit_driver_unreg;
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS 1/2] tcp: change source port randomizarion at connect() time
by Yongqiang Liu 17 Jun '22
by Yongqiang Liu 17 Jun '22
17 Jun '22
From: Eric Dumazet <edumazet(a)google.com>
stable inclusion
from stable-v4.19.246
commit ddec440133913a6b8880e53b896d521a4b7ff24f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5C3A9
CVE: CVE-2022-32296
--------------------------------
commit 190cc82489f46f9d88e73c81a47e14f80a791e1a upstream.
RFC 6056 (Recommendations for Transport-Protocol Port Randomization)
provides good summary of why source selection needs extra care.
David Dworken reminded us that linux implements Algorithm 3
as described in RFC 6056 3.3.3
Quoting David :
In the context of the web, this creates an interesting info leak where
websites can count how many TCP connections a user's computer is
establishing over time. For example, this allows a website to count
exactly how many subresources a third party website loaded.
This also allows:
- Distinguishing between different users behind a VPN based on
distinct source port ranges.
- Tracking users over time across multiple networks.
- Covert communication channels between different browsers/browser
profiles running on the same computer
- Tracking what applications are running on a computer based on
the pattern of how fast source ports are getting incremented.
Section 3.3.4 describes an enhancement, that reduces
attackers ability to use the basic information currently
stored into the shared 'u32 hint'.
This change also decreases collision rate when
multiple applications need to connect() to
different destinations.
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reported-by: David Dworken <ddworken(a)google.com>
Cc: Willem de Bruijn <willemb(a)google.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
[SG: Adjusted context]
Signed-off-by: Stefan Ghinea <stefan.ghinea(a)windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
net/ipv4/inet_hashtables.c
Signed-off-by: Baisong Zhong <zhongbaisong(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
net/ipv4/inet_hashtables.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index bd0108aaa45b..72b8b6f44add 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -666,6 +666,17 @@ void inet_unhash(struct sock *sk)
}
EXPORT_SYMBOL_GPL(inet_unhash);
+/* RFC 6056 3.3.4. Algorithm 4: Double-Hash Port Selection Algorithm
+ * Note that we use 32bit integers (vs RFC 'short integers')
+ * because 2^16 is not a multiple of num_ephemeral and this
+ * property might be used by clever attacker.
+ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement,
+ * we use 256 instead to really give more isolation and
+ * privacy, this only consumes 1 KB of kernel memory.
+ */
+#define INET_TABLE_PERTURB_SHIFT 8
+static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT];
+
int __inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk, u64 port_offset,
int (*check_established)(struct inet_timewait_death_row *,
@@ -679,8 +690,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
struct inet_bind_bucket *tb;
u32 remaining, offset;
int ret, i, low, high;
- static u32 hint;
int l3mdev;
+ u32 index;
if (port) {
head = &hinfo->bhash[inet_bhashfn(net, port,
@@ -707,7 +718,10 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
if (likely(remaining > 1))
remaining &= ~1U;
- offset = hint + port_offset;
+ net_get_random_once(table_perturb, sizeof(table_perturb));
+ index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT);
+
+ offset = READ_ONCE(table_perturb[index]) + port_offset;
offset %= remaining;
/* In first pass we try ports of @low parity.
* inet_csk_get_port() does the opposite choice.
@@ -762,7 +776,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
return -EADDRNOTAVAIL;
ok:
- hint += i + 2;
+ WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2);
/* Head lock still held and bh's disabled */
inet_bind_hash(sk, tb, port);
--
2.25.1
1
1

16 Jun '22
From: Chen Jiahao <chenjiahao16(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 186460, https://gitee.com/src-openeuler/kernel/issues/I53MHA
CVE: CVE-2022-23960
--------------------------------
When introducing a new cpucaps macro ARM64_SPECTRE_BHB, ARM64_NCAPS was
not able to modified easily due to KABI consistency. Here introduce
a workaround to properly setup ARM64_SPECTRE_BHB beyond ARM64_NCAPS
range.
Fixes: def2df575d30 ("KVM: arm64: Add templates for BHB mitigation sequences")
Signed-off-by: Chen Jiahao <chenjiahao16(a)huawei.com>
Reviewed-by: Zhang Jianhua <chris.zjh(a)huawei.com>
Reviewed-by: Liao Chang <liaochang1(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
arch/arm64/include/asm/cpufeature.h | 15 +++++++++++++++
arch/arm64/kernel/alternative.c | 5 +++++
arch/arm64/kernel/cpufeature.c | 3 +++
3 files changed, 23 insertions(+)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index bfb699957880..ffb0a1ec0088 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -368,6 +368,8 @@ extern struct static_key_false arm64_const_caps_ready;
#define ARM64_NPATCHABLE (ARM64_NCAPS + 1)
extern DECLARE_BITMAP(boot_capabilities, ARM64_NPATCHABLE);
+extern bool set_cap_spectre_bhb;
+
bool this_cpu_has_cap(unsigned int cap);
static inline bool cpu_have_feature(unsigned int num)
@@ -378,15 +380,23 @@ static inline bool cpu_have_feature(unsigned int num)
/* System capability check for constant caps */
static __always_inline bool __cpus_have_const_cap(int num)
{
+ if (num == ARM64_SPECTRE_BHB)
+ return set_cap_spectre_bhb;
+
if (num >= ARM64_NCAPS)
return false;
+
return static_branch_unlikely(&cpu_hwcap_keys[num]);
}
static inline bool cpus_have_cap(unsigned int num)
{
+ if (num == ARM64_SPECTRE_BHB)
+ return set_cap_spectre_bhb;
+
if (num >= ARM64_NCAPS)
return false;
+
return test_bit(num, cpu_hwcaps);
}
@@ -400,6 +410,11 @@ static __always_inline bool cpus_have_const_cap(int num)
static inline void cpus_set_cap(unsigned int num)
{
+ if (num == ARM64_SPECTRE_BHB) {
+ set_cap_spectre_bhb = true;
+ return;
+ }
+
if (num >= ARM64_NCAPS) {
pr_warn("Attempt to set an illegal CPU capability (%d >= %d)\n",
num, ARM64_NCAPS);
diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index 8511fc3b94bb..ce5a26080b46 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -41,8 +41,13 @@ struct alt_region {
struct alt_instr *end;
};
+bool set_cap_spectre_bhb;
+
bool alternative_is_applied(u16 cpufeature)
{
+ if (cpufeature == ARM64_SPECTRE_BHB)
+ return set_cap_spectre_bhb;
+
if (WARN_ON(cpufeature >= ARM64_NCAPS))
return false;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index aa9178e9acc6..996d3476f3c8 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1732,6 +1732,9 @@ __enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
for (; caps->matches; caps++) {
unsigned int num = caps->capability;
+ if (num == ARM64_SPECTRE_BHB)
+ set_cap_spectre_bhb = true;
+
if (!(caps->type & scope_mask) || !cpus_have_cap(num))
continue;
--
2.25.1
1
0
Sorry! The Zoom meeting will be held at 2022-06-17 14:00 scheduled by openEuler Kernel SIG has been cancelled.
1
0

[PATCH openEuler-1.0-LTS 1/3] powerpc/32: Fix overread/overwrite of thread_struct via ptrace
by Yongqiang Liu 15 Jun '22
by Yongqiang Liu 15 Jun '22
15 Jun '22
From: Michael Ellerman <mpe(a)ellerman.id.au>
mainline inclusion
from mainline-v5.19-rc2
commit 8e1278444446fc97778a5e5c99bca1ce0bbc5ec9
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5C43D
CVE: CVE-2022-32981
--------------------------------
The ptrace PEEKUSR/POKEUSR (aka PEEKUSER/POKEUSER) API allows a process
to read/write registers of another process.
To get/set a register, the API takes an index into an imaginary address
space called the "USER area", where the registers of the process are
laid out in some fashion.
The kernel then maps that index to a particular register in its own data
structures and gets/sets the value.
The API only allows a single machine-word to be read/written at a time.
So 4 bytes on 32-bit kernels and 8 bytes on 64-bit kernels.
The way floating point registers (FPRs) are addressed is somewhat
complicated, because double precision float values are 64-bit even on
32-bit CPUs. That means on 32-bit kernels each FPR occupies two
word-sized locations in the USER area. On 64-bit kernels each FPR
occupies one word-sized location in the USER area.
Internally the kernel stores the FPRs in an array of u64s, or if VSX is
enabled, an array of pairs of u64s where one half of each pair stores
the FPR. Which half of the pair stores the FPR depends on the kernel's
endianness.
To handle the different layouts of the FPRs depending on VSX/no-VSX and
big/little endian, the TS_FPR() macro was introduced.
Unfortunately the TS_FPR() macro does not take into account the fact
that the addressing of each FPR differs between 32-bit and 64-bit
kernels. It just takes the index into the "USER area" passed from
userspace and indexes into the fp_state.fpr array.
On 32-bit there are 64 indexes that address FPRs, but only 32 entries in
the fp_state.fpr array, meaning the user can read/write 256 bytes past
the end of the array. Because the fp_state sits in the middle of the
thread_struct there are various fields than can be overwritten,
including some pointers. As such it may be exploitable.
It has also been observed to cause systems to hang or otherwise
misbehave when using gdbserver, and is probably the root cause of this
report which could not be easily reproduced:
https://lore.kernel.org/linuxppc-dev/dc38afe9-6b78-f3f5-666b-986939e40fc6@k…
Rather than trying to make the TS_FPR() macro even more complicated to
fix the bug, or add more macros, instead add a special-case for 32-bit
kernels. This is more obvious and hopefully avoids a similar bug
happening again in future.
Note that because 32-bit kernels never have VSX enabled the code doesn't
need to consider TS_FPRWIDTH/OFFSET at all. Add a BUILD_BUG_ON() to
ensure that 32-bit && VSX is never enabled.
Fixes: 87fec0514f61 ("powerpc: PTRACE_PEEKUSR/PTRACE_POKEUSER of FPR registers in little endian builds")
Cc: stable(a)vger.kernel.org # v3.13+
Reported-by: Ariel Miculas <ariel.miculas(a)belden.com>
Tested-by: Christophe Leroy <christophe.leroy(a)csgroup.eu>
Signed-off-by: Michael Ellerman <mpe(a)ellerman.id.au>
Link: https://lore.kernel.org/r/20220609133245.573565-1-mpe@ellerman.id.au
Conflicts:
arch/powerpc/kernel/ptrace/ptrace-fpu.c
arch/powerpc/kernel/ptrace/ptrace.c
Signed-off-by: Yipeng Zou <zouyipeng(a)huawei.com>
Reviewed-by: Zhang Jianhua <chris.zjh(a)huawei.com>
Reviewed-by: Liao Chang <liaochang1(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
arch/powerpc/kernel/ptrace.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index e08b32ccf1d9..d245f0af412a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -2980,6 +2980,9 @@ long arch_ptrace(struct task_struct *child, long request,
void __user *datavp = (void __user *) data;
unsigned long __user *datalp = datavp;
+ // ptrace_get/put_fpr() rely on PPC32 and VSX being incompatible
+ BUILD_BUG_ON(IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_VSX));
+
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
@@ -3006,10 +3009,13 @@ long arch_ptrace(struct task_struct *child, long request,
unsigned int fpidx = index - PT_FPR0;
flush_fp_to_thread(child);
- if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&tmp, &child->thread.TS_FPR(fpidx),
- sizeof(long));
- else
+ if (fpidx < (PT_FPSCR - PT_FPR0)) {
+ if (IS_ENABLED(CONFIG_PPC32))
+ // On 32-bit the index we are passed refers to 32-bit words
+ tmp = ((u32 *)child->thread.fp_state.fpr)[fpidx];
+ else
+ memcpy(&tmp, &child->thread.TS_FPR(fpidx), sizeof(long));
+ } else
tmp = child->thread.fp_state.fpscr;
}
ret = put_user(tmp, datalp);
@@ -3039,10 +3045,13 @@ long arch_ptrace(struct task_struct *child, long request,
unsigned int fpidx = index - PT_FPR0;
flush_fp_to_thread(child);
- if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&child->thread.TS_FPR(fpidx), &data,
- sizeof(long));
- else
+ if (fpidx < (PT_FPSCR - PT_FPR0)) {
+ if (IS_ENABLED(CONFIG_PPC32))
+ // On 32-bit the index we are passed refers to 32-bit words
+ ((u32 *)child->thread.fp_state.fpr)[fpidx] = data;
+ else
+ memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
+ } else
child->thread.fp_state.fpscr = data;
ret = 0;
}
--
2.25.1
1
2

14 Jun '22
From: Xin Long <lucien.xin(a)gmail.com>
stable inclusion
from stable-v4.19.224
commit af6e6e58f7ebf86b4e7201694b1e4f3a62cbc3ec
category: bugfix
bugzilla: 186701, https://gitee.com/src-openeuler/kernel/issues/I5CAM2
CVE: CVE-2022-20154
--------------------------------
[ Upstream commit 5ec7d18d1813a5bead0b495045606c93873aecbb ]
This patch is to delay the endpoint free by calling call_rcu() to fix
another use-after-free issue in sctp_sock_dump():
BUG: KASAN: use-after-free in __lock_acquire+0x36d9/0x4c20
Call Trace:
__lock_acquire+0x36d9/0x4c20 kernel/locking/lockdep.c:3218
lock_acquire+0x1ed/0x520 kernel/locking/lockdep.c:3844
__raw_spin_lock_bh include/linux/spinlock_api_smp.h:135 [inline]
_raw_spin_lock_bh+0x31/0x40 kernel/locking/spinlock.c:168
spin_lock_bh include/linux/spinlock.h:334 [inline]
__lock_sock+0x203/0x350 net/core/sock.c:2253
lock_sock_nested+0xfe/0x120 net/core/sock.c:2774
lock_sock include/net/sock.h:1492 [inline]
sctp_sock_dump+0x122/0xb20 net/sctp/diag.c:324
sctp_for_each_transport+0x2b5/0x370 net/sctp/socket.c:5091
sctp_diag_dump+0x3ac/0x660 net/sctp/diag.c:527
__inet_diag_dump+0xa8/0x140 net/ipv4/inet_diag.c:1049
inet_diag_dump+0x9b/0x110 net/ipv4/inet_diag.c:1065
netlink_dump+0x606/0x1080 net/netlink/af_netlink.c:2244
__netlink_dump_start+0x59a/0x7c0 net/netlink/af_netlink.c:2352
netlink_dump_start include/linux/netlink.h:216 [inline]
inet_diag_handler_cmd+0x2ce/0x3f0 net/ipv4/inet_diag.c:1170
__sock_diag_cmd net/core/sock_diag.c:232 [inline]
sock_diag_rcv_msg+0x31d/0x410 net/core/sock_diag.c:263
netlink_rcv_skb+0x172/0x440 net/netlink/af_netlink.c:2477
sock_diag_rcv+0x2a/0x40 net/core/sock_diag.c:274
This issue occurs when asoc is peeled off and the old sk is freed after
getting it by asoc->base.sk and before calling lock_sock(sk).
To prevent the sk free, as a holder of the sk, ep should be alive when
calling lock_sock(). This patch uses call_rcu() and moves sock_put and
ep free into sctp_endpoint_destroy_rcu(), so that it's safe to try to
hold the ep under rcu_read_lock in sctp_transport_traverse_process().
If sctp_endpoint_hold() returns true, it means this ep is still alive
and we have held it and can continue to dump it; If it returns false,
it means this ep is dead and can be freed after rcu_read_unlock, and
we should skip it.
In sctp_sock_dump(), after locking the sk, if this ep is different from
tsp->asoc->ep, it means during this dumping, this asoc was peeled off
before calling lock_sock(), and the sk should be skipped; If this ep is
the same with tsp->asoc->ep, it means no peeloff happens on this asoc,
and due to lock_sock, no peeloff will happen either until release_sock.
Note that delaying endpoint free won't delay the port release, as the
port release happens in sctp_endpoint_destroy() before calling call_rcu().
Also, freeing endpoint by call_rcu() makes it safe to access the sk by
asoc->base.sk in sctp_assocs_seq_show() and sctp_rcv().
Thanks Jones to bring this issue up.
v1->v2:
- improve the changelog.
- add kfree(ep) into sctp_endpoint_destroy_rcu(), as Jakub noticed.
Reported-by: syzbot+9276d76e83e3bcde6c99(a)syzkaller.appspotmail.com
Reported-by: Lee Jones <lee.jones(a)linaro.org>
Fixes: d25adbeb0cdb ("sctp: fix an use-after-free issue in sctp_sock_dump")
Signed-off-by: Xin Long <lucien.xin(a)gmail.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Huang Guobin <huangguobin4(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/net/sctp/sctp.h | 6 +++---
include/net/sctp/structs.h | 3 ++-
net/sctp/diag.c | 12 ++++++------
net/sctp/endpointola.c | 23 +++++++++++++++--------
net/sctp/socket.c | 23 +++++++++++++++--------
5 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index fef8c3372aee..6d201c6700be 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -118,6 +118,7 @@ extern struct percpu_counter sctp_sockets_allocated;
int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
+typedef int (*sctp_callback_t)(struct sctp_endpoint *, struct sctp_transport *, void *);
void sctp_transport_walk_start(struct rhashtable_iter *iter);
void sctp_transport_walk_stop(struct rhashtable_iter *iter);
struct sctp_transport *sctp_transport_get_next(struct net *net,
@@ -128,9 +129,8 @@ int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
struct net *net,
const union sctp_addr *laddr,
const union sctp_addr *paddr, void *p);
-int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *),
- int (*cb_done)(struct sctp_transport *, void *),
- struct net *net, int *pos, void *p);
+int sctp_transport_traverse_process(sctp_callback_t cb, sctp_callback_t cb_done,
+ struct net *net, int *pos, void *p);
int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p);
int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc,
struct sctp_info *info);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 2882bc7a5b4b..18f9924aa250 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1348,6 +1348,7 @@ struct sctp_endpoint {
u32 secid;
u32 peer_secid;
+ struct rcu_head rcu;
};
/* Recover the outter endpoint structure. */
@@ -1363,7 +1364,7 @@ static inline struct sctp_endpoint *sctp_ep(struct sctp_ep_common *base)
struct sctp_endpoint *sctp_endpoint_new(struct sock *, gfp_t);
void sctp_endpoint_free(struct sctp_endpoint *);
void sctp_endpoint_put(struct sctp_endpoint *);
-void sctp_endpoint_hold(struct sctp_endpoint *);
+int sctp_endpoint_hold(struct sctp_endpoint *ep);
void sctp_endpoint_add_asoc(struct sctp_endpoint *, struct sctp_association *);
struct sctp_association *sctp_endpoint_lookup_assoc(
const struct sctp_endpoint *ep,
diff --git a/net/sctp/diag.c b/net/sctp/diag.c
index 8767405de9fa..0a9db0a7f423 100644
--- a/net/sctp/diag.c
+++ b/net/sctp/diag.c
@@ -307,9 +307,8 @@ static int sctp_tsp_dump_one(struct sctp_transport *tsp, void *p)
return err;
}
-static int sctp_sock_dump(struct sctp_transport *tsp, void *p)
+static int sctp_sock_dump(struct sctp_endpoint *ep, struct sctp_transport *tsp, void *p)
{
- struct sctp_endpoint *ep = tsp->asoc->ep;
struct sctp_comm_param *commp = p;
struct sock *sk = ep->base.sk;
struct sk_buff *skb = commp->skb;
@@ -319,6 +318,8 @@ static int sctp_sock_dump(struct sctp_transport *tsp, void *p)
int err = 0;
lock_sock(sk);
+ if (ep != tsp->asoc->ep)
+ goto release;
list_for_each_entry(assoc, &ep->asocs, asocs) {
if (cb->args[4] < cb->args[1])
goto next;
@@ -361,9 +362,8 @@ static int sctp_sock_dump(struct sctp_transport *tsp, void *p)
return err;
}
-static int sctp_sock_filter(struct sctp_transport *tsp, void *p)
+static int sctp_sock_filter(struct sctp_endpoint *ep, struct sctp_transport *tsp, void *p)
{
- struct sctp_endpoint *ep = tsp->asoc->ep;
struct sctp_comm_param *commp = p;
struct sock *sk = ep->base.sk;
const struct inet_diag_req_v2 *r = commp->r;
@@ -521,8 +521,8 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
if (!(idiag_states & ~(TCPF_LISTEN | TCPF_CLOSE)))
goto done;
- sctp_for_each_transport(sctp_sock_filter, sctp_sock_dump,
- net, &pos, &commp);
+ sctp_transport_traverse_process(sctp_sock_filter, sctp_sock_dump,
+ net, &pos, &commp);
cb->args[2] = pos;
done:
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 8640dedcf64f..c4068451b9c7 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -242,6 +242,18 @@ void sctp_endpoint_free(struct sctp_endpoint *ep)
}
/* Final destructor for endpoint. */
+static void sctp_endpoint_destroy_rcu(struct rcu_head *head)
+{
+ struct sctp_endpoint *ep = container_of(head, struct sctp_endpoint, rcu);
+ struct sock *sk = ep->base.sk;
+
+ sctp_sk(sk)->ep = NULL;
+ sock_put(sk);
+
+ kfree(ep);
+ SCTP_DBG_OBJCNT_DEC(ep);
+}
+
static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
{
struct sock *sk;
@@ -275,18 +287,13 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
if (sctp_sk(sk)->bind_hash)
sctp_put_port(sk);
- sctp_sk(sk)->ep = NULL;
- /* Give up our hold on the sock */
- sock_put(sk);
-
- kfree(ep);
- SCTP_DBG_OBJCNT_DEC(ep);
+ call_rcu(&ep->rcu, sctp_endpoint_destroy_rcu);
}
/* Hold a reference to an endpoint. */
-void sctp_endpoint_hold(struct sctp_endpoint *ep)
+int sctp_endpoint_hold(struct sctp_endpoint *ep)
{
- refcount_inc(&ep->base.refcnt);
+ return refcount_inc_not_zero(&ep->base.refcnt);
}
/* Release a reference to an endpoint and clean up if there are
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index cfa54e56add9..0e979a273dcd 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5059,11 +5059,12 @@ int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
}
EXPORT_SYMBOL_GPL(sctp_transport_lookup_process);
-int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *),
- int (*cb_done)(struct sctp_transport *, void *),
- struct net *net, int *pos, void *p) {
+int sctp_transport_traverse_process(sctp_callback_t cb, sctp_callback_t cb_done,
+ struct net *net, int *pos, void *p)
+{
struct rhashtable_iter hti;
struct sctp_transport *tsp;
+ struct sctp_endpoint *ep;
int ret;
again:
@@ -5072,26 +5073,32 @@ int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *),
tsp = sctp_transport_get_idx(net, &hti, *pos + 1);
for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) {
- ret = cb(tsp, p);
- if (ret)
- break;
+ ep = tsp->asoc->ep;
+ if (sctp_endpoint_hold(ep)) { /* asoc can be peeled off */
+ ret = cb(ep, tsp, p);
+ if (ret)
+ break;
+ sctp_endpoint_put(ep);
+ }
(*pos)++;
sctp_transport_put(tsp);
}
sctp_transport_walk_stop(&hti);
if (ret) {
- if (cb_done && !cb_done(tsp, p)) {
+ if (cb_done && !cb_done(ep, tsp, p)) {
(*pos)++;
+ sctp_endpoint_put(ep);
sctp_transport_put(tsp);
goto again;
}
+ sctp_endpoint_put(ep);
sctp_transport_put(tsp);
}
return ret;
}
-EXPORT_SYMBOL_GPL(sctp_for_each_transport);
+EXPORT_SYMBOL_GPL(sctp_transport_traverse_process);
/* 7.2.1 Association Status (SCTP_STATUS)
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS] ext4: convert from atomic_t to refcount_t on ext4_io_end->count
by Yongqiang Liu 14 Jun '22
by Yongqiang Liu 14 Jun '22
14 Jun '22
From: Xiyu Yang <xiyuyang19(a)fudan.edu.cn>
hulk inclusion
category: bugfix
bugzilla: 186971, https://gitee.com/openeuler/kernel/issues/I5C8IW
CVE: NA
--------------------------------
refcount_t type and corresponding API can protect refcounters from
accidental underflow and overflow and further use-after-free situations.
Signed-off-by: Xiyu Yang <xiyuyang19(a)fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf(a)gmail.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://lore.kernel.org/r/1626674355-55795-1-git-send-email-xiyuyang19@fuda…
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/ext4/ext4.h | 3 ++-
fs/ext4/page-io.c | 8 ++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 16e2b719d47c..6efc710b07bf 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -17,6 +17,7 @@
#ifndef _EXT4_H
#define _EXT4_H
+#include <linux/refcount.h>
#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/magic.h>
@@ -231,7 +232,7 @@ typedef struct ext4_io_end {
struct bio *bio; /* Linked list of completed
* bios covering the extent */
unsigned int flag; /* unwritten or not */
- atomic_t count; /* reference counter */
+ refcount_t count; /* reference counter */
loff_t offset; /* offset in the file */
ssize_t size; /* size of the extent */
} ext4_io_end_t;
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 3de933354a08..decae80aeb98 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -256,14 +256,14 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
if (io) {
io->inode = inode;
INIT_LIST_HEAD(&io->list);
- atomic_set(&io->count, 1);
+ refcount_set(&io->count, 1);
}
return io;
}
void ext4_put_io_end_defer(ext4_io_end_t *io_end)
{
- if (atomic_dec_and_test(&io_end->count)) {
+ if (refcount_dec_and_test(&io_end->count)) {
if (!(io_end->flag & EXT4_IO_END_UNWRITTEN) || !io_end->size) {
ext4_release_io_end(io_end);
return;
@@ -276,7 +276,7 @@ int ext4_put_io_end(ext4_io_end_t *io_end)
{
int err = 0;
- if (atomic_dec_and_test(&io_end->count)) {
+ if (refcount_dec_and_test(&io_end->count)) {
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
err = ext4_convert_unwritten_extents(io_end->handle,
io_end->inode, io_end->offset,
@@ -291,7 +291,7 @@ int ext4_put_io_end(ext4_io_end_t *io_end)
ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
{
- atomic_inc(&io_end->count);
+ refcount_inc(&io_end->count);
return io_end;
}
--
2.25.1
1
0

[PATCH openEuler-5.10 01/49] io_uring: always use original task when preparing req identity
by Zheng Zengkai 14 Jun '22
by Zheng Zengkai 14 Jun '22
14 Jun '22
From: Jens Axboe <axboe(a)kernel.dk>
stable inclusion
from stable-v5.10.116
commit 29f077d070519a88a793fbc70f1e6484dc6d9e35
category: bugfix
bugzilla: 186865,https://gitee.com/src-openeuler/kernel/issues/I593SI
CVE: CVE-2022-1786
--------------------------------
If the ring is setup with IORING_SETUP_IOPOLL and we have more than
one task doing submissions on a ring, we can up in a situation where
we assign the context from the current task rather than the request
originator.
Always use req->task rather than assume it's the same as current.
No upstream patch exists for this issue, as only older kernels with
the non-native workers have this problem.
Reported-by: Kyle Zeng <zengyhkyle(a)gmail.com>
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Guo Xuenan <guoxuenan(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
fs/io_uring.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 2ed0da75000e..cadd491edc6f 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1156,7 +1156,7 @@ static inline void __io_req_init_async(struct io_kiocb *req)
*/
static inline void io_req_init_async(struct io_kiocb *req)
{
- struct io_uring_task *tctx = current->io_uring;
+ struct io_uring_task *tctx = req->task->io_uring;
if (req->flags & REQ_F_WORK_INITIALIZED)
return;
--
2.20.1
1
48
Backport 5.10.107 LTS patches from upstream
kselftest/vm: fix tests build with old libc
sfc: extend the locking on mcdi->seqno
tcp: make tcp_read_sock() more robust
nl80211: Update bss channel on channel switch for P2P_CLIENT
drm/vrr: Set VRR capable prop only if it is attached to connector
iwlwifi: don't advertise TWT support
atm: firestream: check the return value of ioremap() in fs_init()
can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device when fully
ready
ARM: 9178/1: fix unmet dependency on BITREVERSE for HAVE_ARCH_BITREVERSE
MIPS: smp: fill in sibling and core maps earlier
mac80211: refuse aggregations sessions before authorized
ARM: dts: rockchip: fix a typo on rk3288 crypto-controller
ARM: dts: rockchip: reorder rk322x hmdi clocks
arm64: dts: agilex: use the compatible "intel,socfpga-agilex-hsotg"
arm64: dts: rockchip: reorder rk3399 hdmi clocks
arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity
xfrm: Fix xfrm migrate issues when address family changes
xfrm: Check if_id in xfrm_migrate
Revert "xfrm: state and policy should fail if XFRMA_IF_ID 0"
Already merged(3)
arm64: kvm: Fix copy-and-paste error in bhb templates for v5.10 stable
io_uring: return back safer resurrect
sctp: fix the processing for INIT chunk
Total patches: 22 - 3 = 19
Alexander Lobakin (1):
MIPS: smp: fill in sibling and core maps earlier
Chengming Zhou (1):
kselftest/vm: fix tests build with old libc
Corentin Labbe (1):
ARM: dts: rockchip: fix a typo on rk3288 crypto-controller
Dinh Nguyen (1):
arm64: dts: agilex: use the compatible "intel,socfpga-agilex-hsotg"
Eric Dumazet (1):
tcp: make tcp_read_sock() more robust
Golan Ben Ami (1):
iwlwifi: don't advertise TWT support
Jakob Unterwurzacher (1):
arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity
Jia-Ju Bai (1):
atm: firestream: check the return value of ioremap() in fs_init()
Johannes Berg (1):
mac80211: refuse aggregations sessions before authorized
Julian Braha (1):
ARM: 9178/1: fix unmet dependency on BITREVERSE for
HAVE_ARCH_BITREVERSE
Kai Lueke (1):
Revert "xfrm: state and policy should fail if XFRMA_IF_ID 0"
Lad Prabhakar (1):
can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device
when fully ready
Manasi Navare (1):
drm/vrr: Set VRR capable prop only if it is attached to connector
Niels Dossche (1):
sfc: extend the locking on mcdi->seqno
Sascha Hauer (2):
arm64: dts: rockchip: reorder rk3399 hdmi clocks
ARM: dts: rockchip: reorder rk322x hmdi clocks
Sreeramya Soratkal (1):
nl80211: Update bss channel on channel switch for P2P_CLIENT
Yan Yan (2):
xfrm: Check if_id in xfrm_migrate
xfrm: Fix xfrm migrate issues when address family changes
arch/arm/boot/dts/rk322x.dtsi | 4 +--
arch/arm/boot/dts/rk3288.dtsi | 2 +-
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi | 4 +--
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 6 +++++
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 6 ++---
arch/mips/kernel/smp.c | 6 ++---
drivers/atm/firestream.c | 2 ++
drivers/gpu/drm/drm_connector.c | 3 +++
drivers/net/can/rcar/rcar_canfd.c | 6 ++---
drivers/net/ethernet/sfc/mcdi.c | 2 +-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 3 +--
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 1 -
include/net/xfrm.h | 5 ++--
lib/Kconfig | 1 -
net/ipv4/tcp.c | 10 ++++---
net/key/af_key.c | 2 +-
net/mac80211/agg-tx.c | 10 ++++++-
net/wireless/nl80211.c | 3 ++-
net/xfrm/xfrm_policy.c | 14 +++++-----
net/xfrm/xfrm_state.c | 15 ++++++++---
net/xfrm/xfrm_user.c | 27 ++++++-------------
tools/testing/selftests/vm/userfaultfd.c | 1 +
22 files changed, 76 insertions(+), 57 deletions(-)
--
2.20.1
1
19

[PATCH openEuler-1.0-LTS 1/9] HID: add hid_is_usb() function to make it simpler for USB detection
by Yongqiang Liu 14 Jun '22
by Yongqiang Liu 14 Jun '22
14 Jun '22
From: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
stable inclusion
from linux-4.19.221
commit b1efa723b986a84f84a95b6907cffe3a357338c9
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5BTIG
CVE: CVE-2022-20132
--------------------------------
commit f83baa0cb6cfc92ebaf7f9d3a99d7e34f2e77a8a upstream.
A number of HID drivers already call hid_is_using_ll_driver() but only
for the detection of if this is a USB device or not. Make this more
obvious by creating hid_is_usb() and calling the function that way.
Also converts the existing hid_is_using_ll_driver() functions to use the
new call.
Cc: Jiri Kosina <jikos(a)kernel.org>
Cc: Benjamin Tissoires <benjamin.tissoires(a)redhat.com>
Cc: linux-input(a)vger.kernel.org
Cc: stable(a)vger.kernel.org
Tested-by: Benjamin Tissoires <benjamin.tissoires(a)redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires(a)redhat.com>
Link: https://lore.kernel.org/r/20211201183503.2373082-1-gregkh@linuxfoundation.o…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Rui Xiang <rui.xiang(a)huawei.com>
Reviewed-by: Zhang Xiaoxu <zhangxiaoxu5(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/hid/hid-asus.c | 2 +-
drivers/hid/wacom_sys.c | 2 +-
include/linux/hid.h | 5 +++++
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 88a5672f42cd..800b2364e29e 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -622,7 +622,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
drvdata->tp = &asus_i2c_tp;
- if (drvdata->quirks & QUIRK_T100_KEYBOARD) {
+ if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) {
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 3038c975e417..101b5ae2c3a7 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2154,7 +2154,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix)
if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) {
char *product_name = wacom->hdev->name;
- if (hid_is_using_ll_driver(wacom->hdev, &usb_hid_driver)) {
+ if (hid_is_usb(wacom->hdev)) {
struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent);
struct usb_device *dev = interface_to_usbdev(intf);
product_name = dev->product;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index bbbe6c0e0e26..7f321909ec58 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -832,6 +832,11 @@ static inline bool hid_is_using_ll_driver(struct hid_device *hdev,
return hdev->ll_driver == driver;
}
+static inline bool hid_is_usb(struct hid_device *hdev)
+{
+ return hid_is_using_ll_driver(hdev, &usb_hid_driver);
+}
+
#define PM_HINT_FULLON 1<<5
#define PM_HINT_NORMAL 1<<1
--
2.25.1
1
8

[PATCH openEuler-5.10-LTS 01/42] netfilter: nf_tables: sanitize nft_set_desc_concat_parse()
by Zheng Zengkai 14 Jun '22
by Zheng Zengkai 14 Jun '22
14 Jun '22
From: Pablo Neira Ayuso <pablo(a)netfilter.org>
stable inclusion
from stable-v5.10.120
commit c0aff1faf66b6b7a19103f83e6a5d0fdc64b9048
category: bugfix
bugzilla: 186913 https://gitee.com/src-openeuler/kernel/issues/I5B69E
CVE: CVE-2022-1972
--------------------------------
commit fecf31ee395b0295f2d7260aa29946b7605f7c85 upstream.
Add several sanity checks for nft_set_desc_concat_parse():
- validate desc->field_count not larger than desc->field_len array.
- field length cannot be larger than desc->field_len (ie. U8_MAX)
- total length of the concatenation cannot be larger than register array.
Joint work with Florian Westphal.
Fixes: f3a2181e16f1 ("netfilter: nf_tables: Support for sets with multiple ranged fields")
Reported-by: <zhangziming.zzm(a)antgroup.com>
Reviewed-by: Stefano Brivio <sbrivio(a)redhat.com>
Signed-off-by: Florian Westphal <fw(a)strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zhengchao Shao <shaozhengchao(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
net/netfilter/nf_tables_api.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index fdd1da9ecea9..164b686bb4c9 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4047,6 +4047,9 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
u32 len;
int err;
+ if (desc->field_count >= ARRAY_SIZE(desc->field_len))
+ return -E2BIG;
+
err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr,
nft_concat_policy, NULL);
if (err < 0)
@@ -4056,9 +4059,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
return -EINVAL;
len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN]));
-
- if (len * BITS_PER_BYTE / 32 > NFT_REG32_COUNT)
- return -E2BIG;
+ if (!len || len > U8_MAX)
+ return -EINVAL;
desc->field_len[desc->field_count++] = len;
@@ -4069,7 +4071,8 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
const struct nlattr *nla)
{
struct nlattr *attr;
- int rem, err;
+ u32 num_regs = 0;
+ int rem, err, i;
nla_for_each_nested(attr, nla, rem) {
if (nla_type(attr) != NFTA_LIST_ELEM)
@@ -4080,6 +4083,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
return err;
}
+ for (i = 0; i < desc->field_count; i++)
+ num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32));
+
+ if (num_regs > NFT_REG32_COUNT)
+ return -E2BIG;
+
return 0;
}
--
2.20.1
1
41
Backport 5.10.107 LTS patches from upstream
kselftest/vm: fix tests build with old libc
sfc: extend the locking on mcdi->seqno
tcp: make tcp_read_sock() more robust
nl80211: Update bss channel on channel switch for P2P_CLIENT
drm/vrr: Set VRR capable prop only if it is attached to connector
iwlwifi: don't advertise TWT support
atm: firestream: check the return value of ioremap() in fs_init()
can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device when fully
ready
ARM: 9178/1: fix unmet dependency on BITREVERSE for HAVE_ARCH_BITREVERSE
MIPS: smp: fill in sibling and core maps earlier
mac80211: refuse aggregations sessions before authorized
ARM: dts: rockchip: fix a typo on rk3288 crypto-controller
ARM: dts: rockchip: reorder rk322x hmdi clocks
arm64: dts: agilex: use the compatible "intel,socfpga-agilex-hsotg"
arm64: dts: rockchip: reorder rk3399 hdmi clocks
arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity
xfrm: Fix xfrm migrate issues when address family changes
xfrm: Check if_id in xfrm_migrate
Revert "xfrm: state and policy should fail if XFRMA_IF_ID 0"
Already merged(3)
arm64: kvm: Fix copy-and-paste error in bhb templates for v5.10 stable
io_uring: return back safer resurrect
sctp: fix the processing for INIT chunk
Total patches: 22 - 3 = 19
Alexander Lobakin (1):
MIPS: smp: fill in sibling and core maps earlier
Chengming Zhou (1):
kselftest/vm: fix tests build with old libc
Corentin Labbe (1):
ARM: dts: rockchip: fix a typo on rk3288 crypto-controller
Dinh Nguyen (1):
arm64: dts: agilex: use the compatible "intel,socfpga-agilex-hsotg"
Eric Dumazet (1):
tcp: make tcp_read_sock() more robust
Golan Ben Ami (1):
iwlwifi: don't advertise TWT support
Jakob Unterwurzacher (1):
arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity
Jia-Ju Bai (1):
atm: firestream: check the return value of ioremap() in fs_init()
Johannes Berg (1):
mac80211: refuse aggregations sessions before authorized
Julian Braha (1):
ARM: 9178/1: fix unmet dependency on BITREVERSE for
HAVE_ARCH_BITREVERSE
Kai Lueke (1):
Revert "xfrm: state and policy should fail if XFRMA_IF_ID 0"
Lad Prabhakar (1):
can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device
when fully ready
Manasi Navare (1):
drm/vrr: Set VRR capable prop only if it is attached to connector
Niels Dossche (1):
sfc: extend the locking on mcdi->seqno
Sascha Hauer (2):
arm64: dts: rockchip: reorder rk3399 hdmi clocks
ARM: dts: rockchip: reorder rk322x hmdi clocks
Sreeramya Soratkal (1):
nl80211: Update bss channel on channel switch for P2P_CLIENT
Yan Yan (2):
xfrm: Check if_id in xfrm_migrate
xfrm: Fix xfrm migrate issues when address family changes
arch/arm/boot/dts/rk322x.dtsi | 4 +--
arch/arm/boot/dts/rk3288.dtsi | 2 +-
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi | 4 +--
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 6 +++++
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 6 ++---
arch/mips/kernel/smp.c | 6 ++---
drivers/atm/firestream.c | 2 ++
drivers/gpu/drm/drm_connector.c | 3 +++
drivers/net/can/rcar/rcar_canfd.c | 6 ++---
drivers/net/ethernet/sfc/mcdi.c | 2 +-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 3 +--
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 1 -
include/net/xfrm.h | 5 ++--
lib/Kconfig | 1 -
net/ipv4/tcp.c | 10 ++++---
net/key/af_key.c | 2 +-
net/mac80211/agg-tx.c | 10 ++++++-
net/wireless/nl80211.c | 3 ++-
net/xfrm/xfrm_policy.c | 14 +++++-----
net/xfrm/xfrm_state.c | 15 ++++++++---
net/xfrm/xfrm_user.c | 27 ++++++-------------
tools/testing/selftests/vm/userfaultfd.c | 1 +
22 files changed, 76 insertions(+), 57 deletions(-)
--
2.20.1
1
19

[PATCH openEuler-1.0-LTS] netfilter: nf_tables: disallow non-stateful expression in sets earlier
by Yongqiang Liu 14 Jun '22
by Yongqiang Liu 14 Jun '22
14 Jun '22
From: Pablo Neira Ayuso <pablo(a)netfilter.org>
mainline inclusion
from mainline-v5.19-rc1
commit 520778042ccca019f3ffa136dd0ca565c486cedd
category: bugfix
bugzilla: 186905, https://gitee.com/src-openeuler/kernel/issues/I5B3QZ
CVE: CVE-2022-1966
--------------------------------
Since 3e135cd499bf ("netfilter: nft_dynset: dynamic stateful expression
instantiation"), it is possible to attach stateful expressions to set
elements.
cd5125d8f518 ("netfilter: nf_tables: split set destruction in deactivate
and destroy phase") introduces conditional destruction on the object to
accomodate transaction semantics.
nft_expr_init() calls expr->ops->init() first, then check for
NFT_STATEFUL_EXPR, this stills allows to initialize a non-stateful
lookup expressions which points to a set, which might lead to UAF since
the set is not properly detached from the set->binding for this case.
Anyway, this combination is non-sense from nf_tables perspective.
This patch fixes this problem by checking for NFT_STATEFUL_EXPR before
expr->ops->init() is called.
The reporter provides a KASAN splat and a poc reproducer (similar to
those autogenerated by syzbot to report use-after-free errors). It is
unknown to me if they are using syzbot or if they use similar automated
tool to locate the bug that they are reporting.
For the record, this is the KASAN splat.
[ 85.431824] ==================================================================
[ 85.432901] BUG: KASAN: use-after-free in nf_tables_bind_set+0x81b/0xa20
[ 85.433825] Write of size 8 at addr ffff8880286f0e98 by task poc/776
[ 85.434756]
[ 85.434999] CPU: 1 PID: 776 Comm: poc Tainted: G W 5.18.0+ #2
[ 85.436023] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
Fixes: 0b2d8a7b638b ("netfilter: nf_tables: add helper functions for expression handling")
Reported-and-tested-by: Aaron Adams <edg-e(a)nccgroup.com>
Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org>
conflict:
net/netfilter/nf_tables_api.c
net/netfilter/nft_dynset.c
Signed-off-by: Lu Wei <luwei32(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
net/netfilter/nf_tables_api.c | 16 ++++++++++------
net/netfilter/nft_dynset.c | 3 ---
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 9cc8e92f4b00..ab68076d2cba 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2167,27 +2167,31 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
err = nf_tables_expr_parse(ctx, nla, &info);
if (err < 0)
- goto err1;
+ goto err_expr_parse;
+
+ err = -EOPNOTSUPP;
+ if (!(info.ops->type->flags & NFT_EXPR_STATEFUL))
+ goto err_expr_stateful;
err = -ENOMEM;
expr = kzalloc(info.ops->size, GFP_KERNEL);
if (expr == NULL)
- goto err2;
+ goto err_expr_stateful;
err = nf_tables_newexpr(ctx, &info, expr);
if (err < 0)
- goto err3;
+ goto err_expr_new;
return expr;
-err3:
+err_expr_new:
kfree(expr);
-err2:
+err_expr_stateful:
owner = info.ops->type->owner;
if (info.ops->type->release_ops)
info.ops->type->release_ops(info.ops);
module_put(owner);
-err1:
+err_expr_parse:
return ERR_PTR(err);
}
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 4e544044fc2d..cc076d535e14 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -193,9 +193,6 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
return PTR_ERR(priv->expr);
err = -EOPNOTSUPP;
- if (!(priv->expr->ops->type->flags & NFT_EXPR_STATEFUL))
- goto err1;
-
if (priv->expr->ops->type->flags & NFT_EXPR_GC) {
if (set->flags & NFT_SET_TIMEOUT)
goto err1;
--
2.25.1
1
0

[PATCH OLK-5.10 v2] eulerfs: fix potential sbi->persisters free error
by gouhao@uniontech.com 14 Jun '22
by gouhao@uniontech.com 14 Jun '22
14 Jun '22
From: Gou Hao <gouhao(a)uniontech.com>
uniontech inclusion
category: bugfix
bugzilla: NA
CVE: NA
-------------------
After alloc the sbi->persisters memory, dep_init
will call dep_fini when error happened.Because
sbi->persisters is not set to 0, -> dep_fini()
can be called with sbi->persisters[] uninitialized,
thus kthread_stop() can be called with random value.
Signed-off-by: Gou Hao <gouhao(a)uniontech.com>
---
fs/eulerfs/dep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/eulerfs/dep.c b/fs/eulerfs/dep.c
index ec014bbf3700..a41471c5f2ec 100644
--- a/fs/eulerfs/dep.c
+++ b/fs/eulerfs/dep.c
@@ -718,7 +718,7 @@ int dep_init(struct super_block *sb)
for_each_possible_cpu(cpu)
init_llist_head(per_cpu_ptr(sbi->persistee_list, cpu));
- sbi->persisters = kmalloc(sizeof(struct task_struct *) *
+ sbi->persisters = kzalloc(sizeof(struct task_struct *) *
persisters_per_socket * num_sockets,
GFP_KERNEL);
if (!sbi->persisters) {
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS 1/2] Revert "NFSv4: Handle the special Linux file open access mode"
by Yongqiang Liu 14 Jun '22
by Yongqiang Liu 14 Jun '22
14 Jun '22
From: ChenXiaoSong <chenxiaosong2(a)huawei.com>
mainline inclusion
from mainline-v5.18-rc2
commit ab0fc21bc7105b54bafd85bd8b82742f9e68898a
category: bugfix
bugzilla: 186890, https://gitee.com/openeuler/kernel/issues/I5BZTX
CVE: NA
--------------------------------
This reverts commit 44942b4e457beda00981f616402a1a791e8c616e.
After secondly opening a file with O_ACCMODE|O_DIRECT flags,
nfs4_valid_open_stateid() will dereference NULL nfs4_state when lseek().
Reproducer:
1. mount -t nfs -o vers=4.2 $server_ip:/ /mnt/
2. fd = open("/mnt/file", O_ACCMODE|O_DIRECT|O_CREAT)
3. close(fd)
4. fd = open("/mnt/file", O_ACCMODE|O_DIRECT)
5. lseek(fd)
Reported-by: Lyu Tao <tao.lyu(a)epfl.ch>
Signed-off-by: ChenXiaoSong <chenxiaosong2(a)huawei.com>
Signed-off-by: Trond Myklebust <trond.myklebust(a)hammerspace.com>
Signed-off-by: ChenXiaoSong <chenxiaosong2(a)huawei.com>
Reviewed-by: Zhang Xiaoxu <zhangxiaoxu5(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/nfs/inode.c | 1 -
fs/nfs/nfs4file.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index db52430dfbd7..053e78d777f1 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1103,7 +1103,6 @@ int nfs_open(struct inode *inode, struct file *filp)
nfs_fscache_open_file(inode, filp);
return 0;
}
-EXPORT_SYMBOL_GPL(nfs_open);
/*
* This function is called whenever some part of NFS notices that
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index e053a883d08d..09d65a654c2b 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -49,7 +49,7 @@ nfs4_file_open(struct inode *inode, struct file *filp)
return err;
if ((openflags & O_ACCMODE) == 3)
- return nfs_open(inode, filp);
+ openflags--;
/* We can't create new files here */
openflags &= ~(O_CREAT|O_EXCL);
--
2.25.1
1
1
您好!
Kernel SIG 邀请您参加 2022-06-17 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler kernel SIG例会&技术分享
会议内容:
openEuler kernel 技术分享:执行实体创建与切换
会议链接:https://us06web.zoom.us/j/82875828076?pwd=cWVmcGtITlJlM0RxcXYzcDlXZjVJUT09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2022-06-17 14:00,
The subject of the conference is openEuler kernel SIG例会&技术分享,
Summary:
openEuler kernel 技术分享:执行实体创建与切换
You can join the meeting at https://us06web.zoom.us/j/82875828076?pwd=cWVmcGtITlJlM0RxcXYzcDlXZjVJUT09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0

09 Jun '22
mainline inclusion
from mainline-5.3.0-rc3
commit 733e4b69d508d03c20adfdcf4bd27abc60fae9cc
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5986O
CVE: NA
--------------------------------
The namespace disk names must be unique for the lifetime of the
subsystem. This was accomplished by using their parent subsystems'
instances which were allocated independently from the controllers
connected to that subsystem. This allowed name prefixes assigned to
namespaces to match a controller from an unrelated subsystem, and has
created confusion among users examining device nodes.
Ensure a namespace's subsystem instance never clashes with a controller
instance of another subsystem by transferring the instance ownership
to the parent subsystem from the first controller discovered in that
subsystem.
Reviewed-by: Logan Gunthorpe <logang(a)deltatee.com>
Signed-off-by: Keith Busch <kbusch(a)kernel.org>
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Reviewed-by: Minwoo Im <minwoo.im(a)samsung.com>
Reviewed-by: Hannes Reinecke <hare(a)suse.com>
Reviewed-off-by: Sagi Grimberg <sagi(a)grimberg.me>
Signed-off-by: Sagi Grimberg <sagi(a)grimberg.me>
Signed-off-by: Chen Taotao <chentt10(a)chinatelecom.cn>
Signed-off-by: Ctyun Kernel <ctyuncommiter01(a)chinatelecom.cn>
---
drivers/nvme/host/core.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 164ec45da..0b47c8fd8 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -89,7 +89,6 @@ EXPORT_SYMBOL_GPL(nvme_reset_wq);
struct workqueue_struct *nvme_delete_wq;
EXPORT_SYMBOL_GPL(nvme_delete_wq);
-static DEFINE_IDA(nvme_subsystems_ida);
static LIST_HEAD(nvme_subsystems);
static DEFINE_MUTEX(nvme_subsystems_lock);
@@ -2350,7 +2349,8 @@ static void nvme_release_subsystem(struct device *dev)
struct nvme_subsystem *subsys =
container_of(dev, struct nvme_subsystem, dev);
- ida_simple_remove(&nvme_subsystems_ida, subsys->instance);
+ if (subsys->instance >= 0)
+ ida_simple_remove(&nvme_instance_ida, subsys->instance);
kfree(subsys);
}
@@ -2461,12 +2461,8 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
if (!subsys)
return -ENOMEM;
- ret = ida_simple_get(&nvme_subsystems_ida, 0, 0, GFP_KERNEL);
- if (ret < 0) {
- kfree(subsys);
- return ret;
- }
- subsys->instance = ret;
+
+ subsys->instance = -1;
mutex_init(&subsys->lock);
kref_init(&subsys->ref);
INIT_LIST_HEAD(&subsys->ctrls);
@@ -2481,7 +2477,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
subsys->dev.class = nvme_subsys_class;
subsys->dev.release = nvme_release_subsystem;
subsys->dev.groups = nvme_subsys_attrs_groups;
- dev_set_name(&subsys->dev, "nvme-subsys%d", subsys->instance);
+ dev_set_name(&subsys->dev, "nvme-subsys%d", ctrl->instance);
device_initialize(&subsys->dev);
mutex_lock(&nvme_subsystems_lock);
@@ -2514,6 +2510,8 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
list_add_tail(&subsys->entry, &nvme_subsystems);
}
+ if (!found)
+ subsys->instance = ctrl->instance;
ctrl->subsys = subsys;
mutex_unlock(&nvme_subsystems_lock);
@@ -3840,7 +3838,9 @@ static void nvme_free_ctrl(struct device *dev)
container_of(dev, struct nvme_ctrl, ctrl_device);
struct nvme_subsystem *subsys = ctrl->subsys;
- ida_simple_remove(&nvme_instance_ida, ctrl->instance);
+ if (subsys && ctrl->instance != subsys->instance)
+ ida_simple_remove(&nvme_instance_ida, ctrl->instance);
+
kfree(ctrl->effects);
nvme_mpath_uninit(ctrl);
__free_page(ctrl->discard_page);
@@ -4102,7 +4102,6 @@ int __init nvme_core_init(void)
void nvme_core_exit(void)
{
- ida_destroy(&nvme_subsystems_ida);
class_destroy(nvme_subsys_class);
class_destroy(nvme_class);
unregister_chrdev_region(nvme_chr_devt, NVME_MINORS);
--
2.27.0
1
0

[openEuler-5.10-LTS 01/11] xhci: Fix a logic issue when display Zhaoxin XHCI root hub speed
by Zheng Zengkai 07 Jun '22
by Zheng Zengkai 07 Jun '22
07 Jun '22
From: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I40QDN
CVE: NA
----------------------------------------------------------------
Fix a logic issue when display Zhaoxin XHCI root hub speed.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
---
drivers/usb/host/xhci.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ba2b2b5afdd1..0984bd31e0e9 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5271,10 +5271,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
if (XHCI_EXT_PORT_PSIV(xhci->port_caps[j].psi[i]) >= 5)
minor_rev = 1;
}
- if (minor_rev != 1) {
- hcd->speed = HCD_USB3;
- hcd->self.root_hub->speed = USB_SPEED_SUPER;
- }
+ }
+ if (minor_rev != 1) {
+ hcd->speed = HCD_USB3;
+ hcd->self.root_hub->speed = USB_SPEED_SUPER;
}
}
--
2.20.1
1
10
Backport 5.10.106 LTS patches from upstream
watch_queue: Fix filter limit check
ext4: add check to prevent attempting to resize an fs with sparse_super2
x86/traps: Mark do_int3() NOKPROBE_SYMBOL
x86/boot: Add setup_indirect support in early_memremap_is_setup_data()
x86/boot: Fix memremap of setup_indirect structures
watch_queue: Make comment about setting ->defunct more accurate
watch_queue: Fix lack of barrier/sync/lock between post and read
watch_queue: Free the alloc bitmap when the watch_queue is torn down
watch_queue: Fix the alloc bitmap size to reflect notes allocated
watch_queue: Fix to always request a pow-of-2 pipe ring size
watch_queue: Fix to release page in ->release()
watch_queue, pipe: Free watchqueue state after clearing pipe ring
virtio: acknowledge all features before access
virtio: unexport virtio_finalize_features
arm64: dts: marvell: armada-37xx: Remap IO space to bus address 0x0
riscv: Fix auipc+jalr relocation range checks
mmc: meson: Fix usage of meson_mmc_post_req()
net: macb: Fix lost RX packet wakeup race in NAPI receive
staging: gdm724x: fix use after free in gdm_lte_rx()
staging: rtl8723bs: Fix access-point mode deadlock
selftests/memfd: clean up mapping in mfd_fail_write
selftest/vm: fix map_fixed_noreplace test failure
tracing: Ensure trace buffer is at least 4096 bytes large
ipv6: prevent a possible race condition with lifetimes
Revert "xen-netback: Check for hotplug-status existence before watching"
Revert "xen-netback: remove 'hotplug-status' once it has served its purpose"
gpio: Return EPROBE_DEFER if gc->to_irq is NULL
hwmon: (pmbus) Clear pmbus fault/warning bits after read
net-sysfs: add check for netdevice being present to speed_show
spi: rockchip: terminate dma transmission when slave abort
spi: rockchip: Fix error in getting num-cs property
selftests/bpf: Add test for bpf_timer overwriting crash
net: bcmgenet: Don't claim WOL when its not available
sctp: fix kernel-infoleak for SCTP sockets
net: phy: DP83822: clear MISR2 register to disable interrupts
gianfar: ethtool: Fix refcount leak in gfar_get_ts_info
gpio: ts4900: Do not set DAT and OE together
selftests: pmtu.sh: Kill tcpdump processes launched by subshell.
NFC: port100: fix use-after-free in port100_send_complete
net/mlx5e: Lag, Only handle events from highest priority multipath entry
net/mlx5: Fix a race on command flush flow
net/mlx5: Fix size field in bufferx_reg struct
net: ethernet: lpc_eth: Handle error for clk_enable
net: ethernet: ti: cpts: Handle error for clk_enable
tipc: fix incorrect order of state message data sanity check
ethernet: Fix error handling in xemaclite_of_probe
ice: Fix curr_link_speed advertised speed
ice: Rename a couple of variables
ice: Remove unnecessary checker loop
ice: Align macro names to the specification
ice: stop disabling VFs due to PF error responses
i40e: stop disabling VFs due to PF error responses
ARM: dts: aspeed: Fix AST2600 quad spi group
net: dsa: mt7530: fix incorrect test in mt753x_phylink_validate()
drm/sun4i: mixer: Fix P010 and P210 format numbers
qed: return status of qed_iov_get_link
esp: Fix BEET mode inter address family tunneling on GSO
net: qlogic: check the return value of dma_alloc_coherent() in
qed_vf_hw_prepare()
isdn: hfcpci: check the return value of dma_set_mask() in setup_hw()
virtio-blk: Don't use MAX_DISCARD_SEGMENTS if max_discard_seg is zero
mISDN: Fix memory leak in dsp_pipeline_build()
mISDN: Remove obsolete PIPELINE_DEBUG debugging information
tipc: fix kernel panic when enabling bearer
arm64: dts: armada-3720-turris-mox: Add missing ethernet0 alias
HID: vivaldi: fix sysfs attributes leak
clk: qcom: gdsc: Add support to update GDSC transition delay
ARM: boot: dts: bcm2711: Fix HVS register range
Already merged:
ax25: Fix NULL pointer dereference in ax25_kill_by_device
ARM: Spectre-BHB: provide empty stub for non-config
fuse: fix pipe buffer lifetime for direct_io
ARM: fix Thumb2 regression with Spectre BHB
Total patches: 71 - 4 = 67
Alexey Khoroshilov (1):
mISDN: Fix memory leak in dsp_pipeline_build()
Aneesh Kumar K.V (1):
selftest/vm: fix map_fixed_noreplace test failure
Anirudh Venkataramanan (3):
ice: Align macro names to the specification
ice: Remove unnecessary checker loop
ice: Rename a couple of variables
Clément Léger (1):
net: phy: DP83822: clear MISR2 register to disable interrupts
Dan Carpenter (1):
staging: gdm724x: fix use after free in gdm_lte_rx()
David Howells (8):
watch_queue, pipe: Free watchqueue state after clearing pipe ring
watch_queue: Fix to release page in ->release()
watch_queue: Fix to always request a pow-of-2 pipe ring size
watch_queue: Fix the alloc bitmap size to reflect notes allocated
watch_queue: Free the alloc bitmap when the watch_queue is torn down
watch_queue: Fix lack of barrier/sync/lock between post and read
watch_queue: Make comment about setting ->defunct more accurate
watch_queue: Fix filter limit check
Dmitry Torokhov (1):
HID: vivaldi: fix sysfs attributes leak
Emil Renner Berthing (1):
riscv: Fix auipc+jalr relocation range checks
Eric Dumazet (1):
sctp: fix kernel-infoleak for SCTP sockets
Guillaume Nault (1):
selftests: pmtu.sh: Kill tcpdump processes launched by subshell.
Hans de Goede (1):
staging: rtl8723bs: Fix access-point mode deadlock
Jacob Keller (2):
i40e: stop disabling VFs due to PF error responses
ice: stop disabling VFs due to PF error responses
Jedrzej Jagielski (1):
ice: Fix curr_link_speed advertised speed
Jeremy Linton (1):
net: bcmgenet: Don't claim WOL when its not available
Jernej Skrabec (1):
drm/sun4i: mixer: Fix P010 and P210 format numbers
Jia-Ju Bai (2):
isdn: hfcpci: check the return value of dma_set_mask() in setup_hw()
net: qlogic: check the return value of dma_alloc_coherent() in
qed_vf_hw_prepare()
Jiasheng Jiang (2):
net: ethernet: ti: cpts: Handle error for clk_enable
net: ethernet: lpc_eth: Handle error for clk_enable
Joel Stanley (1):
ARM: dts: aspeed: Fix AST2600 quad spi group
Jon Lin (2):
spi: rockchip: Fix error in getting num-cs property
spi: rockchip: terminate dma transmission when slave abort
Josh Triplett (1):
ext4: add check to prevent attempting to resize an fs with
sparse_super2
Kumar Kartikeya Dwivedi (1):
selftests/bpf: Add test for bpf_timer overwriting crash
Li Huafei (1):
x86/traps: Mark do_int3() NOKPROBE_SYMBOL
Marek Marczykowski-Górecki (2):
Revert "xen-netback: remove 'hotplug-status' once it has served its
purpose"
Revert "xen-netback: Check for hotplug-status existence before
watching"
Mark Featherston (1):
gpio: ts4900: Do not set DAT and OE together
Maxime Ripard (1):
ARM: boot: dts: bcm2711: Fix HVS register range
Miaoqian Lin (2):
ethernet: Fix error handling in xemaclite_of_probe
gianfar: ethtool: Fix refcount leak in gfar_get_ts_info
Michael S. Tsirkin (2):
virtio: unexport virtio_finalize_features
virtio: acknowledge all features before access
Mike Kravetz (1):
selftests/memfd: clean up mapping in mfd_fail_write
Mohammad Kabat (1):
net/mlx5: Fix size field in bufferx_reg struct
Moshe Shemesh (1):
net/mlx5: Fix a race on command flush flow
Niels Dossche (1):
ipv6: prevent a possible race condition with lifetimes
Pali Rohár (2):
arm64: dts: armada-3720-turris-mox: Add missing ethernet0 alias
arm64: dts: marvell: armada-37xx: Remap IO space to bus address 0x0
Pavel Skripkin (1):
NFC: port100: fix use-after-free in port100_send_complete
Robert Hancock (1):
net: macb: Fix lost RX packet wakeup race in NAPI receive
Roi Dayan (1):
net/mlx5e: Lag, Only handle events from highest priority multipath
entry
Rong Chen (1):
mmc: meson: Fix usage of meson_mmc_post_req()
Ross Philipson (2):
x86/boot: Fix memremap of setup_indirect structures
x86/boot: Add setup_indirect support in early_memremap_is_setup_data()
Russell King (Oracle) (1):
net: dsa: mt7530: fix incorrect test in mt753x_phylink_validate()
Shreeya Patel (1):
gpio: Return EPROBE_DEFER if gc->to_irq is NULL
Steffen Klassert (1):
esp: Fix BEET mode inter address family tunneling on GSO
Sven Schnelle (1):
tracing: Ensure trace buffer is at least 4096 bytes large
Taniya Das (1):
clk: qcom: gdsc: Add support to update GDSC transition delay
Tom Rix (1):
qed: return status of qed_iov_get_link
Tung Nguyen (2):
tipc: fix kernel panic when enabling bearer
tipc: fix incorrect order of state message data sanity check
Vikash Chandola (1):
hwmon: (pmbus) Clear pmbus fault/warning bits after read
Xie Yongji (1):
virtio-blk: Don't use MAX_DISCARD_SEGMENTS if max_discard_seg is zero
Zhen Lei (1):
mISDN: Remove obsolete PIPELINE_DEBUG debugging information
suresh kumar (1):
net-sysfs: add check for netdevice being present to speed_show
arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 2 +-
arch/arm/boot/dts/bcm2711.dtsi | 1 +
.../dts/marvell/armada-3720-turris-mox.dts | 8 +-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 +-
arch/riscv/kernel/module.c | 21 +++--
arch/x86/kernel/e820.c | 41 +++++++---
arch/x86/kernel/kdebugfs.c | 37 ++++++---
arch/x86/kernel/ksysfs.c | 77 +++++++++++++++----
arch/x86/kernel/setup.c | 34 ++++++--
arch/x86/kernel/traps.c | 1 +
arch/x86/mm/ioremap.c | 57 ++++++++++++--
drivers/block/virtio_blk.c | 10 ++-
drivers/clk/qcom/gdsc.c | 26 +++++--
drivers/clk/qcom/gdsc.h | 8 +-
drivers/gpio/gpio-ts4900.c | 24 ++++--
drivers/gpio/gpiolib.c | 10 +++
drivers/gpu/drm/sun4i/sun8i_mixer.h | 8 +-
drivers/hid/hid-vivaldi.c | 2 +-
drivers/hwmon/pmbus/pmbus_core.c | 5 ++
drivers/isdn/hardware/mISDN/hfcpci.c | 6 +-
drivers/isdn/mISDN/dsp_pipeline.c | 52 ++-----------
drivers/mmc/host/meson-gx-mmc.c | 15 ++--
drivers/net/dsa/mt7530.c | 2 +-
.../ethernet/broadcom/genet/bcmgenet_wol.c | 7 ++
drivers/net/ethernet/cadence/macb_main.c | 25 +++++-
.../net/ethernet/freescale/gianfar_ethtool.c | 1 +
.../net/ethernet/intel/i40e/i40e_debugfs.c | 6 +-
.../ethernet/intel/i40e/i40e_virtchnl_pf.c | 57 ++------------
.../ethernet/intel/i40e/i40e_virtchnl_pf.h | 5 --
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 10 +--
drivers/net/ethernet/intel/ice/ice_common.c | 13 ++--
drivers/net/ethernet/intel/ice/ice_ethtool.c | 70 ++++++++---------
drivers/net/ethernet/intel/ice/ice_main.c | 12 +--
.../net/ethernet/intel/ice/ice_virtchnl_pf.c | 18 -----
.../net/ethernet/intel/ice/ice_virtchnl_pf.h | 3 -
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 15 ++--
.../net/ethernet/mellanox/mlx5/core/lag_mp.c | 11 ++-
drivers/net/ethernet/nxp/lpc_eth.c | 5 +-
drivers/net/ethernet/qlogic/qed/qed_sriov.c | 18 +++--
drivers/net/ethernet/qlogic/qed/qed_vf.c | 7 ++
drivers/net/ethernet/ti/cpts.c | 4 +-
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 +-
drivers/net/phy/dp83822.c | 2 +-
drivers/net/xen-netback/xenbus.c | 14 ++--
drivers/nfc/port100.c | 2 +
drivers/spi/spi-rockchip.c | 13 +++-
drivers/staging/gdm724x/gdm_lte.c | 5 +-
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 7 +-
drivers/staging/rtl8723bs/core/rtw_recv.c | 10 ++-
drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 22 +++---
drivers/staging/rtl8723bs/core/rtw_xmit.c | 16 ++--
.../staging/rtl8723bs/hal/rtl8723bs_xmit.c | 2 +
drivers/virtio/virtio.c | 40 +++++-----
fs/ext4/resize.c | 5 ++
fs/pipe.c | 11 ++-
include/linux/mlx5/mlx5_ifc.h | 4 +-
include/linux/virtio.h | 1 -
include/linux/virtio_config.h | 3 +-
include/linux/watch_queue.h | 3 +-
kernel/trace/trace.c | 10 ++-
kernel/watch_queue.c | 15 ++--
net/core/net-sysfs.c | 2 +-
net/ipv4/esp4_offload.c | 3 +
net/ipv6/addrconf.c | 2 +
net/ipv6/esp6_offload.c | 3 +
net/sctp/diag.c | 9 +--
net/tipc/bearer.c | 12 +--
net/tipc/link.c | 9 ++-
.../selftests/bpf/prog_tests/timer_crash.c | 32 ++++++++
.../testing/selftests/bpf/progs/timer_crash.c | 54 +++++++++++++
tools/testing/selftests/memfd/memfd_test.c | 1 +
tools/testing/selftests/net/pmtu.sh | 7 +-
.../selftests/vm/map_fixed_noreplace.c | 49 +++++++++---
73 files changed, 714 insertions(+), 394 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/timer_crash.c
create mode 100644 tools/testing/selftests/bpf/progs/timer_crash.c
--
2.20.1
1
67

[PATCH openEuler-5.10 01/16] xhci: Fix a logic issue when display Zhaoxin XHCI root hub speed
by Zheng Zengkai 07 Jun '22
by Zheng Zengkai 07 Jun '22
07 Jun '22
From: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I40QDN
CVE: NA
----------------------------------------------------------------
Fix a logic issue when display Zhaoxin XHCI root hub speed.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
---
drivers/usb/host/xhci.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ba2b2b5afdd1..0984bd31e0e9 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5271,10 +5271,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
if (XHCI_EXT_PORT_PSIV(xhci->port_caps[j].psi[i]) >= 5)
minor_rev = 1;
}
- if (minor_rev != 1) {
- hcd->speed = HCD_USB3;
- hcd->self.root_hub->speed = USB_SPEED_SUPER;
- }
+ }
+ if (minor_rev != 1) {
+ hcd->speed = HCD_USB3;
+ hcd->self.root_hub->speed = USB_SPEED_SUPER;
}
}
--
2.20.1
1
15

07 Jun '22
Backport SW64 enhancement and bugfix patches from hardware vendor.
Cui Mingrui (2):
sw64: optimize ip checksum calculation
sw64: fix ip checksum calculation
Du Yilong (3):
sw64: kvm: fix bug when open file with the O_DIRECT flag
sw64: add set time support for hypervisor based rtc
sw64: kvm: remap pages of guest by vm_insert_page()
Gu Zitao (7):
config: add initial openeuler_defconfig for sw64
sw64: fix coding style problems
sw64: fix the VDSO symbol generation for nm
sw64: fix SPDX license identifier in uapi headers
sw64: add SO_RCVTIMEO/ SO_SNDTIMEO socket options
sw64: remove unnecessary include headers
sw64: fix some compile errors
He Chuyue (2):
sw64: add regs and stack access APIs to support kprobe events
sw64: remove unnecessary parameter in REG_OFFSET_NAME
He Sheng (20):
sw64: clean up useless #if 0 and #if 1
sw64: switch GUP to the generic get_user_pages_fast() implementation
sw64: remove unused a.out.h
sw64: fix ex_table entries from misalignment handlers
sw64: define NR_SYSCALLS as generated __NR_syscalls
sw64: clean up a.out and ECOFF binary related headers
sw64: ptrace: clean up debug codes
sw64: add kbuild defconfig rule
sw64: clean up out-of-date selected options
sw64: Kconfig: remove dependence on !PREEMPT
sw64: Kconfig: remove dependence on ARCH_SUPPORTS_ACPI
sw64: add missing global __constant_c_memset
sw64: do some cleanups for rt_sigframe
sw64: fix setup_rt_frame for non SA_SIGINFO
sw64: fix compile error for DISCONTIGMEM=y
sw64: force signal and fault for traps and debugging
sw64: push and pop kernel stack with ldi instruction
sw64: signal: save/restore fpregs with copy user
sw64: fix the number of aux entries in ARCH_DLINFO
sw64: fix sendfile system call
Lu Feifei (6):
sw64: fix printk method for guest os
sw64: unify access to LONGTIME for guest and emulator
sw64: kvm: handle ldl_u and stl_u when exit mmio
sw64: kvm: simplify the code
sw64: pci: align the address of mmio resource to PAGE_SIZE
sw64: unify 32-bit MEMIO address of host and guest
Mao Minkai (29):
sw64: vdso: add automatic syscall fallback
sw64: vdso: change vdso version
sw64: vdso: fix time calculation
sw64: mm: reorder memblock_init process
sw64: mm: warn overlapped memmap and DMA region
sw64: mm: use memblock to find the end of memory
sw64: print correct initrd address
sw64: remove redundant Kconfig source
sw64: modify tc_sched_clock debugfs file
sw64: simplify cpumask_of_node
sw64: remove CONFIG_USE_PERCPU_NUMA_NODE_ID=n code
sw64: fix all compile warnings
sw64: numa: switch to arch node_distance
sw64: mm: mark pci and memmap region as nomap
sw64: use jump label for running modes
sw64: remove MAX_ASN
sw64: kvm: remove MAX_VPN
sw64: fix coding style problems
sw64: rename kvm_mem variables
sw64: reformat syscall.tbl
sw64: add missing pkey syscall numbers
sw64: add clone3 syscall support
sw64: add required include headers to ptrace.h
sw64: switch to old-style semctl/shmctl syscalls
sw64: increase position index in c_next for cpuinfo
sw64: add old sigprocmask back for compatibility
sw64: vdso: fix backtrace of vrt_sigreturn
sw64: vdso: fix CFI directives for fpregs in vrt_sigreturn
sw64: optimize simd version of memcpy and memset
Min Fanlei (4):
sw64: fix the value of QEMU_PRINTF_BUFF_BASE
sw64: add support for emulator running mode
sw64: enable more than 32 CPUs for guest
sw64: kvm: fix bad page state setting outside of kvm memory pool
Tang Jinyang (2):
sw64: add dynamic frequency scaling support
sw64: add dynamic turning on/off cores support
Wang Yingying (3):
hwmon: add voltage sensor support for sw64
sw64: add pvt device to chip3.dts
hwmon: add support for sw64 temperature sensor
Xu Chenjiao (2):
sw64: radeon: add a force flush to delay work when radeon uvd suspend
sw64: pcie: enable PME and AER support
Zhao Yihan (1):
sw64: remap PA with |= in early_ioremap
Zheng Chongzhen (3):
sw64: re-implement sw64_dma_direct_ops according upstream
sw64: iommu: fix 32-bit devices dma ops
sw64: fix compile error for CONFIG_PCI=n
Zhou Xuemei (5):
sw64: pci: remove some useless code
sw64: switch to generic pcibios_set_master and pci_common_swizzle
sw64: clean up some useless codes
sw64: dts: rename spi flash partition to fix warning
sw64: add ARCH_HAS_PTE_SPECIAL support
Zhu Donghong (1):
ipmi: add ipmi driver support
arch/sw_64/Kconfig | 325 +-
arch/sw_64/Makefile | 1 +
arch/sw_64/boot/dts/chip3.dts | 41 +-
arch/sw_64/chip/chip3/chip.c | 130 +-
arch/sw_64/chip/chip3/cpufreq_debugfs.c | 7 +-
arch/sw_64/chip/chip3/i2c-lib.c | 4 -
arch/sw_64/chip/chip3/irq_chip.c | 13 +-
arch/sw_64/chip/chip3/msi.c | 7 +-
arch/sw_64/chip/chip3/pci-quirks.c | 7 +-
arch/sw_64/chip/chip3/vt_msi.c | 6 -
arch/sw_64/configs/openeuler_defconfig | 4312 +++++++++++++++++++++
arch/sw_64/defconfig | 73 -
arch/sw_64/include/asm/Kbuild | 1 +
arch/sw_64/include/asm/a.out-core.h | 80 -
arch/sw_64/include/asm/a.out.h | 16 -
arch/sw_64/include/asm/checksum.h | 58 +-
arch/sw_64/include/asm/chip3_io.h | 4 +-
arch/sw_64/include/asm/clock.h | 56 +
arch/sw_64/include/asm/cputime.h | 4 +-
arch/sw_64/include/asm/early_ioremap.h | 2 +-
arch/sw_64/include/asm/hw_init.h | 29 +-
arch/sw_64/include/asm/kvm_host.h | 3 +-
arch/sw_64/include/asm/mmu_context.h | 3 +-
arch/sw_64/include/asm/numa.h | 1 +
arch/sw_64/include/asm/pci.h | 24 +-
arch/sw_64/include/asm/pgtable.h | 26 +-
arch/sw_64/include/asm/ptrace.h | 8 +-
arch/sw_64/include/asm/topology.h | 29 +-
arch/sw_64/include/asm/unistd.h | 3 +-
arch/sw_64/include/asm/user.h | 53 -
arch/sw_64/include/asm/vdso.h | 4 +-
arch/sw_64/include/asm/vga.h | 18 +-
arch/sw_64/include/uapi/asm/a.out.h | 88 -
arch/sw_64/include/uapi/asm/auxvec.h | 25 +-
arch/sw_64/include/uapi/asm/bitsperlong.h | 2 +-
arch/sw_64/include/uapi/asm/byteorder.h | 2 +-
arch/sw_64/include/uapi/asm/compiler.h | 2 +-
arch/sw_64/include/uapi/asm/console.h | 2 +-
arch/sw_64/include/uapi/asm/errno.h | 2 +-
arch/sw_64/include/uapi/asm/fcntl.h | 2 +-
arch/sw_64/include/uapi/asm/fpu.h | 2 +-
arch/sw_64/include/uapi/asm/gentrap.h | 2 +-
arch/sw_64/include/uapi/asm/hmcall.h | 2 +-
arch/sw_64/include/uapi/asm/ioctl.h | 2 +-
arch/sw_64/include/uapi/asm/ioctls.h | 48 +-
arch/sw_64/include/uapi/asm/ipcbuf.h | 2 +-
arch/sw_64/include/uapi/asm/kvm.h | 14 +-
arch/sw_64/include/uapi/asm/kvm_para.h | 2 +-
arch/sw_64/include/uapi/asm/mman.h | 2 +-
arch/sw_64/include/uapi/asm/msgbuf.h | 2 +-
arch/sw_64/include/uapi/asm/param.h | 2 +-
arch/sw_64/include/uapi/asm/poll.h | 2 +-
arch/sw_64/include/uapi/asm/posix_types.h | 2 +-
arch/sw_64/include/uapi/asm/ptrace.h | 2 +-
arch/sw_64/include/uapi/asm/reg.h | 2 +-
arch/sw_64/include/uapi/asm/regdef.h | 2 +-
arch/sw_64/include/uapi/asm/resource.h | 2 +-
arch/sw_64/include/uapi/asm/sembuf.h | 2 +-
arch/sw_64/include/uapi/asm/setup.h | 2 +-
arch/sw_64/include/uapi/asm/shmbuf.h | 2 +-
arch/sw_64/include/uapi/asm/sigcontext.h | 2 +-
arch/sw_64/include/uapi/asm/siginfo.h | 2 +-
arch/sw_64/include/uapi/asm/signal.h | 2 +-
arch/sw_64/include/uapi/asm/socket.h | 34 +-
arch/sw_64/include/uapi/asm/sockios.h | 2 +-
arch/sw_64/include/uapi/asm/stat.h | 2 +-
arch/sw_64/include/uapi/asm/statfs.h | 2 +-
arch/sw_64/include/uapi/asm/swab.h | 2 +-
arch/sw_64/include/uapi/asm/sysinfo.h | 2 +-
arch/sw_64/include/uapi/asm/termbits.h | 2 +-
arch/sw_64/include/uapi/asm/termios.h | 2 +-
arch/sw_64/include/uapi/asm/types.h | 2 +-
arch/sw_64/include/uapi/asm/unistd.h | 7 +-
arch/sw_64/kernel/Makefile | 5 +-
arch/sw_64/kernel/acpi.c | 19 +-
arch/sw_64/kernel/asm-offsets.c | 7 +-
arch/sw_64/kernel/audit.c | 2 +-
arch/sw_64/kernel/cacheinfo.c | 3 +-
arch/sw_64/kernel/clock.c | 184 +
arch/sw_64/kernel/core.c | 41 +-
arch/sw_64/kernel/cpuautoplug.c | 496 +++
arch/sw_64/kernel/crash_dump.c | 2 -
arch/sw_64/kernel/dup_print.c | 10 +-
arch/sw_64/kernel/early_printk.c | 4 +-
arch/sw_64/kernel/entry.S | 5 +-
arch/sw_64/kernel/ftrace.c | 5 -
arch/sw_64/kernel/insn.c | 13 -
arch/sw_64/kernel/irq.c | 15 -
arch/sw_64/kernel/irq_sw64.c | 9 +-
arch/sw_64/kernel/jump_label.c | 3 +-
arch/sw_64/kernel/kgdb.c | 9 +-
arch/sw_64/kernel/kprobes/decode-insn.c | 6 +-
arch/sw_64/kernel/kprobes/kprobes.c | 4 -
arch/sw_64/kernel/kvm_cma.c | 4 -
arch/sw_64/kernel/machine_kexec.c | 7 +-
arch/sw_64/kernel/module.c | 9 -
arch/sw_64/kernel/msi.c | 25 -
arch/sw_64/kernel/pci-noop.c | 8 -
arch/sw_64/kernel/pci-sysfs.c | 3 -
arch/sw_64/kernel/pci.c | 102 +-
arch/sw_64/kernel/pci_common.c | 285 +-
arch/sw_64/kernel/pci_impl.h | 49 -
arch/sw_64/kernel/perf_event.c | 12 -
arch/sw_64/kernel/perf_regs.c | 4 -
arch/sw_64/kernel/platform.c | 20 +
arch/sw_64/kernel/process.c | 26 -
arch/sw_64/kernel/ptrace.c | 132 +-
arch/sw_64/kernel/relocate.c | 13 +-
arch/sw_64/kernel/segvdbg.c | 4 +-
arch/sw_64/kernel/setup.c | 124 +-
arch/sw_64/kernel/signal.c | 74 +-
arch/sw_64/kernel/smp.c | 25 +-
arch/sw_64/kernel/stacktrace.c | 1 -
arch/sw_64/kernel/suspend.c | 22 +-
arch/sw_64/kernel/syscalls/syscall.tbl | 28 +-
arch/sw_64/kernel/tc.c | 3 -
arch/sw_64/kernel/time.c | 31 +-
arch/sw_64/kernel/timer.c | 21 +-
arch/sw_64/kernel/topology.c | 19 -
arch/sw_64/kernel/traps.c | 95 +-
arch/sw_64/kernel/unaligned.c | 3 -
arch/sw_64/kernel/uprobes.c | 5 -
arch/sw_64/kernel/vdso.c | 9 -
arch/sw_64/kernel/vdso/so2s.sh | 3 +-
arch/sw_64/kernel/vdso/vdso.S | 2 -
arch/sw_64/kernel/vdso/vdso.lds.S | 2 +-
arch/sw_64/kernel/vdso/vgettimeofday.c | 33 +-
arch/sw_64/kernel/vdso/vrt_sigreturn.S | 40 +
arch/sw_64/kvm/emulate.c | 2 +
arch/sw_64/kvm/kvm-sw64.c | 39 +-
arch/sw_64/kvm/vmem.c | 37 +-
arch/sw_64/lib/checksum.c | 136 +-
arch/sw_64/lib/csum_partial_copy.c | 310 +-
arch/sw_64/lib/deep-memcpy.S | 449 ++-
arch/sw_64/lib/deep-memset.S | 27 +-
arch/sw_64/lib/fls.c | 1 -
arch/sw_64/lib/iomap.c | 4 +-
arch/sw_64/lib/udelay.c | 5 -
arch/sw_64/math-emu/math.c | 10 +-
arch/sw_64/mm/fault.c | 21 +-
arch/sw_64/mm/hugetlbpage.c | 7 +-
arch/sw_64/mm/init.c | 48 +-
arch/sw_64/mm/numa.c | 30 +-
arch/sw_64/mm/physaddr.c | 1 -
arch/sw_64/mm/thp.c | 9 -
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/sw64_cpufreq.c | 186 +
drivers/gpu/drm/radeon/radeon_uvd.c | 5 +
drivers/hwmon/Kconfig | 10 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/sw64_pvt.c | 223 ++
drivers/iommu/sw64/sunway_iommu.c | 58 +-
drivers/iommu/sw64/sunway_iommu.h | 2 +-
drivers/rtc/rtc-sw64-virt.c | 24 +-
154 files changed, 7028 insertions(+), 2337 deletions(-)
create mode 100644 arch/sw_64/configs/openeuler_defconfig
delete mode 100644 arch/sw_64/defconfig
delete mode 100644 arch/sw_64/include/asm/a.out-core.h
delete mode 100644 arch/sw_64/include/asm/a.out.h
create mode 100644 arch/sw_64/include/asm/clock.h
delete mode 100644 arch/sw_64/include/asm/user.h
delete mode 100644 arch/sw_64/include/uapi/asm/a.out.h
create mode 100644 arch/sw_64/kernel/clock.c
create mode 100644 arch/sw_64/kernel/cpuautoplug.c
create mode 100644 arch/sw_64/kernel/platform.c
create mode 100644 drivers/cpufreq/sw64_cpufreq.c
create mode 100644 drivers/hwmon/sw64_pvt.c
--
2.20.1
1
90
Backport 5.10.106 LTS patches from upstream
watch_queue: Fix filter limit check
ext4: add check to prevent attempting to resize an fs with sparse_super2
x86/traps: Mark do_int3() NOKPROBE_SYMBOL
x86/boot: Add setup_indirect support in early_memremap_is_setup_data()
x86/boot: Fix memremap of setup_indirect structures
watch_queue: Make comment about setting ->defunct more accurate
watch_queue: Fix lack of barrier/sync/lock between post and read
watch_queue: Free the alloc bitmap when the watch_queue is torn down
watch_queue: Fix the alloc bitmap size to reflect notes allocated
watch_queue: Fix to always request a pow-of-2 pipe ring size
watch_queue: Fix to release page in ->release()
watch_queue, pipe: Free watchqueue state after clearing pipe ring
virtio: acknowledge all features before access
virtio: unexport virtio_finalize_features
arm64: dts: marvell: armada-37xx: Remap IO space to bus address 0x0
riscv: Fix auipc+jalr relocation range checks
mmc: meson: Fix usage of meson_mmc_post_req()
net: macb: Fix lost RX packet wakeup race in NAPI receive
staging: gdm724x: fix use after free in gdm_lte_rx()
staging: rtl8723bs: Fix access-point mode deadlock
selftests/memfd: clean up mapping in mfd_fail_write
selftest/vm: fix map_fixed_noreplace test failure
tracing: Ensure trace buffer is at least 4096 bytes large
ipv6: prevent a possible race condition with lifetimes
Revert "xen-netback: Check for hotplug-status existence before watching"
Revert "xen-netback: remove 'hotplug-status' once it has served its purpose"
gpio: Return EPROBE_DEFER if gc->to_irq is NULL
hwmon: (pmbus) Clear pmbus fault/warning bits after read
net-sysfs: add check for netdevice being present to speed_show
spi: rockchip: terminate dma transmission when slave abort
spi: rockchip: Fix error in getting num-cs property
selftests/bpf: Add test for bpf_timer overwriting crash
net: bcmgenet: Don't claim WOL when its not available
sctp: fix kernel-infoleak for SCTP sockets
net: phy: DP83822: clear MISR2 register to disable interrupts
gianfar: ethtool: Fix refcount leak in gfar_get_ts_info
gpio: ts4900: Do not set DAT and OE together
selftests: pmtu.sh: Kill tcpdump processes launched by subshell.
NFC: port100: fix use-after-free in port100_send_complete
net/mlx5e: Lag, Only handle events from highest priority multipath entry
net/mlx5: Fix a race on command flush flow
net/mlx5: Fix size field in bufferx_reg struct
net: ethernet: lpc_eth: Handle error for clk_enable
net: ethernet: ti: cpts: Handle error for clk_enable
tipc: fix incorrect order of state message data sanity check
ethernet: Fix error handling in xemaclite_of_probe
ice: Fix curr_link_speed advertised speed
ice: Rename a couple of variables
ice: Remove unnecessary checker loop
ice: Align macro names to the specification
ice: stop disabling VFs due to PF error responses
i40e: stop disabling VFs due to PF error responses
ARM: dts: aspeed: Fix AST2600 quad spi group
net: dsa: mt7530: fix incorrect test in mt753x_phylink_validate()
drm/sun4i: mixer: Fix P010 and P210 format numbers
qed: return status of qed_iov_get_link
esp: Fix BEET mode inter address family tunneling on GSO
net: qlogic: check the return value of dma_alloc_coherent() in
qed_vf_hw_prepare()
isdn: hfcpci: check the return value of dma_set_mask() in setup_hw()
virtio-blk: Don't use MAX_DISCARD_SEGMENTS if max_discard_seg is zero
mISDN: Fix memory leak in dsp_pipeline_build()
mISDN: Remove obsolete PIPELINE_DEBUG debugging information
tipc: fix kernel panic when enabling bearer
arm64: dts: armada-3720-turris-mox: Add missing ethernet0 alias
HID: vivaldi: fix sysfs attributes leak
clk: qcom: gdsc: Add support to update GDSC transition delay
ARM: boot: dts: bcm2711: Fix HVS register range
Already merged:
ax25: Fix NULL pointer dereference in ax25_kill_by_device
ARM: Spectre-BHB: provide empty stub for non-config
fuse: fix pipe buffer lifetime for direct_io
ARM: fix Thumb2 regression with Spectre BHB
Total patches: 71 - 4 = 67
Alexey Khoroshilov (1):
mISDN: Fix memory leak in dsp_pipeline_build()
Aneesh Kumar K.V (1):
selftest/vm: fix map_fixed_noreplace test failure
Anirudh Venkataramanan (3):
ice: Align macro names to the specification
ice: Remove unnecessary checker loop
ice: Rename a couple of variables
Clément Léger (1):
net: phy: DP83822: clear MISR2 register to disable interrupts
Dan Carpenter (1):
staging: gdm724x: fix use after free in gdm_lte_rx()
David Howells (8):
watch_queue, pipe: Free watchqueue state after clearing pipe ring
watch_queue: Fix to release page in ->release()
watch_queue: Fix to always request a pow-of-2 pipe ring size
watch_queue: Fix the alloc bitmap size to reflect notes allocated
watch_queue: Free the alloc bitmap when the watch_queue is torn down
watch_queue: Fix lack of barrier/sync/lock between post and read
watch_queue: Make comment about setting ->defunct more accurate
watch_queue: Fix filter limit check
Dmitry Torokhov (1):
HID: vivaldi: fix sysfs attributes leak
Emil Renner Berthing (1):
riscv: Fix auipc+jalr relocation range checks
Eric Dumazet (1):
sctp: fix kernel-infoleak for SCTP sockets
Guillaume Nault (1):
selftests: pmtu.sh: Kill tcpdump processes launched by subshell.
Hans de Goede (1):
staging: rtl8723bs: Fix access-point mode deadlock
Jacob Keller (2):
i40e: stop disabling VFs due to PF error responses
ice: stop disabling VFs due to PF error responses
Jedrzej Jagielski (1):
ice: Fix curr_link_speed advertised speed
Jeremy Linton (1):
net: bcmgenet: Don't claim WOL when its not available
Jernej Skrabec (1):
drm/sun4i: mixer: Fix P010 and P210 format numbers
Jia-Ju Bai (2):
isdn: hfcpci: check the return value of dma_set_mask() in setup_hw()
net: qlogic: check the return value of dma_alloc_coherent() in
qed_vf_hw_prepare()
Jiasheng Jiang (2):
net: ethernet: ti: cpts: Handle error for clk_enable
net: ethernet: lpc_eth: Handle error for clk_enable
Joel Stanley (1):
ARM: dts: aspeed: Fix AST2600 quad spi group
Jon Lin (2):
spi: rockchip: Fix error in getting num-cs property
spi: rockchip: terminate dma transmission when slave abort
Josh Triplett (1):
ext4: add check to prevent attempting to resize an fs with
sparse_super2
Kumar Kartikeya Dwivedi (1):
selftests/bpf: Add test for bpf_timer overwriting crash
Li Huafei (1):
x86/traps: Mark do_int3() NOKPROBE_SYMBOL
Marek Marczykowski-Górecki (2):
Revert "xen-netback: remove 'hotplug-status' once it has served its
purpose"
Revert "xen-netback: Check for hotplug-status existence before
watching"
Mark Featherston (1):
gpio: ts4900: Do not set DAT and OE together
Maxime Ripard (1):
ARM: boot: dts: bcm2711: Fix HVS register range
Miaoqian Lin (2):
ethernet: Fix error handling in xemaclite_of_probe
gianfar: ethtool: Fix refcount leak in gfar_get_ts_info
Michael S. Tsirkin (2):
virtio: unexport virtio_finalize_features
virtio: acknowledge all features before access
Mike Kravetz (1):
selftests/memfd: clean up mapping in mfd_fail_write
Mohammad Kabat (1):
net/mlx5: Fix size field in bufferx_reg struct
Moshe Shemesh (1):
net/mlx5: Fix a race on command flush flow
Niels Dossche (1):
ipv6: prevent a possible race condition with lifetimes
Pali Rohár (2):
arm64: dts: armada-3720-turris-mox: Add missing ethernet0 alias
arm64: dts: marvell: armada-37xx: Remap IO space to bus address 0x0
Pavel Skripkin (1):
NFC: port100: fix use-after-free in port100_send_complete
Robert Hancock (1):
net: macb: Fix lost RX packet wakeup race in NAPI receive
Roi Dayan (1):
net/mlx5e: Lag, Only handle events from highest priority multipath
entry
Rong Chen (1):
mmc: meson: Fix usage of meson_mmc_post_req()
Ross Philipson (2):
x86/boot: Fix memremap of setup_indirect structures
x86/boot: Add setup_indirect support in early_memremap_is_setup_data()
Russell King (Oracle) (1):
net: dsa: mt7530: fix incorrect test in mt753x_phylink_validate()
Shreeya Patel (1):
gpio: Return EPROBE_DEFER if gc->to_irq is NULL
Steffen Klassert (1):
esp: Fix BEET mode inter address family tunneling on GSO
Sven Schnelle (1):
tracing: Ensure trace buffer is at least 4096 bytes large
Taniya Das (1):
clk: qcom: gdsc: Add support to update GDSC transition delay
Tom Rix (1):
qed: return status of qed_iov_get_link
Tung Nguyen (2):
tipc: fix kernel panic when enabling bearer
tipc: fix incorrect order of state message data sanity check
Vikash Chandola (1):
hwmon: (pmbus) Clear pmbus fault/warning bits after read
Xie Yongji (1):
virtio-blk: Don't use MAX_DISCARD_SEGMENTS if max_discard_seg is zero
Zhen Lei (1):
mISDN: Remove obsolete PIPELINE_DEBUG debugging information
suresh kumar (1):
net-sysfs: add check for netdevice being present to speed_show
arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 2 +-
arch/arm/boot/dts/bcm2711.dtsi | 1 +
.../dts/marvell/armada-3720-turris-mox.dts | 8 +-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 +-
arch/riscv/kernel/module.c | 21 +++--
arch/x86/kernel/e820.c | 41 +++++++---
arch/x86/kernel/kdebugfs.c | 37 ++++++---
arch/x86/kernel/ksysfs.c | 77 +++++++++++++++----
arch/x86/kernel/setup.c | 34 ++++++--
arch/x86/kernel/traps.c | 1 +
arch/x86/mm/ioremap.c | 57 ++++++++++++--
drivers/block/virtio_blk.c | 10 ++-
drivers/clk/qcom/gdsc.c | 26 +++++--
drivers/clk/qcom/gdsc.h | 8 +-
drivers/gpio/gpio-ts4900.c | 24 ++++--
drivers/gpio/gpiolib.c | 10 +++
drivers/gpu/drm/sun4i/sun8i_mixer.h | 8 +-
drivers/hid/hid-vivaldi.c | 2 +-
drivers/hwmon/pmbus/pmbus_core.c | 5 ++
drivers/isdn/hardware/mISDN/hfcpci.c | 6 +-
drivers/isdn/mISDN/dsp_pipeline.c | 52 ++-----------
drivers/mmc/host/meson-gx-mmc.c | 15 ++--
drivers/net/dsa/mt7530.c | 2 +-
.../ethernet/broadcom/genet/bcmgenet_wol.c | 7 ++
drivers/net/ethernet/cadence/macb_main.c | 25 +++++-
.../net/ethernet/freescale/gianfar_ethtool.c | 1 +
.../net/ethernet/intel/i40e/i40e_debugfs.c | 6 +-
.../ethernet/intel/i40e/i40e_virtchnl_pf.c | 57 ++------------
.../ethernet/intel/i40e/i40e_virtchnl_pf.h | 5 --
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 10 +--
drivers/net/ethernet/intel/ice/ice_common.c | 13 ++--
drivers/net/ethernet/intel/ice/ice_ethtool.c | 70 ++++++++---------
drivers/net/ethernet/intel/ice/ice_main.c | 12 +--
.../net/ethernet/intel/ice/ice_virtchnl_pf.c | 18 -----
.../net/ethernet/intel/ice/ice_virtchnl_pf.h | 3 -
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 15 ++--
.../net/ethernet/mellanox/mlx5/core/lag_mp.c | 11 ++-
drivers/net/ethernet/nxp/lpc_eth.c | 5 +-
drivers/net/ethernet/qlogic/qed/qed_sriov.c | 18 +++--
drivers/net/ethernet/qlogic/qed/qed_vf.c | 7 ++
drivers/net/ethernet/ti/cpts.c | 4 +-
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 +-
drivers/net/phy/dp83822.c | 2 +-
drivers/net/xen-netback/xenbus.c | 14 ++--
drivers/nfc/port100.c | 2 +
drivers/spi/spi-rockchip.c | 13 +++-
drivers/staging/gdm724x/gdm_lte.c | 5 +-
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 7 +-
drivers/staging/rtl8723bs/core/rtw_recv.c | 10 ++-
drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 22 +++---
drivers/staging/rtl8723bs/core/rtw_xmit.c | 16 ++--
.../staging/rtl8723bs/hal/rtl8723bs_xmit.c | 2 +
drivers/virtio/virtio.c | 40 +++++-----
fs/ext4/resize.c | 5 ++
fs/pipe.c | 11 ++-
include/linux/mlx5/mlx5_ifc.h | 4 +-
include/linux/virtio.h | 1 -
include/linux/virtio_config.h | 3 +-
include/linux/watch_queue.h | 3 +-
kernel/trace/trace.c | 10 ++-
kernel/watch_queue.c | 15 ++--
net/core/net-sysfs.c | 2 +-
net/ipv4/esp4_offload.c | 3 +
net/ipv6/addrconf.c | 2 +
net/ipv6/esp6_offload.c | 3 +
net/sctp/diag.c | 9 +--
net/tipc/bearer.c | 12 +--
net/tipc/link.c | 9 ++-
.../selftests/bpf/prog_tests/timer_crash.c | 32 ++++++++
.../testing/selftests/bpf/progs/timer_crash.c | 54 +++++++++++++
tools/testing/selftests/memfd/memfd_test.c | 1 +
tools/testing/selftests/net/pmtu.sh | 7 +-
.../selftests/vm/map_fixed_noreplace.c | 49 +++++++++---
73 files changed, 714 insertions(+), 394 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/timer_crash.c
create mode 100644 tools/testing/selftests/bpf/progs/timer_crash.c
--
2.20.1
1
67

06 Jun '22
The namespace disk names must be unique for the lifetime of the
subsystem. This was accomplished by using their parent subsystems'
instances which were allocated independently from the controllers
connected to that subsystem. This allowed name prefixes assigned to
namespaces to match a controller from an unrelated subsystem, and has
created confusion among users examining device nodes.
Ensure a namespace's subsystem instance never clashes with a controller
instance of another subsystem by transferring the instance ownership
to the parent subsystem from the first controller discovered in that
subsystem.
Reviewed-by: Logan Gunthorpe <logang(a)deltatee.com>
Signed-off-by: Keith Busch <kbusch(a)kernel.org>
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Reviewed-by: Minwoo Im <minwoo.im(a)samsung.com>
Reviewed-by: Hannes Reinecke <hare(a)suse.com>
Reviewed-off-by: Sagi Grimberg <sagi(a)grimberg.me>
Signed-off-by: Sagi Grimberg <sagi(a)grimberg.me>
---
drivers/nvme/host/core.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 8c760493354f..576da5820a57 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -88,7 +88,6 @@ EXPORT_SYMBOL_GPL(nvme_reset_wq);
struct workqueue_struct *nvme_delete_wq;
EXPORT_SYMBOL_GPL(nvme_delete_wq);
-static DEFINE_IDA(nvme_subsystems_ida);
static LIST_HEAD(nvme_subsystems);
static DEFINE_MUTEX(nvme_subsystems_lock);
@@ -2308,7 +2307,8 @@ static void nvme_release_subsystem(struct device *dev)
struct nvme_subsystem *subsys =
container_of(dev, struct nvme_subsystem, dev);
- ida_simple_remove(&nvme_subsystems_ida, subsys->instance);
+ if (subsys->instance >= 0)
+ ida_simple_remove(&nvme_instance_ida, subsys->instance);
kfree(subsys);
}
@@ -2419,12 +2419,8 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
if (!subsys)
return -ENOMEM;
- ret = ida_simple_get(&nvme_subsystems_ida, 0, 0, GFP_KERNEL);
- if (ret < 0) {
- kfree(subsys);
- return ret;
- }
- subsys->instance = ret;
+
+ subsys->instance = -1;
mutex_init(&subsys->lock);
kref_init(&subsys->ref);
INIT_LIST_HEAD(&subsys->ctrls);
@@ -2439,7 +2435,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
subsys->dev.class = nvme_subsys_class;
subsys->dev.release = nvme_release_subsystem;
subsys->dev.groups = nvme_subsys_attrs_groups;
- dev_set_name(&subsys->dev, "nvme-subsys%d", subsys->instance);
+ dev_set_name(&subsys->dev, "nvme-subsys%d", ctrl->instance);
device_initialize(&subsys->dev);
mutex_lock(&nvme_subsystems_lock);
@@ -2472,6 +2468,8 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
list_add_tail(&subsys->entry, &nvme_subsystems);
}
+ if (!found)
+ subsys->instance = ctrl->instance;
ctrl->subsys = subsys;
mutex_unlock(&nvme_subsystems_lock);
@@ -3749,7 +3747,9 @@ static void nvme_free_ctrl(struct device *dev)
container_of(dev, struct nvme_ctrl, ctrl_device);
struct nvme_subsystem *subsys = ctrl->subsys;
- ida_simple_remove(&nvme_instance_ida, ctrl->instance);
+ if (subsys && ctrl->instance != subsys->instance)
+ ida_simple_remove(&nvme_instance_ida, ctrl->instance);
+
kfree(ctrl->effects);
nvme_mpath_uninit(ctrl);
__free_page(ctrl->discard_page);
@@ -4009,7 +4009,6 @@ int __init nvme_core_init(void)
void nvme_core_exit(void)
{
- ida_destroy(&nvme_subsystems_ida);
class_destroy(nvme_subsys_class);
class_destroy(nvme_class);
unregister_chrdev_region(nvme_chr_devt, NVME_MINORS);
--
2.27.0
1
0
在 2022/06/02 19:24, Gou Hao 写道:
>
> 在 2022/6/2 17:10, Yu Kuai 写道:
>> 在 2022/06/02 10:50, Gou Hao 写道:
>>> uniontech inclusion
>>> category: bugfix
>>> bugzilla: NA
>>> CVE: NA
>>>
>>> ----------------------
>>>
>>> We should not get the socket num in init_eufs_fs, becuse
>>> system usually supports cpu hotplug,so we should get socket
>>> num in dep_int.
>> Hi,
>>
>> What if cpu is offline during mount, and online afterwards?
>>
> Well, in this case, we have to add a monitoring mechanism to
>
> dynamically adjust the number of threads according to the
>
> online status of the CPU.
>
> Or there are other better ways ...
I prefer to keep the current implementation for now.
Thanks,
Kuai
>> Thanks,
>> Kuai
>>>
>>> Socket num is not necessarily the same when file system
>>> mount,so it shoule be eufs_sb_info's member.
>>>
>>> Signed-off-by: Gou Hao <gouhao(a)uniontech.com>
>>> ---
>>> fs/eulerfs/dep.c | 28 ++++++++++++++++++++++------
>>> fs/eulerfs/euler.h | 2 --
>>> fs/eulerfs/euler_def.h | 1 +
>>> fs/eulerfs/super.c | 15 +--------------
>>> 4 files changed, 24 insertions(+), 22 deletions(-)
>>
2
1

[openEuler-22.09 00/34] bcache backport for openEuler-22.09 (up to Linux v5.19-rc1)
by Coly Li 04 Jun '22
by Coly Li 04 Jun '22
04 Jun '22
This series is bcache backport up to Linux v5.19. The referenced bug is,
https://gitee.com/openeuler/kernel/issues/I59A5L#note_10515416
All the patches are tested on Intel x86-64 platform, but not tested on
ARM64 plantform yet.
Coly Li
---
Arnd Bergmann (1):
md: bcache: avoid -Wempty-body warnings
Bhaskar Chowdhury (1):
md: bcache: Trivial typo fixes in the file journal.c
Chao Yu (1):
bcache: fix error info in register_bcache()
Christoph Hellwig (1):
bcache: remove PTR_CACHE
Coly Li (10):
bcache: fix a regression of code compiling failure in debug.c
bcache: remove bcache device self-defined readahead
bcache: avoid oversized read request in cache missing code path
bcache: move uapi header bcache.h to bcache code directory
bcache: improve multithreaded bch_btree_check()
bcache: improve multithreaded bch_sectors_dirty_init()
bcache: remove incremental dirty sector counting for
bch_sectors_dirty_init()
bcache: avoid journal no-space deadlock by reserving 1 journal bucket
bcache: memset on stack variables in bch_btree_check() and
bch_sectors_dirty_init()
bcache: avoid unnecessary soft lockup in kworker
update_writeback_rate()
Ding Senjie (1):
md: bcache: Fix spelling of 'acquire'
Dongsheng Yang (1):
bcache: fix race between setting bdev state to none and new write
request direct to backing
Greg Kroah-Hartman (1):
bcache: use default_groups in kobj_type
Gustavo A. R. Silva (1):
bcache: Use 64-bit arithmetic instead of 32-bit
Jia-Ju Bai (1):
md: bcache: check the return value of kzalloc() in
detached_dev_do_request()
Joe Perches (1):
bcache: Avoid comma separated statements
Kai Krakow (1):
bcache: Fix register_device_aync typo
Lin Feng (2):
bcache: move calc_cached_dev_sectors to proper place on backing device
detach
bcache: fix NULL pointer reference in cached_dev_detach_finish
Ming Lei (1):
bcache: don't pass BIOSET_NEED_BVECS for the 'bio_set' embedded in
'cache_set'
Mingzhe Zou (2):
bcache: fixup bcache_dev_sectors_dirty_add() multithreaded CPU false
sharing
bcache: fixup multiple threads crash
Qing Wang (1):
bcache: replace snprintf in show functions with sysfs_emit
Yang Li (1):
bcache: use NULL instead of using plain integer as pointer
Yi Li (2):
bcache:remove a superfluous check in register_bcache
bcache: set pdev_set_uuid before scond loop iteration
YueHaibing (1):
lib: crc64: fix kernel-doc warning
Zheng Yongjun (1):
md/bcache: convert comma to semicolon
Zhiqiang Liu (1):
bcache: reduce redundant code in bch_cached_dev_run()
dongdong tao (1):
bcache: consider the fragmentation when update the writeback rate
drivers/md/bcache/alloc.c | 5 +-
drivers/md/bcache/bcache.h | 25 ++-
.../md/bcache/bcache_ondisk.h | 0
drivers/md/bcache/bset.c | 12 +-
drivers/md/bcache/bset.h | 2 +-
drivers/md/bcache/btree.c | 67 +++---
drivers/md/bcache/btree.h | 2 +-
drivers/md/bcache/debug.c | 2 +-
drivers/md/bcache/extents.c | 4 +-
drivers/md/bcache/features.c | 4 +-
drivers/md/bcache/features.h | 3 +-
drivers/md/bcache/io.c | 4 +-
drivers/md/bcache/journal.c | 37 +++-
drivers/md/bcache/journal.h | 2 +
drivers/md/bcache/request.c | 25 +--
drivers/md/bcache/stats.c | 17 +-
drivers/md/bcache/stats.h | 1 -
drivers/md/bcache/super.c | 63 +++---
drivers/md/bcache/sysfs.c | 50 +++--
drivers/md/bcache/sysfs.h | 20 +-
drivers/md/bcache/util.h | 19 +-
drivers/md/bcache/writeback.c | 198 +++++++++++-------
drivers/md/bcache/writeback.h | 6 +-
lib/crc64.c | 2 +-
24 files changed, 324 insertions(+), 246 deletions(-)
rename include/uapi/linux/bcache.h => drivers/md/bcache/bcache_ondisk.h (100%)
--
2.35.3
1
34

[openEuler-22.03-LTS 00/34] bcache backport for openEuler-22.03-LTS (up to Linux v5.19-rc1)
by Coly Li 04 Jun '22
by Coly Li 04 Jun '22
04 Jun '22
This series is bcache backport up to Linux v5.19. The referenced bug is,
https://gitee.com/openeuler/kernel/issues/I59A5L#note_10515416
All the patches are tested on Intel x86-64 platform, but not tested on
ARM64 plantform yet.
Coly Li
---
Arnd Bergmann (1):
md: bcache: avoid -Wempty-body warnings
Bhaskar Chowdhury (1):
md: bcache: Trivial typo fixes in the file journal.c
Chao Yu (1):
bcache: fix error info in register_bcache()
Christoph Hellwig (1):
bcache: remove PTR_CACHE
Coly Li (10):
bcache: fix a regression of code compiling failure in debug.c
bcache: remove bcache device self-defined readahead
bcache: avoid oversized read request in cache missing code path
bcache: move uapi header bcache.h to bcache code directory
bcache: improve multithreaded bch_btree_check()
bcache: improve multithreaded bch_sectors_dirty_init()
bcache: remove incremental dirty sector counting for
bch_sectors_dirty_init()
bcache: avoid journal no-space deadlock by reserving 1 journal bucket
bcache: memset on stack variables in bch_btree_check() and
bch_sectors_dirty_init()
bcache: avoid unnecessary soft lockup in kworker
update_writeback_rate()
Ding Senjie (1):
md: bcache: Fix spelling of 'acquire'
Dongsheng Yang (1):
bcache: fix race between setting bdev state to none and new write
request direct to backing
Greg Kroah-Hartman (1):
bcache: use default_groups in kobj_type
Gustavo A. R. Silva (1):
bcache: Use 64-bit arithmetic instead of 32-bit
Jia-Ju Bai (1):
md: bcache: check the return value of kzalloc() in
detached_dev_do_request()
Joe Perches (1):
bcache: Avoid comma separated statements
Kai Krakow (1):
bcache: Fix register_device_aync typo
Lin Feng (2):
bcache: move calc_cached_dev_sectors to proper place on backing device
detach
bcache: fix NULL pointer reference in cached_dev_detach_finish
Ming Lei (1):
bcache: don't pass BIOSET_NEED_BVECS for the 'bio_set' embedded in
'cache_set'
Mingzhe Zou (2):
bcache: fixup bcache_dev_sectors_dirty_add() multithreaded CPU false
sharing
bcache: fixup multiple threads crash
Qing Wang (1):
bcache: replace snprintf in show functions with sysfs_emit
Yang Li (1):
bcache: use NULL instead of using plain integer as pointer
Yi Li (2):
bcache:remove a superfluous check in register_bcache
bcache: set pdev_set_uuid before scond loop iteration
YueHaibing (1):
lib: crc64: fix kernel-doc warning
Zheng Yongjun (1):
md/bcache: convert comma to semicolon
Zhiqiang Liu (1):
bcache: reduce redundant code in bch_cached_dev_run()
dongdong tao (1):
bcache: consider the fragmentation when update the writeback rate
drivers/md/bcache/alloc.c | 5 +-
drivers/md/bcache/bcache.h | 25 ++-
.../md/bcache/bcache_ondisk.h | 0
drivers/md/bcache/bset.c | 12 +-
drivers/md/bcache/bset.h | 2 +-
drivers/md/bcache/btree.c | 67 +++---
drivers/md/bcache/btree.h | 2 +-
drivers/md/bcache/debug.c | 2 +-
drivers/md/bcache/extents.c | 4 +-
drivers/md/bcache/features.c | 4 +-
drivers/md/bcache/features.h | 3 +-
drivers/md/bcache/io.c | 4 +-
drivers/md/bcache/journal.c | 37 +++-
drivers/md/bcache/journal.h | 2 +
drivers/md/bcache/request.c | 25 +--
drivers/md/bcache/stats.c | 17 +-
drivers/md/bcache/stats.h | 1 -
drivers/md/bcache/super.c | 63 +++---
drivers/md/bcache/sysfs.c | 50 +++--
drivers/md/bcache/sysfs.h | 20 +-
drivers/md/bcache/util.h | 19 +-
drivers/md/bcache/writeback.c | 198 +++++++++++-------
drivers/md/bcache/writeback.h | 6 +-
lib/crc64.c | 2 +-
24 files changed, 324 insertions(+), 246 deletions(-)
rename include/uapi/linux/bcache.h => drivers/md/bcache/bcache_ondisk.h (100%)
--
2.35.3
1
34

04 Jun '22
This series is bcache backport up to Linux v5.19. The referenced bug is,
https://gitee.com/openeuler/kernel/issues/I59A5L#note_10515416
All the patches are tested on Intel x86-64 platform, but not tested on
ARM64 plantform yet.
Coly Li
---
Arnd Bergmann (1):
md: bcache: avoid -Wempty-body warnings
Bhaskar Chowdhury (1):
md: bcache: Trivial typo fixes in the file journal.c
Chao Yu (1):
bcache: fix error info in register_bcache()
Christoph Hellwig (1):
bcache: remove PTR_CACHE
Coly Li (10):
bcache: fix a regression of code compiling failure in debug.c
bcache: remove bcache device self-defined readahead
bcache: avoid oversized read request in cache missing code path
bcache: move uapi header bcache.h to bcache code directory
bcache: improve multithreaded bch_btree_check()
bcache: improve multithreaded bch_sectors_dirty_init()
bcache: remove incremental dirty sector counting for
bch_sectors_dirty_init()
bcache: avoid journal no-space deadlock by reserving 1 journal bucket
bcache: memset on stack variables in bch_btree_check() and
bch_sectors_dirty_init()
bcache: avoid unnecessary soft lockup in kworker
update_writeback_rate()
Ding Senjie (1):
md: bcache: Fix spelling of 'acquire'
Dongsheng Yang (1):
bcache: fix race between setting bdev state to none and new write
request direct to backing
Greg Kroah-Hartman (1):
bcache: use default_groups in kobj_type
Gustavo A. R. Silva (1):
bcache: Use 64-bit arithmetic instead of 32-bit
Jia-Ju Bai (1):
md: bcache: check the return value of kzalloc() in
detached_dev_do_request()
Joe Perches (1):
bcache: Avoid comma separated statements
Kai Krakow (1):
bcache: Fix register_device_aync typo
Lin Feng (2):
bcache: move calc_cached_dev_sectors to proper place on backing device
detach
bcache: fix NULL pointer reference in cached_dev_detach_finish
Ming Lei (1):
bcache: don't pass BIOSET_NEED_BVECS for the 'bio_set' embedded in
'cache_set'
Mingzhe Zou (2):
bcache: fixup bcache_dev_sectors_dirty_add() multithreaded CPU false
sharing
bcache: fixup multiple threads crash
Qing Wang (1):
bcache: replace snprintf in show functions with sysfs_emit
Yang Li (1):
bcache: use NULL instead of using plain integer as pointer
Yi Li (2):
bcache:remove a superfluous check in register_bcache
bcache: set pdev_set_uuid before scond loop iteration
YueHaibing (1):
lib: crc64: fix kernel-doc warning
Zheng Yongjun (1):
md/bcache: convert comma to semicolon
Zhiqiang Liu (1):
bcache: reduce redundant code in bch_cached_dev_run()
dongdong tao (1):
bcache: consider the fragmentation when update the writeback rate
drivers/md/bcache/alloc.c | 5 +-
drivers/md/bcache/bcache.h | 25 ++-
.../md/bcache/bcache_ondisk.h | 0
drivers/md/bcache/bset.c | 12 +-
drivers/md/bcache/bset.h | 2 +-
drivers/md/bcache/btree.c | 67 +++---
drivers/md/bcache/btree.h | 2 +-
drivers/md/bcache/debug.c | 2 +-
drivers/md/bcache/extents.c | 4 +-
drivers/md/bcache/features.c | 4 +-
drivers/md/bcache/features.h | 3 +-
drivers/md/bcache/io.c | 4 +-
drivers/md/bcache/journal.c | 37 +++-
drivers/md/bcache/journal.h | 2 +
drivers/md/bcache/request.c | 25 +--
drivers/md/bcache/stats.c | 17 +-
drivers/md/bcache/stats.h | 1 -
drivers/md/bcache/super.c | 63 +++---
drivers/md/bcache/sysfs.c | 50 +++--
drivers/md/bcache/sysfs.h | 20 +-
drivers/md/bcache/util.h | 19 +-
drivers/md/bcache/writeback.c | 198 +++++++++++-------
drivers/md/bcache/writeback.h | 6 +-
lib/crc64.c | 2 +-
24 files changed, 324 insertions(+), 246 deletions(-)
rename include/uapi/linux/bcache.h => drivers/md/bcache/bcache_ondisk.h (100%)
--
2.35.3
1
34
From: Kaixu Xia <kaixuxia(a)tencent.com>
mainline inclusion
from mainline-v5.11-rc6
commit 237d7887ae723af7d978e8b9a385fdff416f357b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5AG18
CVE: NA
--------------------------------
The quota option 'usrquota' should be shown if both the XFS_UQUOTA_ACCT
and XFS_UQUOTA_ENFD flags are set. The option 'uqnoenforce' should be
shown when only the XFS_UQUOTA_ACCT flag is set. The current code logic
seems wrong, Fix it and show proper options.
Signed-off-by: Kaixu Xia <kaixuxia(a)tencent.com>
Reviewed-by: Darrick J. Wong <darrick.wong(a)oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong(a)oracle.com>
Signed-off-by: tangbin <tangbin(a)cmss.chinamobile.com>
---
fs/xfs/xfs_super.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index e126bc6cdeb8..5d8e3a4d2671 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -505,10 +505,12 @@ xfs_showargs(
seq_printf(m, ",swidth=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
- if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
- seq_puts(m, ",usrquota");
- else if (mp->m_qflags & XFS_UQUOTA_ACCT)
- seq_puts(m, ",uqnoenforce");
+ if (mp->m_qflags & XFS_UQUOTA_ACCT) {
+ if (mp->m_qflags & XFS_UQUOTA_ENFD)
+ seq_puts(m, ",usrquota");
+ else
+ seq_puts(m, ",uqnoenforce");
+ }
if (mp->m_qflags & XFS_PQUOTA_ACCT) {
if (mp->m_qflags & XFS_PQUOTA_ENFD)
--
2.18.4
1
0
From: Kaixu Xia <kaixuxia(a)tencent.com>
mainline inclusion
from mainline-v5.11-rc6
commit 237d7887ae723af7d978e8b9a385fdff416f357b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5AG18
CVE: NA
--------------------------------
The quota option 'usrquota' should be shown if both the XFS_UQUOTA_ACCT
and XFS_UQUOTA_ENFD flags are set. The option 'uqnoenforce' should be
shown when only the XFS_UQUOTA_ACCT flag is set. The current code logic
seems wrong, Fix it and show proper options.
Signed-off-by: Kaixu Xia <kaixuxia(a)tencent.com>
Reviewed-by: Darrick J. Wong <darrick.wong(a)oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong(a)oracle.com>
Signed-off-by: tangbin <tangbin(a)cmss.chinamobile.com>
---
fs/xfs/xfs_super.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index e126bc6cdeb8..5d8e3a4d2671 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -505,10 +505,12 @@ xfs_showargs(
seq_printf(m, ",swidth=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
- if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
- seq_puts(m, ",usrquota");
- else if (mp->m_qflags & XFS_UQUOTA_ACCT)
- seq_puts(m, ",uqnoenforce");
+ if (mp->m_qflags & XFS_UQUOTA_ACCT) {
+ if (mp->m_qflags & XFS_UQUOTA_ENFD)
+ seq_puts(m, ",usrquota");
+ else
+ seq_puts(m, ",uqnoenforce");
+ }
if (mp->m_qflags & XFS_PQUOTA_ACCT) {
if (mp->m_qflags & XFS_PQUOTA_ENFD)
--
2.18.4
1
0
在 2022/6/2 17:10, Yu Kuai 写道:
> 在 2022/06/02 10:50, Gou Hao 写道:
>> uniontech inclusion
>> category: bugfix
>> bugzilla: NA
>> CVE: NA
>>
>> ----------------------
>>
>> We should not get the socket num in init_eufs_fs, becuse
>> system usually supports cpu hotplug,so we should get socket
>> num in dep_int.
> Hi,
>
> What if cpu is offline during mount, and online afterwards?
>
Well, in this case, we have to add a monitoring mechanism to
dynamically adjust the number of threads according to the
online status of the CPU.
Or there are other better ways ...
> Thanks,
> Kuai
>>
>> Socket num is not necessarily the same when file system
>> mount,so it shoule be eufs_sb_info's member.
>>
>> Signed-off-by: Gou Hao <gouhao(a)uniontech.com>
>> ---
>> fs/eulerfs/dep.c | 28 ++++++++++++++++++++++------
>> fs/eulerfs/euler.h | 2 --
>> fs/eulerfs/euler_def.h | 1 +
>> fs/eulerfs/super.c | 15 +--------------
>> 4 files changed, 24 insertions(+), 22 deletions(-)
>
--
thanks,
Gou Hao
1
0

02 Jun '22
在 2022/6/2 17:15, Yu Kuai 写道:
> 在 2022/06/02 10:51, Gou Hao 写道:
>> uniontech inclusion
>> category: bugfix
>> bugzilla: NA
>> CVE: NA
>>
>> -------------------
>>
>> After alloc the sbi->persisters memory, dep_init
>> will call dep_fini when error happened.Because
>> sbi->persisters is not set to 0, kthread_stop
>> may happened error.
>
> Looks good to me, just one language fixup:
>
> sbi->persisters is not set to 0
> -> dep_fini() can be called with sbi->persisters[] uninitialized, thus
> kthread_stop() can be called with random value.
>
ok, thank you : )
> Thanks,
> Kuai
>>
>> Signed-off-by: Gou Hao <gouhao(a)uniontech.com>
>> ---
>> fs/eulerfs/dep.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/eulerfs/dep.c b/fs/eulerfs/dep.c
>> index da826a18fa31..62fd1376f980 100644
>> --- a/fs/eulerfs/dep.c
>> +++ b/fs/eulerfs/dep.c
>> @@ -728,8 +728,8 @@ int dep_init(struct super_block *sb)
>> node_num++;
>> sbi->persister_num = node_num * persisters_per_socket;
>> -
>> - sbi->persisters = kmalloc(sizeof(struct task_struct *) *
>> +
>> + sbi->persisters = kzalloc(sizeof(struct task_struct *) *
>> sbi->persister_num, GFP_KERNEL);
>> if (!sbi->persisters) {
>> err = -ENOMEM;
>>
>
--
thanks,
Gou Hao
1
0
Patch series "improve the creation of persister".
The main modification is to create a persistent thread only when
a NUMA node has an online CPU at least, instead of on all NUMA nodes.
In the current code, the number of NUMA nodes is obtained when the module
is loaded, and the same number of persistent threads are created when the
file system is mounted. However, we should ignore NUMA nodes that do not
have an online CPU. So we should decide how many threads to create according
to the online CPU condition when initializing persist.
Patch4 is a bugfix about dep_init().
Gou Hao (4):
eulerfs: add socket_num to eufs_sb_info
eulerfs: create persister on node when it has online cpu
eulerfs: record persister num
eulerfs: fix potential sbi->persisters free error
fs/eulerfs/dep.c | 48 +++++++++++++++++++++++++++---------------
fs/eulerfs/euler.h | 2 --
fs/eulerfs/euler_def.h | 1 +
fs/eulerfs/super.c | 21 ++++--------------
4 files changed, 36 insertions(+), 36 deletions(-)
--
2.20.1
1
4

[PATCH openEuler-5.10-LTS 01/31] inet: fully convert sk->sk_rx_dst to RCU rules
by Zheng Zengkai 31 May '22
by Zheng Zengkai 31 May '22
31 May '22
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v5.16-rc7
commit 8f905c0e7354ef261360fb7535ea079b1082c105
category: bugfix
bugzilla: 186714 https://gitee.com/src-openeuler/kernel/issues/I57QUK
--------------------------------
syzbot reported various issues around early demux,
one being included in this changelog [1]
sk->sk_rx_dst is using RCU protection without clearly
documenting it.
And following sequences in tcp_v4_do_rcv()/tcp_v6_do_rcv()
are not following standard RCU rules.
[a] dst_release(dst);
[b] sk->sk_rx_dst = NULL;
They look wrong because a delete operation of RCU protected
pointer is supposed to clear the pointer before
the call_rcu()/synchronize_rcu() guarding actual memory freeing.
In some cases indeed, dst could be freed before [b] is done.
We could cheat by clearing sk_rx_dst before calling
dst_release(), but this seems the right time to stick
to standard RCU annotations and debugging facilities.
[1]
BUG: KASAN: use-after-free in dst_check include/net/dst.h:470 [inline]
BUG: KASAN: use-after-free in tcp_v4_early_demux+0x95b/0x960 net/ipv4/tcp_ipv4.c:1792
Read of size 2 at addr ffff88807f1cb73a by task syz-executor.5/9204
CPU: 0 PID: 9204 Comm: syz-executor.5 Not tainted 5.16.0-rc5-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
print_address_description.constprop.0.cold+0x8d/0x320 mm/kasan/report.c:247
__kasan_report mm/kasan/report.c:433 [inline]
kasan_report.cold+0x83/0xdf mm/kasan/report.c:450
dst_check include/net/dst.h:470 [inline]
tcp_v4_early_demux+0x95b/0x960 net/ipv4/tcp_ipv4.c:1792
ip_rcv_finish_core.constprop.0+0x15de/0x1e80 net/ipv4/ip_input.c:340
ip_list_rcv_finish.constprop.0+0x1b2/0x6e0 net/ipv4/ip_input.c:583
ip_sublist_rcv net/ipv4/ip_input.c:609 [inline]
ip_list_rcv+0x34e/0x490 net/ipv4/ip_input.c:644
__netif_receive_skb_list_ptype net/core/dev.c:5508 [inline]
__netif_receive_skb_list_core+0x549/0x8e0 net/core/dev.c:5556
__netif_receive_skb_list net/core/dev.c:5608 [inline]
netif_receive_skb_list_internal+0x75e/0xd80 net/core/dev.c:5699
gro_normal_list net/core/dev.c:5853 [inline]
gro_normal_list net/core/dev.c:5849 [inline]
napi_complete_done+0x1f1/0x880 net/core/dev.c:6590
virtqueue_napi_complete drivers/net/virtio_net.c:339 [inline]
virtnet_poll+0xca2/0x11b0 drivers/net/virtio_net.c:1557
__napi_poll+0xaf/0x440 net/core/dev.c:7023
napi_poll net/core/dev.c:7090 [inline]
net_rx_action+0x801/0xb40 net/core/dev.c:7177
__do_softirq+0x29b/0x9c2 kernel/softirq.c:558
invoke_softirq kernel/softirq.c:432 [inline]
__irq_exit_rcu+0x123/0x180 kernel/softirq.c:637
irq_exit_rcu+0x5/0x20 kernel/softirq.c:649
common_interrupt+0x52/0xc0 arch/x86/kernel/irq.c:240
asm_common_interrupt+0x1e/0x40 arch/x86/include/asm/idtentry.h:629
RIP: 0033:0x7f5e972bfd57
Code: 39 d1 73 14 0f 1f 80 00 00 00 00 48 8b 50 f8 48 83 e8 08 48 39 ca 77 f3 48 39 c3 73 3e 48 89 13 48 8b 50 f8 48 89 38 49 8b 0e <48> 8b 3e 48 83 c3 08 48 83 c6 08 eb bc 48 39 d1 72 9e 48 39 d0 73
RSP: 002b:00007fff8a413210 EFLAGS: 00000283
RAX: 00007f5e97108990 RBX: 00007f5e97108338 RCX: ffffffff81d3aa45
RDX: ffffffff81d3aa45 RSI: 00007f5e97108340 RDI: ffffffff81d3aa45
RBP: 00007f5e97107eb8 R08: 00007f5e97108d88 R09: 0000000093c2e8d9
R10: 0000000000000000 R11: 0000000000000000 R12: 00007f5e97107eb0
R13: 00007f5e97108338 R14: 00007f5e97107ea8 R15: 0000000000000019
</TASK>
Allocated by task 13:
kasan_save_stack+0x1e/0x50 mm/kasan/common.c:38
kasan_set_track mm/kasan/common.c:46 [inline]
set_alloc_info mm/kasan/common.c:434 [inline]
__kasan_slab_alloc+0x90/0xc0 mm/kasan/common.c:467
kasan_slab_alloc include/linux/kasan.h:259 [inline]
slab_post_alloc_hook mm/slab.h:519 [inline]
slab_alloc_node mm/slub.c:3234 [inline]
slab_alloc mm/slub.c:3242 [inline]
kmem_cache_alloc+0x202/0x3a0 mm/slub.c:3247
dst_alloc+0x146/0x1f0 net/core/dst.c:92
rt_dst_alloc+0x73/0x430 net/ipv4/route.c:1613
ip_route_input_slow+0x1817/0x3a20 net/ipv4/route.c:2340
ip_route_input_rcu net/ipv4/route.c:2470 [inline]
ip_route_input_noref+0x116/0x2a0 net/ipv4/route.c:2415
ip_rcv_finish_core.constprop.0+0x288/0x1e80 net/ipv4/ip_input.c:354
ip_list_rcv_finish.constprop.0+0x1b2/0x6e0 net/ipv4/ip_input.c:583
ip_sublist_rcv net/ipv4/ip_input.c:609 [inline]
ip_list_rcv+0x34e/0x490 net/ipv4/ip_input.c:644
__netif_receive_skb_list_ptype net/core/dev.c:5508 [inline]
__netif_receive_skb_list_core+0x549/0x8e0 net/core/dev.c:5556
__netif_receive_skb_list net/core/dev.c:5608 [inline]
netif_receive_skb_list_internal+0x75e/0xd80 net/core/dev.c:5699
gro_normal_list net/core/dev.c:5853 [inline]
gro_normal_list net/core/dev.c:5849 [inline]
napi_complete_done+0x1f1/0x880 net/core/dev.c:6590
virtqueue_napi_complete drivers/net/virtio_net.c:339 [inline]
virtnet_poll+0xca2/0x11b0 drivers/net/virtio_net.c:1557
__napi_poll+0xaf/0x440 net/core/dev.c:7023
napi_poll net/core/dev.c:7090 [inline]
net_rx_action+0x801/0xb40 net/core/dev.c:7177
__do_softirq+0x29b/0x9c2 kernel/softirq.c:558
Freed by task 13:
kasan_save_stack+0x1e/0x50 mm/kasan/common.c:38
kasan_set_track+0x21/0x30 mm/kasan/common.c:46
kasan_set_free_info+0x20/0x30 mm/kasan/generic.c:370
____kasan_slab_free mm/kasan/common.c:366 [inline]
____kasan_slab_free mm/kasan/common.c:328 [inline]
__kasan_slab_free+0xff/0x130 mm/kasan/common.c:374
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:1723 [inline]
slab_free_freelist_hook+0x8b/0x1c0 mm/slub.c:1749
slab_free mm/slub.c:3513 [inline]
kmem_cache_free+0xbd/0x5d0 mm/slub.c:3530
dst_destroy+0x2d6/0x3f0 net/core/dst.c:127
rcu_do_batch kernel/rcu/tree.c:2506 [inline]
rcu_core+0x7ab/0x1470 kernel/rcu/tree.c:2741
__do_softirq+0x29b/0x9c2 kernel/softirq.c:558
Last potentially related work creation:
kasan_save_stack+0x1e/0x50 mm/kasan/common.c:38
__kasan_record_aux_stack+0xf5/0x120 mm/kasan/generic.c:348
__call_rcu kernel/rcu/tree.c:2985 [inline]
call_rcu+0xb1/0x740 kernel/rcu/tree.c:3065
dst_release net/core/dst.c:177 [inline]
dst_release+0x79/0xe0 net/core/dst.c:167
tcp_v4_do_rcv+0x612/0x8d0 net/ipv4/tcp_ipv4.c:1712
sk_backlog_rcv include/net/sock.h:1030 [inline]
__release_sock+0x134/0x3b0 net/core/sock.c:2768
release_sock+0x54/0x1b0 net/core/sock.c:3300
tcp_sendmsg+0x36/0x40 net/ipv4/tcp.c:1441
inet_sendmsg+0x99/0xe0 net/ipv4/af_inet.c:819
sock_sendmsg_nosec net/socket.c:704 [inline]
sock_sendmsg+0xcf/0x120 net/socket.c:724
sock_write_iter+0x289/0x3c0 net/socket.c:1057
call_write_iter include/linux/fs.h:2162 [inline]
new_sync_write+0x429/0x660 fs/read_write.c:503
vfs_write+0x7cd/0xae0 fs/read_write.c:590
ksys_write+0x1ee/0x250 fs/read_write.c:643
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x44/0xae
The buggy address belongs to the object at ffff88807f1cb700
which belongs to the cache ip_dst_cache of size 176
The buggy address is located 58 bytes inside of
176-byte region [ffff88807f1cb700, ffff88807f1cb7b0)
The buggy address belongs to the page:
page:ffffea0001fc72c0 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x7f1cb
flags: 0xfff00000000200(slab|node=0|zone=1|lastcpupid=0x7ff)
raw: 00fff00000000200 dead000000000100 dead000000000122 ffff8881413bb780
raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x112a20(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_HARDWALL), pid 5, ts 108466983062, free_ts 108048976062
prep_new_page mm/page_alloc.c:2418 [inline]
get_page_from_freelist+0xa72/0x2f50 mm/page_alloc.c:4149
__alloc_pages+0x1b2/0x500 mm/page_alloc.c:5369
alloc_pages+0x1a7/0x300 mm/mempolicy.c:2191
alloc_slab_page mm/slub.c:1793 [inline]
allocate_slab mm/slub.c:1930 [inline]
new_slab+0x32d/0x4a0 mm/slub.c:1993
___slab_alloc+0x918/0xfe0 mm/slub.c:3022
__slab_alloc.constprop.0+0x4d/0xa0 mm/slub.c:3109
slab_alloc_node mm/slub.c:3200 [inline]
slab_alloc mm/slub.c:3242 [inline]
kmem_cache_alloc+0x35c/0x3a0 mm/slub.c:3247
dst_alloc+0x146/0x1f0 net/core/dst.c:92
rt_dst_alloc+0x73/0x430 net/ipv4/route.c:1613
__mkroute_output net/ipv4/route.c:2564 [inline]
ip_route_output_key_hash_rcu+0x921/0x2d00 net/ipv4/route.c:2791
ip_route_output_key_hash+0x18b/0x300 net/ipv4/route.c:2619
__ip_route_output_key include/net/route.h:126 [inline]
ip_route_output_flow+0x23/0x150 net/ipv4/route.c:2850
ip_route_output_key include/net/route.h:142 [inline]
geneve_get_v4_rt+0x3a6/0x830 drivers/net/geneve.c:809
geneve_xmit_skb drivers/net/geneve.c:899 [inline]
geneve_xmit+0xc4a/0x3540 drivers/net/geneve.c:1082
__netdev_start_xmit include/linux/netdevice.h:4994 [inline]
netdev_start_xmit include/linux/netdevice.h:5008 [inline]
xmit_one net/core/dev.c:3590 [inline]
dev_hard_start_xmit+0x1eb/0x920 net/core/dev.c:3606
__dev_queue_xmit+0x299a/0x3650 net/core/dev.c:4229
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1338 [inline]
free_pcp_prepare+0x374/0x870 mm/page_alloc.c:1389
free_unref_page_prepare mm/page_alloc.c:3309 [inline]
free_unref_page+0x19/0x690 mm/page_alloc.c:3388
qlink_free mm/kasan/quarantine.c:146 [inline]
qlist_free_all+0x5a/0xc0 mm/kasan/quarantine.c:165
kasan_quarantine_reduce+0x180/0x200 mm/kasan/quarantine.c:272
__kasan_slab_alloc+0xa2/0xc0 mm/kasan/common.c:444
kasan_slab_alloc include/linux/kasan.h:259 [inline]
slab_post_alloc_hook mm/slab.h:519 [inline]
slab_alloc_node mm/slub.c:3234 [inline]
kmem_cache_alloc_node+0x255/0x3f0 mm/slub.c:3270
__alloc_skb+0x215/0x340 net/core/skbuff.c:414
alloc_skb include/linux/skbuff.h:1126 [inline]
alloc_skb_with_frags+0x93/0x620 net/core/skbuff.c:6078
sock_alloc_send_pskb+0x783/0x910 net/core/sock.c:2575
mld_newpack+0x1df/0x770 net/ipv6/mcast.c:1754
add_grhead+0x265/0x330 net/ipv6/mcast.c:1857
add_grec+0x1053/0x14e0 net/ipv6/mcast.c:1995
mld_send_initial_cr.part.0+0xf6/0x230 net/ipv6/mcast.c:2242
mld_send_initial_cr net/ipv6/mcast.c:1232 [inline]
mld_dad_work+0x1d3/0x690 net/ipv6/mcast.c:2268
process_one_work+0x9b2/0x1690 kernel/workqueue.c:2298
worker_thread+0x658/0x11f0 kernel/workqueue.c:2445
Memory state around the buggy address:
ffff88807f1cb600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88807f1cb680: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc
>ffff88807f1cb700: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88807f1cb780: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc
ffff88807f1cb800: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Fixes: 41063e9dd119 ("ipv4: Early TCP socket demux.")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Link: https://lore.kernel.org/r/20211220143330.680945-1-eric.dumazet@gmail.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Zhengchao Shao <shaozhengchao(a)huawei.com>
Conflict:
include/net/sock.h
net/ipv4/tcp_ipv4.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/net/sock.h | 2 +-
net/ipv4/af_inet.c | 2 +-
net/ipv4/tcp.c | 3 +--
net/ipv4/tcp_input.c | 2 +-
net/ipv4/tcp_ipv4.c | 11 +++++++----
net/ipv4/udp.c | 6 +++---
net/ipv6/tcp_ipv6.c | 11 +++++++----
net/ipv6/udp.c | 4 ++--
8 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index c958be11d172..bd34faf53b1f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -428,7 +428,7 @@ struct sock {
#ifdef CONFIG_XFRM
struct xfrm_policy __rcu *sk_policy[2];
#endif
- struct dst_entry *sk_rx_dst;
+ struct dst_entry __rcu *sk_rx_dst;
struct dst_entry __rcu *sk_dst_cache;
atomic_t sk_omem_alloc;
int sk_sndbuf;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 8bf43ca7139a..911ad595dbb9 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -158,7 +158,7 @@ void inet_sock_destruct(struct sock *sk)
kfree(rcu_dereference_protected(inet->inet_opt, 1));
dst_release(rcu_dereference_protected(sk->sk_dst_cache, 1));
- dst_release(sk->sk_rx_dst);
+ dst_release(rcu_dereference_protected(sk->sk_rx_dst, 1));
sk_refcnt_debug_dec(sk);
}
EXPORT_SYMBOL(inet_sock_destruct);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index fcd792816756..c19428e97876 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2814,8 +2814,7 @@ int tcp_disconnect(struct sock *sk, int flags)
icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
__sk_dst_reset(sk);
- dst_release(sk->sk_rx_dst);
- sk->sk_rx_dst = NULL;
+ dst_release(xchg((__force struct dst_entry **)&sk->sk_rx_dst, NULL));
tcp_saved_syn_free(tp);
tp->compressed_ack = 0;
tp->segs_in = 0;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 11f3f8e23a8a..6f4ac0f10f57 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5744,7 +5744,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
trace_tcp_probe(sk, skb);
tcp_mstamp_refresh(tp);
- if (unlikely(!sk->sk_rx_dst))
+ if (unlikely(!rcu_access_pointer(sk->sk_rx_dst)))
inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb);
/*
* Header prediction.
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index ebfeeeadd47c..078f3a5d65b3 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1670,15 +1670,18 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
struct sock *rsk;
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
- struct dst_entry *dst = sk->sk_rx_dst;
+ struct dst_entry *dst;
+
+ dst = rcu_dereference_protected(sk->sk_rx_dst,
+ lockdep_sock_is_held(sk));
sock_rps_save_rxhash(sk, skb);
sk_mark_napi_id(sk, skb);
if (dst) {
if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif ||
!dst->ops->check(dst, 0)) {
+ RCU_INIT_POINTER(sk->sk_rx_dst, NULL);
dst_release(dst);
- sk->sk_rx_dst = NULL;
}
}
tcp_rcv_established(sk, skb);
@@ -1753,7 +1756,7 @@ int tcp_v4_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_edemux;
if (sk_fullsock(sk)) {
- struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst);
+ struct dst_entry *dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, 0);
@@ -2160,7 +2163,7 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
struct dst_entry *dst = skb_dst(skb);
if (dst && dst_hold_safe(dst)) {
- sk->sk_rx_dst = dst;
+ rcu_assign_pointer(sk->sk_rx_dst, dst);
inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
}
}
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8cca8bda0612..121c08d4255c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2186,7 +2186,7 @@ bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
struct dst_entry *old;
if (dst_hold_safe(dst)) {
- old = xchg(&sk->sk_rx_dst, dst);
+ old = xchg((__force struct dst_entry **)&sk->sk_rx_dst, dst);
dst_release(old);
return old != dst;
}
@@ -2376,7 +2376,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
struct dst_entry *dst = skb_dst(skb);
int ret;
- if (unlikely(sk->sk_rx_dst != dst))
+ if (unlikely(rcu_dereference(sk->sk_rx_dst) != dst))
udp_sk_rx_dst_set(sk, dst);
ret = udp_unicast_rcv_skb(sk, skb, uh);
@@ -2535,7 +2535,7 @@ int udp_v4_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_efree;
- dst = READ_ONCE(sk->sk_rx_dst);
+ dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, 0);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index df33145b876c..b87b04526e65 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -107,7 +107,7 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
if (dst && dst_hold_safe(dst)) {
const struct rt6_info *rt = (const struct rt6_info *)dst;
- sk->sk_rx_dst = dst;
+ rcu_assign_pointer(sk->sk_rx_dst, dst);
inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
tcp_inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
}
@@ -1482,15 +1482,18 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
opt_skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC));
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
- struct dst_entry *dst = sk->sk_rx_dst;
+ struct dst_entry *dst;
+
+ dst = rcu_dereference_protected(sk->sk_rx_dst,
+ lockdep_sock_is_held(sk));
sock_rps_save_rxhash(sk, skb);
sk_mark_napi_id(sk, skb);
if (dst) {
if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif ||
dst->ops->check(dst, np->rx_dst_cookie) == NULL) {
+ RCU_INIT_POINTER(sk->sk_rx_dst, NULL);
dst_release(dst);
- sk->sk_rx_dst = NULL;
}
}
@@ -1842,7 +1845,7 @@ INDIRECT_CALLABLE_SCOPE void tcp_v6_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_edemux;
if (sk_fullsock(sk)) {
- struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst);
+ struct dst_entry *dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, tcp_inet6_sk(sk)->rx_dst_cookie);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 503706397839..7022dcbb5a11 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -940,7 +940,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
struct dst_entry *dst = skb_dst(skb);
int ret;
- if (unlikely(sk->sk_rx_dst != dst))
+ if (unlikely(rcu_dereference(sk->sk_rx_dst) != dst))
udp6_sk_rx_dst_set(sk, dst);
if (!uh->check && !udp_sk(sk)->no_check6_rx) {
@@ -1054,7 +1054,7 @@ INDIRECT_CALLABLE_SCOPE void udp_v6_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_efree;
- dst = READ_ONCE(sk->sk_rx_dst);
+ dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie);
--
2.20.1
1
30
Backport 5.10.105 LTS patches from upstream
Revert "ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE"
arm64: cpufeature: add HWCAP for FEAT_RPRES
arm64: cpufeature: add HWCAP for FEAT_AFP
arm64: Add Cortex-A510 CPU part definition
arm64: Add Cortex-X2 CPU part definition
arm64: Add Neoverse-N2, Cortex-A710 CPU part definition
arm64: cputype: Add CPU implementor & types for the Apple M1 cores
Conflicts:
arm64: cpufeature: add HWCAP for FEAT_RPRES
arm64: cpufeature: add HWCAP for FEAT_AFP
arm64: Add Cortex-A510 CPU part definition
arm64: Add Neoverse-N2, Cortex-A710 CPU part definition
arm64: cputype: Add CPU implementor & types for the Apple M1 cores
Already merged(51):
xen/netfront: react properly to failing gnttab_end_foreign_access_ref()
xen/gnttab: fix gnttab_end_foreign_access() without page specified
xen/pvcalls: use alloc/free_pages_exact()
xen/9p: use alloc/free_pages_exact()
xen: remove gnttab_query_foreign_access()
xen/gntalloc: don't use gnttab_query_foreign_access()
xen/scsifront: don't use gnttab_query_foreign_access() for mapped status
xen/netfront: don't use gnttab_query_foreign_access() for mapped status
xen/blkfront: don't use gnttab_query_foreign_access() for mapped status
xen/grant-table: add gnttab_try_end_foreign_access()
xen/xenbus: don't let xenbus_grant_ring() remove grants in error case
ARM: Do not use NOCROSSREFS directive with ld.lld
arm64: proton-pack: Include unprivileged eBPF status in Spectre v2 mitigation
reporting
arm64: Use the clearbhb instruction in mitigations
KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and migrated
arm64: Mitigate spectre style branch history side channels
KVM: arm64: Allow indirect vectors to be used without SPECTRE_V3A
arm64: proton-pack: Report Spectre-BHB vulnerabilities as part of Spectre-v2
arm64: Add percpu vectors for EL1
arm64: entry: Add macro for reading symbol addresses from the trampoline
arm64: entry: Add vectors that have the bhb mitigation sequences
arm64: entry: Add non-kpti __bp_harden_el1_vectors for mitigations
arm64: entry: Allow the trampoline text to occupy multiple pages
arm64: entry: Make the kpti trampoline's kpti sequence optional
arm64: entry: Move trampoline macros out of ifdef'd section
arm64: entry: Don't assume tramp_vectors is the start of the vectors
arm64: entry: Allow tramp_alias to access symbols after the 4K boundary
arm64: entry: Move the trampoline data page before the text page
arm64: entry: Free up another register on kpti's tramp_exit path
arm64: entry: Make the trampoline cleanup optional
arm64: spectre: Rename spectre_v4_patch_fw_mitigation_conduit
arm64: entry.S: Add ventry overflow sanity checks
arm64: add ID_AA64ISAR2_EL1 sys register
arm64: Add HWCAP for self-synchronising virtual counter
ARM: include unprivileged BPF status in Spectre V2 reporting
ARM: Spectre-BHB workaround
ARM: use LOADADDR() to get load address of sections
ARM: early traps initialisation
ARM: report Spectre v2 status through sysfs
x86/speculation: Warn about eIBRS + LFENCE + Unprivileged eBPF + SMT
x86/speculation: Warn about Spectre v2 LFENCE mitigation
x86/speculation: Update link to AMD speculation whitepaper
x86/speculation: Use generic retpoline by default on AMD
x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation
reporting
Documentation/hw-vuln: Update spectre doc
x86/speculation: Add eIBRS + Retpoline options
x86/speculation: Rename RETPOLINE_AMD to RETPOLINE_LFENCE
x86,bugs: Unconditionally allow spectre_v2=retpoline,amd
ARM: fix build error when BPF_SYSCALL is disabled
ARM: fix co-processor register typo
ARM: fix build warning in proc-v7-bugs.c
Total patches: 58 - 51 = 7
Anshuman Khandual (2):
arm64: Add Cortex-X2 CPU part definition
arm64: Add Cortex-A510 CPU part definition
Greg Kroah-Hartman (1):
Revert "ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE"
Hector Martin (1):
arm64: cputype: Add CPU implementor & types for the Apple M1 cores
Joey Gouly (2):
arm64: cpufeature: add HWCAP for FEAT_AFP
arm64: cpufeature: add HWCAP for FEAT_RPRES
Suzuki K Poulose (1):
arm64: Add Neoverse-N2, Cortex-A710 CPU part definition
Documentation/arm64/cpu-feature-registers.rst | 17 +++++++++++++++++
Documentation/arm64/elf_hwcaps.rst | 8 ++++++++
arch/arm64/include/asm/cputype.h | 14 ++++++++++++++
arch/arm64/include/asm/hwcap.h | 2 ++
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/include/uapi/asm/hwcap.h | 2 ++
arch/arm64/kernel/cpufeature.c | 4 ++++
arch/arm64/kernel/cpuinfo.c | 2 ++
drivers/acpi/ec.c | 10 ----------
drivers/acpi/sleep.c | 14 ++++++++++----
10 files changed, 60 insertions(+), 14 deletions(-)
--
2.20.1
1
7

[PATCH openEuler-5.10 01/50] inet: fully convert sk->sk_rx_dst to RCU rules
by Zheng Zengkai 31 May '22
by Zheng Zengkai 31 May '22
31 May '22
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v5.16-rc7
commit 8f905c0e7354ef261360fb7535ea079b1082c105
category: bugfix
bugzilla: 186714 https://gitee.com/src-openeuler/kernel/issues/I57QUK
--------------------------------
syzbot reported various issues around early demux,
one being included in this changelog [1]
sk->sk_rx_dst is using RCU protection without clearly
documenting it.
And following sequences in tcp_v4_do_rcv()/tcp_v6_do_rcv()
are not following standard RCU rules.
[a] dst_release(dst);
[b] sk->sk_rx_dst = NULL;
They look wrong because a delete operation of RCU protected
pointer is supposed to clear the pointer before
the call_rcu()/synchronize_rcu() guarding actual memory freeing.
In some cases indeed, dst could be freed before [b] is done.
We could cheat by clearing sk_rx_dst before calling
dst_release(), but this seems the right time to stick
to standard RCU annotations and debugging facilities.
[1]
BUG: KASAN: use-after-free in dst_check include/net/dst.h:470 [inline]
BUG: KASAN: use-after-free in tcp_v4_early_demux+0x95b/0x960 net/ipv4/tcp_ipv4.c:1792
Read of size 2 at addr ffff88807f1cb73a by task syz-executor.5/9204
CPU: 0 PID: 9204 Comm: syz-executor.5 Not tainted 5.16.0-rc5-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
print_address_description.constprop.0.cold+0x8d/0x320 mm/kasan/report.c:247
__kasan_report mm/kasan/report.c:433 [inline]
kasan_report.cold+0x83/0xdf mm/kasan/report.c:450
dst_check include/net/dst.h:470 [inline]
tcp_v4_early_demux+0x95b/0x960 net/ipv4/tcp_ipv4.c:1792
ip_rcv_finish_core.constprop.0+0x15de/0x1e80 net/ipv4/ip_input.c:340
ip_list_rcv_finish.constprop.0+0x1b2/0x6e0 net/ipv4/ip_input.c:583
ip_sublist_rcv net/ipv4/ip_input.c:609 [inline]
ip_list_rcv+0x34e/0x490 net/ipv4/ip_input.c:644
__netif_receive_skb_list_ptype net/core/dev.c:5508 [inline]
__netif_receive_skb_list_core+0x549/0x8e0 net/core/dev.c:5556
__netif_receive_skb_list net/core/dev.c:5608 [inline]
netif_receive_skb_list_internal+0x75e/0xd80 net/core/dev.c:5699
gro_normal_list net/core/dev.c:5853 [inline]
gro_normal_list net/core/dev.c:5849 [inline]
napi_complete_done+0x1f1/0x880 net/core/dev.c:6590
virtqueue_napi_complete drivers/net/virtio_net.c:339 [inline]
virtnet_poll+0xca2/0x11b0 drivers/net/virtio_net.c:1557
__napi_poll+0xaf/0x440 net/core/dev.c:7023
napi_poll net/core/dev.c:7090 [inline]
net_rx_action+0x801/0xb40 net/core/dev.c:7177
__do_softirq+0x29b/0x9c2 kernel/softirq.c:558
invoke_softirq kernel/softirq.c:432 [inline]
__irq_exit_rcu+0x123/0x180 kernel/softirq.c:637
irq_exit_rcu+0x5/0x20 kernel/softirq.c:649
common_interrupt+0x52/0xc0 arch/x86/kernel/irq.c:240
asm_common_interrupt+0x1e/0x40 arch/x86/include/asm/idtentry.h:629
RIP: 0033:0x7f5e972bfd57
Code: 39 d1 73 14 0f 1f 80 00 00 00 00 48 8b 50 f8 48 83 e8 08 48 39 ca 77 f3 48 39 c3 73 3e 48 89 13 48 8b 50 f8 48 89 38 49 8b 0e <48> 8b 3e 48 83 c3 08 48 83 c6 08 eb bc 48 39 d1 72 9e 48 39 d0 73
RSP: 002b:00007fff8a413210 EFLAGS: 00000283
RAX: 00007f5e97108990 RBX: 00007f5e97108338 RCX: ffffffff81d3aa45
RDX: ffffffff81d3aa45 RSI: 00007f5e97108340 RDI: ffffffff81d3aa45
RBP: 00007f5e97107eb8 R08: 00007f5e97108d88 R09: 0000000093c2e8d9
R10: 0000000000000000 R11: 0000000000000000 R12: 00007f5e97107eb0
R13: 00007f5e97108338 R14: 00007f5e97107ea8 R15: 0000000000000019
</TASK>
Allocated by task 13:
kasan_save_stack+0x1e/0x50 mm/kasan/common.c:38
kasan_set_track mm/kasan/common.c:46 [inline]
set_alloc_info mm/kasan/common.c:434 [inline]
__kasan_slab_alloc+0x90/0xc0 mm/kasan/common.c:467
kasan_slab_alloc include/linux/kasan.h:259 [inline]
slab_post_alloc_hook mm/slab.h:519 [inline]
slab_alloc_node mm/slub.c:3234 [inline]
slab_alloc mm/slub.c:3242 [inline]
kmem_cache_alloc+0x202/0x3a0 mm/slub.c:3247
dst_alloc+0x146/0x1f0 net/core/dst.c:92
rt_dst_alloc+0x73/0x430 net/ipv4/route.c:1613
ip_route_input_slow+0x1817/0x3a20 net/ipv4/route.c:2340
ip_route_input_rcu net/ipv4/route.c:2470 [inline]
ip_route_input_noref+0x116/0x2a0 net/ipv4/route.c:2415
ip_rcv_finish_core.constprop.0+0x288/0x1e80 net/ipv4/ip_input.c:354
ip_list_rcv_finish.constprop.0+0x1b2/0x6e0 net/ipv4/ip_input.c:583
ip_sublist_rcv net/ipv4/ip_input.c:609 [inline]
ip_list_rcv+0x34e/0x490 net/ipv4/ip_input.c:644
__netif_receive_skb_list_ptype net/core/dev.c:5508 [inline]
__netif_receive_skb_list_core+0x549/0x8e0 net/core/dev.c:5556
__netif_receive_skb_list net/core/dev.c:5608 [inline]
netif_receive_skb_list_internal+0x75e/0xd80 net/core/dev.c:5699
gro_normal_list net/core/dev.c:5853 [inline]
gro_normal_list net/core/dev.c:5849 [inline]
napi_complete_done+0x1f1/0x880 net/core/dev.c:6590
virtqueue_napi_complete drivers/net/virtio_net.c:339 [inline]
virtnet_poll+0xca2/0x11b0 drivers/net/virtio_net.c:1557
__napi_poll+0xaf/0x440 net/core/dev.c:7023
napi_poll net/core/dev.c:7090 [inline]
net_rx_action+0x801/0xb40 net/core/dev.c:7177
__do_softirq+0x29b/0x9c2 kernel/softirq.c:558
Freed by task 13:
kasan_save_stack+0x1e/0x50 mm/kasan/common.c:38
kasan_set_track+0x21/0x30 mm/kasan/common.c:46
kasan_set_free_info+0x20/0x30 mm/kasan/generic.c:370
____kasan_slab_free mm/kasan/common.c:366 [inline]
____kasan_slab_free mm/kasan/common.c:328 [inline]
__kasan_slab_free+0xff/0x130 mm/kasan/common.c:374
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:1723 [inline]
slab_free_freelist_hook+0x8b/0x1c0 mm/slub.c:1749
slab_free mm/slub.c:3513 [inline]
kmem_cache_free+0xbd/0x5d0 mm/slub.c:3530
dst_destroy+0x2d6/0x3f0 net/core/dst.c:127
rcu_do_batch kernel/rcu/tree.c:2506 [inline]
rcu_core+0x7ab/0x1470 kernel/rcu/tree.c:2741
__do_softirq+0x29b/0x9c2 kernel/softirq.c:558
Last potentially related work creation:
kasan_save_stack+0x1e/0x50 mm/kasan/common.c:38
__kasan_record_aux_stack+0xf5/0x120 mm/kasan/generic.c:348
__call_rcu kernel/rcu/tree.c:2985 [inline]
call_rcu+0xb1/0x740 kernel/rcu/tree.c:3065
dst_release net/core/dst.c:177 [inline]
dst_release+0x79/0xe0 net/core/dst.c:167
tcp_v4_do_rcv+0x612/0x8d0 net/ipv4/tcp_ipv4.c:1712
sk_backlog_rcv include/net/sock.h:1030 [inline]
__release_sock+0x134/0x3b0 net/core/sock.c:2768
release_sock+0x54/0x1b0 net/core/sock.c:3300
tcp_sendmsg+0x36/0x40 net/ipv4/tcp.c:1441
inet_sendmsg+0x99/0xe0 net/ipv4/af_inet.c:819
sock_sendmsg_nosec net/socket.c:704 [inline]
sock_sendmsg+0xcf/0x120 net/socket.c:724
sock_write_iter+0x289/0x3c0 net/socket.c:1057
call_write_iter include/linux/fs.h:2162 [inline]
new_sync_write+0x429/0x660 fs/read_write.c:503
vfs_write+0x7cd/0xae0 fs/read_write.c:590
ksys_write+0x1ee/0x250 fs/read_write.c:643
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x44/0xae
The buggy address belongs to the object at ffff88807f1cb700
which belongs to the cache ip_dst_cache of size 176
The buggy address is located 58 bytes inside of
176-byte region [ffff88807f1cb700, ffff88807f1cb7b0)
The buggy address belongs to the page:
page:ffffea0001fc72c0 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x7f1cb
flags: 0xfff00000000200(slab|node=0|zone=1|lastcpupid=0x7ff)
raw: 00fff00000000200 dead000000000100 dead000000000122 ffff8881413bb780
raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x112a20(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_HARDWALL), pid 5, ts 108466983062, free_ts 108048976062
prep_new_page mm/page_alloc.c:2418 [inline]
get_page_from_freelist+0xa72/0x2f50 mm/page_alloc.c:4149
__alloc_pages+0x1b2/0x500 mm/page_alloc.c:5369
alloc_pages+0x1a7/0x300 mm/mempolicy.c:2191
alloc_slab_page mm/slub.c:1793 [inline]
allocate_slab mm/slub.c:1930 [inline]
new_slab+0x32d/0x4a0 mm/slub.c:1993
___slab_alloc+0x918/0xfe0 mm/slub.c:3022
__slab_alloc.constprop.0+0x4d/0xa0 mm/slub.c:3109
slab_alloc_node mm/slub.c:3200 [inline]
slab_alloc mm/slub.c:3242 [inline]
kmem_cache_alloc+0x35c/0x3a0 mm/slub.c:3247
dst_alloc+0x146/0x1f0 net/core/dst.c:92
rt_dst_alloc+0x73/0x430 net/ipv4/route.c:1613
__mkroute_output net/ipv4/route.c:2564 [inline]
ip_route_output_key_hash_rcu+0x921/0x2d00 net/ipv4/route.c:2791
ip_route_output_key_hash+0x18b/0x300 net/ipv4/route.c:2619
__ip_route_output_key include/net/route.h:126 [inline]
ip_route_output_flow+0x23/0x150 net/ipv4/route.c:2850
ip_route_output_key include/net/route.h:142 [inline]
geneve_get_v4_rt+0x3a6/0x830 drivers/net/geneve.c:809
geneve_xmit_skb drivers/net/geneve.c:899 [inline]
geneve_xmit+0xc4a/0x3540 drivers/net/geneve.c:1082
__netdev_start_xmit include/linux/netdevice.h:4994 [inline]
netdev_start_xmit include/linux/netdevice.h:5008 [inline]
xmit_one net/core/dev.c:3590 [inline]
dev_hard_start_xmit+0x1eb/0x920 net/core/dev.c:3606
__dev_queue_xmit+0x299a/0x3650 net/core/dev.c:4229
page last free stack trace:
reset_page_owner include/linux/page_owner.h:24 [inline]
free_pages_prepare mm/page_alloc.c:1338 [inline]
free_pcp_prepare+0x374/0x870 mm/page_alloc.c:1389
free_unref_page_prepare mm/page_alloc.c:3309 [inline]
free_unref_page+0x19/0x690 mm/page_alloc.c:3388
qlink_free mm/kasan/quarantine.c:146 [inline]
qlist_free_all+0x5a/0xc0 mm/kasan/quarantine.c:165
kasan_quarantine_reduce+0x180/0x200 mm/kasan/quarantine.c:272
__kasan_slab_alloc+0xa2/0xc0 mm/kasan/common.c:444
kasan_slab_alloc include/linux/kasan.h:259 [inline]
slab_post_alloc_hook mm/slab.h:519 [inline]
slab_alloc_node mm/slub.c:3234 [inline]
kmem_cache_alloc_node+0x255/0x3f0 mm/slub.c:3270
__alloc_skb+0x215/0x340 net/core/skbuff.c:414
alloc_skb include/linux/skbuff.h:1126 [inline]
alloc_skb_with_frags+0x93/0x620 net/core/skbuff.c:6078
sock_alloc_send_pskb+0x783/0x910 net/core/sock.c:2575
mld_newpack+0x1df/0x770 net/ipv6/mcast.c:1754
add_grhead+0x265/0x330 net/ipv6/mcast.c:1857
add_grec+0x1053/0x14e0 net/ipv6/mcast.c:1995
mld_send_initial_cr.part.0+0xf6/0x230 net/ipv6/mcast.c:2242
mld_send_initial_cr net/ipv6/mcast.c:1232 [inline]
mld_dad_work+0x1d3/0x690 net/ipv6/mcast.c:2268
process_one_work+0x9b2/0x1690 kernel/workqueue.c:2298
worker_thread+0x658/0x11f0 kernel/workqueue.c:2445
Memory state around the buggy address:
ffff88807f1cb600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88807f1cb680: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc
>ffff88807f1cb700: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88807f1cb780: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc
ffff88807f1cb800: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Fixes: 41063e9dd119 ("ipv4: Early TCP socket demux.")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Link: https://lore.kernel.org/r/20211220143330.680945-1-eric.dumazet@gmail.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Zhengchao Shao <shaozhengchao(a)huawei.com>
Conflict:
include/net/sock.h
net/ipv4/tcp_ipv4.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/net/sock.h | 2 +-
net/ipv4/af_inet.c | 2 +-
net/ipv4/tcp.c | 3 +--
net/ipv4/tcp_input.c | 2 +-
net/ipv4/tcp_ipv4.c | 11 +++++++----
net/ipv4/udp.c | 6 +++---
net/ipv6/tcp_ipv6.c | 11 +++++++----
net/ipv6/udp.c | 4 ++--
8 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index af73dda0285b..7d068cf871a3 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -429,7 +429,7 @@ struct sock {
#ifdef CONFIG_XFRM
struct xfrm_policy __rcu *sk_policy[2];
#endif
- struct dst_entry *sk_rx_dst;
+ struct dst_entry __rcu *sk_rx_dst;
struct dst_entry __rcu *sk_dst_cache;
atomic_t sk_omem_alloc;
int sk_sndbuf;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 8bf43ca7139a..911ad595dbb9 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -158,7 +158,7 @@ void inet_sock_destruct(struct sock *sk)
kfree(rcu_dereference_protected(inet->inet_opt, 1));
dst_release(rcu_dereference_protected(sk->sk_dst_cache, 1));
- dst_release(sk->sk_rx_dst);
+ dst_release(rcu_dereference_protected(sk->sk_rx_dst, 1));
sk_refcnt_debug_dec(sk);
}
EXPORT_SYMBOL(inet_sock_destruct);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index fcd792816756..c19428e97876 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2814,8 +2814,7 @@ int tcp_disconnect(struct sock *sk, int flags)
icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
__sk_dst_reset(sk);
- dst_release(sk->sk_rx_dst);
- sk->sk_rx_dst = NULL;
+ dst_release(xchg((__force struct dst_entry **)&sk->sk_rx_dst, NULL));
tcp_saved_syn_free(tp);
tp->compressed_ack = 0;
tp->segs_in = 0;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 11f3f8e23a8a..6f4ac0f10f57 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5744,7 +5744,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)
trace_tcp_probe(sk, skb);
tcp_mstamp_refresh(tp);
- if (unlikely(!sk->sk_rx_dst))
+ if (unlikely(!rcu_access_pointer(sk->sk_rx_dst)))
inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb);
/*
* Header prediction.
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index ebfeeeadd47c..078f3a5d65b3 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1670,15 +1670,18 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
struct sock *rsk;
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
- struct dst_entry *dst = sk->sk_rx_dst;
+ struct dst_entry *dst;
+
+ dst = rcu_dereference_protected(sk->sk_rx_dst,
+ lockdep_sock_is_held(sk));
sock_rps_save_rxhash(sk, skb);
sk_mark_napi_id(sk, skb);
if (dst) {
if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif ||
!dst->ops->check(dst, 0)) {
+ RCU_INIT_POINTER(sk->sk_rx_dst, NULL);
dst_release(dst);
- sk->sk_rx_dst = NULL;
}
}
tcp_rcv_established(sk, skb);
@@ -1753,7 +1756,7 @@ int tcp_v4_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_edemux;
if (sk_fullsock(sk)) {
- struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst);
+ struct dst_entry *dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, 0);
@@ -2160,7 +2163,7 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
struct dst_entry *dst = skb_dst(skb);
if (dst && dst_hold_safe(dst)) {
- sk->sk_rx_dst = dst;
+ rcu_assign_pointer(sk->sk_rx_dst, dst);
inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
}
}
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8cca8bda0612..121c08d4255c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2186,7 +2186,7 @@ bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
struct dst_entry *old;
if (dst_hold_safe(dst)) {
- old = xchg(&sk->sk_rx_dst, dst);
+ old = xchg((__force struct dst_entry **)&sk->sk_rx_dst, dst);
dst_release(old);
return old != dst;
}
@@ -2376,7 +2376,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
struct dst_entry *dst = skb_dst(skb);
int ret;
- if (unlikely(sk->sk_rx_dst != dst))
+ if (unlikely(rcu_dereference(sk->sk_rx_dst) != dst))
udp_sk_rx_dst_set(sk, dst);
ret = udp_unicast_rcv_skb(sk, skb, uh);
@@ -2535,7 +2535,7 @@ int udp_v4_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_efree;
- dst = READ_ONCE(sk->sk_rx_dst);
+ dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, 0);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index df33145b876c..b87b04526e65 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -107,7 +107,7 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
if (dst && dst_hold_safe(dst)) {
const struct rt6_info *rt = (const struct rt6_info *)dst;
- sk->sk_rx_dst = dst;
+ rcu_assign_pointer(sk->sk_rx_dst, dst);
inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
tcp_inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
}
@@ -1482,15 +1482,18 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
opt_skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC));
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
- struct dst_entry *dst = sk->sk_rx_dst;
+ struct dst_entry *dst;
+
+ dst = rcu_dereference_protected(sk->sk_rx_dst,
+ lockdep_sock_is_held(sk));
sock_rps_save_rxhash(sk, skb);
sk_mark_napi_id(sk, skb);
if (dst) {
if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif ||
dst->ops->check(dst, np->rx_dst_cookie) == NULL) {
+ RCU_INIT_POINTER(sk->sk_rx_dst, NULL);
dst_release(dst);
- sk->sk_rx_dst = NULL;
}
}
@@ -1842,7 +1845,7 @@ INDIRECT_CALLABLE_SCOPE void tcp_v6_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_edemux;
if (sk_fullsock(sk)) {
- struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst);
+ struct dst_entry *dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, tcp_inet6_sk(sk)->rx_dst_cookie);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 503706397839..7022dcbb5a11 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -940,7 +940,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
struct dst_entry *dst = skb_dst(skb);
int ret;
- if (unlikely(sk->sk_rx_dst != dst))
+ if (unlikely(rcu_dereference(sk->sk_rx_dst) != dst))
udp6_sk_rx_dst_set(sk, dst);
if (!uh->check && !udp_sk(sk)->no_check6_rx) {
@@ -1054,7 +1054,7 @@ INDIRECT_CALLABLE_SCOPE void udp_v6_early_demux(struct sk_buff *skb)
skb->sk = sk;
skb->destructor = sock_efree;
- dst = READ_ONCE(sk->sk_rx_dst);
+ dst = rcu_dereference(sk->sk_rx_dst);
if (dst)
dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie);
--
2.20.1
1
49
Backport 5.10.105 LTS patches from upstream
Revert "ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE"
arm64: cpufeature: add HWCAP for FEAT_RPRES
arm64: cpufeature: add HWCAP for FEAT_AFP
arm64: Add Cortex-A510 CPU part definition
arm64: Add Cortex-X2 CPU part definition
arm64: Add Neoverse-N2, Cortex-A710 CPU part definition
arm64: cputype: Add CPU implementor & types for the Apple M1 cores
Conflicts:
Revert "ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE"
arm64: Add Cortex-X2 CPU part definition
Anshuman Khandual (2):
arm64: Add Cortex-X2 CPU part definition
arm64: Add Cortex-A510 CPU part definition
Greg Kroah-Hartman (1):
Revert "ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE"
Hector Martin (1):
arm64: cputype: Add CPU implementor & types for the Apple M1 cores
Joey Gouly (2):
arm64: cpufeature: add HWCAP for FEAT_AFP
arm64: cpufeature: add HWCAP for FEAT_RPRES
Suzuki K Poulose (1):
arm64: Add Neoverse-N2, Cortex-A710 CPU part definition
Documentation/arm64/cpu-feature-registers.rst | 17 +++++++++++++++++
Documentation/arm64/elf_hwcaps.rst | 8 ++++++++
arch/arm64/include/asm/cputype.h | 14 ++++++++++++++
arch/arm64/include/asm/hwcap.h | 2 ++
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/include/uapi/asm/hwcap.h | 2 ++
arch/arm64/kernel/cpufeature.c | 4 ++++
arch/arm64/kernel/cpuinfo.c | 2 ++
drivers/acpi/ec.c | 10 ----------
drivers/acpi/sleep.c | 14 ++++++++++----
10 files changed, 60 insertions(+), 14 deletions(-)
--
2.20.1
1
7
hi, all
Reviewed-by, "jiaofenfang"<jiaofenfang(a)uniontech.com>
------------------ Original ------------------
From: "Chao Liu"<liuchao173(a)huawei.com>;
Date: Sat, May 28, 2022 03:47 PM
To: "kernel"<kernel(a)openeuler.org>;
Cc: "hewenliang4"<hewenliang4(a)huawei.com>; "fangchuangchuang"<fangchuangchuang(a)huawei.com>; "xiexiuqi"<xiexiuqi(a)huawei.com>; "zhengzengkai"<zhengzengkai(a)huawei.com>; "kai.liu"<kai.liu(a)suse.com>; "jiaofenfang"<jiaofenfang(a)uniontech.com>; "yinxiujiang"<yinxiujiang(a)kylinos.cn>;
Subject: [PATCH OLK-5.10] config: change CONFIG_DMATEST from y to m
euler inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I59Q07
CVE: NA
--------------------------------
Simple DMA test client. Say N unless you're debugging a DMA Device driver.
It doesn't need to be compiled into the vmlinux, change it to m.
Signed-off-by: Chao Liu <liuchao173(a)huawei.com>
---
arch/x86/configs/openeuler_defconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 61c4be815462..f9c94b618ad4 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -6370,7 +6370,7 @@ CONFIG_HSU_DMA=y
# DMA Clients
#
CONFIG_ASYNC_TX_DMA=y
-CONFIG_DMATEST=y
+CONFIG_DMATEST=m
CONFIG_DMA_ENGINE_RAID=y
#
--
2.23.0
1
0
euler inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I59Q07
CVE: NA
--------------------------------
Simple DMA test client. Say N unless you're debugging a DMA Device driver.
It doesn't need to be compiled into the vmlinux, change it to m.
Signed-off-by: Chao Liu <liuchao173(a)huawei.com>
---
arch/x86/configs/openeuler_defconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 61c4be815462..f9c94b618ad4 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -6370,7 +6370,7 @@ CONFIG_HSU_DMA=y
# DMA Clients
#
CONFIG_ASYNC_TX_DMA=y
-CONFIG_DMATEST=y
+CONFIG_DMATEST=m
CONFIG_DMA_ENGINE_RAID=y
#
--
2.23.0
3
2

[PATCH openEuler-5.10 1/8] Revert "audit: bugfix for infinite loop when flush the hold queue"
by Zheng Zengkai 28 May '22
by Zheng Zengkai 28 May '22
28 May '22
From: Cui GaoSheng <cuigaosheng1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 186383 https://gitee.com/openeuler/kernel/issues/I4X1AI?from=project-issue
CVE: NA
backport: openEuler-22.03-LTS
--------------------------------
This reverts commit fcfdde9cfc503cfd191b7286f9c48077fb5bf420.
Signed-off-by: Cui GaoSheng <cuigaosheng1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
kernel/audit.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 21be62bc8205..2a38cbaf3ddb 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -732,8 +732,6 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
if (!sk) {
if (err_hook)
(*err_hook)(skb);
- if (queue == &audit_hold_queue)
- goto out;
continue;
}
@@ -750,8 +748,6 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
(*err_hook)(skb);
if (rc == -EAGAIN)
rc = 0;
- if (queue == &audit_hold_queue)
- goto out;
/* continue to drain the queue */
continue;
} else
@@ -763,7 +759,6 @@ static int kauditd_send_queue(struct sock *sk, u32 portid,
}
}
-out:
return (rc >= 0 ? 0 : rc);
}
--
2.20.1
1
7
Backport 5.10.104 LTS patches from upstream
hamradio: fix macro redefine warning
Revert "xfrm: xfrm_state_mtu should return at least 1280 for ipv6"
btrfs: add missing run of delayed items after unlink during log replay
btrfs: qgroup: fix deadlock between rescan worker and remove qgroup
btrfs: fix lost prealloc extents beyond eof after full fsync
tracing: Fix return value of setup handlers
tracing/histogram: Fix sorting on old "cpu" value
HID: add mapping for KEY_ALL_APPLICATIONS
HID: add mapping for KEY_DICTATE
Input: samsung-keypad - properly state IOMEM dependency
Input: elan_i2c - fix regulator enable count imbalance after suspend/resume
Input: elan_i2c - move regulator[en|dis]able() out of elan[en|dis]able_power()
net: dcb: disable softirqs in dcbnl_flush_dev()
drm/amdgpu: fix suspend/resume hang regression
nl80211: Handle nla_memdup failures in handle_nan_filter
iavf: Refactor iavf state machine tracking
net: chelsio: cxgb3: check the return value of pci_find_capability()
ibmvnic: complete init_done on transport events
ARM: tegra: Move panels to AUX bus
soc: fsl: qe: Check of ioremap return value
soc: fsl: guts: Add a missing memory allocation failure check
soc: fsl: guts: Revert commit 3c0d64e867ed
ARM: dts: Use 32KiHz oscillator on devkit8000
ARM: dts: switch timer config to common devkit8000 devicetree
s390/extable: fix exception table sorting
memfd: fix F_SEAL_WRITE after shmem huge page allocated
ibmvnic: free reset-work-item when flushing
igc: igc_write_phy_reg_gpy: drop premature return
pinctrl: sunxi: Use unique lockdep classes for IRQs
selftests: mlxsw: tc_police_scale: Make test more robust
ARM: 9182/1: mmu: fix returns from early_param() and __setup() functions
ARM: Fix kgdb breakpoint for Thumb2
igc: igc_read_phy_reg_gpy: drop premature return
arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
can: gs_usb: change active_channels's type from atomic_t to u8
ASoC: cs4265: Fix the duplicated control name
firmware: arm_scmi: Remove space in MODULE_ALIAS name
efivars: Respect "block" flag in efivar_entry_set_safe()
ixgbe: xsk: change !netif_carrier_ok() handling in ixgbe_xmit_zc()
net: arcnet: com20020: Fix null-ptr-deref in com20020pci_probe()
ibmvnic: register netdev after init of adapter
net: sxgbe: fix return value of __setup handler
iavf: Fix missing check for running netdev
mac80211: treat some SAE auth steps as final
net: stmmac: fix return value of __setup handler
mac80211: fix forwarded mesh frames AC & queue selection
ice: fix concurrent reset and removal of VFs
ice: Fix race conditions between virtchnl handling and VF ndo ops
net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server
net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by client
net/smc: fix connection leak
net: dcb: flush lingering app table entries for unregistered devices
net: ipv6: ensure we call ipv6_mc_down() at most once
batman-adv: Don't expect inter-netns unique iflink indices
batman-adv: Request iflink once in batadv_get_real_netdevice
batman-adv: Request iflink once in batadv-on-batadv check
netfilter: nf_queue: handle socket prefetch
netfilter: nf_queue: fix possible use-after-free
netfilter: nf_queue: don't assume sk is full socket
net: fix up skbs delta_truesize in UDP GRO frag_list
e1000e: Correct NVM checksum verification flow
xfrm: enforce validity of offload input flags
xfrm: fix the if_id check in changelink
bpf, sockmap: Do not ignore orig_len parameter
netfilter: fix use-after-free in __nf_register_net_hook()
xfrm: fix MTU regression
mm: Consider __GFP_NOWARN flag for oversized kvmalloc() calls
ntb: intel: fix port config status offset for SPR
thermal: core: Fix TZ_GET_TRIP NULL pointer dereference
xen/netfront: destroy queues before real_num_tx_queues is zeroed
drm/i915: s/JSP2/ICP2/ PCH
iommu/amd: Recover from event log overflow
ASoC: ops: Shift tested values in snd_soc_put_volsw() by +min
riscv: Fix config KASAN && DEBUG_VIRTUAL
riscv: Fix config KASAN && SPARSEMEM && !SPARSE_VMEMMAP
riscv/efi_stub: Fix get_boot_hartid_from_fdt() return value
ALSA: intel_hdmi: Fix reference to PCM buffer address
tracing: Add ustring operation to filtering string pointers
drm/amdgpu: check vm ready by amdgpu_vm->evicting flag
ata: pata_hpt37x: fix PCI clock detection
serial: stm32: prevent TDR register overwrite when sending x_char
tracing: Add test for user space strings when filtering on string pointers
exfat: fix i_blocks for files truncated over 4 GiB
exfat: reuse exfat_inode_info variable instead of calling EXFAT_I()
net: usb: cdc_mbim: avoid altsetting toggling for Telit FN990
i2c: qup: allow COMPILE_TEST
i2c: cadence: allow COMPILE_TEST
dmaengine: shdma: Fix runtime PM imbalance on error
selftests/seccomp: Fix seccomp failure by adding missing headers
cifs: fix double free race when mount fails in cifs_get_root()
tipc: fix a bit overflow in tipc_crypto_key_rcv()
KVM: arm64: vgic: Read HW interrupt pending state from the HW
Input: clear BTN_RIGHT/MIDDLE on buttonpads
regulator: core: fix false positive in regulator_late_cleanup()
ASoC: rt5682: do not block workqueue if card is unbound
ASoC: rt5668: do not block workqueue if card is unbound
i2c: bcm2835: Avoid clock stretching timeouts
mac80211_hwsim: initialize ieee80211_tx_info at hw_scan_work
mac80211_hwsim: report NOACK frames in tx_status
already merged:
usb: gadget: don't release an existing dev->buf
usb: gadget: clear related members when goto fail
rcu/nocb: Fix missed nocb_timer requeue
sched/topology: Make sched_init_numa() use a set for the deduplicating sort
sched/topology: Fix sched_domain_topology_level alloc in sched_init_numa()
ia64: ensure proper NUMA distance and possible map initialization
Total patches: 105 - 6 = 99
Alexandre Ghiti (2):
riscv: Fix config KASAN && SPARSEMEM && !SPARSE_VMEMMAP
riscv: Fix config KASAN && DEBUG_VIRTUAL
Alyssa Ross (1):
firmware: arm_scmi: Remove space in MODULE_ALIAS name
Amit Cohen (1):
selftests: mlxsw: tc_police_scale: Make test more robust
Anthoine Bourgeois (2):
ARM: dts: switch timer config to common devkit8000 devicetree
ARM: dts: Use 32KiHz oscillator on devkit8000
Antony Antony (1):
xfrm: fix the if_id check in changelink
Benjamin Beichler (1):
mac80211_hwsim: report NOACK frames in tx_status
Brett Creeley (1):
ice: Fix race conditions between virtchnl handling and VF ndo ops
Brian Norris (1):
arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
Christophe JAILLET (2):
soc: fsl: guts: Revert commit 3c0d64e867ed
soc: fsl: guts: Add a missing memory allocation failure check
Christophe Vu-Brugier (2):
exfat: reuse exfat_inode_info variable instead of calling EXFAT_I()
exfat: fix i_blocks for files truncated over 4 GiB
Corinna Vinschen (1):
igc: igc_read_phy_reg_gpy: drop premature return
D. Wythe (3):
net/smc: fix connection leak
net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by
client
net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server
Daniel Borkmann (1):
mm: Consider __GFP_NOWARN flag for oversized kvmalloc() calls
Daniele Palmas (1):
net: usb: cdc_mbim: avoid altsetting toggling for Telit FN990
Dave Jiang (1):
ntb: intel: fix port config status offset for SPR
David Gow (1):
Input: samsung-keypad - properly state IOMEM dependency
Eric Anholt (1):
i2c: bcm2835: Avoid clock stretching timeouts
Eric Dumazet (2):
netfilter: fix use-after-free in __nf_register_net_hook()
bpf, sockmap: Do not ignore orig_len parameter
Fabio Estevam (1):
ASoC: cs4265: Fix the duplicated control name
Filipe Manana (2):
btrfs: fix lost prealloc extents beyond eof after full fsync
btrfs: add missing run of delayed items after unlink during log replay
Florian Westphal (3):
netfilter: nf_queue: don't assume sk is full socket
netfilter: nf_queue: fix possible use-after-free
netfilter: nf_queue: handle socket prefetch
Hangyu Hua (1):
tipc: fix a bit overflow in tipc_crypto_key_rcv()
Hans de Goede (2):
Input: elan_i2c - move regulator_[en|dis]able() out of
elan_[en|dis]able_power()
Input: elan_i2c - fix regulator enable count imbalance after
suspend/resume
Heiko Carstens (1):
s390/extable: fix exception table sorting
Huang Pei (1):
hamradio: fix macro redefine warning
Hugh Dickins (1):
memfd: fix F_SEAL_WRITE after shmem huge page allocated
Jacob Keller (1):
ice: fix concurrent reset and removal of VFs
JaeMan Park (1):
mac80211_hwsim: initialize ieee80211_tx_info at hw_scan_work
Jann Horn (1):
efivars: Respect "block" flag in efivar_entry_set_safe()
Jia-Ju Bai (1):
net: chelsio: cxgb3: check the return value of pci_find_capability()
Jiasheng Jiang (2):
soc: fsl: qe: Check of ioremap return value
nl80211: Handle nla_memdup failures in handle_nan_filter
Jiri Bohac (2):
xfrm: fix MTU regression
Revert "xfrm: xfrm_state_mtu should return at least 1280 for ipv6"
Johannes Berg (1):
mac80211: treat some SAE auth steps as final
José Expósito (1):
Input: clear BTN_RIGHT/MIDDLE on buttonpads
Kai Vehmanen (2):
ASoC: rt5668: do not block workqueue if card is unbound
ASoC: rt5682: do not block workqueue if card is unbound
Lennert Buytenhek (1):
iommu/amd: Recover from event log overflow
Leon Romanovsky (1):
xfrm: enforce validity of offload input flags
Maciej Fijalkowski (1):
ixgbe: xsk: change !netif_carrier_ok() handling in ixgbe_xmit_zc()
Marc Zyngier (1):
KVM: arm64: vgic: Read HW interrupt pending state from the HW
Marek Marczykowski-Górecki (1):
xen/netfront: destroy queues before real_num_tx_queues is zeroed
Marek Vasut (1):
ASoC: ops: Shift tested values in snd_soc_put_volsw() by +min
Mateusz Palczewski (1):
iavf: Refactor iavf state machine tracking
Nicolas Cavallari (1):
thermal: core: Fix TZ_GET_TRIP NULL pointer dereference
Nicolas Escande (1):
mac80211: fix forwarded mesh frames AC & queue selection
Oliver Barta (1):
regulator: core: fix false positive in regulator_late_cleanup()
Qiang Yu (2):
drm/amdgpu: check vm ready by amdgpu_vm->evicting flag
drm/amdgpu: fix suspend/resume hang regression
Randy Dunlap (4):
net: stmmac: fix return value of __setup handler
net: sxgbe: fix return value of __setup handler
ARM: 9182/1: mmu: fix returns from early_param() and __setup()
functions
tracing: Fix return value of __setup handlers
Ronnie Sahlberg (1):
cifs: fix double free race when mount fails in cifs_get_root()
Russell King (Oracle) (1):
ARM: Fix kgdb breakpoint for Thumb2
Samuel Holland (1):
pinctrl: sunxi: Use unique lockdep classes for IRQs
Sasha Neftin (2):
e1000e: Correct NVM checksum verification flow
igc: igc_write_phy_reg_gpy: drop premature return
Sergey Shtylyov (1):
ata: pata_hpt37x: fix PCI clock detection
Sherry Yang (1):
selftests/seccomp: Fix seccomp failure by adding missing headers
Sidong Yang (1):
btrfs: qgroup: fix deadlock between rescan worker and remove qgroup
Slawomir Laba (1):
iavf: Fix missing check for running netdev
Steven Rostedt (2):
tracing: Add test for user space strings when filtering on string
pointers
tracing: Add ustring operation to filtering string pointers
Steven Rostedt (Google) (1):
tracing/histogram: Fix sorting on old "cpu" value
Sukadev Bhattiprolu (3):
ibmvnic: register netdev after init of adapter
ibmvnic: free reset-work-item when flushing
ibmvnic: complete init_done on transport events
Sunil V L (1):
riscv/efi_stub: Fix get_boot_hartid_from_fdt() return value
Sven Eckelmann (3):
batman-adv: Request iflink once in batadv-on-batadv check
batman-adv: Request iflink once in batadv_get_real_netdevice
batman-adv: Don't expect inter-netns unique iflink indices
Thierry Reding (1):
ARM: tegra: Move panels to AUX bus
Valentin Caron (1):
serial: stm32: prevent TDR register overwrite when sending x_char
Ville Syrjälä (1):
drm/i915: s/JSP2/ICP2/ PCH
Vincent Mailhol (1):
can: gs_usb: change active_channels's type from atomic_t to u8
Vladimir Oltean (2):
net: dcb: flush lingering app table entries for unregistered devices
net: dcb: disable softirqs in dcbnl_flush_dev()
William Mahon (2):
HID: add mapping for KEY_DICTATE
HID: add mapping for KEY_ALL_APPLICATIONS
Wolfram Sang (2):
i2c: cadence: allow COMPILE_TEST
i2c: qup: allow COMPILE_TEST
Yongzhi Liu (1):
dmaengine: shdma: Fix runtime PM imbalance on error
Zhen Ni (1):
ALSA: intel_hdmi: Fix reference to PCM buffer address
Zheyu Ma (1):
net: arcnet: com20020: Fix null-ptr-deref in com20020pci_probe()
j.nixdorf(a)avm.de (1):
net: ipv6: ensure we call ipv6_mc_down() at most once
lena wang (1):
net: fix up skbs delta_truesize in UDP GRO frag_list
Documentation/trace/events.rst | 19 ++++
.../arm/boot/dts/omap3-devkit8000-common.dtsi | 18 +++
arch/arm/boot/dts/omap3-devkit8000.dts | 33 ------
arch/arm/boot/dts/tegra124-nyan-big.dts | 15 ++-
arch/arm/boot/dts/tegra124-nyan-blaze.dts | 15 ++-
arch/arm/boot/dts/tegra124-venice2.dts | 14 +--
arch/arm/kernel/kgdb.c | 36 ++++--
arch/arm/mm/mmu.c | 2 +
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 17 ++-
arch/arm64/kvm/vgic/vgic-mmio.c | 2 +
arch/riscv/mm/Makefile | 3 +
arch/riscv/mm/kasan_init.c | 3 +-
arch/s390/include/asm/extable.h | 9 +-
drivers/ata/pata_hpt37x.c | 4 +-
drivers/clocksource/timer-ti-dm-systimer.c | 3 +-
drivers/dma/sh/shdma-base.c | 4 +-
drivers/firmware/arm_scmi/driver.c | 2 +-
drivers/firmware/efi/libstub/riscv-stub.c | 17 +--
drivers/firmware/efi/vars.c | 5 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 10 +-
drivers/gpu/drm/i915/intel_pch.c | 2 +-
drivers/gpu/drm/i915/intel_pch.h | 2 +-
drivers/hid/hid-debug.c | 5 +-
drivers/hid/hid-input.c | 3 +
drivers/i2c/busses/Kconfig | 4 +-
drivers/i2c/busses/i2c-bcm2835.c | 11 ++
drivers/input/input.c | 6 +
drivers/input/keyboard/Kconfig | 2 +-
drivers/input/mouse/elan_i2c_core.c | 64 ++++-------
drivers/iommu/amd/amd_iommu.h | 1 +
drivers/iommu/amd/amd_iommu_types.h | 1 +
drivers/iommu/amd/init.c | 10 ++
drivers/iommu/amd/iommu.c | 10 +-
drivers/net/arcnet/com20020-pci.c | 3 +
drivers/net/can/usb/gs_usb.c | 10 +-
drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 2 +
drivers/net/ethernet/ibm/ibmvnic.c | 21 +++-
drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 +-
drivers/net/ethernet/intel/iavf/iavf.h | 10 ++
drivers/net/ethernet/intel/iavf/iavf_main.c | 44 +++----
.../net/ethernet/intel/iavf/iavf_virtchnl.c | 2 +-
drivers/net/ethernet/intel/ice/ice_main.c | 2 +
.../net/ethernet/intel/ice/ice_virtchnl_pf.c | 58 ++++++++--
.../net/ethernet/intel/ice/ice_virtchnl_pf.h | 5 +
drivers/net/ethernet/intel/igc/igc_phy.c | 4 -
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 6 +-
.../net/ethernet/samsung/sxgbe/sxgbe_main.c | 6 +-
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +-
drivers/net/hamradio/mkiss.c | 2 +
drivers/net/usb/cdc_mbim.c | 5 +
drivers/net/wireless/mac80211_hwsim.c | 13 +++
drivers/net/xen-netfront.c | 39 ++++---
drivers/ntb/hw/intel/ntb_hw_gen4.c | 17 ++-
drivers/ntb/hw/intel/ntb_hw_gen4.h | 16 +++
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 9 ++
drivers/regulator/core.c | 13 +--
drivers/soc/fsl/guts.c | 14 ++-
drivers/soc/fsl/qe/qe_io.c | 2 +
drivers/thermal/thermal_netlink.c | 5 +-
drivers/tty/serial/stm32-usart.c | 12 ++
fs/btrfs/qgroup.c | 9 +-
fs/btrfs/tree-log.c | 61 ++++++++--
fs/cifs/cifsfs.c | 1 +
fs/exfat/file.c | 18 +--
fs/exfat/inode.c | 13 +--
fs/exfat/namei.c | 6 +-
fs/exfat/super.c | 10 +-
include/net/netfilter/nf_queue.h | 2 +-
include/net/xfrm.h | 1 -
include/uapi/linux/input-event-codes.h | 4 +-
include/uapi/linux/xfrm.h | 6 +
kernel/trace/trace.c | 4 +-
kernel/trace/trace_events_filter.c | 107 ++++++++++++++++--
kernel/trace/trace_events_hist.c | 6 +-
kernel/trace/trace_kprobe.c | 2 +-
mm/memfd.c | 40 +++++--
mm/util.c | 4 +-
net/batman-adv/hard-interface.c | 29 +++--
net/core/skbuff.c | 2 +-
net/core/skmsg.c | 2 +-
net/dcb/dcbnl.c | 44 +++++++
net/ipv4/esp4.c | 2 +-
net/ipv6/addrconf.c | 8 +-
net/ipv6/esp6.c | 2 +-
net/ipv6/ip6_output.c | 11 +-
net/mac80211/ieee80211_i.h | 2 +-
net/mac80211/mlme.c | 16 ++-
net/mac80211/rx.c | 4 +-
net/netfilter/core.c | 5 +-
net/netfilter/nf_queue.c | 36 +++++-
net/netfilter/nfnetlink_queue.c | 12 +-
net/smc/af_smc.c | 10 +-
net/smc/smc_core.c | 5 +-
net/tipc/crypto.c | 2 +-
net/wireless/nl80211.c | 12 ++
net/xfrm/xfrm_device.c | 6 +-
net/xfrm/xfrm_interface.c | 2 +-
net/xfrm/xfrm_state.c | 14 +--
sound/soc/codecs/cs4265.c | 3 +-
sound/soc/codecs/rt5668.c | 12 +-
sound/soc/codecs/rt5682.c | 12 +-
sound/soc/soc-ops.c | 4 +-
sound/x86/intel_hdmi_audio.c | 2 +-
.../drivers/net/mlxsw/tc_police_scale.sh | 3 +-
tools/testing/selftests/seccomp/Makefile | 2 +-
105 files changed, 881 insertions(+), 359 deletions(-)
--
2.20.1
1
99

[PATCH openEuler-5.10 1/6] slub: add back check for free nonslab objects
by Zheng Zengkai 28 May '22
by Zheng Zengkai 28 May '22
28 May '22
From: Kefeng Wang <wangkefeng.wang(a)huawei.com>
mainline inclusion
from mainline-v5.16-rc1
commit d0fe47c64152a63ceed4b9f29ac56371407fa7b4
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I57LS2
CVE: NA
backport: openEuler-22.03-LTS
--------------------------------
After commit f227f0faf63b ("slub: fix unreclaimable slab stat for bulk
free"), the check for free nonslab page is replaced by VM_BUG_ON_PAGE,
which only check with CONFIG_DEBUG_VM enabled, but this config may
impact performance, so it only for debug.
Commit 0937502af7c9 ("slub: Add check for kfree() of non slab objects.")
add the ability, which should be needed in any configs to catch the
invalid free, they even could be potential issue, eg, memory corruption,
use after free and double free, so replace VM_BUG_ON_PAGE to
WARN_ON_ONCE, add object address printing to help use to debug the
issue.
Link: https://lkml.kernel.org/r/20210930070214.61499-1-wangkefeng.wang@huawei.com
Signed-off-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Cc: Matthew Wilcox <willy(a)infradead.org>
Cc: Shakeel Butt <shakeelb(a)google.com>
Cc: Vlastimil Babka <vbabka(a)suse.cz>
Cc: Christoph Lameter <cl(a)linux.com>
Cc: Pekka Enberg <penberg(a)kernel.org>
Cc: David Rienjes <rientjes(a)google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim(a)lge.com>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
mm/slub.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/slub.c b/mm/slub.c
index 7a7b0bf82b8e..98452815a066 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3209,7 +3209,9 @@ static inline void free_nonslab_page(struct page *page, void *object)
{
unsigned int order = compound_order(page);
- VM_BUG_ON_PAGE(!PageCompound(page), page);
+ if (WARN_ON_ONCE(!PageCompound(page)))
+ pr_warn_once("object pointer: 0x%p\n", object);
+
kfree_hook(object);
mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B, -(PAGE_SIZE << order));
__free_pages(page, order);
--
2.20.1
1
5

[PATCH openEuler-5.10 v2 1/4] ipv6: per-netns exclusive flowlabel checks
by Zheng Zengkai 28 May '22
by Zheng Zengkai 28 May '22
28 May '22
From: Willem de Bruijn <willemb(a)google.com>
stable inclusion
from stable-v5.10.102
commit 4f523f15e5d753ac055302bc29ca9677d6692eed
bugzilla: https://gitee.com/openeuler/kernel/issues/I575QT
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 0b0dff5b3b98c5c7ce848151df9da0b3cdf0cc8b upstream.
Ipv6 flowlabels historically require a reservation before use.
Optionally in exclusive mode (e.g., user-private).
Commit 59c820b2317f ("ipv6: elide flowlabel check if no exclusive
leases exist") introduced a fastpath that avoids this check when no
exclusive leases exist in the system, and thus any flowlabel use
will be granted.
That allows skipping the control operation to reserve a flowlabel
entirely. Though with a warning if the fast path fails:
This is an optimization. Robust applications still have to revert to
requesting leases if the fast path fails due to an exclusive lease.
Still, this is subtle. Better isolate network namespaces from each
other. Flowlabels are per-netns. Also record per-netns whether
exclusive leases are in use. Then behavior does not change based on
activity in other netns.
Changes
v2
- wrap in IS_ENABLED(CONFIG_IPV6) to avoid breakage if disabled
Fixes: 59c820b2317f ("ipv6: elide flowlabel check if no exclusive leases exist")
Link: https://lore.kernel.org/netdev/MWHPR2201MB1072BCCCFCE779E4094837ACD0329@MWH…
Reported-by: Congyu Liu <liu3101(a)purdue.edu>
Signed-off-by: Willem de Bruijn <willemb(a)google.com>
Tested-by: Congyu Liu <liu3101(a)purdue.edu>
Link: https://lore.kernel.org/r/20220215160037.1976072-1-willemdebruijn.kernel@gm…
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/net/ipv6.h | 5 ++++-
include/net/netns/ipv6.h | 5 +++++
net/ipv6/ip6_flowlabel.c | 4 +++-
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index c0273ae50296..9392a81a3ae4 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -390,17 +390,20 @@ static inline void txopt_put(struct ipv6_txoptions *opt)
kfree_rcu(opt, rcu);
}
+#if IS_ENABLED(CONFIG_IPV6)
struct ip6_flowlabel *__fl6_sock_lookup(struct sock *sk, __be32 label);
extern struct static_key_false_deferred ipv6_flowlabel_exclusive;
static inline struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk,
__be32 label)
{
- if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key))
+ if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key) &&
+ READ_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl))
return __fl6_sock_lookup(sk, label) ? : ERR_PTR(-ENOENT);
return NULL;
}
+#endif
struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
struct ip6_flowlabel *fl,
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index ce5ed87accda..b2a28201f4fd 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -83,6 +83,11 @@ struct netns_ipv6 {
unsigned long ip6_rt_last_gc;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
unsigned int fib6_rules_require_fldissect;
+#endif
+#ifndef __GENKSYMS__
+ unsigned char flowlabel_has_excl;
+#endif
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
bool fib6_has_custom_rules;
#ifdef CONFIG_IPV6_SUBTREES
unsigned int fib6_routes_require_src;
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index aa673a6a7e43..ceb85c67ce39 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -450,8 +450,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
err = -EINVAL;
goto done;
}
- if (fl_shared_exclusive(fl) || fl->opt)
+ if (fl_shared_exclusive(fl) || fl->opt) {
+ WRITE_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl, 1);
static_branch_deferred_inc(&ipv6_flowlabel_exclusive);
+ }
return fl;
done:
--
2.20.1
1
3

26 May '22
From: Willem de Bruijn <willemb(a)google.com>
stable inclusion
from stable-v5.10.102
commit 4f523f15e5d753ac055302bc29ca9677d6692eed
bugzilla: https://gitee.com/openeuler/kernel/issues/I575QT
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 0b0dff5b3b98c5c7ce848151df9da0b3cdf0cc8b upstream.
Ipv6 flowlabels historically require a reservation before use.
Optionally in exclusive mode (e.g., user-private).
Commit 59c820b2317f ("ipv6: elide flowlabel check if no exclusive
leases exist") introduced a fastpath that avoids this check when no
exclusive leases exist in the system, and thus any flowlabel use
will be granted.
That allows skipping the control operation to reserve a flowlabel
entirely. Though with a warning if the fast path fails:
This is an optimization. Robust applications still have to revert to
requesting leases if the fast path fails due to an exclusive lease.
Still, this is subtle. Better isolate network namespaces from each
other. Flowlabels are per-netns. Also record per-netns whether
exclusive leases are in use. Then behavior does not change based on
activity in other netns.
Changes
v2
- wrap in IS_ENABLED(CONFIG_IPV6) to avoid breakage if disabled
Fixes: 59c820b2317f ("ipv6: elide flowlabel check if no exclusive leases exist")
Link: https://lore.kernel.org/netdev/MWHPR2201MB1072BCCCFCE779E4094837ACD0329@MWH…
Reported-by: Congyu Liu <liu3101(a)purdue.edu>
Signed-off-by: Willem de Bruijn <willemb(a)google.com>
Tested-by: Congyu Liu <liu3101(a)purdue.edu>
Link: https://lore.kernel.org/r/20220215160037.1976072-1-willemdebruijn.kernel@gm…
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/net/ipv6.h | 5 ++++-
include/net/netns/ipv6.h | 5 +++++
net/ipv6/ip6_flowlabel.c | 4 +++-
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index c0273ae50296..9392a81a3ae4 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -390,17 +390,20 @@ static inline void txopt_put(struct ipv6_txoptions *opt)
kfree_rcu(opt, rcu);
}
+#if IS_ENABLED(CONFIG_IPV6)
struct ip6_flowlabel *__fl6_sock_lookup(struct sock *sk, __be32 label);
extern struct static_key_false_deferred ipv6_flowlabel_exclusive;
static inline struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk,
__be32 label)
{
- if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key))
+ if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key) &&
+ READ_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl))
return __fl6_sock_lookup(sk, label) ? : ERR_PTR(-ENOENT);
return NULL;
}
+#endif
struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
struct ip6_flowlabel *fl,
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index ce5ed87accda..b2a28201f4fd 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -83,6 +83,11 @@ struct netns_ipv6 {
unsigned long ip6_rt_last_gc;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
unsigned int fib6_rules_require_fldissect;
+#endif
+#ifndef __GENKSYMS__
+ unsigned char flowlabel_has_excl;
+#endif
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
bool fib6_has_custom_rules;
#ifdef CONFIG_IPV6_SUBTREES
unsigned int fib6_routes_require_src;
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index aa673a6a7e43..ceb85c67ce39 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -450,8 +450,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
err = -EINVAL;
goto done;
}
- if (fl_shared_exclusive(fl) || fl->opt)
+ if (fl_shared_exclusive(fl) || fl->opt) {
+ WRITE_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl, 1);
static_branch_deferred_inc(&ipv6_flowlabel_exclusive);
+ }
return fl;
done:
--
2.20.1
1
6
Backport 5.10.103 LTS patches from upstream
memblock: use kfree() to release kmalloced memblock regions
gpio: tegra186: Fix chip_data type confusion
tty: n_gsm: fix deadlock in gsmtty_open()
tty: n_gsm: fix wrong tty control line for flow control
tty: n_gsm: fix NULL pointer access due to DLCI release
tty: n_gsm: fix proper link termination after failed open
tty: n_gsm: fix encoding of control signal octet bit DV
riscv: fix oops caused by irqsoff latency tracer
thermal: int340x: fix memory leak in int3400_notify()
RDMA/cma: Do not change route.addr.src_addr outside state checks
driver core: Free DMA range map when device is released
xhci: Prevent futile URB re-submissions due to incorrect return value.
xhci: re-initialize the HC during resume if HCE was set
usb: dwc3: gadget: Let the interrupt handler disable bottom halves.
usb: dwc3: pci: Fix Bay Trail phy GPIO mappings
usb: dwc2: drd: fix soft connect when gadget is unconfigured
USB: serial: option: add Telit LE910R1 compositions
USB: serial: option: add support for DW5829e
tracefs: Set the group ownership in apply_options() not parse_options()
usb: gadget: rndis: add spinlock for rndis response list
Revert "USB: serial: ch341: add new Product ID for CH341A"
ata: pata_hpt37x: disable primary channel on HPT371
sc16is7xx: Fix for incorrect data being transmitted
iio: Fix error handling for PM
iio: imu: st_lsm6dsx: wait for settling time in st_lsm6dsx_read_oneshot
iio: adc: ad7124: fix mask used for setting AIN_BUFP & AIN_BUFM bits
iio: adc: men_z188_adc: Fix a resource leak in an error handling path
tracing: Have traceon and traceoff trigger honor the instance
RDMA/ib_srp: Fix a deadlock
RDMA/rtrs-clt: Move free_permit from free_clt to rtrs_clt_close
RDMA/rtrs-clt: Kill wait_for_inflight_permits
regmap-irq: Update interrupt clear register for proper reset
spi: spi-zynq-qspi: Fix a NULL pointer dereference in zynq_qspi_exec_mem_op()
net/mlx5e: kTLS, Use CHECKSUM_UNNECESSARY for device-offloaded packets
net/mlx5: Fix wrong limitation of metadata match on ecpf
net/mlx5: Fix possible deadlock on rule deletion
udp_tunnel: Fix end of loop test in udp_tunnel_nic_unregister()
surface: surface3_power: Fix battery readings on batteries without a serial
number
net/smc: Use a mutex for locking "struct smc_pnettable"
netfilter: nf_tables: fix memory leak during stateful obj update
nfp: flower: Fix a potential leak in nfp_tunnel_add_shared_mac()
net: Force inlining of checksum functions in net/checksum.h
net: ll_temac: check the return value of devm_kmalloc()
net/sched: act_ct: Fix flow table lookup after ct clear or switching zones
net/mlx5e: Fix wrong return value on ioctl EEPROM query failure
drm/edid: Always set RGB444
openvswitch: Fix setting ipv6 fields causing hw csum failure
gso: do not skip outer ip header in case of ipip and net_failover
tipc: Fix end of loop tests for list_for_each_entry()
net: __pskb_pull_tail() & pskb_carve_frag_list() drop_monitor friends
io_uring: add a schedule point in io_add_buffers()
bpf: Add schedule points in batch ops
selftests: bpf: Check bpf_msg_push_data return value
bpf: Do not try bpf_msg_push_data with len 0
hwmon: Handle failure to register sensor with thermal zone correctly
bnxt_en: Fix active FEC reporting to ethtool
bnx2x: fix driver load from initrd
perf data: Fix double free in perf_session__delete()
ping: remove pr_err from ping_lookup
optee: use driver internal tee_context for some rpc
tee: export teedev_open() and teedev_close_context()
x86/fpu: Correct pkru/xstate inconsistency
CDC-NCM: avoid overflow in sanity checking
USB: zaurus: support another broken Zaurus
drm/i915: Correctly populate use_sagv_wm for all pipes
drm/amdgpu: disable MMHUB PG for Picasso
KVM: x86/mmu: make apf token non-zero to fix bug
parisc/unaligned: Fix ldw() and stw() unalignment handlers
parisc/unaligned: Fix fldd and fstd unaligned handlers on 32-bit kernel
vhost/vsock: don't check owner in vhost_vsock_stop() while releasing
clk: jz4725b: fix mmc0 clock gating
btrfs: tree-checker: check item_size for dev_item
btrfs: tree-checker: check item_size for inode_item
already merged:
cgroup/cpuset: Fix a race between cpuset_attach() and cpu hotplug
netfilter: nf_tables_offload: incorrect flow offload action array size
configfs: fix a race in configfs_{,un}register_subsystem()
RDMA/rtrs-clt: Fix possible double free in error case
USB: gadget: validate endpoint index for xilinx udc
sr9700: sanity check for packet length
Total patches: 79 - 6 = 73
Alexey Bayduraev (1):
perf data: Fix double free in perf_session__delete()
Ariel Levkovich (1):
net/mlx5: Fix wrong limitation of metadata match on ecpf
Bart Van Assche (1):
RDMA/ib_srp: Fix a deadlock
Brian Geffon (1):
x86/fpu: Correct pkru/xstate inconsistency
Changbin Du (1):
riscv: fix oops caused by irqsoff latency tracer
Christophe JAILLET (2):
nfp: flower: Fix a potential leak in nfp_tunnel_add_shared_mac()
iio: adc: men_z188_adc: Fix a resource leak in an error handling path
Christophe Leroy (1):
net: Force inlining of checksum functions in net/checksum.h
Chuansheng Liu (1):
thermal: int340x: fix memory leak in int3400_notify()
Cosmin Tanislav (1):
iio: adc: ad7124: fix mask used for setting AIN_BUFP & AIN_BUFM bits
Daehwan Jung (1):
usb: gadget: rndis: add spinlock for rndis response list
Dan Carpenter (2):
tipc: Fix end of loop tests for list_for_each_entry()
udp_tunnel: Fix end of loop test in udp_tunnel_nic_unregister()
Daniele Palmas (1):
USB: serial: option: add Telit LE910R1 compositions
Dmytro Bagrii (1):
Revert "USB: serial: ch341: add new Product ID for CH341A"
Eric Dumazet (3):
bpf: Add schedule points in batch ops
io_uring: add a schedule point in io_add_buffers()
net: __pskb_pull_tail() & pskb_carve_frag_list() drop_monitor friends
Evan Quan (1):
drm/amdgpu: disable MMHUB PG for Picasso
Fabio M. De Francesco (1):
net/smc: Use a mutex for locking "struct smc_pnettable"
Fabrice Gasnier (1):
usb: dwc2: drd: fix soft connect when gadget is unconfigured
Felix Maurer (2):
bpf: Do not try bpf_msg_push_data with len 0
selftests: bpf: Check bpf_msg_push_data return value
Florian Westphal (1):
netfilter: nf_tables: fix memory leak during stateful obj update
Gal Pressman (1):
net/mlx5e: Fix wrong return value on ioctl EEPROM query failure
Guenter Roeck (1):
hwmon: Handle failure to register sensor with thermal zone correctly
Guoqing Jiang (1):
RDMA/rtrs-clt: Kill wait_for_inflight_permits
Hans de Goede (2):
surface: surface3_power: Fix battery readings on batteries without a
serial number
usb: dwc3: pci: Fix Bay Trail phy GPIO mappings
Helge Deller (2):
parisc/unaligned: Fix fldd and fstd unaligned handlers on 32-bit
kernel
parisc/unaligned: Fix ldw() and stw() unalignment handlers
Hongyu Xie (1):
xhci: Prevent futile URB re-submissions due to incorrect return value.
Jason Gunthorpe (1):
RDMA/cma: Do not change route.addr.src_addr outside state checks
Jens Wiklander (2):
tee: export teedev_open() and teedev_close_context()
optee: use driver internal tee_context for some rpc
Liang Zhang (1):
KVM: x86/mmu: make apf token non-zero to fix bug
Lorenzo Bianconi (1):
iio: imu: st_lsm6dsx: wait for settling time in
st_lsm6dsx_read_oneshot
Manish Chopra (1):
bnx2x: fix driver load from initrd
Maor Gottlieb (1):
net/mlx5: Fix possible deadlock on rule deletion
Marc Zyngier (1):
gpio: tegra186: Fix chip_data type confusion
Maxime Ripard (1):
drm/edid: Always set RGB444
Md Haris Iqbal (1):
RDMA/rtrs-clt: Move free_permit from free_clt to rtrs_clt_close
Miaohe Lin (1):
memblock: use kfree() to release kmalloced memblock regions
Miaoqian Lin (1):
iio: Fix error handling for PM
Mårten Lindahl (1):
driver core: Free DMA range map when device is released
Oliver Neukum (2):
USB: zaurus: support another broken Zaurus
CDC-NCM: avoid overflow in sanity checking
Paul Blakey (2):
openvswitch: Fix setting ipv6 fields causing hw csum failure
net/sched: act_ct: Fix flow table lookup after ct clear or switching
zones
Phil Elwell (1):
sc16is7xx: Fix for incorrect data being transmitted
Prasad Kumpatla (1):
regmap-irq: Update interrupt clear register for proper reset
Puma Hsu (1):
xhci: re-initialize the HC during resume if HCE was set
Sebastian Andrzej Siewior (1):
usb: dwc3: gadget: Let the interrupt handler disable bottom halves.
Sergey Shtylyov (1):
ata: pata_hpt37x: disable primary channel on HPT371
Siarhei Volkau (1):
clk: jz4725b: fix mmc0 clock gating
Slark Xiao (1):
USB: serial: option: add support for DW5829e
Somnath Kotur (1):
bnxt_en: Fix active FEC reporting to ethtool
Stefano Garzarella (1):
vhost/vsock: don't check owner in vhost_vsock_stop() while releasing
Steven Rostedt (Google) (2):
tracing: Have traceon and traceoff trigger honor the instance
tracefs: Set the group ownership in apply_options() not
parse_options()
Su Yue (2):
btrfs: tree-checker: check item_size for inode_item
btrfs: tree-checker: check item_size for dev_item
Tao Liu (1):
gso: do not skip outer ip header in case of ipip and net_failover
Tariq Toukan (1):
net/mlx5e: kTLS, Use CHECKSUM_UNNECESSARY for device-offloaded packets
Ville Syrjälä (1):
drm/i915: Correctly populate use_sagv_wm for all pipes
Xiaoke Wang (1):
net: ll_temac: check the return value of devm_kmalloc()
Xin Long (1):
ping: remove pr_err from ping_lookup
Zhou Qingyang (1):
spi: spi-zynq-qspi: Fix a NULL pointer dereference in
zynq_qspi_exec_mem_op()
daniel.starke(a)siemens.com (5):
tty: n_gsm: fix encoding of control signal octet bit DV
tty: n_gsm: fix proper link termination after failed open
tty: n_gsm: fix NULL pointer access due to DLCI release
tty: n_gsm: fix wrong tty control line for flow control
tty: n_gsm: fix deadlock in gsmtty_open()
arch/parisc/kernel/unaligned.c | 14 ++---
arch/riscv/kernel/Makefile | 2 +
arch/riscv/kernel/entry.S | 10 ++--
arch/riscv/kernel/trace_irq.c | 27 ++++++++++
arch/riscv/kernel/trace_irq.h | 11 ++++
arch/x86/include/asm/fpu/internal.h | 13 +++--
arch/x86/kernel/process_32.c | 6 +--
arch/x86/kernel/process_64.c | 6 +--
arch/x86/kvm/mmu/mmu.c | 13 ++++-
drivers/ata/pata_hpt37x.c | 14 +++++
drivers/base/dd.c | 5 ++
drivers/base/regmap/regmap-irq.c | 20 +++----
drivers/clk/ingenic/jz4725b-cgu.c | 3 +-
drivers/gpio/gpio-tegra186.c | 14 +++--
drivers/gpu/drm/amd/amdgpu/soc15.c | 5 +-
drivers/gpu/drm/drm_edid.c | 2 +-
drivers/gpu/drm/i915/intel_pm.c | 22 ++++----
drivers/hwmon/hwmon.c | 14 ++---
drivers/iio/accel/bmc150-accel-core.c | 5 +-
drivers/iio/accel/kxcjk-1013.c | 5 +-
drivers/iio/accel/mma9551.c | 5 +-
drivers/iio/accel/mma9553.c | 5 +-
drivers/iio/adc/ad7124.c | 2 +-
drivers/iio/adc/men_z188_adc.c | 9 +++-
drivers/iio/gyro/bmg160_core.c | 5 +-
drivers/iio/imu/kmx61.c | 5 +-
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 6 ++-
drivers/iio/magnetometer/bmc150_magn.c | 5 +-
drivers/infiniband/core/cma.c | 40 ++++++++------
drivers/infiniband/ulp/rtrs/rtrs-clt.c | 19 +++----
drivers/infiniband/ulp/srp/ib_srp.c | 6 ++-
.../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 3 ++
.../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 3 ++
.../ethernet/mellanox/mlx5/core/en_ethtool.c | 2 +-
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 3 +-
.../mellanox/mlx5/core/eswitch_offloads.c | 4 --
.../net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +
.../netronome/nfp/flower/tunnel_conf.c | 4 +-
drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +
drivers/net/usb/cdc_ether.c | 12 +++++
drivers/net/usb/cdc_ncm.c | 8 +--
drivers/net/usb/zaurus.c | 12 +++++
drivers/platform/x86/surface3_power.c | 13 +++--
drivers/spi/spi-zynq-qspi.c | 3 ++
drivers/tee/optee/core.c | 8 +++
drivers/tee/optee/optee_private.h | 2 +
drivers/tee/optee/rpc.c | 8 +--
drivers/tee/tee_core.c | 6 ++-
.../intel/int340x_thermal/int3400_thermal.c | 4 ++
drivers/tty/n_gsm.c | 22 +++++---
drivers/tty/serial/sc16is7xx.c | 3 ++
drivers/usb/dwc2/core.h | 2 +
drivers/usb/dwc2/drd.c | 6 ++-
drivers/usb/dwc3/dwc3-pci.c | 4 +-
drivers/usb/dwc3/gadget.c | 2 +
drivers/usb/gadget/function/rndis.c | 8 +++
drivers/usb/gadget/function/rndis.h | 1 +
drivers/usb/host/xhci.c | 28 ++++++----
drivers/usb/serial/ch341.c | 1 -
drivers/usb/serial/option.c | 12 +++++
drivers/vhost/vsock.c | 21 +++++---
fs/btrfs/tree-checker.c | 15 ++++++
fs/io_uring.c | 1 +
fs/tracefs/inode.c | 5 +-
include/linux/tee_drv.h | 14 +++++
include/net/checksum.h | 48 +++++++++--------
kernel/bpf/syscall.c | 3 ++
kernel/trace/trace_events_trigger.c | 52 ++++++++++++++++---
mm/memblock.c | 10 +++-
net/core/filter.c | 3 ++
net/core/skbuff.c | 4 +-
net/ipv4/af_inet.c | 5 +-
net/ipv4/ping.c | 1 -
net/ipv4/udp_tunnel_nic.c | 2 +-
net/ipv6/ip6_offload.c | 2 +
net/netfilter/nf_tables_api.c | 13 +++--
net/openvswitch/actions.c | 46 +++++++++++++---
net/sched/act_ct.c | 5 --
net/smc/smc_pnet.c | 42 +++++++--------
net/smc/smc_pnet.h | 2 +-
net/tipc/name_table.c | 2 +-
net/tipc/socket.c | 2 +-
tools/perf/util/data.c | 7 ++-
.../selftests/bpf/progs/test_sockmap_kern.h | 26 +++++++---
84 files changed, 594 insertions(+), 243 deletions(-)
create mode 100644 arch/riscv/kernel/trace_irq.c
create mode 100644 arch/riscv/kernel/trace_irq.h
--
2.20.1
1
73

[PATCH openEuler-5.10 01/26] readahead: introduce FMODE_CTL_WILLNEED to read first 2MB of file
by Zheng Zengkai 23 May '22
by Zheng Zengkai 23 May '22
23 May '22
From: Yufen Yu <yuyufen(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I53R0H
CVE: NA
backport: openEuler-22.03-LTS
-------------------------------------------------
In some scenario, likely spark-sql, almost all meta file's size is
less then 2MB and applications read these smaller files in random
mode. That means, it may issue multiple times random io to rotate
disk, which can cause performance degradation.
To improve the small files random read, we try to read the first
2MB into pagecache on the first time of read. Then it can avoid
multiple random io.
In fact, applications can call fadvise system with POSIX_FADV_WILLNEED
to achieve this goal. But, some apps may cannot easily do that.
So, we provide a new file flag FMODE_CTL_WILLNEED.
Signed-off-by: Yufen Yu <yuyufen(a)huawei.com>
Reviewed-by: Hou Tao <houtao1(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
Conflicts:
include/linux/fs.h
Value '0x40000000' has been used for flag FMODE_BUF_RASYNC.
Signed-off-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/linux/fs.h | 7 +++++++
mm/readahead.c | 40 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index db632747781a..dd023a3023b5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -183,6 +183,12 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
/* File supports async buffered reads */
#define FMODE_BUF_RASYNC ((__force fmode_t)0x40000000)
+/* File mode control flag, expect random access pattern */
+#define FMODE_CTL_RANDOM ((__force fmode_t)0x1)
+
+/* File mode control flag, will try to read head of the file into pagecache */
+#define FMODE_CTL_WILLNEED ((__force fmode_t)0x2)
+
/*
* Attribute flags. These should be or-ed together to figure out what
* has been changed!
@@ -947,6 +953,7 @@ struct file {
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
+ fmode_t f_ctl_mode;
struct mutex f_pos_lock;
loff_t f_pos;
struct fown_struct f_owner;
diff --git a/mm/readahead.c b/mm/readahead.c
index c5b0457415be..ed23d5dec123 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -26,6 +26,7 @@
#include "internal.h"
+#define READAHEAD_FIRST_SIZE (2 * 1024 * 1024)
/*
* Initialise a struct file's readahead state. Assumes that the caller has
* memset *ra to zero.
@@ -549,10 +550,41 @@ static void ondemand_readahead(struct readahead_control *ractl,
do_page_cache_ra(ractl, ra->size, ra->async_size);
}
+/*
+ * Try to read first @ra_size from head of the file.
+ */
+static bool page_cache_readahead_from_head(struct address_space *mapping,
+ struct file *filp, pgoff_t offset,
+ unsigned long req_size,
+ unsigned long ra_size)
+{
+ struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
+ struct file_ra_state *ra = &filp->f_ra;
+ unsigned long size = min_t(unsigned long, ra_size,
+ file_inode(filp)->i_size);
+ unsigned long nrpages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+ unsigned long max_pages;
+ unsigned int offs = 0;
+
+ /* Cannot read date over target size, back to normal way */
+ if (offset + req_size > nrpages)
+ return false;
+
+ max_pages = max_t(unsigned long, bdi->io_pages, ra->ra_pages);
+ max_pages = min(max_pages, nrpages);
+ while (offs < nrpages) {
+ force_page_cache_readahead(mapping, filp, offs, max_pages);
+ offs += max_pages;
+ }
+ return true;
+}
+
void page_cache_sync_ra(struct readahead_control *ractl,
struct file_ra_state *ra, unsigned long req_count)
{
- bool do_forced_ra = ractl->file && (ractl->file->f_mode & FMODE_RANDOM);
+ bool do_forced_ra = ractl->file &&
+ ((ractl->file->f_mode & FMODE_RANDOM) ||
+ (ractl->file->f_ctl_mode & FMODE_CTL_RANDOM));
/*
* Even if read-ahead is disabled, issue this request as read-ahead
@@ -567,6 +599,12 @@ void page_cache_sync_ra(struct readahead_control *ractl,
do_forced_ra = true;
}
+ /* try to read first READAHEAD_FIRST_SIZE into pagecache */
+ if (ractl->file && (ractl->file->f_ctl_mode & FMODE_CTL_WILLNEED) &&
+ page_cache_readahead_from_head(ractl->mapping, ractl->file,
+ ractl->_index, req_count, READAHEAD_FIRST_SIZE))
+ return;
+
/* be dumb */
if (do_forced_ra) {
force_page_cache_ra(ractl, ra, req_count);
--
2.20.1
1
25
lockdep: Correct lock_classes index mapping
i2c: brcmstb: fix support for DSL and CM variants
copy_process(): Move fd_install() out of sighand->siglock critical section
i2c: qcom-cci: don't put a device tree node before i2c_add_adapter()
i2c: qcom-cci: don't delete an unregistered adapter
dmaengine: sh: rcar-dmac: Check for error num after dma_set_max_seg_size
dmaengine: stm32-dmamux: Fix PM disable depth imbalance in stm32_dmamux_probe
dmaengine: sh: rcar-dmac: Check for error num after setting mask
net: sched: limit TC_ACT_REPEAT loops
EDAC: Fix calculation of returned address and next offset in edac_align_ptr()
scsi: lpfc: Fix pt2pt NVMe PRLI reject LOGO loop
kconfig: fix failing to generate auto.conf
net: macb: Align the dma and coherent dma masks
net: usb: qmi_wwan: Add support for Dell DW5829e
tracing: Fix tp_printk option related with tp_printk_stop_on_boot
drm/rockchip: dw_hdmi: Do not leave clock enabled in error case
xprtrdma: fix pointer derefs in error cases of rpcrdma_ep_create
soc: aspeed: lpc-ctrl: Block error printing on probe defer cases
ata: libata-core: Disable TRIM on M88V29
kconfig: let 'shell' return enough output for deep path names
selftests: fixup build warnings in pidfd / clone3 tests
pidfd: fix test failure due to stack overflow on some arches
arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610
arm64: dts: meson-g12: add ATF BL32 reserved-memory region
arm64: dts: meson-gx: add ATF BL32 reserved-memory region
netfilter: conntrack: don't refresh sctp entries in closed state
irqchip/sifive-plic: Add missing thead,c900-plic match string
phy: usb: Leave some clocks running during suspend
ARM: OMAP2+: adjust the location of put_device() call in omapdss_init_of
ARM: OMAP2+: hwmod: Add of_node_put() before break
NFS: Don't set NFS_INO_INVALID_XATTR if there is no xattr cache
KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW
KVM: x86/pmu: Don't truncate the PerfEvtSeln MSR when creating a perf event
KVM: x86/pmu: Refactoring find_arch_event() to pmc_perf_hw_id()
Drivers: hv: vmbus: Fix memory leak in vmbus_add_channel_kobj
mtd: rawnand: brcmnand: Fixed incorrect sub-page ECC status
mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe()
tty: n_tty: do not look ahead for EOL character past the end of the buffer
NFS: Do not report writeback errors in nfs_getattr()
block/wbt: fix negative inflight counter when remove scsi device
ASoC: tas2770: Insert post reset delay
KVM: SVM: Never reject emulation due to SMAP errata for !SEV guests
mtd: rawnand: gpmi: don't leak PM reference in error path
powerpc/lib/sstep: fix 'ptesync' build error
ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw_range()
ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw()
ALSA: hda: Fix missing codec probe on Shenker Dock 15
ALSA: hda: Fix regression on forced probe mask option
ALSA: hda/realtek: Fix deadlock by COEF mutex
ALSA: hda/realtek: Add quirk for Legion Y9000X 2019
selftests/exec: Add non-regular to TEST_GEN_PROGS
perf bpf: Defer freeing string after possible strlen() on it
dpaa2-eth: Initialize mutex used in one step timestamping path
libsubcmd: Fix use-after-free for realloc(..., 0)
bonding: fix data-races around agg_select_timer
net_sched: add __rcu annotation to netdev->qdisc
drop_monitor: fix data-race in dropmon_net_event / trace_napi_poll_hit
ping: fix the dif and sdif check in ping_lookup
net: ieee802154: ca8210: Fix lifs/sifs periods
net: dsa: lantiq_gswip: fix use after free in gswip_remove()
net: dsa: lan9303: fix reset on probe
ipv6: per-netns exclusive flowlabel checks
netfilter: nft_synproxy: unregister hooks on init error path
selftests: netfilter: fix exit value for nft_concat_range
iwlwifi: pcie: gen2: fix locking when "HW not ready"
iwlwifi: pcie: fix locking when "HW not ready"
drm/i915/gvt: Make DRM_I915_GVT depend on X86
vsock: remove vsock from connected table when connect is interrupted by a signal
drm/i915/opregion: check port number bounds for SWSCI display power state
drm/radeon: Fix backlight control on iMac 12,1
iwlwifi: fix use-after-free
kbuild: lto: Merge module sections if and only if CONFIG_LTO_CLANG is enabled
kbuild: lto: merge module sections
random: wake up /dev/random writers after zap
gcc-plugins/stackleak: Use noinstr in favor of notrace
Revert "module, async: async_synchronize_full() on module init iff async is
used"
x86/Xen: streamline (and fix) PV CPU enumeration
drm/amdgpu: fix logic inversion in check
nvme-rdma: fix possible use-after-free in transport error_recovery work
nvme-tcp: fix possible use-after-free in transport error_recovery work
nvme: fix a possible use-after-free in controller reset during load
scsi: pm8001: Fix use-after-free for aborted SSP/STP sas_task
scsi: pm8001: Fix use-after-free for aborted TMF sas_task
quota: make dquot_quota_sync return errors from ->sync_fs
vfs: make freeze_super abort when sync_filesystem returns error
selftests: skip mincore.check_file_mmap when fs lacks needed support
selftests: openat2: Skip testcases that fail with EOPNOTSUPP
selftests: openat2: Add missing dependency in Makefile
selftests: openat2: Print also errno in failure messages
selftests/zram: Adapt the situation that /dev/zram0 is being used
selftests/zram01.sh: Fix compression ratio calculation
selftests/zram: Skip max_comp_streams interface on newer kernel
net: ieee802154: at86rf230: Stop leaking skb's
kselftest: signal all child processes
selftests: rtc: Increase test timeout so that all tests run
platform/x86: ISST: Fix possible circular locking dependency detected
platform/x86: touchscreen_dmi: Add info for the RWC NANOTE P8 AY07J 2-in-1
btrfs: send: in case of IO error log it
parisc: Add ioread64_lo_hi() and iowrite64_lo_hi()
PCI: hv: Fix NUMA node assignment when kernel boots with custom NUMA topology
mm: don't try to NUMA-migrate COW pages that have other uses
mmc: block: fix read single on recovery logic
parisc: Fix sglist access in ccio-dma.c
parisc: Fix data TLB miss in sba_unmap_sg
parisc: Drop __init from map_pages declaration
serial: parisc: GSC: fix build when IOSAPIC is not set
Revert "svm: Add warning message for AVIC IPI invalid target"
HID:Add support for UGTABLET WP5540
scsi: lpfc: Fix mailbox command failure during driver initialization
can: isotp: add SF_BROADCAST support for functional addressing
can: isotp: prevent race between isotp_bind() and isotp_setsockopt()
fs/proc: task_mmu.c: don't read mapcount for migration entry
mm: memcg: synchronize objcg lists with a dedicated spinlock
drm/nouveau/pmu/gm200-: use alternate falcon reset sequence
already merged
rcu: Do not report strict GPs for outgoing CPUs
ax25: improve the incomplete fix to avoid UAF and NPD bugs
bonding: force carrier update when releasing slave
NFS: LOOKUP_DIRECTORY is also ok with symlinks
lib/iov_iter: initialize "flags" in new pipe_buffer
fget: clarify and improve __fget_files() implementation
deferred (kabi changes)
ipv6: per-netns exclusive flowlabel checks
Total patches: 120 - 6 - 1 = 113
Al Cooper (1):
phy: usb: Leave some clocks running during suspend
Alexey Khoroshilov (1):
net: dsa: lantiq_gswip: fix use after free in gswip_remove()
Anders Roxell (1):
powerpc/lib/sstep: fix 'ptesync' build error
Andy Shevchenko (1):
parisc: Add ioread64_lo_hi() and iowrite64_lo_hi()
Arnaldo Carvalho de Melo (1):
perf bpf: Defer freeing string after possible strlen() on it
Axel Rasmussen (2):
pidfd: fix test failure due to stack overflow on some arches
selftests: fixup build warnings in pidfd / clone3 tests
Ben Skeggs (1):
drm/nouveau/pmu/gm200-: use alternate falcon reset sequence
Brenda Streiff (1):
kconfig: let 'shell' return enough output for deep path names
Bryan O'Donoghue (1):
mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe()
Cheng Jui Wang (1):
lockdep: Correct lock_classes index mapping
Christian Eggers (1):
mtd: rawnand: gpmi: don't leak PM reference in error path
Christian Hewitt (3):
arm64: dts: meson-gx: add ATF BL32 reserved-memory region
arm64: dts: meson-g12: add ATF BL32 reserved-memory region
arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610
Christian König (1):
drm/amdgpu: fix logic inversion in check
Christian Löhle (1):
mmc: block: fix read single on recovery logic
Cristian Marussi (4):
selftests: openat2: Print also errno in failure messages
selftests: openat2: Add missing dependency in Makefile
selftests: openat2: Skip testcases that fail with EOPNOTSUPP
selftests: skip mincore.check_file_mmap when fs lacks needed support
Dan Aloni (1):
xprtrdma: fix pointer derefs in error cases of rpcrdma_ep_create
Darrick J. Wong (2):
vfs: make freeze_super abort when sync_filesystem returns error
quota: make dquot_quota_sync return errors from ->sync_fs
Dāvis Mosāns (1):
btrfs: send: in case of IO error log it
Eliav Farber (1):
EDAC: Fix calculation of returned address and next offset in
edac_align_ptr()
Eric Dumazet (4):
drop_monitor: fix data-race in dropmon_net_event / trace_napi_poll_hit
net_sched: add __rcu annotation to netdev->qdisc
bonding: fix data-races around agg_select_timer
net: sched: limit TC_ACT_REPEAT loops
Florian Westphal (1):
netfilter: conntrack: don't refresh sctp entries in closed state
Guo Ren (1):
irqchip/sifive-plic: Add missing thead,c900-plic match string
Hangbin Liu (1):
selftests: netfilter: fix exit value for nft_concat_range
Igor Pylypiv (1):
Revert "module, async: async_synchronize_full() on module init iff
async is used"
Jae Hyun Yoo (1):
soc: aspeed: lpc-ctrl: Block error printing on probe defer cases
JaeSang Yoo (1):
tracing: Fix tp_printk option related with tp_printk_stop_on_boot
James Smart (2):
scsi: lpfc: Fix mailbox command failure during driver initialization
scsi: lpfc: Fix pt2pt NVMe PRLI reject LOGO loop
Jan Beulich (1):
x86/Xen: streamline (and fix) PV CPU enumeration
Jani Nikula (1):
drm/i915/opregion: check port number bounds for SWSCI display power
state
Jason A. Donenfeld (1):
random: wake up /dev/random writers after zap
Jiasheng Jiang (2):
dmaengine: sh: rcar-dmac: Check for error num after setting mask
dmaengine: sh: rcar-dmac: Check for error num after
dma_set_max_seg_size
Jim Mattson (2):
KVM: x86/pmu: Don't truncate the PerfEvtSeln MSR when creating a perf
event
KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW
Jing Leng (1):
kconfig: fix failing to generate auto.conf
Johannes Berg (3):
iwlwifi: fix use-after-free
iwlwifi: pcie: fix locking when "HW not ready"
iwlwifi: pcie: gen2: fix locking when "HW not ready"
John David Anglin (3):
parisc: Drop __init from map_pages declaration
parisc: Fix data TLB miss in sba_unmap_sg
parisc: Fix sglist access in ccio-dma.c
John Garry (2):
scsi: pm8001: Fix use-after-free for aborted TMF sas_task
scsi: pm8001: Fix use-after-free for aborted SSP/STP sas_task
Kees Cook (2):
gcc-plugins/stackleak: Use noinstr in favor of notrace
libsubcmd: Fix use-after-free for realloc(..., 0)
Laibin Qiu (1):
block/wbt: fix negative inflight counter when remove scsi device
Li Zhijian (1):
kselftest: signal all child processes
Like Xu (1):
KVM: x86/pmu: Refactoring find_arch_event() to pmc_perf_hw_id()
Linus Torvalds (2):
mm: don't try to NUMA-migrate COW pages that have other uses
tty: n_tty: do not look ahead for EOL character past the end of the
buffer
Long Li (1):
PCI: hv: Fix NUMA node assignment when kernel boots with custom NUMA
topology
Mans Rullgard (1):
net: dsa: lan9303: fix reset on probe
Marc St-Amand (1):
net: macb: Align the dma and coherent dma masks
Mark Brown (2):
ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw()
ASoC: ops: Fix stereo change notifications in
snd_soc_put_volsw_range()
Martin Povišer (1):
ASoC: tas2770: Insert post reset delay
Miaoqian Lin (2):
Drivers: hv: vmbus: Fix memory leak in vmbus_add_channel_kobj
dmaengine: stm32-dmamux: Fix PM disable depth imbalance in
stm32_dmamux_probe
Miquel Raynal (2):
net: ieee802154: at86rf230: Stop leaking skb's
net: ieee802154: ca8210: Fix lifs/sifs periods
Muhammad Usama Anjum (1):
selftests/exec: Add non-regular to TEST_GEN_PROGS
Nicholas Bishop (1):
drm/radeon: Fix backlight control on iMac 12,1
Norbert Slusarek (1):
can: isotp: prevent race between isotp_bind() and isotp_setsockopt()
Nícolas F. R. A. Prado (1):
selftests: rtc: Increase test timeout so that all tests run
Oliver Hartkopp (1):
can: isotp: add SF_BROADCAST support for functional addressing
Pablo Neira Ayuso (1):
netfilter: nft_synproxy: unregister hooks on init error path
Radu Bulie (1):
dpaa2-eth: Initialize mutex used in one step timestamping path
Rafał Miłecki (1):
i2c: brcmstb: fix support for DSL and CM variants
Randy Dunlap (1):
serial: parisc: GSC: fix build when IOSAPIC is not set
Roman Gushchin (1):
mm: memcg: synchronize objcg lists with a dedicated spinlock
Sagi Grimberg (3):
nvme: fix a possible use-after-free in controller reset during load
nvme-tcp: fix possible use-after-free in transport error_recovery work
nvme-rdma: fix possible use-after-free in transport error_recovery
work
Sami Tolvanen (1):
kbuild: lto: merge module sections
Sascha Hauer (1):
drm/rockchip: dw_hdmi: Do not leave clock enabled in error case
Sean Christopherson (3):
Revert "svm: Add warning message for AVIC IPI invalid target"
kbuild: lto: Merge module sections if and only if CONFIG_LTO_CLANG is
enabled
KVM: SVM: Never reject emulation due to SMAP errata for !SEV guests
Sergio Costas (1):
HID:Add support for UGTABLET WP5540
Seth Forshee (1):
vsock: remove vsock from connected table when connect is interrupted
by a signal
Siva Mullati (1):
drm/i915/gvt: Make DRM_I915_GVT depend on X86
Slark Xiao (1):
net: usb: qmi_wwan: Add support for Dell DW5829e
Srinivas Pandruvada (1):
platform/x86: ISST: Fix possible circular locking dependency detected
Takashi Iwai (3):
ALSA: hda/realtek: Fix deadlock by COEF mutex
ALSA: hda: Fix regression on forced probe mask option
ALSA: hda: Fix missing codec probe on Shenker Dock 15
Trond Myklebust (2):
NFS: Do not report writeback errors in nfs_getattr()
NFS: Don't set NFS_INO_INVALID_XATTR if there is no xattr cache
Vladimir Zapolskiy (2):
i2c: qcom-cci: don't delete an unregistered adapter
i2c: qcom-cci: don't put a device tree node before i2c_add_adapter()
Waiman Long (1):
copy_process(): Move fd_install() out of sighand->siglock critical
section
Wan Jiabing (1):
ARM: OMAP2+: hwmod: Add of_node_put() before break
Xin Long (1):
ping: fix the dif and sdif check in ping_lookup
Yang Shi (1):
fs/proc: task_mmu.c: don't read mapcount for migration entry
Yang Xu (3):
selftests/zram: Skip max_comp_streams interface on newer kernel
selftests/zram01.sh: Fix compression ratio calculation
selftests/zram: Adapt the situation that /dev/zram0 is being used
Ye Guojin (1):
ARM: OMAP2+: adjust the location of put_device() call in
omapdss_init_of
Yu Huang (1):
ALSA: hda/realtek: Add quirk for Legion Y9000X 2019
Yuka Kawajiri (1):
platform/x86: touchscreen_dmi: Add info for the RWC NANOTE P8 AY07J
2-in-1
Zoltán Böszörményi (1):
ata: libata-core: Disable TRIM on M88V29
david regan (1):
mtd: rawnand: brcmnand: Fixed incorrect sub-page ECC status
arch/arm/mach-omap2/display.c | 2 +-
arch/arm/mach-omap2/omap_hwmod.c | 4 +-
.../boot/dts/amlogic/meson-g12-common.dtsi | 6 +
.../boot/dts/amlogic/meson-g12a-sei510.dts | 8 --
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 +
.../boot/dts/amlogic/meson-sm1-sei610.dts | 8 --
arch/parisc/lib/iomap.c | 18 +++
arch/parisc/mm/init.c | 9 +-
arch/powerpc/lib/sstep.c | 2 +
arch/x86/kvm/pmu.c | 15 +-
arch/x86/kvm/pmu.h | 3 +-
arch/x86/kvm/svm/avic.c | 2 -
arch/x86/kvm/svm/pmu.c | 8 +-
arch/x86/kvm/svm/svm.c | 7 +-
arch/x86/kvm/vmx/pmu_intel.c | 9 +-
arch/x86/xen/enlighten_pv.c | 4 -
arch/x86/xen/smp_pv.c | 26 +---
block/bfq-iosched.c | 2 +
drivers/ata/libata-core.c | 1 +
drivers/char/random.c | 5 +-
drivers/dma/sh/rcar-dmac.c | 9 +-
drivers/dma/stm32-dmamux.c | 4 +-
drivers/edac/edac_mc.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +-
drivers/gpu/drm/i915/Kconfig | 1 +
drivers/gpu/drm/i915/display/intel_opregion.c | 15 ++
drivers/gpu/drm/nouveau/nvkm/falcon/base.c | 8 +-
.../gpu/drm/nouveau/nvkm/subdev/pmu/gm200.c | 31 +++-
.../gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c | 2 +-
.../gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c | 2 +-
.../gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c | 2 +-
.../gpu/drm/nouveau/nvkm/subdev/pmu/priv.h | 2 +
drivers/gpu/drm/radeon/atombios_encoders.c | 3 +-
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 14 +-
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-quirks.c | 1 +
drivers/hv/vmbus_drv.c | 5 +-
drivers/i2c/busses/i2c-brcmstb.c | 2 +-
drivers/i2c/busses/i2c-qcom-cci.c | 16 ++-
drivers/irqchip/irq-sifive-plic.c | 1 +
drivers/mmc/core/block.c | 28 ++--
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +-
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 3 +-
drivers/mtd/nand/raw/qcom_nandc.c | 14 +-
drivers/net/bonding/bond_3ad.c | 30 +++-
drivers/net/dsa/lan9303-core.c | 2 +-
drivers/net/dsa/lantiq_gswip.c | 2 +-
drivers/net/ethernet/cadence/macb_main.c | 2 +-
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +-
drivers/net/ieee802154/at86rf230.c | 13 +-
drivers/net/ieee802154/ca8210.c | 4 +-
drivers/net/usb/qmi_wwan.c | 2 +
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 2 +
.../wireless/intel/iwlwifi/pcie/trans-gen2.c | 3 +-
.../net/wireless/intel/iwlwifi/pcie/trans.c | 3 +-
drivers/nvme/host/core.c | 9 +-
drivers/nvme/host/rdma.c | 1 +
drivers/nvme/host/tcp.c | 1 +
drivers/parisc/ccio-dma.c | 3 +-
drivers/parisc/sba_iommu.c | 3 +-
drivers/pci/controller/pci-hyperv.c | 13 +-
drivers/phy/broadcom/phy-brcm-usb.c | 38 +++++
.../intel_speed_select_if/isst_if_common.c | 97 ++++++++-----
drivers/platform/x86/touchscreen_dmi.c | 24 ++++
drivers/scsi/lpfc/lpfc.h | 1 +
drivers/scsi/lpfc/lpfc_attr.c | 3 +
drivers/scsi/lpfc/lpfc_els.c | 20 ++-
drivers/scsi/lpfc/lpfc_nportdisc.c | 5 +-
drivers/scsi/lpfc/lpfc_sli.c | 15 +-
drivers/scsi/pm8001/pm8001_sas.c | 5 +
drivers/scsi/pm8001/pm80xx_hwi.c | 4 +-
drivers/soc/aspeed/aspeed-lpc-ctrl.c | 7 +-
drivers/tty/n_tty.c | 6 +-
drivers/tty/serial/8250/8250_gsc.c | 2 +-
fs/btrfs/send.c | 4 +
fs/nfs/inode.c | 23 ++-
fs/proc/task_mmu.c | 43 ++++--
fs/quota/dquot.c | 11 +-
fs/super.c | 19 ++-
include/linux/memcontrol.h | 5 +-
include/linux/netdevice.h | 2 +-
include/linux/sched.h | 1 -
include/net/bond_3ad.h | 2 +-
include/uapi/linux/can/isotp.h | 2 +-
kernel/async.c | 3 -
kernel/fork.c | 7 +-
kernel/locking/lockdep.c | 4 +-
kernel/module.c | 25 +---
kernel/stackleak.c | 5 +-
kernel/trace/trace.c | 4 +
mm/memcontrol.c | 10 +-
mm/mprotect.c | 2 +-
net/can/isotp.c | 71 +++++++---
net/core/drop_monitor.c | 11 +-
net/core/rtnetlink.c | 6 +-
net/ipv4/ping.c | 11 +-
net/netfilter/nf_conntrack_proto_sctp.c | 9 ++
net/netfilter/nft_synproxy.c | 4 +-
net/sched/act_api.c | 13 +-
net/sched/cls_api.c | 6 +-
net/sched/sch_api.c | 22 +--
net/sched/sch_generic.c | 29 ++--
net/sunrpc/xprtrdma/verbs.c | 3 +
net/vmw_vsock/af_vsock.c | 1 +
scripts/kconfig/confdata.c | 13 +-
scripts/kconfig/preprocess.c | 2 +-
scripts/module.lds.S | 26 ++++
sound/pci/hda/hda_intel.c | 5 +-
sound/pci/hda/patch_realtek.c | 40 ++++--
sound/soc/codecs/tas2770.c | 7 +-
sound/soc/soc-ops.c | 29 ++--
tools/lib/subcmd/subcmd-util.h | 11 +-
tools/perf/util/bpf-loader.c | 3 +-
tools/testing/selftests/clone3/clone3.c | 2 -
tools/testing/selftests/exec/Makefile | 4 +-
tools/testing/selftests/kselftest_harness.h | 4 +-
.../selftests/mincore/mincore_selftest.c | 20 ++-
.../selftests/netfilter/nft_concat_range.sh | 2 +-
tools/testing/selftests/openat2/Makefile | 2 +-
tools/testing/selftests/openat2/helpers.h | 12 +-
.../testing/selftests/openat2/openat2_test.c | 12 +-
tools/testing/selftests/pidfd/pidfd.h | 13 +-
.../selftests/pidfd/pidfd_fdinfo_test.c | 22 ++-
tools/testing/selftests/pidfd/pidfd_test.c | 6 +-
tools/testing/selftests/pidfd/pidfd_wait.c | 5 +-
tools/testing/selftests/rtc/settings | 2 +-
tools/testing/selftests/zram/zram.sh | 15 +-
tools/testing/selftests/zram/zram01.sh | 33 ++---
tools/testing/selftests/zram/zram02.sh | 1 -
tools/testing/selftests/zram/zram_lib.sh | 134 ++++++++++++------
130 files changed, 941 insertions(+), 479 deletions(-)
--
2.20.1
1
113

21 May '22
From: Wang Yufen <wangyufen(a)huawei.com>
mainline inclusion
from mainline-v5.13-rc1
commit 37f0e514db660f03f8982b8f4fbbd4b2740abe7d
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I545NW
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Currently we purge the ingress_skb queue only when psock
refcnt goes down to 0, so locking the queue is not necessary,
but in order to be called during ->close, we have to lock it
here.
Signed-off-by: Cong Wang <cong.wang(a)bytedance.com>
Signed-off-by: Alexei Starovoitov <ast(a)kernel.org>
Acked-by: Jakub Sitnicki <jakub(a)cloudflare.com>
Acked-by: John Fastabend <john.fastabend(a)gmail.com>
Link: https://lore.kernel.org/bpf/20210331023237.41094-2-xiyou.wangcong@gmail.com
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Reviewed-by: Liu Jian <liujian56(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
net/core/skmsg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 4ee4fe436847..f80428cc7264 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -638,7 +638,7 @@ void __sk_psock_purge_ingress_msg(struct sk_psock *psock)
static void sk_psock_zap_ingress(struct sk_psock *psock)
{
- __skb_queue_purge(&psock->ingress_skb);
+ skb_queue_purge(&psock->ingress_skb);
__sk_psock_purge_ingress_msg(psock);
}
--
2.20.1
1
38

20 May '22
Backport sw64 enhancement and bugfix patches.
Cui Mingrui (2):
sw64: optimize ip checksum calculation
sw64: fix ip checksum calculation
Du Yilong (3):
sw64: kvm: fix bug when open file with the O_DIRECT flag
sw64: add set time support for hypervisor based rtc
sw64: kvm: remap pages of guest by vm_insert_page()
Gu Zitao (7):
config: add initial openeuler_defconfig for sw64
sw64: fix coding style problems
sw64: fix the VDSO symbol generation for nm
sw64: fix SPDX license identifier in uapi headers
sw64: add SO_RCVTIMEO/ SO_SNDTIMEO socket options
sw64: remove unnecessary include headers
sw64: fix some compile errors
He Chuyue (2):
sw64: add regs and stack access APIs to support kprobe events
sw64: remove unnecessary parameter in REG_OFFSET_NAME
He Sheng (20):
sw64: clean up useless #if 0 and #if 1
sw64: switch GUP to the generic get_user_pages_fast() implementation
sw64: remove unused a.out.h
sw64: fix ex_table entries from misalignment handlers
sw64: define NR_SYSCALLS as generated __NR_syscalls
sw64: clean up a.out and ECOFF binary related headers
sw64: ptrace: clean up debug codes
sw64: add kbuild defconfig rule
sw64: clean up out-of-date selected options
sw64: Kconfig: remove dependence on !PREEMPT
sw64: Kconfig: remove dependence on ARCH_SUPPORTS_ACPI
sw64: add missing global __constant_c_memset
sw64: do some cleanups for rt_sigframe
sw64: fix setup_rt_frame for non SA_SIGINFO
sw64: fix compile error for DISCONTIGMEM=y
sw64: force signal and fault for traps and debugging
sw64: push and pop kernel stack with ldi instruction
sw64: signal: save/restore fpregs with copy user
sw64: fix the number of aux entries in ARCH_DLINFO
sw64: fix sendfile system call
Lu Feifei (6):
sw64: fix printk method for guest os
sw64: unify access to LONGTIME for guest and emulator
sw64: kvm: handle ldl_u and stl_u when exit mmio
sw64: kvm: simplify the code
sw64: pci: align the address of mmio resource to PAGE_SIZE
sw64: unify 32-bit MEMIO address of host and guest
Mao Minkai (29):
sw64: vdso: add automatic syscall fallback
sw64: vdso: change vdso version
sw64: vdso: fix time calculation
sw64: mm: reorder memblock_init process
sw64: mm: warn overlapped memmap and DMA region
sw64: mm: use memblock to find the end of memory
sw64: print correct initrd address
sw64: remove redundant Kconfig source
sw64: modify tc_sched_clock debugfs file
sw64: simplify cpumask_of_node
sw64: remove CONFIG_USE_PERCPU_NUMA_NODE_ID=n code
sw64: fix all compile warnings
sw64: numa: switch to arch node_distance
sw64: mm: mark pci and memmap region as nomap
sw64: use jump label for running modes
sw64: remove MAX_ASN
sw64: kvm: remove MAX_VPN
sw64: fix coding style problems
sw64: rename kvm_mem variables
sw64: reformat syscall.tbl
sw64: add missing pkey syscall numbers
sw64: add clone3 syscall support
sw64: add required include headers to ptrace.h
sw64: switch to old-style semctl/shmctl syscalls
sw64: increase position index in c_next for cpuinfo
sw64: add old sigprocmask back for compatibility
sw64: vdso: fix backtrace of vrt_sigreturn
sw64: vdso: fix CFI directives for fpregs in vrt_sigreturn
sw64: optimize simd version of memcpy and memset
Min Fanlei (4):
sw64: fix the value of QEMU_PRINTF_BUFF_BASE
sw64: add support for emulator running mode
sw64: enable more than 32 CPUs for guest
sw64: kvm: fix bad page state setting outside of kvm memory pool
Tang Jinyang (2):
sw64: add dynamic frequency scaling support
sw64: add dynamic turning on/off cores support
Wang Yingying (3):
hwmon: add voltage sensor support for sw64
sw64: add pvt device to chip3.dts
hwmon: add support for sw64 temperature sensor
Xu Chenjiao (2):
sw64: radeon: add a force flush to delay work when radeon uvd suspend
sw64: pcie: enable PME and AER support
Zhao Yihan (1):
sw64: remap PA with |= in early_ioremap
Zheng Chongzhen (3):
sw64: re-implement sw64_dma_direct_ops according upstream
sw64: iommu: fix 32-bit devices dma ops
sw64: fix compile error for CONFIG_PCI=n
Zhou Xuemei (5):
sw64: pci: remove some useless code
sw64: switch to generic pcibios_set_master and pci_common_swizzle
sw64: clean up some useless codes
sw64: dts: rename spi flash partition to fix warning
sw64: add ARCH_HAS_PTE_SPECIAL support
Zhu Donghong (1):
ipmi: add ipmi driver support
arch/sw_64/Kconfig | 325 +-
arch/sw_64/Makefile | 1 +
arch/sw_64/boot/dts/chip3.dts | 41 +-
arch/sw_64/chip/chip3/chip.c | 130 +-
arch/sw_64/chip/chip3/cpufreq_debugfs.c | 7 +-
arch/sw_64/chip/chip3/i2c-lib.c | 4 -
arch/sw_64/chip/chip3/irq_chip.c | 13 +-
arch/sw_64/chip/chip3/msi.c | 7 +-
arch/sw_64/chip/chip3/pci-quirks.c | 7 +-
arch/sw_64/chip/chip3/vt_msi.c | 6 -
arch/sw_64/configs/openeuler_defconfig | 4312 +++++++++++++++++++++
arch/sw_64/defconfig | 73 -
arch/sw_64/include/asm/Kbuild | 1 +
arch/sw_64/include/asm/a.out-core.h | 80 -
arch/sw_64/include/asm/a.out.h | 16 -
arch/sw_64/include/asm/checksum.h | 58 +-
arch/sw_64/include/asm/chip3_io.h | 4 +-
arch/sw_64/include/asm/clock.h | 56 +
arch/sw_64/include/asm/cputime.h | 4 +-
arch/sw_64/include/asm/early_ioremap.h | 2 +-
arch/sw_64/include/asm/hw_init.h | 29 +-
arch/sw_64/include/asm/kvm_host.h | 3 +-
arch/sw_64/include/asm/mmu_context.h | 3 +-
arch/sw_64/include/asm/numa.h | 1 +
arch/sw_64/include/asm/pci.h | 24 +-
arch/sw_64/include/asm/pgtable.h | 26 +-
arch/sw_64/include/asm/ptrace.h | 8 +-
arch/sw_64/include/asm/topology.h | 29 +-
arch/sw_64/include/asm/unistd.h | 3 +-
arch/sw_64/include/asm/user.h | 53 -
arch/sw_64/include/asm/vdso.h | 4 +-
arch/sw_64/include/asm/vga.h | 18 +-
arch/sw_64/include/uapi/asm/a.out.h | 88 -
arch/sw_64/include/uapi/asm/auxvec.h | 25 +-
arch/sw_64/include/uapi/asm/bitsperlong.h | 2 +-
arch/sw_64/include/uapi/asm/byteorder.h | 2 +-
arch/sw_64/include/uapi/asm/compiler.h | 2 +-
arch/sw_64/include/uapi/asm/console.h | 2 +-
arch/sw_64/include/uapi/asm/errno.h | 2 +-
arch/sw_64/include/uapi/asm/fcntl.h | 2 +-
arch/sw_64/include/uapi/asm/fpu.h | 2 +-
arch/sw_64/include/uapi/asm/gentrap.h | 2 +-
arch/sw_64/include/uapi/asm/hmcall.h | 2 +-
arch/sw_64/include/uapi/asm/ioctl.h | 2 +-
arch/sw_64/include/uapi/asm/ioctls.h | 48 +-
arch/sw_64/include/uapi/asm/ipcbuf.h | 2 +-
arch/sw_64/include/uapi/asm/kvm.h | 14 +-
arch/sw_64/include/uapi/asm/kvm_para.h | 2 +-
arch/sw_64/include/uapi/asm/mman.h | 2 +-
arch/sw_64/include/uapi/asm/msgbuf.h | 2 +-
arch/sw_64/include/uapi/asm/param.h | 2 +-
arch/sw_64/include/uapi/asm/poll.h | 2 +-
arch/sw_64/include/uapi/asm/posix_types.h | 2 +-
arch/sw_64/include/uapi/asm/ptrace.h | 2 +-
arch/sw_64/include/uapi/asm/reg.h | 2 +-
arch/sw_64/include/uapi/asm/regdef.h | 2 +-
arch/sw_64/include/uapi/asm/resource.h | 2 +-
arch/sw_64/include/uapi/asm/sembuf.h | 2 +-
arch/sw_64/include/uapi/asm/setup.h | 2 +-
arch/sw_64/include/uapi/asm/shmbuf.h | 2 +-
arch/sw_64/include/uapi/asm/sigcontext.h | 2 +-
arch/sw_64/include/uapi/asm/siginfo.h | 2 +-
arch/sw_64/include/uapi/asm/signal.h | 2 +-
arch/sw_64/include/uapi/asm/socket.h | 34 +-
arch/sw_64/include/uapi/asm/sockios.h | 2 +-
arch/sw_64/include/uapi/asm/stat.h | 2 +-
arch/sw_64/include/uapi/asm/statfs.h | 2 +-
arch/sw_64/include/uapi/asm/swab.h | 2 +-
arch/sw_64/include/uapi/asm/sysinfo.h | 2 +-
arch/sw_64/include/uapi/asm/termbits.h | 2 +-
arch/sw_64/include/uapi/asm/termios.h | 2 +-
arch/sw_64/include/uapi/asm/types.h | 2 +-
arch/sw_64/include/uapi/asm/unistd.h | 7 +-
arch/sw_64/kernel/Makefile | 5 +-
arch/sw_64/kernel/acpi.c | 19 +-
arch/sw_64/kernel/asm-offsets.c | 7 +-
arch/sw_64/kernel/audit.c | 2 +-
arch/sw_64/kernel/cacheinfo.c | 3 +-
arch/sw_64/kernel/clock.c | 184 +
arch/sw_64/kernel/core.c | 41 +-
arch/sw_64/kernel/cpuautoplug.c | 496 +++
arch/sw_64/kernel/crash_dump.c | 2 -
arch/sw_64/kernel/dup_print.c | 10 +-
arch/sw_64/kernel/early_printk.c | 4 +-
arch/sw_64/kernel/entry.S | 5 +-
arch/sw_64/kernel/ftrace.c | 5 -
arch/sw_64/kernel/insn.c | 13 -
arch/sw_64/kernel/irq.c | 15 -
arch/sw_64/kernel/irq_sw64.c | 9 +-
arch/sw_64/kernel/jump_label.c | 3 +-
arch/sw_64/kernel/kgdb.c | 9 +-
arch/sw_64/kernel/kprobes/decode-insn.c | 6 +-
arch/sw_64/kernel/kprobes/kprobes.c | 4 -
arch/sw_64/kernel/kvm_cma.c | 4 -
arch/sw_64/kernel/machine_kexec.c | 7 +-
arch/sw_64/kernel/module.c | 9 -
arch/sw_64/kernel/msi.c | 25 -
arch/sw_64/kernel/pci-noop.c | 8 -
arch/sw_64/kernel/pci-sysfs.c | 3 -
arch/sw_64/kernel/pci.c | 102 +-
arch/sw_64/kernel/pci_common.c | 285 +-
arch/sw_64/kernel/pci_impl.h | 49 -
arch/sw_64/kernel/perf_event.c | 12 -
arch/sw_64/kernel/perf_regs.c | 4 -
arch/sw_64/kernel/platform.c | 20 +
arch/sw_64/kernel/process.c | 26 -
arch/sw_64/kernel/ptrace.c | 132 +-
arch/sw_64/kernel/relocate.c | 13 +-
arch/sw_64/kernel/segvdbg.c | 4 +-
arch/sw_64/kernel/setup.c | 124 +-
arch/sw_64/kernel/signal.c | 74 +-
arch/sw_64/kernel/smp.c | 25 +-
arch/sw_64/kernel/stacktrace.c | 1 -
arch/sw_64/kernel/suspend.c | 22 +-
arch/sw_64/kernel/syscalls/syscall.tbl | 28 +-
arch/sw_64/kernel/tc.c | 3 -
arch/sw_64/kernel/time.c | 31 +-
arch/sw_64/kernel/timer.c | 21 +-
arch/sw_64/kernel/topology.c | 19 -
arch/sw_64/kernel/traps.c | 95 +-
arch/sw_64/kernel/unaligned.c | 3 -
arch/sw_64/kernel/uprobes.c | 5 -
arch/sw_64/kernel/vdso.c | 9 -
arch/sw_64/kernel/vdso/so2s.sh | 3 +-
arch/sw_64/kernel/vdso/vdso.S | 2 -
arch/sw_64/kernel/vdso/vdso.lds.S | 2 +-
arch/sw_64/kernel/vdso/vgettimeofday.c | 33 +-
arch/sw_64/kernel/vdso/vrt_sigreturn.S | 40 +
arch/sw_64/kvm/emulate.c | 2 +
arch/sw_64/kvm/kvm-sw64.c | 39 +-
arch/sw_64/kvm/vmem.c | 37 +-
arch/sw_64/lib/checksum.c | 136 +-
arch/sw_64/lib/csum_partial_copy.c | 310 +-
arch/sw_64/lib/deep-memcpy.S | 449 ++-
arch/sw_64/lib/deep-memset.S | 27 +-
arch/sw_64/lib/fls.c | 1 -
arch/sw_64/lib/iomap.c | 4 +-
arch/sw_64/lib/udelay.c | 5 -
arch/sw_64/math-emu/math.c | 10 +-
arch/sw_64/mm/fault.c | 21 +-
arch/sw_64/mm/hugetlbpage.c | 7 +-
arch/sw_64/mm/init.c | 48 +-
arch/sw_64/mm/numa.c | 30 +-
arch/sw_64/mm/physaddr.c | 1 -
arch/sw_64/mm/thp.c | 9 -
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/sw64_cpufreq.c | 186 +
drivers/gpu/drm/radeon/radeon_uvd.c | 5 +
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/sw64_pvt.c | 222 ++
drivers/iommu/sw64/sunway_iommu.c | 58 +-
drivers/iommu/sw64/sunway_iommu.h | 2 +-
drivers/rtc/rtc-sw64-virt.c | 24 +-
154 files changed, 7026 insertions(+), 2337 deletions(-)
create mode 100644 arch/sw_64/configs/openeuler_defconfig
delete mode 100644 arch/sw_64/defconfig
delete mode 100644 arch/sw_64/include/asm/a.out-core.h
delete mode 100644 arch/sw_64/include/asm/a.out.h
create mode 100644 arch/sw_64/include/asm/clock.h
delete mode 100644 arch/sw_64/include/asm/user.h
delete mode 100644 arch/sw_64/include/uapi/asm/a.out.h
create mode 100644 arch/sw_64/kernel/clock.c
create mode 100644 arch/sw_64/kernel/cpuautoplug.c
create mode 100644 arch/sw_64/kernel/platform.c
create mode 100644 drivers/cpufreq/sw64_cpufreq.c
create mode 100644 drivers/hwmon/sw64_pvt.c
--
2.20.1
1
90
From: Gu Zitao <guzitao(a)wxiat.com>
Cui Mingrui (2):
sw64: optimize ip checksum calculation
sw64: fix ip checksum calculation
Du Yilong (3):
sw64: kvm: fix bug when open file with the O_DIRECT flag
sw64: add set time support for hypervisor based rtc
sw64: kvm: remap pages of guest by vm_insert_page()
Gu Zitao (7):
config: add initial openeuler_defconfig for sw64
sw64: fix coding style problems
sw64: fix the VDSO symbol generation for nm
sw64: fix SPDX license identifier in uapi headers
sw64: add SO_RCVTIMEO/ SO_SNDTIMEO socket options
sw64: remove unnecessary include headers
sw64: fix some compile errors
He Chuyue (2):
sw64: add regs and stack access APIs to support kprobe events
sw64: remove unnecessary parameter in REG_OFFSET_NAME
He Sheng (20):
sw64: clean up useless #if 0 and #if 1
sw64: switch GUP to the generic get_user_pages_fast() implementation
sw64: remove unused a.out.h
sw64: fix ex_table entries from misalignment handlers
sw64: define NR_SYSCALLS as generated __NR_syscalls
sw64: clean up a.out and ECOFF binary related headers
sw64: ptrace: clean up debug codes
sw64: add kbuild defconfig rule
sw64: clean up out-of-date selected options
sw64: Kconfig: remove dependence on !PREEMPT
sw64: Kconfig: remove dependence on ARCH_SUPPORTS_ACPI
sw64: add missing global __constant_c_memset
sw64: do some cleanups for rt_sigframe
sw64: fix setup_rt_frame for non SA_SIGINFO
sw64: fix compile error for DISCONTIGMEM=y
sw64: force signal and fault for traps and debugging
sw64: push and pop kernel stack with ldi instruction
sw64: signal: save/restore fpregs with copy user
sw64: fix the number of aux entries in ARCH_DLINFO
sw64: fix sendfile system call
Lu Feifei (6):
sw64: fix printk method for guest os
sw64: unify access to LONGTIME for guest and emulator
sw64: kvm: handle ldl_u and stl_u when exit mmio
sw64: kvm: simplify the code
sw64: pci: align the address of mmio resource to PAGE_SIZE
sw64: unify 32-bit MEMIO address of host and guest
Mao Minkai (29):
sw64: vdso: add automatic syscall fallback
sw64: vdso: change vdso version
sw64: vdso: fix time calculation
sw64: mm: reorder memblock_init process
sw64: mm: warn overlapped memmap and DMA region
sw64: mm: use memblock to find the end of memory
sw64: print correct initrd address
sw64: remove redundant Kconfig source
sw64: modify tc_sched_clock debugfs file
sw64: simplify cpumask_of_node
sw64: remove CONFIG_USE_PERCPU_NUMA_NODE_ID=n code
sw64: fix all compile warnings
sw64: numa: switch to arch node_distance
sw64: mm: mark pci and memmap region as nomap
sw64: use jump label for running modes
sw64: remove MAX_ASN
sw64: kvm: remove MAX_VPN
sw64: fix coding style problems
sw64: rename kvm_mem variables
sw64: reformat syscall.tbl
sw64: add missing pkey syscall numbers
sw64: add clone3 syscall support
sw64: add required include headers to ptrace.h
sw64: switch to old-style semctl/shmctl syscalls
sw64: increase position index in c_next for cpuinfo
sw64: add old sigprocmask back for compatibility
sw64: vdso: fix backtrace of vrt_sigreturn
sw64: vdso: fix CFI directives for fpregs in vrt_sigreturn
sw64: optimize simd version of memcpy and memset
Min Fanlei (4):
sw64: fix the value of QEMU_PRINTF_BUFF_BASE
sw64: add support for emulator running mode
sw64: enable more than 32 CPUs for guest
sw64: kvm: fix bad page state setting outside of kvm memory pool
Tang Jinyang (2):
sw64: add dynamic frequency scaling support
sw64: add dynamic turning on/off cores support
Wang Yingying (3):
hwmon: add voltage sensor support for sw64
sw64: add pvt device to chip3.dts
hwmon: add support for sw64 temperature sensor
Xu Chenjiao (2):
sw64: radeon: add a force flush to delay work when radeon uvd suspend
sw64: pcie: enable PME and AER support
Zhao Yihan (1):
sw64: remap PA with |= in early_ioremap
Zheng Chongzhen (3):
sw64: re-implement sw64_dma_direct_ops according upstream
sw64: iommu: fix 32-bit devices dma ops
sw64: fix compile error for CONFIG_PCI=n
Zhou Xuemei (5):
sw64: pci: remove some useless code
sw64: switch to generic pcibios_set_master and pci_common_swizzle
sw64: clean up some useless codes
sw64: dts: rename spi flash partition to fix warning
sw64: add ARCH_HAS_PTE_SPECIAL support
Zhu Donghong (1):
ipmi: add ipmi driver support
arch/sw_64/Kconfig | 325 +-
arch/sw_64/Makefile | 1 +
arch/sw_64/boot/dts/chip3.dts | 41 +-
arch/sw_64/chip/chip3/chip.c | 130 +-
arch/sw_64/chip/chip3/cpufreq_debugfs.c | 7 +-
arch/sw_64/chip/chip3/i2c-lib.c | 4 -
arch/sw_64/chip/chip3/irq_chip.c | 13 +-
arch/sw_64/chip/chip3/msi.c | 7 +-
arch/sw_64/chip/chip3/pci-quirks.c | 7 +-
arch/sw_64/chip/chip3/vt_msi.c | 6 -
arch/sw_64/configs/openeuler_defconfig | 4312 +++++++++++++++++++++
arch/sw_64/defconfig | 73 -
arch/sw_64/include/asm/Kbuild | 1 +
arch/sw_64/include/asm/a.out-core.h | 80 -
arch/sw_64/include/asm/a.out.h | 16 -
arch/sw_64/include/asm/checksum.h | 58 +-
arch/sw_64/include/asm/chip3_io.h | 4 +-
arch/sw_64/include/asm/clock.h | 56 +
arch/sw_64/include/asm/cputime.h | 4 +-
arch/sw_64/include/asm/early_ioremap.h | 2 +-
arch/sw_64/include/asm/hw_init.h | 29 +-
arch/sw_64/include/asm/kvm_host.h | 3 +-
arch/sw_64/include/asm/mmu_context.h | 3 +-
arch/sw_64/include/asm/numa.h | 1 +
arch/sw_64/include/asm/pci.h | 24 +-
arch/sw_64/include/asm/pgtable.h | 26 +-
arch/sw_64/include/asm/ptrace.h | 8 +-
arch/sw_64/include/asm/topology.h | 29 +-
arch/sw_64/include/asm/unistd.h | 3 +-
arch/sw_64/include/asm/user.h | 53 -
arch/sw_64/include/asm/vdso.h | 4 +-
arch/sw_64/include/asm/vga.h | 18 +-
arch/sw_64/include/uapi/asm/a.out.h | 88 -
arch/sw_64/include/uapi/asm/auxvec.h | 25 +-
arch/sw_64/include/uapi/asm/bitsperlong.h | 2 +-
arch/sw_64/include/uapi/asm/byteorder.h | 2 +-
arch/sw_64/include/uapi/asm/compiler.h | 2 +-
arch/sw_64/include/uapi/asm/console.h | 2 +-
arch/sw_64/include/uapi/asm/errno.h | 2 +-
arch/sw_64/include/uapi/asm/fcntl.h | 2 +-
arch/sw_64/include/uapi/asm/fpu.h | 2 +-
arch/sw_64/include/uapi/asm/gentrap.h | 2 +-
arch/sw_64/include/uapi/asm/hmcall.h | 2 +-
arch/sw_64/include/uapi/asm/ioctl.h | 2 +-
arch/sw_64/include/uapi/asm/ioctls.h | 48 +-
arch/sw_64/include/uapi/asm/ipcbuf.h | 2 +-
arch/sw_64/include/uapi/asm/kvm.h | 14 +-
arch/sw_64/include/uapi/asm/kvm_para.h | 2 +-
arch/sw_64/include/uapi/asm/mman.h | 2 +-
arch/sw_64/include/uapi/asm/msgbuf.h | 2 +-
arch/sw_64/include/uapi/asm/param.h | 2 +-
arch/sw_64/include/uapi/asm/poll.h | 2 +-
arch/sw_64/include/uapi/asm/posix_types.h | 2 +-
arch/sw_64/include/uapi/asm/ptrace.h | 2 +-
arch/sw_64/include/uapi/asm/reg.h | 2 +-
arch/sw_64/include/uapi/asm/regdef.h | 2 +-
arch/sw_64/include/uapi/asm/resource.h | 2 +-
arch/sw_64/include/uapi/asm/sembuf.h | 2 +-
arch/sw_64/include/uapi/asm/setup.h | 2 +-
arch/sw_64/include/uapi/asm/shmbuf.h | 2 +-
arch/sw_64/include/uapi/asm/sigcontext.h | 2 +-
arch/sw_64/include/uapi/asm/siginfo.h | 2 +-
arch/sw_64/include/uapi/asm/signal.h | 2 +-
arch/sw_64/include/uapi/asm/socket.h | 34 +-
arch/sw_64/include/uapi/asm/sockios.h | 2 +-
arch/sw_64/include/uapi/asm/stat.h | 2 +-
arch/sw_64/include/uapi/asm/statfs.h | 2 +-
arch/sw_64/include/uapi/asm/swab.h | 2 +-
arch/sw_64/include/uapi/asm/sysinfo.h | 2 +-
arch/sw_64/include/uapi/asm/termbits.h | 2 +-
arch/sw_64/include/uapi/asm/termios.h | 2 +-
arch/sw_64/include/uapi/asm/types.h | 2 +-
arch/sw_64/include/uapi/asm/unistd.h | 7 +-
arch/sw_64/kernel/Makefile | 5 +-
arch/sw_64/kernel/acpi.c | 19 +-
arch/sw_64/kernel/asm-offsets.c | 7 +-
arch/sw_64/kernel/audit.c | 2 +-
arch/sw_64/kernel/cacheinfo.c | 3 +-
arch/sw_64/kernel/clock.c | 184 +
arch/sw_64/kernel/core.c | 41 +-
arch/sw_64/kernel/cpuautoplug.c | 496 +++
arch/sw_64/kernel/crash_dump.c | 2 -
arch/sw_64/kernel/dup_print.c | 10 +-
arch/sw_64/kernel/early_printk.c | 4 +-
arch/sw_64/kernel/entry.S | 5 +-
arch/sw_64/kernel/ftrace.c | 5 -
arch/sw_64/kernel/insn.c | 13 -
arch/sw_64/kernel/irq.c | 15 -
arch/sw_64/kernel/irq_sw64.c | 9 +-
arch/sw_64/kernel/jump_label.c | 3 +-
arch/sw_64/kernel/kgdb.c | 9 +-
arch/sw_64/kernel/kprobes/decode-insn.c | 6 +-
arch/sw_64/kernel/kprobes/kprobes.c | 4 -
arch/sw_64/kernel/kvm_cma.c | 4 -
arch/sw_64/kernel/machine_kexec.c | 7 +-
arch/sw_64/kernel/module.c | 9 -
arch/sw_64/kernel/msi.c | 25 -
arch/sw_64/kernel/pci-noop.c | 8 -
arch/sw_64/kernel/pci-sysfs.c | 3 -
arch/sw_64/kernel/pci.c | 102 +-
arch/sw_64/kernel/pci_common.c | 285 +-
arch/sw_64/kernel/pci_impl.h | 49 -
arch/sw_64/kernel/perf_event.c | 12 -
arch/sw_64/kernel/perf_regs.c | 4 -
arch/sw_64/kernel/platform.c | 20 +
arch/sw_64/kernel/process.c | 26 -
arch/sw_64/kernel/ptrace.c | 132 +-
arch/sw_64/kernel/relocate.c | 13 +-
arch/sw_64/kernel/segvdbg.c | 4 +-
arch/sw_64/kernel/setup.c | 124 +-
arch/sw_64/kernel/signal.c | 74 +-
arch/sw_64/kernel/smp.c | 25 +-
arch/sw_64/kernel/stacktrace.c | 1 -
arch/sw_64/kernel/suspend.c | 22 +-
arch/sw_64/kernel/syscalls/syscall.tbl | 28 +-
arch/sw_64/kernel/tc.c | 3 -
arch/sw_64/kernel/time.c | 31 +-
arch/sw_64/kernel/timer.c | 21 +-
arch/sw_64/kernel/topology.c | 19 -
arch/sw_64/kernel/traps.c | 95 +-
arch/sw_64/kernel/unaligned.c | 3 -
arch/sw_64/kernel/uprobes.c | 5 -
arch/sw_64/kernel/vdso.c | 9 -
arch/sw_64/kernel/vdso/so2s.sh | 3 +-
arch/sw_64/kernel/vdso/vdso.S | 2 -
arch/sw_64/kernel/vdso/vdso.lds.S | 2 +-
arch/sw_64/kernel/vdso/vgettimeofday.c | 33 +-
arch/sw_64/kernel/vdso/vrt_sigreturn.S | 40 +
arch/sw_64/kvm/emulate.c | 2 +
arch/sw_64/kvm/kvm-sw64.c | 39 +-
arch/sw_64/kvm/vmem.c | 37 +-
arch/sw_64/lib/checksum.c | 136 +-
arch/sw_64/lib/csum_partial_copy.c | 310 +-
arch/sw_64/lib/deep-memcpy.S | 449 ++-
arch/sw_64/lib/deep-memset.S | 27 +-
arch/sw_64/lib/fls.c | 1 -
arch/sw_64/lib/iomap.c | 4 +-
arch/sw_64/lib/udelay.c | 5 -
arch/sw_64/math-emu/math.c | 10 +-
arch/sw_64/mm/fault.c | 21 +-
arch/sw_64/mm/hugetlbpage.c | 7 +-
arch/sw_64/mm/init.c | 48 +-
arch/sw_64/mm/numa.c | 30 +-
arch/sw_64/mm/physaddr.c | 1 -
arch/sw_64/mm/thp.c | 9 -
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/sw64_cpufreq.c | 186 +
drivers/gpu/drm/radeon/radeon_uvd.c | 5 +
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/sw64_pvt.c | 222 ++
drivers/iommu/sw64/sunway_iommu.c | 58 +-
drivers/iommu/sw64/sunway_iommu.h | 2 +-
drivers/rtc/rtc-sw64-virt.c | 24 +-
154 files changed, 7026 insertions(+), 2337 deletions(-)
create mode 100644 arch/sw_64/configs/openeuler_defconfig
delete mode 100644 arch/sw_64/defconfig
delete mode 100644 arch/sw_64/include/asm/a.out-core.h
delete mode 100644 arch/sw_64/include/asm/a.out.h
create mode 100644 arch/sw_64/include/asm/clock.h
delete mode 100644 arch/sw_64/include/asm/user.h
delete mode 100644 arch/sw_64/include/uapi/asm/a.out.h
create mode 100644 arch/sw_64/kernel/clock.c
create mode 100644 arch/sw_64/kernel/cpuautoplug.c
create mode 100644 arch/sw_64/kernel/platform.c
create mode 100644 drivers/cpufreq/sw64_cpufreq.c
create mode 100644 drivers/hwmon/sw64_pvt.c
--
2.17.1
1
90
From: Chen Jun <chenjun102(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I584X2
CVE: NA
--------------------------------
On some platforms, there are some error:
genirq: Flags mismatch irq 23. 00010804 (xxx) vs. 00010804 (xxx)
The reason is that there are more than one pmu nodes witch uses the same
irq number.
Add IROF_SHARED when devm_request_irq
Signed-off-by: Chen Jun <chenjun102(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/perf/hisilicon/hisi_uncore_pmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index 07f0c7015181..d31a497020c2 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -168,7 +168,7 @@ int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
return irq;
ret = devm_request_irq(&pdev->dev, irq, hisi_uncore_pmu_isr,
- IRQF_NOBALANCING | IRQF_NO_THREAD,
+ IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED,
dev_name(&pdev->dev), hisi_pmu);
if (ret < 0) {
dev_err(&pdev->dev,
--
2.20.1
1
3

19 May '22
uniontech inclusion
category: bugfix
bugzilla: NA
CVE: NA
----------
If it can't be divided, minimum_size need to add another byte.
Signed-off-by: Gou Hao <gouhao(a)uniontech.com>
---
fs/eulerfs/super.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/eulerfs/super.c b/fs/eulerfs/super.c
index 43fc717002d7..20c7fe845b6c 100644
--- a/fs/eulerfs/super.c
+++ b/fs/eulerfs/super.c
@@ -216,7 +216,7 @@ static bool eufs_check_size(struct super_block *sb, unsigned long size)
/* For Super Block */
minimum_size = 2 << sb->s_blocksize_bits;
/* For Bitmaps */
- minimum_size += size / EUFS_BLOCK_SIZE / 8;
+ minimum_size += DIV_ROUND_UP(size / EUFS_BLOCK_SIZE, 8);
if (size < minimum_size)
return false;
--
2.20.1
1
0
uniontech inclusion
category: bugfix
bugzilla: NA
CVE: NA
----------
If it can't be divided, minimum_size need to add another byte.
Signed-off-by: Gou Hao <gouhao(a)uniontech.com>
---
fs/eulerfs/super.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/eulerfs/super.c b/fs/eulerfs/super.c
index 43fc717002d7..20c7fe845b6c 100644
--- a/fs/eulerfs/super.c
+++ b/fs/eulerfs/super.c
@@ -216,7 +216,7 @@ static bool eufs_check_size(struct super_block *sb, unsigned long size)
/* For Super Block */
minimum_size = 2 << sb->s_blocksize_bits;
/* For Bitmaps */
- minimum_size += size / EUFS_BLOCK_SIZE / 8;
+ minimum_size += DIV_ROUND_UP(size / EUFS_BLOCK_SIZE, 8);
if (size < minimum_size)
return false;
--
2.20.1
1
0

18 May '22
Set CONFIG_SENSORS_ZHAOXIN_CPUTEMP to 'm' by default in openeuler_configs
Signed-off-by: LeoLiuoc <LeoLiu-oc(a)zhaoxin.com>
---
arch/x86/configs/openeuler_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/configs/openeuler_defconfig
b/arch/x86/configs/openeuler_defconfig
index 61c4be815462..4e3692e24b65 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -4052,6 +4052,7 @@ CONFIG_SENSORS_TMP401=m
CONFIG_SENSORS_TMP421=m
# CONFIG_SENSORS_TMP513 is not set
CONFIG_SENSORS_VIA_CPUTEMP=m
+CONFIG_SENSORS_ZHAOXIN_CPUTEMP=m
CONFIG_SENSORS_VIA686A=m
CONFIG_SENSORS_VT1211=m
CONFIG_SENSORS_VT8231=m
--
2.20.1
1
0

[PATCH openEuler-5.10 1/2] net/x25: Fix null-ptr-deref caused by x25_disconnect
by Zheng Zengkai 18 May '22
by Zheng Zengkai 18 May '22
18 May '22
From: Duoming Zhou <duoming(a)zju.edu.cn>
stable inclusion
from stable-v5.10.110
commit 5c94b6205e87411dbe9dc1ca088eb36b8837fb47
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5661B
CVE: CVE-2022-1516
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 7781607938c8371d4c2b243527430241c62e39c2 ]
When the link layer is terminating, x25->neighbour will be set to NULL
in x25_disconnect(). As a result, it could cause null-ptr-deref bugs in
x25_sendmsg(),x25_recvmsg() and x25_connect(). One of the bugs is
shown below.
(Thread 1) | (Thread 2)
x25_link_terminated() | x25_recvmsg()
x25_kill_by_neigh() | ...
x25_disconnect() | lock_sock(sk)
... | ...
x25->neighbour = NULL //(1) |
... | x25->neighbour->extended //(2)
The code sets NULL to x25->neighbour in position (1) and dereferences
x25->neighbour in position (2), which could cause null-ptr-deref bug.
This patch adds lock_sock() in x25_kill_by_neigh() in order to synchronize
with x25_sendmsg(), x25_recvmsg() and x25_connect(). What`s more, the
sock held by lock_sock() is not NULL, because it is extracted from x25_list
and uses x25_list_lock to synchronize.
Fixes: 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect")
Signed-off-by: Duoming Zhou <duoming(a)zju.edu.cn>
Reviewed-by: Lin Ma <linma(a)zju.edu.cn>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Baisong Zhong <zhongbaisong(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
net/x25/af_x25.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 03ed170b8125..d231d4620c38 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1775,10 +1775,15 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
write_lock_bh(&x25_list_lock);
- sk_for_each(s, &x25_list)
- if (x25_sk(s)->neighbour == nb)
+ sk_for_each(s, &x25_list) {
+ if (x25_sk(s)->neighbour == nb) {
+ write_unlock_bh(&x25_list_lock);
+ lock_sock(s);
x25_disconnect(s, ENETUNREACH, 0, 0);
-
+ release_sock(s);
+ write_lock_bh(&x25_list_lock);
+ }
+ }
write_unlock_bh(&x25_list_lock);
/* Remove any related forwards */
--
2.20.1
1
1
iommu: Fix potential use-after-free during probe
perf: Fix list corruption in perf_cgroup_switch()
arm64: dts: imx8mq: fix lcdif port node
scsi: lpfc: Reduce log messages seen after firmware download
scsi: lpfc: Remove NVMe support if kernel has NVME_FC disabled
can: isotp: fix error path in isotp_sendmsg() to unlock wait queue
Makefile.extrawarn: Move -Wunaligned-access to W=1
hwmon: (dell-smm) Speed up setting of fan speed
phy: ti: Fix missing sentinel for clk_div_table
speakup-dectlk: Restore pitch setting
USB: serial: cp210x: add CPI Bulk Coin Recycler id
USB: serial: cp210x: add NCR Retail IO box id
USB: serial: ch341: add support for GW Instek USB2.0-Serial devices
USB: serial: option: add ZTE MF286D modem
USB: serial: ftdi_sio: add support for Brainboxes US-159/235/320
usb: raw-gadget: fix handling of dual-direction-capable endpoints
usb: gadget: f_uac2: Define specific wTerminalType
usb: gadget: udc: renesas_usb3: Fix host to USB_ROLE_NONE transition
usb: dwc3: gadget: Prevent core from processing stale TRBs
usb: ulpi: Call of_node_put correctly
usb: ulpi: Move of_node_put to ulpi_dev_release
net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup
Revert "usb: dwc2: drd: fix soft connect when gadget is unconfigured"
usb: dwc2: drd: fix soft connect when gadget is unconfigured
eeprom: ee1004: limit i2c reads to I2C_SMBUS_BLOCK_MAX
n_tty: wake up poll(POLLRDNORM) on receiving data
vt_ioctl: add array_index_nospec to VT_ACTIVATE
vt_ioctl: fix array_index_nospec in vt_setactivate
net: dsa: mv88e6xxx: fix use-after-free in mv88e6xxx_mdios_unregister
net: mscc: ocelot: fix mutex lock error during ethtool stats read
ice: fix IPIP and SIT TSO offload
ice: fix an error code in ice_cfg_phy_fec()
dpaa2-eth: unregister the netdev before disconnecting from the PHY
net: amd-xgbe: disable interrupts during pci removal
tipc: rate limit warning for received illegal binding update
net: mdio: aspeed: Add missing MODULE_DEVICE_TABLE
veth: fix races around rq->rx_notify_masked
net: fix a memleak when uncloning an skb dst and its metadata
net: do not keep the dst cache when uncloning an skb dst and its metadata
nfp: flower: fix ida_idx not being released
ipmr,ip6mr: acquire RTNL before calling ip[6]mr_free_table() on failure path
net: dsa: lantiq_gswip: don't use devres for mdiobus
net: dsa: felix: don't use devres for mdiobus
net: dsa: bcm_sf2: don't use devres for mdiobus
net: dsa: ar9331: register the mdiobus under devres
net: dsa: mv88e6xxx: don't use devres for mdiobus
bonding: pair enable_port with slave_arr_updates
gpio: sifive: use the correct register to read output values
ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE
drm/panel: simple: Assign data from panel_dpi_probe() correctly
ixgbevf: Require large buffers for build_skb on 82599VF
arm64: dts: meson-g12b-odroid-n2: fix typo 'dio2133'
netfilter: ctnetlink: disable helper autoassign
misc: fastrpc: avoid double fput() on failed usercopy
drm/vc4: hdmi: Allow DBLCLK modes even if horz timing is odd.
gpio: aggregator: Fix calling into sleeping GPIO controllers
usb: f_fs: Fix use-after-free for epfile
ARM: dts: imx7ulp: Fix 'assigned-clocks-parents' typo
phy: xilinx: zynqmp: Fix bus width setting for SGMII
ARM: dts: imx6qdl-udoo: Properly describe the SD card detect
staging: fbtft: Fix error path in fbtft_driver_module_init()
ARM: dts: meson8b: Fix the UART device-tree schema validation
ARM: dts: meson8: Fix the UART device-tree schema validation
ARM: dts: meson: Fix the UART compatible strings
ARM: dts: Fix timer regression for beagleboard revision c
drm/rockchip: vop: Correct RK3399 VOP register fields
PM: s2idle: ACPI: Fix wakeup interrupts handling
ACPI/IORT: Check node revision for PMCG resources
nvme-tcp: fix bogus request completion when failing to send AER
ARM: socfpga: fix missing RESET_CONTROLLER
ARM: dts: Fix boot regression on Skomer
ARM: dts: imx23-evk: Remove MX23_PAD_SSP1_DETECT from hog group
riscv: fix build with binutils 2.38
KVM: VMX: Set vmcs.PENDING_DBG.BS on #DB in STI/MOVSS blocking shadow
KVM: SVM: Don't kill SEV guest if SMAP erratum triggers in usermode
KVM: nVMX: Also filter MSR_IA32_VMX_TRUE_PINBASED_CTLS when eVMCS
KVM: nVMX: eVMCS: Filter out VM_EXIT_SAVE_VMX_PREEMPTION_TIMER
KVM: eventfd: Fix false positive RCU usage warning
net: stmmac: dwmac-sun8i: use return val of readl_poll_timeout()
nvme-pci: add the IGNORE_DEV_SUBNQN quirk for Intel P4500/P4600 SSDs
perf: Always wake the parent event
usb: dwc2: gadget: don't try to disable ep0 in dwc2_hsotg_suspend
PM: hibernate: Remove register_nosave_region_late()
scsi: myrs: Fix crash in error case
scsi: ufs: Treat link loss as fatal error
scsi: pm8001: Fix bogus FW crash for maxcpus=1
scsi: qedf: Fix refcount issue when LOGO is received during TMF
scsi: qedf: Add stag_work to all the vports
scsi: ufs: ufshcd-pltfrm: Check the return value of devm_kstrdup()
scsi: target: iscsi: Make sure the np under each tpg is unique
powerpc/fixmap: Fix VM debug warning on unmap
net: sched: Clarify error message when qdisc kind is unknown
drm: panel-orientation-quirks: Add quirk for the 1Netbook OneXPlayer
x86/perf: Avoid warning for Arch LBR without XSAVE
NFSv4 handle port presence in fs_location server string
NFSv4 expose nfs_parse_server_name function
NFSv4 remove zero number of fs_locations entries error check
NFSv4.1: Fix uninitialised variable in devicenotify
nfs: nfs4clinet: check the return value of kstrdup()
NFSv4 only print the label when its queried
NFS: change nfs_access_get_cached to only report the mask
tracing: Propagate is_signed to expression
drm/amdgpu: Set a suitable dev_info.gart_page_size
NFSD: Fix offset type in I/O trace points
NFSD: Clamp WRITE offsets
NFS: Fix initialisation of nfs_client cl_flags field
net: phy: marvell: Fix MDI-x polarity setting in 88e1118-compatible PHYs
net: phy: marvell: Fix RGMII Tx/Rx delays setting in 88e1121-compatible PHYs
can: isotp: fix potential CAN frame reception race in isotp_rcv()
mmc: sdhci-of-esdhc: Check for error num after setting mask
ima: Do not print policy rule with inactive LSM labels
ima: Allow template selection with ima_template[_fmt]= after ima_hash=
ima: Remove ima_policy file before directory
integrity: check the return value of audit_log_start()
already merged
fb4ff0f96de3 usb: gadget: rndis: check size of RNDIS_MSG_SET command
22ec10047285 USB: gadget: validate interface OS descriptor requests
context conflict:
ima: Remove ima_policy file before directory
Total patches: 116 - 2 = 114
Adam Ford (1):
usb: gadget: udc: renesas_usb3: Fix host to USB_ROLE_NONE transition
Alexander Stein (1):
arm64: dts: imx8mq: fix lcdif port node
Amadeusz Sławiński (1):
PM: hibernate: Remove register_nosave_region_late()
Amelie Delaunay (1):
usb: dwc2: gadget: don't try to disable ep0 in dwc2_hsotg_suspend
Andi Kleen (1):
x86/perf: Avoid warning for Arch LBR without XSAVE
Antoine Tenart (2):
net: do not keep the dst cache when uncloning an skb dst and its
metadata
net: fix a memleak when uncloning an skb dst and its metadata
Armin Wolf (1):
hwmon: (dell-smm) Speed up setting of fan speed
Aurelien Jarno (1):
riscv: fix build with binutils 2.38
Brian Norris (1):
drm/rockchip: vop: Correct RK3399 VOP register fields
Cameron Williams (1):
USB: serial: ftdi_sio: add support for Brainboxes US-159/235/320
Christoph Niedermaier (1):
drm/panel: simple: Assign data from panel_dpi_probe() correctly
Christophe Leroy (1):
powerpc/fixmap: Fix VM debug warning on unmap
Chuck Lever (2):
NFSD: Clamp WRITE offsets
NFSD: Fix offset type in I/O trace points
Colin Foster (1):
net: mscc: ocelot: fix mutex lock error during ethtool stats read
Dan Carpenter (1):
ice: fix an error code in ice_cfg_phy_fec()
Dave Stevenson (1):
drm/vc4: hdmi: Allow DBLCLK modes even if horz timing is odd.
Dongjin Kim (1):
arm64: dts: meson-g12b-odroid-n2: fix typo 'dio2133'
Eric Dumazet (2):
ipmr,ip6mr: acquire RTNL before calling ip[6]mr_free_table() on
failure path
veth: fix races around rq->rx_notify_masked
Fabio Estevam (2):
ARM: dts: imx23-evk: Remove MX23_PAD_SSP1_DETECT from hog group
ARM: dts: imx6qdl-udoo: Properly describe the SD card detect
Fabrice Gasnier (1):
usb: dwc2: drd: fix soft connect when gadget is unconfigured
Florian Westphal (1):
netfilter: ctnetlink: disable helper autoassign
Geert Uytterhoeven (1):
gpio: aggregator: Fix calling into sleeping GPIO controllers
Greg Kroah-Hartman (1):
Revert "usb: dwc2: drd: fix soft connect when gadget is unconfigured"
Hou Wenlong (1):
KVM: eventfd: Fix false positive RCU usage warning
Huacai Chen (1):
drm/amdgpu: Set a suitable dev_info.gart_page_size
Jakob Koschel (2):
vt_ioctl: fix array_index_nospec in vt_setactivate
vt_ioctl: add array_index_nospec to VT_ACTIVATE
James Clark (1):
perf: Always wake the parent event
James Smart (2):
scsi: lpfc: Remove NVMe support if kernel has NVME_FC disabled
scsi: lpfc: Reduce log messages seen after firmware download
Jann Horn (2):
net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup
usb: raw-gadget: fix handling of dual-direction-capable endpoints
Jesse Brandeburg (1):
ice: fix IPIP and SIT TSO offload
Jiasheng Jiang (1):
mmc: sdhci-of-esdhc: Check for error num after setting mask
Jisheng Zhang (1):
net: stmmac: dwmac-sun8i: use return val of readl_poll_timeout()
Joel Stanley (1):
net: mdio: aspeed: Add missing MODULE_DEVICE_TABLE
Johan Hovold (2):
USB: serial: cp210x: add NCR Retail IO box id
USB: serial: cp210x: add CPI Bulk Coin Recycler id
John Garry (1):
scsi: pm8001: Fix bogus FW crash for maxcpus=1
Jon Maloy (1):
tipc: rate limit warning for received illegal binding update
Jonas Malaco (1):
eeprom: ee1004: limit i2c reads to I2C_SMBUS_BLOCK_MAX
Kishon Vijay Abraham I (1):
phy: ti: Fix missing sentinel for clk_div_table
Kiwoong Kim (1):
scsi: ufs: Treat link loss as fatal error
Krzysztof Kozlowski (1):
ARM: socfpga: fix missing RESET_CONTROLLER
Linus Walleij (1):
ARM: dts: Fix boot regression on Skomer
Louis Peens (1):
nfp: flower: fix ida_idx not being released
Mahesh Bandewar (1):
bonding: pair enable_port with slave_arr_updates
Martin Blumenstingl (3):
ARM: dts: meson: Fix the UART compatible strings
ARM: dts: meson8: Fix the UART device-tree schema validation
ARM: dts: meson8b: Fix the UART device-tree schema validation
Mathias Krause (1):
misc: fastrpc: avoid double fput() on failed usercopy
Nathan Chancellor (1):
Makefile.extrawarn: Move -Wunaligned-access to W=1
NeilBrown (1):
NFS: change nfs_access_get_cached to only report the mask
Niklas Cassel (1):
gpio: sifive: use the correct register to read output values
Olga Kornievskaia (4):
NFSv4 only print the label when its queried
NFSv4 remove zero number of fs_locations entries error check
NFSv4 expose nfs_parse_server_name function
NFSv4 handle port presence in fs_location server string
Oliver Hartkopp (2):
can: isotp: fix potential CAN frame reception race in isotp_rcv()
can: isotp: fix error path in isotp_sendmsg() to unlock wait queue
Pavel Hofman (1):
usb: gadget: f_uac2: Define specific wTerminalType
Pavel Parkhomenko (2):
net: phy: marvell: Fix RGMII Tx/Rx delays setting in
88e1121-compatible PHYs
net: phy: marvell: Fix MDI-x polarity setting in 88e1118-compatible
PHYs
Pawel Dembicki (1):
USB: serial: option: add ZTE MF286D modem
Rafael J. Wysocki (2):
PM: s2idle: ACPI: Fix wakeup interrupts handling
ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE
Raju Rangoju (1):
net: amd-xgbe: disable interrupts during pci removal
Raymond Jay Golo (1):
drm: panel-orientation-quirks: Add quirk for the 1Netbook OneXPlayer
Rob Herring (1):
ARM: dts: imx7ulp: Fix 'assigned-clocks-parents' typo
Robert Hancock (1):
phy: xilinx: zynqmp: Fix bus width setting for SGMII
Robert-Ionut Alexa (1):
dpaa2-eth: unregister the netdev before disconnecting from the PHY
Roberto Sassu (1):
ima: Allow template selection with ima_template[_fmt]= after ima_hash=
Robin Murphy (1):
ACPI/IORT: Check node revision for PMCG resources
Sagi Grimberg (1):
nvme-tcp: fix bogus request completion when failing to send AER
Samuel Mendoza-Jonas (1):
ixgbevf: Require large buffers for build_skb on 82599VF
Samuel Thibault (1):
speakup-dectlk: Restore pitch setting
Saurav Kashyap (2):
scsi: qedf: Add stag_work to all the vports
scsi: qedf: Fix refcount issue when LOGO is received during TMF
Sean Anderson (2):
usb: ulpi: Move of_node_put to ulpi_dev_release
usb: ulpi: Call of_node_put correctly
Sean Christopherson (2):
KVM: SVM: Don't kill SEV guest if SMAP erratum triggers in usermode
KVM: VMX: Set vmcs.PENDING_DBG.BS on #DB in STI/MOVSS blocking shadow
Song Liu (1):
perf: Fix list corruption in perf_cgroup_switch()
Stefan Berger (2):
ima: Remove ima_policy file before directory
ima: Do not print policy rule with inactive LSM labels
Stephan Brunner (1):
USB: serial: ch341: add support for GW Instek USB2.0-Serial devices
TATSUKAWA KOSUKE (立川 江介) (1):
n_tty: wake up poll(POLLRDNORM) on receiving data
Tom Zanussi (1):
tracing: Propagate is_signed to expression
Tong Zhang (1):
scsi: myrs: Fix crash in error case
Tony Lindgren (1):
ARM: dts: Fix timer regression for beagleboard revision c
Trond Myklebust (2):
NFS: Fix initialisation of nfs_client cl_flags field
NFSv4.1: Fix uninitialised variable in devicenotify
Udipto Goswami (2):
usb: f_fs: Fix use-after-free for epfile
usb: dwc3: gadget: Prevent core from processing stale TRBs
Uwe Kleine-König (1):
staging: fbtft: Fix error path in fbtft_driver_module_init()
Victor Nogueira (1):
net: sched: Clarify error message when qdisc kind is unknown
Vijayanand Jitta (1):
iommu: Fix potential use-after-free during probe
Vitaly Kuznetsov (2):
KVM: nVMX: eVMCS: Filter out VM_EXIT_SAVE_VMX_PREEMPTION_TIMER
KVM: nVMX: Also filter MSR_IA32_VMX_TRUE_PINBASED_CTLS when eVMCS
Vladimir Oltean (6):
net: dsa: mv88e6xxx: don't use devres for mdiobus
net: dsa: ar9331: register the mdiobus under devres
net: dsa: bcm_sf2: don't use devres for mdiobus
net: dsa: felix: don't use devres for mdiobus
net: dsa: lantiq_gswip: don't use devres for mdiobus
net: dsa: mv88e6xxx: fix use-after-free in mv88e6xxx_mdios_unregister
Wu Zheng (1):
nvme-pci: add the IGNORE_DEV_SUBNQN quirk for Intel P4500/P4600 SSDs
Xiaoke Wang (3):
integrity: check the return value of audit_log_start()
nfs: nfs4clinet: check the return value of kstrdup()
scsi: ufs: ufshcd-pltfrm: Check the return value of devm_kstrdup()
ZouMingzhe (1):
scsi: target: iscsi: Make sure the np under each tpg is unique
.../devicetree/bindings/arm/omap/omap.txt | 3 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/imx23-evk.dts | 1 -
arch/arm/boot/dts/imx6qdl-udoo.dtsi | 5 +-
arch/arm/boot/dts/imx7ulp.dtsi | 2 +-
arch/arm/boot/dts/meson.dtsi | 8 +--
arch/arm/boot/dts/meson8.dtsi | 24 +++----
arch/arm/boot/dts/meson8b.dtsi | 24 +++----
arch/arm/boot/dts/omap3-beagle-ab4.dts | 47 +++++++++++++
arch/arm/boot/dts/omap3-beagle.dts | 33 ---------
.../arm/boot/dts/ste-ux500-samsung-skomer.dts | 4 --
arch/arm/mach-socfpga/Kconfig | 2 +
.../dts/amlogic/meson-g12b-odroid-n2.dtsi | 4 +-
arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 +-
arch/powerpc/include/asm/book3s/32/pgtable.h | 1 +
arch/powerpc/include/asm/book3s/64/pgtable.h | 2 +
arch/powerpc/include/asm/fixmap.h | 6 +-
arch/powerpc/include/asm/nohash/32/pgtable.h | 1 +
arch/powerpc/include/asm/nohash/64/pgtable.h | 1 +
arch/powerpc/mm/pgtable.c | 9 +++
arch/riscv/Makefile | 6 ++
arch/x86/events/intel/lbr.c | 3 +
arch/x86/kvm/svm/svm.c | 16 ++++-
arch/x86/kvm/vmx/evmcs.c | 1 +
arch/x86/kvm/vmx/evmcs.h | 4 +-
arch/x86/kvm/vmx/vmx.c | 25 +++++++
.../accessibility/speakup/speakup_dectlk.c | 1 +
drivers/acpi/arm64/iort.c | 14 +++-
drivers/acpi/ec.c | 10 +++
drivers/acpi/sleep.c | 15 ++--
drivers/base/power/wakeup.c | 41 +++++++++--
drivers/clocksource/timer-ti-dm-systimer.c | 2 +-
drivers/gpio/gpio-aggregator.c | 18 +++--
drivers/gpio/gpio-sifive.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 +-
.../gpu/drm/drm_panel_orientation_quirks.c | 12 ++++
drivers/gpu/drm/panel/panel-simple.c | 1 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 ++-
drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +
drivers/hwmon/dell-smm-hwmon.c | 12 ++--
drivers/iommu/iommu.c | 9 ++-
drivers/misc/eeprom/ee1004.c | 3 +
drivers/misc/fastrpc.c | 9 ++-
drivers/mmc/host/sdhci-of-esdhc.c | 8 ++-
drivers/net/bonding/bond_3ad.c | 3 +-
drivers/net/dsa/bcm_sf2.c | 7 +-
drivers/net/dsa/lantiq_gswip.c | 14 +++-
drivers/net/dsa/mv88e6xxx/chip.c | 15 ++--
drivers/net/dsa/ocelot/felix_vsc9959.c | 4 +-
drivers/net/dsa/qca/ar9331.c | 3 +-
drivers/net/ethernet/amd/xgbe/xgbe-pci.c | 3 +
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 +-
drivers/net/ethernet/intel/ice/ice_common.c | 3 +-
.../net/ethernet/intel/ice/ice_lan_tx_rx.h | 1 +
drivers/net/ethernet/intel/ice/ice_main.c | 25 ++++---
.../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 13 ++--
drivers/net/ethernet/mscc/ocelot.c | 11 +--
.../netronome/nfp/flower/tunnel_conf.c | 12 ++--
.../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +-
drivers/net/mdio/mdio-aspeed.c | 1 +
drivers/net/phy/marvell.c | 17 ++---
drivers/net/usb/ax88179_178a.c | 68 +++++++++++--------
drivers/net/veth.c | 13 ++--
drivers/nvme/host/pci.c | 3 +-
drivers/nvme/host/tcp.c | 10 ++-
drivers/phy/ti/phy-j721e-wiz.c | 1 +
drivers/phy/xilinx/phy-zynqmp.c | 11 +--
drivers/scsi/lpfc/lpfc.h | 13 +++-
drivers/scsi/lpfc/lpfc_attr.c | 4 +-
drivers/scsi/lpfc/lpfc_init.c | 2 +-
drivers/scsi/lpfc/lpfc_sli.c | 8 ++-
drivers/scsi/myrs.c | 3 +-
drivers/scsi/pm8001/pm80xx_hwi.c | 16 ++++-
drivers/scsi/pm8001/pm80xx_hwi.h | 6 +-
drivers/scsi/qedf/qedf_io.c | 1 +
drivers/scsi/qedf/qedf_main.c | 1 +
drivers/scsi/ufs/ufshcd-pltfrm.c | 7 ++
drivers/scsi/ufs/ufshci.h | 3 +-
drivers/staging/fbtft/fbtft.h | 5 +-
drivers/target/iscsi/iscsi_target_tpg.c | 3 +
drivers/tty/n_tty.c | 4 +-
drivers/tty/vt/vt_ioctl.c | 3 +-
drivers/usb/common/ulpi.c | 10 ++-
drivers/usb/dwc2/gadget.c | 2 +-
drivers/usb/dwc3/gadget.c | 13 ++++
drivers/usb/gadget/function/f_fs.c | 56 +++++++++++----
drivers/usb/gadget/function/f_uac2.c | 4 +-
drivers/usb/gadget/legacy/raw_gadget.c | 2 +-
drivers/usb/gadget/udc/renesas_usb3.c | 2 +
drivers/usb/serial/ch341.c | 1 +
drivers/usb/serial/cp210x.c | 2 +
drivers/usb/serial/ftdi_sio.c | 3 +
drivers/usb/serial/ftdi_sio_ids.h | 3 +
drivers/usb/serial/option.c | 2 +
fs/nfs/callback.h | 2 +-
fs/nfs/callback_proc.c | 2 +-
fs/nfs/callback_xdr.c | 18 ++---
fs/nfs/client.c | 2 +-
fs/nfs/dir.c | 20 +++---
fs/nfs/nfs4_fs.h | 3 +-
fs/nfs/nfs4client.c | 5 +-
fs/nfs/nfs4namespace.c | 19 ++++--
fs/nfs/nfs4proc.c | 18 ++---
fs/nfs/nfs4state.c | 3 +
fs/nfs/nfs4xdr.c | 9 ++-
fs/nfsd/nfs3proc.c | 5 ++
fs/nfsd/nfs4proc.c | 5 +-
fs/nfsd/trace.h | 14 ++--
include/linux/nfs_fs.h | 4 +-
include/linux/suspend.h | 15 +---
include/net/dst_metadata.h | 14 +++-
.../linux/netfilter/nf_conntrack_common.h | 2 +-
kernel/events/core.c | 16 +++--
kernel/power/main.c | 5 +-
kernel/power/process.c | 2 +-
kernel/power/snapshot.c | 21 ++----
kernel/power/suspend.c | 2 -
kernel/trace/trace_events_hist.c | 3 +
net/can/isotp.c | 27 ++++++--
net/ipv4/ipmr.c | 2 +
net/ipv6/ip6mr.c | 2 +
net/netfilter/nf_conntrack_netlink.c | 3 +-
net/sched/sch_api.c | 2 +-
net/tipc/name_distr.c | 2 +-
scripts/Makefile.extrawarn | 1 +
security/integrity/ima/ima_fs.c | 2 +-
security/integrity/ima/ima_policy.c | 8 +++
security/integrity/ima/ima_template.c | 10 ++-
security/integrity/integrity_audit.c | 2 +
virt/kvm/eventfd.c | 8 +--
130 files changed, 756 insertions(+), 351 deletions(-)
create mode 100644 arch/arm/boot/dts/omap3-beagle-ab4.dts
--
2.20.1
1
114

17 May '22
Set CONFIG_SENSORS_ZHAOXIN_CPUTEMP to 'm' by default in openeuler_configs
Signed-off-by: LeoLiuoc <LeoLiu-oc(a)zhaoxin.com>
---
arch/x86/configs/openeuler_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/configs/openeuler_defconfig
b/arch/x86/configs/openeuler_defconfig
index 61c4be815462..4e3692e24b65 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -4052,6 +4052,7 @@ CONFIG_SENSORS_TMP401=m
CONFIG_SENSORS_TMP421=m
# CONFIG_SENSORS_TMP513 is not set
CONFIG_SENSORS_VIA_CPUTEMP=m
+CONFIG_SENSORS_ZHAOXIN_CPUTEMP=m
CONFIG_SENSORS_VIA686A=m
CONFIG_SENSORS_VT1211=m
CONFIG_SENSORS_VT8231=m
--
2.20.1
1
0
Backport 5.10.100 LTS patches from upstream
moxart: fix potential use-after-free on remove path
crypto: api - Move cryptomgr soft dependency into algapi
Already merged:
tipc: improve size validations for received domain records
KVM: s390: Return error on SIDA memop on normal guest
Total patches: 2
Greg Kroah-Hartman (1):
moxart: fix potential use-after-free on remove path
Herbert Xu (1):
crypto: api - Move cryptomgr soft dependency into algapi
crypto/algapi.c | 1 +
crypto/api.c | 1 -
drivers/mmc/host/moxart-mmc.c | 2 +-
3 files changed, 2 insertions(+), 2 deletions(-)
--
2.20.1
1
2
Backport 5.10.99 LTS patches from upstream
selftests: nft_concat_range: add test for reload with no element add/del
cgroup/cpuset: Fix "suspicious RCU usage" lockdep warning
net: dsa: mt7530: make NET_DSA_MT7530 select MEDIATEK_GE_PHY
ext4: fix incorrect type issue during replay_del_range
ext4: fix error handling in ext4_fc_record_modified_inode()
ext4: fix error handling in ext4_restore_inline_data()
ext4: modify the logic of ext4_mb_new_blocks_simple
ext4: prevent used blocks from being allocated during fast commit replay
EDAC/xgene: Fix deferred probing
EDAC/altera: Fix deferred probing
x86/perf: Default set FREEZE_ON_SMI for all
perf/x86/intel/pt: Fix crash with stop filters in single-range mode
perf stat: Fix display of grouped aliased events
fbcon: Add option to enable legacy hardware acceleration
Revert "fbcon: Disable accelerated scrolling"
rtc: cmos: Evaluate century appropriate
tools/resolve_btfids: Do not print any commands when building silently
selftests: futex: Use variable MAKE instead of make
selftests/exec: Remove pipe from TEST_GEN_FILES
bpf: Use VM_MAP instead of VM_ALLOC for ringbuf
gve: fix the wrong AdminQ buffer queue index check
nfsd: nfsd4_setclientid_confirm mistakenly expires confirmed client.
scsi: bnx2fc: Make bnx2fc_recv_frame() mp safe
pinctrl: bcm2835: Fix a few error paths
pinctrl: intel: fix unexpected interrupt
pinctrl: intel: Fix a glitch when updating IRQ flags on a preconfigured line
ASoC: max9759: fix underflow in speaker_gain_control_put()
ASoC: cpcap: Check for NULL pointer after calling of_get_child_by_name
ASoC: xilinx: xlnx_formatter_pcm: Make buffer bytes multiple of period bytes
ASoC: fsl: Add missing error handling in pcm030_fabric_probe
drm/i915/overlay: Prevent divide by zero bugs in scaling
net: stmmac: ensure PTP time register reads are consistent
net: stmmac: dump gmac4 DMA registers correctly
net: macsec: Verify that send_sci is on when setting Tx sci explicitly
net: macsec: Fix offload support for NETDEV_UNREGISTER event
net: ieee802154: Return meaningful error codes from the netlink helpers
net: ieee802154: ca8210: Stop leaking skb's
net: ieee802154: mcr20a: Fix lifs/sifs periods
net: ieee802154: hwsim: Ensure proper channel selection at probe time
spi: uniphier: fix reference count leak in uniphier_spi_probe()
spi: meson-spicc: add IRQ check in meson_spicc_probe
spi: mediatek: Avoid NULL pointer crash in interrupt
spi: bcm-qspi: check for valid cs before applying chip select
iommu/amd: Fix loop timeout issue in iommu_ga_log_enable()
iommu/vt-d: Fix potential memory leak in intel_setup_irq_remapping()
RDMA/mlx4: Don't continue event handler after memory allocation failure
RDMA/siw: Fix broken RDMA Read Fence/Resume logic.
IB/rdmavt: Validate remote_addr during loopback atomic tests
RDMA/ucma: Protect mc during concurrent multicast leaves
RDMA/cma: Use correct address when leaving multicast group
Revert "ASoC: mediatek: Check for error clk pointer"
IB/hfi1: Fix AIP early init panic
dma-buf: heaps: Fix potential spectre v1 gadget
block: bio-integrity: Advance seed correctly for larger interval sizes
mm/kmemleak: avoid scanning potential huge holes
mm/pgtable: define pte_index so that preprocessor could recognize it
mm/debug_vm_pgtable: remove pte entry from the page table
nvme-fabrics: fix state check in nvmf_ctlr_matches_baseopts()
drm/amd/display: Force link_rate as LINK_RATE_RBR2 for 2018 15" Apple Retina
panels
drm/nouveau: fix off by one in BIOS boundary checking
btrfs: fix deadlock between quota disable and qgroup rescan worker
ALSA: hda/realtek: Fix silent output on Gigabyte X570 Aorus Xtreme after reboot
from Windows
ALSA: hda/realtek: Fix silent output on Gigabyte X570S Aorus Master (newer
chipset)
ALSA: hda/realtek: Add missing fixup-model entry for Gigabyte X570 ALC1220
quirks
ALSA: hda/realtek: Add quirk for ASUS GU603
ALSA: hda: realtek: Fix race at concurrent COEF updates
ALSA: hda: Fix UAF of leds class devs at unbinding
ALSA: usb-audio: Correct quirk for VF0770
ASoC: ops: Reject out of bounds values in snd_soc_put_xr_sx()
ASoC: ops: Reject out of bounds values in snd_soc_put_volsw_sx()
ASoC: ops: Reject out of bounds values in snd_soc_put_volsw()
selinux: fix double free of cond_list on error paths
already merged:
audit: improve audit queue handling when "audit=1" on cmdline
memcg: charge fs_context and legacy_fs_context
Total patches: 74 - 2 = 72
Albert Geantă (1):
ALSA: hda/realtek: Add quirk for ASUS GU603
Andy Shevchenko (1):
pinctrl: intel: Fix a glitch when updating IRQ flags on a
preconfigured line
Arınç ÜNAL (1):
net: dsa: mt7530: make NET_DSA_MT7530 select MEDIATEK_GE_PHY
Aun-Ali Zaidi (1):
drm/amd/display: Force link_rate as LINK_RATE_RBR2 for 2018 15" Apple
Retina panels
Benjamin Gaignard (1):
spi: mediatek: Avoid NULL pointer crash in interrupt
Bernard Metzler (1):
RDMA/siw: Fix broken RDMA Read Fence/Resume logic.
Camel Guo (1):
net: stmmac: dump gmac4 DMA registers correctly
Christian Lachner (3):
ALSA: hda/realtek: Add missing fixup-model entry for Gigabyte X570
ALC1220 quirks
ALSA: hda/realtek: Fix silent output on Gigabyte X570S Aorus Master
(newer chipset)
ALSA: hda/realtek: Fix silent output on Gigabyte X570 Aorus Xtreme
after reboot from Windows
Dai Ngo (1):
nfsd: nfsd4_setclientid_confirm mistakenly expires confirmed client.
Dan Carpenter (2):
drm/i915/overlay: Prevent divide by zero bugs in scaling
ASoC: max9759: fix underflow in speaker_gain_control_put()
Florian Fainelli (1):
pinctrl: bcm2835: Fix a few error paths
Florian Westphal (1):
selftests: nft_concat_range: add test for reload with no element
add/del
Guenter Roeck (1):
Revert "ASoC: mediatek: Check for error clk pointer"
Guoqing Jiang (1):
iommu/vt-d: Fix potential memory leak in intel_setup_irq_remapping()
Haiyue Wang (1):
gve: fix the wrong AdminQ buffer queue index check
Helge Deller (2):
Revert "fbcon: Disable accelerated scrolling"
fbcon: Add option to enable legacy hardware acceleration
Hou Tao (1):
bpf: Use VM_MAP instead of VM_ALLOC for ringbuf
Ian Rogers (1):
perf stat: Fix display of grouped aliased events
Jiasheng Jiang (1):
ASoC: cpcap: Check for NULL pointer after calling of_get_child_by_name
Joerg Roedel (1):
iommu/amd: Fix loop timeout issue in iommu_ga_log_enable()
John Meneghini (1):
scsi: bnx2fc: Make bnx2fc_recv_frame() mp safe
Jonas Hahnfeld (1):
ALSA: usb-audio: Correct quirk for VF0770
Jordy Zomer (1):
dma-buf: heaps: Fix potential spectre v1 gadget
Kamal Dasu (1):
spi: bcm-qspi: check for valid cs before applying chip select
Lang Yu (1):
mm/kmemleak: avoid scanning potential huge holes
Leon Romanovsky (2):
RDMA/ucma: Protect mc during concurrent multicast leaves
RDMA/mlx4: Don't continue event handler after memory allocation
failure
Lior Nahmanson (2):
net: macsec: Fix offload support for NETDEV_UNREGISTER event
net: macsec: Verify that send_sci is on when setting Tx sci explicitly
Maor Gottlieb (1):
RDMA/cma: Use correct address when leaving multicast group
Mark Brown (3):
ASoC: ops: Reject out of bounds values in snd_soc_put_volsw()
ASoC: ops: Reject out of bounds values in snd_soc_put_volsw_sx()
ASoC: ops: Reject out of bounds values in snd_soc_put_xr_sx()
Martin K. Petersen (1):
block: bio-integrity: Advance seed correctly for larger interval sizes
Miaoqian Lin (2):
spi: meson-spicc: add IRQ check in meson_spicc_probe
ASoC: fsl: Add missing error handling in pcm030_fabric_probe
Mike Marciniszyn (2):
IB/hfi1: Fix AIP early init panic
IB/rdmavt: Validate remote_addr during loopback atomic tests
Mike Rapoport (1):
mm/pgtable: define pte_index so that preprocessor could recognize it
Miquel Raynal (4):
net: ieee802154: hwsim: Ensure proper channel selection at probe time
net: ieee802154: mcr20a: Fix lifs/sifs periods
net: ieee802154: ca8210: Stop leaking skb's
net: ieee802154: Return meaningful error codes from the netlink
helpers
Muhammad Usama Anjum (2):
selftests/exec: Remove pipe from TEST_GEN_FILES
selftests: futex: Use variable MAKE instead of make
Nathan Chancellor (1):
tools/resolve_btfids: Do not print any commands when building silently
Nick Lopez (1):
drm/nouveau: fix off by one in BIOS boundary checking
Pasha Tatashin (1):
mm/debug_vm_pgtable: remove pte entry from the page table
Peter Zijlstra (1):
x86/perf: Default set FREEZE_ON_SMI for all
Ritesh Harjani (2):
ext4: fix error handling in ext4_restore_inline_data()
ext4: fix error handling in ext4_fc_record_modified_inode()
Riwen Lu (1):
rtc: cmos: Evaluate century appropriate
Robert Hancock (1):
ASoC: xilinx: xlnx_formatter_pcm: Make buffer bytes multiple of period
bytes
Sergey Shtylyov (2):
EDAC/altera: Fix deferred probing
EDAC/xgene: Fix deferred probing
Shin'ichiro Kawasaki (1):
btrfs: fix deadlock between quota disable and qgroup rescan worker
Takashi Iwai (2):
ALSA: hda: Fix UAF of leds class devs at unbinding
ALSA: hda: realtek: Fix race at concurrent COEF updates
Tristan Hume (1):
perf/x86/intel/pt: Fix crash with stop filters in single-range mode
Uday Shankar (1):
nvme-fabrics: fix state check in nvmf_ctlr_matches_baseopts()
Vratislav Bendel (1):
selinux: fix double free of cond_list on error paths
Waiman Long (1):
cgroup/cpuset: Fix "suspicious RCU usage" lockdep warning
Xin Xiong (1):
spi: uniphier: fix reference count leak in uniphier_spi_probe()
Xin Yin (3):
ext4: prevent used blocks from being allocated during fast commit
replay
ext4: modify the logic of ext4_mb_new_blocks_simple
ext4: fix incorrect type issue during replay_del_range
Yannick Vignon (1):
net: stmmac: ensure PTP time register reads are consistent
Łukasz Bartosik (1):
pinctrl: intel: fix unexpected interrupt
Documentation/gpu/todo.rst | 18 ----
arch/x86/events/intel/core.c | 13 +++
arch/x86/events/intel/pt.c | 5 +-
block/bio-integrity.c | 2 +-
drivers/dma-buf/dma-heap.c | 2 +
drivers/edac/altera_edac.c | 2 +-
drivers/edac/xgene_edac.c | 2 +-
.../gpu/drm/amd/display/dc/core/dc_link_dp.c | 20 +++++
drivers/gpu/drm/i915/display/intel_overlay.c | 3 +
.../gpu/drm/nouveau/nvkm/subdev/bios/base.c | 2 +-
drivers/infiniband/core/cma.c | 22 ++---
drivers/infiniband/core/ucma.c | 34 ++++---
drivers/infiniband/hw/hfi1/ipoib_main.c | 13 +--
drivers/infiniband/hw/mlx4/main.c | 2 +-
drivers/infiniband/sw/rdmavt/qp.c | 2 +
drivers/infiniband/sw/siw/siw.h | 7 +-
drivers/infiniband/sw/siw/siw_qp_rx.c | 20 +++--
drivers/iommu/amd/init.c | 2 +
drivers/iommu/intel/irq_remapping.c | 13 ++-
drivers/net/dsa/Kconfig | 1 +
drivers/net/ethernet/google/gve/gve_adminq.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 +
.../ethernet/stmicro/stmmac/stmmac_ethtool.c | 19 +++-
.../ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 19 ++--
drivers/net/ieee802154/ca8210.c | 1 +
drivers/net/ieee802154/mac802154_hwsim.c | 1 +
drivers/net/ieee802154/mcr20a.c | 4 +-
drivers/net/macsec.c | 33 ++++---
drivers/nvme/host/fabrics.h | 1 +
drivers/pinctrl/bcm/pinctrl-bcm2835.c | 23 +++--
drivers/pinctrl/intel/pinctrl-intel.c | 64 +++++++------
drivers/rtc/rtc-mc146818-lib.c | 2 +-
drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 21 +++--
drivers/soc/mediatek/mtk-scpsys.c | 15 +---
drivers/spi/spi-bcm-qspi.c | 2 +-
drivers/spi/spi-meson-spicc.c | 5 ++
drivers/spi/spi-mt65xx.c | 2 +-
drivers/spi/spi-uniphier.c | 18 +++-
drivers/video/console/Kconfig | 20 +++++
drivers/video/fbdev/core/fbcon.c | 68 +++++++++++---
drivers/video/fbdev/core/fbcon.h | 15 +++-
drivers/video/fbdev/core/fbcon_ccw.c | 10 +--
drivers/video/fbdev/core/fbcon_cw.c | 10 +--
drivers/video/fbdev/core/fbcon_rotate.h | 4 +-
drivers/video/fbdev/core/fbcon_ud.c | 20 ++---
fs/btrfs/qgroup.c | 21 ++++-
fs/ext4/ext4.h | 3 +
fs/ext4/extents.c | 4 +
fs/ext4/fast_commit.c | 89 ++++++++++---------
fs/ext4/inline.c | 10 ++-
fs/ext4/mballoc.c | 26 ++++--
fs/nfsd/nfs4state.c | 4 +-
include/linux/pgtable.h | 1 +
kernel/bpf/ringbuf.c | 2 +-
kernel/cgroup/cpuset.c | 10 +++
mm/debug_vm_pgtable.c | 2 +
mm/kmemleak.c | 13 +--
net/ieee802154/nl802154.c | 8 +-
security/selinux/ss/conditional.c | 3 +-
sound/pci/hda/hda_generic.c | 17 +++-
sound/pci/hda/hda_generic.h | 3 +
sound/pci/hda/patch_realtek.c | 67 +++++++++++---
sound/soc/codecs/cpcap.c | 2 +
sound/soc/codecs/max9759.c | 3 +-
sound/soc/fsl/pcm030-audio-fabric.c | 11 ++-
sound/soc/soc-ops.c | 29 +++++-
sound/soc/xilinx/xlnx_formatter_pcm.c | 27 +++++-
sound/usb/quirks-table.h | 2 +-
tools/bpf/resolve_btfids/Makefile | 6 +-
tools/perf/util/stat-display.c | 19 ++--
tools/testing/selftests/exec/Makefile | 2 +-
tools/testing/selftests/futex/Makefile | 4 +-
.../selftests/netfilter/nft_concat_range.sh | 72 ++++++++++++++-
73 files changed, 725 insertions(+), 300 deletions(-)
--
2.20.1
1
72
Backport 5.10.98 LTS patches from upstream
Total patches: 2
Greg Kroah-Hartman (2):
Revert "drm/vc4: hdmi: Make sure the device is powered with CEC"
Revert "drm/vc4: hdmi: Make sure the device is powered with CEC" again
drivers/gpu/drm/vc4/vc4_hdmi.c | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)
--
2.20.1
1
2

[PATCH openEuler-22.03-LTS] psi: fix failure of create cgroup psi trigger
by Zheng Zengkai 17 May '22
by Zheng Zengkai 17 May '22
17 May '22
From: Chen Wandun <chenwandun(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I571CC
CVE: NA
--------------------------------
Create cgroup psi would fail after commit: 15b551804d8f
("psi: Fix uaf issue when psi trigger is destroyed while being polled"),
this is due to wrong use of priv member in kernfs_open_file.
Fixes: 15b551804d8f ("psi: Fix uaf issue when psi trigger is destroyed while being polled")
Signed-off-by: Chen Wandun <chenwandun(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
kernel/cgroup/cgroup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 7d47c3b6956f..57f4e19df8c6 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -3655,7 +3655,7 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf,
cgroup_kn_unlock(of->kn);
/* Allow only one trigger per file descriptor */
- if (of->priv) {
+ if (ctx->psi.trigger) {
cgroup_put(cgrp);
return -EBUSY;
}
--
2.20.1
1
0
您好!
Kernel SIG 邀请您参加 2022-05-20 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler kernel 双周例会&技术分享
会议内容:
openEuler kernel 技术分享:内核调度器简史
会议链接:https://us06web.zoom.us/j/81837728501?pwd=THk0TnBjc0ZFbXJ0ZnlJTzBxVCtWUT09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2022-05-20 14:00,
The subject of the conference is openEuler kernel 双周例会&技术分享,
Summary:
openEuler kernel 技术分享:内核调度器简史
You can join the meeting at https://us06web.zoom.us/j/81837728501?pwd=THk0TnBjc0ZFbXJ0ZnlJTzBxVCtWUT09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0

12 May '22
Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OLG
--------------------------------
It works well if these include headers are cleaned up.
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/chip/chip3/chip.c | 6 +----
arch/sw_64/chip/chip3/cpufreq_debugfs.c | 7 +----
arch/sw_64/chip/chip3/i2c-lib.c | 4 ---
arch/sw_64/chip/chip3/irq_chip.c | 13 +---------
arch/sw_64/chip/chip3/msi.c | 7 +----
arch/sw_64/chip/chip3/pci-quirks.c | 3 +--
arch/sw_64/chip/chip3/vt_msi.c | 6 -----
arch/sw_64/kernel/acpi.c | 19 +-------------
arch/sw_64/kernel/asm-offsets.c | 7 +++--
arch/sw_64/kernel/audit.c | 2 +-
arch/sw_64/kernel/cacheinfo.c | 3 +--
arch/sw_64/kernel/core.c | 18 -------------
arch/sw_64/kernel/crash_dump.c | 2 --
arch/sw_64/kernel/dup_print.c | 5 +---
arch/sw_64/kernel/early_printk.c | 4 +--
arch/sw_64/kernel/ftrace.c | 5 ----
arch/sw_64/kernel/insn.c | 13 ----------
arch/sw_64/kernel/irq.c | 15 -----------
arch/sw_64/kernel/irq_sw64.c | 9 +------
arch/sw_64/kernel/jump_label.c | 3 +--
arch/sw_64/kernel/kgdb.c | 3 ---
arch/sw_64/kernel/kprobes/decode-insn.c | 6 +----
arch/sw_64/kernel/kprobes/kprobes.c | 4 ---
arch/sw_64/kernel/kvm_cma.c | 4 ---
arch/sw_64/kernel/machine_kexec.c | 7 +----
arch/sw_64/kernel/module.c | 5 ----
arch/sw_64/kernel/msi.c | 7 -----
arch/sw_64/kernel/pci-noop.c | 8 ------
arch/sw_64/kernel/pci-sysfs.c | 3 ---
arch/sw_64/kernel/pci.c | 13 +---------
arch/sw_64/kernel/pci_common.c | 11 --------
arch/sw_64/kernel/perf_event.c | 12 ---------
arch/sw_64/kernel/perf_regs.c | 4 ---
arch/sw_64/kernel/process.c | 26 -------------------
arch/sw_64/kernel/ptrace.c | 15 +----------
arch/sw_64/kernel/relocate.c | 13 ++--------
arch/sw_64/kernel/segvdbg.c | 4 +--
arch/sw_64/kernel/setup.c | 34 +------------------------
arch/sw_64/kernel/signal.c | 14 ----------
arch/sw_64/kernel/smp.c | 25 +-----------------
arch/sw_64/kernel/stacktrace.c | 1 -
arch/sw_64/kernel/suspend.c | 12 +--------
arch/sw_64/kernel/tc.c | 3 ---
arch/sw_64/kernel/time.c | 27 ++------------------
arch/sw_64/kernel/timer.c | 13 +---------
arch/sw_64/kernel/topology.c | 13 ----------
arch/sw_64/kernel/traps.c | 13 ----------
arch/sw_64/kernel/unaligned.c | 3 ---
arch/sw_64/kernel/uprobes.c | 5 ----
arch/sw_64/kernel/vdso.c | 9 -------
arch/sw_64/kernel/vdso/vdso.S | 2 --
arch/sw_64/kernel/vdso/vgettimeofday.c | 3 +--
arch/sw_64/kvm/kvm-sw64.c | 13 ----------
arch/sw_64/lib/fls.c | 1 -
arch/sw_64/lib/iomap.c | 4 +--
arch/sw_64/lib/udelay.c | 5 ----
arch/sw_64/math-emu/math.c | 10 +++-----
arch/sw_64/mm/fault.c | 21 ++-------------
arch/sw_64/mm/hugetlbpage.c | 7 +----
arch/sw_64/mm/init.c | 23 -----------------
arch/sw_64/mm/numa.c | 16 ------------
arch/sw_64/mm/physaddr.c | 1 -
arch/sw_64/mm/thp.c | 9 -------
63 files changed, 36 insertions(+), 547 deletions(-)
diff --git a/arch/sw_64/chip/chip3/chip.c b/arch/sw_64/chip/chip3/chip.c
index 6c84f4d62e4e..bd20e262e609 100644
--- a/arch/sw_64/chip/chip3/chip.c
+++ b/arch/sw_64/chip/chip3/chip.c
@@ -1,16 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/pci.h>
-#include <linux/seq_file.h>
#include <linux/clocksource.h>
-#include <linux/msi.h>
-#include <linux/delay.h>
+
#include <asm/sw64_init.h>
#include <asm/sw64io.h>
#include <asm/pci.h>
-#include <asm/core.h>
#include <asm/irq_impl.h>
#include <asm/wrperfmon.h>
-#include <asm/hw_init.h>
#include "../../../../drivers/pci/pci.h"
static u64 read_longtime(struct clocksource *cs)
diff --git a/arch/sw_64/chip/chip3/cpufreq_debugfs.c b/arch/sw_64/chip/chip3/cpufreq_debugfs.c
index 3b152f84454f..13696360ef02 100644
--- a/arch/sw_64/chip/chip3/cpufreq_debugfs.c
+++ b/arch/sw_64/chip/chip3/cpufreq_debugfs.c
@@ -1,15 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/debugfs.h>
-#include <linux/list.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm_types.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
-#include <linux/mm.h>
+
#include <asm/sw64io.h>
-#include <asm/hw_init.h>
#include <asm/debug.h>
#define CLK_PRT 0x1UL
diff --git a/arch/sw_64/chip/chip3/i2c-lib.c b/arch/sw_64/chip/chip3/i2c-lib.c
index 581f2b3d81a1..ddf0a187ab5a 100644
--- a/arch/sw_64/chip/chip3/i2c-lib.c
+++ b/arch/sw_64/chip/chip3/i2c-lib.c
@@ -14,14 +14,10 @@
* of the interrupt mode.
*/
-#include <linux/module.h>
-#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/device.h>
#define CPLD_BUSNR 2
diff --git a/arch/sw_64/chip/chip3/irq_chip.c b/arch/sw_64/chip/chip3/irq_chip.c
index ee43e87c554b..24dfa1e1a898 100644
--- a/arch/sw_64/chip/chip3/irq_chip.c
+++ b/arch/sw_64/chip/chip3/irq_chip.c
@@ -1,18 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/of.h>
#include <linux/irqdomain.h>
#include <linux/irqchip.h>
-#include <asm/irq.h>
-#include <asm/sw64io.h>
+
#include <asm/irq_impl.h>
static void fake_irq_mask(struct irq_data *data)
diff --git a/arch/sw_64/chip/chip3/msi.c b/arch/sw_64/chip/chip3/msi.c
index 0c6d415e082e..43688c96ccab 100644
--- a/arch/sw_64/chip/chip3/msi.c
+++ b/arch/sw_64/chip/chip3/msi.c
@@ -1,15 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/irqdomain.h>
+
#include <asm/irq_impl.h>
-#include <asm/msi.h>
-#include <asm/pci.h>
-#include <asm/sw64io.h>
static struct irq_domain *msi_default_domain;
static DEFINE_RAW_SPINLOCK(vector_lock);
diff --git a/arch/sw_64/chip/chip3/pci-quirks.c b/arch/sw_64/chip/chip3/pci-quirks.c
index e70c211df68f..9043e56f9092 100644
--- a/arch/sw_64/chip/chip3/pci-quirks.c
+++ b/arch/sw_64/chip/chip3/pci-quirks.c
@@ -1,9 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/pci.h>
#include <linux/delay.h>
-#include <asm/pci.h>
+
#include <asm/sw64io.h>
-#include <asm/hw_init.h>
static int handshake(void __iomem *ptr, u32 mask, u32 done,
int wait_usec, int delay_usec)
diff --git a/arch/sw_64/chip/chip3/vt_msi.c b/arch/sw_64/chip/chip3/vt_msi.c
index 31f49d3c3511..428757642342 100644
--- a/arch/sw_64/chip/chip3/vt_msi.c
+++ b/arch/sw_64/chip/chip3/vt_msi.c
@@ -1,14 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/pci.h>
#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/msi.h>
-#include <asm/irq_impl.h>
-#include <asm/msi.h>
-#include <asm/pci.h>
-#include <asm/sw64io.h>
#define QEMU_MSIX_MSG_ADDR (0x8000fee00000UL)
diff --git a/arch/sw_64/kernel/acpi.c b/arch/sw_64/kernel/acpi.c
index 1c1afe8e812e..a0b5c4a57a07 100644
--- a/arch/sw_64/kernel/acpi.c
+++ b/arch/sw_64/kernel/acpi.c
@@ -2,25 +2,8 @@
#include <linux/init.h>
#include <linux/acpi.h>
-#include <linux/acpi_pmtmr.h>
-#include <linux/efi.h>
-#include <linux/stddef.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/dmi.h>
-#include <linux/irq.h>
#include <linux/irqdomain.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/memblock.h>
-#include <acpi/actbl.h>
-#include <acpi/actbl2.h>
-
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/numa.h>
+
#include <asm/early_ioremap.h>
int acpi_disabled = 1;
diff --git a/arch/sw_64/kernel/asm-offsets.c b/arch/sw_64/kernel/asm-offsets.c
index 44e7fa77265e..bea12d2d96fe 100644
--- a/arch/sw_64/kernel/asm-offsets.c
+++ b/arch/sw_64/kernel/asm-offsets.c
@@ -5,17 +5,16 @@
* and format the required data.
*/
-#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/sched.h>
-#include <linux/ptrace.h>
#include <linux/kbuild.h>
#include <linux/suspend.h>
-#include <asm/io.h>
+
#include <asm/suspend.h>
+#include <asm/kvm.h>
+
#include "traps.c"
-#include <asm/kvm.h>
void foo(void)
{
DEFINE(TI_TASK, offsetof(struct thread_info, task));
diff --git a/arch/sw_64/kernel/audit.c b/arch/sw_64/kernel/audit.c
index adc4622211d2..dcf58deee3e2 100644
--- a/arch/sw_64/kernel/audit.c
+++ b/arch/sw_64/kernel/audit.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/init.h>
-#include <linux/types.h>
#include <linux/audit.h>
+
#include <asm/unistd.h>
static unsigned int dir_class[] = {
diff --git a/arch/sw_64/kernel/cacheinfo.c b/arch/sw_64/kernel/cacheinfo.c
index 5193d7544b59..87d3f4bcd10f 100644
--- a/arch/sw_64/kernel/cacheinfo.c
+++ b/arch/sw_64/kernel/cacheinfo.c
@@ -14,9 +14,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/arch_topology.h>
#include <linux/cacheinfo.h>
-#include <asm/hw_init.h>
+
#include <asm/topology.h>
/* Populates leaf and increments to next leaf */
diff --git a/arch/sw_64/kernel/core.c b/arch/sw_64/kernel/core.c
index 4d440de68aae..e26b3a5faab2 100644
--- a/arch/sw_64/kernel/core.c
+++ b/arch/sw_64/kernel/core.c
@@ -1,24 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/memblock.h>
-#include <linux/pfn.h>
-#include <linux/export.h>
-#include <asm/core.h>
-#include <asm/tlbflush.h>
-#include <asm/smp.h>
-#include <asm/compiler.h>
-#include <asm/mmu_context.h>
-#include <asm/bitops.h>
-#include <asm/sw64_init.h>
-#include <asm/hw_init.h>
-#ifdef CONFIG_NUMA
-#include <asm/memory.h>
-#endif
-#include "pci_impl.h"
#ifdef CONFIG_DISCONTIGMEM
#ifdef CONFIG_NUMA
diff --git a/arch/sw_64/kernel/crash_dump.c b/arch/sw_64/kernel/crash_dump.c
index f3836afe3e25..4484673823b8 100644
--- a/arch/sw_64/kernel/crash_dump.c
+++ b/arch/sw_64/kernel/crash_dump.c
@@ -14,8 +14,6 @@
* published by the Free Software Foundation.
*/
-#include <linux/errno.h>
-#include <linux/crash_dump.h>
#include <linux/uaccess.h>
#include <linux/io.h>
diff --git a/arch/sw_64/kernel/dup_print.c b/arch/sw_64/kernel/dup_print.c
index e1c05cfa864b..1aa7710b5092 100644
--- a/arch/sw_64/kernel/dup_print.c
+++ b/arch/sw_64/kernel/dup_print.c
@@ -1,11 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/uaccess.h>
+
#include <asm/chip3_io.h>
#ifdef CONFIG_SW64_RRK
diff --git a/arch/sw_64/kernel/early_printk.c b/arch/sw_64/kernel/early_printk.c
index f4d5f2d5c876..62902175217a 100644
--- a/arch/sw_64/kernel/early_printk.c
+++ b/arch/sw_64/kernel/early_printk.c
@@ -1,9 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/console.h>
#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/errno.h>
+
#include <asm/io.h>
static unsigned long early_serial_base; /* ttyS0 */
diff --git a/arch/sw_64/kernel/ftrace.c b/arch/sw_64/kernel/ftrace.c
index 413562b5d9be..42efca28d386 100644
--- a/arch/sw_64/kernel/ftrace.c
+++ b/arch/sw_64/kernel/ftrace.c
@@ -10,13 +10,8 @@
*/
#include <linux/ftrace.h>
-#include <linux/module.h>
-#include <linux/swab.h>
-#include <linux/uaccess.h>
-#include <asm/cacheflush.h>
#include <asm/ftrace.h>
-#include <asm/insn.h>
#ifdef CONFIG_FUNCTION_TRACER
EXPORT_SYMBOL(_mcount);
diff --git a/arch/sw_64/kernel/insn.c b/arch/sw_64/kernel/insn.c
index 71d3832d1fe3..e8dd41b6b7c4 100644
--- a/arch/sw_64/kernel/insn.c
+++ b/arch/sw_64/kernel/insn.c
@@ -14,22 +14,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/bitops.h>
-#include <linux/bug.h>
-#include <linux/compiler.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
#include <linux/spinlock.h>
-#include <linux/stop_machine.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
#include <linux/kprobes.h>
-#include <asm/cacheflush.h>
-#include <asm/insn.h>
-
-
//static DEFINE_RAW_SPINLOCK(patch_lock);
int __kprobes sw64_insn_read(void *addr, u32 *insnp)
diff --git a/arch/sw_64/kernel/irq.c b/arch/sw_64/kernel/irq.c
index 6cd26af15b23..126fe2f70495 100644
--- a/arch/sw_64/kernel/irq.c
+++ b/arch/sw_64/kernel/irq.c
@@ -12,24 +12,9 @@
*/
#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
#include <linux/interrupt.h>
-#include <linux/random.h>
#include <linux/irq.h>
-#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/profile.h>
-#include <linux/bitops.h>
-#include <linux/uaccess.h>
-
-#include <asm/hw_init.h>
-#include <asm/hardirq.h>
-#include <asm/io.h>
volatile unsigned long irq_err_count;
DEFINE_PER_CPU(unsigned long, irq_pmi_count);
diff --git a/arch/sw_64/kernel/irq_sw64.c b/arch/sw_64/kernel/irq_sw64.c
index 376e8397ba35..8ab845d153eb 100644
--- a/arch/sw_64/kernel/irq_sw64.c
+++ b/arch/sw_64/kernel/irq_sw64.c
@@ -3,18 +3,11 @@
* SW64 specific irq code.
*/
-#include <linux/sched.h>
#include <linux/irq.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
#include <linux/irqchip.h>
-#include <linux/irqdesc.h>
-#include <linux/irqdomain.h>
+
#include <asm/dma.h>
#include <asm/irq_impl.h>
-#include <asm/core.h>
-#include <asm/perf_event.h>
-#include <asm/hmcall.h>
asmlinkage void
do_entInt(unsigned long type, unsigned long vector,
diff --git a/arch/sw_64/kernel/jump_label.c b/arch/sw_64/kernel/jump_label.c
index a67d16eb3076..f3bc40370e4d 100644
--- a/arch/sw_64/kernel/jump_label.c
+++ b/arch/sw_64/kernel/jump_label.c
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/kernel.h>
#include <linux/jump_label.h>
-#include <asm/insn.h>
+
#include <asm/bug.h>
#include <asm/cacheflush.h>
diff --git a/arch/sw_64/kernel/kgdb.c b/arch/sw_64/kernel/kgdb.c
index c1100ef8fcdd..09e9ca7a0303 100644
--- a/arch/sw_64/kernel/kgdb.c
+++ b/arch/sw_64/kernel/kgdb.c
@@ -20,11 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/irq.h>
#include <linux/kdebug.h>
#include <linux/kgdb.h>
-#include <linux/uaccess.h>
-#include <asm/cacheflush.h>
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "r0", 8, offsetof(struct pt_regs, r0)},
diff --git a/arch/sw_64/kernel/kprobes/decode-insn.c b/arch/sw_64/kernel/kprobes/decode-insn.c
index e3ab856d6084..d376a7e2bee4 100644
--- a/arch/sw_64/kernel/kprobes/decode-insn.c
+++ b/arch/sw_64/kernel/kprobes/decode-insn.c
@@ -12,12 +12,8 @@
* General Public License for more details.
*/
-#include <linux/kernel.h>
#include <linux/kprobes.h>
-#include <linux/module.h>
-#include <linux/kallsyms.h>
-#include <asm/insn.h>
-#include <asm/sections.h>
+
#include "common.h"
static bool __kprobes sw64_insn_is_steppable(u32 insn)
diff --git a/arch/sw_64/kernel/kprobes/kprobes.c b/arch/sw_64/kernel/kprobes/kprobes.c
index 85400f96f991..59f040eaa3e1 100644
--- a/arch/sw_64/kernel/kprobes/kprobes.c
+++ b/arch/sw_64/kernel/kprobes/kprobes.c
@@ -5,13 +5,9 @@
*/
#include <linux/kprobes.h>
-#include <linux/preempt.h>
-#include <linux/uaccess.h>
#include <linux/kdebug.h>
#include <linux/slab.h>
-#include <asm/ptrace.h>
-#include <asm/insn.h>
#include "common.h"
static u32 breakpoint_insn = BREAK_KPROBE;
diff --git a/arch/sw_64/kernel/kvm_cma.c b/arch/sw_64/kernel/kvm_cma.c
index dc61e2e369e8..054dec95b996 100644
--- a/arch/sw_64/kernel/kvm_cma.c
+++ b/arch/sw_64/kernel/kvm_cma.c
@@ -10,12 +10,8 @@
#include <linux/memblock.h>
#include <linux/err.h>
-#include <linux/mm.h>
#include <linux/sizes.h>
#include <linux/slab.h>
-#include <linux/log2.h>
-#include <linux/highmem.h>
-#include <linux/io.h>
#include <linux/cma.h>
#include <linux/page-isolation.h>
diff --git a/arch/sw_64/kernel/machine_kexec.c b/arch/sw_64/kernel/machine_kexec.c
index c778bc1374af..c9ca7a728bd4 100644
--- a/arch/sw_64/kernel/machine_kexec.c
+++ b/arch/sw_64/kernel/machine_kexec.c
@@ -5,18 +5,13 @@
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
-#include <linux/compiler.h>
#include <linux/kexec.h>
#include <linux/mm.h>
-#include <linux/device.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/reboot.h>
+
#include <asm/cacheflush.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
extern void *kexec_control_page;
extern const unsigned char relocate_new_kernel[];
diff --git a/arch/sw_64/kernel/module.c b/arch/sw_64/kernel/module.c
index d2041afba7bb..2904bb750eb5 100644
--- a/arch/sw_64/kernel/module.c
+++ b/arch/sw_64/kernel/module.c
@@ -1,10 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
#include <linux/slab.h>
#define DEBUGP(fmt...)
diff --git a/arch/sw_64/kernel/msi.c b/arch/sw_64/kernel/msi.c
index d942a688a324..ee1bda3c6447 100644
--- a/arch/sw_64/kernel/msi.c
+++ b/arch/sw_64/kernel/msi.c
@@ -1,14 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
#include <linux/irq.h>
-#include <linux/kernel.h>
#include <linux/msi.h>
-#include <linux/pci.h>
-#include <linux/cpumask.h>
-#include <asm/sw64io.h>
-#include <asm/msi.h>
-#include <asm/pci.h>
-
int msi_compose_msg(unsigned int irq, struct msi_msg *msg)
{
diff --git a/arch/sw_64/kernel/pci-noop.c b/arch/sw_64/kernel/pci-noop.c
index 4ef694e629e8..a0aa2e5bb675 100644
--- a/arch/sw_64/kernel/pci-noop.c
+++ b/arch/sw_64/kernel/pci-noop.c
@@ -6,16 +6,8 @@
*/
#include <linux/pci.h>
-#include <linux/init.h>
#include <linux/memblock.h>
-#include <linux/gfp.h>
-#include <linux/capability.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <linux/module.h>
/*
* The PCI controller list.
diff --git a/arch/sw_64/kernel/pci-sysfs.c b/arch/sw_64/kernel/pci-sysfs.c
index 584243922df9..504fd4a00754 100644
--- a/arch/sw_64/kernel/pci-sysfs.c
+++ b/arch/sw_64/kernel/pci-sysfs.c
@@ -10,9 +10,6 @@
* drivers/pci/pci-sysfs.c
*/
-#include <linux/sched.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
#include <linux/pci.h>
static int hose_mmap_page_range(struct pci_controller *hose,
diff --git a/arch/sw_64/kernel/pci.c b/arch/sw_64/kernel/pci.c
index d42f0d0aec92..fb7b071c10f6 100644
--- a/arch/sw_64/kernel/pci.c
+++ b/arch/sw_64/kernel/pci.c
@@ -1,22 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/string.h>
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
#include <linux/memblock.h>
-#include <linux/module.h>
-#include <linux/cache.h>
-#include <linux/slab.h>
-#include <linux/msi.h>
-#include <linux/irq.h>
-#include <asm/msi.h>
-#include <linux/delay.h>
#include <linux/syscore_ops.h>
-#include <linux/platform_device.h>
+
#include <asm/sw64_init.h>
-#include <asm/pci.h>
#include "pci_impl.h"
diff --git a/arch/sw_64/kernel/pci_common.c b/arch/sw_64/kernel/pci_common.c
index f6316ca507a2..f996baca9d93 100644
--- a/arch/sw_64/kernel/pci_common.c
+++ b/arch/sw_64/kernel/pci_common.c
@@ -3,22 +3,11 @@
* linux/arch/sw_64/kernel/pci_iommu.c
*/
-#include <linux/kernel.h>
-#include <linux/mm.h>
#include <linux/pci.h>
-#include <linux/gfp.h>
-#include <linux/memblock.h>
#include <linux/export.h>
-#include <linux/scatterlist.h>
-#include <linux/log2.h>
#include <linux/dma-mapping.h>
-#include <linux/iommu-helper.h>
-#include <linux/slab.h>
#include <linux/dma-direct.h>
#include <linux/swiotlb.h>
-#include <linux/cache.h>
-#include <linux/module.h>
-#include <asm/dma.h>
static dma_addr_t sw64_direct_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
diff --git a/arch/sw_64/kernel/perf_event.c b/arch/sw_64/kernel/perf_event.c
index dac979d4b09a..d2975e17f666 100644
--- a/arch/sw_64/kernel/perf_event.c
+++ b/arch/sw_64/kernel/perf_event.c
@@ -6,18 +6,6 @@
*/
#include <linux/perf_event.h>
-#include <linux/kprobes.h>
-#include <linux/kernel.h>
-#include <linux/kdebug.h>
-#include <linux/mutex.h>
-#include <linux/init.h>
-#include <linux/uaccess.h>
-
-#include <linux/atomic.h>
-#include <asm/irq.h>
-#include <asm/irq_regs.h>
-#include <asm/hmcall.h>
-#include <asm/hw_irq.h>
/* For tracking PMCs and the hw events they monitor on each CPU. */
struct cpu_hw_events {
diff --git a/arch/sw_64/kernel/perf_regs.c b/arch/sw_64/kernel/perf_regs.c
index 8eec2179eb86..4c12a2cdf912 100644
--- a/arch/sw_64/kernel/perf_regs.c
+++ b/arch/sw_64/kernel/perf_regs.c
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/errno.h>
-#include <linux/kernel.h>
#include <linux/perf_event.h>
-#include <linux/bug.h>
-#include <linux/perf_regs.h>
-#include <asm/ptrace.h>
u64 perf_reg_value(struct pt_regs *regs, int idx)
{
diff --git a/arch/sw_64/kernel/process.c b/arch/sw_64/kernel/process.c
index 8fd493776bec..4192d50f5b0e 100644
--- a/arch/sw_64/kernel/process.c
+++ b/arch/sw_64/kernel/process.c
@@ -3,42 +3,16 @@
* This file handles the architecture-dependent parts of process handling.
*/
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/sched/debug.h>
-#include <linux/sched/task.h>
-#include <linux/sched/task_stack.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/time.h>
-#include <linux/major.h>
-#include <linux/stat.h>
-#include <linux/vt.h>
-#include <linux/mman.h>
#include <linux/elfcore.h>
#include <linux/reboot.h>
-#include <linux/tty.h>
-#include <linux/console.h>
#include <linux/slab.h>
-#include <linux/rcupdate.h>
-#include <linux/tick.h>
#include <linux/random.h>
-#include <linux/uaccess.h>
-#include <asm/reg.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/fpu.h>
-#include <asm/hcall.h>
#include "proto.h"
-#include "pci_impl.h"
/*
* Power off function, if any
diff --git a/arch/sw_64/kernel/ptrace.c b/arch/sw_64/kernel/ptrace.c
index ede3c1053d81..649572bbe613 100644
--- a/arch/sw_64/kernel/ptrace.c
+++ b/arch/sw_64/kernel/ptrace.c
@@ -5,24 +5,11 @@
/* mangled further by Bob Manson (manson(a)santafe.edu) */
/* more mutilation by David Mosberger (davidm(a)azstarnet.com) */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/security.h>
-#include <linux/signal.h>
#include <linux/tracehook.h>
-#include <linux/seccomp.h>
#include <linux/audit.h>
-#include <linux/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/fpu.h>
-#include <asm/core.h>
#include <asm/reg.h>
+
#include "proto.h"
#define CREATE_TRACE_POINTS
diff --git a/arch/sw_64/kernel/relocate.c b/arch/sw_64/kernel/relocate.c
index 36b16d84d5ab..fe403f9c70c7 100644
--- a/arch/sw_64/kernel/relocate.c
+++ b/arch/sw_64/kernel/relocate.c
@@ -9,21 +9,12 @@
* Copyright (C) 2019 He Sheng
* Authors: He Sheng (hesheng05(a)gmail.com)
*/
-#include <asm/hmcall.h>
-#include <asm/setup.h>
-#include <asm/sections.h>
-#include <linux/mm_types.h>
#include <linux/elf.h>
-#include <linux/kernel.h>
-#include <linux/libfdt.h>
-#include <linux/of_fdt.h>
-#include <linux/sched.h>
-#include <linux/start_kernel.h>
-#include <linux/string.h>
-#include <linux/printk.h>
#include <linux/notifier.h>
#include <linux/mm.h>
+#include <asm/sections.h>
+
#define INITRD_ADDR 0x3000000UL
#define KTEXT_MAX 0xffffffffa0000000UL
#define RELOCATED(x) ((void *)((unsigned long)x + offset))
diff --git a/arch/sw_64/kernel/segvdbg.c b/arch/sw_64/kernel/segvdbg.c
index aee4b3863072..5b8a638bf8b9 100644
--- a/arch/sw_64/kernel/segvdbg.c
+++ b/arch/sw_64/kernel/segvdbg.c
@@ -9,9 +9,7 @@
*/
#include <linux/kernel.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
+
#include <asm/debug.h>
extern bool segv_debug_enabled;
diff --git a/arch/sw_64/kernel/setup.c b/arch/sw_64/kernel/setup.c
index 61b498e65e4b..2de954a3c086 100644
--- a/arch/sw_64/kernel/setup.c
+++ b/arch/sw_64/kernel/setup.c
@@ -9,31 +9,13 @@
* Bootup setup stuff.
*/
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
#include <linux/screen_info.h>
#include <linux/delay.h>
#include <linux/kexec.h>
#include <linux/console.h>
-#include <linux/cpu.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
#include <linux/memblock.h>
-#include <linux/pci.h>
-#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/initrd.h>
-#include <linux/eisa.h>
-#include <linux/pfn.h>
#ifdef CONFIG_MAGIC_SYSRQ
#include <linux/sysrq.h>
#include <linux/reboot.h>
@@ -41,26 +23,12 @@
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#endif
-#include <linux/notifier.h>
-#include <linux/log2.h>
-#include <linux/export.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
-#include <linux/uaccess.h>
-#include <linux/cma.h>
#include <linux/genalloc.h>
#include <linux/acpi.h>
-#include <asm/setup.h>
-#include <asm/smp.h>
+
#include <asm/sw64_init.h>
-#include <asm/pgtable.h>
-#include <asm/dma.h>
-#include <asm/mmu_context.h>
-#include <asm/console.h>
-#include <asm/core.h>
-#include <asm/hw_init.h>
-#include <asm/mmzone.h>
-#include <asm/memory.h>
#include <asm/efi.h>
#include <asm/kvm_cma.h>
diff --git a/arch/sw_64/kernel/signal.c b/arch/sw_64/kernel/signal.c
index 74e98063c874..f7b8d391251a 100644
--- a/arch/sw_64/kernel/signal.c
+++ b/arch/sw_64/kernel/signal.c
@@ -7,24 +7,10 @@
* 1997-11-02 Modified for POSIX.1b signals by Richard Henderson
*/
-#include <linux/sched.h>
-#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
-#include <linux/tty.h>
-#include <linux/binfmts.h>
-#include <linux/bitops.h>
-#include <linux/syscalls.h>
#include <linux/tracehook.h>
-#include <linux/uaccess.h>
-#include <asm/sigcontext.h>
#include <asm/ucontext.h>
#include <asm/vdso.h>
diff --git a/arch/sw_64/kernel/smp.c b/arch/sw_64/kernel/smp.c
index 7d9c5c90f1ac..fb915d166069 100644
--- a/arch/sw_64/kernel/smp.c
+++ b/arch/sw_64/kernel/smp.c
@@ -4,41 +4,18 @@
*/
#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
#include <linux/sched/mm.h>
#include <linux/sched/hotplug.h>
-#include <linux/mm.h>
-#include <linux/err.h>
-#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/spinlock.h>
#include <linux/irq.h>
-#include <linux/cache.h>
-#include <linux/profile.h>
-#include <linux/bitops.h>
#include <linux/cpu.h>
-#include <asm/ptrace.h>
-#include <linux/atomic.h>
-
-#include <asm/core.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
-#include <asm/suspend.h>
-#include <asm/hcall.h>
-#include <asm/sw64io.h>
#include <asm/sw64_init.h>
#include <asm/topology.h>
-#include <asm/tc.h>
+
#include "proto.h"
struct smp_rcb_struct *smp_rcb;
diff --git a/arch/sw_64/kernel/stacktrace.c b/arch/sw_64/kernel/stacktrace.c
index bb501c14565b..41cdff5b4941 100644
--- a/arch/sw_64/kernel/stacktrace.c
+++ b/arch/sw_64/kernel/stacktrace.c
@@ -6,7 +6,6 @@
*/
#include <linux/sched.h>
#include <linux/stacktrace.h>
-#include <linux/export.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/debug.h>
diff --git a/arch/sw_64/kernel/suspend.c b/arch/sw_64/kernel/suspend.c
index b2b07ac3042b..c5de4df9d084 100644
--- a/arch/sw_64/kernel/suspend.c
+++ b/arch/sw_64/kernel/suspend.c
@@ -1,17 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/suspend.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/irq.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/ptrace.h>
+
#include <asm/suspend.h>
-#include <asm/smp.h>
-#include <asm/io.h>
-#include <asm/hmcall.h>
-#include <asm/delay.h>
-#include <asm/sw64io.h>
#include <asm/sw64_init.h>
struct processor_state suspend_state;
diff --git a/arch/sw_64/kernel/tc.c b/arch/sw_64/kernel/tc.c
index c047d457e55a..f2de5ac3d9dc 100644
--- a/arch/sw_64/kernel/tc.c
+++ b/arch/sw_64/kernel/tc.c
@@ -5,9 +5,6 @@
#include <linux/topology.h>
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
#include <asm/tc.h>
/*
diff --git a/arch/sw_64/kernel/time.c b/arch/sw_64/kernel/time.c
index 185db832dfb8..15035a01e48a 100644
--- a/arch/sw_64/kernel/time.c
+++ b/arch/sw_64/kernel/time.c
@@ -1,34 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/errno.h>
#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/bcd.h>
-#include <linux/profile.h>
-#include <linux/irq_work.h>
-#include <linux/uaccess.h>
-
-#include <asm/io.h>
-#include <asm/sw64io.h>
-#include <asm/sw64_init.h>
-#include <asm/hw_init.h>
-#include <asm/irq_impl.h>
-#include <asm/debug.h>
-
#include <linux/time.h>
-#include <linux/timex.h>
-#include <linux/clocksource.h>
#include <linux/clk-provider.h>
-#include <linux/sched/clock.h>
-#include <linux/sched_clock.h>
+
+#include <asm/debug.h>
#include "proto.h"
diff --git a/arch/sw_64/kernel/timer.c b/arch/sw_64/kernel/timer.c
index c29e7d1b664b..60c75096d8c4 100644
--- a/arch/sw_64/kernel/timer.c
+++ b/arch/sw_64/kernel/timer.c
@@ -4,20 +4,9 @@
* Description: percpu local timer, based on arch/x86/kernel/apic/apic.c
*/
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/memblock.h>
#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/ioport.h>
-#include <linux/cpu.h>
#include <linux/clockchips.h>
-#include <linux/acpi_pmtmr.h>
-#include <linux/module.h>
-#include <linux/dmi.h>
-#include <linux/dmar.h>
-#include <asm/hcall.h>
+
#include <asm/hw_init.h>
#include <asm/hardirq.h>
diff --git a/arch/sw_64/kernel/topology.c b/arch/sw_64/kernel/topology.c
index 2e2878ba8656..964d6a83d901 100644
--- a/arch/sw_64/kernel/topology.c
+++ b/arch/sw_64/kernel/topology.c
@@ -1,20 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/acpi.h>
-#include <linux/arch_topology.h>
-#include <linux/cacheinfo.h>
-#include <linux/cpu.h>
-#include <linux/cpumask.h>
-#include <linux/init.h>
-#include <linux/percpu.h>
-#include <linux/node.h>
-#include <linux/nodemask.h>
#include <linux/of.h>
-#include <linux/sched.h>
-#include <linux/sched/topology.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-#include <linux/string.h>
#include <asm/topology.h>
diff --git a/arch/sw_64/kernel/traps.c b/arch/sw_64/kernel/traps.c
index d4354d72d6aa..2090eda082cf 100644
--- a/arch/sw_64/kernel/traps.c
+++ b/arch/sw_64/kernel/traps.c
@@ -9,29 +9,16 @@
* This file initializes the trap entry points
*/
-#include <linux/jiffies.h>
-#include <linux/mm.h>
-#include <linux/sched/signal.h>
-#include <linux/sched/debug.h>
-#include <linux/tty.h>
-#include <linux/delay.h>
#include <linux/extable.h>
-#include <linux/kallsyms.h>
-#include <linux/ratelimit.h>
-#include <linux/uaccess.h>
#include <linux/perf_event.h>
#include <linux/kdebug.h>
#include <linux/kexec.h>
#include <asm/gentrap.h>
-#include <asm/unaligned.h>
-#include <asm/sysinfo.h>
#include <asm/mmu_context.h>
-#include <asm/special_insns.h>
#include <asm/fpu.h>
#include <asm/kprobes.h>
#include <asm/uprobes.h>
-#include <asm/core.h>
#include "proto.h"
diff --git a/arch/sw_64/kernel/unaligned.c b/arch/sw_64/kernel/unaligned.c
index 4ec1187d6cd0..a1bbdab4a266 100644
--- a/arch/sw_64/kernel/unaligned.c
+++ b/arch/sw_64/kernel/unaligned.c
@@ -12,9 +12,6 @@
* for more details.
*/
-#include <linux/kernel.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
#include <asm/unaligned.h>
#include <asm/debug.h>
diff --git a/arch/sw_64/kernel/uprobes.c b/arch/sw_64/kernel/uprobes.c
index d10464d0dcdd..786f2e38a59f 100644
--- a/arch/sw_64/kernel/uprobes.c
+++ b/arch/sw_64/kernel/uprobes.c
@@ -1,14 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/highmem.h>
#include <linux/kdebug.h>
-#include <linux/types.h>
-#include <linux/notifier.h>
-#include <linux/sched.h>
#include <linux/uprobes.h>
#include <linux/ptrace.h>
-#include <asm/ptrace.h>
-
#define UPROBE_TRAP_NR ULONG_MAX
/**
diff --git a/arch/sw_64/kernel/vdso.c b/arch/sw_64/kernel/vdso.c
index 32ed952748f0..b4126cbaa4bd 100644
--- a/arch/sw_64/kernel/vdso.c
+++ b/arch/sw_64/kernel/vdso.c
@@ -14,20 +14,11 @@
*
*/
-#include <linux/kernel.h>
-#include <linux/clocksource.h>
#include <linux/elf.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/gfp.h>
#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/timekeeper_internal.h>
-#include <linux/vmalloc.h>
-#include <asm/cacheflush.h>
#include <asm/vdso.h>
extern char vdso_start, vdso_end;
diff --git a/arch/sw_64/kernel/vdso/vdso.S b/arch/sw_64/kernel/vdso/vdso.S
index ce5448d00cf7..edd9be27db9d 100644
--- a/arch/sw_64/kernel/vdso/vdso.S
+++ b/arch/sw_64/kernel/vdso/vdso.S
@@ -15,9 +15,7 @@
*
*/
-#include <linux/init.h>
#include <linux/linkage.h>
-#include <linux/const.h>
#include <asm/page.h>
__PAGE_ALIGNED_DATA
diff --git a/arch/sw_64/kernel/vdso/vgettimeofday.c b/arch/sw_64/kernel/vdso/vgettimeofday.c
index 3579e0eddfe2..b9c9a137f9d3 100644
--- a/arch/sw_64/kernel/vdso/vgettimeofday.c
+++ b/arch/sw_64/kernel/vdso/vgettimeofday.c
@@ -13,10 +13,9 @@
*/
#include <linux/time.h>
-#include <asm/timex.h>
+
#include <asm/unistd.h>
#include <asm/vdso.h>
-#include <asm/io.h>
static __always_inline int syscall_fallback(clockid_t clkid, struct timespec64 *ts)
{
diff --git a/arch/sw_64/kvm/kvm-sw64.c b/arch/sw_64/kvm/kvm-sw64.c
index cc9817037b58..bc24a4711311 100644
--- a/arch/sw_64/kvm/kvm-sw64.c
+++ b/arch/sw_64/kvm/kvm-sw64.c
@@ -5,31 +5,18 @@
* linhn <linhn(a)example.com>
*/
-#include <linux/cpu.h>
#include <linux/errno.h>
-#include <linux/err.h>
#include <linux/kvm_host.h>
#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
#include <linux/mman.h>
#include <linux/sched/signal.h>
-#include <linux/freezer.h>
-#include <linux/smp.h>
#include <linux/kvm.h>
#include <linux/uaccess.h>
-#include <linux/genalloc.h>
-#include <asm/kvm_emulate.h>
-#include <asm/kvm_asm.h>
-#include <asm/sw64io.h>
#include <asm/kvm_timer.h>
-#include <asm/kvm_host.h>
#include <asm/kvm_emulate.h>
-#include <asm/page.h>
#include "../kernel/pci_impl.h"
-
#include "vmem.c"
bool set_msi_flag;
diff --git a/arch/sw_64/lib/fls.c b/arch/sw_64/lib/fls.c
index e960b1c06782..aa4231f7e472 100644
--- a/arch/sw_64/lib/fls.c
+++ b/arch/sw_64/lib/fls.c
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
-#include <linux/bitops.h>
/* This is fls(x)-1, except zero is held to zero. This allows most
* efficient input into extbl, plus it allows easy handling of fls(0)=0.
diff --git a/arch/sw_64/lib/iomap.c b/arch/sw_64/lib/iomap.c
index 30d24923624d..39e3d5498ae6 100644
--- a/arch/sw_64/lib/iomap.c
+++ b/arch/sw_64/lib/iomap.c
@@ -3,10 +3,8 @@
* Sw_64 IO and memory functions.
*/
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
#include <linux/module.h>
+
#include <asm/io.h>
/*
diff --git a/arch/sw_64/lib/udelay.c b/arch/sw_64/lib/udelay.c
index 595887caa7b3..48356ab8872f 100644
--- a/arch/sw_64/lib/udelay.c
+++ b/arch/sw_64/lib/udelay.c
@@ -6,11 +6,6 @@
*/
#include <linux/module.h>
-#include <linux/sched.h> /* for udelay's use of smp_processor_id */
-#include <asm/param.h>
-#include <asm/smp.h>
-#include <asm/hw_init.h>
-#include <linux/delay.h>
/*
* Use only for very small delays (< 1 msec).
diff --git a/arch/sw_64/math-emu/math.c b/arch/sw_64/math-emu/math.c
index 3903b421b8f4..9f281d82ad83 100644
--- a/arch/sw_64/math-emu/math.c
+++ b/arch/sw_64/math-emu/math.c
@@ -8,16 +8,12 @@
* fire3 2008-12-27 Add SIMD floating emulation code for SW64
*/
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <asm/ptrace.h>
-
-
#include <linux/uaccess.h>
+#include <asm/ptrace.h>
+
#include "sfp-util.h"
+
#include <math-emu/soft-fp.h>
#include <math-emu/single.h>
#include <math-emu/double.h>
diff --git a/arch/sw_64/mm/fault.c b/arch/sw_64/mm/fault.c
index c68be4a40d23..b580450893ba 100644
--- a/arch/sw_64/mm/fault.c
+++ b/arch/sw_64/mm/fault.c
@@ -3,28 +3,11 @@
* Copyright (C) 1995 Linus Torvalds
*/
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <asm/io.h>
-
-#include <asm/mmu_context.h>
-#include <asm/tlbflush.h>
-#include <asm/core.h>
-
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
-#include <linux/fs.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
#include <linux/extable.h>
#include <linux/perf_event.h>
#include <linux/kprobes.h>
-#include <linux/uaccess.h>
+
+#include <asm/mmu_context.h>
__read_mostly bool segv_debug_enabled;
diff --git a/arch/sw_64/mm/hugetlbpage.c b/arch/sw_64/mm/hugetlbpage.c
index 3c03709d441c..2a40225af4d8 100644
--- a/arch/sw_64/mm/hugetlbpage.c
+++ b/arch/sw_64/mm/hugetlbpage.c
@@ -3,18 +3,13 @@
* SW64 Huge TLB Page Support for Kernel.
*/
-#include <linux/init.h>
-#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched/mm.h>
#include <linux/hugetlb.h>
-#include <linux/pagemap.h>
#include <linux/err.h>
-#include <linux/sysctl.h>
+
#include <asm/mman.h>
#include <asm/tlb.h>
-#include <asm/tlbflush.h>
-#include <asm/pgalloc.h>
/*
* pmd_huge() returns 1 if @pmd is hugetlb related entry, that is normal
diff --git a/arch/sw_64/mm/init.c b/arch/sw_64/mm/init.c
index e3c2a20e54a2..4dda5ecb4f2e 100644
--- a/arch/sw_64/mm/init.c
+++ b/arch/sw_64/mm/init.c
@@ -5,36 +5,13 @@
/* 2.3.x zone allocator, 1999 Andrea Arcangeli <andrea(a)suse.de> */
-#include <linux/pagemap.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/gfp.h>
-#include <linux/uaccess.h>
#include <linux/memblock.h>
-#include <linux/dma-mapping.h>
#include <linux/swiotlb.h>
#include <linux/acpi.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/dma.h>
#include <asm/mmu_context.h>
-#include <asm/console.h>
-#include <asm/tlb.h>
-#include <asm/setup.h>
-#include <asm/sections.h>
-#include <asm/memory.h>
-#include <asm/hw_init.h>
extern void die_if_kernel(char *, struct pt_regs *, long);
diff --git a/arch/sw_64/mm/numa.c b/arch/sw_64/mm/numa.c
index 940c12fcbb8d..7cb13587e465 100644
--- a/arch/sw_64/mm/numa.c
+++ b/arch/sw_64/mm/numa.c
@@ -3,27 +3,11 @@
* DISCONTIGMEM NUMA sw64 support.
*/
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
#include <linux/memblock.h>
-#include <linux/swap.h>
-#include <linux/initrd.h>
-#include <linux/pfn.h>
-#include <linux/module.h>
#include <linux/cpuset.h>
-#include <linux/init.h>
-#ifdef CONFIG_PCI
-#include <linux/pci.h>
-#endif
#include <linux/acpi.h>
#include <linux/of.h>
-#include <asm/pgalloc.h>
-#include <asm/sections.h>
-#include <asm/sw64_init.h>
-#include <asm/hw_init.h>
-#include <asm/memory.h>
#include <asm/core.h>
int cpu_to_node_map[NR_CPUS];
diff --git a/arch/sw_64/mm/physaddr.c b/arch/sw_64/mm/physaddr.c
index d5cf83e671ae..fbb489ae4db5 100644
--- a/arch/sw_64/mm/physaddr.c
+++ b/arch/sw_64/mm/physaddr.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/mmdebug.h>
#include <linux/module.h>
-#include <linux/mm.h>
#include <asm/page.h>
unsigned long __phys_addr(unsigned long x)
diff --git a/arch/sw_64/mm/thp.c b/arch/sw_64/mm/thp.c
index 68260dd0e837..833bb59f79d0 100644
--- a/arch/sw_64/mm/thp.c
+++ b/arch/sw_64/mm/thp.c
@@ -1,13 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/hugetlb.h>
-#include <linux/pagemap.h>
-#include <linux/err.h>
-#include <linux/sysctl.h>
-#include <asm/mman.h>
-#include <asm/tlb.h>
#include <asm/tlbflush.h>
#include <asm/pgalloc.h>
--
2.17.1
1
8

[PATCH v1 OLK-5.10 60/90] sw64: increase position index in c_next for cpuinfo
by Gu Zitao 12 May '22
by Gu Zitao 12 May '22
12 May '22
From: Mao Minkai <maominkai(a)wxiat.com>
Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OLG
--------------------------------
Signed-off-by: Mao Minkai <maominkai(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/kernel/setup.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/sw_64/kernel/setup.c b/arch/sw_64/kernel/setup.c
index 95d25c7c8204..61b498e65e4b 100644
--- a/arch/sw_64/kernel/setup.c
+++ b/arch/sw_64/kernel/setup.c
@@ -957,6 +957,7 @@ c_start(struct seq_file *f, loff_t *pos)
static void *
c_next(struct seq_file *f, void *v, loff_t *pos)
{
+ (*pos)++;
return NULL;
}
--
2.17.1
1
0

[PATCH v1 OLK-5.10 50/90] sw64: define NR_SYSCALLS as generated __NR_syscalls
by Gu Zitao 12 May '22
by Gu Zitao 12 May '22
12 May '22
From: He Sheng <hesheng(a)wxiat.com>
Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56XYC
--------------------------------
With this definition, the asm/unistd.h can keep unchanged if the
number of syscalls has changed.
Signed-off-by: He Sheng <hesheng(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/include/asm/unistd.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sw_64/include/asm/unistd.h b/arch/sw_64/include/asm/unistd.h
index b8854163d96f..6d1b8d1e2011 100644
--- a/arch/sw_64/include/asm/unistd.h
+++ b/arch/sw_64/include/asm/unistd.h
@@ -4,7 +4,7 @@
#include <uapi/asm/unistd.h>
-#define NR_SYSCALLS 519
+#define NR_SYSCALLS __NR_syscalls
#define NR_syscalls NR_SYSCALLS
#define __ARCH_WANT_NEW_STAT
--
2.17.1
1
9

12 May '22
From: Mao Minkai <maominkai(a)wxiat.com>
Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OLG
--------------------------------
Signed-off-by: Mao Minkai <maominkai(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/include/asm/ptrace.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/sw_64/include/asm/ptrace.h b/arch/sw_64/include/asm/ptrace.h
index 1dde5e6cba8a..33f5cc97c976 100644
--- a/arch/sw_64/include/asm/ptrace.h
+++ b/arch/sw_64/include/asm/ptrace.h
@@ -3,7 +3,11 @@
#define _ASM_SW64_PTRACE_H
#include <uapi/asm/ptrace.h>
-
+#include <linux/sched/task_stack.h>
+#include <asm/hmcall.h>
+#include <asm/thread_info.h>
+#include <asm/processor.h>
+#include <asm/page.h>
#define arch_has_single_step() (1)
#define user_mode(regs) (((regs)->ps & 8) != 0)
--
2.17.1
1
9
From: Mao Minkai <maominkai(a)wxiat.com>
Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OLG
--------------------------------
Rename variables for kvm_mem cmdline to improve readability.
Signed-off-by: Mao Minkai <maominkai(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/kernel/setup.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/arch/sw_64/kernel/setup.c b/arch/sw_64/kernel/setup.c
index e5abef2dc593..26a611448ad6 100644
--- a/arch/sw_64/kernel/setup.c
+++ b/arch/sw_64/kernel/setup.c
@@ -81,8 +81,8 @@ DEFINE_PER_CPU(unsigned long, hard_node_id) = { 0 };
struct cma *sw64_kvm_cma;
EXPORT_SYMBOL(sw64_kvm_cma);
-static phys_addr_t size_cmdline;
-static phys_addr_t base_cmdline;
+static phys_addr_t kvm_mem_size;
+static phys_addr_t kvm_mem_base;
struct gen_pool *sw64_kvm_pool;
EXPORT_SYMBOL(sw64_kvm_pool);
@@ -748,17 +748,17 @@ static int __init early_kvm_reserved_mem(char *p)
return -EINVAL;
}
- size_cmdline = memparse(p, &p);
+ kvm_mem_size = memparse(p, &p);
if (*p != '@')
return -EINVAL;
- base_cmdline = memparse(p + 1, &p);
+ kvm_mem_base = memparse(p + 1, &p);
return 0;
}
early_param("kvm_mem", early_kvm_reserved_mem);
void __init sw64_kvm_reserve(void)
{
- kvm_cma_declare_contiguous(base_cmdline, size_cmdline, 0,
+ kvm_cma_declare_contiguous(kvm_mem_base, kvm_mem_size, 0,
PAGE_SIZE, 0, "sw64_kvm_cma", &sw64_kvm_cma);
}
#endif
@@ -1030,14 +1030,14 @@ static int __init sw64_kvm_pool_init(void)
if (!sw64_kvm_cma)
goto out;
- kvm_pool_virt = (unsigned long)base_cmdline;
+ kvm_pool_virt = (unsigned long)kvm_mem_base;
sw64_kvm_pool = gen_pool_create(PAGE_SHIFT, -1);
if (!sw64_kvm_pool)
goto out;
- status = gen_pool_add_virt(sw64_kvm_pool, kvm_pool_virt, base_cmdline,
- size_cmdline, -1);
+ status = gen_pool_add_virt(sw64_kvm_pool, kvm_pool_virt, kvm_mem_base,
+ kvm_mem_size, -1);
if (status < 0) {
pr_err("failed to add memory chunks to sw64 kvm pool\n");
gen_pool_destroy(sw64_kvm_pool);
@@ -1046,8 +1046,8 @@ static int __init sw64_kvm_pool_init(void)
}
gen_pool_set_algo(sw64_kvm_pool, gen_pool_best_fit, NULL);
- base_page = pfn_to_page(base_cmdline >> PAGE_SHIFT);
- end_page = pfn_to_page((base_cmdline + size_cmdline) >> PAGE_SHIFT);
+ base_page = pfn_to_page(kvm_mem_base >> PAGE_SHIFT);
+ end_page = pfn_to_page((kvm_mem_base + kvm_mem_size) >> PAGE_SHIFT);
p = base_page;
while (page_ref_count(p) == 0 &&
--
2.17.1
1
9

12 May '22
From: Min Fanlei <minfanlei(a)wxiat.com>
Sunway inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I56WV8
--------------------------------
Signed-off-by: Min Fanlei <minfanlei(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/kernel/dup_print.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/sw_64/kernel/dup_print.c b/arch/sw_64/kernel/dup_print.c
index ac0a95d4d30b..fae543625f62 100644
--- a/arch/sw_64/kernel/dup_print.c
+++ b/arch/sw_64/kernel/dup_print.c
@@ -6,6 +6,7 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
+#include <asm/chip3_io.h>
#ifdef CONFIG_SW64_RRK
@@ -20,7 +21,7 @@ unsigned long sw64_printk_offset;
* For output the kernel message on the console
* with full-system emulator.
*/
-#define QEMU_PRINTF_BUFF_BASE (0x805000040000ULL | PAGE_OFFSET)
+#define QEMU_PRINTF_BUFF_BASE (IO_BASE | MCU_BASE | 0x40000UL | PAGE_OFFSET)
int sw64_printk(const char *fmt, va_list args)
{
--
2.17.1
1
9

[PATCH v1 OLK-5.10 12/90] sw64: switch to generic pcibios_set_master and pci_common_swizzle
by Gu Zitao 12 May '22
by Gu Zitao 12 May '22
12 May '22
From: Zhou Xuemei <zhouxuemei(a)wxiat.com>
Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56U83
--------------------------------
The generic implementation is better than arch-specific version. So
we remove the arch-specific one and switch to the generic version.
Signed-off-by: Zhou Xuemei <zhouxuemei(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/kernel/pci.c | 22 +---------------------
1 file changed, 1 insertion(+), 21 deletions(-)
diff --git a/arch/sw_64/kernel/pci.c b/arch/sw_64/kernel/pci.c
index b8505ad8972c..2c53e0717c9a 100644
--- a/arch/sw_64/kernel/pci.c
+++ b/arch/sw_64/kernel/pci.c
@@ -175,21 +175,6 @@ struct pci_dev *sw64_gendev_to_pci(struct device *dev)
return NULL;
}
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as certain firmware forgets to set it properly.
- */
-void pcibios_set_master(struct pci_dev *dev)
-{
- u8 lat;
-
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- if (lat >= 16)
- return;
- pr_info("PCI: Setting latency timer of device %s to 64\n", pci_name(dev));
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-}
-
void __init pcibios_claim_one_bus(struct pci_bus *b)
{
struct pci_dev *dev;
@@ -265,7 +250,7 @@ void __init common_init_pci(void)
bridge->sysdata = hose;
bridge->busnr = hose->busn_space->start;
bridge->ops = &sw64_pci_ops;
- bridge->swizzle_irq = sw64_swizzle;
+ bridge->swizzle_irq = pci_common_swizzle;
bridge->map_irq = sw64_map_irq;
ret = pci_scan_root_bus_bridge(bridge);
@@ -593,11 +578,6 @@ int sw64_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return sw64_chip_init->pci_init.map_irq(dev, slot, pin);
}
-unsigned char sw64_swizzle(struct pci_dev *dev, u8 *pinp)
-{
- return PCI_SLOT(dev->devfn);
-}
-
static void __init
sw64_init_host(unsigned long node, unsigned long index)
{
--
2.17.1
1
0

12 May '22
From: Mao Minkai <maominkai(a)wxiat.com>
Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OLG
--------------------------------
Use debugfs_create_file() to create debugfs file for tc_sched_clock
so it is protected against file removals. Change its name to
"tc_sched_clock" to stay consistent with what we use in cmdline.
Signed-off-by: Mao Minkai <maominkai(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/kernel/time.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/sw_64/kernel/time.c b/arch/sw_64/kernel/time.c
index 0815d06b03d4..185db832dfb8 100644
--- a/arch/sw_64/kernel/time.c
+++ b/arch/sw_64/kernel/time.c
@@ -237,8 +237,8 @@ static int __init sched_clock_debug_init(void)
if (!sw64_debugfs_dir)
return -ENODEV;
- sched_clock_status = debugfs_create_file_unsafe("use_tc_as_sched_clock",
- 0666, sw64_debugfs_dir, NULL,
+ sched_clock_status = debugfs_create_file("tc_sched_clock",
+ 0644, sw64_debugfs_dir, NULL,
&sched_clock_status_fops);
if (!sched_clock_status)
--
2.17.1
1
5
From: Mao Minkai <maominkai(a)wxiat.com>
Sunway inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OLG
--------------------------------
Remove redundant Kconfig source to avoid compiler warning.
Signed-off-by: Mao Minkai <maominkai(a)wxiat.com>
Signed-off-by: Gu Zitao <guzitao(a)wxiat.com>
---
arch/sw_64/Kconfig | 3 ---
1 file changed, 3 deletions(-)
diff --git a/arch/sw_64/Kconfig b/arch/sw_64/Kconfig
index a81d388ed304..318a423d87dd 100644
--- a/arch/sw_64/Kconfig
+++ b/arch/sw_64/Kconfig
@@ -419,9 +419,6 @@ config ARCH_DISCONTIGMEM_ENABLE
or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa> for more.
-source "kernel/Kconfig.preempt"
-
-
config NUMA
bool "NUMA Support"
depends on SMP && !FLATMEM
--
2.17.1
1
0
Cui Mingrui (2):
sw64: optimize ip checksum calculation
sw64: fix ip checksum calculation
Du Yilong (3):
sw64: kvm: fix bug when open file with the O_DIRECT flag
sw64: add set time support for hypervisor based rtc
sw64: kvm: remap pages of guest by vm_insert_page()
Gu Zitao (7):
config: add initial openeuler_defconfig for sw64
sw64: fix coding style problems
sw64: fix the VDSO symbol generation for nm
sw64: fix SPDX license identifier in uapi headers
sw64: add SO_RCVTIMEO/ SO_SNDTIMEO socket options
sw64: remove unnecessary include headers
sw64: fix some compile errors
He Chuyue (2):
sw64: add regs and stack access APIs to support kprobe events
sw64: remove unnecessary parameter in REG_OFFSET_NAME
He Sheng (20):
sw64: clean up useless #if 0 and #if 1
sw64: switch GUP to the generic get_user_pages_fast() implementation
sw64: remove unused a.out.h
sw64: fix ex_table entries from misalignment handlers
sw64: define NR_SYSCALLS as generated __NR_syscalls
sw64: clean up a.out and ECOFF binary related headers
sw64: ptrace: clean up debug codes
sw64: add kbuild defconfig rule
sw64: clean up out-of-date selected options
sw64: Kconfig: remove dependence on !PREEMPT
sw64: Kconfig: remove dependence on ARCH_SUPPORTS_ACPI
sw64: add missing global __constant_c_memset
sw64: do some cleanups for rt_sigframe
sw64: fix setup_rt_frame for non SA_SIGINFO
sw64: fix compile error for DISCONTIGMEM=y
sw64: force signal and fault for traps and debugging
sw64: push and pop kernel stack with ldi instruction
sw64: signal: save/restore fpregs with copy user
sw64: fix the number of aux entries in ARCH_DLINFO
sw64: fix sendfile system call
Lu Feifei (6):
sw64: fix printk method for guest os
sw64: unify access to LONGTIME for guest and emulator
sw64: kvm: handle ldl_u and stl_u when exit mmio
sw64: kvm: simplify the code
sw64: pci: align the address of mmio resource to PAGE_SIZE
sw64: unify 32-bit MEMIO address of host and guest
Mao Minkai (29):
sw64: vdso: add automatic syscall fallback
sw64: vdso: change vdso version
sw64: vdso: fix time calculation
sw64: mm: reorder memblock_init process
sw64: mm: warn overlapped memmap and DMA region
sw64: mm: use memblock to find the end of memory
sw64: print correct initrd address
sw64: remove redundant Kconfig source
sw64: modify tc_sched_clock debugfs file
sw64: simplify cpumask_of_node
sw64: remove CONFIG_USE_PERCPU_NUMA_NODE_ID=n code
sw64: fix all compile warnings
sw64: numa: switch to arch node_distance
sw64: mm: mark pci and memmap region as nomap
sw64: use jump label for running modes
sw64: remove MAX_ASN
sw64: kvm: remove MAX_VPN
sw64: fix coding style problems
sw64: rename kvm_mem variables
sw64: reformat syscall.tbl
sw64: add missing pkey syscall numbers
sw64: add clone3 syscall support
sw64: add required include headers to ptrace.h
sw64: switch to old-style semctl/shmctl syscalls
sw64: increase position index in c_next for cpuinfo
sw64: add old sigprocmask back for compatibility
sw64: vdso: fix backtrace of vrt_sigreturn
sw64: vdso: fix CFI directives for fpregs in vrt_sigreturn
sw64: optimize simd version of memcpy and memset
Min Fanlei (4):
sw64: fix the value of QEMU_PRINTF_BUFF_BASE
sw64: add support for emulator running mode
sw64: enable more than 32 CPUs for guest
sw64: kvm: fix bad page state setting outside of kvm memory pool
Tang Jinyang (2):
sw64: add dynamic frequency scaling support
sw64: add dynamic turning on/off cores support
Wang Yingying (3):
hwmon: add voltage sensor support for sw64
sw64: add pvt device to chip3.dts
hwmon: add support for sw64 temperature sensor
Xu Chenjiao (2):
sw64: radeon: add a force flush to delay work when radeon uvd suspend
sw64: pcie: enable PME and AER support
Zhao Yihan (1):
sw64: remap PA with |= in early_ioremap
Zheng Chongzhen (3):
sw64: re-implement sw64_dma_direct_ops according upstream
sw64: iommu: fix 32-bit devices dma ops
sw64: fix compile error for CONFIG_PCI=n
Zhou Xuemei (5):
sw64: pci: remove some useless code
sw64: switch to generic pcibios_set_master and pci_common_swizzle
sw64: clean up some useless codes
sw64: dts: rename spi flash partition to fix warning
sw64: add ARCH_HAS_PTE_SPECIAL support
Zhu Donghong (1):
ipmi: add ipmi driver support
arch/sw_64/Kconfig | 325 +-
arch/sw_64/Makefile | 1 +
arch/sw_64/boot/dts/chip3.dts | 41 +-
arch/sw_64/chip/chip3/chip.c | 130 +-
arch/sw_64/chip/chip3/cpufreq_debugfs.c | 7 +-
arch/sw_64/chip/chip3/i2c-lib.c | 4 -
arch/sw_64/chip/chip3/irq_chip.c | 13 +-
arch/sw_64/chip/chip3/msi.c | 7 +-
arch/sw_64/chip/chip3/pci-quirks.c | 7 +-
arch/sw_64/chip/chip3/vt_msi.c | 6 -
arch/sw_64/configs/openeuler_defconfig | 4312 +++++++++++++++++++++
arch/sw_64/defconfig | 73 -
arch/sw_64/include/asm/Kbuild | 1 +
arch/sw_64/include/asm/a.out-core.h | 80 -
arch/sw_64/include/asm/a.out.h | 16 -
arch/sw_64/include/asm/checksum.h | 58 +-
arch/sw_64/include/asm/chip3_io.h | 4 +-
arch/sw_64/include/asm/clock.h | 56 +
arch/sw_64/include/asm/cputime.h | 4 +-
arch/sw_64/include/asm/early_ioremap.h | 2 +-
arch/sw_64/include/asm/hw_init.h | 29 +-
arch/sw_64/include/asm/kvm_host.h | 3 +-
arch/sw_64/include/asm/mmu_context.h | 3 +-
arch/sw_64/include/asm/numa.h | 1 +
arch/sw_64/include/asm/pci.h | 24 +-
arch/sw_64/include/asm/pgtable.h | 26 +-
arch/sw_64/include/asm/ptrace.h | 8 +-
arch/sw_64/include/asm/topology.h | 29 +-
arch/sw_64/include/asm/unistd.h | 3 +-
arch/sw_64/include/asm/user.h | 53 -
arch/sw_64/include/asm/vdso.h | 4 +-
arch/sw_64/include/asm/vga.h | 18 +-
arch/sw_64/include/uapi/asm/a.out.h | 88 -
arch/sw_64/include/uapi/asm/auxvec.h | 25 +-
arch/sw_64/include/uapi/asm/bitsperlong.h | 2 +-
arch/sw_64/include/uapi/asm/byteorder.h | 2 +-
arch/sw_64/include/uapi/asm/compiler.h | 2 +-
arch/sw_64/include/uapi/asm/console.h | 2 +-
arch/sw_64/include/uapi/asm/errno.h | 2 +-
arch/sw_64/include/uapi/asm/fcntl.h | 2 +-
arch/sw_64/include/uapi/asm/fpu.h | 2 +-
arch/sw_64/include/uapi/asm/gentrap.h | 2 +-
arch/sw_64/include/uapi/asm/hmcall.h | 2 +-
arch/sw_64/include/uapi/asm/ioctl.h | 2 +-
arch/sw_64/include/uapi/asm/ioctls.h | 48 +-
arch/sw_64/include/uapi/asm/ipcbuf.h | 2 +-
arch/sw_64/include/uapi/asm/kvm.h | 14 +-
arch/sw_64/include/uapi/asm/kvm_para.h | 2 +-
arch/sw_64/include/uapi/asm/mman.h | 2 +-
arch/sw_64/include/uapi/asm/msgbuf.h | 2 +-
arch/sw_64/include/uapi/asm/param.h | 2 +-
arch/sw_64/include/uapi/asm/poll.h | 2 +-
arch/sw_64/include/uapi/asm/posix_types.h | 2 +-
arch/sw_64/include/uapi/asm/ptrace.h | 2 +-
arch/sw_64/include/uapi/asm/reg.h | 2 +-
arch/sw_64/include/uapi/asm/regdef.h | 2 +-
arch/sw_64/include/uapi/asm/resource.h | 2 +-
arch/sw_64/include/uapi/asm/sembuf.h | 2 +-
arch/sw_64/include/uapi/asm/setup.h | 2 +-
arch/sw_64/include/uapi/asm/shmbuf.h | 2 +-
arch/sw_64/include/uapi/asm/sigcontext.h | 2 +-
arch/sw_64/include/uapi/asm/siginfo.h | 2 +-
arch/sw_64/include/uapi/asm/signal.h | 2 +-
arch/sw_64/include/uapi/asm/socket.h | 34 +-
arch/sw_64/include/uapi/asm/sockios.h | 2 +-
arch/sw_64/include/uapi/asm/stat.h | 2 +-
arch/sw_64/include/uapi/asm/statfs.h | 2 +-
arch/sw_64/include/uapi/asm/swab.h | 2 +-
arch/sw_64/include/uapi/asm/sysinfo.h | 2 +-
arch/sw_64/include/uapi/asm/termbits.h | 2 +-
arch/sw_64/include/uapi/asm/termios.h | 2 +-
arch/sw_64/include/uapi/asm/types.h | 2 +-
arch/sw_64/include/uapi/asm/unistd.h | 7 +-
arch/sw_64/kernel/Makefile | 5 +-
arch/sw_64/kernel/acpi.c | 19 +-
arch/sw_64/kernel/asm-offsets.c | 7 +-
arch/sw_64/kernel/audit.c | 2 +-
arch/sw_64/kernel/cacheinfo.c | 3 +-
arch/sw_64/kernel/clock.c | 184 +
arch/sw_64/kernel/core.c | 41 +-
arch/sw_64/kernel/cpuautoplug.c | 496 +++
arch/sw_64/kernel/crash_dump.c | 2 -
arch/sw_64/kernel/dup_print.c | 10 +-
arch/sw_64/kernel/early_printk.c | 4 +-
arch/sw_64/kernel/entry.S | 5 +-
arch/sw_64/kernel/ftrace.c | 5 -
arch/sw_64/kernel/insn.c | 13 -
arch/sw_64/kernel/irq.c | 15 -
arch/sw_64/kernel/irq_sw64.c | 9 +-
arch/sw_64/kernel/jump_label.c | 3 +-
arch/sw_64/kernel/kgdb.c | 9 +-
arch/sw_64/kernel/kprobes/decode-insn.c | 6 +-
arch/sw_64/kernel/kprobes/kprobes.c | 4 -
arch/sw_64/kernel/kvm_cma.c | 4 -
arch/sw_64/kernel/machine_kexec.c | 7 +-
arch/sw_64/kernel/module.c | 9 -
arch/sw_64/kernel/msi.c | 25 -
arch/sw_64/kernel/pci-noop.c | 8 -
arch/sw_64/kernel/pci-sysfs.c | 3 -
arch/sw_64/kernel/pci.c | 102 +-
arch/sw_64/kernel/pci_common.c | 285 +-
arch/sw_64/kernel/pci_impl.h | 49 -
arch/sw_64/kernel/perf_event.c | 12 -
arch/sw_64/kernel/perf_regs.c | 4 -
arch/sw_64/kernel/platform.c | 20 +
arch/sw_64/kernel/process.c | 26 -
arch/sw_64/kernel/ptrace.c | 132 +-
arch/sw_64/kernel/relocate.c | 13 +-
arch/sw_64/kernel/segvdbg.c | 4 +-
arch/sw_64/kernel/setup.c | 124 +-
arch/sw_64/kernel/signal.c | 74 +-
arch/sw_64/kernel/smp.c | 25 +-
arch/sw_64/kernel/stacktrace.c | 1 -
arch/sw_64/kernel/suspend.c | 22 +-
arch/sw_64/kernel/syscalls/syscall.tbl | 28 +-
arch/sw_64/kernel/tc.c | 3 -
arch/sw_64/kernel/time.c | 31 +-
arch/sw_64/kernel/timer.c | 21 +-
arch/sw_64/kernel/topology.c | 19 -
arch/sw_64/kernel/traps.c | 95 +-
arch/sw_64/kernel/unaligned.c | 3 -
arch/sw_64/kernel/uprobes.c | 5 -
arch/sw_64/kernel/vdso.c | 9 -
arch/sw_64/kernel/vdso/so2s.sh | 3 +-
arch/sw_64/kernel/vdso/vdso.S | 2 -
arch/sw_64/kernel/vdso/vdso.lds.S | 2 +-
arch/sw_64/kernel/vdso/vgettimeofday.c | 33 +-
arch/sw_64/kernel/vdso/vrt_sigreturn.S | 40 +
arch/sw_64/kvm/emulate.c | 2 +
arch/sw_64/kvm/kvm-sw64.c | 39 +-
arch/sw_64/kvm/vmem.c | 37 +-
arch/sw_64/lib/checksum.c | 136 +-
arch/sw_64/lib/csum_partial_copy.c | 310 +-
arch/sw_64/lib/deep-memcpy.S | 449 ++-
arch/sw_64/lib/deep-memset.S | 27 +-
arch/sw_64/lib/fls.c | 1 -
arch/sw_64/lib/iomap.c | 4 +-
arch/sw_64/lib/udelay.c | 5 -
arch/sw_64/math-emu/math.c | 10 +-
arch/sw_64/mm/fault.c | 21 +-
arch/sw_64/mm/hugetlbpage.c | 7 +-
arch/sw_64/mm/init.c | 48 +-
arch/sw_64/mm/numa.c | 30 +-
arch/sw_64/mm/physaddr.c | 1 -
arch/sw_64/mm/thp.c | 9 -
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/sw64_cpufreq.c | 186 +
drivers/gpu/drm/radeon/radeon_uvd.c | 5 +
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/sw64_pvt.c | 222 ++
drivers/iommu/sw64/sunway_iommu.c | 58 +-
drivers/iommu/sw64/sunway_iommu.h | 2 +-
drivers/rtc/rtc-sw64-virt.c | 24 +-
154 files changed, 7026 insertions(+), 2337 deletions(-)
create mode 100644 arch/sw_64/configs/openeuler_defconfig
delete mode 100644 arch/sw_64/defconfig
delete mode 100644 arch/sw_64/include/asm/a.out-core.h
delete mode 100644 arch/sw_64/include/asm/a.out.h
create mode 100644 arch/sw_64/include/asm/clock.h
delete mode 100644 arch/sw_64/include/asm/user.h
delete mode 100644 arch/sw_64/include/uapi/asm/a.out.h
create mode 100644 arch/sw_64/kernel/clock.c
create mode 100644 arch/sw_64/kernel/cpuautoplug.c
create mode 100644 arch/sw_64/kernel/platform.c
create mode 100644 drivers/cpufreq/sw64_cpufreq.c
create mode 100644 drivers/hwmon/sw64_pvt.c
--
2.17.1
1
11

[PATCH openEuler-5.10 01/43] rcu: Prevent expedited GP from enabling tick on offline CPU
by Zheng Zengkai 10 May '22
by Zheng Zengkai 10 May '22
10 May '22
From: "Paul E. McKenney" <paulmck(a)kernel.org>
mainline inclusion
from mainline-v5.17-rc1
commit 147f04b14adde831eb4a0a1e378667429732f9e8
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I53ILL
CVE: NA
-------------------------------------------------------------------------
If an RCU expedited grace period starts just when a CPU is in the process
of going offline, so that the outgoing CPU has completed its pass through
stop-machine but has not yet completed its final dive into the idle loop,
RCU will attempt to enable that CPU's scheduling-clock tick via a call
to tick_dep_set_cpu(). For this to happen, that CPU has to have been
online when the expedited grace period completed its CPU-selection phase.
This is pointless: The outgoing CPU has interrupts disabled, so it cannot
take a scheduling-clock tick anyway. In addition, the tick_dep_set_cpu()
function's eventual call to irq_work_queue_on() will splat as follows:
smpboot: CPU 1 is now offline
WARNING: CPU: 6 PID: 124 at kernel/irq_work.c:95
+irq_work_queue_on+0x57/0x60
Modules linked in:
CPU: 6 PID: 124 Comm: kworker/6:2 Not tainted 5.15.0-rc1+ #3
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
+rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014
Workqueue: rcu_gp wait_rcu_exp_gp
RIP: 0010:irq_work_queue_on+0x57/0x60
Code: 8b 05 1d c7 ea 62 a9 00 00 f0 00 75 21 4c 89 ce 44 89 c7 e8
+9b 37 fa ff ba 01 00 00 00 89 d0 c3 4c 89 cf e8 3b ff ff ff eb ee <0f> 0b eb b7
+0f 0b eb db 90 48 c7 c0 98 2a 02 00 65 48 03 05 91
6f
RSP: 0000:ffffb12cc038fe48 EFLAGS: 00010282
RAX: 0000000000000001 RBX: 0000000000005208 RCX: 0000000000000020
RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffff9ad01f45a680
RBP: 000000000004c990 R08: 0000000000000001 R09: ffff9ad01f45a680
R10: ffffb12cc0317db0 R11: 0000000000000001 R12: 00000000fffecee8
R13: 0000000000000001 R14: 0000000000026980 R15: ffffffff9e53ae00
FS: 0000000000000000(0000) GS:ffff9ad01f580000(0000)
+knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 000000000de0c000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
tick_nohz_dep_set_cpu+0x59/0x70
rcu_exp_wait_wake+0x54e/0x870
? sync_rcu_exp_select_cpus+0x1fc/0x390
process_one_work+0x1ef/0x3c0
? process_one_work+0x3c0/0x3c0
worker_thread+0x28/0x3c0
? process_one_work+0x3c0/0x3c0
kthread+0x115/0x140
? set_kthread_struct+0x40/0x40
ret_from_fork+0x22/0x30
---[ end trace c5bf75eb6aa80bc6 ]---
This commit therefore avoids invoking tick_dep_set_cpu() on offlined
CPUs to limit both futility and false-positive splats.
Signed-off-by: Paul E. McKenney <paulmck(a)kernel.org>
Signed-off-by: Zhen Lei <thunder.leizhen(a)huawei.com>
Reviewed-by: Cheng Jian <cj.chengjian(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
kernel/rcu/tree_exp.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
index 0dc16345e668..2bc4538e8a61 100644
--- a/kernel/rcu/tree_exp.h
+++ b/kernel/rcu/tree_exp.h
@@ -507,7 +507,10 @@ static void synchronize_rcu_expedited_wait(void)
if (rdp->rcu_forced_tick_exp)
continue;
rdp->rcu_forced_tick_exp = true;
- tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
+ preempt_disable();
+ if (cpu_online(cpu))
+ tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
+ preempt_enable();
}
}
j = READ_ONCE(jiffies_till_first_fqs);
--
2.20.1
1
42
Backport 5.10.97 LTS patches from upstream.
Conflicts
already merged
cgroup-v1: Require capabilities to set release_agent
net: sched: fix use-after-free in tc_new_tfilter()
context conflict
psi: Fix uaf issue when psi trigger is destroyed while being polled
Alex Elder (3):
net: ipa: fix atomic update in ipa_endpoint_replenish()
net: ipa: use a bitmap for endpoint replenish_enabled
net: ipa: prevent concurrent replenish
Dan Carpenter (1):
fanotify: Fix stale file descriptor in copy_event_to_user()
Eric Dumazet (3):
rtnetlink: make sure to refresh master_dev/m_ops in __rtnl_newlink()
af_packet: fix data-race in packet_setsockopt / packet_setsockopt
tcp: add missing tcp_skb_can_collapse() test in tcp_shift_skb_data()
Georgi Valkov (1):
ipheth: fix EOVERFLOW in ipheth_rcvbulk_callback
Kevin Hilman (1):
Revert "drivers: bus: simple-pm-bus: Add support for probing simple
bus only devices"
Lukas Wunner (1):
PCI: pciehp: Fix infinite loop in IRQ handler upon power fault
Maher Sanalla (1):
net/mlx5: Use del_timer_sync in fw reset flow of halting poll
Maor Dickman (2):
net/mlx5e: Fix handling of wrong devices during bond netevent
net/mlx5: E-Switch, Fix uninitialized variable modact
Maxime Ripard (1):
drm/vc4: hdmi: Make sure the device is powered with CEC
Raju Rangoju (1):
net: amd-xgbe: ensure to reset the tx_timer_active flag
Sean Christopherson (1):
KVM: x86: Forcibly leave nested virt when SMM state is toggled
Shyam Sundar S K (1):
net: amd-xgbe: Fix skb data length underflow
Suren Baghdasaryan (1):
psi: Fix uaf issue when psi trigger is destroyed while being polled
Tianchen Ding (1):
cpuset: Fix the bug that subpart_cpus updated wrongly in
update_cpumask()
Tony Luck (2):
x86/mce: Add Xeon Sapphire Rapids to list of CPUs that support PPIN
x86/cpu: Add Xeon Icelake-D to list of CPUs that support PPIN
Documentation/accounting/psi.rst | 3 +-
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kernel/cpu/mce/intel.c | 2 +
arch/x86/kvm/svm/nested.c | 10 ++-
arch/x86/kvm/svm/svm.c | 2 +-
arch/x86/kvm/svm/svm.h | 2 +-
arch/x86/kvm/vmx/nested.c | 1 +
arch/x86/kvm/x86.c | 2 +
drivers/bus/simple-pm-bus.c | 39 +----------
drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +++----
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 14 +++-
.../ethernet/mellanox/mlx5/core/en/rep/bond.c | 32 ++++-----
.../ethernet/mellanox/mlx5/core/fw_reset.c | 2 +-
.../mellanox/mlx5/core/lib/fs_chains.c | 2 +-
drivers/net/ipa/ipa_endpoint.c | 25 ++++---
drivers/net/ipa/ipa_endpoint.h | 15 ++++-
drivers/net/usb/ipheth.c | 6 +-
drivers/pci/hotplug/pciehp_hpc.c | 7 +-
fs/notify/fanotify/fanotify_user.c | 6 +-
include/linux/psi.h | 2 +-
include/linux/psi_types.h | 3 -
kernel/cgroup/cgroup.c | 11 +++-
kernel/cgroup/cpuset.c | 3 +-
kernel/sched/psi.c | 66 ++++++++-----------
net/core/rtnetlink.c | 6 +-
net/ipv4/tcp_input.c | 2 +
net/packet/af_packet.c | 8 ++-
27 files changed, 153 insertions(+), 144 deletions(-)
--
2.20.1
1
21
Backport 5.10.96 LTS patches from upstream.
complicts:
Already merged(6):
udf: Restore i_lenAlloc when inode expansion fails
NFSv4: Handle case where the lookup of a directory fails
yam: fix a memory leak in yam_siocdevprivate()
net: hns3: handle empty unknown interrupt for VF
NFSv4: nfs_atomic_open() can race when looking up a non-regular file
udf: Fix NULL ptr deref when converting from inline format
Context conflict:
arm64: errata: Fix exec handling in erratum 1418040 workaround
defered (2) (cause symbol kabi changes):
net: fix information leakage in /proc/net/ptype
perf: Fix perf_event_read_local() time
Alan Stern (2):
usb-storage: Add unusual-devs entry for VL817 USB-SATA bridge
USB: core: Fix hang in usb_kill_urb by adding memory barriers
Amir Goldstein (2):
fsnotify: fix fsnotify hooks in pseudo filesystems
fsnotify: invalidate dcache before IN_DELETE event
Ard Biesheuvel (1):
efi: runtime: avoid EFIv2 runtime services on Apple x86 machines
Athira Rajeev (1):
powerpc/perf: Fix power_pmu_disable to call clear_pmi_irq_pending only
if PMI is pending
Badhri Jagan Sridharan (1):
usb: typec: tcpm: Do not disconnect while receiving VBUS off
Brian Gix (1):
Bluetooth: refactor malicious adv data check
Cameron Williams (1):
tty: Add support for Brainboxes UC cards.
Christophe Leroy (3):
powerpc/32s: Allocate one 256k IBAT instead of two consecutives 128k
IBATs
powerpc/32s: Fix kasan_init_region() for KASAN
powerpc/32: Fix boot failure with GCC latent entropy plugin
D Scott Phillips (1):
arm64: errata: Fix exec handling in erratum 1418040 workaround
David Howells (1):
rxrpc: Adjust retransmission backoff
Dmitry V. Levin (1):
usr/include/Makefile: add linux/nfc.h to the compile-test coverage
Eric Dumazet (5):
ipv4: avoid using shared IP generator for connected sockets
ipv6: annotate accesses to fn->fn_sernum
ipv4: raw: lock the socket in raw_bind()
ipv4: tcp: send zero IPID in SYNACK messages
ipv4: remove sparse error in ip_neigh_gw4()
Florian Westphal (1):
netfilter: conntrack: don't increment invalid counter on NF_REPEAT
Frank Li (1):
usb: xhci-plat: fix crash when suspend if remote wake enable
Geert Uytterhoeven (1):
mtd: rawnand: mpc5121: Remove unused variable in ads5121_select_chip()
Greg Kroah-Hartman (1):
PM: wakeup: simplify the output logic of pm_show_wakelocks()
Guenter Roeck (4):
hwmon: (lm90) Mark alert as broken for MAX6646/6647/6649
hwmon: (lm90) Mark alert as broken for MAX6680
hwmon: (lm90) Reduce maximum conversion rate for G781
hwmon: (lm90) Mark alert as broken for MAX6654
Guillaume Nault (1):
Revert "ipv6: Honor all IPv6 PIO Valid Lifetime values"
Ido Schimmel (1):
ipv6_tunnel: Rate limit warning messages
Ilya Leoshkevich (1):
s390/module: fix loading modules with a lot of relocations
Jakub Kicinski (1):
ipv4: fix ip option filtering for locally generated fragments
Jedrzej Jagielski (2):
i40e: Increase delay to 1 s after global EMP reset
i40e: Fix issue when maximum queues is exceeded
Jeff Layton (2):
ceph: properly put ceph_string reference after async create attempt
ceph: set pool_ns in new inode layout for async creates
Jianguo Wu (1):
net-procfs: show net devices bound packet types
Joe Damato (1):
i40e: fix unsigned stat widths
John Meneghini (1):
scsi: bnx2fc: Flush destroy_work queue before calling
bnx2fc_interface_put()
Jon Hunter (1):
usb: common: ulpi: Fix crash in ulpi_match()
Joseph Qi (2):
jbd2: export jbd2_journal_[grab|put]_journal_head
ocfs2: fix a deadlock when commit trans
José Expósito (2):
drm/msm/dsi: invalid parameter check in msm_dsi_phy_enable
drm/msm/dpu: invalid parameter check in dpu_setup_dspp_pcc
Karen Sornek (1):
i40e: Fix for failed to init adminq while VF reset
Like Xu (1):
KVM: x86: Update vCPU's runtime CPUID on write to MSR_IA32_XSS
Linyu Yuan (1):
usb: roles: fix include/linux/usb/role.h compile issue
Lucas Stach (1):
drm/etnaviv: relax submit size limits
Marc Kleine-Budde (1):
dt-bindings: can: tcan4x5x: fix mram-cfg RX FIFO config
Marek Behún (2):
net: sfp: ignore disabled SFP node
phylib: fix potential use-after-free
Mathieu Desnoyers (1):
sched/membarrier: Fix membarrier-rseq fence command missing from query
bitmask
Matthias Kaehlcke (1):
rpmsg: char: Fix race between the release of rpmsg_eptdev and cdev
Miaoqian Lin (2):
drm/msm/dsi: Fix missing put_device() call in dsi_get_phy
drm/msm/hdmi: Fix missing put_device() call in msm_hdmi_get_phy
Michael Kelley (1):
video: hyperv_fb: Fix validation of screen resolution
Mihai Carabas (1):
efi/libstub: arm64: Fix image check alignment at entry
Mohammad Athari Bin Ismail (1):
net: stmmac: skip only stmmac_ptp_register when resume from suspend
Naveen N. Rao (2):
bpf: Guard against accessing NULL pt_regs in bpf_get_task_stack()
powerpc64/bpf: Limit 'ldbrx' to processors compliant with ISA v2.06
Nikolay Aleksandrov (1):
net: bridge: vlan: fix single net device option dumping
OGAWA Hirofumi (1):
block: Fix wrong offset in bio_truncate()
Pablo Neira Ayuso (1):
netfilter: nft_payload: do not update layer 4 checksum when mangling
fragments
Pavankumar Kondeti (1):
usb: gadget: f_sourcesink: Fix isoc transfer for USB_SPEED_SUPER_PLUS
Randy Dunlap (1):
kernel: delete repeated words in comments
Robert Hancock (2):
serial: 8250: of: Fix mapped region size when using reg-offset
property
net: phy: broadcom: hook up soft_reset for BCM54616S
Sean Christopherson (1):
Revert "KVM: SVM: avoid infinite loop on NPF from bad address"
Sing-Han Chen (1):
ucsi_ccg: Check DEV_INT bit only when starting CCG4
Stanimir Varbanov (1):
media: venus: core: Drop second v4l2 device unregister
Steffen Maier (1):
scsi: zfcp: Fix failed recovery on gone remote port with non-NPIV FCP
devices
Subbaraya Sundeep (1):
octeontx2-pf: Forward error codes to VF
Sujit Kautkar (1):
rpmsg: char: Fix race between the release of rpmsg_ctrldev and cdev
Sukadev Bhattiprolu (2):
ibmvnic: init ->running_cap_crqs early
ibmvnic: don't spin in tasklet
Sylwester Dziedziuch (1):
i40e: Fix queues reservation for XDP
Tim Yi (1):
net: bridge: vlan: fix memory leak in __allowed_ingress
Toke Høiland-Jørgensen (1):
net: cpsw: Properly initialise struct page_pool_params
Tom Zanussi (1):
tracing: Don't inc err_log entry count if entry allocation fails
Trond Myklebust (2):
NFS: Ensure the server has an up to date ctime before hardlinking
NFS: Ensure the server has an up to date ctime before renaming
Valentin Caron (1):
serial: stm32: fix software flow control transfer
Vasily Gorbik (1):
s390/hypfs: include z/VM guests with access control group set
Vincent Guittot (1):
sched/pelt: Relax the sync of util_sum with util_avg
Xianting Tian (1):
drm/msm: Fix wrong size calculation
Xiaoke Wang (1):
tracing/histogram: Fix a potential memory leak for kstrdup()
Xin Long (1):
ping: fix the sk_bound_dev_if match in ping_lookup
Yajun Deng (2):
net: ipv4: Move ip_options_fragment() out of loop
net: ipv4: Fix the warning for dereference
Yazen Ghannam (1):
x86/MCE/AMD: Allow thresholding interface updates after init
Zhengjun Xing (1):
perf/x86/intel/uncore: Fix CAS_COUNT_WRITE issue for ICX
daniel.starke(a)siemens.com (1):
tty: n_gsm: fix SW flow control encoding/handling
.../devicetree/bindings/net/can/tcan4x5x.txt | 2 +-
arch/arm64/kernel/process.c | 39 +++---
arch/powerpc/include/asm/book3s/32/mmu-hash.h | 2 +
arch/powerpc/include/asm/ppc-opcode.h | 1 +
arch/powerpc/kernel/Makefile | 1 +
arch/powerpc/lib/Makefile | 3 +
arch/powerpc/mm/book3s32/mmu.c | 15 ++-
arch/powerpc/mm/kasan/book3s_32.c | 59 ++++-----
arch/powerpc/net/bpf_jit_comp64.c | 22 ++--
arch/powerpc/perf/core-book3s.c | 17 ++-
arch/s390/hypfs/hypfs_vm.c | 6 +-
arch/s390/kernel/module.c | 37 +++---
arch/x86/events/intel/uncore_snbep.c | 2 +-
arch/x86/kernel/cpu/mce/amd.c | 2 +-
arch/x86/kvm/svm/svm.c | 7 --
arch/x86/kvm/x86.c | 1 +
block/bio.c | 3 +-
drivers/firmware/efi/efi.c | 7 ++
drivers/firmware/efi/libstub/arm64-stub.c | 6 +-
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 4 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c | 11 +-
drivers/gpu/drm/msm/dsi/dsi.c | 7 +-
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 4 +-
drivers/gpu/drm/msm/hdmi/hdmi.c | 7 +-
drivers/gpu/drm/msm/msm_drv.c | 2 +-
drivers/hwmon/lm90.c | 7 +-
drivers/media/platform/qcom/venus/core.c | 2 -
drivers/mtd/nand/raw/mpc5121_nfc.c | 1 -
drivers/net/ethernet/ibm/ibmvnic.c | 112 +++++++++++-------
drivers/net/ethernet/intel/i40e/i40e.h | 9 +-
.../net/ethernet/intel/i40e/i40e_debugfs.c | 2 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 44 ++++---
.../net/ethernet/intel/i40e/i40e_register.h | 3 +
.../ethernet/intel/i40e/i40e_virtchnl_pf.c | 103 +++++++++++++++-
.../ethernet/intel/i40e/i40e_virtchnl_pf.h | 1 +
.../ethernet/marvell/octeontx2/nic/otx2_pf.c | 7 +-
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++--
drivers/net/ethernet/ti/cpsw_priv.c | 2 +-
drivers/net/phy/broadcom.c | 1 +
drivers/net/phy/phy_device.c | 6 +-
drivers/net/phy/sfp-bus.c | 5 +
drivers/rpmsg/rpmsg_char.c | 22 +---
drivers/s390/scsi/zfcp_fc.c | 13 +-
drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 20 +---
drivers/tty/n_gsm.c | 4 +-
drivers/tty/serial/8250/8250_of.c | 11 +-
drivers/tty/serial/8250/8250_pci.c | 100 +++++++++++++++-
drivers/tty/serial/stm32-usart.c | 2 +-
drivers/usb/common/ulpi.c | 7 +-
drivers/usb/core/hcd.c | 14 +++
drivers/usb/core/urb.c | 12 ++
drivers/usb/gadget/function/f_sourcesink.c | 1 +
drivers/usb/host/xhci-plat.c | 3 +
drivers/usb/storage/unusual_devs.h | 10 ++
drivers/usb/typec/tcpm/tcpm.c | 3 +-
drivers/usb/typec/ucsi/ucsi_ccg.c | 2 +-
drivers/video/fbdev/hyperv_fb.c | 16 +--
fs/btrfs/ioctl.c | 6 +-
fs/ceph/file.c | 9 ++
fs/configfs/dir.c | 6 +-
fs/devpts/inode.c | 2 +-
fs/jbd2/journal.c | 2 +
fs/namei.c | 10 +-
fs/nfs/dir.c | 4 +
fs/nfsd/nfsctl.c | 5 +-
fs/ocfs2/suballoc.c | 25 ++--
include/linux/fsnotify.h | 48 +++++++-
include/linux/usb/role.h | 6 +
include/net/addrconf.h | 2 +
include/net/ip.h | 21 ++--
include/net/ip6_fib.h | 2 +-
include/net/route.h | 2 +-
kernel/bpf/stackmap.c | 5 +-
kernel/events/core.c | 8 +-
kernel/events/uprobes.c | 2 +-
kernel/locking/rtmutex.c | 4 +-
kernel/locking/rwsem.c | 2 +-
kernel/locking/semaphore.c | 2 +-
kernel/power/wakelock.c | 11 +-
kernel/sched/fair.c | 18 ++-
kernel/sched/membarrier.c | 11 +-
kernel/sched/pelt.h | 4 +-
kernel/trace/trace.c | 3 +-
kernel/trace/trace_events_hist.c | 1 +
net/bluetooth/hci_event.c | 10 +-
net/bridge/br_vlan.c | 9 +-
net/core/net-procfs.c | 35 +++++-
net/ipv4/ip_output.c | 41 ++++---
net/ipv4/ping.c | 3 +-
net/ipv4/raw.c | 5 +-
net/ipv6/addrconf.c | 27 +++--
net/ipv6/ip6_fib.c | 23 ++--
net/ipv6/ip6_tunnel.c | 8 +-
net/ipv6/route.c | 2 +-
net/netfilter/nf_conntrack_core.c | 8 +-
net/netfilter/nft_payload.c | 3 +
net/rxrpc/call_event.c | 8 +-
net/rxrpc/output.c | 2 +-
net/sunrpc/rpc_pipe.c | 4 +-
usr/include/Makefile | 1 -
virt/kvm/kvm_main.c | 1 -
101 files changed, 836 insertions(+), 407 deletions(-)
--
2.20.1
1
92
Backport 5.10.95 LTS patches from upstream.
David Matlack (1):
KVM: x86/mmu: Fix write-protection of PTs mapped by the TDP MMU
Jan Kara (1):
select: Fix indefinitely sleeping task in poll_schedule_timeout()
Manish Chopra (2):
bnx2x: Utilize firmware 7.13.21.0
bnx2x: Invalidate fastpath HSI version for VFs
Mathias Krause (1):
drm/vmwgfx: Fix stale file descriptors on failed usercopy
Paul E. McKenney (1):
rcu: Tighten rcu_advance_cbs_nowake() checks
Tvrtko Ursulin (1):
drm/i915: Flush TLBs before releasing backing store
arch/x86/kvm/mmu/tdp_mmu.c | 6 +-
.../gpu/drm/i915/gem/i915_gem_object_types.h | 1 +
drivers/gpu/drm/i915/gem/i915_gem_pages.c | 10 ++
drivers/gpu/drm/i915/gt/intel_gt.c | 102 ++++++++++++++++++
drivers/gpu/drm/i915/gt/intel_gt.h | 2 +
drivers/gpu/drm/i915/gt/intel_gt_types.h | 2 +
drivers/gpu/drm/i915/i915_reg.h | 11 ++
drivers/gpu/drm/i915/i915_vma.c | 3 +
drivers/gpu/drm/i915/intel_uncore.c | 26 ++++-
drivers/gpu/drm/i915/intel_uncore.h | 2 +
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 5 +-
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 33 +++---
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +-
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 11 +-
.../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 6 +-
.../ethernet/broadcom/bnx2x/bnx2x_fw_defs.h | 2 +
.../net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 3 +-
.../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 75 +++++++++----
.../net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 13 ++-
fs/select.c | 63 +++++------
kernel/rcu/tree.c | 7 +-
22 files changed, 296 insertions(+), 91 deletions(-)
--
2.20.1
1
7

[PATCH openEuler-5.10 1/5] arm64: kdump: Update the name of crashk_low_res
by Zheng Zengkai 28 Apr '22
by Zheng Zengkai 28 Apr '22
28 Apr '22
From: Zhen Lei <thunder.leizhen(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I545H8
CVE: NA
-------------------------------------------------------------------------
To be consistent with the style of other ARCHs such as x86, the kexec
commit b5a34a20984c ("arm64: support more than one crash kernel regions")
requires all crash regions to be named "Crash kernel". Update the name of
crashk_low_res, so that we can directly use the latest kexec tool without
having to maintain a private version.
Signed-off-by: Zhen Lei <thunder.leizhen(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
arch/arm64/kernel/setup.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 2dd3ea837d35..ddca8d27fca6 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -274,16 +274,9 @@ static void __init request_standard_resources(void)
request_memmap_resources(res);
#ifdef CONFIG_KEXEC_CORE
- /*
- * Userspace will find "Crash kernel" or "Crash kernel (low)"
- * region in /proc/iomem.
- * In order to distinct from the high region and make no effect
- * to the use of existing kexec-tools, rename the low region as
- * "Crash kernel (low)".
- */
+ /* Userspace will find "Crash kernel" region in /proc/iomem. */
if (crashk_low_res.end && crashk_low_res.start >= res->start &&
crashk_low_res.end <= res->end) {
- crashk_low_res.name = "Crash kernel (low)";
request_resource(res, &crashk_low_res);
}
if (crashk_res.end && crashk_res.start >= res->start &&
--
2.20.1
1
4

[PATCH openEuler-5.10 1/6] Revert "xfrm: rate limit SA mapping change message to user space"
by Zheng Zengkai 28 Apr '22
by Zheng Zengkai 28 Apr '22
28 Apr '22
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I531X9
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
This reverts commit 71022a70c75395d2edbd2bf83101794f65719a69.
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Acked-by: Xie XiuQi <xiexiuqi(a)huawei.com>
---
include/net/xfrm.h | 5 -----
include/uapi/linux/xfrm.h | 1 -
net/xfrm/xfrm_compat.c | 6 ++----
net/xfrm/xfrm_state.c | 23 +----------------------
net/xfrm/xfrm_user.c | 18 +-----------------
5 files changed, 4 insertions(+), 49 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index c3437ae77e7d..f2875c629d06 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -199,11 +199,6 @@ struct xfrm_state {
struct xfrm_algo_aead *aead;
const char *geniv;
- /* mapping change rate limiting */
- __be16 new_mapping_sport;
- u32 new_mapping; /* seconds */
- u32 mapping_maxage; /* seconds for input SA */
-
/* Data for encapsulator */
struct xfrm_encap_tmpl *encap;
struct sock __rcu *encap_sk;
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 2290c98b47cf..ffc6a5391bb7 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -308,7 +308,6 @@ enum xfrm_attr_type_t {
XFRMA_SET_MARK, /* __u32 */
XFRMA_SET_MARK_MASK, /* __u32 */
XFRMA_IF_ID, /* __u32 */
- XFRMA_MTIMER_THRESH, /* __u32 in seconds for input SA */
__XFRMA_MAX
#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */
diff --git a/net/xfrm/xfrm_compat.c b/net/xfrm/xfrm_compat.c
index a0f62fa02e06..2bf269390163 100644
--- a/net/xfrm/xfrm_compat.c
+++ b/net/xfrm/xfrm_compat.c
@@ -127,7 +127,6 @@ static const struct nla_policy compat_policy[XFRMA_MAX+1] = {
[XFRMA_SET_MARK] = { .type = NLA_U32 },
[XFRMA_SET_MARK_MASK] = { .type = NLA_U32 },
[XFRMA_IF_ID] = { .type = NLA_U32 },
- [XFRMA_MTIMER_THRESH] = { .type = NLA_U32 },
};
static struct nlmsghdr *xfrm_nlmsg_put_compat(struct sk_buff *skb,
@@ -275,10 +274,9 @@ static int xfrm_xlate64_attr(struct sk_buff *dst, const struct nlattr *src)
case XFRMA_SET_MARK:
case XFRMA_SET_MARK_MASK:
case XFRMA_IF_ID:
- case XFRMA_MTIMER_THRESH:
return xfrm_nla_cpy(dst, src, nla_len(src));
default:
- BUILD_BUG_ON(XFRMA_MAX != XFRMA_MTIMER_THRESH);
+ BUILD_BUG_ON(XFRMA_MAX != XFRMA_IF_ID);
pr_warn_once("unsupported nla_type %d\n", src->nla_type);
return -EOPNOTSUPP;
}
@@ -433,7 +431,7 @@ static int xfrm_xlate32_attr(void *dst, const struct nlattr *nla,
int err;
if (type > XFRMA_MAX) {
- BUILD_BUG_ON(XFRMA_MAX != XFRMA_MTIMER_THRESH);
+ BUILD_BUG_ON(XFRMA_MAX != XFRMA_IF_ID);
NL_SET_ERR_MSG(extack, "Bad attribute");
return -EOPNOTSUPP;
}
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 65e2805fa113..c158e70e8ae1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1557,9 +1557,6 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
x->km.seq = orig->km.seq;
x->replay = orig->replay;
x->preplay = orig->preplay;
- x->mapping_maxage = orig->mapping_maxage;
- x->new_mapping = 0;
- x->new_mapping_sport = 0;
return x;
@@ -2211,7 +2208,7 @@ int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
}
EXPORT_SYMBOL(km_query);
-static int __km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
+int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
{
int err = -EINVAL;
struct xfrm_mgr *km;
@@ -2226,24 +2223,6 @@ static int __km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16
rcu_read_unlock();
return err;
}
-
-int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
-{
- int ret = 0;
-
- if (x->mapping_maxage) {
- if ((jiffies / HZ - x->new_mapping) > x->mapping_maxage ||
- x->new_mapping_sport != sport) {
- x->new_mapping_sport = sport;
- x->new_mapping = jiffies / HZ;
- ret = __km_new_mapping(x, ipaddr, sport);
- }
- } else {
- ret = __km_new_mapping(x, ipaddr, sport);
- }
-
- return ret;
-}
EXPORT_SYMBOL(km_new_mapping);
void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index d0fdfbf4c5f7..ddf1b3a5f7c1 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -282,10 +282,6 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
err = 0;
- if (attrs[XFRMA_MTIMER_THRESH])
- if (!attrs[XFRMA_ENCAP])
- err = -EINVAL;
-
out:
return err;
}
@@ -525,7 +521,6 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
- struct nlattr *mt = attrs[XFRMA_MTIMER_THRESH];
if (re) {
struct xfrm_replay_state_esn *replay_esn;
@@ -557,9 +552,6 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
if (rt)
x->replay_maxdiff = nla_get_u32(rt);
-
- if (mt)
- x->mapping_maxage = nla_get_u32(mt);
}
static void xfrm_smark_init(struct nlattr **attrs, struct xfrm_mark *m)
@@ -977,13 +969,8 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
if (ret)
goto out;
}
- if (x->security) {
+ if (x->security)
ret = copy_sec_ctx(x->security, skb);
- if (ret)
- goto out;
- }
- if (x->mapping_maxage)
- ret = nla_put_u32(skb, XFRMA_MTIMER_THRESH, x->mapping_maxage);
out:
return ret;
}
@@ -2937,9 +2924,6 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x)
/* Must count x->lastused as it may become non-zero behind our back. */
l += nla_total_size_64bit(sizeof(u64));
- if (x->mapping_maxage)
- l += nla_total_size(sizeof(x->mapping_maxage));
-
return l;
}
--
2.20.1
1
5

[PATCH openEuler-5.10 01/13] ixgbe: add the ability for the PF to disable VF link state
by Zheng Zengkai 27 Apr '22
by Zheng Zengkai 27 Apr '22
27 Apr '22
From: Slawomir Mrozowicz <slawomirx.mrozowicz(a)intel.com>
mainline inclusion
from mainline-v5.18-rc1
commit 366fd1000995d4cf64e1a61a0d78a051550b9841
category: bugfix
bugzilla: 186597, https://gitee.com/src-openeuler/kernel/issues/I532H9
CVE: CVE-2021-33061
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Add support for ndo_set_vf_link_state the Network Device Option that
allows the PF driver to control the virtual link state of the VF devices.
Without this change a VF cannot be disabled/enabled by the administrator.
In the implementation the auto state takes over PF link state to
VF link setting, the enable state is not supported, the disable state
shut off the VF link regardless of the PF setting.
Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz(a)intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski(a)intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen(a)intel.com>
Signed-off-by: Ziyang Xuan <william.xuanziyang(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 2 +
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 11 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h | 2 +
.../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 207 ++++++++++++++----
.../net/ethernet/intel/ixgbe/ixgbe_sriov.h | 4 +-
5 files changed, 182 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index de0fc6ecf491..21bdae9eac75 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -177,6 +177,8 @@ struct vf_data_storage {
u16 pf_vlan; /* When set, guest VLAN config not allowed. */
u16 pf_qos;
u16 tx_rate;
+ int link_enable;
+ int link_state;
u8 spoofchk_enabled;
bool rss_query_enabled;
u8 trusted;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0109b47b2fe6..c0a56308dfd6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5683,6 +5683,9 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+
+ /* update setting rx tx for all active vfs */
+ ixgbe_set_all_vfs(adapter);
}
void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
@@ -6140,11 +6143,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
for (i = 0 ; i < adapter->num_vfs; i++)
adapter->vfinfo[i].clear_to_send = false;
- /* ping all the active vfs to let them know we are going down */
- ixgbe_ping_all_vfs(adapter);
-
- /* Disable all VFTE/VFRE TX/RX */
- ixgbe_disable_tx_rx(adapter);
+ /* update setting rx tx for all active vfs */
+ ixgbe_set_all_vfs(adapter);
}
/* disable transmits in the hardware now that interrupts are off */
@@ -10255,6 +10255,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
.ndo_set_vf_rate = ixgbe_ndo_set_vf_bw,
.ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
+ .ndo_set_vf_link_state = ixgbe_ndo_set_vf_link_state,
.ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en,
.ndo_set_vf_trust = ixgbe_ndo_set_vf_trust,
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
index a148534d7256..8f4316b19278 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
@@ -85,6 +85,8 @@ enum ixgbe_pfvf_api_rev {
#define IXGBE_VF_IPSEC_ADD 0x0d
#define IXGBE_VF_IPSEC_DEL 0x0e
+#define IXGBE_VF_GET_LINK_STATE 0x10 /* get vf link state */
+
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
/* word in permanent address message with the current multicast type */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 214a38de3f41..7f11c0a8e7a9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -96,6 +96,7 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
for (i = 0; i < num_vfs; i++) {
/* enable spoof checking for all VFs */
adapter->vfinfo[i].spoofchk_enabled = true;
+ adapter->vfinfo[i].link_enable = true;
/* We support VF RSS querying only for 82599 and x540
* devices at the moment. These devices share RSS
@@ -820,6 +821,57 @@ static inline void ixgbe_write_qde(struct ixgbe_adapter *adapter, u32 vf,
}
}
+/**
+ * ixgbe_set_vf_rx_tx - Set VF rx tx
+ * @adapter: Pointer to adapter struct
+ * @vf: VF identifier
+ *
+ * Set or reset correct transmit and receive for vf
+ **/
+static void ixgbe_set_vf_rx_tx(struct ixgbe_adapter *adapter, int vf)
+{
+ u32 reg_cur_tx, reg_cur_rx, reg_req_tx, reg_req_rx;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 reg_offset, vf_shift;
+
+ vf_shift = vf % 32;
+ reg_offset = vf / 32;
+
+ reg_cur_tx = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset));
+ reg_cur_rx = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));
+
+ if (adapter->vfinfo[vf].link_enable) {
+ reg_req_tx = reg_cur_tx | 1 << vf_shift;
+ reg_req_rx = reg_cur_rx | 1 << vf_shift;
+ } else {
+ reg_req_tx = reg_cur_tx & ~(1 << vf_shift);
+ reg_req_rx = reg_cur_rx & ~(1 << vf_shift);
+ }
+
+ /* The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs.
+ * For more info take a look at ixgbe_set_vf_lpe
+ */
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ struct net_device *dev = adapter->netdev;
+ int pf_max_frame = dev->mtu + ETH_HLEN;
+
+#if IS_ENABLED(CONFIG_FCOE)
+ if (dev->features & NETIF_F_FCOE_MTU)
+ pf_max_frame = max_t(int, pf_max_frame,
+ IXGBE_FCOE_JUMBO_FRAME_SIZE);
+#endif /* CONFIG_FCOE */
+
+ if (pf_max_frame > ETH_FRAME_LEN)
+ reg_req_rx = reg_cur_rx & ~(1 << vf_shift);
+ }
+
+ /* Enable/Disable particular VF */
+ if (reg_cur_tx != reg_req_tx)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg_req_tx);
+ if (reg_cur_rx != reg_req_rx)
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg_req_rx);
+}
+
static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
@@ -845,11 +897,6 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
vf_shift = vf % 32;
reg_offset = vf / 32;
- /* enable transmit for vf */
- reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset));
- reg |= BIT(vf_shift);
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg);
-
/* force drop enable for all VF Rx queues */
reg = IXGBE_QDE_ENABLE;
if (adapter->vfinfo[vf].pf_vlan)
@@ -857,27 +904,7 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
ixgbe_write_qde(adapter, vf, reg);
- /* enable receive for vf */
- reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));
- reg |= BIT(vf_shift);
- /*
- * The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs.
- * For more info take a look at ixgbe_set_vf_lpe
- */
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- struct net_device *dev = adapter->netdev;
- int pf_max_frame = dev->mtu + ETH_HLEN;
-
-#ifdef CONFIG_FCOE
- if (dev->features & NETIF_F_FCOE_MTU)
- pf_max_frame = max_t(int, pf_max_frame,
- IXGBE_FCOE_JUMBO_FRAME_SIZE);
-
-#endif /* CONFIG_FCOE */
- if (pf_max_frame > ETH_FRAME_LEN)
- reg &= ~BIT(vf_shift);
- }
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg);
+ ixgbe_set_vf_rx_tx(adapter, vf);
/* enable VF mailbox for further messages */
adapter->vfinfo[vf].clear_to_send = true;
@@ -1202,6 +1229,26 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
return 0;
}
+static int ixgbe_get_vf_link_state(struct ixgbe_adapter *adapter,
+ u32 *msgbuf, u32 vf)
+{
+ u32 *link_state = &msgbuf[1];
+
+ /* verify the PF is supporting the correct API */
+ switch (adapter->vfinfo[vf].vf_api) {
+ case ixgbe_mbox_api_12:
+ case ixgbe_mbox_api_13:
+ case ixgbe_mbox_api_14:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ *link_state = adapter->vfinfo[vf].link_enable;
+
+ return 0;
+}
+
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{
u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
@@ -1267,6 +1314,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
case IXGBE_VF_UPDATE_XCAST_MODE:
retval = ixgbe_update_vf_xcast_mode(adapter, msgbuf, vf);
break;
+ case IXGBE_VF_GET_LINK_STATE:
+ retval = ixgbe_get_vf_link_state(adapter, msgbuf, vf);
+ break;
case IXGBE_VF_IPSEC_ADD:
retval = ixgbe_ipsec_vf_add_sa(adapter, msgbuf, vf);
break;
@@ -1322,18 +1372,6 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter)
}
}
-void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
-
- /* disable transmit and receive for all vfs */
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0);
-
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0);
-}
-
static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -1359,6 +1397,21 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)
}
}
+/**
+ * ixgbe_set_all_vfs - update vfs queues
+ * @adapter: Pointer to adapter struct
+ *
+ * Update setting transmit and receive queues for all vfs
+ **/
+void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter)
+{
+ int i;
+
+ for (i = 0 ; i < adapter->num_vfs; i++)
+ ixgbe_set_vf_link_state(adapter, i,
+ adapter->vfinfo[i].link_state);
+}
+
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -1656,6 +1709,84 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
return 0;
}
+/**
+ * ixgbe_set_vf_link_state - Set link state
+ * @adapter: Pointer to adapter struct
+ * @vf: VF identifier
+ * @state: required link state
+ *
+ * Set a link force state on/off a single vf
+ **/
+void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state)
+{
+ adapter->vfinfo[vf].link_state = state;
+
+ switch (state) {
+ case IFLA_VF_LINK_STATE_AUTO:
+ if (test_bit(__IXGBE_DOWN, &adapter->state))
+ adapter->vfinfo[vf].link_enable = false;
+ else
+ adapter->vfinfo[vf].link_enable = true;
+ break;
+ case IFLA_VF_LINK_STATE_ENABLE:
+ adapter->vfinfo[vf].link_enable = true;
+ break;
+ case IFLA_VF_LINK_STATE_DISABLE:
+ adapter->vfinfo[vf].link_enable = false;
+ break;
+ }
+
+ ixgbe_set_vf_rx_tx(adapter, vf);
+
+ /* restart the VF */
+ adapter->vfinfo[vf].clear_to_send = false;
+ ixgbe_ping_vf(adapter, vf);
+}
+
+/**
+ * ixgbe_ndo_set_vf_link_state - Set link state
+ * @netdev: network interface device structure
+ * @vf: VF identifier
+ * @state: required link state
+ *
+ * Set the link state of a specified VF, regardless of physical link state
+ **/
+int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ int ret = 0;
+
+ if (vf < 0 || vf >= adapter->num_vfs) {
+ dev_err(&adapter->pdev->dev,
+ "NDO set VF link - invalid VF identifier %d\n", vf);
+ return -EINVAL;
+ }
+
+ switch (state) {
+ case IFLA_VF_LINK_STATE_ENABLE:
+ dev_info(&adapter->pdev->dev,
+ "NDO set VF %d link state %d - not supported\n",
+ vf, state);
+ break;
+ case IFLA_VF_LINK_STATE_DISABLE:
+ dev_info(&adapter->pdev->dev,
+ "NDO set VF %d link state disable\n", vf);
+ ixgbe_set_vf_link_state(adapter, vf, state);
+ break;
+ case IFLA_VF_LINK_STATE_AUTO:
+ dev_info(&adapter->pdev->dev,
+ "NDO set VF %d link state auto\n", vf);
+ ixgbe_set_vf_link_state(adapter, vf, state);
+ break;
+ default:
+ dev_err(&adapter->pdev->dev,
+ "NDO set VF %d - invalid link state %d\n", vf, state);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
bool setting)
{
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index 3ec21923c89c..0690ecb8dfa3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -17,8 +17,8 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
#endif
void ixgbe_msg_task(struct ixgbe_adapter *adapter);
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
-void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
+void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter);
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
u8 qos, __be16 vlan_proto);
@@ -31,7 +31,9 @@ int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting);
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi);
+int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state);
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
+void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state);
int ixgbe_disable_sriov(struct ixgbe_adapter *adapter);
#ifdef CONFIG_PCI_IOV
void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs);
--
2.20.1
1
12

[PATCH openEuler-5.10 01/42] can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error path
by Zheng Zengkai 27 Apr '22
by Zheng Zengkai 27 Apr '22
27 Apr '22
From: Hangyu Hua <hbh25y(a)gmail.com>
stable inclusion
from stable-v5.10.110
commit 5318cdf4fd834856ce71238b064f35386f9ef528
category: bugfix
bugzilla: 186592 https://gitee.com/src-openeuler/kernel/issues/I51YBQ?from=project-issue
CVE: CVE-2022-28388
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 3d3925ff6433f98992685a9679613a2cc97f3ce2 upstream.
There is no need to call dev_kfree_skb() when usb_submit_urb() fails
because can_put_echo_skb() deletes original skb and
can_free_echo_skb() deletes the cloned skb.
Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices")
Link: https://lore.kernel.org/all/20220311080614.45229-1-hbh25y@gmail.com
Cc: stable(a)vger.kernel.org
Signed-off-by: Hangyu Hua <hbh25y(a)gmail.com>
Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Ziyang Xuan <william.xuanziyang(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/net/can/usb/usb_8dev.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index ca7c55d6a41d..985e00aee4ee 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -670,9 +670,20 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
atomic_inc(&priv->active_tx_urbs);
err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err))
- goto failed;
- else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
+ if (unlikely(err)) {
+ can_free_echo_skb(netdev, context->echo_index);
+
+ usb_unanchor_urb(urb);
+ usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
+
+ atomic_dec(&priv->active_tx_urbs);
+
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ else
+ netdev_warn(netdev, "failed tx_urb %d\n", err);
+ stats->tx_dropped++;
+ } else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
/* Slow down tx path */
netif_stop_queue(netdev);
@@ -691,19 +702,6 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
-failed:
- can_free_echo_skb(netdev, context->echo_index);
-
- usb_unanchor_urb(urb);
- usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
-
- atomic_dec(&priv->active_tx_urbs);
-
- if (err == -ENODEV)
- netif_device_detach(netdev);
- else
- netdev_warn(netdev, "failed tx_urb %d\n", err);
-
nomembuf:
usb_free_urb(urb);
--
2.20.1
1
41
Backport 5.10.94 LTS patches from upstream.
Complicts:
Already merged(-11):
f2fs: fix to do sanity check in is_alive()
RDMA/hns: Validate the pkey index
iommu/iova: Fix race between FQ timeout and teardown By 1bfe3f8bbb24 iommu/iova: wait 'fq_timer' handler to finish before destroying 'fq'
scsi: block: pm: Always set request queue runtime active in blk_post_runtime_resume()
mwifiex: Fix skb_over_panic in mwifiex_usb_recv() By 7c24452ca6d mwifiex_usb: Fix skb_over_panic in mwifiex_usb_recv
audit: ensure userspace is penalized the same as the kernel when under pressure By 29d444b2cd53 audit: ensure userspace is penalized the same as the kernel when under pressure
jffs2: GC deadlock reading a page that is used in jffs2_write_begin()
ext4: Fix BUG_ON in ext4_bread when write quota data
ext4: fix null-ptr-deref in '__ext4_journal_ensure_credits'
RDMA/hns: Modify the mapping attribute of doorbell to device Use mainline mainline-v5.15-rc3 solution by 8d4553b61b1c RDMA/hns: Modify the mapping attribute of doorbell to device
block: Fix fsync always failed if once failed Use mainline mainline-v5.17 solution by 2ffb13b95b88 block: Fix fsync always failed if once failed
Context conflict:
mm_zone: add function to check if managed dma zone exists
sched/fair: Fix per-CPU kthread and wakee stacking for asym CPU capacity
x86/kbuild: Enable CONFIG_KALLSYMS_ALL=y in the defconfigs
PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors
Will be merged separately(-2):
arm64: lib: Annotate {clear, copy}_page() as position-independent
arm64: clear_page() shouldn't use DC ZVA when DCZID_EL0.DZP == 1
Implement changed(reverted old one and reapplied the LTS patch, +1):
sched/rt: Try to restart rt period timer when rt runtime exceeded
Modified(fix build error):
iommu/io-pgtable-arm: Fix table descriptor paddr formatting
Total patches: 560 - 11 - 2 + 1(the reverted patch) = 548
Adam Ford (1):
clk: imx8mn: Fix imx8mn_clko1_sels
Adrian Hunter (1):
perf script: Fix hex dump character output
Alex Deucher (1):
drm/amdgpu/display: set vblank_disable_immediate for DC
Alexander Aring (4):
fs: dlm: use sk->sk_socket instead of con->sock
fs: dlm: don't call kernel_getpeername() in error_report()
fs: dlm: fix build with CONFIG_IPV6 disabled
fs: dlm: filter user dlm messages for kernel locks
Alexander Gordeev (1):
s390/mm: fix 2KB pgtable release race
Alexander Stein (4):
arm64: dts: amlogic: meson-g12: Fix GPU operating point table node
name
arm64: dts: amlogic: Fix SPI NOR flash node name for ODROID N2/N2+
dt-bindings: display: meson-dw-hdmi: add missing sound-name-prefix
property
dt-bindings: display: meson-vpu: Add missing amlogic,canvas property
Alexei Starovoitov (1):
bpf: Adjust BTF log size limit.
Alexey Kardashevskiy (2):
KVM: PPC: Book3S: Suppress warnings when allocating too big memory
slots
KVM: PPC: Book3S: Suppress failed alloc warning in H_COPY_TOFROM_GUEST
Aline Santana Cordeiro (1):
media: staging: media: atomisp: pci: Balance braces around conditional
statements in file atomisp_cmd.c
Alistair Francis (1):
HID: quirks: Allow inverting the absolute X/Y values
Alistair Popple (1):
mm/hmm.c: allow VM_MIXEDMAP to work with hmm_range_fault
Alyssa Ross (1):
ASoC: fsl_mqs: fix MODULE_ALIAS
Amelie Delaunay (1):
dmaengine: stm32-mdma: fix STM32_MDMA_CTBR_TSEL_MASK
Ammar Faizi (2):
tools/nolibc: x86-64: Fix startup code bug
powerpc/xive: Add missing null check after calling kmalloc
Anders Roxell (2):
selftests: clone3: clone3: add case CLONE3_ARGS_NO_TEST
powerpc/cell: Fix clang -Wimplicit-fallthrough warning
Andre Przywara (1):
ARM: 9159/1: decompressor: Avoid UNPREDICTABLE NOP encoding
Andreas Oetken (1):
mtd: Fixed breaking list in __mtd_del_partition.
Andrey Konovalov (1):
lib/test_meminit: destroy cache in kmem_cache_alloc_bulk() test
Andrey Ryabinin (1):
cputime, cpuacct: Include guest time in user time in cpuacct.stat
Andrii Nakryiko (1):
selftests/bpf: Fix bpf_object leak in skb_ctx selftest
Anilkumar Kolli (1):
ath11k: Use host CE parameters for CE interrupts configuration
Antoine Tenart (1):
net-sysfs: update the queue counts in the unregistration path
Anton Vasilyev (1):
media: dw2102: Fix use after free
Antony Antony (3):
xfrm: interface with if_id 0 should return error
xfrm: state and policy should fail if XFRMA_IF_ID 0
xfrm: rate limit SA mapping change message to user space
Arnaud Pouliquen (1):
rpmsg: core: Clean up resources on announce_create failure.
Arnd Bergmann (1):
dmaengine: pxa/mmp: stop referencing config->slave_id
Arseny Demidov (1):
hwmon: (mr75203) fix wrong power-up delay value
Athira Rajeev (2):
powerpc/perf: MMCR0 control for PMU registers under PMCC=00
powerpc/perf: Fix PMU callbacks to clear pending PMI before resetting
an overflown PMC
Avihai Horon (2):
RDMA/core: Let ib_find_gid() continue search even after empty entry
RDMA/cma: Let cma_resolve_ib_dev() continue search even after empty
entry
Aya Levin (2):
net/mlx5e: Fix page DMA map/unmap attributes
Revert "net/mlx5e: Block offload of outer header csum for UDP tunnels"
Baochen Qiang (2):
ath11k: Fix crash caused by uninitialized TX ring
ath11k: Avoid false DEADLOCK warning reported by lockdep
Baoquan He (3):
mm_zone: add function to check if managed dma zone exists
dma/pool: create dma atomic pool only if dma zone has managed pages
mm/page_alloc.c: do not warn allocation failure on zone DMA if no
managed pages
Bart Van Assche (2):
scsi: ufs: Fix race conditions related to driver data
scsi: core: Show SCMD_LAST in text form
Baruch Siach (3):
arm64: dts: qcom: ipq6018: Fix gpio-ranges property
of: base: Fix phandle argument length mismatch error message
of: base: Improve argument length mismatch error
Ben Greear (1):
ath11k: Fix napi related hang
Ben Hutchings (1):
firmware: Update Kconfig help text for Google firmware
Ben Skeggs (1):
drm/nouveau/pmu/gm200-: avoid touching PMU outside of
DEVINIT/PREOS/ACR
Benjamin Li (3):
wcn36xx: ensure pairing of init_scan/finish_scan and
start_scan/end_scan
wcn36xx: populate band before determining rate on RX
wcn36xx: fix RX BD rate mapping for 5GHz legacy rates
Bernard Zhao (1):
selinux: fix potential memleak in selinux_add_opt()
Bhaskar Chowdhury (1):
crypto: qat - fix spelling mistake: "messge" -> "message"
Biju Das (1):
arm64: dts: renesas: cat875: Add rx/tx delays
Biwen Li (1):
arm64: dts: ls1028a-qds: move rtc node to the correct i2c bus
Bixuan Cui (1):
ALSA: oss: fix compile error when OSS_DEBUG is enabled
Borislav Petkov (4):
x86/mce: Allow instrumentation during task work queueing
x86/mce: Mark mce_panic() noinstr
x86/mce: Mark mce_end() noinstr
x86/mce: Mark mce_read_aux() noinstr
Brian Norris (8):
drm/panel: kingdisplay-kd097d04: Delete panel on attach() failure
drm/panel: innolux-p079zca: Delete panel on attach() failure
drm/rockchip: dsi: Fix unbalanced clock on probe error
drm/rockchip: dsi: Hold pm-runtime across bind/unbind
drm/rockchip: dsi: Disable PLL clock on bind error
drm/rockchip: dsi: Reconfigure hardware on resume()
mwifiex: Fix possible ABBA deadlock
drm/bridge: analogix_dp: Make PSR-exit block less
Bryan O'Donoghue (5):
wcn36xx: Indicate beacon not connection loss on MISSED_BEACON_IND
wcn36xx: Fix DMA channel enable/disable cycle
wcn36xx: Release DMA channel descriptor allocations
wcn36xx: Put DXE block into reset before freeing memory
media: venus: core, venc, vdec: Fix probe dependency error
Cezary Rojewski (1):
ASoC: Intel: catpt: Test dmaengine_submit() result before moving on
Changcheng Deng (1):
PM: AVS: qcom-cpr: Use div64_ul instead of do_div
Chao Yu (1):
f2fs: fix to reserve space for IO align feature
Chen Jun (1):
tpm: add request_locality before write TPM_INT_ENABLE
Chengfeng Ye (3):
crypto: qce - fix uaf on qce_ahash_register_one
crypto: qce - fix uaf on qce_skcipher_register_one
HSI: core: Fix return freed object in hsi_new_client
Chengguang Xu (1):
RDMA/rxe: Fix a typo in opcode name
Christian Eggers (1):
mtd: rawnand: gpmi: Add ERR007117 protection for nfc_apply_timings
Christian Hewitt (2):
arm64: dts: meson-gxbb-wetek: fix HDMI in early boot
arm64: dts: meson-gxbb-wetek: fix missing GPIO binding
Christian König (1):
drm/radeon: fix error handling in radeon_driver_open_kms
Christian Lamparter (1):
ARM: dts: gemini: NAS4220-B: fis-index-block with 128 KiB sectors
Christoph Hellwig (2):
dm: fix alloc_dax error handling in alloc_dev
scsi: sr: Don't use GFP_DMA
Christophe JAILLET (3):
media: venus: core: Fix a potential NULL pointer dereference in an
error handling path
media: venus: core: Fix a resource leak in the error handling path of
'venus_probe()'
RDMA/bnxt_re: Scan the whole bitmap when checking if "disabling RCFW
with pending cmd-bit"
Christophe Jaillet (1):
tpm_tis: Fix an error handling path in 'tpm_tis_core_init()'
Christophe Leroy (7):
lkdtm: Fix content of section containing lkdtm_rodata_do_nothing()
powerpc/irq: Add helper to set regs->softe
powerpc/32s: Fix shift-out-of-bounds in KASAN init
powerpc/powermac: Add additional missing lockdep_register_key()
powerpc/powermac: Add missing lockdep_register_key()
w1: Misuse of get_user()/put_user() reported by sparse
powerpc/40x: Map 32Mbytes of memory at startup
Chunguang Xu (1):
ext4: fix a possible ABBA deadlock due to busy PA
Claudiu Beznea (2):
mfd: atmel-flexcom: Remove #ifdef CONFIG_PM_SLEEP
mfd: atmel-flexcom: Use .resume_noirq
Clément Léger (1):
software node: fix wrong node passed to find nargs_prop
Conor Dooley (1):
clk: bm1880: remove kfrees on static allocations
Dafna Hirschfeld (1):
media: mtk-vcodec: call v4l2_m2m_ctx_release first when file is
released
Dan Carpenter (7):
drm/bridge: display-connector: fix an uninitialized pointer in probe()
media: atomisp: fix uninitialized bug in gmin_get_pmic_id_and_addr()
drm/vboxvideo: fix a NULL vs IS_ERR() check
rocker: fix a sleeping in atomic bug
Bluetooth: L2CAP: uninitialized variables in l2cap_sock_setsockopt()
ax25: uninitialized variable in ax25_setsockopt()
netrom: fix api breakage in nr_setsockopt()
Daniel Borkmann (1):
bpf: Don't promote bogus looking registers after null check.
Daniel Thompson (1):
Documentation: dmaengine: Correctly describe dmatest with channel
unset
Danielle Ratson (2):
mlxsw: pci: Add shutdown method in PCI driver
mlxsw: pci: Avoid flow control for EMAD packets
David Heidelberg (1):
arm64: dts: qcom: msm8996: drop not documented adreno properties
Dillon Min (3):
media: videobuf2: Fix the size printk format
ARM: dts: stm32: fix dtbs_check warning on ili9341 dts binding on
stm32f429 disco
clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
system enter shell
Dinh Nguyen (1):
EDAC/synopsys: Use the quirk for version instead of ddr version
Dmitry Baryshkov (2):
arm64: dts: qcom: msm8916: fix MMC controller aliases
drm/msm/dpu: fix safe status debugfs file
Dmitry Osipenko (1):
gpu: host1x: Add back arm_iommu_detach_device()
Dmitry Torokhov (1):
HID: vivaldi: fix handling devices not using numbered reports
Dominik Brodowski (1):
pcmcia: fix setting of kthread task states
Dongliang Mu (1):
media: em28xx: fix memory leak in em28xx_init_dev
Doyle, Patrick (1):
mtd: nand: bbt: Fix corner case in bad block table handling
Eli Cohen (1):
vdpa/mlx5: Fix wrong configuration of virtio_version_1_0
Eric Dumazet (7):
xfrm: fix a small bug in xfrm_sa_len()
ppp: ensure minimum packet size in ppp_write()
ipv4: update fib_info_cnt under spinlock protection
ipv4: avoid quadratic behavior in netns dismantle
af_unix: annote lockless accesses to unix_tot_inflight &
gc_in_progress
inet: frags: annotate races around fqdir->dead and fqdir->high_thresh
netns: add schedule point in ops_exit_list()
Eric W. Biederman (1):
taskstats: Cleanup the use of task->exit_code
Fabio Estevam (3):
media: imx-pxp: Initialize the spinlock prior to using it
regmap: Call regmap_debugfs_exit() prior to _init()
ath10k: Fix the MTU size on QCA9377 SDIO
Fabrice Gasnier (1):
counter: stm32-lptimer-cnt: remove iio counter abi
Filipe Manana (2):
btrfs: fix deadlock between quota enable and other quota operations
btrfs: respect the max size in the header when activating swap file
Florian Fainelli (1):
net: mdio: Demote probed message to debug print
Florian Westphal (2):
netfilter: bridge: add support for pppoe filtering
netfilter: nft_set_pipapo: allocate pcpu scratch maps on clone
Frank Rowand (1):
of: unittest: 64 bit dma address test requires arch support
Frederic Weisbecker (1):
rcu/exp: Mark current CPU as exp-QS in IPI loop second pass
Fugang Duan (1):
tty: serial: imx: disable UCR4_OREN in .stop_rx() instead of
.shutdown()
Gang Li (1):
shmem: fix a race between shmem_unused_huge_shrink and
shmem_evict_inode
George G. Davis (1):
mtd: hyperbus: rpc-if: fix bug in rpcif_hb_remove
German Gomez (1):
perf evsel: Override attr->sample_period for non-libpfm4 events
Ghalem Boudour (1):
xfrm: fix policy lookup for ipv6 gre packets
Giovanni Cabiddu (1):
crypto: qat - fix undetected PFVF timeout in ACK loop
Guillaume Nault (3):
xfrm: Don't accidentally set RTO_ONLINK in decode_session4()
gre: Don't accidentally set RTO_ONLINK in gre_fill_metadata_dst()
libcxgb: Don't accidentally set RTO_ONLINK in cxgb_find_route()
Hans Verkuil (2):
media: v4l2-ioctl.c: readbuffers depends on V4L2_CAP_READWRITE
media: cec-pin: fix interrupt en/disable handling
Hans de Goede (9):
ACPI: scan: Create platform device for BCM4752 and LNV4752 ACPI nodes
media: atomisp-ov2680: Fix ov2680_set_fmt() clobbering the exposure
drm: panel-orientation-quirks: Add quirk for the Lenovo Yoga Book
X91F/L
gpiolib: acpi: Do not set the IRQ type if the IRQ is already in use
ACPI / x86: Drop PWM2 device on Lenovo Yoga Book from always present
table
ACPI: Change acpi_device_always_present() into
acpi_device_override_status()
ACPI / x86: Allow specifying acpi_device_override_status() quirks by
path
ACPI / x86: Add not-present quirk for the PCI0.SDHB.BRC1 device on the
GPD win
PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep
errors
Hari Bathini (2):
powerpc: handle kdump appropriately with crash_kexec_post_notifiers
option
powerpc/fadump: Fix inaccurate CPU state info in vmcore generated with
panic
Harshad Shirwadkar (1):
ext4: initialize err_blk before calling __ext4_get_inode_loc
Hector Martin (1):
iommu/io-pgtable-arm: Fix table descriptor paddr formatting
Heiko Carstens (1):
selftests/ftrace: make kprobe profile testcase description unique
Heiner Kallweit (2):
i2c: i801: Don't silently correct invalid transfer size
crypto: omap-aes - Fix broken pm_runtime_and_get() usage
Herbert Xu (2):
crypto: stm32 - Fix last sparse warning in
stm32_cryp_check_ctr_counter
crypto: stm32 - Revert broken pm_runtime_resume_and_get changes
Hou Tao (1):
bpf: Disallow BPF_LOG_KERNEL log level for bpf(BPF_BTF_LOAD)
Hyeong-Jun Kim (1):
f2fs: compress: fix potential deadlock of compress file
Igor Pylypiv (1):
scsi: pm80xx: Update WARN_ON check in pm8001_mpi_build_cmd()
Ilan Peer (2):
iwlwifi: mvm: Fix calculation of frame length
iwlwifi: mvm: Increase the scan timeout guard to 30 seconds
Ilia Mirkin (1):
drm/nouveau/kms/nv04: use vzalloc for nv04_display
Ingo Molnar (1):
x86/kbuild: Enable CONFIG_KALLSYMS_ALL=y in the defconfigs
Iwona Winiarska (1):
gpio: aspeed: Convert aspeed_gpio.lock to raw_spinlock
Jackie Liu (1):
drm/msm/dp: displayPort driver need algorithm rational
Jakub Kicinski (1):
selftests: harness: avoid false negatives if test has no ASSERTs
James Hilliard (1):
media: uvcvideo: Increase UVC_CTRL_CONTROL_TIMEOUT to 5 seconds.
James Smart (1):
scsi: lpfc: Trigger SLI4 firmware dump before doing driver cleanup
Jammy Huang (2):
media: aspeed: fix mode-detect always time out at 2nd run
media: aspeed: Update signal status immediately to ensure sane hw
state
Jan Kara (4):
ext4: avoid trim error on fs with small groups
udf: Fix error handling in udf_new_inode()
ext4: make sure to reset inode lockdep class when quota enabling fails
ext4: make sure quota gets properly shutdown on error
Jan Kiszka (1):
soc: ti: pruss: fix referenced node in error message
Jann Horn (1):
HID: uhid: Fix worker destroying device without any protection
Jason A. Donenfeld (1):
random: do not throw away excess input to crng_fast_load
Jason Gerecke (3):
HID: wacom: Reset expected and received contact counts at the same
time
HID: wacom: Ignore the confidence flag when a touch is removed
HID: wacom: Avoid using stale array indicies to read contact count
Jens Wiklander (1):
tee: fix put order in teedev_close_context()
Jernej Skrabec (1):
media: hantro: Fix probe func error path
Jiasheng Jiang (9):
media: coda/imx-vdoa: Handle dma_set_coherent_mask error codes
power: reset: mt6397: Check for null res pointer
staging: greybus: audio: Check null pointer
fsl/fman: Check for null pointer after calling devm_ioremap
Bluetooth: hci_bcm: Check for error irq
can: xilinx_can: xcan_probe(): check for error irq
ASoC: rt5663: Handle device_property_read_u32_array error codes
ASoC: mediatek: Check for error clk pointer
ASoC: samsung: idma: Check of ioremap return value
Jie Wang (1):
net: bonding: fix bond_xmit_broadcast return value error bug
Jim Quinlan (1):
of: unittest: fix warning on PowerPC frame size warning
Joakim Tjernlund (1):
i2c: mpc: Correct I2C reset procedure
Joe Thornber (2):
dm btree: add a defensive bounds check to insert_at()
dm space map common: add bounds check to sm_ll_lookup_bitmap()
Joerg Roedel (1):
x86/mm: Flush global TLB when switching to trampoline page-table
Johan Hovold (9):
media: flexcop-usb: fix control-message timeouts
media: mceusb: fix control-message timeouts
media: em28xx: fix control-message timeouts
media: cpia2: fix control-message timeouts
media: s2255: fix control-message timeouts
media: redrat3: fix control-message timeouts
media: pvrusb2: fix control-message timeouts
media: stk1160: fix control-message timeouts
can: softing_cs: softingcs_probe(): fix memleak on registration
failure
Johannes Berg (6):
iwlwifi: mvm: fix 32-bit build in FTM
um: fix ndelay/udelay defines
um: virtio_uml: Fix time-travel external time propagation
iwlwifi: mvm: synchronize with FW after multicast commands
iwlwifi: fix leaks/bad data after failed firmware load
iwlwifi: remove module loading failure message
John David Anglin (2):
parisc: Avoid calling faulthandler_disabled() twice
parisc: Fix lpa and lpa_user defines
Jonathan Cameron (1):
iio: adc: ti-adc081c: Partial revert of removal of ACPI IDs
Jordan Niethe (1):
powerpc/64s: Convert some cpu_setup() and cpu_restore() functions to C
Josef Bacik (3):
btrfs: remove BUG_ON() in find_parent_nodes()
btrfs: remove BUG_ON(!eie) in find_parent_nodes
btrfs: check the root node for uptodate before returning it
José Expósito (5):
HID: hid-uclogic-params: Invalid parameter check in
uclogic_params_init
HID: hid-uclogic-params: Invalid parameter check in
uclogic_params_get_str_desc
HID: hid-uclogic-params: Invalid parameter check in
uclogic_params_huion_init
HID: hid-uclogic-params: Invalid parameter check in
uclogic_params_frame_init_v1_buttonpad
HID: apple: Do not reset quirks when the Fn key is not found
Julia Lawall (4):
powerpc/6xx: add missing of_node_put
powerpc/powernv: add missing of_node_put
powerpc/cell: add missing of_node_put
powerpc/btext: add missing of_node_put
Kai-Heng Feng (1):
usb: hub: Add delay for SuperSpeed hub resume to let links transit to
U0
Kajol Jain (1):
bpf: Remove config check to enable bpf support for branch records
Kamal Heib (2):
RDMA/qedr: Fix reporting max_{send/recv}_wr attrs
RDMA/cxgb4: Set queue pair state when being queried
Karthikeyan Kathirvel (2):
ath11k: clear the keys properly via DISABLE_KEY
ath11k: reset RSN/WPA present state for open BSS
Kees Cook (2):
x86/uaccess: Move variable into switch case statement
char/mwave: Adjust io port register size
Kevin Bracey (1):
net_sched: restore "mpu xxx" handling
Kirill A. Shutemov (1):
ACPICA: Hardware: Do not flush CPU cache when entering S4 and S5
Kishon Vijay Abraham I (1):
arm64: dts: ti: j7200-main: Fix 'dtbs_check' serdes_ln_ctrl node
Konrad Dybcio (1):
regulator: qcom_smd: Align probe function with rpmh-regulator
Krzysztof Kozlowski (1):
nfc: llcp: fix NULL error pointer dereference on sendmsg() after
failed bind()
Kunihiko Hayashi (2):
spi: uniphier: Fix a bug that doesn't point to private data correctly
dmaengine: uniphier-xdmac: Fix type of address variables
Kuniyuki Iwashima (1):
bpf: Fix SO_RCVBUF/SO_SNDBUF handling in _bpf_setsockopt().
Lad Prabhakar (2):
mtd: hyperbus: rpc-if: Check return value of rpcif_sw_init()
memory: renesas-rpc-if: Return error in case devm_ioremap_resource()
fails
Lakshmi Sowjanya D (1):
i2c: designware-pci: Fix to change data types of hcnt and lcnt
parameters
Laurence de Bruxelles (1):
rtc: pxa: fix null pointer dereference
Laurent Pinchart (1):
drm: rcar-du: Fix CRTC timings when CMM is used
Leon Romanovsky (1):
devlink: Remove misleading internal_flags from health reporter dump
Li Hua (1):
sched/rt: Try to restart rt period timer when rt runtime exceeded
Lino Sanfilippo (1):
serial: amba-pl011: do not request memory region twice
Linus Lüssing (1):
batman-adv: allow netlink usage in unprivileged containers
Lizhi Hou (1):
tty: serial: uartlite: allow 64 bit address
Luca Coelho (1):
iwlwifi: pcie: make sure prph_info is set when treating wakeup IRQ
Lucas De Marchi (1):
x86/gpu: Reserve stolen memory for first integrated Intel GPU
Lucas Stach (2):
drm/etnaviv: consider completed fence seqno in hang check
drm/etnaviv: limit submit sizes
Luiz Augusto von Dentz (4):
Bluetooth: L2CAP: Fix not initializing sk_peer_pid
Bluetooth: L2CAP: Fix using wrong mode
Bluetooth: vhci: Set HCI_QUIRK_VALID_LE_STATES
Bluetooth: hci_sync: Fix not setting adv set duration
Lukas Bulwahn (5):
ASoC: uniphier: drop selecting non-existing SND_SOC_UNIPHIER_AIO_DMA
mips: add SYS_HAS_CPU_MIPS64_R5 config for MIPS Release 5 support
mips: fix Kconfig reference to PHYS_ADDR_T_64BIT
ARM: imx: rename DEBUG_IMX21_IMX27_UART to DEBUG_IMX27_UART
Documentation: refer to config RANDOMIZE_BASE for kernel address-space
randomization
Lukas Wunner (3):
serial: pl010: Drop CR register reset on set_termios
serial: core: Keep mctrl register state and cached copy in sync
serial: Fix incorrect rs485 polarity on uart open
Luís Henriques (1):
ext4: set csum seed in tmp inode while migrating to extents
Lv Yunlong (1):
wireless: iwlwifi: Fix a double free in iwl_txq_dyn_alloc_dma
Mansur Alisha Shaik (1):
media: venus: avoid calling core_clk_setrate() concurrently during
concurrent video sessions
Maor Dickman (1):
net/mlx5e: Don't block routes with nexthop objects in SW
Marc Kleine-Budde (3):
can: mcp251xfd: add missing newline to printed strings
can: softing: softing_startstop(): fix set but not used variable
warning
can: mcp251xfd: mcp251xfd_tef_obj_read(): fix typo in error message
Marc Zyngier (1):
irqchip/gic-v4: Disable redistributors' view of the VPE table at boot
time
Marcelo Tosatti (1):
KVM: VMX: switch blocked_vcpu_on_cpu_lock to raw spinlock
Marco Chiappero (2):
crypto: qat - remove unnecessary collision prevention step in PFVF
crypto: qat - make pfvf send message direction agnostic
Marek Behún (1):
ARM: dts: armada-38x: Add generic compatible to UART nodes
Marek Vasut (1):
crypto: stm32/crc32 - Fix kernel BUG triggered in probe()
Marijn Suijten (6):
backlight: qcom-wled: Validate enabled string indices in DT
backlight: qcom-wled: Pass number of elements to read to
read_u32_array
backlight: qcom-wled: Fix off-by-one maximum with default num_strings
backlight: qcom-wled: Override default length with
qcom,enabled-strings
backlight: qcom-wled: Use cpu_to_le16 macro to perform conversion
backlight: qcom-wled: Respect enabled-strings in set_brightness
Marina Nikolic (1):
amdgpu/pm: Make sysfs pm attributes as read-only for VFs
Mark Langsdorf (1):
ACPICA: actypes.h: Expand the ACPI_ACCESS_ definitions
Martin Blumenstingl (1):
clk: meson: gxbb: Fix the SDM_EN bit for MPLL0 on GXBB
Martyn Welch (1):
drm/bridge: megachips: Ensure both bridges are probed before
registration
Mateusz Jończyk (1):
rtc: cmos: take rtc_lock while reading from CMOS
Matthias Schiffer (1):
scripts/dtc: dtx_diff: remove broken example from help text
Mauro Carvalho Chehab (7):
media: atomisp: fix enum formats logic
media: atomisp: fix try_fmt logic
media: atomisp: set per-device's default mode
media: atomisp: handle errors at sh_css_create_isp_params()
media: m920x: don't use stack on USB reads
scripts: sphinx-pre-install: add required ctex dependency
scripts: sphinx-pre-install: Fix ctex support on Debian
Maxim Levitsky (1):
iommu/amd: Restore GA log/tail pointer on host resume
Maxime Ripard (4):
clk: bcm-2835: Pick the closest clock rate
clk: bcm-2835: Remove rounding up the dividers
drm/vc4: hdmi: Set a default HSM rate
drm/vc4: hdmi: Make sure the device is powered with CEC
Meng Li (1):
crypto: caam - replace this_cpu_ptr with raw_cpu_ptr
Miaoqian Lin (6):
Bluetooth: hci_qca: Fix NULL vs IS_ERR_OR_NULL check in
qca_serdev_probe
usb: dwc3: qcom: Fix NULL vs IS_ERR checking in dwc3_qcom_probe
spi: spi-meson-spifc: Add missing pm_runtime_disable() in
meson_spifc_probe
phy: mediatek: Fix missing check in mtk_mipi_tx_probe
parisc: pdc_stable: Fix memory leak in pdcs_register_pathentries
lib82596: Fix IRQ check in sni_82596_probe
Michael Ellerman (1):
powerpc/smp: Move setup_profiling_timer() under CONFIG_PROFILING
Michael Kuron (1):
media: dib0700: fix undefined behavior in tuner shutdown
Michael S. Tsirkin (1):
virtio_ring: mark ring unused on error
Michal Suchanek (1):
debugfs: lockdown: Allow reading debugfs files that are not world
readable
Mika Westerberg (1):
thunderbolt: Runtime PM activate both ends of the device link
Moshe Shemesh (2):
net/mlx5: Set command entry semaphore up once got index free
Revert "net/mlx5: Add retry mechanism to the command entry index
allocation"
Nathan Chancellor (3):
x86/boot/compressed: Move CLANG_FLAGS to beginning of KBUILD_CFLAGS
iwlwifi: mvm: Use div_s64 instead of do_div in
iwl_mvm_ftm_rtt_smoothing()
MIPS: Loongson64: Use three arguments for slti
Nathan Errera (1):
iwlwifi: mvm: test roc running status bits before removing the sta
Neal Liu (1):
usb: uhci: add aspeed ast2600 uhci support
Neil Armstrong (1):
drm/bridge: dw-hdmi: handle ELD when DRM_BRIDGE_ATTACH_NO_CONNECTOR
Nicholas Piggin (3):
powerpc/perf: move perf irq/nmi handling details into traps.c
powerpc/watchdog: Fix missed watchdog reset due to memory ordering
race
powerpc/64s/radix: Fix huge vmap false positive
Nicolas Toromanoff (6):
crypto: stm32/cryp - fix CTR counter carry
crypto: stm32/cryp - fix xts and race condition in crypto_engine
requests
crypto: stm32/cryp - check early input data
crypto: stm32/cryp - fix double pm exit
crypto: stm32/cryp - fix lrw chaining mode
crypto: stm32/cryp - fix bugs and crash in tests
Niklas Söderlund (2):
dt-bindings: thermal: Fix definition of cooling-maps contribution
property
media: rcar-vin: Update format alignment constraints
Nishanth Menon (3):
arm64: dts: ti: k3-j7200: Fix the L2 cache sets
arm64: dts: ti: k3-j721e: Fix the L2 cache sets
arm64: dts: ti: k3-j7200: Correct the d-cache-sets info
Oleksandr Andrushchenko (1):
xen/gntdev: fix unmap notification order
Oleksij Rempel (1):
thermal/drivers/imx: Implement runtime PM support
Pali Rohár (5):
PCI: pci-bridge-emul: Make expansion ROM Base Address register
read-only
PCI: pci-bridge-emul: Properly mark reserved PCIe bits in PCI config
space
PCI: pci-bridge-emul: Fix definitions of reserved bits
PCI: pci-bridge-emul: Correctly set PCIe capabilities
PCI: pci-bridge-emul: Set PCI_STATUS_CAP_LIST for PCIe device
Panicker Harish (1):
Bluetooth: hci_qca: Stop IBS timer during BT OFF
Paolo Abeni (1):
bpf: Do not WARN in bpf_warn_invalid_xdp_action()
Patrick Williams (1):
tpm: fix NPE on probe for missing device
Paul Cercueil (3):
mtd: rawnand: davinci: Don't calculate ECC when reading page
mtd: rawnand: davinci: Avoid duplicated page read
mtd: rawnand: davinci: Rewrite function description
Paul Chaignon (1):
bpftool: Enable line buffering for stdout
Paul E. McKenney (1):
clocksource: Reduce clocksource-skew threshold
Paul Gerber (1):
thermal/drivers/imx8mm: Enable ADC when enabling monitor
Pavankumar Kondeti (1):
usb: gadget: f_fs: Use stream_open() for endpoint files
Pavel Skripkin (2):
Bluetooth: stop proccessing malicious adv data
net: mcs7830: handle usb read errors properly
Peiwei Hu (1):
powerpc/prom_init: Fix improper check of prom_getprop()
Peng Fan (1):
arm64: dts: ti: k3-j721e: correct cache-sets info
Petr Cvachoucek (1):
ubifs: Error path in ubifs_remount_rw() seems to wrongly free write
buffers
Philipp Zabel (1):
media: coda: fix CODA960 JPEG encoder buffer overflow
Ping-Ke Shih (1):
mac80211: allow non-standard VHT MCS-10/11
Po-Hao Huang (1):
rtw88: 8822c: update rx settings to prevent potential hw deadlock
Qiang Yu (1):
drm/lima: fix warning when CONFIG_DEBUG_SG=y & CONFIG_DMA_API_DEBUG=y
Quentin Monnet (1):
bpftool: Remove inclusion of utilities.mak from Makefiles
Rafael J. Wysocki (5):
ACPI: EC: Rework flushing of EC work while suspended to idle
PM: runtime: Add safety net to supplier device release
cpufreq: Fix initialization of min and max frequency QoS requests
ACPICA: Utilities: Avoid deleting the same object twice in a row
ACPICA: Executer: Fix the REFCLASS_REFOF case in
acpi_ex_opcode_1A_0T_1R()
Rameshkumar Sundaram (2):
ath11k: Send PPDU_STATS_CFG with proper pdev mask to firmware
ath11k: Fix deleting uninitialized kernel timer during fragment cache
flush
Randy Dunlap (5):
mips: lantiq: add support for clk_set_parent()
mips: bcm63xx: add support for clk_set_parent()
um: registers: Rename function names to avoid conflicts and build
problems
media: correct MEDIA_TEST_SUPPORT help text
Documentation: fix firewire.rst ABI file path error
Rob Herring (1):
PCI: xgene: Fix IB window setup
Robert Hancock (10):
clk: si5341: Fix clock HW provider cleanup
net: axienet: increase reset timeout
net: axienet: Wait for PhyRstCmplt after core reset
net: axienet: reset core on initialization prior to MDIO access
net: axienet: add missing memory barriers
net: axienet: limit minimum TX ring size
net: axienet: Fix TX ring slot available check
net: axienet: fix number of TX ring slots for available check
net: axienet: fix for TX busy handling
net: axienet: increase default TX ring size to 128
Robert Marko (2):
arm64: dts: marvell: cn9130: add GPIO and SPI aliases
arm64: dts: marvell: cn9130: enable CP0 GPIO controllers
Robert Schlabbach (1):
media: si2157: Fix "warm" tuner state detection
Robin Murphy (1):
drm/tegra: vic: Fix DMA API misuse
Russell King (Oracle) (4):
net: phy: prefer 1000baseT over 1000baseKX
net: phy: marvell: configure RGMII delays for 88E1118
net: gemini: allow any RGMII interface mode
net: sfp: fix high power modules without diagnostic monitoring
Ryuta NAKANISHI (1):
phy: uniphier-usb3ss: fix unintended writing zeros to PHY register
Sakari Ailus (2):
device property: Fix fwnode_graph_devcon_match() fwnode leak
Documentation: ACPI: Fix data node reference documentation
Sam Protsenko (1):
dt-bindings: watchdog: Require samsung,syscon-phandle for Exynos7
Sameer Pujar (2):
arm64: tegra: Fix Tegra194 HDA {clock,reset}-names ordering
arm64: tegra: Remove non existent Tegra194 reset
Sean Wang (1):
Bluetooth: btmtksdio: fix resume failure
Sean Young (1):
media: igorplugusb: receiver overflow should be reported
Sebastian Andrzej Siewior (1):
ext4: destroy ext4_fc_dentry_cachep kmemcache on module removal
Sebastian Gottschall (1):
ath10k: Fix tx hanging
Sergey Shtylyov (3):
mmc: meson-mx-sdhc: add IRQ check
mmc: meson-mx-sdio: add IRQ check
bcmgenet: add WOL IRQ check
Shaul Triebitz (1):
iwlwifi: mvm: avoid clearing a just saved session protection id
Shengjiu Wang (1):
ASoC: fsl_asrc: refine the check of available clock divider
Sicelo A. Mhlongo (1):
ARM: dts: omap3-n900: Fix lp5523 for multi color
Srinivas Kandagatla (2):
arm64: dts: qcom: c630: Fix soundcard setup
nvmem: core: set size for sysfs bin file
Sriram R (1):
ath11k: Avoid NULL ptr access during mgmt tx cleanup
Stafford Horne (1):
openrisc: Add clone3 ABI wrapper
Stanimir Varbanov (1):
media: venus: pm_helpers: Control core power domain manually
Stefan Riedmueller (1):
mtd: rawnand: gpmi: Remove explicit default gpmi clock setting for
i.MX6
Stephan Müller (1):
crypto: jitter - consider 32 LSB for APT
Stephen Boyd (2):
drm/bridge: ti-sn65dsi86: Set max register for regmap
clk: Emit a stern warning with writable debugfs enabled
Sudeep Holla (1):
ACPICA: Fix wrong interpretation of PCC address
Suravee Suthikulpanit (1):
iommu/amd: Remove iommu_init_ga()
Suresh Kumar (1):
net: bonding: debug: avoid printing debug logs when bond is not
notifying peers
Suresh Udipi (2):
media: rcar-csi2: Correct the selection of hsfreqrange
media: rcar-csi2: Optimize the selection PHTW register
Sven Eckelmann (1):
ath11k: Fix ETSI regd with weather radar overlap
Takashi Iwai (5):
ALSA: jack: Add missing rwsem around snd_ctl_remove() calls
ALSA: PCM: Add missing rwsem around snd_ctl_remove() calls
ALSA: hda: Add missing rwsem around snd_ctl_remove() calls
ALSA: usb-audio: Drop superfluous '0' in Presonus Studio 1810c's ID
ALSA: seq: Set upper limit of processed events
Tasos Sahanidis (1):
floppy: Fix hang in watchdog when disk is ejected
Thadeu Lima de Souza Cascardo (1):
selftests/powerpc/spectre_v2: Return skip code when miss_percent is
high
Theodore Ts'o (1):
ext4: don't use the orphan list when migrating an inode
Thierry Reding (1):
arm64: tegra: Adjust length of CCPLEX cluster MMIO region
Thomas Gleixner (1):
PCI/MSI: Fix pci_irq_vector()/pci_irq_get_affinity()
Thomas Hellström (1):
dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()
Thomas Weißschuh (1):
ACPI: battery: Add the ThinkPad "Not Charging" quirk
Tianjia Zhang (1):
MIPS: Octeon: Fix build errors using clang
Tobias Waldekranz (3):
powerpc/fsl/dts: Enable WA for erratum A-009885 on fman3l MDIO buses
net/fsl: xgmac_mdio: Add workaround for erratum A-009885
net/fsl: xgmac_mdio: Fix incorrect iounmap when removing module
Todd Kjos (1):
binder: fix handling of error during copy
Toke Høiland-Jørgensen (1):
xdp: check prog type before updating BPF link
Tom Rix (2):
net: ethernet: mtk_eth_soc: fix error checking in mtk_mac_config()
net: mscc: ocelot: fix using match before it is set
Tsuchiya Yuto (7):
media: atomisp: add missing media_device_cleanup() in
atomisp_unregister_entities()
media: atomisp: fix punit_ddr_dvfs_enable() argument for mrfld_power
up case
media: atomisp: fix inverted logic in buffers_needed()
media: atomisp: do not use err var when checking port validity for
ISP2400
media: atomisp: fix inverted error check for
ia_css_mipi_is_source_port_valid()
media: atomisp: fix ifdefs in sh_css.c
media: atomisp: add NULL check for asd obtained from
atomisp_video_pipe
Tudor Ambarus (8):
tty: serial: atmel: Check return code of dmaengine_submit()
tty: serial: atmel: Call dma_async_issue_pending()
dmaengine: at_xdmac: Don't start transactions at tx_submit level
dmaengine: at_xdmac: Start transfer for cyclic channels in
issue_pending
dmaengine: at_xdmac: Print debug message after realeasing the lock
dmaengine: at_xdmac: Fix concurrency over xfers_list
dmaengine: at_xdmac: Fix lld view setting
dmaengine: at_xdmac: Fix at_xdmac_lld struct definition
Tzung-Bi Shih (2):
ASoC: mediatek: mt8173: fix device_node leak
ASoC: mediatek: mt8183: fix device_node leak
Ulf Hansson (1):
mmc: core: Fixup storing of OCR for MMC_QUIRK_NONSTD_SDIO
Vincent Donnefort (2):
sched/fair: Fix detection of per-CPU kthreads waking a task
sched/fair: Fix per-CPU kthread and wakee stacking for asym CPU
capacity
Waiman Long (1):
clocksource: Avoid accidental unstable marking of clocksources
Wan Jiabing (1):
ARM: shmobile: rcar-gen2: Add missing of_node_put()
Wang Hai (4):
drm: fix null-ptr-deref in drm_dev_init_release()
Bluetooth: cmtp: fix possible panic when cmtp_init_sockets() fails
media: dmxdev: fix UAF when dvb_register_device() fails
media: msi001: fix possible null-ptr-deref in msi001_probe()
Wei Yongjun (3):
usb: ftdi-elan: fix memory leak on device disconnect
misc: lattice-ecp3-config: Fix task hung when firmware load failed
Bluetooth: Fix debugfs entry leak in hci_register_dev()
Wen Gong (1):
ath11k: avoid deadlock by change ieee80211_queue_work for
regd_update_work
Wen Gu (1):
net/smc: Fix hung_task when removing SMC-R devices
William Kucharski (1):
cgroup: Trace event cgroup id fields should be u64
Willy Tarreau (2):
tools/nolibc: i386: fix initial stack alignment
tools/nolibc: fix incorrect truncation of exit code
Xiangyang Zhang (1):
tracing/kprobes: 'nmissed' not showed correctly for kretprobe
Xie Yongji (1):
fuse: Pass correct lend value to filemap_write_and_wait_range()
Xin Xiong (1):
netfilter: ipt_CLUSTERIP: fix refcount leak in clusterip_tg_check()
Xin Yin (3):
ext4: fix fast commit may miss tracking range for FALLOC_FL_ZERO_RANGE
ext4: use ext4_ext_remove_space() for fast commit replay delete range
ext4: fast commit may miss tracking unwritten range during ftruncate
Xiongwei Song (1):
floppy: Add max size check for user space request
Yang Li (1):
drm/amd/display: check top_pipe_to_program pointer
Yang Yingliang (3):
media: si470x-i2c: fix possible memory leak in si470x_i2c_probe()
staging: rtl8192e: return error code from rtllib_softmac_init()
staging: rtl8192e: rtllib_module: fix error handle case in
alloc_rtllib()
Ye Guojin (1):
MIPS: OCTEON: add put_device() after of_find_device_by_node()
Yifeng Li (1):
PCI: Add function 1 DMA alias quirk for Marvell 88SE9125 SATA
controller
Yunfei Wang (1):
iommu/io-pgtable-arm-v7s: Add error handle for page table allocation
failure
Zechuan Chen (1):
perf probe: Fix ppc64 'perf probe add events failed' case
Zekun Shen (4):
ar5523: Fix null-ptr-deref with unexpected WDCMSG_TARGET_START reply
rsi: Fix use-after-free in rsi_rx_done_handler()
rsi: Fix out-of-bounds read in rsi_read_pkt()
ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream
Zhang Zixun (1):
x86/mce/inject: Avoid out-of-bounds write when setting flags
Zheng Zengkai (1):
Revert "sched/rt: Try to restart rt period timer when rt runtime
exceeded"
Zheyu Ma (1):
media: b2c2: Add missing check in flexcop_pci_isr:
Zhou Qingyang (9):
drm/amdgpu: Fix a NULL pointer dereference in
amdgpu_connector_lcd_native_mode()
drm/radeon/radeon_kms: Fix a NULL pointer dereference in
radeon_driver_open_kms()
media: dib8000: Fix a memleak in dib8000_init()
media: saa7146: mxb: Fix a NULL pointer dereference in mxb_attach()
ath11k: Fix a NULL pointer dereference in ath11k_mac_op_hw_scan()
pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in
__nonstatic_find_io_region()
pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in
nonstatic_find_mem_region()
media: saa7146: hexium_orion: Fix a NULL pointer dereference in
hexium_attach()
media: saa7146: hexium_gemini: Fix a NULL pointer dereference in
hexium_attach()
Zizhuang Deng (1):
lib/mpi: Add the return value check of kcalloc()
Zongmin Zhou (1):
drm/amdgpu: fixup bad vram size on gmc v8
xinhui pan (1):
drm/ttm: Put BO in its memory manager's lru list
.../ABI/testing/sysfs-bus-iio-lptimer-stm32 | 62 --
Documentation/admin-guide/hw-vuln/spectre.rst | 2 +-
.../display/amlogic,meson-dw-hdmi.yaml | 5 +
.../bindings/display/amlogic,meson-vpu.yaml | 6 +
.../bindings/thermal/thermal-zones.yaml | 9 +-
.../bindings/watchdog/samsung-wdt.yaml | 5 +-
.../driver-api/dmaengine/dmatest.rst | 7 +-
Documentation/driver-api/firewire.rst | 4 +-
.../acpi/dsd/data-node-references.rst | 10 +-
arch/arm/Kconfig.debug | 14 +-
arch/arm/boot/compressed/efi-header.S | 22 +-
arch/arm/boot/compressed/head.S | 3 +-
arch/arm/boot/dts/armada-38x.dtsi | 4 +-
arch/arm/boot/dts/gemini-nas4220b.dts | 2 +-
arch/arm/boot/dts/omap3-n900.dts | 50 +-
arch/arm/boot/dts/stm32f429-disco.dts | 2 +-
arch/arm/include/debug/imx-uart.h | 18 +-
.../mach-shmobile/regulator-quirk-rcar-gen2.c | 5 +-
.../boot/dts/amlogic/meson-g12-common.dtsi | 2 +-
.../dts/amlogic/meson-g12b-odroid-n2.dtsi | 2 +-
.../boot/dts/amlogic/meson-gxbb-wetek.dtsi | 3 +
.../boot/dts/freescale/fsl-ls1028a-qds.dts | 14 +-
arch/arm64/boot/dts/marvell/cn9130.dtsi | 15 +
arch/arm64/boot/dts/nvidia/tegra186.dtsi | 2 +-
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 9 +-
arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +-
arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 +-
arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 -
.../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 27 +
arch/arm64/boot/dts/renesas/cat875.dtsi | 1 +
arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 2 +-
arch/arm64/boot/dts/ti/k3-j7200.dtsi | 6 +-
arch/arm64/boot/dts/ti/k3-j721e.dtsi | 6 +-
arch/mips/Kconfig | 6 +-
arch/mips/bcm63xx/clk.c | 6 +
arch/mips/cavium-octeon/octeon-platform.c | 2 +
arch/mips/cavium-octeon/octeon-usb.c | 1 +
.../asm/mach-loongson64/kernel-entry-init.h | 4 +-
arch/mips/include/asm/octeon/cvmx-bootinfo.h | 4 +-
arch/mips/lantiq/clk.c | 6 +
arch/openrisc/include/asm/syscalls.h | 2 +
arch/openrisc/kernel/entry.S | 5 +
arch/parisc/include/asm/special_insns.h | 44 +-
arch/parisc/kernel/traps.c | 2 +-
arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi | 2 +
arch/powerpc/include/asm/cpu_setup_power.h | 12 +
arch/powerpc/include/asm/hw_irq.h | 51 +-
arch/powerpc/include/asm/reg.h | 1 +
arch/powerpc/kernel/btext.c | 4 +-
arch/powerpc/kernel/cpu_setup_power.S | 252 -----
arch/powerpc/kernel/cpu_setup_power.c | 272 +++++
arch/powerpc/kernel/cputable.c | 12 +-
arch/powerpc/kernel/dt_cpu_ftrs.c | 1 +
arch/powerpc/kernel/fadump.c | 8 +
arch/powerpc/kernel/head_40x.S | 9 +-
arch/powerpc/kernel/prom_init.c | 2 +-
arch/powerpc/kernel/smp.c | 42 +
arch/powerpc/kernel/traps.c | 31 +-
arch/powerpc/kernel/watchdog.c | 41 +-
arch/powerpc/kvm/book3s_hv.c | 8 +-
arch/powerpc/kvm/book3s_hv_nested.c | 2 +-
arch/powerpc/mm/book3s64/radix_pgtable.c | 4 +-
arch/powerpc/mm/kasan/book3s_32.c | 3 +-
arch/powerpc/mm/pgtable_64.c | 14 +-
arch/powerpc/perf/core-book3s.c | 97 +-
arch/powerpc/perf/core-fsl-emb.c | 25 -
arch/powerpc/perf/isa207-common.c | 8 +
arch/powerpc/platforms/cell/iommu.c | 1 +
arch/powerpc/platforms/cell/pervasive.c | 1 +
arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 1 +
arch/powerpc/platforms/powermac/low_i2c.c | 3 +
arch/powerpc/platforms/powernv/opal-lpc.c | 1 +
arch/powerpc/sysdev/xive/spapr.c | 3 +
arch/s390/mm/pgalloc.c | 4 +-
arch/um/drivers/virtio_uml.c | 4 +
arch/um/include/asm/delay.h | 4 +-
arch/um/include/shared/registers.h | 4 +-
arch/um/os-Linux/registers.c | 4 +-
arch/um/os-Linux/start_up.c | 2 +-
arch/x86/boot/compressed/Makefile | 7 +-
arch/x86/configs/i386_defconfig | 1 +
arch/x86/configs/x86_64_defconfig | 1 +
arch/x86/include/asm/realmode.h | 1 +
arch/x86/include/asm/uaccess.h | 5 +-
arch/x86/kernel/cpu/mce/core.c | 42 +-
arch/x86/kernel/cpu/mce/inject.c | 2 +-
arch/x86/kernel/early-quirks.c | 10 +-
arch/x86/kernel/reboot.c | 12 +-
arch/x86/kernel/tsc.c | 1 +
arch/x86/kvm/vmx/posted_intr.c | 16 +-
arch/x86/realmode/init.c | 26 +
arch/x86/um/syscalls_64.c | 3 +-
crypto/jitterentropy.c | 3 +-
drivers/acpi/acpica/exfield.c | 7 +-
drivers/acpi/acpica/exoparg1.c | 3 +-
drivers/acpi/acpica/hwesleep.c | 4 +-
drivers/acpi/acpica/hwsleep.c | 4 +-
drivers/acpi/acpica/hwxfsleep.c | 2 -
drivers/acpi/acpica/utdelete.c | 1 +
drivers/acpi/battery.c | 22 +
drivers/acpi/bus.c | 4 +-
drivers/acpi/ec.c | 57 +-
drivers/acpi/internal.h | 2 +
drivers/acpi/scan.c | 13 +-
drivers/acpi/x86/utils.c | 116 ++-
drivers/android/binder.c | 4 +-
drivers/base/core.c | 3 +-
drivers/base/power/runtime.c | 41 +-
drivers/base/property.c | 4 +-
drivers/base/regmap/regmap.c | 1 +
drivers/base/swnode.c | 2 +-
drivers/block/floppy.c | 6 +-
drivers/bluetooth/btmtksdio.c | 2 +
drivers/bluetooth/hci_bcm.c | 7 +-
drivers/bluetooth/hci_qca.c | 5 +-
drivers/bluetooth/hci_vhci.c | 2 +
drivers/char/mwave/3780i.h | 2 +-
drivers/char/random.c | 19 +-
drivers/char/tpm/tpm_tis_core.c | 14 +-
drivers/clk/bcm/clk-bcm2835.c | 13 +-
drivers/clk/clk-bm1880.c | 20 +-
drivers/clk/clk-si5341.c | 2 +-
drivers/clk/clk-stm32f4.c | 4 -
drivers/clk/clk.c | 18 +
drivers/clk/imx/clk-imx8mn.c | 6 +-
drivers/clk/meson/gxbb.c | 44 +-
drivers/counter/Kconfig | 2 +-
drivers/counter/stm32-lptimer-cnt.c | 297 +-----
drivers/cpufreq/cpufreq.c | 4 +-
drivers/crypto/caam/caamalg_qi2.c | 2 +-
drivers/crypto/omap-aes.c | 2 +-
drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 45 +-
drivers/crypto/qat/qat_common/adf_vf2pf_msg.c | 4 +-
drivers/crypto/qce/sha.c | 2 +-
drivers/crypto/qce/skcipher.c | 2 +-
drivers/crypto/stm32/stm32-crc32.c | 4 +-
drivers/crypto/stm32/stm32-cryp.c | 938 +++++++-----------
drivers/crypto/stm32/stm32-hash.c | 6 +-
drivers/dma-buf/dma-fence-array.c | 6 +-
drivers/dma/at_xdmac.c | 57 +-
drivers/dma/mmp_pdma.c | 6 -
drivers/dma/pxa_dma.c | 7 -
drivers/dma/stm32-mdma.c | 2 +-
drivers/dma/uniphier-xdmac.c | 5 +-
drivers/edac/synopsys_edac.c | 3 +-
drivers/firmware/google/Kconfig | 6 +-
drivers/gpio/gpio-aspeed.c | 52 +-
drivers/gpio/gpiolib-acpi.c | 15 +-
.../gpu/drm/amd/amdgpu/amdgpu_connectors.c | 6 +
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 1 -
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 13 +-
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +
drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +-
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 6 +
.../gpu/drm/bridge/analogix/analogix_dp_reg.c | 14 +-
drivers/gpu/drm/bridge/display-connector.c | 2 +-
.../bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 40 +-
.../drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 10 +-
.../gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 4 +-
.../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 9 +-
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 12 +-
drivers/gpu/drm/bridge/ti-sn65dsi86.c | 1 +
drivers/gpu/drm/drm_drv.c | 9 +-
.../gpu/drm/drm_panel_orientation_quirks.c | 6 +
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 6 +
drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 1 +
drivers/gpu/drm/etnaviv/etnaviv_sched.c | 4 +-
drivers/gpu/drm/lima/lima_device.c | 1 +
drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 2 +
drivers/gpu/drm/msm/Kconfig | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 +-
drivers/gpu/drm/nouveau/dispnv04/disp.c | 4 +-
.../gpu/drm/nouveau/nvkm/subdev/pmu/base.c | 37 +-
drivers/gpu/drm/panel/panel-innolux-p079zca.c | 10 +-
.../drm/panel/panel-kingdisplay-kd097d04.c | 8 +-
drivers/gpu/drm/radeon/radeon_kms.c | 42 +-
drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 20 +-
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 82 +-
drivers/gpu/drm/tegra/vic.c | 7 +-
drivers/gpu/drm/ttm/ttm_bo.c | 2 +
drivers/gpu/drm/vboxvideo/vbox_main.c | 4 +-
drivers/gpu/drm/vc4/vc4_hdmi.c | 24 +-
drivers/gpu/host1x/dev.c | 15 +
drivers/hid/hid-apple.c | 2 +-
drivers/hid/hid-input.c | 6 +
drivers/hid/hid-uclogic-params.c | 31 +-
drivers/hid/hid-vivaldi.c | 34 +-
drivers/hid/uhid.c | 29 +-
drivers/hid/wacom_wac.c | 39 +-
drivers/hsi/hsi_core.c | 1 +
drivers/hwmon/mr75203.c | 2 +-
drivers/i2c/busses/i2c-designware-pcidrv.c | 8 +-
drivers/i2c/busses/i2c-i801.c | 15 +-
drivers/i2c/busses/i2c-mpc.c | 23 +-
drivers/iio/adc/ti-adc081c.c | 22 +-
drivers/infiniband/core/cma.c | 12 +-
drivers/infiniband/core/device.c | 3 +-
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 6 +-
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 -
drivers/infiniband/hw/cxgb4/qp.c | 1 +
drivers/infiniband/hw/qedr/verbs.c | 2 +
drivers/infiniband/sw/rxe/rxe_opcode.c | 2 +-
drivers/iommu/amd/init.c | 48 +-
drivers/iommu/io-pgtable-arm-v7s.c | 6 +-
drivers/iommu/io-pgtable-arm.c | 11 +-
drivers/irqchip/irq-gic-v3.c | 16 +
drivers/md/dm.c | 4 +-
drivers/md/persistent-data/dm-btree.c | 8 +-
.../md/persistent-data/dm-space-map-common.c | 5 +
drivers/media/Kconfig | 8 +-
drivers/media/cec/core/cec-pin.c | 31 +-
drivers/media/common/saa7146/saa7146_fops.c | 2 +-
.../common/videobuf2/videobuf2-dma-contig.c | 8 +-
drivers/media/dvb-core/dmxdev.c | 18 +-
drivers/media/dvb-frontends/dib8000.c | 4 +-
drivers/media/pci/b2c2/flexcop-pci.c | 3 +
drivers/media/pci/saa7146/hexium_gemini.c | 7 +-
drivers/media/pci/saa7146/hexium_orion.c | 8 +-
drivers/media/pci/saa7146/mxb.c | 8 +-
drivers/media/platform/aspeed-video.c | 14 +-
drivers/media/platform/coda/coda-common.c | 8 +-
drivers/media/platform/coda/coda-jpeg.c | 21 +-
drivers/media/platform/coda/imx-vdoa.c | 6 +-
drivers/media/platform/imx-pxp.c | 4 +-
.../platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 2 +-
drivers/media/platform/qcom/venus/core.c | 39 +-
drivers/media/platform/qcom/venus/core.h | 2 -
.../media/platform/qcom/venus/pm_helpers.c | 94 +-
.../media/platform/qcom/venus/pm_helpers.h | 7 +-
drivers/media/platform/rcar-vin/rcar-csi2.c | 18 +-
drivers/media/platform/rcar-vin/rcar-v4l2.c | 15 +-
drivers/media/radio/si470x/radio-si470x-i2c.c | 3 +-
drivers/media/rc/igorplugusb.c | 4 +-
drivers/media/rc/mceusb.c | 8 +-
drivers/media/rc/redrat3.c | 22 +-
drivers/media/tuners/msi001.c | 7 +
drivers/media/tuners/si2157.c | 2 +-
drivers/media/usb/b2c2/flexcop-usb.c | 10 +-
drivers/media/usb/b2c2/flexcop-usb.h | 12 +-
drivers/media/usb/cpia2/cpia2_usb.c | 4 +-
drivers/media/usb/dvb-usb/dib0700_core.c | 2 -
drivers/media/usb/dvb-usb/dw2102.c | 338 ++++---
drivers/media/usb/dvb-usb/m920x.c | 12 +-
drivers/media/usb/em28xx/em28xx-cards.c | 18 +-
drivers/media/usb/em28xx/em28xx-core.c | 4 +-
drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 8 +-
drivers/media/usb/s2255/s2255drv.c | 4 +-
drivers/media/usb/stk1160/stk1160-core.c | 4 +-
drivers/media/usb/uvc/uvcvideo.h | 2 +-
drivers/media/v4l2-core/v4l2-ioctl.c | 4 +-
drivers/memory/renesas-rpc-if.c | 2 +-
drivers/mfd/atmel-flexcom.c | 11 +-
drivers/misc/lattice-ecp3-config.c | 12 +-
drivers/misc/lkdtm/Makefile | 2 +-
drivers/mmc/core/sdio.c | 4 +-
drivers/mmc/host/meson-mx-sdhc-mmc.c | 5 +
drivers/mmc/host/meson-mx-sdio.c | 5 +
drivers/mtd/hyperbus/rpc-if.c | 8 +-
drivers/mtd/mtdpart.c | 2 +-
drivers/mtd/nand/bbt.c | 2 +-
drivers/mtd/nand/raw/davinci_nand.c | 16 +-
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 37 +-
drivers/net/bonding/bond_main.c | 36 +-
drivers/net/can/softing/softing_cs.c | 2 +-
drivers/net/can/softing/softing_fw.c | 11 +-
.../net/can/spi/mcp251xfd/mcp251xfd-core.c | 6 +-
drivers/net/can/xilinx_can.c | 7 +-
.../net/ethernet/broadcom/genet/bcmgenet.c | 10 +-
.../net/ethernet/chelsio/libcxgb/libcxgb_cm.c | 3 +-
drivers/net/ethernet/cortina/gemini.c | 9 +-
drivers/net/ethernet/freescale/fman/mac.c | 21 +-
drivers/net/ethernet/freescale/xgmac_mdio.c | 28 +-
drivers/net/ethernet/i825xx/sni_82596.c | 3 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 36 +-
.../ethernet/mellanox/mlx5/core/en/xsk/pool.c | 4 +-
.../net/ethernet/mellanox/mlx5/core/en_main.c | 10 +-
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 7 +-
.../net/ethernet/mellanox/mlx5/core/lag_mp.c | 6 +-
drivers/net/ethernet/mellanox/mlxsw/cmd.h | 12 +
drivers/net/ethernet/mellanox/mlxsw/pci.c | 7 +-
drivers/net/ethernet/mscc/ocelot_flower.c | 15 +-
drivers/net/ethernet/rocker/rocker_ofdpa.c | 3 +-
.../net/ethernet/xilinx/xilinx_axienet_main.c | 135 ++-
drivers/net/phy/marvell.c | 6 +
drivers/net/phy/mdio_bus.c | 2 +-
drivers/net/phy/phy-core.c | 2 +-
drivers/net/phy/sfp.c | 25 +-
drivers/net/ppp/ppp_generic.c | 7 +-
drivers/net/usb/mcs7830.c | 12 +-
drivers/net/wireless/ath/ar5523/ar5523.c | 4 +
drivers/net/wireless/ath/ath10k/core.c | 19 +-
drivers/net/wireless/ath/ath10k/htt_tx.c | 3 +
drivers/net/wireless/ath/ath10k/hw.h | 3 +
drivers/net/wireless/ath/ath10k/txrx.c | 2 -
drivers/net/wireless/ath/ath11k/ahb.c | 28 +-
drivers/net/wireless/ath/ath11k/core.h | 2 +-
drivers/net/wireless/ath/ath11k/dp.h | 3 +-
drivers/net/wireless/ath/ath11k/dp_tx.c | 2 +-
drivers/net/wireless/ath/ath11k/hal.c | 22 +
drivers/net/wireless/ath/ath11k/hal.h | 2 +
drivers/net/wireless/ath/ath11k/hw.c | 2 -
drivers/net/wireless/ath/ath11k/mac.c | 52 +-
drivers/net/wireless/ath/ath11k/pci.c | 12 +-
drivers/net/wireless/ath/ath11k/reg.c | 103 +-
drivers/net/wireless/ath/ath11k/wmi.c | 5 +-
drivers/net/wireless/ath/ath9k/hif_usb.c | 7 +
drivers/net/wireless/ath/wcn36xx/dxe.c | 49 +-
drivers/net/wireless/ath/wcn36xx/main.c | 34 +-
drivers/net/wireless/ath/wcn36xx/smd.c | 8 +-
drivers/net/wireless/ath/wcn36xx/txrx.c | 41 +-
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 17 +-
.../intel/iwlwifi/mvm/ftm-initiator.c | 2 +-
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 17 +
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 27 +
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +-
.../wireless/intel/iwlwifi/mvm/time-event.c | 27 +-
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 7 +-
drivers/net/wireless/intel/iwlwifi/queue/tx.c | 1 +
.../net/wireless/marvell/mwifiex/sta_event.c | 8 +-
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8821c.h | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 +-
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 +-
drivers/net/wireless/rsi/rsi_91x_main.c | 4 +
drivers/net/wireless/rsi/rsi_91x_usb.c | 9 +-
drivers/net/wireless/rsi/rsi_usb.h | 2 +
drivers/nvmem/core.c | 2 +
drivers/of/base.c | 11 +-
drivers/of/unittest.c | 21 +-
drivers/parisc/pdc_stable.c | 4 +-
drivers/pci/controller/pci-aardvark.c | 4 +-
drivers/pci/controller/pci-mvebu.c | 8 +
drivers/pci/controller/pci-xgene.c | 2 +-
drivers/pci/hotplug/pciehp.h | 3 +
drivers/pci/hotplug/pciehp_core.c | 2 +-
drivers/pci/hotplug/pciehp_hpc.c | 21 +-
drivers/pci/msi.c | 26 +-
drivers/pci/pci-bridge-emul.c | 70 +-
drivers/pci/quirks.c | 3 +
drivers/pcmcia/cs.c | 8 +-
drivers/pcmcia/rsrc_nonstatic.c | 6 +
drivers/phy/socionext/phy-uniphier-usb3ss.c | 10 +-
drivers/power/reset/mt6323-poweroff.c | 3 +
drivers/regulator/qcom_smd-regulator.c | 100 +-
drivers/rpmsg/rpmsg_core.c | 20 +-
drivers/rtc/rtc-cmos.c | 3 +
drivers/rtc/rtc-pxa.c | 4 +
drivers/scsi/lpfc/lpfc.h | 2 +-
drivers/scsi/lpfc/lpfc_attr.c | 62 +-
drivers/scsi/lpfc/lpfc_hbadisc.c | 8 +-
drivers/scsi/lpfc/lpfc_sli.c | 6 -
drivers/scsi/pm8001/pm8001_hwi.c | 4 +-
drivers/scsi/scsi_debugfs.c | 1 +
drivers/scsi/sr.c | 2 +-
drivers/scsi/sr_vendor.c | 4 +-
drivers/scsi/ufs/tc-dwc-g210-pci.c | 1 -
drivers/scsi/ufs/ufshcd-pci.c | 2 -
drivers/scsi/ufs/ufshcd-pltfrm.c | 2 -
drivers/scsi/ufs/ufshcd.c | 7 +
drivers/soc/mediatek/mtk-scpsys.c | 15 +-
drivers/soc/qcom/cpr.c | 2 +-
drivers/soc/ti/pruss.c | 2 +-
drivers/spi/spi-meson-spifc.c | 1 +
drivers/spi/spi-uniphier.c | 11 +-
drivers/staging/greybus/audio_topology.c | 15 +
drivers/staging/media/atomisp/i2c/ov2680.h | 24 -
.../staging/media/atomisp/pci/atomisp_cmd.c | 92 +-
.../staging/media/atomisp/pci/atomisp_fops.c | 11 +
.../media/atomisp/pci/atomisp_gmin_platform.c | 2 +-
.../staging/media/atomisp/pci/atomisp_ioctl.c | 185 +++-
.../media/atomisp/pci/atomisp_subdev.c | 15 +-
.../media/atomisp/pci/atomisp_subdev.h | 3 +
.../staging/media/atomisp/pci/atomisp_v4l2.c | 13 +-
.../staging/media/atomisp/pci/atomisp_v4l2.h | 3 +-
drivers/staging/media/atomisp/pci/sh_css.c | 27 +-
.../staging/media/atomisp/pci/sh_css_mipi.c | 41 +-
.../staging/media/atomisp/pci/sh_css_params.c | 8 +-
drivers/staging/media/hantro/hantro_drv.c | 3 +-
drivers/staging/rtl8192e/rtllib.h | 2 +-
drivers/staging/rtl8192e/rtllib_module.c | 16 +-
drivers/staging/rtl8192e/rtllib_softmac.c | 6 +-
drivers/tee/tee_core.c | 4 +-
drivers/thermal/imx8mm_thermal.c | 3 +
drivers/thermal/imx_thermal.c | 145 ++-
drivers/thunderbolt/acpi.c | 13 +
drivers/tty/serial/amba-pl010.c | 3 -
drivers/tty/serial/amba-pl011.c | 27 +-
drivers/tty/serial/atmel_serial.c | 14 +
drivers/tty/serial/imx.c | 7 +-
drivers/tty/serial/serial_core.c | 7 +-
drivers/tty/serial/uartlite.c | 2 +-
drivers/usb/core/hub.c | 5 +-
drivers/usb/dwc3/dwc3-qcom.c | 7 +-
drivers/usb/gadget/function/f_fs.c | 4 +-
drivers/usb/host/uhci-platform.c | 3 +-
drivers/usb/misc/ftdi-elan.c | 1 +
drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 -
drivers/video/backlight/qcom-wled.c | 122 ++-
drivers/virtio/virtio_ring.c | 4 +-
drivers/w1/slaves/w1_ds28e04.c | 26 +-
drivers/xen/gntdev.c | 6 +-
fs/btrfs/backref.c | 21 +-
fs/btrfs/ctree.c | 19 +-
fs/btrfs/inode.c | 11 +
fs/btrfs/qgroup.c | 19 +
fs/debugfs/file.c | 2 +-
fs/dlm/lock.c | 9 +
fs/dlm/lowcomms.c | 45 +-
fs/ext4/ext4.h | 1 +
fs/ext4/extents.c | 2 -
fs/ext4/fast_commit.c | 18 +-
fs/ext4/inode.c | 14 +-
fs/ext4/ioctl.c | 2 -
fs/ext4/mballoc.c | 48 +-
fs/ext4/migrate.c | 23 +-
fs/ext4/super.c | 25 +-
fs/f2fs/compress.c | 50 +-
fs/f2fs/f2fs.h | 11 +
fs/f2fs/segment.h | 3 +-
fs/f2fs/super.c | 44 +
fs/f2fs/sysfs.c | 4 +-
fs/fuse/file.c | 2 +-
fs/ubifs/super.c | 1 -
fs/udf/ialloc.c | 2 +
include/acpi/acpi_bus.h | 5 +-
include/acpi/actypes.h | 10 +-
include/linux/bpf_verifier.h | 7 +
include/linux/clocksource.h | 3 +
include/linux/hid.h | 2 +
include/linux/mmzone.h | 9 +
include/linux/pm_runtime.h | 3 +
include/net/inet_frag.h | 11 +-
include/net/ipv6_frag.h | 3 +-
include/net/sch_generic.h | 5 +
include/net/xfrm.h | 5 +
include/trace/events/cgroup.h | 12 +-
include/uapi/linux/xfrm.h | 1 +
kernel/bpf/btf.c | 3 +-
kernel/bpf/verifier.c | 18 +-
kernel/dma/pool.c | 4 +-
kernel/rcu/tree_exp.h | 1 +
kernel/sched/cputime.c | 4 +-
kernel/sched/fair.c | 4 +-
kernel/sched/rt.c | 33 +-
kernel/time/clocksource.c | 96 +-
kernel/time/jiffies.c | 15 +-
kernel/trace/bpf_trace.c | 6 +-
kernel/trace/trace_kprobe.c | 5 +-
kernel/tsacct.c | 7 +-
lib/mpi/mpi-mod.c | 2 +
lib/test_hmm.c | 24 +
lib/test_meminit.c | 1 +
mm/hmm.c | 5 +-
mm/page_alloc.c | 19 +-
mm/shmem.c | 37 +-
net/ax25/af_ax25.c | 10 +-
net/batman-adv/netlink.c | 30 +-
net/bluetooth/cmtp/core.c | 4 +-
net/bluetooth/hci_core.c | 1 +
net/bluetooth/hci_event.c | 8 +-
net/bluetooth/hci_request.c | 2 +-
net/bluetooth/l2cap_sock.c | 45 +-
net/bridge/br_netfilter_hooks.c | 7 +-
net/core/dev.c | 6 +
net/core/devlink.c | 2 -
net/core/filter.c | 8 +-
net/core/net-sysfs.c | 3 +
net/core/net_namespace.c | 4 +-
net/ipv4/fib_semantics.c | 47 +-
net/ipv4/inet_fragment.c | 8 +-
net/ipv4/ip_fragment.c | 3 +-
net/ipv4/ip_gre.c | 5 +-
net/ipv4/netfilter/ipt_CLUSTERIP.c | 5 +-
net/ipv6/ip6_gre.c | 5 +-
net/mac80211/rx.c | 2 +-
net/netfilter/nft_set_pipapo.c | 8 +
net/netrom/af_netrom.c | 12 +-
net/nfc/llcp_sock.c | 5 +
net/sched/sch_generic.c | 1 +
net/smc/smc_core.c | 17 +-
net/unix/garbage.c | 14 +-
net/unix/scm.c | 6 +-
net/xfrm/xfrm_compat.c | 6 +-
net/xfrm/xfrm_interface.c | 14 +-
net/xfrm/xfrm_policy.c | 24 +-
net/xfrm/xfrm_state.c | 23 +-
net/xfrm/xfrm_user.c | 41 +-
scripts/dtc/dtx_diff | 8 +-
scripts/sphinx-pre-install | 4 +
security/selinux/hooks.c | 12 +-
sound/core/jack.c | 3 +
sound/core/oss/pcm_oss.c | 2 +-
sound/core/pcm.c | 6 +-
sound/core/seq/seq_queue.c | 14 +-
sound/pci/hda/hda_codec.c | 3 +
sound/soc/codecs/rt5663.c | 12 +-
sound/soc/fsl/fsl_asrc.c | 69 +-
sound/soc/fsl/fsl_mqs.c | 2 +-
sound/soc/intel/catpt/dsp.c | 14 +-
sound/soc/mediatek/mt8173/mt8173-max98090.c | 3 +
.../mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 +
.../mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 +
sound/soc/mediatek/mt8173/mt8173-rt5650.c | 2 +
.../mediatek/mt8183/mt8183-da7219-max98357.c | 6 +-
.../mt8183/mt8183-mt6358-ts3a227-max98357.c | 7 +-
sound/soc/samsung/idma.c | 2 +
sound/soc/uniphier/Kconfig | 2 -
sound/usb/format.c | 2 +-
sound/usb/mixer_quirks.c | 2 +-
sound/usb/quirks.c | 2 +-
tools/bpf/bpftool/Documentation/Makefile | 1 -
tools/bpf/bpftool/Makefile | 1 -
tools/bpf/bpftool/main.c | 2 +
tools/include/nolibc/nolibc.h | 33 +-
tools/perf/util/debug.c | 2 +-
tools/perf/util/evsel.c | 25 +-
tools/perf/util/probe-event.c | 3 +
.../selftests/bpf/prog_tests/skb_ctx.c | 2 +
tools/testing/selftests/clone3/clone3.c | 6 +
.../selftests/ftrace/test.d/kprobe/profile.tc | 2 +-
tools/testing/selftests/kselftest_harness.h | 2 +-
.../selftests/powerpc/security/spectre_v2.c | 2 +-
tools/testing/selftests/vm/hmm-tests.c | 42 +
525 files changed, 5467 insertions(+), 3290 deletions(-)
delete mode 100644 Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32
create mode 100644 arch/powerpc/include/asm/cpu_setup_power.h
delete mode 100644 arch/powerpc/kernel/cpu_setup_power.S
create mode 100644 arch/powerpc/kernel/cpu_setup_power.c
--
2.20.1
1
547
Hello every one
The release team is collecting requirements for openEuler 22.09 version.
Please submit intel arch feature add into release-plan.md,the url address is below
https://gitee.com/openeuler/release-management/blob/master/openEuler-22.09/…
We are looking forward to features of intel can merge into openEuler 22.09.
1
0

[PATCH openEuler-1.0-LTS] x86/tsc: Make cur->adjusted values in package#1 to be the same
by LeoLiuoc 26 Apr '22
by LeoLiuoc 26 Apr '22
26 Apr '22
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I54V2W
CVE: NA
----------------------------------------------------------------
When resume from S4 on Zhaoxin 2 packages platform that support
X86_FEATURE_TSC_ADJUST,
the following warning messages appear:
[ 327.445302] [Firmware Bug]: TSC ADJUST differs: CPU15 45960750 -->
78394770. Restoring
[ 329.209120] [Firmware Bug]: TSC ADJUST differs: CPU14 45960750 -->
78394770. Restoring
[ 329.209128] [Firmware Bug]: TSC ADJUST differs: CPU13 45960750 -->
78394770. Restoring
[ 329.209138] [Firmware Bug]: TSC ADJUST differs: CPU12 45960750 -->
78394770. Restoring
[ 329.209151] [Firmware Bug]: TSC ADJUST differs: CPU11 45960750 -->
78394770. Restoring
[ 329.209160] [Firmware Bug]: TSC ADJUST differs: CPU10 45960750 -->
78394770. Restoring
[ 329.209169] [Firmware Bug]: TSC ADJUST differs: CPU9 45960750 -->
78394770. Restoring
The reason is:
Step 1: Bring up.
TSC is sync after bring up with following settings:
MSR 0x3b cur->adjusted
Package#0 CPU 0-7 0 0
Package#1 first CPU value1 value1
Package#1 non-first CPU value1 value1
Step 2: Suspend to S4.
Settings in Step 1 are not changed in this Step.
Step 3: Bring up caused by S4 wake up event.
TSC is sync when bring up with following settings:
MSR 0x3b cur->adjusted
Package#0 CPU 0-7 0 0
Package#1 first CPU value2 value2
Package#1 non-first CPU value2 value2
Step 4: Resume from S4.
When resuming from S4, Current TSC synchronous mechanism
cause following settings:
MSR 0x3b cur->adjusted
Package#0 CPU 0-7 0 0
Package#1 first CPU value2 value2
Package#1 non-first CPU value2 value1
In these Steps, value1 != 0 and value2 != value1.
In Step4, as function tsc_store_and_check_tsc_adjust() do, when the value
of MSR 0x3b on the non-first online CPU in package#1 is equal to the value
of cur->adjusted on the first online CPU in the same package,
the cur->adjusted value on this non-first online CPU will hold the old
value1.
This cause function tsc_verify_tsc_adjust() set the value of MSR 0x3b on the
non-first online CPUs in the package#1 to the old value1 and print the
beginning warning messages.
Fix it by setting cur->adjusted value on the non-first online CPU in a
package
to the value of MSR 0x3b on the same CPU when they are not equal.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
arch/x86/kernel/tsc_sync.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index ec534f978867..e0cc4170325c 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -190,6 +190,11 @@ bool tsc_store_and_check_tsc_adjust(bool bootcpu)
if (bootval != ref->adjusted) {
cur->adjusted = ref->adjusted;
wrmsrl(MSR_IA32_TSC_ADJUST, ref->adjusted);
+ } else if (cur->adjusted != bootval) {
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN) {
+ cur->adjusted = bootval;
+ }
}
/*
* We have the TSCs forced to be in sync on this package. Skip sync
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS] Add support for PxSCT.LPM set based on actual LPM circumstances
by LeoLiuoc 26 Apr '22
by LeoLiuoc 26 Apr '22
26 Apr '22
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I54V2K
CVE: NA
----------------------------------------------------------------
AHCI Spec shows that the PxSCTL.IPM field in each port must be programmed
to disallow device initiated LPM requests when HBA can not support
transitions to the LPM state. The current LPM driver has no restrictions
on LPM transitions when enabling device initiated LPM.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/ata/libata-core.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 290ff99bf1d8..c21a079f6d34 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3975,6 +3975,9 @@ int sata_link_scr_lpm(struct ata_link *link, enum
ata_lpm_policy policy,
bool spm_wakeup)
{
struct ata_eh_context *ehc = &link->eh_context;
+ struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
+ struct device *dev = ap ? ap->host->dev : NULL;
+ struct pci_dev *pdev = (!dev || !dev_is_pci(dev)) ? NULL :
to_pci_dev(dev);
bool woken_up = false;
u32 scontrol;
int rc;
@@ -4001,10 +4004,20 @@ int sata_link_scr_lpm(struct ata_link *link,
enum ata_lpm_policy policy,
case ATA_LPM_MED_POWER_WITH_DIPM:
case ATA_LPM_MIN_POWER_WITH_PARTIAL:
case ATA_LPM_MIN_POWER:
- if (ata_link_nr_enabled(link) > 0)
+ if (ata_link_nr_enabled(link) > 0) {
/* no restrictions on LPM transitions */
scontrol &= ~(0x7 << 8);
- else {
+ /*
+ * If Host does not support partial, then disallows it,
+ * the same for slumber.
+ */
+ if (pdev && pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) {
+ if (!(link->ap->host->flags & ATA_HOST_PART))
+ scontrol |= (0x1 << 8);
+ if (!(link->ap->host->flags & ATA_HOST_SSC))
+ scontrol |= (0x2 << 8);
+ }
+ } else {
/* empty port, power off */
scontrol &= ~0xf;
scontrol |= (0x1 << 2);
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS] Adding support for PxSCT.LPM setting based on actual LPM circumstances
by LeoLiuoc 26 Apr '22
by LeoLiuoc 26 Apr '22
26 Apr '22
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I54V27
CVE: NA
----------------------------------------------------------------
In AHCI spec, PhyRdy Change Interrupt cannot coexist with
Link Power Management (LPM). While LPM driver would disable
PhyRdy Change interrupt without checking whether HBA supports
LPM or not before enabling it. Therefore, if enabling LPM from
LPM driver by default, we can not disable it from BIOS without
influence Hotplug out capability.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/ata/ahci.c | 11 +++++++++++
drivers/ata/libata-eh.c | 7 +++++++
include/linux/libata.h | 3 +++
3 files changed, 21 insertions(+)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ebb2bfd4ab0a..8ed2f42b85fd 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1855,6 +1855,17 @@ static int ahci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
else
dev_info(&pdev->dev, "SSS flag set, parallel bus scan
disabled\n");
+ if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) {
+ if (hpriv->cap & HOST_CAP_PART)
+ host->flags |= ATA_HOST_PART;
+
+ if (hpriv->cap & HOST_CAP_SSC)
+ host->flags |= ATA_HOST_SSC;
+
+ if (hpriv->cap2 & HOST_CAP2_SDS)
+ host->flags |= ATA_HOST_DEVSLP;
+ }
+
if (pi.flags & ATA_FLAG_EM)
ahci_reset_em(host);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index ccc80ff57eb2..e4e0e6d94741 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -3448,6 +3448,8 @@ static int ata_eh_set_lpm(struct ata_link *link,
enum ata_lpm_policy policy,
struct ata_device **r_failed_dev)
{
struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
+ struct device *device = ap->host->dev;
+ struct pci_dev *pdev = (!device || !dev_is_pci(device)) ? NULL :
to_pci_dev(device);
struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
enum ata_lpm_policy old_policy = link->lpm_policy;
@@ -3456,6 +3458,11 @@ static int ata_eh_set_lpm(struct ata_link *link,
enum ata_lpm_policy policy,
unsigned int err_mask;
int rc;
+ /* if controller does not support lpm, then sets no LPM flags */
+ if ((pdev && pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) &&
+ !(ap->host->flags & (ATA_HOST_PART | ATA_HOST_SSC |
ATA_HOST_DEVSLP)))
+ link->flags |= ATA_LFLAG_NO_LPM;
+
/* if the link or host doesn't do LPM, noop */
if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm))
return 0;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index dc164b7ebbb0..1cec68e5b104 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -276,6 +276,9 @@ enum {
ATA_HOST_STARTED = (1 << 1), /* Host started */
ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can
be scanned in parallel */
ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on
this host. */
+ ATA_HOST_PART = (1 << 4), /* Host support partial. */
+ ATA_HOST_SSC = (1 << 5), /* Host support slumber. */
+ ATA_HOST_DEVSLP = (1 << 6), /* Host support devslp. */
/* bits 24:31 of host->flags are reserved for LLD specific flags */
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS] XHCI:Fix some device identify fail when enable xHCI runtime suspend
by LeoLiuoc 26 Apr '22
by LeoLiuoc 26 Apr '22
26 Apr '22
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I54V16
CVE: NA
----------------------------------------------------------------
If plug out device form xhci with runtime suspend enabled.
On the one hand, driver will disconnect this device and send disabled
slot command to xhci.
On the other hand, without no device connect to xhci, PM core will
call xhci suspend function to let xhci go to D3 to save power.
However there is a temporal competition to get xhci lock between
disable slot command interrupt and xhci suspend.
If xhci suspend function get xhci lock first, then this function will
clear xhci command ring. It will get error command trb when driver to
handle disable slot command interrupt. This is a serious error for
driver and driver will cleanup xhci. So,any device connect to this
xhci port again will not be recognized.
In order to fix this issues, we let disable slot command interrupt ISR
to get xhci lock first. So, add a delay in xhci suspend function before
to get xhci lock.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/usb/host/xhci-pci.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 238a32cc311c..4c2376a4c1d6 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -223,6 +223,9 @@ static void xhci_pci_quirks(struct device *dev,
struct xhci_hcd *xhci)
xhci->quirks |= XHCI_ZHAOXIN_HOST;
}
+ if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN)
+ xhci->quirks |= XHCI_SUSPEND_DELAY;
+
/* See https://bugzilla.kernel.org/show_bug.cgi?id=79511 */
if (pdev->vendor == PCI_VENDOR_ID_VIA &&
pdev->device == 0x3432)
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS] EHCI: Clear wakeup signal locked in S0, state when device plug in
by LeoLiuoc 26 Apr '22
by LeoLiuoc 26 Apr '22
26 Apr '22
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I54V1P
CVE: NA
----------------------------------------------------------------
If we plug in a LS/FS device on USB2 port of EHCI, it will latch a wakeup
signal in EHCI internal. This is a bug of EHCI for Some project of
ZhaoXin. If enable EHCI runtime suspend and no device attach.
PM core will let EHCI go to D3 to save power. However, once EHCI go to D3,
it will release wakeup signal that latched on device connect to port
during S0. Which will generate a SCI interrupt and bring EHCI to D0.
But without device connect, EHCI will go to D3 again.
So, there is suspend-resume loop and generate SCI interrupt Continuously.
In order to fix this issues, we need to clear the wakeup signal latched
in EHCI when EHCI suspend function is called.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/pci/pci-driver.c | 6 +++++-
drivers/usb/host/ehci-hcd.c | 21 +++++++++++++++++++++
drivers/usb/host/ehci-pci.c | 4 ++++
drivers/usb/host/ehci.h | 1 +
4 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 45c3a78d6004..9329f4881d42 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -513,7 +513,11 @@ static int pci_restore_standard_config(struct
pci_dev *pci_dev)
}
pci_restore_state(pci_dev);
- pci_pme_restore(pci_dev);
+ if (!(pci_dev->vendor == PCI_VENDOR_ID_ZHAOXIN &&
+ pci_dev->device == 0x3104 &&
+ (pci_dev->revision & 0xf0) == 0x90 &&
+ pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI))
+ pci_pme_restore(pci_dev);
return 0;
}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 8608ac513fb7..0daa6d98f9b9 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1110,6 +1110,27 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
return -EBUSY;
}
+ /* Clear wakeup signal locked in S0 state when device plug in */
+ if (ehci->zx_wakeup_clear == 1) {
+ u32 __iomem *reg = &ehci->regs->port_status[4];
+ u32 t1 = ehci_readl(ehci, reg);
+
+ t1 &= (u32)~0xf0000;
+ t1 |= PORT_TEST_FORCE;
+ ehci_writel(ehci, t1, reg);
+ t1 = ehci_readl(ehci, reg);
+ usleep_range(1000, 2000);
+ t1 &= (u32)~0xf0000;
+ ehci_writel(ehci, t1, reg);
+ usleep_range(1000, 2000);
+ t1 = ehci_readl(ehci, reg);
+ ehci_writel(ehci, t1 | PORT_CSC, reg);
+ udelay(500);
+ t1 = ehci_readl(ehci, &ehci->regs->status);
+ ehci_writel(ehci, t1 & STS_PCD, &ehci->regs->status);
+ ehci_readl(ehci, &ehci->regs->status);
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(ehci_suspend);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index baae879dbddd..357dc140e914 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -216,6 +216,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
ehci_info(ehci, "applying MosChip frame-index workaround\n");
ehci->frame_index_bug = 1;
break;
+ case PCI_VENDOR_ID_ZHAOXIN:
+ if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90)
+ ehci->zx_wakeup_clear = 1;
+ break;
}
/* optional debug port, normally in the first BAR */
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index c8e9a48e1d51..9625b6030757 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -218,6 +218,7 @@ struct ehci_hcd { /* one per controller */
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
unsigned need_oc_pp_cycle:1; /* MPC834X port power */
unsigned imx28_write_fix:1; /* For Freescale i.MX28 */
+ unsigned zx_wakeup_clear:1;
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS] rtc: Fix set RTC time delay 500ms on some Zhaoxin SOCs
by LeoLiuoc 26 Apr '22
by LeoLiuoc 26 Apr '22
26 Apr '22
zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I54V04
CVE: NA
----------------------------------------------------------------
When the RTC divider is changed from reset to an operating time base,
the first update cycle should be 500ms later. But on some Zhaoxin SOCs,
this first update cycle is one second later.
So set RTC time on these Zhaoxin SOCs will causing 500ms delay.
Skip setup RTC divider on these SOCs in mc146818_set_time to fix it.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/rtc/rtc-mc146818-lib.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c
index 2f1772a358ca..1a866ebbbe62 100644
--- a/drivers/rtc/rtc-mc146818-lib.c
+++ b/drivers/rtc/rtc-mc146818-lib.c
@@ -7,6 +7,23 @@
#include <linux/acpi.h>
#endif
+#ifdef CONFIG_X86
+static inline bool follow_mc146818_divider_reset(void)
+{
+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN) &&
+ (boot_cpu_data.x86 <= 7 && boot_cpu_data.x86_model <= 59)) {
+ return false;
+ }
+ return true;
+}
+#else
+static inline bool follow_mc146818_divider_reset(void)
+{
+ return true;
+}
+#endif
+
/*
* Returns true if a clock update is in progress
*/
@@ -170,8 +187,10 @@ int mc146818_set_time(struct rtc_time *time)
save_control = CMOS_READ(RTC_CONTROL);
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
- save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
- CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+ if (follow_mc146818_divider_reset()) {
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
+ CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+ }
#ifdef CONFIG_MACH_DECSTATION
CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
@@ -189,7 +208,8 @@ int mc146818_set_time(struct rtc_time *time)
#endif
CMOS_WRITE(save_control, RTC_CONTROL);
- CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ if (follow_mc146818_divider_reset())
+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
spin_unlock_irqrestore(&rtc_lock, flags);
--
2.20.1
1
0

[PATCH openEuler-5.10 01/10] mtd: phram: Fix error return code in phram_setup()
by Zheng Zengkai 24 Apr '22
by Zheng Zengkai 24 Apr '22
24 Apr '22
From: Yu Kuai <yukuai3(a)huawei.com>
mainline inclusion
from mainline-v5.14-rc1
commit da1e6fe563e62801fa033255f68c0bb9bf8c2c69
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I53BBP
backport: openEuler-22.03-LTS
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Return a negative error code from the error handling case instead
of 0, as done elsewhere in this function.
Reported-by: Hulk Robot <hulkci(a)huawei.com>
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Signed-off-by: Miquel Raynal <miquel.raynal(a)bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210408133812.1209798-1-yukuai3@huawei.c…
Signed-off-by: Yi Yang <yiyang13(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/mtd/devices/phram.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index aa88558c7edb..d7d17a4b61f5 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -270,6 +270,7 @@ static int phram_setup(const char *val)
if (len == 0 || erasesize == 0 || erasesize > len
|| erasesize > UINT_MAX || rem) {
parse_err("illegal erasesize or len\n");
+ ret = -EINVAL;
goto error;
}
--
2.20.1
1
9

[PATCH openEuler-5.10 01/28] af_key: add __GFP_ZERO flag for compose_sadb_supported in function pfkey_register
by Zheng Zengkai 21 Apr '22
by Zheng Zengkai 21 Apr '22
21 Apr '22
From: Haimin Zhang <tcs_kernel(a)tencent.com>
stable inclusion
from stable-v5.10.110
commit 8d3f4ad43054619379ccc697cfcbdb2c266800d8
category: bugfix
bugzilla: 186606, https://gitee.com/src-openeuler/kernel/issues/I53SSV
CVE: CVE-2022-1353
--------------------------------
[ Upstream commit 9a564bccb78a76740ea9d75a259942df8143d02c ]
Add __GFP_ZERO flag for compose_sadb_supported in function pfkey_register
to initialize the buffer of supp_skb to fix a kernel-info-leak issue.
1) Function pfkey_register calls compose_sadb_supported to request
a sk_buff. 2) compose_sadb_supported calls alloc_sbk to allocate
a sk_buff, but it doesn't zero it. 3) If auth_len is greater 0, then
compose_sadb_supported treats the memory as a struct sadb_supported and
begins to initialize. But it just initializes the field sadb_supported_len
and field sadb_supported_exttype without field sadb_supported_reserved.
Reported-by: TCS Robot <tcs_robot(a)tencent.com>
Signed-off-by: Haimin Zhang <tcs_kernel(a)tencent.com>
Signed-off-by: Steffen Klassert <steffen.klassert(a)secunet.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Xu Jia <xujia39(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
net/key/af_key.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ef9b4ac03e7b..b95684b8903e 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1703,7 +1703,7 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad
xfrm_probe_algs();
- supp_skb = compose_sadb_supported(hdr, GFP_KERNEL);
+ supp_skb = compose_sadb_supported(hdr, GFP_KERNEL | __GFP_ZERO);
if (!supp_skb) {
if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC)
pfk->registered &= ~(1<<hdr->sadb_msg_satype);
--
2.20.1
1
27

19 Apr '22
From: Jay Fang <f.fangjian(a)huawei.com>
mainline inclusion
from mainline-v5.14-rc1
commit 2b2142f247eb
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4UR1H
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
-----------------------------------------------------------------------
This patch uses debugfs_regset32 interface to create the registers dump
file. Use it instead of creating a generic debugfs file with manually
written read callback function.
With these entries, users can check all the SPI controller registers
during run time.
Signed-off-by: Jay Fang <f.fangjian(a)huawei.com>
Link: https://lore.kernel.org/r/1622789718-13977-1-git-send-email-f.fangjian@huaw…
Signed-off-by: Mark Brown <broonie(a)kernel.org>
Reviewed-by: Jay Fang <f.fangjian(a)huawei.com>
Acked-by: Xie XiuQi <xiexiuqi(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/spi/spi-hisi-kunpeng.c | 51 +++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c
index 3f986ba1c328..58b823a16fc4 100644
--- a/drivers/spi/spi-hisi-kunpeng.c
+++ b/drivers/spi/spi-hisi-kunpeng.c
@@ -9,6 +9,7 @@
#include <linux/acpi.h>
#include <linux/bitfield.h>
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
@@ -126,6 +127,7 @@ struct hisi_spi {
void __iomem *regs;
int irq;
u32 fifo_len; /* depth of the FIFO buffer */
+ u16 bus_num;
/* Current message transfer state info */
const void *tx;
@@ -133,8 +135,49 @@ struct hisi_spi {
void *rx;
unsigned int rx_len;
u8 n_bytes; /* current is a 1/2/4 bytes op */
+
+ struct dentry *debugfs;
+ struct debugfs_regset32 regset;
+};
+
+#define HISI_SPI_DBGFS_REG(_name, _off) \
+{ \
+ .name = _name, \
+ .offset = _off, \
+}
+
+static const struct debugfs_reg32 hisi_spi_regs[] = {
+ HISI_SPI_DBGFS_REG("CSCR", HISI_SPI_CSCR),
+ HISI_SPI_DBGFS_REG("CR", HISI_SPI_CR),
+ HISI_SPI_DBGFS_REG("ENR", HISI_SPI_ENR),
+ HISI_SPI_DBGFS_REG("FIFOC", HISI_SPI_FIFOC),
+ HISI_SPI_DBGFS_REG("IMR", HISI_SPI_IMR),
+ HISI_SPI_DBGFS_REG("DIN", HISI_SPI_DIN),
+ HISI_SPI_DBGFS_REG("DOUT", HISI_SPI_DOUT),
+ HISI_SPI_DBGFS_REG("SR", HISI_SPI_SR),
+ HISI_SPI_DBGFS_REG("RISR", HISI_SPI_RISR),
+ HISI_SPI_DBGFS_REG("ISR", HISI_SPI_ISR),
+ HISI_SPI_DBGFS_REG("ICR", HISI_SPI_ICR),
+ HISI_SPI_DBGFS_REG("VERSION", HISI_SPI_VERSION),
};
+static int hisi_spi_debugfs_init(struct hisi_spi *hs)
+{
+ char name[32];
+
+ snprintf(name, 32, "hisi_spi%d", hs->bus_num);
+ hs->debugfs = debugfs_create_dir(name, NULL);
+ if (!hs->debugfs)
+ return -ENOMEM;
+
+ hs->regset.regs = hisi_spi_regs;
+ hs->regset.nregs = ARRAY_SIZE(hisi_spi_regs);
+ hs->regset.base = hs->regs;
+ debugfs_create_regset32("registers", 0400, hs->debugfs, &hs->regset);
+
+ return 0;
+}
+
static u32 hisi_spi_busy(struct hisi_spi *hs)
{
return readl(hs->regs + HISI_SPI_SR) & SR_BUSY;
@@ -424,6 +467,7 @@ static int hisi_spi_probe(struct platform_device *pdev)
hs = spi_controller_get_devdata(master);
hs->dev = dev;
hs->irq = irq;
+ hs->bus_num = pdev->id;
hs->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(hs->regs))
@@ -446,7 +490,7 @@ static int hisi_spi_probe(struct platform_device *pdev)
master->use_gpio_descriptors = true;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
- master->bus_num = pdev->id;
+ master->bus_num = hs->bus_num;
master->setup = hisi_spi_setup;
master->cleanup = hisi_spi_cleanup;
master->transfer_one = hisi_spi_transfer_one;
@@ -462,6 +506,9 @@ static int hisi_spi_probe(struct platform_device *pdev)
return ret;
}
+ if (hisi_spi_debugfs_init(hs))
+ dev_info(dev, "failed to create debugfs dir\n");
+
ret = spi_register_controller(master);
if (ret) {
dev_err(dev, "failed to register spi master, ret=%d\n", ret);
@@ -478,7 +525,9 @@ static int hisi_spi_probe(struct platform_device *pdev)
static int hisi_spi_remove(struct platform_device *pdev)
{
struct spi_controller *master = platform_get_drvdata(pdev);
+ struct hisi_spi *hs = spi_controller_get_devdata(master);
+ debugfs_remove_recursive(hs->debugfs);
spi_unregister_controller(master);
return 0;
--
2.20.1
1
28
Backport following CVE fix patches:
CVE-2022-1055:
04c2a47ffb13c net: sched: fix use-after-free in tc_new_tfilter()
CVE-2022-23036:
6b1775f26a2d xen/grant-table: add gnttab_try_end_foreign_access()
abf1fd5919d6 xen/blkfront: don't use gnttab_query_foreign_access() for mapped status
CVE-2022-23037:
31185df7e2b1d xen/netfront: don't use gnttab_query_foreign_access() for mapped status
CVE-2022-23038:
33172ab50a535 xen/scsifront: don't use gnttab_query_foreign_access() for mapped status
CVE-2022-23039:
d3b6372c5881 xen/gntalloc: don't use gnttab_query_foreign_access()
CVE-2022-23040:
3777ea7bac31 xen/xenbus: don't let xenbus_grant_ring() remove grants in error case
CVE-2022-23041:
5cadd4bb1d7f xen/9p: use alloc/free_pages_exact()
b0576cc9c6b8 xen/pvcalls: use alloc/free_pages_exact()
42baefac638f xen/gnttab: fix gnttab_end_foreign_access() without page specified
CVE-2022-23042:
66e3531b33ee5 xen/netfront: react properly to failing gnttab_end_foreign_access_ref()
Eric Dumazet (1):
net: sched: fix use-after-free in tc_new_tfilter()
Juergen Gross (11):
xen/xenbus: don't let xenbus_grant_ring() remove grants in error case
xen/grant-table: add gnttab_try_end_foreign_access()
xen/blkfront: don't use gnttab_query_foreign_access() for mapped
status
xen/netfront: don't use gnttab_query_foreign_access() for mapped
status
xen/scsifront: don't use gnttab_query_foreign_access() for mapped
status
xen/gntalloc: don't use gnttab_query_foreign_access()
xen: remove gnttab_query_foreign_access()
xen/9p: use alloc/free_pages_exact()
xen/pvcalls: use alloc/free_pages_exact()
xen/gnttab: fix gnttab_end_foreign_access() without page specified
xen/netfront: react properly to failing
gnttab_end_foreign_access_ref()
drivers/block/xen-blkfront.c | 63 +++++++++++++++-----------
drivers/net/xen-netfront.c | 54 ++++++++++++++---------
drivers/scsi/xen-scsifront.c | 3 +-
drivers/xen/gntalloc.c | 25 +++--------
drivers/xen/grant-table.c | 71 ++++++++++++++++--------------
drivers/xen/pvcalls-front.c | 8 ++--
drivers/xen/xenbus/xenbus_client.c | 24 +++++-----
include/xen/grant_table.h | 19 +++++++-
net/9p/trans_xen.c | 14 +++---
net/sched/cls_api.c | 11 +++--
10 files changed, 162 insertions(+), 130 deletions(-)
--
2.20.1
1
12
Backport 5.10.93 LTS patches from upstream.
Conflicts:
already merged(git am --skip):
7f4308792a vfs: fs_context: fix up param length parsing in legacy_parse_param
Arie Geiger (1):
ALSA: hda/realtek: Add speaker fixup for some Yoga 15ITL5 devices
Arnd Bergmann (1):
mtd: fixup CFI on ixp4xx
Baole Fang (1):
ALSA: hda/realtek: Add quirk for Legion Y9000X 2020
Bart Kroon (1):
ALSA: hda: ALC287: Add Lenovo IdeaPad Slim 9i 14ITL5 speaker quirk
Christian Brauner (1):
9p: only copy valid iattrs in 9P2000.L setattr implementation
Christian Lachner (1):
ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master
after reboot from Windows
Christophe JAILLET (1):
orangefs: Fix the size of a memory allocation in
orangefs_bufmap_alloc()
Eric Farman (1):
KVM: s390: Clarify SIGP orders versus STOP/RESTART
Javier Martinez Canillas (1):
video: vga16fb: Only probe for EGA and VGA 16 color graphic cards
Johan Hovold (4):
media: uvcvideo: fix division by zero at stream start
firmware: qemu_fw_cfg: fix sysfs information leak
firmware: qemu_fw_cfg: fix NULL-pointer deref on duplicate entries
firmware: qemu_fw_cfg: fix kobject leak in probe error path
Larry Finger (1):
rtlwifi: rtl8192cu: Fix WARNING when calling local_irq_restore() with
interrupts enabled
Nathan Chancellor (1):
kbuild: Add $(KBUILD_HOSTLDFLAGS) to 'has_libelf' test
NeilBrown (1):
devtmpfs regression fix: reconfigure on each mount
Nicholas Piggin (1):
powerpc/pseries: Get entry and uaccess flush required bits from
H_GET_CPU_CHARACTERISTICS
Sean Christopherson (2):
perf: Protect perf_guest_cbs with RCU
KVM: x86: Register Processor Trace interrupt hook iff PT enabled in
guest
Stephen Boyd (1):
remoteproc: qcom: pil_info: Don't memcpy_toio more than is provided
Takashi Iwai (1):
ALSA: hda/realtek: Re-order quirk entries for Lenovo
Wei Wang (1):
KVM: x86: remove PMU FIXED_CTR3 from msrs_to_save_all
Makefile | 2 +-
arch/arm/kernel/perf_callchain.c | 17 ++++---
arch/arm64/kernel/perf_callchain.c | 18 ++++---
arch/csky/kernel/perf_callchain.c | 6 ++-
arch/nds32/kernel/perf_event_cpu.c | 17 ++++---
arch/powerpc/include/asm/hvcall.h | 2 +
arch/powerpc/platforms/pseries/setup.c | 6 +++
arch/riscv/kernel/perf_callchain.c | 7 ++-
arch/s390/kvm/interrupt.c | 7 +++
arch/s390/kvm/kvm-s390.c | 9 +++-
arch/s390/kvm/kvm-s390.h | 1 +
arch/s390/kvm/sigp.c | 28 ++++++++++
arch/x86/events/core.c | 17 ++++---
arch/x86/events/intel/core.c | 9 ++--
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/vmx/vmx.c | 1 +
arch/x86/kvm/x86.c | 7 ++-
drivers/base/devtmpfs.c | 7 +++
drivers/firmware/qemu_fw_cfg.c | 20 +++-----
drivers/media/usb/uvc/uvc_video.c | 4 ++
drivers/mtd/chips/Kconfig | 2 +
drivers/mtd/maps/Kconfig | 2 +-
.../wireless/realtek/rtlwifi/rtl8192cu/hw.c | 1 +
drivers/remoteproc/qcom_pil_info.c | 2 +-
drivers/video/fbdev/vga16fb.c | 24 +++++++++
fs/9p/vfs_inode_dotl.c | 29 +++++++----
fs/orangefs/orangefs-bufmap.c | 7 ++-
fs/super.c | 4 +-
include/linux/fs_context.h | 2 +
include/linux/perf_event.h | 13 ++++-
kernel/events/core.c | 13 +++--
sound/pci/hda/patch_realtek.c | 51 +++++++++++++++++--
32 files changed, 264 insertions(+), 72 deletions(-)
--
2.20.1
1
22
Backport 5.10.92 LTS patches from upstream.
Conflicts:
already merged(git am --skip):
35ab8c9085b0a bpf: Fix out of bounds access from invalid *_or_null type verification
Aaron Ma (2):
Bluetooth: btusb: Add support for Foxconn MT7922A
Bluetooth: btusb: Add support for Foxconn QCA 0xe0d0
Adrian Hunter (1):
mmc: sdhci-pci: Add PCI ID for Intel ADL
Alan Stern (2):
USB: core: Fix bug in resuming hub's handling of wakeup requests
USB: Fix "slab-out-of-bounds Write" bug in usb_hcd_poll_rh_status
Andy Shevchenko (1):
mfd: intel-lpss: Fix too early PM enablement in the ACPI ->probe()
Arnd Bergmann (1):
staging: greybus: fix stack size warning with UBSAN
Brian Silverman (1):
can: gs_usb: gs_can_start_xmit(): zero-initialize hf->{flags,reserved}
Daniel Borkmann (1):
veth: Do not record rx queue hint in veth_xmit
Dominik Brodowski (1):
random: fix crash on multiple early calls to
add_bootloader_randomness()
Eric Biggers (2):
random: fix data race on crng_node_pool
random: fix data race on crng init time
Frederic Weisbecker (1):
workqueue: Fix unbind_workers() VS wq_worker_running() race
Johan Hovold (1):
Bluetooth: bfusb: fix division by zero in send path
Marc Kleine-Budde (2):
can: gs_usb: fix use of uninitialized variable, detach device on
reception of invalid USB data
can: isotp: convert struct tpcon::{idx,len} to unsigned int
Mark-YW.Chen (1):
Bluetooth: btusb: fix memory leak in btusb_mtk_submit_wmt_recv_urb()
Nathan Chancellor (2):
staging: wlan-ng: Avoid bitwise vs logical OR warning in
hfa384x_usb_throttlefn()
drm/i915: Avoid bitwise vs logical OR warning in
snb_wm_latency_quirk()
Paul Cercueil (1):
ARM: dts: exynos: Fix BCM4330 Bluetooth reset polarity in I9100
Ricardo Ribalda (1):
media: Revert "media: uvcvideo: Set unique vdev name based in type"
Sven Eckelmann (1):
ath11k: Fix buffer overflow when scanning with extraie
Zijun Hu (1):
Bluetooth: btusb: Add two more Bluetooth parts for WCN6855
arch/arm/boot/dts/exynos4210-i9100.dts | 2 +-
drivers/bluetooth/bfusb.c | 3 +
drivers/bluetooth/btusb.c | 22 +++++
drivers/char/random.c | 117 +++++++++++++----------
drivers/gpu/drm/i915/intel_pm.c | 6 +-
drivers/media/usb/uvc/uvc_driver.c | 7 +-
drivers/mfd/intel-lpss-acpi.c | 7 +-
drivers/mmc/host/sdhci-pci-core.c | 1 +
drivers/mmc/host/sdhci-pci.h | 1 +
drivers/net/can/usb/gs_usb.c | 5 +-
drivers/net/veth.c | 1 -
drivers/net/wireless/ath/ath11k/wmi.c | 6 +-
drivers/staging/greybus/audio_topology.c | 92 +++++++++---------
drivers/staging/wlan-ng/hfa384x_usb.c | 22 ++---
drivers/usb/core/hcd.c | 9 +-
drivers/usb/core/hub.c | 2 +-
kernel/workqueue.c | 9 ++
net/can/isotp.c | 4 +-
18 files changed, 190 insertions(+), 126 deletions(-)
--
2.20.1
1
23
help
------------------ 原始邮件 ------------------
发件人: "kernel-request" <kernel-request(a)openeuler.org>;
发送时间: 2022年4月19日(星期二) 下午4:29
收件人: "王滨"<734059002(a)qq.com>;
主题: Welcome to the "Kernel" mailing list
欢迎使用“Kernel”邮件列表!
要通过此列表交流,请发送电子邮件至:
kernel(a)openeuler.org
取消订阅或调整选项请发送电子邮件至:
kernel-leave(a)openeuler.org
在主题或正文中使用"help"一词(不包括引号), 您将会收到一条带有说明的信息。更改
设置需要用到密码,但出于安全考虑,此处不包括此密码。如果您忘记了密码,则需要 通过网络用户界面重置密码。
Welcome to the "Kernel" mailing list!
To post to this list, send your email to:
kernel(a)openeuler.org
You can unsubscribe or make adjustments to your options via email by
sending a message to:
kernel-leave(a)openeuler.org
with the word 'help' in the subject or body (don't include the
quotes), and you will receive a message with instructions. You will
need your password to change your options, but for security purposes,
this password is not included here. If you have forgotten your
password, you will need to reset it via the web UI.
1
0
------------------ 原始邮件 ------------------
发件人: "kernel-request" <kernel-request(a)openeuler.org>;
发送时间: 2022年4月19日(星期二) 下午4:29
收件人: "王滨"<734059002(a)qq.com>;
主题: Welcome to the "Kernel" mailing list
欢迎使用“Kernel”邮件列表!
要通过此列表交流,请发送电子邮件至:
kernel(a)openeuler.org
取消订阅或调整选项请发送电子邮件至:
kernel-leave(a)openeuler.org
在主题或正文中使用"help"一词(不包括引号), 您将会收到一条带有说明的信息。更改
设置需要用到密码,但出于安全考虑,此处不包括此密码。如果您忘记了密码,则需要 通过网络用户界面重置密码。
Welcome to the "Kernel" mailing list!
To post to this list, send your email to:
kernel(a)openeuler.org
You can unsubscribe or make adjustments to your options via email by
sending a message to:
kernel-leave(a)openeuler.org
with the word 'help' in the subject or body (don't include the
quotes), and you will receive a message with instructions. You will
need your password to change your options, but for security purposes,
this password is not included here. If you have forgotten your
password, you will need to reset it via the web UI.
1
0

19 Apr '22
zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52DS7
CVE: NA
Add support for the temperature sensor inside CPU.
Supported are all known variants of the Zhaoxin processors.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/via-cputemp.c | 1 -
drivers/hwmon/zhaoxin-cputemp.c | 292 ++++++++++++++++++++++++++++++++
4 files changed, 302 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwmon/zhaoxin-cputemp.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0c2b032ee617..c11c3c46898a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1889,6 +1889,15 @@ config SENSORS_VIA_CPUTEMP
sensor inside your CPU. Supported are all known variants of
the VIA C7 and Nano.
+config SENSORS_ZHAOXIN_CPUTEMP
+ tristate "Zhaoxin CPU temperature sensor"
+ depends on X86
+ select HWMON_VID
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Supported are all known variants of
+ the Zhaoxin processors.
+
config SENSORS_VIA686A
tristate "VIA686A"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 9db2903b61e5..2427687972c9 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -184,6 +184,7 @@ obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TMP513) += tmp513.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
+obj-$(CONFIG_SENSORS_ZHAOXIN_CPUTEMP) += zhaoxin-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index e5d18dac8ee7..0a5057dbe51a 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -273,7 +273,6 @@ static const struct x86_cpu_id __initconst
cputemp_ids[] = {
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_A,
NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_D,
NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_NANO,
NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
{}
};
MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
diff --git a/drivers/hwmon/zhaoxin-cputemp.c
b/drivers/hwmon/zhaoxin-cputemp.c
new file mode 100644
index 000000000000..dcedb51515f0
--- /dev/null
+++ b/drivers/hwmon/zhaoxin-cputemp.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * zhaoxin-cputemp.c - Driver for Zhaoxin CPU core temperature monitoring
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define DRVNAME "zhaoxin_cputemp"
+
+enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
+
+/* Functions declaration */
+
+struct zhaoxin_cputemp_data {
+ struct device *hwmon_dev;
+ const char *name;
+ u8 vrm;
+ u32 id;
+ u32 msr_temp;
+ u32 msr_vid;
+};
+
+/* Sysfs stuff */
+
+static ssize_t name_show(struct device *dev, struct device_attribute
*devattr,
+ char *buf)
+{
+ int ret;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+
+ if (attr->index == SHOW_NAME)
+ ret = sprintf(buf, "%s\n", data->name);
+ else /* show label */
+ ret = sprintf(buf, "Core %d\n", data->id);
+ return ret;
+}
+
+static ssize_t temp_show(struct device *dev, struct device_attribute
*devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
+}
+
+static ssize_t cpu0_vid_show(struct device *dev, struct
device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, SHOW_TEMP);
+static SENSOR_DEVICE_ATTR_RO(temp1_label, name, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR_RO(name, name, SHOW_NAME);
+
+static struct attribute *zhaoxin_cputemp_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group zhaoxin_cputemp_group = {
+ .attrs = zhaoxin_cputemp_attributes,
+};
+
+/* Optional attributes */
+static DEVICE_ATTR_RO(cpu0_vid);
+
+static int zhaoxin_cputemp_probe(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data;
+ int err;
+ u32 eax, edx;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(struct
zhaoxin_cputemp_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->id = pdev->id;
+ data->name = "zhaoxin_cputemp";
+ data->msr_temp = 0x1423;
+
+ /* test if we can access the TEMPERATURE MSR */
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving
up\n");
+ return err;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ err = sysfs_create_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ if (err)
+ return err;
+
+ if (data->msr_vid)
+ data->vrm = vid_which_vrm();
+
+ if (data->vrm) {
+ err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_remove;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return err;
+}
+
+static int zhaoxin_cputemp_remove(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return 0;
+}
+
+static struct platform_driver zhaoxin_cputemp_driver = {
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = zhaoxin_cputemp_probe,
+ .remove = zhaoxin_cputemp_remove,
+};
+
+struct pdev_entry {
+ struct list_head list;
+ struct platform_device *pdev;
+ unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int zhaoxin_cputemp_online(unsigned int cpu)
+{
+ int err;
+ struct platform_device *pdev;
+ struct pdev_entry *pdev_entry;
+
+ pdev = platform_device_alloc(DRVNAME, cpu);
+ if (!pdev) {
+ err = -ENOMEM;
+ pr_err("Device allocation failed\n");
+ goto exit;
+ }
+
+ pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+ if (!pdev_entry) {
+ err = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ pr_err("Device addition failed (%d)\n", err);
+ goto exit_device_free;
+ }
+
+ pdev_entry->pdev = pdev;
+ pdev_entry->cpu = cpu;
+ mutex_lock(&pdev_list_mutex);
+ list_add_tail(&pdev_entry->list, &pdev_list);
+ mutex_unlock(&pdev_list_mutex);
+
+ return 0;
+
+exit_device_free:
+ kfree(pdev_entry);
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+static int zhaoxin_cputemp_down_prep(unsigned int cpu)
+{
+ struct pdev_entry *p;
+
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry(p, &pdev_list, list) {
+ if (p->cpu == cpu) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
+ kfree(p);
+ return 0;
+ }
+ }
+ mutex_unlock(&pdev_list_mutex);
+ return 0;
+}
+
+static const struct x86_cpu_id __initconst cputemp_ids[] = {
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(ZHAOXIN, 7, X86_MODEL_ANY, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
+
+static enum cpuhp_state zhaoxin_temp_online;
+
+static int __init zhaoxin_cputemp_init(void)
+{
+ int err;
+
+ if (!x86_match_cpu(cputemp_ids))
+ return -ENODEV;
+
+ err = platform_driver_register(&zhaoxin_cputemp_driver);
+ if (err)
+ goto exit;
+
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/zhaoxin:online",
+ zhaoxin_cputemp_online, zhaoxin_cputemp_down_prep);
+ if (err < 0)
+ goto exit_driver_unreg;
+ zhaoxin_temp_online = err;
+
+#ifndef CONFIG_HOTPLUG_CPU
+ if (list_empty(&pdev_list)) {
+ err = -ENODEV;
+ goto exit_hp_unreg;
+ }
+#endif
+ return 0;
+
+#ifndef CONFIG_HOTPLUG_CPU
+exit_hp_unreg:
+ cpuhp_remove_state_nocalls(zhaoxin_temp_online);
+#endif
+exit_driver_unreg:
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+exit:
+ return err;
+}
+
+static void __exit zhaoxin_cputemp_exit(void)
+{
+ cpuhp_remove_state(zhaoxin_temp_online);
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+}
+
+MODULE_DESCRIPTION("Zhaoxin CPU temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(zhaoxin_cputemp_init)
+module_exit(zhaoxin_cputemp_exit)
--
2.20.1
1
0

[PATCH openEuler-5.10] vfio: pci: fix Memory deallocated more than once fault_pages
by yan 18 Apr '22
by yan 18 Apr '22
18 Apr '22
1
0

18 Apr '22
1
0

18 Apr '22
1
0
1
0

15 Apr '22
zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52DS7
CVE: NA
Add support for the temperature sensor inside CPU.
Supported are all known variants of the Zhaoxin processors.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/via-cputemp.c | 1 -
drivers/hwmon/zhaoxin-cputemp.c | 288 ++++++++++++++++++++++++++++++++
4 files changed, 298 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwmon/zhaoxin-cputemp.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c7adaca2ab01..1ef7c384d652 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1720,6 +1720,15 @@ config SENSORS_VIA_CPUTEMP
sensor inside your CPU. Supported are all known variants of
the VIA C7 and Nano.
+config SENSORS_ZHAOXIN_CPUTEMP
+ tristate "Zhaoxin CPU temperature sensor"
+ depends on X86
+ select HWMON_VID
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Supported are all known variants of
+ the Zhaoxin processors.
+
config SENSORS_VIA686A
tristate "VIA686A"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 93f7f41ea4ad..44674a1e75e8 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -168,6 +168,7 @@ obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
+obj-$(CONFIG_SENSORS_ZHAOXIN_CPUTEMP) += zhaoxin-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index 0e81f287d305..3c960b999958 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -287,7 +287,6 @@ static const struct x86_cpu_id __initconst
cputemp_ids[] = {
{ X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */
{ X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */
{ X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */
- { X86_VENDOR_CENTAUR, 7, X86_MODEL_ANY, },
{}
};
MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
diff --git a/drivers/hwmon/zhaoxin-cputemp.c
b/drivers/hwmon/zhaoxin-cputemp.c
new file mode 100644
index 000000000000..24462719b6ca
--- /dev/null
+++ b/drivers/hwmon/zhaoxin-cputemp.c
@@ -0,0 +1,288 @@
+/*
+ * zhaoxin-cputemp.c - Driver for Zhaoxin CPU core temperature monitoring
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define DRVNAME "zhaoxin_cputemp"
+
+enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
+
+/* Functions declaration */
+struct zhaoxin_cputemp_data {
+ struct device *hwmon_dev;
+ const char *name;
+ u8 vrm;
+ u32 id;
+ u32 msr_temp;
+ u32 msr_vid;
+};
+
+/* Sysfs stuff */
+static ssize_t show_name(struct device *dev, struct device_attribute
*devattr, char *buf)
+{
+ int ret;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+
+ if (attr->index == SHOW_NAME)
+ ret = sprintf(buf, "%s\n", data->name);
+ else /* show label */
+ ret = sprintf(buf, "Core %d\n", data->id);
+ return ret;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute
*devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
+}
+
+static ssize_t cpu0_vid_show(struct device *dev, struct
device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
SHOW_TEMP);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL,
SHOW_LABEL);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
+
+static struct attribute *zhaoxin_cputemp_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group zhaoxin_cputemp_group = {
+ .attrs = zhaoxin_cputemp_attributes,
+};
+
+/* Optional attributes */
+static DEVICE_ATTR_RO(cpu0_vid);
+
+static int zhaoxin_cputemp_probe(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data;
+ int err;
+ u32 eax, edx;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(struct
zhaoxin_cputemp_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->id = pdev->id;
+ data->name = "zhaoxin_cputemp";
+ data->msr_temp = 0x1423;
+
+ /* Test if we can access the TEMPERATURE MSR */
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving
up\n");
+ return err;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ err = sysfs_create_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ if (err)
+ return err;
+
+ if (data->msr_vid)
+ data->vrm = vid_which_vrm();
+
+ if (data->vrm) {
+ err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_remove;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return err;
+}
+
+static int zhaoxin_cputemp_remove(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return 0;
+}
+
+static struct platform_driver zhaoxin_cputemp_driver = {
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = zhaoxin_cputemp_probe,
+ .remove = zhaoxin_cputemp_remove,
+};
+
+struct pdev_entry {
+ struct list_head list;
+ struct platform_device *pdev;
+ unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int zhaoxin_cputemp_online(unsigned int cpu)
+{
+ int err;
+ struct platform_device *pdev;
+ struct pdev_entry *pdev_entry;
+
+ pdev = platform_device_alloc(DRVNAME, cpu);
+ if (!pdev) {
+ err = -ENOMEM;
+ pr_err("Device allocation failed\n");
+ goto exit;
+ }
+
+ pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+ if (!pdev_entry) {
+ err = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ pr_err("Device addition failed (%d)\n", err);
+ goto exit_device_free;
+ }
+
+ pdev_entry->pdev = pdev;
+ pdev_entry->cpu = cpu;
+ mutex_lock(&pdev_list_mutex);
+ list_add_tail(&pdev_entry->list, &pdev_list);
+ mutex_unlock(&pdev_list_mutex);
+
+ return 0;
+
+exit_device_free:
+ kfree(pdev_entry);
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+static int zhaoxin_cputemp_down_prep(unsigned int cpu)
+{
+ struct pdev_entry *p;
+
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry(p, &pdev_list, list) {
+ if (p->cpu == cpu) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
+ kfree(p);
+ return 0;
+ }
+ }
+ mutex_unlock(&pdev_list_mutex);
+ return 0;
+}
+
+static const struct x86_cpu_id __initconst cputemp_ids[] = {
+ { X86_VENDOR_CENTAUR, 7, X86_MODEL_ANY, },
+ { X86_VENDOR_ZHAOXIN, 7, X86_MODEL_ANY, },
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
+
+static enum cpuhp_state zhaoxin_temp_online;
+
+static int __init zhaoxin_cputemp_init(void)
+{
+ int err;
+
+ if (!x86_match_cpu(cputemp_ids))
+ return -ENODEV;
+
+ err = platform_driver_register(&zhaoxin_cputemp_driver);
+ if (err)
+ goto exit;
+
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/zhaoxin:online",
+ zhaoxin_cputemp_online, zhaoxin_cputemp_down_prep);
+ if (err < 0)
+ goto exit_driver_unreg;
+ zhaoxin_temp_online = err;
+
+#ifndef CONFIG_HOTPLUG_CPU
+ if (list_empty(&pdev_list)) {
+ err = -ENODEV;
+ goto exit_hp_unreg;
+ }
+#endif
+ return 0;
+
+#ifndef CONFIG_HOTPLUG_CPU
+exit_hp_unreg:
+ cpuhp_remove_state_nocalls(zhaoxin_temp_online);
+#endif
+exit_driver_unreg:
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+exit:
+ return err;
+}
+
+static void __exit zhaoxin_cputemp_exit(void)
+{
+ cpuhp_remove_state(zhaoxin_temp_online);
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+}
+
+MODULE_DESCRIPTION("Zhaoxin CPU temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(zhaoxin_cputemp_init)
+module_exit(zhaoxin_cputemp_exit)
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS 01/15] binder: use euid from cred instead of using task
by Laibin Qiu 15 Apr '22
by Laibin Qiu 15 Apr '22
15 Apr '22
From: Todd Kjos <tkjos(a)google.com>
stable inclusion
from linux-4.19.218
commit 5d40061285b81a7e213dc9b37acc4a0545eedf32
--------------------------------
commit 29bc22ac5e5bc63275e850f0c8fc549e3d0e306b upstream.
Save the 'struct cred' associated with a binder process
at initial open to avoid potential race conditions
when converting to an euid.
Set a transaction's sender_euid from the 'struct cred'
saved at binder_open() instead of looking up the euid
from the binder proc's 'struct task'. This ensures
the euid is associated with the security context that
of the task that opened binder.
Cc: stable(a)vger.kernel.org # 4.4+
Fixes: 457b9a6f09f0 ("Staging: android: add binder driver")
Signed-off-by: Todd Kjos <tkjos(a)google.com>
Suggested-by: Stephen Smalley <stephen.smalley.work(a)gmail.com>
Suggested-by: Jann Horn <jannh(a)google.com>
Acked-by: Casey Schaufler <casey(a)schaufler-ca.com>
Signed-off-by: Paul Moore <paul(a)paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
drivers/android/binder.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 18c32637047f..3ba23d29f50a 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -483,6 +483,9 @@ enum binder_deferred_state {
* @files files_struct for process
* (protected by @files_lock)
* @files_lock mutex to protect @files
+ * @cred struct cred associated with the `struct file`
+ * in binder_open()
+ * (invariant after initialized)
* @deferred_work_node: element for binder_deferred_list
* (protected by binder_deferred_lock)
* @deferred_work: bitmap of deferred work to perform
@@ -529,6 +532,7 @@ struct binder_proc {
struct task_struct *tsk;
struct files_struct *files;
struct mutex files_lock;
+ const struct cred *cred;
struct hlist_node deferred_work_node;
int deferred_work;
bool is_dead;
@@ -2956,7 +2960,7 @@ static void binder_transaction(struct binder_proc *proc,
t->from = thread;
else
t->from = NULL;
- t->sender_euid = task_euid(proc->tsk);
+ t->sender_euid = proc->cred->euid;
t->to_proc = target_proc;
t->to_thread = target_thread;
t->code = tr->code;
@@ -4328,6 +4332,7 @@ static void binder_free_proc(struct binder_proc *proc)
BUG_ON(!list_empty(&proc->delivered_death));
binder_alloc_deferred_release(&proc->alloc);
put_task_struct(proc->tsk);
+ put_cred(proc->cred);
binder_stats_deleted(BINDER_STAT_PROC);
kfree(proc);
}
@@ -4786,6 +4791,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
get_task_struct(current->group_leader);
proc->tsk = current->group_leader;
mutex_init(&proc->files_lock);
+ proc->cred = get_cred(filp->f_cred);
INIT_LIST_HEAD(&proc->todo);
proc->default_priority = task_nice(current);
binder_dev = container_of(filp->private_data, struct binder_device,
--
2.22.0
1
14
1
0
各位好,
openEuler开发者大会于4月13-15日线上举报,周四下午14:00内核SIG工作会议,周五下午14:00内核分论坛主题演讲,欢迎大家参与。
参与周四下午的SIG工作会议需要注册,麻烦大家提前注册,方便届时接入:https://us06web.zoom.us/webinar/register/WN_nxtHqu_VSbOuWhiP16e-Bw
观看周五下午的内核分论坛主题演讲,请关注官网直播:https://www.openeuler.org/zh/interaction/summit-li…
谢谢大家支持。
1
0

13 Apr '22
zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52DS7
CVE: NA
Add support for the temperature sensor inside CPU.
Supported are all known variants of the Zhaoxin processors.
v1: Fix some character encoding mistaken.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/via-cputemp.c | 1 -
drivers/hwmon/zhaoxin-cputemp.c | 292 ++++++++++++++++++++++++++++++++
4 files changed, 302 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwmon/zhaoxin-cputemp.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0c2b032ee617..c11c3c46898a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1889,6 +1889,15 @@ config SENSORS_VIA_CPUTEMP
sensor inside your CPU. Supported are all known variants of
the VIA C7 and Nano.
+config SENSORS_ZHAOXIN_CPUTEMP
+ tristate "Zhaoxin CPU temperature sensor"
+ depends on X86
+ select HWMON_VID
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Supported are all known variants of
+ the Zhaoxin processors.
+
config SENSORS_VIA686A
tristate "VIA686A"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 9db2903b61e5..2427687972c9 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -184,6 +184,7 @@ obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TMP513) += tmp513.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
+obj-$(CONFIG_SENSORS_ZHAOXIN_CPUTEMP) += zhaoxin-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index e5d18dac8ee7..0a5057dbe51a 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -273,7 +273,6 @@ static const struct x86_cpu_id __initconst
cputemp_ids[] = {
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_A,
NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_D,
NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_NANO,
NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
{}
};
MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
diff --git a/drivers/hwmon/zhaoxin-cputemp.c
b/drivers/hwmon/zhaoxin-cputemp.c
new file mode 100644
index 000000000000..dcedb51515f0
--- /dev/null
+++ b/drivers/hwmon/zhaoxin-cputemp.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * zhaoxin-cputemp.c - Driver for Zhaoxin CPU core temperature monitoring
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define DRVNAME "zhaoxin_cputemp"
+
+enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
+
+/* Functions declaration */
+
+struct zhaoxin_cputemp_data {
+ struct device *hwmon_dev;
+ const char *name;
+ u8 vrm;
+ u32 id;
+ u32 msr_temp;
+ u32 msr_vid;
+};
+
+/* Sysfs stuff */
+
+static ssize_t name_show(struct device *dev, struct device_attribute
*devattr,
+ char *buf)
+{
+ int ret;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+
+ if (attr->index == SHOW_NAME)
+ ret = sprintf(buf, "%s\n", data->name);
+ else /* show label */
+ ret = sprintf(buf, "Core %d\n", data->id);
+ return ret;
+}
+
+static ssize_t temp_show(struct device *dev, struct device_attribute
*devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
+}
+
+static ssize_t cpu0_vid_show(struct device *dev, struct
device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, SHOW_TEMP);
+static SENSOR_DEVICE_ATTR_RO(temp1_label, name, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR_RO(name, name, SHOW_NAME);
+
+static struct attribute *zhaoxin_cputemp_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group zhaoxin_cputemp_group = {
+ .attrs = zhaoxin_cputemp_attributes,
+};
+
+/* Optional attributes */
+static DEVICE_ATTR_RO(cpu0_vid);
+
+static int zhaoxin_cputemp_probe(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data;
+ int err;
+ u32 eax, edx;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(struct
zhaoxin_cputemp_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->id = pdev->id;
+ data->name = "zhaoxin_cputemp";
+ data->msr_temp = 0x1423;
+
+ /* test if we can access the TEMPERATURE MSR */
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving
up\n");
+ return err;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ err = sysfs_create_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ if (err)
+ return err;
+
+ if (data->msr_vid)
+ data->vrm = vid_which_vrm();
+
+ if (data->vrm) {
+ err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_remove;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return err;
+}
+
+static int zhaoxin_cputemp_remove(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return 0;
+}
+
+static struct platform_driver zhaoxin_cputemp_driver = {
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = zhaoxin_cputemp_probe,
+ .remove = zhaoxin_cputemp_remove,
+};
+
+struct pdev_entry {
+ struct list_head list;
+ struct platform_device *pdev;
+ unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int zhaoxin_cputemp_online(unsigned int cpu)
+{
+ int err;
+ struct platform_device *pdev;
+ struct pdev_entry *pdev_entry;
+
+ pdev = platform_device_alloc(DRVNAME, cpu);
+ if (!pdev) {
+ err = -ENOMEM;
+ pr_err("Device allocation failed\n");
+ goto exit;
+ }
+
+ pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+ if (!pdev_entry) {
+ err = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ pr_err("Device addition failed (%d)\n", err);
+ goto exit_device_free;
+ }
+
+ pdev_entry->pdev = pdev;
+ pdev_entry->cpu = cpu;
+ mutex_lock(&pdev_list_mutex);
+ list_add_tail(&pdev_entry->list, &pdev_list);
+ mutex_unlock(&pdev_list_mutex);
+
+ return 0;
+
+exit_device_free:
+ kfree(pdev_entry);
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+static int zhaoxin_cputemp_down_prep(unsigned int cpu)
+{
+ struct pdev_entry *p;
+
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry(p, &pdev_list, list) {
+ if (p->cpu == cpu) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
+ kfree(p);
+ return 0;
+ }
+ }
+ mutex_unlock(&pdev_list_mutex);
+ return 0;
+}
+
+static const struct x86_cpu_id __initconst cputemp_ids[] = {
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(ZHAOXIN, 7, X86_MODEL_ANY, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
+
+static enum cpuhp_state zhaoxin_temp_online;
+
+static int __init zhaoxin_cputemp_init(void)
+{
+ int err;
+
+ if (!x86_match_cpu(cputemp_ids))
+ return -ENODEV;
+
+ err = platform_driver_register(&zhaoxin_cputemp_driver);
+ if (err)
+ goto exit;
+
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/zhaoxin:online",
+ zhaoxin_cputemp_online, zhaoxin_cputemp_down_prep);
+ if (err < 0)
+ goto exit_driver_unreg;
+ zhaoxin_temp_online = err;
+
+#ifndef CONFIG_HOTPLUG_CPU
+ if (list_empty(&pdev_list)) {
+ err = -ENODEV;
+ goto exit_hp_unreg;
+ }
+#endif
+ return 0;
+
+#ifndef CONFIG_HOTPLUG_CPU
+exit_hp_unreg:
+ cpuhp_remove_state_nocalls(zhaoxin_temp_online);
+#endif
+exit_driver_unreg:
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+exit:
+ return err;
+}
+
+static void __exit zhaoxin_cputemp_exit(void)
+{
+ cpuhp_remove_state(zhaoxin_temp_online);
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+}
+
+MODULE_DESCRIPTION("Zhaoxin CPU temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(zhaoxin_cputemp_init)
+module_exit(zhaoxin_cputemp_exit)
--
2.20.1
1
0

13 Apr '22
From: Halil Pasic <pasic(a)linux.ibm.com>
mainline inclusion
from mainline-v5.17-rc6
commit ddbd89deb7d32b1fbb879f48d68fda1a8ac58e8e
category: bugfix
bugzilla: 186478, https://gitee.com/src-openeuler/kernel/issues/I503W4
CVE: CVE-2022-0854
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
The problem I'm addressing was discovered by the LTP test covering
cve-2018-1000204.
A short description of what happens follows:
1) The test case issues a command code 00 (TEST UNIT READY) via the SG_IO
interface with: dxfer_len == 524288, dxdfer_dir == SG_DXFER_FROM_DEV
and a corresponding dxferp. The peculiar thing about this is that TUR
is not reading from the device.
2) In sg_start_req() the invocation of blk_rq_map_user() effectively
bounces the user-space buffer. As if the device was to transfer into
it. Since commit a45b599ad808 ("scsi: sg: allocate with __GFP_ZERO in
sg_build_indirect()") we make sure this first bounce buffer is
allocated with GFP_ZERO.
3) For the rest of the story we keep ignoring that we have a TUR, so the
device won't touch the buffer we prepare as if the we had a
DMA_FROM_DEVICE type of situation. My setup uses a virtio-scsi device
and the buffer allocated by SG is mapped by the function
virtqueue_add_split() which uses DMA_FROM_DEVICE for the "in" sgs (here
scatter-gather and not scsi generics). This mapping involves bouncing
via the swiotlb (we need swiotlb to do virtio in protected guest like
s390 Secure Execution, or AMD SEV).
4) When the SCSI TUR is done, we first copy back the content of the second
(that is swiotlb) bounce buffer (which most likely contains some
previous IO data), to the first bounce buffer, which contains all
zeros. Then we copy back the content of the first bounce buffer to
the user-space buffer.
5) The test case detects that the buffer, which it zero-initialized,
ain't all zeros and fails.
One can argue that this is an swiotlb problem, because without swiotlb
we leak all zeros, and the swiotlb should be transparent in a sense that
it does not affect the outcome (if all other participants are well
behaved).
Copying the content of the original buffer into the swiotlb buffer is
the only way I can think of to make swiotlb transparent in such
scenarios. So let's do just that if in doubt, but allow the driver
to tell us that the whole mapped buffer is going to be overwritten,
in which case we can preserve the old behavior and avoid the performance
impact of the extra bounce.
Signed-off-by: Halil Pasic <pasic(a)linux.ibm.com>
Signed-off-by: Christoph Hellwig <hch(a)lst.de>
Conflicts:
kernel/dma/swiotlb.c
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
Documentation/core-api/dma-attributes.rst | 8 ++++++++
include/linux/dma-mapping.h | 8 ++++++++
kernel/dma/swiotlb.c | 3 ++-
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/Documentation/core-api/dma-attributes.rst b/Documentation/core-api/dma-attributes.rst
index 1887d92e8e92..17706dc91ec9 100644
--- a/Documentation/core-api/dma-attributes.rst
+++ b/Documentation/core-api/dma-attributes.rst
@@ -130,3 +130,11 @@ accesses to DMA buffers in both privileged "supervisor" and unprivileged
subsystem that the buffer is fully accessible at the elevated privilege
level (and ideally inaccessible or at least read-only at the
lesser-privileged levels).
+
+DMA_ATTR_OVERWRITE
+------------------
+
+This is a hint to the DMA-mapping subsystem that the device is expected to
+overwrite the entire mapped size, thus the caller does not require any of the
+previous buffer contents to be preserved. This allows bounce-buffering
+implementations to optimise DMA_FROM_DEVICE transfers.
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index a7d70cdee25e..a9361178c5db 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -61,6 +61,14 @@
*/
#define DMA_ATTR_PRIVILEGED (1UL << 9)
+/*
+ * This is a hint to the DMA-mapping subsystem that the device is expected
+ * to overwrite the entire mapped size, thus the caller does not require any
+ * of the previous buffer contents to be preserved. This allows
+ * bounce-buffering implementations to optimise DMA_FROM_DEVICE transfers.
+ */
+#define DMA_ATTR_OVERWRITE (1UL << 10)
+
/*
* A dma_addr_t can hold any valid DMA or bus address for the platform. It can
* be given to a device to use as a DMA source or target. It is specific to a
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index 0ed0e1f215c7..62b1e5fa8673 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -598,7 +598,8 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
tlb_addr = slot_addr(io_tlb_start, index) + offset;
if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
- (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
+ (!(attrs & DMA_ATTR_OVERWRITE) || dir == DMA_TO_DEVICE ||
+ dir == DMA_BIDIRECTIONAL))
swiotlb_bounce(orig_addr, tlb_addr, mapping_size, DMA_TO_DEVICE);
return tlb_addr;
}
--
2.20.1
1
3

12 Apr '22
zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I52DS7
CVE: NA
Add support for the temperature sensor inside your CPU.
Supported are all known variants of the Zhaoxin processors.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/via-cputemp.c | 1 -
drivers/hwmon/zhaoxin-cputemp.c | 292 ++++++++++++++++++++++++++++++++
4 files changed, 302 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwmon/zhaoxin-cputemp.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0c2b032ee617..c11c3c46898a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1889,6 +1889,15 @@ config SENSORS_VIA_CPUTEMP
sensor inside your CPU. Supported are all known variants of
the VIA C7 and Nano.
+config SENSORS_ZHAOXIN_CPUTEMP
+ tristate "VIA CPU temperature sensor"
+ depends on X86
+ select HWMON_VID
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Supported are all known variants of
+ the Zhaoxin processors.
+
config SENSORS_VIA686A
tristate "VIA686A"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 9db2903b61e5..2427687972c9 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -184,6 +184,7 @@ obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TMP513) += tmp513.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
+obj-$(CONFIG_SENSORS_ZHAOXIN_CPUTEMP) += zhaoxin-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index e5d18dac8ee7..0a5057dbe51a 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -273,7 +273,6 @@ static const struct x86_cpu_id __initconst
cputemp_ids[] = {
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_A,
NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_C7_D,
NULL),
X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 6, X86_CENTAUR_FAM6_NANO,
NULL),
- X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
{}
};
MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
diff --git a/drivers/hwmon/zhaoxin-cputemp.c
b/drivers/hwmon/zhaoxin-cputemp.c
new file mode 100644
index 000000000000..dcedb51515f0
--- /dev/null
+++ b/drivers/hwmon/zhaoxin-cputemp.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * zhaoxin-cputemp.c - Driver for Zhaoxin CPU core temperature monitoring
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define DRVNAME "zhaoxin_cputemp"
+
+enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
+
+/* Functions declaration */
+
+struct zhaoxin_cputemp_data {
+ struct device *hwmon_dev;
+ const char *name;
+ u8 vrm;
+ u32 id;
+ u32 msr_temp;
+ u32 msr_vid;
+};
+
+/* Sysfs stuff */
+
+static ssize_t name_show(struct device *dev, struct device_attribute
*devattr,
+ char *buf)
+{
+ int ret;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+
+ if (attr->index == SHOW_NAME)
+ ret = sprintf(buf, "%s\n", data->name);
+ else /* show label */
+ ret = sprintf(buf, "Core %d\n", data->id);
+ return ret;
+}
+
+static ssize_t temp_show(struct device *dev, struct device_attribute
*devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
+}
+
+static ssize_t cpu0_vid_show(struct device *dev, struct
device_attribute *devattr, char *buf)
+{
+ struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev);
+ u32 eax, edx;
+ int err;
+
+ err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
+ if (err)
+ return -EAGAIN;
+
+ return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
+}
+
+static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, SHOW_TEMP);
+static SENSOR_DEVICE_ATTR_RO(temp1_label, name, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR_RO(name, name, SHOW_NAME);
+
+static struct attribute *zhaoxin_cputemp_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group zhaoxin_cputemp_group = {
+ .attrs = zhaoxin_cputemp_attributes,
+};
+
+/* Optional attributes */
+static DEVICE_ATTR_RO(cpu0_vid);
+
+static int zhaoxin_cputemp_probe(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data;
+ int err;
+ u32 eax, edx;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(struct
zhaoxin_cputemp_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->id = pdev->id;
+ data->name = "zhaoxin_cputemp";
+ data->msr_temp = 0x1423;
+
+ /* test if we can access the TEMPERATURE MSR */
+ err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to access TEMPERATURE MSR, giving
up\n");
+ return err;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ err = sysfs_create_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ if (err)
+ return err;
+
+ if (data->msr_vid)
+ data->vrm = vid_which_vrm();
+
+ if (data->vrm) {
+ err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_remove;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return err;
+}
+
+static int zhaoxin_cputemp_remove(struct platform_device *pdev)
+{
+ struct zhaoxin_cputemp_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ if (data->vrm)
+ device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
+ sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group);
+ return 0;
+}
+
+static struct platform_driver zhaoxin_cputemp_driver = {
+ .driver = {
+ .name = DRVNAME,
+ },
+ .probe = zhaoxin_cputemp_probe,
+ .remove = zhaoxin_cputemp_remove,
+};
+
+struct pdev_entry {
+ struct list_head list;
+ struct platform_device *pdev;
+ unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int zhaoxin_cputemp_online(unsigned int cpu)
+{
+ int err;
+ struct platform_device *pdev;
+ struct pdev_entry *pdev_entry;
+
+ pdev = platform_device_alloc(DRVNAME, cpu);
+ if (!pdev) {
+ err = -ENOMEM;
+ pr_err("Device allocation failed\n");
+ goto exit;
+ }
+
+ pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+ if (!pdev_entry) {
+ err = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ pr_err("Device addition failed (%d)\n", err);
+ goto exit_device_free;
+ }
+
+ pdev_entry->pdev = pdev;
+ pdev_entry->cpu = cpu;
+ mutex_lock(&pdev_list_mutex);
+ list_add_tail(&pdev_entry->list, &pdev_list);
+ mutex_unlock(&pdev_list_mutex);
+
+ return 0;
+
+exit_device_free:
+ kfree(pdev_entry);
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+static int zhaoxin_cputemp_down_prep(unsigned int cpu)
+{
+ struct pdev_entry *p;
+
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry(p, &pdev_list, list) {
+ if (p->cpu == cpu) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ mutex_unlock(&pdev_list_mutex);
+ kfree(p);
+ return 0;
+ }
+ }
+ mutex_unlock(&pdev_list_mutex);
+ return 0;
+}
+
+static const struct x86_cpu_id __initconst cputemp_ids[] = {
+ X86_MATCH_VENDOR_FAM_MODEL(CENTAUR, 7, X86_MODEL_ANY, NULL),
+ X86_MATCH_VENDOR_FAM_MODEL(ZHAOXIN, 7, X86_MODEL_ANY, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
+
+static enum cpuhp_state zhaoxin_temp_online;
+
+static int __init zhaoxin_cputemp_init(void)
+{
+ int err;
+
+ if (!x86_match_cpu(cputemp_ids))
+ return -ENODEV;
+
+ err = platform_driver_register(&zhaoxin_cputemp_driver);
+ if (err)
+ goto exit;
+
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/zhaoxin:online",
+ zhaoxin_cputemp_online, zhaoxin_cputemp_down_prep);
+ if (err < 0)
+ goto exit_driver_unreg;
+ zhaoxin_temp_online = err;
+
+#ifndef CONFIG_HOTPLUG_CPU
+ if (list_empty(&pdev_list)) {
+ err = -ENODEV;
+ goto exit_hp_unreg;
+ }
+#endif
+ return 0;
+
+#ifndef CONFIG_HOTPLUG_CPU
+exit_hp_unreg:
+ cpuhp_remove_state_nocalls(zhaoxin_temp_online);
+#endif
+exit_driver_unreg:
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+exit:
+ return err;
+}
+
+static void __exit zhaoxin_cputemp_exit(void)
+{
+ cpuhp_remove_state(zhaoxin_temp_online);
+ platform_driver_unregister(&zhaoxin_cputemp_driver);
+}
+
+MODULE_DESCRIPTION("Zhaoxin CPU temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(zhaoxin_cputemp_init)
+module_exit(zhaoxin_cputemp_exit)
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS 01/62] PM: wakeup: simplify the output logic of pm_show_wakelocks()
by Laibin Qiu 12 Apr '22
by Laibin Qiu 12 Apr '22
12 Apr '22
From: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
stable inclusion
from linux-4.19.228
commit cf94a8a3ff3d7aa06742f1beb5166fa45ba72122
--------------------------------
commit c9d967b2ce40d71e968eb839f36c936b8a9cf1ea upstream.
The buffer handling in pm_show_wakelocks() is tricky, and hopefully
correct. Ensure it really is correct by using sysfs_emit_at() which
handles all of the tricky string handling logic in a PAGE_SIZE buffer
for us automatically as this is a sysfs file being read from.
Reviewed-by: Lee Jones <lee.jones(a)linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
kernel/power/wakelock.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
index 4210152e56f0..aad7c8fcb22f 100644
--- a/kernel/power/wakelock.c
+++ b/kernel/power/wakelock.c
@@ -39,23 +39,19 @@ ssize_t pm_show_wakelocks(char *buf, bool show_active)
{
struct rb_node *node;
struct wakelock *wl;
- char *str = buf;
- char *end = buf + PAGE_SIZE;
+ int len = 0;
mutex_lock(&wakelocks_lock);
for (node = rb_first(&wakelocks_tree); node; node = rb_next(node)) {
wl = rb_entry(node, struct wakelock, node);
if (wl->ws.active == show_active)
- str += scnprintf(str, end - str, "%s ", wl->name);
+ len += sysfs_emit_at(buf, len, "%s ", wl->name);
}
- if (str > buf)
- str--;
-
- str += scnprintf(str, end - str, "\n");
+ len += sysfs_emit_at(buf, len, "\n");
mutex_unlock(&wakelocks_lock);
- return (str - buf);
+ return len;
}
#if CONFIG_PM_WAKELOCKS_LIMIT > 0
--
2.22.0
1
61

[PATCH OLK-5.10] xhci: Fix a logic issue when display Zhaoxin XHCI root hub speed
by LeoLiuoc 11 Apr '22
by LeoLiuoc 11 Apr '22
11 Apr '22
Fix a logic issue when display Zhaoxin XHCI root hub speed.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/usb/host/xhci.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7f1e5296d0f6..71dcc1ba73ac 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5261,10 +5261,10 @@ int xhci_gen_setup(struct usb_hcd *hcd,
xhci_get_quirks_t get_quirks)
if (XHCI_EXT_PORT_PSIV(xhci->port_caps[j].psi[i])
>= 5)
minor_rev = 1;
}
- if (minor_rev != 1) {
- hcd->speed = HCD_USB3;
- hcd->self.root_hub->speed = USB_SPEED_SUPER;
- }
+ }
+ if (minor_rev != 1) {
+ hcd->speed = HCD_USB3;
+ hcd->self.root_hub->speed = USB_SPEED_SUPER;
}
}
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS 1/3] printk: Convert a use of sprintf to snprintf in console_unlock
by Laibin Qiu 11 Apr '22
by Laibin Qiu 11 Apr '22
11 Apr '22
From: Nathan Chancellor <natechancellor(a)gmail.com>
mainline inclusion
from mainline-v5.8-rc1
commit 5661dd95a2958634485bb1a53f90a6ab621d4b0c
category: bugfix
bugzilla: 91291
CVE: N/A
--------------------------------
When CONFIG_PRINTK is disabled (e.g. when building allnoconfig), clang
warns:
../kernel/printk/printk.c:2416:10: warning: 'sprintf' will always
overflow; destination buffer has size 0, but format string expands to at
least 33 [-Wfortify-source]
len = sprintf(text,
^
1 warning generated.
It is not wrong; text has a zero size when CONFIG_PRINTK is disabled
because LOG_LINE_MAX and PREFIX_MAX are both zero. Change to snprintf so
that this case is explicitly handled without any risk of overflow.
Link: https://github.com/ClangBuiltLinux/linux/issues/846
Link: https://github.com/llvm/llvm-project/commit/6d485ff455ea2b37fef9e06e426dae6…
Link: http://lkml.kernel.org/r/20200130221644.2273-1-natechancellor@gmail.com
Cc: Steven Rostedt <rostedt(a)goodmis.org>
Cc: linux-kernel(a)vger.kernel.org
Cc: clang-built-linux(a)googlegroups.com
Signed-off-by: Nathan Chancellor <natechancellor(a)gmail.com>
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky(a)gmail.com>
Signed-off-by: Petr Mladek <pmladek(a)suse.com>
Signed-off-by: Yi Yang <yiyang13(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
kernel/printk/printk.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0fe45941b5c7..c645a7221d0b 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2423,9 +2423,9 @@ void console_unlock(void)
printk_safe_enter_irqsave(flags);
raw_spin_lock(&logbuf_lock);
if (console_seq < log_first_seq) {
- len = sprintf(text,
- "** %llu printk messages dropped **\n",
- log_first_seq - console_seq);
+ len = snprintf(text, sizeof(text),
+ "** %llu printk messages dropped **\n",
+ log_first_seq - console_seq);
/* messages are gone, move to first one */
console_seq = log_first_seq;
--
2.22.0
1
2
Fix CWE-404 bug: Leak of memory or pointers to system resoources
3
3

[PATCH openEuler-5.10 01/28] mm: share_pool: adjust sp_make_share_k2u behavior when coredump
by Zheng Zengkai 07 Apr '22
by Zheng Zengkai 07 Apr '22
07 Apr '22
From: Guo Mengqi <guomengqi3(a)huawei.com>
ascend inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4MUV2
CVE: NA
when k2u is being executed ont the whole sharepool group,
and one process coredumps, k2u will skip the coredumped process and
continue on the rest processes in the group.
Signed-off-by: Guo Mengqi <guomengqi3(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
mm/share_pool.c | 50 +++++++++++++++++++++++++++++++------------------
1 file changed, 32 insertions(+), 18 deletions(-)
diff --git a/mm/share_pool.c b/mm/share_pool.c
index 494a829d6f3a..f18bcd188027 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -666,8 +666,25 @@ static unsigned long sp_mmap(struct mm_struct *mm, struct file *file,
struct sp_area *spa, unsigned long *populate,
unsigned long prot);
static void sp_munmap(struct mm_struct *mm, unsigned long addr, unsigned long size);
+
+#define K2U_NORMAL 0
+#define K2U_COREDUMP 1
+
+struct sp_k2u_context {
+ unsigned long kva;
+ unsigned long kva_aligned;
+ unsigned long size;
+ unsigned long size_aligned;
+ unsigned long sp_flags;
+ int state;
+ int spg_id;
+ bool to_task;
+ struct timespec64 start;
+ struct timespec64 end;
+};
+
static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa,
- struct mm_struct *mm, unsigned long prot);
+ struct mm_struct *mm, unsigned long prot, struct sp_k2u_context *kc);
static void free_sp_group_id(int spg_id)
{
@@ -1313,7 +1330,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
spin_unlock(&sp_area_lock);
if (spa->type == SPA_TYPE_K2SPG && spa->kva) {
- addr = sp_remap_kva_to_vma(spa->kva, spa, mm, prot);
+ addr = sp_remap_kva_to_vma(spa->kva, spa, mm, prot, NULL);
if (IS_ERR_VALUE(addr))
pr_warn("add group remap k2u failed %ld\n", addr);
@@ -2586,7 +2603,7 @@ static unsigned long __sp_remap_get_pfn(unsigned long kva)
/* when called by k2u to group, always make sure rw_lock of spg is down */
static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa,
- struct mm_struct *mm, unsigned long prot)
+ struct mm_struct *mm, unsigned long prot, struct sp_k2u_context *kc)
{
struct vm_area_struct *vma;
unsigned long ret_addr;
@@ -2598,6 +2615,8 @@ static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa,
if (unlikely(mm->core_state)) {
pr_err("k2u mmap: encountered coredump, abort\n");
ret_addr = -EBUSY;
+ if (kc)
+ kc->state = K2U_COREDUMP;
goto put_mm;
}
@@ -2683,7 +2702,7 @@ static void *sp_make_share_kva_to_task(unsigned long kva, unsigned long size, un
spa->kva = kva;
- uva = (void *)sp_remap_kva_to_vma(kva, spa, current->mm, prot);
+ uva = (void *)sp_remap_kva_to_vma(kva, spa, current->mm, prot, NULL);
__sp_area_drop(spa);
if (IS_ERR(uva))
pr_err("remap k2u to task failed %ld\n", PTR_ERR(uva));
@@ -2711,6 +2730,8 @@ static void *sp_make_share_kva_to_spg(unsigned long kva, unsigned long size,
struct mm_struct *mm;
struct sp_group_node *spg_node;
void *uva = ERR_PTR(-ENODEV);
+ struct sp_k2u_context kc;
+ unsigned long ret_addr = -ENODEV;
down_read(&spg->rw_lock);
spa = sp_alloc_area(size, sp_flags, spg, SPA_TYPE_K2SPG, current->tgid);
@@ -2725,12 +2746,17 @@ static void *sp_make_share_kva_to_spg(unsigned long kva, unsigned long size,
list_for_each_entry(spg_node, &spg->procs, proc_node) {
mm = spg_node->master->mm;
- uva = (void *)sp_remap_kva_to_vma(kva, spa, mm, spg_node->prot);
- if (IS_ERR(uva)) {
+ kc.state = K2U_NORMAL;
+ ret_addr = sp_remap_kva_to_vma(kva, spa, mm, spg_node->prot, &kc);
+ if (IS_ERR_VALUE(ret_addr)) {
+ if (kc.state == K2U_COREDUMP)
+ continue;
+ uva = (void *)ret_addr;
pr_err("remap k2u to spg failed %ld\n", PTR_ERR(uva));
__sp_free(spg, spa->va_start, spa_size(spa), mm);
goto out;
}
+ uva = (void *)ret_addr;
}
out:
@@ -2755,18 +2781,6 @@ static bool vmalloc_area_set_flag(unsigned long kva, unsigned long flags)
return false;
}
-struct sp_k2u_context {
- unsigned long kva;
- unsigned long kva_aligned;
- unsigned long size;
- unsigned long size_aligned;
- unsigned long sp_flags;
- int spg_id;
- bool to_task;
- struct timespec64 start;
- struct timespec64 end;
-};
-
static void trace_sp_k2u_begin(struct sp_k2u_context *kc)
{
if (!sysctl_sp_perf_k2u)
--
2.20.1
1
27
大家好,openEuler开发者大会Kernel SIG工作会议将在4月14日下午进行。诚邀大家参加,并在此征集议题。议题内容不限于需求讨论、社区治理,问题反馈等。
如有议题申报请在如下链接填写:
https://etherpad.openeuler.org/p/sig-kernel-22.09-planning
谢谢大家的支持。
1
0
From: Yi Li <yili(a)winhong.com>
Some distributions are about to switch to Python 3 support only.
This means that /usr/bin/python, which is Python 2, is not available
anymore. Hence, switch scripts to use Python 3 explicitly.
*** ERROR: ambiguous python shebang in ***/power/pm-graph/sleepgraph.py:
#!/usr/bin/python. Change it to python3 (or python2) explicitly.
*** ERROR: ambiguous python shebang in ***/power/pm-graph/bootgraph.py:
#!/usr/bin/python. Change it to python3 (or python2) explicitly.
*** ERROR: ambiguous python shebang in ***/intel_pstate_tracer.py:
#!/usr/bin/env python. Change it to python3 (or python2) explicitly.
use sed command fix all python files.
Signed-off-by: Yi Li <yili(a)winhong.com>
---
Documentation/networking/device_drivers/atm/cxacru-cf.py | 2 +-
Documentation/sphinx/maintainers_include.py | 2 +-
Documentation/target/tcm_mod_builder.py | 2 +-
Documentation/trace/postprocess/decode_msr.py | 2 +-
arch/ia64/scripts/unwcheck.py | 2 +-
drivers/staging/greybus/tools/lbtest | 2 +-
scripts/jobserver-exec | 2 +-
scripts/show_delta | 2 +-
scripts/spdxcheck.py | 2 +-
scripts/tracing/draw_functrace.py | 2 +-
tools/hv/lsvmbus | 2 +-
tools/perf/python/tracepoint.py | 2 +-
tools/perf/python/twatch.py | 2 +-
tools/perf/scripts/python/exported-sql-viewer.py | 2 +-
tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py | 2 +-
.../selftests/drivers/net/mlxsw/sharedbuffer_configuration.py | 2 +-
16 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/Documentation/networking/device_drivers/atm/cxacru-cf.py b/Documentation/networking/device_drivers/atm/cxacru-cf.py
index b41d298398c8..1b960fb45982 100644
--- a/Documentation/networking/device_drivers/atm/cxacru-cf.py
+++ b/Documentation/networking/device_drivers/atm/cxacru-cf.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright 2009 Simon Arlott
#
# This program is free software; you can redistribute it and/or modify it
diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py
index dc8fed48d3c2..5b7cb116886b 100755
--- a/Documentation/sphinx/maintainers_include.py
+++ b/Documentation/sphinx/maintainers_include.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# -*- coding: utf-8; mode: python -*-
# pylint: disable=R0903, C0330, R0914, R0912, E0401
diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py
index 54492aa813b9..92b740465e73 100755
--- a/Documentation/target/tcm_mod_builder.py
+++ b/Documentation/target/tcm_mod_builder.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD
#
# Copyright (c) 2010 Rising Tide Systems
diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py
index aa9cc7abd5c2..009122b700a6 100644
--- a/Documentation/trace/postprocess/decode_msr.py
+++ b/Documentation/trace/postprocess/decode_msr.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# add symbolic names to read_msr / write_msr in trace
# decode_msr msr-index.h < trace
import sys
diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py
index bfd1b671e35f..9581742f0db2 100644
--- a/arch/ia64/scripts/unwcheck.py
+++ b/arch/ia64/scripts/unwcheck.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
#
# Usage: unwcheck.py FILE
diff --git a/drivers/staging/greybus/tools/lbtest b/drivers/staging/greybus/tools/lbtest
index 47c481239e98..4e6fcfbd815a 100755
--- a/drivers/staging/greybus/tools/lbtest
+++ b/drivers/staging/greybus/tools/lbtest
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2015 Google, Inc.
diff --git a/scripts/jobserver-exec b/scripts/jobserver-exec
index 0fdb31a790a8..48d141e3ec56 100755
--- a/scripts/jobserver-exec
+++ b/scripts/jobserver-exec
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0+
#
# This determines how many parallel tasks "make" is expecting, as it is
diff --git a/scripts/show_delta b/scripts/show_delta
index 28e67e178194..4660a988b2ad 100755
--- a/scripts/show_delta
+++ b/scripts/show_delta
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
#
# show_deltas: Read list of printk messages instrumented with
diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py
index bc87200f9c7c..cbdb5c83c08f 100755
--- a/scripts/spdxcheck.py
+++ b/scripts/spdxcheck.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# Copyright Thomas Gleixner <tglx(a)linutronix.de>
diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py
index 7011fbe003ff..025a5c8106a6 100755
--- a/scripts/tracing/draw_functrace.py
+++ b/scripts/tracing/draw_functrace.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
"""
diff --git a/tools/hv/lsvmbus b/tools/hv/lsvmbus
index 099f2c44dbed..f83698f14da2 100644
--- a/tools/hv/lsvmbus
+++ b/tools/hv/lsvmbus
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
import os
diff --git a/tools/perf/python/tracepoint.py b/tools/perf/python/tracepoint.py
index 461848c7f57d..640c740f460a 100755
--- a/tools/perf/python/tracepoint.py
+++ b/tools/perf/python/tracepoint.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# -*- python -*-
# -*- coding: utf-8 -*-
diff --git a/tools/perf/python/twatch.py b/tools/perf/python/twatch.py
index 04f3db29b9bc..56ed003a1d97 100755
--- a/tools/perf/python/twatch.py
+++ b/tools/perf/python/twatch.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
# -*- python -*-
# -*- coding: utf-8 -*-
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index 711d4f9f5645..2768fc8f6141 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# exported-sql-viewer.py: view data from sql database
# Copyright (c) 2014-2018, Intel Corporation.
diff --git a/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py b/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
index e15e20696d17..a14953f61e5d 100755
--- a/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
+++ b/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
# -*- coding: utf-8 -*-
#
diff --git a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py
index 2223337eed0c..bdacd8eb00f3 100755
--- a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py
+++ b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer_configuration.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
import subprocess
--
2.25.3
3
4

[PATCH openEuler-1.0-LTS] serial: 8250: Fix max baud limit in generic 8250 port
by Laibin Qiu 02 Apr '22
by Laibin Qiu 02 Apr '22
02 Apr '22
From: Serge Semin <Sergey.Semin(a)baikalelectronics.ru>
stable inclusion
from linux-4.19.130
commit 0eeaf62981ecc79e8395ca8caa1570eaf3a12257
category: bugfix
bugzilla: 89545
CVE: N/A
------------------------------------------------
[ Upstream commit 7b668c064ec33f3d687c3a413d05e355172e6c92 ]
Standard 8250 UART ports are designed in a way so they can communicate
with baud rates up to 1/16 of a reference frequency. It's expected from
most of the currently supported UART controllers. That's why the former
version of serial8250_get_baud_rate() method called uart_get_baud_rate()
with min and max baud rates passed as (port->uartclk / 16 / UART_DIV_MAX)
and ((port->uartclk + tolerance) / 16) respectively. Doing otherwise, like
it was suggested in commit ("serial: 8250_mtk: support big baud rate."),
caused acceptance of bauds, which was higher than the normal UART
controllers actually supported. As a result if some user-space program
requested to set a baud greater than (uartclk / 16) it would have been
permitted without truncation, but then serial8250_get_divisor(baud)
(which calls uart_get_divisor() to get the reference clock divisor) would
have returned a zero divisor. Setting zero divisor will cause an
unpredictable effect varying from chip to chip. In case of DW APB UART the
communications just stop.
Lets fix this problem by getting back the limitation of (uartclk +
tolerance) / 16 maximum baud supported by the generic 8250 port. Mediatek
8250 UART ports driver developer shouldn't have touched it in the first
place notably seeing he already provided a custom version of set_termios()
callback in that glue-driver which took into account the extended baud
rate values and accordingly updated the standard and vendor-specific
divisor latch registers anyway.
Fixes: 81bb549fdf14 ("serial: 8250_mtk: support big baud rate.")
Signed-off-by: Serge Semin <Sergey.Semin(a)baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov(a)baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend(a)alpha.franken.de>
Cc: Paul Burton <paulburton(a)kernel.org>
Cc: Ralf Baechle <ralf(a)linux-mips.org>
Cc: Arnd Bergmann <arnd(a)arndb.de>
Cc: Long Cheng <long.cheng(a)mediatek.com>
Cc: Andy Shevchenko <andriy.shevchenko(a)linux.intel.com>
Cc: Maxime Ripard <mripard(a)kernel.org>
Cc: Catalin Marinas <catalin.marinas(a)arm.com>
Cc: Will Deacon <will(a)kernel.org>
Cc: Russell King <linux(a)armlinux.org.uk>
Cc: linux-mips(a)vger.kernel.org
Cc: linux-arm-kernel(a)lists.infradead.org
Cc: linux-mediatek(a)lists.infradead.org
Link: https://lore.kernel.org/r/20200506233136.11842-2-Sergey.Semin@baikalelectro…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yi Yang <yiyang13(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
drivers/tty/serial/8250/8250_port.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 1867c2546cd9..3a0604b025e9 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2647,6 +2647,8 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port,
struct ktermios *termios,
struct ktermios *old)
{
+ unsigned int tolerance = port->uartclk / 100;
+
/*
* Ask the core to calculate the divisor for us.
* Allow 1% tolerance at the upper limit so uart clks marginally
@@ -2655,7 +2657,7 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port,
*/
return uart_get_baud_rate(port, termios, old,
port->uartclk / 16 / UART_DIV_MAX,
- port->uartclk);
+ (port->uartclk + tolerance) / 16);
}
void
--
2.22.0
1
0
Hi all:
Who can help figure out why makecache failed?
[root@localhost yum.repos.d]# yum makecache
OS 3.3 kB/s | 217 B 00:00
Error: Failed to download metadata for repo 'OS': repomd.xml parser error: Parse error at line: 3 (Couldn't find end of Start Tag meta
cat openEuler.repo
# http://license.coscl.org.cn/MulanPSL2
#THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
#PURPOSE.
#See the Mulan PSL v2 for more details.
[OS]
name=OS
baseurl=http://121.36.97.194/openEuler-20.03-LTS-SP3/OS/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://121.36.97.194/openEuler-20.03-LTS-SP3/OS/$basearch/RPM-GPG-KEY-openEuler
3
3
openEuler开发者大会议题征集,官方截止时间为3月30号上午9:00。如有议题想要在大会分享的,请进入如下链接填写,谢谢:
https://shimo.im/forms/7DO3Fg79JSAfaflt/fill
1
0
From: Yun Xu <xuyun(a)ramaxel.com>
Ramaxel inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4ZR0O
CVE: NA
------------------------------------
There are some issues of the driver that cannot be fixed now.
The driver is not good enough for the LTS quality requirements of
openEuler,so remove it.
Signed-off-by: Yun Xu <xuyun(a)ramaxel.com>
Signed-off-by: Yanling Song <songyl(a)ramaxel.com>
Reviewed-by: Yun Xu <xuyun(a)ramaxel.com>
Acked-by: Xie Xiuqi <xiexiuqi(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
arch/arm64/configs/openeuler_defconfig | 1 -
arch/x86/configs/openeuler_defconfig | 1 -
drivers/scsi/Kconfig | 1 -
drivers/scsi/Makefile | 1 -
drivers/scsi/spfc/Kconfig | 16 -
drivers/scsi/spfc/Makefile | 47 -
drivers/scsi/spfc/common/unf_common.h | 1753 -------
drivers/scsi/spfc/common/unf_disc.c | 1276 -----
drivers/scsi/spfc/common/unf_disc.h | 51 -
drivers/scsi/spfc/common/unf_event.c | 517 --
drivers/scsi/spfc/common/unf_event.h | 83 -
drivers/scsi/spfc/common/unf_exchg.c | 2317 ---------
drivers/scsi/spfc/common/unf_exchg.h | 436 --
drivers/scsi/spfc/common/unf_exchg_abort.c | 825 ---
drivers/scsi/spfc/common/unf_exchg_abort.h | 23 -
drivers/scsi/spfc/common/unf_fcstruct.h | 459 --
drivers/scsi/spfc/common/unf_gs.c | 2521 ---------
drivers/scsi/spfc/common/unf_gs.h | 58 -
drivers/scsi/spfc/common/unf_init.c | 353 --
drivers/scsi/spfc/common/unf_io.c | 1219 -----
drivers/scsi/spfc/common/unf_io.h | 96 -
drivers/scsi/spfc/common/unf_io_abnormal.c | 986 ----
drivers/scsi/spfc/common/unf_io_abnormal.h | 19 -
drivers/scsi/spfc/common/unf_log.h | 178 -
drivers/scsi/spfc/common/unf_lport.c | 1008 ----
drivers/scsi/spfc/common/unf_lport.h | 519 --
drivers/scsi/spfc/common/unf_ls.c | 4883 ------------------
drivers/scsi/spfc/common/unf_ls.h | 61 -
drivers/scsi/spfc/common/unf_npiv.c | 1005 ----
drivers/scsi/spfc/common/unf_npiv.h | 47 -
drivers/scsi/spfc/common/unf_npiv_portman.c | 360 --
drivers/scsi/spfc/common/unf_npiv_portman.h | 17 -
drivers/scsi/spfc/common/unf_portman.c | 2431 ---------
drivers/scsi/spfc/common/unf_portman.h | 96 -
drivers/scsi/spfc/common/unf_rport.c | 2286 --------
drivers/scsi/spfc/common/unf_rport.h | 301 --
drivers/scsi/spfc/common/unf_scsi.c | 1462 ------
drivers/scsi/spfc/common/unf_scsi_common.h | 570 --
drivers/scsi/spfc/common/unf_service.c | 1430 -----
drivers/scsi/spfc/common/unf_service.h | 66 -
drivers/scsi/spfc/common/unf_type.h | 216 -
drivers/scsi/spfc/hw/spfc_chipitf.c | 1105 ----
drivers/scsi/spfc/hw/spfc_chipitf.h | 797 ---
drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c | 1611 ------
drivers/scsi/spfc/hw/spfc_cqm_bat_cla.h | 215 -
drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c | 885 ----
drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.h | 65 -
drivers/scsi/spfc/hw/spfc_cqm_main.c | 987 ----
drivers/scsi/spfc/hw/spfc_cqm_main.h | 411 --
drivers/scsi/spfc/hw/spfc_cqm_object.c | 937 ----
drivers/scsi/spfc/hw/spfc_cqm_object.h | 279 -
drivers/scsi/spfc/hw/spfc_hba.c | 1751 -------
drivers/scsi/spfc/hw/spfc_hba.h | 341 --
drivers/scsi/spfc/hw/spfc_hw_wqe.h | 1645 ------
drivers/scsi/spfc/hw/spfc_io.c | 1193 -----
drivers/scsi/spfc/hw/spfc_io.h | 138 -
drivers/scsi/spfc/hw/spfc_lld.c | 997 ----
drivers/scsi/spfc/hw/spfc_lld.h | 76 -
drivers/scsi/spfc/hw/spfc_module.h | 297 --
drivers/scsi/spfc/hw/spfc_parent_context.h | 269 -
drivers/scsi/spfc/hw/spfc_queue.c | 4852 -----------------
drivers/scsi/spfc/hw/spfc_queue.h | 711 ---
drivers/scsi/spfc/hw/spfc_service.c | 2170 --------
drivers/scsi/spfc/hw/spfc_service.h | 282 -
drivers/scsi/spfc/hw/spfc_utils.c | 102 -
drivers/scsi/spfc/hw/spfc_utils.h | 202 -
drivers/scsi/spfc/hw/spfc_wqe.c | 646 ---
drivers/scsi/spfc/hw/spfc_wqe.h | 239 -
drivers/scsi/spfc/sphw_api_cmd.c | 1 -
drivers/scsi/spfc/sphw_cmdq.c | 1 -
drivers/scsi/spfc/sphw_common.c | 1 -
drivers/scsi/spfc/sphw_eqs.c | 1 -
drivers/scsi/spfc/sphw_hw_cfg.c | 1 -
drivers/scsi/spfc/sphw_hw_comm.c | 1 -
drivers/scsi/spfc/sphw_hwdev.c | 1 -
drivers/scsi/spfc/sphw_hwif.c | 1 -
drivers/scsi/spfc/sphw_mbox.c | 1 -
drivers/scsi/spfc/sphw_mgmt.c | 1 -
drivers/scsi/spfc/sphw_prof_adap.c | 1 -
drivers/scsi/spfc/sphw_wq.c | 1 -
80 files changed, 53210 deletions(-)
delete mode 100644 drivers/scsi/spfc/Kconfig
delete mode 100644 drivers/scsi/spfc/Makefile
delete mode 100644 drivers/scsi/spfc/common/unf_common.h
delete mode 100644 drivers/scsi/spfc/common/unf_disc.c
delete mode 100644 drivers/scsi/spfc/common/unf_disc.h
delete mode 100644 drivers/scsi/spfc/common/unf_event.c
delete mode 100644 drivers/scsi/spfc/common/unf_event.h
delete mode 100644 drivers/scsi/spfc/common/unf_exchg.c
delete mode 100644 drivers/scsi/spfc/common/unf_exchg.h
delete mode 100644 drivers/scsi/spfc/common/unf_exchg_abort.c
delete mode 100644 drivers/scsi/spfc/common/unf_exchg_abort.h
delete mode 100644 drivers/scsi/spfc/common/unf_fcstruct.h
delete mode 100644 drivers/scsi/spfc/common/unf_gs.c
delete mode 100644 drivers/scsi/spfc/common/unf_gs.h
delete mode 100644 drivers/scsi/spfc/common/unf_init.c
delete mode 100644 drivers/scsi/spfc/common/unf_io.c
delete mode 100644 drivers/scsi/spfc/common/unf_io.h
delete mode 100644 drivers/scsi/spfc/common/unf_io_abnormal.c
delete mode 100644 drivers/scsi/spfc/common/unf_io_abnormal.h
delete mode 100644 drivers/scsi/spfc/common/unf_log.h
delete mode 100644 drivers/scsi/spfc/common/unf_lport.c
delete mode 100644 drivers/scsi/spfc/common/unf_lport.h
delete mode 100644 drivers/scsi/spfc/common/unf_ls.c
delete mode 100644 drivers/scsi/spfc/common/unf_ls.h
delete mode 100644 drivers/scsi/spfc/common/unf_npiv.c
delete mode 100644 drivers/scsi/spfc/common/unf_npiv.h
delete mode 100644 drivers/scsi/spfc/common/unf_npiv_portman.c
delete mode 100644 drivers/scsi/spfc/common/unf_npiv_portman.h
delete mode 100644 drivers/scsi/spfc/common/unf_portman.c
delete mode 100644 drivers/scsi/spfc/common/unf_portman.h
delete mode 100644 drivers/scsi/spfc/common/unf_rport.c
delete mode 100644 drivers/scsi/spfc/common/unf_rport.h
delete mode 100644 drivers/scsi/spfc/common/unf_scsi.c
delete mode 100644 drivers/scsi/spfc/common/unf_scsi_common.h
delete mode 100644 drivers/scsi/spfc/common/unf_service.c
delete mode 100644 drivers/scsi/spfc/common/unf_service.h
delete mode 100644 drivers/scsi/spfc/common/unf_type.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_chipitf.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_chipitf.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bat_cla.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_main.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_main.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_object.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_object.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_hba.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_hba.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_hw_wqe.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_io.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_io.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_lld.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_lld.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_module.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_parent_context.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_queue.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_queue.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_service.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_service.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_utils.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_utils.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_wqe.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_wqe.h
delete mode 120000 drivers/scsi/spfc/sphw_api_cmd.c
delete mode 120000 drivers/scsi/spfc/sphw_cmdq.c
delete mode 120000 drivers/scsi/spfc/sphw_common.c
delete mode 120000 drivers/scsi/spfc/sphw_eqs.c
delete mode 120000 drivers/scsi/spfc/sphw_hw_cfg.c
delete mode 120000 drivers/scsi/spfc/sphw_hw_comm.c
delete mode 120000 drivers/scsi/spfc/sphw_hwdev.c
delete mode 120000 drivers/scsi/spfc/sphw_hwif.c
delete mode 120000 drivers/scsi/spfc/sphw_mbox.c
delete mode 120000 drivers/scsi/spfc/sphw_mgmt.c
delete mode 120000 drivers/scsi/spfc/sphw_prof_adap.c
delete mode 120000 drivers/scsi/spfc/sphw_wq.c
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index 401ab0f99631..1fd250cc103c 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -2403,7 +2403,6 @@ CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_QEDI=m
CONFIG_QEDF=m
-CONFIG_SPFC=m
CONFIG_SCSI_HUAWEI_FC=m
CONFIG_SCSI_FC_HIFC=m
CONFIG_SCSI_LPFC=m
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 64afe7021c45..cd9aaba18fa4 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -2367,7 +2367,6 @@ CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_QEDI=m
CONFIG_QEDF=m
-CONFIG_SPFC=m
CONFIG_SCSI_HUAWEI_FC=m
CONFIG_SCSI_FC_HIFC=m
CONFIG_SCSI_LPFC=m
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 170d59df48d1..0fbe4edeccd0 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1151,7 +1151,6 @@ source "drivers/scsi/qla2xxx/Kconfig"
source "drivers/scsi/qla4xxx/Kconfig"
source "drivers/scsi/qedi/Kconfig"
source "drivers/scsi/qedf/Kconfig"
-source "drivers/scsi/spfc/Kconfig"
source "drivers/scsi/huawei/Kconfig"
config SCSI_LPFC
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 299d3318fac8..78a3c832394c 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -85,7 +85,6 @@ obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o
obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
obj-$(CONFIG_SCSI_QLA_ISCSI) += libiscsi.o qla4xxx/
-obj-$(CONFIG_SPFC) += spfc/
obj-$(CONFIG_SCSI_LPFC) += lpfc/
obj-$(CONFIG_SCSI_HUAWEI_FC) += huawei/
obj-$(CONFIG_SCSI_BFA_FC) += bfa/
diff --git a/drivers/scsi/spfc/Kconfig b/drivers/scsi/spfc/Kconfig
deleted file mode 100644
index 9d4566d90809..000000000000
--- a/drivers/scsi/spfc/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Ramaxel SPFC driver configuration
-#
-
-config SPFC
- tristate "Ramaxel Fabric Channel Host Adapter Support"
- default m
- depends on PCI && SCSI
- depends on SCSI_FC_ATTRS
- depends on ARM64 || X86_64
- help
- This driver supports Ramaxel Fabric Channel PCIe host adapter.
- To compile this driver as part of the kernel, choose Y here.
- If unsure, choose N.
- The default is M.
diff --git a/drivers/scsi/spfc/Makefile b/drivers/scsi/spfc/Makefile
deleted file mode 100644
index 849b730ac733..000000000000
--- a/drivers/scsi/spfc/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_SPFC) += spfc.o
-
-subdir-ccflags-y += -I$(srctree)/$(src)/../../net/ethernet/ramaxel/spnic/hw
-subdir-ccflags-y += -I$(srctree)/$(src)/hw
-subdir-ccflags-y += -I$(srctree)/$(src)/common
-
-spfc-objs := common/unf_init.o \
- common/unf_event.o \
- common/unf_exchg.o \
- common/unf_exchg_abort.o \
- common/unf_io.o \
- common/unf_io_abnormal.o \
- common/unf_lport.o \
- common/unf_npiv.o \
- common/unf_npiv_portman.o \
- common/unf_disc.o \
- common/unf_rport.o \
- common/unf_service.o \
- common/unf_ls.o \
- common/unf_gs.o \
- common/unf_portman.o \
- common/unf_scsi.o \
- hw/spfc_utils.o \
- hw/spfc_lld.o \
- hw/spfc_io.o \
- hw/spfc_wqe.o \
- hw/spfc_service.o \
- hw/spfc_chipitf.o \
- hw/spfc_queue.o \
- hw/spfc_hba.o \
- hw/spfc_cqm_bat_cla.o \
- hw/spfc_cqm_bitmap_table.o \
- hw/spfc_cqm_main.o \
- hw/spfc_cqm_object.o \
- sphw_hwdev.o \
- sphw_hw_cfg.o \
- sphw_hw_comm.o \
- sphw_prof_adap.o \
- sphw_common.o \
- sphw_hwif.o \
- sphw_wq.o \
- sphw_cmdq.o \
- sphw_eqs.o \
- sphw_mbox.o \
- sphw_mgmt.o \
- sphw_api_cmd.o
diff --git a/drivers/scsi/spfc/common/unf_common.h b/drivers/scsi/spfc/common/unf_common.h
deleted file mode 100644
index 9613649308bf..000000000000
--- a/drivers/scsi/spfc/common/unf_common.h
+++ /dev/null
@@ -1,1753 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_COMMON_H
-#define UNF_COMMON_H
-
-#include "unf_type.h"
-#include "unf_fcstruct.h"
-
-/* version num */
-#define SPFC_DRV_VERSION "B101"
-#define SPFC_DRV_DESC "Ramaxel Memory Technology Fibre Channel Driver"
-
-#define UNF_MAX_SECTORS 0xffff
-#define UNF_PKG_FREE_OXID 0x0
-#define UNF_PKG_FREE_RXID 0x1
-
-#define UNF_SPFC_MAXRPORT_NUM (2048)
-#define SPFC_DEFAULT_RPORT_INDEX (UNF_SPFC_MAXRPORT_NUM - 1)
-
-/* session use sq num */
-#define UNF_SQ_NUM_PER_SESSION 3
-
-extern atomic_t fc_mem_ref;
-extern u32 unf_dgb_level;
-extern u32 spfc_dif_type;
-extern u32 spfc_dif_enable;
-extern u8 spfc_guard;
-extern int link_lose_tmo;
-
-/* define bits */
-#define UNF_BIT(n) (0x1UL << (n))
-#define UNF_BIT_0 UNF_BIT(0)
-#define UNF_BIT_1 UNF_BIT(1)
-#define UNF_BIT_2 UNF_BIT(2)
-#define UNF_BIT_3 UNF_BIT(3)
-#define UNF_BIT_4 UNF_BIT(4)
-#define UNF_BIT_5 UNF_BIT(5)
-
-#define UNF_BITS_PER_BYTE 8
-
-#define UNF_NOTIFY_UP_CLEAN_FLASH 2
-
-/* Echo macro define */
-#define ECHO_MG_VERSION_LOCAL 1
-#define ECHO_MG_VERSION_REMOTE 2
-
-#define SPFC_WIN_NPIV_NUM 32
-
-#define UNF_GET_NAME_HIGH_WORD(name) (((name) >> 32) & 0xffffffff)
-#define UNF_GET_NAME_LOW_WORD(name) ((name) & 0xffffffff)
-
-#define UNF_FIRST_LPORT_ID_MASK 0xffffff00
-#define UNF_PORT_ID_MASK 0x000000ff
-#define UNF_FIRST_LPORT_ID 0x00000000
-#define UNF_SECOND_LPORT_ID 0x00000001
-#define UNF_EIGHTH_LPORT_ID 0x00000007
-#define SPFC_MAX_COUNTER_TYPE 128
-
-#define UNF_EVENT_ASYN 0
-#define UNF_EVENT_SYN 1
-#define UNF_GLOBAL_EVENT_ASYN 2
-#define UNF_GLOBAL_EVENT_SYN 3
-
-#define UNF_GET_SLOT_ID_BY_PORTID(port_id) (((port_id) & 0x001f00) >> 8)
-#define UNF_GET_FUNC_ID_BY_PORTID(port_id) ((port_id) & 0x0000ff)
-#define UNF_GET_BOARD_TYPE_AND_SLOT_ID_BY_PORTID(port_id) \
- (((port_id) & 0x00FF00) >> 8)
-
-#define UNF_FC_SERVER_BOARD_8_G 13 /* 8G mode */
-#define UNF_FC_SERVER_BOARD_16_G 7 /* 16G mode */
-#define UNF_FC_SERVER_BOARD_32_G 6 /* 32G mode */
-
-#define UNF_PORT_TYPE_FC_QSFP 1
-#define UNF_PORT_TYPE_FC_SFP 0
-#define UNF_PORT_UNGRADE_FW_RESET_ACTIVE 0
-#define UNF_PORT_UNGRADE_FW_RESET_INACTIVE 1
-
-enum unf_rport_qos_level {
- UNF_QOS_LEVEL_DEFAULT = 0,
- UNF_QOS_LEVEL_MIDDLE,
- UNF_QOS_LEVEL_HIGH,
- UNF_QOS_LEVEL_BUTT
-};
-
-struct buff_list {
- u8 *vaddr;
- dma_addr_t paddr;
-};
-
-struct buf_describe {
- struct buff_list *buflist;
- u32 buf_size;
- u32 buf_num;
-};
-
-#define IO_STATICS
-struct unf_port_info {
- u32 local_nport_id;
- u32 nport_id;
- u32 rport_index;
- u64 port_name;
- enum unf_rport_qos_level qos_level;
- u8 cs_ctrl;
- u8 rsvd0[3];
- u32 sqn_base;
-};
-
-struct unf_cfg_item {
- char *puc_name;
- u32 min_value;
- u32 default_value;
- u32 max_value;
-};
-
-struct unf_port_param {
- u32 ra_tov;
- u32 ed_tov;
-};
-
-/* get wwpn adn wwnn */
-struct unf_get_chip_info_argout {
- u8 board_type;
- u64 wwpn;
- u64 wwnn;
- u64 sys_mac;
-};
-
-/* get sfp info: present and speed */
-struct unf_get_port_info_argout {
- u8 sfp_speed;
- u8 present;
- u8 rsvd[2];
-};
-
-/* SFF-8436(QSFP+) Rev 4.7 */
-struct unf_sfp_plus_field_a0 {
- u8 identifier;
- /* offset 1~2 */
- struct {
- u8 reserved;
- u8 status;
- } status_indicator;
- /* offset 3~21 */
- struct {
- u8 rx_tx_los;
- u8 tx_fault;
- u8 all_resv;
-
- u8 ini_complete : 1;
- u8 bit_resv : 3;
- u8 temp_low_warn : 1;
- u8 temp_high_warn : 1;
- u8 temp_low_alarm : 1;
- u8 temp_high_alarm : 1;
-
- u8 resv : 4;
- u8 vcc_low_warn : 1;
- u8 vcc_high_warn : 1;
- u8 vcc_low_alarm : 1;
- u8 vcc_high_alarm : 1;
-
- u8 resv8;
- u8 rx_pow[2];
- u8 tx_bias[2];
- u8 reserved[6];
- u8 vendor_specifics[3];
- } interrupt_flag;
- /* offset 22~33 */
- struct {
- u8 temp[2];
- u8 reserved[2];
- u8 supply_vol[2];
- u8 reserveds[2];
- u8 vendor_specific[4];
- } module_monitors;
- /* offset 34~81 */
- struct {
- u8 rx_pow[8];
- u8 tx_bias[8];
- u8 reserved[16];
- u8 vendor_specific[16];
- } channel_monitor_val;
-
- /* offset 82~85 */
- u8 reserved[4];
-
- /* offset 86~97 */
- struct {
- /* 86~88 */
- u8 tx_disable;
- u8 rx_rate_select;
- u8 tx_rate_select;
-
- /* 89~92 */
- u8 rx4_app_select;
- u8 rx3_app_select;
- u8 rx2_app_select;
- u8 rx1_app_select;
- /* 93 */
- u8 power_override : 1;
- u8 power_set : 1;
- u8 reserved : 6;
-
- /* 94~97 */
- u8 tx4_app_select;
- u8 tx3_app_select;
- u8 tx2_app_select;
- u8 tx1_app_select;
- /* 98~99 */
- u8 reserved2[2];
- } control;
- /* 100~106 */
- struct {
- /* 100 */
- u8 m_rx1_los : 1;
- u8 m_rx2_los : 1;
- u8 m_rx3_los : 1;
- u8 m_rx4_los : 1;
- u8 m_tx1_los : 1;
- u8 m_tx2_los : 1;
- u8 m_tx3_los : 1;
- u8 m_tx4_los : 1;
- /* 101 */
- u8 m_tx1_fault : 1;
- u8 m_tx2_fault : 1;
- u8 m_tx3_fault : 1;
- u8 m_tx4_fault : 1;
- u8 reserved : 4;
- /* 102 */
- u8 reserved1;
- /* 103 */
- u8 mini_cmp_flag : 1;
- u8 rsv : 3;
- u8 m_temp_low_warn : 1;
- u8 m_temp_high_warn : 1;
- u8 m_temp_low_alarm : 1;
- u8 m_temp_high_alarm : 1;
- /* 104 */
- u8 rsv1 : 4;
- u8 m_vcc_low_warn : 1;
- u8 m_vcc_high_warn : 1;
- u8 m_vcc_low_alarm : 1;
- u8 m_vcc_high_alarm : 1;
- /* 105~106 */
- u8 vendor_specific[2];
- } module_channel_mask_bit;
- /* 107~118 */
- u8 resv[12];
- /* 119~126 */
- u8 password_reserved[8];
- /* 127 */
- u8 page_select;
-};
-
-/* page 00 */
-struct unf_sfp_plus_field_00 {
- /* 128~191 */
- struct {
- u8 id;
- u8 id_ext;
- u8 connector;
- u8 speci_com[6];
- u8 mode;
- u8 speed;
- u8 encoding;
- u8 br_nominal;
- u8 ext_rate_select_com;
- u8 length_smf;
- u8 length_om3;
- u8 length_om2;
- u8 length_om1;
- u8 length_copper;
- u8 device_tech;
- u8 vendor_name[16];
- u8 ex_module;
- u8 vendor_oui[3];
- u8 vendor_pn[16];
- u8 vendor_rev[2];
- /* Wave length or Copper cable Attenuation*/
- u8 wave_or_copper_attenuation[2];
- u8 wave_length_toler[2]; /* Wavelength tolerance */
- u8 max_temp;
- u8 cc_base;
- } base_id_fields;
- /* 192~223 */
- struct {
- u8 options[4];
- u8 vendor_sn[16];
- u8 date_code[8];
- u8 diagn_monit_type;
- u8 enhance_opt;
- u8 reserved;
- u8 ccext;
- } ext_id_fields;
- /* 224~255 */
- u8 vendor_spec_eeprom[32];
-};
-
-/* page 01 */
-struct unf_sfp_plus_field_01 {
- u8 optional01[128];
-};
-
-/* page 02 */
-struct unf_sfp_plus_field_02 {
- u8 optional02[128];
-};
-
-/* page 03 */
-struct unf_sfp_plus_field_03 {
- u8 temp_high_alarm[2];
- u8 temp_low_alarm[2];
- u8 temp_high_warn[2];
- u8 temp_low_warn[2];
-
- u8 reserved1[8];
-
- u8 vcc_high_alarm[2];
- u8 vcc_low_alarm[2];
- u8 vcc_high_warn[2];
- u8 vcc_low_warn[2];
-
- u8 reserved2[8];
- u8 vendor_specific1[16];
-
- u8 pow_high_alarm[2];
- u8 pow_low_alarm[2];
- u8 pow_high_warn[2];
- u8 pow_low_warn[2];
-
- u8 bias_high_alarm[2];
- u8 bias_low_alarm[2];
- u8 bias_high_warn[2];
- u8 bias_low_warn[2];
-
- u8 tx_power_high_alarm[2];
- u8 tx_power_low_alarm[2];
- u8 reserved3[4];
-
- u8 reserved4[8];
-
- u8 vendor_specific2[16];
- u8 reserved5[2];
- u8 vendor_specific3[12];
- u8 rx_ampl[2];
- u8 rx_tx_sq_disable;
- u8 rx_output_disable;
- u8 chan_monit_mask[12];
- u8 reserved6[2];
-};
-
-struct unf_sfp_plus_info {
- struct unf_sfp_plus_field_a0 sfp_plus_info_a0;
- struct unf_sfp_plus_field_00 sfp_plus_info_00;
- struct unf_sfp_plus_field_01 sfp_plus_info_01;
- struct unf_sfp_plus_field_02 sfp_plus_info_02;
- struct unf_sfp_plus_field_03 sfp_plus_info_03;
-};
-
-struct unf_sfp_data_field_a0 {
- /* Offset 0~63 */
- struct {
- u8 id;
- u8 id_ext;
- u8 connector;
- u8 transceiver[8];
- u8 encoding;
- u8 br_nominal; /* Nominal signalling rate, units of 100MBd. */
- u8 rate_identifier; /* Type of rate select functionality */
- /* Link length supported for single mode fiber, units of km */
- u8 length_smk_km;
- /* Link length supported for single mode fiber,
- *units of 100 m
- */
- u8 length_smf;
- /* Link length supported for 50 um OM2 fiber,units of 10 m */
- u8 length_smf_om2;
- /* Link length supported for 62.5 um OM1 fiber, units of 10 m */
- u8 length_smf_om1;
- /*Link length supported for copper/direct attach cable,
- *units of m
- */
- u8 length_cable;
- /* Link length supported for 50 um OM3 fiber, units of 10m */
- u8 length_om3;
- u8 vendor_name[16]; /* ASCII */
- /* Code for electronic or optical compatibility*/
- u8 transceiver2;
- u8 vendor_oui[3]; /* SFP vendor IEEE company ID */
- u8 vendor_pn[16]; /* Part number provided by SFP vendor (ASCII)
- */
- /* Revision level for part number provided by vendor (ASCII) */
- u8 vendor_rev[4];
- /* Laser wavelength (Passive/Active Cable
- *Specification Compliance)
- */
- u8 wave_length[2];
- u8 unallocated;
- /* Check code for Base ID Fields (addresses 0 to 62)*/
- u8 cc_base;
- } base_id_fields;
-
- /* Offset 64~95 */
- struct {
- u8 options[2];
- u8 br_max;
- u8 br_min;
- u8 vendor_sn[16];
- u8 date_code[8];
- u8 diag_monitoring_type;
- u8 enhanced_options;
- u8 sff8472_compliance;
- u8 cc_ext;
- } ext_id_fields;
-
- /* Offset 96~255 */
- struct {
- u8 vendor_spec_eeprom[32];
- u8 rsvd[128];
- } vendor_spec_id_fields;
-};
-
-struct unf_sfp_data_field_a2 {
- /* Offset 0~119 */
- struct {
- /* 0~39 */
- struct {
- u8 temp_alarm_high[2];
- u8 temp_alarm_low[2];
- u8 temp_warning_high[2];
- u8 temp_warning_low[2];
-
- u8 vcc_alarm_high[2];
- u8 vcc_alarm_low[2];
- u8 vcc_warning_high[2];
- u8 vcc_warning_low[2];
-
- u8 bias_alarm_high[2];
- u8 bias_alarm_low[2];
- u8 bias_warning_high[2];
- u8 bias_warning_low[2];
-
- u8 tx_alarm_high[2];
- u8 tx_alarm_low[2];
- u8 tx_warning_high[2];
- u8 tx_warning_low[2];
-
- u8 rx_alarm_high[2];
- u8 rx_alarm_low[2];
- u8 rx_warning_high[2];
- u8 rx_warning_low[2];
- } alarm_warn_th;
-
- u8 unallocated0[16];
- u8 ext_cal_constants[36];
- u8 unallocated1[3];
- u8 cc_dmi;
-
- /* 96~105 */
- struct {
- u8 temp[2];
- u8 vcc[2];
- u8 tx_bias[2];
- u8 tx_power[2];
- u8 rx_power[2];
- } diag;
-
- u8 unallocated2[4];
-
- struct {
- u8 data_rdy_bar_state : 1;
- u8 rx_los : 1;
- u8 tx_fault_state : 1;
- u8 soft_rate_select_state : 1;
- u8 rate_select_state : 1;
- u8 rs_state : 1;
- u8 soft_tx_disable_select : 1;
- u8 tx_disable_state : 1;
- } status_ctrl;
- u8 rsvd;
-
- /* 112~113 */
- struct {
- /* 112 */
- u8 tx_alarm_low : 1;
- u8 tx_alarm_high : 1;
- u8 tx_bias_alarm_low : 1;
- u8 tx_bias_alarm_high : 1;
- u8 vcc_alarm_low : 1;
- u8 vcc_alarm_high : 1;
- u8 temp_alarm_low : 1;
- u8 temp_alarm_high : 1;
-
- /* 113 */
- u8 rsvd : 6;
- u8 rx_alarm_low : 1;
- u8 rx_alarm_high : 1;
- } alarm;
-
- u8 unallocated3[2];
-
- /* 116~117 */
- struct {
- /* 116 */
- u8 tx_warn_lo : 1;
- u8 tx_warn_hi : 1;
- u8 bias_warn_lo : 1;
- u8 bias_warn_hi : 1;
- u8 vcc_warn_lo : 1;
- u8 vcc_warn_hi : 1;
- u8 temp_warn_lo : 1;
- u8 temp_warn_hi : 1;
-
- /* 117 */
- u8 rsvd : 6;
- u8 rx_warn_lo : 1;
- u8 rx_warn_hi : 1;
- } warning;
-
- u8 ext_status_and_ctrl[2];
- } diag;
-
- /* Offset 120~255 */
- struct {
- u8 vendor_spec[8];
- u8 user_eeprom[120];
- u8 vendor_ctrl[8];
- } general_use_fields;
-};
-
-struct unf_sfp_info {
- struct unf_sfp_data_field_a0 sfp_info_a0;
- struct unf_sfp_data_field_a2 sfp_info_a2;
-};
-
-struct unf_sfp_err_rome_info {
- struct unf_sfp_info sfp_info;
- struct unf_sfp_plus_info sfp_plus_info;
-};
-
-struct unf_err_code {
- u32 loss_of_signal_count;
- u32 bad_rx_char_count;
- u32 loss_of_sync_count;
- u32 link_fail_count;
- u32 rx_eof_a_count;
- u32 dis_frame_count;
- u32 bad_crc_count;
- u32 proto_error_count;
-};
-
-/* config file */
-enum unf_port_mode {
- UNF_PORT_MODE_UNKNOWN = 0x00,
- UNF_PORT_MODE_TGT = 0x10,
- UNF_PORT_MODE_INI = 0x20,
- UNF_PORT_MODE_BOTH = 0x30
-};
-
-enum unf_port_upgrade {
- UNF_PORT_UNSUPPORT_UPGRADE_REPORT = 0x00,
- UNF_PORT_SUPPORT_UPGRADE_REPORT = 0x01,
- UNF_PORT_UPGRADE_BUTT
-};
-
-#define UNF_BYTES_OF_DWORD 0x4
-static inline void __attribute__((unused)) unf_big_end_to_cpu(u8 *buffer, u32 size)
-{
- u32 *buf = NULL;
- u32 word_sum = 0;
- u32 index = 0;
-
- if (!buffer)
- return;
-
- buf = (u32 *)buffer;
-
- /* byte to word */
- if (size % UNF_BYTES_OF_DWORD == 0)
- word_sum = size / UNF_BYTES_OF_DWORD;
- else
- return;
-
- /* word to byte */
- while (index < word_sum) {
- *buf = be32_to_cpu(*buf);
- buf++;
- index++;
- }
-}
-
-static inline void __attribute__((unused)) unf_cpu_to_big_end(void *buffer, u32 size)
-{
-#define DWORD_BIT 32
-#define BYTE_BIT 8
- u32 *buf = NULL;
- u32 word_sum = 0;
- u32 index = 0;
- u32 tmp = 0;
-
- if (!buffer)
- return;
-
- buf = (u32 *)buffer;
-
- /* byte to dword */
- word_sum = size / UNF_BYTES_OF_DWORD;
-
- /* dword to byte */
- while (index < word_sum) {
- *buf = cpu_to_be32(*buf);
- buf++;
- index++;
- }
-
- if (size % UNF_BYTES_OF_DWORD) {
- tmp = cpu_to_be32(*buf);
- tmp =
- tmp >> (DWORD_BIT - (size % UNF_BYTES_OF_DWORD) * BYTE_BIT);
- memcpy(buf, &tmp, (size % UNF_BYTES_OF_DWORD));
- }
-}
-
-#define UNF_TOP_AUTO_MASK 0x0f
-#define UNF_TOP_UNKNOWN 0xff
-#define SPFC_TOP_AUTO 0x0
-
-#define UNF_NORMAL_MODE 0
-#define UNF_SET_NOMAL_MODE(mode) ((mode) = UNF_NORMAL_MODE)
-
-/*
- * * SCSI status
- */
-#define SCSI_GOOD 0x00
-#define SCSI_CHECK_CONDITION 0x02
-#define SCSI_CONDITION_MET 0x04
-#define SCSI_BUSY 0x08
-#define SCSI_INTERMEDIATE 0x10
-#define SCSI_INTERMEDIATE_COND_MET 0x14
-#define SCSI_RESERVATION_CONFLICT 0x18
-#define SCSI_TASK_SET_FULL 0x28
-#define SCSI_ACA_ACTIVE 0x30
-#define SCSI_TASK_ABORTED 0x40
-
-enum unf_act_topo {
- UNF_ACT_TOP_PUBLIC_LOOP = 0x1,
- UNF_ACT_TOP_PRIVATE_LOOP = 0x2,
- UNF_ACT_TOP_P2P_DIRECT = 0x4,
- UNF_ACT_TOP_P2P_FABRIC = 0x8,
- UNF_TOP_LOOP_MASK = 0x03,
- UNF_TOP_P2P_MASK = 0x0c,
- UNF_TOP_FCOE_MASK = 0x30,
- UNF_ACT_TOP_UNKNOWN
-};
-
-#define UNF_FL_PORT_LOOP_ADDR 0x00
-#define UNF_INVALID_LOOP_ADDR 0xff
-
-#define UNF_LOOP_ROLE_MASTER_OR_SLAVE 0x0
-#define UNF_LOOP_ROLE_ONLY_SLAVE 0x1
-
-#define UNF_TOU16_CHECK(dest, src, over_action) \
- do { \
- if (unlikely(0xFFFF < (src))) { \
- FC_DRV_PRINT(UNF_LOG_REG_ATT, \
- UNF_ERR, "ToU16 error, src 0x%x ", \
- (src)); \
- over_action; \
- } \
- ((dest) = (u16)(src)); \
- } while (0)
-
-#define UNF_PORT_SPEED_AUTO 0
-#define UNF_PORT_SPEED_2_G 2
-#define UNF_PORT_SPEED_4_G 4
-#define UNF_PORT_SPEED_8_G 8
-#define UNF_PORT_SPEED_10_G 10
-#define UNF_PORT_SPEED_16_G 16
-#define UNF_PORT_SPEED_32_G 32
-
-#define UNF_PORT_SPEED_UNKNOWN (~0)
-#define UNF_PORT_SFP_SPEED_ERR 0xFF
-
-#define UNF_OP_DEBUG_DUMP 0x0001
-#define UNF_OP_FCPORT_INFO 0x0002
-#define UNF_OP_FCPORT_LINK_CMD_TEST 0x0003
-#define UNF_OP_TEST_MBX 0x0004
-
-/* max frame size */
-#define UNF_MAX_FRAME_SIZE 2112
-
-/* default */
-#define UNF_DEFAULT_FRAME_SIZE 2048
-#define UNF_DEFAULT_EDTOV 2000
-#define UNF_DEFAULT_RATOV 10000
-#define UNF_DEFAULT_FABRIC_RATOV 10000
-#define UNF_MAX_RETRY_COUNT 3
-#define UNF_RRQ_MIN_TIMEOUT_INTERVAL 30000
-#define UNF_LOGO_TIMEOUT_INTERVAL 3000
-#define UNF_SFS_MIN_TIMEOUT_INTERVAL 15000
-#define UNF_WRITE_RRQ_SENDERR_INTERVAL 3000
-#define UNF_REC_TOV 3000
-
-#define UNF_WAIT_SEM_TIMEOUT (5000UL)
-#define UNF_WAIT_ABTS_RSP_TIMEOUT (20000UL)
-#define UNF_MAX_ABTS_WAIT_INTERVAL ((UNF_WAIT_SEM_TIMEOUT - 500) / 1000)
-
-#define UNF_TGT_RRQ_REDUNDANT_TIME 2000
-#define UNF_INI_RRQ_REDUNDANT_TIME 500
-#define UNF_INI_ELS_REDUNDANT_TIME 2000
-
-/* ELS command values */
-#define UNF_ELS_CMND_HIGH_MASK 0xff000000
-#define UNF_ELS_CMND_RJT 0x01000000
-#define UNF_ELS_CMND_ACC 0x02000000
-#define UNF_ELS_CMND_PLOGI 0x03000000
-#define UNF_ELS_CMND_FLOGI 0x04000000
-#define UNF_ELS_CMND_LOGO 0x05000000
-#define UNF_ELS_CMND_RLS 0x0F000000
-#define UNF_ELS_CMND_ECHO 0x10000000
-#define UNF_ELS_CMND_REC 0x13000000
-#define UNF_ELS_CMND_RRQ 0x12000000
-#define UNF_ELS_CMND_PRLI 0x20000000
-#define UNF_ELS_CMND_PRLO 0x21000000
-#define UNF_ELS_CMND_PDISC 0x50000000
-#define UNF_ELS_CMND_FDISC 0x51000000
-#define UNF_ELS_CMND_ADISC 0x52000000
-#define UNF_ELS_CMND_FAN 0x60000000
-#define UNF_ELS_CMND_RSCN 0x61000000
-#define UNF_FCP_CMND_SRR 0x14000000
-#define UNF_GS_CMND_SCR 0x62000000
-
-#define UNF_PLOGI_VERSION_UPPER 0x20
-#define UNF_PLOGI_VERSION_LOWER 0x20
-#define UNF_PLOGI_CONCURRENT_SEQ 0x00FF
-#define UNF_PLOGI_RO_CATEGORY 0x00FE
-#define UNF_PLOGI_SEQ_PER_XCHG 0x0001
-#define UNF_LGN_INFRAMESIZE 2048
-
-/* CT_IU pream defines */
-#define UNF_REV_NPORTID_INIT 0x01000000
-#define UNF_FSTYPE_OPT_INIT 0xfc020000
-#define UNF_FSTYPE_RFT_ID 0x02170000
-#define UNF_FSTYPE_GID_PT 0x01A10000
-#define UNF_FSTYPE_GID_FT 0x01710000
-#define UNF_FSTYPE_RFF_ID 0x021F0000
-#define UNF_FSTYPE_GFF_ID 0x011F0000
-#define UNF_FSTYPE_GNN_ID 0x01130000
-#define UNF_FSTYPE_GPN_ID 0x01120000
-
-#define UNF_CT_IU_RSP_MASK 0xffff0000
-#define UNF_CT_IU_REASON_MASK 0x00ff0000
-#define UNF_CT_IU_EXPLAN_MASK 0x0000ff00
-#define UNF_CT_IU_REJECT 0x80010000
-#define UNF_CT_IU_ACCEPT 0x80020000
-
-#define UNF_FABRIC_FULL_REG 0x00000003
-
-#define UNF_FC4_SCSI_BIT8 0x00000100
-#define UNF_FC4_FCP_TYPE 0x00000008
-#define UNF_FRAG_REASON_VENDOR 0
-
-/* GID_PT, GID_FT */
-#define UNF_GID_PT_TYPE 0x7F000000
-#define UNF_GID_FT_TYPE 0x00000008
-
-/*
- *FC4 defines
- */
-#define UNF_FC4_FRAME_PAGE_SIZE 0x10
-#define UNF_FC4_FRAME_PAGE_SIZE_SHIFT 16
-
-#define UNF_FC4_FRAME_PARM_0_FCP 0x08000000
-#define UNF_FC4_FRAME_PARM_0_I_PAIR 0x00002000
-#define UNF_FC4_FRAME_PARM_0_GOOD_RSP_CODE 0x00000100
-#define UNF_FC4_FRAME_PARM_0_MASK \
- (UNF_FC4_FRAME_PARM_0_FCP | UNF_FC4_FRAME_PARM_0_I_PAIR | \
- UNF_FC4_FRAME_PARM_0_GOOD_RSP_CODE)
-#define UNF_FC4_FRAME_PARM_3_INI 0x00000020
-#define UNF_FC4_FRAME_PARM_3_TGT 0x00000010
-#define UNF_FC4_FRAME_PARM_3_BOTH \
- (UNF_FC4_FRAME_PARM_3_INI | UNF_FC4_FRAME_PARM_3_TGT)
-#define UNF_FC4_FRAME_PARM_3_R_XFER_DIS 0x00000002
-#define UNF_FC4_FRAME_PARM_3_W_XFER_DIS 0x00000001
-#define UNF_FC4_FRAME_PARM_3_REC_SUPPORT 0x00000400 /* bit 10 */
-#define UNF_FC4_FRAME_PARM_3_TASK_RETRY_ID_SUPPORT 0x00000200 /* bit 9 */
-#define UNF_FC4_FRAME_PARM_3_RETRY_SUPPORT 0x00000100 /* bit 8 */
-#define UNF_FC4_FRAME_PARM_3_CONF_ALLOW 0x00000080 /* bit 7 */
-
-#define UNF_FC4_FRAME_PARM_3_MASK \
- (UNF_FC4_FRAME_PARM_3_INI | UNF_FC4_FRAME_PARM_3_TGT | \
- UNF_FC4_FRAME_PARM_3_R_XFER_DIS)
-
-#define UNF_FC4_TYPE_SHIFT 24
-#define UNF_FC4_TYPE_MASK 0xff
-/* FC4 feature we support */
-#define UNF_GFF_ACC_MASK 0xFF000000
-
-/* Reject CT_IU Reason Codes */
-#define UNF_CTIU_RJT_MASK 0xffff0000
-#define UNF_CTIU_RJT_INVALID_COMMAND 0x00010000
-#define UNF_CTIU_RJT_INVALID_VERSION 0x00020000
-#define UNF_CTIU_RJT_LOGIC_ERR 0x00030000
-#define UNF_CTIU_RJT_INVALID_SIZE 0x00040000
-#define UNF_CTIU_RJT_LOGIC_BUSY 0x00050000
-#define UNF_CTIU_RJT_PROTOCOL_ERR 0x00070000
-#define UNF_CTIU_RJT_UNABLE_PERFORM 0x00090000
-#define UNF_CTIU_RJT_NOT_SUPPORTED 0x000B0000
-
-/* FS_RJT Reason code explanations, FC-GS-2 6.5 */
-#define UNF_CTIU_RJT_EXP_MASK 0x0000FF00
-#define UNF_CTIU_RJT_EXP_NO_ADDTION 0x00000000
-#define UNF_CTIU_RJT_EXP_PORTID_NO_REG 0x00000100
-#define UNF_CTIU_RJT_EXP_PORTNAME_NO_REG 0x00000200
-#define UNF_CTIU_RJT_EXP_NODENAME_NO_REG 0x00000300
-#define UNF_CTIU_RJT_EXP_FC4TYPE_NO_REG 0x00000700
-#define UNF_CTIU_RJT_EXP_PORTTYPE_NO_REG 0x00000A00
-
-/*
- * LS_RJT defines
- */
-#define UNF_FC_LS_RJT_REASON_MASK 0x00ff0000
-
-/*
- * LS_RJT reason code defines
- */
-#define UNF_LS_OK 0x00000000
-#define UNF_LS_RJT_INVALID_COMMAND 0x00010000
-#define UNF_LS_RJT_LOGICAL_ERROR 0x00030000
-#define UNF_LS_RJT_BUSY 0x00050000
-#define UNF_LS_RJT_PROTOCOL_ERROR 0x00070000
-#define UNF_LS_RJT_REQUEST_DENIED 0x00090000
-#define UNF_LS_RJT_NOT_SUPPORTED 0x000b0000
-#define UNF_LS_RJT_CLASS_ERROR 0x000c0000
-
-/*
- * LS_RJT code explanation
- */
-#define UNF_LS_RJT_NO_ADDITIONAL_INFO 0x00000000
-#define UNF_LS_RJT_INV_DATA_FIELD_SIZE 0x00000700
-#define UNF_LS_RJT_INV_COMMON_SERV_PARAM 0x00000F00
-#define UNF_LS_RJT_INVALID_OXID_RXID 0x00001700
-#define UNF_LS_RJT_COMMAND_IN_PROGRESS 0x00001900
-#define UNF_LS_RJT_INSUFFICIENT_RESOURCES 0x00002900
-#define UNF_LS_RJT_COMMAND_NOT_SUPPORTED 0x00002C00
-#define UNF_LS_RJT_UNABLE_TO_SUPLY_REQ_DATA 0x00002A00
-#define UNF_LS_RJT_INVALID_PAYLOAD_LENGTH 0x00002D00
-
-#define UNF_P2P_LOCAL_NPORT_ID 0x000000EF
-#define UNF_P2P_REMOTE_NPORT_ID 0x000000D6
-
-#define UNF_BBCREDIT_MANAGE_NFPORT 0
-#define UNF_BBCREDIT_MANAGE_LPORT 1
-#define UNF_BBCREDIT_LPORT 0
-#define UNF_CONTIN_INCREASE_SUPPORT 1
-#define UNF_CLASS_VALID 1
-#define UNF_CLASS_INVALID 0
-#define UNF_NOT_MEANINGFUL 0
-#define UNF_NO_SERVICE_PARAMS 0
-#define UNF_CLEAN_ADDRESS_DEFAULT 0
-#define UNF_PRIORITY_ENABLE 1
-#define UNF_PRIORITY_DISABLE 0
-#define UNF_SEQUEN_DELIVERY_REQ 1 /* Sequential delivery requested */
-
-#define UNF_FC_PROTOCOL_CLASS_3 0x0
-#define UNF_FC_PROTOCOL_CLASS_2 0x1
-#define UNF_FC_PROTOCOL_CLASS_1 0x2
-#define UNF_FC_PROTOCOL_CLASS_F 0x3
-#define UNF_FC_PROTOCOL_CLASS_OTHER 0x4
-
-#define UNF_RSCN_PORT_ADDR 0x0
-#define UNF_RSCN_AREA_ADDR_GROUP 0x1
-#define UNF_RSCN_DOMAIN_ADDR_GROUP 0x2
-#define UNF_RSCN_FABRIC_ADDR_GROUP 0x3
-
-#define UNF_GET_RSCN_PLD_LEN(cmnd) ((cmnd) & 0x0000ffff)
-#define UNF_RSCN_PAGE_LEN 0x4
-
-#define UNF_PORT_LINK_UP 0x0000
-#define UNF_PORT_LINK_DOWN 0x0001
-#define UNF_PORT_RESET_START 0x0002
-#define UNF_PORT_RESET_END 0x0003
-#define UNF_PORT_LINK_UNKNOWN 0x0004
-#define UNF_PORT_NOP 0x0005
-#define UNF_PORT_CORE_FATAL_ERROR 0x0006
-#define UNF_PORT_CORE_UNRECOVERABLE_ERROR 0x0007
-#define UNF_PORT_CORE_RECOVERABLE_ERROR 0x0008
-#define UNF_PORT_LOGOUT 0x0009
-#define UNF_PORT_CLEAR_VLINK 0x000a
-#define UNF_PORT_UPDATE_PROCESS 0x000b
-#define UNF_PORT_DEBUG_DUMP 0x000c
-#define UNF_PORT_GET_FWLOG 0x000d
-#define UNF_PORT_CLEAN_DONE 0x000e
-#define UNF_PORT_BEGIN_REMOVE 0x000f
-#define UNF_PORT_RELEASE_RPORT_INDEX 0x0010
-#define UNF_PORT_ABNORMAL_RESET 0x0012
-
-/*
- * SCSI begin
- */
-#define SCSIOPC_TEST_UNIT_READY 0x00
-#define SCSIOPC_INQUIRY 0x12
-#define SCSIOPC_MODE_SENSE_6 0x1A
-#define SCSIOPC_MODE_SENSE_10 0x5A
-#define SCSIOPC_MODE_SELECT_6 0x15
-#define SCSIOPC_RESERVE 0x16
-#define SCSIOPC_RELEASE 0x17
-#define SCSIOPC_START_STOP_UNIT 0x1B
-#define SCSIOPC_READ_CAPACITY_10 0x25
-#define SCSIOPC_READ_CAPACITY_16 0x9E
-#define SCSIOPC_READ_6 0x08
-#define SCSIOPC_READ_10 0x28
-#define SCSIOPC_READ_12 0xA8
-#define SCSIOPC_READ_16 0x88
-#define SCSIOPC_WRITE_6 0x0A
-#define SCSIOPC_WRITE_10 0x2A
-#define SCSIOPC_WRITE_12 0xAA
-#define SCSIOPC_WRITE_16 0x8A
-#define SCSIOPC_WRITE_VERIFY 0x2E
-#define SCSIOPC_VERIFY_10 0x2F
-#define SCSIOPC_VERIFY_12 0xAF
-#define SCSIOPC_VERIFY_16 0x8F
-#define SCSIOPC_REQUEST_SENSE 0x03
-#define SCSIOPC_REPORT_LUN 0xA0
-#define SCSIOPC_FORMAT_UNIT 0x04
-#define SCSIOPC_SEND_DIAGNOSTIC 0x1D
-#define SCSIOPC_WRITE_SAME_10 0x41
-#define SCSIOPC_WRITE_SAME_16 0x93
-#define SCSIOPC_READ_BUFFER 0x3C
-#define SCSIOPC_WRITE_BUFFER 0x3B
-
-#define SCSIOPC_LOG_SENSE 0x4D
-#define SCSIOPC_MODE_SELECT_10 0x55
-#define SCSIOPC_SYNCHRONIZE_CACHE_10 0x35
-#define SCSIOPC_SYNCHRONIZE_CACHE_16 0x91
-#define SCSIOPC_WRITE_AND_VERIFY_10 0x2E
-#define SCSIOPC_WRITE_AND_VERIFY_12 0xAE
-#define SCSIOPC_WRITE_AND_VERIFY_16 0x8E
-#define SCSIOPC_READ_MEDIA_SERIAL_NUMBER 0xAB
-#define SCSIOPC_REASSIGN_BLOCKS 0x07
-#define SCSIOPC_ATA_PASSTHROUGH_16 0x85
-#define SCSIOPC_ATA_PASSTHROUGH_12 0xa1
-
-/*
- * SCSI end
- */
-#define IS_READ_COMMAND(opcode) \
- ((opcode) == SCSIOPC_READ_6 || (opcode) == SCSIOPC_READ_10 || \
- (opcode) == SCSIOPC_READ_12 || (opcode) == SCSIOPC_READ_16)
-#define IS_WRITE_COMMAND(opcode) \
- ((opcode) == SCSIOPC_WRITE_6 || (opcode) == SCSIOPC_WRITE_10 || \
- (opcode) == SCSIOPC_WRITE_12 || (opcode) == SCSIOPC_WRITE_16)
-
-#define IS_VERIFY_COMMAND(opcode) \
- ((opcode) == SCSIOPC_VERIFY_10 || (opcode) == SCSIOPC_VERIFY_12 || \
- (opcode) == SCSIOPC_VERIFY_16)
-
-#define FCP_RSP_LEN_VALID_MASK 0x1
-#define FCP_SNS_LEN_VALID_MASK 0x2
-#define FCP_RESID_OVER_MASK 0x4
-#define FCP_RESID_UNDER_MASK 0x8
-#define FCP_CONF_REQ_MASK 0x10
-#define FCP_SCSI_STATUS_GOOD 0x0
-
-#define UNF_DELAYED_WORK_SYNC(ret, port_id, work, work_symb) \
- do { \
- if (!cancel_delayed_work_sync(work)) { \
- FC_DRV_PRINT(UNF_LOG_REG_ATT, \
- UNF_INFO, \
- "[info]LPort or RPort(0x%x) %s worker " \
- "can't destroy, or no " \
- "worker", \
- port_id, work_symb); \
- ret = UNF_RETURN_ERROR; \
- } else { \
- ret = RETURN_OK; \
- } \
- } while (0)
-
-#define UNF_GET_SFS_ENTRY(pkg) ((union unf_sfs_u *)(void *)(((struct unf_frame_pkg *)(pkg)) \
- ->unf_cmnd_pload_bl.buffer_ptr))
-/* FLOGI */
-#define UNF_GET_FLOGI_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->flogi.flogi_payload))
-#define UNF_FLOGI_PAYLOAD_LEN sizeof(struct unf_flogi_fdisc_payload)
-
-/* FLOGI ACC */
-#define UNF_GET_FLOGI_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg))) \
- ->flogi_acc.flogi_payload))
-#define UNF_FLOGI_ACC_PAYLOAD_LEN sizeof(struct unf_flogi_fdisc_payload)
-
-/* FDISC */
-#define UNF_FDISC_PAYLOAD_LEN UNF_FLOGI_PAYLOAD_LEN
-#define UNF_FDISC_ACC_PAYLOAD_LEN UNF_FLOGI_ACC_PAYLOAD_LEN
-
-/* PLOGI */
-#define UNF_GET_PLOGI_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->plogi.payload))
-#define UNF_PLOGI_PAYLOAD_LEN sizeof(struct unf_plogi_payload)
-
-/* PLOGI ACC */
-#define UNF_GET_PLOGI_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->plogi_acc.payload))
-#define UNF_PLOGI_ACC_PAYLOAD_LEN sizeof(struct unf_plogi_payload)
-
-/* LOGO */
-#define UNF_GET_LOGO_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->logo.payload))
-#define UNF_LOGO_PAYLOAD_LEN sizeof(struct unf_logo_payload)
-
-/* ECHO */
-#define UNF_GET_ECHO_PAYLOAD(pkg) \
- (((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->echo.echo_pld)
-
-/* ECHO PHYADDR */
-#define UNF_GET_ECHO_PAYLOAD_PHYADDR(pkg) \
- (((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->echo.phy_echo_addr)
-
-#define UNF_ECHO_PAYLOAD_LEN sizeof(struct unf_echo_payload)
-
-/* REC */
-#define UNF_GET_REC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->rec.rec_pld))
-
-#define UNF_REC_PAYLOAD_LEN sizeof(struct unf_rec_pld)
-
-/* ECHO ACC */
-#define UNF_GET_ECHO_ACC_PAYLOAD(pkg) \
- (((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->echo_acc.echo_pld)
-#define UNF_ECHO_ACC_PAYLOAD_LEN sizeof(struct unf_echo_payload)
-
-/* RRQ */
-#define UNF_GET_RRQ_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->rrq.cmnd))
-#define UNF_RRQ_PAYLOAD_LEN \
- (sizeof(struct unf_rrq) - sizeof(struct unf_fc_head))
-
-/* PRLI */
-#define UNF_GET_PRLI_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->prli.payload))
-#define UNF_PRLI_PAYLOAD_LEN sizeof(struct unf_prli_payload)
-
-/* PRLI ACC */
-#define UNF_GET_PRLI_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->prli_acc.payload))
-#define UNF_PRLI_ACC_PAYLOAD_LEN sizeof(struct unf_prli_payload)
-
-/* PRLO */
-#define UNF_GET_PRLO_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->prlo.payload))
-#define UNF_PRLO_PAYLOAD_LEN sizeof(struct unf_prli_payload)
-
-#define UNF_GET_PRLO_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->prlo_acc.payload))
-#define UNF_PRLO_ACC_PAYLOAD_LEN sizeof(struct unf_prli_payload)
-
-/* PDISC */
-#define UNF_GET_PDISC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->pdisc.payload))
-#define UNF_PDISC_PAYLOAD_LEN sizeof(struct unf_plogi_payload)
-
-/* PDISC ACC */
-#define UNF_GET_PDISC_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->pdisc_acc.payload))
-#define UNF_PDISC_ACC_PAYLOAD_LEN sizeof(struct unf_plogi_payload)
-
-/* ADISC */
-#define UNF_GET_ADISC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->adisc.adisc_payl))
-#define UNF_ADISC_PAYLOAD_LEN sizeof(struct unf_adisc_payload)
-
-/* ADISC ACC */
-#define UNF_GET_ADISC_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->adisc_acc.adisc_payl))
-#define UNF_ADISC_ACC_PAYLOAD_LEN sizeof(struct unf_adisc_payload)
-
-/* RSCN ACC */
-#define UNF_GET_RSCN_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->els_acc.cmnd))
-#define UNF_RSCN_ACC_PAYLOAD_LEN \
- (sizeof(struct unf_els_acc) - sizeof(struct unf_fc_head))
-
-/* LOGO ACC */
-#define UNF_GET_LOGO_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->els_acc.cmnd))
-#define UNF_LOGO_ACC_PAYLOAD_LEN \
- (sizeof(struct unf_els_acc) - sizeof(struct unf_fc_head))
-
-/* RRQ ACC */
-#define UNF_GET_RRQ_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->els_acc.cmnd))
-#define UNF_RRQ_ACC_PAYLOAD_LEN \
- (sizeof(struct unf_els_acc) - sizeof(struct unf_fc_head))
-
-/* REC ACC */
-#define UNF_GET_REC_ACC_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)(UNF_GET_SFS_ENTRY(pkg)))->els_acc.cmnd))
-#define UNF_REC_ACC_PAYLOAD_LEN \
- (sizeof(struct unf_els_acc) - sizeof(struct unf_fc_head))
-
-/* GPN_ID */
-#define UNF_GET_GPNID_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->gpn_id.ctiu_pream))
-#define UNF_GPNID_PAYLOAD_LEN \
- (sizeof(struct unf_gpnid) - sizeof(struct unf_fc_head))
-
-#define UNF_GET_GPNID_RSP_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->gpn_id_rsp.ctiu_pream))
-#define UNF_GPNID_RSP_PAYLOAD_LEN \
- (sizeof(struct unf_gpnid_rsp) - sizeof(struct unf_fc_head))
-
-/* GNN_ID */
-#define UNF_GET_GNNID_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->gnn_id.ctiu_pream))
-#define UNF_GNNID_PAYLOAD_LEN \
- (sizeof(struct unf_gnnid) - sizeof(struct unf_fc_head))
-
-#define UNF_GET_GNNID_RSP_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->gnn_id_rsp.ctiu_pream))
-#define UNF_GNNID_RSP_PAYLOAD_LEN \
- (sizeof(struct unf_gnnid_rsp) - sizeof(struct unf_fc_head))
-
-/* GFF_ID */
-#define UNF_GET_GFFID_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->gff_id.ctiu_pream))
-#define UNF_GFFID_PAYLOAD_LEN \
- (sizeof(struct unf_gffid) - sizeof(struct unf_fc_head))
-
-#define UNF_GET_GFFID_RSP_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->gff_id_rsp.ctiu_pream))
-#define UNF_GFFID_RSP_PAYLOAD_LEN \
- (sizeof(struct unf_gffid_rsp) - sizeof(struct unf_fc_head))
-
-/* GID_FT/GID_PT */
-#define UNF_GET_GID_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg)) \
- ->get_id.gid_req.ctiu_pream))
-
-#define UNF_GID_PAYLOAD_LEN (sizeof(struct unf_ctiu_prem) + sizeof(u32))
-#define UNF_GET_GID_ACC_PAYLOAD(pkg) \
- (((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg)) \
- ->get_id.gid_rsp.gid_acc_pld)
-#define UNF_GID_ACC_PAYLOAD_LEN sizeof(struct unf_gid_acc_pld)
-
-/* RFT_ID */
-#define UNF_GET_RFTID_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->rft_id.ctiu_pream))
-#define UNF_RFTID_PAYLOAD_LEN \
- (sizeof(struct unf_rftid) - sizeof(struct unf_fc_head))
-
-#define UNF_GET_RFTID_RSP_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->rft_id_rsp.ctiu_pream))
-#define UNF_RFTID_RSP_PAYLOAD_LEN sizeof(struct unf_ctiu_prem)
-
-/* RFF_ID */
-#define UNF_GET_RFFID_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->rff_id.ctiu_pream))
-#define UNF_RFFID_PAYLOAD_LEN \
- (sizeof(struct unf_rffid) - sizeof(struct unf_fc_head))
-
-#define UNF_GET_RFFID_RSP_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->rff_id_rsp.ctiu_pream))
-#define UNF_RFFID_RSP_PAYLOAD_LEN sizeof(struct unf_ctiu_prem)
-
-/* ACC&RJT */
-#define UNF_GET_ELS_ACC_RJT_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->els_rjt.cmnd))
-#define UNF_ELS_ACC_RJT_LEN \
- (sizeof(struct unf_els_rjt) - sizeof(struct unf_fc_head))
-
-/* SCR */
-#define UNF_SCR_PAYLOAD(pkg) \
- (((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->scr.payload)
-#define UNF_SCR_PAYLOAD_LEN \
- (sizeof(struct unf_scr) - sizeof(struct unf_fc_head))
-
-#define UNF_SCR_RSP_PAYLOAD(pkg) \
- (&(((union unf_sfs_u *)UNF_GET_SFS_ENTRY(pkg))->els_acc.cmnd))
-#define UNF_SCR_RSP_PAYLOAD_LEN \
- (sizeof(struct unf_els_acc) - sizeof(struct unf_fc_head))
-
-#define UNF_GS_RSP_PAYLOAD_LEN \
- (sizeof(union unf_sfs_u) - sizeof(struct unf_fc_head))
-
-#define UNF_GET_XCHG_TAG(pkg) \
- (((struct unf_frame_pkg *)(pkg)) \
- ->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX])
-#define UNF_GET_ABTS_XCHG_TAG(pkg) \
- ((u16)(((pkg)->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX]) >> 16))
-#define UNF_GET_IO_XCHG_TAG(pkg) \
- ((u16)((pkg)->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX]))
-
-#define UNF_GET_HOTPOOL_TAG(pkg) \
- (((struct unf_frame_pkg *)(pkg)) \
- ->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX])
-#define UNF_GET_SID(pkg) \
- (((struct unf_frame_pkg *)(pkg))->frame_head.csctl_sid & \
- UNF_NPORTID_MASK)
-#define UNF_GET_DID(pkg) \
- (((struct unf_frame_pkg *)(pkg))->frame_head.rctl_did & \
- UNF_NPORTID_MASK)
-#define UNF_GET_OXID(pkg) \
- (((struct unf_frame_pkg *)(pkg))->frame_head.oxid_rxid >> 16)
-#define UNF_GET_RXID(pkg) \
- ((u16)((struct unf_frame_pkg *)(pkg))->frame_head.oxid_rxid)
-#define UNF_GET_XID_RELEASE_TIMER(pkg) \
- (((struct unf_frame_pkg *)(pkg))->release_task_id_timer)
-#define UNF_GETXCHGALLOCTIME(pkg) \
- (((struct unf_frame_pkg *)(pkg)) \
- ->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME])
-
-#define UNF_SET_XCHG_ALLOC_TIME(pkg, xchg) \
- (((struct unf_frame_pkg *)(pkg)) \
- ->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = \
- (((struct unf_xchg *)(xchg)) \
- ->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME]))
-#define UNF_SET_ABORT_INFO_IOTYPE(pkg, xchg) \
- (((struct unf_frame_pkg *)(pkg)) \
- ->private_data[PKG_PRIVATE_XCHG_ABORT_INFO] |= \
- (((u8)(((struct unf_xchg *)(xchg))->data_direction & 0x7)) \
- << 2))
-
-#define UNF_CHECK_NPORT_FPORT_BIT(els_payload) \
- (((struct unf_flogi_fdisc_payload *)(els_payload)) \
- ->fabric_parms.co_parms.nport)
-
-#define UNF_GET_RSP_BUF(pkg) \
- ((void *)(((struct unf_frame_pkg *)(pkg))->unf_rsp_pload_bl.buffer_ptr))
-#define UNF_GET_RSP_LEN(pkg) \
- (((struct unf_frame_pkg *)(pkg))->unf_rsp_pload_bl.length)
-
-#define UNF_N_PORT 0
-#define UNF_F_PORT 1
-
-#define UNF_GET_RA_TOV_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.r_a_tov)
-#define UNF_GET_RT_TOV_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.r_t_tov)
-#define UNF_GET_E_D_TOV_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.e_d_tov)
-#define UNF_GET_E_D_TOV_RESOLUTION_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.e_d_tov_resolution)
-#define UNF_GET_BB_SC_N_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.bbscn)
-#define UNF_GET_BB_CREDIT_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.bb_credit)
-
-enum unf_pcie_error_code {
- UNF_PCIE_ERROR_NONE = 0,
- UNF_PCIE_DATAPARITYDETECTED = 1,
- UNF_PCIE_SIGNALTARGETABORT,
- UNF_PCIE_RECEIVEDTARGETABORT,
- UNF_PCIE_RECEIVEDMASTERABORT,
- UNF_PCIE_SIGNALEDSYSTEMERROR,
- UNF_PCIE_DETECTEDPARITYERROR,
- UNF_PCIE_CORRECTABLEERRORDETECTED,
- UNF_PCIE_NONFATALERRORDETECTED,
- UNF_PCIE_FATALERRORDETECTED,
- UNF_PCIE_UNSUPPORTEDREQUESTDETECTED,
- UNF_PCIE_AUXILIARYPOWERDETECTED,
- UNF_PCIE_TRANSACTIONSPENDING,
-
- UNF_PCIE_UNCORRECTINTERERRSTATUS,
- UNF_PCIE_UNSUPPORTREQERRSTATUS,
- UNF_PCIE_ECRCERRORSTATUS,
- UNF_PCIE_MALFORMEDTLPSTATUS,
- UNF_PCIE_RECEIVEROVERFLOWSTATUS,
- UNF_PCIE_UNEXPECTCOMPLETESTATUS,
- UNF_PCIE_COMPLETERABORTSTATUS,
- UNF_PCIE_COMPLETIONTIMEOUTSTATUS,
- UNF_PCIE_FLOWCTRLPROTOCOLERRSTATUS,
- UNF_PCIE_POISONEDTLPSTATUS,
- UNF_PCIE_SURPRISEDOWNERRORSTATUS,
- UNF_PCIE_DATALINKPROTOCOLERRSTATUS,
- UNF_PCIE_ADVISORYNONFATALERRSTATUS,
- UNF_PCIE_REPLAYTIMERTIMEOUTSTATUS,
- UNF_PCIE_REPLAYNUMROLLOVERSTATUS,
- UNF_PCIE_BADDLLPSTATUS,
- UNF_PCIE_BADTLPSTATUS,
- UNF_PCIE_RECEIVERERRORSTATUS,
-
- UNF_PCIE_BUTT
-};
-
-#define UNF_DMA_HI32(a) (((a) >> 32) & 0xffffffff)
-#define UNF_DMA_LO32(a) ((a) & 0xffffffff)
-
-#define UNF_WWN_LEN 8
-#define UNF_MAC_LEN 6
-
-/* send BLS/ELS/BLS REPLY/ELS REPLY/GS/ */
-/* rcvd BLS/ELS/REQ DONE/REPLY DONE */
-#define UNF_PKG_BLS_REQ 0x0100
-#define UNF_PKG_BLS_REQ_DONE 0x0101
-#define UNF_PKG_BLS_REPLY 0x0102
-#define UNF_PKG_BLS_REPLY_DONE 0x0103
-
-#define UNF_PKG_ELS_REQ 0x0200
-#define UNF_PKG_ELS_REQ_DONE 0x0201
-
-#define UNF_PKG_ELS_REPLY 0x0202
-#define UNF_PKG_ELS_REPLY_DONE 0x0203
-
-#define UNF_PKG_GS_REQ 0x0300
-#define UNF_PKG_GS_REQ_DONE 0x0301
-
-#define UNF_PKG_TGT_XFER 0x0400
-#define UNF_PKG_TGT_RSP 0x0401
-#define UNF_PKG_TGT_RSP_NOSGL 0x0402
-#define UNF_PKG_TGT_RSP_STATUS 0x0403
-
-#define UNF_PKG_INI_IO 0x0500
-#define UNF_PKG_INI_RCV_TGT_RSP 0x0507
-
-/* external sgl struct start */
-struct unf_esgl_page {
- u64 page_address;
- dma_addr_t esgl_phy_addr;
- u32 page_size;
-};
-
-/* external sgl struct end */
-struct unf_esgl {
- struct list_head entry_esgl;
- struct unf_esgl_page page;
-};
-
-#define UNF_RESPONE_DATA_LEN 8
-struct unf_frame_payld {
- u8 *buffer_ptr;
- dma_addr_t buf_dma_addr;
- u32 length;
-};
-
-enum pkg_private_index {
- PKG_PRIVATE_LOWLEVEL_XCHG_ADD = 0,
- PKG_PRIVATE_XCHG_HOT_POOL_INDEX = 1, /* Hot Pool Index */
- PKG_PRIVATE_XCHG_RPORT_INDEX = 2, /* RPort index */
- PKG_PRIVATE_XCHG_VP_INDEX = 3, /* VPort index */
- PKG_PRIVATE_XCHG_SSQ_INDEX,
- PKG_PRIVATE_RPORT_RX_SIZE,
- PKG_PRIVATE_XCHG_TIMEER,
- PKG_PRIVATE_XCHG_ALLOC_TIME,
- PKG_PRIVATE_XCHG_ABORT_INFO,
- PKG_PRIVATE_ECHO_CMD_SND_TIME, /* local send echo cmd time stamp */
- PKG_PRIVATE_ECHO_ACC_RCV_TIME, /* local receive echo acc time stamp */
- PKG_PRIVATE_ECHO_CMD_RCV_TIME, /* remote receive echo cmd time stamp */
- PKG_PRIVATE_ECHO_RSP_SND_TIME, /* remote send echo rsp time stamp */
- PKG_MAX_PRIVATE_DATA_SIZE
-};
-
-extern u32 dix_flag;
-extern u32 dif_sgl_mode;
-extern u32 dif_app_esc_check;
-extern u32 dif_ref_esc_check;
-
-#define UNF_DIF_ACTION_NONE 0
-
-enum unf_adm_dif_mode_E {
- UNF_SWITCH_DIF_DIX = 0,
- UNF_APP_REF_ESCAPE,
- ALL_DIF_MODE = 20,
-};
-
-#define UNF_DIF_CRC_ERR 0x1001
-#define UNF_DIF_APP_ERR 0x1002
-#define UNF_DIF_LBA_ERR 0x1003
-
-#define UNF_VERIFY_CRC_MASK (1 << 1)
-#define UNF_VERIFY_APP_MASK (1 << 2)
-#define UNF_VERIFY_LBA_MASK (1 << 3)
-
-#define UNF_REPLACE_CRC_MASK (1 << 8)
-#define UNF_REPLACE_APP_MASK (1 << 9)
-#define UNF_REPLACE_LBA_MASK (1 << 10)
-
-#define UNF_DIF_ACTION_MASK (0xff << 16)
-#define UNF_DIF_ACTION_INSERT (0x1 << 16)
-#define UNF_DIF_ACTION_VERIFY_AND_DELETE (0x2 << 16)
-#define UNF_DIF_ACTION_VERIFY_AND_FORWARD (0x3 << 16)
-#define UNF_DIF_ACTION_VERIFY_AND_REPLACE (0x4 << 16)
-
-#define UNF_DIF_ACTION_NO_INCREASE_REFTAG (0x1 << 24)
-
-#define UNF_DEFAULT_CRC_GUARD_SEED (0)
-#define UNF_CAL_512_BLOCK_CNT(data_len) ((data_len) >> 9)
-#define UNF_CAL_BLOCK_CNT(data_len, sector_size) ((data_len) / (sector_size))
-#define UNF_CAL_CRC_BLK_CNT(crc_data_len, sector_size) \
- ((crc_data_len) / ((sector_size) + 8))
-
-#define UNF_DIF_DOUBLE_SGL (1 << 1)
-#define UNF_DIF_SECTSIZE_4KB (1 << 2)
-#define UNF_DIF_SECTSIZE_512 (0 << 2)
-#define UNF_DIF_LBA_NONE_INCREASE (1 << 3)
-#define UNF_DIF_TYPE3 (1 << 4)
-
-#define SECTOR_SIZE_512 512
-#define SECTOR_SIZE_4096 4096
-#define SPFC_DIF_APP_REF_ESC_NOT_CHECK 1
-#define SPFC_DIF_APP_REF_ESC_CHECK 0
-
-struct unf_dif {
- u16 crc;
- u16 app_tag;
- u32 lba;
-};
-
-enum unf_io_state { UNF_INI_IO = 0, UNF_TGT_XFER = 1, UNF_TGT_RSP = 2 };
-
-#define UNF_PKG_LAST_RESPONSE 0
-#define UNF_PKG_NOT_LAST_RESPONSE 1
-
-struct unf_frame_pkg {
- /* pkt type:BLS/ELS/FC4LS/CMND/XFER/RSP */
- u32 type;
- u32 last_pkg_flag;
- u32 fcp_conf_flag;
-
-#define UNF_FCP_RESPONSE_VALID 0x01
-#define UNF_FCP_SENSE_VALID 0x02
- u32 response_and_sense_valid_flag; /* resp and sense vailed flag */
- u32 cmnd;
- struct unf_fc_head frame_head;
- u32 entry_count;
- void *xchg_contex;
- u32 transfer_len;
- u32 residus_len;
- u32 status;
- u32 status_sub_code;
- enum unf_io_state io_state;
- u32 qos_level;
- u32 private_data[PKG_MAX_PRIVATE_DATA_SIZE];
- struct unf_fcp_cmnd *fcp_cmnd;
- struct unf_dif_control_info dif_control;
- struct unf_frame_payld unf_cmnd_pload_bl;
- struct unf_frame_payld unf_rsp_pload_bl;
- struct unf_frame_payld unf_sense_pload_bl;
- void *upper_cmd;
- u32 abts_maker_status;
- u32 release_task_id_timer;
- u8 byte_orders;
- u8 rx_or_ox_id;
- u8 class_mode;
- u8 rsvd;
- u8 *peresp;
- u32 rcvrsp_len;
- ulong timeout;
- u32 origin_hottag;
- u32 origin_magicnum;
-};
-
-#define UNF_MAX_SFS_XCHG 2048
-#define UNF_RESERVE_SFS_XCHG 128 /* times on exchange mgr num */
-
-struct unf_lport_cfg_item {
- u32 port_id;
- u32 port_mode; /* INI(0x20), TGT(0x10), BOTH(0x30) */
- u32 port_topology; /* 0x3:loop , 0xc:p2p ,0xf:auto */
- u32 max_queue_depth;
- u32 max_io; /* Recommended Value 512-4096 */
- u32 max_login;
- u32 max_sfs_xchg;
- u32 port_speed; /* 0:auto 1:1Gbps 2:2Gbps 4:4Gbps 8:8Gbps 16:16Gbps */
- u32 tape_support; /* ape support */
- u32 fcp_conf; /* fcp confirm support */
- u32 bbscn;
-};
-
-struct unf_port_dynamic_info {
- u32 sfp_posion;
- u32 sfp_valid;
- u32 phy_link;
- u32 firmware_state;
- u32 cur_speed;
- u32 mailbox_timeout_cnt;
-};
-
-struct unf_port_intr_coalsec {
- u32 delay_timer;
- u32 depth;
-};
-
-struct unf_port_topo {
- u32 topo_cfg;
- enum unf_act_topo topo_act;
-};
-
-struct unf_port_transfer_para {
- u32 type;
- u32 value;
-};
-
-struct unf_buf {
- u8 *buf;
- u32 buf_len;
-};
-
-/* get ucode & up ver */
-#define SPFC_VER_LEN (16)
-#define SPFC_COMPILE_TIME_LEN (20)
-struct unf_fw_version {
- u32 message_type;
- u8 fw_version[SPFC_VER_LEN];
-};
-
-struct unf_port_wwn {
- u64 sys_port_wwn;
- u64 sys_node_name;
-};
-
-enum unf_port_config_set_op {
- UNF_PORT_CFG_SET_SPEED,
- UNF_PORT_CFG_SET_PORT_SWITCH,
- UNF_PORT_CFG_SET_POWER_STATE,
- UNF_PORT_CFG_SET_PORT_STATE,
- UNF_PORT_CFG_UPDATE_WWN,
- UNF_PORT_CFG_TEST_FLASH,
- UNF_PORT_CFG_UPDATE_FABRIC_PARAM,
- UNF_PORT_CFG_UPDATE_PLOGI_PARAM,
- UNF_PORT_CFG_SET_BUTT
-};
-
-enum unf_port_cfg_get_op {
- UNF_PORT_CFG_GET_TOPO_ACT,
- UNF_PORT_CFG_GET_LOOP_MAP,
- UNF_PORT_CFG_GET_SFP_PRESENT,
- UNF_PORT_CFG_GET_FW_VER,
- UNF_PORT_CFG_GET_HW_VER,
- UNF_PORT_CFG_GET_WORKBALE_BBCREDIT,
- UNF_PORT_CFG_GET_WORKBALE_BBSCN,
- UNF_PORT_CFG_GET_FC_SERDES,
- UNF_PORT_CFG_GET_LOOP_ALPA,
- UNF_PORT_CFG_GET_MAC_ADDR,
- UNF_PORT_CFG_GET_SFP_VER,
- UNF_PORT_CFG_GET_SFP_SUPPORT_UPDATE,
- UNF_PORT_CFG_GET_SFP_LOG,
- UNF_PORT_CFG_GET_PCIE_LINK_STATE,
- UNF_PORT_CFG_GET_FLASH_DATA_INFO,
- UNF_PORT_CFG_GET_BUTT,
-};
-
-enum unf_port_config_state {
- UNF_PORT_CONFIG_STATE_START,
- UNF_PORT_CONFIG_STATE_STOP,
- UNF_PORT_CONFIG_STATE_RESET,
- UNF_PORT_CONFIG_STATE_STOP_INTR,
- UNF_PORT_CONFIG_STATE_BUTT
-};
-
-enum unf_port_config_update {
- UNF_PORT_CONFIG_UPDATE_FW_MINIMUM,
- UNF_PORT_CONFIG_UPDATE_FW_ALL,
- UNF_PORT_CONFIG_UPDATE_BUTT
-};
-
-enum unf_disable_vp_mode {
- UNF_DISABLE_VP_MODE_ONLY = 0x8,
- UNF_DISABLE_VP_MODE_REINIT_LINK = 0x9,
- UNF_DISABLE_VP_MODE_NOFAB_LOGO = 0xA,
- UNF_DISABLE_VP_MODE_LOGO_ALL = 0xB
-};
-
-struct unf_vport_info {
- u16 vp_index;
- u64 node_name;
- u64 port_name;
- u32 port_mode; /* INI, TGT or both */
- enum unf_disable_vp_mode disable_mode;
- u32 nport_id; /* maybe acquired by lowlevel and update to common */
- void *vport;
-};
-
-struct unf_port_login_parms {
- enum unf_act_topo act_topo;
-
- u32 rport_index;
- u32 seq_cnt : 1;
- u32 ed_tov : 1;
- u32 reserved : 14;
- u32 tx_mfs : 16;
- u32 ed_tov_timer_val;
-
- u8 remote_rttov_tag;
- u8 remote_edtov_tag;
- u16 remote_bb_credit;
- u16 compared_bbscn;
- u32 compared_edtov_val;
- u32 compared_ratov_val;
- u32 els_cmnd_code;
-};
-
-struct unf_mbox_head_info {
- /* mbox header */
- u8 cmnd_type;
- u8 length;
- u8 port_id;
- u8 pad0;
-
- /* operation */
- u32 opcode : 4;
- u32 pad1 : 28;
-};
-
-struct unf_mbox_head_sts {
- /* mbox header */
- u8 cmnd_type;
- u8 length;
- u8 port_id;
- u8 pad0;
-
- /* operation */
- u16 pad1;
- u8 pad2;
- u8 status;
-};
-
-struct unf_low_level_service_op {
- u32 (*unf_ls_gs_send)(void *hba, struct unf_frame_pkg *pkg);
- u32 (*unf_bls_send)(void *hba, struct unf_frame_pkg *pkg);
- u32 (*unf_cmnd_send)(void *hba, struct unf_frame_pkg *pkg);
- u32 (*unf_rsp_send)(void *handle, struct unf_frame_pkg *pkg);
- u32 (*unf_release_rport_res)(void *handle, struct unf_port_info *rport_info);
- u32 (*unf_flush_ini_resp_que)(void *handle);
- u32 (*unf_alloc_rport_res)(void *handle, struct unf_port_info *rport_info);
- u32 (*ll_release_xid)(void *handle, struct unf_frame_pkg *pkg);
- u32 (*unf_xfer_send)(void *handle, struct unf_frame_pkg *pkg);
-};
-
-struct unf_low_level_port_mgr_op {
- /* fcport/opcode/input parameter */
- u32 (*ll_port_config_set)(void *fc_port, enum unf_port_config_set_op opcode, void *para_in);
-
- /* fcport/opcode/output parameter */
- u32 (*ll_port_config_get)(void *fc_port, enum unf_port_cfg_get_op opcode, void *para_out);
-};
-
-struct unf_chip_info {
- u8 chip_type;
- u8 chip_work_mode;
- u8 disable_err_flag;
-};
-
-struct unf_low_level_functioon_op {
- struct unf_chip_info chip_info;
- /* low level type */
- u32 low_level_type;
- const char *name;
- struct pci_dev *dev;
- u64 sys_node_name;
- u64 sys_port_name;
- struct unf_lport_cfg_item lport_cfg_items;
-#define UNF_LOW_LEVEL_MGR_TYPE_ACTIVE 0
-#define UNF_LOW_LEVEL_MGR_TYPE_PASSTIVE 1
- const u32 xchg_mgr_type;
-
-#define UNF_NO_EXTRA_ABTS_XCHG 0x0
-#define UNF_LL_IOC_ABTS_XCHG 0x1
- const u32 abts_xchg;
-
-#define UNF_CM_RPORT_SET_QUALIFIER 0x0
-#define UNF_CM_RPORT_SET_QUALIFIER_REUSE 0x1
-#define UNF_CM_RPORT_SET_QUALIFIER_SPFC 0x2
-
- /* low level pass-through flag. */
-#define UNF_LOW_LEVEL_PASS_THROUGH_FIP 0x0
-#define UNF_LOW_LEVEL_PASS_THROUGH_FABRIC_LOGIN 0x1
-#define UNF_LOW_LEVEL_PASS_THROUGH_PORT_LOGIN 0x2
- u32 passthrough_flag;
-
- /* low level parameter */
- u32 support_max_npiv_num;
- u32 support_max_ssq_num;
- u32 support_max_speed;
- u32 support_min_speed;
- u32 fc_ser_max_speed;
-
- u32 support_max_rport;
-
- u32 support_max_hot_tag_range;
- u32 sfp_type;
- u32 update_fw_reset_active;
- u32 support_upgrade_report;
- u32 multi_conf_support;
- u32 port_type;
-#define UNF_LOW_LEVEL_RELEASE_RPORT_SYNC 0x0
-#define UNF_LOW_LEVEL_RELEASE_RPORT_ASYNC 0x1
- u8 rport_release_type;
-#define UNF_LOW_LEVEL_SIRT_PAGE_MODE_FIXED 0x0
-#define UNF_LOW_LEVEL_SIRT_PAGE_MODE_XCHG 0x1
- u8 sirt_page_mode;
- u8 sfp_speed;
-
- /* IO reference */
- struct unf_low_level_service_op service_op;
-
- /* Port Mgr reference */
- struct unf_low_level_port_mgr_op port_mgr_op;
-
- u8 chip_id;
-};
-
-struct unf_cm_handle_op {
- /* return:L_Port */
- void *(*unf_alloc_local_port)(void *private_data,
- struct unf_low_level_functioon_op *low_level_op);
-
- /* input para:L_Port */
- u32 (*unf_release_local_port)(void *lport);
-
- /* input para:L_Port, FRAME_PKG_S */
- u32 (*unf_receive_ls_gs_pkg)(void *lport, struct unf_frame_pkg *pkg);
-
- /* input para:L_Port, FRAME_PKG_S */
- u32 (*unf_receive_bls_pkg)(void *lport, struct unf_frame_pkg *pkg);
- /* input para:L_Port, FRAME_PKG_S */
- u32 (*unf_send_els_done)(void *lport, struct unf_frame_pkg *pkg);
-
- /* input para:L_Port, FRAME_PKG_S */
- u32 (*unf_receive_marker_status)(void *lport, struct unf_frame_pkg *pkg);
- u32 (*unf_receive_abts_marker_status)(void *lport, struct unf_frame_pkg *pkg);
- /* input para:L_Port, FRAME_PKG_S */
- u32 (*unf_receive_ini_response)(void *lport, struct unf_frame_pkg *pkg);
-
- int (*unf_get_cfg_parms)(char *section_name,
- struct unf_cfg_item *cfg_parm, u32 *cfg_value,
- u32 item_num);
-
- /* TGT IO interface */
- u32 (*unf_process_fcp_cmnd)(void *lport, struct unf_frame_pkg *pkg);
-
- /* TGT IO Done */
- u32 (*unf_tgt_cmnd_xfer_or_rsp_echo)(void *lport, struct unf_frame_pkg *pkg);
-
- u32 (*unf_cm_get_sgl_entry)(void *pkg, char **buf, u32 *buf_len);
- u32 (*unf_cm_get_dif_sgl_entry)(void *pkg, char **buf, u32 *buf_len);
-
- struct unf_esgl_page *(*unf_get_one_free_esgl_page)(void *lport, struct unf_frame_pkg *pkg);
-
- /* input para:L_Port, EVENT */
- u32 (*unf_fc_port_event)(void *lport, u32 events, void *input);
-
- int (*unf_drv_start_work)(void *lport);
-
- void (*unf_card_rport_chip_err)(struct pci_dev const *pci_dev);
-};
-
-u32 unf_get_cm_handle_ops(struct unf_cm_handle_op *cm_handle);
-int unf_common_init(void);
-void unf_common_exit(void);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_disc.c b/drivers/scsi/spfc/common/unf_disc.c
deleted file mode 100644
index c48d0ba670d4..000000000000
--- a/drivers/scsi/spfc/common/unf_disc.c
+++ /dev/null
@@ -1,1276 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_disc.h"
-#include "unf_log.h"
-#include "unf_common.h"
-#include "unf_event.h"
-#include "unf_lport.h"
-#include "unf_rport.h"
-#include "unf_exchg.h"
-#include "unf_ls.h"
-#include "unf_gs.h"
-#include "unf_portman.h"
-
-#define UNF_LIST_RSCN_PAGE_CNT 2560
-#define UNF_MAX_PORTS_PRI_LOOP 2
-#define UNF_MAX_GS_SEND_NUM 8
-#define UNF_OS_REMOVE_CARD_TIMEOUT (60 * 1000)
-
-static void unf_set_disc_state(struct unf_disc *disc,
- enum unf_disc_state states)
-{
- FC_CHECK_RETURN_VOID(disc);
-
- if (states != disc->states) {
- /* Reset disc retry count */
- disc->retry_count = 0;
- }
-
- disc->states = states;
-}
-
-static inline u32 unf_get_loop_map(struct unf_lport *lport, u8 loop_map[], u32 loop_map_size)
-{
- struct unf_buf buf = {0};
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport->low_level_func.port_mgr_op.ll_port_config_get,
- UNF_RETURN_ERROR);
-
- buf.buf = loop_map;
- buf.buf_len = loop_map_size;
-
- ret = lport->low_level_func.port_mgr_op.ll_port_config_get(lport->fc_port,
- UNF_PORT_CFG_GET_LOOP_MAP,
- (void *)&buf);
- return ret;
-}
-
-static void unf_login_with_loop_node(struct unf_lport *lport, u32 alpa)
-{
- /* Only used for Private Loop LOGIN */
- struct unf_rport *unf_rport = NULL;
- ulong rport_flag = 0;
- u32 port_feature = 0;
- u32 ret;
-
- /* Check AL_PA validity */
- if (lport->nport_id == alpa) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) is the same as RPort with AL_PA(0x%x), do nothing",
- lport->port_id, alpa);
- return;
- }
-
- if (alpa == 0) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) is fabric, do nothing",
- lport->port_id, alpa);
- return;
- }
-
- /* Get & set R_Port: reuse only */
- unf_rport = unf_get_rport_by_nport_id(lport, alpa);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) RPort(0x%x_0x%p) login with private loop",
- lport->port_id, lport->nport_id, alpa, unf_rport);
-
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY, alpa);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) allocate new RPort(0x%x) failed",
- lport->port_id, lport->nport_id, alpa);
- return;
- }
-
- /* Update R_Port state & N_Port_ID */
- spin_lock_irqsave(&unf_rport->rport_state_lock, rport_flag);
- unf_rport->nport_id = alpa;
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, rport_flag);
-
- /* Private Loop: check whether need delay to send PLOGI or not */
- port_feature = unf_rport->options;
-
- /* check Rport and Lport feature */
- if (port_feature == UNF_PORT_MODE_UNKNOWN &&
- lport->options == UNF_PORT_MODE_INI) {
- /* Start to send PLOGI */
- ret = unf_send_plogi(lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send PLOGI to RPort(0x%x) failed",
- lport->port_id, lport->nport_id, unf_rport->nport_id);
-
- unf_rport_error_recovery(unf_rport);
- }
- } else {
- unf_check_rport_need_delay_plogi(lport, unf_rport, port_feature);
- }
-}
-
-static int unf_discover_private_loop(void *arg_in, void *arg_out)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)arg_in;
- u32 ret = UNF_RETURN_ERROR;
- u32 i = 0;
- u8 loop_id = 0;
- u32 alpa_index = 0;
- u8 loop_map[UNF_LOOPMAP_COUNT];
-
- FC_CHECK_RETURN_VALUE(unf_lport, UNF_RETURN_ERROR);
- memset(loop_map, 0x0, UNF_LOOPMAP_COUNT);
-
- /* Get Port Loop Map */
- ret = unf_get_loop_map(unf_lport, loop_map, UNF_LOOPMAP_COUNT);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) get loop map failed", unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Check Loop Map Ports Count */
- if (loop_map[ARRAY_INDEX_0] > UNF_MAX_PORTS_PRI_LOOP) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) has more than %d ports(%u) in private loop",
- unf_lport->port_id, UNF_MAX_PORTS_PRI_LOOP, loop_map[ARRAY_INDEX_0]);
-
- return UNF_RETURN_ERROR;
- }
-
- /* AL_PA = 0 means Public Loop */
- if (loop_map[ARRAY_INDEX_1] == UNF_FL_PORT_LOOP_ADDR ||
- loop_map[ARRAY_INDEX_2] == UNF_FL_PORT_LOOP_ADDR) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) one or more AL_PA is 0x00, indicate it's FL_Port",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Discovery Private Loop Ports */
- for (i = 0; i < loop_map[ARRAY_INDEX_0]; i++) {
- alpa_index = i + 1;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) start to disc(0x%x) with count(0x%x)",
- unf_lport->port_id, loop_map[alpa_index], i);
-
- /* Check whether need delay to send PLOGI or not */
- loop_id = loop_map[alpa_index];
- unf_login_with_loop_node(unf_lport, (u32)loop_id);
- }
-
- return RETURN_OK;
-}
-
-u32 unf_disc_start(void *lport)
-{
- /*
- * Call by:
- * 1. Enter Private Loop Login
- * 2. Analysis RSCN payload
- * 3. SCR callback
- * *
- * Doing:
- * Fabric/Public Loop: Send GID_PT
- * Private Loop: (delay to) send PLOGI or send LOGO immediately
- * P2P: do nothing
- */
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
- struct unf_rport *unf_rport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_cm_event_report *event = NULL;
- u32 ret = RETURN_OK;
- ulong flag = 0;
- enum unf_act_topo act_topo = UNF_ACT_TOP_UNKNOWN;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- act_topo = unf_lport->act_topo;
- disc = &unf_lport->disc;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Port(0x%x) with topo(0x%x) begin to discovery",
- unf_lport->port_id, act_topo);
-
- if (act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- act_topo == UNF_ACT_TOP_PUBLIC_LOOP) {
- /* 1. Fabric or Public Loop Topology: for directory server */
- unf_rport = unf_get_rport_by_nport_id(unf_lport,
- UNF_FC_FID_DIR_SERV); /* 0xfffffc */
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) unable to get SNS RPort(0xfffffc)",
- unf_lport->port_id);
-
- unf_rport = unf_rport_get_free_and_init(unf_lport, UNF_PORT_TYPE_FC,
- UNF_FC_FID_DIR_SERV);
- if (!unf_rport)
- return UNF_RETURN_ERROR;
-
- unf_rport->nport_id = UNF_FC_FID_DIR_SERV;
- }
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_set_disc_state(disc, UNF_DISC_ST_START); /* disc start */
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_NORMAL_ENTER);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- /*
- * NOTE: Send GID_PT
- * The Name Server shall, when it receives a GID_PT request,
- * return all Port Identifiers having registered support for the
- * specified Port Type. One or more Port Identifiers, having
- * registered as the specified Port Type, are returned.
- */
- ret = unf_send_gid_pt(unf_lport, unf_rport);
- if (ret != RETURN_OK)
- unf_disc_error_recovery(unf_lport);
- } else if (act_topo == UNF_ACT_TOP_PRIVATE_LOOP) {
- /* Private Loop: to thread process */
- event = unf_get_one_event_node(unf_lport);
- FC_CHECK_RETURN_VALUE(event, UNF_RETURN_ERROR);
-
- event->lport = unf_lport;
- event->event_asy_flag = UNF_EVENT_ASYN;
- event->unf_event_task = unf_discover_private_loop;
- event->para_in = (void *)unf_lport;
-
- unf_post_one_event_node(unf_lport, event);
- } else {
- /* P2P toplogy mode: Do nothing */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) with topo(0x%x) need do nothing",
- unf_lport->port_id, act_topo);
- }
-
- return ret;
-}
-
-static u32 unf_disc_stop(void *lport)
-{
- /* Call by GID_ACC processer */
- struct unf_lport *unf_lport = NULL;
- struct unf_lport *root_lport = NULL;
- struct unf_rport *sns_port = NULL;
- struct unf_disc_rport *disc_rport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_disc *root_disc = NULL;
- struct list_head *node = NULL;
- ulong flag = 0;
- u32 ret = RETURN_OK;
- u32 nport_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- unf_lport = (struct unf_lport *)lport;
- disc = &unf_lport->disc;
- root_lport = (struct unf_lport *)unf_lport->root_lport;
- root_disc = &root_lport->disc;
-
- /* Get R_Port for Directory server */
- sns_port = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_DIR_SERV);
- if (!sns_port) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find fabric RPort(0xfffffc) failed",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* for R_Port from disc pool busy list */
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- if (list_empty(&disc->disc_rport_mgr.list_disc_rports_busy)) {
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- return RETURN_OK;
- }
-
- node = UNF_OS_LIST_NEXT(&disc->disc_rport_mgr.list_disc_rports_busy);
- do {
- /* Delete from Disc busy list */
- disc_rport = list_entry(node, struct unf_disc_rport, entry_rport);
- nport_id = disc_rport->nport_id;
- list_del_init(node);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- /* Add back to (free) Disc R_Port pool (list) */
- spin_lock_irqsave(&root_disc->rport_busy_pool_lock, flag);
- list_add_tail(node, &root_disc->disc_rport_mgr.list_disc_rports_pool);
- spin_unlock_irqrestore(&root_disc->rport_busy_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Port(0x%x_0x%x) remove nportid:0x%x from rportbusy list",
- unf_lport->port_id, unf_lport->nport_id, disc_rport->nport_id);
- /* Send GNN_ID to Name Server */
- ret = unf_get_and_post_disc_event(unf_lport, sns_port, nport_id,
- UNF_DISC_GET_NODE_NAME);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- unf_lport->nport_id, UNF_DISC_GET_NODE_NAME, nport_id);
-
- /* NOTE: go to next stage */
- unf_rcv_gnn_id_rsp_unknown(unf_lport, sns_port, nport_id);
- }
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- node = UNF_OS_LIST_NEXT(&disc->disc_rport_mgr.list_disc_rports_busy);
- } while (node != &disc->disc_rport_mgr.list_disc_rports_busy);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- return ret;
-}
-
-static u32 unf_init_rport_pool(struct unf_lport *lport)
-{
- struct unf_rport_pool *rport_pool = NULL;
- struct unf_rport *unf_rport = NULL;
- u32 ret = RETURN_OK;
- u32 i = 0;
- u32 bitmap_cnt = 0;
- ulong flag = 0;
- u32 max_login = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* Init RPort Pool info */
- rport_pool = &lport->rport_pool;
- max_login = lport->low_level_func.lport_cfg_items.max_login;
- rport_pool->rport_pool_completion = NULL;
- rport_pool->rport_pool_count = max_login;
- spin_lock_init(&rport_pool->rport_free_pool_lock);
- INIT_LIST_HEAD(&rport_pool->list_rports_pool); /* free RPort pool */
-
- /* 1. Alloc RPort Pool buffer/resource (memory) */
- rport_pool->rport_pool_add = vmalloc((size_t)(max_login * sizeof(struct unf_rport)));
- if (!rport_pool->rport_pool_add) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) allocate RPort(s) resource failed", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- memset(rport_pool->rport_pool_add, 0, (max_login * sizeof(struct unf_rport)));
-
- /* 2. Alloc R_Port Pool bitmap */
- bitmap_cnt = (lport->low_level_func.support_max_rport) / BITS_PER_LONG + 1;
- rport_pool->rpi_bitmap = vmalloc((size_t)(bitmap_cnt * sizeof(ulong)));
- if (!rport_pool->rpi_bitmap) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) allocate RPort Bitmap failed", lport->port_id);
-
- vfree(rport_pool->rport_pool_add);
- rport_pool->rport_pool_add = NULL;
- return UNF_RETURN_ERROR;
- }
- memset(rport_pool->rpi_bitmap, 0, (bitmap_cnt * sizeof(ulong)));
-
- /* 3. Rport resource Management: Add Rports (buffer) to Rport Pool List
- */
- unf_rport = (struct unf_rport *)(rport_pool->rport_pool_add);
- spin_lock_irqsave(&rport_pool->rport_free_pool_lock, flag);
- for (i = 0; i < rport_pool->rport_pool_count; i++) {
- spin_lock_init(&unf_rport->rport_state_lock);
- list_add_tail(&unf_rport->entry_rport, &rport_pool->list_rports_pool);
- sema_init(&unf_rport->task_sema, 0);
- unf_rport++;
- }
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flag);
-
- return ret;
-}
-
-static void unf_free_rport_pool(struct unf_lport *lport)
-{
- struct unf_rport_pool *rport_pool = NULL;
- bool wait = false;
- ulong flag = 0;
- u32 remain = 0;
- u64 timeout = 0;
- u32 max_login = 0;
- u32 i;
- struct unf_rport *unf_rport = NULL;
- struct completion rport_pool_completion;
-
- init_completion(&rport_pool_completion);
- FC_CHECK_RETURN_VOID(lport);
-
- rport_pool = &lport->rport_pool;
- max_login = lport->low_level_func.lport_cfg_items.max_login;
-
- spin_lock_irqsave(&rport_pool->rport_free_pool_lock, flag);
- if (rport_pool->rport_pool_count != max_login) {
- rport_pool->rport_pool_completion = &rport_pool_completion;
- remain = max_login - rport_pool->rport_pool_count;
- wait = true;
- }
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flag);
-
- if (wait) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) begin to wait for RPort pool completion, remain(0x%x)",
- lport->port_id, remain);
-
- unf_show_all_rport(lport);
-
- timeout = wait_for_completion_timeout(rport_pool->rport_pool_completion,
- msecs_to_jiffies(UNF_OS_REMOVE_CARD_TIMEOUT));
- if (timeout == 0)
- unf_cm_mark_dirty_mem(lport, UNF_LPORT_DIRTY_FLAG_RPORT_POOL_DIRTY);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) wait for RPort pool completion end",
- lport->port_id);
-
- spin_lock_irqsave(&rport_pool->rport_free_pool_lock, flag);
- rport_pool->rport_pool_completion = NULL;
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flag);
- }
-
- unf_rport = (struct unf_rport *)(rport_pool->rport_pool_add);
- for (i = 0; i < rport_pool->rport_pool_count; i++) {
- if (!unf_rport)
- break;
- unf_rport++;
- }
-
- if ((lport->dirty_flag & UNF_LPORT_DIRTY_FLAG_RPORT_POOL_DIRTY) == 0) {
- vfree(rport_pool->rport_pool_add);
- rport_pool->rport_pool_add = NULL;
- vfree(rport_pool->rpi_bitmap);
- rport_pool->rpi_bitmap = NULL;
- }
-}
-
-static void unf_init_rscn_node(struct unf_port_id_page *port_id_page)
-{
- FC_CHECK_RETURN_VOID(port_id_page);
-
- port_id_page->addr_format = 0;
- port_id_page->event_qualifier = 0;
- port_id_page->reserved = 0;
- port_id_page->port_id_area = 0;
- port_id_page->port_id_domain = 0;
- port_id_page->port_id_port = 0;
-}
-
-struct unf_port_id_page *unf_get_free_rscn_node(void *rscn_mg)
-{
- /* Call by Save RSCN Port_ID */
- struct unf_rscn_mgr *rscn_mgr = NULL;
- struct unf_port_id_page *port_id_node = NULL;
- struct list_head *list_node = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(rscn_mg, NULL);
- rscn_mgr = (struct unf_rscn_mgr *)rscn_mg;
-
- spin_lock_irqsave(&rscn_mgr->rscn_id_list_lock, flag);
- if (list_empty(&rscn_mgr->list_free_rscn_page)) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_WARN,
- "[warn]No RSCN node anymore");
-
- spin_unlock_irqrestore(&rscn_mgr->rscn_id_list_lock, flag);
- return NULL;
- }
-
- /* Get from list_free_RSCN_page */
- list_node = UNF_OS_LIST_NEXT(&rscn_mgr->list_free_rscn_page);
- list_del(list_node);
- rscn_mgr->free_rscn_count--;
- port_id_node = list_entry(list_node, struct unf_port_id_page, list_node_rscn);
- unf_init_rscn_node(port_id_node);
- spin_unlock_irqrestore(&rscn_mgr->rscn_id_list_lock, flag);
-
- return port_id_node;
-}
-
-static void unf_release_rscn_node(void *rscn_mg, void *port_id_node)
-{
- /* Call by RSCN GID_ACC */
- struct unf_rscn_mgr *rscn_mgr = NULL;
- struct unf_port_id_page *port_id_page = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(rscn_mg);
- FC_CHECK_RETURN_VOID(port_id_node);
- rscn_mgr = (struct unf_rscn_mgr *)rscn_mg;
- port_id_page = (struct unf_port_id_page *)port_id_node;
-
- /* Back to list_free_RSCN_page */
- spin_lock_irqsave(&rscn_mgr->rscn_id_list_lock, flag);
- rscn_mgr->free_rscn_count++;
- unf_init_rscn_node(port_id_page);
- list_add_tail(&port_id_page->list_node_rscn, &rscn_mgr->list_free_rscn_page);
- spin_unlock_irqrestore(&rscn_mgr->rscn_id_list_lock, flag);
-}
-
-static u32 unf_init_rscn_pool(struct unf_lport *lport)
-{
- struct unf_rscn_mgr *rscn_mgr = NULL;
- struct unf_port_id_page *port_id_page = NULL;
- u32 ret = RETURN_OK;
- u32 i = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- rscn_mgr = &lport->disc.rscn_mgr;
-
- /* Get RSCN Pool buffer */
- rscn_mgr->rscn_pool_add = vmalloc(UNF_LIST_RSCN_PAGE_CNT * sizeof(struct unf_port_id_page));
- if (!rscn_mgr->rscn_pool_add) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) allocate RSCN pool failed", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- memset(rscn_mgr->rscn_pool_add, 0,
- UNF_LIST_RSCN_PAGE_CNT * sizeof(struct unf_port_id_page));
-
- spin_lock_irqsave(&rscn_mgr->rscn_id_list_lock, flag);
- port_id_page = (struct unf_port_id_page *)(rscn_mgr->rscn_pool_add);
- for (i = 0; i < UNF_LIST_RSCN_PAGE_CNT; i++) {
- /* Add tail to list_free_RSCN_page */
- list_add_tail(&port_id_page->list_node_rscn, &rscn_mgr->list_free_rscn_page);
-
- rscn_mgr->free_rscn_count++;
- port_id_page++;
- }
- spin_unlock_irqrestore(&rscn_mgr->rscn_id_list_lock, flag);
-
- return ret;
-}
-
-static void unf_freerscn_pool(struct unf_lport *lport)
-{
- struct unf_disc *disc = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- disc = &lport->disc;
- if (disc->rscn_mgr.rscn_pool_add) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_INFO, "[info]Port(0x%x) free RSCN pool", lport->nport_id);
-
- vfree(disc->rscn_mgr.rscn_pool_add);
- disc->rscn_mgr.rscn_pool_add = NULL;
- }
-}
-
-static u32 unf_init_rscn_mgr(struct unf_lport *lport)
-{
- struct unf_rscn_mgr *rscn_mgr = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- rscn_mgr = &lport->disc.rscn_mgr;
-
- INIT_LIST_HEAD(&rscn_mgr->list_free_rscn_page); /* free RSCN page list */
- INIT_LIST_HEAD(&rscn_mgr->list_using_rscn_page); /* busy RSCN page list */
- spin_lock_init(&rscn_mgr->rscn_id_list_lock);
- rscn_mgr->free_rscn_count = 0;
- rscn_mgr->unf_get_free_rscn_node = unf_get_free_rscn_node;
- rscn_mgr->unf_release_rscn_node = unf_release_rscn_node;
-
- ret = unf_init_rscn_pool(lport);
- return ret;
-}
-
-static void unf_destroy_rscn_mngr(struct unf_lport *lport)
-{
- struct unf_rscn_mgr *rscn_mgr = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- rscn_mgr = &lport->disc.rscn_mgr;
-
- rscn_mgr->free_rscn_count = 0;
- rscn_mgr->unf_get_free_rscn_node = NULL;
- rscn_mgr->unf_release_rscn_node = NULL;
-
- unf_freerscn_pool(lport);
-}
-
-static u32 unf_init_disc_rport_pool(struct unf_lport *lport)
-{
- struct unf_disc_rport_mg *disc_mgr = NULL;
- struct unf_disc_rport *disc_rport = NULL;
- u32 i = 0;
- u32 max_log_in = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- max_log_in = lport->low_level_func.lport_cfg_items.max_login;
- disc_mgr = &lport->disc.disc_rport_mgr;
-
- /* Alloc R_Port Disc Pool buffer */
- disc_mgr->disc_pool_add =
- vmalloc(max_log_in * sizeof(struct unf_disc_rport));
- if (!disc_mgr->disc_pool_add) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) allocate disc RPort pool failed", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- memset(disc_mgr->disc_pool_add, 0, (max_log_in * sizeof(struct unf_disc_rport)));
-
- /* Add R_Port to (free) DISC R_Port Pool */
- spin_lock_irqsave(&lport->disc.rport_busy_pool_lock, flag);
- disc_rport = (struct unf_disc_rport *)(disc_mgr->disc_pool_add);
- for (i = 0; i < max_log_in; i++) {
- /* Add tail to list_disc_Rport_pool */
- list_add_tail(&disc_rport->entry_rport, &disc_mgr->list_disc_rports_pool);
-
- disc_rport++;
- }
- spin_unlock_irqrestore(&lport->disc.rport_busy_pool_lock, flag);
-
- return RETURN_OK;
-}
-
-static void unf_free_disc_rport_pool(struct unf_lport *lport)
-{
- struct unf_disc *disc = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- disc = &lport->disc;
- if (disc->disc_rport_mgr.disc_pool_add) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_INFO, "[info]Port(0x%x) free disc RPort pool", lport->port_id);
-
- vfree(disc->disc_rport_mgr.disc_pool_add);
- disc->disc_rport_mgr.disc_pool_add = NULL;
- }
-}
-
-int unf_discover_port_info(void *arg_in)
-{
- struct unf_disc_gs_event_info *disc_gs_info = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
-
- FC_CHECK_RETURN_VALUE(arg_in, UNF_RETURN_ERROR);
-
- disc_gs_info = (struct unf_disc_gs_event_info *)arg_in;
- unf_lport = (struct unf_lport *)disc_gs_info->lport;
- unf_rport = (struct unf_rport *)disc_gs_info->rport;
-
- switch (disc_gs_info->type) {
- case UNF_DISC_GET_PORT_NAME:
- ret = unf_send_gpn_id(unf_lport, unf_rport, disc_gs_info->rport_id);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send GPN_ID failed RPort(0x%x)",
- unf_lport->nport_id, disc_gs_info->rport_id);
- unf_rcv_gpn_id_rsp_unknown(unf_lport, disc_gs_info->rport_id);
- }
- break;
- case UNF_DISC_GET_FEATURE:
- ret = unf_send_gff_id(unf_lport, unf_rport, disc_gs_info->rport_id);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send GFF_ID failed to get RPort(0x%x)'s feature",
- unf_lport->port_id, disc_gs_info->rport_id);
-
- unf_rcv_gff_id_rsp_unknown(unf_lport, disc_gs_info->rport_id);
- }
- break;
- case UNF_DISC_GET_NODE_NAME:
- ret = unf_send_gnn_id(unf_lport, unf_rport, disc_gs_info->rport_id);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) GNN_ID send failed with NPort ID(0x%x)",
- unf_lport->port_id, disc_gs_info->rport_id);
-
- /* NOTE: Continue to next stage */
- unf_rcv_gnn_id_rsp_unknown(unf_lport, unf_rport, disc_gs_info->rport_id);
- }
- break;
- default:
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]Send GS packet type(0x%x) is unknown", disc_gs_info->type);
- }
-
- kfree(disc_gs_info);
-
- return (int)ret;
-}
-
-u32 unf_get_and_post_disc_event(void *lport, void *sns_port, u32 nport_id,
- enum unf_disc_type type)
-{
- struct unf_disc_gs_event_info *disc_gs_info = NULL;
- ulong flag = 0;
- struct unf_lport *root_lport = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_disc_manage_info *disc_info = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(sns_port, UNF_RETURN_ERROR);
-
- unf_lport = (struct unf_lport *)lport;
-
- if (unf_lport->link_up == UNF_PORT_LINK_DOWN)
- return RETURN_OK;
-
- root_lport = unf_lport->root_lport;
- disc_info = &root_lport->disc.disc_thread_info;
-
- if (disc_info->thread_exit)
- return RETURN_OK;
-
- disc_gs_info = kmalloc(sizeof(struct unf_disc_gs_event_info), GFP_ATOMIC);
- if (!disc_gs_info)
- return UNF_RETURN_ERROR;
-
- disc_gs_info->type = type;
- disc_gs_info->lport = unf_lport;
- disc_gs_info->rport = sns_port;
- disc_gs_info->rport_id = nport_id;
-
- INIT_LIST_HEAD(&disc_gs_info->list_entry);
-
- spin_lock_irqsave(&disc_info->disc_event_list_lock, flag);
- list_add_tail(&disc_gs_info->list_entry, &disc_info->list_head);
- spin_unlock_irqrestore(&disc_info->disc_event_list_lock, flag);
- wake_up_process(disc_info->thread);
- return RETURN_OK;
-}
-
-static int unf_disc_event_process(void *arg)
-{
- struct list_head *node = NULL;
- struct unf_disc_gs_event_info *disc_gs_info = NULL;
- ulong flags = 0;
- struct unf_disc *disc = (struct unf_disc *)arg;
- struct unf_disc_manage_info *disc_info = &disc->disc_thread_info;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) enter discovery thread.", disc->lport->port_id);
-
- while (!kthread_should_stop()) {
- if (disc_info->thread_exit)
- break;
-
- spin_lock_irqsave(&disc_info->disc_event_list_lock, flags);
- if ((list_empty(&disc_info->list_head)) ||
- (atomic_read(&disc_info->disc_contrl_size) == 0)) {
- spin_unlock_irqrestore(&disc_info->disc_event_list_lock, flags);
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout((long)msecs_to_jiffies(UNF_S_TO_MS));
- } else {
- node = UNF_OS_LIST_NEXT(&disc_info->list_head);
- list_del_init(node);
- disc_gs_info = list_entry(node, struct unf_disc_gs_event_info, list_entry);
- spin_unlock_irqrestore(&disc_info->disc_event_list_lock, flags);
- unf_discover_port_info(disc_gs_info);
- }
- }
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MAJOR,
- "Port(0x%x) discovery thread over.", disc->lport->port_id);
-
- return RETURN_OK;
-}
-
-void unf_flush_disc_event(void *disc, void *vport)
-{
- struct unf_disc *unf_disc = (struct unf_disc *)disc;
- struct unf_disc_manage_info *disc_info = NULL;
- struct list_head *list = NULL;
- struct list_head *list_tmp = NULL;
- struct unf_disc_gs_event_info *disc_gs_info = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(disc);
-
- disc_info = &unf_disc->disc_thread_info;
-
- spin_lock_irqsave(&disc_info->disc_event_list_lock, flag);
- list_for_each_safe(list, list_tmp, &disc_info->list_head) {
- disc_gs_info = list_entry(list, struct unf_disc_gs_event_info, list_entry);
-
- if (!vport || disc_gs_info->lport == vport) {
- list_del_init(&disc_gs_info->list_entry);
- kfree(disc_gs_info);
- }
- }
-
- if (!vport)
- atomic_set(&disc_info->disc_contrl_size, UNF_MAX_GS_SEND_NUM);
- spin_unlock_irqrestore(&disc_info->disc_event_list_lock, flag);
-}
-
-void unf_disc_ctrl_size_inc(void *lport, u32 cmnd)
-{
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport = (struct unf_lport *)lport;
- unf_lport = unf_lport->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- if (atomic_read(&unf_lport->disc.disc_thread_info.disc_contrl_size) ==
- UNF_MAX_GS_SEND_NUM)
- return;
-
- if (cmnd == NS_GPN_ID || cmnd == NS_GNN_ID || cmnd == NS_GFF_ID)
- atomic_inc(&unf_lport->disc.disc_thread_info.disc_contrl_size);
-}
-
-void unf_destroy_disc_thread(void *disc)
-{
- struct unf_disc_manage_info *disc_info = NULL;
- struct unf_disc *unf_disc = (struct unf_disc *)disc;
-
- FC_CHECK_RETURN_VOID(unf_disc);
-
- disc_info = &unf_disc->disc_thread_info;
-
- disc_info->thread_exit = true;
- unf_flush_disc_event(unf_disc, NULL);
-
- wake_up_process(disc_info->thread);
- kthread_stop(disc_info->thread);
- disc_info->thread = NULL;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) destroy discovery thread succeed.",
- unf_disc->lport->port_id);
-}
-
-u32 unf_crerate_disc_thread(void *disc)
-{
- struct unf_disc_manage_info *disc_info = NULL;
- struct unf_disc *unf_disc = (struct unf_disc *)disc;
-
- FC_CHECK_RETURN_VALUE(unf_disc, UNF_RETURN_ERROR);
-
- /* If the thread cannot be found, apply for a new thread. */
- disc_info = &unf_disc->disc_thread_info;
-
- memset(disc_info, 0, sizeof(struct unf_disc_manage_info));
-
- INIT_LIST_HEAD(&disc_info->list_head);
- spin_lock_init(&disc_info->disc_event_list_lock);
- atomic_set(&disc_info->disc_contrl_size, UNF_MAX_GS_SEND_NUM);
-
- disc_info->thread_exit = false;
- disc_info->thread = kthread_create(unf_disc_event_process, unf_disc, "%x_DiscT",
- unf_disc->lport->port_id);
-
- if (IS_ERR(disc_info->thread) || !disc_info->thread) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) creat discovery thread(0x%p) unsuccessful.",
- unf_disc->lport->port_id, disc_info->thread);
-
- return UNF_RETURN_ERROR;
- }
-
- wake_up_process(disc_info->thread);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) creat discovery thread succeed.", unf_disc->lport->port_id);
-
- return RETURN_OK;
-}
-
-void unf_disc_ref_cnt_dec(struct unf_disc *disc)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(disc);
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- if (atomic_dec_and_test(&disc->disc_ref_cnt)) {
- if (disc->disc_completion)
- complete(disc->disc_completion);
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-}
-
-void unf_wait_disc_complete(struct unf_lport *lport)
-{
- struct unf_disc *disc = NULL;
- bool wait = false;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- u64 time_out = 0;
-
- struct completion disc_completion;
-
- init_completion(&disc_completion);
- disc = &lport->disc;
-
- UNF_DELAYED_WORK_SYNC(ret, (lport->port_id), (&disc->disc_work),
- "Disc_work");
- if (ret == RETURN_OK)
- unf_disc_ref_cnt_dec(disc);
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- if (atomic_read(&disc->disc_ref_cnt) != 0) {
- disc->disc_completion = &disc_completion;
- wait = true;
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- if (wait) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) begin to wait for discover completion",
- lport->port_id);
-
- time_out =
- wait_for_completion_timeout(disc->disc_completion,
- msecs_to_jiffies(UNF_OS_REMOVE_CARD_TIMEOUT));
- if (time_out == 0)
- unf_cm_mark_dirty_mem(lport, UNF_LPORT_DIRTY_FLAG_DISC_DIRTY);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) wait for discover completion end", lport->port_id);
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- disc->disc_completion = NULL;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- }
-}
-
-void unf_disc_mgr_destroy(void *lport)
-{
- struct unf_disc *disc = NULL;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- unf_lport = (struct unf_lport *)lport;
-
- disc = &unf_lport->disc;
- disc->retry_count = 0;
- disc->disc_temp.unf_disc_start = NULL;
- disc->disc_temp.unf_disc_stop = NULL;
- disc->disc_temp.unf_disc_callback = NULL;
-
- unf_free_disc_rport_pool(unf_lport);
- unf_destroy_rscn_mngr(unf_lport);
- unf_wait_disc_complete(unf_lport);
-
- if (unf_lport->root_lport != unf_lport)
- return;
-
- unf_destroy_disc_thread(disc);
- unf_free_rport_pool(unf_lport);
- unf_lport->destroy_step = UNF_LPORT_DESTROY_STEP_6_DESTROY_DISC_MGR;
-}
-
-void unf_disc_error_recovery(void *lport)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_disc *disc = NULL;
- ulong delay = 0;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport = (struct unf_lport *)lport;
- disc = &unf_lport->disc;
-
- unf_rport = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_DIR_SERV);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) find RPort failed", unf_lport->port_id);
- return;
- }
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
-
- /* Delay work is pending */
- if (delayed_work_pending(&disc->disc_work)) {
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) disc_work is running and do nothing",
- unf_lport->port_id);
- return;
- }
-
- /* Continue to retry */
- if (disc->retry_count < disc->max_retry_count) {
- disc->retry_count++;
- delay = (ulong)unf_lport->ed_tov;
- if (queue_delayed_work(unf_wq, &disc->disc_work,
- (ulong)msecs_to_jiffies((u32)delay)))
- atomic_inc(&disc->disc_ref_cnt);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- } else {
- /* Go to next stage */
- if (disc->states == UNF_DISC_ST_GIDPT_WAIT) {
- /* GID_PT_WAIT --->>> Send GID_FT */
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_RETRY_TIMEOUT);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- while ((ret != RETURN_OK) &&
- (disc->retry_count < disc->max_retry_count)) {
- ret = unf_send_gid_ft(unf_lport, unf_rport);
- disc->retry_count++;
- }
- } else if (disc->states == UNF_DISC_ST_GIDFT_WAIT) {
- /* GID_FT_WAIT --->>> Send LOGO */
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_RETRY_TIMEOUT);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- } else {
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- }
- }
-}
-
-enum unf_disc_state unf_disc_stat_start(enum unf_disc_state old_state,
- enum unf_disc_event event)
-{
- enum unf_disc_state next_state = UNF_DISC_ST_END;
-
- if (event == UNF_EVENT_DISC_NORMAL_ENTER)
- next_state = UNF_DISC_ST_GIDPT_WAIT;
- else
- next_state = old_state;
-
- return next_state;
-}
-
-enum unf_disc_state unf_disc_stat_gid_pt_wait(enum unf_disc_state old_state,
- enum unf_disc_event event)
-{
- enum unf_disc_state next_state = UNF_DISC_ST_END;
-
- switch (event) {
- case UNF_EVENT_DISC_FAILED:
- next_state = UNF_DISC_ST_GIDPT_WAIT;
- break;
-
- case UNF_EVENT_DISC_RETRY_TIMEOUT:
- next_state = UNF_DISC_ST_GIDFT_WAIT;
- break;
-
- case UNF_EVENT_DISC_SUCCESS:
- next_state = UNF_DISC_ST_END;
- break;
-
- case UNF_EVENT_DISC_LINKDOWN:
- next_state = UNF_DISC_ST_START;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-enum unf_disc_state unf_disc_stat_gid_ft_wait(enum unf_disc_state old_state,
- enum unf_disc_event event)
-{
- enum unf_disc_state next_state = UNF_DISC_ST_END;
-
- switch (event) {
- case UNF_EVENT_DISC_FAILED:
- next_state = UNF_DISC_ST_GIDFT_WAIT;
- break;
-
- case UNF_EVENT_DISC_RETRY_TIMEOUT:
- next_state = UNF_DISC_ST_END;
- break;
-
- case UNF_EVENT_DISC_LINKDOWN:
- next_state = UNF_DISC_ST_START;
- break;
-
- case UNF_EVENT_DISC_SUCCESS:
- next_state = UNF_DISC_ST_END;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-enum unf_disc_state unf_disc_stat_end(enum unf_disc_state old_state, enum unf_disc_event event)
-{
- enum unf_disc_state next_state = UNF_DISC_ST_END;
-
- if (event == UNF_EVENT_DISC_LINKDOWN)
- next_state = UNF_DISC_ST_START;
- else
- next_state = old_state;
-
- return next_state;
-}
-
-void unf_disc_state_ma(struct unf_lport *lport, enum unf_disc_event event)
-{
- struct unf_disc *disc = NULL;
- enum unf_disc_state old_state = UNF_DISC_ST_START;
- enum unf_disc_state next_state = UNF_DISC_ST_START;
-
- FC_CHECK_RETURN_VOID(lport);
-
- disc = &lport->disc;
- old_state = disc->states;
-
- switch (disc->states) {
- case UNF_DISC_ST_START:
- next_state = unf_disc_stat_start(old_state, event);
- break;
-
- case UNF_DISC_ST_GIDPT_WAIT:
- next_state = unf_disc_stat_gid_pt_wait(old_state, event);
- break;
-
- case UNF_DISC_ST_GIDFT_WAIT:
- next_state = unf_disc_stat_gid_ft_wait(old_state, event);
- break;
-
- case UNF_DISC_ST_END:
- next_state = unf_disc_stat_end(old_state, event);
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- unf_set_disc_state(disc, next_state);
-}
-
-static void unf_lport_disc_timeout(struct work_struct *work)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_disc *disc = NULL;
- enum unf_disc_state state = UNF_DISC_ST_END;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(work);
-
- disc = container_of(work, struct unf_disc, disc_work.work);
- if (!disc) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Get discover pointer failed");
-
- return;
- }
-
- unf_lport = disc->lport;
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Find Port by discovery work failed");
-
- unf_disc_ref_cnt_dec(disc);
- return;
- }
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- state = disc->states;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- unf_rport = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_DIR_SERV); /* 0xfffffc */
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find fabric RPort failed", unf_lport->port_id);
-
- unf_disc_ref_cnt_dec(disc);
- return;
- }
-
- switch (state) {
- case UNF_DISC_ST_START:
- break;
-
- case UNF_DISC_ST_GIDPT_WAIT:
- (void)unf_send_gid_pt(unf_lport, unf_rport);
- break;
-
- case UNF_DISC_ST_GIDFT_WAIT:
- (void)unf_send_gid_ft(unf_lport, unf_rport);
- break;
-
- case UNF_DISC_ST_END:
- break;
-
- default:
- break;
- }
-
- unf_disc_ref_cnt_dec(disc);
-}
-
-u32 unf_init_disc_mgr(struct unf_lport *lport)
-{
- struct unf_disc *disc = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- disc = &lport->disc;
- disc->max_retry_count = UNF_DISC_RETRY_TIMES;
- disc->retry_count = 0;
- disc->disc_flag = UNF_DISC_NONE;
- INIT_LIST_HEAD(&disc->list_busy_rports);
- INIT_LIST_HEAD(&disc->list_delete_rports);
- INIT_LIST_HEAD(&disc->list_destroy_rports);
- spin_lock_init(&disc->rport_busy_pool_lock);
-
- disc->disc_rport_mgr.disc_pool_add = NULL;
- INIT_LIST_HEAD(&disc->disc_rport_mgr.list_disc_rports_pool);
- INIT_LIST_HEAD(&disc->disc_rport_mgr.list_disc_rports_busy);
-
- disc->disc_completion = NULL;
- disc->lport = lport;
- INIT_DELAYED_WORK(&disc->disc_work, unf_lport_disc_timeout);
- disc->disc_temp.unf_disc_start = unf_disc_start;
- disc->disc_temp.unf_disc_stop = unf_disc_stop;
- disc->disc_temp.unf_disc_callback = NULL;
- atomic_set(&disc->disc_ref_cnt, 0);
-
- /* Init RSCN Manager */
- ret = unf_init_rscn_mgr(lport);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
-
- if (lport->root_lport != lport)
- return ret;
-
- ret = unf_crerate_disc_thread(disc);
- if (ret != RETURN_OK) {
- unf_destroy_rscn_mngr(lport);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Init R_Port free Pool */
- ret = unf_init_rport_pool(lport);
- if (ret != RETURN_OK) {
- unf_destroy_disc_thread(disc);
- unf_destroy_rscn_mngr(lport);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Init R_Port free disc Pool */
- ret = unf_init_disc_rport_pool(lport);
- if (ret != RETURN_OK) {
- unf_destroy_disc_thread(disc);
- unf_free_rport_pool(lport);
- unf_destroy_rscn_mngr(lport);
-
- return UNF_RETURN_ERROR;
- }
-
- return ret;
-}
diff --git a/drivers/scsi/spfc/common/unf_disc.h b/drivers/scsi/spfc/common/unf_disc.h
deleted file mode 100644
index 7ecad3eec424..000000000000
--- a/drivers/scsi/spfc/common/unf_disc.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_DISC_H
-#define UNF_DISC_H
-
-#include "unf_type.h"
-
-#define UNF_DISC_RETRY_TIMES 3
-#define UNF_DISC_NONE 0
-#define UNF_DISC_FABRIC 1
-#define UNF_DISC_LOOP 2
-
-enum unf_disc_state {
- UNF_DISC_ST_START = 0x3000,
- UNF_DISC_ST_GIDPT_WAIT,
- UNF_DISC_ST_GIDFT_WAIT,
- UNF_DISC_ST_END
-};
-
-enum unf_disc_event {
- UNF_EVENT_DISC_NORMAL_ENTER = 0x8000,
- UNF_EVENT_DISC_FAILED = 0x8001,
- UNF_EVENT_DISC_SUCCESS = 0x8002,
- UNF_EVENT_DISC_RETRY_TIMEOUT = 0x8003,
- UNF_EVENT_DISC_LINKDOWN = 0x8004
-};
-
-enum unf_disc_type {
- UNF_DISC_GET_PORT_NAME = 0,
- UNF_DISC_GET_NODE_NAME,
- UNF_DISC_GET_FEATURE
-};
-
-struct unf_disc_gs_event_info {
- void *lport;
- void *rport;
- u32 rport_id;
- enum unf_disc_type type;
- struct list_head list_entry;
-};
-
-u32 unf_get_and_post_disc_event(void *lport, void *sns_port, u32 nport_id,
- enum unf_disc_type type);
-
-void unf_flush_disc_event(void *disc, void *vport);
-void unf_disc_ctrl_size_inc(void *lport, u32 cmnd);
-void unf_disc_error_recovery(void *lport);
-void unf_disc_mgr_destroy(void *lport);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_event.c b/drivers/scsi/spfc/common/unf_event.c
deleted file mode 100644
index cf51c31ca4a3..000000000000
--- a/drivers/scsi/spfc/common/unf_event.c
+++ /dev/null
@@ -1,517 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_event.h"
-#include "unf_log.h"
-#include "unf_common.h"
-#include "unf_lport.h"
-
-struct unf_event_list fc_event_list;
-struct unf_global_event_queue global_event_queue;
-
-/* Max global event node */
-#define UNF_MAX_GLOBAL_ENENT_NODE 24
-
-u32 unf_init_event_msg(struct unf_lport *lport)
-{
- struct unf_event_mgr *event_mgr = NULL;
- struct unf_cm_event_report *event_node = NULL;
- u32 ret = RETURN_OK;
- u32 index = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- event_mgr = &lport->event_mgr;
-
- /* Get and Initial Event Node resource */
- event_mgr->mem_add = vmalloc((size_t)event_mgr->free_event_count *
- sizeof(struct unf_cm_event_report));
- if (!event_mgr->mem_add) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) allocate event manager failed",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- memset(event_mgr->mem_add, 0,
- ((size_t)event_mgr->free_event_count * sizeof(struct unf_cm_event_report)));
-
- event_node = (struct unf_cm_event_report *)(event_mgr->mem_add);
-
- spin_lock_irqsave(&event_mgr->port_event_lock, flag);
- for (index = 0; index < event_mgr->free_event_count; index++) {
- INIT_LIST_HEAD(&event_node->list_entry);
- list_add_tail(&event_node->list_entry, &event_mgr->list_free_event);
- event_node++;
- }
- spin_unlock_irqrestore(&event_mgr->port_event_lock, flag);
-
- return ret;
-}
-
-static void unf_del_event_center_fun_op(struct unf_lport *lport)
-{
- struct unf_event_mgr *event_mgr = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- event_mgr = &lport->event_mgr;
- event_mgr->unf_get_free_event_func = NULL;
- event_mgr->unf_release_event = NULL;
- event_mgr->unf_post_event_func = NULL;
-}
-
-void unf_init_event_node(struct unf_cm_event_report *event_node)
-{
- FC_CHECK_RETURN_VOID(event_node);
-
- event_node->event = UNF_EVENT_TYPE_REQUIRE;
- event_node->event_asy_flag = UNF_EVENT_ASYN;
- event_node->delay_times = 0;
- event_node->para_in = NULL;
- event_node->para_out = NULL;
- event_node->result = 0;
- event_node->lport = NULL;
- event_node->unf_event_task = NULL;
-}
-
-struct unf_cm_event_report *unf_get_free_event_node(void *lport)
-{
- struct unf_event_mgr *event_mgr = NULL;
- struct unf_cm_event_report *event_node = NULL;
- struct list_head *list_node = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- unf_lport = (struct unf_lport *)lport;
- unf_lport = unf_lport->root_lport;
-
- if (unlikely(atomic_read(&unf_lport->lport_no_operate_flag) == UNF_LPORT_NOP))
- return NULL;
-
- event_mgr = &unf_lport->event_mgr;
-
- spin_lock_irqsave(&event_mgr->port_event_lock, flags);
- if (list_empty(&event_mgr->list_free_event)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) have no event node anymore",
- unf_lport->port_id);
-
- spin_unlock_irqrestore(&event_mgr->port_event_lock, flags);
- return NULL;
- }
-
- list_node = UNF_OS_LIST_NEXT(&event_mgr->list_free_event);
- list_del(list_node);
- event_mgr->free_event_count--;
- event_node = list_entry(list_node, struct unf_cm_event_report, list_entry);
-
- unf_init_event_node(event_node);
- spin_unlock_irqrestore(&event_mgr->port_event_lock, flags);
-
- return event_node;
-}
-
-void unf_post_event(void *lport, void *event_node)
-{
- struct unf_cm_event_report *cm_event_node = NULL;
- struct unf_chip_manage_info *card_thread_info = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(event_node);
- cm_event_node = (struct unf_cm_event_report *)event_node;
-
- /* If null, post to global event center */
- if (!lport) {
- spin_lock_irqsave(&fc_event_list.fc_event_list_lock, flags);
- fc_event_list.list_num++;
- list_add_tail(&cm_event_node->list_entry, &fc_event_list.list_head);
- spin_unlock_irqrestore(&fc_event_list.fc_event_list_lock, flags);
-
- wake_up_process(event_task_thread);
- } else {
- unf_lport = (struct unf_lport *)lport;
- unf_lport = unf_lport->root_lport;
- card_thread_info = unf_lport->chip_info;
-
- /* Post to global event center */
- if (!card_thread_info) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_WARN,
- "[warn]Port(0x%x) has strange event with type(0x%x)",
- unf_lport->nport_id, cm_event_node->event);
-
- spin_lock_irqsave(&fc_event_list.fc_event_list_lock, flags);
- fc_event_list.list_num++;
- list_add_tail(&cm_event_node->list_entry, &fc_event_list.list_head);
- spin_unlock_irqrestore(&fc_event_list.fc_event_list_lock, flags);
-
- wake_up_process(event_task_thread);
- } else {
- spin_lock_irqsave(&card_thread_info->chip_event_list_lock, flags);
- card_thread_info->list_num++;
- list_add_tail(&cm_event_node->list_entry, &card_thread_info->list_head);
- spin_unlock_irqrestore(&card_thread_info->chip_event_list_lock, flags);
-
- wake_up_process(card_thread_info->thread);
- }
- }
-}
-
-void unf_check_event_mgr_status(struct unf_event_mgr *event_mgr)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(event_mgr);
-
- spin_lock_irqsave(&event_mgr->port_event_lock, flag);
- if (event_mgr->emg_completion && event_mgr->free_event_count == UNF_MAX_EVENT_NODE)
- complete(event_mgr->emg_completion);
-
- spin_unlock_irqrestore(&event_mgr->port_event_lock, flag);
-}
-
-void unf_release_event(void *lport, void *event_node)
-{
- struct unf_event_mgr *event_mgr = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_cm_event_report *cm_event_node = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(event_node);
-
- cm_event_node = (struct unf_cm_event_report *)event_node;
- unf_lport = (struct unf_lport *)lport;
- unf_lport = unf_lport->root_lport;
- event_mgr = &unf_lport->event_mgr;
-
- spin_lock_irqsave(&event_mgr->port_event_lock, flags);
- event_mgr->free_event_count++;
- unf_init_event_node(cm_event_node);
- list_add_tail(&cm_event_node->list_entry, &event_mgr->list_free_event);
- spin_unlock_irqrestore(&event_mgr->port_event_lock, flags);
-
- unf_check_event_mgr_status(event_mgr);
-}
-
-void unf_release_global_event(void *event_node)
-{
- ulong flag = 0;
- struct unf_cm_event_report *cm_event_node = NULL;
-
- FC_CHECK_RETURN_VOID(event_node);
- cm_event_node = (struct unf_cm_event_report *)event_node;
-
- unf_init_event_node(cm_event_node);
-
- spin_lock_irqsave(&global_event_queue.global_event_list_lock, flag);
- global_event_queue.list_number++;
- list_add_tail(&cm_event_node->list_entry, &global_event_queue.global_event_list);
- spin_unlock_irqrestore(&global_event_queue.global_event_list_lock, flag);
-}
-
-u32 unf_init_event_center(void *lport)
-{
- struct unf_event_mgr *event_mgr = NULL;
- u32 ret = RETURN_OK;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- unf_lport = (struct unf_lport *)lport;
-
- /* Initial Disc manager */
- event_mgr = &unf_lport->event_mgr;
- event_mgr->free_event_count = UNF_MAX_EVENT_NODE;
- event_mgr->unf_get_free_event_func = unf_get_free_event_node;
- event_mgr->unf_release_event = unf_release_event;
- event_mgr->unf_post_event_func = unf_post_event;
-
- INIT_LIST_HEAD(&event_mgr->list_free_event);
- spin_lock_init(&event_mgr->port_event_lock);
- event_mgr->emg_completion = NULL;
-
- ret = unf_init_event_msg(unf_lport);
-
- return ret;
-}
-
-void unf_wait_event_mgr_complete(struct unf_event_mgr *event_mgr)
-{
- struct unf_event_mgr *event_mgr_temp = NULL;
- bool wait = false;
- ulong mg_flag = 0;
-
- struct completion fc_event_completion;
-
- init_completion(&fc_event_completion);
- FC_CHECK_RETURN_VOID(event_mgr);
- event_mgr_temp = event_mgr;
-
- spin_lock_irqsave(&event_mgr_temp->port_event_lock, mg_flag);
- if (event_mgr_temp->free_event_count != UNF_MAX_EVENT_NODE) {
- event_mgr_temp->emg_completion = &fc_event_completion;
- wait = true;
- }
- spin_unlock_irqrestore(&event_mgr_temp->port_event_lock, mg_flag);
-
- if (wait)
- wait_for_completion(event_mgr_temp->emg_completion);
-
- spin_lock_irqsave(&event_mgr_temp->port_event_lock, mg_flag);
- event_mgr_temp->emg_completion = NULL;
- spin_unlock_irqrestore(&event_mgr_temp->port_event_lock, mg_flag);
-}
-
-u32 unf_event_center_destroy(void *lport)
-{
- struct unf_event_mgr *event_mgr = NULL;
- struct list_head *list = NULL;
- struct list_head *list_tmp = NULL;
- struct unf_cm_event_report *event_node = NULL;
- u32 ret = RETURN_OK;
- ulong flag = 0;
- ulong list_lock_flag = 0;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- unf_lport = (struct unf_lport *)lport;
- event_mgr = &unf_lport->event_mgr;
-
- spin_lock_irqsave(&fc_event_list.fc_event_list_lock, list_lock_flag);
- if (!list_empty(&fc_event_list.list_head)) {
- list_for_each_safe(list, list_tmp, &fc_event_list.list_head) {
- event_node = list_entry(list, struct unf_cm_event_report, list_entry);
-
- if (event_node->lport == unf_lport) {
- list_del_init(&event_node->list_entry);
- if (event_node->event_asy_flag == UNF_EVENT_SYN) {
- event_node->result = UNF_RETURN_ERROR;
- complete(&event_node->event_comp);
- }
-
- spin_lock_irqsave(&event_mgr->port_event_lock, flag);
- event_mgr->free_event_count++;
- list_add_tail(&event_node->list_entry,
- &event_mgr->list_free_event);
- spin_unlock_irqrestore(&event_mgr->port_event_lock, flag);
- }
- }
- }
- spin_unlock_irqrestore(&fc_event_list.fc_event_list_lock, list_lock_flag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) begin to wait event",
- unf_lport->port_id);
-
- unf_wait_event_mgr_complete(event_mgr);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) wait event process end",
- unf_lport->port_id);
-
- unf_del_event_center_fun_op(unf_lport);
-
- vfree(event_mgr->mem_add);
- event_mgr->mem_add = NULL;
- unf_lport->destroy_step = UNF_LPORT_DESTROY_STEP_3_DESTROY_EVENT_CENTER;
-
- return ret;
-}
-
-static void unf_procee_asyn_event(struct unf_cm_event_report *event_node)
-{
- struct unf_lport *lport = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- lport = (struct unf_lport *)event_node->lport;
-
- FC_CHECK_RETURN_VOID(lport);
- if (event_node->unf_event_task) {
- ret = (u32)event_node->unf_event_task(event_node->para_in,
- event_node->para_out);
- }
-
- if (lport->event_mgr.unf_release_event)
- lport->event_mgr.unf_release_event(lport, event_node);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_WARN,
- "[warn]Port(0x%x) handle event(0x%x) failed",
- lport->port_id, event_node->event);
- }
-}
-
-void unf_handle_event(struct unf_cm_event_report *event_node)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 event = 0;
- u32 event_asy_flag = UNF_EVENT_ASYN;
-
- FC_CHECK_RETURN_VOID(event_node);
-
- event = event_node->event;
- event_asy_flag = event_node->event_asy_flag;
-
- switch (event_asy_flag) {
- case UNF_EVENT_SYN: /* synchronous event node */
- case UNF_GLOBAL_EVENT_SYN:
- if (event_node->unf_event_task)
- ret = (u32)event_node->unf_event_task(event_node->para_in,
- event_node->para_out);
-
- event_node->result = ret;
- complete(&event_node->event_comp);
- break;
-
- case UNF_EVENT_ASYN: /* asynchronous event node */
- unf_procee_asyn_event(event_node);
- break;
-
- case UNF_GLOBAL_EVENT_ASYN:
- if (event_node->unf_event_task) {
- ret = (u32)event_node->unf_event_task(event_node->para_in,
- event_node->para_out);
- }
-
- unf_release_global_event(event_node);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_WARN,
- "[warn]handle global event(0x%x) failed", event);
- }
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_WARN,
- "[warn]Unknown event(0x%x)", event);
- break;
- }
-}
-
-u32 unf_init_global_event_msg(void)
-{
- struct unf_cm_event_report *event_node = NULL;
- u32 ret = RETURN_OK;
- u32 index = 0;
- ulong flag = 0;
-
- INIT_LIST_HEAD(&global_event_queue.global_event_list);
- spin_lock_init(&global_event_queue.global_event_list_lock);
- global_event_queue.list_number = 0;
-
- global_event_queue.global_event_add = vmalloc(UNF_MAX_GLOBAL_ENENT_NODE *
- sizeof(struct unf_cm_event_report));
- if (!global_event_queue.global_event_add) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Can't allocate global event queue");
-
- return UNF_RETURN_ERROR;
- }
- memset(global_event_queue.global_event_add, 0,
- (UNF_MAX_GLOBAL_ENENT_NODE * sizeof(struct unf_cm_event_report)));
-
- event_node = (struct unf_cm_event_report *)(global_event_queue.global_event_add);
-
- spin_lock_irqsave(&global_event_queue.global_event_list_lock, flag);
- for (index = 0; index < UNF_MAX_GLOBAL_ENENT_NODE; index++) {
- INIT_LIST_HEAD(&event_node->list_entry);
- list_add_tail(&event_node->list_entry, &global_event_queue.global_event_list);
-
- global_event_queue.list_number++;
- event_node++;
- }
- spin_unlock_irqrestore(&global_event_queue.global_event_list_lock, flag);
-
- return ret;
-}
-
-void unf_destroy_global_event_msg(void)
-{
- if (global_event_queue.list_number != UNF_MAX_GLOBAL_ENENT_NODE) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_CRITICAL,
- "[warn]Global event release not complete with remain nodes(0x%x)",
- global_event_queue.list_number);
- }
-
- vfree(global_event_queue.global_event_add);
-}
-
-u32 unf_schedule_global_event(void *para_in, u32 event_asy_flag,
- int (*unf_event_task)(void *arg_in, void *arg_out))
-{
- struct list_head *list_node = NULL;
- struct unf_cm_event_report *event_node = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- spinlock_t *event_list_lock = NULL;
-
- FC_CHECK_RETURN_VALUE(unf_event_task, UNF_RETURN_ERROR);
-
- if (event_asy_flag != UNF_GLOBAL_EVENT_ASYN && event_asy_flag != UNF_GLOBAL_EVENT_SYN) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Event async flag(0x%x) abnormity",
- event_asy_flag);
-
- return UNF_RETURN_ERROR;
- }
-
- event_list_lock = &global_event_queue.global_event_list_lock;
- spin_lock_irqsave(event_list_lock, flag);
- if (list_empty(&global_event_queue.global_event_list)) {
- spin_unlock_irqrestore(event_list_lock, flag);
-
- return UNF_RETURN_ERROR;
- }
-
- list_node = UNF_OS_LIST_NEXT(&global_event_queue.global_event_list);
- list_del_init(list_node);
- global_event_queue.list_number--;
- event_node = list_entry(list_node, struct unf_cm_event_report, list_entry);
- spin_unlock_irqrestore(event_list_lock, flag);
-
- /* Initial global event */
- unf_init_event_node(event_node);
- init_completion(&event_node->event_comp);
- event_node->event_asy_flag = event_asy_flag;
- event_node->unf_event_task = unf_event_task;
- event_node->para_in = (void *)para_in;
- event_node->para_out = NULL;
-
- unf_post_event(NULL, event_node);
-
- if (event_asy_flag == UNF_GLOBAL_EVENT_SYN) {
- /* must wait for complete */
- wait_for_completion(&event_node->event_comp);
- ret = event_node->result;
- unf_release_global_event(event_node);
- } else {
- ret = RETURN_OK;
- }
-
- return ret;
-}
-
-struct unf_cm_event_report *unf_get_one_event_node(void *lport)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(unf_lport->event_mgr.unf_get_free_event_func, NULL);
-
- return unf_lport->event_mgr.unf_get_free_event_func((void *)unf_lport);
-}
-
-void unf_post_one_event_node(void *lport, struct unf_cm_event_report *event)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(event);
-
- FC_CHECK_RETURN_VOID(unf_lport->event_mgr.unf_post_event_func);
- FC_CHECK_RETURN_VOID(event);
-
- unf_lport->event_mgr.unf_post_event_func((void *)unf_lport, event);
-}
diff --git a/drivers/scsi/spfc/common/unf_event.h b/drivers/scsi/spfc/common/unf_event.h
deleted file mode 100644
index 3fbd72bff8d7..000000000000
--- a/drivers/scsi/spfc/common/unf_event.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_EVENT_H
-#define UNF_EVENT_H
-
-#include "unf_type.h"
-
-#define UNF_MAX_EVENT_NODE 256
-
-enum unf_event_type {
- UNF_EVENT_TYPE_ALARM = 0, /* Alarm */
- UNF_EVENT_TYPE_REQUIRE, /* Require */
- UNF_EVENT_TYPE_RECOVERY, /* Recovery */
- UNF_EVENT_TYPE_BUTT
-};
-
-struct unf_cm_event_report {
- /* event type */
- u32 event;
-
- /* ASY flag */
- u32 event_asy_flag;
-
- /* Delay times,must be async event */
- u32 delay_times;
-
- struct list_head list_entry;
-
- void *lport;
-
- /* parameter */
- void *para_in;
- void *para_out;
- u32 result;
-
- /* recovery strategy */
- int (*unf_event_task)(void *arg_in, void *arg_out);
-
- struct completion event_comp;
-};
-
-struct unf_event_mgr {
- spinlock_t port_event_lock;
- u32 free_event_count;
-
- struct list_head list_free_event;
-
- struct completion *emg_completion;
-
- void *mem_add;
- struct unf_cm_event_report *(*unf_get_free_event_func)(void *lport);
- void (*unf_release_event)(void *lport, void *event_node);
- void (*unf_post_event_func)(void *lport, void *event_node);
-};
-
-struct unf_global_event_queue {
- void *global_event_add;
- u32 list_number;
- struct list_head global_event_list;
- spinlock_t global_event_list_lock;
-};
-
-struct unf_event_list {
- struct list_head list_head;
- spinlock_t fc_event_list_lock;
- u32 list_num; /* list node number */
-};
-
-void unf_handle_event(struct unf_cm_event_report *event_node);
-u32 unf_init_global_event_msg(void);
-void unf_destroy_global_event_msg(void);
-u32 unf_schedule_global_event(void *para_in, u32 event_asy_flag,
- int (*unf_event_task)(void *arg_in, void *arg_out));
-struct unf_cm_event_report *unf_get_one_event_node(void *lport);
-void unf_post_one_event_node(void *lport, struct unf_cm_event_report *event);
-u32 unf_event_center_destroy(void *lport);
-u32 unf_init_event_center(void *lport);
-
-extern struct task_struct *event_task_thread;
-extern struct unf_global_event_queue global_event_queue;
-extern struct unf_event_list fc_event_list;
-#endif
diff --git a/drivers/scsi/spfc/common/unf_exchg.c b/drivers/scsi/spfc/common/unf_exchg.c
deleted file mode 100644
index ab35cc318b6f..000000000000
--- a/drivers/scsi/spfc/common/unf_exchg.c
+++ /dev/null
@@ -1,2317 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_exchg.h"
-#include "unf_log.h"
-#include "unf_common.h"
-#include "unf_rport.h"
-#include "unf_service.h"
-#include "unf_io.h"
-#include "unf_exchg_abort.h"
-
-#define SPFC_XCHG_TYPE_MASK 0xFFFF
-#define UNF_DEL_XCHG_TIMER_SAFE(xchg) \
- do { \
- if (cancel_delayed_work(&((xchg)->timeout_work))) { \
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR, \
- "Exchange(0x%p) is free, but timer is pending.", \
- xchg); \
- } else { \
- FC_DRV_PRINT(UNF_LOG_IO_ATT, \
- UNF_CRITICAL, \
- "Exchange(0x%p) is free, but timer is running.", \
- xchg); \
- } \
- } while (0)
-
-static struct unf_io_flow_id io_stage_table[] = {
- {"XCHG_ALLOC"}, {"TGT_RECEIVE_ABTS"},
- {"TGT_ABTS_DONE"}, {"TGT_IO_SRR"},
- {"SFS_RESPONSE"}, {"SFS_TIMEOUT"},
- {"INI_SEND_CMND"}, {"INI_RESPONSE_DONE"},
- {"INI_EH_ABORT"}, {"INI_EH_DEVICE_RESET"},
- {"INI_EH_BLS_DONE"}, {"INI_IO_TIMEOUT"},
- {"INI_REQ_TIMEOUT"}, {"XCHG_CANCEL_TIMER"},
- {"XCHG_FREE_XCHG"}, {"SEND_ELS"},
- {"IO_XCHG_WAIT"},
-};
-
-static void unf_init_xchg_attribute(struct unf_xchg *xchg);
-static void unf_delay_work_del_syn(struct unf_xchg *xchg);
-static void unf_free_lport_sfs_xchg(struct unf_xchg_mgr *xchg_mgr,
- bool done_ini_flag);
-static void unf_free_lport_destroy_xchg(struct unf_xchg_mgr *xchg_mgr);
-
-void unf_wake_up_scsi_task_cmnd(struct unf_lport *lport)
-{
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_xchg *xchg = NULL;
- ulong hot_pool_lock_flags = 0;
- ulong xchg_flag = 0;
- struct unf_xchg_mgr *xchg_mgrs = NULL;
- u32 i;
-
- FC_CHECK_RETURN_VOID(lport);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- xchg_mgrs = unf_get_xchg_mgr_by_lport(lport, i);
-
- if (!xchg_mgrs) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MINOR,
- "Can't find LPort(0x%x) MgrIdx %u exchange manager.",
- lport->port_id, i);
- continue;
- }
-
- spin_lock_irqsave(&xchg_mgrs->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- list_for_each_safe(node, next_node,
- (&xchg_mgrs->hot_pool->ini_busylist)) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- if (INI_IO_STATE_UPTASK & xchg->io_state &&
- (atomic_read(&xchg->ref_cnt) > 0)) {
- UNF_SET_SCSI_CMND_RESULT(xchg, UNF_IO_SUCCESS);
- up(&xchg->task_sema);
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MINOR,
- "Wake up task command exchange(0x%p), Hot Pool Tag(0x%x).",
- xchg, xchg->hotpooltag);
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
- }
-
- spin_unlock_irqrestore(&xchg_mgrs->hot_pool->xchg_hotpool_lock,
- hot_pool_lock_flags);
- }
-}
-
-void *unf_cm_get_free_xchg(void *lport, u32 xchg_type)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_cm_xchg_mgr_template *xchg_mgr_temp = NULL;
-
- FC_CHECK_RETURN_VALUE(unlikely(lport), NULL);
-
- unf_lport = (struct unf_lport *)lport;
- xchg_mgr_temp = &unf_lport->xchg_mgr_temp;
-
- /* Find the corresponding Lport Xchg management template. */
- FC_CHECK_RETURN_VALUE(unlikely(xchg_mgr_temp->unf_xchg_get_free_and_init), NULL);
-
- return xchg_mgr_temp->unf_xchg_get_free_and_init(unf_lport, xchg_type);
-}
-
-void unf_cm_free_xchg(void *lport, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_cm_xchg_mgr_template *xchg_mgr_temp = NULL;
-
- FC_CHECK_RETURN_VOID(unlikely(lport));
- FC_CHECK_RETURN_VOID(unlikely(xchg));
-
- unf_lport = (struct unf_lport *)lport;
- xchg_mgr_temp = &unf_lport->xchg_mgr_temp;
- FC_CHECK_RETURN_VOID(unlikely(xchg_mgr_temp->unf_xchg_release));
-
- /*
- * unf_cm_free_xchg --->>> unf_free_xchg
- * --->>> unf_xchg_ref_dec --->>> unf_free_fcp_xchg --->>>
- * unf_done_ini_xchg
- */
- xchg_mgr_temp->unf_xchg_release(lport, xchg);
-}
-
-void *unf_cm_lookup_xchg_by_tag(void *lport, u16 hot_pool_tag)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_cm_xchg_mgr_template *xchg_mgr_temp = NULL;
-
- FC_CHECK_RETURN_VALUE(unlikely(lport), NULL);
-
- /* Find the corresponding Lport Xchg management template */
- unf_lport = (struct unf_lport *)lport;
- xchg_mgr_temp = &unf_lport->xchg_mgr_temp;
-
- FC_CHECK_RETURN_VALUE(unlikely(xchg_mgr_temp->unf_look_up_xchg_by_tag), NULL);
-
- return xchg_mgr_temp->unf_look_up_xchg_by_tag(lport, hot_pool_tag);
-}
-
-void *unf_cm_lookup_xchg_by_id(void *lport, u16 ox_id, u32 oid)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_cm_xchg_mgr_template *xchg_mgr_temp = NULL;
-
- FC_CHECK_RETURN_VALUE(unlikely(lport), NULL);
-
- unf_lport = (struct unf_lport *)lport;
- xchg_mgr_temp = &unf_lport->xchg_mgr_temp;
-
- /* Find the corresponding Lport Xchg management template */
- FC_CHECK_RETURN_VALUE(unlikely(xchg_mgr_temp->unf_look_up_xchg_by_id), NULL);
-
- return xchg_mgr_temp->unf_look_up_xchg_by_id(lport, ox_id, oid);
-}
-
-struct unf_xchg *unf_cm_lookup_xchg_by_cmnd_sn(void *lport, u64 command_sn,
- u32 world_id, void *pinitiator)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_cm_xchg_mgr_template *xchg_mgr_temp = NULL;
- struct unf_xchg *xchg = NULL;
-
- FC_CHECK_RETURN_VALUE(unlikely(lport), NULL);
-
- unf_lport = (struct unf_lport *)lport;
- xchg_mgr_temp = &unf_lport->xchg_mgr_temp;
-
- FC_CHECK_RETURN_VALUE(unlikely(xchg_mgr_temp->unf_look_up_xchg_by_cmnd_sn), NULL);
-
- xchg = (struct unf_xchg *)xchg_mgr_temp->unf_look_up_xchg_by_cmnd_sn(unf_lport,
- command_sn,
- world_id,
- pinitiator);
-
- return xchg;
-}
-
-static u32 unf_init_xchg(struct unf_lport *lport, struct unf_xchg_mgr *xchg_mgr,
- u32 xchg_sum, u32 sfs_sum)
-{
- struct unf_xchg *xchg_mem = NULL;
- union unf_sfs_u *sfs_mm_start = NULL;
- dma_addr_t sfs_dma_addr;
- struct unf_xchg *xchg = NULL;
- struct unf_xchg_free_pool *free_pool = NULL;
- ulong flags = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VALUE((sfs_sum <= xchg_sum), UNF_RETURN_ERROR);
-
- free_pool = &xchg_mgr->free_pool;
- xchg_mem = xchg_mgr->fcp_mm_start;
- xchg = xchg_mem;
-
- sfs_mm_start = (union unf_sfs_u *)xchg_mgr->sfs_mm_start;
- sfs_dma_addr = xchg_mgr->sfs_phy_addr;
- /* 1. Allocate the SFS UNION memory to each SFS XCHG
- * and mount the SFS XCHG to the corresponding FREE linked list
- */
- free_pool->total_sfs_xchg = 0;
- free_pool->sfs_xchg_sum = sfs_sum;
- for (i = 0; i < sfs_sum; i++) {
- INIT_LIST_HEAD(&xchg->list_xchg_entry);
- INIT_LIST_HEAD(&xchg->list_esgls);
- spin_lock_init(&xchg->xchg_state_lock);
- sema_init(&xchg->task_sema, 0);
- sema_init(&xchg->echo_info.echo_sync_sema, 0);
-
- spin_lock_irqsave(&free_pool->xchg_freepool_lock, flags);
- xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr = sfs_mm_start;
- xchg->fcp_sfs_union.sfs_entry.sfs_buff_phy_addr = sfs_dma_addr;
- xchg->fcp_sfs_union.sfs_entry.sfs_buff_len = sizeof(*sfs_mm_start);
- list_add_tail(&xchg->list_xchg_entry, &free_pool->list_sfs_xchg_list);
- free_pool->total_sfs_xchg++;
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
-
- sfs_mm_start++;
- sfs_dma_addr = sfs_dma_addr + sizeof(union unf_sfs_u);
- xchg++;
- }
-
- free_pool->total_fcp_xchg = 0;
-
- for (i = 0; (i < xchg_sum - sfs_sum); i++) {
- INIT_LIST_HEAD(&xchg->list_xchg_entry);
-
- INIT_LIST_HEAD(&xchg->list_esgls);
- spin_lock_init(&xchg->xchg_state_lock);
- sema_init(&xchg->task_sema, 0);
- sema_init(&xchg->echo_info.echo_sync_sema, 0);
-
- /* alloc dma buffer for fcp_rsp_iu */
- spin_lock_irqsave(&free_pool->xchg_freepool_lock, flags);
- list_add_tail(&xchg->list_xchg_entry, &free_pool->list_free_xchg_list);
- free_pool->total_fcp_xchg++;
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
-
- xchg++;
- }
-
- free_pool->fcp_xchg_sum = free_pool->total_fcp_xchg;
-
- return RETURN_OK;
-}
-
-static u32 unf_get_xchg_config_sum(struct unf_lport *lport, u32 *xchg_sum)
-{
- struct unf_lport_cfg_item *lport_cfg_items = NULL;
-
- lport_cfg_items = &lport->low_level_func.lport_cfg_items;
-
- /* It has been checked at the bottom layer. Don't need to check it
- * again.
- */
- *xchg_sum = lport_cfg_items->max_sfs_xchg + lport_cfg_items->max_io;
- if ((*xchg_sum / UNF_EXCHG_MGR_NUM) == 0 ||
- lport_cfg_items->max_sfs_xchg / UNF_EXCHG_MGR_NUM == 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) Xchgsum(%u) or SfsXchg(%u) is less than ExchangeMgrNum(%u).",
- lport->port_id, *xchg_sum, lport_cfg_items->max_sfs_xchg,
- UNF_EXCHG_MGR_NUM);
- return UNF_RETURN_ERROR;
- }
-
- if (*xchg_sum > (INVALID_VALUE16 - 1)) {
- /* If the format of ox_id/rx_id is exceeded, this function is
- * not supported
- */
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) Exchange num(0x%x) is Too Big.",
- lport->port_id, *xchg_sum);
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-static void unf_xchg_cancel_timer(void *xchg)
-{
- struct unf_xchg *tmp_xchg = NULL;
- bool need_dec_xchg_ref = false;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
- tmp_xchg = (struct unf_xchg *)xchg;
-
- spin_lock_irqsave(&tmp_xchg->xchg_state_lock, flag);
- if (cancel_delayed_work(&tmp_xchg->timeout_work))
- need_dec_xchg_ref = true;
-
- spin_unlock_irqrestore(&tmp_xchg->xchg_state_lock, flag);
-
- if (need_dec_xchg_ref)
- unf_xchg_ref_dec(xchg, XCHG_CANCEL_TIMER);
-}
-
-void unf_show_all_xchg(struct unf_lport *lport, struct unf_xchg_mgr *xchg_mgr)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *xchg = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(xchg_mgr);
-
- unf_lport = lport;
-
- /* hot Xchg */
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN, "INI busy :");
- list_for_each_safe(xchg_node, next_xchg_node, &xchg_mgr->hot_pool->ini_busylist) {
- xchg = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "0x%p---0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----%llu.",
- xchg, (u32)xchg->hotpooltag, (u32)xchg->xchg_type,
- (u32)xchg->oxid, (u32)xchg->rxid, (u32)xchg->sid, (u32)xchg->did,
- atomic_read(&xchg->ref_cnt), (u32)xchg->io_state, xchg->alloc_jif);
- }
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN, "SFS :");
- list_for_each_safe(xchg_node, next_xchg_node, &xchg_mgr->hot_pool->sfs_busylist) {
- xchg = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "0x%p---0x%x---0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----%llu.",
- xchg, xchg->cmnd_code, (u32)xchg->hotpooltag,
- (u32)xchg->xchg_type, (u32)xchg->oxid, (u32)xchg->rxid, (u32)xchg->sid,
- (u32)xchg->did, atomic_read(&xchg->ref_cnt),
- (u32)xchg->io_state, xchg->alloc_jif);
- }
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN, "Destroy list.");
- list_for_each_safe(xchg_node, next_xchg_node, &xchg_mgr->hot_pool->list_destroy_xchg) {
- xchg = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "0x%p---0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----%llu.",
- xchg, (u32)xchg->hotpooltag, (u32)xchg->xchg_type,
- (u32)xchg->oxid, (u32)xchg->rxid, (u32)xchg->sid, (u32)xchg->did,
- atomic_read(&xchg->ref_cnt), (u32)xchg->io_state, xchg->alloc_jif);
- }
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock, flags);
-}
-
-static u32 unf_free_lport_xchg(struct unf_lport *lport, struct unf_xchg_mgr *xchg_mgr)
-{
-#define UNF_OS_WAITIO_TIMEOUT (10 * 1000)
-
- ulong free_pool_lock_flags = 0;
- bool wait = false;
- u32 total_xchg = 0;
- u32 total_xchg_sum = 0;
- u32 ret = RETURN_OK;
- u64 time_out = 0;
- struct completion xchg_mgr_completion;
-
- init_completion(&xchg_mgr_completion);
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg_mgr, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg_mgr->hot_pool, UNF_RETURN_ERROR);
-
- unf_free_lport_sfs_xchg(xchg_mgr, false);
-
- /* free INI Mode exchanges belong to L_Port */
- unf_free_lport_ini_xchg(xchg_mgr, false);
-
- spin_lock_irqsave(&xchg_mgr->free_pool.xchg_freepool_lock, free_pool_lock_flags);
- total_xchg = xchg_mgr->free_pool.total_fcp_xchg + xchg_mgr->free_pool.total_sfs_xchg;
- total_xchg_sum = xchg_mgr->free_pool.fcp_xchg_sum + xchg_mgr->free_pool.sfs_xchg_sum;
- if (total_xchg != total_xchg_sum) {
- xchg_mgr->free_pool.xchg_mgr_completion = &xchg_mgr_completion;
- wait = true;
- }
- spin_unlock_irqrestore(&xchg_mgr->free_pool.xchg_freepool_lock, free_pool_lock_flags);
-
- if (wait) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) begin to wait for exchange manager completion (0x%x:0x%x)",
- lport->port_id, total_xchg, total_xchg_sum);
-
- unf_show_all_xchg(lport, xchg_mgr);
-
- time_out = wait_for_completion_timeout(xchg_mgr->free_pool.xchg_mgr_completion,
- msecs_to_jiffies(UNF_OS_WAITIO_TIMEOUT));
- if (time_out == 0)
- unf_free_lport_destroy_xchg(xchg_mgr);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) wait for exchange manager completion end",
- lport->port_id);
-
- spin_lock_irqsave(&xchg_mgr->free_pool.xchg_freepool_lock, free_pool_lock_flags);
- xchg_mgr->free_pool.xchg_mgr_completion = NULL;
- spin_unlock_irqrestore(&xchg_mgr->free_pool.xchg_freepool_lock,
- free_pool_lock_flags);
- }
-
- return ret;
-}
-
-void unf_free_lport_all_xchg(struct unf_lport *lport)
-{
- struct unf_xchg_mgr *xchg_mgr = NULL;
- u32 i;
-
- FC_CHECK_RETURN_VOID(lport);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- xchg_mgr = unf_get_xchg_mgr_by_lport(lport, i);
- ;
- if (unlikely(!xchg_mgr)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) hot pool is NULL",
- lport->port_id);
-
- continue;
- }
- unf_free_lport_sfs_xchg(xchg_mgr, false);
-
- /* free INI Mode exchanges belong to L_Port */
- unf_free_lport_ini_xchg(xchg_mgr, false);
-
- unf_free_lport_destroy_xchg(xchg_mgr);
- }
-}
-
-static void unf_delay_work_del_syn(struct unf_xchg *xchg)
-{
- FC_CHECK_RETURN_VOID(xchg);
-
- /* synchronous release timer */
- if (!cancel_delayed_work_sync(&xchg->timeout_work)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Exchange(0x%p), State(0x%x) can't delete work timer, timer is running or no timer.",
- xchg, xchg->io_state);
- } else {
- /* The reference count cannot be directly subtracted.
- * This prevents the XCHG from being moved to the Free linked
- * list when the card is unloaded.
- */
- unf_cm_free_xchg(xchg->lport, xchg);
- }
-}
-
-static void unf_free_lport_sfs_xchg(struct unf_xchg_mgr *xchg_mgr, bool done_ini_flag)
-{
- struct list_head *list = NULL;
- struct unf_xchg *xchg = NULL;
- ulong hot_pool_lock_flags = 0;
-
- FC_CHECK_RETURN_VOID(xchg_mgr);
- FC_CHECK_RETURN_VOID(xchg_mgr->hot_pool);
-
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- while (!list_empty(&xchg_mgr->hot_pool->sfs_busylist)) {
- list = UNF_OS_LIST_NEXT(&xchg_mgr->hot_pool->sfs_busylist);
- list_del_init(list);
-
- /* Prevent the xchg of the sfs from being accessed repeatedly.
- * The xchg is first mounted to the destroy linked list.
- */
- list_add_tail(list, &xchg_mgr->hot_pool->list_destroy_xchg);
-
- xchg = list_entry(list, struct unf_xchg, list_xchg_entry);
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- unf_delay_work_del_syn(xchg);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Free SFS Exchange(0x%p), State(0x%x), Reference count(%d), Start time(%llu).",
- xchg, xchg->io_state, atomic_read(&xchg->ref_cnt), xchg->alloc_jif);
-
- unf_cm_free_xchg(xchg->lport, xchg);
-
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- }
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
-}
-
-void unf_free_lport_ini_xchg(struct unf_xchg_mgr *xchg_mgr, bool done_ini_flag)
-{
- struct list_head *list = NULL;
- struct unf_xchg *xchg = NULL;
- ulong hot_pool_lock_flags = 0;
- u32 up_status = 0;
-
- FC_CHECK_RETURN_VOID(xchg_mgr);
- FC_CHECK_RETURN_VOID(xchg_mgr->hot_pool);
-
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- while (!list_empty(&xchg_mgr->hot_pool->ini_busylist)) {
- /* for each INI busy_list (exchange) node */
- list = UNF_OS_LIST_NEXT(&xchg_mgr->hot_pool->ini_busylist);
-
- /* Put exchange node to destroy_list, prevent done repeatly */
- list_del_init(list);
- list_add_tail(list, &xchg_mgr->hot_pool->list_destroy_xchg);
- xchg = list_entry(list, struct unf_xchg, list_xchg_entry);
- if (atomic_read(&xchg->ref_cnt) <= 0)
- continue;
-
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock,
- hot_pool_lock_flags);
- unf_delay_work_del_syn(xchg);
-
- /* In the case of INI done, the command should be set to fail to
- * prevent data inconsistency caused by the return of OK
- */
- up_status = unf_get_up_level_cmnd_errcode(xchg->scsi_cmnd_info.err_code_table,
- xchg->scsi_cmnd_info.err_code_table_cout,
- UNF_IO_PORT_LOGOUT);
-
- if (INI_IO_STATE_UPABORT & xchg->io_state) {
- /*
- * About L_Port destroy:
- * UP_ABORT ---to--->>> ABORT_Port_Removing
- */
- up_status = UNF_IO_ABORT_PORT_REMOVING;
- }
-
- xchg->scsi_cmnd_info.result = up_status;
- up(&xchg->task_sema);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Free INI exchange(0x%p) state(0x%x) reference count(%d) start time(%llu)",
- xchg, xchg->io_state, atomic_read(&xchg->ref_cnt), xchg->alloc_jif);
-
- unf_cm_free_xchg(xchg->lport, xchg);
-
- /* go to next INI busy_list (exchange) node */
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- }
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
-}
-
-static void unf_free_lport_destroy_xchg(struct unf_xchg_mgr *xchg_mgr)
-{
-#define UNF_WAIT_DESTROY_EMPTY_STEP_MS 1000
-#define UNF_WAIT_IO_STATE_TGT_FRONT_MS (10 * 1000)
-
- struct unf_xchg *xchg = NULL;
- struct list_head *next_xchg_node = NULL;
- ulong hot_pool_lock_flags = 0;
- ulong xchg_flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg_mgr);
- FC_CHECK_RETURN_VOID(xchg_mgr->hot_pool);
-
- /* In this case, the timer on the destroy linked list is deleted.
- * You only need to check whether the timer is released at the end of
- * the tgt.
- */
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- while (!list_empty(&xchg_mgr->hot_pool->list_destroy_xchg)) {
- next_xchg_node = UNF_OS_LIST_NEXT(&xchg_mgr->hot_pool->list_destroy_xchg);
- xchg = list_entry(next_xchg_node, struct unf_xchg, list_xchg_entry);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Free Exchange(0x%p), Type(0x%x), State(0x%x), Reference count(%d), Start time(%llu)",
- xchg, xchg->xchg_type, xchg->io_state,
- atomic_read(&xchg->ref_cnt), xchg->alloc_jif);
-
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
-
- /* This interface can be invoked to ensure that the timer is
- * successfully canceled or wait until the timer execution is
- * complete
- */
- unf_delay_work_del_syn(xchg);
-
- /*
- * If the timer is canceled successfully, delete Xchg
- * If the timer has burst, the Xchg may have been released,In
- * this case, deleting the Xchg will be failed
- */
- unf_cm_free_xchg(xchg->lport, xchg);
-
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
- };
-
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock, hot_pool_lock_flags);
-}
-
-static void unf_free_all_big_sfs(struct unf_xchg_mgr *xchg_mgr)
-{
- struct unf_big_sfs *big_sfs = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- u32 i;
-
- FC_CHECK_RETURN_VOID(xchg_mgr);
-
- /* Release the free resources in the busy state */
- spin_lock_irqsave(&xchg_mgr->big_sfs_pool.big_sfs_pool_lock, flag);
- list_for_each_safe(node, next_node, &xchg_mgr->big_sfs_pool.list_busypool) {
- list_del(node);
- list_add_tail(node, &xchg_mgr->big_sfs_pool.list_freepool);
- }
-
- list_for_each_safe(node, next_node, &xchg_mgr->big_sfs_pool.list_freepool) {
- list_del(node);
- big_sfs = list_entry(node, struct unf_big_sfs, entry_bigsfs);
- if (big_sfs->addr)
- big_sfs->addr = NULL;
- }
- spin_unlock_irqrestore(&xchg_mgr->big_sfs_pool.big_sfs_pool_lock, flag);
-
- if (xchg_mgr->big_sfs_buf_list.buflist) {
- for (i = 0; i < xchg_mgr->big_sfs_buf_list.buf_num; i++) {
- kfree(xchg_mgr->big_sfs_buf_list.buflist[i].vaddr);
- xchg_mgr->big_sfs_buf_list.buflist[i].vaddr = NULL;
- }
-
- kfree(xchg_mgr->big_sfs_buf_list.buflist);
- xchg_mgr->big_sfs_buf_list.buflist = NULL;
- }
-}
-
-static void unf_free_big_sfs_pool(struct unf_xchg_mgr *xchg_mgr)
-{
- FC_CHECK_RETURN_VOID(xchg_mgr);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Free Big SFS Pool, Count(0x%x).",
- xchg_mgr->big_sfs_pool.free_count);
-
- unf_free_all_big_sfs(xchg_mgr);
- xchg_mgr->big_sfs_pool.free_count = 0;
-
- if (xchg_mgr->big_sfs_pool.big_sfs_pool) {
- vfree(xchg_mgr->big_sfs_pool.big_sfs_pool);
- xchg_mgr->big_sfs_pool.big_sfs_pool = NULL;
- }
-}
-
-static void unf_free_xchg_mgr_mem(struct unf_lport *lport, struct unf_xchg_mgr *xchg_mgr)
-{
- struct unf_xchg *xchg = NULL;
- u32 i = 0;
- u32 xchg_sum = 0;
- struct unf_xchg_free_pool *free_pool = NULL;
-
- FC_CHECK_RETURN_VOID(xchg_mgr);
-
- unf_free_big_sfs_pool(xchg_mgr);
-
- /* The sfs is released first, and the XchgMgr is allocated by the get
- * free page. Therefore, the XchgMgr is compared with the '0'
- */
- if (xchg_mgr->sfs_mm_start != 0) {
- dma_free_coherent(&lport->low_level_func.dev->dev, xchg_mgr->sfs_mem_size,
- xchg_mgr->sfs_mm_start, xchg_mgr->sfs_phy_addr);
- xchg_mgr->sfs_mm_start = 0;
- }
-
- /* Release Xchg first */
- if (xchg_mgr->fcp_mm_start) {
- unf_get_xchg_config_sum(lport, &xchg_sum);
- xchg_sum = xchg_sum / UNF_EXCHG_MGR_NUM;
-
- xchg = xchg_mgr->fcp_mm_start;
- for (i = 0; i < xchg_sum; i++) {
- if (!xchg)
- break;
- xchg++;
- }
-
- vfree(xchg_mgr->fcp_mm_start);
- xchg_mgr->fcp_mm_start = NULL;
- }
-
- /* release the hot pool */
- if (xchg_mgr->hot_pool) {
- vfree(xchg_mgr->hot_pool);
- xchg_mgr->hot_pool = NULL;
- }
-
- free_pool = &xchg_mgr->free_pool;
-
- vfree(xchg_mgr);
-}
-
-static void unf_free_xchg_mgr(struct unf_lport *lport, struct unf_xchg_mgr *xchg_mgr)
-{
- ulong flags = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(xchg_mgr);
-
- /* 1. At first, free exchanges for this Exch_Mgr */
- ret = unf_free_lport_xchg(lport, xchg_mgr);
-
- /* 2. Delete this Exch_Mgr entry */
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- list_del_init(&xchg_mgr->xchg_mgr_entry);
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
-
- /* 3. free Exch_Mgr memory if necessary */
- if (ret == RETURN_OK) {
- /* free memory directly */
- unf_free_xchg_mgr_mem(lport, xchg_mgr);
- } else {
- /* Add it to Dirty list */
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- list_add_tail(&xchg_mgr->xchg_mgr_entry, &lport->list_drty_xchg_mgr_head);
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
-
- /* Mark dirty flag */
- unf_cm_mark_dirty_mem(lport, UNF_LPORT_DIRTY_FLAG_XCHGMGR_DIRTY);
- }
-}
-
-void unf_free_all_xchg_mgr(struct unf_lport *lport)
-{
- struct unf_xchg_mgr *xchg_mgr = NULL;
- ulong flags = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- /* for each L_Port->Exch_Mgr_List */
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- while (!list_empty(&lport->list_xchg_mgr_head)) {
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
-
- xchg_mgr = unf_get_xchg_mgr_by_lport(lport, i);
- unf_free_xchg_mgr(lport, xchg_mgr);
- if (i < UNF_EXCHG_MGR_NUM)
- lport->xchg_mgr[i] = NULL;
-
- i++;
-
- /* go to next */
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- }
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
-
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_4_DESTROY_EXCH_MGR;
-}
-
-static u32 unf_init_xchg_mgr(struct unf_xchg_mgr *xchg_mgr)
-{
- FC_CHECK_RETURN_VALUE(xchg_mgr, UNF_RETURN_ERROR);
-
- memset(xchg_mgr, 0, sizeof(struct unf_xchg_mgr));
-
- INIT_LIST_HEAD(&xchg_mgr->xchg_mgr_entry);
- xchg_mgr->fcp_mm_start = NULL;
- xchg_mgr->mem_szie = sizeof(struct unf_xchg_mgr);
-
- return RETURN_OK;
-}
-
-static u32 unf_init_xchg_mgr_free_pool(struct unf_xchg_mgr *xchg_mgr)
-{
- struct unf_xchg_free_pool *free_pool = NULL;
-
- FC_CHECK_RETURN_VALUE(xchg_mgr, UNF_RETURN_ERROR);
-
- free_pool = &xchg_mgr->free_pool;
- INIT_LIST_HEAD(&free_pool->list_free_xchg_list);
- INIT_LIST_HEAD(&free_pool->list_sfs_xchg_list);
- spin_lock_init(&free_pool->xchg_freepool_lock);
- free_pool->fcp_xchg_sum = 0;
- free_pool->xchg_mgr_completion = NULL;
-
- return RETURN_OK;
-}
-
-static u32 unf_init_xchg_hot_pool(struct unf_lport *lport, struct unf_xchg_hot_pool *hot_pool,
- u32 xchg_sum)
-{
- FC_CHECK_RETURN_VALUE(hot_pool, UNF_RETURN_ERROR);
-
- INIT_LIST_HEAD(&hot_pool->sfs_busylist);
- INIT_LIST_HEAD(&hot_pool->ini_busylist);
- spin_lock_init(&hot_pool->xchg_hotpool_lock);
- INIT_LIST_HEAD(&hot_pool->list_destroy_xchg);
- hot_pool->total_xchges = 0;
- hot_pool->wait_state = false;
- hot_pool->lport = lport;
-
- /* Slab Pool Index */
- hot_pool->slab_next_index = 0;
- UNF_TOU16_CHECK(hot_pool->slab_total_sum, xchg_sum, return UNF_RETURN_ERROR);
-
- return RETURN_OK;
-}
-
-static u32 unf_alloc_and_init_big_sfs_pool(struct unf_lport *lport, struct unf_xchg_mgr *xchg_mgr)
-{
-#define UNF_MAX_RESOURCE_RESERVED_FOR_RSCN 20
-#define UNF_BIG_SFS_POOL_TYPES 6
- u32 i = 0;
- u32 size = 0;
- u32 align_size = 0;
- u32 npiv_cnt = 0;
- struct unf_big_sfs_pool *big_sfs_pool = NULL;
- struct unf_big_sfs *big_sfs_buff = NULL;
- u32 buf_total_size;
- u32 buf_num;
- u32 buf_cnt_per_huge_buf;
- u32 alloc_idx;
- u32 cur_buf_idx = 0;
- u32 cur_buf_offset = 0;
-
- FC_CHECK_RETURN_VALUE(xchg_mgr, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- big_sfs_pool = &xchg_mgr->big_sfs_pool;
-
- INIT_LIST_HEAD(&big_sfs_pool->list_freepool);
- INIT_LIST_HEAD(&big_sfs_pool->list_busypool);
- spin_lock_init(&big_sfs_pool->big_sfs_pool_lock);
- npiv_cnt = lport->low_level_func.support_max_npiv_num;
-
- /*
- * The value*6 indicates GID_PT/GID_FT, RSCN, and ECHO
- * Another command is received when a command is being responded
- * A maximum of 20 resources are reserved for the RSCN. During the test,
- * multiple rscn are found. As a result, the resources are insufficient
- * and the disc fails.
- */
- big_sfs_pool->free_count = (npiv_cnt + 1) * UNF_BIG_SFS_POOL_TYPES +
- UNF_MAX_RESOURCE_RESERVED_FOR_RSCN;
- big_sfs_buff =
- (struct unf_big_sfs *)vmalloc(big_sfs_pool->free_count * sizeof(struct unf_big_sfs));
- if (!big_sfs_buff) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Allocate Big SFS buf fail.");
-
- return UNF_RETURN_ERROR;
- }
- memset(big_sfs_buff, 0, big_sfs_pool->free_count * sizeof(struct unf_big_sfs));
- xchg_mgr->mem_szie += (u32)(big_sfs_pool->free_count * sizeof(struct unf_big_sfs));
- big_sfs_pool->big_sfs_pool = (void *)big_sfs_buff;
-
- /*
- * Use the larger value of sizeof (struct unf_gid_acc_pld) and sizeof
- * (struct unf_rscn_pld) to avoid the icp error.Therefore, the value is
- * directly assigned instead of being compared.
- */
- size = sizeof(struct unf_gid_acc_pld);
- align_size = ALIGN(size, PAGE_SIZE);
-
- buf_total_size = align_size * big_sfs_pool->free_count;
- xchg_mgr->big_sfs_buf_list.buf_size =
- buf_total_size > BUF_LIST_PAGE_SIZE ? BUF_LIST_PAGE_SIZE
- : buf_total_size;
-
- buf_cnt_per_huge_buf = xchg_mgr->big_sfs_buf_list.buf_size / align_size;
- buf_num = big_sfs_pool->free_count % buf_cnt_per_huge_buf
- ? big_sfs_pool->free_count / buf_cnt_per_huge_buf + 1
- : big_sfs_pool->free_count / buf_cnt_per_huge_buf;
-
- xchg_mgr->big_sfs_buf_list.buflist = (struct buff_list *)kmalloc(buf_num *
- sizeof(struct buff_list), GFP_KERNEL);
- xchg_mgr->big_sfs_buf_list.buf_num = buf_num;
-
- if (!xchg_mgr->big_sfs_buf_list.buflist) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate BigSfs pool buf list failed out of memory");
- goto free_buff;
- }
- memset(xchg_mgr->big_sfs_buf_list.buflist, 0, buf_num * sizeof(struct buff_list));
- for (alloc_idx = 0; alloc_idx < buf_num; alloc_idx++) {
- xchg_mgr->big_sfs_buf_list.buflist[alloc_idx].vaddr =
- kmalloc(xchg_mgr->big_sfs_buf_list.buf_size, GFP_ATOMIC);
- if (xchg_mgr->big_sfs_buf_list.buflist[alloc_idx].vaddr ==
- NULL) {
- goto free_buff;
- }
- memset(xchg_mgr->big_sfs_buf_list.buflist[alloc_idx].vaddr, 0,
- xchg_mgr->big_sfs_buf_list.buf_size);
- }
-
- for (i = 0; i < big_sfs_pool->free_count; i++) {
- if (i != 0 && !(i % buf_cnt_per_huge_buf))
- cur_buf_idx++;
-
- cur_buf_offset = align_size * (i % buf_cnt_per_huge_buf);
- big_sfs_buff->addr = xchg_mgr->big_sfs_buf_list.buflist[cur_buf_idx].vaddr +
- cur_buf_offset;
- big_sfs_buff->size = size;
- xchg_mgr->mem_szie += size;
- list_add_tail(&big_sfs_buff->entry_bigsfs, &big_sfs_pool->list_freepool);
- big_sfs_buff++;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[EVENT]Allocate BigSfs pool size:%d,align_size:%d,buf_num:%u,buf_size:%u",
- size, align_size, xchg_mgr->big_sfs_buf_list.buf_num,
- xchg_mgr->big_sfs_buf_list.buf_size);
- return RETURN_OK;
-free_buff:
- unf_free_all_big_sfs(xchg_mgr);
- vfree(big_sfs_buff);
- big_sfs_pool->big_sfs_pool = NULL;
- return UNF_RETURN_ERROR;
-}
-
-static void unf_free_one_big_sfs(struct unf_xchg *xchg)
-{
- ulong flag = 0;
- struct unf_xchg_mgr *xchg_mgr = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
- xchg_mgr = xchg->xchg_mgr;
- FC_CHECK_RETURN_VOID(xchg_mgr);
- if (!xchg->big_sfs_buf)
- return;
-
- if (xchg->cmnd_code != NS_GID_PT && xchg->cmnd_code != NS_GID_FT &&
- xchg->cmnd_code != ELS_ECHO &&
- xchg->cmnd_code != (UNF_SET_ELS_ACC_TYPE(ELS_ECHO)) && xchg->cmnd_code != ELS_RSCN &&
- xchg->cmnd_code != (UNF_SET_ELS_ACC_TYPE(ELS_RSCN))) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "Exchange(0x%p), Command(0x%x) big SFS buf is not NULL.",
- xchg, xchg->cmnd_code);
- }
-
- spin_lock_irqsave(&xchg_mgr->big_sfs_pool.big_sfs_pool_lock, flag);
- list_del(&xchg->big_sfs_buf->entry_bigsfs);
- list_add_tail(&xchg->big_sfs_buf->entry_bigsfs,
- &xchg_mgr->big_sfs_pool.list_freepool);
- xchg_mgr->big_sfs_pool.free_count++;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Free one big SFS buf(0x%p), Count(0x%x), Exchange(0x%p), Command(0x%x).",
- xchg->big_sfs_buf->addr, xchg_mgr->big_sfs_pool.free_count,
- xchg, xchg->cmnd_code);
- spin_unlock_irqrestore(&xchg_mgr->big_sfs_pool.big_sfs_pool_lock, flag);
-}
-
-static void unf_free_exchg_mgr_info(struct unf_lport *lport)
-{
- u32 i;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flags = 0;
- struct unf_xchg_mgr *xchg_mgr = NULL;
-
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- list_for_each_safe(node, next_node, &lport->list_xchg_mgr_head) {
- list_del(node);
- xchg_mgr = list_entry(node, struct unf_xchg_mgr, xchg_mgr_entry);
- }
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- xchg_mgr = lport->xchg_mgr[i];
-
- if (xchg_mgr) {
- unf_free_big_sfs_pool(xchg_mgr);
-
- if (xchg_mgr->sfs_mm_start) {
- dma_free_coherent(&lport->low_level_func.dev->dev,
- xchg_mgr->sfs_mem_size, xchg_mgr->sfs_mm_start,
- xchg_mgr->sfs_phy_addr);
- xchg_mgr->sfs_mm_start = 0;
- }
-
- if (xchg_mgr->fcp_mm_start) {
- vfree(xchg_mgr->fcp_mm_start);
- xchg_mgr->fcp_mm_start = NULL;
- }
-
- if (xchg_mgr->hot_pool) {
- vfree(xchg_mgr->hot_pool);
- xchg_mgr->hot_pool = NULL;
- }
-
- vfree(xchg_mgr);
- lport->xchg_mgr[i] = NULL;
- }
- }
-}
-
-static u32 unf_alloc_and_init_xchg_mgr(struct unf_lport *lport)
-{
- struct unf_xchg_mgr *xchg_mgr = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct unf_xchg *xchg_mem = NULL;
- void *sfs_mm_start = 0;
- dma_addr_t sfs_phy_addr = 0;
- u32 xchg_sum = 0;
- u32 sfs_xchg_sum = 0;
- ulong flags = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 slab_num = 0;
- u32 i = 0;
-
- ret = unf_get_xchg_config_sum(lport, &xchg_sum);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) can't get Exchange.", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* SFS Exchange Sum */
- sfs_xchg_sum = lport->low_level_func.lport_cfg_items.max_sfs_xchg /
- UNF_EXCHG_MGR_NUM;
- xchg_sum = xchg_sum / UNF_EXCHG_MGR_NUM;
- slab_num = lport->low_level_func.support_max_hot_tag_range / UNF_EXCHG_MGR_NUM;
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- /* Alloc Exchange Manager */
- xchg_mgr = (struct unf_xchg_mgr *)vmalloc(sizeof(struct unf_xchg_mgr));
- if (!xchg_mgr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) allocate Exchange Manager Memory Fail.",
- lport->port_id);
- goto exit;
- }
-
- /* Init Exchange Manager */
- ret = unf_init_xchg_mgr(xchg_mgr);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) initialization Exchange Manager unsuccessful.",
- lport->port_id);
- goto free_xchg_mgr;
- }
-
- /* Initialize the Exchange Free Pool resource */
- ret = unf_init_xchg_mgr_free_pool(xchg_mgr);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) initialization Exchange Manager Free Pool unsuccessful.",
- lport->port_id);
- goto free_xchg_mgr;
- }
-
- /* Allocate memory for Hot Pool and Xchg slab */
- hot_pool = vmalloc(sizeof(struct unf_xchg_hot_pool) +
- sizeof(struct unf_xchg *) * slab_num);
- if (!hot_pool) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) allocate Hot Pool Memory Fail.",
- lport->port_id);
- goto free_xchg_mgr;
- }
- memset(hot_pool, 0,
- sizeof(struct unf_xchg_hot_pool) + sizeof(struct unf_xchg *) * slab_num);
-
- xchg_mgr->mem_szie += (u32)(sizeof(struct unf_xchg_hot_pool) +
- sizeof(struct unf_xchg *) * slab_num);
- /* Initialize the Exchange Hot Pool resource */
- ret = unf_init_xchg_hot_pool(lport, hot_pool, slab_num);
- if (ret != RETURN_OK)
- goto free_hot_pool;
-
- hot_pool->base += (u16)(i * slab_num);
- /* Allocate the memory of all Xchg (IO/SFS) */
- xchg_mem = vmalloc(sizeof(struct unf_xchg) * xchg_sum);
- if (!xchg_mem) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) allocate Exchange Memory Fail.",
- lport->port_id);
- goto free_hot_pool;
- }
- memset(xchg_mem, 0, sizeof(struct unf_xchg) * xchg_sum);
-
- xchg_mgr->mem_szie += (u32)(sizeof(struct unf_xchg) * xchg_sum);
- xchg_mgr->hot_pool = hot_pool;
- xchg_mgr->fcp_mm_start = xchg_mem;
- /* Allocate the memory used by the SFS Xchg to carry the
- * ELS/BLS/GS command and response
- */
- xchg_mgr->sfs_mem_size = (u32)(sizeof(union unf_sfs_u) * sfs_xchg_sum);
-
- /* Apply for the DMA space for sending sfs frames.
- * If the value of DMA32 is less than 4 GB, cross-4G problems
- * will not occur
- */
- sfs_mm_start = dma_alloc_coherent(&lport->low_level_func.dev->dev,
- xchg_mgr->sfs_mem_size,
- &sfs_phy_addr, GFP_KERNEL);
- if (!sfs_mm_start) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) Get Free Pagers Fail .",
- lport->port_id);
- goto free_xchg_mem;
- }
- memset(sfs_mm_start, 0, sizeof(union unf_sfs_u) * sfs_xchg_sum);
-
- xchg_mgr->mem_szie += xchg_mgr->sfs_mem_size;
- xchg_mgr->sfs_mm_start = sfs_mm_start;
- xchg_mgr->sfs_phy_addr = sfs_phy_addr;
- /* The Xchg is initialized and mounted to the Free Pool */
- ret = unf_init_xchg(lport, xchg_mgr, xchg_sum, sfs_xchg_sum);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) initialization Exchange unsuccessful, Exchange Number(%d), SFS Exchange number(%d).",
- lport->port_id, xchg_sum, sfs_xchg_sum);
- dma_free_coherent(&lport->low_level_func.dev->dev, xchg_mgr->sfs_mem_size,
- xchg_mgr->sfs_mm_start, xchg_mgr->sfs_phy_addr);
- xchg_mgr->sfs_mm_start = 0;
- goto free_xchg_mem;
- }
-
- /* Apply for the memory used by GID_PT, GID_FT, and RSCN */
- ret = unf_alloc_and_init_big_sfs_pool(lport, xchg_mgr);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) allocate big SFS fail", lport->port_id);
- dma_free_coherent(&lport->low_level_func.dev->dev, xchg_mgr->sfs_mem_size,
- xchg_mgr->sfs_mm_start, xchg_mgr->sfs_phy_addr);
- xchg_mgr->sfs_mm_start = 0;
- goto free_xchg_mem;
- }
-
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- lport->xchg_mgr[i] = (void *)xchg_mgr;
- list_add_tail(&xchg_mgr->xchg_mgr_entry, &lport->list_xchg_mgr_head);
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) ExchangeMgr:(0x%p),Base:(0x%x).",
- lport->port_id, lport->xchg_mgr[i], hot_pool->base);
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) allocate Exchange Manager size(0x%x).",
- lport->port_id, xchg_mgr->mem_szie);
- return RETURN_OK;
-free_xchg_mem:
- vfree(xchg_mem);
-free_hot_pool:
- vfree(hot_pool);
-free_xchg_mgr:
- vfree(xchg_mgr);
-exit:
- unf_free_exchg_mgr_info(lport);
- return UNF_RETURN_ERROR;
-}
-
-void unf_xchg_mgr_destroy(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- unf_free_all_xchg_mgr(lport);
-}
-
-u32 unf_alloc_xchg_resource(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- INIT_LIST_HEAD(&lport->list_drty_xchg_mgr_head);
- INIT_LIST_HEAD(&lport->list_xchg_mgr_head);
- spin_lock_init(&lport->xchg_mgr_lock);
-
- /* LPort Xchg Management Unit Alloc */
- if (unf_alloc_and_init_xchg_mgr(lport) != RETURN_OK)
- return UNF_RETURN_ERROR;
-
- return RETURN_OK;
-}
-
-void unf_destroy_dirty_xchg(struct unf_lport *lport, bool show_only)
-{
- u32 dirty_xchg = 0;
- struct unf_xchg_mgr *xchg_mgr = NULL;
- ulong flags = 0;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- if (lport->dirty_flag & UNF_LPORT_DIRTY_FLAG_XCHGMGR_DIRTY) {
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- list_for_each_safe(node, next_node, &lport->list_drty_xchg_mgr_head) {
- xchg_mgr = list_entry(node, struct unf_xchg_mgr, xchg_mgr_entry);
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
- if (xchg_mgr) {
- dirty_xchg = (xchg_mgr->free_pool.total_fcp_xchg +
- xchg_mgr->free_pool.total_sfs_xchg);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) has %u dirty exchange(s)",
- lport->port_id, dirty_xchg);
-
- unf_show_all_xchg(lport, xchg_mgr);
-
- if (!show_only) {
- /* Delete Dirty Exchange Mgr entry */
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- list_del_init(&xchg_mgr->xchg_mgr_entry);
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
-
- /* Free Dirty Exchange Mgr memory */
- unf_free_xchg_mgr_mem(lport, xchg_mgr);
- }
- }
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- }
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
- }
-}
-
-struct unf_xchg_mgr *unf_get_xchg_mgr_by_lport(struct unf_lport *lport, u32 idx)
-{
- struct unf_xchg_mgr *xchg_mgr = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE((idx < UNF_EXCHG_MGR_NUM), NULL);
-
- spin_lock_irqsave(&lport->xchg_mgr_lock, flags);
- xchg_mgr = lport->xchg_mgr[idx];
- spin_unlock_irqrestore(&lport->xchg_mgr_lock, flags);
-
- return xchg_mgr;
-}
-
-struct unf_xchg_hot_pool *unf_get_hot_pool_by_lport(struct unf_lport *lport,
- u32 mgr_idx)
-{
- struct unf_xchg_mgr *xchg_mgr = NULL;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- unf_lport = (struct unf_lport *)(lport->root_lport);
-
- FC_CHECK_RETURN_VALUE(unf_lport, NULL);
-
- /* Get Xchg Manager */
- xchg_mgr = unf_get_xchg_mgr_by_lport(unf_lport, mgr_idx);
- if (!xchg_mgr) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) Exchange Manager is NULL.",
- unf_lport->port_id);
-
- return NULL;
- }
-
- /* Get Xchg Manager Hot Pool */
- return xchg_mgr->hot_pool;
-}
-
-static inline void unf_hot_pool_slab_set(struct unf_xchg_hot_pool *hot_pool,
- u16 slab_index, struct unf_xchg *xchg)
-{
- FC_CHECK_RETURN_VOID(hot_pool);
-
- hot_pool->xchg_slab[slab_index] = xchg;
-}
-
-static inline struct unf_xchg *unf_get_xchg_by_xchg_tag(struct unf_xchg_hot_pool *hot_pool,
- u16 slab_index)
-{
- FC_CHECK_RETURN_VALUE(hot_pool, NULL);
-
- return hot_pool->xchg_slab[slab_index];
-}
-
-static void *unf_look_up_xchg_by_tag(void *lport, u16 hot_pool_tag)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct unf_xchg *xchg = NULL;
- ulong flags = 0;
- u32 exchg_mgr_idx = 0;
- struct unf_xchg_mgr *xchg_mgr = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- /* In the case of NPIV, lport is the Vport pointer,
- * the share uses the ExchMgr of RootLport
- */
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VALUE(unf_lport, NULL);
-
- exchg_mgr_idx = (hot_pool_tag * UNF_EXCHG_MGR_NUM) /
- unf_lport->low_level_func.support_max_hot_tag_range;
- if (unlikely(exchg_mgr_idx >= UNF_EXCHG_MGR_NUM)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) Get ExchgMgr %u err",
- unf_lport->port_id, exchg_mgr_idx);
-
- return NULL;
- }
-
- xchg_mgr = unf_lport->xchg_mgr[exchg_mgr_idx];
-
- if (unlikely(!xchg_mgr)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) ExchgMgr %u is null",
- unf_lport->port_id, exchg_mgr_idx);
-
- return NULL;
- }
-
- hot_pool = xchg_mgr->hot_pool;
-
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) Hot Pool is NULL.",
- unf_lport->port_id);
-
- return NULL;
- }
-
- if (unlikely(hot_pool_tag >= (hot_pool->slab_total_sum + hot_pool->base))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]LPort(0x%x) can't Input Tag(0x%x), Max(0x%x).",
- unf_lport->port_id, hot_pool_tag,
- (hot_pool->slab_total_sum + hot_pool->base));
-
- return NULL;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
- xchg = unf_get_xchg_by_xchg_tag(hot_pool, hot_pool_tag - hot_pool->base);
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
-
- return (void *)xchg;
-}
-
-static void *unf_find_xchg_by_ox_id(void *lport, u16 ox_id, u32 oid)
-{
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct unf_xchg *xchg = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong flags = 0;
- ulong xchg_flags = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- /* In the case of NPIV, the lport is the Vport pointer,
- * and the share uses the ExchMgr of the RootLport
- */
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VALUE(unf_lport, NULL);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(unf_lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) MgrIdex %u Hot Pool is NULL.",
- unf_lport->port_id, i);
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
-
- /* 1. Traverse sfs_busy list */
- list_for_each_safe(node, next_node, &hot_pool->sfs_busylist) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flags);
- if (unf_check_oxid_matched(ox_id, oid, xchg)) {
- atomic_inc(&xchg->ref_cnt);
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flags);
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- return xchg;
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flags);
- }
-
- /* 2. Traverse INI_Busy List */
- list_for_each_safe(node, next_node, &hot_pool->ini_busylist) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flags);
- if (unf_check_oxid_matched(ox_id, oid, xchg)) {
- atomic_inc(&xchg->ref_cnt);
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flags);
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- return xchg;
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock,
- xchg_flags);
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- }
-
- return NULL;
-}
-
-static inline bool unf_check_xchg_matched(struct unf_xchg *xchg, u64 command_sn,
- u32 world_id, void *pinitiator)
-{
- bool matched = false;
-
- matched = (command_sn == xchg->cmnd_sn);
- if (matched && (atomic_read(&xchg->ref_cnt) > 0))
- return true;
- else
- return false;
-}
-
-static void *unf_look_up_xchg_by_cmnd_sn(void *lport, u64 command_sn,
- u32 world_id, void *pinitiator)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_xchg *xchg = NULL;
- ulong flags = 0;
- u32 i;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- /* In NPIV, lport is a Vport pointer, and idle resources are shared by
- * ExchMgr of RootLport. However, busy resources are mounted on each
- * vport. Therefore, vport needs to be used.
- */
- unf_lport = (struct unf_lport *)lport;
- FC_CHECK_RETURN_VALUE(unf_lport, NULL);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(unf_lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) hot pool is NULL",
- unf_lport->port_id);
-
- continue;
- }
-
- /* from busy_list */
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
- list_for_each_safe(node, next_node, &hot_pool->ini_busylist) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
- if (unf_check_xchg_matched(xchg, command_sn, world_id, pinitiator)) {
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
-
- return xchg;
- }
- }
-
- /* vport: from destroy_list */
- if (unf_lport != unf_lport->root_lport) {
- list_for_each_safe(node, next_node, &hot_pool->list_destroy_xchg) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
- if (unf_check_xchg_matched(xchg, command_sn, world_id,
- pinitiator)) {
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Port(0x%x) lookup exchange from destroy list",
- unf_lport->port_id);
-
- return xchg;
- }
- }
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- }
-
- return NULL;
-}
-
-static inline u32 unf_alloc_hot_pool_slab(struct unf_xchg_hot_pool *hot_pool, struct unf_xchg *xchg)
-{
- u16 slab_index = 0;
-
- FC_CHECK_RETURN_VALUE(hot_pool, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- /* Check whether the hotpool tag is in the specified range sirt.
- * If yes, set up the management relationship. If no, handle the problem
- * according to the normal IO. If the sirt digitmap is used but the tag
- * is occupied, it indicates that the I/O is discarded.
- */
-
- hot_pool->slab_next_index = (u16)hot_pool->slab_next_index;
- slab_index = hot_pool->slab_next_index;
- while (unf_get_xchg_by_xchg_tag(hot_pool, slab_index)) {
- slab_index++;
- slab_index = slab_index % hot_pool->slab_total_sum;
-
- /* Rewind occurs */
- if (slab_index == hot_pool->slab_next_index) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_MAJOR,
- "There is No Slab At Hot Pool(0x%p) for xchg(0x%p).",
- hot_pool, xchg);
-
- return UNF_RETURN_ERROR;
- }
- }
-
- unf_hot_pool_slab_set(hot_pool, slab_index, xchg);
- xchg->hotpooltag = slab_index + hot_pool->base;
- slab_index++;
- hot_pool->slab_next_index = slab_index % hot_pool->slab_total_sum;
-
- return RETURN_OK;
-}
-
-struct unf_esgl_page *
-unf_get_and_add_one_free_esgl_page(struct unf_lport *lport, struct unf_xchg *xchg)
-{
- struct unf_esgl *esgl = NULL;
- struct list_head *list_head = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(xchg, NULL);
-
- /* Obtain a new Esgl from the EsglPool and add it to the list_esgls of
- * the Xchg
- */
- spin_lock_irqsave(&lport->esgl_pool.esgl_pool_lock, flag);
- if (!list_empty(&lport->esgl_pool.list_esgl_pool)) {
- list_head = UNF_OS_LIST_NEXT(&lport->esgl_pool.list_esgl_pool);
- list_del(list_head);
- lport->esgl_pool.esgl_pool_count--;
- list_add_tail(list_head, &xchg->list_esgls);
-
- esgl = list_entry(list_head, struct unf_esgl, entry_esgl);
- atomic_inc(&xchg->esgl_cnt);
- spin_unlock_irqrestore(&lport->esgl_pool.esgl_pool_lock, flag);
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) esgl pool is empty",
- lport->nport_id);
-
- spin_unlock_irqrestore(&lport->esgl_pool.esgl_pool_lock, flag);
- return NULL;
- }
-
- return &esgl->page;
-}
-
-void unf_release_esgls(struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct list_head *list = NULL;
- struct list_head *list_tmp = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
- FC_CHECK_RETURN_VOID(xchg->lport);
-
- if (atomic_read(&xchg->esgl_cnt) <= 0)
- return;
-
- /* In the case of NPIV, the Vport pointer is saved in v_pstExch,
- * and the EsglPool of RootLport is shared.
- */
- unf_lport = (xchg->lport)->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- spin_lock_irqsave(&unf_lport->esgl_pool.esgl_pool_lock, flag);
- if (!list_empty(&xchg->list_esgls)) {
- list_for_each_safe(list, list_tmp, &xchg->list_esgls) {
- list_del(list);
- list_add_tail(list, &unf_lport->esgl_pool.list_esgl_pool);
- unf_lport->esgl_pool.esgl_pool_count++;
- atomic_dec(&xchg->esgl_cnt);
- }
- }
- spin_unlock_irqrestore(&unf_lport->esgl_pool.esgl_pool_lock, flag);
-}
-
-static void unf_add_back_to_fcp_list(struct unf_xchg_free_pool *free_pool, struct unf_xchg *xchg)
-{
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(free_pool);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_init_xchg_attribute(xchg);
-
- /* The released I/O resources are added to the queue tail to facilitate
- * fault locating
- */
- spin_lock_irqsave(&free_pool->xchg_freepool_lock, flags);
- list_add_tail(&xchg->list_xchg_entry, &free_pool->list_free_xchg_list);
- free_pool->total_fcp_xchg++;
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
-}
-
-static void unf_check_xchg_mgr_status(struct unf_xchg_mgr *xchg_mgr)
-{
- ulong flags = 0;
- u32 total_xchg = 0;
- u32 total_xchg_sum = 0;
-
- FC_CHECK_RETURN_VOID(xchg_mgr);
-
- spin_lock_irqsave(&xchg_mgr->free_pool.xchg_freepool_lock, flags);
-
- total_xchg = xchg_mgr->free_pool.total_fcp_xchg + xchg_mgr->free_pool.total_sfs_xchg;
- total_xchg_sum = xchg_mgr->free_pool.fcp_xchg_sum + xchg_mgr->free_pool.sfs_xchg_sum;
-
- if (xchg_mgr->free_pool.xchg_mgr_completion && total_xchg == total_xchg_sum)
- complete(xchg_mgr->free_pool.xchg_mgr_completion);
-
- spin_unlock_irqrestore(&xchg_mgr->free_pool.xchg_freepool_lock, flags);
-}
-
-static void unf_free_fcp_xchg(struct unf_xchg *xchg)
-{
- struct unf_xchg_free_pool *free_pool = NULL;
- struct unf_xchg_mgr *xchg_mgr = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- /* Releasing a Specified INI I/O and Invoking the scsi_done Process */
- unf_done_ini_xchg(xchg);
- free_pool = xchg->free_pool;
- xchg_mgr = xchg->xchg_mgr;
- unf_lport = xchg->lport;
- unf_rport = xchg->rport;
-
- atomic_dec(&unf_rport->pending_io_cnt);
- /* Release the Esgls in the Xchg structure and return it to the EsglPool
- * of the Lport
- */
- unf_release_esgls(xchg);
-
- if (unlikely(xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu)) {
- kfree(xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu);
- xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu = NULL;
- }
-
- /* Mount I/O resources to the FCP Free linked list */
- unf_add_back_to_fcp_list(free_pool, xchg);
-
- /* The Xchg is released synchronously and then forcibly released to
- * prevent the Xchg from accessing the Xchg in the normal I/O process
- */
- if (unlikely(unf_lport->port_removing))
- unf_check_xchg_mgr_status(xchg_mgr);
-}
-
-static void unf_init_io_xchg_param(struct unf_xchg *xchg, struct unf_lport *lport,
- struct unf_xchg_mgr *xchg_mgr)
-{
- static atomic64_t exhd_id;
-
- xchg->start_jif = atomic64_inc_return(&exhd_id);
- xchg->xchg_mgr = xchg_mgr;
- xchg->free_pool = &xchg_mgr->free_pool;
- xchg->hot_pool = xchg_mgr->hot_pool;
- xchg->lport = lport;
- xchg->xchg_type = UNF_XCHG_TYPE_INI;
- xchg->free_xchg = unf_free_fcp_xchg;
- xchg->scsi_or_tgt_cmnd_func = NULL;
- xchg->io_state = UNF_IO_STATE_NEW;
- xchg->io_send_stage = TGT_IO_SEND_STAGE_NONE;
- xchg->io_send_result = TGT_IO_SEND_RESULT_INVALID;
- xchg->io_send_abort = false;
- xchg->io_abort_result = false;
- xchg->oxid = INVALID_VALUE16;
- xchg->abort_oxid = INVALID_VALUE16;
- xchg->rxid = INVALID_VALUE16;
- xchg->sid = INVALID_VALUE32;
- xchg->did = INVALID_VALUE32;
- xchg->oid = INVALID_VALUE32;
- xchg->seq_id = INVALID_VALUE8;
- xchg->cmnd_code = INVALID_VALUE32;
- xchg->data_len = 0;
- xchg->resid_len = 0;
- xchg->data_direction = DMA_NONE;
- xchg->may_consume_res_cnt = 0;
- xchg->fast_consume_res_cnt = 0;
- xchg->io_front_jif = 0;
- xchg->tmf_state = 0;
- xchg->ucode_abts_state = INVALID_VALUE32;
- xchg->abts_state = 0;
- xchg->rport_bind_jifs = INVALID_VALUE64;
- xchg->scsi_id = INVALID_VALUE32;
- xchg->qos_level = 0;
- xchg->world_id = INVALID_VALUE32;
-
- memset(&xchg->dif_control, 0, sizeof(struct unf_dif_control_info));
- memset(&xchg->req_sgl_info, 0, sizeof(struct unf_req_sgl_info));
- memset(&xchg->dif_sgl_info, 0, sizeof(struct unf_req_sgl_info));
- xchg->scsi_cmnd_info.result = 0;
-
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- (u32)atomic64_inc_return(&((struct unf_lport *)lport->root_lport)->exchg_index);
-
- if (xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] == INVALID_VALUE32) {
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- (u32)atomic64_inc_return(&((struct unf_lport *)lport->root_lport)->exchg_index);
- }
-
- if (xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] == 0) {
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- (u32)atomic64_inc_return(&((struct unf_lport *)lport->root_lport)->exchg_index);
- }
-
- atomic_set(&xchg->ref_cnt, 0);
- atomic_set(&xchg->delay_flag, 0);
-
- if (delayed_work_pending(&xchg->timeout_work))
- UNF_DEL_XCHG_TIMER_SAFE(xchg);
-
- INIT_DELAYED_WORK(&xchg->timeout_work, unf_fc_ini_io_xchg_time_out);
-}
-
-static struct unf_xchg *unf_alloc_io_xchg(struct unf_lport *lport,
- struct unf_xchg_mgr *xchg_mgr)
-{
- struct unf_xchg *xchg = NULL;
- struct list_head *list_node = NULL;
- struct unf_xchg_free_pool *free_pool = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(xchg_mgr, NULL);
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- free_pool = &xchg_mgr->free_pool;
- hot_pool = xchg_mgr->hot_pool;
- FC_CHECK_RETURN_VALUE(free_pool, NULL);
- FC_CHECK_RETURN_VALUE(hot_pool, NULL);
-
- /* 1. Free Pool */
- spin_lock_irqsave(&free_pool->xchg_freepool_lock, flags);
- if (unlikely(list_empty(&free_pool->list_free_xchg_list))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "Port(0x%x) have no Exchange anymore.",
- lport->port_id);
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
- return NULL;
- }
-
- /* Select an idle node from free pool */
- list_node = UNF_OS_LIST_NEXT(&free_pool->list_free_xchg_list);
- list_del(list_node);
- free_pool->total_fcp_xchg--;
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
-
- xchg = list_entry(list_node, struct unf_xchg, list_xchg_entry);
- /*
- * Hot Pool:
- * When xchg is mounted to Hot Pool, the mount mode and release mode
- * of Xchg must be specified and stored in the sfs linked list.
- */
- flags = 0;
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
- if (unf_alloc_hot_pool_slab(hot_pool, xchg) != RETURN_OK) {
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- unf_add_back_to_fcp_list(free_pool, xchg);
- if (unlikely(lport->port_removing))
- unf_check_xchg_mgr_status(xchg_mgr);
-
- return NULL;
- }
- list_add_tail(&xchg->list_xchg_entry, &hot_pool->ini_busylist);
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
-
- /* 3. Exchange State */
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- unf_init_io_xchg_param(xchg, lport, xchg_mgr);
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- return xchg;
-}
-
-static void unf_add_back_to_sfs_list(struct unf_xchg_free_pool *free_pool,
- struct unf_xchg *xchg)
-{
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(free_pool);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_init_xchg_attribute(xchg);
-
- spin_lock_irqsave(&free_pool->xchg_freepool_lock, flags);
-
- list_add_tail(&xchg->list_xchg_entry, &free_pool->list_sfs_xchg_list);
- free_pool->total_sfs_xchg++;
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
-}
-
-static void unf_free_sfs_xchg(struct unf_xchg *xchg)
-{
- struct unf_xchg_free_pool *free_pool = NULL;
- struct unf_xchg_mgr *xchg_mgr = NULL;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- free_pool = xchg->free_pool;
- unf_lport = xchg->lport;
- xchg_mgr = xchg->xchg_mgr;
-
- /* The memory is applied for when the GID_PT/GID_FT is sent.
- * If no response is received, the GID_PT/GID_FT needs to be forcibly
- * released.
- */
-
- unf_free_one_big_sfs(xchg);
-
- unf_add_back_to_sfs_list(free_pool, xchg);
-
- if (unlikely(unf_lport->port_removing))
- unf_check_xchg_mgr_status(xchg_mgr);
-}
-
-static void unf_fc_xchg_add_timer(void *xchg, ulong time_ms,
- enum unf_timer_type time_type)
-{
- ulong flag = 0;
- struct unf_xchg *unf_xchg = NULL;
- ulong times_ms = time_ms;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
- unf_xchg = (struct unf_xchg *)xchg;
- unf_lport = unf_xchg->lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- /* update timeout */
- switch (time_type) {
- /* The processing of TGT RRQ timeout is the same as that of TGT IO
- * timeout. The timeout period is different.
- */
- case UNF_TIMER_TYPE_TGT_RRQ:
- times_ms = times_ms + UNF_TGT_RRQ_REDUNDANT_TIME;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "TGT RRQ Timer set.");
- break;
-
- case UNF_TIMER_TYPE_INI_RRQ:
- times_ms = times_ms - UNF_INI_RRQ_REDUNDANT_TIME;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "INI RRQ Timer set.");
- break;
-
- case UNF_TIMER_TYPE_SFS:
- times_ms = times_ms + UNF_INI_ELS_REDUNDANT_TIME;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "INI ELS Timer set.");
- break;
- default:
- break;
- }
-
- /* The xchg of the timer must be valid. If the reference count of xchg
- * is 0, the timer must not be added
- */
- if (atomic_read(&unf_xchg->ref_cnt) <= 0) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_KEVENT,
- "[warn]Abnormal Exchange(0x%p), Reference count(0x%x), Can't add timer.",
- unf_xchg, atomic_read(&unf_xchg->ref_cnt));
- return;
- }
-
- /* Delay Work: Hold for timer */
- spin_lock_irqsave(&unf_xchg->xchg_state_lock, flag);
- if (queue_delayed_work(unf_lport->xchg_wq, &unf_xchg->timeout_work,
- (ulong)msecs_to_jiffies((u32)times_ms))) {
- /* hold for timer */
- atomic_inc(&unf_xchg->ref_cnt);
- }
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flag);
-}
-
-static void unf_init_sfs_xchg_param(struct unf_xchg *xchg,
- struct unf_lport *lport,
- struct unf_xchg_mgr *xchg_mgr)
-{
- xchg->free_pool = &xchg_mgr->free_pool;
- xchg->hot_pool = xchg_mgr->hot_pool;
- xchg->lport = lport;
- xchg->xchg_mgr = xchg_mgr;
- xchg->free_xchg = unf_free_sfs_xchg;
- xchg->xchg_type = UNF_XCHG_TYPE_SFS;
- xchg->io_state = UNF_IO_STATE_NEW;
- xchg->scsi_cmnd_info.result = 0;
- xchg->ob_callback_sts = UNF_IO_SUCCESS;
-
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- (u32)atomic64_inc_return(&((struct unf_lport *)lport->root_lport)->exchg_index);
-
- if (xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] ==
- INVALID_VALUE32) {
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- (u32)atomic64_inc_return(&((struct unf_lport *)lport->root_lport)->exchg_index);
- }
-
- if (xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] == 0) {
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- (u32)atomic64_inc_return(&((struct unf_lport *)lport->root_lport)->exchg_index);
- }
-
- if (delayed_work_pending(&xchg->timeout_work))
- UNF_DEL_XCHG_TIMER_SAFE(xchg);
-
- INIT_DELAYED_WORK(&xchg->timeout_work, unf_sfs_xchg_time_out);
-}
-
-static struct unf_xchg *unf_alloc_sfs_xchg(struct unf_lport *lport,
- struct unf_xchg_mgr *xchg_mgr)
-{
- struct unf_xchg *xchg = NULL;
- struct list_head *list_node = NULL;
- struct unf_xchg_free_pool *free_pool = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(xchg_mgr, NULL);
- free_pool = &xchg_mgr->free_pool;
- hot_pool = xchg_mgr->hot_pool;
- FC_CHECK_RETURN_VALUE(free_pool, NULL);
- FC_CHECK_RETURN_VALUE(hot_pool, NULL);
-
- /* Select an idle node from free pool */
- spin_lock_irqsave(&free_pool->xchg_freepool_lock, flags);
- if (list_empty(&free_pool->list_sfs_xchg_list)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) have no Exchange anymore.",
- lport->port_id);
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
- return NULL;
- }
-
- list_node = UNF_OS_LIST_NEXT(&free_pool->list_sfs_xchg_list);
- list_del(list_node);
- free_pool->total_sfs_xchg--;
- spin_unlock_irqrestore(&free_pool->xchg_freepool_lock, flags);
-
- xchg = list_entry(list_node, struct unf_xchg, list_xchg_entry);
- /*
- * The xchg is mounted to the Hot Pool.
- * The mount mode and release mode of the xchg must be specified
- * and stored in the sfs linked list.
- */
- flags = 0;
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
- if (unf_alloc_hot_pool_slab(hot_pool, xchg) != RETURN_OK) {
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- unf_add_back_to_sfs_list(free_pool, xchg);
- if (unlikely(lport->port_removing))
- unf_check_xchg_mgr_status(xchg_mgr);
-
- return NULL;
- }
-
- list_add_tail(&xchg->list_xchg_entry, &hot_pool->sfs_busylist);
- hot_pool->total_xchges++;
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- unf_init_sfs_xchg_param(xchg, lport, xchg_mgr);
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- return xchg;
-}
-
-static void *unf_get_new_xchg(void *lport, u32 xchg_type)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg_mgr *xchg_mgr = NULL;
- struct unf_xchg *xchg = NULL;
- u32 exchg_type = 0;
- u16 xchg_mgr_type;
- u32 rtry_cnt = 0;
- u32 last_exchg_mgr_idx;
-
- xchg_mgr_type = (xchg_type >> UNF_SHIFT_16);
- exchg_type = xchg_type & SPFC_XCHG_TYPE_MASK;
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- /* In the case of NPIV, the lport is the Vport pointer,
- * and the share uses the ExchMgr of the RootLport.
- */
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VALUE(unf_lport, NULL);
-
- if (unlikely((atomic_read(&unf_lport->lport_no_operate_flag) == UNF_LPORT_NOP) ||
- (atomic_read(&((struct unf_lport *)lport)->lport_no_operate_flag) ==
- UNF_LPORT_NOP))) {
- return NULL;
- }
-
- last_exchg_mgr_idx = (u32)atomic64_inc_return(&unf_lport->last_exchg_mgr_idx);
-try_next_mgr:
- rtry_cnt++;
- if (unlikely(rtry_cnt > UNF_EXCHG_MGR_NUM))
- return NULL;
-
- /* If Fixed mode,only use XchgMgr 0 */
- if (unlikely(xchg_mgr_type == UNF_XCHG_MGR_TYPE_FIXED)) {
- xchg_mgr = (struct unf_xchg_mgr *)unf_lport->xchg_mgr[ARRAY_INDEX_0];
- } else {
- xchg_mgr = (struct unf_xchg_mgr *)unf_lport
- ->xchg_mgr[last_exchg_mgr_idx % UNF_EXCHG_MGR_NUM];
- }
- if (unlikely(!xchg_mgr)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) get exchangemgr %u is null.",
- unf_lport->port_id, last_exchg_mgr_idx % UNF_EXCHG_MGR_NUM);
- return NULL;
- }
- last_exchg_mgr_idx++;
-
- /* Allocate entries based on the Exchange type */
- switch (exchg_type) {
- case UNF_XCHG_TYPE_SFS:
- xchg = unf_alloc_sfs_xchg(lport, xchg_mgr);
- break;
- case UNF_XCHG_TYPE_INI:
- xchg = unf_alloc_io_xchg(lport, xchg_mgr);
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) unwonted, Exchange type(0x%x).",
- unf_lport->port_id, exchg_type);
- break;
- }
-
- if (likely(xchg)) {
- xchg->oxid = INVALID_VALUE16;
- xchg->abort_oxid = INVALID_VALUE16;
- xchg->rxid = INVALID_VALUE16;
- xchg->debug_hook = false;
- xchg->alloc_jif = jiffies;
-
- atomic_set(&xchg->ref_cnt, 1);
- atomic_set(&xchg->esgl_cnt, 0);
- } else {
- goto try_next_mgr;
- }
-
- return xchg;
-}
-
-static void unf_free_xchg(void *lport, void *xchg)
-{
- struct unf_xchg *unf_xchg = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_xchg = (struct unf_xchg *)xchg;
- unf_xchg_ref_dec(unf_xchg, XCHG_FREE_XCHG);
-}
-
-u32 unf_init_xchg_mgr_temp(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- lport->xchg_mgr_temp.unf_xchg_get_free_and_init = unf_get_new_xchg;
- lport->xchg_mgr_temp.unf_xchg_release = unf_free_xchg;
- lport->xchg_mgr_temp.unf_look_up_xchg_by_tag = unf_look_up_xchg_by_tag;
- lport->xchg_mgr_temp.unf_look_up_xchg_by_id = unf_find_xchg_by_ox_id;
- lport->xchg_mgr_temp.unf_xchg_add_timer = unf_fc_xchg_add_timer;
- lport->xchg_mgr_temp.unf_xchg_cancel_timer = unf_xchg_cancel_timer;
- lport->xchg_mgr_temp.unf_xchg_abort_all_io = unf_xchg_abort_all_xchg;
- lport->xchg_mgr_temp.unf_look_up_xchg_by_cmnd_sn = unf_look_up_xchg_by_cmnd_sn;
- lport->xchg_mgr_temp.unf_xchg_abort_by_lun = unf_xchg_abort_by_lun;
- lport->xchg_mgr_temp.unf_xchg_abort_by_session = unf_xchg_abort_by_session;
- lport->xchg_mgr_temp.unf_xchg_mgr_io_xchg_abort = unf_xchg_mgr_io_xchg_abort;
- lport->xchg_mgr_temp.unf_xchg_mgr_sfs_xchg_abort = unf_xchg_mgr_sfs_xchg_abort;
-
- return RETURN_OK;
-}
-
-void unf_release_xchg_mgr_temp(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- if (lport->dirty_flag & UNF_LPORT_DIRTY_FLAG_XCHGMGR_DIRTY) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) has dirty exchange, Don't release exchange manager template.",
- lport->port_id);
-
- return;
- }
-
- memset(&lport->xchg_mgr_temp, 0, sizeof(struct unf_cm_xchg_mgr_template));
-
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_7_DESTROY_XCHG_MGR_TMP;
-}
-
-void unf_set_hot_pool_wait_state(struct unf_lport *lport, bool wait_state)
-{
- struct unf_xchg_hot_pool *hot_pool = NULL;
- ulong pool_lock_flags = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) hot pool is NULL",
- lport->port_id);
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, pool_lock_flags);
- hot_pool->wait_state = wait_state;
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, pool_lock_flags);
- }
-}
-
-u32 unf_xchg_ref_inc(struct unf_xchg *xchg, enum unf_ioflow_id io_stage)
-{
- struct unf_xchg_hot_pool *hot_pool = NULL;
- ulong flags = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- if (unlikely(xchg->debug_hook)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Xchg(0x%p) State(0x%x) SID_DID(0x%x_0x%x) OX_ID_RX_ID(0x%x_0x%x) AllocJiff(%llu) Refcnt(%d) Stage(%s)",
- xchg, xchg->io_state, xchg->sid, xchg->did,
- xchg->oxid, xchg->rxid, xchg->alloc_jif,
- atomic_read(&xchg->ref_cnt),
- io_stage_table[io_stage].stage);
- }
-
- hot_pool = xchg->hot_pool;
- FC_CHECK_RETURN_VALUE(hot_pool, UNF_RETURN_ERROR);
-
- /* Exchange -> Hot Pool Tag check */
- if (unlikely((xchg->hotpooltag >= (hot_pool->slab_total_sum + hot_pool->base)) ||
- xchg->hotpooltag < hot_pool->base)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Xchg(0x%p) S_ID(%xh) D_ID(0x%x) hot_pool_tag(0x%x) is bigger than slab total num(0x%x) base(0x%x)",
- xchg, xchg->sid, xchg->did, xchg->hotpooltag,
- hot_pool->slab_total_sum + hot_pool->base, hot_pool->base);
-
- return UNF_RETURN_ERROR;
- }
-
- /* atomic read & inc */
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if (unlikely(atomic_read(&xchg->ref_cnt) <= 0)) {
- ret = UNF_RETURN_ERROR;
- } else {
- if (unf_get_xchg_by_xchg_tag(hot_pool, xchg->hotpooltag - hot_pool->base) == xchg) {
- atomic_inc(&xchg->ref_cnt);
- ret = RETURN_OK;
- } else {
- ret = UNF_RETURN_ERROR;
- }
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- return ret;
-}
-
-void unf_xchg_ref_dec(struct unf_xchg *xchg, enum unf_ioflow_id io_stage)
-{
- /* Atomic dec ref_cnt & test, free exchange if necessary (ref_cnt==0) */
- struct unf_xchg_hot_pool *hot_pool = NULL;
- void (*free_xchg)(struct unf_xchg *) = NULL;
- ulong flags = 0;
- ulong xchg_lock_falgs = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- if (xchg->debug_hook) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Xchg(0x%p) State(0x%x) SID_DID(0x%x_0x%x) OXID_RXID(0x%x_0x%x) AllocJiff(%llu) Refcnt(%d) Statge %s",
- xchg, xchg->io_state, xchg->sid, xchg->did, xchg->oxid,
- xchg->rxid, xchg->alloc_jif,
- atomic_read(&xchg->ref_cnt),
- io_stage_table[io_stage].stage);
- }
-
- hot_pool = xchg->hot_pool;
- FC_CHECK_RETURN_VOID(hot_pool);
- FC_CHECK_RETURN_VOID((xchg->hotpooltag >= hot_pool->base));
-
- /*
- * 1. Atomic dec & test
- * 2. Free exchange if necessary (ref_cnt == 0)
- */
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_lock_falgs);
- if (atomic_dec_and_test(&xchg->ref_cnt)) {
- free_xchg = xchg->free_xchg;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_lock_falgs);
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
- unf_hot_pool_slab_set(hot_pool,
- xchg->hotpooltag - hot_pool->base, NULL);
- /* Delete exchange list entry */
- list_del_init(&xchg->list_xchg_entry);
- hot_pool->total_xchges--;
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
-
- /* unf_free_fcp_xchg --->>> unf_done_ini_xchg */
- if (free_xchg)
- free_xchg(xchg);
- } else {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_lock_falgs);
- }
-}
-
-static void unf_init_xchg_attribute(struct unf_xchg *xchg)
-{
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- xchg->xchg_mgr = NULL;
- xchg->free_pool = NULL;
- xchg->hot_pool = NULL;
- xchg->lport = NULL;
- xchg->rport = NULL;
- xchg->disc_rport = NULL;
- xchg->io_state = UNF_IO_STATE_NEW;
- xchg->io_send_stage = TGT_IO_SEND_STAGE_NONE;
- xchg->io_send_result = TGT_IO_SEND_RESULT_INVALID;
- xchg->io_send_abort = false;
- xchg->io_abort_result = false;
- xchg->abts_state = 0;
- xchg->oxid = INVALID_VALUE16;
- xchg->abort_oxid = INVALID_VALUE16;
- xchg->rxid = INVALID_VALUE16;
- xchg->sid = INVALID_VALUE32;
- xchg->did = INVALID_VALUE32;
- xchg->oid = INVALID_VALUE32;
- xchg->disc_portid = INVALID_VALUE32;
- xchg->seq_id = INVALID_VALUE8;
- xchg->cmnd_code = INVALID_VALUE32;
- xchg->cmnd_sn = INVALID_VALUE64;
- xchg->data_len = 0;
- xchg->resid_len = 0;
- xchg->data_direction = DMA_NONE;
- xchg->hotpooltag = INVALID_VALUE16;
- xchg->big_sfs_buf = NULL;
- xchg->may_consume_res_cnt = 0;
- xchg->fast_consume_res_cnt = 0;
- xchg->io_front_jif = INVALID_VALUE64;
- xchg->ob_callback_sts = UNF_IO_SUCCESS;
- xchg->start_jif = 0;
- xchg->rport_bind_jifs = INVALID_VALUE64;
- xchg->scsi_id = INVALID_VALUE32;
- xchg->qos_level = 0;
- xchg->world_id = INVALID_VALUE32;
-
- memset(&xchg->seq, 0, sizeof(struct unf_seq));
- memset(&xchg->fcp_cmnd, 0, sizeof(struct unf_fcp_cmnd));
- memset(&xchg->scsi_cmnd_info, 0, sizeof(struct unf_scsi_cmd_info));
- memset(&xchg->dif_info, 0, sizeof(struct dif_info));
- memset(xchg->private_data, 0, (PKG_MAX_PRIVATE_DATA_SIZE * sizeof(u32)));
- xchg->echo_info.echo_result = UNF_ELS_ECHO_RESULT_OK;
- xchg->echo_info.response_time = 0;
-
- if (xchg->xchg_type == UNF_XCHG_TYPE_SFS) {
- if (xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr) {
- memset(xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr, 0,
- sizeof(union unf_sfs_u));
- xchg->fcp_sfs_union.sfs_entry.cur_offset = 0;
- }
- } else if (xchg->xchg_type != UNF_XCHG_TYPE_INI) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Exchange Type(0x%x) SFS Union uninited.",
- xchg->xchg_type);
- }
- xchg->xchg_type = UNF_XCHG_TYPE_INVALID;
- xchg->xfer_or_rsp_echo = NULL;
- xchg->scsi_or_tgt_cmnd_func = NULL;
- xchg->ob_callback = NULL;
- xchg->callback = NULL;
- xchg->free_xchg = NULL;
-
- atomic_set(&xchg->ref_cnt, 0);
- atomic_set(&xchg->esgl_cnt, 0);
- atomic_set(&xchg->delay_flag, 0);
-
- if (delayed_work_pending(&xchg->timeout_work))
- UNF_DEL_XCHG_TIMER_SAFE(xchg);
-
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-}
-
-bool unf_busy_io_completed(struct unf_lport *lport)
-{
- struct unf_xchg_mgr *xchg_mgr = NULL;
- ulong pool_lock_flags = 0;
- u32 i;
-
- FC_CHECK_RETURN_VALUE(lport, true);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- xchg_mgr = unf_get_xchg_mgr_by_lport(lport, i);
- if (unlikely(!xchg_mgr)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) Exchange Manager is NULL",
- lport->port_id);
- continue;
- }
-
- spin_lock_irqsave(&xchg_mgr->hot_pool->xchg_hotpool_lock,
- pool_lock_flags);
- if (!list_empty(&xchg_mgr->hot_pool->ini_busylist)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Port(0x%x) ini busylist is not empty.",
- lport->port_id);
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock,
- pool_lock_flags);
- return false;
- }
- spin_unlock_irqrestore(&xchg_mgr->hot_pool->xchg_hotpool_lock,
- pool_lock_flags);
- }
- return true;
-}
diff --git a/drivers/scsi/spfc/common/unf_exchg.h b/drivers/scsi/spfc/common/unf_exchg.h
deleted file mode 100644
index 0a48be31b971..000000000000
--- a/drivers/scsi/spfc/common/unf_exchg.h
+++ /dev/null
@@ -1,436 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_EXCHG_H
-#define UNF_EXCHG_H
-
-#include "unf_type.h"
-#include "unf_fcstruct.h"
-#include "unf_lport.h"
-#include "unf_scsi_common.h"
-
-enum unf_ioflow_id {
- XCHG_ALLOC = 0,
- TGT_RECEIVE_ABTS,
- TGT_ABTS_DONE,
- TGT_IO_SRR,
- SFS_RESPONSE,
- SFS_TIMEOUT,
- INI_SEND_CMND,
- INI_RESPONSE_DONE,
- INI_EH_ABORT,
- INI_EH_DEVICE_RESET,
- INI_EH_BLS_DONE,
- INI_IO_TIMEOUT,
- INI_REQ_TIMEOUT,
- XCHG_CANCEL_TIMER,
- XCHG_FREE_XCHG,
- SEND_ELS,
- IO_XCHG_WAIT,
- XCHG_BUTT
-};
-
-enum unf_xchg_type {
- UNF_XCHG_TYPE_INI = 0, /* INI IO */
- UNF_XCHG_TYPE_SFS = 1,
- UNF_XCHG_TYPE_INVALID
-};
-
-enum unf_xchg_mgr_type {
- UNF_XCHG_MGR_TYPE_RANDOM = 0,
- UNF_XCHG_MGR_TYPE_FIXED = 1,
- UNF_XCHG_MGR_TYPE_INVALID
-};
-
-enum tgt_io_send_stage {
- TGT_IO_SEND_STAGE_NONE = 0,
- TGT_IO_SEND_STAGE_DOING = 1, /* xfer/rsp into queue */
- TGT_IO_SEND_STAGE_DONE = 2, /* xfer/rsp into queue complete */
- TGT_IO_SEND_STAGE_ECHO = 3, /* driver handled TSTS */
- TGT_IO_SEND_STAGE_INVALID
-};
-
-enum tgt_io_send_result {
- TGT_IO_SEND_RESULT_OK = 0, /* xfer/rsp enqueue succeed */
- TGT_IO_SEND_RESULT_FAIL = 1, /* xfer/rsp enqueue fail */
- TGT_IO_SEND_RESULT_INVALID
-};
-
-struct unf_io_flow_id {
- char *stage;
-};
-
-#define unf_check_oxid_matched(ox_id, oid, xchg) \
- (((ox_id) == (xchg)->oxid) && ((oid) == (xchg)->oid) && \
- (atomic_read(&(xchg)->ref_cnt) > 0))
-
-#define UNF_CHECK_ALLOCTIME_VALID(lport, xchg_tag, exchg, pkg_alloc_time, \
- xchg_alloc_time) \
- do { \
- if (unlikely(((pkg_alloc_time) != 0) && \
- ((pkg_alloc_time) != (xchg_alloc_time)))) { \
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR, \
- "Lport(0x%x_0x%x_0x%x_0x%p) AllocTime is not " \
- "equal,PKG " \
- "AllocTime:0x%x,Exhg AllocTime:0x%x", \
- (lport)->port_id, (lport)->nport_id, xchg_tag, \
- exchg, pkg_alloc_time, xchg_alloc_time); \
- return UNF_RETURN_ERROR; \
- }; \
- if (unlikely((pkg_alloc_time) == 0)) { \
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR, \
- "Lport(0x%x_0x%x_0x%x_0x%p) pkgtime err,PKG " \
- "AllocTime:0x%x,Exhg AllocTime:0x%x", \
- (lport)->port_id, (lport)->nport_id, xchg_tag, \
- exchg, pkg_alloc_time, xchg_alloc_time); \
- }; \
- } while (0)
-
-#define UNF_SET_SCSI_CMND_RESULT(xchg, cmnd_result) \
- ((xchg)->scsi_cmnd_info.result = (cmnd_result))
-
-#define UNF_GET_GS_SFS_XCHG_TIMER(lport) (3 * (ulong)(lport)->ra_tov)
-
-#define UNF_GET_BLS_SFS_XCHG_TIMER(lport) (2 * (ulong)(lport)->ra_tov)
-
-#define UNF_GET_ELS_SFS_XCHG_TIMER(lport) (2 * (ulong)(lport)->ra_tov)
-
-#define UNF_ELS_ECHO_RESULT_OK 0
-#define UNF_ELS_ECHO_RESULT_FAIL 1
-
-struct unf_xchg;
-/* Xchg hot pool, busy IO lookup Xchg */
-struct unf_xchg_hot_pool {
- /* Xchg sum, in hot pool */
- u16 total_xchges;
- bool wait_state;
-
- /* pool lock */
- spinlock_t xchg_hotpool_lock;
-
- /* Xchg posiontion list */
- struct list_head sfs_busylist;
- struct list_head ini_busylist;
- struct list_head list_destroy_xchg;
-
- /* Next free hot point */
- u16 slab_next_index;
- u16 slab_total_sum;
- u16 base;
-
- struct unf_lport *lport;
-
- struct unf_xchg *xchg_slab[ARRAY_INDEX_0];
-};
-
-/* Xchg's FREE POOL */
-struct unf_xchg_free_pool {
- spinlock_t xchg_freepool_lock;
-
- u32 fcp_xchg_sum;
-
- /* IO used Xchg */
- struct list_head list_free_xchg_list;
- u32 total_fcp_xchg;
-
- /* SFS used Xchg */
- struct list_head list_sfs_xchg_list;
- u32 total_sfs_xchg;
- u32 sfs_xchg_sum;
-
- struct completion *xchg_mgr_completion;
-};
-
-struct unf_big_sfs {
- struct list_head entry_bigsfs;
- void *addr;
- u32 size;
-};
-
-struct unf_big_sfs_pool {
- void *big_sfs_pool;
- u32 free_count;
- struct list_head list_freepool;
- struct list_head list_busypool;
- spinlock_t big_sfs_pool_lock;
-};
-
-/* Xchg Manager for vport Xchg */
-struct unf_xchg_mgr {
- /* MG type */
- u32 mgr_type;
-
- /* MG entry */
- struct list_head xchg_mgr_entry;
-
- /* MG attribution */
- u32 mem_szie;
-
- /* MG alloced resource */
- void *fcp_mm_start;
-
- u32 sfs_mem_size;
- void *sfs_mm_start;
- dma_addr_t sfs_phy_addr;
-
- struct unf_xchg_free_pool free_pool;
- struct unf_xchg_hot_pool *hot_pool;
-
- struct unf_big_sfs_pool big_sfs_pool;
-
- struct buf_describe big_sfs_buf_list;
-};
-
-struct unf_seq {
- /* Seq ID */
- u8 seq_id;
-
- /* Seq Cnt */
- u16 seq_cnt;
-
- /* Seq state and len,maybe used for fcoe */
- u16 seq_stat;
- u32 rec_data_len;
-};
-
-union unf_xchg_fcp_sfs {
- struct unf_sfs_entry sfs_entry;
- struct unf_fcp_rsp_iu_entry fcp_rsp_entry;
-};
-
-#define UNF_IO_STATE_NEW 0
-#define TGT_IO_STATE_SEND_XFERRDY (1 << 2) /* succeed to send XFer rdy */
-#define TGT_IO_STATE_RSP (1 << 5) /* chip send rsp */
-#define TGT_IO_STATE_ABORT (1 << 7)
-
-#define INI_IO_STATE_UPTASK \
- (1 << 15) /* INI Upper-layer Task Management Commands */
-#define INI_IO_STATE_UPABORT \
- (1 << 16) /* INI Upper-layer timeout Abort flag \
- */
-#define INI_IO_STATE_DRABORT (1 << 17) /* INI driver Abort flag */
-#define INI_IO_STATE_DONE (1 << 18) /* INI complete flag */
-#define INI_IO_STATE_WAIT_RRQ (1 << 19) /* INI wait send rrq */
-#define INI_IO_STATE_UPSEND_ERR (1 << 20) /* INI send fail flag */
-/* INI only clear firmware resource flag */
-#define INI_IO_STATE_ABORT_RESOURCE (1 << 21)
-/* ioc abort:INI send ABTS ,5S timeout Semaphore,than set 1 */
-#define INI_IO_STATE_ABORT_TIMEOUT (1 << 22)
-#define INI_IO_STATE_RRQSEND_ERR (1 << 23) /* INI send RRQ fail flag */
-#define INI_IO_STATE_LOGO (1 << 24) /* INI busy IO session logo status */
-#define INI_IO_STATE_TMF_ABORT (1 << 25) /* INI TMF ABORT IO flag */
-#define INI_IO_STATE_REC_TIMEOUT_WAIT (1 << 26) /* INI REC TIMEOUT WAIT */
-#define INI_IO_STATE_REC_TIMEOUT (1 << 27) /* INI REC TIMEOUT */
-
-#define TMF_RESPONSE_RECEIVED (1 << 0)
-#define MARKER_STS_RECEIVED (1 << 1)
-#define ABTS_RESPONSE_RECEIVED (1 << 2)
-
-struct unf_scsi_cmd_info {
- ulong time_out;
- ulong abort_time_out;
- void *scsi_cmnd;
- void (*done)(struct unf_scsi_cmnd *scsi_cmd);
- ini_get_sgl_entry_buf unf_get_sgl_entry_buf;
- struct unf_ini_error_code *err_code_table; /* error code table */
- char *sense_buf;
- u32 err_code_table_cout; /* Size of the error code table */
- u32 buf_len;
- u32 entry_cnt;
- u32 result; /* Stores command execution results */
- u32 port_id;
-/* Re-search for rport based on scsiid during retry. Otherwise,
- *data inconsistency will occur
- */
- u32 scsi_id;
- void *sgl;
- uplevel_cmd_done uplevel_done;
-};
-
-struct unf_req_sgl_info {
- void *sgl;
- void *sgl_start;
- u32 req_index;
- u32 entry_index;
-};
-
-struct unf_els_echo_info {
- u64 response_time;
- struct semaphore echo_sync_sema;
- u32 echo_result;
-};
-
-struct unf_xchg {
- /* Mg resource relative */
- /* list delete from HotPool */
- struct unf_xchg_hot_pool *hot_pool;
-
- /* attach to FreePool */
- struct unf_xchg_free_pool *free_pool;
- struct unf_xchg_mgr *xchg_mgr;
- struct unf_lport *lport; /* Local LPort/VLPort */
- struct unf_rport *rport; /* Rmote Port */
- struct unf_rport *disc_rport; /* Discover Rmote Port */
- struct list_head list_xchg_entry;
- struct list_head list_abort_xchg_entry;
- spinlock_t xchg_state_lock;
-
- /* Xchg reference */
- atomic_t ref_cnt;
- atomic_t esgl_cnt;
- bool debug_hook;
- /* Xchg attribution */
- u16 hotpooltag;
- u16 abort_oxid;
- u32 xchg_type; /* LS,TGT CMND ,REQ,or SCSI Cmnd */
- u16 oxid;
- u16 rxid;
- u32 sid;
- u32 did;
- u32 oid; /* ID of the exchange initiator */
- u32 disc_portid; /* Send GNN_ID/GFF_ID NPortId */
- u8 seq_id;
- u8 byte_orders; /* Byte order */
- struct unf_seq seq;
-
- u32 cmnd_code;
- u32 world_id;
- /* Dif control */
- struct unf_dif_control_info dif_control;
- struct dif_info dif_info;
- /* IO status Abort,timer out */
- u32 io_state; /* TGT_IO_STATE_E */
- u32 tmf_state; /* TMF STATE */
- u32 ucode_abts_state;
- u32 abts_state;
-
- /* IO Enqueuing */
- enum tgt_io_send_stage io_send_stage; /* tgt_io_send_stage */
- /* IO Enqueuing result, success or failure */
- enum tgt_io_send_result io_send_result; /* tgt_io_send_result */
-
- u8 io_send_abort; /* is or not send io abort */
- /*result of io abort cmd(succ:true; fail:false)*/
- u8 io_abort_result;
- /* for INI,Indicates the length of the data transmitted over the PCI
- * link
- */
- u32 data_len;
- /* ResidLen,greater than 0 UnderFlow or Less than Overflow */
- int resid_len;
- /* +++++++++++++++++IO Special++++++++++++++++++++ */
- /* point to tgt cmnd/req/scsi cmnd */
- /* Fcp cmnd */
- struct unf_fcp_cmnd fcp_cmnd;
-
- struct unf_scsi_cmd_info scsi_cmnd_info;
-
- struct unf_req_sgl_info req_sgl_info;
-
- struct unf_req_sgl_info dif_sgl_info;
-
- u64 cmnd_sn;
- void *pinitiator;
-
- /* timestamp */
- u64 start_jif;
- u64 alloc_jif;
-
- u64 io_front_jif;
-
- u32 may_consume_res_cnt;
- u32 fast_consume_res_cnt;
-
- /* scsi req info */
- u32 data_direction;
-
- struct unf_big_sfs *big_sfs_buf;
-
- /* scsi cmnd sense_buffer pointer */
- union unf_xchg_fcp_sfs fcp_sfs_union;
-
- /* One exchange may use several External Sgls */
- struct list_head list_esgls;
- struct unf_els_echo_info echo_info;
- struct semaphore task_sema;
-
- /* for RRQ ,IO Xchg add to SFS Xchg */
- void *io_xchg;
-
- /* Xchg delay work */
- struct delayed_work timeout_work;
-
- void (*xfer_or_rsp_echo)(struct unf_xchg *xchg, u32 status);
-
- /* wait list XCHG send function */
- int (*scsi_or_tgt_cmnd_func)(struct unf_xchg *xchg);
-
- /* send result callback */
- void (*ob_callback)(struct unf_xchg *xchg);
-
- /* Response IO callback */
- void (*callback)(void *lport, void *rport, void *xchg);
-
- /* Xchg release function */
- void (*free_xchg)(struct unf_xchg *xchg);
-
- /* +++++++++++++++++low level Special++++++++++++++++++++ */
- /* private data,provide for low level */
- u32 private_data[PKG_MAX_PRIVATE_DATA_SIZE];
-
- u64 rport_bind_jifs;
-
- /* sfs exchg ob callback status */
- u32 ob_callback_sts;
- u32 scsi_id;
- u32 qos_level;
- void *ls_rsp_addr;
- void *ls_req;
- u32 status;
- atomic_t delay_flag;
- void *upper_ct;
-};
-
-struct unf_esgl_page *
-unf_get_and_add_one_free_esgl_page(struct unf_lport *lport,
- struct unf_xchg *xchg);
-void unf_release_xchg_mgr_temp(struct unf_lport *lport);
-u32 unf_init_xchg_mgr_temp(struct unf_lport *lport);
-u32 unf_alloc_xchg_resource(struct unf_lport *lport);
-void unf_free_all_xchg_mgr(struct unf_lport *lport);
-void unf_xchg_mgr_destroy(struct unf_lport *lport);
-u32 unf_xchg_ref_inc(struct unf_xchg *xchg, enum unf_ioflow_id io_stage);
-void unf_xchg_ref_dec(struct unf_xchg *xchg, enum unf_ioflow_id io_stage);
-struct unf_xchg_mgr *unf_get_xchg_mgr_by_lport(struct unf_lport *lport,
- u32 mgr_idx);
-struct unf_xchg_hot_pool *unf_get_hot_pool_by_lport(struct unf_lport *lport,
- u32 mgr_idx);
-void unf_free_lport_ini_xchg(struct unf_xchg_mgr *xchg_mgr, bool done_ini_flag);
-struct unf_xchg *unf_cm_lookup_xchg_by_cmnd_sn(void *lport, u64 command_sn,
- u32 world_id, void *pinitiator);
-void *unf_cm_lookup_xchg_by_id(void *lport, u16 ox_id, u32 oid);
-void unf_cm_xchg_abort_by_lun(struct unf_lport *lport, struct unf_rport *rport,
- u64 lun_id, void *tm_xchg,
- bool abort_all_lun_flag);
-void unf_cm_xchg_abort_by_session(struct unf_lport *lport,
- struct unf_rport *rport);
-
-void unf_cm_xchg_mgr_abort_io_by_id(struct unf_lport *lport,
- struct unf_rport *rport, u32 sid, u32 did,
- u32 extra_io_stat);
-void unf_cm_xchg_mgr_abort_sfs_by_id(struct unf_lport *lport,
- struct unf_rport *rport, u32 sid, u32 did);
-void unf_cm_free_xchg(void *lport, void *xchg);
-void *unf_cm_get_free_xchg(void *lport, u32 xchg_type);
-void *unf_cm_lookup_xchg_by_tag(void *lport, u16 hot_pool_tag);
-void unf_release_esgls(struct unf_xchg *xchg);
-void unf_show_all_xchg(struct unf_lport *lport, struct unf_xchg_mgr *xchg_mgr);
-void unf_destroy_dirty_xchg(struct unf_lport *lport, bool show_only);
-void unf_wake_up_scsi_task_cmnd(struct unf_lport *lport);
-void unf_set_hot_pool_wait_state(struct unf_lport *lport, bool wait_state);
-void unf_free_lport_all_xchg(struct unf_lport *lport);
-extern u32 unf_get_up_level_cmnd_errcode(struct unf_ini_error_code *err_table,
- u32 err_table_count, u32 drv_err_code);
-bool unf_busy_io_completed(struct unf_lport *lport);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_exchg_abort.c b/drivers/scsi/spfc/common/unf_exchg_abort.c
deleted file mode 100644
index 68f751be04aa..000000000000
--- a/drivers/scsi/spfc/common/unf_exchg_abort.c
+++ /dev/null
@@ -1,825 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_exchg_abort.h"
-#include "unf_log.h"
-#include "unf_common.h"
-#include "unf_rport.h"
-#include "unf_service.h"
-#include "unf_ls.h"
-#include "unf_io.h"
-
-void unf_cm_xchg_mgr_abort_io_by_id(struct unf_lport *lport, struct unf_rport *rport, u32 sid,
- u32 did, u32 extra_io_state)
-{
- /*
- * for target session: set ABORT
- * 1. R_Port remove
- * 2. Send PLOGI_ACC callback
- * 3. RCVD PLOGI
- * 4. RCVD LOGO
- */
- FC_CHECK_RETURN_VOID(lport);
-
- if (lport->xchg_mgr_temp.unf_xchg_mgr_io_xchg_abort) {
- /* The SID/DID of the Xchg is in reverse direction in different
- * phases. Therefore, the reverse direction needs to be
- * considered
- */
- lport->xchg_mgr_temp.unf_xchg_mgr_io_xchg_abort(lport, rport, sid, did,
- extra_io_state);
- lport->xchg_mgr_temp.unf_xchg_mgr_io_xchg_abort(lport, rport, did, sid,
- extra_io_state);
- }
-}
-
-void unf_cm_xchg_mgr_abort_sfs_by_id(struct unf_lport *lport,
- struct unf_rport *rport, u32 sid, u32 did)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- if (lport->xchg_mgr_temp.unf_xchg_mgr_sfs_xchg_abort) {
- /* The SID/DID of the Xchg is in reverse direction in different
- * phases, therefore, the reverse direction needs to be
- * considered
- */
- lport->xchg_mgr_temp.unf_xchg_mgr_sfs_xchg_abort(lport, rport, sid, did);
- lport->xchg_mgr_temp.unf_xchg_mgr_sfs_xchg_abort(lport, rport, did, sid);
- }
-}
-
-void unf_cm_xchg_abort_by_lun(struct unf_lport *lport, struct unf_rport *rport,
- u64 lun_id, void *xchg, bool abort_all_lun_flag)
-{
- /*
- * LUN Reset: set UP_ABORT tag, with:
- * INI_Busy_list, IO_Wait_list,
- * IO_Delay_list, IO_Delay_transfer_list
- */
- void (*unf_xchg_abort_by_lun)(void *, void *, u64, void *, bool) = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_xchg_abort_by_lun = lport->xchg_mgr_temp.unf_xchg_abort_by_lun;
- if (unf_xchg_abort_by_lun)
- unf_xchg_abort_by_lun((void *)lport, (void *)rport, lun_id,
- xchg, abort_all_lun_flag);
-}
-
-void unf_cm_xchg_abort_by_session(struct unf_lport *lport, struct unf_rport *rport)
-{
- void (*unf_xchg_abort_by_session)(void *, void *) = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_xchg_abort_by_session = lport->xchg_mgr_temp.unf_xchg_abort_by_session;
- if (unf_xchg_abort_by_session)
- unf_xchg_abort_by_session((void *)lport, (void *)rport);
-}
-
-static void unf_xchg_abort_all_sfs_xchg(struct unf_lport *lport, bool clean)
-{
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- struct unf_xchg *xchg = NULL;
- ulong pool_lock_falgs = 0;
- ulong xchg_lock_flags = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT,
- UNF_MAJOR, "Port(0x%x) Hot Pool is NULL.", lport->port_id);
-
- continue;
- }
-
- if (!clean) {
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
-
- /* Clearing the SFS_Busy_list Exchange Resource */
- list_for_each_safe(xchg_node, next_xchg_node, &hot_pool->sfs_busylist) {
- xchg = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_lock_flags);
- if (atomic_read(&xchg->ref_cnt) > 0)
- xchg->io_state |= TGT_IO_STATE_ABORT;
-
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_lock_flags);
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
- } else {
- continue;
- }
- }
-}
-
-static void unf_xchg_abort_ini_io_xchg(struct unf_lport *lport, bool clean)
-{
- /* Clean L_Port/V_Port Link Down I/O: Abort */
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- struct unf_xchg *xchg = NULL;
- ulong pool_lock_falgs = 0;
- ulong xchg_lock_flags = 0;
- u32 io_state = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) hot pool is NULL",
- lport->port_id);
-
- continue;
- }
-
- if (!clean) {
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
-
- /* 1. Abort INI_Busy_List IO */
- list_for_each_safe(xchg_node, next_xchg_node, &hot_pool->ini_busylist) {
- xchg = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_lock_flags);
- if (atomic_read(&xchg->ref_cnt) > 0)
- xchg->io_state |= INI_IO_STATE_DRABORT | io_state;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_lock_flags);
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
- } else {
- /* Do nothing, just return */
- continue;
- }
- }
-}
-
-void unf_xchg_abort_all_xchg(void *lport, u32 xchg_type, bool clean)
-{
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- unf_lport = (struct unf_lport *)lport;
-
- switch (xchg_type) {
- case UNF_XCHG_TYPE_SFS:
- unf_xchg_abort_all_sfs_xchg(unf_lport, clean);
- break;
- /* Clean L_Port/V_Port Link Down I/O: Abort */
- case UNF_XCHG_TYPE_INI:
- unf_xchg_abort_ini_io_xchg(unf_lport, clean);
- break;
- default:
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) unknown exch type(0x%x)",
- unf_lport->port_id, xchg_type);
- break;
- }
-}
-
-static void unf_xchg_abort_ini_send_tm_cmd(void *lport, void *rport, u64 lun_id)
-{
- /*
- * LUN Reset: set UP_ABORT tag, with:
- * INI_Busy_list, IO_Wait_list,
- * IO_Delay_list, IO_Delay_transfer_list
- */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_xchg *xchg = NULL;
- ulong flags = 0;
- ulong xchg_flag = 0;
- u32 i = 0;
- u64 raw_lun_id = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
- unf_rport = (struct unf_rport *)rport;
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(unf_lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) hot pool is NULL",
- unf_lport->port_id);
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
-
- /* 1. for each exchange from busy list */
- list_for_each_safe(node, next_node, &hot_pool->ini_busylist) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
-
- raw_lun_id = *(u64 *)(xchg->fcp_cmnd.lun) >> UNF_SHIFT_16 &
- UNF_RAW_LUN_ID_MASK;
- if (lun_id == raw_lun_id && unf_rport == xchg->rport) {
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- xchg->io_state |= INI_IO_STATE_TMF_ABORT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Exchange(%p) state(0x%x) S_ID(0x%x) D_ID(0x%x) tag(0x%x) abort by TMF CMD",
- xchg, xchg->io_state,
- ((struct unf_lport *)lport)->nport_id,
- unf_rport->nport_id, xchg->hotpooltag);
- }
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- }
-}
-
-static void unf_xchg_abort_ini_tmf_target_reset(void *lport, void *rport)
-{
- /*
- * LUN Reset: set UP_ABORT tag, with:
- * INI_Busy_list, IO_Wait_list,
- * IO_Delay_list, IO_Delay_transfer_list
- */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_xchg *xchg = NULL;
- ulong flags = 0;
- ulong xchg_flag = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
- unf_rport = (struct unf_rport *)rport;
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(unf_lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) hot pool is NULL",
- unf_lport->port_id);
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
-
- /* 1. for each exchange from busy_list */
- list_for_each_safe(node, next_node, &hot_pool->ini_busylist) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
- if (unf_rport == xchg->rport) {
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- xchg->io_state |= INI_IO_STATE_TMF_ABORT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Exchange(%p) state(0x%x) S_ID(0x%x) D_ID(0x%x) tag(0x%x) abort by TMF CMD",
- xchg, xchg->io_state, unf_lport->nport_id,
- unf_rport->nport_id, xchg->hotpooltag);
- }
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- }
-}
-
-void unf_xchg_abort_by_lun(void *lport, void *rport, u64 lun_id, void *xchg,
- bool abort_all_lun_flag)
-{
- /* ABORT: set UP_ABORT tag for target LUN I/O */
- struct unf_xchg *tm_xchg = (struct unf_xchg *)xchg;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[event]Port(0x%x) LUN_ID(0x%llx) TM_EXCH(0x%p) flag(%d)",
- ((struct unf_lport *)lport)->port_id, lun_id, xchg,
- abort_all_lun_flag);
-
- /* for INI Mode */
- if (!tm_xchg) {
- /*
- * LUN Reset: set UP_ABORT tag, with:
- * INI_Busy_list, IO_Wait_list,
- * IO_Delay_list, IO_Delay_transfer_list
- */
- unf_xchg_abort_ini_send_tm_cmd(lport, rport, lun_id);
-
- return;
- }
-}
-
-void unf_xchg_abort_by_session(void *lport, void *rport)
-{
- /*
- * LUN Reset: set UP_ABORT tag, with:
- * INI_Busy_list, IO_Wait_list,
- * IO_Delay_list, IO_Delay_transfer_list
- */
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[event]Port(0x%x) Rport(0x%x) start session reset with TMF",
- ((struct unf_lport *)lport)->port_id, ((struct unf_rport *)rport)->nport_id);
-
- unf_xchg_abort_ini_tmf_target_reset(lport, rport);
-}
-
-void unf_xchg_up_abort_io_by_scsi_id(void *lport, u32 scsi_id)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_xchg *xchg = NULL;
- ulong flags = 0;
- ulong xchg_flag = 0;
- u32 i;
- u32 io_abort_flag = INI_IO_STATE_UPABORT | INI_IO_STATE_UPSEND_ERR |
- INI_IO_STATE_TMF_ABORT;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(unf_lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) hot pool is NULL",
- unf_lport->port_id);
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
-
- /* 1. for each exchange from busy_list */
- list_for_each_safe(node, next_node, &hot_pool->ini_busylist) {
- xchg = list_entry(node, struct unf_xchg, list_xchg_entry);
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- if (lport == xchg->lport && scsi_id == xchg->scsi_id &&
- !(xchg->io_state & io_abort_flag)) {
- xchg->io_state |= INI_IO_STATE_UPABORT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Exchange(%p) scsi_cmd(0x%p) state(0x%x) scsi_id(0x%x) tag(0x%x) upabort by scsi id",
- xchg, xchg->scsi_cmnd_info.scsi_cmnd,
- xchg->io_state, scsi_id, xchg->hotpooltag);
- } else {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
- }
- }
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- }
-}
-
-static void unf_ini_busy_io_xchg_abort(void *xchg_hot_pool, void *rport,
- u32 sid, u32 did, u32 extra_io_state)
-{
- /*
- * for target session: Set (DRV) ABORT
- * 1. R_Port remove
- * 2. Send PLOGI_ACC callback
- * 3. RCVD PLOGI
- * 4. RCVD LOGO
- */
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct unf_xchg *xchg = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong xchg_lock_flags = 0;
-
- unf_rport = (struct unf_rport *)rport;
- hot_pool = (struct unf_xchg_hot_pool *)xchg_hot_pool;
-
- /* ABORT INI IO: INI_BUSY_LIST */
- list_for_each_safe(xchg_node, next_xchg_node, &hot_pool->ini_busylist) {
- xchg = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_lock_flags);
- if (did == xchg->did && sid == xchg->sid &&
- unf_rport == xchg->rport &&
- (atomic_read(&xchg->ref_cnt) > 0)) {
- xchg->scsi_cmnd_info.result = UNF_SCSI_HOST(DID_IMM_RETRY);
- xchg->io_state |= INI_IO_STATE_DRABORT;
- xchg->io_state |= extra_io_state;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Abort INI:0x%p---0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----%llu.",
- xchg, (u32)xchg->hotpooltag, (u32)xchg->xchg_type,
- (u32)xchg->oxid, (u32)xchg->rxid,
- (u32)xchg->sid, (u32)xchg->did, (u32)xchg->io_state,
- atomic_read(&xchg->ref_cnt), xchg->alloc_jif);
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_lock_flags);
- }
-}
-
-void unf_xchg_mgr_io_xchg_abort(void *lport, void *rport, u32 sid, u32 did, u32 extra_io_state)
-{
- /*
- * for target session: set ABORT
- * 1. R_Port remove
- * 2. Send PLOGI_ACC callback
- * 3. RCVD PLOGI
- * 4. RCVD LOGO
- */
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong pool_lock_falgs = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(unf_lport, i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) hot pool is NULL",
- unf_lport->port_id);
-
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
-
- /* 1. Clear INI (session) IO: INI Mode */
- unf_ini_busy_io_xchg_abort(hot_pool, rport, sid, did, extra_io_state);
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
- }
-}
-
-void unf_xchg_mgr_sfs_xchg_abort(void *lport, void *rport, u32 sid, u32 did)
-{
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- struct unf_xchg *xchg = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong pool_lock_falgs = 0;
- ulong xchg_lock_flags = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport(unf_lport, i);
- if (!hot_pool) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT,
- UNF_MAJOR, "Port(0x%x) Hot Pool is NULL.",
- unf_lport->port_id);
-
- continue;
- }
-
- unf_rport = (struct unf_rport *)rport;
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
-
- /* Clear the SFS exchange of the corresponding connection */
- list_for_each_safe(xchg_node, next_xchg_node, &hot_pool->sfs_busylist) {
- xchg = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_lock_flags);
- if (did == xchg->did && sid == xchg->sid &&
- unf_rport == xchg->rport && (atomic_read(&xchg->ref_cnt) > 0)) {
- xchg->io_state |= TGT_IO_STATE_ABORT;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Abort SFS:0x%p---0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----0x%x----%llu.",
- xchg, (u32)xchg->hotpooltag, (u32)xchg->xchg_type,
- (u32)xchg->oxid, (u32)xchg->rxid, (u32)xchg->sid,
- (u32)xchg->did, (u32)xchg->io_state,
- atomic_read(&xchg->ref_cnt), xchg->alloc_jif);
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_lock_flags);
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, pool_lock_falgs);
- }
-}
-
-static void unf_fc_wait_abts_complete(struct unf_lport *lport, struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = lport;
- struct unf_scsi_cmnd scsi_cmnd = {0};
- ulong flag = 0;
- u32 time_out_value = 2000;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- u32 io_result;
-
- scsi_cmnd.scsi_id = xchg->scsi_cmnd_info.scsi_id;
- scsi_cmnd.upper_cmnd = xchg->scsi_cmnd_info.scsi_cmnd;
- scsi_cmnd.done = xchg->scsi_cmnd_info.done;
- scsi_image_table = &unf_lport->rport_scsi_table;
-
- if (down_timeout(&xchg->task_sema, (s64)msecs_to_jiffies(time_out_value))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) recv abts marker timeout,Exch(0x%p) OX_ID(0x%x) RX_ID(0x%x)",
- unf_lport->port_id, xchg, xchg->oxid, xchg->rxid);
- goto ABTS_FIAILED;
- }
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- if (xchg->ucode_abts_state == UNF_IO_SUCCESS ||
- xchg->scsi_cmnd_info.result == UNF_IO_ABORT_PORT_REMOVING) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Port(0x%x) Send ABTS succeed and recv marker Exch(0x%p) OX_ID(0x%x) RX_ID(0x%x) marker status(0x%x)",
- unf_lport->port_id, xchg, xchg->oxid, xchg->rxid,
- xchg->ucode_abts_state);
- io_result = DID_BUS_BUSY;
- UNF_IO_RESULT_CNT(scsi_image_table, scsi_cmnd.scsi_id, io_result);
- unf_complete_cmnd(&scsi_cmnd, io_result << UNF_SHIFT_16);
- return;
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ABTS failed. Exch(0x%p) hot_tag(0x%x) ret(0x%x) xchg->io_state (0x%x)",
- unf_lport->port_id, xchg, xchg->hotpooltag,
- xchg->scsi_cmnd_info.result, xchg->io_state);
- goto ABTS_FIAILED;
-
-ABTS_FIAILED:
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- xchg->io_state &= ~INI_IO_STATE_UPABORT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-}
-
-void unf_fc_abort_time_out_cmnd(struct unf_lport *lport, struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = lport;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- if (xchg->io_state & INI_IO_STATE_UPABORT) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "LPort(0x%x) xchange(0x%p) OX_ID(0x%x), RX_ID(0x%x) Cmdsn(0x%lx) has been aborted.",
- unf_lport->port_id, xchg, xchg->oxid,
- xchg->rxid, (ulong)xchg->cmnd_sn);
- return;
- }
- xchg->io_state |= INI_IO_STATE_UPABORT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_KEVENT,
- "LPort(0x%x) exchg(0x%p) OX_ID(0x%x) RX_ID(0x%x) Cmdsn(0x%lx) timeout abort it",
- unf_lport->port_id, xchg, xchg->oxid, xchg->rxid, (ulong)xchg->cmnd_sn);
-
- unf_lport->xchg_mgr_temp.unf_xchg_add_timer((void *)xchg,
- (ulong)UNF_WAIT_ABTS_RSP_TIMEOUT, UNF_TIMER_TYPE_INI_ABTS);
-
- sema_init(&xchg->task_sema, 0);
-
- if (unf_send_abts(unf_lport, xchg) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "LPort(0x%x) send ABTS, Send ABTS unsuccessful. Exchange OX_ID(0x%x), RX_ID(0x%x).",
- unf_lport->port_id, xchg->oxid, xchg->rxid);
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- xchg->io_state &= ~INI_IO_STATE_UPABORT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
- return;
- }
- unf_fc_wait_abts_complete(unf_lport, xchg);
-}
-
-static void unf_fc_ini_io_rec_wait_time_out(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- ulong time_out = 0;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) Exch(0x%p) Rec timeout exchange OX_ID(0x%x) RX_ID(0x%x) state(0x%x)",
- lport->port_id, rport->nport_id, xchg, xchg->oxid,
- xchg->rxid, xchg->io_state);
-
- if (xchg->rport_bind_jifs == rport->rport_alloc_jifs) {
- unf_send_rec(lport, rport, xchg);
-
- if (xchg->scsi_cmnd_info.abort_time_out > 0) {
- time_out = (xchg->scsi_cmnd_info.abort_time_out > UNF_REC_TOV) ?
- (xchg->scsi_cmnd_info.abort_time_out - UNF_REC_TOV) : 0;
- if (time_out > 0) {
- lport->xchg_mgr_temp.unf_xchg_add_timer((void *)xchg, time_out,
- UNF_TIMER_TYPE_REQ_IO);
- } else {
- unf_fc_abort_time_out_cmnd(lport, xchg);
- }
- }
- }
-}
-
-static void unf_fc_ini_send_abts_time_out(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- if (xchg->rport_bind_jifs == rport->rport_alloc_jifs &&
- xchg->rport_bind_jifs != INVALID_VALUE64) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) Exch(0x%p) first time to send abts timeout, retry again OX_ID(0x%x) RX_ID(0x%x) HotTag(0x%x) state(0x%x)",
- lport->port_id, rport->nport_id, xchg, xchg->oxid,
- xchg->rxid, xchg->hotpooltag, xchg->io_state);
-
- lport->xchg_mgr_temp.unf_xchg_add_timer((void *)xchg,
- (ulong)UNF_WAIT_ABTS_RSP_TIMEOUT, UNF_TIMER_TYPE_INI_ABTS);
-
- if (unf_send_abts(lport, xchg) != RETURN_OK) {
- lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
-
- unf_abts_timeout_recovery_default(rport, xchg);
-
- unf_cm_free_xchg(lport, xchg);
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) Exch(0x%p) rport is invalid, exchg rport jiff(0x%llx 0x%llx), free exchange OX_ID(0x%x) RX_ID(0x%x) state(0x%x)",
- lport->port_id, rport->nport_id, xchg,
- xchg->rport_bind_jifs, rport->rport_alloc_jifs,
- xchg->oxid, xchg->rxid, xchg->io_state);
-
- unf_cm_free_xchg(lport, xchg);
- }
-}
-
-void unf_fc_ini_io_xchg_time_out(struct work_struct *work)
-{
- struct unf_xchg *xchg = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flags = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 port_valid_flag = 0;
-
- xchg = container_of(work, struct unf_xchg, timeout_work.work);
- FC_CHECK_RETURN_VOID(xchg);
-
- ret = unf_xchg_ref_inc(xchg, INI_IO_TIMEOUT);
- FC_CHECK_RETURN_VOID(ret == RETURN_OK);
-
- unf_lport = xchg->lport;
- unf_rport = xchg->rport;
-
- port_valid_flag = (!unf_lport) || (!unf_rport);
- if (port_valid_flag) {
- unf_xchg_ref_dec(xchg, INI_IO_TIMEOUT);
- unf_xchg_ref_dec(xchg, INI_IO_TIMEOUT);
- return;
- }
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- /* 1. for Send RRQ failed Timer timeout */
- if (INI_IO_STATE_RRQSEND_ERR & xchg->io_state) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[info]LPort(0x%x) RPort(0x%x) Exch(0x%p) had wait enough time for RRQ send failed OX_ID(0x%x) RX_ID(0x%x) state(0x%x)",
- unf_lport->port_id, unf_rport->nport_id, xchg,
- xchg->oxid, xchg->rxid, xchg->io_state);
- unf_notify_chip_free_xid(xchg);
- unf_cm_free_xchg(unf_lport, xchg);
- }
- /* Second ABTS timeout and enter LOGO process */
- else if ((INI_IO_STATE_ABORT_TIMEOUT & xchg->io_state) &&
- (!(ABTS_RESPONSE_RECEIVED & xchg->abts_state))) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) Exch(0x%p) had wait enough time for second abts send OX_ID(0x%x) RX_ID(0x%x) state(0x%x)",
- unf_lport->port_id, unf_rport->nport_id, xchg,
- xchg->oxid, xchg->rxid, xchg->io_state);
- unf_abts_timeout_recovery_default(unf_rport, xchg);
- unf_cm_free_xchg(unf_lport, xchg);
- }
- /* First time to send ABTS, timeout and retry to send ABTS again */
- else if ((INI_IO_STATE_UPABORT & xchg->io_state) &&
- (!(ABTS_RESPONSE_RECEIVED & xchg->abts_state))) {
- xchg->io_state |= INI_IO_STATE_ABORT_TIMEOUT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- unf_fc_ini_send_abts_time_out(unf_lport, unf_rport, xchg);
- }
- /* 3. IO_DONE */
- else if ((INI_IO_STATE_DONE & xchg->io_state) &&
- (ABTS_RESPONSE_RECEIVED & xchg->abts_state)) {
- /*
- * for IO_DONE:
- * 1. INI ABTS first timer time out
- * 2. INI RCVD ABTS Response
- * 3. Normal case for I/O Done
- */
- /* Send ABTS & RCVD RSP & no timeout */
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- if (unf_send_rrq(unf_lport, unf_rport, xchg) == RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]LPort(0x%x) send RRQ succeed to RPort(0x%x) Exch(0x%p) OX_ID(0x%x) RX_ID(0x%x) state(0x%x)",
- unf_lport->port_id, unf_rport->nport_id, xchg,
- xchg->oxid, xchg->rxid, xchg->io_state);
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]LPort(0x%x) can't send RRQ to RPort(0x%x) Exch(0x%p) OX_ID(0x%x) RX_ID(0x%x) state(0x%x)",
- unf_lport->port_id, unf_rport->nport_id, xchg,
- xchg->oxid, xchg->rxid, xchg->io_state);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- xchg->io_state |= INI_IO_STATE_RRQSEND_ERR;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- unf_lport->xchg_mgr_temp.unf_xchg_add_timer((void *)xchg,
- (ulong)UNF_WRITE_RRQ_SENDERR_INTERVAL, UNF_TIMER_TYPE_INI_IO);
- }
- } else if (INI_IO_STATE_REC_TIMEOUT_WAIT & xchg->io_state) {
- xchg->io_state &= ~INI_IO_STATE_REC_TIMEOUT_WAIT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- unf_fc_ini_io_rec_wait_time_out(unf_lport, unf_rport, xchg);
- } else {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- unf_fc_abort_time_out_cmnd(unf_lport, xchg);
- }
-
- unf_xchg_ref_dec(xchg, INI_IO_TIMEOUT);
- unf_xchg_ref_dec(xchg, INI_IO_TIMEOUT);
-}
-
-void unf_sfs_xchg_time_out(struct work_struct *work)
-{
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(work);
- xchg = container_of(work, struct unf_xchg, timeout_work.work);
- FC_CHECK_RETURN_VOID(xchg);
-
- ret = unf_xchg_ref_inc(xchg, SFS_TIMEOUT);
- FC_CHECK_RETURN_VOID(ret == RETURN_OK);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- unf_lport = xchg->lport;
- unf_rport = xchg->rport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- unf_xchg_ref_dec(xchg, SFS_TIMEOUT);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]SFS Exch(%p) Cmnd(0x%x) IO Exch(0x%p) Sid_Did(0x%x:0x%x) HotTag(0x%x) State(0x%x) Timeout.",
- xchg, xchg->cmnd_code, xchg->io_xchg, xchg->sid, xchg->did,
- xchg->hotpooltag, xchg->io_state);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if ((xchg->io_state & TGT_IO_STATE_ABORT) &&
- xchg->cmnd_code != ELS_RRQ && xchg->cmnd_code != ELS_LOGO) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "SFS Exch(0x%p) Cmnd(0x%x) Hot Pool Tag(0x%x) timeout, but aborted, no need to handle.",
- xchg, xchg->cmnd_code, xchg->hotpooltag);
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- unf_xchg_ref_dec(xchg, SFS_TIMEOUT);
- unf_xchg_ref_dec(xchg, SFS_TIMEOUT);
-
- return;
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- /* The sfs times out. If the sfs is ELS reply,
- * go to UNF_RPortErrorRecovery/unf_lport_error_recovery.
- * Otherwise, go to the corresponding obCallback.
- */
- if (UNF_XCHG_IS_ELS_REPLY(xchg) && unf_rport) {
- if (unf_rport->nport_id >= UNF_FC_FID_DOM_MGR)
- unf_lport_error_recovery(unf_lport);
- else
- unf_rport_error_recovery(unf_rport);
-
- } else if (xchg->ob_callback) {
- xchg->ob_callback(xchg);
- } else {
- /* Do nothing */
- }
- unf_notify_chip_free_xid(xchg);
- unf_xchg_ref_dec(xchg, SFS_TIMEOUT);
- unf_xchg_ref_dec(xchg, SFS_TIMEOUT);
-}
diff --git a/drivers/scsi/spfc/common/unf_exchg_abort.h b/drivers/scsi/spfc/common/unf_exchg_abort.h
deleted file mode 100644
index 75b5a1bab733..000000000000
--- a/drivers/scsi/spfc/common/unf_exchg_abort.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_EXCHG_ABORT_H
-#define UNF_EXCHG_ABORT_H
-
-#include "unf_type.h"
-#include "unf_exchg.h"
-
-#define UNF_RAW_LUN_ID_MASK 0x000000000000ffff
-
-void unf_xchg_abort_by_lun(void *lport, void *rport, u64 lun_id, void *tm_xchg,
- bool abort_all_lun_flag);
-void unf_xchg_abort_by_session(void *lport, void *rport);
-void unf_xchg_mgr_io_xchg_abort(void *lport, void *rport, u32 sid, u32 did,
- u32 extra_io_state);
-void unf_xchg_mgr_sfs_xchg_abort(void *lport, void *rport, u32 sid, u32 did);
-void unf_xchg_abort_all_xchg(void *lport, u32 xchg_type, bool clean);
-void unf_fc_abort_time_out_cmnd(struct unf_lport *lport, struct unf_xchg *xchg);
-void unf_fc_ini_io_xchg_time_out(struct work_struct *work);
-void unf_sfs_xchg_time_out(struct work_struct *work);
-void unf_xchg_up_abort_io_by_scsi_id(void *lport, u32 scsi_id);
-#endif
diff --git a/drivers/scsi/spfc/common/unf_fcstruct.h b/drivers/scsi/spfc/common/unf_fcstruct.h
deleted file mode 100644
index d6eb8592994b..000000000000
--- a/drivers/scsi/spfc/common/unf_fcstruct.h
+++ /dev/null
@@ -1,459 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_FCSTRUCT_H
-#define UNF_FCSTRUCT_H
-
-#include "unf_type.h"
-#include "unf_scsi_common.h"
-
-#define FC_RCTL_BLS 0x80000000
-
-/*
- * * R_CTL Basic Link Data defines
- */
-
-#define FC_RCTL_BLS_ACC (FC_RCTL_BLS | 0x04000000)
-#define FC_RCTL_BLS_RJT (FC_RCTL_BLS | 0x05000000)
-
-/*
- * * BA_RJT reason code defines
- */
-#define FCXLS_BA_RJT_LOGICAL_ERROR 0x00030000
-
-/*
- * * BA_RJT code explanation
- */
-
-#define FCXLS_LS_RJT_INVALID_OXID_RXID 0x00001700
-
-/*
- * * ELS ACC
- */
-struct unf_els_acc {
- struct unf_fc_head frame_hdr;
- u32 cmnd;
-};
-
-/*
- * * ELS RJT
- */
-struct unf_els_rjt {
- struct unf_fc_head frame_hdr;
- u32 cmnd;
- u32 reason_code;
-};
-
-/*
- * * FLOGI payload,
- * * FC-LS-2 FLOGI, PLOGI, FDISC or LS_ACC Payload
- */
-struct unf_flogi_fdisc_payload {
- u32 cmnd;
- struct unf_fabric_parm fabric_parms;
-};
-
-/*
- * * Flogi and Flogi accept frames. They are the same structure
- */
-struct unf_flogi_fdisc_acc {
- struct unf_fc_head frame_hdr;
- struct unf_flogi_fdisc_payload flogi_payload;
-};
-
-/*
- * * Fdisc and Fdisc accept frames. They are the same structure
- */
-
-struct unf_fdisc_acc {
- struct unf_fc_head frame_hdr;
- struct unf_flogi_fdisc_payload fdisc_payload;
-};
-
-/*
- * * PLOGI payload
- */
-struct unf_plogi_payload {
- u32 cmnd;
- struct unf_lgn_parm stparms;
-};
-
-/*
- *Plogi, Plogi accept, Pdisc and Pdisc accept frames. They are all the same
- *structure.
- */
-struct unf_plogi_pdisc {
- struct unf_fc_head frame_hdr;
- struct unf_plogi_payload payload;
-};
-
-/*
- * * LOGO logout link service requests invalidation of service parameters and
- * * port name.
- * * see FC-PH 4.3 Section 21.4.8
- */
-struct unf_logo_payload {
- u32 cmnd;
- u32 nport_id;
- u32 high_port_name;
- u32 low_port_name;
-};
-
-/*
- * * payload to hold LOGO command
- */
-struct unf_logo {
- struct unf_fc_head frame_hdr;
- struct unf_logo_payload payload;
-};
-
-/*
- * * payload for ECHO command, refer to FC-LS-2 4.2.4
- */
-struct unf_echo_payload {
- u32 cmnd;
-#define UNF_FC_ECHO_PAYLOAD_LENGTH 255 /* Length in words */
- u32 data[UNF_FC_ECHO_PAYLOAD_LENGTH];
-};
-
-struct unf_echo {
- struct unf_fc_head frame_hdr;
- struct unf_echo_payload *echo_pld;
- dma_addr_t phy_echo_addr;
-};
-
-#define UNF_PRLI_SIRT_EXTRA_SIZE 12
-
-/*
- * * payload for PRLI and PRLO
- */
-struct unf_prli_payload {
- u32 cmnd;
-#define UNF_FC_PRLI_PAYLOAD_LENGTH 7 /* Length in words */
- u32 parms[UNF_FC_PRLI_PAYLOAD_LENGTH];
-};
-
-/*
- * * FCHS structure with payload
- */
-struct unf_prli_prlo {
- struct unf_fc_head frame_hdr;
- struct unf_prli_payload payload;
-};
-
-struct unf_adisc_payload {
- u32 cmnd;
- u32 hard_address;
- u32 high_port_name;
- u32 low_port_name;
- u32 high_node_name;
- u32 low_node_name;
- u32 nport_id;
-};
-
-/*
- * * FCHS structure with payload
- */
-struct unf_adisc {
- struct unf_fc_head frame_hdr; /* FCHS structure */
- struct unf_adisc_payload
- adisc_payl; /* Payload data containing ADISC info
- */
-};
-
-/*
- * * RLS payload
- */
-struct unf_rls_payload {
- u32 cmnd;
- u32 nport_id; /* in litle endian format */
-};
-
-/*
- * * RLS
- */
-struct unf_rls {
- struct unf_fc_head frame_hdr; /* FCHS structure */
- struct unf_rls_payload rls; /* payload data containing the RLS info */
-};
-
-/*
- * * RLS accept payload
- */
-struct unf_rls_acc_payload {
- u32 cmnd;
- u32 link_failure_count;
- u32 loss_of_sync_count;
- u32 loss_of_signal_count;
- u32 primitive_seq_count;
- u32 invalid_trans_word_count;
- u32 invalid_crc_count;
-};
-
-/*
- * * RLS accept
- */
-struct unf_rls_acc {
- struct unf_fc_head frame_hdr; /* FCHS structure */
- struct unf_rls_acc_payload
- rls; /* payload data containing the RLS ACC info
- */
-};
-
-/*
- * * FCHS structure with payload
- */
-struct unf_rrq {
- struct unf_fc_head frame_hdr;
- u32 cmnd;
- u32 sid;
- u32 oxid_rxid;
-};
-
-#define UNF_SCR_PAYLOAD_CNT 2
-struct unf_scr {
- struct unf_fc_head frame_hdr;
- u32 payload[UNF_SCR_PAYLOAD_CNT];
-};
-
-struct unf_ctiu_prem {
- u32 rev_inid;
- u32 gstype_gssub_options;
- u32 cmnd_rsp_size;
- u32 frag_reason_exp_vend;
-};
-
-#define UNF_FC4TYPE_CNT 8
-struct unf_rftid {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 nport_id;
- u32 fc4_types[UNF_FC4TYPE_CNT];
-};
-
-struct unf_rffid {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 nport_id;
- u32 fc4_feature;
-};
-
-struct unf_rffid_rsp {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
-};
-
-struct unf_gffid {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 nport_id;
-};
-
-struct unf_gffid_rsp {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 fc4_feature[32];
-};
-
-struct unf_gnnid {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 nport_id;
-};
-
-struct unf_gnnid_rsp {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 node_name[2];
-};
-
-struct unf_gpnid {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 nport_id;
-};
-
-struct unf_gpnid_rsp {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
- u32 port_name[2];
-};
-
-struct unf_rft_rsp {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
-};
-
-struct unf_ls_rjt_pld {
- u32 srr_op; /* 01000000h */
- u8 vandor;
- u8 reason_exp;
- u8 reason;
- u8 reserved;
-};
-
-struct unf_ls_rjt {
- struct unf_fc_head frame_hdr;
- struct unf_ls_rjt_pld pld;
-};
-
-struct unf_rec_pld {
- u32 rec_cmnd;
- u32 xchg_org_sid; /* bit0-bit23 */
- u16 rx_id;
- u16 ox_id;
-};
-
-struct unf_rec {
- struct unf_fc_head frame_hdr;
- struct unf_rec_pld rec_pld;
-};
-
-struct unf_rec_acc_pld {
- u32 cmnd;
- u16 rx_id;
- u16 ox_id;
- u32 org_addr_id; /* bit0-bit23 */
- u32 rsp_addr_id; /* bit0-bit23 */
-};
-
-struct unf_rec_acc {
- struct unf_fc_head frame_hdr;
- struct unf_rec_acc_pld payload;
-};
-
-struct unf_gid {
- struct unf_ctiu_prem ctiu_pream;
- u32 scope_type;
-};
-
-struct unf_gid_acc {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
-};
-
-#define UNF_LOOPMAP_COUNT 128
-struct unf_loop_init {
- struct unf_fc_head frame_hdr;
- u32 cmnd;
-#define UNF_FC_ALPA_BIT_MAP_SIZE 4
- u32 alpha_bit_map[UNF_FC_ALPA_BIT_MAP_SIZE];
-};
-
-struct unf_loop_map {
- struct unf_fc_head frame_hdr;
- u32 cmnd;
- u32 loop_map[32];
-};
-
-struct unf_ctiu_rjt {
- struct unf_fc_head frame_hdr;
- struct unf_ctiu_prem ctiu_pream;
-};
-
-struct unf_gid_acc_pld {
- struct unf_ctiu_prem ctiu_pream;
-
- u32 gid_port_id[UNF_GID_PORT_CNT];
-};
-
-struct unf_gid_rsp {
- struct unf_gid_acc_pld *gid_acc_pld;
-};
-
-struct unf_gid_req_rsp {
- struct unf_fc_head frame_hdr;
- struct unf_gid gid_req;
- struct unf_gid_rsp gid_rsp;
-};
-
-/* FC-LS-2 Table 31 RSCN Payload */
-struct unf_rscn_port_id_page {
- u8 port_id_port;
- u8 port_id_area;
- u8 port_id_domain;
-
- u8 addr_format : 2;
- u8 event_qualifier : 4;
- u8 reserved : 2;
-};
-
-struct unf_rscn_pld {
- u32 cmnd;
- struct unf_rscn_port_id_page port_id_page[UNF_RSCN_PAGE_SUM];
-};
-
-struct unf_rscn {
- struct unf_fc_head frame_hdr;
- struct unf_rscn_pld *rscn_pld;
-};
-
-union unf_sfs_u {
- struct {
- struct unf_fc_head frame_head;
- u8 data[0];
- } sfs_common;
- struct unf_els_acc els_acc;
- struct unf_els_rjt els_rjt;
- struct unf_plogi_pdisc plogi;
- struct unf_logo logo;
- struct unf_echo echo;
- struct unf_echo echo_acc;
- struct unf_prli_prlo prli;
- struct unf_prli_prlo prlo;
- struct unf_rls rls;
- struct unf_rls_acc rls_acc;
- struct unf_plogi_pdisc pdisc;
- struct unf_adisc adisc;
- struct unf_rrq rrq;
- struct unf_flogi_fdisc_acc flogi;
- struct unf_fdisc_acc fdisc;
- struct unf_scr scr;
- struct unf_rec rec;
- struct unf_rec_acc rec_acc;
- struct unf_ls_rjt ls_rjt;
- struct unf_rscn rscn;
- struct unf_gid_req_rsp get_id;
- struct unf_rftid rft_id;
- struct unf_rft_rsp rft_id_rsp;
- struct unf_rffid rff_id;
- struct unf_rffid_rsp rff_id_rsp;
- struct unf_gffid gff_id;
- struct unf_gffid_rsp gff_id_rsp;
- struct unf_gnnid gnn_id;
- struct unf_gnnid_rsp gnn_id_rsp;
- struct unf_gpnid gpn_id;
- struct unf_gpnid_rsp gpn_id_rsp;
- struct unf_plogi_pdisc plogi_acc;
- struct unf_plogi_pdisc pdisc_acc;
- struct unf_adisc adisc_acc;
- struct unf_prli_prlo prli_acc;
- struct unf_prli_prlo prlo_acc;
- struct unf_flogi_fdisc_acc flogi_acc;
- struct unf_fdisc_acc fdisc_acc;
- struct unf_loop_init lpi;
- struct unf_loop_map loop_map;
- struct unf_ctiu_rjt ctiu_rjt;
-};
-
-struct unf_sfs_entry {
- union unf_sfs_u *fc_sfs_entry_ptr; /* Virtual addr of SFS buffer */
- u64 sfs_buff_phy_addr; /* Physical addr of SFS buffer */
- u32 sfs_buff_len; /* Length of bytes in SFS buffer */
- u32 cur_offset;
-};
-
-struct unf_fcp_rsp_iu_entry {
- u8 *fcp_rsp_iu;
- u32 fcp_sense_len;
-};
-
-struct unf_rjt_info {
- u32 els_cmnd_code;
- u32 reason_code;
- u32 reason_explanation;
- u8 class_mode;
- u8 ucrsvd[3];
-};
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_gs.c b/drivers/scsi/spfc/common/unf_gs.c
deleted file mode 100644
index cb5fc1a5d246..000000000000
--- a/drivers/scsi/spfc/common/unf_gs.c
+++ /dev/null
@@ -1,2521 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_gs.h"
-#include "unf_log.h"
-#include "unf_exchg.h"
-#include "unf_rport.h"
-#include "unf_service.h"
-#include "unf_portman.h"
-#include "unf_ls.h"
-
-static void unf_gpn_id_callback(void *lport, void *sns_port, void *xchg);
-static void unf_gpn_id_ob_callback(struct unf_xchg *xchg);
-static void unf_gnn_id_ob_callback(struct unf_xchg *xchg);
-static void unf_scr_callback(void *lport, void *rport, void *xchg);
-static void unf_scr_ob_callback(struct unf_xchg *xchg);
-static void unf_gff_id_ob_callback(struct unf_xchg *xchg);
-static void unf_gff_id_callback(void *lport, void *sns_port, void *xchg);
-static void unf_gnn_id_callback(void *lport, void *sns_port, void *xchg);
-static void unf_gid_ft_ob_callback(struct unf_xchg *xchg);
-static void unf_gid_ft_callback(void *lport, void *rport, void *xchg);
-static void unf_gid_pt_ob_callback(struct unf_xchg *xchg);
-static void unf_gid_pt_callback(void *lport, void *rport, void *xchg);
-static void unf_rft_id_ob_callback(struct unf_xchg *xchg);
-static void unf_rft_id_callback(void *lport, void *rport, void *xchg);
-static void unf_rff_id_callback(void *lport, void *rport, void *xchg);
-static void unf_rff_id_ob_callback(struct unf_xchg *xchg);
-
-#define UNF_GET_DOMAIN_ID(x) (((x) & 0xFF0000) >> 16)
-#define UNF_GET_AREA_ID(x) (((x) & 0x00FF00) >> 8)
-
-#define UNF_GID_LAST_PORT_ID 0x80
-#define UNF_GID_CONTROL(nport_id) ((nport_id) >> 24)
-#define UNF_GET_PORT_OPTIONS(fc_4feature) ((fc_4feature) >> 20)
-
-#define UNF_SERVICE_GET_NPORTID_FORM_GID_PAGE(port_id_page) \
- (((u32)(port_id_page)->port_id_domain << 16) | \
- ((u32)(port_id_page)->port_id_area << 8) | \
- ((u32)(port_id_page)->port_id_port))
-
-#define UNF_GNN_GFF_ID_RJT_REASON(rjt_reason) \
- ((UNF_CTIU_RJT_UNABLE_PERFORM == \
- ((rjt_reason) & UNF_CTIU_RJT_MASK)) && \
- ((UNF_CTIU_RJT_EXP_PORTID_NO_REG == \
- ((rjt_reason) & UNF_CTIU_RJT_EXP_MASK)) || \
- (UNF_CTIU_RJT_EXP_PORTNAME_NO_REG == \
- ((rjt_reason) & UNF_CTIU_RJT_EXP_MASK)) || \
- (UNF_CTIU_RJT_EXP_NODENAME_NO_REG == \
- ((rjt_reason) & UNF_CTIU_RJT_EXP_MASK))))
-
-u32 unf_send_scr(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* after RCVD RFF_ID ACC */
- struct unf_scr *scr = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, NULL, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for SCR",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_SCR;
-
- xchg->callback = unf_scr_callback;
- xchg->ob_callback = unf_scr_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- scr = &fc_entry->scr;
- memset(scr, 0, sizeof(struct unf_scr));
- scr->payload[ARRAY_INDEX_0] = (UNF_GS_CMND_SCR); /* SCR is 0x62 */
- scr->payload[ARRAY_INDEX_1] = (UNF_FABRIC_FULL_REG); /* Full registration */
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: SCR send %s. Port(0x%x_0x%x)--->RPort(0x%x) with hottag(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- lport->nport_id, rport->nport_id, xchg->hotpooltag);
-
- return ret;
-}
-
-static void unf_fill_gff_id_pld(struct unf_gffid *gff_id, u32 nport_id)
-{
- FC_CHECK_RETURN_VOID(gff_id);
-
- gff_id->ctiu_pream.rev_inid = (UNF_REV_NPORTID_INIT);
- gff_id->ctiu_pream.gstype_gssub_options = (UNF_FSTYPE_OPT_INIT);
- gff_id->ctiu_pream.cmnd_rsp_size = (UNF_FSTYPE_GFF_ID);
- gff_id->ctiu_pream.frag_reason_exp_vend = UNF_FRAG_REASON_VENDOR;
- gff_id->nport_id = nport_id;
-}
-
-static void unf_ctpass_thru_callback(void *lport, void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_gid_acc_pld *gid_acc_pld = NULL;
- struct unf_xchg *unf_xchg = NULL;
- union unf_sfs_u *sfs = NULL;
- u32 cmnd_rsp_size = 0;
-
- struct send_com_trans_out *out_send = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_xchg = (struct unf_xchg *)xchg;
- sfs = unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
-
- gid_acc_pld = sfs->get_id.gid_rsp.gid_acc_pld;
- if (!gid_acc_pld) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) CT PassThru response payload is NULL",
- unf_lport->port_id);
-
- return;
- }
-
- out_send = (struct send_com_trans_out *)unf_xchg->upper_ct;
-
- cmnd_rsp_size = (gid_acc_pld->ctiu_pream.cmnd_rsp_size);
- if (UNF_CT_IU_ACCEPT == (cmnd_rsp_size & UNF_CT_IU_RSP_MASK)) {
- out_send->hba_status = 0; /* HBA_STATUS_OK 0 */
- out_send->total_resp_buffer_cnt = unf_xchg->fcp_sfs_union.sfs_entry.cur_offset;
- out_send->actual_resp_buffer_cnt = unf_xchg->fcp_sfs_union.sfs_entry.cur_offset;
- unf_cpu_to_big_end(out_send->resp_buffer, (u32)out_send->total_resp_buffer_cnt);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) CT PassThru was receive len is(0x%0x)",
- unf_lport->port_id, unf_lport->nport_id,
- out_send->total_resp_buffer_cnt);
- } else if (UNF_CT_IU_REJECT == (cmnd_rsp_size & UNF_CT_IU_RSP_MASK)) {
- out_send->hba_status = 13; /* HBA_STATUS_ERROR_ELS_REJECT 13 */
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) CT PassThru was rejected",
- unf_lport->port_id, unf_lport->nport_id);
- } else {
- out_send->hba_status = 1; /* HBA_STATUS_ERROR 1 */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) CT PassThru was UNKNOWN",
- unf_lport->port_id, unf_lport->nport_id);
- }
-
- up(&unf_lport->wmi_task_sema);
-}
-
-u32 unf_send_ctpass_thru(struct unf_lport *lport, void *buffer, u32 bufflen)
-{
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_rport *sns_port = NULL;
- struct send_com_trans_in *in_send = (struct send_com_trans_in *)buffer;
- struct send_com_trans_out *out_send =
- (struct send_com_trans_out *)buffer;
- struct unf_ctiu_prem *ctiu_pream = NULL;
- struct unf_gid *gs_pld = NULL;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buffer, UNF_RETURN_ERROR);
-
- ctiu_pream = (struct unf_ctiu_prem *)in_send->req_buffer;
- unf_cpu_to_big_end(ctiu_pream, sizeof(struct unf_gid));
-
- if (ctiu_pream->cmnd_rsp_size >> UNF_SHIFT_16 == NS_GIEL) {
- sns_port = unf_get_rport_by_nport_id(lport, UNF_FC_FID_MGMT_SERV);
- if (!sns_port) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) can't find SNS port",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- } else if (ctiu_pream->cmnd_rsp_size >> UNF_SHIFT_16 == NS_GA_NXT) {
- sns_port = unf_get_rport_by_nport_id(lport, UNF_FC_FID_DIR_SERV);
- if (!sns_port) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) can't find SNS port",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[info]%s cmnd(0x%x) is error:", __func__,
- ctiu_pream->cmnd_rsp_size >> UNF_SHIFT_16);
-
- return UNF_RETURN_ERROR;
- }
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, sns_port->nport_id, sns_port, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for GFF_ID",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- xchg->cmnd_code = ctiu_pream->cmnd_rsp_size >> UNF_SHIFT_16;
- xchg->upper_ct = buffer;
- xchg->ob_callback = NULL;
- xchg->callback = unf_ctpass_thru_callback;
- xchg->oxid = xchg->hotpooltag;
- unf_fill_package(&pkg, xchg, sns_port);
- pkg.type = UNF_PKG_GS_REQ;
- xchg->fcp_sfs_union.sfs_entry.sfs_buff_len = bufflen;
- gs_pld = &fc_entry->get_id.gid_req; /* GID req payload */
- memset(gs_pld, 0, sizeof(struct unf_gid));
- memcpy(gs_pld, (struct unf_gid *)in_send->req_buffer, sizeof(struct unf_gid));
- fc_entry->get_id.gid_rsp.gid_acc_pld = (struct unf_gid_acc_pld *)out_send->resp_buffer;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
-
- return ret;
-}
-
-u32 unf_send_gff_id(struct unf_lport *lport, struct unf_rport *sns_port,
- u32 nport_id)
-{
- struct unf_gffid *gff_id = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- struct unf_frame_pkg pkg;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(sns_port, UNF_RETURN_ERROR);
-
- if (unf_is_lport_valid(lport) != RETURN_OK)
- /* Lport is invalid, no retry or handle required, return ok */
- return RETURN_OK;
-
- unf_lport = (struct unf_lport *)lport->root_lport;
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, sns_port->nport_id, sns_port, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for GFF_ID",
- lport->port_id);
-
- return unf_get_and_post_disc_event(lport, sns_port, nport_id, UNF_DISC_GET_FEATURE);
- }
-
- xchg->cmnd_code = NS_GFF_ID;
- xchg->disc_portid = nport_id;
-
- xchg->ob_callback = unf_gff_id_ob_callback;
- xchg->callback = unf_gff_id_callback;
-
- unf_fill_package(&pkg, xchg, sns_port);
- pkg.type = UNF_PKG_GS_REQ;
-
- gff_id = &fc_entry->gff_id;
- memset(gff_id, 0, sizeof(struct unf_gffid));
- unf_fill_gff_id_pld(gff_id, nport_id);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- else
- atomic_dec(&unf_lport->disc.disc_thread_info.disc_contrl_size);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: GFF_ID send %s. Port(0x%x)--->RPort(0x%x). Inquire RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- sns_port->nport_id, nport_id);
-
- return ret;
-}
-
-static void unf_fill_gnnid_pld(struct unf_gnnid *gnnid_pld, u32 nport_id)
-{
- /* Inquiry R_Port node name from SW */
- FC_CHECK_RETURN_VOID(gnnid_pld);
-
- gnnid_pld->ctiu_pream.rev_inid = (UNF_REV_NPORTID_INIT);
- gnnid_pld->ctiu_pream.gstype_gssub_options = (UNF_FSTYPE_OPT_INIT);
- gnnid_pld->ctiu_pream.cmnd_rsp_size = (UNF_FSTYPE_GNN_ID);
- gnnid_pld->ctiu_pream.frag_reason_exp_vend = UNF_FRAG_REASON_VENDOR;
-
- gnnid_pld->nport_id = nport_id;
-}
-
-u32 unf_send_gnn_id(struct unf_lport *lport, struct unf_rport *sns_port,
- u32 nport_id)
-{
- /* from DISC stop/re-login */
- struct unf_gnnid *unf_gnnid = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(sns_port, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Port(0x%x_0x%x) send gnnid to 0x%x.", lport->port_id,
- lport->nport_id, nport_id);
-
- if (unf_is_lport_valid(lport) != RETURN_OK)
- /* Lport is invalid, no retry or handle required, return ok */
- return RETURN_OK;
-
- unf_lport = (struct unf_lport *)lport->root_lport;
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, sns_port->nport_id,
- sns_port, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) exchange can't be NULL for GNN_ID",
- lport->port_id);
-
- return unf_get_and_post_disc_event(lport, sns_port, nport_id,
- UNF_DISC_GET_NODE_NAME);
- }
-
- xchg->cmnd_code = NS_GNN_ID;
- xchg->disc_portid = nport_id;
-
- xchg->ob_callback = unf_gnn_id_ob_callback;
- xchg->callback = unf_gnn_id_callback;
-
- unf_fill_package(&pkg, xchg, sns_port);
- pkg.type = UNF_PKG_GS_REQ;
-
- unf_gnnid = &fc_entry->gnn_id; /* GNNID payload */
- memset(unf_gnnid, 0, sizeof(struct unf_gnnid));
- unf_fill_gnnid_pld(unf_gnnid, nport_id);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- else
- atomic_dec(&unf_lport->disc.disc_thread_info.disc_contrl_size);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: GNN_ID send %s. Port(0x%x_0x%x)--->RPort(0x%x) inquire Nportid(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- lport->nport_id, sns_port->nport_id, nport_id);
-
- return ret;
-}
-
-static void unf_fill_gpnid_pld(struct unf_gpnid *gpnid_pld, u32 nport_id)
-{
- FC_CHECK_RETURN_VOID(gpnid_pld);
-
- gpnid_pld->ctiu_pream.rev_inid = (UNF_REV_NPORTID_INIT);
- gpnid_pld->ctiu_pream.gstype_gssub_options = (UNF_FSTYPE_OPT_INIT);
- gpnid_pld->ctiu_pream.cmnd_rsp_size = (UNF_FSTYPE_GPN_ID);
- gpnid_pld->ctiu_pream.frag_reason_exp_vend = UNF_FRAG_REASON_VENDOR;
-
- /* Inquiry WWN from SW */
- gpnid_pld->nport_id = nport_id;
-}
-
-u32 unf_send_gpn_id(struct unf_lport *lport, struct unf_rport *sns_port,
- u32 nport_id)
-{
- struct unf_gpnid *gpnid_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(sns_port, UNF_RETURN_ERROR);
-
- if (unf_is_lport_valid(lport) != RETURN_OK)
- /* Lport is invalid, no retry or handle required, return ok */
- return RETURN_OK;
-
- unf_lport = (struct unf_lport *)lport->root_lport;
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, sns_port->nport_id,
- sns_port, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for GPN_ID",
- lport->port_id);
-
- return unf_get_and_post_disc_event(lport, sns_port, nport_id,
- UNF_DISC_GET_PORT_NAME);
- }
-
- xchg->cmnd_code = NS_GPN_ID;
- xchg->disc_portid = nport_id;
-
- xchg->callback = unf_gpn_id_callback;
- xchg->ob_callback = unf_gpn_id_ob_callback;
-
- unf_fill_package(&pkg, xchg, sns_port);
- pkg.type = UNF_PKG_GS_REQ;
-
- gpnid_pld = &fc_entry->gpn_id;
- memset(gpnid_pld, 0, sizeof(struct unf_gpnid));
- unf_fill_gpnid_pld(gpnid_pld, nport_id);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- else
- atomic_dec(&unf_lport->disc.disc_thread_info.disc_contrl_size);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: GPN_ID send %s. Port(0x%x)--->RPort(0x%x). Inquire RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- sns_port->nport_id, nport_id);
-
- return ret;
-}
-
-static void unf_fill_gid_ft_pld(struct unf_gid *gid_pld)
-{
- FC_CHECK_RETURN_VOID(gid_pld);
-
- gid_pld->ctiu_pream.rev_inid = (UNF_REV_NPORTID_INIT);
- gid_pld->ctiu_pream.gstype_gssub_options = (UNF_FSTYPE_OPT_INIT);
- gid_pld->ctiu_pream.cmnd_rsp_size = (UNF_FSTYPE_GID_FT);
- gid_pld->ctiu_pream.frag_reason_exp_vend = UNF_FRAG_REASON_VENDOR;
-
- gid_pld->scope_type = (UNF_GID_FT_TYPE);
-}
-
-u32 unf_send_gid_ft(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_gid *gid_pld = NULL;
- struct unf_gid_rsp *gid_rsp = NULL;
- struct unf_gid_acc_pld *gid_acc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id,
- rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for GID_FT",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = NS_GID_FT;
-
- xchg->ob_callback = unf_gid_ft_ob_callback;
- xchg->callback = unf_gid_ft_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_GS_REQ;
-
- gid_pld = &fc_entry->get_id.gid_req; /* GID req payload */
- unf_fill_gid_ft_pld(gid_pld);
- gid_rsp = &fc_entry->get_id.gid_rsp; /* GID rsp payload */
-
- gid_acc_pld = (struct unf_gid_acc_pld *)unf_get_one_big_sfs_buf(xchg);
- if (!gid_acc_pld) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) allocate GID_FT response buffer failed",
- lport->port_id);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
- memset(gid_acc_pld, 0, sizeof(struct unf_gid_acc_pld));
- gid_rsp->gid_acc_pld = gid_acc_pld;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: GID_FT send %s. Port(0x%x)--->RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id);
-
- return ret;
-}
-
-static void unf_fill_gid_pt_pld(struct unf_gid *gid_pld,
- struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(gid_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- gid_pld->ctiu_pream.rev_inid = (UNF_REV_NPORTID_INIT);
- gid_pld->ctiu_pream.gstype_gssub_options = (UNF_FSTYPE_OPT_INIT);
- gid_pld->ctiu_pream.cmnd_rsp_size = (UNF_FSTYPE_GID_PT);
- gid_pld->ctiu_pream.frag_reason_exp_vend = UNF_FRAG_REASON_VENDOR;
-
- /* 0x7F000000 means NX_Port */
- gid_pld->scope_type = (UNF_GID_PT_TYPE);
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, gid_pld,
- sizeof(struct unf_gid));
-}
-
-u32 unf_send_gid_pt(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* from DISC start */
- struct unf_gid *gid_pld = NULL;
- struct unf_gid_rsp *gid_rsp = NULL;
- struct unf_gid_acc_pld *gid_acc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id,
- rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for GID_PT",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = NS_GID_PT;
-
- xchg->ob_callback = unf_gid_pt_ob_callback;
- xchg->callback = unf_gid_pt_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_GS_REQ;
-
- gid_pld = &fc_entry->get_id.gid_req; /* GID req payload */
- unf_fill_gid_pt_pld(gid_pld, lport);
- gid_rsp = &fc_entry->get_id.gid_rsp; /* GID rsp payload */
-
- gid_acc_pld = (struct unf_gid_acc_pld *)unf_get_one_big_sfs_buf(xchg);
- if (!gid_acc_pld) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%0x) Allocate GID_PT response buffer failed",
- lport->port_id);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
- memset(gid_acc_pld, 0, sizeof(struct unf_gid_acc_pld));
- gid_rsp->gid_acc_pld = gid_acc_pld;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: GID_PT send %s. Port(0x%x_0x%x)--->RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- lport->nport_id, rport->nport_id);
-
- return ret;
-}
-
-static void unf_fill_rft_id_pld(struct unf_rftid *rftid_pld,
- struct unf_lport *lport)
-{
- u32 index = 1;
-
- FC_CHECK_RETURN_VOID(rftid_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- rftid_pld->ctiu_pream.rev_inid = (UNF_REV_NPORTID_INIT);
- rftid_pld->ctiu_pream.gstype_gssub_options = (UNF_FSTYPE_OPT_INIT);
- rftid_pld->ctiu_pream.cmnd_rsp_size = (UNF_FSTYPE_RFT_ID);
- rftid_pld->ctiu_pream.frag_reason_exp_vend = UNF_FRAG_REASON_VENDOR;
- rftid_pld->nport_id = (lport->nport_id);
- rftid_pld->fc4_types[ARRAY_INDEX_0] = (UNF_FC4_SCSI_BIT8);
-
- for (index = ARRAY_INDEX_2; index < UNF_FC4TYPE_CNT; index++)
- rftid_pld->fc4_types[index] = 0;
-}
-
-u32 unf_send_rft_id(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* After PLOGI process */
- struct unf_rftid *rft_id = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id,
- rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for RFT_ID",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = NS_RFT_ID;
-
- xchg->callback = unf_rft_id_callback;
- xchg->ob_callback = unf_rft_id_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_GS_REQ;
-
- rft_id = &fc_entry->rft_id;
- memset(rft_id, 0, sizeof(struct unf_rftid));
- unf_fill_rft_id_pld(rft_id, lport);
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: RFT_ID send %s. Port(0x%x_0x%x)--->RPort(0x%x). rport(0x%p) wwpn(0x%llx) ",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- lport->nport_id, rport->nport_id, rport, rport->port_name);
-
- return ret;
-}
-
-static void unf_fill_rff_id_pld(struct unf_rffid *rffid_pld,
- struct unf_lport *lport, u32 fc4_type)
-{
- FC_CHECK_RETURN_VOID(rffid_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- rffid_pld->ctiu_pream.rev_inid = (UNF_REV_NPORTID_INIT);
- rffid_pld->ctiu_pream.gstype_gssub_options = (UNF_FSTYPE_OPT_INIT);
- rffid_pld->ctiu_pream.cmnd_rsp_size = (UNF_FSTYPE_RFF_ID);
- rffid_pld->ctiu_pream.frag_reason_exp_vend = UNF_FRAG_REASON_VENDOR;
- rffid_pld->nport_id = (lport->nport_id);
- rffid_pld->fc4_feature = (fc4_type | (lport->options << UNF_SHIFT_4));
-}
-
-u32 unf_send_rff_id(struct unf_lport *lport, struct unf_rport *rport,
- u32 fc4_type)
-{
- /* from RFT_ID, then Send SCR */
- struct unf_rffid *rff_id = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_INFO, "%s Enter", __func__);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id,
- rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for RFF_ID",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = NS_RFF_ID;
-
- xchg->callback = unf_rff_id_callback;
- xchg->ob_callback = unf_rff_id_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_GS_REQ;
-
- rff_id = &fc_entry->rff_id;
- memset(rff_id, 0, sizeof(struct unf_rffid));
- unf_fill_rff_id_pld(rff_id, lport, fc4_type);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: RFF_ID feature 0x%x(10:TGT,20:INI,30:COM) send %s. Port(0x%x_0x%x)--->RPortid(0x%x) rport(0x%p)",
- lport->options, (ret != RETURN_OK) ? "failed" : "succeed",
- lport->port_id, lport->nport_id, rport->nport_id, rport);
-
- return ret;
-}
-
-void unf_handle_init_gid_acc(struct unf_gid_acc_pld *gid_acc_pld,
- struct unf_lport *lport)
-{
- /*
- * from SCR ACC callback
- * NOTE: inquiry disc R_Port used for NPIV
- */
- struct unf_disc_rport *disc_rport = NULL;
- struct unf_disc *disc = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 gid_port_id = 0;
- u32 nport_id = 0;
- u32 index = 0;
- u8 control = 0;
-
- FC_CHECK_RETURN_VOID(gid_acc_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- /*
- * 1. Find & Check & Get (new) R_Port from list_disc_rports_pool
- * then, Add to R_Port Disc_busy_list
- */
- while (index < UNF_GID_PORT_CNT) {
- gid_port_id = (gid_acc_pld->gid_port_id[index]);
- nport_id = UNF_NPORTID_MASK & gid_port_id;
- control = UNF_GID_CONTROL(gid_port_id);
-
- /* for each N_Port_ID from GID_ACC payload */
- if (lport->nport_id != nport_id && nport_id != 0 &&
- (!unf_lookup_lport_by_nportid(lport, nport_id))) {
- /* for New Port, not L_Port */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) get nportid(0x%x) from GID_ACC",
- lport->port_id, lport->nport_id, nport_id);
-
- /* Get R_Port from list of RPort Disc Pool */
- disc_rport = unf_rport_get_free_and_init(lport,
- UNF_PORT_TYPE_DISC, nport_id);
- if (!disc_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) can't allocate new rport(0x%x) from disc pool",
- lport->port_id, lport->nport_id,
- nport_id);
-
- index++;
- continue;
- }
- }
-
- if (UNF_GID_LAST_PORT_ID == (UNF_GID_LAST_PORT_ID & control))
- break;
-
- index++;
- }
-
- /*
- * 2. Do port disc stop operation:
- * NOTE: Do DISC & release R_Port from busy_list back to
- * list_disc_rports_pool
- */
- disc = &lport->disc;
- if (!disc->disc_temp.unf_disc_stop) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) disc stop function is NULL",
- lport->port_id, lport->nport_id);
-
- return;
- }
-
- ret = disc->disc_temp.unf_disc_stop(lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) do disc stop failed",
- lport->port_id, lport->nport_id);
- }
-}
-
-u32 unf_rport_relogin(struct unf_lport *lport, u32 nport_id)
-{
- /* Send GNN_ID */
- struct unf_rport *sns_port = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* Get SNS R_Port */
- sns_port = unf_get_rport_by_nport_id(lport, UNF_FC_FID_DIR_SERV);
- if (!sns_port) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't find fabric Port", lport->nport_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Send GNN_ID now to SW */
- ret = unf_get_and_post_disc_event(lport, sns_port, nport_id,
- UNF_DISC_GET_NODE_NAME);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- lport->nport_id, UNF_DISC_GET_NODE_NAME, nport_id);
-
- /* NOTE: Continue to next stage */
- unf_rcv_gnn_id_rsp_unknown(lport, sns_port, nport_id);
- }
-
- return ret;
-}
-
-u32 unf_rport_check_wwn(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* Send GPN_ID */
- struct unf_rport *sns_port = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- /* Get SNS R_Port */
- sns_port = unf_get_rport_by_nport_id(lport, UNF_FC_FID_DIR_SERV);
- if (!sns_port) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't find fabric Port", lport->nport_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Send GPN_ID to SW */
- ret = unf_get_and_post_disc_event(lport, sns_port, rport->nport_id,
- UNF_DISC_GET_PORT_NAME);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- lport->nport_id, UNF_DISC_GET_PORT_NAME,
- rport->nport_id);
-
- unf_rcv_gpn_id_rsp_unknown(lport, rport->nport_id);
- }
-
- return ret;
-}
-
-u32 unf_handle_rscn_port_not_indisc(struct unf_lport *lport, u32 rscn_nport_id)
-{
- /* RSCN Port_ID not in GID_ACC payload table: Link Down */
- struct unf_rport *unf_rport = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* from R_Port busy list by N_Port_ID */
- unf_rport = unf_get_rport_by_nport_id(lport, rscn_nport_id);
- if (unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x) RPort(0x%x) wwpn(0x%llx) has been removed and link down it",
- lport->port_id, rscn_nport_id, unf_rport->port_name);
-
- unf_rport_linkdown(lport, unf_rport);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) has no RPort(0x%x) and do nothing",
- lport->nport_id, rscn_nport_id);
- }
-
- return ret;
-}
-
-u32 unf_handle_rscn_port_indisc(struct unf_lport *lport, u32 rscn_nport_id)
-{
- /* Send GPN_ID or re-login(GNN_ID) */
- struct unf_rport *unf_rport = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* from R_Port busy list by N_Port_ID */
- unf_rport = unf_get_rport_by_nport_id(lport, rscn_nport_id);
- if (unf_rport) {
- /* R_Port exist: send GPN_ID */
- ret = unf_rport_check_wwn(lport, unf_rport);
- } else {
- if (UNF_PORT_MODE_INI == (lport->options & UNF_PORT_MODE_INI))
- /* Re-LOGIN with INI mode: Send GNN_ID */
- ret = unf_rport_relogin(lport, rscn_nport_id);
- else
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) with no INI feature. Do nothing",
- lport->nport_id);
- }
-
- return ret;
-}
-
-static u32 unf_handle_rscn_port_addr(struct unf_port_id_page *portid_page,
- struct unf_gid_acc_pld *gid_acc_pld,
- struct unf_lport *lport)
-{
- /*
- * Input parameters:
- * 1. Port_ID_page: saved from RSCN payload
- * 2. GID_ACC_payload: back from GID_ACC (GID_PT or GID_FT)
- * *
- * Do work: check whether RSCN Port_ID within GID_ACC payload or not
- * then, re-login or link down rport
- */
- u32 rscn_nport_id = 0;
- u32 gid_port_id = 0;
- u32 nport_id = 0;
- u32 index = 0;
- u8 control = 0;
- u32 ret = RETURN_OK;
- bool have_same_id = false;
-
- FC_CHECK_RETURN_VALUE(portid_page, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(gid_acc_pld, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* 1. get RSCN_NPort_ID from (L_Port->Disc->RSCN_Mgr)->RSCN_Port_ID_Page
- */
- rscn_nport_id = UNF_SERVICE_GET_NPORTID_FORM_GID_PAGE(portid_page);
-
- /*
- * 2. for RSCN_NPort_ID
- * check whether RSCN_NPort_ID within GID_ACC_Payload or not
- */
- while (index < UNF_GID_PORT_CNT) {
- gid_port_id = (gid_acc_pld->gid_port_id[index]);
- nport_id = UNF_NPORTID_MASK & gid_port_id;
- control = UNF_GID_CONTROL(gid_port_id);
-
- if (lport->nport_id != nport_id && nport_id != 0) {
- /* is not L_Port */
- if (nport_id == rscn_nport_id) {
- /* RSCN Port_ID within GID_ACC payload */
- have_same_id = true;
- break;
- }
- }
-
- if (UNF_GID_LAST_PORT_ID == (UNF_GID_LAST_PORT_ID & control))
- break;
-
- index++;
- }
-
- /* 3. RSCN_Port_ID not within GID_ACC payload table */
- if (!have_same_id) {
- /* rport has been removed */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[warn]Port(0x%x_0x%x) find RSCN N_Port_ID(0x%x) in GID_ACC table failed",
- lport->port_id, lport->nport_id, rscn_nport_id);
-
- /* Link down rport */
- ret = unf_handle_rscn_port_not_indisc(lport, rscn_nport_id);
-
- } else { /* 4. RSCN_Port_ID within GID_ACC payload table */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x_0x%x) find RSCN N_Port_ID(0x%x) in GID_ACC table succeed",
- lport->port_id, lport->nport_id, rscn_nport_id);
-
- /* Re-login with INI mode */
- ret = unf_handle_rscn_port_indisc(lport, rscn_nport_id);
- }
-
- return ret;
-}
-
-void unf_check_rport_rscn_process(struct unf_rport *rport,
- struct unf_port_id_page *portid_page)
-{
- struct unf_rport *unf_rport = rport;
- struct unf_port_id_page *unf_portid_page = portid_page;
- u8 addr_format = unf_portid_page->addr_format;
-
- switch (addr_format) {
- /* domain+area */
- case UNF_RSCN_AREA_ADDR_GROUP:
- if (UNF_GET_DOMAIN_ID(unf_rport->nport_id) == unf_portid_page->port_id_domain &&
- UNF_GET_AREA_ID(unf_rport->nport_id) == unf_portid_page->port_id_area)
- unf_rport->rscn_position = UNF_RPORT_NEED_PROCESS;
-
- break;
- /* domain */
- case UNF_RSCN_DOMAIN_ADDR_GROUP:
- if (UNF_GET_DOMAIN_ID(unf_rport->nport_id) == unf_portid_page->port_id_domain)
- unf_rport->rscn_position = UNF_RPORT_NEED_PROCESS;
-
- break;
- /* all */
- case UNF_RSCN_FABRIC_ADDR_GROUP:
- unf_rport->rscn_position = UNF_RPORT_NEED_PROCESS;
- break;
- default:
- break;
- }
-}
-
-static void unf_set_rport_rscn_position(struct unf_lport *lport,
- struct unf_port_id_page *portid_page)
-{
- struct unf_rport *unf_rport = NULL;
- struct list_head *list_node = NULL;
- struct list_head *list_nextnode = NULL;
- struct unf_disc *disc = NULL;
- ulong disc_flag = 0;
- ulong rport_flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- disc = &lport->disc;
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, disc_flag);
- list_for_each_safe(list_node, list_nextnode, &disc->list_busy_rports) {
- unf_rport = list_entry(list_node, struct unf_rport, entry_rport);
- spin_lock_irqsave(&unf_rport->rport_state_lock, rport_flag);
-
- if (unf_rport->nport_id < UNF_FC_FID_DOM_MGR) {
- if (unf_rport->rscn_position == UNF_RPORT_NOT_NEED_PROCESS)
- unf_check_rport_rscn_process(unf_rport, portid_page);
- } else {
- unf_rport->rscn_position = UNF_RPORT_NOT_NEED_PROCESS;
- }
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, rport_flag);
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
-}
-
-static void unf_set_rport_rscn_position_local(struct unf_lport *lport)
-{
- struct unf_rport *unf_rport = NULL;
- struct list_head *list_node = NULL;
- struct list_head *list_nextnode = NULL;
- struct unf_disc *disc = NULL;
- ulong disc_flag = 0;
- ulong rport_flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- disc = &lport->disc;
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, disc_flag);
- list_for_each_safe(list_node, list_nextnode, &disc->list_busy_rports) {
- unf_rport = list_entry(list_node, struct unf_rport, entry_rport);
- spin_lock_irqsave(&unf_rport->rport_state_lock, rport_flag);
-
- if (unf_rport->nport_id < UNF_FC_FID_DOM_MGR) {
- if (unf_rport->rscn_position == UNF_RPORT_NEED_PROCESS)
- unf_rport->rscn_position = UNF_RPORT_ONLY_IN_LOCAL_PROCESS;
- } else {
- unf_rport->rscn_position = UNF_RPORT_NOT_NEED_PROCESS;
- }
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, rport_flag);
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
-}
-
-static void unf_reset_rport_rscn_setting(struct unf_lport *lport)
-{
- struct unf_rport *rport = NULL;
- struct list_head *list_node = NULL;
- struct list_head *list_nextnode = NULL;
- struct unf_disc *disc = NULL;
- ulong rport_flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- disc = &lport->disc;
-
- list_for_each_safe(list_node, list_nextnode, &disc->list_busy_rports) {
- rport = list_entry(list_node, struct unf_rport, entry_rport);
- spin_lock_irqsave(&rport->rport_state_lock, rport_flag);
- rport->rscn_position = UNF_RPORT_NOT_NEED_PROCESS;
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
- }
-}
-
-void unf_compare_nport_id_with_rport_list(struct unf_lport *lport, u32 nport_id,
- struct unf_port_id_page *portid_page)
-{
- struct unf_rport *rport = NULL;
- ulong rport_flag = 0;
- u8 addr_format = portid_page->addr_format;
-
- FC_CHECK_RETURN_VOID(lport);
-
- switch (addr_format) {
- /* domain+area */
- case UNF_RSCN_AREA_ADDR_GROUP:
- if ((UNF_GET_DOMAIN_ID(nport_id) != portid_page->port_id_domain) ||
- (UNF_GET_AREA_ID(nport_id) != portid_page->port_id_area))
- return;
-
- break;
- /* domain */
- case UNF_RSCN_DOMAIN_ADDR_GROUP:
- if (UNF_GET_DOMAIN_ID(nport_id) != portid_page->port_id_domain)
- return;
-
- break;
- /* all */
- case UNF_RSCN_FABRIC_ADDR_GROUP:
- break;
- /* can't enter this branch guarantee by outer */
- default:
- break;
- }
-
- rport = unf_get_rport_by_nport_id(lport, nport_id);
-
- if (!rport) {
- if (UNF_PORT_MODE_INI == (lport->options & UNF_PORT_MODE_INI)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x) Find Rport(0x%x) by RSCN",
- lport->nport_id, nport_id);
- unf_rport_relogin(lport, nport_id);
- }
- } else {
- spin_lock_irqsave(&rport->rport_state_lock, rport_flag);
- if (rport->rscn_position == UNF_RPORT_NEED_PROCESS)
- rport->rscn_position = UNF_RPORT_IN_DISC_AND_LOCAL_PROCESS;
-
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
- }
-}
-
-static void unf_compare_disc_with_local_rport(struct unf_lport *lport,
- struct unf_gid_acc_pld *pld,
- struct unf_port_id_page *page)
-{
- u32 gid_port_id = 0;
- u32 nport_id = 0;
- u32 index = 0;
- u8 control = 0;
-
- FC_CHECK_RETURN_VOID(pld);
- FC_CHECK_RETURN_VOID(lport);
-
- while (index < UNF_GID_PORT_CNT) {
- gid_port_id = (pld->gid_port_id[index]);
- nport_id = UNF_NPORTID_MASK & gid_port_id;
- control = UNF_GID_CONTROL(gid_port_id);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_INFO, "[info]Port(0x%x) DISC N_Port_ID(0x%x)",
- lport->nport_id, nport_id);
-
- if (nport_id != 0 &&
- (!unf_lookup_lport_by_nportid(lport, nport_id)))
- unf_compare_nport_id_with_rport_list(lport, nport_id, page);
-
- if (UNF_GID_LAST_PORT_ID == (UNF_GID_LAST_PORT_ID & control))
- break;
-
- index++;
- }
-
- unf_set_rport_rscn_position_local(lport);
-}
-
-static u32 unf_process_each_rport_after_rscn(struct unf_lport *lport,
- struct unf_rport *sns_port,
- struct unf_rport *rport)
-{
- ulong rport_flag = 0;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(sns_port, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(sns_port, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&rport->rport_state_lock, rport_flag);
-
- if (rport->rscn_position == UNF_RPORT_IN_DISC_AND_LOCAL_PROCESS) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x_0x%x) RPort(0x%x) rescan position(0x%x), check wwpn",
- lport->port_id, lport->nport_id, rport->nport_id,
- rport->rscn_position);
- rport->rscn_position = UNF_RPORT_NOT_NEED_PROCESS;
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
- ret = unf_rport_check_wwn(lport, rport);
- } else if (rport->rscn_position == UNF_RPORT_ONLY_IN_LOCAL_PROCESS) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x_0x%x) RPort(0x%x) rescan position(0x%x), linkdown it",
- lport->port_id, lport->nport_id, rport->nport_id,
- rport->rscn_position);
- rport->rscn_position = UNF_RPORT_NOT_NEED_PROCESS;
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
- unf_rport_linkdown(lport, rport);
- } else {
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
- }
-
- return ret;
-}
-
-static u32 unf_process_local_rport_after_rscn(struct unf_lport *lport,
- struct unf_rport *sns_port)
-{
- struct unf_rport *unf_rport = NULL;
- struct list_head *list_node = NULL;
- struct unf_disc *disc = NULL;
- ulong disc_flag = 0;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(sns_port, UNF_RETURN_ERROR);
- disc = &lport->disc;
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, disc_flag);
- if (list_empty(&disc->list_busy_rports)) {
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
-
- return UNF_RETURN_ERROR;
- }
-
- list_node = UNF_OS_LIST_NEXT(&disc->list_busy_rports);
-
- do {
- unf_rport = list_entry(list_node, struct unf_rport, entry_rport);
-
- if (unf_rport->rscn_position == UNF_RPORT_NOT_NEED_PROCESS) {
- list_node = UNF_OS_LIST_NEXT(list_node);
- continue;
- } else {
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
- ret = unf_process_each_rport_after_rscn(lport, sns_port, unf_rport);
- spin_lock_irqsave(&disc->rport_busy_pool_lock, disc_flag);
- list_node = UNF_OS_LIST_NEXT(&disc->list_busy_rports);
- }
- } while (list_node != &disc->list_busy_rports);
-
- unf_reset_rport_rscn_setting(lport);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
-
- return ret;
-}
-
-static u32 unf_handle_rscn_group_addr(struct unf_port_id_page *portid_page,
- struct unf_gid_acc_pld *gid_acc_pld,
- struct unf_lport *lport)
-{
- struct unf_rport *sns_port = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(portid_page, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(gid_acc_pld, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- sns_port = unf_get_rport_by_nport_id(lport, UNF_FC_FID_DIR_SERV);
- if (!sns_port) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find fabric port failed", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- unf_set_rport_rscn_position(lport, portid_page);
- unf_compare_disc_with_local_rport(lport, gid_acc_pld, portid_page);
-
- ret = unf_process_local_rport_after_rscn(lport, sns_port);
-
- return ret;
-}
-
-static void unf_handle_rscn_gid_acc(struct unf_gid_acc_pld *gid_acc_pid,
- struct unf_lport *lport)
-{
- /* for N_Port_ID table return from RSCN */
- struct unf_port_id_page *port_id_page = NULL;
- struct unf_rscn_mgr *rscn_mgr = NULL;
- struct list_head *list_node = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(gid_acc_pid);
- FC_CHECK_RETURN_VOID(lport);
- rscn_mgr = &lport->disc.rscn_mgr;
-
- spin_lock_irqsave(&rscn_mgr->rscn_id_list_lock, flag);
- while (!list_empty(&rscn_mgr->list_using_rscn_page)) {
- /*
- * for each RSCN_Using_Page(NPortID)
- * for each
- * L_Port->Disc->RSCN_Mgr->RSCN_Using_Page(Port_ID_Page)
- * * NOTE:
- * check using_page_port_id whether within GID_ACC payload or
- * not
- */
- list_node = UNF_OS_LIST_NEXT(&rscn_mgr->list_using_rscn_page);
- port_id_page = list_entry(list_node, struct unf_port_id_page, list_node_rscn);
- list_del(list_node); /* NOTE: here delete node (from RSCN using Page) */
- spin_unlock_irqrestore(&rscn_mgr->rscn_id_list_lock, flag);
-
- switch (port_id_page->addr_format) {
- /* each page of RSNC corresponding one of N_Port_ID */
- case UNF_RSCN_PORT_ADDR:
- (void)unf_handle_rscn_port_addr(port_id_page, gid_acc_pid, lport);
- break;
-
- /* each page of RSNC corresponding address group */
- case UNF_RSCN_AREA_ADDR_GROUP:
- case UNF_RSCN_DOMAIN_ADDR_GROUP:
- case UNF_RSCN_FABRIC_ADDR_GROUP:
- (void)unf_handle_rscn_group_addr(port_id_page, gid_acc_pid, lport);
- break;
-
- default:
- break;
- }
-
- /* NOTE: release this RSCN_Node */
- rscn_mgr->unf_release_rscn_node(rscn_mgr, port_id_page);
-
- /* go to next */
- spin_lock_irqsave(&rscn_mgr->rscn_id_list_lock, flag);
- }
-
- spin_unlock_irqrestore(&rscn_mgr->rscn_id_list_lock, flag);
-}
-
-static void unf_gid_acc_handle(struct unf_gid_acc_pld *gid_acc_pid,
- struct unf_lport *lport)
-{
-#define UNF_NONE_DISC 0X0 /* before enter DISC */
- struct unf_disc *disc = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(gid_acc_pid);
- FC_CHECK_RETURN_VOID(lport);
- disc = &lport->disc;
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- switch (disc->disc_option) {
- case UNF_INIT_DISC: /* from SCR callback with INI mode */
- disc->disc_option = UNF_NONE_DISC;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- unf_handle_init_gid_acc(gid_acc_pid, lport); /* R_Port from Disc_list */
- break;
-
- case UNF_RSCN_DISC: /* from RSCN payload parse(analysis) */
- disc->disc_option = UNF_NONE_DISC;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- unf_handle_rscn_gid_acc(gid_acc_pid, lport); /* R_Port from busy_list */
- break;
-
- default:
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x)'s disc option(0x%x) is abnormal",
- lport->port_id, lport->nport_id, disc->disc_option);
- break;
- }
-}
-
-static void unf_gid_ft_ob_callback(struct unf_xchg *xchg)
-{
- /* Do recovery */
- struct unf_lport *lport = NULL;
- union unf_sfs_u *sfs_ptr = NULL;
- struct unf_disc *disc = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- sfs_ptr = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!sfs_ptr)
- return;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- lport = xchg->lport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
- if (!lport)
- return;
-
- disc = &lport->disc;
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(lport, UNF_EVENT_DISC_FAILED);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- /* Do DISC recovery operation */
- unf_disc_error_recovery(lport);
-}
-
-static void unf_gid_ft_callback(void *lport, void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_gid_acc_pld *gid_acc_pld = NULL;
- struct unf_xchg *unf_xchg = NULL;
- union unf_sfs_u *sfs_ptr = NULL;
- u32 cmnd_rsp_size = 0;
- u32 rjt_reason = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_xchg = (struct unf_xchg *)xchg;
- disc = &unf_lport->disc;
-
- sfs_ptr = unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- gid_acc_pld = sfs_ptr->get_id.gid_rsp.gid_acc_pld;
- if (!gid_acc_pld) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) GID_FT response payload is NULL",
- unf_lport->port_id);
-
- return;
- }
-
- cmnd_rsp_size = gid_acc_pld->ctiu_pream.cmnd_rsp_size;
- if (UNF_CT_IU_ACCEPT == (cmnd_rsp_size & UNF_CT_IU_RSP_MASK)) {
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_SUCCESS);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- /* Process GID_FT ACC */
- unf_gid_acc_handle(gid_acc_pld, unf_lport);
- } else if (UNF_CT_IU_REJECT == (cmnd_rsp_size & UNF_CT_IU_RSP_MASK)) {
- rjt_reason = (gid_acc_pld->ctiu_pream.frag_reason_exp_vend);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) GID_FT was rejected with reason code(0x%x)",
- unf_lport->port_id, rjt_reason);
-
- if (UNF_CTIU_RJT_EXP_FC4TYPE_NO_REG ==
- (rjt_reason & UNF_CTIU_RJT_EXP_MASK)) {
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_SUCCESS);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- unf_gid_acc_handle(gid_acc_pld, unf_lport);
- } else {
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_SUCCESS);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- }
- } else {
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_FAILED);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- /* Do DISC recovery operation */
- unf_disc_error_recovery(unf_lport);
- }
-}
-
-static void unf_gid_pt_ob_callback(struct unf_xchg *xchg)
-{
- /* Do recovery */
- struct unf_lport *lport = NULL;
- union unf_sfs_u *sfs_ptr = NULL;
- struct unf_disc *disc = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- sfs_ptr = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!sfs_ptr)
- return;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- lport = xchg->lport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
- if (!lport)
- return;
-
- disc = &lport->disc;
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(lport, UNF_EVENT_DISC_FAILED);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- /* Do DISC recovery operation */
- unf_disc_error_recovery(lport);
-}
-
-static void unf_gid_pt_callback(void *lport, void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_gid_acc_pld *gid_acc_pld = NULL;
- struct unf_xchg *unf_xchg = NULL;
- union unf_sfs_u *sfs_ptr = NULL;
- u32 cmnd_rsp_size = 0;
- u32 rjt_reason = 0;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_rport = (struct unf_rport *)rport;
- disc = &unf_lport->disc;
- unf_xchg = (struct unf_xchg *)xchg;
- sfs_ptr = unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
-
- gid_acc_pld = sfs_ptr->get_id.gid_rsp.gid_acc_pld;
- if (!gid_acc_pld) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) GID_PT response payload is NULL",
- unf_lport->port_id);
- return;
- }
-
- cmnd_rsp_size = (gid_acc_pld->ctiu_pream.cmnd_rsp_size);
- if ((cmnd_rsp_size & UNF_CT_IU_RSP_MASK) == UNF_CT_IU_ACCEPT) {
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_SUCCESS);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- unf_gid_acc_handle(gid_acc_pld, unf_lport);
- } else if ((cmnd_rsp_size & UNF_CT_IU_RSP_MASK) == UNF_CT_IU_REJECT) {
- rjt_reason = (gid_acc_pld->ctiu_pream.frag_reason_exp_vend);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) GID_PT was rejected with reason code(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, rjt_reason);
-
- if ((rjt_reason & UNF_CTIU_RJT_EXP_MASK) ==
- UNF_CTIU_RJT_EXP_PORTTYPE_NO_REG) {
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_SUCCESS);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- unf_gid_acc_handle(gid_acc_pld, unf_lport);
- } else {
- ret = unf_send_gid_ft(unf_lport, unf_rport);
- if (ret != RETURN_OK)
- goto SEND_GID_PT_FT_FAILED;
- }
- } else {
- goto SEND_GID_PT_FT_FAILED;
- }
-
- return;
-SEND_GID_PT_FT_FAILED:
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- unf_disc_state_ma(unf_lport, UNF_EVENT_DISC_FAILED);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- unf_disc_error_recovery(unf_lport);
-}
-
-static void unf_gnn_id_ob_callback(struct unf_xchg *xchg)
-{
- /* Send GFF_ID */
- struct unf_lport *lport = NULL;
- struct unf_rport *sns_port = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 nport_id = 0;
- struct unf_lport *root_lport = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
- lport = xchg->lport;
- FC_CHECK_RETURN_VOID(lport);
- sns_port = xchg->rport;
- FC_CHECK_RETURN_VOID(sns_port);
- nport_id = xchg->disc_portid;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send GNN_ID failed to inquire RPort(0x%x)",
- lport->port_id, nport_id);
-
- root_lport = (struct unf_lport *)lport->root_lport;
- atomic_inc(&root_lport->disc.disc_thread_info.disc_contrl_size);
- wake_up_process(root_lport->disc.disc_thread_info.thread);
-
- /* NOTE: continue next stage */
- ret = unf_get_and_post_disc_event(lport, sns_port, nport_id, UNF_DISC_GET_FEATURE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- lport->port_id, UNF_DISC_GET_FEATURE, nport_id);
-
- unf_rcv_gff_id_rsp_unknown(lport, nport_id);
- }
-}
-
-static void unf_rcv_gnn_id_acc(struct unf_lport *lport,
- struct unf_rport *sns_port,
- struct unf_gnnid_rsp *gnnid_rsp_pld,
- u32 nport_id)
-{
- /* Send GFF_ID or Link down immediately */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_sns_port = sns_port;
- struct unf_gnnid_rsp *unf_gnnid_rsp_pld = gnnid_rsp_pld;
- struct unf_rport *rport = NULL;
- u64 node_name = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(sns_port);
- FC_CHECK_RETURN_VOID(gnnid_rsp_pld);
-
- node_name = ((u64)(unf_gnnid_rsp_pld->node_name[ARRAY_INDEX_0]) << UNF_SHIFT_32) |
- ((u64)(unf_gnnid_rsp_pld->node_name[ARRAY_INDEX_1]));
-
- if (unf_lport->node_name == node_name) {
- /* R_Port & L_Port with same Node Name */
- rport = unf_get_rport_by_nport_id(unf_lport, nport_id);
- if (rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x) has the same node name(0x%llx) with RPort(0x%x), linkdown it",
- unf_lport->port_id, node_name, nport_id);
-
- /* Destroy immediately */
- unf_rport_immediate_link_down(unf_lport, rport);
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x) got RPort(0x%x) with node name(0x%llx) by GNN_ID",
- unf_lport->port_id, nport_id, node_name);
-
- /* Start to Send GFF_ID */
- ret = unf_get_and_post_disc_event(unf_lport, unf_sns_port,
- nport_id, UNF_DISC_GET_FEATURE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- unf_lport->port_id, UNF_DISC_GET_FEATURE, nport_id);
-
- unf_rcv_gff_id_rsp_unknown(unf_lport, nport_id);
- }
- }
-}
-
-static void unf_rcv_gnn_id_rjt(struct unf_lport *lport,
- struct unf_rport *sns_port,
- struct unf_gnnid_rsp *gnnid_rsp_pld,
- u32 nport_id)
-{
- /* Send GFF_ID */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_sns_port = sns_port;
- struct unf_gnnid_rsp *unf_gnnid_rsp_pld = gnnid_rsp_pld;
- u32 rjt_reason = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(sns_port);
- FC_CHECK_RETURN_VOID(gnnid_rsp_pld);
-
- rjt_reason = (unf_gnnid_rsp_pld->ctiu_pream.frag_reason_exp_vend);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) GNN_ID was rejected with reason code(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, rjt_reason);
-
- if (!UNF_GNN_GFF_ID_RJT_REASON(rjt_reason)) {
- /* Node existence: Continue next stage */
- ret = unf_get_and_post_disc_event(unf_lport, unf_sns_port,
- nport_id, UNF_DISC_GET_FEATURE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- unf_lport->port_id, UNF_DISC_GET_FEATURE, nport_id);
-
- unf_rcv_gff_id_rsp_unknown(unf_lport, nport_id);
- }
- }
-}
-
-void unf_rcv_gnn_id_rsp_unknown(struct unf_lport *lport,
- struct unf_rport *sns_port, u32 nport_id)
-{
- /* Send GFF_ID */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_sns_port = sns_port;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(sns_port);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) Rportid(0x%x) GNN_ID response is unknown. Sending GFF_ID",
- unf_lport->port_id, unf_lport->nport_id, nport_id);
-
- ret = unf_get_and_post_disc_event(unf_lport, unf_sns_port, nport_id, UNF_DISC_GET_FEATURE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- unf_lport->port_id, UNF_DISC_GET_FEATURE,
- nport_id);
-
- /* NOTE: go to next stage */
- unf_rcv_gff_id_rsp_unknown(unf_lport, nport_id);
- }
-}
-
-static void unf_gnn_id_callback(void *lport, void *sns_port, void *xchg)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
- struct unf_rport *unf_sns_port = (struct unf_rport *)sns_port;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_gnnid_rsp *gnnid_rsp_pld = NULL;
- u32 cmnd_rsp_size = 0;
- u32 nport_id = 0;
- struct unf_lport *root_lport = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(sns_port);
- FC_CHECK_RETURN_VOID(xchg);
-
- nport_id = unf_xchg->disc_portid;
- gnnid_rsp_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->gnn_id_rsp;
- cmnd_rsp_size = gnnid_rsp_pld->ctiu_pream.cmnd_rsp_size;
-
- root_lport = (struct unf_lport *)unf_lport->root_lport;
- atomic_inc(&root_lport->disc.disc_thread_info.disc_contrl_size);
- wake_up_process(root_lport->disc.disc_thread_info.thread);
-
- if ((cmnd_rsp_size & UNF_CT_IU_RSP_MASK) == UNF_CT_IU_ACCEPT) {
- /* Case ACC: send GFF_ID or Link down immediately */
- unf_rcv_gnn_id_acc(unf_lport, unf_sns_port, gnnid_rsp_pld, nport_id);
- } else if ((cmnd_rsp_size & UNF_CT_IU_RSP_MASK) == UNF_CT_IU_REJECT) {
- /* Case RJT: send GFF_ID */
- unf_rcv_gnn_id_rjt(unf_lport, unf_sns_port, gnnid_rsp_pld, nport_id);
- } else { /* NOTE: continue next stage */
- /* Case unknown: send GFF_ID */
- unf_rcv_gnn_id_rsp_unknown(unf_lport, unf_sns_port, nport_id);
- }
-}
-
-static void unf_gff_id_ob_callback(struct unf_xchg *xchg)
-{
- /* Send PLOGI */
- struct unf_lport *lport = NULL;
- struct unf_lport *root_lport = NULL;
- struct unf_rport *rport = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 nport_id = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- lport = xchg->lport;
- nport_id = xchg->disc_portid;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_CHECK_RETURN_VOID(lport);
-
- root_lport = (struct unf_lport *)lport->root_lport;
- atomic_inc(&root_lport->disc.disc_thread_info.disc_contrl_size);
- wake_up_process(root_lport->disc.disc_thread_info.thread);
-
- /* Get (safe) R_Port */
- rport = unf_get_rport_by_nport_id(lport, nport_id);
- rport = unf_get_safe_rport(lport, rport, UNF_RPORT_REUSE_ONLY, nport_id);
- if (!rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't allocate new RPort(0x%x)",
- lport->port_id, nport_id);
- return;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) send GFF_ID(0x%x_0x%x) to RPort(0x%x_0x%x) abnormal",
- lport->port_id, lport->nport_id, xchg->oxid, xchg->rxid,
- rport->rport_index, rport->nport_id);
-
- /* Update R_Port state: PLOGI_WAIT */
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->nport_id = nport_id;
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* NOTE: Start to send PLOGI */
- ret = unf_send_plogi(lport, rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send PLOGI failed, enter recovry",
- lport->port_id);
-
- /* Do R_Port recovery */
- unf_rport_error_recovery(rport);
- }
-}
-
-void unf_rcv_gff_id_acc(struct unf_lport *lport,
- struct unf_gffid_rsp *gffid_rsp_pld, u32 nport_id)
-{
- /* Delay to LOGIN */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *rport = NULL;
- struct unf_gffid_rsp *unf_gffid_rsp_pld = gffid_rsp_pld;
- u32 fc_4feacture = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(gffid_rsp_pld);
-
- fc_4feacture = unf_gffid_rsp_pld->fc4_feature[ARRAY_INDEX_1];
- if ((UNF_GFF_ACC_MASK & fc_4feacture) == 0)
- fc_4feacture = be32_to_cpu(unf_gffid_rsp_pld->fc4_feature[ARRAY_INDEX_1]);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) RPort(0x%x) received GFF_ID ACC. FC4 feature is 0x%x(1:TGT,2:INI,3:COM)",
- unf_lport->port_id, unf_lport->nport_id, nport_id, fc_4feacture);
-
- /* Check (& Get new) R_Port */
- rport = unf_get_rport_by_nport_id(unf_lport, nport_id);
- if (rport)
- rport = unf_find_rport(unf_lport, nport_id, rport->port_name);
-
- if (rport || (UNF_GET_PORT_OPTIONS(fc_4feacture) != UNF_PORT_MODE_INI)) {
- rport = unf_get_safe_rport(unf_lport, rport, UNF_RPORT_REUSE_ONLY, nport_id);
- FC_CHECK_RETURN_VOID(rport);
- } else {
- return;
- }
-
- if ((fc_4feacture & UNF_GFF_ACC_MASK) != 0) {
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->options = UNF_GET_PORT_OPTIONS(fc_4feacture);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- } else if (rport->port_name != INVALID_WWPN) {
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->options = unf_get_port_feature(rport->port_name);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- }
-
- /* NOTE: Send PLOGI if necessary */
- unf_check_rport_need_delay_plogi(unf_lport, rport, rport->options);
-}
-
-void unf_rcv_gff_id_rjt(struct unf_lport *lport,
- struct unf_gffid_rsp *gffid_rsp_pld, u32 nport_id)
-{
- /* Delay LOGIN or LOGO */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *rport = NULL;
- struct unf_gffid_rsp *unf_gffid_rsp_pld = gffid_rsp_pld;
- u32 rjt_reason = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(gffid_rsp_pld);
-
- /* Check (& Get new) R_Port */
- rport = unf_get_rport_by_nport_id(unf_lport, nport_id);
- if (rport)
- rport = unf_find_rport(unf_lport, nport_id, rport->port_name);
-
- if (!rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) get RPort by N_Port_ID(0x%x) failed and alloc new",
- unf_lport->port_id, nport_id);
-
- rport = unf_rport_get_free_and_init(unf_lport, UNF_PORT_TYPE_FC, nport_id);
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->nport_id = nport_id;
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- }
-
- rjt_reason = unf_gffid_rsp_pld->ctiu_pream.frag_reason_exp_vend;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send GFF_ID for RPort(0x%x) but was rejected. Reason code(0x%x)",
- unf_lport->port_id, nport_id, rjt_reason);
-
- if (!UNF_GNN_GFF_ID_RJT_REASON(rjt_reason)) {
- rport = unf_get_safe_rport(lport, rport, UNF_RPORT_REUSE_ONLY, nport_id);
- FC_CHECK_RETURN_VOID(rport);
-
- /* Update R_Port state: PLOGI_WAIT */
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->nport_id = nport_id;
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* Delay to send PLOGI */
- unf_rport_delay_login(rport);
- } else {
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- if (rport->rp_state == UNF_RPORT_ST_INIT) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* Enter closing state */
- unf_rport_enter_logo(unf_lport, rport);
- } else {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- }
- }
-}
-
-void unf_rcv_gff_id_rsp_unknown(struct unf_lport *lport, u32 nport_id)
-{
- /* Send PLOGI */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *rport = NULL;
- ulong flag = 0;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send GFF_ID for RPort(0x%x) but response is unknown",
- unf_lport->port_id, nport_id);
-
- /* Get (Safe) R_Port & Set State */
- rport = unf_get_rport_by_nport_id(unf_lport, nport_id);
- if (rport)
- rport = unf_find_rport(unf_lport, nport_id, rport->port_name);
-
- if (!rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) can't get RPort by NPort ID(0x%x), allocate new RPort",
- unf_lport->port_id, unf_lport->nport_id, nport_id);
-
- rport = unf_rport_get_free_and_init(unf_lport, UNF_PORT_TYPE_FC, nport_id);
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->nport_id = nport_id;
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- }
-
- rport = unf_get_safe_rport(unf_lport, rport, UNF_RPORT_REUSE_ONLY, nport_id);
- FC_CHECK_RETURN_VOID(rport);
-
- /* Update R_Port state: PLOGI_WAIT */
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->nport_id = nport_id;
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* Start to send PLOGI */
- ret = unf_send_plogi(unf_lport, rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) can not send PLOGI for RPort(0x%x), enter recovery",
- unf_lport->port_id, nport_id);
-
- unf_rport_error_recovery(rport);
- }
-}
-
-static void unf_gff_id_callback(void *lport, void *sns_port, void *xchg)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
- struct unf_lport *root_lport = NULL;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_gffid_rsp *gffid_rsp_pld = NULL;
- u32 cmnd_rsp_size = 0;
- u32 nport_id = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(sns_port);
- FC_CHECK_RETURN_VOID(xchg);
-
- nport_id = unf_xchg->disc_portid;
-
- gffid_rsp_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->gff_id_rsp;
- cmnd_rsp_size = (gffid_rsp_pld->ctiu_pream.cmnd_rsp_size);
-
- root_lport = (struct unf_lport *)unf_lport->root_lport;
- atomic_inc(&root_lport->disc.disc_thread_info.disc_contrl_size);
- wake_up_process(root_lport->disc.disc_thread_info.thread);
-
- if ((cmnd_rsp_size & UNF_CT_IU_RSP_MASK) == UNF_CT_IU_ACCEPT) {
- /* Case for GFF_ID ACC: (Delay)PLOGI */
- unf_rcv_gff_id_acc(unf_lport, gffid_rsp_pld, nport_id);
- } else if ((cmnd_rsp_size & UNF_CT_IU_RSP_MASK) == UNF_CT_IU_REJECT) {
- /* Case for GFF_ID RJT: Delay PLOGI or LOGO directly */
- unf_rcv_gff_id_rjt(unf_lport, gffid_rsp_pld, nport_id);
- } else {
- /* Send PLOGI */
- unf_rcv_gff_id_rsp_unknown(unf_lport, nport_id);
- }
-}
-
-static void unf_rcv_gpn_id_acc(struct unf_lport *lport,
- u32 nport_id, u64 port_name)
-{
- /* then PLOGI or re-login */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *rport = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- rport = unf_find_valid_rport(unf_lport, port_name, nport_id);
- if (rport) {
- /* R_Port with TGT mode & L_Port with INI mode:
- * send PLOGI with INIT state
- */
- if ((rport->options & UNF_PORT_MODE_TGT) == UNF_PORT_MODE_TGT) {
- rport = unf_get_safe_rport(lport, rport, UNF_RPORT_REUSE_INIT, nport_id);
- FC_CHECK_RETURN_VOID(rport);
-
- /* Update R_Port state: PLOGI_WAIT */
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->nport_id = nport_id;
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* Start to send PLOGI */
- ret = unf_send_plogi(unf_lport, rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send PLOGI failed for 0x%x, enter recovry",
- unf_lport->port_id, unf_lport->nport_id, nport_id);
-
- unf_rport_error_recovery(rport);
- }
- } else {
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- if (rport->rp_state != UNF_RPORT_ST_PLOGI_WAIT &&
- rport->rp_state != UNF_RPORT_ST_PRLI_WAIT &&
- rport->rp_state != UNF_RPORT_ST_READY) {
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* Do LOGO operation */
- unf_rport_enter_logo(unf_lport, rport);
- } else {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- }
- }
- } else {
- /* Send GNN_ID */
- (void)unf_rport_relogin(unf_lport, nport_id);
- }
-}
-
-static void unf_rcv_gpn_id_rjt(struct unf_lport *lport, u32 nport_id)
-{
- struct unf_lport *unf_lport = lport;
- struct unf_rport *rport = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- rport = unf_get_rport_by_nport_id(unf_lport, nport_id);
- if (rport)
- /* Do R_Port Link down */
- unf_rport_linkdown(unf_lport, rport);
-}
-
-void unf_rcv_gpn_id_rsp_unknown(struct unf_lport *lport, u32 nport_id)
-{
- struct unf_lport *unf_lport = lport;
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) wrong response of GPN_ID with RPort(0x%x)",
- unf_lport->port_id, nport_id);
-
- /* NOTE: go to next stage */
- (void)unf_rport_relogin(unf_lport, nport_id);
-}
-
-static void unf_gpn_id_ob_callback(struct unf_xchg *xchg)
-{
- struct unf_lport *lport = NULL;
- u32 nport_id = 0;
- struct unf_lport *root_lport = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- lport = xchg->lport;
- nport_id = xchg->disc_portid;
- FC_CHECK_RETURN_VOID(lport);
-
- root_lport = (struct unf_lport *)lport->root_lport;
- atomic_inc(&root_lport->disc.disc_thread_info.disc_contrl_size);
- wake_up_process(root_lport->disc.disc_thread_info.thread);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send GPN_ID failed to inquire RPort(0x%x)",
- lport->port_id, nport_id);
-
- /* NOTE: go to next stage */
- (void)unf_rport_relogin(lport, nport_id);
-}
-
-static void unf_gpn_id_callback(void *lport, void *sns_port, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_gpnid_rsp *gpnid_rsp_pld = NULL;
- u64 port_name = 0;
- u32 cmnd_rsp_size = 0;
- u32 nport_id = 0;
- struct unf_lport *root_lport = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(sns_port);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_xchg = (struct unf_xchg *)xchg;
- nport_id = unf_xchg->disc_portid;
-
- root_lport = (struct unf_lport *)unf_lport->root_lport;
- atomic_inc(&root_lport->disc.disc_thread_info.disc_contrl_size);
- wake_up_process(root_lport->disc.disc_thread_info.thread);
-
- gpnid_rsp_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->gpn_id_rsp;
- cmnd_rsp_size = gpnid_rsp_pld->ctiu_pream.cmnd_rsp_size;
- if (UNF_CT_IU_ACCEPT == (cmnd_rsp_size & UNF_CT_IU_RSP_MASK)) {
- /* GPN_ID ACC */
- port_name = ((u64)(gpnid_rsp_pld->port_name[ARRAY_INDEX_0])
- << UNF_SHIFT_32) |
- ((u64)(gpnid_rsp_pld->port_name[ARRAY_INDEX_1]));
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x) GPN_ID ACC with WWN(0x%llx) RPort NPort ID(0x%x)",
- unf_lport->port_id, port_name, nport_id);
-
- /* Send PLOGI or LOGO or GNN_ID */
- unf_rcv_gpn_id_acc(unf_lport, nport_id, port_name);
- } else if (UNF_CT_IU_REJECT == (cmnd_rsp_size & UNF_CT_IU_RSP_MASK)) {
- /* GPN_ID RJT: Link Down */
- unf_rcv_gpn_id_rjt(unf_lport, nport_id);
- } else {
- /* GPN_ID response type unknown: Send GNN_ID */
- unf_rcv_gpn_id_rsp_unknown(unf_lport, nport_id);
- }
-}
-
-static void unf_rff_id_ob_callback(struct unf_xchg *xchg)
-{
- /* Do recovery */
- struct unf_lport *lport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- lport = xchg->lport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send RFF_ID failed",
- lport->port_id, lport->nport_id);
-
- unf_lport_error_recovery(lport);
-}
-
-static void unf_rff_id_callback(void *lport, void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_ctiu_prem *ctiu_prem = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 cmnd_rsp_size = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_xchg = (struct unf_xchg *)xchg;
- if (unlikely(!unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr))
- return;
-
- unf_rport = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_FCTRL);
- unf_rport = unf_get_safe_rport(unf_lport, unf_rport,
- UNF_RPORT_REUSE_ONLY, UNF_FC_FID_FCTRL);
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't allocate RPort(0x%x)",
- unf_lport->port_id, UNF_FC_FID_FCTRL);
- return;
- }
-
- unf_rport->nport_id = UNF_FC_FID_FCTRL;
- ctiu_prem = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->rff_id_rsp.ctiu_pream;
- cmnd_rsp_size = ctiu_prem->cmnd_rsp_size;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Port(0x%x_0x%x) RFF_ID rsp is (0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- (cmnd_rsp_size & UNF_CT_IU_RSP_MASK));
-
- /* RSP Type check: some SW not support RFF_ID, go to next stage also */
- if ((cmnd_rsp_size & UNF_CT_IU_RSP_MASK) == UNF_CT_IU_ACCEPT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) receive RFF ACC(0x%x) in state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- (cmnd_rsp_size & UNF_CT_IU_RSP_MASK), unf_lport->states);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) receive RFF RJT(0x%x) in state(0x%x) with RJT reason code(0x%x) explanation(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- (cmnd_rsp_size & UNF_CT_IU_RSP_MASK), unf_lport->states,
- (ctiu_prem->frag_reason_exp_vend) & UNF_CT_IU_REASON_MASK,
- (ctiu_prem->frag_reason_exp_vend) & UNF_CT_IU_EXPLAN_MASK);
- }
-
- /* L_Port state check */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- if (unf_lport->states != UNF_LPORT_ST_RFF_ID_WAIT) {
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) receive RFF reply in state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, unf_lport->states);
-
- return;
- }
- /* LPort: RFF_ID_WAIT --> SCR_WAIT */
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_REMOTE_ACC);
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- ret = unf_send_scr(unf_lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send SCR failed",
- unf_lport->port_id, unf_lport->nport_id);
- unf_lport_error_recovery(unf_lport);
- }
-}
-
-static void unf_rft_id_ob_callback(struct unf_xchg *xchg)
-{
- struct unf_lport *lport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- lport = xchg->lport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send RFT_ID failed",
- lport->port_id, lport->nport_id);
- unf_lport_error_recovery(lport);
-}
-
-static void unf_rft_id_callback(void *lport, void *rport, void *xchg)
-{
- /* RFT_ID --->>> RFF_ID */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_ctiu_prem *ctiu_prem = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 cmnd_rsp_size = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_rport = (struct unf_rport *)rport;
- unf_xchg = (struct unf_xchg *)xchg;
-
- if (!unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) SFS entry is NULL with state(0x%x)",
- unf_lport->port_id, unf_lport->states);
- return;
- }
-
- ctiu_prem = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr
- ->rft_id_rsp.ctiu_pream;
- cmnd_rsp_size = (ctiu_prem->cmnd_rsp_size);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) RFT_ID response is (0x%x)",
- (cmnd_rsp_size & UNF_CT_IU_RSP_MASK), unf_lport->port_id,
- unf_lport->nport_id);
-
- if (UNF_CT_IU_ACCEPT == (cmnd_rsp_size & UNF_CT_IU_RSP_MASK)) {
- /* Case for RFT_ID ACC: send RFF_ID */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- if (unf_lport->states != UNF_LPORT_ST_RFT_ID_WAIT) {
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) receive RFT_ID ACC in state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- unf_lport->states);
-
- return;
- }
-
- /* LPort: RFT_ID_WAIT --> RFF_ID_WAIT */
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_REMOTE_ACC);
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- /* Start to send RFF_ID GS command */
- ret = unf_send_rff_id(unf_lport, unf_rport, UNF_FC4_FCP_TYPE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send RFF_ID failed",
- unf_lport->port_id, unf_lport->nport_id);
- unf_lport_error_recovery(unf_lport);
- }
- } else {
- /* Case for RFT_ID RJT: do recovery */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) receive RFT_ID RJT with reason_code(0x%x) explanation(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- (ctiu_prem->frag_reason_exp_vend) & UNF_CT_IU_REASON_MASK,
- (ctiu_prem->frag_reason_exp_vend) & UNF_CT_IU_EXPLAN_MASK);
-
- /* Do L_Port recovery */
- unf_lport_error_recovery(unf_lport);
- }
-}
-
-static void unf_scr_ob_callback(struct unf_xchg *xchg)
-{
- /* Callback fucnion for exception: Do L_Port error recovery */
- struct unf_lport *lport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- lport = xchg->lport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send SCR failed and do port recovery",
- lport->port_id);
-
- unf_lport_error_recovery(lport);
-}
-
-static void unf_scr_callback(void *lport, void *rport, void *xchg)
-{
- /* Callback function for SCR response: Send GID_PT with INI mode */
- struct unf_lport *unf_lport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_els_acc *els_acc = NULL;
- u32 ret = UNF_RETURN_ERROR;
- ulong port_flag = 0;
- ulong disc_flag = 0;
- u32 cmnd = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_xchg = (struct unf_xchg *)xchg;
- disc = &unf_lport->disc;
-
- if (!unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr)
- return;
-
- els_acc = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->els_acc;
- if (unf_xchg->byte_orders & UNF_BIT_2)
- cmnd = be32_to_cpu(els_acc->cmnd);
- else
- cmnd = (els_acc->cmnd);
-
- if ((cmnd & UNF_ELS_CMND_HIGH_MASK) == UNF_ELS_CMND_ACC) {
- spin_lock_irqsave(&unf_lport->lport_state_lock, port_flag);
- if (unf_lport->states != UNF_LPORT_ST_SCR_WAIT) {
- spin_unlock_irqrestore(&unf_lport->lport_state_lock,
- port_flag);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) receive SCR ACC with error state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- unf_lport->states);
- return;
- }
-
- /* LPort: SCR_WAIT --> READY */
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_REMOTE_ACC);
- if (unf_lport->states == UNF_LPORT_ST_READY) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) enter READY state when received SCR response",
- unf_lport->port_id, unf_lport->nport_id);
- }
-
- /* Start to Discovery with INI mode: GID_PT */
- if ((unf_lport->options & UNF_PORT_MODE_INI) ==
- UNF_PORT_MODE_INI) {
- spin_unlock_irqrestore(&unf_lport->lport_state_lock,
- port_flag);
-
- if (unf_lport->disc.disc_temp.unf_disc_start) {
- spin_lock_irqsave(&disc->rport_busy_pool_lock,
- disc_flag);
- unf_lport->disc.disc_option = UNF_INIT_DISC;
- disc->last_disc_jiff = jiffies;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
-
- ret = unf_lport->disc.disc_temp.unf_disc_start(unf_lport);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Port(0x%x) DISC %s with INI mode",
- unf_lport->port_id,
- (ret != RETURN_OK) ? "failed" : "succeed");
- }
- return;
- }
-
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, port_flag);
- /* NOTE: set state with UNF_DISC_ST_END used for
- * RSCN process
- */
- spin_lock_irqsave(&disc->rport_busy_pool_lock, disc_flag);
- unf_lport->disc.states = UNF_DISC_ST_END;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) is TGT mode, no need to discovery",
- unf_lport->port_id);
-
- return;
- }
- unf_lport_error_recovery(unf_lport);
-}
-
-void unf_check_rport_need_delay_plogi(struct unf_lport *lport,
- struct unf_rport *rport, u32 port_feature)
-{
- /*
- * Called by:
- * 1. Private loop
- * 2. RCVD GFF_ID ACC
- */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- ulong flag = 0;
- u32 nport_id = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- nport_id = unf_rport->nport_id;
-
- /*
- * Send GFF_ID means L_Port has INI attribute
- * *
- * When to send PLOGI:
- * 1. R_Port has TGT mode (COM or TGT), send PLOGI immediately
- * 2. R_Port only with INI, send LOGO immediately
- * 3. R_Port with unknown attribute, delay to send PLOGI
- */
- if ((UNF_PORT_MODE_TGT & port_feature) ||
- (UNF_LPORT_ENHANCED_FEATURE_ENHANCED_GFF &
- unf_lport->enhanced_features)) {
- /* R_Port has TGT mode: send PLOGI immediately */
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY, nport_id);
- FC_CHECK_RETURN_VOID(unf_rport);
-
- /* Update R_Port state: PLOGI_WAIT */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = nport_id;
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Start to send PLOGI */
- ret = unf_send_plogi(unf_lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send PLOGI to RPort(0x%x) failed",
- unf_lport->port_id, unf_lport->nport_id,
- nport_id);
-
- unf_rport_error_recovery(unf_rport);
- }
- } else if (port_feature == UNF_PORT_MODE_INI) {
- /* R_Port only with INI mode: can't send PLOGI
- * --->>> LOGO/nothing
- */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- if (unf_rport->rp_state == UNF_RPORT_ST_INIT) {
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send LOGO to RPort(0x%x) which only with INI mode",
- unf_lport->port_id, unf_lport->nport_id, nport_id);
-
- /* Enter Closing state */
- unf_rport_enter_logo(unf_lport, unf_rport);
- } else {
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
- }
- } else {
- /* Unknown R_Port attribute: Delay to send PLOGI */
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY, nport_id);
- FC_CHECK_RETURN_VOID(unf_rport);
-
- /* Update R_Port state: PLOGI_WAIT */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = nport_id;
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- unf_rport_delay_login(unf_rport);
- }
-}
diff --git a/drivers/scsi/spfc/common/unf_gs.h b/drivers/scsi/spfc/common/unf_gs.h
deleted file mode 100644
index d9856133b3cd..000000000000
--- a/drivers/scsi/spfc/common/unf_gs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_GS_H
-#define UNF_GS_H
-
-#include "unf_type.h"
-#include "unf_lport.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-u32 unf_send_scr(struct unf_lport *lport,
- struct unf_rport *rport);
-u32 unf_send_ctpass_thru(struct unf_lport *lport,
- void *buffer, u32 bufflen);
-
-u32 unf_send_gid_ft(struct unf_lport *lport,
- struct unf_rport *rport);
-u32 unf_send_gid_pt(struct unf_lport *lport,
- struct unf_rport *rport);
-u32 unf_send_gpn_id(struct unf_lport *lport,
- struct unf_rport *sns_port, u32 nport_id);
-u32 unf_send_gnn_id(struct unf_lport *lport,
- struct unf_rport *sns_port, u32 nport_id);
-u32 unf_send_gff_id(struct unf_lport *lport,
- struct unf_rport *sns_port, u32 nport_id);
-
-u32 unf_send_rff_id(struct unf_lport *lport,
- struct unf_rport *rport, u32 fc4_type);
-u32 unf_send_rft_id(struct unf_lport *lport,
- struct unf_rport *rport);
-void unf_rcv_gnn_id_rsp_unknown(struct unf_lport *lport,
- struct unf_rport *sns_port, u32 nport_id);
-void unf_rcv_gpn_id_rsp_unknown(struct unf_lport *lport, u32 nport_id);
-void unf_rcv_gff_id_rsp_unknown(struct unf_lport *lport, u32 nport_id);
-void unf_check_rport_need_delay_plogi(struct unf_lport *lport,
- struct unf_rport *rport, u32 port_feature);
-
-struct send_com_trans_in {
- unsigned char port_wwn[8];
- u32 req_buffer_count;
- unsigned char req_buffer[ARRAY_INDEX_1];
-};
-
-struct send_com_trans_out {
- u32 hba_status;
- u32 total_resp_buffer_cnt;
- u32 actual_resp_buffer_cnt;
- unsigned char resp_buffer[ARRAY_INDEX_1];
-};
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_init.c b/drivers/scsi/spfc/common/unf_init.c
deleted file mode 100644
index 7e6f98d16977..000000000000
--- a/drivers/scsi/spfc/common/unf_init.c
+++ /dev/null
@@ -1,353 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_type.h"
-#include "unf_log.h"
-#include "unf_scsi_common.h"
-#include "unf_event.h"
-#include "unf_exchg.h"
-#include "unf_portman.h"
-#include "unf_rport.h"
-#include "unf_service.h"
-#include "unf_io.h"
-#include "unf_io_abnormal.h"
-
-#define UNF_PID 12
-#define MY_PID UNF_PID
-
-#define RPORT_FEATURE_POOL_SIZE 4096
-struct task_struct *event_task_thread;
-struct workqueue_struct *unf_wq;
-
-atomic_t fc_mem_ref;
-
-struct unf_global_card_thread card_thread_mgr;
-u32 unf_dgb_level = UNF_MAJOR;
-u32 log_print_level = UNF_INFO;
-u32 log_limited_times = UNF_LOGIN_ATT_PRINT_TIMES;
-
-static struct unf_esgl_page *unf_get_one_free_esgl_page
- (void *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(pkg, NULL);
-
- unf_lport = (struct unf_lport *)lport;
- unf_xchg = (struct unf_xchg *)pkg->xchg_contex;
-
- return unf_get_and_add_one_free_esgl_page(unf_lport, unf_xchg);
-}
-
-static int unf_get_cfg_parms(char *section_name, struct unf_cfg_item *cfg_itm,
- u32 *cfg_value, u32 itemnum)
-{
- /* Maximum length of a configuration item value, including the end
- * character
- */
-#define UNF_MAX_ITEM_VALUE_LEN (256)
-
- u32 *unf_cfg_value = NULL;
- struct unf_cfg_item *unf_cfg_itm = NULL;
- u32 i = 0;
-
- unf_cfg_itm = cfg_itm;
- unf_cfg_value = cfg_value;
-
- for (i = 0; i < itemnum; i++) {
- if (!unf_cfg_itm || !unf_cfg_value) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_ERR,
- "[err]Config name or value is NULL");
-
- return UNF_RETURN_ERROR;
- }
-
- if (strcmp("End", unf_cfg_itm->puc_name) == 0x0)
- break;
-
- if (strcmp("fw_path", unf_cfg_itm->puc_name) == 0x0) {
- unf_cfg_itm++;
- unf_cfg_value += UNF_MAX_ITEM_VALUE_LEN / sizeof(u32);
- continue;
- }
-
- *unf_cfg_value = unf_cfg_itm->default_value;
- unf_cfg_itm++;
- unf_cfg_value++;
- }
-
- return RETURN_OK;
-}
-
-struct unf_cm_handle_op unf_cm_handle_ops = {
- .unf_alloc_local_port = unf_lport_create_and_init,
- .unf_release_local_port = unf_release_local_port,
- .unf_receive_ls_gs_pkg = unf_receive_ls_gs_pkg,
- .unf_receive_bls_pkg = unf_receive_bls_pkg,
- .unf_send_els_done = unf_send_els_done,
- .unf_receive_ini_response = unf_ini_scsi_completed,
- .unf_get_cfg_parms = unf_get_cfg_parms,
- .unf_receive_marker_status = unf_recv_tmf_marker_status,
- .unf_receive_abts_marker_status = unf_recv_abts_marker_status,
-
- .unf_process_fcp_cmnd = NULL,
- .unf_tgt_cmnd_xfer_or_rsp_echo = NULL,
- .unf_cm_get_sgl_entry = unf_ini_get_sgl_entry,
- .unf_cm_get_dif_sgl_entry = unf_ini_get_dif_sgl_entry,
- .unf_get_one_free_esgl_page = unf_get_one_free_esgl_page,
- .unf_fc_port_event = unf_fc_port_link_event,
-};
-
-u32 unf_get_cm_handle_ops(struct unf_cm_handle_op *cm_handle)
-{
- FC_CHECK_RETURN_VALUE(cm_handle, UNF_RETURN_ERROR);
-
- memcpy(cm_handle, &unf_cm_handle_ops, sizeof(struct unf_cm_handle_op));
-
- return RETURN_OK;
-}
-
-static void unf_deinit_cm_handle_ops(void)
-{
- memset(&unf_cm_handle_ops, 0, sizeof(struct unf_cm_handle_op));
-}
-
-int unf_event_process(void *worker_ptr)
-{
- struct list_head *event_list = NULL;
- struct unf_cm_event_report *event_node = NULL;
- struct completion *create_done = (struct completion *)worker_ptr;
- ulong flags = 0;
-
- set_user_nice(current, UNF_OS_THRD_PRI_LOW);
- recalc_sigpending();
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[event]Enter event thread");
-
- if (create_done)
- complete(create_done);
-
- do {
- spin_lock_irqsave(&fc_event_list.fc_event_list_lock, flags);
- if (list_empty(&fc_event_list.list_head)) {
- spin_unlock_irqrestore(&fc_event_list.fc_event_list_lock, flags);
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout((long)msecs_to_jiffies(UNF_S_TO_MS));
- } else {
- event_list = UNF_OS_LIST_NEXT(&fc_event_list.list_head);
- list_del_init(event_list);
- fc_event_list.list_num--;
- event_node = list_entry(event_list,
- struct unf_cm_event_report,
- list_entry);
- spin_unlock_irqrestore(&fc_event_list.fc_event_list_lock, flags);
-
- /* Process event node */
- unf_handle_event(event_node);
- }
- } while (!kthread_should_stop());
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MAJOR,
- "[event]Event thread exit");
-
- return RETURN_OK;
-}
-
-static int unf_creat_event_center(void)
-{
- struct completion create_done;
-
- init_completion(&create_done);
- INIT_LIST_HEAD(&fc_event_list.list_head);
- fc_event_list.list_num = 0;
- spin_lock_init(&fc_event_list.fc_event_list_lock);
-
- event_task_thread = kthread_run(unf_event_process, &create_done, "spfc_event");
- if (IS_ERR(event_task_thread)) {
- complete_and_exit(&create_done, 0);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Create event thread failed(0x%p)",
- event_task_thread);
-
- return UNF_RETURN_ERROR;
- }
- wait_for_completion(&create_done);
- return RETURN_OK;
-}
-
-static void unf_cm_event_thread_exit(void)
-{
- if (event_task_thread)
- kthread_stop(event_task_thread);
-}
-
-static void unf_init_card_mgr_list(void)
-{
- /* So far, do not care */
- INIT_LIST_HEAD(&card_thread_mgr.card_list_head);
-
- spin_lock_init(&card_thread_mgr.global_card_list_lock);
-
- card_thread_mgr.card_num = 0;
-}
-
-int unf_port_feature_pool_init(void)
-{
- u32 index = 0;
- u32 rport_feature_pool_size = 0;
- struct unf_rport_feature_recard *rport_feature = NULL;
- unsigned long flags = 0;
-
- rport_feature_pool_size = sizeof(struct unf_rport_feature_pool);
- port_feature_pool = vmalloc(rport_feature_pool_size);
- if (!port_feature_pool) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]cannot allocate rport feature pool");
-
- return UNF_RETURN_ERROR;
- }
- memset(port_feature_pool, 0, rport_feature_pool_size);
- spin_lock_init(&port_feature_pool->port_fea_pool_lock);
- INIT_LIST_HEAD(&port_feature_pool->list_busy_head);
- INIT_LIST_HEAD(&port_feature_pool->list_free_head);
-
- port_feature_pool->port_feature_pool_addr =
- vmalloc((size_t)(RPORT_FEATURE_POOL_SIZE * sizeof(struct unf_rport_feature_recard)));
- if (!port_feature_pool->port_feature_pool_addr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]cannot allocate rport feature pool address");
-
- vfree(port_feature_pool);
- port_feature_pool = NULL;
-
- return UNF_RETURN_ERROR;
- }
-
- memset(port_feature_pool->port_feature_pool_addr, 0,
- RPORT_FEATURE_POOL_SIZE * sizeof(struct unf_rport_feature_recard));
- rport_feature = (struct unf_rport_feature_recard *)
- port_feature_pool->port_feature_pool_addr;
-
- spin_lock_irqsave(&port_feature_pool->port_fea_pool_lock, flags);
- for (index = 0; index < RPORT_FEATURE_POOL_SIZE; index++) {
- list_add_tail(&rport_feature->entry_feature, &port_feature_pool->list_free_head);
- rport_feature++;
- }
- spin_unlock_irqrestore(&port_feature_pool->port_fea_pool_lock, flags);
-
- return RETURN_OK;
-}
-
-void unf_free_port_feature_pool(void)
-{
- if (port_feature_pool->port_feature_pool_addr) {
- vfree(port_feature_pool->port_feature_pool_addr);
- port_feature_pool->port_feature_pool_addr = NULL;
- }
-
- vfree(port_feature_pool);
- port_feature_pool = NULL;
-}
-
-int unf_common_init(void)
-{
- int ret = RETURN_OK;
-
- unf_dgb_level = UNF_MAJOR;
- log_print_level = UNF_KEVENT;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "UNF Driver Version:%s.", SPFC_DRV_VERSION);
-
- atomic_set(&fc_mem_ref, 0);
- ret = unf_port_feature_pool_init();
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port Feature Pool init failed");
- return ret;
- }
-
- ret = (int)unf_register_ini_transport();
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]INI interface init failed");
- goto REG_INITRANSPORT_FAIL;
- }
-
- unf_port_mgmt_init();
- unf_init_card_mgr_list();
- ret = (int)unf_init_global_event_msg();
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Create global event center failed");
- goto CREAT_GLBEVENTMSG_FAIL;
- }
-
- ret = (int)unf_creat_event_center();
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Create event center (thread) failed");
- goto CREAT_EVENTCENTER_FAIL;
- }
-
- unf_wq = create_workqueue("unf_wq");
- if (!unf_wq) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Create work queue failed");
- goto CREAT_WORKQUEUE_FAIL;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Init common layer succeed");
- return ret;
-CREAT_WORKQUEUE_FAIL:
- unf_cm_event_thread_exit();
-CREAT_EVENTCENTER_FAIL:
- unf_destroy_global_event_msg();
-CREAT_GLBEVENTMSG_FAIL:
- unf_unregister_ini_transport();
-REG_INITRANSPORT_FAIL:
- unf_free_port_feature_pool();
- return UNF_RETURN_ERROR;
-}
-
-static void unf_destroy_dirty_port(void)
-{
- u32 ditry_port_num = 0;
-
- unf_show_dirty_port(false, &ditry_port_num);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Sys has %u dirty L_Port(s)", ditry_port_num);
-}
-
-void unf_common_exit(void)
-{
- unf_free_port_feature_pool();
-
- unf_destroy_dirty_port();
-
- flush_workqueue(unf_wq);
- destroy_workqueue(unf_wq);
- unf_wq = NULL;
-
- unf_cm_event_thread_exit();
-
- unf_destroy_global_event_msg();
-
- unf_deinit_cm_handle_ops();
-
- unf_port_mgmt_deinit();
-
- unf_unregister_ini_transport();
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[info]SPFC module remove succeed, memory reference count is %d",
- atomic_read(&fc_mem_ref));
-}
diff --git a/drivers/scsi/spfc/common/unf_io.c b/drivers/scsi/spfc/common/unf_io.c
deleted file mode 100644
index 5de69f8ddc6d..000000000000
--- a/drivers/scsi/spfc/common/unf_io.c
+++ /dev/null
@@ -1,1219 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_io.h"
-#include "unf_log.h"
-#include "unf_portman.h"
-#include "unf_service.h"
-#include "unf_io_abnormal.h"
-
-u32 sector_size_flag;
-
-#define UNF_GET_FCP_CTL(pkg) ((((pkg)->status) >> UNF_SHIFT_8) & 0xFF)
-#define UNF_GET_SCSI_STATUS(pkg) (((pkg)->status) & 0xFF)
-
-static u32 unf_io_success_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 up_status);
-static u32 unf_ini_error_default_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg,
- u32 up_status);
-static u32 unf_io_underflow_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 up_status);
-static u32 unf_ini_dif_error_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 up_status);
-
-struct unf_ini_error_handler_s {
- u32 ini_error_code;
- u32 (*unf_ini_error_handler)(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 up_status);
-};
-
-struct unf_ini_error_handler_s ini_error_handler_table[] = {
- {UNF_IO_SUCCESS, unf_io_success_handler},
- {UNF_IO_ABORTED, unf_ini_error_default_handler},
- {UNF_IO_FAILED, unf_ini_error_default_handler},
- {UNF_IO_ABORT_ABTS, unf_ini_error_default_handler},
- {UNF_IO_ABORT_LOGIN, unf_ini_error_default_handler},
- {UNF_IO_ABORT_REET, unf_ini_error_default_handler},
- {UNF_IO_ABORT_FAILED, unf_ini_error_default_handler},
- {UNF_IO_OUTOF_ORDER, unf_ini_error_default_handler},
- {UNF_IO_FTO, unf_ini_error_default_handler},
- {UNF_IO_LINK_FAILURE, unf_ini_error_default_handler},
- {UNF_IO_OVER_FLOW, unf_ini_error_default_handler},
- {UNF_IO_RSP_OVER, unf_ini_error_default_handler},
- {UNF_IO_LOST_FRAME, unf_ini_error_default_handler},
- {UNF_IO_UNDER_FLOW, unf_io_underflow_handler},
- {UNF_IO_HOST_PROG_ERROR, unf_ini_error_default_handler},
- {UNF_IO_SEST_PROG_ERROR, unf_ini_error_default_handler},
- {UNF_IO_INVALID_ENTRY, unf_ini_error_default_handler},
- {UNF_IO_ABORT_SEQ_NOT, unf_ini_error_default_handler},
- {UNF_IO_REJECT, unf_ini_error_default_handler},
- {UNF_IO_EDC_IN_ERROR, unf_ini_error_default_handler},
- {UNF_IO_EDC_OUT_ERROR, unf_ini_error_default_handler},
- {UNF_IO_UNINIT_KEK_ERR, unf_ini_error_default_handler},
- {UNF_IO_DEK_OUTOF_RANGE, unf_ini_error_default_handler},
- {UNF_IO_KEY_UNWRAP_ERR, unf_ini_error_default_handler},
- {UNF_IO_KEY_TAG_ERR, unf_ini_error_default_handler},
- {UNF_IO_KEY_ECC_ERR, unf_ini_error_default_handler},
- {UNF_IO_BLOCK_SIZE_ERROR, unf_ini_error_default_handler},
- {UNF_IO_ILLEGAL_CIPHER_MODE, unf_ini_error_default_handler},
- {UNF_IO_CLEAN_UP, unf_ini_error_default_handler},
- {UNF_IO_ABORTED_BY_TARGET, unf_ini_error_default_handler},
- {UNF_IO_TRANSPORT_ERROR, unf_ini_error_default_handler},
- {UNF_IO_LINK_FLASH, unf_ini_error_default_handler},
- {UNF_IO_TIMEOUT, unf_ini_error_default_handler},
- {UNF_IO_DMA_ERROR, unf_ini_error_default_handler},
- {UNF_IO_DIF_ERROR, unf_ini_dif_error_handler},
- {UNF_IO_INCOMPLETE, unf_ini_error_default_handler},
- {UNF_IO_DIF_REF_ERROR, unf_ini_dif_error_handler},
- {UNF_IO_DIF_GEN_ERROR, unf_ini_dif_error_handler},
- {UNF_IO_NO_XCHG, unf_ini_error_default_handler}
- };
-
-void unf_done_ini_xchg(struct unf_xchg *xchg)
-{
- /*
- * About I/O Done
- * 1. normal case
- * 2. Send ABTS & RCVD RSP
- * 3. Send ABTS & timer timeout
- */
- struct unf_scsi_cmnd scsi_cmd = {0};
- ulong flags = 0;
- struct unf_scsi_cmd_info *scsi_cmnd_info = NULL;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- u32 scsi_id = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- if (unlikely(!xchg->scsi_cmnd_info.scsi_cmnd))
- return;
-
- /* 1. Free RX_ID for INI SIRT: Do not care */
-
- /*
- * 2. set & check exchange state
- * *
- * for Set UP_ABORT Tag:
- * 1) L_Port destroy
- * 2) LUN reset
- * 3) Target/Session reset
- * 4) SCSI send Abort(ABTS)
- */
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- xchg->io_state |= INI_IO_STATE_DONE;
- if (unlikely(xchg->io_state &
- (INI_IO_STATE_UPABORT | INI_IO_STATE_UPSEND_ERR | INI_IO_STATE_TMF_ABORT))) {
- /*
- * a. UPABORT: scsi have send ABTS
- * --->>> do not call SCSI_Done, return directly
- * b. UPSEND_ERR: error happened duiring LLDD send SCSI_CMD
- * --->>> do not call SCSI_Done, scsi need retry
- */
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_KEVENT,
- "[event]Exchange(0x%p) Cmdsn:0x%lx upCmd:%p hottag(0x%x) with state(0x%x) has been aborted or send error",
- xchg, (ulong)xchg->cmnd_sn, xchg->scsi_cmnd_info.scsi_cmnd,
- xchg->hotpooltag, xchg->io_state);
-
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- return;
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- scsi_cmnd_info = &xchg->scsi_cmnd_info;
-
- /*
- * 3. Set:
- * scsi_cmnd;
- * cmnd_done_func;
- * cmnd up_level_done;
- * sense_buff_addr;
- * resid_length;
- * cmnd_result;
- * dif_info
- * **
- * UNF_SCSI_CMND <<-- UNF_SCSI_CMND_INFO
- */
- UNF_SET_HOST_CMND((&scsi_cmd), scsi_cmnd_info->scsi_cmnd);
- UNF_SER_CMND_DONE_FUNC((&scsi_cmd), scsi_cmnd_info->done);
- UNF_SET_UP_LEVEL_CMND_DONE_FUNC(&scsi_cmd, scsi_cmnd_info->uplevel_done);
- scsi_cmd.drv_private = xchg->lport;
- if (unlikely((UNF_SCSI_STATUS(xchg->scsi_cmnd_info.result)) & FCP_SNS_LEN_VALID_MASK)) {
- unf_save_sense_data(scsi_cmd.upper_cmnd,
- (char *)xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu,
- (int)xchg->fcp_sfs_union.fcp_rsp_entry.fcp_sense_len);
- }
- UNF_SET_RESID((&scsi_cmd), (u32)xchg->resid_len);
- UNF_SET_CMND_RESULT((&scsi_cmd), scsi_cmnd_info->result);
- memcpy(&scsi_cmd.dif_info, &xchg->dif_info, sizeof(struct dif_info));
-
- scsi_id = scsi_cmnd_info->scsi_id;
-
- UNF_DONE_SCSI_CMND((&scsi_cmd));
-
- /* 4. Update IO result CNT */
- if (likely(xchg->lport)) {
- scsi_image_table = &xchg->lport->rport_scsi_table;
- UNF_IO_RESULT_CNT(scsi_image_table, scsi_id,
- (scsi_cmnd_info->result >> UNF_SHIFT_16));
- }
-}
-
-static inline u32 unf_ini_get_sgl_entry_buf(ini_get_sgl_entry_buf ini_get_sgl,
- void *cmnd, void *driver_sgl,
- void **upper_sgl, u32 *req_index,
- u32 *index, char **buf,
- u32 *buf_len)
-{
- if (unlikely(!ini_get_sgl)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Command(0x%p) Get sgl Entry func Null.", cmnd);
-
- return UNF_RETURN_ERROR;
- }
-
- return ini_get_sgl(cmnd, driver_sgl, upper_sgl, req_index, index, buf, buf_len);
-}
-
-u32 unf_ini_get_sgl_entry(void *pkg, char **buf, u32 *buf_len)
-{
- struct unf_frame_pkg *unf_pkg = (struct unf_frame_pkg *)pkg;
- struct unf_xchg *unf_xchg = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buf, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buf_len, UNF_RETURN_ERROR);
-
- unf_xchg = (struct unf_xchg *)unf_pkg->xchg_contex;
- FC_CHECK_RETURN_VALUE(unf_xchg, UNF_RETURN_ERROR);
-
- /* Get SGL Entry buffer for INI Mode */
- ret = unf_ini_get_sgl_entry_buf(unf_xchg->scsi_cmnd_info.unf_get_sgl_entry_buf,
- unf_xchg->scsi_cmnd_info.scsi_cmnd, NULL,
- &unf_xchg->req_sgl_info.sgl,
- &unf_xchg->scsi_cmnd_info.port_id,
- &((unf_xchg->req_sgl_info).entry_index), buf, buf_len);
-
- return ret;
-}
-
-u32 unf_ini_get_dif_sgl_entry(void *pkg, char **buf, u32 *buf_len)
-{
- struct unf_frame_pkg *unf_pkg = (struct unf_frame_pkg *)pkg;
- struct unf_xchg *unf_xchg = NULL;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buf, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buf_len, UNF_RETURN_ERROR);
-
- unf_xchg = (struct unf_xchg *)unf_pkg->xchg_contex;
- FC_CHECK_RETURN_VALUE(unf_xchg, UNF_RETURN_ERROR);
-
- /* Get SGL Entry buffer for INI Mode */
- ret = unf_ini_get_sgl_entry_buf(unf_xchg->scsi_cmnd_info.unf_get_sgl_entry_buf,
- unf_xchg->scsi_cmnd_info.scsi_cmnd, NULL,
- &unf_xchg->dif_sgl_info.sgl,
- &unf_xchg->scsi_cmnd_info.port_id,
- &((unf_xchg->dif_sgl_info).entry_index), buf, buf_len);
- return ret;
-}
-
-u32 unf_get_up_level_cmnd_errcode(struct unf_ini_error_code *err_table,
- u32 err_table_count, u32 drv_err_code)
-{
- u32 loop = 0;
-
- /* fail return UNF_RETURN_ERROR,adjust by up level */
- if (unlikely(!err_table)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Error Code Table is Null, Error Code(0x%x).", drv_err_code);
-
- return (u32)UNF_SCSI_HOST(DID_ERROR);
- }
-
- for (loop = 0; loop < err_table_count; loop++) {
- if (err_table[loop].drv_errcode == drv_err_code)
- return err_table[loop].ap_errcode;
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Unsupported Ap Error code by Error Code(0x%x).", drv_err_code);
-
- return (u32)UNF_SCSI_HOST(DID_ERROR);
-}
-
-static u32 unf_ini_status_handle(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg)
-{
- u32 loop = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 up_status = 0;
-
- for (loop = 0; loop < sizeof(ini_error_handler_table) /
- sizeof(struct unf_ini_error_handler_s); loop++) {
- if (UNF_GET_LL_ERR(pkg) == ini_error_handler_table[loop].ini_error_code) {
- up_status =
- unf_get_up_level_cmnd_errcode(xchg->scsi_cmnd_info.err_code_table,
- xchg->scsi_cmnd_info.err_code_table_cout,
- UNF_GET_LL_ERR(pkg));
-
- if (ini_error_handler_table[loop].unf_ini_error_handler) {
- ret = ini_error_handler_table[loop]
- .unf_ini_error_handler(xchg, pkg, up_status);
- } else {
- /* set exchange->result ---to--->>>scsi_result */
- ret = unf_ini_error_default_handler(xchg, pkg, up_status);
- }
-
- return ret;
- }
- }
-
- up_status = unf_get_up_level_cmnd_errcode(xchg->scsi_cmnd_info.err_code_table,
- xchg->scsi_cmnd_info.err_code_table_cout,
- UNF_IO_SOFT_ERR);
-
- ret = unf_ini_error_default_handler(xchg, pkg, up_status);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Can not find com status, SID(0x%x) exchange(0x%p) com_status(0x%x) DID(0x%x) hot_pool_tag(0x%x)",
- xchg->sid, xchg, pkg->status, xchg->did, xchg->hotpooltag);
-
- return ret;
-}
-
-static void unf_analysis_response_info(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg,
- u32 *up_status)
-{
- u8 *resp_buf = NULL;
-
- /* LL_Driver use Little End, and copy RSP_INFO to COM_Driver */
- if (unlikely(pkg->unf_rsp_pload_bl.length > UNF_RESPONE_DATA_LEN)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Receive FCP response resp buffer len is invalid 0x%x",
- pkg->unf_rsp_pload_bl.length);
- return;
- }
-
- resp_buf = (u8 *)pkg->unf_rsp_pload_bl.buffer_ptr;
- if (resp_buf) {
- /* If chip use Little End, then change it to Big End */
- if ((pkg->byte_orders & UNF_BIT_3) == 0)
- unf_cpu_to_big_end(resp_buf, pkg->unf_rsp_pload_bl.length);
-
- /* Chip DAM data with Big End */
- if (resp_buf[ARRAY_INDEX_3] != UNF_FCP_TM_RSP_COMPLETE) {
- *up_status = UNF_SCSI_HOST(DID_BUS_BUSY);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%p) DID bus busy, scsi_status(0x%x)",
- xchg->lport, UNF_GET_SCSI_STATUS(pkg));
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Receive FCP response, resp buffer is NULL resp buffer len is 0x%x",
- pkg->unf_rsp_pload_bl.length);
- }
-}
-
-static void unf_analysis_sense_info(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 *up_status)
-{
- u32 length = 0;
-
- /* 4 bytes Align */
- length = MIN(SCSI_SENSE_DATA_LEN, pkg->unf_sense_pload_bl.length);
-
- if (unlikely(pkg->unf_sense_pload_bl.length > SCSI_SENSE_DATA_LEN)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[info]Receive FCP response resp buffer len is 0x%x",
- pkg->unf_sense_pload_bl.length);
- }
- /*
- * If have sense info then copy directly
- * else, the chip has been dma the data to sense buffer
- */
-
- if (length != 0 && pkg->unf_rsp_pload_bl.buffer_ptr) {
- /* has been dma to exchange buffer */
- if (unlikely(pkg->unf_rsp_pload_bl.length > UNF_RESPONE_DATA_LEN)) {
- *up_status = UNF_SCSI_HOST(DID_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Receive FCP response resp buffer len is invalid 0x%x",
- pkg->unf_rsp_pload_bl.length);
-
- return;
- }
-
- xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu = (u8 *)kmalloc(length, GFP_ATOMIC);
- if (!xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Alloc FCP sense buffer failed");
- return;
- }
-
- memcpy(xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu,
- ((u8 *)(pkg->unf_rsp_pload_bl.buffer_ptr)) +
- pkg->unf_rsp_pload_bl.length, length);
-
- xchg->fcp_sfs_union.fcp_rsp_entry.fcp_sense_len = length;
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Receive FCP response, sense buffer is NULL sense buffer len is 0x%x",
- length);
- }
-}
-
-static u32 unf_io_success_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 up_status)
-{
- u8 scsi_status = 0;
- u8 control = 0;
- u32 status = up_status;
-
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- control = UNF_GET_FCP_CTL(pkg);
- scsi_status = UNF_GET_SCSI_STATUS(pkg);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]Port(0x%p), Exchange(0x%p) Completed, Control(0x%x), Scsi Status(0x%x)",
- xchg->lport, xchg, control, scsi_status);
-
- if (control & FCP_SNS_LEN_VALID_MASK) {
- /* has sense info */
- if (scsi_status == FCP_SCSI_STATUS_GOOD)
- scsi_status = SCSI_CHECK_CONDITION;
-
- unf_analysis_sense_info(xchg, pkg, &status);
- } else {
- /*
- * When the FCP_RSP_LEN_VALID bit is set to one,
- * the content of the SCSI STATUS CODE field is not reliable
- * and shall be ignored by the application client.
- */
- if (control & FCP_RSP_LEN_VALID_MASK)
- unf_analysis_response_info(xchg, pkg, &status);
- }
-
- xchg->scsi_cmnd_info.result = status | UNF_SCSI_STATUS(scsi_status);
-
- return RETURN_OK;
-}
-
-static u32 unf_ini_error_default_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg,
- u32 up_status)
-{
- /* set exchange->result ---to--->>> scsi_cmnd->result */
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_ABNORMAL, UNF_WARN,
- "[warn]SID(0x%x) exchange(0x%p) com_status(0x%x) up_status(0x%x) DID(0x%x) hot_pool_tag(0x%x) response_len(0x%x)",
- xchg->sid, xchg, pkg->status, up_status, xchg->did,
- xchg->hotpooltag, pkg->residus_len);
-
- xchg->scsi_cmnd_info.result =
- up_status | UNF_SCSI_STATUS(UNF_GET_SCSI_STATUS(pkg));
-
- return RETURN_OK;
-}
-
-static u32 unf_ini_dif_error_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 up_status)
-{
- u8 *sense_data = NULL;
- u16 sense_code = 0;
-
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- /*
- * According to DIF scheme
- * drive set check condition(0x2) when dif error occurs,
- * and returns the values base on the upper-layer verification resule
- * Check sequence: crc,Lba,App,
- * if CRC error is found, the subsequent check is not performed
- */
- xchg->scsi_cmnd_info.result = UNF_SCSI_STATUS(SCSI_CHECK_CONDITION);
-
- sense_code = (u16)pkg->status_sub_code;
- sense_data = (u8 *)kmalloc(SCSI_SENSE_DATA_LEN, GFP_ATOMIC);
- if (!sense_data) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Alloc FCP sense buffer failed");
-
- return UNF_RETURN_ERROR;
- }
- memset(sense_data, 0, SCSI_SENSE_DATA_LEN);
- sense_data[ARRAY_INDEX_0] = SENSE_DATA_RESPONSE_CODE; /* response code:0x70 */
- sense_data[ARRAY_INDEX_2] = ILLEGAL_REQUEST; /* sense key:0x05; */
- sense_data[ARRAY_INDEX_7] = ADDITINONAL_SENSE_LEN; /* additional sense length:0x7 */
- sense_data[ARRAY_INDEX_12] = (u8)(sense_code >> UNF_SHIFT_8);
- sense_data[ARRAY_INDEX_13] = (u8)sense_code;
-
- xchg->fcp_sfs_union.fcp_rsp_entry.fcp_rsp_iu = sense_data;
- xchg->fcp_sfs_union.fcp_rsp_entry.fcp_sense_len = SCSI_SENSE_DATA_LEN;
-
- /* valid sense data length snscode[13] */
- return RETURN_OK;
-}
-
-static u32 unf_io_underflow_handler(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg, u32 up_status)
-{
- /* under flow: residlen > 0 */
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- if (xchg->fcp_cmnd.cdb[ARRAY_INDEX_0] != SCSIOPC_REPORT_LUN &&
- xchg->fcp_cmnd.cdb[ARRAY_INDEX_0] != SCSIOPC_INQUIRY) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]IO under flow: SID(0x%x) exchange(0x%p) com status(0x%x) up_status(0x%x) DID(0x%x) hot_pool_tag(0x%x) response SID(0x%x)",
- xchg->sid, xchg, pkg->status, up_status,
- xchg->did, xchg->hotpooltag, pkg->residus_len);
- }
-
- xchg->resid_len = (int)pkg->residus_len;
- (void)unf_io_success_handler(xchg, pkg, up_status);
-
- return RETURN_OK;
-}
-
-void unf_complete_cmnd(struct unf_scsi_cmnd *scsi_cmnd, u32 result_size)
-{
- /*
- * Exception during process Que_CMND
- * 1. L_Port == NULL;
- * 2. L_Port == removing;
- * 3. R_Port == NULL;
- * 4. Xchg == NULL.
- */
- FC_CHECK_RETURN_VOID((UNF_GET_CMND_DONE_FUNC(scsi_cmnd)));
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]Command(0x%p), Result(0x%x).", scsi_cmnd, result_size);
-
- UNF_SET_CMND_RESULT(scsi_cmnd, result_size);
-
- UNF_DONE_SCSI_CMND(scsi_cmnd);
-}
-
-static inline void unf_bind_xchg_scsi_cmd(struct unf_xchg *xchg,
- struct unf_scsi_cmnd *scsi_cmnd)
-{
- struct unf_scsi_cmd_info *scsi_cmnd_info = NULL;
-
- scsi_cmnd_info = &xchg->scsi_cmnd_info;
-
- /* UNF_SCSI_CMND_INFO <<-- UNF_SCSI_CMND */
- scsi_cmnd_info->err_code_table = UNF_GET_ERR_CODE_TABLE(scsi_cmnd);
- scsi_cmnd_info->err_code_table_cout = UNF_GET_ERR_CODE_TABLE_COUNT(scsi_cmnd);
- scsi_cmnd_info->done = UNF_GET_CMND_DONE_FUNC(scsi_cmnd);
- scsi_cmnd_info->scsi_cmnd = UNF_GET_HOST_CMND(scsi_cmnd);
- scsi_cmnd_info->sense_buf = (char *)UNF_GET_SENSE_BUF_ADDR(scsi_cmnd);
- scsi_cmnd_info->uplevel_done = UNF_GET_UP_LEVEL_CMND_DONE(scsi_cmnd);
- scsi_cmnd_info->unf_get_sgl_entry_buf = UNF_GET_SGL_ENTRY_BUF_FUNC(scsi_cmnd);
- scsi_cmnd_info->sgl = UNF_GET_CMND_SGL(scsi_cmnd);
- scsi_cmnd_info->time_out = scsi_cmnd->time_out;
- scsi_cmnd_info->entry_cnt = scsi_cmnd->entry_count;
- scsi_cmnd_info->port_id = (u32)scsi_cmnd->port_id;
- scsi_cmnd_info->scsi_id = UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd);
-}
-
-u32 unf_ini_scsi_completed(void *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_fcp_cmnd *fcp_cmnd = NULL;
- u32 control = 0;
- u16 xchg_tag = 0x0ffff;
- u32 ret = UNF_RETURN_ERROR;
- ulong xchg_flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- unf_lport = (struct unf_lport *)lport;
- xchg_tag = (u16)pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX];
-
- /* 1. Find Exchange Context */
- unf_xchg = unf_cm_lookup_xchg_by_tag(lport, (u16)xchg_tag);
- if (unlikely(!unf_xchg)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) can not find exchange by tag(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, xchg_tag);
-
- /* NOTE: return directly */
- return UNF_RETURN_ERROR;
- }
-
- /* 2. Consistency check */
- UNF_CHECK_ALLOCTIME_VALID(unf_lport, xchg_tag, unf_xchg,
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME],
- unf_xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME]);
-
- /* 3. Increase ref_cnt for exchange protecting */
- ret = unf_xchg_ref_inc(unf_xchg, INI_RESPONSE_DONE); /* hold */
- FC_CHECK_RETURN_VALUE((ret == RETURN_OK), UNF_RETURN_ERROR);
-
- fcp_cmnd = &unf_xchg->fcp_cmnd;
- control = fcp_cmnd->control;
- control = UNF_GET_TASK_MGMT_FLAGS(control);
-
- /* 4. Cancel timer if necessary */
- if (unf_xchg->scsi_cmnd_info.time_out != 0)
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer(unf_xchg);
-
- /* 5. process scsi TMF if necessary */
- if (control != 0) {
- unf_process_scsi_mgmt_result(pkg, unf_xchg);
- unf_xchg_ref_dec(unf_xchg, INI_RESPONSE_DONE); /* cancel hold */
-
- /* NOTE: return directly */
- return RETURN_OK;
- }
-
- /* 6. Xchg Abort state check */
- spin_lock_irqsave(&unf_xchg->xchg_state_lock, xchg_flag);
- unf_xchg->oxid = UNF_GET_OXID(pkg);
- unf_xchg->rxid = UNF_GET_RXID(pkg);
- if (INI_IO_STATE_UPABORT & unf_xchg->io_state) {
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, xchg_flag);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "[warn]Port(0x%x) find exchange(%p) state(0x%x) has been aborted",
- unf_lport->port_id, unf_xchg, unf_xchg->io_state);
-
- /* NOTE: release exchange during SCSI ABORT(ABTS) */
- unf_xchg_ref_dec(unf_xchg, INI_RESPONSE_DONE); /* cancel hold */
-
- return ret;
- }
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, xchg_flag);
-
- /*
- * 7. INI SCSI CMND Status process
- * set exchange->result ---to--->>> scsi_result
- */
- ret = unf_ini_status_handle(unf_xchg, pkg);
-
- /* 8. release exchangenecessary */
- unf_cm_free_xchg(unf_lport, unf_xchg);
-
- /* 9. dec exch ref_cnt */
- unf_xchg_ref_dec(unf_xchg, INI_RESPONSE_DONE); /* cancel hold: release resource now */
-
- return ret;
-}
-
-u32 unf_hardware_start_io(struct unf_lport *lport, struct unf_frame_pkg *pkg)
-{
- if (unlikely(!lport->low_level_func.service_op.unf_cmnd_send)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) low level send scsi function is NULL",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- return lport->low_level_func.service_op.unf_cmnd_send(lport->fc_port, pkg);
-}
-
-struct unf_rport *unf_find_rport_by_scsi_id(struct unf_lport *lport,
- struct unf_ini_error_code *err_code_table,
- u32 err_code_table_cout, u32 scsi_id, u32 *scsi_result)
-{
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- struct unf_wwpn_rport_info *wwpn_rport_info = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flags = 0;
-
- /* scsi_table -> session_table ->image_table */
- scsi_image_table = &lport->rport_scsi_table;
-
- /* 1. Scsi_Id validity check */
- if (unlikely(scsi_id >= scsi_image_table->max_scsi_id)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Input scsi_id(0x%x) bigger than max_scsi_id(0x%x).",
- scsi_id, scsi_image_table->max_scsi_id);
-
- *scsi_result = unf_get_up_level_cmnd_errcode(err_code_table, err_code_table_cout,
- UNF_IO_SOFT_ERR); /* did_soft_error */
-
- return NULL;
- }
-
- /* 2. GetR_Port_Info/R_Port: use Scsi_Id find from L_Port's
- * Rport_Scsi_Table (image table)
- */
- spin_lock_irqsave(&scsi_image_table->scsi_image_table_lock, flags);
- wwpn_rport_info = &scsi_image_table->wwn_rport_info_table[scsi_id];
- unf_rport = wwpn_rport_info->rport;
- spin_unlock_irqrestore(&scsi_image_table->scsi_image_table_lock, flags);
-
- if (unlikely(!unf_rport)) {
- *scsi_result = unf_get_up_level_cmnd_errcode(err_code_table,
- err_code_table_cout,
- UNF_IO_PORT_LOGOUT);
-
- return NULL;
- }
-
- return unf_rport;
-}
-
-static u32 unf_build_xchg_fcpcmnd(struct unf_fcp_cmnd *fcp_cmnd,
- struct unf_scsi_cmnd *scsi_cmnd)
-{
- memcpy(fcp_cmnd->cdb, &UNF_GET_FCP_CMND(scsi_cmnd), scsi_cmnd->cmnd_len);
-
- if ((fcp_cmnd->control == UNF_FCP_WR_DATA &&
- (IS_READ_COMMAND(fcp_cmnd->cdb[ARRAY_INDEX_0]))) ||
- (fcp_cmnd->control == UNF_FCP_RD_DATA &&
- (IS_WRITE_COMMAND(fcp_cmnd->cdb[ARRAY_INDEX_0])))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MINOR,
- "Scsi command direction inconsistent, CDB[ARRAY_INDEX_0](0x%x), direction(0x%x).",
- fcp_cmnd->cdb[ARRAY_INDEX_0], fcp_cmnd->control);
-
- return UNF_RETURN_ERROR;
- }
-
- memcpy(fcp_cmnd->lun, scsi_cmnd->lun_id, sizeof(fcp_cmnd->lun));
-
- unf_big_end_to_cpu((void *)fcp_cmnd->cdb, sizeof(fcp_cmnd->cdb));
- fcp_cmnd->data_length = UNF_GET_DATA_LEN(scsi_cmnd);
-
- return RETURN_OK;
-}
-
-static void unf_adjust_xchg_len(struct unf_xchg *xchg, u32 scsi_cmnd)
-{
- switch (scsi_cmnd) {
- case SCSIOPC_REQUEST_SENSE: /* requires different buffer */
- xchg->data_len = UNF_SCSI_SENSE_BUFFERSIZE;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MINOR, "Request Sense new.");
- break;
-
- case SCSIOPC_TEST_UNIT_READY:
- case SCSIOPC_RESERVE:
- case SCSIOPC_RELEASE:
- case SCSIOPC_START_STOP_UNIT:
- xchg->data_len = 0;
- break;
-
- default:
- break;
- }
-}
-
-static void unf_copy_dif_control(struct unf_dif_control_info *dif_control,
- struct unf_scsi_cmnd *scsi_cmnd)
-{
- dif_control->fcp_dl = scsi_cmnd->dif_control.fcp_dl;
- dif_control->protect_opcode = scsi_cmnd->dif_control.protect_opcode;
- dif_control->start_lba = scsi_cmnd->dif_control.start_lba;
- dif_control->app_tag = scsi_cmnd->dif_control.app_tag;
-
- dif_control->flags = scsi_cmnd->dif_control.flags;
- dif_control->dif_sge_count = scsi_cmnd->dif_control.dif_sge_count;
- dif_control->dif_sgl = scsi_cmnd->dif_control.dif_sgl;
-}
-
-static void unf_adjust_dif_pci_transfer_len(struct unf_xchg *xchg, u32 direction)
-{
- struct unf_dif_control_info *dif_control = NULL;
- u32 sector_size = 0;
-
- dif_control = &xchg->dif_control;
-
- if (dif_control->protect_opcode == UNF_DIF_ACTION_NONE)
- return;
- if ((dif_control->flags & UNF_DIF_SECTSIZE_4KB) == 0)
- sector_size = SECTOR_SIZE_512;
- else
- sector_size = SECTOR_SIZE_4096;
- switch (dif_control->protect_opcode & UNF_DIF_ACTION_MASK) {
- case UNF_DIF_ACTION_INSERT:
- if (direction == DMA_TO_DEVICE) {
- /* write IO,insert,Indicates that data with DIF is
- * transmitted over the link.
- */
- dif_control->fcp_dl = xchg->data_len +
- UNF_CAL_BLOCK_CNT(xchg->data_len, sector_size) * UNF_DIF_AREA_SIZE;
- } else {
- /* read IO,insert,Indicates that the internal DIf is
- * carried, and the link does not carry the DIf.
- */
- dif_control->fcp_dl = xchg->data_len;
- }
- break;
-
- case UNF_DIF_ACTION_VERIFY_AND_DELETE:
- if (direction == DMA_TO_DEVICE) {
- /* write IO,Delete,Indicates that the internal DIf is
- * carried, and the link does not carry the DIf.
- */
- dif_control->fcp_dl = xchg->data_len;
- } else {
- /* read IO,Delete,Indicates that data with DIF is
- * carried on the link and does not contain DIF on
- * internal.
- */
- dif_control->fcp_dl = xchg->data_len +
- UNF_CAL_BLOCK_CNT(xchg->data_len, sector_size) * UNF_DIF_AREA_SIZE;
- }
- break;
-
- case UNF_DIF_ACTION_VERIFY_AND_FORWARD:
- dif_control->fcp_dl = xchg->data_len +
- UNF_CAL_BLOCK_CNT(xchg->data_len, sector_size) * UNF_DIF_AREA_SIZE;
- break;
-
- default:
- dif_control->fcp_dl = xchg->data_len;
- break;
- }
-
- xchg->fcp_cmnd.data_length = dif_control->fcp_dl;
-}
-
-static void unf_get_dma_direction(struct unf_fcp_cmnd *fcp_cmnd,
- struct unf_scsi_cmnd *scsi_cmnd)
-{
- if (UNF_GET_DATA_DIRECTION(scsi_cmnd) == DMA_TO_DEVICE) {
- fcp_cmnd->control = UNF_FCP_WR_DATA;
- } else if (UNF_GET_DATA_DIRECTION(scsi_cmnd) == DMA_FROM_DEVICE) {
- fcp_cmnd->control = UNF_FCP_RD_DATA;
- } else {
- /* DMA Direction None */
- fcp_cmnd->control = 0;
- }
-}
-
-static int unf_save_scsi_cmnd_to_xchg(struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_xchg *xchg,
- struct unf_scsi_cmnd *scsi_cmnd)
-{
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- struct unf_xchg *unf_xchg = xchg;
- u32 result_size = 0;
-
- scsi_cmnd->driver_scribble = (void *)unf_xchg->start_jif;
- unf_xchg->rport = unf_rport;
- unf_xchg->rport_bind_jifs = unf_rport->rport_alloc_jifs;
-
- /* Build Xchg SCSI_CMND info */
- unf_bind_xchg_scsi_cmd(unf_xchg, scsi_cmnd);
-
- unf_xchg->data_len = UNF_GET_DATA_LEN(scsi_cmnd);
- unf_xchg->data_direction = UNF_GET_DATA_DIRECTION(scsi_cmnd);
- unf_xchg->sid = unf_lport->nport_id;
- unf_xchg->did = unf_rport->nport_id;
- unf_xchg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] = unf_rport->rport_index;
- unf_xchg->world_id = scsi_cmnd->world_id;
- unf_xchg->cmnd_sn = scsi_cmnd->cmnd_sn;
- unf_xchg->pinitiator = scsi_cmnd->pinitiator;
- unf_xchg->scsi_id = scsi_cmnd->scsi_id;
- if (scsi_cmnd->qos_level == UNF_QOS_LEVEL_DEFAULT)
- unf_xchg->qos_level = unf_rport->qos_level;
- else
- unf_xchg->qos_level = scsi_cmnd->qos_level;
-
- unf_get_dma_direction(&unf_xchg->fcp_cmnd, scsi_cmnd);
- result_size = unf_build_xchg_fcpcmnd(&unf_xchg->fcp_cmnd, scsi_cmnd);
- if (unlikely(result_size != RETURN_OK))
- return UNF_RETURN_ERROR;
-
- unf_adjust_xchg_len(unf_xchg, UNF_GET_FCP_CMND(scsi_cmnd));
-
- unf_adjust_xchg_len(unf_xchg, UNF_GET_FCP_CMND(scsi_cmnd));
-
- /* Dif (control) info */
- unf_copy_dif_control(&unf_xchg->dif_control, scsi_cmnd);
- memcpy(&unf_xchg->dif_info, &scsi_cmnd->dif_info, sizeof(struct dif_info));
- unf_adjust_dif_pci_transfer_len(unf_xchg, UNF_GET_DATA_DIRECTION(scsi_cmnd));
-
- /* single sgl info */
- if (unf_xchg->data_direction != DMA_NONE && UNF_GET_CMND_SGL(scsi_cmnd)) {
- unf_xchg->req_sgl_info.sgl = UNF_GET_CMND_SGL(scsi_cmnd);
- unf_xchg->req_sgl_info.sgl_start = unf_xchg->req_sgl_info.sgl;
- /* Save the sgl header for easy
- * location and printing.
- */
- unf_xchg->req_sgl_info.req_index = 0;
- unf_xchg->req_sgl_info.entry_index = 0;
- }
-
- if (scsi_cmnd->dif_control.dif_sgl) {
- unf_xchg->dif_sgl_info.sgl = UNF_INI_GET_DIF_SGL(scsi_cmnd);
- unf_xchg->dif_sgl_info.entry_index = 0;
- unf_xchg->dif_sgl_info.req_index = 0;
- unf_xchg->dif_sgl_info.sgl_start = unf_xchg->dif_sgl_info.sgl;
- }
-
- return RETURN_OK;
-}
-
-static int unf_send_fcpcmnd(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
-#define UNF_MAX_PENDING_IO_CNT 3
- struct unf_scsi_cmd_info *scsi_cmnd_info = NULL;
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- struct unf_xchg *unf_xchg = xchg;
- struct unf_frame_pkg pkg = {0};
- u32 result_size = 0;
- ulong flags = 0;
-
- memcpy(&pkg.dif_control, &unf_xchg->dif_control, sizeof(struct unf_dif_control_info));
- pkg.dif_control.fcp_dl = unf_xchg->dif_control.fcp_dl;
- pkg.transfer_len = unf_xchg->data_len; /* Pcie data transfer length */
- pkg.xchg_contex = unf_xchg;
- pkg.qos_level = unf_xchg->qos_level;
- scsi_cmnd_info = &xchg->scsi_cmnd_info;
- pkg.entry_count = unf_xchg->scsi_cmnd_info.entry_cnt;
- if (unf_xchg->data_direction == DMA_NONE || !scsi_cmnd_info->sgl)
- pkg.entry_count = 0;
-
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- unf_xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME];
- pkg.private_data[PKG_PRIVATE_XCHG_VP_INDEX] = unf_lport->vp_index;
- pkg.private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] = unf_rport->rport_index;
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = unf_xchg->hotpooltag;
-
- unf_select_sq(unf_xchg, &pkg);
- pkg.fcp_cmnd = &unf_xchg->fcp_cmnd;
- pkg.frame_head.csctl_sid = unf_lport->nport_id;
- pkg.frame_head.rctl_did = unf_rport->nport_id;
- pkg.upper_cmd = unf_xchg->scsi_cmnd_info.scsi_cmnd;
-
- /* exch->fcp_rsp_id --->>> pkg->buffer_ptr */
- pkg.frame_head.oxid_rxid = ((u32)unf_xchg->oxid << (u32)UNF_SHIFT_16 | unf_xchg->rxid);
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_INFO,
- "[info]LPort (0x%p), Nport ID(0x%x) RPort ID(0x%x) direction(0x%x) magic number(0x%x) IO to entry count(0x%x) hottag(0x%x)",
- unf_lport, unf_lport->nport_id, unf_rport->nport_id,
- xchg->data_direction, pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME],
- pkg.entry_count, unf_xchg->hotpooltag);
-
- atomic_inc(&unf_rport->pending_io_cnt);
- if (unf_rport->tape_support_needed &&
- (atomic_read(&unf_rport->pending_io_cnt) <= UNF_MAX_PENDING_IO_CNT)) {
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- unf_xchg->io_state |= INI_IO_STATE_REC_TIMEOUT_WAIT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- scsi_cmnd_info->abort_time_out = scsi_cmnd_info->time_out;
- scsi_cmnd_info->time_out = UNF_REC_TOV;
- }
- /* 3. add INI I/O timer if necessary */
- if (scsi_cmnd_info->time_out != 0) {
- /* I/O inner timer, do not used at this time */
- unf_lport->xchg_mgr_temp.unf_xchg_add_timer(unf_xchg,
- scsi_cmnd_info->time_out, UNF_TIMER_TYPE_REQ_IO);
- }
-
- /* 4. R_Port state check */
- if (unlikely(unf_rport->lport_ini_state != UNF_PORT_STATE_LINKUP ||
- unf_rport->rp_state > UNF_RPORT_ST_READY)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[info]Port(0x%x) RPort(0x%p) NPortId(0x%x) inistate(0x%x): RPort state(0x%x) pUpperCmd(0x%p) is not ready",
- unf_lport->port_id, unf_rport, unf_rport->nport_id,
- unf_rport->lport_ini_state, unf_rport->rp_state, pkg.upper_cmd);
-
- result_size = unf_get_up_level_cmnd_errcode(scsi_cmnd_info->err_code_table,
- scsi_cmnd_info->err_code_table_cout,
- UNF_IO_INCOMPLETE);
- scsi_cmnd_info->result = result_size;
-
- if (scsi_cmnd_info->time_out != 0)
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer(unf_xchg);
-
- unf_cm_free_xchg(unf_lport, unf_xchg);
-
- /* DID_IMM_RETRY */
- return RETURN_OK;
- } else if (unf_rport->rp_state < UNF_RPORT_ST_READY) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[info]Port(0x%x) RPort(0x%p) NPortId(0x%x) inistate(0x%x): RPort state(0x%x) pUpperCmd(0x%p) is not ready",
- unf_lport->port_id, unf_rport, unf_rport->nport_id,
- unf_rport->lport_ini_state, unf_rport->rp_state, pkg.upper_cmd);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- unf_xchg->io_state |= INI_IO_STATE_UPSEND_ERR; /* need retry */
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- if (unlikely(scsi_cmnd_info->time_out != 0))
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)unf_xchg);
-
- /* Host busy & need scsi retry */
- return UNF_RETURN_ERROR;
- }
-
- /* 5. send scsi_cmnd to FC_LL Driver */
- if (unf_hardware_start_io(unf_lport, &pkg) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port (0x%x) pUpperCmd(0x%p) Hardware Send IO failed.",
- unf_lport->port_id, pkg.upper_cmd);
-
- unf_release_esgls(unf_xchg);
-
- result_size = unf_get_up_level_cmnd_errcode(scsi_cmnd_info->err_code_table,
- scsi_cmnd_info->err_code_table_cout,
- UNF_IO_INCOMPLETE);
- scsi_cmnd_info->result = result_size;
-
- if (scsi_cmnd_info->time_out != 0)
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer(unf_xchg);
-
- unf_cm_free_xchg(unf_lport, unf_xchg);
-
- /* SCSI_DONE */
- return RETURN_OK;
- }
-
- return RETURN_OK;
-}
-
-int unf_prefer_to_send_scsi_cmnd(struct unf_xchg *xchg)
-{
- /*
- * About INI_IO_STATE_DRABORT:
- * 1. Set ABORT tag: Clean L_Port/V_Port Link Down I/O
- * with: INI_busy_list, delay_list, delay_transfer_list, wait_list
- * *
- * 2. Set ABORT tag: for target session:
- * with: INI_busy_list, delay_list, delay_transfer_list, wait_list
- * a. R_Port remove
- * b. Send PLOGI_ACC callback
- * c. RCVD PLOGI
- * d. RCVD LOGO
- * *
- * 3. if set ABORT: prevent send scsi_cmnd to target
- */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- int ret = RETURN_OK;
- ulong flags = 0;
-
- unf_lport = xchg->lport;
-
- unf_rport = xchg->rport;
- if (unlikely(!unf_lport || !unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%p) or RPort(0x%p) is NULL", unf_lport, unf_rport);
-
- /* if happened (never happen): need retry */
- return UNF_RETURN_ERROR;
- }
-
- /* 1. inc ref_cnt to protect exchange */
- ret = (int)unf_xchg_ref_inc(xchg, INI_SEND_CMND);
- if (unlikely(ret != RETURN_OK)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) exhg(%p) exception ref(%d) ", unf_lport->port_id,
- xchg, atomic_read(&xchg->ref_cnt));
- /* exchange exception, need retry */
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- xchg->io_state |= INI_IO_STATE_UPSEND_ERR;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- /* INI_IO_STATE_UPSEND_ERR: Host busy --->>> need retry */
- return UNF_RETURN_ERROR;
- }
-
- /* 2. Xchg Abort state check: Free EXCH if necessary */
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if (unlikely((xchg->io_state & INI_IO_STATE_UPABORT) ||
- (xchg->io_state & INI_IO_STATE_DRABORT))) {
- /* Prevent to send: UP_ABORT/DRV_ABORT */
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- xchg->scsi_cmnd_info.result = UNF_SCSI_HOST(DID_IMM_RETRY);
- ret = RETURN_OK;
-
- unf_xchg_ref_dec(xchg, INI_SEND_CMND);
- unf_cm_free_xchg(unf_lport, xchg);
-
- /*
- * Release exchange & return directly:
- * 1. FC LLDD rcvd ABTS before scsi_cmnd: do nothing
- * 2. INI_IO_STATE_UPABORT/INI_IO_STATE_DRABORT: discard this
- * cmnd directly
- */
- return ret;
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- /* 3. Send FCP_CMND to FC_LL Driver */
- ret = unf_send_fcpcmnd(unf_lport, unf_rport, xchg);
- if (unlikely(ret != RETURN_OK)) {
- /* exchange exception, need retry */
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send exhg(%p) hottag(0x%x) to Rport(%p) NPortID(0x%x) state(0x%x) scsi_id(0x%x) failed",
- unf_lport->port_id, xchg, xchg->hotpooltag, unf_rport,
- unf_rport->nport_id, unf_rport->rp_state, unf_rport->scsi_id);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
-
- xchg->io_state |= INI_IO_STATE_UPSEND_ERR;
- /* need retry */
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- /* INI_IO_STATE_UPSEND_ERR: Host busy --->>> need retry */
- unf_cm_free_xchg(unf_lport, xchg);
- }
-
- /* 4. dec ref_cnt */
- unf_xchg_ref_dec(xchg, INI_SEND_CMND);
-
- return ret;
-}
-
-struct unf_lport *unf_find_lport_by_scsi_cmd(struct unf_scsi_cmnd *scsi_cmnd)
-{
- struct unf_lport *unf_lport = NULL;
-
- /* cmd -->> L_Port */
- unf_lport = (struct unf_lport *)UNF_GET_HOST_PORT_BY_CMND(scsi_cmnd);
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Find Port by scsi_cmnd(0x%p) failed", scsi_cmnd);
-
- /* cmnd -->> scsi_host_id -->> L_Port */
- unf_lport = unf_find_lport_by_scsi_hostid(UNF_GET_SCSI_HOST_ID_BY_CMND(scsi_cmnd));
- }
-
- return unf_lport;
-}
-
-int unf_cm_queue_command(struct unf_scsi_cmnd *scsi_cmnd)
-{
- /* SCSI Command --->>> FC FCP Command */
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- u32 cmnd_result = 0;
- int ret = RETURN_OK;
- ulong flags = 0;
- u32 scsi_id = 0;
- u32 exhg_mgr_type = UNF_XCHG_MGR_TYPE_RANDOM;
-
- /* 1. Get L_Port */
- unf_lport = unf_find_lport_by_scsi_cmd(scsi_cmnd);
-
- /*
- * corresponds to the insertion or removal scenario or the remove card
- * scenario. This method is used to search for LPort information based
- * on SCSI_HOST_ID. The Slave alloc is not invoked when LUNs are not
- * scanned. Therefore, the Lport cannot be obtained. You need to obtain
- * the Lport from the Lport linked list.
- * *
- * FC After Link Up, the first SCSI command is inquiry.
- * Before inquiry, SCSI delivers slave_alloc.
- */
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Find Port by scsi cmd(0x%p) failed", scsi_cmnd);
-
- /* find from ini_error_code_table1 */
- cmnd_result = unf_get_up_level_cmnd_errcode(scsi_cmnd->err_code_table,
- scsi_cmnd->err_code_table_cout,
- UNF_IO_NO_LPORT);
-
- /* DID_NOT_CONNECT & SCSI_DONE & RETURN_OK(0) & I/O error */
- unf_complete_cmnd(scsi_cmnd, cmnd_result);
- return RETURN_OK;
- }
-
- /* Get Local SCSI_Image_table & SCSI_ID */
- scsi_image_table = &unf_lport->rport_scsi_table;
- scsi_id = scsi_cmnd->scsi_id;
-
- /* 2. L_Port State check */
- if (unlikely(unf_lport->port_removing || unf_lport->pcie_link_down)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) is removing(%d) or pcielinkdown(%d) and return with scsi_id(0x%x)",
- unf_lport->port_id, unf_lport->port_removing,
- unf_lport->pcie_link_down, UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd));
-
- cmnd_result = unf_get_up_level_cmnd_errcode(scsi_cmnd->err_code_table,
- scsi_cmnd->err_code_table_cout,
- UNF_IO_NO_LPORT);
-
- UNF_IO_RESULT_CNT(scsi_image_table, scsi_id, (cmnd_result >> UNF_SHIFT_16));
-
- /* DID_NOT_CONNECT & SCSI_DONE & RETURN_OK(0) & I/O error */
- unf_complete_cmnd(scsi_cmnd, cmnd_result);
- return RETURN_OK;
- }
-
- /* 3. Get R_Port */
- unf_rport = unf_find_rport_by_scsi_id(unf_lport, scsi_cmnd->err_code_table,
- scsi_cmnd->err_code_table_cout,
- UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd), &cmnd_result);
- if (unlikely(!unf_rport)) {
- /* never happen: do not care */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) find RPort by scsi_id(0x%x) failed",
- unf_lport->port_id, UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd));
-
- UNF_IO_RESULT_CNT(scsi_image_table, scsi_id, (cmnd_result >> UNF_SHIFT_16));
-
- /* DID_NOT_CONNECT/DID_SOFT_ERROR & SCSI_DONE & RETURN_OK(0) &
- * I/O error
- */
- unf_complete_cmnd(scsi_cmnd, cmnd_result);
- return RETURN_OK;
- }
-
- /* 4. Can't get exchange & return host busy, retry by uplevel */
- unf_xchg = (struct unf_xchg *)unf_cm_get_free_xchg(unf_lport,
- exhg_mgr_type << UNF_SHIFT_16 | UNF_XCHG_TYPE_INI);
- if (unlikely(!unf_xchg)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[err]Port(0x%x) get free exchange for INI IO(0x%x) failed",
- unf_lport->port_id, UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd));
-
- /* NOTE: need scsi retry */
- return UNF_RETURN_ERROR;
- }
-
- unf_xchg->scsi_cmnd_info.result = UNF_SCSI_HOST(DID_ERROR);
-
- /* 5. Save the SCSI CMND information in advance. */
- ret = unf_save_scsi_cmnd_to_xchg(unf_lport, unf_rport, unf_xchg, scsi_cmnd);
- if (unlikely(ret != RETURN_OK)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[err]Port(0x%x) save scsi_cmnd info(0x%x) to exchange failed",
- unf_lport->port_id, UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd));
-
- spin_lock_irqsave(&unf_xchg->xchg_state_lock, flags);
- unf_xchg->io_state |= INI_IO_STATE_UPSEND_ERR;
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flags);
-
- /* INI_IO_STATE_UPSEND_ERR: Don't Do SCSI_DONE, need retry I/O */
- unf_cm_free_xchg(unf_lport, unf_xchg);
-
- /* NOTE: need scsi retry */
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]Get exchange(0x%p) hottag(0x%x) for Pcmd:%p,Cmdsn:0x%lx,WorldId:%d",
- unf_xchg, unf_xchg->hotpooltag, scsi_cmnd->upper_cmnd,
- (ulong)scsi_cmnd->cmnd_sn, scsi_cmnd->world_id);
- /* 6. Send SCSI CMND */
- ret = unf_prefer_to_send_scsi_cmnd(unf_xchg);
-
- return ret;
-}
diff --git a/drivers/scsi/spfc/common/unf_io.h b/drivers/scsi/spfc/common/unf_io.h
deleted file mode 100644
index d8e50eb8035e..000000000000
--- a/drivers/scsi/spfc/common/unf_io.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_IO_H
-#define UNF_IO_H
-
-#include "unf_type.h"
-#include "unf_scsi_common.h"
-#include "unf_exchg.h"
-#include "unf_rport.h"
-
-#define UNF_MAX_TARGET_NUMBER 2048
-#define UNF_DEFAULT_MAX_LUN 0xFFFF
-#define UNF_MAX_DMA_SEGS 0x400
-#define UNF_MAX_SCSI_CMND_LEN 16
-#define UNF_MAX_BUS_CHANNEL 0
-#define UNF_DMA_BOUNDARY 0xffffffffffffffff
-#define UNF_MAX_CMND_PER_LUN 64 /* LUN max command */
-#define UNF_CHECK_LUN_ID_MATCH(lun_id, raw_lun_id, scsi_id, xchg) \
- (((lun_id) == (raw_lun_id) || (lun_id) == INVALID_VALUE64) && \
- ((scsi_id) == (xchg)->scsi_id))
-
-#define NO_SENSE 0x00
-#define RECOVERED_ERROR 0x01
-#define NOT_READY 0x02
-#define MEDIUM_ERROR 0x03
-#define HARDWARE_ERROR 0x04
-#define ILLEGAL_REQUEST 0x05
-#define UNIT_ATTENTION 0x06
-#define DATA_PROTECT 0x07
-#define BLANK_CHECK 0x08
-#define COPY_ABORTED 0x0a
-#define ABORTED_COMMAND 0x0b
-#define VOLUME_OVERFLOW 0x0d
-#define MISCOMPARE 0x0e
-
-#define SENSE_DATA_RESPONSE_CODE 0x70
-#define ADDITINONAL_SENSE_LEN 0x7
-
-extern u32 sector_size_flag;
-
-#define UNF_GET_SCSI_HOST_ID_BY_CMND(cmd) ((cmd)->scsi_host_id)
-#define UNF_GET_SCSI_ID_BY_CMND(cmd) ((cmd)->scsi_id)
-#define UNF_GET_HOST_PORT_BY_CMND(cmd) ((cmd)->drv_private)
-#define UNF_GET_FCP_CMND(cmd) ((cmd)->pcmnd[ARRAY_INDEX_0])
-#define UNF_GET_DATA_LEN(cmd) ((cmd)->transfer_len)
-#define UNF_GET_DATA_DIRECTION(cmd) ((cmd)->data_direction)
-
-#define UNF_GET_HOST_CMND(cmd) ((cmd)->upper_cmnd)
-#define UNF_GET_CMND_DONE_FUNC(cmd) ((cmd)->done)
-#define UNF_GET_UP_LEVEL_CMND_DONE(cmd) ((cmd)->uplevel_done)
-#define UNF_GET_SGL_ENTRY_BUF_FUNC(cmd) ((cmd)->unf_ini_get_sgl_entry)
-#define UNF_GET_SENSE_BUF_ADDR(cmd) ((cmd)->sense_buf)
-#define UNF_GET_ERR_CODE_TABLE(cmd) ((cmd)->err_code_table)
-#define UNF_GET_ERR_CODE_TABLE_COUNT(cmd) ((cmd)->err_code_table_cout)
-
-#define UNF_SET_HOST_CMND(cmd, host_cmd) ((cmd)->upper_cmnd = (host_cmd))
-#define UNF_SER_CMND_DONE_FUNC(cmd, pfn) ((cmd)->done = (pfn))
-#define UNF_SET_UP_LEVEL_CMND_DONE_FUNC(cmd, pfn) ((cmd)->uplevel_done = (pfn))
-
-#define UNF_SET_RESID(cmd, uiresid) ((cmd)->resid = (uiresid))
-#define UNF_SET_CMND_RESULT(cmd, uiresult) ((cmd)->result = ((int)(uiresult)))
-
-#define UNF_DONE_SCSI_CMND(cmd) ((cmd)->done(cmd))
-
-#define UNF_GET_CMND_SGL(cmd) ((cmd)->sgl)
-#define UNF_INI_GET_DIF_SGL(cmd) ((cmd)->dif_control.dif_sgl)
-
-u32 unf_ini_scsi_completed(void *lport, struct unf_frame_pkg *pkg);
-u32 unf_ini_get_sgl_entry(void *pkg, char **buf, u32 *buf_len);
-u32 unf_ini_get_dif_sgl_entry(void *pkg, char **buf, u32 *buf_len);
-void unf_complete_cmnd(struct unf_scsi_cmnd *scsi_cmnd, u32 result_size);
-void unf_done_ini_xchg(struct unf_xchg *xchg);
-u32 unf_tmf_timeout_recovery_special(void *rport, void *xchg);
-u32 unf_tmf_timeout_recovery_default(void *rport, void *xchg);
-void unf_abts_timeout_recovery_default(void *rport, void *xchg);
-int unf_cm_queue_command(struct unf_scsi_cmnd *scsi_cmnd);
-int unf_cm_eh_abort_handler(struct unf_scsi_cmnd *scsi_cmnd);
-int unf_cm_eh_device_reset_handler(struct unf_scsi_cmnd *scsi_cmnd);
-int unf_cm_target_reset_handler(struct unf_scsi_cmnd *scsi_cmnd);
-int unf_cm_bus_reset_handler(struct unf_scsi_cmnd *scsi_cmnd);
-int unf_cm_virtual_reset_handler(struct unf_scsi_cmnd *scsi_cmnd);
-struct unf_rport *unf_find_rport_by_scsi_id(struct unf_lport *lport,
- struct unf_ini_error_code *errcode_table,
- u32 errcode_table_count,
- u32 scsi_id, u32 *scsi_result);
-u32 UNF_IOExchgDelayProcess(struct unf_lport *lport, struct unf_xchg *xchg);
-struct unf_lport *unf_find_lport_by_scsi_cmd(struct unf_scsi_cmnd *scsi_cmnd);
-int unf_send_scsi_mgmt_cmnd(struct unf_xchg *xchg, struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_scsi_cmnd *scsi_cmnd,
- enum unf_task_mgmt_cmd task_mgnt_cmd_type);
-void unf_tmf_abnormal_recovery(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_io_abnormal.c b/drivers/scsi/spfc/common/unf_io_abnormal.c
deleted file mode 100644
index 4e268ac026ca..000000000000
--- a/drivers/scsi/spfc/common/unf_io_abnormal.c
+++ /dev/null
@@ -1,986 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_io_abnormal.h"
-#include "unf_log.h"
-#include "unf_scsi_common.h"
-#include "unf_rport.h"
-#include "unf_io.h"
-#include "unf_portman.h"
-#include "unf_service.h"
-
-static int unf_send_abts_success(struct unf_lport *lport, struct unf_xchg *xchg,
- struct unf_scsi_cmnd *scsi_cmnd,
- u32 time_out_value)
-{
- bool need_wait_marker = true;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- u32 scsi_id = 0;
- u32 return_value = 0;
- ulong xchg_flag = 0;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- need_wait_marker = (xchg->abts_state & MARKER_STS_RECEIVED) ? false : true;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- if (need_wait_marker) {
- if (down_timeout(&xchg->task_sema, (s64)msecs_to_jiffies(time_out_value))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) recv abts marker timeout,Exch(0x%p) OX_ID(0x%x 0x%x) RX_ID(0x%x)",
- lport->port_id, xchg, xchg->oxid,
- xchg->hotpooltag, xchg->rxid);
-
- /* Cancel abts rsp timer when sema timeout */
- lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
-
- /* Cnacel the flag of INI_IO_STATE_UPABORT and process
- * the io in TMF
- */
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- xchg->io_state &= ~INI_IO_STATE_UPABORT;
- xchg->io_state |= INI_IO_STATE_TMF_ABORT;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- return UNF_SCSI_ABORT_FAIL;
- }
- } else {
- xchg->ucode_abts_state = UNF_IO_SUCCESS;
- }
-
- scsi_image_table = &lport->rport_scsi_table;
- scsi_id = scsi_cmnd->scsi_id;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- if (xchg->ucode_abts_state == UNF_IO_SUCCESS ||
- xchg->scsi_cmnd_info.result == UNF_IO_ABORT_PORT_REMOVING) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Port(0x%x) Send ABTS succeed and recv marker Exch(0x%p) OX_ID(0x%x) RX_ID(0x%x) marker status(0x%x)",
- lport->port_id, xchg, xchg->oxid, xchg->rxid, xchg->ucode_abts_state);
- return_value = DID_RESET;
- UNF_IO_RESULT_CNT(scsi_image_table, scsi_id, return_value);
- unf_complete_cmnd(scsi_cmnd, DID_RESET << UNF_SHIFT_16);
- return UNF_SCSI_ABORT_SUCCESS;
- }
-
- xchg->io_state &= ~INI_IO_STATE_UPABORT;
- xchg->io_state |= INI_IO_STATE_TMF_ABORT;
-
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- /* Cancel abts rsp timer when sema timeout */
- lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ABTS failed. Exch(0x%p) oxid(0x%x) hot_tag(0x%x) ret(0x%x) xchg->io_state (0x%x)",
- lport->port_id, xchg, xchg->oxid, xchg->hotpooltag,
- xchg->scsi_cmnd_info.result, xchg->io_state);
-
- /* return fail and then enter TMF */
- return UNF_SCSI_ABORT_FAIL;
-}
-
-static int unf_ini_abort_cmnd(struct unf_lport *lport, struct unf_xchg *xchg,
- struct unf_scsi_cmnd *scsi_cmnd)
-{
- /*
- * About INI_IO_STATE_UPABORT:
- * *
- * 1. Check: L_Port destroy
- * 2. Check: I/O XCHG timeout
- * 3. Set ABORT: send ABTS
- * 4. Set ABORT: LUN reset
- * 5. Set ABORT: Target reset
- * 6. Check: Prevent to send I/O to target
- * (unf_prefer_to_send_scsi_cmnd)
- * 7. Check: Done INI XCHG --->>> do not call scsi_done, return directly
- * 8. Check: INI SCSI Complete --->>> do not call scsi_done, return
- * directly
- */
-#define UNF_RPORT_NOTREADY_WAIT_SEM_TIMEOUT (2000)
-
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong rport_flag = 0;
- ulong xchg_flag = 0;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- u32 scsi_id = 0;
- u32 time_out_value = (u32)UNF_WAIT_SEM_TIMEOUT;
- u32 return_value = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_SCSI_ABORT_FAIL);
- unf_lport = lport;
-
- /* 1. Xchg State Set: INI_IO_STATE_UPABORT */
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- xchg->io_state |= INI_IO_STATE_UPABORT;
- unf_rport = xchg->rport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- /* 2. R_Port check */
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ABTS but no RPort, OX_ID(0x%x) RX_ID(0x%x)",
- unf_lport->port_id, xchg->oxid, xchg->rxid);
-
- return UNF_SCSI_ABORT_SUCCESS;
- }
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, rport_flag);
- if (unlikely(unf_rport->rp_state != UNF_RPORT_ST_READY)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) find RPort's state(0x%x) is not ready but send ABTS also, exchange(0x%p) tag(0x%x)",
- unf_lport->port_id, unf_rport->rp_state, xchg, xchg->hotpooltag);
-
- /*
- * Important: Send ABTS also & update timer
- * Purpose: only used for release chip (uCode) resource,
- * continue
- */
- time_out_value = UNF_RPORT_NOTREADY_WAIT_SEM_TIMEOUT;
- }
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, rport_flag);
-
- /* 3. L_Port State check */
- if (unlikely(unf_lport->port_removing)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) is removing", unf_lport->port_id);
-
- xchg->io_state &= ~INI_IO_STATE_UPABORT;
-
- return UNF_SCSI_ABORT_FAIL;
- }
-
- scsi_image_table = &unf_lport->rport_scsi_table;
- scsi_id = scsi_cmnd->scsi_id;
-
- /* If pcie linkdown, complete this io and flush all io */
- if (unlikely(unf_lport->pcie_link_down)) {
- return_value = DID_RESET;
- UNF_IO_RESULT_CNT(scsi_image_table, scsi_id, return_value);
- unf_complete_cmnd(scsi_cmnd, DID_RESET << UNF_SHIFT_16);
- unf_free_lport_all_xchg(lport);
- return UNF_SCSI_ABORT_SUCCESS;
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_KEVENT,
- "[abort]Port(0x%x) Exchg(0x%p) delay(%llu) SID(0x%x) DID(0x%x) wwpn(0x%llx) hottag(0x%x) scsi_id(0x%x) lun_id(0x%x) cmdsn(0x%llx) Ini:%p",
- unf_lport->port_id, xchg,
- (u64)jiffies_to_msecs(jiffies) - (u64)jiffies_to_msecs(xchg->alloc_jif),
- xchg->sid, xchg->did, unf_rport->port_name, xchg->hotpooltag,
- scsi_cmnd->scsi_id, (u32)scsi_cmnd->raw_lun_id, scsi_cmnd->cmnd_sn,
- scsi_cmnd->pinitiator);
-
- /* Init abts marker semaphore */
- sema_init(&xchg->task_sema, 0);
-
- if (xchg->scsi_cmnd_info.time_out != 0)
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer(xchg);
-
- lport->xchg_mgr_temp.unf_xchg_add_timer((void *)xchg, (ulong)UNF_WAIT_ABTS_RSP_TIMEOUT,
- UNF_TIMER_TYPE_INI_ABTS);
-
- /* 4. Send INI ABTS CMND */
- if (unf_send_abts(unf_lport, xchg) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) Send ABTS failed. Exch(0x%p) hottag(0x%x)",
- unf_lport->port_id, xchg, xchg->hotpooltag);
-
- lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, xchg_flag);
- xchg->io_state &= ~INI_IO_STATE_UPABORT;
- xchg->io_state |= INI_IO_STATE_TMF_ABORT;
-
- spin_unlock_irqrestore(&xchg->xchg_state_lock, xchg_flag);
-
- return UNF_SCSI_ABORT_FAIL;
- }
-
- return unf_send_abts_success(unf_lport, xchg, scsi_cmnd, time_out_value);
-}
-
-static void unf_flush_ini_resp_que(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- if (lport->low_level_func.service_op.unf_flush_ini_resp_que)
- (void)lport->low_level_func.service_op.unf_flush_ini_resp_que(lport->fc_port);
-}
-
-int unf_cm_eh_abort_handler(struct unf_scsi_cmnd *scsi_cmnd)
-{
- /*
- * SCSI ABORT Command --->>> FC ABTS Command
- * If return ABORT_FAIL, then enter TMF process
- */
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_lport *xchg_lport = NULL;
- int ret = UNF_SCSI_ABORT_SUCCESS;
- ulong flag = 0;
-
- /* 1. Get L_Port: Point to Scsi_host */
- unf_lport = unf_find_lport_by_scsi_cmd(scsi_cmnd);
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Can't find port by scsi host id(0x%x)",
- UNF_GET_SCSI_HOST_ID_BY_CMND(scsi_cmnd));
- return UNF_SCSI_ABORT_FAIL;
- }
-
- /* 2. find target Xchg for INI Abort CMND */
- unf_xchg = unf_cm_lookup_xchg_by_cmnd_sn(unf_lport, scsi_cmnd->cmnd_sn,
- scsi_cmnd->world_id,
- scsi_cmnd->pinitiator);
- if (unlikely(!unf_xchg)) {
- FC_DRV_PRINT(UNF_LOG_ABNORMAL, UNF_WARN,
- "[warn]Port(0x%x) can't find exchange by Cmdsn(0x%lx),Ini:%p",
- unf_lport->port_id, (ulong)scsi_cmnd->cmnd_sn,
- scsi_cmnd->pinitiator);
-
- unf_flush_ini_resp_que(unf_lport);
-
- return UNF_SCSI_ABORT_SUCCESS;
- }
-
- /* 3. increase ref_cnt to protect exchange */
- ret = (int)unf_xchg_ref_inc(unf_xchg, INI_EH_ABORT);
- if (unlikely(ret != RETURN_OK)) {
- unf_flush_ini_resp_que(unf_lport);
-
- return UNF_SCSI_ABORT_SUCCESS;
- }
-
- scsi_cmnd->upper_cmnd = unf_xchg->scsi_cmnd_info.scsi_cmnd;
- unf_xchg->debug_hook = true;
-
- /* 4. Exchang L_Port/R_Port Get & check */
- spin_lock_irqsave(&unf_xchg->xchg_state_lock, flag);
- xchg_lport = unf_xchg->lport;
- unf_rport = unf_xchg->rport;
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flag);
-
- if (unlikely(!xchg_lport || !unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Exchange(0x%p)'s L_Port or R_Port is NULL, state(0x%x)",
- unf_xchg, unf_xchg->io_state);
-
- unf_xchg_ref_dec(unf_xchg, INI_EH_ABORT);
-
- if (!xchg_lport)
- /* for L_Port */
- return UNF_SCSI_ABORT_FAIL;
- /* for R_Port */
- return UNF_SCSI_ABORT_SUCCESS;
- }
-
- /* 5. Send INI Abort Cmnd */
- ret = unf_ini_abort_cmnd(xchg_lport, unf_xchg, scsi_cmnd);
-
- /* 6. decrease exchange ref_cnt */
- unf_xchg_ref_dec(unf_xchg, INI_EH_ABORT);
-
- return ret;
-}
-
-u32 unf_tmf_timeout_recovery_default(void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- ulong flag = 0;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_rport *unf_rport = (struct unf_rport *)rport;
-
- unf_lport = unf_xchg->lport;
- FC_CHECK_RETURN_VALUE(unf_lport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- unf_rport_enter_logo(unf_lport, unf_rport);
-
- return RETURN_OK;
-}
-
-void unf_abts_timeout_recovery_default(void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- ulong flag = 0;
- ulong flags = 0;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_rport *unf_rport = (struct unf_rport *)rport;
-
- unf_lport = unf_xchg->lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- spin_lock_irqsave(&unf_xchg->xchg_state_lock, flags);
- if (INI_IO_STATE_DONE & unf_xchg->io_state) {
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flags);
-
- return;
- }
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flags);
-
- if (unf_xchg->rport_bind_jifs != unf_rport->rport_alloc_jifs)
- return;
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- unf_rport_enter_logo(unf_lport, unf_rport);
-}
-
-u32 unf_tmf_timeout_recovery_special(void *rport, void *xchg)
-{
- /* Do port reset or R_Port LOGO */
- int ret = UNF_RETURN_ERROR;
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_rport *unf_rport = (struct unf_rport *)rport;
-
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(unf_xchg->lport, UNF_RETURN_ERROR);
-
- unf_lport = unf_xchg->lport->root_lport;
- FC_CHECK_RETURN_VALUE(unf_lport, UNF_RETURN_ERROR);
-
- /* 1. TMF response timeout & Marker STS timeout */
- if (!(unf_xchg->tmf_state &
- (MARKER_STS_RECEIVED | TMF_RESPONSE_RECEIVED))) {
- /* TMF timeout & marker timeout */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive marker status timeout and do recovery",
- unf_lport->port_id);
-
- /* Do port reset */
- ret = unf_cm_reset_port(unf_lport->port_id);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) do reset failed",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
- }
-
- /* 2. default case: Do LOGO process */
- unf_tmf_timeout_recovery_default(unf_rport, unf_xchg);
-
- return RETURN_OK;
-}
-
-void unf_tmf_abnormal_recovery(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- /*
- * for device(lun)/target(session) reset:
- * Do port reset or R_Port LOGO
- */
- if (lport->unf_tmf_abnormal_recovery)
- lport->unf_tmf_abnormal_recovery((void *)rport, (void *)xchg);
-}
-
-int unf_cm_eh_device_reset_handler(struct unf_scsi_cmnd *scsi_cmnd)
-{
- /* SCSI Device/LUN Reset Command --->>> FC LUN/Device Reset Command */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- u32 cmnd_result = 0;
- int ret = SUCCESS;
-
- FC_CHECK_RETURN_VALUE(scsi_cmnd, FAILED);
- FC_CHECK_RETURN_VALUE(scsi_cmnd->lun_id, FAILED);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[event]Enter device/LUN reset handler");
-
- /* 1. Get L_Port */
- unf_lport = unf_find_lport_by_scsi_cmd(scsi_cmnd);
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Can't find port by scsi_host_id(0x%x)",
- UNF_GET_SCSI_HOST_ID_BY_CMND(scsi_cmnd));
-
- return FAILED;
- }
-
- /* 2. L_Port State checking */
- if (unlikely(unf_lport->port_removing)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%p) is removing", unf_lport);
-
- return FAILED;
- }
-
- /*
- * 3. Get R_Port: no rport is found or rport is not ready,return ok
- * from: L_Port -->> rport_scsi_table (image table) -->>
- * rport_info_table
- */
- unf_rport = unf_find_rport_by_scsi_id(unf_lport, scsi_cmnd->err_code_table,
- scsi_cmnd->err_code_table_cout,
- UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd), &cmnd_result);
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) Can't find rport by scsi_id(0x%x)",
- unf_lport->port_id, UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd));
-
- return SUCCESS;
- }
-
- /*
- * 4. Set the I/O of the corresponding LUN to abort.
- * *
- * LUN Reset: set UP_ABORT tag, with:
- * INI_Busy_list, IO_Wait_list,
- * IO_Delay_list, IO_Delay_transfer_list
- */
- unf_cm_xchg_abort_by_lun(unf_lport, unf_rport, *((u64 *)scsi_cmnd->lun_id), NULL, false);
-
- /* 5. R_Port state check */
- if (unlikely(unf_rport->rp_state != UNF_RPORT_ST_READY)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) state(0x%x) SCSI Command(0x%p), rport is not ready",
- unf_lport->port_id, unf_rport->nport_id,
- unf_rport->rp_state, scsi_cmnd);
-
- return SUCCESS;
- }
-
- /* 6. Get & inc ref_cnt free Xchg for Device reset */
- unf_xchg = (struct unf_xchg *)unf_cm_get_free_xchg(unf_lport, UNF_XCHG_TYPE_INI);
- if (unlikely(!unf_xchg)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%p) can't get free exchange", unf_lport);
-
- return FAILED;
- }
-
- /* increase ref_cnt for protecting exchange */
- ret = (int)unf_xchg_ref_inc(unf_xchg, INI_EH_DEVICE_RESET);
- FC_CHECK_RETURN_VALUE((ret == RETURN_OK), FAILED);
-
- /* 7. Send Device/LUN Reset to Low level */
- ret = unf_send_scsi_mgmt_cmnd(unf_xchg, unf_lport, unf_rport, scsi_cmnd,
- UNF_FCP_TM_LOGICAL_UNIT_RESET);
- if (unlikely(ret == FAILED)) {
- /*
- * Do port reset or R_Port LOGO:
- * 1. FAILED: send failed
- * 2. FAILED: semaphore timeout
- * 3. SUCCESS: rcvd rsp & semaphore has been waken up
- */
- unf_tmf_abnormal_recovery(unf_lport, unf_rport, unf_xchg);
- }
-
- /*
- * 8. Release resource immediately if necessary
- * NOTE: here, semaphore timeout or rcvd rsp(semaphore has been waken
- * up)
- */
- if (likely(!unf_lport->port_removing || unf_lport->root_lport != unf_lport))
- unf_cm_free_xchg(unf_xchg->lport, unf_xchg);
-
- /* decrease ref_cnt */
- unf_xchg_ref_dec(unf_xchg, INI_EH_DEVICE_RESET);
-
- return SUCCESS;
-}
-
-int unf_cm_target_reset_handler(struct unf_scsi_cmnd *scsi_cmnd)
-{
- /* SCSI Target Reset Command --->>> FC Session Reset/Delete Command */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- u32 cmnd_result = 0;
- int ret = SUCCESS;
-
- FC_CHECK_RETURN_VALUE(scsi_cmnd, FAILED);
- FC_CHECK_RETURN_VALUE(scsi_cmnd->lun_id, FAILED);
-
- /* 1. Get L_Port */
- unf_lport = unf_find_lport_by_scsi_cmd(scsi_cmnd);
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Can't find port by scsi_host_id(0x%x)",
- UNF_GET_SCSI_HOST_ID_BY_CMND(scsi_cmnd));
-
- return FAILED;
- }
-
- /* 2. L_Port State check */
- if (unlikely(unf_lport->port_removing)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%p) is removing", unf_lport);
-
- return FAILED;
- }
-
- /*
- * 3. Get R_Port: no rport is found or rport is not ready,return ok
- * from: L_Port -->> rport_scsi_table (image table) -->>
- * rport_info_table
- */
- unf_rport = unf_find_rport_by_scsi_id(unf_lport, scsi_cmnd->err_code_table,
- scsi_cmnd->err_code_table_cout,
- UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd), &cmnd_result);
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Can't find rport by scsi_id(0x%x)",
- UNF_GET_SCSI_ID_BY_CMND(scsi_cmnd));
-
- return SUCCESS;
- }
-
- /*
- * 4. set UP_ABORT on Target IO and Session IO
- * *
- * LUN Reset: set UP_ABORT tag, with:
- * INI_Busy_list, IO_Wait_list,
- * IO_Delay_list, IO_Delay_transfer_list
- */
- unf_cm_xchg_abort_by_session(unf_lport, unf_rport);
-
- /* 5. R_Port state check */
- if (unlikely(unf_rport->rp_state != UNF_RPORT_ST_READY)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) state(0x%x) is not ready, SCSI Command(0x%p)",
- unf_lport->port_id, unf_rport->nport_id,
- unf_rport->rp_state, scsi_cmnd);
-
- return SUCCESS;
- }
-
- /* 6. Get free Xchg for Target Reset CMND */
- unf_xchg = (struct unf_xchg *)unf_cm_get_free_xchg(unf_lport, UNF_XCHG_TYPE_INI);
- if (unlikely(!unf_xchg)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%p) can't get free exchange", unf_lport);
-
- return FAILED;
- }
-
- /* increase ref_cnt to protect exchange */
- ret = (int)unf_xchg_ref_inc(unf_xchg, INI_EH_DEVICE_RESET);
- FC_CHECK_RETURN_VALUE((ret == RETURN_OK), FAILED);
-
- /* 7. Send Target Reset Cmnd to low-level */
- ret = unf_send_scsi_mgmt_cmnd(unf_xchg, unf_lport, unf_rport, scsi_cmnd,
- UNF_FCP_TM_TARGET_RESET);
- if (unlikely(ret == FAILED)) {
- /*
- * Do port reset or R_Port LOGO:
- * 1. FAILED: send failed
- * 2. FAILED: semaphore timeout
- * 3. SUCCESS: rcvd rsp & semaphore has been waken up
- */
- unf_tmf_abnormal_recovery(unf_lport, unf_rport, unf_xchg);
- }
-
- /*
- * 8. Release resource immediately if necessary
- * NOTE: here, semaphore timeout or rcvd rsp(semaphore has been waken
- * up)
- */
- if (likely(!unf_lport->port_removing || unf_lport->root_lport != unf_lport))
- unf_cm_free_xchg(unf_xchg->lport, unf_xchg);
-
- /* decrease exchange ref_cnt */
- unf_xchg_ref_dec(unf_xchg, INI_EH_DEVICE_RESET);
-
- return SUCCESS;
-}
-
-int unf_cm_bus_reset_handler(struct unf_scsi_cmnd *scsi_cmnd)
-{
- /* SCSI BUS Reset Command --->>> FC Port Reset Command */
- struct unf_lport *unf_lport = NULL;
- int cmnd_result = 0;
-
- /* 1. Get L_Port */
- unf_lport = unf_find_lport_by_scsi_cmd(scsi_cmnd);
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Can't find port by scsi_host_id(0x%x)",
- UNF_GET_SCSI_HOST_ID_BY_CMND(scsi_cmnd));
-
- return FAILED;
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_KEVENT,
- "[event]Do port reset with scsi_bus_reset");
-
- cmnd_result = unf_cm_reset_port(unf_lport->port_id);
- if (unlikely(cmnd_result == UNF_RETURN_ERROR))
- return FAILED;
- else
- return SUCCESS;
-}
-
-void unf_process_scsi_mgmt_result(struct unf_frame_pkg *pkg,
- struct unf_xchg *xchg)
-{
- u8 *rsp_info = NULL;
- u8 rsp_code = 0;
- u32 code_index = 0;
-
- /*
- * LLT found that:RSP_CODE is the third byte of
- * FCP_RSP_INFO, on Little endian should be byte 0, For
- * detail FCP_4 Table 26 FCP_RSP_INFO field format
- * *
- * 1. state setting
- * 2. wake up semaphore
- */
- FC_CHECK_RETURN_VOID(pkg);
- FC_CHECK_RETURN_VOID(xchg);
-
- xchg->tmf_state |= TMF_RESPONSE_RECEIVED;
-
- if (UNF_GET_LL_ERR(pkg) != UNF_IO_SUCCESS ||
- pkg->unf_rsp_pload_bl.length > UNF_RESPONE_DATA_LEN) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Send scsi manage command failed with error code(0x%x) resp len(0x%x)",
- UNF_GET_LL_ERR(pkg), pkg->unf_rsp_pload_bl.length);
-
- xchg->scsi_cmnd_info.result = UNF_IO_FAILED;
-
- /* wakeup semaphore & return */
- up(&xchg->task_sema);
-
- return;
- }
-
- rsp_info = pkg->unf_rsp_pload_bl.buffer_ptr;
- if (rsp_info && pkg->unf_rsp_pload_bl.length != 0) {
- /* change to little end if necessary */
- if (pkg->byte_orders & UNF_BIT_3)
- unf_big_end_to_cpu(rsp_info, pkg->unf_rsp_pload_bl.length);
- }
-
- if (!rsp_info) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]FCP response data pointer is NULL with Xchg TAG(0x%x)",
- xchg->hotpooltag);
-
- xchg->scsi_cmnd_info.result = UNF_IO_SUCCESS;
-
- /* wakeup semaphore & return */
- up(&xchg->task_sema);
-
- return;
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]FCP response data length(0x%x), RSP_CODE(0x%x:%x:%x:%x:%x:%x:%x:%x)",
- pkg->unf_rsp_pload_bl.length, rsp_info[ARRAY_INDEX_0],
- rsp_info[ARRAY_INDEX_1], rsp_info[ARRAY_INDEX_2],
- rsp_info[ARRAY_INDEX_3], rsp_info[ARRAY_INDEX_4],
- rsp_info[ARRAY_INDEX_5], rsp_info[ARRAY_INDEX_6],
- rsp_info[ARRAY_INDEX_7]);
-
- rsp_code = rsp_info[code_index];
- if (rsp_code == UNF_FCP_TM_RSP_COMPLETE || rsp_code == UNF_FCP_TM_RSP_SUCCEED)
- xchg->scsi_cmnd_info.result = UNF_IO_SUCCESS;
- else
- xchg->scsi_cmnd_info.result = UNF_IO_FAILED;
-
- /* wakeup semaphore & return */
- up(&xchg->task_sema);
-}
-
-static void unf_build_task_mgmt_fcp_cmnd(struct unf_fcp_cmnd *fcp_cmnd,
- struct unf_scsi_cmnd *scsi_cmnd,
- enum unf_task_mgmt_cmd task_mgmt)
-{
- FC_CHECK_RETURN_VOID(fcp_cmnd);
- FC_CHECK_RETURN_VOID(scsi_cmnd);
-
- unf_big_end_to_cpu((void *)scsi_cmnd->lun_id, UNF_FCP_LUNID_LEN_8);
- (*(u64 *)(scsi_cmnd->lun_id)) >>= UNF_SHIFT_8;
- memcpy(fcp_cmnd->lun, scsi_cmnd->lun_id, sizeof(fcp_cmnd->lun));
-
- /*
- * If the TASK MANAGEMENT FLAGS field is set to a nonzero value,
- * the FCP_CDB field, the FCP_DL field, the TASK ATTRIBUTE field,
- * the RDDATA bit, and the WRDATA bit shall be ignored and the
- * FCP_BIDIRECTIONAL_READ_DL field shall not be included in the FCP_CMND
- * IU payload
- */
- fcp_cmnd->control = UNF_SET_TASK_MGMT_FLAGS((u32)(task_mgmt));
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "SCSI cmnd(0x%x) is task mgmt cmnd. ntrl Flag(LITTLE END) is 0x%x.",
- task_mgmt, fcp_cmnd->control);
-}
-
-int unf_send_scsi_mgmt_cmnd(struct unf_xchg *xchg, struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_scsi_cmnd *scsi_cmnd,
- enum unf_task_mgmt_cmd task_mgnt_cmd_type)
-{
- /*
- * 1. Device/LUN reset
- * 2. Target/Session reset
- */
- struct unf_xchg *unf_xchg = NULL;
- int ret = SUCCESS;
- struct unf_frame_pkg pkg = {0};
- ulong xchg_flag = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, FAILED);
- FC_CHECK_RETURN_VALUE(rport, FAILED);
- FC_CHECK_RETURN_VALUE(xchg, FAILED);
- FC_CHECK_RETURN_VALUE(scsi_cmnd, FAILED);
- FC_CHECK_RETURN_VALUE(task_mgnt_cmd_type <= UNF_FCP_TM_TERMINATE_TASK &&
- task_mgnt_cmd_type >= UNF_FCP_TM_QUERY_TASK_SET, FAILED);
-
- unf_xchg = xchg;
- unf_xchg->lport = lport;
- unf_xchg->rport = rport;
-
- /* 1. State: Up_Task */
- spin_lock_irqsave(&unf_xchg->xchg_state_lock, xchg_flag);
- unf_xchg->io_state |= INI_IO_STATE_UPTASK;
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, xchg_flag);
- pkg.frame_head.oxid_rxid = ((u32)unf_xchg->oxid << (u32)UNF_SHIFT_16) | unf_xchg->rxid;
-
- /* 2. Set TASK MANAGEMENT FLAGS of FCP_CMND to the corresponding task
- * management command
- */
- unf_build_task_mgmt_fcp_cmnd(&unf_xchg->fcp_cmnd, scsi_cmnd, task_mgnt_cmd_type);
-
- pkg.xchg_contex = unf_xchg;
- pkg.private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] = rport->rport_index;
- pkg.fcp_cmnd = &unf_xchg->fcp_cmnd;
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = unf_xchg->hotpooltag;
- pkg.frame_head.csctl_sid = lport->nport_id;
- pkg.frame_head.rctl_did = rport->nport_id;
-
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME];
-
- if (unlikely(lport->pcie_link_down)) {
- unf_free_lport_all_xchg(lport);
- return SUCCESS;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Port(0x%x) send task_cmnd(0x%x) to RPort(0x%x) Hottag(0x%x) lunid(0x%llx)",
- lport->port_id, task_mgnt_cmd_type, rport->nport_id,
- unf_xchg->hotpooltag, *((u64 *)scsi_cmnd->lun_id));
-
- /* 3. Init exchange task semaphore */
- sema_init(&unf_xchg->task_sema, 0);
-
- /* 4. Send Mgmt Task to low-level */
- if (unf_hardware_start_io(lport, &pkg) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send task_cmnd(0x%x) to RPort(0x%x) failed",
- lport->port_id, task_mgnt_cmd_type, rport->nport_id);
-
- return FAILED;
- }
-
- /*
- * semaphore timeout
- **
- * Code review: The second input parameter needs to be converted to
- jiffies.
- * set semaphore after the message is sent successfully.The semaphore is
- returned when the semaphore times out or is woken up.
- **
- * 5. The semaphore is cleared and counted when the Mgmt Task message is
- sent, and is Wake Up when the RSP message is received.
- * If the semaphore is not Wake Up, the semaphore is triggered after
- timeout. That is, no RSP message is received within the timeout period.
- */
- if (down_timeout(&unf_xchg->task_sema, (s64)msecs_to_jiffies((u32)UNF_WAIT_SEM_TIMEOUT))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send task_cmnd(0x%x) to RPort(0x%x) timeout scsi id(0x%x) lun id(0x%x)",
- lport->nport_id, task_mgnt_cmd_type,
- rport->nport_id, scsi_cmnd->scsi_id,
- (u32)scsi_cmnd->raw_lun_id);
- unf_notify_chip_free_xid(unf_xchg);
- /* semaphore timeout */
- ret = FAILED;
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- if (lport->states == UNF_LPORT_ST_RESET)
- ret = SUCCESS;
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- return ret;
- }
-
- /*
- * 6. NOTE: no timeout (has been waken up)
- * Do Scsi_Cmnd(Mgmt Task) result checking
- * *
- * FAILED: with error code or RSP is error
- * SUCCESS: others
- */
- if (unf_xchg->scsi_cmnd_info.result == UNF_IO_SUCCESS) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Port(0x%x) send task_cmnd(0x%x) to RPort(0x%x) and receive rsp succeed",
- lport->nport_id, task_mgnt_cmd_type, rport->nport_id);
-
- ret = SUCCESS;
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send task_cmnd(0x%x) to RPort(0x%x) and receive rsp failed scsi id(0x%x) lun id(0x%x)",
- lport->nport_id, task_mgnt_cmd_type, rport->nport_id,
- scsi_cmnd->scsi_id, (u32)scsi_cmnd->raw_lun_id);
-
- ret = FAILED;
- }
-
- return ret;
-}
-
-u32 unf_recv_tmf_marker_status(void *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_lport *unf_lport = NULL;
- u32 uret = RETURN_OK;
- struct unf_xchg *unf_xchg = NULL;
- u16 hot_pool_tag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- unf_lport = (struct unf_lport *)lport;
-
- /* Find exchange which point to marker sts */
- if (!unf_lport->xchg_mgr_temp.unf_look_up_xchg_by_tag) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) tag function is NULL", unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- hot_pool_tag =
- (u16)(pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX]);
-
- unf_xchg =
- (struct unf_xchg *)(unf_lport->xchg_mgr_temp
- .unf_look_up_xchg_by_tag((void *)unf_lport, hot_pool_tag));
- if (!unf_xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) find exchange by tag(0x%x) failed",
- unf_lport->port_id, unf_lport->nport_id, hot_pool_tag);
-
- return UNF_RETURN_ERROR;
- }
-
- /*
- * NOTE: set exchange TMF state with MARKER_STS_RECEIVED
- * *
- * About TMF state
- * 1. STS received
- * 2. Response received
- * 3. Do check if necessary
- */
- unf_xchg->tmf_state |= MARKER_STS_RECEIVED;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Marker STS: D_ID(0x%x) S_ID(0x%x) OX_ID(0x%x) RX_ID(0x%x), EXCH: D_ID(0x%x) S_ID(0x%x) OX_ID(0x%x) RX_ID(0x%x)",
- pkg->frame_head.rctl_did & UNF_NPORTID_MASK,
- pkg->frame_head.csctl_sid & UNF_NPORTID_MASK,
- (u16)(pkg->frame_head.oxid_rxid >> UNF_SHIFT_16),
- (u16)(pkg->frame_head.oxid_rxid), unf_xchg->did, unf_xchg->sid,
- unf_xchg->oxid, unf_xchg->rxid);
-
- return uret;
-}
-
-u32 unf_recv_abts_marker_status(void *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- u16 hot_pool_tag = 0;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- unf_lport = (struct unf_lport *)lport;
-
- /* Find exchange by tag */
- if (!unf_lport->xchg_mgr_temp.unf_look_up_xchg_by_tag) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) tag function is NULL", unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- hot_pool_tag = (u16)(pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX]);
-
- unf_xchg =
- (struct unf_xchg *)(unf_lport->xchg_mgr_temp.unf_look_up_xchg_by_tag((void *)unf_lport,
- hot_pool_tag));
- if (!unf_xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) find exchange by tag(0x%x) failed",
- unf_lport->port_id, unf_lport->nport_id, hot_pool_tag);
-
- return UNF_RETURN_ERROR;
- }
-
- /*
- * NOTE: set exchange ABTS state with MARKER_STS_RECEIVED
- * *
- * About exchange ABTS state
- * 1. STS received
- * 2. Response received
- * 3. Do check if necessary
- * *
- * About Exchange status get from low level
- * 1. Set: when RCVD ABTS Marker
- * 2. Set: when RCVD ABTS Req Done
- * 3. value: set value with pkg->status
- */
- spin_lock_irqsave(&unf_xchg->xchg_state_lock, flags);
- unf_xchg->ucode_abts_state = pkg->status;
- unf_xchg->abts_state |= MARKER_STS_RECEIVED;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x) wake up SEMA for Abts marker exchange(0x%p) oxid(0x%x 0x%x) hottag(0x%x) status(0x%x)",
- unf_lport->port_id, unf_xchg, unf_xchg->oxid, unf_xchg->rxid,
- unf_xchg->hotpooltag, pkg->abts_maker_status);
-
- /*
- * NOTE: Second time for ABTS marker received, or
- * ABTS response have been received, no need to wake up sema
- */
- if ((INI_IO_STATE_ABORT_TIMEOUT & unf_xchg->io_state) ||
- (ABTS_RESPONSE_RECEIVED & unf_xchg->abts_state)) {
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x) no need to wake up SEMA for Abts marker ABTS_STATE(0x%x) IO_STATE(0x%x)",
- unf_lport->port_id, unf_xchg->abts_state, unf_xchg->io_state);
-
- return RETURN_OK;
- }
-
- if (unf_xchg->io_state & INI_IO_STATE_TMF_ABORT) {
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flags);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x) receive Abts marker, exchange(%p) state(0x%x) free it",
- unf_lport->port_id, unf_xchg, unf_xchg->io_state);
-
- unf_cm_free_xchg(unf_lport, unf_xchg);
- } else {
- spin_unlock_irqrestore(&unf_xchg->xchg_state_lock, flags);
- up(&unf_xchg->task_sema);
- }
-
- return RETURN_OK;
-}
diff --git a/drivers/scsi/spfc/common/unf_io_abnormal.h b/drivers/scsi/spfc/common/unf_io_abnormal.h
deleted file mode 100644
index 31cc8e30e51a..000000000000
--- a/drivers/scsi/spfc/common/unf_io_abnormal.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_IO_ABNORMAL_H
-#define UNF_IO_ABNORMAL_H
-
-#include "unf_type.h"
-#include "unf_lport.h"
-#include "unf_exchg.h"
-
-#define UNF_GET_LL_ERR(pkg) (((pkg)->status) >> 16)
-
-void unf_process_scsi_mgmt_result(struct unf_frame_pkg *pkg,
- struct unf_xchg *xchg);
-u32 unf_hardware_start_io(struct unf_lport *lport, struct unf_frame_pkg *pkg);
-u32 unf_recv_abts_marker_status(void *lport, struct unf_frame_pkg *pkg);
-u32 unf_recv_tmf_marker_status(void *lport, struct unf_frame_pkg *pkg);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_log.h b/drivers/scsi/spfc/common/unf_log.h
deleted file mode 100644
index 801e23ac0829..000000000000
--- a/drivers/scsi/spfc/common/unf_log.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_LOG_H
-#define UNF_LOG_H
-#include "unf_type.h"
-
-#define UNF_CRITICAL 1
-#define UNF_ERR 2
-#define UNF_WARN 3
-#define UNF_KEVENT 4
-#define UNF_MAJOR 5
-#define UNF_MINOR 6
-#define UNF_INFO 7
-#define UNF_DATA 7
-#define UNF_ALL 7
-
-enum unf_debug_type {
- UNF_DEBUG_TYPE_MML = 0,
- UNF_DEBUG_TYPE_DIAGNOSE = 1,
- UNF_DEBUG_TYPE_MESSAGE = 2,
- UNF_DEBUG_TYPE_BUTT
-};
-
-enum unf_log_attr {
- UNF_LOG_LOGIN_ATT = 0x1,
- UNF_LOG_IO_ATT = 0x2,
- UNF_LOG_EQUIP_ATT = 0x4,
- UNF_LOG_REG_ATT = 0x8,
- UNF_LOG_REG_MML_TEST = 0x10,
- UNF_LOG_EVENT = 0x20,
- UNF_LOG_NORMAL = 0x40,
- UNF_LOG_ABNORMAL = 0X80,
- UNF_LOG_BUTT
-};
-
-enum event_log {
- UNF_EVTLOG_DRIVER_SUC = 0,
- UNF_EVTLOG_DRIVER_INFO,
- UNF_EVTLOG_DRIVER_WARN,
- UNF_EVTLOG_DRIVER_ERR,
- UNF_EVTLOG_LINK_SUC,
- UNF_EVTLOG_LINK_INFO,
- UNF_EVTLOG_LINK_WARN,
- UNF_EVTLOG_LINK_ERR,
- UNF_EVTLOG_IO_SUC,
- UNF_EVTLOG_IO_INFO,
- UNF_EVTLOG_IO_WARN,
- UNF_EVTLOG_IO_ERR,
- UNF_EVTLOG_TOOL_SUC,
- UNF_EVTLOG_TOOL_INFO,
- UNF_EVTLOG_TOOL_WARN,
- UNF_EVTLOG_TOOL_ERR,
- UNF_EVTLOG_BUT
-};
-
-#define UNF_IO_ATT_PRINT_TIMES 2
-#define UNF_LOGIN_ATT_PRINT_TIMES 100
-
-#define UNF_IO_ATT_PRINT_LIMIT msecs_to_jiffies(2 * 1000)
-
-extern u32 unf_dgb_level;
-extern u32 log_print_level;
-extern u32 log_limited_times;
-
-#define DRV_LOG_LIMIT(module_id, log_level, log_att, format, ...) \
- do { \
- static unsigned long pre; \
- static int should_print = UNF_LOGIN_ATT_PRINT_TIMES; \
- if (time_after_eq(jiffies, pre + (UNF_IO_ATT_PRINT_LIMIT))) { \
- if (log_att == UNF_LOG_ABNORMAL) { \
- should_print = UNF_IO_ATT_PRINT_TIMES; \
- } else { \
- should_print = log_limited_times; \
- } \
- } \
- if (should_print < 0) { \
- if (log_att != UNF_LOG_ABNORMAL) \
- pre = jiffies; \
- break; \
- } \
- if (should_print-- > 0) { \
- printk(log_level "[%d][FC_UNF]" format "[%s][%-5d]\n", \
- smp_processor_id(), ##__VA_ARGS__, __func__, \
- __LINE__); \
- } \
- if (should_print == 0) { \
- printk(log_level "[FC_UNF]log is limited[%s][%-5d]\n", \
- __func__, __LINE__); \
- } \
- pre = jiffies; \
- } while (0)
-
-#define FC_CHECK_RETURN_VALUE(condition, ret) \
- do { \
- if (unlikely(!(condition))) { \
- FC_DRV_PRINT(UNF_LOG_REG_ATT, \
- UNF_ERR, "Para check(%s) invalid", \
- #condition); \
- return ret; \
- } \
- } while (0)
-
-#define FC_CHECK_RETURN_VOID(condition) \
- do { \
- if (unlikely(!(condition))) { \
- FC_DRV_PRINT(UNF_LOG_REG_ATT, \
- UNF_ERR, "Para check(%s) invalid", \
- #condition); \
- return; \
- } \
- } while (0)
-
-#define FC_DRV_PRINT(log_att, log_level, format, ...) \
- do { \
- if (unlikely((log_level) <= log_print_level)) { \
- if (log_level == UNF_CRITICAL) { \
- DRV_LOG_LIMIT(UNF_PID, KERN_CRIT, \
- log_att, format, ##__VA_ARGS__); \
- } else if (log_level == UNF_WARN) { \
- DRV_LOG_LIMIT(UNF_PID, KERN_WARNING, \
- log_att, format, ##__VA_ARGS__); \
- } else if (log_level == UNF_ERR) { \
- DRV_LOG_LIMIT(UNF_PID, KERN_ERR, \
- log_att, format, ##__VA_ARGS__); \
- } else if (log_level == UNF_MAJOR || \
- log_level == UNF_MINOR || \
- log_level == UNF_KEVENT) { \
- DRV_LOG_LIMIT(UNF_PID, KERN_NOTICE, \
- log_att, format, ##__VA_ARGS__); \
- } else if (log_level == UNF_INFO || \
- log_level == UNF_DATA) { \
- DRV_LOG_LIMIT(UNF_PID, KERN_INFO, \
- log_att, format, ##__VA_ARGS__); \
- } \
- } \
- } while (0)
-
-#define UNF_PRINT_SFS(dbg_level, portid, data, size) \
- do { \
- if ((dbg_level) <= log_print_level) { \
- u32 cnt = 0; \
- printk(KERN_INFO "[INFO]Port(0x%x) sfs:0x", (portid)); \
- for (cnt = 0; cnt < (size) / 4; cnt++) { \
- printk(KERN_INFO "%08x ", \
- ((u32 *)(data))[cnt]); \
- } \
- printk(KERN_INFO "[FC_UNF][%s]\n", __func__); \
- } \
- } while (0)
-
-#define UNF_PRINT_SFS_LIMIT(dbg_level, portid, data, size) \
- do { \
- if ((dbg_level) <= log_print_level) { \
- static ulong pre; \
- static int should_print = UNF_LOGIN_ATT_PRINT_TIMES; \
- if (time_after_eq( \
- jiffies, pre + UNF_IO_ATT_PRINT_LIMIT)) { \
- should_print = log_limited_times; \
- } \
- if (should_print < 0) { \
- pre = jiffies; \
- break; \
- } \
- if (should_print-- > 0) { \
- UNF_PRINT_SFS(dbg_level, portid, data, size); \
- } \
- if (should_print == 0) { \
- printk( \
- KERN_INFO \
- "[FC_UNF]sfs log is limited[%s][%-5d]\n", \
- __func__, __LINE__); \
- } \
- pre = jiffies; \
- } \
- } while (0)
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_lport.c b/drivers/scsi/spfc/common/unf_lport.c
deleted file mode 100644
index 66d3ac14d676..000000000000
--- a/drivers/scsi/spfc/common/unf_lport.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_lport.h"
-#include "unf_log.h"
-#include "unf_rport.h"
-#include "unf_exchg.h"
-#include "unf_service.h"
-#include "unf_ls.h"
-#include "unf_gs.h"
-#include "unf_portman.h"
-
-static void unf_lport_config(struct unf_lport *lport);
-void unf_cm_mark_dirty_mem(struct unf_lport *lport, enum unf_lport_dirty_flag type)
-{
- FC_CHECK_RETURN_VOID((lport));
-
- lport->dirty_flag |= (u32)type;
-}
-
-u32 unf_init_lport_route(struct unf_lport *lport)
-{
- u32 ret = RETURN_OK;
- int ret_val = 0;
-
- FC_CHECK_RETURN_VALUE((lport), UNF_RETURN_ERROR);
-
- /* Init L_Port route work */
- INIT_DELAYED_WORK(&lport->route_timer_work, unf_lport_route_work);
-
- /* Delay route work */
- ret_val = queue_delayed_work(unf_wq, &lport->route_timer_work,
- (ulong)msecs_to_jiffies(UNF_LPORT_POLL_TIMER));
- if (unlikely((!(bool)(ret_val)))) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_WARN,
- "[warn]Port(0x%x) schedule route work failed",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- ret = unf_lport_ref_inc(lport);
- return ret;
-}
-
-void unf_destroy_lport_route(struct unf_lport *lport)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
-
- /* Cancel (route timer) delay work */
- UNF_DELAYED_WORK_SYNC(ret, (lport->port_id), (&lport->route_timer_work),
- "Route Timer work");
- if (ret == RETURN_OK)
- /* Corresponding to ADD operation */
- unf_lport_ref_dec(lport);
-
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_2_CLOSE_ROUTE;
-}
-
-void unf_init_port_parms(struct unf_lport *lport)
-{
- INIT_LIST_HEAD(&lport->list_vports_head);
- INIT_LIST_HEAD(&lport->list_intergrad_vports);
- INIT_LIST_HEAD(&lport->list_destroy_vports);
- INIT_LIST_HEAD(&lport->entry_lport);
- INIT_LIST_HEAD(&lport->list_qos_head);
-
- spin_lock_init(&lport->qos_mgr_lock);
- spin_lock_init(&lport->lport_state_lock);
-
- lport->max_frame_size = max_frame_size;
- lport->ed_tov = UNF_DEFAULT_EDTOV;
- lport->ra_tov = UNF_DEFAULT_RATOV;
- lport->fabric_node_name = 0;
- lport->qos_level = UNF_QOS_LEVEL_DEFAULT;
- lport->qos_cs_ctrl = false;
- lport->priority = (bool)UNF_PRIORITY_DISABLE;
- lport->port_dirt_exchange = false;
-
- unf_lport_config(lport);
-
- unf_set_lport_state(lport, UNF_LPORT_ST_ONLINE);
-
- lport->link_up = UNF_PORT_LINK_DOWN;
- lport->port_removing = false;
- lport->lport_free_completion = NULL;
- lport->last_tx_fault_jif = 0;
- lport->enhanced_features = 0;
- lport->destroy_step = INVALID_VALUE32;
- lport->dirty_flag = 0;
- lport->switch_state = false;
- lport->bbscn_support = false;
- lport->loop_back_test_mode = false;
- lport->start_work_state = UNF_START_WORK_STOP;
- lport->sfp_power_fault_count = 0;
- lport->sfp_9545_fault_count = 0;
-
- atomic_set(&lport->lport_no_operate_flag, UNF_LPORT_NORMAL);
- atomic_set(&lport->port_ref_cnt, 0);
- atomic_set(&lport->scsi_session_add_success, 0);
- atomic_set(&lport->scsi_session_add_failed, 0);
- atomic_set(&lport->scsi_session_del_success, 0);
- atomic_set(&lport->scsi_session_del_failed, 0);
- atomic_set(&lport->add_start_work_failed, 0);
- atomic_set(&lport->add_closing_work_failed, 0);
- atomic_set(&lport->alloc_scsi_id, 0);
- atomic_set(&lport->resume_scsi_id, 0);
- atomic_set(&lport->reuse_scsi_id, 0);
- atomic_set(&lport->device_alloc, 0);
- atomic_set(&lport->device_destroy, 0);
- atomic_set(&lport->session_loss_tmo, 0);
- atomic_set(&lport->host_no, 0);
- atomic64_set(&lport->exchg_index, 0x1000);
- atomic_inc(&lport->port_ref_cnt);
-
- memset(&lport->port_dynamic_info, 0, sizeof(struct unf_port_dynamic_info));
- memset(&lport->link_service_info, 0, sizeof(struct unf_link_service_collect));
- memset(&lport->err_code_sum, 0, sizeof(struct unf_err_code));
-}
-
-void unf_reset_lport_params(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = lport;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport->link_up = UNF_PORT_LINK_DOWN;
- unf_lport->nport_id = 0;
- unf_lport->max_frame_size = max_frame_size;
- unf_lport->ed_tov = UNF_DEFAULT_EDTOV;
- unf_lport->ra_tov = UNF_DEFAULT_RATOV;
- unf_lport->fabric_node_name = 0;
-}
-
-static enum unf_lport_login_state
-unf_lport_state_online(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_LINK_UP:
- next_state = UNF_LPORT_ST_LINK_UP;
- break;
-
- case UNF_EVENT_LPORT_NORMAL_ENTER:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_initial(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_LINK_UP:
- next_state = UNF_LPORT_ST_LINK_UP;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_linkup(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_NORMAL_ENTER:
- next_state = UNF_LPORT_ST_FLOGI_WAIT;
- break;
-
- case UNF_EVENT_LPORT_READY:
- next_state = UNF_LPORT_ST_READY;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_flogi_wait(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_REMOTE_ACC:
- next_state = UNF_LPORT_ST_PLOGI_WAIT;
- break;
-
- case UNF_EVENT_LPORT_READY:
- next_state = UNF_LPORT_ST_READY;
- break;
-
- case UNF_EVENT_LPORT_REMOTE_TIMEOUT:
- next_state = UNF_LPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_plogi_wait(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_REMOTE_ACC:
- next_state = UNF_LPORT_ST_RFT_ID_WAIT;
- break;
-
- case UNF_EVENT_LPORT_REMOTE_TIMEOUT:
- next_state = UNF_LPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state
-unf_lport_state_rftid_wait(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_REMOTE_ACC:
- next_state = UNF_LPORT_ST_RFF_ID_WAIT;
- break;
-
- case UNF_EVENT_LPORT_REMOTE_TIMEOUT:
- next_state = UNF_LPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_rffid_wait(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_REMOTE_ACC:
- next_state = UNF_LPORT_ST_SCR_WAIT;
- break;
-
- case UNF_EVENT_LPORT_REMOTE_TIMEOUT:
- next_state = UNF_LPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_scr_wait(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_REMOTE_ACC:
- next_state = UNF_LPORT_ST_READY;
- break;
-
- case UNF_EVENT_LPORT_REMOTE_TIMEOUT:
- next_state = UNF_LPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state
-unf_lport_state_logo(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_NORMAL_ENTER:
- next_state = UNF_LPORT_ST_OFFLINE;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_offline(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_ONLINE:
- next_state = UNF_LPORT_ST_ONLINE;
- break;
-
- case UNF_EVENT_LPORT_RESET:
- next_state = UNF_LPORT_ST_RESET;
- break;
-
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_reset(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_NORMAL_ENTER:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_lport_login_state unf_lport_state_ready(enum unf_lport_login_state old_state,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
-
- switch (lport_event) {
- case UNF_EVENT_LPORT_LINK_DOWN:
- next_state = UNF_LPORT_ST_INITIAL;
- break;
-
- case UNF_EVENT_LPORT_RESET:
- next_state = UNF_LPORT_ST_RESET;
- break;
-
- case UNF_EVENT_LPORT_OFFLINE:
- next_state = UNF_LPORT_ST_LOGO;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static struct unf_lport_state_ma lport_state[] = {
- {UNF_LPORT_ST_ONLINE, unf_lport_state_online},
- {UNF_LPORT_ST_INITIAL, unf_lport_state_initial},
- {UNF_LPORT_ST_LINK_UP, unf_lport_state_linkup},
- {UNF_LPORT_ST_FLOGI_WAIT, unf_lport_state_flogi_wait},
- {UNF_LPORT_ST_PLOGI_WAIT, unf_lport_state_plogi_wait},
- {UNF_LPORT_ST_RFT_ID_WAIT, unf_lport_state_rftid_wait},
- {UNF_LPORT_ST_RFF_ID_WAIT, unf_lport_state_rffid_wait},
- {UNF_LPORT_ST_SCR_WAIT, unf_lport_state_scr_wait},
- {UNF_LPORT_ST_LOGO, unf_lport_state_logo},
- {UNF_LPORT_ST_OFFLINE, unf_lport_state_offline},
- {UNF_LPORT_ST_RESET, unf_lport_state_reset},
- {UNF_LPORT_ST_READY, unf_lport_state_ready},
-};
-
-void unf_lport_state_ma(struct unf_lport *lport,
- enum unf_lport_event lport_event)
-{
- enum unf_lport_login_state old_state = UNF_LPORT_ST_ONLINE;
- enum unf_lport_login_state next_state = UNF_LPORT_ST_ONLINE;
- u32 index = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- old_state = lport->states;
-
- while (index < (sizeof(lport_state) / sizeof(struct unf_lport_state_ma))) {
- if (lport->states == lport_state[index].lport_state) {
- next_state = lport_state[index].lport_state_ma(old_state, lport_event);
- break;
- }
- index++;
- }
-
- if (index >= (sizeof(lport_state) / sizeof(struct unf_lport_state_ma))) {
- next_state = old_state;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR, "[info]Port(0x%x) hold state(0x%x)",
- lport->port_id, lport->states);
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) with old state(0x%x) event(0x%x) next state(0x%x)",
- lport->port_id, old_state, lport_event, next_state);
-
- unf_set_lport_state(lport, next_state);
-}
-
-u32 unf_lport_retry_flogi(struct unf_lport *lport)
-{
- struct unf_rport *unf_rport = NULL;
- u32 ret = UNF_RETURN_ERROR;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* Get (new) R_Port */
- unf_rport = unf_get_rport_by_nport_id(lport, UNF_FC_FID_FLOGI);
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY, UNF_FC_FID_FLOGI);
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) allocate RPort failed",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Check L_Port state */
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- if (lport->states != UNF_LPORT_ST_FLOGI_WAIT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) no need to retry FLOGI with state(0x%x)",
- lport->port_id, lport->states);
-
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
- return RETURN_OK;
- }
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = UNF_FC_FID_FLOGI;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Send FLOGI or FDISC */
- if (lport->root_lport != lport) {
- ret = unf_send_fdisc(lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send FDISC failed", lport->port_id);
-
- /* Do L_Port recovery */
- unf_lport_error_recovery(lport);
- }
- } else {
- ret = unf_send_flogi(lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send FLOGI failed\n", lport->port_id);
-
- /* Do L_Port recovery */
- unf_lport_error_recovery(lport);
- }
- }
-
- return ret;
-}
-
-u32 unf_lport_name_server_register(struct unf_lport *lport,
- enum unf_lport_login_state state)
-{
- struct unf_rport *unf_rport = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 fabric_id = UNF_FC_FID_DIR_SERV;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- if (state == UNF_LPORT_ST_SCR_WAIT)
- fabric_id = UNF_FC_FID_FCTRL;
-
- /* Get (safe) R_Port */
- unf_rport =
- unf_get_rport_by_nport_id(lport, fabric_id);
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY,
- fabric_id);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) allocate RPort failed",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Update R_Port & L_Port state */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = fabric_id;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- unf_lport_state_ma(lport, UNF_EVENT_LPORT_NORMAL_ENTER);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- switch (state) {
- /* RFT_ID */
- case UNF_LPORT_ST_RFT_ID_WAIT:
- ret = unf_send_rft_id(lport, unf_rport);
- break;
- /* RFF_ID */
- case UNF_LPORT_ST_RFF_ID_WAIT:
- ret = unf_send_rff_id(lport, unf_rport, UNF_FC4_FCP_TYPE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) register SCSI FC4Type to fabric(0xfffffc) failed",
- lport->nport_id);
- unf_lport_error_recovery(lport);
- }
- break;
-
- /* SCR */
- case UNF_LPORT_ST_SCR_WAIT:
- ret = unf_send_scr(lport, unf_rport);
- break;
-
- /* PLOGI */
- case UNF_LPORT_ST_PLOGI_WAIT:
- default:
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- ret = unf_send_plogi(lport, unf_rport);
- break;
- }
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) register fabric(0xfffffc) failed",
- lport->nport_id);
-
- /* Do L_Port recovery */
- unf_lport_error_recovery(lport);
- }
-
- return ret;
-}
-
-u32 unf_lport_enter_sns_logo(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_rport *unf_rport = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- if (!rport)
- unf_rport = unf_get_rport_by_nport_id(lport, UNF_FC_FID_DIR_SERV);
- else
- unf_rport = rport;
-
- if (!unf_rport) {
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- unf_lport_state_ma(lport, UNF_EVENT_LPORT_NORMAL_ENTER);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- return RETURN_OK;
- }
-
- /* Update L_Port & R_Port state */
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- unf_lport_state_ma(lport, UNF_EVENT_LPORT_NORMAL_ENTER);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Do R_Port LOGO state */
- unf_rport_enter_logo(lport, unf_rport);
-
- return ret;
-}
-
-void unf_lport_enter_sns_plogi(struct unf_lport *lport)
-{
- /* Fabric or Public Loop Mode: Login with Name server */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
-
- /* Get (safe) R_Port */
- unf_rport = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_DIR_SERV);
- if (unf_rport) {
- /* for port swap: Delete old R_Port if necessary */
- if (unf_rport->local_nport_id != lport->nport_id) {
- unf_rport_immediate_link_down(lport, unf_rport);
- unf_rport = NULL;
- }
- }
-
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY,
- UNF_FC_FID_DIR_SERV);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) allocate RPort failed",
- lport->port_id);
-
- unf_lport_error_recovery(unf_lport);
- return;
- }
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = UNF_FC_FID_DIR_SERV;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Send PLOGI to Fabric(0xfffffc) */
- ret = unf_send_plogi(unf_lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send PLOGI to name server failed",
- lport->port_id);
-
- unf_lport_error_recovery(unf_lport);
- }
-}
-
-int unf_get_port_params(void *arg_in, void *arg_out)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)arg_in;
- struct unf_low_level_port_mgr_op *port_mgr = NULL;
- struct unf_port_param port_params = {0};
-
- FC_CHECK_RETURN_VALUE(arg_in, UNF_RETURN_ERROR);
-
- port_mgr = &unf_lport->low_level_func.port_mgr_op;
- if (!port_mgr->ll_port_config_get) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_WARN,
- "[warn]Port(0x%x) low level port_config_get function is NULL",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_INFO,
- "[warn]Port(0x%x) get parameters with default:R_A_TOV(%d) E_D_TOV(%d)",
- unf_lport->port_id, UNF_DEFAULT_FABRIC_RATOV,
- UNF_DEFAULT_EDTOV);
-
- port_params.ra_tov = UNF_DEFAULT_FABRIC_RATOV;
- port_params.ed_tov = UNF_DEFAULT_EDTOV;
-
- /* Update parameters with Fabric mode */
- if (unf_lport->act_topo == UNF_ACT_TOP_PUBLIC_LOOP ||
- unf_lport->act_topo == UNF_ACT_TOP_P2P_FABRIC) {
- unf_lport->ra_tov = port_params.ra_tov;
- unf_lport->ed_tov = port_params.ed_tov;
- }
-
- return RETURN_OK;
-}
-
-u32 unf_lport_enter_flogi(struct unf_lport *lport)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_cm_event_report *event = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 nport_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* Get (safe) R_Port */
- nport_id = UNF_FC_FID_FLOGI;
- unf_rport = unf_get_rport_by_nport_id(lport, UNF_FC_FID_FLOGI);
-
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY, nport_id);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) allocate RPort failed",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Updtae L_Port state */
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- unf_lport_state_ma(lport, UNF_EVENT_LPORT_NORMAL_ENTER);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- /* Update R_Port N_Port_ID */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = UNF_FC_FID_FLOGI;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- event = unf_get_one_event_node(lport);
- if (event) {
- event->lport = lport;
- event->event_asy_flag = UNF_EVENT_ASYN;
- event->unf_event_task = unf_get_port_params;
- event->para_in = (void *)lport;
- unf_post_one_event_node(lport, event);
- }
-
- if (lport->root_lport != lport) {
- /* for NPIV */
- ret = unf_send_fdisc(lport, unf_rport);
- if (ret != RETURN_OK)
- unf_lport_error_recovery(lport);
- } else {
- /* for Physical Port */
- ret = unf_send_flogi(lport, unf_rport);
- if (ret != RETURN_OK)
- unf_lport_error_recovery(lport);
- }
-
- return ret;
-}
-
-void unf_set_lport_state(struct unf_lport *lport, enum unf_lport_login_state state)
-{
- FC_CHECK_RETURN_VOID(lport);
- if (lport->states != state)
- lport->retries = 0;
-
- lport->states = state;
-}
-
-static void unf_lport_timeout(struct work_struct *work)
-{
- struct unf_lport *unf_lport = NULL;
- enum unf_lport_login_state state = UNF_LPORT_ST_READY;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(work);
- unf_lport = container_of(work, struct unf_lport, retry_work.work);
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- state = unf_lport->states;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) is timeout with state(0x%x)",
- unf_lport->port_id, state);
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- switch (state) {
- /* FLOGI retry */
- case UNF_LPORT_ST_FLOGI_WAIT:
- (void)unf_lport_retry_flogi(unf_lport);
- break;
-
- case UNF_LPORT_ST_PLOGI_WAIT:
- case UNF_LPORT_ST_RFT_ID_WAIT:
- case UNF_LPORT_ST_RFF_ID_WAIT:
- case UNF_LPORT_ST_SCR_WAIT:
- (void)unf_lport_name_server_register(unf_lport, state);
- break;
-
- /* Send LOGO External */
- case UNF_LPORT_ST_LOGO:
- break;
-
- /* Do nothing */
- case UNF_LPORT_ST_OFFLINE:
- case UNF_LPORT_ST_READY:
- case UNF_LPORT_ST_RESET:
- case UNF_LPORT_ST_ONLINE:
- case UNF_LPORT_ST_INITIAL:
- case UNF_LPORT_ST_LINK_UP:
-
- unf_lport->retries = 0;
- break;
- default:
- break;
- }
-
- unf_lport_ref_dec_to_destroy(unf_lport);
-}
-
-static void unf_lport_config(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- INIT_DELAYED_WORK(&lport->retry_work, unf_lport_timeout);
-
- lport->max_retry_count = UNF_MAX_RETRY_COUNT;
- lport->retries = 0;
-}
-
-void unf_lport_error_recovery(struct unf_lport *lport)
-{
- ulong delay = 0;
- ulong flag = 0;
- int ret_val = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
-
- ret = unf_lport_ref_inc(lport);
- if (unlikely(ret != RETURN_OK)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) is removing and no need process",
- lport->port_id);
- return;
- }
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
-
- /* Port State: removing */
- if (lport->port_removing) {
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) is removing and no need process",
- lport->port_id);
-
- unf_lport_ref_dec_to_destroy(lport);
- return;
- }
-
- /* Port State: offline */
- if (lport->states == UNF_LPORT_ST_OFFLINE) {
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) is offline and no need process",
- lport->port_id);
-
- unf_lport_ref_dec_to_destroy(lport);
- return;
- }
-
- /* Queue work state check */
- if (delayed_work_pending(&lport->retry_work)) {
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- unf_lport_ref_dec_to_destroy(lport);
- return;
- }
-
- /* Do retry operation */
- if (lport->retries < lport->max_retry_count) {
- lport->retries++;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) enter recovery and retry %u times",
- lport->port_id, lport->nport_id, lport->retries);
-
- delay = (ulong)lport->ed_tov;
- ret_val = queue_delayed_work(unf_wq, &lport->retry_work,
- (ulong)msecs_to_jiffies((u32)delay));
- if (ret_val != 0) {
- atomic_inc(&lport->port_ref_cnt);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) queue work success and reference count is %d",
- lport->port_id,
- atomic_read(&lport->port_ref_cnt));
- }
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
- } else {
- unf_lport_state_ma(lport, UNF_EVENT_LPORT_REMOTE_TIMEOUT);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) register operation timeout and do LOGO",
- lport->port_id);
-
- (void)unf_lport_enter_sns_logo(lport, NULL);
- }
-
- unf_lport_ref_dec_to_destroy(lport);
-}
-
-struct unf_lport *unf_cm_lookup_vport_by_vp_index(struct unf_lport *lport, u16 vp_index)
-{
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- if (vp_index == 0)
- return lport;
-
- if (!lport->lport_mgr_temp.unf_look_up_vport_by_index) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) function do look up vport by index is NULL",
- lport->port_id);
-
- return NULL;
- }
-
- return lport->lport_mgr_temp.unf_look_up_vport_by_index(lport, vp_index);
-}
-
-struct unf_lport *unf_cm_lookup_vport_by_did(struct unf_lport *lport, u32 did)
-{
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- if (!lport->lport_mgr_temp.unf_look_up_vport_by_did) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) function do look up vport by D_ID is NULL",
- lport->port_id);
-
- return NULL;
- }
-
- return lport->lport_mgr_temp.unf_look_up_vport_by_did(lport, did);
-}
-
-struct unf_lport *unf_cm_lookup_vport_by_wwpn(struct unf_lport *lport, u64 wwpn)
-{
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- if (!lport->lport_mgr_temp.unf_look_up_vport_by_wwpn) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) function do look up vport by WWPN is NULL",
- lport->port_id);
-
- return NULL;
- }
-
- return lport->lport_mgr_temp.unf_look_up_vport_by_wwpn(lport, wwpn);
-}
-
-void unf_cm_vport_remove(struct unf_lport *vport)
-{
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(vport);
- unf_lport = vport->root_lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- if (!unf_lport->lport_mgr_temp.unf_vport_remove) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) function do vport remove is NULL",
- unf_lport->port_id);
- return;
- }
-
- unf_lport->lport_mgr_temp.unf_vport_remove(vport);
-}
diff --git a/drivers/scsi/spfc/common/unf_lport.h b/drivers/scsi/spfc/common/unf_lport.h
deleted file mode 100644
index dbd531f15b13..000000000000
--- a/drivers/scsi/spfc/common/unf_lport.h
+++ /dev/null
@@ -1,519 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_LPORT_H
-#define UNF_LPORT_H
-
-#include "unf_type.h"
-#include "unf_disc.h"
-#include "unf_event.h"
-#include "unf_common.h"
-
-#define UNF_PORT_TYPE_FC 0
-#define UNF_PORT_TYPE_DISC 1
-#define UNF_FW_UPDATE_PATH_LEN_MAX 255
-#define UNF_EXCHG_MGR_NUM (4)
-#define UNF_ERR_CODE_PRINT_TIME 10 /* error code print times */
-#define UNF_MAX_IO_TYPE_STAT_NUM 48 /* IO abnormal max counter */
-#define UNF_MAX_IO_RETURN_VALUE 0x12
-#define UNF_MAX_SCSI_CMD 0xFF
-#define UNF_MAX_LPRT_SCSI_ID_MAP 2048
-
-enum unf_scsi_error_handle_type {
- UNF_SCSI_ABORT_IO_TYPE = 0,
- UNF_SCSI_DEVICE_RESET_TYPE,
- UNF_SCSI_TARGET_RESET_TYPE,
- UNF_SCSI_BUS_RESET_TYPE,
- UNF_SCSI_HOST_RESET_TYPE,
- UNF_SCSI_VIRTUAL_RESET_TYPE,
- UNF_SCSI_ERROR_HANDLE_BUTT
-};
-
-enum unf_lport_destroy_step {
- UNF_LPORT_DESTROY_STEP_0_SET_REMOVING = 0,
- UNF_LPORT_DESTROY_STEP_1_REPORT_PORT_OUT,
- UNF_LPORT_DESTROY_STEP_2_CLOSE_ROUTE,
- UNF_LPORT_DESTROY_STEP_3_DESTROY_EVENT_CENTER,
- UNF_LPORT_DESTROY_STEP_4_DESTROY_EXCH_MGR,
- UNF_LPORT_DESTROY_STEP_5_DESTROY_ESGL_POOL,
- UNF_LPORT_DESTROY_STEP_6_DESTROY_DISC_MGR,
- UNF_LPORT_DESTROY_STEP_7_DESTROY_XCHG_MGR_TMP,
- UNF_LPORT_DESTROY_STEP_8_DESTROY_RPORT_MG_TMP,
- UNF_LPORT_DESTROY_STEP_9_DESTROY_LPORT_MG_TMP,
- UNF_LPORT_DESTROY_STEP_10_DESTROY_SCSI_TABLE,
- UNF_LPORT_DESTROY_STEP_11_UNREG_TGT_HOST,
- UNF_LPORT_DESTROY_STEP_12_UNREG_SCSI_HOST,
- UNF_LPORT_DESTROY_STEP_13_DESTROY_LW_INTERFACE,
- UNF_LPORT_DESTROY_STEP_BUTT
-};
-
-enum unf_lport_enhanced_feature {
- /* Enhance GFF feature connect even if fail to get GFF feature */
- UNF_LPORT_ENHANCED_FEATURE_ENHANCED_GFF = 0x0001,
- UNF_LPORT_ENHANCED_FEATURE_IO_TRANSFERLIST = 0x0002, /* Enhance IO balance */
- UNF_LPORT_ENHANCED_FEATURE_IO_CHECKPOINT = 0x0004, /* Enhance IO check */
- UNF_LPORT_ENHANCED_FEATURE_CLOSE_FW_ROUTE = 0x0008, /* Close FW ROUTE */
- /* lowest frequency read SFP information */
- UNF_LPORT_ENHANCED_FEATURE_READ_SFP_ONCE = 0x0010,
- UNF_LPORT_ENHANCED_FEATURE_BUTT
-};
-
-enum unf_lport_login_state {
- UNF_LPORT_ST_ONLINE = 0x2000, /* uninitialized */
- UNF_LPORT_ST_INITIAL, /* initialized and LinkDown */
- UNF_LPORT_ST_LINK_UP, /* initialized and Link UP */
- UNF_LPORT_ST_FLOGI_WAIT, /* waiting for FLOGI completion */
- UNF_LPORT_ST_PLOGI_WAIT, /* waiting for PLOGI completion */
- UNF_LPORT_ST_RNN_ID_WAIT, /* waiting for RNN_ID completion */
- UNF_LPORT_ST_RSNN_NN_WAIT, /* waiting for RSNN_NN completion */
- UNF_LPORT_ST_RSPN_ID_WAIT, /* waiting for RSPN_ID completion */
- UNF_LPORT_ST_RPN_ID_WAIT, /* waiting for RPN_ID completion */
- UNF_LPORT_ST_RFT_ID_WAIT, /* waiting for RFT_ID completion */
- UNF_LPORT_ST_RFF_ID_WAIT, /* waiting for RFF_ID completion */
- UNF_LPORT_ST_SCR_WAIT, /* waiting for SCR completion */
- UNF_LPORT_ST_READY, /* ready for use */
- UNF_LPORT_ST_LOGO, /* waiting for LOGO completion */
- UNF_LPORT_ST_RESET, /* being reset and will restart */
- UNF_LPORT_ST_OFFLINE, /* offline */
- UNF_LPORT_ST_BUTT
-};
-
-enum unf_lport_event {
- UNF_EVENT_LPORT_NORMAL_ENTER = 0x8000, /* next state enter */
- UNF_EVENT_LPORT_ONLINE = 0x8001, /* LPort link up */
- UNF_EVENT_LPORT_LINK_UP = 0x8002, /* LPort link up */
- UNF_EVENT_LPORT_LINK_DOWN = 0x8003, /* LPort link down */
- UNF_EVENT_LPORT_OFFLINE = 0x8004, /* lPort bing stopped */
- UNF_EVENT_LPORT_RESET = 0x8005,
- UNF_EVENT_LPORT_REMOTE_ACC = 0x8006, /* next state enter */
- UNF_EVENT_LPORT_REMOTE_RJT = 0x8007, /* rport reject */
- UNF_EVENT_LPORT_REMOTE_TIMEOUT = 0x8008, /* rport time out */
- UNF_EVENT_LPORT_READY = 0x8009,
- UNF_EVENT_LPORT_REMOTE_BUTT
-};
-
-struct unf_cm_disc_mg_template {
- /* start input:L_Port,return:ok/fail */
- u32 (*unf_disc_start)(void *lport);
- /* stop input: L_Port,return:ok/fail */
- u32 (*unf_disc_stop)(void *lport);
-
- /* Callback after disc complete[with event:ok/fail]. */
- void (*unf_disc_callback)(void *lport, u32 result);
-};
-
-struct unf_chip_manage_info {
- struct list_head list_chip_thread_entry;
- struct list_head list_head;
- spinlock_t chip_event_list_lock;
- struct task_struct *thread;
- u32 list_num;
- u32 slot_id;
- u8 chip_id;
- u8 rsv;
- u8 sfp_9545_fault;
- u8 sfp_power_fault;
- atomic_t ref_cnt;
- u32 thread_exit;
- struct unf_chip_info chip_info;
- atomic_t card_loop_test_flag;
- spinlock_t card_loop_back_state_lock;
- char update_path[UNF_FW_UPDATE_PATH_LEN_MAX];
-};
-
-enum unf_timer_type {
- UNF_TIMER_TYPE_TGT_IO,
- UNF_TIMER_TYPE_INI_IO,
- UNF_TIMER_TYPE_REQ_IO,
- UNF_TIMER_TYPE_TGT_RRQ,
- UNF_TIMER_TYPE_INI_RRQ,
- UNF_TIMER_TYPE_SFS,
- UNF_TIMER_TYPE_INI_ABTS
-};
-
-struct unf_cm_xchg_mgr_template {
- void *(*unf_xchg_get_free_and_init)(void *lport, u32 xchg_type);
- void *(*unf_look_up_xchg_by_id)(void *lport, u16 ox_id, u32 oid);
- void *(*unf_look_up_xchg_by_tag)(void *lport, u16 hot_pool_tag);
- void (*unf_xchg_release)(void *lport, void *xchg);
- void (*unf_xchg_mgr_io_xchg_abort)(void *lport, void *rport, u32 sid, u32 did,
- u32 extra_io_state);
- void (*unf_xchg_mgr_sfs_xchg_abort)(void *lport, void *rport, u32 sid, u32 did);
- void (*unf_xchg_add_timer)(void *xchg, ulong time_ms, enum unf_timer_type time_type);
- void (*unf_xchg_cancel_timer)(void *xchg);
- void (*unf_xchg_abort_all_io)(void *lport, u32 xchg_type, bool clean);
- void *(*unf_look_up_xchg_by_cmnd_sn)(void *lport, u64 command_sn,
- u32 world_id, void *pinitiator);
- void (*unf_xchg_abort_by_lun)(void *lport, void *rport, u64 lun_id, void *xchg,
- bool abort_all_lun_flag);
-
- void (*unf_xchg_abort_by_session)(void *lport, void *rport);
-};
-
-struct unf_cm_lport_template {
- void *(*unf_look_up_vport_by_index)(void *lport, u16 vp_index);
- void *(*unf_look_up_vport_by_port_id)(void *lport, u32 port_id);
- void *(*unf_look_up_vport_by_wwpn)(void *lport, u64 wwpn);
- void *(*unf_look_up_vport_by_did)(void *lport, u32 did);
- void (*unf_vport_remove)(void *vport);
-};
-
-struct unf_lport_state_ma {
- enum unf_lport_login_state lport_state;
- enum unf_lport_login_state (*lport_state_ma)(enum unf_lport_login_state old_state,
- enum unf_lport_event event);
-};
-
-struct unf_rport_pool {
- u32 rport_pool_count;
- void *rport_pool_add;
- struct list_head list_rports_pool;
- spinlock_t rport_free_pool_lock;
- /* for synchronous reuse RPort POOL completion */
- struct completion *rport_pool_completion;
- ulong *rpi_bitmap;
-};
-
-struct unf_vport_pool {
- u16 vport_pool_count;
- void *vport_pool_addr;
- struct list_head list_vport_pool;
- spinlock_t vport_pool_lock;
- struct completion *vport_pool_completion;
- u16 slab_next_index; /* Next free vport */
- u16 slab_total_sum; /* Total Vport num */
- struct unf_lport *vport_slab[ARRAY_INDEX_0];
-};
-
-struct unf_esgl_pool {
- u32 esgl_pool_count;
- void *esgl_pool_addr;
- struct list_head list_esgl_pool;
- spinlock_t esgl_pool_lock;
- struct buf_describe esgl_buff_list;
-};
-
-/* little endium */
-struct unf_port_id_page {
- struct list_head list_node_rscn;
- u8 port_id_port;
- u8 port_id_area;
- u8 port_id_domain;
- u8 addr_format : 2;
- u8 event_qualifier : 4;
- u8 reserved : 2;
-};
-
-struct unf_rscn_mgr {
- spinlock_t rscn_id_list_lock;
- u32 free_rscn_count;
- struct list_head list_free_rscn_page;
- struct list_head list_using_rscn_page;
- void *rscn_pool_add;
- struct unf_port_id_page *(*unf_get_free_rscn_node)(void *rscn_mg);
- void (*unf_release_rscn_node)(void *rscn_mg, void *rscn_node);
-};
-
-struct unf_disc_rport_mg {
- void *disc_pool_add;
- struct list_head list_disc_rports_pool;
- struct list_head list_disc_rports_busy;
-};
-
-struct unf_disc_manage_info {
- struct list_head list_head;
- spinlock_t disc_event_list_lock;
- atomic_t disc_contrl_size;
-
- u32 thread_exit;
- struct task_struct *thread;
-};
-
-struct unf_disc {
- u32 retry_count;
- u32 max_retry_count;
- u32 disc_flag;
-
- struct completion *disc_completion;
- atomic_t disc_ref_cnt;
-
- struct list_head list_busy_rports;
- struct list_head list_delete_rports;
- struct list_head list_destroy_rports;
-
- spinlock_t rport_busy_pool_lock;
-
- struct unf_lport *lport;
- enum unf_disc_state states;
- struct delayed_work disc_work;
-
- /* Disc operation template */
- struct unf_cm_disc_mg_template disc_temp;
-
- /* UNF_INIT_DISC/UNF_RSCN_DISC */
- u32 disc_option;
-
- /* RSCN list */
- struct unf_rscn_mgr rscn_mgr;
- struct unf_disc_rport_mg disc_rport_mgr;
- struct unf_disc_manage_info disc_thread_info;
-
- u64 last_disc_jiff;
-};
-
-enum unf_service_item {
- UNF_SERVICE_ITEM_FLOGI = 0,
- UNF_SERVICE_ITEM_PLOGI,
- UNF_SERVICE_ITEM_PRLI,
- UNF_SERVICE_ITEM_RSCN,
- UNF_SERVICE_ITEM_ABTS,
- UNF_SERVICE_ITEM_PDISC,
- UNF_SERVICE_ITEM_ADISC,
- UNF_SERVICE_ITEM_LOGO,
- UNF_SERVICE_ITEM_SRR,
- UNF_SERVICE_ITEM_RRQ,
- UNF_SERVICE_ITEM_ECHO,
- UNF_SERVICE_BUTT
-};
-
-/* Link service counter */
-struct unf_link_service_collect {
- u64 service_cnt[UNF_SERVICE_BUTT];
-};
-
-struct unf_pcie_error_count {
- u32 pcie_error_count[UNF_PCIE_BUTT];
-};
-
-#define INVALID_WWPN 0
-
-enum unf_device_scsi_state {
- UNF_SCSI_ST_INIT = 0,
- UNF_SCSI_ST_OFFLINE,
- UNF_SCSI_ST_ONLINE,
- UNF_SCSI_ST_DEAD,
- UNF_SCSI_ST_BUTT
-};
-
-struct unf_wwpn_dfx_counter_info {
- atomic64_t io_done_cnt[UNF_MAX_IO_RETURN_VALUE];
- atomic64_t scsi_cmd_cnt[UNF_MAX_SCSI_CMD];
- atomic64_t target_busy;
- atomic64_t host_busy;
- atomic_t error_handle[UNF_SCSI_ERROR_HANDLE_BUTT];
- atomic_t error_handle_result[UNF_SCSI_ERROR_HANDLE_BUTT];
- atomic_t device_alloc;
- atomic_t device_destroy;
-};
-
-#define UNF_MAX_LUN_PER_TARGET 256
-struct unf_wwpn_rport_info {
- u64 wwpn;
- struct unf_rport *rport; /* Rport which linkup */
- void *lport; /* Lport */
- u32 target_id; /* target_id distribute by scsi */
- u32 las_ten_scsi_state;
- atomic_t scsi_state;
- struct unf_wwpn_dfx_counter_info *dfx_counter;
- struct delayed_work loss_tmo_work;
- bool need_scan;
- struct list_head fc_lun_list;
- u8 *lun_qos_level;
-};
-
-struct unf_rport_scsi_id_image {
- spinlock_t scsi_image_table_lock;
- struct unf_wwpn_rport_info
- *wwn_rport_info_table;
- u32 max_scsi_id;
-};
-
-enum unf_lport_dirty_flag {
- UNF_LPORT_DIRTY_FLAG_NONE = 0,
- UNF_LPORT_DIRTY_FLAG_XCHGMGR_DIRTY = 0x100,
- UNF_LPORT_DIRTY_FLAG_RPORT_POOL_DIRTY = 0x200,
- UNF_LPORT_DIRTY_FLAG_DISC_DIRTY = 0x400,
- UNF_LPORT_DIRTY_FLAG_BUTT
-};
-
-typedef struct unf_rport *(*unf_rport_set_qualifier)(struct unf_lport *lport,
- struct unf_rport *rport_by_nport_id,
- struct unf_rport *rport_by_wwpn,
- u64 wwpn, u32 sid);
-
-typedef u32 (*unf_tmf_status_recovery)(void *rport, void *xchg);
-
-enum unf_start_work_state {
- UNF_START_WORK_STOP,
- UNF_START_WORK_BEGIN,
- UNF_START_WORK_COMPLETE
-};
-
-struct unf_qos_info {
- u64 wwpn;
- u32 nport_id;
- enum unf_rport_qos_level qos_level;
- struct list_head entry_qos_info;
-};
-
-struct unf_ini_private_info {
- u32 driver_type; /* Driver Type */
- void *lower; /* driver private pointer */
-};
-
-struct unf_product_host_info {
- void *tgt_host;
- struct Scsi_Host *host;
- struct unf_ini_private_info drv_private_info;
- struct Scsi_Host scsihost;
-};
-
-struct unf_lport {
- u32 port_type; /* Port Type, fc or fcoe */
- atomic_t port_ref_cnt; /* LPort reference counter */
- void *fc_port; /* hard adapter hba pointer */
- void *rport, *drport; /* Used for SCSI interface */
- void *vport;
- ulong system_io_bus_num;
-
- struct unf_product_host_info host_info; /* scsi host mg */
- struct unf_rport_scsi_id_image rport_scsi_table;
- bool port_removing;
- bool io_allowed;
- bool port_dirt_exchange;
-
- spinlock_t xchg_mgr_lock;
- struct list_head list_xchg_mgr_head;
- struct list_head list_drty_xchg_mgr_head;
- void *xchg_mgr[UNF_EXCHG_MGR_NUM];
- bool qos_cs_ctrl;
- bool priority;
- enum unf_rport_qos_level qos_level;
- spinlock_t qos_mgr_lock;
- struct list_head list_qos_head;
- struct list_head list_vports_head; /* Vport Mg */
- struct list_head list_intergrad_vports; /* Vport intergrad list */
- struct list_head list_destroy_vports; /* Vport destroy list */
-
- struct list_head entry_vport; /* VPort entry, hook in list_vports_head */
-
- struct list_head entry_lport; /* LPort entry */
- spinlock_t lport_state_lock; /* UL Port Lock */
- struct unf_disc disc; /* Disc and rport Mg */
- struct unf_rport_pool rport_pool; /* rport pool,Vport share Lport pool */
- struct unf_esgl_pool esgl_pool; /* external sgl pool */
- u32 port_id; /* Port Management ,0x11000 etc. */
- enum unf_lport_login_state states;
- u32 link_up;
- u32 speed;
-
- u64 node_name;
- u64 port_name;
- u64 fabric_node_name;
- u32 nport_id;
- u32 max_frame_size;
- u32 ed_tov;
- u32 ra_tov;
- u32 class_of_service;
- u32 options; /* ini or tgt */
- u32 retries;
- u32 max_retry_count;
- enum unf_act_topo act_topo;
- bool switch_state; /* TRUE---->ON,false---->OFF */
- bool last_switch_state; /* TRUE---->ON,false---->OFF */
- bool bbscn_support; /* TRUE---->ON,false---->OFF */
-
- enum unf_start_work_state start_work_state;
- struct unf_cm_xchg_mgr_template xchg_mgr_temp; /* Xchg Mg operation template */
- struct unf_cm_lport_template lport_mgr_temp; /* Xchg LPort operation template */
- struct unf_low_level_functioon_op low_level_func;
- struct unf_event_mgr event_mgr; /* Disc and rport Mg */
- struct delayed_work retry_work; /* poll work or delay work */
-
- struct workqueue_struct *link_event_wq;
- struct workqueue_struct *xchg_wq;
- atomic64_t io_stat[UNF_MAX_IO_TYPE_STAT_NUM];
- struct unf_err_code err_code_sum; /* Error code counter */
- struct unf_port_dynamic_info port_dynamic_info;
- struct unf_link_service_collect link_service_info;
- struct unf_pcie_error_count pcie_error_cnt;
- unf_rport_set_qualifier unf_qualify_rport; /* Qualify Rport */
-
- unf_tmf_status_recovery unf_tmf_abnormal_recovery; /* tmf marker recovery */
-
- struct delayed_work route_timer_work; /* L_Port timer route */
-
- u16 vp_index; /* Vport Index, Lport:0 */
- u16 path_id;
- struct unf_vport_pool *vport_pool; /* Only for Lport */
- void *lport_mgr[UNF_MAX_LPRT_SCSI_ID_MAP];
- bool vport_remove_flags;
-
- void *root_lport; /* Point to physic Lport */
-
- struct completion *lport_free_completion; /* Free LPort Completion */
-
-#define UNF_LPORT_NOP 1
-#define UNF_LPORT_NORMAL 0
-
- atomic_t lport_no_operate_flag;
-
- bool loop_back_test_mode;
- bool switch_state_before_test_mode; /* TRUE---->ON,false---->OFF */
- u32 enhanced_features; /* Enhanced Features */
-
- u32 destroy_step;
- u32 dirty_flag;
- struct unf_chip_manage_info *chip_info;
-
- u8 unique_position;
- u8 sfp_power_fault_count;
- u8 sfp_9545_fault_count;
- u64 last_tx_fault_jif; /* SFP last tx fault jiffies */
- u32 target_cnt;
- /* Server card: UNF_FC_SERVER_BOARD_32_G(6) for 32G mode,
- * UNF_FC_SERVER_BOARD_16_G(7) for 16G mode
- */
- u32 card_type;
- atomic_t scsi_session_add_success;
- atomic_t scsi_session_add_failed;
- atomic_t scsi_session_del_success;
- atomic_t scsi_session_del_failed;
- atomic_t add_start_work_failed;
- atomic_t add_closing_work_failed;
- atomic_t device_alloc;
- atomic_t device_destroy;
- atomic_t session_loss_tmo;
- atomic_t alloc_scsi_id;
- atomic_t resume_scsi_id;
- atomic_t reuse_scsi_id;
- atomic64_t last_exchg_mgr_idx;
- atomic_t host_no;
- atomic64_t exchg_index;
- int scan_world_id;
- struct semaphore wmi_task_sema;
- bool ready_to_remove;
- u32 pcie_link_down_cnt;
- bool pcie_link_down;
- u8 fw_version[SPFC_VER_LEN];
- atomic_t link_lose_tmo;
- u32 max_ssq_num;
-};
-
-void unf_lport_state_ma(struct unf_lport *lport, enum unf_lport_event lport_event);
-void unf_lport_error_recovery(struct unf_lport *lport);
-void unf_set_lport_state(struct unf_lport *lport, enum unf_lport_login_state state);
-void unf_init_port_parms(struct unf_lport *lport);
-u32 unf_lport_enter_flogi(struct unf_lport *lport);
-void unf_lport_enter_sns_plogi(struct unf_lport *lport);
-u32 unf_init_disc_mgr(struct unf_lport *lport);
-u32 unf_init_lport_route(struct unf_lport *lport);
-void unf_destroy_lport_route(struct unf_lport *lport);
-void unf_reset_lport_params(struct unf_lport *lport);
-void unf_cm_mark_dirty_mem(struct unf_lport *lport, enum unf_lport_dirty_flag type);
-struct unf_lport *unf_cm_lookup_vport_by_vp_index(struct unf_lport *lport, u16 vp_index);
-struct unf_lport *unf_cm_lookup_vport_by_did(struct unf_lport *lport, u32 did);
-struct unf_lport *unf_cm_lookup_vport_by_wwpn(struct unf_lport *lport, u64 wwpn);
-void unf_cm_vport_remove(struct unf_lport *vport);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_ls.c b/drivers/scsi/spfc/common/unf_ls.c
deleted file mode 100644
index 6a2e1fd1872f..000000000000
--- a/drivers/scsi/spfc/common/unf_ls.c
+++ /dev/null
@@ -1,4883 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_ls.h"
-#include "unf_log.h"
-#include "unf_service.h"
-#include "unf_portman.h"
-#include "unf_gs.h"
-#include "unf_npiv.h"
-
-static void unf_flogi_acc_ob_callback(struct unf_xchg *xchg);
-static void unf_plogi_acc_ob_callback(struct unf_xchg *xchg);
-static void unf_prli_acc_ob_callback(struct unf_xchg *xchg);
-static void unf_rscn_acc_ob_callback(struct unf_xchg *xchg);
-static void unf_pdisc_acc_ob_callback(struct unf_xchg *xchg);
-static void unf_adisc_acc_ob_callback(struct unf_xchg *xchg);
-static void unf_logo_acc_ob_callback(struct unf_xchg *xchg);
-static void unf_logo_ob_callback(struct unf_xchg *xchg);
-static void unf_logo_callback(void *lport, void *rport, void *xchg);
-static void unf_rrq_callback(void *lport, void *rport, void *xchg);
-static void unf_rrq_ob_callback(struct unf_xchg *xchg);
-static void unf_lport_update_nport_id(struct unf_lport *lport, u32 nport_id);
-static void
-unf_lport_update_time_params(struct unf_lport *lport,
- struct unf_flogi_fdisc_payload *flogi_payload);
-
-static void unf_login_with_rport_in_n2n(struct unf_lport *lport,
- u64 remote_port_name,
- u64 remote_node_name);
-#define UNF_LOWLEVEL_BBCREDIT 0x6
-#define UNF_DEFAULT_BB_SC_N 0
-
-#define UNF_ECHO_REQ_SIZE 0
-#define UNF_ECHO_WAIT_SEM_TIMEOUT(lport) (2 * (ulong)(lport)->ra_tov)
-
-#define UNF_SERVICE_COLLECT(service_collect, item) \
- do { \
- if ((item) < UNF_SERVICE_BUTT) { \
- (service_collect).service_cnt[(item)]++; \
- } \
- } while (0)
-
-static void unf_check_rport_need_delay_prli(struct unf_lport *lport,
- struct unf_rport *rport,
- u32 port_feature)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- port_feature &= UNF_PORT_MODE_BOTH;
-
- /* Used for: L_Port has INI mode & R_Port is not SW */
- if (rport->nport_id < UNF_FC_FID_DOM_MGR) {
- /*
- * 1. immediately: R_Port only with TGT, or
- * L_Port only with INI & R_Port has TGT mode, send PRLI
- * immediately
- */
- if ((port_feature == UNF_PORT_MODE_TGT ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) ||
- (UNF_PORT_MODE_TGT == (port_feature & UNF_PORT_MODE_TGT))) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) Rport(0x%x) with feature(0x%x) send PRLI",
- lport->port_id, lport->nport_id,
- rport->nport_id, port_feature);
- ret = unf_send_prli(lport, rport, ELS_PRLI);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) Rport(0x%x) with feature(0x%x) send PRLI failed",
- lport->port_id, lport->nport_id,
- rport->nport_id, port_feature);
-
- unf_rport_error_recovery(rport);
- }
- }
- /* 2. R_Port has BOTH mode or unknown, Delay to send PRLI */
- else if (port_feature != UNF_PORT_MODE_INI) {
- /* Prevent: PRLI done before PLOGI */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) Rport(0x%x) with feature(0x%x) delay to send PRLI",
- lport->port_id, lport->nport_id,
- rport->nport_id, port_feature);
-
- /* Delay to send PRLI to R_Port */
- unf_rport_delay_login(rport);
- } else {
- /* 3. R_Port only with INI mode: wait for R_Port's PRLI:
- * Do not care
- */
- /* Cancel recovery(timer) work */
- if (delayed_work_pending(&rport->recovery_work)) {
- if (cancel_delayed_work(&rport->recovery_work)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Port(0x%x_0x%x) Rport(0x%x) with feature(0x%x) is pure INI",
- lport->port_id,
- lport->nport_id,
- rport->nport_id,
- port_feature);
-
- unf_rport_ref_dec(rport);
- }
- }
-
- /* Server: R_Port only support INI, do not care this
- * case
- */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x) Rport(0x%x) with feature(0x%x) wait for PRLI",
- lport->port_id, lport->nport_id,
- rport->nport_id, port_feature);
- }
- }
-}
-
-static u32 unf_low_level_bb_credit(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 bb_credit = UNF_LOWLEVEL_BBCREDIT;
-
- if (unlikely(!lport))
- return bb_credit;
-
- unf_lport = lport;
-
- if (unlikely(!unf_lport->low_level_func.port_mgr_op.ll_port_config_get))
- return bb_credit;
-
- ret = unf_lport->low_level_func.port_mgr_op.ll_port_config_get((void *)unf_lport->fc_port,
- UNF_PORT_CFG_GET_WORKBALE_BBCREDIT,
- (void *)&bb_credit);
- if (unlikely(ret != RETURN_OK)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[warn]Port(0x%x) get BB_Credit failed, use default value(%d)",
- unf_lport->port_id, UNF_LOWLEVEL_BBCREDIT);
-
- bb_credit = UNF_LOWLEVEL_BBCREDIT;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) with BB_Credit(%u)", unf_lport->port_id,
- bb_credit);
-
- return bb_credit;
-}
-
-u32 unf_low_level_bb_scn(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_low_level_port_mgr_op *port_mgr = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 bb_scn = UNF_DEFAULT_BB_SC_N;
-
- if (unlikely(!lport))
- return bb_scn;
-
- unf_lport = lport;
- port_mgr = &unf_lport->low_level_func.port_mgr_op;
-
- if (unlikely(!port_mgr->ll_port_config_get))
- return bb_scn;
-
- ret = port_mgr->ll_port_config_get((void *)unf_lport->fc_port,
- UNF_PORT_CFG_GET_WORKBALE_BBSCN,
- (void *)&bb_scn);
- if (unlikely(ret != RETURN_OK)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[warn]Port(0x%x) get bbscn failed, use default value(%d)",
- unf_lport->port_id, UNF_DEFAULT_BB_SC_N);
-
- bb_scn = UNF_DEFAULT_BB_SC_N;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x)'s bbscn(%d)", unf_lport->port_id, bb_scn);
-
- return bb_scn;
-}
-
-static void unf_fill_rec_pld(struct unf_rec_pld *rec_pld, u32 sid)
-{
- FC_CHECK_RETURN_VOID(rec_pld);
-
- rec_pld->rec_cmnd = (UNF_ELS_CMND_REC);
- rec_pld->xchg_org_sid = sid;
- rec_pld->ox_id = INVALID_VALUE16;
- rec_pld->rx_id = INVALID_VALUE16;
-}
-
-u32 unf_send_rec(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *io_xchg)
-{
- struct unf_rec_pld *rec_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(io_xchg, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for PLOGI",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_REC;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
- pkg.origin_hottag = io_xchg->hotpooltag;
- pkg.origin_magicnum = io_xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME];
- rec_pld = &fc_entry->rec.rec_pld;
- memset(rec_pld, 0, sizeof(struct unf_rec_pld));
-
- unf_fill_rec_pld(rec_pld, lport->nport_id);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]LOGIN: Send REC %s. Port(0x%x_0x%x_0x%llx)--->RPort(0x%x_0x%llx) with hottag(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- lport->nport_id, lport->port_name, rport->nport_id,
- rport->port_name, xchg->hotpooltag);
-
- return ret;
-}
-
-static void unf_fill_flogi_pld(struct unf_flogi_fdisc_payload *flogi_pld,
- struct unf_lport *lport)
-{
- struct unf_fabric_parm *fabric_parms = NULL;
-
- FC_CHECK_RETURN_VOID(flogi_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- fabric_parms = &flogi_pld->fabric_parms;
- if (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT ||
- lport->act_topo == UNF_TOP_P2P_MASK) {
- /* Fabric or P2P or FCoE VN2VN topology */
- fabric_parms->co_parms.bb_credit = unf_low_level_bb_credit(lport);
- fabric_parms->co_parms.lowest_version = UNF_PLOGI_VERSION_LOWER;
- fabric_parms->co_parms.highest_version = UNF_PLOGI_VERSION_UPPER;
- fabric_parms->co_parms.bb_receive_data_field_size = (lport->max_frame_size);
- fabric_parms->co_parms.bbscn = unf_low_level_bb_scn(lport);
- } else {
- /* Loop topology here */
- fabric_parms->co_parms.clean_address = UNF_CLEAN_ADDRESS_DEFAULT;
- fabric_parms->co_parms.bb_credit = UNF_BBCREDIT_LPORT;
- fabric_parms->co_parms.lowest_version = UNF_PLOGI_VERSION_LOWER;
- fabric_parms->co_parms.highest_version = UNF_PLOGI_VERSION_UPPER;
- fabric_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_LPORT;
- fabric_parms->co_parms.bb_receive_data_field_size = (lport->max_frame_size);
- }
-
- if (lport->low_level_func.support_max_npiv_num != 0)
- /* support NPIV */
- fabric_parms->co_parms.clean_address = 1;
-
- fabric_parms->cl_parms[ARRAY_INDEX_2].valid = UNF_CLASS_VALID;
-
- /* according the user value to set the priority */
- if (lport->qos_cs_ctrl)
- fabric_parms->cl_parms[ARRAY_INDEX_2].priority = UNF_PRIORITY_ENABLE;
- else
- fabric_parms->cl_parms[ARRAY_INDEX_2].priority = UNF_PRIORITY_DISABLE;
-
- fabric_parms->cl_parms[ARRAY_INDEX_2].sequential_delivery = UNF_SEQUEN_DELIVERY_REQ;
- fabric_parms->cl_parms[ARRAY_INDEX_2].received_data_field_size = (lport->max_frame_size);
-
- fabric_parms->high_node_name = UNF_GET_NAME_HIGH_WORD(lport->node_name);
- fabric_parms->low_node_name = UNF_GET_NAME_LOW_WORD(lport->node_name);
- fabric_parms->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- fabric_parms->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
-}
-
-u32 unf_send_flogi(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_xchg *xchg = NULL;
- struct unf_flogi_fdisc_payload *flogi_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for FLOGI",
- lport->port_id);
-
- return ret;
- }
-
- /* FLOGI */
- xchg->cmnd_code = ELS_FLOGI;
-
- /* for rcvd flogi acc/rjt processer */
- xchg->callback = unf_flogi_callback;
- /* for send flogi failed processer */
- xchg->ob_callback = unf_flogi_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- flogi_pld = &fc_entry->flogi.flogi_payload;
- memset(flogi_pld, 0, sizeof(struct unf_flogi_fdisc_payload));
- unf_fill_flogi_pld(flogi_pld, lport);
- flogi_pld->cmnd = (UNF_ELS_CMND_FLOGI);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Begin to send FLOGI. Port(0x%x)--->RPort(0x%x) with hottag(0x%x)",
- lport->port_id, rport->nport_id, xchg->hotpooltag);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, flogi_pld,
- sizeof(struct unf_flogi_fdisc_payload));
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]LOGIN: Send FLOGI failed. Port(0x%x)--->RPort(0x%x)",
- lport->port_id, rport->nport_id);
-
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- }
-
- return ret;
-}
-
-u32 unf_send_fdisc(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_xchg *exch = NULL;
- struct unf_flogi_fdisc_payload *fdisc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- exch = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!exch) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for FDISC",
- lport->port_id);
-
- return ret;
- }
-
- exch->cmnd_code = ELS_FDISC;
-
- exch->callback = unf_fdisc_callback;
- exch->ob_callback = unf_fdisc_ob_callback;
-
- unf_fill_package(&pkg, exch, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- fdisc_pld = &fc_entry->fdisc.fdisc_payload;
- memset(fdisc_pld, 0, sizeof(struct unf_flogi_fdisc_payload));
- unf_fill_flogi_pld(fdisc_pld, lport);
- fdisc_pld->cmnd = UNF_ELS_CMND_FDISC;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, exch);
-
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)exch);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: FDISC send %s. Port(0x%x)--->RPort(0x%x) with hottag(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, exch->hotpooltag);
-
- return ret;
-}
-
-static void unf_fill_plogi_pld(struct unf_plogi_payload *plogi_pld,
- struct unf_lport *lport)
-{
- struct unf_lgn_parm *login_parms = NULL;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(plogi_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport = lport->root_lport;
- plogi_pld->cmnd = (UNF_ELS_CMND_PLOGI);
- login_parms = &plogi_pld->stparms;
-
- if (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- /* P2P or Fabric mode or FCoE VN2VN */
- login_parms->co_parms.bb_credit = (unf_low_level_bb_credit(lport));
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_NFPORT;
- login_parms->co_parms.bbscn =
- (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC)
- ? 0
- : unf_low_level_bb_scn(lport);
- } else {
- /* Public loop & Private loop mode */
- login_parms->co_parms.bb_credit = UNF_BBCREDIT_LPORT;
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_LPORT;
- }
-
- login_parms->co_parms.lowest_version = UNF_PLOGI_VERSION_LOWER;
- login_parms->co_parms.highest_version = UNF_PLOGI_VERSION_UPPER;
- login_parms->co_parms.continuously_increasing = UNF_CONTIN_INCREASE_SUPPORT;
- login_parms->co_parms.bb_receive_data_field_size = (lport->max_frame_size);
- login_parms->co_parms.nport_total_concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->co_parms.relative_offset = (UNF_PLOGI_RO_CATEGORY);
- login_parms->co_parms.e_d_tov = UNF_DEFAULT_EDTOV;
- if (unf_lport->priority == UNF_PRIORITY_ENABLE) {
- login_parms->cl_parms[ARRAY_INDEX_2].priority =
- UNF_PRIORITY_ENABLE;
- } else {
- login_parms->cl_parms[ARRAY_INDEX_2].priority =
- UNF_PRIORITY_DISABLE;
- }
-
- /* for class_3 */
- login_parms->cl_parms[ARRAY_INDEX_2].valid = UNF_CLASS_VALID;
- login_parms->cl_parms[ARRAY_INDEX_2].received_data_field_size = (lport->max_frame_size);
- login_parms->cl_parms[ARRAY_INDEX_2].concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->cl_parms[ARRAY_INDEX_2].open_sequence_per_exchange = (UNF_PLOGI_SEQ_PER_XCHG);
-
- login_parms->high_node_name = UNF_GET_NAME_HIGH_WORD(lport->node_name);
- login_parms->low_node_name = UNF_GET_NAME_LOW_WORD(lport->node_name);
- login_parms->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- login_parms->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, plogi_pld, sizeof(struct unf_plogi_payload));
-}
-
-u32 unf_send_plogi(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_plogi_payload *plogi_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for PLOGI",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_PLOGI;
-
- xchg->callback = unf_plogi_callback;
- xchg->ob_callback = unf_plogi_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
- unf_cm_xchg_mgr_abort_io_by_id(lport, rport, xchg->sid, xchg->did, 0);
-
- plogi_pld = &fc_entry->plogi.payload;
- memset(plogi_pld, 0, sizeof(struct unf_plogi_payload));
- unf_fill_plogi_pld(plogi_pld, lport);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Send PLOGI %s. Port(0x%x_0x%x_0x%llx)--->RPort(0x%x_0x%llx) with hottag(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- lport->nport_id, lport->port_name, rport->nport_id,
- rport->port_name, xchg->hotpooltag);
-
- return ret;
-}
-
-static void unf_fill_logo_pld(struct unf_logo_payload *logo_pld,
- struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(logo_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- logo_pld->cmnd = (UNF_ELS_CMND_LOGO);
- logo_pld->nport_id = (lport->nport_id);
- logo_pld->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- logo_pld->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, logo_pld, sizeof(struct unf_logo_payload));
-}
-
-u32 unf_send_logo(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_logo_payload *logo_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- struct unf_frame_pkg pkg = {0};
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for LOGO",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_LOGO;
- /* retry or link down immediately */
- xchg->callback = unf_logo_callback;
- /* do nothing */
- xchg->ob_callback = unf_logo_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- logo_pld = &fc_entry->logo.payload;
- memset(logo_pld, 0, sizeof(struct unf_logo_payload));
- unf_fill_logo_pld(logo_pld, lport);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- rport->logo_retries++;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]LOGIN: LOGO send %s. Port(0x%x)--->RPort(0x%x) hottag(0x%x) Retries(%d)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, xchg->hotpooltag, rport->logo_retries);
-
- return ret;
-}
-
-u32 unf_send_logo_by_did(struct unf_lport *lport, u32 did)
-{
- struct unf_logo_payload *logo_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- struct unf_frame_pkg pkg = {0};
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, did, NULL, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for LOGO",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_LOGO;
-
- unf_fill_package(&pkg, xchg, NULL);
- pkg.type = UNF_PKG_ELS_REQ;
-
- logo_pld = &fc_entry->logo.payload;
- memset(logo_pld, 0, sizeof(struct unf_logo_payload));
- unf_fill_logo_pld(logo_pld, lport);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: LOGO send %s. Port(0x%x)--->RPort(0x%x) with hottag(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- did, xchg->hotpooltag);
-
- return ret;
-}
-
-static void unf_echo_callback(void *lport, void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
- struct unf_rport *unf_rport = (struct unf_rport *)rport;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_echo_payload *echo_rsp_pld = NULL;
- u32 cmnd = 0;
- u32 mag_ver_local = 0;
- u32 mag_ver_remote = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_xchg = (struct unf_xchg *)xchg;
- if (!unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr)
- return;
-
- echo_rsp_pld = unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo_acc.echo_pld;
- FC_CHECK_RETURN_VOID(echo_rsp_pld);
-
- if (unf_xchg->byte_orders & UNF_BIT_2) {
- unf_big_end_to_cpu((u8 *)echo_rsp_pld, sizeof(struct unf_echo_payload));
- cmnd = echo_rsp_pld->cmnd;
- } else {
- cmnd = echo_rsp_pld->cmnd;
- }
-
- mag_ver_local = echo_rsp_pld->data[ARRAY_INDEX_0];
- mag_ver_remote = echo_rsp_pld->data[ARRAY_INDEX_1];
-
- if (UNF_ELS_CMND_ACC == (cmnd & UNF_ELS_CMND_HIGH_MASK)) {
- if (mag_ver_local == ECHO_MG_VERSION_LOCAL &&
- mag_ver_remote == ECHO_MG_VERSION_REMOTE) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "LPort(0x%x) send ECHO to RPort(0x%x), received ACC. local snd echo:(0x%x), remote rcv echo:(0x%x), remote snd echo acc:(0x%x), local rcv echo acc:(0x%x)",
- unf_lport->port_id, unf_rport->nport_id,
- unf_xchg->private_data[PKG_PRIVATE_ECHO_CMD_SND_TIME],
- unf_xchg->private_data[PKG_PRIVATE_ECHO_CMD_RCV_TIME],
- unf_xchg->private_data[PKG_PRIVATE_ECHO_RSP_SND_TIME],
- unf_xchg->private_data[PKG_PRIVATE_ECHO_ACC_RCV_TIME]);
- } else if ((mag_ver_local == ECHO_MG_VERSION_LOCAL) &&
- (mag_ver_remote != ECHO_MG_VERSION_REMOTE)) {
- /* the peer don't supprt smartping, only local snd and
- * rcv rsp time stamp
- */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "LPort(0x%x) send ECHO to RPort(0x%x), received ACC. local snd echo:(0x%x), local rcv echo acc:(0x%x)",
- unf_lport->port_id, unf_rport->nport_id,
- unf_xchg->private_data[PKG_PRIVATE_ECHO_CMD_SND_TIME],
- unf_xchg->private_data[PKG_PRIVATE_ECHO_ACC_RCV_TIME]);
- } else if ((mag_ver_local != ECHO_MG_VERSION_LOCAL) &&
- (mag_ver_remote != ECHO_MG_VERSION_REMOTE)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR,
- "LPort(0x%x) send ECHO to RPort(0x%x), received ACC. local and remote is not FC HBA",
- unf_lport->port_id, unf_rport->nport_id);
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ECHO to RPort(0x%x) and received RJT",
- unf_lport->port_id, unf_rport->nport_id);
- }
-
- unf_xchg->echo_info.echo_result = UNF_ELS_ECHO_RESULT_OK;
- unf_xchg->echo_info.response_time = jiffies - unf_xchg->echo_info.response_time;
-
- /* wake up semaphore */
- up(&unf_xchg->echo_info.echo_sync_sema);
-}
-
-static void unf_echo_ob_callback(struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
- unf_lport = xchg->lport;
- FC_CHECK_RETURN_VOID(unf_lport);
- unf_rport = xchg->rport;
- FC_CHECK_RETURN_VOID(unf_rport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ECHO to RPort(0x%x) but timeout",
- unf_lport->port_id, unf_rport->nport_id);
-
- xchg->echo_info.echo_result = UNF_ELS_ECHO_RESULT_FAIL;
-
- /* wake up semaphore */
- up(&xchg->echo_info.echo_sync_sema);
-}
-
-u32 unf_send_echo(struct unf_lport *lport, struct unf_rport *rport, u32 *time)
-{
- struct unf_echo_payload *echo_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- struct unf_frame_pkg pkg = {0};
- u32 ret = UNF_RETURN_ERROR;
- ulong delay = 0;
- dma_addr_t phy_echo_addr;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(time, UNF_RETURN_ERROR);
-
- delay = UNF_ECHO_WAIT_SEM_TIMEOUT(lport);
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for ECHO",
- lport->port_id);
-
- return ret;
- }
-
- /* ECHO */
- xchg->cmnd_code = ELS_ECHO;
- xchg->fcp_sfs_union.sfs_entry.cur_offset = UNF_ECHO_REQ_SIZE;
-
- /* Set callback function, wake up semaphore */
- xchg->callback = unf_echo_callback;
- /* wake up semaphore */
- xchg->ob_callback = unf_echo_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- echo_pld = (struct unf_echo_payload *)unf_get_one_big_sfs_buf(xchg);
- if (!echo_pld) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't allocate buffer for ECHO",
- lport->port_id);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- fc_entry->echo.echo_pld = echo_pld;
- phy_echo_addr = pci_map_single(lport->low_level_func.dev, echo_pld,
- UNF_ECHO_PAYLOAD_LEN,
- DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(lport->low_level_func.dev, phy_echo_addr)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) pci map err", lport->port_id);
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
- fc_entry->echo.phy_echo_addr = phy_echo_addr;
- memset(echo_pld, 0, sizeof(struct unf_echo_payload));
- echo_pld->cmnd = (UNF_ELS_CMND_ECHO);
- echo_pld->data[ARRAY_INDEX_0] = ECHO_MG_VERSION_LOCAL;
-
- ret = unf_xchg_ref_inc(xchg, SEND_ELS);
- FC_CHECK_RETURN_VALUE((ret == RETURN_OK), UNF_RETURN_ERROR);
-
- xchg->echo_info.response_time = jiffies;
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK) {
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- } else {
- if (down_timeout(&xchg->echo_info.echo_sync_sema,
- (long)msecs_to_jiffies((u32)delay))) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]ECHO send %s. Port(0x%x)--->RPort(0x%x) but response timeout ",
- (ret != RETURN_OK) ? "failed" : "succeed",
- lport->port_id, rport->nport_id);
-
- xchg->echo_info.echo_result = UNF_ELS_ECHO_RESULT_FAIL;
- }
-
- if (xchg->echo_info.echo_result == UNF_ELS_ECHO_RESULT_FAIL) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR, "Echo send fail or timeout");
-
- ret = UNF_RETURN_ERROR;
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "echo acc rsp,echo_cmd_snd(0x%xus)-->echo_cmd_rcv(0x%xus)-->echo_acc_ snd(0x%xus)-->echo_acc_rcv(0x%xus).",
- xchg->private_data[PKG_PRIVATE_ECHO_CMD_SND_TIME],
- xchg->private_data[PKG_PRIVATE_ECHO_CMD_RCV_TIME],
- xchg->private_data[PKG_PRIVATE_ECHO_RSP_SND_TIME],
- xchg->private_data[PKG_PRIVATE_ECHO_ACC_RCV_TIME]);
-
- *time =
- (xchg->private_data[PKG_PRIVATE_ECHO_ACC_RCV_TIME] -
- xchg->private_data[PKG_PRIVATE_ECHO_CMD_SND_TIME]) -
- (xchg->private_data[PKG_PRIVATE_ECHO_RSP_SND_TIME] -
- xchg->private_data[PKG_PRIVATE_ECHO_CMD_RCV_TIME]);
- }
- }
-
- pci_unmap_single(lport->low_level_func.dev, phy_echo_addr,
- UNF_ECHO_PAYLOAD_LEN, DMA_BIDIRECTIONAL);
- fc_entry->echo.phy_echo_addr = 0;
- unf_xchg_ref_dec(xchg, SEND_ELS);
-
- return ret;
-}
-
-static void unf_fill_prli_pld(struct unf_prli_payload *prli_pld,
- struct unf_lport *lport)
-{
- u32 pld_len = 0;
-
- FC_CHECK_RETURN_VOID(prli_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- pld_len = sizeof(struct unf_prli_payload) - UNF_PRLI_SIRT_EXTRA_SIZE;
- prli_pld->cmnd =
- (UNF_ELS_CMND_PRLI |
- ((u32)UNF_FC4_FRAME_PAGE_SIZE << UNF_FC4_FRAME_PAGE_SIZE_SHIFT) |
- ((u32)pld_len));
-
- prli_pld->parms[ARRAY_INDEX_0] = (UNF_FC4_FRAME_PARM_0_FCP | UNF_FC4_FRAME_PARM_0_I_PAIR);
- prli_pld->parms[ARRAY_INDEX_1] = UNF_NOT_MEANINGFUL;
- prli_pld->parms[ARRAY_INDEX_2] = UNF_NOT_MEANINGFUL;
-
- /* About Read Xfer_rdy disable */
- prli_pld->parms[ARRAY_INDEX_3] = (UNF_FC4_FRAME_PARM_3_R_XFER_DIS | lport->options);
-
- /* About FCP confirm */
- if (lport->low_level_func.lport_cfg_items.fcp_conf)
- prli_pld->parms[ARRAY_INDEX_3] |= UNF_FC4_FRAME_PARM_3_CONF_ALLOW;
-
- /* About Tape support */
- if (lport->low_level_func.lport_cfg_items.tape_support)
- prli_pld->parms[ARRAY_INDEX_3] |=
- (UNF_FC4_FRAME_PARM_3_REC_SUPPORT |
- UNF_FC4_FRAME_PARM_3_RETRY_SUPPORT |
- UNF_FC4_FRAME_PARM_3_TASK_RETRY_ID_SUPPORT |
- UNF_FC4_FRAME_PARM_3_CONF_ALLOW);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x)'s PRLI payload: options(0x%x) parameter-3(0x%x)",
- lport->port_id, lport->options,
- prli_pld->parms[ARRAY_INDEX_3]);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, prli_pld, sizeof(struct unf_prli_payload));
-}
-
-u32 unf_send_prli(struct unf_lport *lport, struct unf_rport *rport,
- u32 cmnd_code)
-{
- struct unf_prli_payload *prli_pal = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for PRLI",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = cmnd_code;
-
- /* for rcvd prli acc/rjt processer */
- xchg->callback = unf_prli_callback;
- /* for send prli failed processer */
- xchg->ob_callback = unf_prli_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- prli_pal = &fc_entry->prli.payload;
- memset(prli_pal, 0, sizeof(struct unf_prli_payload));
- unf_fill_prli_pld(prli_pal, lport);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: PRLI send %s. Port(0x%x)--->RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id);
-
- return ret;
-}
-
-static void unf_fill_prlo_pld(struct unf_prli_payload *prlo_pld,
- struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(prlo_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- prlo_pld->cmnd = (UNF_ELS_CMND_PRLO);
- prlo_pld->parms[ARRAY_INDEX_0] = (UNF_FC4_FRAME_PARM_0_FCP);
- prlo_pld->parms[ARRAY_INDEX_1] = UNF_NOT_MEANINGFUL;
- prlo_pld->parms[ARRAY_INDEX_2] = UNF_NOT_MEANINGFUL;
- prlo_pld->parms[ARRAY_INDEX_3] = UNF_NO_SERVICE_PARAMS;
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, prlo_pld, sizeof(struct unf_prli_payload));
-}
-
-u32 unf_send_prlo(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_prli_payload *prlo_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for PRLO", lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_PRLO;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- prlo_pld = &fc_entry->prlo.payload;
- memset(prlo_pld, 0, sizeof(struct unf_prli_payload));
- unf_fill_prlo_pld(prlo_pld, lport);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: PRLO send %s. Port(0x%x)--->RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id);
-
- return ret;
-}
-
-static void unf_fill_pdisc_pld(struct unf_plogi_payload *pdisc_pld,
- struct unf_lport *lport)
-{
- struct unf_lgn_parm *login_parms = NULL;
-
- FC_CHECK_RETURN_VOID(pdisc_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- pdisc_pld->cmnd = (UNF_ELS_CMND_PDISC);
- login_parms = &pdisc_pld->stparms;
-
- if (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- /* P2P & Fabric */
- login_parms->co_parms.bb_credit = (unf_low_level_bb_credit(lport));
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_NFPORT;
- login_parms->co_parms.bbscn =
- (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC)
- ? 0
- : unf_low_level_bb_scn(lport);
- } else {
- /* Public loop & Private loop */
- login_parms->co_parms.bb_credit = UNF_BBCREDIT_LPORT;
- /* :1 */
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_LPORT;
- }
-
- login_parms->co_parms.lowest_version = UNF_PLOGI_VERSION_LOWER;
- login_parms->co_parms.highest_version = UNF_PLOGI_VERSION_UPPER;
- login_parms->co_parms.continuously_increasing = UNF_CONTIN_INCREASE_SUPPORT;
- login_parms->co_parms.bb_receive_data_field_size = (lport->max_frame_size);
- login_parms->co_parms.nport_total_concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->co_parms.relative_offset = (UNF_PLOGI_RO_CATEGORY);
- login_parms->co_parms.e_d_tov = (lport->ed_tov);
-
- login_parms->high_node_name = UNF_GET_NAME_HIGH_WORD(lport->node_name);
- login_parms->low_node_name = UNF_GET_NAME_LOW_WORD(lport->node_name);
- login_parms->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- login_parms->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
-
- /* class-3 */
- login_parms->cl_parms[ARRAY_INDEX_2].valid = UNF_CLASS_VALID;
- login_parms->cl_parms[ARRAY_INDEX_2].received_data_field_size = (lport->max_frame_size);
- login_parms->cl_parms[ARRAY_INDEX_2].concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->cl_parms[ARRAY_INDEX_2].open_sequence_per_exchange = (UNF_PLOGI_SEQ_PER_XCHG);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, pdisc_pld, sizeof(struct unf_plogi_payload));
-}
-
-u32 unf_send_pdisc(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* PLOGI/PDISC with same payload */
- struct unf_plogi_payload *pdisc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for PDISC",
- lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_PDISC;
- xchg->callback = NULL;
- xchg->ob_callback = NULL;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- pdisc_pld = &fc_entry->pdisc.payload;
- memset(pdisc_pld, 0, sizeof(struct unf_plogi_payload));
- unf_fill_pdisc_pld(pdisc_pld, lport);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: PDISC send %s. Port(0x%x)--->RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id, rport->nport_id);
-
- return ret;
-}
-
-static void unf_fill_adisc_pld(struct unf_adisc_payload *adisc_pld,
- struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(adisc_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- adisc_pld->cmnd = (UNF_ELS_CMND_ADISC);
- adisc_pld->high_node_name = UNF_GET_NAME_HIGH_WORD(lport->node_name);
- adisc_pld->low_node_name = UNF_GET_NAME_LOW_WORD(lport->node_name);
- adisc_pld->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- adisc_pld->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, adisc_pld, sizeof(struct unf_adisc_payload));
-}
-
-u32 unf_send_adisc(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_adisc_payload *adisc_pal = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for ADISC", lport->port_id);
-
- return ret;
- }
-
- xchg->cmnd_code = ELS_ADISC;
-
- xchg->callback = NULL;
- xchg->ob_callback = NULL;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
-
- adisc_pal = &fc_entry->adisc.adisc_payl;
- memset(adisc_pal, 0, sizeof(struct unf_adisc_payload));
- unf_fill_adisc_pld(adisc_pal, lport);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: ADISC send %s. Port(0x%x)--->RPort(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id);
-
- return ret;
-}
-
-static void unf_fill_rrq_pld(struct unf_rrq *rrq_pld, struct unf_xchg *xchg)
-{
- FC_CHECK_RETURN_VOID(rrq_pld);
- FC_CHECK_RETURN_VOID(xchg);
-
- rrq_pld->cmnd = UNF_ELS_CMND_RRQ;
- rrq_pld->sid = xchg->sid;
- rrq_pld->oxid_rxid = ((u32)xchg->oxid << UNF_SHIFT_16 | xchg->rxid);
-}
-
-u32 unf_send_rrq(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- /* after ABTS Done */
- struct unf_rrq *rrq_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_frame_pkg pkg = {0};
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- unf_xchg = unf_get_sfs_free_xchg_and_init(lport, rport->nport_id, rport, &fc_entry);
- if (!unf_xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for RRQ",
- lport->port_id);
-
- return ret;
- }
-
- unf_xchg->cmnd_code = ELS_RRQ; /* RRQ */
-
- unf_xchg->callback = unf_rrq_callback; /* release I/O exchange context */
- unf_xchg->ob_callback = unf_rrq_ob_callback; /* release I/O exchange context */
- unf_xchg->io_xchg = xchg; /* pointer to IO XCHG */
-
- unf_fill_package(&pkg, unf_xchg, rport);
- pkg.type = UNF_PKG_ELS_REQ;
- rrq_pld = &fc_entry->rrq;
- memset(rrq_pld, 0, sizeof(struct unf_rrq));
- unf_fill_rrq_pld(rrq_pld, xchg);
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, unf_xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)unf_xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]RRQ send %s. Port(0x%x)--->RPort(0x%x) free old exchange(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, xchg->hotpooltag);
-
- return ret;
-}
-
-u32 unf_send_flogi_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_flogi_fdisc_payload *flogi_acc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
- u16 ox_id = 0;
- u16 rx_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_FLOGI);
-
- xchg->did = 0; /* D_ID must be 0 */
- xchg->sid = UNF_FC_FID_FLOGI; /* S_ID must be 0xfffffe */
- xchg->oid = xchg->sid;
- xchg->callback = NULL;
- xchg->lport = lport;
- xchg->rport = rport;
- xchg->ob_callback = unf_flogi_acc_ob_callback; /* call back for sending
- * FLOGI response
- */
-
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- flogi_acc_pld = &fc_entry->flogi_acc.flogi_payload;
- flogi_acc_pld->cmnd = (UNF_ELS_CMND_ACC);
- unf_fill_flogi_pld(flogi_acc_pld, lport);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]LOGIN: FLOGI ACC send %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, ox_id, rx_id);
- return ret;
-}
-
-static void unf_fill_plogi_acc_pld(struct unf_plogi_payload *plogi_acc_pld,
- struct unf_lport *lport)
-{
- struct unf_lgn_parm *login_parms = NULL;
-
- FC_CHECK_RETURN_VOID(plogi_acc_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- plogi_acc_pld->cmnd = (UNF_ELS_CMND_ACC);
- login_parms = &plogi_acc_pld->stparms;
-
- if (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- login_parms->co_parms.bb_credit = (unf_low_level_bb_credit(lport));
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_NFPORT; /* 0 */
- login_parms->co_parms.bbscn =
- (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC)
- ? 0
- : unf_low_level_bb_scn(lport);
- } else {
- login_parms->co_parms.bb_credit = UNF_BBCREDIT_LPORT;
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_LPORT; /* 1 */
- }
-
- login_parms->co_parms.lowest_version = UNF_PLOGI_VERSION_LOWER;
- login_parms->co_parms.highest_version = UNF_PLOGI_VERSION_UPPER;
- login_parms->co_parms.continuously_increasing = UNF_CONTIN_INCREASE_SUPPORT;
- login_parms->co_parms.bb_receive_data_field_size = (lport->max_frame_size);
- login_parms->co_parms.nport_total_concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->co_parms.relative_offset = (UNF_PLOGI_RO_CATEGORY);
- login_parms->co_parms.e_d_tov = (lport->ed_tov);
- login_parms->cl_parms[ARRAY_INDEX_2].valid = UNF_CLASS_VALID; /* class-3 */
- login_parms->cl_parms[ARRAY_INDEX_2].received_data_field_size = (lport->max_frame_size);
- login_parms->cl_parms[ARRAY_INDEX_2].concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->cl_parms[ARRAY_INDEX_2].open_sequence_per_exchange = (UNF_PLOGI_SEQ_PER_XCHG);
- login_parms->high_node_name = UNF_GET_NAME_HIGH_WORD(lport->node_name);
- login_parms->low_node_name = UNF_GET_NAME_LOW_WORD(lport->node_name);
- login_parms->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- login_parms->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, plogi_acc_pld,
- sizeof(struct unf_plogi_payload));
-}
-
-u32 unf_send_plogi_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_plogi_payload *plogi_acc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
- u16 ox_id = 0;
- u16 rx_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_PLOGI);
-
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->callback = NULL;
- xchg->lport = lport;
- xchg->rport = rport;
-
- xchg->ob_callback = unf_plogi_acc_ob_callback; /* call back for sending PLOGI ACC */
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- plogi_acc_pld = &fc_entry->plogi_acc.payload;
- unf_fill_plogi_acc_pld(plogi_acc_pld, lport);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- if (rport->nport_id < UNF_FC_FID_DOM_MGR ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: PLOGI ACC send %s. Port(0x%x_0x%x_0x%llx)--->RPort(0x%x_0x%llx) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed",
- lport->port_id, lport->nport_id, lport->port_name,
- rport->nport_id, rport->port_name, ox_id, rx_id);
- }
-
- return ret;
-}
-
-static void unf_fill_prli_acc_pld(struct unf_prli_payload *prli_acc_pld,
- struct unf_lport *lport,
- struct unf_rport *rport)
-{
- u32 port_mode = UNF_FC4_FRAME_PARM_3_TGT;
-
- FC_CHECK_RETURN_VOID(prli_acc_pld);
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- prli_acc_pld->cmnd =
- (UNF_ELS_CMND_ACC |
- ((u32)UNF_FC4_FRAME_PAGE_SIZE << UNF_FC4_FRAME_PAGE_SIZE_SHIFT) |
- ((u32)(sizeof(struct unf_prli_payload) - UNF_PRLI_SIRT_EXTRA_SIZE)));
-
- prli_acc_pld->parms[ARRAY_INDEX_0] =
- (UNF_FC4_FRAME_PARM_0_FCP | UNF_FC4_FRAME_PARM_0_I_PAIR |
- UNF_FC4_FRAME_PARM_0_GOOD_RSP_CODE);
- prli_acc_pld->parms[ARRAY_INDEX_1] = UNF_NOT_MEANINGFUL;
- prli_acc_pld->parms[ARRAY_INDEX_2] = UNF_NOT_MEANINGFUL;
-
- /* About INI/TGT mode */
- if (rport->nport_id < UNF_FC_FID_DOM_MGR) {
- /* return INI (0x20): R_Port has TGT mode, L_Port has INI mode
- */
- port_mode = UNF_FC4_FRAME_PARM_3_INI;
- } else {
- port_mode = lport->options;
- }
-
- /* About Read xfer_rdy disable */
- prli_acc_pld->parms[ARRAY_INDEX_3] =
- (UNF_FC4_FRAME_PARM_3_R_XFER_DIS | port_mode); /* 0x2 */
-
- /* About Tape support */
- if (rport->tape_support_needed) {
- prli_acc_pld->parms[ARRAY_INDEX_3] |=
- (UNF_FC4_FRAME_PARM_3_REC_SUPPORT |
- UNF_FC4_FRAME_PARM_3_RETRY_SUPPORT |
- UNF_FC4_FRAME_PARM_3_TASK_RETRY_ID_SUPPORT |
- UNF_FC4_FRAME_PARM_3_CONF_ALLOW);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "PRLI ACC tape support");
- }
-
- /* About confirm */
- if (lport->low_level_func.lport_cfg_items.fcp_conf)
- prli_acc_pld->parms[ARRAY_INDEX_3] |=
- UNF_FC4_FRAME_PARM_3_CONF_ALLOW; /* 0x80 */
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, prli_acc_pld,
- sizeof(struct unf_prli_payload));
-}
-
-u32 unf_send_prli_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_prli_payload *prli_acc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
- u16 ox_id = 0;
- u16 rx_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_PRLI);
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
-
- xchg->callback = NULL;
- xchg->ob_callback =
- unf_prli_acc_ob_callback; /* callback when send succeed */
-
- unf_fill_package(&pkg, xchg, rport);
-
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- prli_acc_pld = &fc_entry->prli_acc.payload;
- unf_fill_prli_acc_pld(prli_acc_pld, lport, rport);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- if (rport->nport_id < UNF_FC_FID_DOM_MGR ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: PRLI ACC send %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed",
- lport->port_id, rport->nport_id, ox_id, rx_id);
- }
-
- return ret;
-}
-
-u32 unf_send_rec_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- /* Reserved */
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- return RETURN_OK;
-}
-
-static void unf_rrq_acc_ob_callback(struct unf_xchg *xchg)
-{
- FC_CHECK_RETURN_VOID(xchg);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]RRQ ACC Xchg(0x%p) tag(0x%x)", xchg,
- xchg->hotpooltag);
-}
-
-static void unf_fill_els_acc_pld(struct unf_els_acc *els_acc_pld)
-{
- FC_CHECK_RETURN_VOID(els_acc_pld);
-
- els_acc_pld->cmnd = (UNF_ELS_CMND_ACC);
-}
-
-u32 unf_send_rscn_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_els_acc *rscn_acc = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_RSCN);
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
-
- xchg->callback = NULL;
- xchg->ob_callback = unf_rscn_acc_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- rscn_acc = &fc_entry->els_acc;
- unf_fill_els_acc_pld(rscn_acc);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: RSCN ACC send %s. Port(0x%x)--->RPort(0x%x) with OXID(0x%x) RXID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, ox_id, rx_id);
-
- return ret;
-}
-
-u32 unf_send_logo_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_els_acc *logo_acc = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_LOGO);
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
- xchg->callback = NULL;
- xchg->ob_callback = unf_logo_acc_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- logo_acc = &fc_entry->els_acc;
- unf_fill_els_acc_pld(logo_acc);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- if (rport->nport_id < UNF_FC_FID_DOM_MGR) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: LOGO ACC send %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed",
- lport->port_id, rport->nport_id, ox_id, rx_id);
- }
-
- return ret;
-}
-
-static u32 unf_send_rrq_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_els_acc *rrq_acc = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
- xchg->callback = NULL; /* do noting */
-
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- rrq_acc = &fc_entry->els_acc;
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_RRQ);
- xchg->ob_callback = unf_rrq_acc_ob_callback; /* do noting */
- unf_fill_els_acc_pld(rrq_acc);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]RRQ ACC send %s. Port(0x%x)--->RPort(0x%x) with Xchg(0x%p) OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, xchg, ox_id, rx_id);
-
- return ret;
-}
-
-static void unf_fill_pdisc_acc_pld(struct unf_plogi_payload *pdisc_acc_pld,
- struct unf_lport *lport)
-{
- struct unf_lgn_parm *login_parms = NULL;
-
- FC_CHECK_RETURN_VOID(pdisc_acc_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- pdisc_acc_pld->cmnd = (UNF_ELS_CMND_ACC);
- login_parms = &pdisc_acc_pld->stparms;
-
- if (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- login_parms->co_parms.bb_credit = (unf_low_level_bb_credit(lport));
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_NFPORT;
- login_parms->co_parms.bbscn =
- (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC)
- ? 0
- : unf_low_level_bb_scn(lport);
- } else {
- login_parms->co_parms.bb_credit = UNF_BBCREDIT_LPORT;
- login_parms->co_parms.alternate_bb_credit_mgmt = UNF_BBCREDIT_MANAGE_LPORT;
- }
-
- login_parms->co_parms.lowest_version = UNF_PLOGI_VERSION_LOWER;
- login_parms->co_parms.highest_version = UNF_PLOGI_VERSION_UPPER;
- login_parms->co_parms.continuously_increasing = UNF_CONTIN_INCREASE_SUPPORT;
- login_parms->co_parms.bb_receive_data_field_size = (lport->max_frame_size);
- login_parms->co_parms.nport_total_concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->co_parms.relative_offset = (UNF_PLOGI_RO_CATEGORY);
- login_parms->co_parms.e_d_tov = (lport->ed_tov);
-
- login_parms->cl_parms[ARRAY_INDEX_2].valid = UNF_CLASS_VALID; /* class-3 */
- login_parms->cl_parms[ARRAY_INDEX_2].received_data_field_size = (lport->max_frame_size);
- login_parms->cl_parms[ARRAY_INDEX_2].concurrent_sequences = (UNF_PLOGI_CONCURRENT_SEQ);
- login_parms->cl_parms[ARRAY_INDEX_2].open_sequence_per_exchange = (UNF_PLOGI_SEQ_PER_XCHG);
-
- login_parms->high_node_name = UNF_GET_NAME_HIGH_WORD(lport->node_name);
- login_parms->low_node_name = UNF_GET_NAME_LOW_WORD(lport->node_name);
- login_parms->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- login_parms->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, pdisc_acc_pld,
- sizeof(struct unf_plogi_payload));
-}
-
-u32 unf_send_pdisc_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_plogi_payload *pdisc_acc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_PDISC);
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
-
- xchg->callback = NULL;
- xchg->ob_callback = unf_pdisc_acc_ob_callback;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- pdisc_acc_pld = &fc_entry->pdisc_acc.payload;
- unf_fill_pdisc_acc_pld(pdisc_acc_pld, lport);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Send PDISC ACC %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, ox_id, rx_id);
-
- return ret;
-}
-
-static void unf_fill_adisc_acc_pld(struct unf_adisc_payload *adisc_acc_pld,
- struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(adisc_acc_pld);
- FC_CHECK_RETURN_VOID(lport);
-
- adisc_acc_pld->cmnd = (UNF_ELS_CMND_ACC);
-
- adisc_acc_pld->hard_address = (lport->nport_id & UNF_ALPA_MASK);
- adisc_acc_pld->high_node_name = UNF_GET_NAME_HIGH_WORD(lport->node_name);
- adisc_acc_pld->low_node_name = UNF_GET_NAME_LOW_WORD(lport->node_name);
- adisc_acc_pld->high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- adisc_acc_pld->low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
- adisc_acc_pld->nport_id = lport->nport_id;
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, adisc_acc_pld,
- sizeof(struct unf_adisc_payload));
-}
-
-u32 unf_send_adisc_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_adisc_payload *adisc_acc_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
- u16 ox_id = 0;
- u16 rx_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_ADISC);
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
-
- xchg->callback = NULL;
- xchg->ob_callback = unf_adisc_acc_ob_callback;
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- adisc_acc_pld = &fc_entry->adisc_acc.adisc_payl;
- unf_fill_adisc_acc_pld(adisc_acc_pld, lport);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Send ADISC ACC %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, ox_id, rx_id);
-
- return ret;
-}
-
-static void unf_fill_prlo_acc_pld(struct unf_prli_prlo *prlo_acc,
- struct unf_lport *lport)
-{
- struct unf_prli_payload *prlo_acc_pld = NULL;
-
- FC_CHECK_RETURN_VOID(prlo_acc);
-
- prlo_acc_pld = &prlo_acc->payload;
- prlo_acc_pld->cmnd =
- (UNF_ELS_CMND_ACC |
- ((u32)UNF_FC4_FRAME_PAGE_SIZE << UNF_FC4_FRAME_PAGE_SIZE_SHIFT) |
- ((u32)sizeof(struct unf_prli_payload)));
- prlo_acc_pld->parms[ARRAY_INDEX_0] =
- (UNF_FC4_FRAME_PARM_0_FCP | UNF_FC4_FRAME_PARM_0_GOOD_RSP_CODE);
- prlo_acc_pld->parms[ARRAY_INDEX_1] = 0;
- prlo_acc_pld->parms[ARRAY_INDEX_2] = 0;
- prlo_acc_pld->parms[ARRAY_INDEX_3] = 0;
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, prlo_acc_pld,
- sizeof(struct unf_prli_payload));
-}
-
-u32 unf_send_prlo_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg)
-{
- struct unf_prli_prlo *prlo_acc = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_PRLO);
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
-
- xchg->callback = NULL;
- xchg->ob_callback = NULL;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- memset(fc_entry, 0, sizeof(union unf_sfs_u));
- prlo_acc = &fc_entry->prlo_acc;
- unf_fill_prlo_acc_pld(prlo_acc, lport);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Send PRLO ACC %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, ox_id, rx_id);
-
- return ret;
-}
-
-static void unf_prli_acc_ob_callback(struct unf_xchg *xchg)
-{
- /* Report R_Port scsi Link Up */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flags = 0;
- enum unf_rport_login_state rport_state = UNF_RPORT_ST_INIT;
-
- FC_CHECK_RETURN_VOID(xchg);
- unf_lport = xchg->lport;
- unf_rport = xchg->rport;
- FC_CHECK_RETURN_VOID(unf_lport);
- FC_CHECK_RETURN_VOID(unf_rport);
-
- /* Update & Report Link Up */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_READY);
- rport_state = unf_rport->rp_state;
- if (unf_rport->nport_id < UNF_FC_FID_DOM_MGR) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]LOGIN: Port(0x%x) RPort(0x%x) state(0x%x) WWN(0x%llx) prliacc",
- unf_lport->port_id, unf_rport->nport_id,
- unf_rport->rp_state, unf_rport->port_name);
- }
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- if (rport_state == UNF_RPORT_ST_READY) {
- unf_rport->logo_retries = 0;
- unf_update_lport_state_by_linkup_event(unf_lport, unf_rport,
- unf_rport->options);
- }
-}
-
-static void unf_schedule_open_work(struct unf_lport *lport,
- struct unf_rport *rport)
-{
- /* Used for L_Port port only with TGT, or R_Port only with INI */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- ulong delay = 0;
- ulong flag = 0;
- u32 ret = 0;
- u32 port_feature = INVALID_VALUE32;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- delay = (ulong)unf_lport->ed_tov;
- port_feature = unf_rport->options & UNF_PORT_MODE_BOTH;
-
- if (unf_lport->options == UNF_PORT_MODE_TGT ||
- port_feature == UNF_PORT_MODE_INI) {
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
-
- ret = unf_rport_ref_inc(unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) RPort(0x%x) abnormal, no need open",
- unf_lport->port_id, unf_lport->nport_id, unf_rport->nport_id);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
- return;
- }
-
- /* Delay work pending check */
- if (delayed_work_pending(&unf_rport->open_work)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) RPort(0x%x) open work is running, no need re-open",
- unf_lport->port_id, unf_lport->nport_id,
- unf_rport->nport_id);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
- unf_rport_ref_dec(unf_rport);
- return;
- }
-
- /* start open work */
- if (queue_delayed_work(unf_wq, &unf_rport->open_work,
- (ulong)msecs_to_jiffies((u32)delay))) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) RPort(0x%x) start open work",
- unf_lport->port_id, unf_lport->nport_id, unf_rport->nport_id);
-
- (void)unf_rport_ref_inc(unf_rport);
- }
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- unf_rport_ref_dec(unf_rport);
- }
-}
-
-static void unf_plogi_acc_ob_callback(struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- unf_lport = xchg->lport;
- unf_rport = xchg->rport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- FC_CHECK_RETURN_VOID(unf_lport);
- FC_CHECK_RETURN_VOID(unf_rport);
-
- /*
- * 1. According to FC-LS 4.2.7.1:
- * after RCVD PLOGI or sending PLOGI ACC, need to termitate open EXCH
- */
- unf_cm_xchg_mgr_abort_io_by_id(unf_lport, unf_rport,
- unf_rport->nport_id, unf_lport->nport_id, 0);
-
- /* 2. Send PLOGI ACC fail */
- if (xchg->ob_callback_sts != UNF_IO_SUCCESS) {
- /* Do R_Port recovery */
- unf_rport_error_recovery(unf_rport);
-
- /* Do not care: Just used for L_Port only is TGT mode or R_Port
- * only is INI mode
- */
- unf_schedule_open_work(unf_lport, unf_rport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x_0x%x) send PLOGI ACC failed(0x%x) with RPort(0x%x) feature(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- unf_lport->options, xchg->ob_callback_sts,
- unf_rport->nport_id, unf_rport->options);
-
- return;
- }
-
- /* 3. Private Loop: check whether or not need to send PRLI */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- if (unf_lport->act_topo == UNF_ACT_TOP_PRIVATE_LOOP &&
- (unf_rport->rp_state == UNF_RPORT_ST_PRLI_WAIT ||
- unf_rport->rp_state == UNF_RPORT_ST_READY)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) RPort(0x%x) with State(0x%x) return directly",
- unf_lport->port_id, unf_lport->nport_id,
- unf_rport->nport_id, unf_rport->rp_state);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
- return;
- }
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PRLI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- /* 4. Set Port Feature with BOTH: cancel */
- if (unf_rport->options == UNF_PORT_MODE_UNKNOWN && unf_rport->port_name != INVALID_WWPN)
- unf_rport->options = unf_get_port_feature(unf_rport->port_name);
-
- /*
- * 5. Check whether need to send PRLI delay
- * Call by: RCVD PLOGI ACC or callback for sending PLOGI ACC succeed
- */
- unf_check_rport_need_delay_prli(unf_lport, unf_rport, unf_rport->options);
-
- /* 6. Do not care: Just used for L_Port only is TGT mode or R_Port only
- * is INI mode
- */
- unf_schedule_open_work(unf_lport, unf_rport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x_0x%x) send PLOGI ACC succeed with RPort(0x%x) feature(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, unf_lport->options,
- unf_rport->nport_id, unf_rport->options);
-}
-
-static void unf_flogi_acc_ob_callback(struct unf_xchg *xchg)
-{
- /* Callback for Sending FLOGI ACC succeed */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flags = 0;
- u64 rport_port_name = 0;
- u64 rport_node_name = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
- FC_CHECK_RETURN_VOID(xchg->lport);
- FC_CHECK_RETURN_VOID(xchg->rport);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- unf_lport = xchg->lport;
- unf_rport = xchg->rport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- if (unf_rport->port_name == 0 && unf_rport->node_name == 0) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x_0x%x_0x%x) already send Plogi with RPort(0x%x) feature(0x%x).",
- unf_lport->port_id, unf_lport->nport_id, unf_lport->options,
- unf_rport->nport_id, unf_rport->options);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
- return;
- }
-
- rport_port_name = unf_rport->port_name;
- rport_node_name = unf_rport->node_name;
-
- /* Swap case: Set WWPN & WWNN with zero */
- unf_rport->port_name = 0;
- unf_rport->node_name = 0;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- /* Enter PLOGI stage: after send FLOGI ACC succeed */
- unf_login_with_rport_in_n2n(unf_lport, rport_port_name, rport_node_name);
-}
-
-static void unf_rscn_acc_ob_callback(struct unf_xchg *xchg)
-{
-}
-
-static void unf_logo_acc_ob_callback(struct unf_xchg *xchg)
-{
-}
-
-static void unf_adisc_acc_ob_callback(struct unf_xchg *xchg)
-{
-}
-
-static void unf_pdisc_acc_ob_callback(struct unf_xchg *xchg)
-{
-}
-
-static inline u8 unf_determin_bbscn(u8 local_bbscn, u8 remote_bbscn)
-{
- if (remote_bbscn == 0 || local_bbscn == 0)
- local_bbscn = 0;
- else
- local_bbscn = local_bbscn > remote_bbscn ? local_bbscn : remote_bbscn;
-
- return local_bbscn;
-}
-
-static void unf_cfg_lowlevel_fabric_params(struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_fabric_parm *login_parms)
-{
- struct unf_port_login_parms login_co_parms = {0};
- u32 remote_edtov = 0;
- u32 ret = 0;
- u8 remote_edtov_resolution = 0; /* 0:ms; 1:ns */
-
- if (!lport->low_level_func.port_mgr_op.ll_port_config_set)
- return;
-
- login_co_parms.remote_rttov_tag = (u8)UNF_GET_RT_TOV_FROM_PARAMS(login_parms);
- login_co_parms.remote_edtov_tag = 0;
- login_co_parms.remote_bb_credit = (u16)UNF_GET_BB_CREDIT_FROM_PARAMS(login_parms);
- login_co_parms.compared_bbscn =
- (u32)unf_determin_bbscn((u8)lport->low_level_func.lport_cfg_items.bbscn,
- (u8)UNF_GET_BB_SC_N_FROM_PARAMS(login_parms));
-
- remote_edtov_resolution = (u8)UNF_GET_E_D_TOV_RESOLUTION_FROM_PARAMS(login_parms);
- remote_edtov = UNF_GET_E_D_TOV_FROM_PARAMS(login_parms);
- login_co_parms.compared_edtov_val =
- remote_edtov_resolution ? (remote_edtov / UNF_OS_MS_TO_NS)
- : remote_edtov;
-
- login_co_parms.compared_ratov_val = UNF_GET_RA_TOV_FROM_PARAMS(login_parms);
- login_co_parms.els_cmnd_code = ELS_FLOGI;
-
- if (UNF_TOP_P2P_MASK & (u32)lport->act_topo) {
- login_co_parms.act_topo = (login_parms->co_parms.nport == UNF_F_PORT)
- ? UNF_ACT_TOP_P2P_FABRIC
- : UNF_ACT_TOP_P2P_DIRECT;
- } else {
- login_co_parms.act_topo = lport->act_topo;
- }
-
- ret = lport->low_level_func.port_mgr_op.ll_port_config_set((void *)lport->fc_port,
- UNF_PORT_CFG_UPDATE_FABRIC_PARAM, (void *)&login_co_parms);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Lowlevel unsupport fabric config");
- }
-}
-
-u32 unf_check_flogi_params(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_fabric_parm *fabric_parms)
-{
- u32 ret = RETURN_OK;
- u32 high_port_name;
- u32 low_port_name;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(fabric_parms, UNF_RETURN_ERROR);
-
- if (fabric_parms->cl_parms[ARRAY_INDEX_2].valid == UNF_CLASS_INVALID) {
- /* Discard directly */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) NPort_ID(0x%x) FLOGI not support class3",
- lport->port_id, rport->nport_id);
-
- return UNF_RETURN_ERROR;
- }
-
- high_port_name = UNF_GET_NAME_HIGH_WORD(lport->port_name);
- low_port_name = UNF_GET_NAME_LOW_WORD(lport->port_name);
- if (fabric_parms->high_port_name == high_port_name &&
- fabric_parms->low_port_name == low_port_name) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]The wwpn(0x%x%x) of lport(0x%x) is same as the wwpn of rport(0x%x)",
- high_port_name, low_port_name, lport->port_id, rport->nport_id);
- return UNF_RETURN_ERROR;
- }
-
- return ret;
-}
-
-static void unf_save_fabric_params(struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_fabric_parm *fabric_parms)
-{
- u64 fabric_node_name = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(fabric_parms);
-
- fabric_node_name = (u64)(((u64)(fabric_parms->high_node_name) << UNF_SHIFT_32) |
- ((u64)(fabric_parms->low_node_name)));
-
- /* R_Port for 0xfffffe is used for FLOGI, not need to save WWN */
- if (fabric_parms->co_parms.bb_receive_data_field_size > UNF_MAX_FRAME_SIZE)
- rport->max_frame_size = UNF_MAX_FRAME_SIZE; /* 2112 */
- else
- rport->max_frame_size = fabric_parms->co_parms.bb_receive_data_field_size;
-
- /* with Fabric attribute */
- if (fabric_parms->co_parms.nport == UNF_F_PORT) {
- rport->ed_tov = fabric_parms->co_parms.e_d_tov;
- rport->ra_tov = fabric_parms->co_parms.r_a_tov;
- lport->ed_tov = fabric_parms->co_parms.e_d_tov;
- lport->ra_tov = fabric_parms->co_parms.r_a_tov;
- lport->fabric_node_name = fabric_node_name;
- }
-
- /* Configure info from FLOGI to chip */
- unf_cfg_lowlevel_fabric_params(lport, rport, fabric_parms);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) Rport(0x%x) login parameter: E_D_TOV = %u. LPort E_D_TOV = %u. fabric nodename: 0x%x%x",
- lport->port_id, rport->nport_id, (fabric_parms->co_parms.e_d_tov),
- lport->ed_tov, fabric_parms->high_node_name, fabric_parms->low_node_name);
-}
-
-u32 unf_flogi_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_flogi_fdisc_acc *flogi_frame = NULL;
- struct unf_fabric_parm *fabric_login_parms = NULL;
- u32 ret = UNF_RETURN_ERROR;
- ulong flag = 0;
- u64 wwpn = 0;
- u64 wwnn = 0;
- enum unf_act_topo unf_active_topo;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x)<---RPort(0x%x) Receive FLOGI with OX_ID(0x%x)",
- lport->port_id, sid, xchg->oxid);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_FLOGI);
-
- /* Check L_Port state: Offline */
- if (lport->states >= UNF_LPORT_ST_OFFLINE) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) with state(0x%x) not need to handle FLOGI",
- lport->port_id, lport->states);
-
- unf_cm_free_xchg(lport, xchg);
- return ret;
- }
-
- flogi_frame = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->flogi;
- fabric_login_parms = &flogi_frame->flogi_payload.fabric_parms;
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, &flogi_frame->flogi_payload,
- sizeof(struct unf_flogi_fdisc_payload));
- wwpn = (u64)(((u64)(fabric_login_parms->high_port_name) << UNF_SHIFT_32) |
- ((u64)fabric_login_parms->low_port_name));
- wwnn = (u64)(((u64)(fabric_login_parms->high_node_name) << UNF_SHIFT_32) |
- ((u64)fabric_login_parms->low_node_name));
-
- /* Get (new) R_Port: reuse only */
- unf_rport = unf_get_rport_by_nport_id(lport, UNF_FC_FID_FLOGI);
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY, UNF_FC_FID_FLOGI);
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) has no RPort. do nothing", lport->port_id);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- /* Update R_Port info */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->port_name = wwpn;
- unf_rport->node_name = wwnn;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Check RCVD FLOGI parameters: only for class-3 */
- ret = unf_check_flogi_params(lport, unf_rport, fabric_login_parms);
- if (ret != RETURN_OK) {
- /* Discard directly */
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- /* Save fabric parameters */
- unf_save_fabric_params(lport, unf_rport, fabric_login_parms);
-
- if ((u32)lport->act_topo & UNF_TOP_P2P_MASK) {
- unf_active_topo =
- (fabric_login_parms->co_parms.nport == UNF_F_PORT)
- ? UNF_ACT_TOP_P2P_FABRIC
- : UNF_ACT_TOP_P2P_DIRECT;
- unf_lport_update_topo(lport, unf_active_topo);
- }
- /* Send ACC for FLOGI */
- ret = unf_send_flogi_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send FLOGI ACC failed and do recover",
- lport->port_id);
-
- /* Do L_Port recovery */
- unf_lport_error_recovery(lport);
- }
-
- return ret;
-}
-
-static void unf_cfg_lowlevel_port_params(struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_lgn_parm *login_parms,
- u32 cmd_type)
-{
- struct unf_port_login_parms login_co_parms = {0};
- u32 ret = 0;
-
- if (!lport->low_level_func.port_mgr_op.ll_port_config_set)
- return;
-
- login_co_parms.rport_index = rport->rport_index;
- login_co_parms.seq_cnt = 0;
- login_co_parms.ed_tov = 0; /* ms */
- login_co_parms.ed_tov_timer_val = lport->ed_tov;
- login_co_parms.tx_mfs = rport->max_frame_size;
-
- login_co_parms.remote_rttov_tag = (u8)UNF_GET_RT_TOV_FROM_PARAMS(login_parms);
- login_co_parms.remote_edtov_tag = 0;
- login_co_parms.remote_bb_credit = (u16)UNF_GET_BB_CREDIT_FROM_PARAMS(login_parms);
- login_co_parms.els_cmnd_code = cmd_type;
-
- if (lport->act_topo == UNF_ACT_TOP_PRIVATE_LOOP) {
- login_co_parms.compared_bbscn = 0;
- } else {
- login_co_parms.compared_bbscn =
- (u32)unf_determin_bbscn((u8)lport->low_level_func.lport_cfg_items.bbscn,
- (u8)UNF_GET_BB_SC_N_FROM_PARAMS(login_parms));
- }
-
- login_co_parms.compared_edtov_val = lport->ed_tov;
- login_co_parms.compared_ratov_val = lport->ra_tov;
-
- ret = lport->low_level_func.port_mgr_op.ll_port_config_set((void *)lport->fc_port,
- UNF_PORT_CFG_UPDATE_PLOGI_PARAM, (void *)&login_co_parms);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) Lowlevel unsupport port config", lport->port_id);
- }
-}
-
-u32 unf_check_plogi_params(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_lgn_parm *login_parms)
-{
- u32 ret = RETURN_OK;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(login_parms, UNF_RETURN_ERROR);
-
- /* Parameters check: Class-type */
- if (login_parms->cl_parms[ARRAY_INDEX_2].valid == UNF_CLASS_INVALID ||
- login_parms->co_parms.bb_receive_data_field_size == 0) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort N_Port_ID(0x%x) with PLOGI parameters invalid: class3(%u), BBReceiveDataFieldSize(0x%x), send LOGO",
- lport->port_id, rport->nport_id,
- login_parms->cl_parms[ARRAY_INDEX_2].valid,
- login_parms->co_parms.bb_receive_data_field_size);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LOGO); /* --->>> LOGO */
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* Enter LOGO stage */
- unf_rport_enter_logo(lport, rport);
- return UNF_RETURN_ERROR;
- }
-
- /* 16G FC Brocade SW, Domain Controller's PLOGI both support CLASS-1 &
- * CLASS-2
- */
- if (login_parms->cl_parms[ARRAY_INDEX_0].valid == UNF_CLASS_VALID ||
- login_parms->cl_parms[ARRAY_INDEX_1].valid == UNF_CLASS_VALID) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) get PLOGI class1(%u) class2(%u) from N_Port_ID(0x%x)",
- lport->port_id, login_parms->cl_parms[ARRAY_INDEX_0].valid,
- login_parms->cl_parms[ARRAY_INDEX_1].valid, rport->nport_id);
- }
-
- return ret;
-}
-
-static void unf_save_plogi_params(struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_lgn_parm *login_parms,
- u32 cmd_code)
-{
-#define UNF_DELAY_TIME 100 /* WWPN smaller delay to send PRLI with COM mode */
-
- u64 wwpn = INVALID_VALUE64;
- u64 wwnn = INVALID_VALUE64;
- u32 ed_tov = 0;
- u32 remote_edtov = 0;
-
- if (login_parms->co_parms.bb_receive_data_field_size > UNF_MAX_FRAME_SIZE)
- rport->max_frame_size = UNF_MAX_FRAME_SIZE; /* 2112 */
- else
- rport->max_frame_size = login_parms->co_parms.bb_receive_data_field_size;
-
- wwnn = (u64)(((u64)(login_parms->high_node_name) << UNF_SHIFT_32) |
- ((u64)login_parms->low_node_name));
- wwpn = (u64)(((u64)(login_parms->high_port_name) << UNF_SHIFT_32) |
- ((u64)login_parms->low_port_name));
-
- remote_edtov = login_parms->co_parms.e_d_tov;
- ed_tov = login_parms->co_parms.e_d_tov_resolution
- ? (remote_edtov / UNF_OS_MS_TO_NS)
- : remote_edtov;
-
- rport->port_name = wwpn;
- rport->node_name = wwnn;
- rport->local_nport_id = lport->nport_id;
-
- if (lport->act_topo == UNF_ACT_TOP_P2P_DIRECT ||
- lport->act_topo == UNF_ACT_TOP_PRIVATE_LOOP) {
- /* P2P or Private Loop or FCoE VN2VN */
- lport->ed_tov = (lport->ed_tov > ed_tov) ? lport->ed_tov : ed_tov;
- lport->ra_tov = 2 * lport->ed_tov; /* 2 * E_D_TOV */
-
- if (ed_tov != 0)
- rport->ed_tov = ed_tov;
- else
- rport->ed_tov = UNF_DEFAULT_EDTOV;
- } else {
- /* SAN: E_D_TOV updated by FLOGI */
- rport->ed_tov = lport->ed_tov;
- }
-
- /* WWPN smaller: delay to send PRLI */
- if (rport->port_name > lport->port_name)
- rport->ed_tov += UNF_DELAY_TIME; /* 100ms */
-
- /* Configure port parameters to low level (chip) */
- unf_cfg_lowlevel_port_params(lport, rport, login_parms, cmd_code);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) RPort(0x%x) with WWPN(0x%llx) WWNN(0x%llx) login: ED_TOV(%u) Port: ED_TOV(%u)",
- lport->port_id, rport->nport_id, rport->port_name, rport->node_name,
- ed_tov, lport->ed_tov);
-}
-
-static bool unf_check_bbscn_is_enabled(u8 local_bbscn, u8 remote_bbscn)
-{
- return unf_determin_bbscn(local_bbscn, remote_bbscn) ? true : false;
-}
-
-static u32 unf_irq_process_switch2thread(void *lport, struct unf_xchg *xchg,
- unf_event_task evt_task)
-{
- struct unf_cm_event_report *event = NULL;
- struct unf_xchg *unf_xchg = NULL;
- u32 ret = 0;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- unf_lport = lport;
- unf_xchg = xchg;
-
- if (unlikely(!unf_lport->event_mgr.unf_get_free_event_func ||
- !unf_lport->event_mgr.unf_post_event_func ||
- !unf_lport->event_mgr.unf_release_event)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) event function is NULL",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- ret = unf_xchg_ref_inc(unf_xchg, SFS_RESPONSE);
- FC_CHECK_RETURN_VALUE((ret == RETURN_OK), UNF_RETURN_ERROR);
-
- event = unf_lport->event_mgr.unf_get_free_event_func((void *)lport);
- FC_CHECK_RETURN_VALUE(event, UNF_RETURN_ERROR);
-
- event->lport = unf_lport;
- event->event_asy_flag = UNF_EVENT_ASYN;
- event->unf_event_task = evt_task;
- event->para_in = xchg;
- unf_lport->event_mgr.unf_post_event_func(unf_lport, event);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) start to switch thread process now",
- unf_lport->port_id);
-
- return ret;
-}
-
-u32 unf_plogi_handler_com_process(struct unf_xchg *xchg)
-{
- struct unf_xchg *unf_xchg = xchg;
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_plogi_pdisc *plogi_frame = NULL;
- struct unf_lgn_parm *login_parms = NULL;
- u32 ret = UNF_RETURN_ERROR;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(unf_xchg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(unf_xchg->lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(unf_xchg->rport, UNF_RETURN_ERROR);
-
- unf_lport = unf_xchg->lport;
- unf_rport = unf_xchg->rport;
- plogi_frame = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->plogi;
- login_parms = &plogi_frame->payload.stparms;
-
- unf_save_plogi_params(unf_lport, unf_rport, login_parms, ELS_PLOGI);
-
- /* Update state: PLOGI_WAIT */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = unf_xchg->sid;
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Send PLOGI ACC to remote port */
- ret = unf_send_plogi_acc(unf_lport, unf_rport, unf_xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send PLOGI ACC failed",
- unf_lport->port_id);
-
- /* NOTE: exchange has been freed inner(before) */
- unf_rport_error_recovery(unf_rport);
- return ret;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Port(0x%x) send PLOGI ACC to Port(0x%x) succeed",
- unf_lport->port_id, unf_rport->nport_id);
-
- return ret;
-}
-
-int unf_plogi_async_handle(void *argc_in, void *argc_out)
-{
- struct unf_xchg *xchg = (struct unf_xchg *)argc_in;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- ret = unf_plogi_handler_com_process(xchg);
-
- unf_xchg_ref_dec(xchg, SFS_RESPONSE);
-
- return (int)ret;
-}
-
-u32 unf_plogi_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_xchg *unf_xchg = xchg;
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = NULL;
- struct unf_plogi_pdisc *plogi_frame = NULL;
- struct unf_lgn_parm *login_parms = NULL;
- struct unf_rjt_info rjt_info = {0};
- u64 wwpn = INVALID_VALUE64;
- u32 ret = UNF_RETURN_ERROR;
- bool bbscn_enabled = false;
- bool switch2thread = false;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- /* 1. Maybe: PLOGI is sent by Name server */
- if (sid < UNF_FC_FID_DOM_MGR ||
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Receive PLOGI. Port(0x%x_0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- lport->port_id, lport->nport_id, sid, xchg->oxid);
- }
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_PLOGI);
-
- /* 2. State check: Offline */
- if (unf_lport->states >= UNF_LPORT_ST_OFFLINE) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) received PLOGI with state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, unf_lport->states);
-
- unf_cm_free_xchg(unf_lport, unf_xchg);
- return UNF_RETURN_ERROR;
- }
-
- /* Get R_Port by WWpn */
- plogi_frame = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->plogi;
- login_parms = &plogi_frame->payload.stparms;
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, unf_lport->port_id, &plogi_frame->payload,
- sizeof(struct unf_plogi_payload));
-
- wwpn = (u64)(((u64)(login_parms->high_port_name) << UNF_SHIFT_32) |
- ((u64)login_parms->low_port_name));
-
- /* 3. Get (new) R_Port (by wwpn) */
- unf_rport = unf_find_rport(unf_lport, sid, wwpn);
- unf_rport = unf_get_safe_rport(unf_lport, unf_rport, UNF_RPORT_REUSE_ONLY, sid);
- if (!unf_rport) {
- memset(&rjt_info, 0, sizeof(struct unf_rjt_info));
- rjt_info.els_cmnd_code = ELS_PLOGI;
- rjt_info.reason_code = UNF_LS_RJT_BUSY;
- rjt_info.reason_explanation = UNF_LS_RJT_INSUFFICIENT_RESOURCES;
-
- /* R_Port is NULL: Send ELS RJT for PLOGI */
- (void)unf_send_els_rjt_by_did(unf_lport, unf_xchg, sid, &rjt_info);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) has no RPort and send PLOGI reject",
- unf_lport->port_id);
- return RETURN_OK;
- }
-
- /*
- * 4. According to FC-LS 4.2.7.1:
- * After RCVD PLogi or send Plogi ACC, need to termitate open EXCH
- */
- unf_cm_xchg_mgr_abort_io_by_id(unf_lport, unf_rport, sid, unf_lport->nport_id, 0);
-
- /* 5. Cancel recovery timer work after RCVD PLOGI */
- if (cancel_delayed_work(&unf_rport->recovery_work))
- atomic_dec(&unf_rport->rport_ref_cnt);
-
- /*
- * 6. Plogi parameters check
- * Call by: (RCVD) PLOGI handler & callback function for RCVD PLOGI_ACC
- */
- ret = unf_check_plogi_params(unf_lport, unf_rport, login_parms);
- if (ret != RETURN_OK) {
- unf_cm_free_xchg(unf_lport, unf_xchg);
- return UNF_RETURN_ERROR;
- }
-
- unf_xchg->lport = lport;
- unf_xchg->rport = unf_rport;
- unf_xchg->sid = sid;
-
- /* 7. About bbscn for context change */
- bbscn_enabled =
- unf_check_bbscn_is_enabled((u8)unf_lport->low_level_func.lport_cfg_items.bbscn,
- (u8)UNF_GET_BB_SC_N_FROM_PARAMS(login_parms));
- if (unf_lport->act_topo == UNF_ACT_TOP_P2P_DIRECT && bbscn_enabled) {
- switch2thread = true;
- unf_lport->bbscn_support = true;
- }
-
- /* 8. Process PLOGI Frame: switch to thread if necessary */
- if (switch2thread && unf_lport->root_lport == unf_lport) {
- /* Wait for LR complete sync */
- ret = unf_irq_process_switch2thread(unf_lport, unf_xchg, unf_plogi_async_handle);
- } else {
- ret = unf_plogi_handler_com_process(unf_xchg);
- }
-
- return ret;
-}
-
-static void unf_obtain_tape_capacity(struct unf_lport *lport,
- struct unf_rport *rport, u32 tape_parm)
-{
- u32 rec_support = 0;
- u32 task_retry_support = 0;
- u32 retry_support = 0;
-
- rec_support = tape_parm & UNF_FC4_FRAME_PARM_3_REC_SUPPORT;
- task_retry_support =
- tape_parm & UNF_FC4_FRAME_PARM_3_TASK_RETRY_ID_SUPPORT;
- retry_support = tape_parm & UNF_FC4_FRAME_PARM_3_RETRY_SUPPORT;
-
- if (lport->low_level_func.lport_cfg_items.tape_support &&
- rec_support && task_retry_support && retry_support) {
- rport->tape_support_needed = true;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) FC_tape is needed for RPort(0x%x)",
- lport->port_id, lport->nport_id, rport->nport_id);
- }
-
- if ((tape_parm & UNF_FC4_FRAME_PARM_3_CONF_ALLOW) &&
- lport->low_level_func.lport_cfg_items.fcp_conf) {
- rport->fcp_conf_needed = true;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) FCP confirm is needed for RPort(0x%x)",
- lport->port_id, lport->nport_id, rport->nport_id);
- }
-}
-
-static u32 unf_prli_handler_com_process(struct unf_xchg *xchg)
-{
- struct unf_prli_prlo *prli = NULL;
- u32 ret = UNF_RETURN_ERROR;
- ulong flags = 0;
- u32 sid = 0;
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
-
- unf_xchg = xchg;
- FC_CHECK_RETURN_VALUE(unf_xchg->lport, UNF_RETURN_ERROR);
- unf_lport = unf_xchg->lport;
- sid = xchg->sid;
-
- UNF_SERVICE_COLLECT(unf_lport->link_service_info, UNF_SERVICE_ITEM_PRLI);
-
- /* 1. Get R_Port: for each R_Port from rport_busy_list */
- unf_rport = unf_get_rport_by_nport_id(unf_lport, sid);
- if (!unf_rport) {
- /* non session (R_Port) existence */
- (void)unf_send_logo_by_did(unf_lport, sid);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) received PRLI but no RPort SID(0x%x) OX_ID(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, sid, xchg->oxid);
-
- unf_cm_free_xchg(unf_lport, xchg);
- return ret;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Receive PRLI. Port(0x%x)<---RPort(0x%x) with S_ID(0x%x)",
- unf_lport->port_id, unf_rport->nport_id, sid);
-
- /* 2. Get PRLI info */
- prli = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->prli;
- if (sid < UNF_FC_FID_DOM_MGR || unf_lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Receive PRLI. Port(0x%x_0x%x)<---RPort(0x%x) parameter-3(0x%x) OX_ID(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, sid,
- prli->payload.parms[ARRAY_INDEX_3], xchg->oxid);
- }
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, unf_lport->port_id, &prli->payload,
- sizeof(struct unf_prli_payload));
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
-
- /* 3. Increase R_Port ref_cnt */
- ret = unf_rport_ref_inc(unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x_0x%p) is removing and do nothing",
- unf_lport->port_id, unf_rport->nport_id, unf_rport);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- unf_cm_free_xchg(unf_lport, xchg);
- return RETURN_ERROR;
- }
-
- /* 4. Cancel R_Port Open work */
- if (cancel_delayed_work(&unf_rport->open_work)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) RPort(0x%x) cancel open work succeed",
- unf_lport->port_id, unf_lport->nport_id, unf_rport->nport_id);
-
- /* This is not the last counter */
- atomic_dec(&unf_rport->rport_ref_cnt);
- }
-
- /* 5. Check R_Port state */
- if (unf_rport->rp_state != UNF_RPORT_ST_PRLI_WAIT &&
- unf_rport->rp_state != UNF_RPORT_ST_READY) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) RPort(0x%x) with state(0x%x) when received PRLI, send LOGO",
- unf_lport->port_id, unf_lport->nport_id,
- unf_rport->nport_id, unf_rport->rp_state);
-
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- /* NOTE: Start to send LOGO */
- unf_rport_enter_logo(unf_lport, unf_rport);
-
- unf_cm_free_xchg(unf_lport, xchg);
- unf_rport_ref_dec(unf_rport);
-
- return RETURN_ERROR;
- }
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- /* 6. Update R_Port options(INI/TGT/BOTH) */
- unf_rport->options =
- prli->payload.parms[ARRAY_INDEX_3] &
- (UNF_FC4_FRAME_PARM_3_TGT | UNF_FC4_FRAME_PARM_3_INI);
-
- unf_update_port_feature(unf_rport->port_name, unf_rport->options);
-
- /* for Confirm */
- unf_rport->fcp_conf_needed = false;
-
- unf_obtain_tape_capacity(unf_lport, unf_rport, prli->payload.parms[ARRAY_INDEX_3]);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x_0x%x) RPort(0x%x) parameter-3(0x%x) options(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, unf_rport->nport_id,
- prli->payload.parms[ARRAY_INDEX_3], unf_rport->options);
-
- /* 7. Send PRLI ACC */
- ret = unf_send_prli_acc(unf_lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) RPort(0x%x) send PRLI ACC failed",
- unf_lport->port_id, unf_lport->nport_id, unf_rport->nport_id);
-
- /* NOTE: exchange has been freed inner(before) */
- unf_rport_error_recovery(unf_rport);
- }
-
- /* 8. Decrease R_Port ref_cnt */
- unf_rport_ref_dec(unf_rport);
-
- return ret;
-}
-
-int unf_prli_async_handle(void *argc_in, void *argc_out)
-{
- struct unf_xchg *xchg = (struct unf_xchg *)argc_in;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- ret = unf_prli_handler_com_process(xchg);
-
- unf_xchg_ref_dec(xchg, SFS_RESPONSE);
-
- return (int)ret;
-}
-
-u32 unf_prli_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- u32 ret = UNF_RETURN_ERROR;
- bool switch2thread = false;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- xchg->sid = sid;
- xchg->lport = lport;
- unf_lport = lport;
-
- if (lport->bbscn_support &&
- lport->act_topo == UNF_ACT_TOP_P2P_DIRECT)
- switch2thread = true;
-
- if (switch2thread && unf_lport->root_lport == unf_lport) {
- /* Wait for LR done sync */
- ret = unf_irq_process_switch2thread(lport, xchg, unf_prli_async_handle);
- } else {
- ret = unf_prli_handler_com_process(xchg);
- }
-
- return ret;
-}
-
-static void unf_save_rscn_port_id(struct unf_rscn_mgr *rscn_mg,
- struct unf_rscn_port_id_page *rscn_port_id)
-{
- struct unf_port_id_page *exit_port_id_page = NULL;
- struct unf_port_id_page *new_port_id_page = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- bool is_repeat = false;
-
- FC_CHECK_RETURN_VOID(rscn_mg);
- FC_CHECK_RETURN_VOID(rscn_port_id);
-
- /* 1. check new RSCN Port_ID (RSNC_Page) whether within RSCN_Mgr or not
- */
- spin_lock_irqsave(&rscn_mg->rscn_id_list_lock, flag);
- if (list_empty(&rscn_mg->list_using_rscn_page)) {
- is_repeat = false;
- } else {
- /* Check repeat: for each exist RSCN page form RSCN_Mgr Page
- * list
- */
- list_for_each_safe(node, next_node, &rscn_mg->list_using_rscn_page) {
- exit_port_id_page = list_entry(node, struct unf_port_id_page,
- list_node_rscn);
- if (exit_port_id_page->port_id_port == rscn_port_id->port_id_port &&
- exit_port_id_page->port_id_area == rscn_port_id->port_id_area &&
- exit_port_id_page->port_id_domain == rscn_port_id->port_id_domain) {
- is_repeat = true;
- break;
- }
- }
- }
- spin_unlock_irqrestore(&rscn_mg->rscn_id_list_lock, flag);
-
- FC_CHECK_RETURN_VOID(rscn_mg->unf_get_free_rscn_node);
-
- /* 2. Get & add free RSNC Node --->>> RSCN_Mgr */
- if (!is_repeat) {
- new_port_id_page = rscn_mg->unf_get_free_rscn_node(rscn_mg);
- if (!new_port_id_page) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_ERR, "[err]Get free RSCN node failed");
-
- return;
- }
-
- new_port_id_page->addr_format = rscn_port_id->addr_format;
- new_port_id_page->event_qualifier = rscn_port_id->event_qualifier;
- new_port_id_page->reserved = rscn_port_id->reserved;
- new_port_id_page->port_id_domain = rscn_port_id->port_id_domain;
- new_port_id_page->port_id_area = rscn_port_id->port_id_area;
- new_port_id_page->port_id_port = rscn_port_id->port_id_port;
-
- /* Add entry to list: using_rscn_page */
- spin_lock_irqsave(&rscn_mg->rscn_id_list_lock, flag);
- list_add_tail(&new_port_id_page->list_node_rscn, &rscn_mg->list_using_rscn_page);
- spin_unlock_irqrestore(&rscn_mg->rscn_id_list_lock, flag);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) has repeat RSCN node with domain(0x%x) area(0x%x)",
- rscn_port_id->port_id_domain, rscn_port_id->port_id_area,
- rscn_port_id->port_id_port);
- }
-}
-
-static u32 unf_analysis_rscn_payload(struct unf_lport *lport,
- struct unf_rscn_pld *rscn_pld)
-{
-#define UNF_OS_DISC_REDISC_TIME 10000
-
- struct unf_rscn_port_id_page *rscn_port_id = NULL;
- struct unf_disc *disc = NULL;
- struct unf_rscn_mgr *rscn_mgr = NULL;
- u32 index = 0;
- u32 pld_len = 0;
- u32 port_id_page_cnt = 0;
- u32 ret = RETURN_OK;
- ulong flag = 0;
- bool eb_need_disc_flag = false;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rscn_pld, UNF_RETURN_ERROR);
-
- /* This field is the length in bytes of the entire Payload, inclusive of
- * the word 0
- */
- pld_len = UNF_GET_RSCN_PLD_LEN(rscn_pld->cmnd);
- pld_len -= sizeof(rscn_pld->cmnd);
- port_id_page_cnt = pld_len / UNF_RSCN_PAGE_LEN;
-
- /* Pages within payload is nor more than 255 */
- if (port_id_page_cnt > UNF_RSCN_PAGE_SUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x_0x%x) page num(0x%x) exceed 255 in RSCN",
- lport->port_id, lport->nport_id, port_id_page_cnt);
-
- return UNF_RETURN_ERROR;
- }
-
- /* L_Port-->Disc-->Rscn_Mgr */
- disc = &lport->disc;
- rscn_mgr = &disc->rscn_mgr;
-
- /* for each ID from RSCN_Page: check whether need to Disc or not */
- while (index < port_id_page_cnt) {
- rscn_port_id = &rscn_pld->port_id_page[index];
- if (unf_lookup_lport_by_nportid(lport, *(u32 *)rscn_port_id)) {
- /* Prevent to create session with L_Port which have the
- * same N_Port_ID
- */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) find local N_Port_ID(0x%x) within RSCN payload",
- ((struct unf_lport *)(lport->root_lport))->nport_id,
- *(u32 *)rscn_port_id);
- } else {
- /* New RSCN_Page ID find, save it to RSCN_Mgr */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x_0x%x) save RSCN N_Port_ID(0x%x)",
- lport->port_id, lport->nport_id,
- *(u32 *)rscn_port_id);
-
- /* 1. new RSCN_Page ID find, save it to RSCN_Mgr */
- unf_save_rscn_port_id(rscn_mgr, rscn_port_id);
- eb_need_disc_flag = true;
- }
- index++;
- }
-
- if (!eb_need_disc_flag) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info]Port(0x%x) find all N_Port_ID and do not need to disc",
- ((struct unf_lport *)(lport->root_lport))->nport_id);
-
- return RETURN_OK;
- }
-
- /* 2. Do/Start Disc: Check & do Disc (GID_PT) process */
- if (!disc->disc_temp.unf_disc_start) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) DISC start function is NULL",
- lport->nport_id, lport->nport_id);
-
- return UNF_RETURN_ERROR;
- }
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- if (disc->states == UNF_DISC_ST_END ||
- ((jiffies - disc->last_disc_jiff) > msecs_to_jiffies(UNF_OS_DISC_REDISC_TIME))) {
- disc->disc_option = UNF_RSCN_DISC;
- disc->last_disc_jiff = jiffies;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- ret = disc->disc_temp.unf_disc_start(lport);
- } else {
- FC_DRV_PRINT(UNF_LOG_ABNORMAL, UNF_INFO,
- "[info]Port(0x%x_0x%x) DISC state(0x%x) with last time(%llu) and don't do DISC",
- lport->port_id, lport->nport_id, disc->states,
- disc->last_disc_jiff);
-
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- }
-
- return ret;
-}
-
-u32 unf_rscn_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- /*
- * A RSCN ELS shall be sent to registered Nx_Ports
- * when an event occurs that may have affected the state of
- * one or more Nx_Ports, or the ULP state within the Nx_Port.
- * *
- * The Payload of a RSCN Request includes a list
- * containing the addresses of the affected Nx_Ports.
- * *
- * Each affected Port_ID page contains the ID of the Nx_Port,
- * Fabric Controller, E_Port, domain, or area for which the event was
- * detected.
- */
- struct unf_rscn_pld *rscn_pld = NULL;
- struct unf_rport *unf_rport = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 pld_len = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Receive RSCN Port(0x%x_0x%x)<---RPort(0x%x) OX_ID(0x%x)",
- lport->port_id, lport->nport_id, sid, xchg->oxid);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_RSCN);
-
- /* 1. Get R_Port by S_ID */
- unf_rport = unf_get_rport_by_nport_id(lport, sid); /* rport busy_list */
- if (!unf_rport) {
- unf_rport = unf_rport_get_free_and_init(lport, UNF_PORT_TYPE_FC, sid);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) received RSCN but has no RPort(0x%x) with OX_ID(0x%x)",
- lport->port_id, lport->nport_id, sid, xchg->oxid);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- unf_rport->nport_id = sid;
- }
-
- rscn_pld = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->rscn.rscn_pld;
- FC_CHECK_RETURN_VALUE(rscn_pld, UNF_RETURN_ERROR);
- pld_len = UNF_GET_RSCN_PLD_LEN(rscn_pld->cmnd);
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, rscn_pld, pld_len);
-
- /* 2. NOTE: Analysis RSCN payload(save & disc if necessary) */
- ret = unf_analysis_rscn_payload(lport, rscn_pld);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) analysis RSCN failed",
- lport->port_id, lport->nport_id);
- }
-
- /* 3. send rscn_acc after analysis payload */
- ret = unf_send_rscn_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) send RSCN response failed",
- lport->port_id, lport->nport_id);
- }
-
- return ret;
-}
-
-static void unf_analysis_pdisc_pld(struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_plogi_pdisc *pdisc)
-{
- struct unf_lgn_parm *pdisc_params = NULL;
- u64 wwpn = INVALID_VALUE64;
- u64 wwnn = INVALID_VALUE64;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(pdisc);
-
- pdisc_params = &pdisc->payload.stparms;
- if (pdisc_params->co_parms.bb_receive_data_field_size > UNF_MAX_FRAME_SIZE)
- rport->max_frame_size = UNF_MAX_FRAME_SIZE;
- else
- rport->max_frame_size = pdisc_params->co_parms.bb_receive_data_field_size;
-
- wwnn = (u64)(((u64)(pdisc_params->high_node_name) << UNF_SHIFT_32) |
- ((u64)pdisc_params->low_node_name));
- wwpn = (u64)(((u64)(pdisc_params->high_port_name) << UNF_SHIFT_32) |
- ((u64)pdisc_params->low_port_name));
-
- rport->port_name = wwpn;
- rport->node_name = wwnn;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) save PDISC parameters to Rport(0x%x) WWPN(0x%llx) WWNN(0x%llx)",
- lport->port_id, rport->nport_id, rport->port_name,
- rport->node_name);
-}
-
-u32 unf_send_pdisc_rjt(struct unf_lport *lport, struct unf_rport *rport, struct unf_xchg *xchg)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct unf_rjt_info rjt_info;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- memset(&rjt_info, 0, sizeof(struct unf_rjt_info));
- rjt_info.els_cmnd_code = ELS_PDISC;
- rjt_info.reason_code = UNF_LS_RJT_LOGICAL_ERROR;
- rjt_info.reason_explanation = UNF_LS_RJT_NO_ADDITIONAL_INFO;
-
- ret = unf_send_els_rjt_by_rport(lport, xchg, rport, &rjt_info);
-
- return ret;
-}
-
-u32 unf_pdisc_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_plogi_pdisc *pdisc = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flags = 0;
- u32 ret = RETURN_OK;
- u64 wwpn = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Receive PDISC. Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- lport->port_id, sid, xchg->oxid);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_PDISC);
- pdisc = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->pdisc;
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, &pdisc->payload,
- sizeof(struct unf_plogi_payload));
- wwpn = (u64)(((u64)(pdisc->payload.stparms.high_port_name) << UNF_SHIFT_32) |
- ((u64)pdisc->payload.stparms.low_port_name));
-
- unf_rport = unf_find_rport(lport, sid, wwpn);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't find RPort by NPort ID(0x%x). Free exchange and send LOGO",
- lport->port_id, sid);
-
- unf_cm_free_xchg(lport, xchg);
- (void)unf_send_logo_by_did(lport, sid);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MINOR,
- "[info]Port(0x%x) get exist RPort(0x%x) when receive PDISC with S_Id(0x%x)",
- lport->port_id, unf_rport->nport_id, sid);
-
- if (sid >= UNF_FC_FID_DOM_MGR)
- return unf_send_pdisc_rjt(lport, unf_rport, xchg);
-
- unf_analysis_pdisc_pld(lport, unf_rport, pdisc);
-
- /* State: READY */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- if (unf_rport->rp_state == UNF_RPORT_ST_READY) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) find RPort(0x%x) state is READY when receiving PDISC",
- lport->port_id, sid);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- ret = unf_send_pdisc_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) handle PDISC failed",
- lport->port_id);
-
- return ret;
- }
-
- /* Report Down/Up event to scsi */
- unf_update_lport_state_by_linkup_event(lport,
- unf_rport, unf_rport->options);
- } else if ((unf_rport->rp_state == UNF_RPORT_ST_CLOSING) &&
- (unf_rport->session)) {
- /* State: Closing */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find RPort(0x%x) state is 0x%x when receiving PDISC",
- lport->port_id, sid, unf_rport->rp_state);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- unf_cm_free_xchg(lport, xchg);
- (void)unf_send_logo_by_did(lport, sid);
- } else if (unf_rport->rp_state == UNF_RPORT_ST_PRLI_WAIT) {
- /* State: PRLI_WAIT */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) find RPort(0x%x) state is 0x%x when receiving PDISC",
- lport->port_id, sid, unf_rport->rp_state);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- ret = unf_send_pdisc_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) handle PDISC failed",
- lport->port_id);
-
- return ret;
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find RPort(0x%x) state is 0x%x when receiving PDISC, send LOGO",
- lport->port_id, sid, unf_rport->rp_state);
-
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- unf_rport_enter_logo(lport, unf_rport);
- unf_cm_free_xchg(lport, xchg);
- }
- }
-
- return ret;
-}
-
-static void unf_analysis_adisc_pld(struct unf_lport *lport,
- struct unf_rport *rport,
- struct unf_adisc_payload *adisc_pld)
-{
- u64 wwpn = INVALID_VALUE64;
- u64 wwnn = INVALID_VALUE64;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(adisc_pld);
-
- wwnn = (u64)(((u64)(adisc_pld->high_node_name) << UNF_SHIFT_32) |
- ((u64)adisc_pld->low_node_name));
- wwpn = (u64)(((u64)(adisc_pld->high_port_name) << UNF_SHIFT_32) |
- ((u64)adisc_pld->low_port_name));
-
- rport->port_name = wwpn;
- rport->node_name = wwnn;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) save ADISC parameters to RPort(0x%x), WWPN(0x%llx) WWNN(0x%llx) NPort ID(0x%x)",
- lport->port_id, rport->nport_id, rport->port_name,
- rport->node_name, adisc_pld->nport_id);
-}
-
-u32 unf_adisc_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_adisc_payload *adisc_pld = NULL;
- ulong flags = 0;
- u64 wwpn = 0;
- u32 ret = RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Receive ADISC. Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- lport->port_id, sid, xchg->oxid);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_ADISC);
- adisc_pld = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->adisc.adisc_payl;
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, adisc_pld, sizeof(struct unf_adisc_payload));
- wwpn = (u64)(((u64)(adisc_pld->high_port_name) << UNF_SHIFT_32) |
- ((u64)adisc_pld->low_port_name));
-
- unf_rport = unf_find_rport(lport, sid, wwpn);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't find RPort by NPort ID(0x%x). Free exchange and send LOGO",
- lport->port_id, sid);
-
- unf_cm_free_xchg(lport, xchg);
- (void)unf_send_logo_by_did(lport, sid);
-
- return ret;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MINOR,
- "[info]Port(0x%x) get exist RPort(0x%x) when receive ADISC with S_ID(0x%x)",
- lport->port_id, unf_rport->nport_id, sid);
-
- unf_analysis_adisc_pld(lport, unf_rport, adisc_pld);
-
- /* State: READY */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- if (unf_rport->rp_state == UNF_RPORT_ST_READY) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) find RPort(0x%x) state is READY when receiving ADISC",
- lport->port_id, sid);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- /* Return ACC directly */
- ret = unf_send_adisc_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ADISC ACC failed", lport->port_id);
-
- return ret;
- }
-
- /* Report Down/Up event to SCSI */
- unf_update_lport_state_by_linkup_event(lport, unf_rport, unf_rport->options);
- }
- /* State: Closing */
- else if ((unf_rport->rp_state == UNF_RPORT_ST_CLOSING) &&
- (unf_rport->session)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find RPort(0x%x) state is 0x%x when receiving ADISC",
- lport->port_id, sid, unf_rport->rp_state);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- unf_rport = unf_get_safe_rport(lport, unf_rport,
- UNF_RPORT_REUSE_RECOVER,
- unf_rport->nport_id);
- if (unf_rport) {
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- unf_rport->nport_id = sid;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- ret = unf_send_adisc_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ADISC ACC failed",
- lport->port_id);
-
- return ret;
- }
-
- unf_update_lport_state_by_linkup_event(lport,
- unf_rport, unf_rport->options);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't find RPort by NPort_ID(0x%x). Free exchange and send LOGO",
- lport->port_id, sid);
-
- unf_cm_free_xchg(lport, xchg);
- (void)unf_send_logo_by_did(lport, sid);
- }
- } else if (unf_rport->rp_state == UNF_RPORT_ST_PRLI_WAIT) {
- /* State: PRLI_WAIT */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) find RPort(0x%x) state is 0x%x when receiving ADISC",
- lport->port_id, sid, unf_rport->rp_state);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- ret = unf_send_adisc_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ADISC ACC failed", lport->port_id);
-
- return ret;
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find RPort(0x%x) state is 0x%x when receiving ADISC, send LOGO",
- lport->port_id, sid, unf_rport->rp_state);
-
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- unf_rport_enter_logo(lport, unf_rport);
- unf_cm_free_xchg(lport, xchg);
- }
-
- return ret;
-}
-
-u32 unf_rec_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_rport *unf_rport = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x) receive REC", lport->port_id);
-
- /* Send rec acc */
- ret = unf_send_rec_acc(lport, unf_rport, xchg); /* discard directly */
-
- return ret;
-}
-
-u32 unf_rrq_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_rrq *rrq = NULL;
- struct unf_xchg *xchg_reused = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
- u32 unf_sid = 0;
- ulong flags = 0;
- struct unf_rjt_info rjt_info = {0};
- struct unf_xchg_hot_pool *hot_pool = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_RRQ);
- rrq = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->rrq;
- ox_id = (u16)(rrq->oxid_rxid >> UNF_SHIFT_16);
- rx_id = (u16)(rrq->oxid_rxid);
- unf_sid = rrq->sid & UNF_NPORTID_MASK;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_KEVENT,
- "[warn]Receive RRQ. Port(0x%x)<---RPort(0x%x) sfsXchg(0x%p) OX_ID(0x%x,0x%x) RX_ID(0x%x)",
- lport->port_id, sid, xchg, ox_id, xchg->oxid, rx_id);
-
- /* Get R_Port */
- unf_rport = unf_get_rport_by_nport_id(lport, sid);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive RRQ but has no RPort(0x%x)",
- lport->port_id, sid);
-
- /* NOTE: send LOGO */
- unf_send_logo_by_did(lport, unf_sid);
-
- unf_cm_free_xchg(lport, xchg);
- return ret;
- }
-
- /* Get Target (Abort I/O) exchange context */
- xchg_reused = unf_cm_lookup_xchg_by_id(lport, ox_id, unf_sid); /* unf_find_xchg_by_ox_id */
- if (!xchg_reused) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) cannot find exchange with OX_ID(0x%x) RX_ID(0x%x) S_ID(0x%x)",
- lport->port_id, ox_id, rx_id, unf_sid);
-
- rjt_info.els_cmnd_code = ELS_RRQ;
- rjt_info.reason_code = FCXLS_BA_RJT_LOGICAL_ERROR | FCXLS_LS_RJT_INVALID_OXID_RXID;
-
- /* NOTE: send ELS RJT */
- if (unf_send_els_rjt_by_rport(lport, xchg, unf_rport, &rjt_info) != RETURN_OK) {
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
- }
-
- hot_pool = xchg_reused->hot_pool;
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) OxId(0x%x) Rxid(0x%x) Sid(0x%x) Hot Pool is NULL.",
- lport->port_id, ox_id, rx_id, unf_sid);
-
- return ret;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
- xchg_reused->oxid = INVALID_VALUE16;
- xchg_reused->rxid = INVALID_VALUE16;
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
-
- /* NOTE: release I/O exchange context */
- unf_xchg_ref_dec(xchg_reused, SFS_RESPONSE);
-
- /* Send RRQ ACC */
- ret = unf_send_rrq_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) can not send RRQ rsp. Xchg(0x%p) Ioxchg(0x%p) OX_RX_ID(0x%x 0x%x) S_ID(0x%x)",
- lport->port_id, xchg, xchg_reused, ox_id, rx_id, unf_sid);
-
- unf_cm_free_xchg(lport, xchg);
- }
-
- return ret;
-}
-
-u32 unf_logo_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_rport *logo_rport = NULL;
- struct unf_logo *logo = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 nport_id = 0;
- struct unf_rjt_info rjt_info = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_LOGO);
- logo = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->logo;
- nport_id = logo->payload.nport_id & UNF_NPORTID_MASK;
-
- if (sid < UNF_FC_FID_DOM_MGR) {
- /* R_Port is not fabric port */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]LOGIN: Receive LOGO. Port(0x%x)<---RPort(0x%x) NPort_ID(0x%x) OXID(0x%x)",
- lport->port_id, sid, nport_id, xchg->oxid);
- }
-
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, &logo->payload,
- sizeof(struct unf_logo_payload));
-
- /*
- * 1. S_ID unequal to NPort_ID:
- * link down Rport find by NPort_ID immediately
- */
- if (sid != nport_id) {
- logo_rport = unf_get_rport_by_nport_id(lport, nport_id);
- if (logo_rport)
- unf_rport_immediate_link_down(lport, logo_rport);
- }
-
- /* 2. Get R_Port by S_ID (frame header) */
- unf_rport = unf_get_rport_by_nport_id(lport, sid);
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_INIT, sid); /* INIT */
- if (!unf_rport) {
- memset(&rjt_info, 0, sizeof(struct unf_rjt_info));
- rjt_info.els_cmnd_code = ELS_LOGO;
- rjt_info.reason_code = UNF_LS_RJT_LOGICAL_ERROR;
- rjt_info.reason_explanation = UNF_LS_RJT_NO_ADDITIONAL_INFO;
- ret = unf_send_els_rjt_by_did(lport, xchg, sid, &rjt_info);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive LOGO but has no RPort(0x%x)",
- lport->port_id, sid);
-
- return ret;
- }
-
- /*
- * 3. I/O resource release: set ABORT tag
- * *
- * Call by: R_Port remove; RCVD LOGO; RCVD PLOGI; send PLOGI ACC
- */
- unf_cm_xchg_mgr_abort_io_by_id(lport, unf_rport, sid, lport->nport_id, INI_IO_STATE_LOGO);
-
- /* 4. Send LOGO ACC */
- ret = unf_send_logo_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) send LOGO failed", lport->port_id);
- }
- /*
- * 5. Do same operations with RCVD LOGO/PRLO & Send LOGO:
- * retry (LOGIN or LOGO) or link down immediately
- */
- unf_process_rport_after_logo(lport, unf_rport);
-
- return ret;
-}
-
-u32 unf_prlo_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_prli_prlo *prlo = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Receive PRLO. Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- lport->port_id, sid, xchg->oxid);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_LOGO);
-
- /* Get (new) R_Port */
- unf_rport = unf_get_rport_by_nport_id(lport, sid);
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_INIT, sid); /* INIT */
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive PRLO but has no RPort",
- lport->port_id);
-
- /* Discard directly */
- unf_cm_free_xchg(lport, xchg);
- return ret;
- }
-
- prlo = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->prlo;
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, &prlo->payload,
- sizeof(struct unf_prli_payload));
-
- /* Send PRLO ACC to remote */
- ret = unf_send_prlo_acc(lport, unf_rport, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) send PRLO ACC failed", lport->port_id);
- }
-
- /* Enter Enhanced action after LOGO (retry LOGIN or LOGO) */
- unf_process_rport_after_logo(lport, unf_rport);
-
- return ret;
-}
-
-static void unf_fill_echo_acc_pld(struct unf_echo *echo_acc)
-{
- struct unf_echo_payload *echo_acc_pld = NULL;
-
- FC_CHECK_RETURN_VOID(echo_acc);
-
- echo_acc_pld = echo_acc->echo_pld;
- FC_CHECK_RETURN_VOID(echo_acc_pld);
-
- echo_acc_pld->cmnd = UNF_ELS_CMND_ACC;
-}
-
-static void unf_echo_acc_callback(struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = xchg->lport;
-
- FC_CHECK_RETURN_VOID(unf_lport);
- if (xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo_acc.phy_echo_addr) {
- pci_unmap_single(unf_lport->low_level_func.dev,
- xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo_acc
- .phy_echo_addr,
- UNF_ECHO_PAYLOAD_LEN, DMA_BIDIRECTIONAL);
- xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo_acc.phy_echo_addr = 0;
- }
-}
-
-static u32 unf_send_echo_acc(struct unf_lport *lport, u32 did,
- struct unf_xchg *xchg)
-{
- struct unf_echo *echo_acc = NULL;
- union unf_sfs_u *fc_entry = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
- struct unf_frame_pkg pkg;
- dma_addr_t phy_echo_acc_addr;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
- xchg->cmnd_code = UNF_SET_ELS_ACC_TYPE(ELS_ECHO);
- xchg->did = did;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
-
- xchg->callback = NULL;
- xchg->ob_callback = unf_echo_acc_callback;
-
- unf_fill_package(&pkg, xchg, xchg->rport);
- pkg.type = UNF_PKG_ELS_REPLY;
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- echo_acc = &fc_entry->echo_acc;
- unf_fill_echo_acc_pld(echo_acc);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
- phy_echo_acc_addr = pci_map_single(lport->low_level_func.dev,
- echo_acc->echo_pld,
- UNF_ECHO_PAYLOAD_LEN,
- DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(lport->low_level_func.dev, phy_echo_acc_addr)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) pci map err",
- lport->port_id);
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
- echo_acc->phy_echo_addr = phy_echo_acc_addr;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK) {
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- pci_unmap_single(lport->low_level_func.dev,
- phy_echo_acc_addr, UNF_ECHO_PAYLOAD_LEN,
- DMA_BIDIRECTIONAL);
- echo_acc->phy_echo_addr = 0;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]ECHO ACC send %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- did, ox_id, rx_id);
-
- return ret;
-}
-
-u32 unf_echo_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg)
-{
- struct unf_echo_payload *echo_pld = NULL;
- struct unf_rport *unf_rport = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 data_len = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- data_len = xchg->fcp_sfs_union.sfs_entry.cur_offset;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Receive ECHO. Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x))",
- lport->port_id, sid, xchg->oxid);
-
- UNF_SERVICE_COLLECT(lport->link_service_info, UNF_SERVICE_ITEM_ECHO);
- echo_pld = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo.echo_pld;
- UNF_PRINT_SFS_LIMIT(UNF_INFO, lport->port_id, echo_pld, data_len);
- unf_rport = unf_get_rport_by_nport_id(lport, sid);
- xchg->rport = unf_rport;
-
- ret = unf_send_echo_acc(lport, sid, xchg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) send ECHO ACC failed", lport->port_id);
- }
-
- return ret;
-}
-
-static void unf_login_with_rport_in_n2n(struct unf_lport *lport,
- u64 remote_port_name,
- u64 remote_node_name)
-{
- /*
- * Call by (P2P):
- * 1. RCVD FLOGI ACC
- * 2. Send FLOGI ACC succeed
- * *
- * Compare WWN, larger is master, then send PLOGI
- */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = NULL;
- ulong lport_flag = 0;
- ulong rport_flag = 0;
- u64 port_name = 0;
- u64 node_name = 0;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VOID(lport);
-
- spin_lock_irqsave(&unf_lport->lport_state_lock, lport_flag);
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_READY); /* LPort: FLOGI_WAIT --> READY */
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, lport_flag);
-
- port_name = remote_port_name;
- node_name = remote_node_name;
-
- if (unf_lport->port_name > port_name) {
- /* Master case: send PLOGI */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x)'s WWN(0x%llx) is larger than rport(0x%llx), should be master",
- unf_lport->port_id, unf_lport->port_name, port_name);
-
- /* Update N_Port_ID now: 0xEF */
- unf_lport->nport_id = UNF_P2P_LOCAL_NPORT_ID;
-
- unf_rport = unf_find_valid_rport(lport, port_name, UNF_P2P_REMOTE_NPORT_ID);
- unf_rport = unf_get_safe_rport(lport, unf_rport, UNF_RPORT_REUSE_ONLY,
- UNF_P2P_REMOTE_NPORT_ID);
- if (unf_rport) {
- unf_rport->node_name = node_name;
- unf_rport->port_name = port_name;
- unf_rport->nport_id = UNF_P2P_REMOTE_NPORT_ID; /* 0xD6 */
- unf_rport->local_nport_id = UNF_P2P_LOCAL_NPORT_ID; /* 0xEF */
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, rport_flag);
- if (unf_rport->rp_state == UNF_RPORT_ST_PLOGI_WAIT ||
- unf_rport->rp_state == UNF_RPORT_ST_PRLI_WAIT ||
- unf_rport->rp_state == UNF_RPORT_ST_READY) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x) Rport(0x%x) have sent PLOGI or PRLI with state(0x%x)",
- unf_lport->port_id,
- unf_rport->nport_id,
- unf_rport->rp_state);
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock,
- rport_flag);
- return;
- }
- /* Update L_Port State: PLOGI_WAIT */
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, rport_flag);
-
- /* P2P with master: Start to Send PLOGI */
- ret = unf_send_plogi(unf_lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) with WWN(0x%llx) send PLOGI to(0x%llx) failed",
- unf_lport->port_id,
- unf_lport->port_name, port_name);
-
- unf_rport_error_recovery(unf_rport);
- }
- } else {
- /* Get/Alloc R_Port failed */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) with WWN(0x%llx) allocate RPort(ID:0x%x,WWPN:0x%llx) failed",
- unf_lport->port_id, unf_lport->port_name,
- UNF_P2P_REMOTE_NPORT_ID, port_name);
- }
- } else {
- /* Slave case: L_Port's Port Name is smaller than R_Port */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) with WWN(0x%llx) is smaller than rport(0x%llx), do nothing",
- unf_lport->port_id, unf_lport->port_name, port_name);
- }
-}
-
-void unf_lport_enter_mns_plogi(struct unf_lport *lport)
-{
- /* Fabric or Public Loop Mode: Login with Name server */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = NULL;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_plogi_payload *plogi_pld = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_xchg *xchg = NULL;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VOID(lport);
-
- /* Get (safe) R_Port */
- unf_rport = unf_rport_get_free_and_init(lport, UNF_PORT_TYPE_FC, UNF_FC_FID_MGMT_SERV);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) allocate RPort failed", lport->port_id);
- return;
- }
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = UNF_FC_FID_MGMT_SERV; /* 0xfffffa */
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
-
- /* Get & Set new free exchange */
- xchg = unf_cm_get_free_xchg(lport, UNF_XCHG_TYPE_SFS);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange can't be NULL for PLOGI", lport->port_id);
-
- return;
- }
-
- xchg->cmnd_code = ELS_PLOGI; /* PLOGI */
- xchg->did = unf_rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = unf_lport;
- xchg->rport = unf_rport;
-
- /* Set callback function */
- xchg->callback = NULL; /* for rcvd plogi acc/rjt processer */
- xchg->ob_callback = NULL; /* for send plogi failed processer */
-
- unf_fill_package(&pkg, xchg, unf_rport);
- pkg.type = UNF_PKG_ELS_REQ;
- /* Fill PLOGI payload */
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return;
- }
-
- plogi_pld = &fc_entry->plogi.payload;
- memset(plogi_pld, 0, sizeof(struct unf_plogi_payload));
- unf_fill_plogi_pld(plogi_pld, lport);
-
- /* Start to Send PLOGI command */
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-}
-
-static void unf_register_to_switch(struct unf_lport *lport)
-{
- /* Register to Fabric, used for: FABRIC & PUBLI LOOP */
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- unf_lport_state_ma(lport, UNF_EVENT_LPORT_REMOTE_ACC);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- /* Login with Name server: PLOGI */
- unf_lport_enter_sns_plogi(lport);
-
- unf_lport_enter_mns_plogi(lport);
-
- /* Physical Port */
- if (lport->root_lport == lport &&
- lport->act_topo == UNF_ACT_TOP_P2P_FABRIC) {
- unf_linkup_all_vports(lport);
- }
-}
-
-void unf_fdisc_ob_callback(struct unf_xchg *xchg)
-{
- /* Do recovery */
- struct unf_lport *unf_lport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- unf_lport = xchg->lport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: FDISC send failed");
-
- FC_CHECK_RETURN_VOID(unf_lport);
-
- /* Do L_Port error recovery */
- unf_lport_error_recovery(unf_lport);
-}
-
-void unf_fdisc_callback(void *lport, void *rport, void *exch)
-{
- /* Register to Name Server or Do recovery */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *xchg = NULL;
- struct unf_flogi_fdisc_payload *fdisc_pld = NULL;
- ulong flag = 0;
- u32 cmd = 0;
-
- unf_lport = (struct unf_lport *)lport;
- unf_rport = (struct unf_rport *)rport;
- xchg = (struct unf_xchg *)exch;
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(exch);
- FC_CHECK_RETURN_VOID(xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr);
- fdisc_pld = &xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->fdisc_acc.fdisc_payload;
- if (xchg->byte_orders & UNF_BIT_2)
- unf_big_end_to_cpu((u8 *)fdisc_pld, sizeof(struct unf_flogi_fdisc_payload));
-
- cmd = fdisc_pld->cmnd;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: FDISC response is (0x%x). Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- cmd, unf_lport->port_id, unf_rport->nport_id, xchg->oxid);
- unf_rport = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_FLOGI);
- unf_rport = unf_get_safe_rport(unf_lport, unf_rport,
- UNF_RPORT_REUSE_ONLY, UNF_FC_FID_FLOGI);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) has no Rport", unf_lport->port_id);
- return;
- }
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = UNF_FC_FID_FLOGI;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- if ((cmd & UNF_ELS_CMND_HIGH_MASK) == UNF_ELS_CMND_ACC) {
- /* Case for ACC */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- if (unf_lport->states != UNF_LPORT_ST_FLOGI_WAIT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) receive Flogi/Fdisc ACC in state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, unf_lport->states);
-
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
- return;
- }
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- unf_lport_update_nport_id(unf_lport, xchg->sid);
- unf_lport_update_time_params(unf_lport, fdisc_pld);
- unf_register_to_switch(unf_lport);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: FDISC response is (0x%x). Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- cmd, unf_lport->port_id, unf_rport->nport_id, xchg->oxid);
-
- /* Case for RJT: Do L_Port recovery */
- unf_lport_error_recovery(unf_lport);
- }
-}
-
-void unf_flogi_ob_callback(struct unf_xchg *xchg)
-{
- /* Send FLOGI failed & Do L_Port recovery */
- struct unf_lport *unf_lport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- /* Get L_port from exchange context */
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- unf_lport = xchg->lport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
- FC_CHECK_RETURN_VOID(unf_lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send FLOGI failed",
- unf_lport->port_id);
-
- /* Check L_Port state */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- if (unf_lport->states != UNF_LPORT_ST_FLOGI_WAIT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send FLOGI failed with state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, unf_lport->states);
-
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
- return;
- }
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- /* Do L_Port error recovery */
- unf_lport_error_recovery(unf_lport);
-}
-
-static void unf_lport_update_nport_id(struct unf_lport *lport, u32 nport_id)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- lport->nport_id = nport_id;
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-}
-
-static void
-unf_lport_update_time_params(struct unf_lport *lport,
- struct unf_flogi_fdisc_payload *flogi_payload)
-{
- ulong flag = 0;
- u32 ed_tov = 0;
- u32 ra_tov = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(flogi_payload);
-
- ed_tov = flogi_payload->fabric_parms.co_parms.e_d_tov;
- ra_tov = flogi_payload->fabric_parms.co_parms.r_a_tov;
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
-
- /* FC-FS-3: 21.3.4, 21.3.5 */
- if (lport->act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- lport->act_topo == UNF_ACT_TOP_PUBLIC_LOOP) {
- lport->ed_tov = ed_tov;
- lport->ra_tov = ra_tov;
- } else {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) with topo(0x%x) no need to save time parameters",
- lport->port_id, lport->nport_id, lport->act_topo);
- }
-
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-}
-
-static void unf_rcv_flogi_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_flogi_fdisc_payload *flogi_pld,
- u32 nport_id, struct unf_xchg *xchg)
-{
- /* PLOGI to Name server or remote port */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- struct unf_flogi_fdisc_payload *unf_flogi_pld = flogi_pld;
- struct unf_fabric_parm *fabric_params = NULL;
- u64 port_name = 0;
- u64 node_name = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(flogi_pld);
-
- /* Check L_Port state: FLOGI_WAIT */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- if (unf_lport->states != UNF_LPORT_ST_FLOGI_WAIT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[info]Port(0x%x_0x%x) receive FLOGI ACC with state(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, unf_lport->states);
-
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
- return;
- }
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- fabric_params = &unf_flogi_pld->fabric_parms;
- node_name =
- (u64)(((u64)(fabric_params->high_node_name) << UNF_SHIFT_32) |
- ((u64)(fabric_params->low_node_name)));
- port_name =
- (u64)(((u64)(fabric_params->high_port_name) << UNF_SHIFT_32) |
- ((u64)(fabric_params->low_port_name)));
-
- /* flogi acc pyload class 3 service priority value */
- if (unf_lport->root_lport == unf_lport && unf_lport->qos_cs_ctrl &&
- fabric_params->cl_parms[ARRAY_INDEX_2].priority == UNF_PRIORITY_ENABLE)
- unf_lport->priority = (bool)UNF_PRIORITY_ENABLE;
- else
- unf_lport->priority = (bool)UNF_PRIORITY_DISABLE;
-
- /* Save Flogi parameters */
- unf_save_fabric_params(unf_lport, unf_rport, fabric_params);
-
- if (UNF_CHECK_NPORT_FPORT_BIT(unf_flogi_pld) == UNF_N_PORT) {
- /* P2P Mode */
- unf_lport_update_topo(unf_lport, UNF_ACT_TOP_P2P_DIRECT);
- unf_login_with_rport_in_n2n(unf_lport, port_name, node_name);
- } else {
- /* for:
- * UNF_ACT_TOP_PUBLIC_LOOP/UNF_ACT_TOP_P2P_FABRIC
- * /UNF_TOP_P2P_MASK
- */
- if (unf_lport->act_topo != UNF_ACT_TOP_PUBLIC_LOOP)
- unf_lport_update_topo(unf_lport, UNF_ACT_TOP_P2P_FABRIC);
-
- unf_lport_update_nport_id(unf_lport, nport_id);
- unf_lport_update_time_params(unf_lport, unf_flogi_pld);
-
- /* Save process both for Public loop & Fabric */
- unf_register_to_switch(unf_lport);
- }
-}
-
-static void unf_flogi_acc_com_process(struct unf_xchg *xchg)
-{
- /* Maybe within interrupt or thread context */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_flogi_fdisc_payload *flogi_pld = NULL;
- u32 nport_id = 0;
- u32 cmnd = 0;
- ulong flags = 0;
- struct unf_xchg *unf_xchg = xchg;
-
- FC_CHECK_RETURN_VOID(unf_xchg);
- FC_CHECK_RETURN_VOID(unf_xchg->lport);
-
- unf_lport = unf_xchg->lport;
- unf_rport = unf_xchg->rport;
- flogi_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->flogi_acc.flogi_payload;
- cmnd = flogi_pld->cmnd;
-
- /* Get N_Port_ID & R_Port */
- /* Others: 0xFFFFFE */
- unf_rport = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_FLOGI);
- nport_id = UNF_FC_FID_FLOGI;
-
- /* Get Safe R_Port: reuse only */
- unf_rport = unf_get_safe_rport(unf_lport, unf_rport, UNF_RPORT_REUSE_ONLY, nport_id);
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can not allocate new Rport", unf_lport->port_id);
-
- return;
- }
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- unf_rport->nport_id = UNF_FC_FID_FLOGI;
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- /* Process FLOGI ACC or RJT */
- if ((cmnd & UNF_ELS_CMND_HIGH_MASK) == UNF_ELS_CMND_ACC) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: FLOGI response is(0x%x). Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- cmnd, unf_lport->port_id, unf_rport->nport_id, unf_xchg->oxid);
-
- /* Case for ACC */
- unf_rcv_flogi_acc(unf_lport, unf_rport, flogi_pld, unf_xchg->sid, unf_xchg);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: FLOGI response is(0x%x). Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- cmnd, unf_lport->port_id, unf_rport->nport_id,
- unf_xchg->oxid);
-
- /* Case for RJT: do L_Port error recovery */
- unf_lport_error_recovery(unf_lport);
- }
-}
-
-static int unf_rcv_flogi_acc_async_callback(void *argc_in, void *argc_out)
-{
- struct unf_xchg *xchg = (struct unf_xchg *)argc_in;
-
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- unf_flogi_acc_com_process(xchg);
-
- unf_xchg_ref_dec(xchg, SFS_RESPONSE);
-
- return RETURN_OK;
-}
-
-void unf_flogi_callback(void *lport, void *rport, void *xchg)
-{
- /* Callback function for FLOGI ACC or RJT */
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_flogi_fdisc_payload *flogi_pld = NULL;
- bool bbscn_enabled = false;
- enum unf_act_topo act_topo = UNF_ACT_TOP_UNKNOWN;
- bool switch2thread = false;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
- FC_CHECK_RETURN_VOID(unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr);
-
- unf_xchg->lport = lport;
- flogi_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->flogi_acc.flogi_payload;
-
- if (unf_xchg->byte_orders & UNF_BIT_2)
- unf_big_end_to_cpu((u8 *)flogi_pld, sizeof(struct unf_flogi_fdisc_payload));
-
- if (unf_lport->act_topo != UNF_ACT_TOP_PUBLIC_LOOP &&
- (UNF_CHECK_NPORT_FPORT_BIT(flogi_pld) == UNF_F_PORT))
- /* Get Top Mode (P2P_F) --->>> used for BBSCN */
- act_topo = UNF_ACT_TOP_P2P_FABRIC;
-
- bbscn_enabled =
- unf_check_bbscn_is_enabled((u8)unf_lport->low_level_func.lport_cfg_items.bbscn,
- (u8)UNF_GET_BB_SC_N_FROM_PARAMS(&flogi_pld->fabric_parms));
- if (act_topo == UNF_ACT_TOP_P2P_FABRIC && bbscn_enabled) {
- /* BBSCN Enable or not --->>> used for Context change */
- unf_lport->bbscn_support = true;
- switch2thread = true;
- }
-
- if (switch2thread && unf_lport->root_lport == unf_lport) {
- /* Wait for LR done sync: for Root Port */
- (void)unf_irq_process_switch2thread(unf_lport, unf_xchg,
- unf_rcv_flogi_acc_async_callback);
- } else {
- /* Process FLOGI response directly */
- unf_flogi_acc_com_process(unf_xchg);
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ALL,
- "[info]Port(0x%x) process FLOGI response: switch(%d) to thread done",
- unf_lport->port_id, switch2thread);
-}
-
-void unf_plogi_ob_callback(struct unf_xchg *xchg)
-{
- /* Do L_Port or R_Port recovery */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- unf_lport = xchg->lport;
- unf_rport = xchg->rport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_CHECK_RETURN_VOID(unf_lport);
- FC_CHECK_RETURN_VOID(unf_rport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) send PLOGI(0x%x_0x%x) to RPort(%p:0x%x_0x%x) failed",
- unf_lport->port_id, unf_lport->nport_id, xchg->oxid,
- xchg->rxid, unf_rport, unf_rport->rport_index,
- unf_rport->nport_id);
-
- /* Start to recovery */
- if (unf_rport->nport_id > UNF_FC_FID_DOM_MGR) {
- /* with Name server: R_Port is fabric --->>> L_Port error
- * recovery
- */
- unf_lport_error_recovery(unf_lport);
- } else {
- /* R_Port is not fabric --->>> R_Port error recovery */
- unf_rport_error_recovery(unf_rport);
- }
-}
-
-void unf_rcv_plogi_acc(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_lgn_parm *login_parms)
-{
- /* PLOGI ACC: PRLI(non fabric) or RFT_ID(fabric) */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- struct unf_lgn_parm *unf_login_parms = login_parms;
- u64 node_name = 0;
- u64 port_name = 0;
- ulong flag = 0;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(login_parms);
-
- node_name = (u64)(((u64)(unf_login_parms->high_node_name) << UNF_SHIFT_32) |
- ((u64)(unf_login_parms->low_node_name)));
- port_name = (u64)(((u64)(unf_login_parms->high_port_name) << UNF_SHIFT_32) |
- ((u64)(unf_login_parms->low_port_name)));
-
- /* ACC & Case for: R_Port is fabric (RFT_ID) */
- if (unf_rport->nport_id >= UNF_FC_FID_DOM_MGR) {
- /* Check L_Port state */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- if (unf_lport->states != UNF_LPORT_ST_PLOGI_WAIT) {
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive PLOGI ACC with error state(0x%x)",
- lport->port_id, unf_lport->states);
-
- return;
- }
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_REMOTE_ACC);
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- /* PLOGI parameters save */
- unf_save_plogi_params(unf_lport, unf_rport, unf_login_parms, ELS_ACC);
-
- /* Update R_Port WWPN & WWNN */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->node_name = node_name;
- unf_rport->port_name = port_name;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Start to Send RFT_ID */
- ret = unf_send_rft_id(unf_lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send RFT_ID failed",
- lport->port_id);
-
- unf_lport_error_recovery(unf_lport);
- }
- } else {
- /* ACC & Case for: R_Port is not fabric */
- if (unf_rport->options == UNF_PORT_MODE_UNKNOWN &&
- unf_rport->port_name != INVALID_WWPN)
- unf_rport->options = unf_get_port_feature(port_name);
-
- /* Set Port Feature with BOTH: cancel */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->node_name = node_name;
- unf_rport->port_name = port_name;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Port(0x%x)<---LS_ACC(DID:0x%x SID:0x%x) for PLOGI ACC with RPort state(0x%x) NodeName(0x%llx) E_D_TOV(%u)",
- unf_lport->port_id, unf_lport->nport_id,
- unf_rport->nport_id, unf_rport->rp_state,
- unf_rport->node_name, unf_rport->ed_tov);
-
- if (unf_lport->act_topo == UNF_ACT_TOP_PRIVATE_LOOP &&
- (unf_rport->rp_state == UNF_RPORT_ST_PRLI_WAIT ||
- unf_rport->rp_state == UNF_RPORT_ST_READY)) {
- /* Do nothing, return directly */
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
- return;
- }
-
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PRLI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* PLOGI parameters save */
- unf_save_plogi_params(unf_lport, unf_rport, unf_login_parms, ELS_ACC);
-
- /*
- * Need Delay to Send PRLI or not
- * Used for: L_Port with INI mode & R_Port is not Fabric
- */
- unf_check_rport_need_delay_prli(unf_lport, unf_rport, unf_rport->options);
-
- /* Do not care: Just used for L_Port only is TGT mode or R_Port
- * only is INI mode
- */
- unf_schedule_open_work(unf_lport, unf_rport);
- }
-}
-
-void unf_plogi_acc_com_process(struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_plogi_payload *plogi_pld = NULL;
- struct unf_lgn_parm *login_parms = NULL;
- ulong flag = 0;
- u64 port_name = 0;
- u32 rport_nport_id = 0;
- u32 cmnd = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(unf_xchg);
- FC_CHECK_RETURN_VOID(unf_xchg->lport);
- FC_CHECK_RETURN_VOID(unf_xchg->rport);
-
- unf_lport = unf_xchg->lport;
- unf_rport = unf_xchg->rport;
- rport_nport_id = unf_rport->nport_id;
- plogi_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->plogi_acc.payload;
- login_parms = &plogi_pld->stparms;
- cmnd = (plogi_pld->cmnd);
-
- if (UNF_ELS_CMND_ACC == (cmnd & UNF_ELS_CMND_HIGH_MASK)) {
- /* Case for PLOGI ACC: Go to next stage */
- port_name =
- (u64)(((u64)(login_parms->high_port_name) << UNF_SHIFT_32) |
- ((u64)(login_parms->low_port_name)));
-
- /* Get (new) R_Port: 0xfffffc has same WWN with 0xfffcxx */
- unf_rport = unf_find_rport(unf_lport, rport_nport_id, port_name);
- unf_rport = unf_get_safe_rport(unf_lport, unf_rport,
- UNF_RPORT_REUSE_ONLY, rport_nport_id);
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) alloc new RPort with wwpn(0x%llx) failed",
- unf_lport->port_id, unf_lport->nport_id, port_name);
- return;
- }
-
- /* PLOGI parameters check */
- ret = unf_check_plogi_params(unf_lport, unf_rport, login_parms);
- if (ret != RETURN_OK)
- return;
-
- /* Update R_Port state */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->nport_id = rport_nport_id;
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Start to process PLOGI ACC */
- unf_rcv_plogi_acc(unf_lport, unf_rport, login_parms);
- } else {
- /* Case for PLOGI RJT: L_Port or R_Port recovery */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x)<---RPort(0x%p) with LS_RJT(DID:0x%x SID:0x%x) for PLOGI",
- unf_lport->port_id, unf_rport, unf_lport->nport_id,
- unf_rport->nport_id);
-
- if (unf_rport->nport_id >= UNF_FC_FID_DOM_MGR)
- unf_lport_error_recovery(unf_lport);
- else
- unf_rport_error_recovery(unf_rport);
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: PLOGI response(0x%x). Port(0x%x_0x%x)<---RPort(0x%x_0x%p) wwpn(0x%llx) OX_ID(0x%x)",
- cmnd, unf_lport->port_id, unf_lport->nport_id, unf_rport->nport_id,
- unf_rport, port_name, unf_xchg->oxid);
-}
-
-static int unf_rcv_plogi_acc_async_callback(void *argc_in, void *argc_out)
-{
- struct unf_xchg *xchg = (struct unf_xchg *)argc_in;
-
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- unf_plogi_acc_com_process(xchg);
-
- unf_xchg_ref_dec(xchg, SFS_RESPONSE);
-
- return RETURN_OK;
-}
-
-void unf_plogi_callback(void *lport, void *rport, void *xchg)
-{
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
- struct unf_xchg *unf_xchg = (struct unf_xchg *)xchg;
- struct unf_plogi_payload *plogi_pld = NULL;
- struct unf_lgn_parm *login_parms = NULL;
- bool bbscn_enabled = false;
- bool switch2thread = false;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
- FC_CHECK_RETURN_VOID(unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr);
-
- plogi_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->plogi_acc.payload;
- login_parms = &plogi_pld->stparms;
- unf_xchg->lport = lport;
-
- if (unf_xchg->byte_orders & UNF_BIT_2)
- unf_big_end_to_cpu((u8 *)plogi_pld, sizeof(struct unf_plogi_payload));
-
- bbscn_enabled =
- unf_check_bbscn_is_enabled((u8)unf_lport->low_level_func.lport_cfg_items.bbscn,
- (u8)UNF_GET_BB_SC_N_FROM_PARAMS(login_parms));
- if ((bbscn_enabled) &&
- unf_lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- switch2thread = true;
- unf_lport->bbscn_support = true;
- }
-
- if (switch2thread && unf_lport->root_lport == unf_lport) {
- /* Wait for LR done sync: just for ROOT Port */
- (void)unf_irq_process_switch2thread(unf_lport, unf_xchg,
- unf_rcv_plogi_acc_async_callback);
- } else {
- unf_plogi_acc_com_process(unf_xchg);
- }
-}
-
-static void unf_logo_ob_callback(struct unf_xchg *xchg)
-{
- struct unf_lport *lport = NULL;
- struct unf_rport *rport = NULL;
- struct unf_rport *old_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- u32 nport_id = 0;
- u32 logo_retry = 0;
- u32 max_frame_size = 0;
- u64 port_name = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
- unf_xchg = xchg;
- old_rport = unf_xchg->rport;
- logo_retry = old_rport->logo_retries;
- max_frame_size = old_rport->max_frame_size;
- port_name = old_rport->port_name;
- unf_rport_enter_closing(old_rport);
-
- lport = unf_xchg->lport;
- if (unf_is_lport_valid(lport) != RETURN_OK)
- return;
-
- /* Get R_Port by exchange info: Init state */
- nport_id = unf_xchg->did;
- rport = unf_get_rport_by_nport_id(lport, nport_id);
- rport = unf_get_safe_rport(lport, rport, UNF_RPORT_REUSE_INIT, nport_id);
- if (!rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) cannot allocate RPort", lport->port_id);
- return;
- }
-
- rport->logo_retries = logo_retry;
- rport->max_frame_size = max_frame_size;
- rport->port_name = port_name;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[info]LOGIN: Port(0x%x) received LOGO RSP timeout topo(0x%x) retries(%u)",
- lport->port_id, lport->act_topo, rport->logo_retries);
-
- /* RCVD LOGO/PRLO & SEND LOGO: the same process */
- if (rport->logo_retries < UNF_MAX_RETRY_COUNT) {
- /* <: retry (LOGIN or LOGO) if necessary */
- unf_process_rport_after_logo(lport, rport);
- } else {
- /* >=: Link down */
- unf_rport_immediate_link_down(lport, rport);
- }
-}
-
-static void unf_logo_callback(void *lport, void *rport, void *xchg)
-{
- /* RCVD LOGO ACC/RJT: retry(LOGIN/LOGO) or link down immediately */
- struct unf_lport *unf_lport = (struct unf_lport *)lport;
- struct unf_rport *unf_rport = NULL;
- struct unf_rport *old_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_els_rjt *els_acc_rjt = NULL;
- u32 cmnd = 0;
- u32 nport_id = 0;
- u32 logo_retry = 0;
- u32 max_frame_size = 0;
- u64 port_name = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_xchg = (struct unf_xchg *)xchg;
- old_rport = unf_xchg->rport;
-
- logo_retry = old_rport->logo_retries;
- max_frame_size = old_rport->max_frame_size;
- port_name = old_rport->port_name;
- unf_rport_enter_closing(old_rport);
-
- if (unf_is_lport_valid(lport) != RETURN_OK)
- return;
-
- if (!unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr)
- return;
-
- /* Get R_Port by exchange info: Init state */
- els_acc_rjt = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->els_rjt;
- nport_id = unf_xchg->did;
- unf_rport = unf_get_rport_by_nport_id(unf_lport, nport_id);
- unf_rport = unf_get_safe_rport(unf_lport, unf_rport, UNF_RPORT_REUSE_INIT, nport_id);
-
- if (!unf_rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Port(0x%x) cannot allocate RPort",
- unf_lport->port_id);
- return;
- }
-
- unf_rport->logo_retries = logo_retry;
- unf_rport->max_frame_size = max_frame_size;
- unf_rport->port_name = port_name;
- cmnd = be32_to_cpu(els_acc_rjt->cmnd);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x) received LOGO RSP(0x%x),topo(0x%x) Port options(0x%x) RPort options(0x%x) retries(%u)",
- unf_lport->port_id, (cmnd & UNF_ELS_CMND_HIGH_MASK),
- unf_lport->act_topo, unf_lport->options, unf_rport->options,
- unf_rport->logo_retries);
-
- /* RCVD LOGO/PRLO & SEND LOGO: the same process */
- if (unf_rport->logo_retries < UNF_MAX_RETRY_COUNT) {
- /* <: retry (LOGIN or LOGO) if necessary */
- unf_process_rport_after_logo(unf_lport, unf_rport);
- } else {
- /* >=: Link down */
- unf_rport_immediate_link_down(unf_lport, unf_rport);
- }
-}
-
-void unf_prli_ob_callback(struct unf_xchg *xchg)
-{
- /* Do R_Port recovery */
- struct unf_lport *lport = NULL;
- struct unf_rport *rport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flag);
- lport = xchg->lport;
- rport = xchg->rport;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flag);
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x_0x%x) RPort(0x%x) send PRLI failed and do recovery",
- lport->port_id, lport->nport_id, rport->nport_id);
-
- /* Start to do R_Port error recovery */
- unf_rport_error_recovery(rport);
-}
-
-void unf_prli_callback(void *lport, void *rport, void *xchg)
-{
- /* RCVD PRLI RSP: ACC or RJT --->>> SCSI Link Up */
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_prli_payload *prli_acc_pld = NULL;
- ulong flag = 0;
- u32 cmnd = 0;
- u32 options = 0;
- u32 fcp_conf = 0;
- u32 rec_support = 0;
- u32 task_retry_support = 0;
- u32 retry_support = 0;
- u32 tape_support = 0;
- u32 fc4_type = 0;
- enum unf_rport_login_state rport_state = UNF_RPORT_ST_INIT;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
- unf_lport = (struct unf_lport *)lport;
- unf_rport = (struct unf_rport *)rport;
- unf_xchg = (struct unf_xchg *)xchg;
-
- if (!unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) exchange(%p) entry is NULL",
- unf_lport->port_id, unf_xchg);
- return;
- }
-
- /* Get PRLI ACC payload */
- prli_acc_pld = &unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->prli_acc.payload;
- if (unf_xchg->byte_orders & UNF_BIT_2) {
- /* Change to little End, About INI/TGT mode & confirm info */
- options = be32_to_cpu(prli_acc_pld->parms[ARRAY_INDEX_3]) &
- (UNF_FC4_FRAME_PARM_3_TGT | UNF_FC4_FRAME_PARM_3_INI);
-
- cmnd = be32_to_cpu(prli_acc_pld->cmnd);
- fcp_conf = be32_to_cpu(prli_acc_pld->parms[ARRAY_INDEX_3]) &
- UNF_FC4_FRAME_PARM_3_CONF_ALLOW;
- rec_support = be32_to_cpu(prli_acc_pld->parms[ARRAY_INDEX_3]) &
- UNF_FC4_FRAME_PARM_3_REC_SUPPORT;
- task_retry_support = be32_to_cpu(prli_acc_pld->parms[ARRAY_INDEX_3]) &
- UNF_FC4_FRAME_PARM_3_TASK_RETRY_ID_SUPPORT;
- retry_support = be32_to_cpu(prli_acc_pld->parms[ARRAY_INDEX_3]) &
- UNF_FC4_FRAME_PARM_3_RETRY_SUPPORT;
- fc4_type = be32_to_cpu(prli_acc_pld->parms[ARRAY_INDEX_0]) >>
- UNF_FC4_TYPE_SHIFT & UNF_FC4_TYPE_MASK;
- } else {
- options = (prli_acc_pld->parms[ARRAY_INDEX_3]) &
- (UNF_FC4_FRAME_PARM_3_TGT | UNF_FC4_FRAME_PARM_3_INI);
-
- cmnd = (prli_acc_pld->cmnd);
- fcp_conf = prli_acc_pld->parms[ARRAY_INDEX_3] & UNF_FC4_FRAME_PARM_3_CONF_ALLOW;
- rec_support = prli_acc_pld->parms[ARRAY_INDEX_3] & UNF_FC4_FRAME_PARM_3_REC_SUPPORT;
- task_retry_support = prli_acc_pld->parms[ARRAY_INDEX_3] &
- UNF_FC4_FRAME_PARM_3_TASK_RETRY_ID_SUPPORT;
- retry_support = prli_acc_pld->parms[ARRAY_INDEX_3] &
- UNF_FC4_FRAME_PARM_3_RETRY_SUPPORT;
- fc4_type = prli_acc_pld->parms[ARRAY_INDEX_0] >> UNF_FC4_TYPE_SHIFT;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: PRLI RSP: RPort(0x%x) parameter-3(0x%x) option(0x%x) cmd(0x%x) uiRecSupport:%u",
- unf_rport->nport_id, prli_acc_pld->parms[ARRAY_INDEX_3],
- options, cmnd, rec_support);
-
- /* PRLI ACC: R_Port READY & Report R_Port Link Up */
- if (UNF_ELS_CMND_ACC == (cmnd & UNF_ELS_CMND_HIGH_MASK)) {
- /* Update R_Port options(INI/TGT/BOTH) */
- unf_rport->options = options;
-
- unf_update_port_feature(unf_rport->port_name, unf_rport->options);
-
- /* NOTE: R_Port only with INI mode, send LOGO */
- if (unf_rport->options == UNF_PORT_MODE_INI) {
- /* Update R_Port state: LOGO */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* NOTE: Start to Send LOGO */
- unf_rport_enter_logo(unf_lport, unf_rport);
- return;
- }
-
- /* About confirm */
- if (fcp_conf && unf_lport->low_level_func.lport_cfg_items.fcp_conf) {
- unf_rport->fcp_conf_needed = true;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) FCP config is need for RPort(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- unf_rport->nport_id);
- }
-
- tape_support = (rec_support && task_retry_support && retry_support);
- if (tape_support && unf_lport->low_level_func.lport_cfg_items.tape_support) {
- unf_rport->tape_support_needed = true;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x_0x%x) Rec is enabled for RPort(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- unf_rport->nport_id);
- }
-
- /* Update R_Port state: READY */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_READY);
- rport_state = unf_rport->rp_state;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Report R_Port online (Link Up) event to SCSI */
- if (rport_state == UNF_RPORT_ST_READY) {
- unf_rport->logo_retries = 0;
- unf_update_lport_state_by_linkup_event(unf_lport, unf_rport,
- unf_rport->options);
- }
- } else {
- /* PRLI RJT: Do R_Port error recovery */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Port(0x%x)<---LS_RJT(DID:0x%x SID:0x%x) for PRLI. RPort(0x%p) OX_ID(0x%x)",
- unf_lport->port_id, unf_lport->nport_id,
- unf_rport->nport_id, unf_rport, unf_xchg->oxid);
-
- unf_rport_error_recovery(unf_rport);
- }
-}
-
-static void unf_rrq_callback(void *lport, void *rport, void *xchg)
-{
- /* Release I/O */
- struct unf_lport *unf_lport = NULL;
- struct unf_xchg *unf_xchg = NULL;
- struct unf_xchg *io_xchg = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(xchg);
-
- unf_lport = (struct unf_lport *)lport;
- unf_xchg = (struct unf_xchg *)xchg;
-
- if (!unf_xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) exchange(0x%p) SfsEntryPtr is NULL",
- unf_lport->port_id, unf_xchg);
- return;
- }
-
- io_xchg = (struct unf_xchg *)unf_xchg->io_xchg;
- if (!io_xchg) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) IO exchange is NULL. RRQ cb sfs xchg(0x%p) tag(0x%x)",
- unf_lport->port_id, unf_xchg, unf_xchg->hotpooltag);
- return;
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Port(0x%x) release IO exch(0x%p) tag(0x%x). RRQ cb sfs xchg(0x%p) tag(0x%x)",
- unf_lport->port_id, unf_xchg->io_xchg, io_xchg->hotpooltag,
- unf_xchg, unf_xchg->hotpooltag);
-
- /* After RRQ Success, Free xid */
- unf_notify_chip_free_xid(io_xchg);
-
- /* NOTE: release I/O exchange resource */
- unf_xchg_ref_dec(io_xchg, XCHG_ALLOC);
-}
-
-static void unf_rrq_ob_callback(struct unf_xchg *xchg)
-{
- /* Release I/O */
- struct unf_xchg *unf_xchg = NULL;
- struct unf_xchg *io_xchg = NULL;
-
- unf_xchg = (struct unf_xchg *)xchg;
- if (!unf_xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Exchange can't be NULL");
- return;
- }
-
- io_xchg = (struct unf_xchg *)unf_xchg->io_xchg;
- if (!io_xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]IO exchange can't be NULL with Sfs exch(0x%p) tag(0x%x)",
- unf_xchg, unf_xchg->hotpooltag);
- return;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]send RRQ failed: SFS exch(0x%p) tag(0x%x) exch(0x%p) tag(0x%x) OXID_RXID(0x%x_0x%x) SID_DID(0x%x_0x%x)",
- unf_xchg, unf_xchg->hotpooltag, io_xchg, io_xchg->hotpooltag,
- io_xchg->oxid, io_xchg->rxid, io_xchg->sid, io_xchg->did);
-
- /* If RRQ failure or timepout, Free xid. */
- unf_notify_chip_free_xid(io_xchg);
-
- /* NOTE: Free I/O exchange resource */
- unf_xchg_ref_dec(io_xchg, XCHG_ALLOC);
-}
diff --git a/drivers/scsi/spfc/common/unf_ls.h b/drivers/scsi/spfc/common/unf_ls.h
deleted file mode 100644
index 5fdd9e1a258d..000000000000
--- a/drivers/scsi/spfc/common/unf_ls.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_LS_H
-#define UNF_LS_H
-
-#include "unf_type.h"
-#include "unf_exchg.h"
-#include "unf_rport.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-u32 unf_send_adisc(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_send_pdisc(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_send_flogi(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_send_fdisc(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_send_plogi(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_send_prli(struct unf_lport *lport, struct unf_rport *rport,
- u32 cmnd_code);
-u32 unf_send_prlo(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_send_logo(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_send_logo_by_did(struct unf_lport *lport, u32 did);
-u32 unf_send_echo(struct unf_lport *lport, struct unf_rport *rport, u32 *time);
-u32 unf_send_plogi_rjt_by_did(struct unf_lport *lport, u32 did);
-u32 unf_send_rrq(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg);
-void unf_flogi_ob_callback(struct unf_xchg *xchg);
-void unf_flogi_callback(void *lport, void *rport, void *xchg);
-void unf_fdisc_ob_callback(struct unf_xchg *xchg);
-void unf_fdisc_callback(void *lport, void *rport, void *xchg);
-
-void unf_plogi_ob_callback(struct unf_xchg *xchg);
-void unf_plogi_callback(void *lport, void *rport, void *xchg);
-void unf_prli_ob_callback(struct unf_xchg *xchg);
-void unf_prli_callback(void *lport, void *rport, void *xchg);
-u32 unf_flogi_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_plogi_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_rec_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_prli_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_prlo_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_rscn_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_logo_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_echo_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_pdisc_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_send_pdisc_rjt(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *xchg);
-u32 unf_adisc_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_rrq_handler(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-u32 unf_send_rec(struct unf_lport *lport, struct unf_rport *rport,
- struct unf_xchg *io_xchg);
-
-u32 unf_low_level_bb_scn(struct unf_lport *lport);
-typedef int (*unf_event_task)(void *arg_in, void *arg_out);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __UNF_SERVICE_H__ */
diff --git a/drivers/scsi/spfc/common/unf_npiv.c b/drivers/scsi/spfc/common/unf_npiv.c
deleted file mode 100644
index 0d441f1c9e06..000000000000
--- a/drivers/scsi/spfc/common/unf_npiv.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_npiv.h"
-#include "unf_log.h"
-#include "unf_rport.h"
-#include "unf_exchg.h"
-#include "unf_portman.h"
-#include "unf_npiv_portman.h"
-
-#define UNF_DELETE_VPORT_MAX_WAIT_TIME_MS 60000
-
-u32 unf_init_vport_pool(struct unf_lport *lport)
-{
- u32 ret = RETURN_OK;
- u32 i;
- u16 vport_cnt = 0;
- struct unf_lport *vport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- u32 vport_pool_size;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, RETURN_ERROR);
-
- UNF_TOU16_CHECK(vport_cnt, lport->low_level_func.support_max_npiv_num,
- return RETURN_ERROR);
- if (vport_cnt == 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) do not support NPIV",
- lport->port_id);
-
- return RETURN_OK;
- }
-
- vport_pool_size = sizeof(struct unf_vport_pool) + sizeof(struct unf_lport *) * vport_cnt;
- lport->vport_pool = vmalloc(vport_pool_size);
- if (!lport->vport_pool) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) cannot allocate vport pool",
- lport->port_id);
-
- return RETURN_ERROR;
- }
- memset(lport->vport_pool, 0, vport_pool_size);
- vport_pool = lport->vport_pool;
- vport_pool->vport_pool_count = vport_cnt;
- vport_pool->vport_pool_completion = NULL;
- spin_lock_init(&vport_pool->vport_pool_lock);
- INIT_LIST_HEAD(&vport_pool->list_vport_pool);
-
- vport_pool->vport_pool_addr =
- vmalloc((size_t)(vport_cnt * sizeof(struct unf_lport)));
- if (!vport_pool->vport_pool_addr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) cannot allocate vport pool address",
- lport->port_id);
- vfree(lport->vport_pool);
- lport->vport_pool = NULL;
-
- return RETURN_ERROR;
- }
-
- memset(vport_pool->vport_pool_addr, 0,
- vport_cnt * sizeof(struct unf_lport));
- vport = (struct unf_lport *)vport_pool->vport_pool_addr;
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- for (i = 0; i < vport_cnt; i++) {
- list_add_tail(&vport->entry_vport, &vport_pool->list_vport_pool);
- vport++;
- }
-
- vport_pool->slab_next_index = 0;
- vport_pool->slab_total_sum = vport_cnt;
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- return ret;
-}
-
-void unf_free_vport_pool(struct unf_lport *lport)
-{
- struct unf_vport_pool *vport_pool = NULL;
- bool wait = false;
- ulong flag = 0;
- u32 remain = 0;
- struct completion vport_pool_completion;
-
- init_completion(&vport_pool_completion);
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(lport->vport_pool);
- vport_pool = lport->vport_pool;
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flag);
-
- if (vport_pool->slab_total_sum != vport_pool->vport_pool_count) {
- vport_pool->vport_pool_completion = &vport_pool_completion;
- remain = vport_pool->slab_total_sum - vport_pool->vport_pool_count;
- wait = true;
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- if (wait) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) begin to wait for vport pool completion remain(0x%x)",
- lport->port_id, remain);
-
- wait_for_completion(vport_pool->vport_pool_completion);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) wait for vport pool completion end",
- lport->port_id);
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flag);
- vport_pool->vport_pool_completion = NULL;
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
- }
-
- if (lport->vport_pool->vport_pool_addr) {
- vfree(lport->vport_pool->vport_pool_addr);
- lport->vport_pool->vport_pool_addr = NULL;
- }
-
- vfree(lport->vport_pool);
- lport->vport_pool = NULL;
-}
-
-struct unf_lport *unf_get_vport_by_slab_index(struct unf_vport_pool *vport_pool,
- u16 slab_index)
-{
- FC_CHECK_RETURN_VALUE(vport_pool, NULL);
-
- return vport_pool->vport_slab[slab_index];
-}
-
-static inline void unf_vport_pool_slab_set(struct unf_vport_pool *vport_pool,
- u16 slab_index,
- struct unf_lport *vport)
-{
- FC_CHECK_RETURN_VOID(vport_pool);
-
- vport_pool->vport_slab[slab_index] = vport;
-}
-
-u32 unf_alloc_vp_index(struct unf_vport_pool *vport_pool,
- struct unf_lport *vport, u16 vpid)
-{
- u16 slab_index;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(vport_pool, RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(vport, RETURN_ERROR);
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- if (vpid == 0) {
- slab_index = vport_pool->slab_next_index;
- while (unf_get_vport_by_slab_index(vport_pool, slab_index)) {
- slab_index = (slab_index + 1) % vport_pool->slab_total_sum;
-
- if (vport_pool->slab_next_index == slab_index) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]VPort pool has no slab ");
-
- return RETURN_ERROR;
- }
- }
- } else {
- slab_index = vpid - 1;
- if (unf_get_vport_by_slab_index(vport_pool, slab_index)) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_WARN,
- "[warn]VPort Index(0x%x) is occupy", vpid);
-
- return RETURN_ERROR;
- }
- }
-
- unf_vport_pool_slab_set(vport_pool, slab_index, vport);
-
- vport_pool->slab_next_index = (slab_index + 1) % vport_pool->slab_total_sum;
-
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- spin_lock_irqsave(&vport->lport_state_lock, flags);
- vport->vp_index = slab_index + 1;
- spin_unlock_irqrestore(&vport->lport_state_lock, flags);
-
- return RETURN_OK;
-}
-
-void unf_free_vp_index(struct unf_vport_pool *vport_pool,
- struct unf_lport *vport)
-{
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(vport_pool);
- FC_CHECK_RETURN_VOID(vport);
-
- if (vport->vp_index == 0 ||
- vport->vp_index > vport_pool->slab_total_sum) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Input vpoot index(0x%x) is beyond the normal range, min(0x1), max(0x%x).",
- vport->vp_index, vport_pool->slab_total_sum);
- return;
- }
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- unf_vport_pool_slab_set(vport_pool, vport->vp_index - 1,
- NULL); /* SlabIndex=VpIndex-1 */
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- spin_lock_irqsave(&vport->lport_state_lock, flags);
- vport->vp_index = INVALID_VALUE16;
- spin_unlock_irqrestore(&vport->lport_state_lock, flags);
-}
-
-struct unf_lport *unf_get_free_vport(struct unf_lport *lport)
-{
- struct unf_lport *vport = NULL;
- struct list_head *list_head = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(lport->vport_pool, NULL);
-
- vport_pool = lport->vport_pool;
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flag);
- if (!list_empty(&vport_pool->list_vport_pool)) {
- list_head = UNF_OS_LIST_NEXT(&vport_pool->list_vport_pool);
- list_del(list_head);
- vport_pool->vport_pool_count--;
- list_add_tail(list_head, &lport->list_vports_head);
- vport = list_entry(list_head, struct unf_lport, entry_vport);
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]LPort(0x%x)'s vport pool is empty", lport->port_id);
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- return NULL;
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- return vport;
-}
-
-void unf_vport_back_to_pool(void *vport)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *list = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(vport);
- unf_vport = vport;
- unf_lport = (struct unf_lport *)(unf_vport->root_lport);
- FC_CHECK_RETURN_VOID(unf_lport);
- FC_CHECK_RETURN_VOID(unf_lport->vport_pool);
-
- unf_free_vp_index(unf_lport->vport_pool, unf_vport);
-
- spin_lock_irqsave(&unf_lport->vport_pool->vport_pool_lock, flag);
-
- list = &unf_vport->entry_vport;
- list_del(list);
- list_add_tail(list, &unf_lport->vport_pool->list_vport_pool);
- unf_lport->vport_pool->vport_pool_count++;
-
- spin_unlock_irqrestore(&unf_lport->vport_pool->vport_pool_lock, flag);
-}
-
-void unf_init_vport_from_lport(struct unf_lport *vport, struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(vport);
- FC_CHECK_RETURN_VOID(lport);
-
- vport->port_type = lport->port_type;
- vport->fc_port = lport->fc_port;
- vport->act_topo = lport->act_topo;
- vport->root_lport = lport;
- vport->unf_qualify_rport = lport->unf_qualify_rport;
- vport->link_event_wq = lport->link_event_wq;
- vport->xchg_wq = lport->xchg_wq;
-
- memcpy(&vport->xchg_mgr_temp, &lport->xchg_mgr_temp,
- sizeof(struct unf_cm_xchg_mgr_template));
-
- memcpy(&vport->event_mgr, &lport->event_mgr, sizeof(struct unf_event_mgr));
-
- memset(&vport->lport_mgr_temp, 0, sizeof(struct unf_cm_lport_template));
-
- memcpy(&vport->low_level_func, &lport->low_level_func,
- sizeof(struct unf_low_level_functioon_op));
-}
-
-void unf_check_vport_pool_status(struct unf_lport *lport)
-{
- struct unf_vport_pool *vport_pool = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- vport_pool = lport->vport_pool;
- FC_CHECK_RETURN_VOID(vport_pool);
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
-
- if (vport_pool->vport_pool_completion &&
- vport_pool->slab_total_sum == vport_pool->vport_pool_count) {
- complete(vport_pool->vport_pool_completion);
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-}
-
-void unf_vport_fabric_logo(struct unf_lport *vport)
-{
- struct unf_rport *unf_rport = NULL;
- ulong flag = 0;
-
- unf_rport = unf_get_rport_by_nport_id(vport, UNF_FC_FID_FLOGI);
- FC_CHECK_RETURN_VOID(unf_rport);
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- unf_rport_enter_logo(vport, unf_rport);
-}
-
-void unf_vport_deinit(void *vport)
-{
- struct unf_lport *unf_vport = NULL;
-
- FC_CHECK_RETURN_VOID(vport);
- unf_vport = (struct unf_lport *)vport;
-
- unf_unregister_scsi_host(unf_vport);
-
- unf_disc_mgr_destroy(unf_vport);
-
- unf_release_xchg_mgr_temp(unf_vport);
-
- unf_release_vport_mgr_temp(unf_vport);
-
- unf_destroy_scsi_id_table(unf_vport);
-
- unf_lport_release_lw_funop(unf_vport);
- unf_vport->fc_port = NULL;
- unf_vport->vport = NULL;
-
- if (unf_vport->lport_free_completion) {
- complete(unf_vport->lport_free_completion);
- } else {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]VPort(0x%x) point(0x%p) completion free function is NULL",
- unf_vport->port_id, unf_vport);
- dump_stack();
- }
-}
-
-void unf_vport_ref_dec(struct unf_lport *vport)
-{
- FC_CHECK_RETURN_VOID(vport);
-
- if (atomic_dec_and_test(&vport->port_ref_cnt)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]VPort(0x%x) point(0x%p) reference count is 0 and freevport",
- vport->port_id, vport);
-
- unf_vport_deinit(vport);
- }
-}
-
-u32 unf_vport_init(void *vport)
-{
- struct unf_lport *unf_vport = NULL;
-
- FC_CHECK_RETURN_VALUE(vport, RETURN_ERROR);
- unf_vport = (struct unf_lport *)vport;
-
- unf_vport->options = UNF_PORT_MODE_INI;
- unf_vport->nport_id = 0;
-
- if (unf_init_scsi_id_table(unf_vport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Vport(0x%x) can not initialize SCSI ID table",
- unf_vport->port_id);
-
- return RETURN_ERROR;
- }
-
- if (unf_init_disc_mgr(unf_vport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Vport(0x%x) can not initialize discover manager",
- unf_vport->port_id);
- unf_destroy_scsi_id_table(unf_vport);
-
- return RETURN_ERROR;
- }
-
- if (unf_register_scsi_host(unf_vport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Vport(0x%x) vport can not register SCSI host",
- unf_vport->port_id);
- unf_disc_mgr_destroy(unf_vport);
- unf_destroy_scsi_id_table(unf_vport);
-
- return RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Vport(0x%x) Create succeed with wwpn(0x%llx)",
- unf_vport->port_id, unf_vport->port_name);
-
- return RETURN_OK;
-}
-
-void unf_vport_remove(void *vport)
-{
- struct unf_lport *unf_vport = NULL;
- struct unf_lport *unf_lport = NULL;
- struct completion port_free_completion;
-
- init_completion(&port_free_completion);
- FC_CHECK_RETURN_VOID(vport);
- unf_vport = (struct unf_lport *)vport;
- unf_lport = (struct unf_lport *)(unf_vport->root_lport);
- unf_vport->lport_free_completion = &port_free_completion;
-
- unf_set_lport_removing(unf_vport);
-
- unf_vport_ref_dec(unf_vport);
-
- wait_for_completion(unf_vport->lport_free_completion);
- unf_vport_back_to_pool(unf_vport);
-
- unf_check_vport_pool_status(unf_lport);
-}
-
-u32 unf_npiv_conf(u32 port_id, u64 wwpn, enum unf_rport_qos_level qos_level)
-{
-#define VPORT_WWN_MASK 0xff00ffffffffffff
-#define VPORT_WWN_SHIFT 48
-
- struct fc_vport_identifiers vid = {0};
- struct Scsi_Host *host = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_lport *unf_vport = NULL;
- u16 vport_id = 0;
-
- unf_lport = unf_find_lport_by_port_id(port_id);
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Cannot find LPort by (0x%x).", port_id);
-
- return RETURN_ERROR;
- }
-
- unf_vport = unf_cm_lookup_vport_by_wwpn(unf_lport, wwpn);
- if (unf_vport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Port(0x%x) has find vport with wwpn(0x%llx), can't create again",
- unf_lport->port_id, wwpn);
-
- return RETURN_ERROR;
- }
-
- unf_vport = unf_get_free_vport(unf_lport);
- if (!unf_vport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Can not get free vport from pool");
-
- return RETURN_ERROR;
- }
-
- unf_init_port_parms(unf_vport);
- unf_init_vport_from_lport(unf_vport, unf_lport);
-
- if ((unf_lport->port_name & VPORT_WWN_MASK) == (wwpn & VPORT_WWN_MASK)) {
- vport_id = (wwpn & ~VPORT_WWN_MASK) >> VPORT_WWN_SHIFT;
- if (vport_id == 0)
- vport_id = (unf_lport->port_name & ~VPORT_WWN_MASK) >> VPORT_WWN_SHIFT;
- }
-
- if (unf_alloc_vp_index(unf_lport->vport_pool, unf_vport, vport_id) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Vport can not allocate vport index");
- unf_vport_back_to_pool(unf_vport);
-
- return RETURN_ERROR;
- }
- unf_vport->port_id = (((u32)unf_vport->vp_index) << PORTID_VPINDEX_SHIT) |
- unf_lport->port_id;
-
- vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
- vid.vport_type = FC_PORTTYPE_NPIV;
- vid.disable = false;
- vid.node_name = unf_lport->node_name;
-
- if (wwpn) {
- vid.port_name = wwpn;
- } else {
- if ((unf_lport->port_name & ~VPORT_WWN_MASK) >> VPORT_WWN_SHIFT !=
- unf_vport->vp_index) {
- vid.port_name = (unf_lport->port_name & VPORT_WWN_MASK) |
- (((u64)unf_vport->vp_index) << VPORT_WWN_SHIFT);
- } else {
- vid.port_name = (unf_lport->port_name & VPORT_WWN_MASK);
- }
- }
-
- unf_vport->port_name = vid.port_name;
-
- host = unf_lport->host_info.host;
-
- if (!fc_vport_create(host, 0, &vid)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) Cannot Failed to create vport wwpn=%llx",
- unf_lport->port_id, vid.port_name);
-
- unf_vport_back_to_pool(unf_vport);
-
- return RETURN_ERROR;
- }
-
- unf_vport->qos_level = qos_level;
- return RETURN_OK;
-}
-
-struct unf_lport *unf_creat_vport(struct unf_lport *lport,
- struct vport_config *vport_config)
-{
- u32 ret = RETURN_OK;
- struct unf_lport *unf_lport = NULL;
- struct unf_lport *vport = NULL;
- enum unf_act_topo lport_topo;
- enum unf_lport_login_state lport_state;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(vport_config, NULL);
-
- if (vport_config->port_mode != FC_PORT_ROLE_FCP_INITIATOR) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Only support INITIATOR port mode(0x%x)",
- vport_config->port_mode);
-
- return NULL;
- }
- unf_lport = lport;
-
- if (unf_lport->root_lport != unf_lport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) not root port return",
- unf_lport->port_id);
-
- return NULL;
- }
-
- vport = unf_cm_lookup_vport_by_wwpn(unf_lport, vport_config->port_name);
- if (!vport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Port(0x%x) can not find vport with wwpn(0x%llx)",
- unf_lport->port_id, vport_config->port_name);
-
- return NULL;
- }
-
- ret = unf_vport_init(vport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]VPort(0x%x) can not initialize vport",
- vport->port_id);
-
- return NULL;
- }
-
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- lport_topo = unf_lport->act_topo;
- lport_state = unf_lport->states;
-
- vport_config->node_name = unf_lport->node_name;
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- vport->port_name = vport_config->port_name;
- vport->node_name = vport_config->node_name;
-
- if (lport_topo == UNF_ACT_TOP_P2P_FABRIC &&
- lport_state >= UNF_LPORT_ST_PLOGI_WAIT &&
- lport_state <= UNF_LPORT_ST_READY) {
- vport->link_up = unf_lport->link_up;
- (void)unf_lport_login(vport, lport_topo);
- }
-
- return vport;
-}
-
-u32 unf_drop_vport(struct unf_lport *vport)
-{
- u32 ret = RETURN_ERROR;
- struct fc_vport *unf_vport = NULL;
-
- FC_CHECK_RETURN_VALUE(vport, RETURN_ERROR);
-
- unf_vport = vport->vport;
- if (!unf_vport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]VPort(0x%x) find vport in scsi is NULL",
- vport->port_id);
-
- return ret;
- }
-
- ret = fc_vport_terminate(unf_vport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]VPort(0x%x) terminate vport(%p) in scsi failed",
- vport->port_id, unf_vport);
-
- return ret;
- }
- return ret;
-}
-
-u32 unf_delete_vport(u32 port_id, u32 vp_index)
-{
- struct unf_lport *unf_lport = NULL;
- u16 unf_vp_index = 0;
- struct unf_lport *vport = NULL;
-
- unf_lport = unf_find_lport_by_port_id(port_id);
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) can not be found by portid", port_id);
-
- return RETURN_ERROR;
- }
-
- if (atomic_read(&unf_lport->lport_no_operate_flag) == UNF_LPORT_NOP) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) is in NOP, destroy all vports function will be called",
- unf_lport->port_id);
-
- return RETURN_OK;
- }
-
- UNF_TOU16_CHECK(unf_vp_index, vp_index, return RETURN_ERROR);
- vport = unf_cm_lookup_vport_by_vp_index(unf_lport, unf_vp_index);
- if (!vport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Can not lookup VPort by VPort index(0x%x)",
- unf_vp_index);
-
- return RETURN_ERROR;
- }
-
- return unf_drop_vport(vport);
-}
-
-void unf_vport_abort_all_sfs_exch(struct unf_lport *vport)
-{
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- struct unf_xchg *exch = NULL;
- ulong pool_lock_flags = 0;
- ulong exch_lock_flags = 0;
- u32 i;
-
- FC_CHECK_RETURN_VOID(vport);
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport((struct unf_lport *)(vport->root_lport), i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) hot pool is NULL",
- ((struct unf_lport *)(vport->root_lport))->port_id);
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, pool_lock_flags);
- list_for_each_safe(xchg_node, next_xchg_node, &hot_pool->sfs_busylist) {
- exch = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
- spin_lock_irqsave(&exch->xchg_state_lock, exch_lock_flags);
- if (vport == exch->lport && (atomic_read(&exch->ref_cnt) > 0)) {
- exch->io_state |= TGT_IO_STATE_ABORT;
- spin_unlock_irqrestore(&exch->xchg_state_lock, exch_lock_flags);
- unf_disc_ctrl_size_inc(vport, exch->cmnd_code);
- /* Transfer exch to destroy chain */
- list_del(xchg_node);
- list_add_tail(xchg_node, &hot_pool->list_destroy_xchg);
- } else {
- spin_unlock_irqrestore(&exch->xchg_state_lock, exch_lock_flags);
- }
- }
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, pool_lock_flags);
- }
-}
-
-void unf_vport_abort_ini_io_exch(struct unf_lport *vport)
-{
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- struct unf_xchg *exch = NULL;
- ulong pool_lock_flags = 0;
- ulong exch_lock_flags = 0;
- u32 i;
-
- FC_CHECK_RETURN_VOID(vport);
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool = unf_get_hot_pool_by_lport((struct unf_lport *)(vport->root_lport), i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) MgrIdex %u hot pool is NULL",
- ((struct unf_lport *)(vport->root_lport))->port_id, i);
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, pool_lock_flags);
- list_for_each_safe(xchg_node, next_xchg_node, &hot_pool->ini_busylist) {
- exch = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
-
- if (vport == exch->lport && atomic_read(&exch->ref_cnt) > 0) {
- /* Transfer exch to destroy chain */
- list_del(xchg_node);
- list_add_tail(xchg_node, &hot_pool->list_destroy_xchg);
-
- spin_lock_irqsave(&exch->xchg_state_lock, exch_lock_flags);
- exch->io_state |= INI_IO_STATE_DRABORT;
- spin_unlock_irqrestore(&exch->xchg_state_lock, exch_lock_flags);
- }
- }
-
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, pool_lock_flags);
- }
-}
-
-void unf_vport_abort_exch(struct unf_lport *vport)
-{
- FC_CHECK_RETURN_VOID(vport);
-
- unf_vport_abort_all_sfs_exch(vport);
-
- unf_vport_abort_ini_io_exch(vport);
-}
-
-u32 unf_vport_wait_all_exch_removed(struct unf_lport *vport)
-{
-#define UNF_WAIT_EXCH_REMOVE_ONE_TIME_MS 1000
- struct unf_xchg_hot_pool *hot_pool = NULL;
- struct list_head *xchg_node = NULL;
- struct list_head *next_xchg_node = NULL;
- struct unf_xchg *exch = NULL;
- u32 vport_uses = 0;
- ulong flags = 0;
- u32 wait_timeout = 0;
- u32 i = 0;
-
- FC_CHECK_RETURN_VALUE(vport, RETURN_ERROR);
-
- while (1) {
- vport_uses = 0;
-
- for (i = 0; i < UNF_EXCHG_MGR_NUM; i++) {
- hot_pool =
- unf_get_hot_pool_by_lport((struct unf_lport *)(vport->root_lport), i);
- if (unlikely(!hot_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) hot Pool is NULL",
- ((struct unf_lport *)(vport->root_lport))->port_id);
-
- continue;
- }
-
- spin_lock_irqsave(&hot_pool->xchg_hotpool_lock, flags);
- list_for_each_safe(xchg_node, next_xchg_node,
- &hot_pool->list_destroy_xchg) {
- exch = list_entry(xchg_node, struct unf_xchg, list_xchg_entry);
-
- if (exch->lport != vport)
- continue;
- vport_uses++;
- if (wait_timeout >=
- UNF_DELETE_VPORT_MAX_WAIT_TIME_MS) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[error]VPort(0x%x) Abort Exch(0x%p) Type(0x%x) OxRxid(0x%x 0x%x),sid did(0x%x 0x%x) SeqId(0x%x) IOState(0x%x) Ref(0x%x)",
- vport->port_id, exch,
- (u32)exch->xchg_type,
- (u32)exch->oxid,
- (u32)exch->rxid, (u32)exch->sid,
- (u32)exch->did, (u32)exch->seq_id,
- (u32)exch->io_state,
- atomic_read(&exch->ref_cnt));
- }
- }
- spin_unlock_irqrestore(&hot_pool->xchg_hotpool_lock, flags);
- }
-
- if (vport_uses == 0) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]VPort(0x%x) has removed all exchanges it used",
- vport->port_id);
- break;
- }
-
- if (wait_timeout >= UNF_DELETE_VPORT_MAX_WAIT_TIME_MS)
- return RETURN_ERROR;
-
- msleep(UNF_WAIT_EXCH_REMOVE_ONE_TIME_MS);
- wait_timeout += UNF_WAIT_EXCH_REMOVE_ONE_TIME_MS;
- }
-
- return RETURN_OK;
-}
-
-u32 unf_vport_wait_rports_removed(struct unf_lport *vport)
-{
-#define UNF_WAIT_RPORT_REMOVE_ONE_TIME_MS 5000
-
- struct unf_disc *disc = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- u32 vport_uses = 0;
- ulong flags = 0;
- u32 wait_timeout = 0;
- struct unf_rport *unf_rport = NULL;
-
- FC_CHECK_RETURN_VALUE(vport, RETURN_ERROR);
- disc = &vport->disc;
-
- while (1) {
- vport_uses = 0;
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flags);
- list_for_each_safe(node, next_node, &disc->list_delete_rports) {
- unf_rport = list_entry(node, struct unf_rport, entry_rport);
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info]Vport(0x%x) Rport(0x%x) point(%p) is in Delete",
- vport->port_id, unf_rport->nport_id, unf_rport);
- vport_uses++;
- }
-
- list_for_each_safe(node, next_node, &disc->list_destroy_rports) {
- unf_rport = list_entry(node, struct unf_rport, entry_rport);
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info]Vport(0x%x) Rport(0x%x) point(%p) is in Destroy",
- vport->port_id, unf_rport->nport_id, unf_rport);
- vport_uses++;
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flags);
-
- if (vport_uses == 0) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]VPort(0x%x) has removed all RPorts it used",
- vport->port_id);
- break;
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Vport(0x%x) has %u RPorts not removed wait timeout(%u ms)",
- vport->port_id, vport_uses, wait_timeout);
-
- if (wait_timeout >= UNF_DELETE_VPORT_MAX_WAIT_TIME_MS)
- return RETURN_ERROR;
-
- msleep(UNF_WAIT_RPORT_REMOVE_ONE_TIME_MS);
- wait_timeout += UNF_WAIT_RPORT_REMOVE_ONE_TIME_MS;
- }
-
- return RETURN_OK;
-}
-
-u32 unf_destroy_one_vport(struct unf_lport *vport)
-{
- u32 ret;
- struct unf_lport *root_port = NULL;
-
- FC_CHECK_RETURN_VALUE(vport, RETURN_ERROR);
-
- root_port = (struct unf_lport *)vport->root_lport;
-
- unf_vport_fabric_logo(vport);
-
- /* 1 set NOP */
- atomic_set(&vport->lport_no_operate_flag, UNF_LPORT_NOP);
- vport->port_removing = true;
-
- /* 2 report linkdown to scsi and delele rpot */
- unf_linkdown_one_vport(vport);
-
- /* 3 set abort for exchange */
- unf_vport_abort_exch(vport);
-
- /* 4 wait exch return freepool */
- if (!root_port->port_dirt_exchange) {
- ret = unf_vport_wait_all_exch_removed(vport);
- if (ret != RETURN_OK) {
- if (!root_port->port_removing) {
- vport->port_removing = false;
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]VPort(0x%x) can not wait Exchange return freepool",
- vport->port_id);
-
- return RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "[warn]Port(0x%x) is removing, there is dirty exchange, continue",
- root_port->port_id);
-
- root_port->port_dirt_exchange = true;
- }
- }
-
- /* wait rport return rportpool */
- ret = unf_vport_wait_rports_removed(vport);
- if (ret != RETURN_OK) {
- vport->port_removing = false;
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]VPort(0x%x) can not wait Rport return freepool",
- vport->port_id);
-
- return RETURN_ERROR;
- }
-
- unf_cm_vport_remove(vport);
-
- return RETURN_OK;
-}
-
-void unf_destroy_all_vports(struct unf_lport *lport)
-{
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_lport *vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flags = 0;
-
- unf_lport = lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Lport(0x%x) VPort pool is NULL", unf_lport->port_id);
-
- return;
- }
-
- /* Transfer to the transition chain */
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- vport = list_entry(node, struct unf_lport, entry_vport);
- list_del_init(&vport->entry_vport);
- list_add_tail(&vport->entry_vport, &unf_lport->list_destroy_vports);
- }
-
- list_for_each_safe(node, next_node, &unf_lport->list_intergrad_vports) {
- vport = list_entry(node, struct unf_lport, entry_vport);
- list_del_init(&vport->entry_vport);
- list_add_tail(&vport->entry_vport, &unf_lport->list_destroy_vports);
- atomic_dec(&vport->port_ref_cnt);
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- while (!list_empty(&unf_lport->list_destroy_vports)) {
- node = UNF_OS_LIST_NEXT(&unf_lport->list_destroy_vports);
- vport = list_entry(node, struct unf_lport, entry_vport);
-
- list_del_init(&vport->entry_vport);
- list_add_tail(&vport->entry_vport, &unf_lport->list_vports_head);
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]VPort(0x%x) Destroy begin", vport->port_id);
- unf_drop_vport(vport);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[info]VPort(0x%x) Destroy end", vport->port_id);
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-}
-
-u32 unf_init_vport_mgr_temp(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- lport->lport_mgr_temp.unf_look_up_vport_by_index = unf_lookup_vport_by_index;
- lport->lport_mgr_temp.unf_look_up_vport_by_port_id = unf_lookup_vport_by_portid;
- lport->lport_mgr_temp.unf_look_up_vport_by_did = unf_lookup_vport_by_did;
- lport->lport_mgr_temp.unf_look_up_vport_by_wwpn = unf_lookup_vport_by_wwpn;
- lport->lport_mgr_temp.unf_vport_remove = unf_vport_remove;
-
- return RETURN_OK;
-}
-
-void unf_release_vport_mgr_temp(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- memset(&lport->lport_mgr_temp, 0, sizeof(struct unf_cm_lport_template));
-
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_9_DESTROY_LPORT_MG_TMP;
-}
diff --git a/drivers/scsi/spfc/common/unf_npiv.h b/drivers/scsi/spfc/common/unf_npiv.h
deleted file mode 100644
index 6f522470f47a..000000000000
--- a/drivers/scsi/spfc/common/unf_npiv.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_NPIV_H
-#define UNF_NPIV_H
-
-#include "unf_type.h"
-#include "unf_common.h"
-#include "unf_lport.h"
-
-/* product VPORT configure */
-struct vport_config {
- u64 node_name;
- u64 port_name;
- u32 port_mode; /* INI, TGT or both */
-};
-
-/* product Vport function */
-#define PORTID_VPINDEX_MASK 0xff000000
-#define PORTID_VPINDEX_SHIT 24
-u32 unf_npiv_conf(u32 port_id, u64 wwpn, enum unf_rport_qos_level qos_level);
-struct unf_lport *unf_creat_vport(struct unf_lport *lport,
- struct vport_config *vport_config);
-u32 unf_delete_vport(u32 port_id, u32 vp_index);
-
-/* Vport pool creat and release function */
-u32 unf_init_vport_pool(struct unf_lport *lport);
-void unf_free_vport_pool(struct unf_lport *lport);
-
-/* Lport resigster stLPortMgTemp function */
-void unf_vport_remove(void *vport);
-void unf_vport_ref_dec(struct unf_lport *vport);
-
-/* linkdown all Vport after receive linkdown event */
-void unf_linkdown_all_vports(void *lport);
-/* Lport receive Flogi Acc linkup all Vport */
-void unf_linkup_all_vports(struct unf_lport *lport);
-/* Lport remove delete all Vport */
-void unf_destroy_all_vports(struct unf_lport *lport);
-void unf_vport_fabric_logo(struct unf_lport *vport);
-u32 unf_destroy_one_vport(struct unf_lport *vport);
-u32 unf_drop_vport(struct unf_lport *vport);
-u32 unf_init_vport_mgr_temp(struct unf_lport *lport);
-void unf_release_vport_mgr_temp(struct unf_lport *lport);
-struct unf_lport *unf_get_vport_by_slab_index(struct unf_vport_pool *vport_pool,
- u16 slab_index);
-#endif
diff --git a/drivers/scsi/spfc/common/unf_npiv_portman.c b/drivers/scsi/spfc/common/unf_npiv_portman.c
deleted file mode 100644
index b4f393f2e732..000000000000
--- a/drivers/scsi/spfc/common/unf_npiv_portman.c
+++ /dev/null
@@ -1,360 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_npiv_portman.h"
-#include "unf_log.h"
-#include "unf_common.h"
-#include "unf_rport.h"
-#include "unf_npiv.h"
-#include "unf_portman.h"
-
-void *unf_lookup_vport_by_index(void *lport, u16 vp_index)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_vport = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- unf_lport = (struct unf_lport *)lport;
-
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) vport pool is NULL", unf_lport->port_id);
-
- return NULL;
- }
-
- if (vp_index == 0 || vp_index > vport_pool->slab_total_sum) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) input vport index(0x%x) is beyond the normal range(0x1~0x%x)",
- unf_lport->port_id, vp_index, vport_pool->slab_total_sum);
-
- return NULL;
- }
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- unf_vport = unf_get_vport_by_slab_index(vport_pool, vp_index - 1);
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- return (void *)unf_vport;
-}
-
-void *unf_lookup_vport_by_portid(void *lport, u32 port_id)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- unf_lport = (struct unf_lport *)lport;
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) vport pool is NULL", unf_lport->port_id);
-
- return NULL;
- }
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flag);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->port_id == port_id) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
- return unf_vport;
- }
- }
-
- list_for_each_safe(node, next_node, &unf_lport->list_intergrad_vports) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->port_id == port_id) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
- return unf_vport;
- }
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) has no vport ID(0x%x).",
- unf_lport->port_id, port_id);
- return NULL;
-}
-
-void *unf_lookup_vport_by_did(void *lport, u32 did)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- unf_lport = (struct unf_lport *)lport;
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) vport pool is NULL", unf_lport->port_id);
-
- return NULL;
- }
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flag);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->nport_id == did) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- return unf_vport;
- }
- }
-
- list_for_each_safe(node, next_node, &unf_lport->list_intergrad_vports) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->nport_id == did) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
- return unf_vport;
- }
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) has no vport Nport ID(0x%x)", unf_lport->port_id, did);
- return NULL;
-}
-
-void *unf_lookup_vport_by_wwpn(void *lport, u64 wwpn)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- unf_lport = (struct unf_lport *)lport;
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) vport pool is NULL", unf_lport->port_id);
-
- return NULL;
- }
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flag);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->port_name == wwpn) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- return unf_vport;
- }
- }
-
- list_for_each_safe(node, next_node, &unf_lport->list_intergrad_vports) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->port_name == wwpn) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
- return unf_vport;
- }
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) has no vport WWPN(0x%llx)",
- unf_lport->port_id, wwpn);
-
- return NULL;
-}
-
-void unf_linkdown_one_vport(struct unf_lport *vport)
-{
- ulong flag = 0;
- struct unf_lport *root_lport = NULL;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_KEVENT,
- "[info]VPort(0x%x) linkdown", vport->port_id);
-
- spin_lock_irqsave(&vport->lport_state_lock, flag);
- vport->link_up = UNF_PORT_LINK_DOWN;
- vport->nport_id = 0; /* set nportid 0 before send fdisc again */
- unf_lport_state_ma(vport, UNF_EVENT_LPORT_LINK_DOWN);
- spin_unlock_irqrestore(&vport->lport_state_lock, flag);
-
- root_lport = (struct unf_lport *)vport->root_lport;
-
- unf_flush_disc_event(&root_lport->disc, vport);
-
- unf_clean_linkdown_rport(vport);
-}
-
-void unf_linkdown_all_vports(void *lport)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport = (struct unf_lport *)lport;
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) VPort pool is NULL", unf_lport->port_id);
-
- return;
- }
-
- /* Transfer to the transition chain */
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- list_del_init(&unf_vport->entry_vport);
- list_add_tail(&unf_vport->entry_vport, &unf_lport->list_intergrad_vports);
- (void)unf_lport_ref_inc(unf_vport);
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- while (!list_empty(&unf_lport->list_intergrad_vports)) {
- node = UNF_OS_LIST_NEXT(&unf_lport->list_intergrad_vports);
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
-
- list_del_init(&unf_vport->entry_vport);
- list_add_tail(&unf_vport->entry_vport, &unf_lport->list_vports_head);
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- unf_linkdown_one_vport(unf_vport);
-
- unf_vport_ref_dec(unf_vport);
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-}
-
-int unf_process_vports_linkup(void *arg_in, void *arg_out)
-{
-#define UNF_WAIT_VPORT_LOGIN_ONE_TIME_MS 100
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flags = 0;
- int ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(arg_in, RETURN_ERROR);
-
- unf_lport = (struct unf_lport *)arg_in;
-
- if (atomic_read(&unf_lport->lport_no_operate_flag) == UNF_LPORT_NOP) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) is NOP don't continue", unf_lport->port_id);
-
- return RETURN_OK;
- }
-
- if (unf_lport->link_up != UNF_PORT_LINK_UP) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) is not linkup don't continue.",
- unf_lport->port_id);
-
- return RETURN_OK;
- }
-
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) VPort pool is NULL.", unf_lport->port_id);
-
- return RETURN_OK;
- }
-
- /* Transfer to the transition chain */
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- list_del_init(&unf_vport->entry_vport);
- list_add_tail(&unf_vport->entry_vport, &unf_lport->list_intergrad_vports);
- (void)unf_lport_ref_inc(unf_vport);
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- while (!list_empty(&unf_lport->list_intergrad_vports)) {
- node = UNF_OS_LIST_NEXT(&unf_lport->list_intergrad_vports);
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
-
- list_del_init(&unf_vport->entry_vport);
- list_add_tail(&unf_vport->entry_vport, &unf_lport->list_vports_head);
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- if (atomic_read(&unf_vport->lport_no_operate_flag) == UNF_LPORT_NOP) {
- unf_vport_ref_dec(unf_vport);
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- continue;
- }
-
- if (unf_lport->link_up == UNF_PORT_LINK_UP &&
- unf_lport->act_topo == UNF_ACT_TOP_P2P_FABRIC) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Vport(0x%x) begin login", unf_vport->port_id);
-
- unf_vport->link_up = UNF_PORT_LINK_UP;
- (void)unf_lport_login(unf_vport, unf_lport->act_topo);
-
- msleep(UNF_WAIT_VPORT_LOGIN_ONE_TIME_MS);
- } else {
- unf_linkdown_one_vport(unf_vport);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Vport(0x%x) login failed because root port linkdown",
- unf_vport->port_id);
- }
-
- unf_vport_ref_dec(unf_vport);
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flags);
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flags);
-
- return ret;
-}
-
-void unf_linkup_all_vports(struct unf_lport *lport)
-{
- struct unf_cm_event_report *event = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
-
- if (unlikely(!lport->event_mgr.unf_get_free_event_func ||
- !lport->event_mgr.unf_post_event_func ||
- !lport->event_mgr.unf_release_event)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) Event fun is NULL",
- lport->port_id);
- return;
- }
-
- event = lport->event_mgr.unf_get_free_event_func((void *)lport);
- FC_CHECK_RETURN_VOID(event);
-
- event->lport = lport;
- event->event_asy_flag = UNF_EVENT_ASYN;
- event->unf_event_task = unf_process_vports_linkup;
- event->para_in = (void *)lport;
-
- lport->event_mgr.unf_post_event_func(lport, event);
-}
diff --git a/drivers/scsi/spfc/common/unf_npiv_portman.h b/drivers/scsi/spfc/common/unf_npiv_portman.h
deleted file mode 100644
index 284c23c9abe4..000000000000
--- a/drivers/scsi/spfc/common/unf_npiv_portman.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_NPIV_PORTMAN_H
-#define UNF_NPIV_PORTMAN_H
-
-#include "unf_type.h"
-#include "unf_lport.h"
-
-/* Lport resigster stLPortMgTemp function */
-void *unf_lookup_vport_by_index(void *lport, u16 vp_index);
-void *unf_lookup_vport_by_portid(void *lport, u32 port_id);
-void *unf_lookup_vport_by_did(void *lport, u32 did);
-void *unf_lookup_vport_by_wwpn(void *lport, u64 wwpn);
-void unf_linkdown_one_vport(struct unf_lport *vport);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_portman.c b/drivers/scsi/spfc/common/unf_portman.c
deleted file mode 100644
index ef8f90eb3777..000000000000
--- a/drivers/scsi/spfc/common/unf_portman.c
+++ /dev/null
@@ -1,2431 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_portman.h"
-#include "unf_log.h"
-#include "unf_exchg.h"
-#include "unf_rport.h"
-#include "unf_io.h"
-#include "unf_npiv.h"
-#include "unf_scsi_common.h"
-
-#define UNF_LPORT_CHIP_ERROR(unf_lport) \
- ((unf_lport)->pcie_error_cnt.pcie_error_count[UNF_PCIE_FATALERRORDETECTED])
-
-struct unf_global_lport global_lport_mgr;
-
-static int unf_port_switch(struct unf_lport *lport, bool switch_flag);
-static u32 unf_build_lport_wwn(struct unf_lport *lport);
-static int unf_lport_destroy(void *lport, void *arg_out);
-static u32 unf_port_linkup(struct unf_lport *lport, void *input);
-static u32 unf_port_linkdown(struct unf_lport *lport, void *input);
-static u32 unf_port_abnormal_reset(struct unf_lport *lport, void *input);
-static u32 unf_port_reset_start(struct unf_lport *lport, void *input);
-static u32 unf_port_reset_end(struct unf_lport *lport, void *input);
-static u32 unf_port_nop(struct unf_lport *lport, void *input);
-static void unf_destroy_card_thread(struct unf_lport *lport);
-static u32 unf_creat_card_thread(struct unf_lport *lport);
-static u32 unf_find_card_thread(struct unf_lport *lport);
-static u32 unf_port_begin_remove(struct unf_lport *lport, void *input);
-
-static struct unf_port_action g_lport_action[] = {
- {UNF_PORT_LINK_UP, unf_port_linkup},
- {UNF_PORT_LINK_DOWN, unf_port_linkdown},
- {UNF_PORT_RESET_START, unf_port_reset_start},
- {UNF_PORT_RESET_END, unf_port_reset_end},
- {UNF_PORT_NOP, unf_port_nop},
- {UNF_PORT_BEGIN_REMOVE, unf_port_begin_remove},
- {UNF_PORT_RELEASE_RPORT_INDEX, unf_port_release_rport_index},
- {UNF_PORT_ABNORMAL_RESET, unf_port_abnormal_reset},
-};
-
-static void unf_destroy_dirty_rport(struct unf_lport *lport, bool show_only)
-{
- u32 dirty_rport = 0;
-
- /* for whole L_Port */
- if (lport->dirty_flag & UNF_LPORT_DIRTY_FLAG_RPORT_POOL_DIRTY) {
- dirty_rport = lport->rport_pool.rport_pool_count;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) has %d dirty RPort(s)",
- lport->port_id, dirty_rport);
-
- /* Show L_Port's R_Port(s) from busy_list & destroy_list */
- unf_show_all_rport(lport);
-
- /* free R_Port pool memory & bitmap */
- if (!show_only) {
- vfree(lport->rport_pool.rport_pool_add);
- lport->rport_pool.rport_pool_add = NULL;
- vfree(lport->rport_pool.rpi_bitmap);
- lport->rport_pool.rpi_bitmap = NULL;
- }
- }
-}
-
-void unf_show_dirty_port(bool show_only, u32 *dirty_port_num)
-{
- struct list_head *node = NULL;
- struct list_head *node_next = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong flags = 0;
- u32 port_num = 0;
-
- FC_CHECK_RETURN_VOID(dirty_port_num);
-
- /* for each dirty L_Port from global L_Port list */
- spin_lock_irqsave(&global_lport_mgr.global_lport_list_lock, flags);
- list_for_each_safe(node, node_next, &global_lport_mgr.dirty_list_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) has dirty data(0x%x)",
- unf_lport->port_id, unf_lport->dirty_flag);
-
- /* Destroy dirty L_Port's exchange(s) & R_Port(s) */
- unf_destroy_dirty_xchg(unf_lport, show_only);
- unf_destroy_dirty_rport(unf_lport, show_only);
-
- /* Delete (dirty L_Port) list entry if necessary */
- if (!show_only) {
- list_del_init(node);
- vfree(unf_lport);
- }
-
- port_num++;
- }
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
-
- *dirty_port_num = port_num;
-}
-
-void unf_show_all_rport(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_disc *disc = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- u32 rport_cnt = 0;
- u32 target_cnt = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- unf_lport = lport;
- disc = &unf_lport->disc;
-
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info]Port(0x%x) disc state(0x%x)", unf_lport->port_id, disc->states);
-
- /* for each R_Port from busy_list */
- list_for_each_safe(node, next_node, &disc->list_busy_rports) {
- unf_rport = list_entry(node, struct unf_rport, entry_rport);
- rport_cnt++;
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info]Port(0x%x) busy RPorts(%u_%p) WWPN(0x%016llx) scsi_id(0x%x) local N_Port_ID(0x%x) N_Port_ID(0x%06x). State(0x%04x) options(0x%04x) index(0x%04x) ref(%d) pend:%d",
- unf_lport->port_id, rport_cnt, unf_rport,
- unf_rport->port_name, unf_rport->scsi_id,
- unf_rport->local_nport_id, unf_rport->nport_id,
- unf_rport->rp_state, unf_rport->options,
- unf_rport->rport_index,
- atomic_read(&unf_rport->rport_ref_cnt),
- atomic_read(&unf_rport->pending_io_cnt));
-
- if (unf_rport->nport_id < UNF_FC_FID_DOM_MGR)
- target_cnt++;
- }
-
- unf_lport->target_cnt = target_cnt;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) targetnum=(%u)", unf_lport->port_id,
- unf_lport->target_cnt);
-
- /* for each R_Port from destroy_list */
- list_for_each_safe(node, next_node, &disc->list_destroy_rports) {
- unf_rport = list_entry(node, struct unf_rport, entry_rport);
- rport_cnt++;
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info]Port(0x%x) destroy RPorts(%u) WWPN(0x%016llx) N_Port_ID(0x%06x) State(0x%04x) options(0x%04x) index(0x%04x) ref(%d)",
- unf_lport->port_id, rport_cnt, unf_rport->port_name,
- unf_rport->nport_id, unf_rport->rp_state,
- unf_rport->options, unf_rport->rport_index,
- atomic_read(&unf_rport->rport_ref_cnt));
- }
-
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-}
-
-u32 unf_lport_ref_inc(struct unf_lport *lport)
-{
- ulong lport_flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&lport->lport_state_lock, lport_flags);
- if (atomic_read(&lport->port_ref_cnt) <= 0) {
- spin_unlock_irqrestore(&lport->lport_state_lock, lport_flags);
-
- return UNF_RETURN_ERROR;
- }
-
- atomic_inc(&lport->port_ref_cnt);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%p) port_id(0x%x) reference count is %d",
- lport, lport->port_id, atomic_read(&lport->port_ref_cnt));
-
- spin_unlock_irqrestore(&lport->lport_state_lock, lport_flags);
-
- return RETURN_OK;
-}
-
-void unf_lport_ref_dec(struct unf_lport *lport)
-{
- ulong flags = 0;
- ulong lport_flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "LPort(0x%p), port ID(0x%x), reference count is %d.",
- lport, lport->port_id, atomic_read(&lport->port_ref_cnt));
-
- spin_lock_irqsave(&global_lport_mgr.global_lport_list_lock, flags);
- spin_lock_irqsave(&lport->lport_state_lock, lport_flags);
- if (atomic_dec_and_test(&lport->port_ref_cnt)) {
- spin_unlock_irqrestore(&lport->lport_state_lock, lport_flags);
- list_del(&lport->entry_lport);
- global_lport_mgr.lport_sum--;
-
- /* attaches the lport to the destroy linked list for dfx */
- list_add_tail(&lport->entry_lport, &global_lport_mgr.destroy_list_head);
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
-
- (void)unf_lport_destroy(lport, NULL);
- } else {
- spin_unlock_irqrestore(&lport->lport_state_lock, lport_flags);
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
- }
-}
-
-void unf_lport_update_topo(struct unf_lport *lport,
- enum unf_act_topo active_topo)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- if (active_topo > UNF_ACT_TOP_UNKNOWN || active_topo < UNF_ACT_TOP_PUBLIC_LOOP) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) set invalid topology(0x%x) with current value(0x%x)",
- lport->nport_id, active_topo, lport->act_topo);
-
- return;
- }
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- lport->act_topo = active_topo;
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-}
-
-void unf_set_lport_removing(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- lport->fc_port = NULL;
- lport->port_removing = true;
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_0_SET_REMOVING;
-}
-
-u32 unf_release_local_port(void *lport)
-{
- struct unf_lport *unf_lport = lport;
- struct completion lport_free_completion;
-
- init_completion(&lport_free_completion);
- FC_CHECK_RETURN_VALUE(unf_lport, UNF_RETURN_ERROR);
-
- unf_lport->lport_free_completion = &lport_free_completion;
- unf_set_lport_removing(unf_lport);
- unf_lport_ref_dec(unf_lport);
- wait_for_completion(unf_lport->lport_free_completion);
- /* for dirty case */
- if (unf_lport->dirty_flag == 0)
- vfree(unf_lport);
-
- return RETURN_OK;
-}
-
-static void unf_free_all_esgl_pages(struct unf_lport *lport)
-{
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- u32 i;
-
- FC_CHECK_RETURN_VOID(lport);
- spin_lock_irqsave(&lport->esgl_pool.esgl_pool_lock, flag);
- list_for_each_safe(node, next_node, &lport->esgl_pool.list_esgl_pool) {
- list_del(node);
- }
-
- spin_unlock_irqrestore(&lport->esgl_pool.esgl_pool_lock, flag);
- if (lport->esgl_pool.esgl_buff_list.buflist) {
- for (i = 0; i < lport->esgl_pool.esgl_buff_list.buf_num; i++) {
- if (lport->esgl_pool.esgl_buff_list.buflist[i].vaddr) {
- dma_free_coherent(&lport->low_level_func.dev->dev,
- lport->esgl_pool.esgl_buff_list.buf_size,
- lport->esgl_pool.esgl_buff_list.buflist[i].vaddr,
- lport->esgl_pool.esgl_buff_list.buflist[i].paddr);
- lport->esgl_pool.esgl_buff_list.buflist[i].vaddr = NULL;
- }
- }
- kfree(lport->esgl_pool.esgl_buff_list.buflist);
- lport->esgl_pool.esgl_buff_list.buflist = NULL;
- }
-}
-
-static u32 unf_init_esgl_pool(struct unf_lport *lport)
-{
- struct unf_esgl *esgl = NULL;
- u32 ret = RETURN_OK;
- u32 index = 0;
- u32 buf_total_size;
- u32 buf_num;
- u32 alloc_idx;
- u32 curbuf_idx = 0;
- u32 curbuf_offset = 0;
- u32 buf_cnt_perhugebuf;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- lport->esgl_pool.esgl_pool_count = lport->low_level_func.lport_cfg_items.max_io;
- spin_lock_init(&lport->esgl_pool.esgl_pool_lock);
- INIT_LIST_HEAD(&lport->esgl_pool.list_esgl_pool);
-
- lport->esgl_pool.esgl_pool_addr =
- vmalloc((size_t)((lport->esgl_pool.esgl_pool_count) * sizeof(struct unf_esgl)));
- if (!lport->esgl_pool.esgl_pool_addr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "LPort(0x%x) cannot allocate ESGL Pool.", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- esgl = (struct unf_esgl *)lport->esgl_pool.esgl_pool_addr;
- memset(esgl, 0, ((lport->esgl_pool.esgl_pool_count) * sizeof(struct unf_esgl)));
-
- buf_total_size = (u32)(PAGE_SIZE * lport->esgl_pool.esgl_pool_count);
-
- lport->esgl_pool.esgl_buff_list.buf_size =
- buf_total_size > BUF_LIST_PAGE_SIZE ? BUF_LIST_PAGE_SIZE : buf_total_size;
- buf_cnt_perhugebuf = lport->esgl_pool.esgl_buff_list.buf_size / PAGE_SIZE;
- buf_num = lport->esgl_pool.esgl_pool_count % buf_cnt_perhugebuf
- ? lport->esgl_pool.esgl_pool_count / buf_cnt_perhugebuf + 1
- : lport->esgl_pool.esgl_pool_count / buf_cnt_perhugebuf;
- lport->esgl_pool.esgl_buff_list.buflist =
- (struct buff_list *)kmalloc(buf_num * sizeof(struct buff_list), GFP_KERNEL);
- lport->esgl_pool.esgl_buff_list.buf_num = buf_num;
-
- if (!lport->esgl_pool.esgl_buff_list.buflist) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate Esgl pool buf list failed out of memory");
- goto free_buff;
- }
- memset(lport->esgl_pool.esgl_buff_list.buflist, 0, buf_num * sizeof(struct buff_list));
-
- for (alloc_idx = 0; alloc_idx < buf_num; alloc_idx++) {
- lport->esgl_pool.esgl_buff_list.buflist[alloc_idx]
- .vaddr = dma_alloc_coherent(&lport->low_level_func.dev->dev,
- lport->esgl_pool.esgl_buff_list.buf_size,
- &lport->esgl_pool.esgl_buff_list.buflist[alloc_idx].paddr, GFP_KERNEL);
- if (!lport->esgl_pool.esgl_buff_list.buflist[alloc_idx].vaddr)
- goto free_buff;
- memset(lport->esgl_pool.esgl_buff_list.buflist[alloc_idx].vaddr, 0,
- lport->esgl_pool.esgl_buff_list.buf_size);
- }
-
- /* allocates the Esgl page, and the DMA uses the */
- for (index = 0; index < lport->esgl_pool.esgl_pool_count; index++) {
- if (index != 0 && !(index % buf_cnt_perhugebuf))
- curbuf_idx++;
- curbuf_offset = (u32)(PAGE_SIZE * (index % buf_cnt_perhugebuf));
- esgl->page.page_address =
- (u64)lport->esgl_pool.esgl_buff_list.buflist[curbuf_idx].vaddr + curbuf_offset;
- esgl->page.page_size = PAGE_SIZE;
- esgl->page.esgl_phy_addr =
- lport->esgl_pool.esgl_buff_list.buflist[curbuf_idx].paddr + curbuf_offset;
- list_add_tail(&esgl->entry_esgl, &lport->esgl_pool.list_esgl_pool);
- esgl++;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[EVENT]Allocate bufnum:%u,buf_total_size:%u", buf_num, buf_total_size);
-
- return ret;
-free_buff:
- unf_free_all_esgl_pages(lport);
- vfree(lport->esgl_pool.esgl_pool_addr);
-
- return UNF_RETURN_ERROR;
-}
-
-static void unf_free_esgl_pool(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- unf_free_all_esgl_pages(lport);
- lport->esgl_pool.esgl_pool_count = 0;
-
- if (lport->esgl_pool.esgl_pool_addr) {
- vfree(lport->esgl_pool.esgl_pool_addr);
- lport->esgl_pool.esgl_pool_addr = NULL;
- }
-
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_5_DESTROY_ESGL_POOL;
-}
-
-struct unf_lport *unf_find_lport_by_port_id(u32 port_id)
-{
- struct unf_lport *unf_lport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flags = 0;
- u32 portid = port_id & (~PORTID_VPINDEX_MASK);
- u16 vport_index;
- spinlock_t *lport_list_lock = NULL;
-
- lport_list_lock = &global_lport_mgr.global_lport_list_lock;
- vport_index = (port_id & PORTID_VPINDEX_MASK) >> PORTID_VPINDEX_SHIT;
- spin_lock_irqsave(lport_list_lock, flags);
-
- list_for_each_safe(node, next_node, &global_lport_mgr.lport_list_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
- if (unf_lport->port_id == portid && !unf_lport->port_removing) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return unf_cm_lookup_vport_by_vp_index(unf_lport, vport_index);
- }
- }
-
- list_for_each_safe(node, next_node, &global_lport_mgr.intergrad_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
- if (unf_lport->port_id == portid && !unf_lport->port_removing) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return unf_cm_lookup_vport_by_vp_index(unf_lport, vport_index);
- }
- }
-
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return NULL;
-}
-
-u32 unf_is_vport_valid(struct unf_lport *lport, struct unf_lport *vport)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- spinlock_t *vport_pool_lock = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(vport, UNF_RETURN_ERROR);
-
- unf_lport = lport;
- vport_pool = unf_lport->vport_pool;
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) vport pool is NULL", unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- vport_pool_lock = &vport_pool->vport_pool_lock;
- spin_lock_irqsave(vport_pool_lock, flag);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
-
- if (unf_vport == vport && !unf_vport->port_removing) {
- spin_unlock_irqrestore(vport_pool_lock, flag);
-
- return RETURN_OK;
- }
- }
-
- list_for_each_safe(node, next_node, &unf_lport->list_intergrad_vports) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
-
- if (unf_vport == vport && !unf_vport->port_removing) {
- spin_unlock_irqrestore(vport_pool_lock, flag);
-
- return RETURN_OK;
- }
- }
- spin_unlock_irqrestore(vport_pool_lock, flag);
-
- return UNF_RETURN_ERROR;
-}
-
-u32 unf_is_lport_valid(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flags = 0;
- spinlock_t *lport_list_lock = NULL;
-
- lport_list_lock = &global_lport_mgr.global_lport_list_lock;
- spin_lock_irqsave(lport_list_lock, flags);
-
- list_for_each_safe(node, next_node, &global_lport_mgr.lport_list_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
-
- if (unf_lport == lport && !unf_lport->port_removing) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return RETURN_OK;
- }
-
- if (unf_is_vport_valid(unf_lport, lport) == RETURN_OK) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return RETURN_OK;
- }
- }
-
- list_for_each_safe(node, next_node, &global_lport_mgr.intergrad_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
-
- if (unf_lport == lport && !unf_lport->port_removing) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return RETURN_OK;
- }
-
- if (unf_is_vport_valid(unf_lport, lport) == RETURN_OK) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return RETURN_OK;
- }
- }
-
- list_for_each_safe(node, next_node, &global_lport_mgr.destroy_list_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
-
- if (unf_lport == lport && !unf_lport->port_removing) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return RETURN_OK;
- }
-
- if (unf_is_vport_valid(unf_lport, lport) == RETURN_OK) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return RETURN_OK;
- }
- }
-
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return UNF_RETURN_ERROR;
-}
-
-static void unf_clean_linkdown_io(struct unf_lport *lport, bool clean_flag)
-{
- /* Clean L_Port/V_Port Link Down I/O: Set Abort Tag */
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(lport->xchg_mgr_temp.unf_xchg_abort_all_io);
-
- lport->xchg_mgr_temp.unf_xchg_abort_all_io(lport, UNF_XCHG_TYPE_INI, clean_flag);
- lport->xchg_mgr_temp.unf_xchg_abort_all_io(lport, UNF_XCHG_TYPE_SFS, clean_flag);
-}
-
-u32 unf_fc_port_link_event(void *lport, u32 events, void *input)
-{
- struct unf_lport *unf_lport = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 index = 0;
-
- if (unlikely(!lport))
- return UNF_RETURN_ERROR;
- unf_lport = (struct unf_lport *)lport;
-
- ret = unf_lport_ref_inc(unf_lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) is removing and do nothing",
- unf_lport->port_id);
-
- return RETURN_OK;
- }
-
- /* process port event */
- while (index < (sizeof(g_lport_action) / sizeof(struct unf_port_action))) {
- if (g_lport_action[index].action == events) {
- ret = g_lport_action[index].unf_action(unf_lport, input);
-
- unf_lport_ref_dec_to_destroy(unf_lport);
-
- return ret;
- }
- index++;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive unknown event(0x%x)",
- unf_lport->port_id, events);
-
- unf_lport_ref_dec_to_destroy(unf_lport);
-
- return ret;
-}
-
-void unf_port_mgmt_init(void)
-{
- memset(&global_lport_mgr, 0, sizeof(struct unf_global_lport));
-
- INIT_LIST_HEAD(&global_lport_mgr.lport_list_head);
-
- INIT_LIST_HEAD(&global_lport_mgr.intergrad_head);
-
- INIT_LIST_HEAD(&global_lport_mgr.destroy_list_head);
-
- INIT_LIST_HEAD(&global_lport_mgr.dirty_list_head);
-
- spin_lock_init(&global_lport_mgr.global_lport_list_lock);
-
- UNF_SET_NOMAL_MODE(global_lport_mgr.dft_mode);
-
- global_lport_mgr.start_work = true;
-}
-
-void unf_port_mgmt_deinit(void)
-{
- if (global_lport_mgr.lport_sum != 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]There are %u port pool memory giveaway",
- global_lport_mgr.lport_sum);
- }
-
- memset(&global_lport_mgr, 0, sizeof(struct unf_global_lport));
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Common port manager exit succeed");
-}
-
-static void unf_port_register(struct unf_lport *lport)
-{
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Register LPort(0x%p), port ID(0x%x).", lport, lport->port_id);
-
- /* Add to the global management linked list header */
- spin_lock_irqsave(&global_lport_mgr.global_lport_list_lock, flags);
- list_add_tail(&lport->entry_lport, &global_lport_mgr.lport_list_head);
- global_lport_mgr.lport_sum++;
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
-}
-
-static void unf_port_unregister(struct unf_lport *lport)
-{
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Unregister LPort(0x%p), port ID(0x%x).", lport, lport->port_id);
-
- /* Remove from the global management linked list header */
- spin_lock_irqsave(&global_lport_mgr.global_lport_list_lock, flags);
- list_del(&lport->entry_lport);
- global_lport_mgr.lport_sum--;
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
-}
-
-int unf_port_start_work(struct unf_lport *lport)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- if (lport->start_work_state != UNF_START_WORK_STOP) {
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- return RETURN_OK;
- }
- lport->start_work_state = UNF_START_WORK_COMPLETE;
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- /* switch sfp to start work */
- (void)unf_port_switch(lport, true);
-
- return RETURN_OK;
-}
-
-static u32
-unf_lport_init_lw_funop(struct unf_lport *lport,
- struct unf_low_level_functioon_op *low_level_op)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(low_level_op, UNF_RETURN_ERROR);
-
- lport->port_id = low_level_op->lport_cfg_items.port_id;
- lport->port_name = low_level_op->sys_port_name;
- lport->node_name = low_level_op->sys_node_name;
- lport->options = low_level_op->lport_cfg_items.port_mode;
- lport->act_topo = UNF_ACT_TOP_UNKNOWN;
- lport->max_ssq_num = low_level_op->support_max_ssq_num;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) .", lport->port_id);
-
- memcpy(&lport->low_level_func, low_level_op, sizeof(struct unf_low_level_functioon_op));
-
- return RETURN_OK;
-}
-
-void unf_lport_release_lw_funop(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VOID(lport);
-
- memset(&lport->low_level_func, 0, sizeof(struct unf_low_level_functioon_op));
-
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_13_DESTROY_LW_INTERFACE;
-}
-
-struct unf_lport *unf_find_lport_by_scsi_hostid(u32 scsi_host_id)
-{
- struct list_head *node = NULL, *next_node = NULL;
- struct list_head *vp_node = NULL, *next_vp_node = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_lport *unf_vport = NULL;
- ulong flags = 0;
- ulong pool_flags = 0;
- spinlock_t *vp_pool_lock = NULL;
- spinlock_t *lport_list_lock = &global_lport_mgr.global_lport_list_lock;
-
- spin_lock_irqsave(lport_list_lock, flags);
- list_for_each_safe(node, next_node, &global_lport_mgr.lport_list_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
- vp_pool_lock = &unf_lport->vport_pool->vport_pool_lock;
- if (scsi_host_id == UNF_GET_SCSI_HOST_ID(unf_lport->host_info.host)) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return unf_lport;
- }
-
- /* support NPIV */
- if (unf_lport->vport_pool) {
- spin_lock_irqsave(vp_pool_lock, pool_flags);
- list_for_each_safe(vp_node, next_vp_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(vp_node, struct unf_lport, entry_vport);
-
- if (scsi_host_id ==
- UNF_GET_SCSI_HOST_ID(unf_vport->host_info.host)) {
- spin_unlock_irqrestore(vp_pool_lock, pool_flags);
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return unf_vport;
- }
- }
- spin_unlock_irqrestore(vp_pool_lock, pool_flags);
- }
- }
-
- list_for_each_safe(node, next_node, &global_lport_mgr.intergrad_head) {
- unf_lport = list_entry(node, struct unf_lport, entry_lport);
- vp_pool_lock = &unf_lport->vport_pool->vport_pool_lock;
- if (scsi_host_id ==
- UNF_GET_SCSI_HOST_ID(unf_lport->host_info.host)) {
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return unf_lport;
- }
-
- /* support NPIV */
- if (unf_lport->vport_pool) {
- spin_lock_irqsave(vp_pool_lock, pool_flags);
- list_for_each_safe(vp_node, next_vp_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(vp_node, struct unf_lport, entry_vport);
-
- if (scsi_host_id ==
- UNF_GET_SCSI_HOST_ID(unf_vport->host_info.host)) {
- spin_unlock_irqrestore(vp_pool_lock, pool_flags);
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- return unf_vport;
- }
- }
- spin_unlock_irqrestore(vp_pool_lock, pool_flags);
- }
- }
- spin_unlock_irqrestore(lport_list_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Can not find port by scsi_host_id(0x%x), may be removing",
- scsi_host_id);
-
- return NULL;
-}
-
-u32 unf_init_scsi_id_table(struct unf_lport *lport)
-{
- struct unf_rport_scsi_id_image *rport_scsi_id_image = NULL;
- struct unf_wwpn_rport_info *wwpn_port_info = NULL;
- u32 idx;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- rport_scsi_id_image = &lport->rport_scsi_table;
- rport_scsi_id_image->max_scsi_id = UNF_MAX_SCSI_ID;
-
- /* If the number of remote connections supported by the L_Port is 0, an
- * exception occurs
- */
- if (rport_scsi_id_image->max_scsi_id == 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x), supported maximum login is zero.", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- rport_scsi_id_image->wwn_rport_info_table =
- vmalloc(rport_scsi_id_image->max_scsi_id * sizeof(struct unf_wwpn_rport_info));
- if (!rport_scsi_id_image->wwn_rport_info_table) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) can't allocate SCSI ID Table(0x%x).",
- lport->port_id, rport_scsi_id_image->max_scsi_id);
-
- return UNF_RETURN_ERROR;
- }
- memset(rport_scsi_id_image->wwn_rport_info_table, 0,
- rport_scsi_id_image->max_scsi_id * sizeof(struct unf_wwpn_rport_info));
-
- wwpn_port_info = rport_scsi_id_image->wwn_rport_info_table;
-
- for (idx = 0; idx < rport_scsi_id_image->max_scsi_id; idx++) {
- INIT_DELAYED_WORK(&wwpn_port_info->loss_tmo_work, unf_sesion_loss_timeout);
- INIT_LIST_HEAD(&wwpn_port_info->fc_lun_list);
- wwpn_port_info->lport = lport;
- wwpn_port_info->target_id = INVALID_VALUE32;
- wwpn_port_info++;
- }
-
- spin_lock_init(&rport_scsi_id_image->scsi_image_table_lock);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Port(0x%x) supported maximum login is %u.",
- lport->port_id, rport_scsi_id_image->max_scsi_id);
-
- return RETURN_OK;
-}
-
-void unf_destroy_scsi_id_table(struct unf_lport *lport)
-{
- struct unf_rport_scsi_id_image *rport_scsi_id_image = NULL;
- struct unf_wwpn_rport_info *wwn_rport_info = NULL;
- u32 i = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
-
- rport_scsi_id_image = &lport->rport_scsi_table;
- if (rport_scsi_id_image->wwn_rport_info_table) {
- for (i = 0; i < UNF_MAX_SCSI_ID; i++) {
- wwn_rport_info = &rport_scsi_id_image->wwn_rport_info_table[i];
- UNF_DELAYED_WORK_SYNC(ret, (lport->port_id),
- (&wwn_rport_info->loss_tmo_work),
- "loss tmo Timer work");
- if (wwn_rport_info->lun_qos_level) {
- vfree(wwn_rport_info->lun_qos_level);
- wwn_rport_info->lun_qos_level = NULL;
- }
- }
-
- if (ret) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Port(0x%x) cancel loss tmo work success", lport->port_id);
- }
- vfree(rport_scsi_id_image->wwn_rport_info_table);
- rport_scsi_id_image->wwn_rport_info_table = NULL;
- }
-
- rport_scsi_id_image->max_scsi_id = 0;
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_10_DESTROY_SCSI_TABLE;
-}
-
-static u32 unf_lport_init(struct unf_lport *lport, void *private_data,
- struct unf_low_level_functioon_op *low_level_op)
-{
- u32 ret = RETURN_OK;
- char work_queue_name[13];
-
- unf_init_port_parms(lport);
-
- /* Associating LPort with FCPort */
- lport->fc_port = private_data;
-
- /* VpIndx=0 is reserved for Lport, and rootLport points to its own */
- lport->vp_index = 0;
- lport->root_lport = lport;
- lport->chip_info = NULL;
-
- /* Initialize the units related to L_Port and lw func */
- ret = unf_lport_init_lw_funop(lport, low_level_op);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) initialize lowlevel function unsuccessful.",
- lport->port_id);
-
- return ret;
- }
-
- /* Init Linkevent workqueue */
- snprintf(work_queue_name, sizeof(work_queue_name), "%x_lkq", lport->port_id);
-
- lport->link_event_wq = create_singlethread_workqueue(work_queue_name);
- if (!lport->link_event_wq) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]Port(0x%x) creat link event work queue failed", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- snprintf(work_queue_name, sizeof(work_queue_name), "%x_xchgwq", lport->port_id);
- lport->xchg_wq = create_workqueue(work_queue_name);
- if (!lport->xchg_wq) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]Port(0x%x) creat Exchg work queue failed",
- lport->port_id);
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
- return UNF_RETURN_ERROR;
- }
- /* scsi table (R_Port) required for initializing INI
- * Initialize the scsi id Table table to manage the mapping between SCSI
- * ID, WWN, and Rport.
- */
-
- ret = unf_init_scsi_id_table(lport);
- if (ret != RETURN_OK) {
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
- return ret;
- }
-
- /* Initialize the EXCH resource */
- ret = unf_alloc_xchg_resource(lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) can't allocate exchange resource.", lport->port_id);
-
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
- unf_destroy_scsi_id_table(lport);
-
- return ret;
- }
-
- /* Initialize the ESGL resource pool used by Lport */
- ret = unf_init_esgl_pool(lport);
- if (ret != RETURN_OK) {
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
- unf_free_all_xchg_mgr(lport);
- unf_destroy_scsi_id_table(lport);
-
- return ret;
- }
- /* Initialize the disc manager under Lport */
- ret = unf_init_disc_mgr(lport);
- if (ret != RETURN_OK) {
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
- unf_free_esgl_pool(lport);
- unf_free_all_xchg_mgr(lport);
- unf_destroy_scsi_id_table(lport);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) initialize discover manager unsuccessful.",
- lport->port_id);
-
- return ret;
- }
-
- /* Initialize the LPort manager */
- ret = unf_init_vport_mgr_temp(lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) initialize RPort manager unsuccessful.", lport->port_id);
-
- goto RELEASE_LPORT;
- }
-
- /* Initialize the EXCH manager */
- ret = unf_init_xchg_mgr_temp(lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) initialize exchange manager unsuccessful.",
- lport->port_id);
- goto RELEASE_LPORT;
- }
- /* Initialize the resources required by the event processing center */
- ret = unf_init_event_center(lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) initialize event center unsuccessful.", lport->port_id);
- goto RELEASE_LPORT;
- }
- /* Initialize the initialization status of Lport */
- unf_set_lport_state(lport, UNF_LPORT_ST_INITIAL);
-
- /* Initialize the Lport route test case */
- ret = unf_init_lport_route(lport);
- if (ret != RETURN_OK) {
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
- (void)unf_event_center_destroy(lport);
- unf_disc_mgr_destroy(lport);
- unf_free_esgl_pool(lport);
- unf_free_all_xchg_mgr(lport);
- unf_destroy_scsi_id_table(lport);
-
- return ret;
- }
- /* Thesupports the initialization stepof the NPIV */
- ret = unf_init_vport_pool(lport);
- if (ret != RETURN_OK) {
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
-
- unf_destroy_lport_route(lport);
- (void)unf_event_center_destroy(lport);
- unf_disc_mgr_destroy(lport);
- unf_free_esgl_pool(lport);
- unf_free_all_xchg_mgr(lport);
- unf_destroy_scsi_id_table(lport);
-
- return ret;
- }
-
- /* qualifier rport callback */
- lport->unf_qualify_rport = unf_rport_set_qualifier_key_reuse;
- lport->unf_tmf_abnormal_recovery = unf_tmf_timeout_recovery_special;
- return RETURN_OK;
-RELEASE_LPORT:
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
-
- unf_disc_mgr_destroy(lport);
- unf_free_esgl_pool(lport);
- unf_free_all_xchg_mgr(lport);
- unf_destroy_scsi_id_table(lport);
-
- return ret;
-}
-
-void unf_free_qos_info(struct unf_lport *lport)
-{
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_qos_info *qos_info = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- spin_lock_irqsave(&lport->qos_mgr_lock, flag);
- list_for_each_safe(node, next_node, &lport->list_qos_head) {
- qos_info = (struct unf_qos_info *)list_entry(node,
- struct unf_qos_info, entry_qos_info);
- list_del_init(&qos_info->entry_qos_info);
- kfree(qos_info);
- }
-
- spin_unlock_irqrestore(&lport->qos_mgr_lock, flag);
-}
-
-u32 unf_lport_deinit(struct unf_lport *lport)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- unf_free_qos_info(lport);
-
- unf_unregister_scsi_host(lport);
-
- /* If the card is unloaded normally, the thread is stopped once. The
- * problem does not occur if you stop the thread again.
- */
- unf_destroy_lport_route(lport);
-
- /* minus the reference count of the card event; the last port deletes
- * the card thread
- */
- unf_destroy_card_thread(lport);
- flush_workqueue(lport->link_event_wq);
- destroy_workqueue(lport->link_event_wq);
- lport->link_event_wq = NULL;
-
- (void)unf_event_center_destroy(lport);
- unf_free_vport_pool(lport);
- unf_xchg_mgr_destroy(lport);
-
- unf_free_esgl_pool(lport);
-
- /* reliability review :Disc should release after Xchg. Destroy the disc
- * manager
- */
- unf_disc_mgr_destroy(lport);
-
- unf_release_xchg_mgr_temp(lport);
-
- unf_release_vport_mgr_temp(lport);
-
- unf_destroy_scsi_id_table(lport);
-
- flush_workqueue(lport->xchg_wq);
- destroy_workqueue(lport->xchg_wq);
- lport->xchg_wq = NULL;
-
- /* Releasing the lw Interface Template */
- unf_lport_release_lw_funop(lport);
- lport->fc_port = NULL;
-
- return RETURN_OK;
-}
-
-static int unf_card_event_process(void *arg)
-{
- struct list_head *node = NULL;
- struct unf_cm_event_report *event_node = NULL;
- ulong flags = 0;
- struct unf_chip_manage_info *chip_info = (struct unf_chip_manage_info *)arg;
-
- set_user_nice(current, UNF_OS_THRD_PRI_LOW);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Slot(%u) chip(0x%x) enter event thread.",
- chip_info->slot_id, chip_info->chip_id);
-
- while (!kthread_should_stop()) {
- if (chip_info->thread_exit)
- break;
-
- spin_lock_irqsave(&chip_info->chip_event_list_lock, flags);
- if (list_empty(&chip_info->list_head)) {
- spin_unlock_irqrestore(&chip_info->chip_event_list_lock, flags);
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout((long)msecs_to_jiffies(UNF_S_TO_MS));
- } else {
- node = UNF_OS_LIST_NEXT(&chip_info->list_head);
- list_del_init(node);
- chip_info->list_num--;
- event_node = list_entry(node, struct unf_cm_event_report, list_entry);
- spin_unlock_irqrestore(&chip_info->chip_event_list_lock, flags);
- unf_handle_event(event_node);
- }
- }
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MAJOR,
- "Slot(%u) chip(0x%x) exit event thread.",
- chip_info->slot_id, chip_info->chip_id);
-
- return RETURN_OK;
-}
-
-static void unf_destroy_card_thread(struct unf_lport *lport)
-{
- struct unf_event_mgr *event_mgr = NULL;
- struct unf_chip_manage_info *chip_info = NULL;
- struct list_head *list = NULL;
- struct list_head *list_tmp = NULL;
- struct unf_cm_event_report *event_node = NULL;
- ulong event_lock_flag = 0;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- /* If the thread cannot be found, apply for a new thread. */
- chip_info = lport->chip_info;
- if (!chip_info) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) has no event thread.", lport->port_id);
- return;
- }
- event_mgr = &lport->event_mgr;
-
- spin_lock_irqsave(&chip_info->chip_event_list_lock, flag);
- if (!list_empty(&chip_info->list_head)) {
- list_for_each_safe(list, list_tmp, &chip_info->list_head) {
- event_node = list_entry(list, struct unf_cm_event_report, list_entry);
-
- /* The LPort under the global event node is null. */
- if (event_node->lport == lport) {
- list_del_init(&event_node->list_entry);
- if (event_node->event_asy_flag == UNF_EVENT_SYN) {
- event_node->result = UNF_RETURN_ERROR;
- complete(&event_node->event_comp);
- }
-
- spin_lock_irqsave(&event_mgr->port_event_lock, event_lock_flag);
- event_mgr->free_event_count++;
- list_add_tail(&event_node->list_entry, &event_mgr->list_free_event);
- spin_unlock_irqrestore(&event_mgr->port_event_lock,
- event_lock_flag);
- }
- }
- }
- spin_unlock_irqrestore(&chip_info->chip_event_list_lock, flag);
-
- /* If the number of events introduced by the event thread is 0,
- * it indicates that no interface is used. In this case, thread
- * resources need to be consumed
- */
- if (atomic_dec_and_test(&chip_info->ref_cnt)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) destroy slot(%u) chip(0x%x) event thread succeed.",
- lport->port_id, chip_info->slot_id, chip_info->chip_id);
- chip_info->thread_exit = true;
- wake_up_process(chip_info->thread);
- kthread_stop(chip_info->thread);
- chip_info->thread = NULL;
-
- spin_lock_irqsave(&card_thread_mgr.global_card_list_lock, flag);
- list_del_init(&chip_info->list_chip_thread_entry);
- card_thread_mgr.card_num--;
- spin_unlock_irqrestore(&card_thread_mgr.global_card_list_lock, flag);
-
- vfree(chip_info);
- }
-
- lport->chip_info = NULL;
-}
-
-static u32 unf_creat_card_thread(struct unf_lport *lport)
-{
- ulong flag = 0;
- struct unf_chip_manage_info *chip_manage_info = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* If the thread cannot be found, apply for a new thread. */
- chip_manage_info = (struct unf_chip_manage_info *)
- vmalloc(sizeof(struct unf_chip_manage_info));
- if (!chip_manage_info) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) cannot allocate thread memory.", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- memset(chip_manage_info, 0, sizeof(struct unf_chip_manage_info));
-
- memcpy(&chip_manage_info->chip_info, &lport->low_level_func.chip_info,
- sizeof(struct unf_chip_info));
- chip_manage_info->slot_id = UNF_GET_BOARD_TYPE_AND_SLOT_ID_BY_PORTID(lport->port_id);
- chip_manage_info->chip_id = lport->low_level_func.chip_id;
- chip_manage_info->list_num = 0;
- chip_manage_info->sfp_9545_fault = false;
- chip_manage_info->sfp_power_fault = false;
- atomic_set(&chip_manage_info->ref_cnt, 1);
- atomic_set(&chip_manage_info->card_loop_test_flag, false);
- spin_lock_init(&chip_manage_info->card_loop_back_state_lock);
- INIT_LIST_HEAD(&chip_manage_info->list_head);
- spin_lock_init(&chip_manage_info->chip_event_list_lock);
-
- chip_manage_info->thread_exit = false;
- chip_manage_info->thread = kthread_create(unf_card_event_process,
- chip_manage_info, "%x_et", lport->port_id);
-
- if (IS_ERR(chip_manage_info->thread) || !chip_manage_info->thread) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) creat event thread(0x%p) unsuccessful.",
- lport->port_id, chip_manage_info->thread);
-
- vfree(chip_manage_info);
-
- return UNF_RETURN_ERROR;
- }
-
- lport->chip_info = chip_manage_info;
- wake_up_process(chip_manage_info->thread);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) creat slot(%u) chip(0x%x) event thread succeed.",
- lport->port_id, chip_manage_info->slot_id,
- chip_manage_info->chip_id);
-
- spin_lock_irqsave(&card_thread_mgr.global_card_list_lock, flag);
- list_add_tail(&chip_manage_info->list_chip_thread_entry, &card_thread_mgr.card_list_head);
- card_thread_mgr.card_num++;
- spin_unlock_irqrestore(&card_thread_mgr.global_card_list_lock, flag);
-
- return RETURN_OK;
-}
-
-static u32 unf_find_card_thread(struct unf_lport *lport)
-{
- ulong flag = 0;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_chip_manage_info *chip_info = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- spin_lock_irqsave(&card_thread_mgr.global_card_list_lock, flag);
- list_for_each_safe(node, next_node, &card_thread_mgr.card_list_head) {
- chip_info = list_entry(node, struct unf_chip_manage_info, list_chip_thread_entry);
-
- if (chip_info->chip_id == lport->low_level_func.chip_id &&
- chip_info->slot_id ==
- UNF_GET_BOARD_TYPE_AND_SLOT_ID_BY_PORTID(lport->port_id)) {
- atomic_inc(&chip_info->ref_cnt);
- lport->chip_info = chip_info;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) find card(%u) chip(0x%x) event thread succeed.",
- lport->port_id, chip_info->slot_id, chip_info->chip_id);
-
- spin_unlock_irqrestore(&card_thread_mgr.global_card_list_lock, flag);
-
- return RETURN_OK;
- }
- }
- spin_unlock_irqrestore(&card_thread_mgr.global_card_list_lock, flag);
-
- ret = unf_creat_card_thread(lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) creat event thread unsuccessful. Destroy LPort.",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- } else {
- return RETURN_OK;
- }
-}
-
-void *unf_lport_create_and_init(void *private_data, struct unf_low_level_functioon_op *low_level_op)
-{
- struct unf_lport *unf_lport = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- if (!private_data) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Private Data is NULL");
-
- return NULL;
- }
- if (!low_level_op) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LowLevel port(0x%p) function is NULL", private_data);
-
- return NULL;
- }
-
- /* 1. vmalloc & Memset L_Port */
- unf_lport = vmalloc(sizeof(struct unf_lport));
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Alloc LPort memory failed.");
-
- return NULL;
- }
- memset(unf_lport, 0, sizeof(struct unf_lport));
-
- /* 2. L_Port Init */
- if (unf_lport_init(unf_lport, private_data, low_level_op) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort initialize unsuccessful.");
-
- vfree(unf_lport);
-
- return NULL;
- }
-
- /* 4. Get or Create Chip Thread
- * Chip_ID & Slot_ID
- */
- ret = unf_find_card_thread(unf_lport);
- if (ret != RETURN_OK) {
- (void)unf_lport_deinit(unf_lport);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%x) Find Chip thread unsuccessful. Destroy LPort.",
- unf_lport->port_id);
-
- vfree(unf_lport);
- return NULL;
- }
-
- /* 5. Registers with in the port management global linked list */
- unf_port_register(unf_lport);
- /* update WWN */
- if (unf_build_lport_wwn(unf_lport) != RETURN_OK) {
- unf_port_unregister(unf_lport);
- (void)unf_lport_deinit(unf_lport);
- vfree(unf_lport);
- return NULL;
- }
-
- // unf_init_link_lose_tmo(unf_lport);//TO DO
-
- /* initialize Scsi Host */
- if (unf_register_scsi_host(unf_lport) != RETURN_OK) {
- unf_port_unregister(unf_lport);
- (void)unf_lport_deinit(unf_lport);
- vfree(unf_lport);
- return NULL;
- }
- /* 7. Here, start work now */
- if (global_lport_mgr.start_work) {
- if (unf_port_start_work(unf_lport) != RETURN_OK) {
- unf_port_unregister(unf_lport);
-
- (void)unf_lport_deinit(unf_lport);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) start work failed", unf_lport->port_id);
- vfree(unf_lport);
- return NULL;
- }
- }
-
- return unf_lport;
-}
-
-static int unf_lport_destroy(void *lport, void *arg_out)
-{
- struct unf_lport *unf_lport = NULL;
- ulong flags = 0;
-
- if (!lport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR, "LPort is NULL.");
-
- return UNF_RETURN_ERROR;
- }
-
- unf_lport = (struct unf_lport *)lport;
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "Destroy LPort(0x%p), ID(0x%x).", unf_lport, unf_lport->port_id);
- /* NPIV Ensure that all Vport are deleted */
- unf_destroy_all_vports(unf_lport);
- unf_lport->destroy_step = UNF_LPORT_DESTROY_STEP_1_REPORT_PORT_OUT;
-
- (void)unf_lport_deinit(lport);
-
- /* The port is removed from the destroy linked list. The next step is to
- * release the memory
- */
- spin_lock_irqsave(&global_lport_mgr.global_lport_list_lock, flags);
- list_del(&unf_lport->entry_lport);
-
- /* If the port has dirty memory, the port is mounted to the linked list
- * of dirty ports
- */
- if (unf_lport->dirty_flag)
- list_add_tail(&unf_lport->entry_lport, &global_lport_mgr.dirty_list_head);
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
-
- if (unf_lport->lport_free_completion) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Complete LPort(0x%p), port ID(0x%x)'s Free Completion.",
- unf_lport, unf_lport->port_id);
- complete(unf_lport->lport_free_completion);
- } else {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "LPort(0x%p), port ID(0x%x)'s Free Completion is NULL.",
- unf_lport, unf_lport->port_id);
- dump_stack();
- }
-
- return RETURN_OK;
-}
-
-static int unf_port_switch(struct unf_lport *lport, bool switch_flag)
-{
- struct unf_lport *unf_lport = lport;
- int ret = UNF_RETURN_ERROR;
- bool flag = false;
-
- FC_CHECK_RETURN_VALUE(unf_lport, UNF_RETURN_ERROR);
-
- if (!unf_lport->low_level_func.port_mgr_op.ll_port_config_set) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_WARN,
- "[warn]Port(0x%x)'s config(switch) function is NULL",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- flag = switch_flag ? true : false;
-
- ret = (int)unf_lport->low_level_func.port_mgr_op.ll_port_config_set(unf_lport->fc_port,
- UNF_PORT_CFG_SET_PORT_SWITCH, (void *)&flag);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_WARN, "[warn]Port(0x%x) switch %s failed",
- unf_lport->port_id, switch_flag ? "On" : "Off");
-
- return UNF_RETURN_ERROR;
- }
-
- unf_lport->switch_state = (bool)flag;
-
- return RETURN_OK;
-}
-
-static int unf_send_event(u32 port_id, u32 syn_flag, void *argc_in, void *argc_out,
- int (*func)(void *argc_in, void *argc_out))
-{
- struct unf_lport *lport = NULL;
- struct unf_cm_event_report *event = NULL;
- int ret = 0;
-
- lport = unf_find_lport_by_port_id(port_id);
- if (!lport) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_INFO, "Cannot find LPort(0x%x).", port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- if (unf_lport_ref_inc(lport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "LPort(0x%x) is removing, no need process.",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- if (unlikely(!lport->event_mgr.unf_get_free_event_func ||
- !lport->event_mgr.unf_post_event_func ||
- !lport->event_mgr.unf_release_event)) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_MAJOR, "Event function is NULL.");
-
- unf_lport_ref_dec_to_destroy(lport);
-
- return UNF_RETURN_ERROR;
- }
-
- if (lport->port_removing) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "LPort(0x%x) is removing, no need process.",
- lport->port_id);
-
- unf_lport_ref_dec_to_destroy(lport);
-
- return UNF_RETURN_ERROR;
- }
-
- event = lport->event_mgr.unf_get_free_event_func((void *)lport);
- if (!event) {
- unf_lport_ref_dec_to_destroy(lport);
-
- return UNF_RETURN_ERROR;
- }
-
- init_completion(&event->event_comp);
- event->lport = lport;
- event->event_asy_flag = syn_flag;
- event->unf_event_task = func;
- event->para_in = argc_in;
- event->para_out = argc_out;
- lport->event_mgr.unf_post_event_func(lport, event);
-
- if (event->event_asy_flag) {
- /* You must wait for the other party to return. Otherwise, the
- * linked list may be in disorder.
- */
- wait_for_completion(&event->event_comp);
- ret = (int)event->result;
- lport->event_mgr.unf_release_event(lport, event);
- } else {
- ret = RETURN_OK;
- }
-
- unf_lport_ref_dec_to_destroy(lport);
- return ret;
-}
-
-static int unf_reset_port(void *arg_in, void *arg_out)
-{
- struct unf_reset_port_argin *input = (struct unf_reset_port_argin *)arg_in;
- struct unf_lport *lport = NULL;
- u32 ret = UNF_RETURN_ERROR;
- enum unf_port_config_state port_state = UNF_PORT_CONFIG_STATE_RESET;
-
- FC_CHECK_RETURN_VALUE(input, UNF_RETURN_ERROR);
-
- lport = unf_find_lport_by_port_id(input->port_id);
- if (!lport) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_MAJOR, "Not find LPort(0x%x).",
- input->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* reset port */
- if (!lport->low_level_func.port_mgr_op.ll_port_config_set) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_MAJOR,
- "Port(0x%x)'s corresponding function is NULL.", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- lport->act_topo = UNF_ACT_TOP_UNKNOWN;
- lport->speed = UNF_PORT_SPEED_UNKNOWN;
- lport->fabric_node_name = 0;
-
- ret = lport->low_level_func.port_mgr_op.ll_port_config_set(lport->fc_port,
- UNF_PORT_CFG_SET_PORT_STATE,
- (void *)&port_state);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_MAJOR, "Reset port(0x%x) unsuccessful.",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-int unf_cm_reset_port(u32 port_id)
-{
- int ret = UNF_RETURN_ERROR;
-
- ret = unf_send_event(port_id, UNF_EVENT_SYN, (void *)&port_id,
- (void *)NULL, unf_reset_port);
- return ret;
-}
-
-int unf_lport_reset_port(struct unf_lport *lport, u32 flag)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- return unf_send_event(lport->port_id, flag, (void *)&lport->port_id,
- (void *)NULL, unf_reset_port);
-}
-
-static inline u32 unf_get_loop_alpa(struct unf_lport *lport, void *loop_alpa)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport->low_level_func.port_mgr_op.ll_port_config_get,
- UNF_RETURN_ERROR);
-
- ret = lport->low_level_func.port_mgr_op.ll_port_config_get(lport->fc_port,
- UNF_PORT_CFG_GET_LOOP_ALPA, loop_alpa);
-
- return ret;
-}
-
-static u32 unf_lport_enter_private_loop_login(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = lport;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_READY); /* LPort: LINK_UP --> READY */
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- unf_lport_update_topo(unf_lport, UNF_ACT_TOP_PRIVATE_LOOP);
-
- /* NOP: check L_Port state */
- if (atomic_read(&unf_lport->lport_no_operate_flag) == UNF_LPORT_NOP) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR, "[info]Port(0x%x) is NOP, do nothing",
- unf_lport->port_id);
-
- return RETURN_OK;
- }
-
- /* INI: check L_Port mode */
- if (UNF_PORT_MODE_INI != (unf_lport->options & UNF_PORT_MODE_INI)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) has no INI feature(0x%x), do nothing",
- unf_lport->port_id, unf_lport->options);
-
- return RETURN_OK;
- }
-
- if (unf_lport->disc.disc_temp.unf_disc_start) {
- ret = unf_lport->disc.disc_temp.unf_disc_start(unf_lport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) with nportid(0x%x) start discovery failed",
- unf_lport->port_id, unf_lport->nport_id);
- }
- }
-
- return ret;
-}
-
-u32 unf_lport_login(struct unf_lport *lport, enum unf_act_topo act_topo)
-{
- u32 loop_alpa = 0;
- u32 ret = RETURN_OK;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* 1. Update (set) L_Port topo which get from low level */
- unf_lport_update_topo(lport, act_topo);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
-
- /* 2. Link state check */
- if (lport->link_up != UNF_PORT_LINK_UP) {
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) with link_state(0x%x) port_state(0x%x) when login",
- lport->port_id, lport->link_up, lport->states);
-
- return UNF_RETURN_ERROR;
- }
-
- /* 3. Update L_Port state */
- unf_lport_state_ma(lport, UNF_EVENT_LPORT_LINK_UP); /* LPort: INITIAL --> LINK UP */
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]LOGIN: Port(0x%x) start to login with topology(0x%x)",
- lport->port_id, lport->act_topo);
-
- /* 4. Start logoin */
- if (act_topo == UNF_TOP_P2P_MASK ||
- act_topo == UNF_ACT_TOP_P2P_FABRIC ||
- act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- /* P2P or Fabric mode */
- ret = unf_lport_enter_flogi(lport);
- } else if (act_topo == UNF_ACT_TOP_PUBLIC_LOOP) {
- /* Public loop */
- (void)unf_get_loop_alpa(lport, &loop_alpa);
-
- /* Before FLOGI ALPA just low 8 bit, after FLOGI ACC, switch
- * will assign complete addresses
- */
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- lport->nport_id = loop_alpa;
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- ret = unf_lport_enter_flogi(lport);
- } else if (act_topo == UNF_ACT_TOP_PRIVATE_LOOP) {
- /* Private loop */
- (void)unf_get_loop_alpa(lport, &loop_alpa);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- lport->nport_id = loop_alpa;
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- ret = unf_lport_enter_private_loop_login(lport);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]LOGIN: Port(0x%x) login with unknown topology(0x%x)",
- lport->port_id, lport->act_topo);
- }
-
- return ret;
-}
-
-static u32 unf_port_linkup(struct unf_lport *lport, void *input)
-{
- struct unf_lport *unf_lport = lport;
- u32 ret = RETURN_OK;
- enum unf_act_topo act_topo = UNF_ACT_TOP_UNKNOWN;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- /* If NOP state, stop */
- if (atomic_read(&unf_lport->lport_no_operate_flag) == UNF_LPORT_NOP) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]Port(0x%x) is NOP and do nothing", unf_lport->port_id);
-
- return RETURN_OK;
- }
-
- /* Update port state */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- unf_lport->link_up = UNF_PORT_LINK_UP;
- unf_lport->speed = *((u32 *)input);
- unf_set_lport_state(lport, UNF_LPORT_ST_INITIAL); /* INITIAL state */
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- /* set hot pool wait state: so far, do not care */
- unf_set_hot_pool_wait_state(unf_lport, true);
-
- unf_lport->enhanced_features |= UNF_LPORT_ENHANCED_FEATURE_READ_SFP_ONCE;
-
- /* Get port active topopolgy (from low level) */
- if (!unf_lport->low_level_func.port_mgr_op.ll_port_config_get) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]Port(0x%x) get topo function is NULL", unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
- ret = unf_lport->low_level_func.port_mgr_op.ll_port_config_get(unf_lport->fc_port,
- UNF_PORT_CFG_GET_TOPO_ACT, (void *)&act_topo);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]Port(0x%x) get topo from low level failed",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Start Login process */
- ret = unf_lport_login(unf_lport, act_topo);
-
- return ret;
-}
-
-static u32 unf_port_linkdown(struct unf_lport *lport, void *input)
-{
- ulong flag = 0;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- unf_lport = lport;
-
- /* To prevent repeated reporting linkdown */
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- unf_lport->speed = UNF_PORT_SPEED_UNKNOWN;
- unf_lport->act_topo = UNF_ACT_TOP_UNKNOWN;
- if (unf_lport->link_up == UNF_PORT_LINK_DOWN) {
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- return RETURN_OK;
- }
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_LINK_DOWN);
- unf_reset_lport_params(unf_lport);
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- unf_set_hot_pool_wait_state(unf_lport, false);
-
- /*
- * clear I/O:
- * 1. INI do ABORT only,
- * 2. TGT need do source clear with Wait_IO
- * *
- * for INI: busy/delay/delay_transfer/wait
- * Clean L_Port/V_Port Link Down I/O: only set ABORT tag
- */
- unf_flush_disc_event(&unf_lport->disc, NULL);
-
- unf_clean_linkdown_io(unf_lport, false);
-
- /* for L_Port's R_Ports */
- unf_clean_linkdown_rport(unf_lport);
- /* for L_Port's all Vports */
- unf_linkdown_all_vports(lport);
- return RETURN_OK;
-}
-
-static u32 unf_port_abnormal_reset(struct unf_lport *lport, void *input)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- unf_lport = lport;
-
- ret = (u32)unf_lport_reset_port(unf_lport, UNF_EVENT_ASYN);
-
- return ret;
-}
-
-static u32 unf_port_reset_start(struct unf_lport *lport, void *input)
-{
- u32 ret = RETURN_OK;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- unf_set_lport_state(lport, UNF_LPORT_ST_RESET);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Port(0x%x) begin to reset.", lport->port_id);
-
- return ret;
-}
-
-static u32 unf_port_reset_end(struct unf_lport *lport, void *input)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Port(0x%x) reset end.", lport->port_id);
-
- /* Task management command returns success and avoid repair measures
- * case offline device
- */
- unf_wake_up_scsi_task_cmnd(lport);
-
- spin_lock_irqsave(&lport->lport_state_lock, flag);
- unf_set_lport_state(lport, UNF_LPORT_ST_INITIAL);
- spin_unlock_irqrestore(&lport->lport_state_lock, flag);
-
- return RETURN_OK;
-}
-
-static u32 unf_port_nop(struct unf_lport *lport, void *input)
-{
- struct unf_lport *unf_lport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- unf_lport = lport;
-
- atomic_set(&unf_lport->lport_no_operate_flag, UNF_LPORT_NOP);
-
- spin_lock_irqsave(&unf_lport->lport_state_lock, flag);
- unf_lport_state_ma(unf_lport, UNF_EVENT_LPORT_LINK_DOWN);
- unf_reset_lport_params(unf_lport);
- spin_unlock_irqrestore(&unf_lport->lport_state_lock, flag);
-
- /* Set Tag prevent pending I/O to wait_list when close sfp failed */
- unf_set_hot_pool_wait_state(unf_lport, false);
-
- unf_flush_disc_event(&unf_lport->disc, NULL);
-
- /* L_Port/V_Port's I/O(s): Clean Link Down I/O: Set Abort Tag */
- unf_clean_linkdown_io(unf_lport, false);
-
- /* L_Port/V_Port's R_Port(s): report link down event to scsi & clear
- * resource
- */
- unf_clean_linkdown_rport(unf_lport);
- unf_linkdown_all_vports(unf_lport);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) report NOP event done", unf_lport->nport_id);
-
- return RETURN_OK;
-}
-
-static u32 unf_port_begin_remove(struct unf_lport *lport, void *input)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- /* Cancel route timer delay work */
- unf_destroy_lport_route(lport);
-
- return RETURN_OK;
-}
-
-static u32 unf_get_pcie_link_state(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = lport;
- bool linkstate = true;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(unf_lport->low_level_func.port_mgr_op.ll_port_config_get,
- UNF_RETURN_ERROR);
-
- ret = unf_lport->low_level_func.port_mgr_op.ll_port_config_get(unf_lport->fc_port,
- UNF_PORT_CFG_GET_PCIE_LINK_STATE, (void *)&linkstate);
- if (ret != RETURN_OK || linkstate != true) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_KEVENT, "[err]Can't Get Pcie Link State");
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-void unf_root_lport_ref_dec(struct unf_lport *lport)
-{
- ulong flags = 0;
- ulong lport_flags = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%p) port_id(0x%x) reference count is %d",
- lport, lport->port_id, atomic_read(&lport->port_ref_cnt));
-
- spin_lock_irqsave(&global_lport_mgr.global_lport_list_lock, flags);
- spin_lock_irqsave(&lport->lport_state_lock, lport_flags);
- if (atomic_dec_and_test(&lport->port_ref_cnt)) {
- spin_unlock_irqrestore(&lport->lport_state_lock, lport_flags);
-
- list_del(&lport->entry_lport);
- global_lport_mgr.lport_sum--;
-
- /* Put L_Port to destroy list for debuging */
- list_add_tail(&lport->entry_lport, &global_lport_mgr.destroy_list_head);
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
-
- ret = unf_schedule_global_event((void *)lport, UNF_GLOBAL_EVENT_ASYN,
- unf_lport_destroy);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_CRITICAL,
- "[warn]Schedule global event faile. remain nodes(0x%x)",
- global_event_queue.list_number);
- }
- } else {
- spin_unlock_irqrestore(&lport->lport_state_lock, lport_flags);
- spin_unlock_irqrestore(&global_lport_mgr.global_lport_list_lock, flags);
- }
-}
-
-void unf_lport_ref_dec_to_destroy(struct unf_lport *lport)
-{
- if (lport->root_lport != lport)
- unf_vport_ref_dec(lport);
- else
- unf_root_lport_ref_dec(lport);
-}
-
-void unf_lport_route_work(struct work_struct *work)
-{
-#define UNF_MAX_PCIE_LINK_DOWN_TIMES 3
- struct unf_lport *unf_lport = NULL;
- int ret = 0;
-
- FC_CHECK_RETURN_VOID(work);
-
- unf_lport = container_of(work, struct unf_lport, route_timer_work.work);
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_KEVENT, "[err]LPort is NULL");
-
- return;
- }
-
- if (unlikely(unf_lport->port_removing)) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_KEVENT,
- "[warn]LPort(0x%x) route work is closing.", unf_lport->port_id);
-
- unf_lport_ref_dec_to_destroy(unf_lport);
-
- return;
- }
-
- if (unlikely(unf_get_pcie_link_state(unf_lport)))
- unf_lport->pcie_link_down_cnt++;
- else
- unf_lport->pcie_link_down_cnt = 0;
-
- if (unf_lport->pcie_link_down_cnt >= UNF_MAX_PCIE_LINK_DOWN_TIMES) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_KEVENT,
- "[warn]LPort(0x%x) detected pcie linkdown, closing route work",
- unf_lport->port_id);
- unf_lport->pcie_link_down = true;
- unf_free_lport_all_xchg(unf_lport);
- unf_lport_ref_dec_to_destroy(unf_lport);
- return;
- }
-
- if (unlikely(UNF_LPORT_CHIP_ERROR(unf_lport))) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_KEVENT,
- "[warn]LPort(0x%x) reported chip error, closing route work. ",
- unf_lport->port_id);
-
- unf_lport_ref_dec_to_destroy(unf_lport);
-
- return;
- }
-
- if (unf_lport->enhanced_features &
- UNF_LPORT_ENHANCED_FEATURE_CLOSE_FW_ROUTE) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_KEVENT,
- "[warn]User close LPort(0x%x) route work. ", unf_lport->port_id);
-
- unf_lport_ref_dec_to_destroy(unf_lport);
-
- return;
- }
-
- /* Scheduling 1 second */
- ret = queue_delayed_work(unf_wq, &unf_lport->route_timer_work,
- (ulong)msecs_to_jiffies(UNF_LPORT_POLL_TIMER));
- if (ret == 0) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_KEVENT,
- "[warn]LPort(0x%x) schedule work unsuccessful.", unf_lport->port_id);
-
- unf_lport_ref_dec_to_destroy(unf_lport);
- }
-}
-
-static int unf_cm_get_mac_adr(void *argc_in, void *argc_out)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_get_chip_info_argout *chip_info = NULL;
-
- FC_CHECK_RETURN_VALUE(argc_in, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(argc_out, UNF_RETURN_ERROR);
-
- unf_lport = (struct unf_lport *)argc_in;
- chip_info = (struct unf_get_chip_info_argout *)argc_out;
-
- if (!unf_lport) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT,
- UNF_MAJOR, " LPort is null.");
-
- return UNF_RETURN_ERROR;
- }
-
- if (!unf_lport->low_level_func.port_mgr_op.ll_port_config_get) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x)'s corresponding function is NULL.", unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- if (unf_lport->low_level_func.port_mgr_op.ll_port_config_get(unf_lport->fc_port,
- UNF_PORT_CFG_GET_MAC_ADDR,
- chip_info) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) get .", unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-int unf_build_sys_wwn(u32 port_id, u64 *sys_port_name, u64 *sys_node_name)
-{
- struct unf_get_chip_info_argout wwn = {0};
- u32 ret = UNF_RETURN_ERROR;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE((sys_port_name), UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE((sys_node_name), UNF_RETURN_ERROR);
-
- unf_lport = unf_find_lport_by_port_id(port_id);
- if (!unf_lport)
- return UNF_RETURN_ERROR;
-
- ret = (u32)unf_send_event(unf_lport->port_id, UNF_EVENT_SYN,
- (void *)unf_lport, (void *)&wwn, unf_cm_get_mac_adr);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "send event(port get mac adr) fail.");
- return UNF_RETURN_ERROR;
- }
-
- /* save card mode: UNF_FC_SERVER_BOARD_32_G(6):32G;
- * UNF_FC_SERVER_BOARD_16_G(7):16G MODE
- */
- unf_lport->card_type = wwn.board_type;
-
- /* update port max speed */
- if (wwn.board_type == UNF_FC_SERVER_BOARD_32_G)
- unf_lport->low_level_func.fc_ser_max_speed = UNF_PORT_SPEED_32_G;
- else if (wwn.board_type == UNF_FC_SERVER_BOARD_16_G)
- unf_lport->low_level_func.fc_ser_max_speed = UNF_PORT_SPEED_16_G;
- else if (wwn.board_type == UNF_FC_SERVER_BOARD_8_G)
- unf_lport->low_level_func.fc_ser_max_speed = UNF_PORT_SPEED_8_G;
- else
- unf_lport->low_level_func.fc_ser_max_speed = UNF_PORT_SPEED_32_G;
-
- *sys_port_name = wwn.wwpn;
- *sys_node_name = wwn.wwnn;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) Port Name(0x%llx), Node Name(0x%llx.)",
- port_id, *sys_port_name, *sys_node_name);
-
- return RETURN_OK;
-}
-
-static u32 unf_update_port_wwn(struct unf_lport *lport,
- struct unf_port_wwn *port_wwn)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(port_wwn, UNF_RETURN_ERROR);
-
- /* Now notice lowlevel to update */
- if (!lport->low_level_func.port_mgr_op.ll_port_config_set) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x)'s corresponding function is NULL.",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- if (lport->low_level_func.port_mgr_op.ll_port_config_set(lport->fc_port,
- UNF_PORT_CFG_UPDATE_WWN,
- port_wwn) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) update WWN unsuccessful.",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) update WWN: previous(0x%llx, 0x%llx), now(0x%llx, 0x%llx).",
- lport->port_id, lport->port_name, lport->node_name,
- port_wwn->sys_port_wwn, port_wwn->sys_node_name);
-
- lport->port_name = port_wwn->sys_port_wwn;
- lport->node_name = port_wwn->sys_node_name;
-
- return RETURN_OK;
-}
-
-static u32 unf_build_lport_wwn(struct unf_lport *lport)
-{
- struct unf_port_wwn port_wwn = {0};
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- if (unf_build_sys_wwn(lport->port_id, &port_wwn.sys_port_wwn,
- &port_wwn.sys_node_name) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "Port(0x%x) build WWN unsuccessful.", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) build WWN succeed", lport->port_id);
-
- if (unf_update_port_wwn(lport, &port_wwn) != RETURN_OK)
- return UNF_RETURN_ERROR;
-
- return RETURN_OK;
-}
-
-u32 unf_port_release_rport_index(struct unf_lport *lport, void *input)
-{
- u32 rport_index = INVALID_VALUE32;
- ulong flag = 0;
- struct unf_rport_pool *rport_pool = NULL;
- struct unf_lport *unf_lport = NULL;
- spinlock_t *rport_pool_lock = NULL;
-
- unf_lport = (struct unf_lport *)lport->root_lport;
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- if (input) {
- rport_index = *(u32 *)input;
- if (rport_index < lport->low_level_func.support_max_rport) {
- rport_pool = &unf_lport->rport_pool;
- rport_pool_lock = &rport_pool->rport_free_pool_lock;
- spin_lock_irqsave(rport_pool_lock, flag);
- if (test_bit((int)rport_index, rport_pool->rpi_bitmap)) {
- clear_bit((int)rport_index, rport_pool->rpi_bitmap);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) try to release a free rport index(0x%x)",
- lport->port_id, rport_index);
- }
- spin_unlock_irqrestore(rport_pool_lock, flag);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) try to release a not exist rport index(0x%x)",
- lport->port_id, rport_index);
- }
- }
-
- return RETURN_OK;
-}
-
-void *unf_lookup_lport_by_nportid(void *lport, u32 nport_id)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_vport_pool *vport_pool = NULL;
- struct unf_lport *unf_vport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- unf_lport = (struct unf_lport *)lport;
- unf_lport = unf_lport->root_lport;
- vport_pool = unf_lport->vport_pool;
-
- if (unf_lport->nport_id == nport_id)
- return unf_lport;
-
- if (unlikely(!vport_pool)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) vport pool is NULL", unf_lport->port_id);
-
- return NULL;
- }
-
- spin_lock_irqsave(&vport_pool->vport_pool_lock, flag);
- list_for_each_safe(node, next_node, &unf_lport->list_vports_head) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->nport_id == nport_id) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
- return unf_vport;
- }
- }
-
- list_for_each_safe(node, next_node, &unf_lport->list_intergrad_vports) {
- unf_vport = list_entry(node, struct unf_lport, entry_vport);
- if (unf_vport->nport_id == nport_id) {
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
- return unf_vport;
- }
- }
- spin_unlock_irqrestore(&vport_pool->vport_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Port(0x%x) has no vport Nport ID(0x%x)",
- unf_lport->port_id, nport_id);
-
- return NULL;
-}
-
-int unf_get_link_lose_tmo(struct unf_lport *lport)
-{
- u32 tmo_value = 0;
-
- if (!lport)
- return UNF_LOSE_TMO;
-
- tmo_value = atomic_read(&lport->link_lose_tmo);
-
- if (!tmo_value)
- tmo_value = UNF_LOSE_TMO;
-
- return (int)tmo_value;
-}
-
-u32 unf_register_scsi_host(struct unf_lport *lport)
-{
- struct unf_host_param host_param = {0};
-
- struct Scsi_Host **scsi_host = NULL;
- struct unf_lport_cfg_item *lport_cfg_items = NULL;
-
- FC_CHECK_RETURN_VALUE((lport), UNF_RETURN_ERROR);
-
- /* Point to -->> L_port->Scsi_host */
- scsi_host = &lport->host_info.host;
-
- lport_cfg_items = &lport->low_level_func.lport_cfg_items;
- host_param.can_queue = (int)lport_cfg_items->max_queue_depth;
-
- /* Performance optimization */
- host_param.cmnd_per_lun = UNF_MAX_CMND_PER_LUN;
-
- host_param.sg_table_size = UNF_MAX_DMA_SEGS;
- host_param.max_id = UNF_MAX_TARGET_NUMBER;
- host_param.max_lun = UNF_DEFAULT_MAX_LUN;
- host_param.max_channel = UNF_MAX_BUS_CHANNEL;
- host_param.max_cmnd_len = UNF_MAX_SCSI_CMND_LEN; /* CDB-16 */
- host_param.dma_boundary = UNF_DMA_BOUNDARY;
- host_param.max_sectors = UNF_MAX_SECTORS;
- host_param.port_id = lport->port_id;
- host_param.lport = lport;
- host_param.pdev = &lport->low_level_func.dev->dev;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Port(0x%x) allocate scsi host: can queue(%u), command performance LUN(%u), max lun(%u)",
- lport->port_id, host_param.can_queue, host_param.cmnd_per_lun,
- host_param.max_lun);
-
- if (unf_alloc_scsi_host(scsi_host, &host_param) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) allocate scsi host failed", lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Port(0x%x) allocate scsi host(0x%x) succeed",
- lport->port_id, UNF_GET_SCSI_HOST_ID(*scsi_host));
-
- return RETURN_OK;
-}
-
-void unf_unregister_scsi_host(struct unf_lport *lport)
-{
- struct Scsi_Host *scsi_host = NULL;
- u32 host_no = 0;
-
- FC_CHECK_RETURN_VOID(lport);
-
- scsi_host = lport->host_info.host;
-
- if (scsi_host) {
- host_no = UNF_GET_SCSI_HOST_ID(scsi_host);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[event]Port(0x%x) starting unregister scsi host(0x%x)",
- lport->port_id, host_no);
- unf_free_scsi_host(scsi_host);
- /* can`t set scsi_host for NULL, since it does`t alloc by itself */
- } else {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[warn]Port(0x%x) unregister scsi host, invalid scsi_host ",
- lport->port_id);
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[event]Port(0x%x) unregister scsi host(0x%x) succeed",
- lport->port_id, host_no);
-
- lport->destroy_step = UNF_LPORT_DESTROY_STEP_12_UNREG_SCSI_HOST;
-}
diff --git a/drivers/scsi/spfc/common/unf_portman.h b/drivers/scsi/spfc/common/unf_portman.h
deleted file mode 100644
index 4ad93d32bcaa..000000000000
--- a/drivers/scsi/spfc/common/unf_portman.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_PORTMAN_H
-#define UNF_PORTMAN_H
-
-#include "unf_type.h"
-#include "unf_lport.h"
-
-#define UNF_LPORT_POLL_TIMER ((u32)(1 * 1000))
-#define UNF_TX_CREDIT_REG_32_G 0x2289420
-#define UNF_RX_CREDIT_REG_32_G 0x228950c
-#define UNF_CREDIT_REG_16_G 0x2283418
-#define UNF_PORT_OFFSET_BASE 0x10000
-#define UNF_CREDIT_EMU_VALUE 0x20
-#define UNF_CREDIT_VALUE_32_G 0x8
-#define UNF_CREDIT_VALUE_16_G 0x8000000080008
-
-struct unf_nportid_map {
- u32 sid;
- u32 did;
- void *rport[1024];
- void *lport;
-};
-
-struct unf_global_card_thread {
- struct list_head card_list_head;
- spinlock_t global_card_list_lock;
- u32 card_num;
-};
-
-/* Global L_Port MG,manage all L_Port */
-struct unf_global_lport {
- struct list_head lport_list_head;
-
- /* Temporary list,used in hold list traverse */
- struct list_head intergrad_head;
-
- /* destroy list,used in card remove */
- struct list_head destroy_list_head;
-
- /* Dirty list,abnormal port */
- struct list_head dirty_list_head;
- spinlock_t global_lport_list_lock;
- u32 lport_sum;
- u8 dft_mode;
- bool start_work;
-};
-
-struct unf_port_action {
- u32 action;
- u32 (*unf_action)(struct unf_lport *lport, void *input);
-};
-
-struct unf_reset_port_argin {
- u32 port_id;
-};
-
-extern struct unf_global_lport global_lport_mgr;
-extern struct unf_global_card_thread card_thread_mgr;
-extern struct workqueue_struct *unf_wq;
-
-struct unf_lport *unf_find_lport_by_port_id(u32 port_id);
-struct unf_lport *unf_find_lport_by_scsi_hostid(u32 scsi_host_id);
-void *
-unf_lport_create_and_init(void *private_data,
- struct unf_low_level_functioon_op *low_level_op);
-u32 unf_fc_port_link_event(void *lport, u32 events, void *input);
-u32 unf_release_local_port(void *lport);
-void unf_lport_route_work(struct work_struct *work);
-void unf_lport_update_topo(struct unf_lport *lport,
- enum unf_act_topo active_topo);
-void unf_lport_ref_dec(struct unf_lport *lport);
-u32 unf_lport_ref_inc(struct unf_lport *lport);
-void unf_lport_ref_dec_to_destroy(struct unf_lport *lport);
-void unf_port_mgmt_deinit(void);
-void unf_port_mgmt_init(void);
-void unf_show_dirty_port(bool show_only, u32 *dirty_port_num);
-void *unf_lookup_lport_by_nportid(void *lport, u32 nport_id);
-u32 unf_is_lport_valid(struct unf_lport *lport);
-int unf_lport_reset_port(struct unf_lport *lport, u32 flag);
-int unf_cm_ops_handle(u32 type, void **arg_in);
-u32 unf_register_scsi_host(struct unf_lport *lport);
-void unf_unregister_scsi_host(struct unf_lport *lport);
-void unf_destroy_scsi_id_table(struct unf_lport *lport);
-u32 unf_lport_login(struct unf_lport *lport, enum unf_act_topo act_topo);
-u32 unf_init_scsi_id_table(struct unf_lport *lport);
-void unf_set_lport_removing(struct unf_lport *lport);
-void unf_lport_release_lw_funop(struct unf_lport *lport);
-void unf_show_all_rport(struct unf_lport *lport);
-void unf_disc_state_ma(struct unf_lport *lport, enum unf_disc_event evnet);
-int unf_get_link_lose_tmo(struct unf_lport *lport);
-u32 unf_port_release_rport_index(struct unf_lport *lport, void *input);
-int unf_cm_reset_port(u32 port_id);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_rport.c b/drivers/scsi/spfc/common/unf_rport.c
deleted file mode 100644
index 9b06df884524..000000000000
--- a/drivers/scsi/spfc/common/unf_rport.c
+++ /dev/null
@@ -1,2286 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_rport.h"
-#include "unf_log.h"
-#include "unf_exchg.h"
-#include "unf_ls.h"
-#include "unf_service.h"
-#include "unf_portman.h"
-
-/* rport state:ready --->>> link_down --->>> closing --->>> timeout --->>> delete */
-struct unf_rport_feature_pool *port_feature_pool;
-
-void unf_sesion_loss_timeout(struct work_struct *work)
-{
- struct unf_wwpn_rport_info *wwpn_rport_info = NULL;
-
- FC_CHECK_RETURN_VOID(work);
-
- wwpn_rport_info = container_of(work, struct unf_wwpn_rport_info, loss_tmo_work.work);
- if (unlikely(!wwpn_rport_info)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]wwpn_rport_info is NULL");
- return;
- }
-
- atomic_set(&wwpn_rport_info->scsi_state, UNF_SCSI_ST_DEAD);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[info]Port(0x%x) wwpn(0x%llx) set target(0x%x) scsi state to dead",
- ((struct unf_lport *)(wwpn_rport_info->lport))->port_id,
- wwpn_rport_info->wwpn, wwpn_rport_info->target_id);
-}
-
-u32 unf_alloc_scsi_id(struct unf_lport *lport, struct unf_rport *rport)
-{
- struct unf_rport_scsi_id_image *rport_scsi_table = NULL;
- struct unf_wwpn_rport_info *wwn_rport_info = NULL;
- ulong flags = 0;
- u32 index = 0;
- u32 ret = UNF_RETURN_ERROR;
- spinlock_t *rport_scsi_tb_lock = NULL;
-
- rport_scsi_table = &lport->rport_scsi_table;
- rport_scsi_tb_lock = &rport_scsi_table->scsi_image_table_lock;
- spin_lock_irqsave(rport_scsi_tb_lock, flags);
-
- /* 1. At first, existence check */
- for (index = 0; index < rport_scsi_table->max_scsi_id; index++) {
- wwn_rport_info = &rport_scsi_table->wwn_rport_info_table[index];
- if (rport->port_name == wwn_rport_info->wwpn) {
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
- UNF_DELAYED_WORK_SYNC(ret, (lport->port_id),
- (&wwn_rport_info->loss_tmo_work),
- "loss tmo Timer work");
-
- /* Plug case: reuse again */
- spin_lock_irqsave(rport_scsi_tb_lock, flags);
- wwn_rport_info->rport = rport;
- wwn_rport_info->las_ten_scsi_state =
- atomic_read(&wwn_rport_info->scsi_state);
- atomic_set(&wwn_rport_info->scsi_state, UNF_SCSI_ST_ONLINE);
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) find the same scsi_id(0x%x) by wwpn(0x%llx) RPort(%p) N_Port_ID(0x%x)",
- lport->port_id, index, wwn_rport_info->wwpn, rport,
- rport->nport_id);
-
- atomic_inc(&lport->resume_scsi_id);
- goto find;
- }
- }
-
- /* 2. Alloc new SCSI ID */
- for (index = 0; index < rport_scsi_table->max_scsi_id; index++) {
- wwn_rport_info = &rport_scsi_table->wwn_rport_info_table[index];
- if (wwn_rport_info->wwpn == INVALID_WWPN) {
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
- UNF_DELAYED_WORK_SYNC(ret, (lport->port_id),
- (&wwn_rport_info->loss_tmo_work),
- "loss tmo Timer work");
- /* Use the free space */
- spin_lock_irqsave(rport_scsi_tb_lock, flags);
- wwn_rport_info->rport = rport;
- wwn_rport_info->wwpn = rport->port_name;
- wwn_rport_info->las_ten_scsi_state =
- atomic_read(&wwn_rport_info->scsi_state);
- atomic_set(&wwn_rport_info->scsi_state, UNF_SCSI_ST_ONLINE);
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) allco new scsi_id(0x%x) by wwpn(0x%llx) RPort(%p) N_Port_ID(0x%x)",
- lport->port_id, index, wwn_rport_info->wwpn, rport,
- rport->nport_id);
-
- atomic_inc(&lport->alloc_scsi_id);
- goto find;
- }
- }
-
- /* 3. Reuse space has been used */
- for (index = 0; index < rport_scsi_table->max_scsi_id; index++) {
- wwn_rport_info = &rport_scsi_table->wwn_rport_info_table[index];
- if (atomic_read(&wwn_rport_info->scsi_state) == UNF_SCSI_ST_DEAD) {
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
- UNF_DELAYED_WORK_SYNC(ret, (lport->port_id),
- (&wwn_rport_info->loss_tmo_work),
- "loss tmo Timer work");
-
- spin_lock_irqsave(rport_scsi_tb_lock, flags);
- if (wwn_rport_info->dfx_counter) {
- memset(wwn_rport_info->dfx_counter, 0,
- sizeof(struct unf_wwpn_dfx_counter_info));
- }
- if (wwn_rport_info->lun_qos_level) {
- memset(wwn_rport_info->lun_qos_level, 0,
- sizeof(u8) * UNF_MAX_LUN_PER_TARGET);
- }
- wwn_rport_info->rport = rport;
- wwn_rport_info->wwpn = rport->port_name;
- wwn_rport_info->las_ten_scsi_state =
- atomic_read(&wwn_rport_info->scsi_state);
- atomic_set(&wwn_rport_info->scsi_state, UNF_SCSI_ST_ONLINE);
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[info]Port(0x%x) reuse a dead scsi_id(0x%x) by wwpn(0x%llx) RPort(%p) N_Port_ID(0x%x)",
- lport->port_id, index, wwn_rport_info->wwpn, rport,
- rport->nport_id);
-
- atomic_inc(&lport->reuse_scsi_id);
- goto find;
- }
- }
-
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) there is not enough scsi_id with max_value(0x%x)",
- lport->port_id, index);
-
- return INVALID_VALUE32;
-
-find:
- if (!wwn_rport_info->dfx_counter) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Port(0x%x) allocate Rport(0x%x) DFX buffer",
- lport->port_id, wwn_rport_info->rport->nport_id);
- wwn_rport_info->dfx_counter = vmalloc(sizeof(struct unf_wwpn_dfx_counter_info));
- if (!wwn_rport_info->dfx_counter) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) allocate DFX buffer fail",
- lport->port_id);
-
- return INVALID_VALUE32;
- }
-
- memset(wwn_rport_info->dfx_counter, 0, sizeof(struct unf_wwpn_dfx_counter_info));
- }
-
- return index;
-}
-
-u32 unf_get_scsi_id_by_wwpn(struct unf_lport *lport, u64 wwpn)
-{
- struct unf_rport_scsi_id_image *rport_scsi_table = NULL;
- struct unf_wwpn_rport_info *wwn_rport_info = NULL;
- ulong flags = 0;
- u32 index = 0;
- spinlock_t *rport_scsi_tb_lock = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, INVALID_VALUE32);
- rport_scsi_table = &lport->rport_scsi_table;
- rport_scsi_tb_lock = &rport_scsi_table->scsi_image_table_lock;
-
- if (wwpn == 0)
- return INVALID_VALUE32;
-
- spin_lock_irqsave(rport_scsi_tb_lock, flags);
-
- for (index = 0; index < rport_scsi_table->max_scsi_id; index++) {
- wwn_rport_info = &rport_scsi_table->wwn_rport_info_table[index];
- if (wwn_rport_info->wwpn == wwpn) {
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
- return index;
- }
- }
-
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
-
- return INVALID_VALUE32;
-}
-
-void unf_set_device_state(struct unf_lport *lport, u32 scsi_id, int scsi_state)
-{
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- struct unf_wwpn_rport_info *wwpn_rport_info = NULL;
-
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) RPort scsi_id(0x%x) is max than 0x%x",
- lport->port_id, scsi_id, UNF_MAX_SCSI_ID);
- return;
- }
-
- scsi_image_table = &lport->rport_scsi_table;
- wwpn_rport_info = &scsi_image_table->wwn_rport_info_table[scsi_id];
- atomic_set(&wwpn_rport_info->scsi_state, scsi_state);
-}
-
-void unf_rport_linkdown(struct unf_lport *lport, struct unf_rport *rport)
-{
- /*
- * 1. port_logout
- * 2. rcvd_rscn_port_not_in_disc
- * 3. each_rport_after_rscn
- * 4. rcvd_gpnid_rjt
- * 5. rport_after_logout(rport is fabric port)
- */
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- /* 1. Update R_Port state: Link Down Event --->>> closing state */
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LINK_DOWN);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* 3. Port enter closing (then enter to Delete) process */
- unf_rport_enter_closing(rport);
-}
-
-static struct unf_rport *unf_rport_is_changed(struct unf_lport *lport,
- struct unf_rport *rport, u32 sid)
-{
- if (rport) {
- /* S_ID or D_ID has been changed */
- if (rport->nport_id != sid || rport->local_nport_id != lport->nport_id) {
- /* 1. Swap case: (SID or DID changed): Report link down
- * & delete immediately
- */
- unf_rport_immediate_link_down(lport, rport);
- return NULL;
- }
- }
-
- return rport;
-}
-
-struct unf_rport *unf_rport_set_qualifier_key_reuse(struct unf_lport *lport,
- struct unf_rport *rport_by_nport_id,
- struct unf_rport *rport_by_wwpn,
- u64 wwpn, u32 sid)
-{
- /* Used for SPFC Chip */
- struct unf_rport *rport = NULL;
- struct unf_rport *rporta = NULL;
- struct unf_rport *rportb = NULL;
- bool wwpn_flag = false;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- /* About R_Port by N_Port_ID */
- rporta = unf_rport_is_changed(lport, rport_by_nport_id, sid);
-
- /* About R_Port by WWpn */
- rportb = unf_rport_is_changed(lport, rport_by_wwpn, sid);
-
- if (!rporta && !rportb) {
- return NULL;
- } else if (!rporta && rportb) {
- /* 3. Plug case: reuse again */
- rport = rportb;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) RPort(0x%p) WWPN(0x%llx) S_ID(0x%x) D_ID(0x%x) reused by wwpn",
- lport->port_id, rport, rport->port_name,
- rport->nport_id, rport->local_nport_id);
-
- return rport;
- } else if (rporta && !rportb) {
- wwpn_flag = (rporta->port_name != wwpn && rporta->port_name != 0 &&
- rporta->port_name != INVALID_VALUE64);
- if (wwpn_flag) {
- /* 4. WWPN changed: Report link down & delete
- * immediately
- */
- unf_rport_immediate_link_down(lport, rporta);
- return NULL;
- }
-
- /* Updtae WWPN */
- rporta->port_name = wwpn;
- rport = rporta;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) RPort(0x%p) WWPN(0x%llx) S_ID(0x%x) D_ID(0x%x) reused by N_Port_ID",
- lport->port_id, rport, rport->port_name,
- rport->nport_id, rport->local_nport_id);
-
- return rport;
- }
-
- /* 5. Case for A == B && A != NULL && B != NULL */
- if (rportb == rporta) {
- rport = rporta;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) find the same RPort(0x%p) WWPN(0x%llx) S_ID(0x%x) D_ID(0x%x)",
- lport->port_id, rport, rport->port_name, rport->nport_id,
- rport->local_nport_id);
-
- return rport;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find two duplicate login. RPort(A:0x%p, WWPN:0x%llx, S_ID:0x%x, D_ID:0x%x) RPort(B:0x%p, WWPN:0x%llx, S_ID:0x%x, D_ID:0x%x)",
- lport->port_id, rporta, rporta->port_name, rporta->nport_id,
- rporta->local_nport_id, rportb, rportb->port_name, rportb->nport_id,
- rportb->local_nport_id);
-
- /* 6. Case for A != B && A != NULL && B != NULL: Immediate
- * Report && Deletion
- */
- unf_rport_immediate_link_down(lport, rporta);
- unf_rport_immediate_link_down(lport, rportb);
-
- return NULL;
-}
-
-struct unf_rport *unf_find_valid_rport(struct unf_lport *lport, u64 wwpn, u32 sid)
-{
- struct unf_rport *rport = NULL;
- struct unf_rport *rport_by_nport_id = NULL;
- struct unf_rport *rport_by_wwpn = NULL;
- ulong flags = 0;
- spinlock_t *rport_state_lock = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(lport->unf_qualify_rport, NULL);
-
- /* Get R_Port by WWN & N_Port_ID */
- rport_by_nport_id = unf_get_rport_by_nport_id(lport, sid);
- rport_by_wwpn = unf_get_rport_by_wwn(lport, wwpn);
- rport_state_lock = &rport_by_wwpn->rport_state_lock;
-
- /* R_Port check: by WWPN */
- if (rport_by_wwpn) {
- spin_lock_irqsave(rport_state_lock, flags);
- if (rport_by_wwpn->nport_id == UNF_FC_FID_FLOGI) {
- spin_unlock_irqrestore(rport_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) RPort(0x%p) find by WWPN(0x%llx) is invalid",
- lport->port_id, rport_by_wwpn, wwpn);
-
- rport_by_wwpn = NULL;
- } else {
- spin_unlock_irqrestore(rport_state_lock, flags);
- }
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) RPort(0x%p) find by N_Port_ID(0x%x) and RPort(0x%p) by WWPN(0x%llx)",
- lport->port_id, lport->nport_id, rport_by_nport_id, sid, rport_by_wwpn, wwpn);
-
- /* R_Port validity check: get by WWPN & N_Port_ID */
- rport = lport->unf_qualify_rport(lport, rport_by_nport_id,
- rport_by_wwpn, wwpn, sid);
-
- return rport;
-}
-
-void unf_rport_delay_login(struct unf_rport *rport)
-{
- FC_CHECK_RETURN_VOID(rport);
-
- /* Do R_Port recovery: PLOGI or PRLI or LOGO */
- unf_rport_error_recovery(rport);
-}
-
-void unf_rport_enter_logo(struct unf_lport *lport, struct unf_rport *rport)
-{
- /*
- * 1. TMF/ABTS timeout recovery :Y
- * 2. L_Port error recovery --->>> larger than retry_count :Y
- * 3. R_Port error recovery --->>> larger than retry_count :Y
- * 4. Check PLOGI parameter --->>> parameter is error :Y
- * 5. PRLI handler --->>> R_Port state is error :Y
- * 6. PDISC handler --->>> R_Port state is not PRLI_WAIT :Y
- * 7. ADISC handler --->>> R_Port state is not PRLI_WAIT :Y
- * 8. PLOGI wait timeout with R_PORT is INI mode :Y
- * 9. RCVD GFFID_RJT --->>> R_Port state is INIT :Y
- * 10. RCVD GPNID_ACC --->>> R_Port state is error :Y
- * 11. Private Loop mode with LOGO case :Y
- * 12. P2P mode with LOGO case :Y
- * 13. Fabric mode with LOGO case :Y
- * 14. RCVD PRLI_ACC with R_Port is INI :Y
- * 15. TGT RCVD BLS_REQ with session is error :Y
- */
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&rport->rport_state_lock, flags);
-
- if (rport->rp_state == UNF_RPORT_ST_CLOSING ||
- rport->rp_state == UNF_RPORT_ST_DELETE) {
- /* 1. Already within Closing or Delete: Do nothing */
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- return;
- } else if (rport->rp_state == UNF_RPORT_ST_LOGO) {
- /* 2. Update R_Port state: Normal Enter Event --->>> closing
- * state
- */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_NORMAL_ENTER);
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- /* Send Logo if necessary */
- if (unf_send_logo(lport, rport) != RETURN_OK)
- unf_rport_enter_closing(rport);
- } else {
- /* 3. Update R_Port state: Link Down Event --->>> closing state
- */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LINK_DOWN);
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- unf_rport_enter_closing(rport);
- }
-}
-
-u32 unf_free_scsi_id(struct unf_lport *lport, u32 scsi_id)
-{
- ulong flags = 0;
- struct unf_rport_scsi_id_image *rport_scsi_table = NULL;
- struct unf_wwpn_rport_info *wwn_rport_info = NULL;
- spinlock_t *rport_scsi_tb_lock = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- if (unlikely(lport->port_removing)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) is removing and do nothing",
- lport->port_id, lport->nport_id);
-
- return UNF_RETURN_ERROR;
- }
-
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x_0x%x) scsi_id(0x%x) is bigger than %d",
- lport->port_id, lport->nport_id, scsi_id, UNF_MAX_SCSI_ID);
-
- return UNF_RETURN_ERROR;
- }
-
- rport_scsi_table = &lport->rport_scsi_table;
- rport_scsi_tb_lock = &rport_scsi_table->scsi_image_table_lock;
- if (rport_scsi_table->wwn_rport_info_table) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[warn]Port(0x%x_0x%x) RPort(0x%p) free scsi_id(0x%x) wwpn(0x%llx) target_id(0x%x) succeed",
- lport->port_id, lport->nport_id,
- rport_scsi_table->wwn_rport_info_table[scsi_id].rport,
- scsi_id, rport_scsi_table->wwn_rport_info_table[scsi_id].wwpn,
- rport_scsi_table->wwn_rport_info_table[scsi_id].target_id);
-
- spin_lock_irqsave(rport_scsi_tb_lock, flags);
- wwn_rport_info = &rport_scsi_table->wwn_rport_info_table[scsi_id];
- if (wwn_rport_info->rport) {
- wwn_rport_info->rport->rport = NULL;
- wwn_rport_info->rport = NULL;
- }
- wwn_rport_info->target_id = INVALID_VALUE32;
- atomic_set(&wwn_rport_info->scsi_state, UNF_SCSI_ST_DEAD);
-
- /* NOTE: remain WWPN/Port_Name unchanged(un-cleared) */
- spin_unlock_irqrestore(rport_scsi_tb_lock, flags);
-
- return RETURN_OK;
- }
-
- return UNF_RETURN_ERROR;
-}
-
-static void unf_report_ini_linkwown_event(struct unf_lport *lport, struct unf_rport *rport)
-{
- u32 scsi_id = 0;
- struct fc_rport *unf_rport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- /*
- * 1. set local device(rport/rport_info_table) state
- * -------------------------------------------------OFF_LINE
- * *
- * about rport->scsi_id
- * valid during rport link up to link down
- */
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- scsi_id = rport->scsi_id;
- unf_set_device_state(lport, scsi_id, UNF_SCSI_ST_OFFLINE);
-
- /* 2. delete scsi's rport */
- unf_rport = (struct fc_rport *)rport->rport;
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- if (unf_rport) {
- fc_remote_port_delete(unf_rport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x_0x%x) delete RPort(0x%x) wwpn(0x%llx) scsi_id(0x%x) succeed",
- lport->port_id, lport->nport_id, rport->nport_id,
- rport->port_name, scsi_id);
-
- atomic_inc(&lport->scsi_session_del_success);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[warn]Port(0x%x_0x%x) delete RPort(0x%x_0x%p) failed",
- lport->port_id, lport->nport_id, rport->nport_id, rport);
- }
-}
-
-static void unf_report_ini_linkup_event(struct unf_lport *lport, struct unf_rport *rport)
-{
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[event]Port(0x%x) RPort(0x%x_0x%p) put INI link up work(%p) to work_queue",
- lport->port_id, rport->nport_id, rport, &rport->start_work);
-
- if (unlikely(!queue_work(lport->link_event_wq, &rport->start_work))) {
- atomic_inc(&lport->add_start_work_failed);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]Port(0x%x) RPort(0x%x_0x%p) put INI link up to work_queue failed",
- lport->port_id, rport->nport_id, rport);
- }
-}
-
-void unf_update_lport_state_by_linkup_event(struct unf_lport *lport,
- struct unf_rport *rport,
- u32 rport_att)
-{
- /* Report R_Port Link Up/Down Event */
- ulong flag = 0;
- enum unf_port_state lport_state = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
-
- /* 1. R_Port does not has TGT mode any more */
- if (((rport_att & UNF_FC4_FRAME_PARM_3_TGT) == 0) &&
- rport->lport_ini_state == UNF_PORT_STATE_LINKUP) {
- rport->last_lport_ini_state = rport->lport_ini_state;
- rport->lport_ini_state = UNF_PORT_STATE_LINKDOWN;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) does not have TGT attribute(0x%x) any more",
- lport->port_id, rport->nport_id, rport_att);
- }
-
- /* 2. R_Port with TGT mode, L_Port with INI mode */
- if ((rport_att & UNF_FC4_FRAME_PARM_3_TGT) &&
- (lport->options & UNF_FC4_FRAME_PARM_3_INI)) {
- rport->last_lport_ini_state = rport->lport_ini_state;
- rport->lport_ini_state = UNF_PORT_STATE_LINKUP;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[warn]Port(0x%x) update INI state with last(0x%x) and now(0x%x)",
- lport->port_id, rport->last_lport_ini_state,
- rport->lport_ini_state);
- }
-
- /* 3. Report L_Port INI/TGT Down/Up event to SCSI */
- if (rport->last_lport_ini_state == rport->lport_ini_state) {
- if (rport->nport_id < UNF_FC_FID_DOM_MGR) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x %p) INI state(0x%x) has not been changed",
- lport->port_id, rport->nport_id, rport,
- rport->lport_ini_state);
- }
-
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- return;
- }
-
- lport_state = rport->lport_ini_state;
-
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- switch (lport_state) {
- case UNF_PORT_STATE_LINKDOWN:
- unf_report_ini_linkwown_event(lport, rport);
- break;
- case UNF_PORT_STATE_LINKUP:
- unf_report_ini_linkup_event(lport, rport);
- break;
- default:
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) with unknown link status(0x%x)",
- lport->port_id, rport->lport_ini_state);
- break;
- }
-}
-
-static void unf_rport_callback(void *rport, void *lport, u32 result)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(rport);
- FC_CHECK_RETURN_VOID(lport);
- unf_rport = (struct unf_rport *)rport;
- unf_lport = (struct unf_lport *)lport;
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport->last_lport_ini_state = unf_rport->lport_ini_state;
- unf_rport->lport_ini_state = UNF_PORT_STATE_LINKDOWN;
- unf_rport->last_lport_tgt_state = unf_rport->lport_tgt_state;
- unf_rport->lport_tgt_state = UNF_PORT_STATE_LINKDOWN;
-
- /* Report R_Port Link Down Event to scsi */
- if (unf_rport->last_lport_ini_state == unf_rport->lport_ini_state) {
- if (unf_rport->nport_id < UNF_FC_FID_DOM_MGR) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x %p) INI state(0x%x) has not been changed",
- unf_lport->port_id, unf_rport->nport_id,
- unf_rport, unf_rport->lport_ini_state);
- }
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- return;
- }
-
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- unf_report_ini_linkwown_event(unf_lport, unf_rport);
-}
-
-static void unf_rport_recovery_timeout(struct work_struct *work)
-{
- struct unf_lport *lport = NULL;
- struct unf_rport *rport = NULL;
- u32 ret = RETURN_OK;
- ulong flag = 0;
- enum unf_rport_login_state rp_state = UNF_RPORT_ST_INIT;
-
- FC_CHECK_RETURN_VOID(work);
-
- rport = container_of(work, struct unf_rport, recovery_work.work);
- if (unlikely(!rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]RPort is NULL");
-
- return;
- }
-
- lport = rport->lport;
- if (unlikely(!lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]RPort(0x%x) Port is NULL", rport->nport_id);
-
- /* for timer */
- unf_rport_ref_dec(rport);
- return;
- }
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rp_state = rport->rp_state;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) RPort(0x%x) state(0x%x) recovery timer timeout",
- lport->port_id, lport->nport_id, rport->nport_id, rp_state);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- switch (rp_state) {
- case UNF_RPORT_ST_PLOGI_WAIT:
- if ((lport->act_topo == UNF_ACT_TOP_P2P_DIRECT &&
- lport->port_name > rport->port_name) ||
- lport->act_topo != UNF_ACT_TOP_P2P_DIRECT) {
- /* P2P: Name is master with P2P_D
- * or has INI Mode
- */
- ret = unf_send_plogi(rport->lport, rport);
- }
- break;
- case UNF_RPORT_ST_PRLI_WAIT:
- ret = unf_send_prli(rport->lport, rport, ELS_PRLI);
- if (ret != RETURN_OK)
- unf_rport_error_recovery(rport);
- fallthrough;
- default:
- break;
- }
-
- if (ret != RETURN_OK)
- unf_rport_error_recovery(rport);
-
- /* company with timer */
- unf_rport_ref_dec(rport);
-}
-
-void unf_schedule_closing_work(struct unf_lport *lport, struct unf_rport *rport)
-{
- ulong flags = 0;
- struct unf_rport_scsi_id_image *rport_scsi_table = NULL;
- struct unf_wwpn_rport_info *wwn_rport_info = NULL;
- u32 scsi_id = 0;
- u32 ret = 0;
- u32 delay = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- delay = (u32)(unf_get_link_lose_tmo(lport) * 1000);
-
- rport_scsi_table = &lport->rport_scsi_table;
- scsi_id = rport->scsi_id;
- spin_lock_irqsave(&rport->rport_state_lock, flags);
-
- /* 1. Cancel recovery_work */
- if (cancel_delayed_work(&rport->recovery_work)) {
- atomic_dec(&rport->rport_ref_cnt);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) RPort(0x%x_0x%p) cancel recovery work succeed",
- lport->port_id, lport->nport_id, rport->nport_id, rport);
- }
-
- /* 2. Cancel Open_work */
- if (cancel_delayed_work(&rport->open_work)) {
- atomic_dec(&rport->rport_ref_cnt);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) RPort(0x%x_0x%p) cancel open work succeed",
- lport->port_id, lport->nport_id, rport->nport_id, rport);
- }
-
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- /* 3. Work in-queue (switch to thread context) */
- if (!queue_work(lport->link_event_wq, &rport->closing_work)) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[warn]Port(0x%x) RPort(0x%x_0x%p) add link down to work queue failed",
- lport->port_id, rport->nport_id, rport);
-
- atomic_inc(&lport->add_closing_work_failed);
- } else {
- spin_lock_irqsave(&rport->rport_state_lock, flags);
- (void)unf_rport_ref_inc(rport);
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info]Port(0x%x) RPort(0x%x_0x%p) add link down to work(%p) queue succeed",
- lport->port_id, rport->nport_id, rport,
- &rport->closing_work);
- }
-
- if (rport->nport_id > UNF_FC_FID_DOM_MGR)
- return;
-
- if (scsi_id >= UNF_MAX_SCSI_ID) {
- scsi_id = unf_get_scsi_id_by_wwpn(lport, rport->port_name);
- if (scsi_id >= UNF_MAX_SCSI_ID) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%p) NPortId(0x%x) wwpn(0x%llx) option(0x%x) scsi_id(0x%x) is max than(0x%x)",
- lport->port_id, rport, rport->nport_id,
- rport->port_name, rport->options, scsi_id,
- UNF_MAX_SCSI_ID);
-
- return;
- }
- }
-
- wwn_rport_info = &rport_scsi_table->wwn_rport_info_table[scsi_id];
- ret = queue_delayed_work(unf_wq, &wwn_rport_info->loss_tmo_work,
- (ulong)msecs_to_jiffies((u32)delay));
- if (!ret) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info] Port(0x%x) add RPort(0x%p) NPortId(0x%x) scsi_id(0x%x) wwpn(0x%llx) loss timeout work failed",
- lport->port_id, rport, rport->nport_id, scsi_id,
- rport->port_name);
- }
-}
-
-static void unf_rport_closing_timeout(struct work_struct *work)
-{
- /* closing --->>>(timeout)--->>> delete */
- struct unf_rport *rport = NULL;
- struct unf_lport *lport = NULL;
- struct unf_disc *disc = NULL;
- ulong rport_flag = 0;
- ulong disc_flag = 0;
- void (*unf_rport_callback)(void *, void *, u32) = NULL;
- enum unf_rport_login_state old_state;
-
- FC_CHECK_RETURN_VOID(work);
-
- /* Get R_Port & L_Port & Disc */
- rport = container_of(work, struct unf_rport, closing_work);
- if (unlikely(!rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]RPort is NULL");
- return;
- }
-
- lport = rport->lport;
- if (unlikely(!lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]RPort(0x%x_0x%p) Port is NULL",
- rport->nport_id, rport);
-
- /* Release directly (for timer) */
- unf_rport_ref_dec(rport);
- return;
- }
- disc = &lport->disc;
-
- spin_lock_irqsave(&rport->rport_state_lock, rport_flag);
-
- old_state = rport->rp_state;
- /* 1. Update R_Port state: event_timeout --->>> state_delete */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_CLS_TIMEOUT);
-
- /* Check R_Port state */
- if (rport->rp_state != UNF_RPORT_ST_DELETE) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x_0x%x) RPort(0x%x_0x%p) closing timeout with error state(0x%x->0x%x)",
- lport->port_id, lport->nport_id, rport->nport_id,
- rport, old_state, rport->rp_state);
-
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
-
- /* Dec ref_cnt for timer */
- unf_rport_ref_dec(rport);
- return;
- }
-
- unf_rport_callback = rport->unf_rport_callback;
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
-
- /* 2. Put R_Port to delete list */
- spin_lock_irqsave(&disc->rport_busy_pool_lock, disc_flag);
- list_del_init(&rport->entry_rport);
- list_add_tail(&rport->entry_rport, &disc->list_delete_rports);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_flag);
-
- /* 3. Report rport link down event to scsi */
- if (unf_rport_callback) {
- unf_rport_callback((void *)rport, (void *)rport->lport, RETURN_OK);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]RPort(0x%x) callback is NULL",
- rport->nport_id);
- }
-
- /* 4. Remove/delete R_Port */
- unf_rport_ref_dec(rport);
- unf_rport_ref_dec(rport);
-}
-
-static void unf_rport_linkup_to_scsi(struct work_struct *work)
-{
- struct fc_rport_identifiers rport_ids;
- struct fc_rport *rport = NULL;
- ulong flags = RETURN_OK;
- struct unf_wwpn_rport_info *wwn_rport_info = NULL;
- struct unf_rport_scsi_id_image *rport_scsi_table = NULL;
- u32 scsi_id = 0;
-
- struct unf_lport *lport = NULL;
- struct unf_rport *unf_rport = NULL;
-
- FC_CHECK_RETURN_VOID(work);
-
- unf_rport = container_of(work, struct unf_rport, start_work);
- if (unlikely(!unf_rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]RPort is NULL for work(%p)", work);
- return;
- }
-
- lport = unf_rport->lport;
- if (unlikely(!lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]RPort(0x%x_0x%p) Port is NULL",
- unf_rport->nport_id, unf_rport);
- return;
- }
-
- /* 1. Alloc R_Port SCSI_ID (image table) */
- unf_rport->scsi_id = unf_alloc_scsi_id(lport, unf_rport);
- if (unlikely(unf_rport->scsi_id == INVALID_VALUE32)) {
- atomic_inc(&lport->scsi_session_add_failed);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[err]Port(0x%x_0x%x) RPort(0x%x_0x%p) wwpn(0x%llx) scsi_id(0x%x) is invalid",
- lport->port_id, lport->nport_id,
- unf_rport->nport_id, unf_rport,
- unf_rport->port_name, unf_rport->scsi_id);
-
- /* NOTE: return */
- return;
- }
-
- /* 2. Add rport to scsi */
- scsi_id = unf_rport->scsi_id;
- rport_ids.node_name = unf_rport->node_name;
- rport_ids.port_name = unf_rport->port_name;
- rport_ids.port_id = unf_rport->nport_id;
- rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
- rport = fc_remote_port_add(lport->host_info.host, 0, &rport_ids);
- if (unlikely(!rport)) {
- atomic_inc(&lport->scsi_session_add_failed);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x_0x%x) RPort(0x%x_0x%p) wwpn(0x%llx) report link up to scsi failed",
- lport->port_id, lport->nport_id, unf_rport->nport_id, unf_rport,
- unf_rport->port_name);
-
- unf_free_scsi_id(lport, scsi_id);
- return;
- }
-
- /* 3. Change rport role */
- *((u32 *)rport->dd_data) = scsi_id; /* save local SCSI_ID to scsi rport */
- rport->supported_classes = FC_COS_CLASS3;
- rport_ids.roles |= FC_PORT_ROLE_FCP_TARGET;
- rport->dev_loss_tmo = (u32)unf_get_link_lose_tmo(lport); /* default 30s */
- fc_remote_port_rolechg(rport, rport_ids.roles);
-
- /* 4. Save scsi rport info to local R_Port */
- spin_lock_irqsave(&unf_rport->rport_state_lock, flags);
- unf_rport->rport = rport;
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flags);
-
- rport_scsi_table = &lport->rport_scsi_table;
- spin_lock_irqsave(&rport_scsi_table->scsi_image_table_lock, flags);
- wwn_rport_info = &rport_scsi_table->wwn_rport_info_table[scsi_id];
- wwn_rport_info->target_id = rport->scsi_target_id;
- wwn_rport_info->rport = unf_rport;
- atomic_set(&wwn_rport_info->scsi_state, UNF_SCSI_ST_ONLINE);
- spin_unlock_irqrestore(&rport_scsi_table->scsi_image_table_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x_0x%x) RPort(0x%x) wwpn(0x%llx) scsi_id(0x%x) link up to scsi succeed",
- lport->port_id, lport->nport_id, unf_rport->nport_id,
- unf_rport->port_name, scsi_id);
-
- atomic_inc(&lport->scsi_session_add_success);
-}
-
-static void unf_rport_open_timeout(struct work_struct *work)
-{
- struct unf_rport *rport = NULL;
- struct unf_lport *lport = NULL;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VOID(work);
-
- rport = container_of(work, struct unf_rport, open_work.work);
- if (!rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]RPort is NULL");
-
- return;
- }
-
- spin_lock_irqsave(&rport->rport_state_lock, flags);
- lport = rport->lport;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) RPort(0x%x) open work timeout with state(0x%x)",
- lport->port_id, lport->nport_id, rport->nport_id,
- rport->rp_state);
-
- /* NOTE: R_Port state check */
- if (rport->rp_state != UNF_RPORT_ST_PRLI_WAIT) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- /* Dec ref_cnt for timer case */
- unf_rport_ref_dec(rport);
- return;
- }
-
- /* Report R_Port Link Down event */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LINK_DOWN);
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- unf_rport_enter_closing(rport);
- /* Dec ref_cnt for timer case */
- unf_rport_ref_dec(rport);
-}
-
-static u32 unf_alloc_index_for_rport(struct unf_lport *lport, struct unf_rport *rport)
-{
- ulong rport_flag = 0;
- ulong pool_flag = 0;
- u32 alloc_indx = 0;
- u32 max_rport = 0;
- struct unf_rport_pool *rport_pool = NULL;
- spinlock_t *rport_scsi_tb_lock = NULL;
-
- rport_pool = &lport->rport_pool;
- rport_scsi_tb_lock = &rport_pool->rport_free_pool_lock;
- max_rport = lport->low_level_func.lport_cfg_items.max_login;
-
- max_rport = max_rport > SPFC_DEFAULT_RPORT_INDEX ? SPFC_DEFAULT_RPORT_INDEX : max_rport;
-
- spin_lock_irqsave(rport_scsi_tb_lock, pool_flag);
- while (alloc_indx < max_rport) {
- if (!test_bit((int)alloc_indx, rport_pool->rpi_bitmap)) {
- /* Case for SPFC */
- if (unlikely(atomic_read(&lport->lport_no_operate_flag) == UNF_LPORT_NOP)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) is within NOP", lport->port_id);
-
- spin_unlock_irqrestore(rport_scsi_tb_lock, pool_flag);
- return UNF_RETURN_ERROR;
- }
-
- spin_lock_irqsave(&rport->rport_state_lock, rport_flag);
- rport->rport_index = alloc_indx;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) RPort(0x%x) alloc index(0x%x) succeed",
- lport->port_id, alloc_indx, rport->nport_id);
-
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_flag);
-
- /* Set (index) bit */
- set_bit((int)alloc_indx, rport_pool->rpi_bitmap);
-
- /* Break here */
- break;
- }
- alloc_indx++;
- }
- spin_unlock_irqrestore(rport_scsi_tb_lock, pool_flag);
-
- if (max_rport == alloc_indx)
- return UNF_RETURN_ERROR;
- return RETURN_OK;
-}
-
-static void unf_check_rport_pool_status(struct unf_lport *lport)
-{
- struct unf_lport *unf_lport = lport;
- struct unf_rport_pool *rport_pool = NULL;
- ulong flags = 0;
- u32 max_rport = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- rport_pool = &unf_lport->rport_pool;
-
- spin_lock_irqsave(&rport_pool->rport_free_pool_lock, flags);
- max_rport = unf_lport->low_level_func.lport_cfg_items.max_login;
- if (rport_pool->rport_pool_completion &&
- rport_pool->rport_pool_count == max_rport) {
- complete(rport_pool->rport_pool_completion);
- }
-
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flags);
-}
-
-static void unf_init_rport_sq_num(struct unf_rport *rport, struct unf_lport *lport)
-{
- u32 session_order;
- u32 ssq_average_session_num;
-
- ssq_average_session_num = (lport->max_ssq_num - 1) / UNF_SQ_NUM_PER_SESSION;
- session_order = (rport->rport_index) % ssq_average_session_num;
- rport->sqn_base = (session_order * UNF_SQ_NUM_PER_SESSION);
-}
-
-void unf_init_rport_params(struct unf_rport *rport, struct unf_lport *lport)
-{
- struct unf_rport *unf_rport = rport;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(unf_rport);
- FC_CHECK_RETURN_VOID(lport);
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_set_rport_state(unf_rport, UNF_RPORT_ST_INIT);
- unf_rport->unf_rport_callback = unf_rport_callback;
- unf_rport->lport = lport;
- unf_rport->fcp_conf_needed = false;
- unf_rport->tape_support_needed = false;
- unf_rport->max_retries = UNF_MAX_RETRY_COUNT;
- unf_rport->logo_retries = 0;
- unf_rport->retries = 0;
- unf_rport->rscn_position = UNF_RPORT_NOT_NEED_PROCESS;
- unf_rport->last_lport_ini_state = UNF_PORT_STATE_LINKDOWN;
- unf_rport->lport_ini_state = UNF_PORT_STATE_LINKDOWN;
- unf_rport->last_lport_tgt_state = UNF_PORT_STATE_LINKDOWN;
- unf_rport->lport_tgt_state = UNF_PORT_STATE_LINKDOWN;
- unf_rport->node_name = 0;
- unf_rport->port_name = INVALID_WWPN;
- unf_rport->disc_done = 0;
- unf_rport->scsi_id = INVALID_VALUE32;
- unf_rport->data_thread = NULL;
- sema_init(&unf_rport->task_sema, 0);
- atomic_set(&unf_rport->rport_ref_cnt, 0);
- atomic_set(&unf_rport->pending_io_cnt, 0);
- unf_rport->rport_alloc_jifs = jiffies;
-
- unf_rport->ed_tov = UNF_DEFAULT_EDTOV + 500;
- unf_rport->ra_tov = UNF_DEFAULT_RATOV;
-
- INIT_WORK(&unf_rport->closing_work, unf_rport_closing_timeout);
- INIT_WORK(&unf_rport->start_work, unf_rport_linkup_to_scsi);
- INIT_DELAYED_WORK(&unf_rport->recovery_work, unf_rport_recovery_timeout);
- INIT_DELAYED_WORK(&unf_rport->open_work, unf_rport_open_timeout);
-
- atomic_inc(&unf_rport->rport_ref_cnt);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-}
-
-static u32 unf_alloc_ll_rport_resource(struct unf_lport *lport,
- struct unf_rport *rport, u32 nport_id)
-{
- u32 ret = RETURN_OK;
- struct unf_port_info rport_info = {0};
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_qos_info *qos_info = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong flag = 0;
-
- unf_lport = lport->root_lport;
-
- if (unf_lport->low_level_func.service_op.unf_alloc_rport_res) {
- spin_lock_irqsave(&lport->qos_mgr_lock, flag);
- rport_info.qos_level = lport->qos_level;
- list_for_each_safe(node, next_node, &lport->list_qos_head) {
- qos_info = (struct unf_qos_info *)list_entry(node, struct unf_qos_info,
- entry_qos_info);
-
- if (qos_info && qos_info->nport_id == nport_id) {
- rport_info.qos_level = qos_info->qos_level;
- break;
- }
- }
-
- spin_unlock_irqrestore(&lport->qos_mgr_lock, flag);
-
- unf_init_rport_sq_num(rport, unf_lport);
-
- rport->qos_level = rport_info.qos_level;
- rport_info.nport_id = nport_id;
- rport_info.rport_index = rport->rport_index;
- rport_info.local_nport_id = lport->nport_id;
- rport_info.port_name = 0;
- rport_info.cs_ctrl = UNF_CSCTRL_INVALID;
- rport_info.sqn_base = rport->sqn_base;
-
- if (unf_lport->priority == UNF_PRIORITY_ENABLE) {
- if (rport_info.qos_level == UNF_QOS_LEVEL_DEFAULT)
- rport_info.cs_ctrl = UNF_CSCTRL_LOW;
- else if (rport_info.qos_level == UNF_QOS_LEVEL_MIDDLE)
- rport_info.cs_ctrl = UNF_CSCTRL_MIDDLE;
- else if (rport_info.qos_level == UNF_QOS_LEVEL_HIGH)
- rport_info.cs_ctrl = UNF_CSCTRL_HIGH;
- }
-
- ret = unf_lport->low_level_func.service_op.unf_alloc_rport_res(unf_lport->fc_port,
- &rport_info);
- } else {
- ret = RETURN_OK;
- }
-
- return ret;
-}
-
-static void *unf_add_rport_to_busy_list(struct unf_lport *lport,
- struct unf_rport *new_rport,
- u32 nport_id)
-{
- struct unf_rport_pool *rport_pool = NULL;
- struct unf_lport *unf_lport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_rport *unf_new_rport = new_rport;
- struct unf_rport *old_rport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- spinlock_t *rport_free_lock = NULL;
- spinlock_t *rport_busy_lock = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(new_rport, NULL);
-
- unf_lport = lport->root_lport;
- disc = &lport->disc;
- FC_CHECK_RETURN_VALUE(unf_lport, NULL);
- rport_pool = &unf_lport->rport_pool;
- rport_free_lock = &rport_pool->rport_free_pool_lock;
- rport_busy_lock = &disc->rport_busy_pool_lock;
-
- spin_lock_irqsave(rport_busy_lock, flag);
- list_for_each_safe(node, next_node, &disc->list_busy_rports) {
- /* According to N_Port_ID */
- old_rport = list_entry(node, struct unf_rport, entry_rport);
- if (old_rport->nport_id == nport_id)
- break;
- old_rport = NULL;
- }
-
- if (old_rport) {
- spin_unlock_irqrestore(rport_busy_lock, flag);
-
- /* Use old R_Port & Add new R_Port back to R_Port Pool */
- spin_lock_irqsave(rport_free_lock, flag);
- clear_bit((int)unf_new_rport->rport_index, rport_pool->rpi_bitmap);
- list_add_tail(&unf_new_rport->entry_rport, &rport_pool->list_rports_pool);
- rport_pool->rport_pool_count++;
- spin_unlock_irqrestore(rport_free_lock, flag);
-
- unf_check_rport_pool_status(unf_lport);
- return (void *)old_rport;
- }
- spin_unlock_irqrestore(rport_busy_lock, flag);
- if (nport_id != UNF_FC_FID_FLOGI) {
- if (unf_alloc_ll_rport_resource(lport, unf_new_rport, nport_id) != RETURN_OK) {
- /* Add new R_Port back to R_Port Pool */
- spin_lock_irqsave(rport_free_lock, flag);
- clear_bit((int)unf_new_rport->rport_index, rport_pool->rpi_bitmap);
- list_add_tail(&unf_new_rport->entry_rport, &rport_pool->list_rports_pool);
- rport_pool->rport_pool_count++;
- spin_unlock_irqrestore(rport_free_lock, flag);
- unf_check_rport_pool_status(unf_lport);
-
- return NULL;
- }
- }
-
- spin_lock_irqsave(rport_busy_lock, flag);
- /* Add new R_Port to busy list */
- list_add_tail(&unf_new_rport->entry_rport, &disc->list_busy_rports);
- unf_new_rport->nport_id = nport_id;
- unf_new_rport->local_nport_id = lport->nport_id;
- spin_unlock_irqrestore(rport_busy_lock, flag);
- unf_init_rport_params(unf_new_rport, lport);
-
- return (void *)unf_new_rport;
-}
-
-void *unf_rport_get_free_and_init(void *lport, u32 port_type, u32 nport_id)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_rport_pool *rport_pool = NULL;
- struct unf_disc *disc = NULL;
- struct unf_disc *vport_disc = NULL;
- struct unf_rport *rport = NULL;
- struct list_head *list_head = NULL;
- ulong flag = 0;
- struct unf_disc_rport *disc_rport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- unf_lport = ((struct unf_lport *)lport)->root_lport;
- FC_CHECK_RETURN_VALUE(unf_lport, NULL);
-
- /* Check L_Port state: NOP */
- if (unlikely(atomic_read(&unf_lport->lport_no_operate_flag) == UNF_LPORT_NOP))
- return NULL;
-
- rport_pool = &unf_lport->rport_pool;
- disc = &unf_lport->disc;
-
- /* 1. UNF_PORT_TYPE_DISC: Get from disc_rport_pool */
- if (port_type == UNF_PORT_TYPE_DISC) {
- vport_disc = &((struct unf_lport *)lport)->disc;
- /* NOTE: list_disc_rports_pool used with list_disc_rports_busy */
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- if (!list_empty(&disc->disc_rport_mgr.list_disc_rports_pool)) {
- /* Get & delete from Disc R_Port Pool & Add it to Busy list */
- list_head = UNF_OS_LIST_NEXT(&disc->disc_rport_mgr.list_disc_rports_pool);
- list_del_init(list_head);
- disc_rport = list_entry(list_head, struct unf_disc_rport, entry_rport);
- disc_rport->nport_id = nport_id;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- /* Add to list_disc_rports_busy */
- spin_lock_irqsave(&vport_disc->rport_busy_pool_lock, flag);
- list_add_tail(list_head, &vport_disc->disc_rport_mgr.list_disc_rports_busy);
- spin_unlock_irqrestore(&vport_disc->rport_busy_pool_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "Port(0x%x_0x%x) add nportid:0x%x to rportbusy list",
- unf_lport->port_id, unf_lport->nport_id,
- disc_rport->nport_id);
- } else {
- disc_rport = NULL;
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
- }
-
- /* NOTE: return */
- return disc_rport;
- }
-
- /* 2. UNF_PORT_TYPE_FC (rport_pool): Get from list_rports_pool */
- spin_lock_irqsave(&rport_pool->rport_free_pool_lock, flag);
- if (!list_empty(&rport_pool->list_rports_pool)) {
- /* Get & delete from R_Port free Pool */
- list_head = UNF_OS_LIST_NEXT(&rport_pool->list_rports_pool);
- list_del_init(list_head);
- rport_pool->rport_pool_count--;
- rport = list_entry(list_head, struct unf_rport, entry_rport);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) RPort pool is empty",
- unf_lport->port_id, unf_lport->nport_id);
-
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flag);
-
- return NULL;
- }
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flag);
-
- /* 3. Alloc (& set bit) R_Port index */
- if (unf_alloc_index_for_rport(unf_lport, rport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) allocate index for new RPort failed",
- unf_lport->nport_id);
-
- /* Alloc failed: Add R_Port back to R_Port Pool */
- spin_lock_irqsave(&rport_pool->rport_free_pool_lock, flag);
- list_add_tail(&rport->entry_rport, &rport_pool->list_rports_pool);
- rport_pool->rport_pool_count++;
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flag);
- unf_check_rport_pool_status(unf_lport);
- return NULL;
- }
-
- /* 4. Add R_Port to busy list */
- rport = unf_add_rport_to_busy_list(lport, rport, nport_id);
-
- return (void *)rport;
-}
-
-u32 unf_release_rport_res(struct unf_lport *lport, struct unf_rport *rport)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct unf_port_info rport_info;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- memset(&rport_info, 0, sizeof(struct unf_port_info));
-
- rport_info.rport_index = rport->rport_index;
- rport_info.nport_id = rport->nport_id;
- rport_info.port_name = rport->port_name;
- rport_info.sqn_base = rport->sqn_base;
-
- /* 2. release R_Port(parent context/Session) resource */
- if (!lport->low_level_func.service_op.unf_release_rport_res) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) release rport resource function can't be NULL",
- lport->port_id);
-
- return ret;
- }
-
- ret = lport->low_level_func.service_op.unf_release_rport_res(lport->fc_port, &rport_info);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) rport_index(0x%x, %p) send release session CMND failed",
- lport->port_id, rport_info.rport_index, rport);
- }
-
- return ret;
-}
-
-static void unf_reset_rport_attribute(struct unf_rport *rport)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- rport->unf_rport_callback = NULL;
- rport->lport = NULL;
- rport->node_name = INVALID_VALUE64;
- rport->port_name = INVALID_WWPN;
- rport->nport_id = INVALID_VALUE32;
- rport->local_nport_id = INVALID_VALUE32;
- rport->max_frame_size = UNF_MAX_FRAME_SIZE;
- rport->ed_tov = UNF_DEFAULT_EDTOV;
- rport->ra_tov = UNF_DEFAULT_RATOV;
- rport->rport_index = INVALID_VALUE32;
- rport->scsi_id = INVALID_VALUE32;
- rport->rport_alloc_jifs = INVALID_VALUE64;
-
- /* ini or tgt */
- rport->options = 0;
-
- /* fcp conf */
- rport->fcp_conf_needed = false;
-
- /* special req retry times */
- rport->retries = 0;
- rport->logo_retries = 0;
-
- /* special req retry times */
- rport->max_retries = UNF_MAX_RETRY_COUNT;
-
- /* for target mode */
- rport->session = NULL;
- rport->last_lport_ini_state = UNF_PORT_STATE_LINKDOWN;
- rport->lport_ini_state = UNF_PORT_STATE_LINKDOWN;
- rport->rp_state = UNF_RPORT_ST_INIT;
- rport->last_lport_tgt_state = UNF_PORT_STATE_LINKDOWN;
- rport->lport_tgt_state = UNF_PORT_STATE_LINKDOWN;
- rport->rscn_position = UNF_RPORT_NOT_NEED_PROCESS;
- rport->disc_done = 0;
- rport->sqn_base = 0;
-
- /* for scsi */
- rport->data_thread = NULL;
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-}
-
-u32 unf_rport_remove(void *rport)
-{
- struct unf_lport *lport = NULL;
- struct unf_rport *unf_rport = NULL;
- struct unf_rport_pool *rport_pool = NULL;
- ulong flag = 0;
- u32 rport_index = 0;
- u32 nport_id = 0;
-
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- unf_rport = (struct unf_rport *)rport;
- lport = unf_rport->lport;
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- rport_pool = &((struct unf_lport *)lport->root_lport)->rport_pool;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Remove RPort(0x%p) with remote_nport_id(0x%x) local_nport_id(0x%x)",
- unf_rport, unf_rport->nport_id, unf_rport->local_nport_id);
-
- /* 1. Terminate open exchange before rport remove: set ABORT tag */
- unf_cm_xchg_mgr_abort_io_by_id(lport, unf_rport, unf_rport->nport_id, lport->nport_id, 0);
-
- /* 2. Abort sfp exchange before rport remove */
- unf_cm_xchg_mgr_abort_sfs_by_id(lport, unf_rport, unf_rport->nport_id, lport->nport_id);
-
- /* 3. Release R_Port resource: session reset/delete */
- if (likely(unf_rport->nport_id != UNF_FC_FID_FLOGI))
- (void)unf_release_rport_res(lport, unf_rport);
-
- nport_id = unf_rport->nport_id;
-
- /* 4.1 Delete R_Port from disc destroy/delete list */
- spin_lock_irqsave(&lport->disc.rport_busy_pool_lock, flag);
- list_del_init(&unf_rport->entry_rport);
- spin_unlock_irqrestore(&lport->disc.rport_busy_pool_lock, flag);
-
- rport_index = unf_rport->rport_index;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x) release RPort(0x%x_%p) with index(0x%x)",
- lport->port_id, unf_rport->nport_id, unf_rport,
- unf_rport->rport_index);
-
- unf_reset_rport_attribute(unf_rport);
-
- /* 4.2 Add rport to --->>> rport_pool (free pool) & clear bitmap */
- spin_lock_irqsave(&rport_pool->rport_free_pool_lock, flag);
- if (unlikely(nport_id == UNF_FC_FID_FLOGI)) {
- if (test_bit((int)rport_index, rport_pool->rpi_bitmap))
- clear_bit((int)rport_index, rport_pool->rpi_bitmap);
- }
-
- list_add_tail(&unf_rport->entry_rport, &rport_pool->list_rports_pool);
- rport_pool->rport_pool_count++;
- spin_unlock_irqrestore(&rport_pool->rport_free_pool_lock, flag);
-
- unf_check_rport_pool_status((struct unf_lport *)lport->root_lport);
- up(&unf_rport->task_sema);
-
- return RETURN_OK;
-}
-
-u32 unf_rport_ref_inc(struct unf_rport *rport)
-{
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- if (atomic_read(&rport->rport_ref_cnt) <= 0) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Rport(0x%x) reference count is wrong %d",
- rport->nport_id,
- atomic_read(&rport->rport_ref_cnt));
- return UNF_RETURN_ERROR;
- }
-
- atomic_inc(&rport->rport_ref_cnt);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Rport(0x%x) reference count is %d", rport->nport_id,
- atomic_read(&rport->rport_ref_cnt));
-
- return RETURN_OK;
-}
-
-void unf_rport_ref_dec(struct unf_rport *rport)
-{
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(rport);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Rport(0x%x) reference count is %d", rport->nport_id,
- atomic_read(&rport->rport_ref_cnt));
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- if (atomic_dec_and_test(&rport->rport_ref_cnt)) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- (void)unf_rport_remove(rport);
- } else {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- }
-}
-
-void unf_set_rport_state(struct unf_rport *rport,
- enum unf_rport_login_state states)
-{
- FC_CHECK_RETURN_VOID(rport);
-
- if (rport->rp_state != states) {
- /* Reset R_Port retry count */
- rport->retries = 0;
- }
-
- rport->rp_state = states;
-}
-
-static enum unf_rport_login_state
-unf_rport_stat_init(enum unf_rport_login_state old_state,
- enum unf_rport_event event)
-{
- enum unf_rport_login_state next_state = UNF_RPORT_ST_INIT;
-
- switch (event) {
- case UNF_EVENT_RPORT_LOGO:
- next_state = UNF_RPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_RPORT_ENTER_PLOGI:
- next_state = UNF_RPORT_ST_PLOGI_WAIT;
- break;
-
- case UNF_EVENT_RPORT_LINK_DOWN:
- next_state = UNF_RPORT_ST_CLOSING;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_rport_login_state unf_rport_stat_plogi_wait(enum unf_rport_login_state old_state,
- enum unf_rport_event event)
-{
- enum unf_rport_login_state next_state = UNF_RPORT_ST_INIT;
-
- switch (event) {
- case UNF_EVENT_RPORT_ENTER_PRLI:
- next_state = UNF_RPORT_ST_PRLI_WAIT;
- break;
-
- case UNF_EVENT_RPORT_LINK_DOWN:
- next_state = UNF_RPORT_ST_CLOSING;
- break;
-
- case UNF_EVENT_RPORT_LOGO:
- next_state = UNF_RPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_RPORT_RECOVERY:
- next_state = UNF_RPORT_ST_READY;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_rport_login_state unf_rport_stat_prli_wait(enum unf_rport_login_state old_state,
- enum unf_rport_event event)
-{
- enum unf_rport_login_state next_state = UNF_RPORT_ST_INIT;
-
- switch (event) {
- case UNF_EVENT_RPORT_READY:
- next_state = UNF_RPORT_ST_READY;
- break;
-
- case UNF_EVENT_RPORT_LOGO:
- next_state = UNF_RPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_RPORT_LINK_DOWN:
- next_state = UNF_RPORT_ST_CLOSING;
- break;
-
- case UNF_EVENT_RPORT_RECOVERY:
- next_state = UNF_RPORT_ST_READY;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_rport_login_state unf_rport_stat_ready(enum unf_rport_login_state old_state,
- enum unf_rport_event event)
-{
- enum unf_rport_login_state next_state = UNF_RPORT_ST_INIT;
-
- switch (event) {
- case UNF_EVENT_RPORT_LOGO:
- next_state = UNF_RPORT_ST_LOGO;
- break;
-
- case UNF_EVENT_RPORT_LINK_DOWN:
- next_state = UNF_RPORT_ST_CLOSING;
- break;
-
- case UNF_EVENT_RPORT_ENTER_PLOGI:
- next_state = UNF_RPORT_ST_PLOGI_WAIT;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_rport_login_state unf_rport_stat_closing(enum unf_rport_login_state old_state,
- enum unf_rport_event event)
-{
- enum unf_rport_login_state next_state = UNF_RPORT_ST_INIT;
-
- switch (event) {
- case UNF_EVENT_RPORT_CLS_TIMEOUT:
- next_state = UNF_RPORT_ST_DELETE;
- break;
-
- case UNF_EVENT_RPORT_RELOGIN:
- next_state = UNF_RPORT_ST_INIT;
- break;
-
- case UNF_EVENT_RPORT_RECOVERY:
- next_state = UNF_RPORT_ST_READY;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-static enum unf_rport_login_state unf_rport_stat_logo(enum unf_rport_login_state old_state,
- enum unf_rport_event event)
-{
- enum unf_rport_login_state next_state = UNF_RPORT_ST_INIT;
-
- switch (event) {
- case UNF_EVENT_RPORT_NORMAL_ENTER:
- next_state = UNF_RPORT_ST_CLOSING;
- break;
-
- case UNF_EVENT_RPORT_RECOVERY:
- next_state = UNF_RPORT_ST_READY;
- break;
-
- default:
- next_state = old_state;
- break;
- }
-
- return next_state;
-}
-
-void unf_rport_state_ma(struct unf_rport *rport, enum unf_rport_event event)
-{
- enum unf_rport_login_state old_state = UNF_RPORT_ST_INIT;
- enum unf_rport_login_state next_state = UNF_RPORT_ST_INIT;
-
- FC_CHECK_RETURN_VOID(rport);
-
- old_state = rport->rp_state;
-
- switch (rport->rp_state) {
- case UNF_RPORT_ST_INIT:
- next_state = unf_rport_stat_init(old_state, event);
- break;
- case UNF_RPORT_ST_PLOGI_WAIT:
- next_state = unf_rport_stat_plogi_wait(old_state, event);
- break;
- case UNF_RPORT_ST_PRLI_WAIT:
- next_state = unf_rport_stat_prli_wait(old_state, event);
- break;
- case UNF_RPORT_ST_LOGO:
- next_state = unf_rport_stat_logo(old_state, event);
- break;
- case UNF_RPORT_ST_CLOSING:
- next_state = unf_rport_stat_closing(old_state, event);
- break;
- case UNF_RPORT_ST_READY:
- next_state = unf_rport_stat_ready(old_state, event);
- break;
- case UNF_RPORT_ST_DELETE:
- default:
- next_state = UNF_RPORT_ST_INIT;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR, "[info]RPort(0x%x) hold state(0x%x)",
- rport->nport_id, rport->rp_state);
- break;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MINOR,
- "[info]RPort(0x%x) with oldstate(0x%x) event(0x%x) nextstate(0x%x)",
- rport->nport_id, old_state, event, next_state);
-
- unf_set_rport_state(rport, next_state);
-}
-
-void unf_clean_linkdown_rport(struct unf_lport *lport)
-{
- /* for L_Port's R_Port(s) */
- struct unf_disc *disc = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct unf_rport *rport = NULL;
- struct unf_lport *unf_lport = NULL;
- ulong disc_lock_flag = 0;
- ulong rport_lock_flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- disc = &lport->disc;
-
- /* for each busy R_Port */
- spin_lock_irqsave(&disc->rport_busy_pool_lock, disc_lock_flag);
- list_for_each_safe(node, next_node, &disc->list_busy_rports) {
- rport = list_entry(node, struct unf_rport, entry_rport);
-
- /* 1. Prevent process Repeatly: Closing */
- spin_lock_irqsave(&rport->rport_state_lock, rport_lock_flag);
- if (rport->rp_state == UNF_RPORT_ST_CLOSING) {
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_lock_flag);
- continue;
- }
-
- /* 2. Increase ref_cnt to protect R_Port */
- if (unf_rport_ref_inc(rport) != RETURN_OK) {
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_lock_flag);
- continue;
- }
-
- /* 3. Update R_Port state: Link Down Event --->>> closing state
- */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LINK_DOWN);
-
- /* 4. Put R_Port from busy to destroy list */
- list_del_init(&rport->entry_rport);
- list_add_tail(&rport->entry_rport, &disc->list_destroy_rports);
-
- unf_lport = rport->lport;
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_lock_flag);
-
- /* 5. Schedule Closing work (Enqueuing workqueue) */
- unf_schedule_closing_work(unf_lport, rport);
-
- /* 6. decrease R_Port ref_cnt (company with 2) */
- unf_rport_ref_dec(rport);
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, disc_lock_flag);
-}
-
-void unf_rport_enter_closing(struct unf_rport *rport)
-{
- /*
- * call by
- * 1. with RSCN processer
- * 2. with LOGOUT processer
- * *
- * from
- * 1. R_Port Link Down
- * 2. R_Port enter LOGO
- */
- ulong rport_lock_flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_lport *lport = NULL;
- struct unf_disc *disc = NULL;
-
- FC_CHECK_RETURN_VOID(rport);
-
- /* 1. Increase ref_cnt to protect R_Port */
- spin_lock_irqsave(&rport->rport_state_lock, rport_lock_flag);
- ret = unf_rport_ref_inc(rport);
- if (ret != RETURN_OK) {
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_lock_flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]RPort(0x%x_0x%p) is removing and no need process",
- rport->nport_id, rport);
-
- return;
- }
-
- /* NOTE: R_Port state has been set(with closing) */
-
- lport = rport->lport;
- spin_unlock_irqrestore(&rport->rport_state_lock, rport_lock_flag);
-
- /* 2. Put R_Port from busy to destroy list */
- disc = &lport->disc;
- spin_lock_irqsave(&disc->rport_busy_pool_lock, rport_lock_flag);
- list_del_init(&rport->entry_rport);
- list_add_tail(&rport->entry_rport, &disc->list_destroy_rports);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, rport_lock_flag);
-
- /* 3. Schedule Closing work (Enqueuing workqueue) */
- unf_schedule_closing_work(lport, rport);
-
- /* 4. dec R_Port ref_cnt */
- unf_rport_ref_dec(rport);
-}
-
-void unf_rport_error_recovery(struct unf_rport *rport)
-{
- ulong delay = 0;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
-
- ret = unf_rport_ref_inc(rport);
- if (ret != RETURN_OK) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]RPort(0x%x_0x%p) is removing and no need process",
- rport->nport_id, rport);
- return;
- }
-
- /* Check R_Port state */
- if (rport->rp_state == UNF_RPORT_ST_CLOSING ||
- rport->rp_state == UNF_RPORT_ST_DELETE) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]RPort(0x%x_0x%p) offline and no need process",
- rport->nport_id, rport);
-
- unf_rport_ref_dec(rport);
- return;
- }
-
- /* Check repeatability with recovery work */
- if (delayed_work_pending(&rport->recovery_work)) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]RPort(0x%x_0x%p) recovery work is running and no need process",
- rport->nport_id, rport);
-
- unf_rport_ref_dec(rport);
- return;
- }
-
- /* NOTE: Re-login or Logout directly (recovery work) */
- if (rport->retries < rport->max_retries) {
- rport->retries++;
- delay = UNF_DEFAULT_EDTOV / 4;
-
- if (queue_delayed_work(unf_wq, &rport->recovery_work,
- (ulong)msecs_to_jiffies((u32)delay))) {
- /* Inc ref_cnt: corresponding to this work timer */
- (void)unf_rport_ref_inc(rport);
- }
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]RPort(0x%x_0x%p) state(0x%x) retry login failed",
- rport->nport_id, rport, rport->rp_state);
-
- /* Update R_Port state: LOGO event --->>> ST_LOGO */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LOGO);
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- unf_rport_enter_logo(rport->lport, rport);
- }
-
- unf_rport_ref_dec(rport);
-}
-
-static u32 unf_rport_reuse_only(struct unf_rport *rport)
-{
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- ret = unf_rport_ref_inc(rport);
- if (ret != RETURN_OK) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* R_Port with delete state */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]RPort(0x%x_0x%p) is removing and no need process",
- rport->nport_id, rport);
-
- return UNF_RETURN_ERROR;
- }
-
- /* R_Port State check: delete */
- if (rport->rp_state == UNF_RPORT_ST_DELETE ||
- rport->rp_state == UNF_RPORT_ST_CLOSING) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]RPort(0x%x_0x%p) state(0x%x) is delete or closing no need process",
- rport->nport_id, rport, rport->rp_state);
-
- ret = UNF_RETURN_ERROR;
- }
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- unf_rport_ref_dec(rport);
-
- return ret;
-}
-
-static u32 unf_rport_reuse_recover(struct unf_rport *rport)
-{
- ulong flags = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&rport->rport_state_lock, flags);
- ret = unf_rport_ref_inc(rport);
- if (ret != RETURN_OK) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- /* R_Port with delete state */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]RPort(0x%x_0x%p) is removing and no need process",
- rport->nport_id, rport);
-
- return UNF_RETURN_ERROR;
- }
-
- /* R_Port state check: delete */
- if (rport->rp_state == UNF_RPORT_ST_DELETE ||
- rport->rp_state == UNF_RPORT_ST_CLOSING) {
- ret = UNF_RETURN_ERROR;
- }
-
- /* Update R_Port state: recovery --->>> ready */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_RECOVERY);
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- unf_rport_ref_dec(rport);
-
- return ret;
-}
-
-static u32 unf_rport_reuse_init(struct unf_rport *rport)
-{
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&rport->rport_state_lock, flag);
- ret = unf_rport_ref_inc(rport);
- if (ret != RETURN_OK) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- /* R_Port with delete state */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]RPort(0x%x_0x%p) is removing and no need process",
- rport->nport_id, rport);
-
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]RPort(0x%x)'s state is 0x%x with use_init flag",
- rport->nport_id, rport->rp_state);
-
- /* R_Port State check: delete */
- if (rport->rp_state == UNF_RPORT_ST_DELETE ||
- rport->rp_state == UNF_RPORT_ST_CLOSING) {
- ret = UNF_RETURN_ERROR;
- } else {
- /* Update R_Port state: re-enter Init state */
- unf_set_rport_state(rport, UNF_RPORT_ST_INIT);
- }
- spin_unlock_irqrestore(&rport->rport_state_lock, flag);
-
- unf_rport_ref_dec(rport);
-
- return ret;
-}
-
-struct unf_rport *unf_get_rport_by_nport_id(struct unf_lport *lport,
- u32 nport_id)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_rport *rport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- struct unf_rport *find_rport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- unf_lport = (struct unf_lport *)lport;
- disc = &unf_lport->disc;
-
- /* for each r_port from rport_busy_list: compare N_Port_ID */
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- list_for_each_safe(node, next_node, &disc->list_busy_rports) {
- rport = list_entry(node, struct unf_rport, entry_rport);
- if (rport && rport->nport_id == nport_id) {
- find_rport = rport;
- break;
- }
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- return find_rport;
-}
-
-struct unf_rport *unf_get_rport_by_wwn(struct unf_lport *lport, u64 wwpn)
-{
- struct unf_lport *unf_lport = NULL;
- struct unf_disc *disc = NULL;
- struct unf_rport *rport = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flag = 0;
- struct unf_rport *find_rport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- unf_lport = (struct unf_lport *)lport;
- disc = &unf_lport->disc;
-
- /* for each r_port from busy_list: compare wwpn(port name) */
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flag);
- list_for_each_safe(node, next_node, &disc->list_busy_rports) {
- rport = list_entry(node, struct unf_rport, entry_rport);
- if (rport && rport->port_name == wwpn) {
- find_rport = rport;
- break;
- }
- }
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flag);
-
- return find_rport;
-}
-
-struct unf_rport *unf_get_safe_rport(struct unf_lport *lport,
- struct unf_rport *rport,
- enum unf_rport_reuse_flag reuse_flag,
- u32 nport_id)
-{
- /*
- * New add or plug
- * *
- * retry_flogi --->>> reuse_only
- * name_server_register --->>> reuse_only
- * SNS_plogi --->>> reuse_only
- * enter_flogi --->>> reuse_only
- * logout --->>> reuse_only
- * flogi_handler --->>> reuse_only
- * plogi_handler --->>> reuse_only
- * adisc_handler --->>> reuse_recovery
- * logout_handler --->>> reuse_init
- * prlo_handler --->>> reuse_init
- * login_with_loop --->>> reuse_only
- * gffid_callback --->>> reuse_only
- * delay_plogi --->>> reuse_only
- * gffid_rjt --->>> reuse_only
- * gffid_rsp_unknown --->>> reuse_only
- * gpnid_acc --->>> reuse_init
- * fdisc_callback --->>> reuse_only
- * flogi_acc --->>> reuse_only
- * plogi_acc --->>> reuse_only
- * logo_callback --->>> reuse_init
- * rffid_callback --->>> reuse_only
- */
-#define UNF_AVOID_LINK_FLASH_TIME 3000
-
- struct unf_rport *unf_rport = rport;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- /* 1. Alloc New R_Port or Update R_Port Property */
- if (!unf_rport) {
- /* If NULL, get/Alloc new node (R_Port from R_Port pool)
- * directly
- */
- unf_rport = unf_rport_get_free_and_init(lport, UNF_PORT_TYPE_FC, nport_id);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_INFO,
- "[info]Port(0x%x) get exist RPort(0x%x) with state(0x%x) and reuse_flag(0x%x)",
- lport->port_id, unf_rport->nport_id,
- unf_rport->rp_state, reuse_flag);
-
- switch (reuse_flag) {
- case UNF_RPORT_REUSE_ONLY:
- ret = unf_rport_reuse_only(unf_rport);
- if (ret != RETURN_OK) {
- /* R_Port within delete list: need get new */
- unf_rport = unf_rport_get_free_and_init(lport, UNF_PORT_TYPE_FC,
- nport_id);
- }
- break;
-
- case UNF_RPORT_REUSE_INIT:
- ret = unf_rport_reuse_init(unf_rport);
- if (ret != RETURN_OK) {
- /* R_Port within delete list: need get new */
- unf_rport = unf_rport_get_free_and_init(lport, UNF_PORT_TYPE_FC,
- nport_id);
- }
- break;
-
- case UNF_RPORT_REUSE_RECOVER:
- ret = unf_rport_reuse_recover(unf_rport);
- if (ret != RETURN_OK) {
- /* R_Port within delete list,
- * NOTE: do nothing
- */
- unf_rport = NULL;
- }
- break;
-
- default:
- break;
- }
- } // end else: R_Port != NULL
-
- return unf_rport;
-}
-
-u32 unf_get_port_feature(u64 wwpn)
-{
- struct unf_rport_feature_recard *port_fea = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- ulong flags = 0;
- struct list_head list_temp_node;
- struct list_head *list_busy_head = NULL;
- struct list_head *list_free_head = NULL;
- spinlock_t *feature_lock = NULL;
-
- list_busy_head = &port_feature_pool->list_busy_head;
- list_free_head = &port_feature_pool->list_free_head;
- feature_lock = &port_feature_pool->port_fea_pool_lock;
- spin_lock_irqsave(feature_lock, flags);
- list_for_each_safe(node, next_node, list_busy_head) {
- port_fea = list_entry(node, struct unf_rport_feature_recard, entry_feature);
-
- if (port_fea->wwpn == wwpn) {
- list_del(&port_fea->entry_feature);
- list_add(&port_fea->entry_feature, list_busy_head);
- spin_unlock_irqrestore(feature_lock, flags);
-
- return port_fea->port_feature;
- }
- }
-
- list_for_each_safe(node, next_node, list_free_head) {
- port_fea = list_entry(node, struct unf_rport_feature_recard, entry_feature);
-
- if (port_fea->wwpn == wwpn) {
- list_del(&port_fea->entry_feature);
- list_add(&port_fea->entry_feature, list_busy_head);
- spin_unlock_irqrestore(feature_lock, flags);
-
- return port_fea->port_feature;
- }
- }
-
- /* can't find wwpn */
- if (list_empty(list_free_head)) {
- /* free is empty, transport busy to free */
- list_temp_node = port_feature_pool->list_free_head;
- port_feature_pool->list_free_head = port_feature_pool->list_busy_head;
- port_feature_pool->list_busy_head = list_temp_node;
- }
-
- port_fea = list_entry(UNF_OS_LIST_PREV(list_free_head),
- struct unf_rport_feature_recard,
- entry_feature);
- list_del(&port_fea->entry_feature);
- list_add(&port_fea->entry_feature, list_busy_head);
-
- port_fea->wwpn = wwpn;
- port_fea->port_feature = UNF_PORT_MODE_UNKNOWN;
-
- spin_unlock_irqrestore(feature_lock, flags);
- return UNF_PORT_MODE_UNKNOWN;
-}
-
-void unf_update_port_feature(u64 wwpn, u32 port_feature)
-{
- struct unf_rport_feature_recard *port_fea = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct list_head *busy_head = NULL;
- struct list_head *free_head = NULL;
- ulong flags = 0;
- spinlock_t *feature_lock = NULL;
-
- feature_lock = &port_feature_pool->port_fea_pool_lock;
- busy_head = &port_feature_pool->list_busy_head;
- free_head = &port_feature_pool->list_free_head;
-
- spin_lock_irqsave(feature_lock, flags);
- list_for_each_safe(node, next_node, busy_head) {
- port_fea = list_entry(node, struct unf_rport_feature_recard, entry_feature);
-
- if (port_fea->wwpn == wwpn) {
- port_fea->port_feature = port_feature;
- list_del(&port_fea->entry_feature);
- list_add(&port_fea->entry_feature, busy_head);
- spin_unlock_irqrestore(feature_lock, flags);
-
- return;
- }
- }
-
- list_for_each_safe(node, next_node, free_head) {
- port_fea = list_entry(node, struct unf_rport_feature_recard, entry_feature);
-
- if (port_fea->wwpn == wwpn) {
- port_fea->port_feature = port_feature;
- list_del(&port_fea->entry_feature);
- list_add(&port_fea->entry_feature, busy_head);
-
- spin_unlock_irqrestore(feature_lock, flags);
-
- return;
- }
- }
-
- spin_unlock_irqrestore(feature_lock, flags);
-}
diff --git a/drivers/scsi/spfc/common/unf_rport.h b/drivers/scsi/spfc/common/unf_rport.h
deleted file mode 100644
index a9d58cb29b8a..000000000000
--- a/drivers/scsi/spfc/common/unf_rport.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_RPORT_H
-#define UNF_RPORT_H
-
-#include "unf_type.h"
-#include "unf_common.h"
-#include "unf_lport.h"
-
-extern struct unf_rport_feature_pool *port_feature_pool;
-
-#define UNF_MAX_SCSI_ID 2048
-#define UNF_LOSE_TMO 30
-#define UNF_RPORT_INVALID_INDEX 0xffff
-
-/* RSCN compare DISC list with local RPort macro */
-#define UNF_RPORT_NEED_PROCESS 0x1
-#define UNF_RPORT_ONLY_IN_DISC_PROCESS 0x2
-#define UNF_RPORT_ONLY_IN_LOCAL_PROCESS 0x3
-#define UNF_RPORT_IN_DISC_AND_LOCAL_PROCESS 0x4
-#define UNF_RPORT_NOT_NEED_PROCESS 0x5
-
-#define UNF_ECHO_SEND_MAX_TIMES 1
-
-/* csctrl level value */
-#define UNF_CSCTRL_LOW 0x81
-#define UNF_CSCTRL_MIDDLE 0x82
-#define UNF_CSCTRL_HIGH 0x83
-#define UNF_CSCTRL_INVALID 0x0
-
-enum unf_rport_login_state {
- UNF_RPORT_ST_INIT = 0x1000, /* initialized */
- UNF_RPORT_ST_PLOGI_WAIT, /* waiting for PLOGI completion */
- UNF_RPORT_ST_PRLI_WAIT, /* waiting for PRLI completion */
- UNF_RPORT_ST_READY, /* ready for use */
- UNF_RPORT_ST_LOGO, /* port logout sent */
- UNF_RPORT_ST_CLOSING, /* being closed */
- UNF_RPORT_ST_DELETE, /* port being deleted */
- UNF_RPORT_ST_BUTT
-};
-
-enum unf_rport_event {
- UNF_EVENT_RPORT_NORMAL_ENTER = 0x9000,
- UNF_EVENT_RPORT_ENTER_PLOGI = 0x9001,
- UNF_EVENT_RPORT_ENTER_PRLI = 0x9002,
- UNF_EVENT_RPORT_READY = 0x9003,
- UNF_EVENT_RPORT_LOGO = 0x9004,
- UNF_EVENT_RPORT_CLS_TIMEOUT = 0x9005,
- UNF_EVENT_RPORT_RECOVERY = 0x9006,
- UNF_EVENT_RPORT_RELOGIN = 0x9007,
- UNF_EVENT_RPORT_LINK_DOWN = 0x9008,
- UNF_EVENT_RPORT_BUTT
-};
-
-/* RPort local link state */
-enum unf_port_state {
- UNF_PORT_STATE_LINKUP = 0x1001,
- UNF_PORT_STATE_LINKDOWN = 0x1002
-};
-
-enum unf_rport_reuse_flag {
- UNF_RPORT_REUSE_ONLY = 0x1001,
- UNF_RPORT_REUSE_INIT = 0x1002,
- UNF_RPORT_REUSE_RECOVER = 0x1003
-};
-
-struct unf_disc_rport {
- /* RPort entry */
- struct list_head entry_rport;
-
- u32 nport_id; /* Remote port NPortID */
- u32 disc_done; /* 1:Disc done */
-};
-
-struct unf_rport_feature_pool {
- struct list_head list_busy_head;
- struct list_head list_free_head;
- void *port_feature_pool_addr;
- spinlock_t port_fea_pool_lock;
-};
-
-struct unf_rport_feature_recard {
- struct list_head entry_feature;
- u64 wwpn;
- u32 port_feature;
- u32 reserved;
-};
-
-struct unf_os_thread_private_data {
- struct list_head list;
- spinlock_t spin_lock;
- struct task_struct *thread;
- unsigned int in_process;
- unsigned int cpu_id;
- atomic_t user_count;
-};
-
-/* Remote Port struct */
-struct unf_rport {
- u32 max_frame_size;
- u32 supported_classes;
-
- /* Dynamic Attributes */
- /* Remote Port loss timeout in seconds. */
- u32 dev_loss_tmo;
-
- u64 node_name;
- u64 port_name;
- u32 nport_id; /* Remote port NPortID */
- u32 local_nport_id;
-
- u32 roles;
-
- /* Remote port local INI state */
- enum unf_port_state lport_ini_state;
- enum unf_port_state last_lport_ini_state;
-
- /* Remote port local TGT state */
- enum unf_port_state lport_tgt_state;
- enum unf_port_state last_lport_tgt_state;
-
- /* Port Type,fc or fcoe */
- u32 port_type;
-
- /* RPort reference counter */
- atomic_t rport_ref_cnt;
-
- /* Pending IO count */
- atomic_t pending_io_cnt;
-
- /* RPort entry */
- struct list_head entry_rport;
-
- /* Port State,delay reclaim when uiRpState == complete. */
- enum unf_rport_login_state rp_state;
- u32 disc_done; /* 1:Disc done */
-
- struct unf_lport *lport;
- void *rport;
- spinlock_t rport_state_lock;
-
- /* Port attribution */
- u32 ed_tov;
- u32 ra_tov;
- u32 options; /* ini or tgt */
- u32 last_report_link_up_options;
- u32 fcp_conf_needed; /* INI Rport send FCP CONF flag */
- u32 tape_support_needed; /* INI tape support flag */
- u32 retries; /* special req retry times */
- u32 logo_retries; /* logo error recovery retry times */
- u32 max_retries; /* special req retry times */
- u64 rport_alloc_jifs; /* Rport alloc jiffies */
-
- void *session;
-
- /* binding with SCSI */
- u32 scsi_id;
-
- /* disc list compare flag */
- u32 rscn_position;
-
- u32 rport_index;
-
- u32 sqn_base;
- enum unf_rport_qos_level qos_level;
-
- /* RPort timer,closing status */
- struct work_struct closing_work;
-
- /* RPort timer,rport linkup */
- struct work_struct start_work;
-
- /* RPort timer,recovery */
- struct delayed_work recovery_work;
-
- /* RPort timer,TGT mode,PRLI waiting */
- struct delayed_work open_work;
-
- struct semaphore task_sema;
- /* Callback after rport Ready/delete.[with state:ok/fail].Creat/free TGT session here */
- /* input : L_Port,R_Port,state:ready --creat session/delete--free session */
- void (*unf_rport_callback)(void *rport, void *lport, u32 result);
-
- struct unf_os_thread_private_data *data_thread;
-};
-
-#define UNF_IO_RESULT_CNT(scsi_table, scsi_id, io_result) \
- do { \
- if (likely(((io_result) < UNF_MAX_IO_RETURN_VALUE) && \
- ((scsi_id) < UNF_MAX_SCSI_ID) && \
- ((scsi_table)->wwn_rport_info_table) && \
- (((scsi_table)->wwn_rport_info_table[scsi_id].dfx_counter)))) {\
- atomic64_inc(&((scsi_table)->wwn_rport_info_table[scsi_id] \
- .dfx_counter->io_done_cnt[(io_result)])); \
- } else { \
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, \
- UNF_ERR, \
- "[err] io return value(0x%x) or " \
- "scsi id(0x%x) is invalid", \
- io_result, scsi_id); \
- } \
- } while (0)
-
-#define UNF_SCSI_CMD_CNT(scsi_table, scsi_id, io_type) \
- do { \
- if (likely(((io_type) < UNF_MAX_SCSI_CMD) && \
- ((scsi_id) < UNF_MAX_SCSI_ID) && \
- ((scsi_table)->wwn_rport_info_table) && \
- (((scsi_table)->wwn_rport_info_table[scsi_id].dfx_counter)))) { \
- atomic64_inc(&(((scsi_table)->wwn_rport_info_table[scsi_id]) \
- .dfx_counter->scsi_cmd_cnt[io_type])); \
- } else { \
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, \
- UNF_ERR, \
- "[err] scsi_cmd(0x%x) or scsi id(0x%x) " \
- "is invalid", \
- io_type, scsi_id); \
- } \
- } while (0)
-
-#define UNF_SCSI_ERROR_HANDLE_CNT(scsi_table, scsi_id, io_type) \
- do { \
- if (likely(((io_type) < UNF_SCSI_ERROR_HANDLE_BUTT) && \
- ((scsi_id) < UNF_MAX_SCSI_ID) && \
- ((scsi_table)->wwn_rport_info_table) && \
- (((scsi_table)->wwn_rport_info_table[scsi_id] \
- .dfx_counter)))) { \
- atomic_inc(&((scsi_table)->wwn_rport_info_table[scsi_id] \
- .dfx_counter->error_handle[io_type])); \
- } else { \
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, \
- UNF_ERR, \
- "[err] scsi_cmd(0x%x) or scsi id(0x%x) " \
- "is invalid", \
- (io_type), (scsi_id)); \
- } \
- } while (0)
-
-#define UNF_SCSI_ERROR_HANDLE_RESULT_CNT(scsi_table, scsi_id, io_type) \
- do { \
- if (likely(((io_type) < UNF_SCSI_ERROR_HANDLE_BUTT) && \
- ((scsi_id) < UNF_MAX_SCSI_ID) && \
- ((scsi_table)->wwn_rport_info_table) &&\
- (((scsi_table)-> \
- wwn_rport_info_table[scsi_id].dfx_counter)))) { \
- atomic_inc(&( \
- (scsi_table) \
- ->wwn_rport_info_table[scsi_id] \
- .dfx_counter->error_handle_result[io_type])); \
- } else { \
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, \
- UNF_ERR, \
- "[err] scsi_cmd(0x%x) or scsi id(0x%x) " \
- "is invalid", \
- io_type, scsi_id); \
- } \
- } while (0)
-
-void unf_rport_state_ma(struct unf_rport *rport, enum unf_rport_event event);
-void unf_update_lport_state_by_linkup_event(struct unf_lport *lport,
- struct unf_rport *rport,
- u32 rport_att);
-
-void unf_set_rport_state(struct unf_rport *rport, enum unf_rport_login_state states);
-void unf_rport_enter_closing(struct unf_rport *rport);
-u32 unf_release_rport_res(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_initrport_mgr_temp(struct unf_lport *lport);
-void unf_clean_linkdown_rport(struct unf_lport *lport);
-void unf_rport_error_recovery(struct unf_rport *rport);
-struct unf_rport *unf_get_rport_by_nport_id(struct unf_lport *lport, u32 nport_id);
-struct unf_rport *unf_get_rport_by_wwn(struct unf_lport *lport, u64 wwpn);
-void unf_rport_enter_logo(struct unf_lport *lport, struct unf_rport *rport);
-u32 unf_rport_ref_inc(struct unf_rport *rport);
-void unf_rport_ref_dec(struct unf_rport *rport);
-
-struct unf_rport *unf_rport_set_qualifier_key_reuse(struct unf_lport *lport,
- struct unf_rport *rport_by_nport_id,
- struct unf_rport *rport_by_wwpn,
- u64 wwpn, u32 sid);
-void unf_rport_delay_login(struct unf_rport *rport);
-struct unf_rport *unf_find_valid_rport(struct unf_lport *lport, u64 wwpn,
- u32 sid);
-void unf_rport_linkdown(struct unf_lport *lport, struct unf_rport *rport);
-void unf_apply_for_session(struct unf_lport *lport, struct unf_rport *rport);
-struct unf_rport *unf_get_safe_rport(struct unf_lport *lport,
- struct unf_rport *rport,
- enum unf_rport_reuse_flag reuse_flag,
- u32 nport_id);
-void *unf_rport_get_free_and_init(void *lport, u32 port_type, u32 nport_id);
-
-void unf_set_device_state(struct unf_lport *lport, u32 scsi_id, int scsi_state);
-u32 unf_get_scsi_id_by_wwpn(struct unf_lport *lport, u64 wwpn);
-u32 unf_get_device_state(struct unf_lport *lport, u32 scsi_id);
-u32 unf_free_scsi_id(struct unf_lport *lport, u32 scsi_id);
-void unf_schedule_closing_work(struct unf_lport *lport, struct unf_rport *rport);
-void unf_sesion_loss_timeout(struct work_struct *work);
-u32 unf_get_port_feature(u64 wwpn);
-void unf_update_port_feature(u64 wwpn, u32 port_feature);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_scsi.c b/drivers/scsi/spfc/common/unf_scsi.c
deleted file mode 100644
index 3615d95c77e9..000000000000
--- a/drivers/scsi/spfc/common/unf_scsi.c
+++ /dev/null
@@ -1,1462 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_type.h"
-#include "unf_log.h"
-#include "unf_scsi_common.h"
-#include "unf_lport.h"
-#include "unf_rport.h"
-#include "unf_portman.h"
-#include "unf_exchg.h"
-#include "unf_exchg_abort.h"
-#include "unf_npiv.h"
-#include "unf_io.h"
-
-#define UNF_LUN_ID_MASK 0x00000000ffff0000
-#define UNF_CMD_PER_LUN 3
-
-static int unf_scsi_queue_cmd(struct Scsi_Host *phost, struct scsi_cmnd *pcmd);
-static int unf_scsi_abort_scsi_cmnd(struct scsi_cmnd *v_cmnd);
-static int unf_scsi_device_reset_handler(struct scsi_cmnd *v_cmnd);
-static int unf_scsi_bus_reset_handler(struct scsi_cmnd *v_cmnd);
-static int unf_scsi_target_reset_handler(struct scsi_cmnd *v_cmnd);
-static int unf_scsi_slave_alloc(struct scsi_device *sdev);
-static void unf_scsi_destroy_slave(struct scsi_device *sdev);
-static int unf_scsi_slave_configure(struct scsi_device *sdev);
-static int unf_scsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
-static void unf_scsi_scan_start(struct Scsi_Host *shost);
-
-static struct scsi_transport_template *scsi_transport_template;
-static struct scsi_transport_template *scsi_transport_template_v;
-
-struct unf_ini_error_code ini_error_code_table1[] = {
- {UNF_IO_SUCCESS, UNF_SCSI_HOST(DID_OK)},
- {UNF_IO_ABORTED, UNF_SCSI_HOST(DID_ABORT)},
- {UNF_IO_FAILED, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_ABORT_ABTS, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_ABORT_LOGIN, UNF_SCSI_HOST(DID_NO_CONNECT)},
- {UNF_IO_ABORT_REET, UNF_SCSI_HOST(DID_RESET)},
- {UNF_IO_ABORT_FAILED, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_OUTOF_ORDER, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_FTO, UNF_SCSI_HOST(DID_TIME_OUT)},
- {UNF_IO_LINK_FAILURE, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_OVER_FLOW, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_RSP_OVER, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_LOST_FRAME, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_UNDER_FLOW, UNF_SCSI_HOST(DID_OK)},
- {UNF_IO_HOST_PROG_ERROR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_SEST_PROG_ERROR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_INVALID_ENTRY, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_ABORT_SEQ_NOT, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_REJECT, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_EDC_IN_ERROR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_EDC_OUT_ERROR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_UNINIT_KEK_ERR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_DEK_OUTOF_RANGE, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_KEY_UNWRAP_ERR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_KEY_TAG_ERR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_KEY_ECC_ERR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_BLOCK_SIZE_ERROR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_ILLEGAL_CIPHER_MODE, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_CLEAN_UP, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_ABORTED_BY_TARGET, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_TRANSPORT_ERROR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_LINK_FLASH, UNF_SCSI_HOST(DID_NO_CONNECT)},
- {UNF_IO_TIMEOUT, UNF_SCSI_HOST(DID_TIME_OUT)},
- {UNF_IO_DMA_ERROR, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_NO_LPORT, UNF_SCSI_HOST(DID_NO_CONNECT)},
- {UNF_IO_NO_XCHG, UNF_SCSI_HOST(DID_SOFT_ERROR)},
- {UNF_IO_SOFT_ERR, UNF_SCSI_HOST(DID_SOFT_ERROR)},
- {UNF_IO_PORT_LOGOUT, UNF_SCSI_HOST(DID_NO_CONNECT)},
- {UNF_IO_ERREND, UNF_SCSI_HOST(DID_ERROR)},
- {UNF_IO_DIF_ERROR, (UNF_SCSI_HOST(DID_OK) | UNF_SCSI_STATUS(SCSI_CHECK_CONDITION))},
- {UNF_IO_INCOMPLETE, UNF_SCSI_HOST(DID_IMM_RETRY)},
- {UNF_IO_DIF_REF_ERROR, (UNF_SCSI_HOST(DID_OK) | UNF_SCSI_STATUS(SCSI_CHECK_CONDITION))},
- {UNF_IO_DIF_GEN_ERROR, (UNF_SCSI_HOST(DID_OK) | UNF_SCSI_STATUS(SCSI_CHECK_CONDITION))}
-};
-
-u32 ini_err_code_table_cnt1 = sizeof(ini_error_code_table1) / sizeof(struct unf_ini_error_code);
-
-static void unf_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
-{
- if (timeout)
- rport->dev_loss_tmo = timeout;
- else
- rport->dev_loss_tmo = 1;
-}
-
-static void unf_get_host_port_id(struct Scsi_Host *shost)
-{
- struct unf_lport *unf_lport = NULL;
-
- unf_lport = (struct unf_lport *)shost->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Port is null");
- return;
- }
-
- fc_host_port_id(shost) = unf_lport->port_id;
-}
-
-static void unf_get_host_speed(struct Scsi_Host *shost)
-{
- struct unf_lport *unf_lport = NULL;
- u32 speed = FC_PORTSPEED_UNKNOWN;
-
- unf_lport = (struct unf_lport *)shost->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Port is null");
- return;
- }
-
- switch (unf_lport->speed) {
- case UNF_PORT_SPEED_2_G:
- speed = FC_PORTSPEED_2GBIT;
- break;
- case UNF_PORT_SPEED_4_G:
- speed = FC_PORTSPEED_4GBIT;
- break;
- case UNF_PORT_SPEED_8_G:
- speed = FC_PORTSPEED_8GBIT;
- break;
- case UNF_PORT_SPEED_16_G:
- speed = FC_PORTSPEED_16GBIT;
- break;
- case UNF_PORT_SPEED_32_G:
- speed = FC_PORTSPEED_32GBIT;
- break;
- default:
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) with unknown speed(0x%x) for FC mode",
- unf_lport->port_id, unf_lport->speed);
- break;
- }
-
- fc_host_speed(shost) = speed;
-}
-
-static void unf_get_host_port_type(struct Scsi_Host *shost)
-{
- struct unf_lport *unf_lport = NULL;
- u32 port_type = FC_PORTTYPE_UNKNOWN;
-
- unf_lport = (struct unf_lport *)shost->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Port is null");
- return;
- }
-
- switch (unf_lport->act_topo) {
- case UNF_ACT_TOP_PRIVATE_LOOP:
- port_type = FC_PORTTYPE_LPORT;
- break;
- case UNF_ACT_TOP_PUBLIC_LOOP:
- port_type = FC_PORTTYPE_NLPORT;
- break;
- case UNF_ACT_TOP_P2P_DIRECT:
- port_type = FC_PORTTYPE_PTP;
- break;
- case UNF_ACT_TOP_P2P_FABRIC:
- port_type = FC_PORTTYPE_NPORT;
- break;
- default:
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) with unknown topo type(0x%x) for FC mode",
- unf_lport->port_id, unf_lport->act_topo);
- break;
- }
-
- fc_host_port_type(shost) = port_type;
-}
-
-static void unf_get_symbolic_name(struct Scsi_Host *shost)
-{
- u8 *name = NULL;
- struct unf_lport *unf_lport = NULL;
-
- unf_lport = (struct unf_lport *)(uintptr_t)shost->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Check l_port failed");
- return;
- }
-
- name = fc_host_symbolic_name(shost);
- if (name)
- snprintf(name, FC_SYMBOLIC_NAME_SIZE, "SPFC_FW_RELEASE:%s SPFC_DRV_RELEASE:%s",
- unf_lport->fw_version, SPFC_DRV_VERSION);
-}
-
-static void unf_get_host_fabric_name(struct Scsi_Host *shost)
-{
- struct unf_lport *unf_lport = NULL;
-
- unf_lport = (struct unf_lport *)shost->hostdata[0];
-
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Port is null");
- return;
- }
- fc_host_fabric_name(shost) = unf_lport->fabric_node_name;
-}
-
-static void unf_get_host_port_state(struct Scsi_Host *shost)
-{
- struct unf_lport *unf_lport = NULL;
- enum fc_port_state port_state;
-
- unf_lport = (struct unf_lport *)shost->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Port is null");
- return;
- }
-
- switch (unf_lport->link_up) {
- case UNF_PORT_LINK_DOWN:
- port_state = FC_PORTSTATE_OFFLINE;
- break;
- case UNF_PORT_LINK_UP:
- port_state = FC_PORTSTATE_ONLINE;
- break;
- default:
- port_state = FC_PORTSTATE_UNKNOWN;
- break;
- }
-
- fc_host_port_state(shost) = port_state;
-}
-
-static void unf_dev_loss_timeout_callbk(struct fc_rport *rport)
-{
- /*
- * NOTE: about rport->dd_data
- * --->>> local SCSI_ID
- * 1. Assignment during scsi rport link up
- * 2. Released when scsi rport link down & timeout(30s)
- * 3. Used during scsi do callback with slave_alloc function
- */
- struct Scsi_Host *host = NULL;
- struct unf_lport *unf_lport = NULL;
- u32 scsi_id = 0;
-
- if (unlikely(!rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]SCSI rport is null");
- return;
- }
-
- host = rport_to_shost(rport);
- if (unlikely(!host)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Host is null");
- return;
- }
-
- scsi_id = *(u32 *)(rport->dd_data); /* according to Local SCSI_ID */
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]rport(0x%p) scsi_id(0x%x) is max than(0x%x)",
- rport, scsi_id, UNF_MAX_SCSI_ID);
- return;
- }
-
- unf_lport = (struct unf_lport *)host->hostdata[0];
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[event]Port(0x%x_0x%x) rport(0x%p) scsi_id(0x%x) target_id(0x%x) loss timeout",
- unf_lport->port_id, unf_lport->nport_id, rport,
- scsi_id, rport->scsi_target_id);
-
- atomic_inc(&unf_lport->session_loss_tmo);
-
- /* Free SCSI ID & set table state with DEAD */
- (void)unf_free_scsi_id(unf_lport, scsi_id);
- unf_xchg_up_abort_io_by_scsi_id(unf_lport, scsi_id);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(%p) is invalid", unf_lport);
- }
-
- *((u32 *)rport->dd_data) = INVALID_VALUE32;
-}
-
-int unf_scsi_create_vport(struct fc_vport *fc_port, bool disabled)
-{
- struct unf_lport *vport = NULL;
- struct unf_lport *unf_lport = NULL;
- struct Scsi_Host *shost = NULL;
- struct vport_config vport_config = {0};
-
- shost = vport_to_shost(fc_port);
-
- unf_lport = (struct unf_lport *)shost->hostdata[0];
- if (unf_is_lport_valid(unf_lport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(%p) is invalid", unf_lport);
-
- return RETURN_ERROR;
- }
-
- vport_config.port_name = fc_port->port_name;
-
- vport_config.port_mode = fc_port->roles;
-
- vport = unf_creat_vport(unf_lport, &vport_config);
- if (!vport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) Create Vport failed on lldrive",
- unf_lport->port_id);
-
- return RETURN_ERROR;
- }
-
- fc_port->dd_data = vport;
- vport->vport = fc_port;
-
- return RETURN_OK;
-}
-
-int unf_scsi_delete_vport(struct fc_vport *fc_port)
-{
- int ret = RETURN_ERROR;
- struct unf_lport *vport = NULL;
-
- vport = (struct unf_lport *)fc_port->dd_data;
- if (unf_is_lport_valid(vport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]VPort(%p) is invalid or is removing", vport);
-
- fc_port->dd_data = NULL;
-
- return ret;
- }
-
- ret = (int)unf_destroy_one_vport(vport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]VPort(0x%x) destroy failed on drive", vport->port_id);
-
- return ret;
- }
-
- fc_port->dd_data = NULL;
- return ret;
-}
-
-struct fc_function_template function_template = {
- .show_host_node_name = 1,
- .show_host_port_name = 1,
- .show_host_supported_classes = 1,
- .show_host_supported_speeds = 1,
-
- .get_host_port_id = unf_get_host_port_id,
- .show_host_port_id = 1,
- .get_host_speed = unf_get_host_speed,
- .show_host_speed = 1,
- .get_host_port_type = unf_get_host_port_type,
- .show_host_port_type = 1,
- .get_host_symbolic_name = unf_get_symbolic_name,
- .show_host_symbolic_name = 1,
- .set_host_system_hostname = NULL,
- .show_host_system_hostname = 1,
- .get_host_fabric_name = unf_get_host_fabric_name,
- .show_host_fabric_name = 1,
- .get_host_port_state = unf_get_host_port_state,
- .show_host_port_state = 1,
-
- .dd_fcrport_size = sizeof(void *),
- .show_rport_supported_classes = 1,
-
- .get_starget_node_name = NULL,
- .show_starget_node_name = 1,
- .get_starget_port_name = NULL,
- .show_starget_port_name = 1,
- .get_starget_port_id = NULL,
- .show_starget_port_id = 1,
-
- .set_rport_dev_loss_tmo = unf_set_rport_loss_tmo,
- .show_rport_dev_loss_tmo = 0,
-
- .issue_fc_host_lip = NULL,
- .dev_loss_tmo_callbk = unf_dev_loss_timeout_callbk,
- .terminate_rport_io = NULL,
- .get_fc_host_stats = NULL,
-
- .vport_create = unf_scsi_create_vport,
- .vport_disable = NULL,
- .vport_delete = unf_scsi_delete_vport,
- .bsg_request = NULL,
- .bsg_timeout = NULL,
-};
-
-struct fc_function_template function_template_v = {
- .show_host_node_name = 1,
- .show_host_port_name = 1,
- .show_host_supported_classes = 1,
- .show_host_supported_speeds = 1,
-
- .get_host_port_id = unf_get_host_port_id,
- .show_host_port_id = 1,
- .get_host_speed = unf_get_host_speed,
- .show_host_speed = 1,
- .get_host_port_type = unf_get_host_port_type,
- .show_host_port_type = 1,
- .get_host_symbolic_name = unf_get_symbolic_name,
- .show_host_symbolic_name = 1,
- .set_host_system_hostname = NULL,
- .show_host_system_hostname = 1,
- .get_host_fabric_name = unf_get_host_fabric_name,
- .show_host_fabric_name = 1,
- .get_host_port_state = unf_get_host_port_state,
- .show_host_port_state = 1,
-
- .dd_fcrport_size = sizeof(void *),
- .show_rport_supported_classes = 1,
-
- .get_starget_node_name = NULL,
- .show_starget_node_name = 1,
- .get_starget_port_name = NULL,
- .show_starget_port_name = 1,
- .get_starget_port_id = NULL,
- .show_starget_port_id = 1,
-
- .set_rport_dev_loss_tmo = unf_set_rport_loss_tmo,
- .show_rport_dev_loss_tmo = 0,
-
- .issue_fc_host_lip = NULL,
- .dev_loss_tmo_callbk = unf_dev_loss_timeout_callbk,
- .terminate_rport_io = NULL,
- .get_fc_host_stats = NULL,
-
- .vport_create = NULL,
- .vport_disable = NULL,
- .vport_delete = NULL,
- .bsg_request = NULL,
- .bsg_timeout = NULL,
-};
-
-struct scsi_host_template scsi_host_template = {
- .module = THIS_MODULE,
- .name = "SPFC",
-
- .queuecommand = unf_scsi_queue_cmd,
- .eh_timed_out = fc_eh_timed_out,
- .eh_abort_handler = unf_scsi_abort_scsi_cmnd,
- .eh_device_reset_handler = unf_scsi_device_reset_handler,
-
- .eh_target_reset_handler = unf_scsi_target_reset_handler,
- .eh_bus_reset_handler = unf_scsi_bus_reset_handler,
- .eh_host_reset_handler = NULL,
-
- .slave_configure = unf_scsi_slave_configure,
- .slave_alloc = unf_scsi_slave_alloc,
- .slave_destroy = unf_scsi_destroy_slave,
-
- .scan_finished = unf_scsi_scan_finished,
- .scan_start = unf_scsi_scan_start,
-
- .this_id = -1, /* this_id: -1 */
- .cmd_per_lun = UNF_CMD_PER_LUN,
- .shost_attrs = NULL,
- .sg_tablesize = SG_ALL,
- .max_sectors = UNF_MAX_SECTORS,
- .supported_mode = MODE_INITIATOR,
-};
-
-void unf_unmap_prot_sgl(struct scsi_cmnd *cmnd)
-{
- struct device *dev = NULL;
-
- if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) && spfc_dif_enable &&
- (scsi_prot_sg_count(cmnd))) {
- dev = cmnd->device->host->dma_dev;
- dma_unmap_sg(dev, scsi_prot_sglist(cmnd),
- (int)scsi_prot_sg_count(cmnd),
- cmnd->sc_data_direction);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "scsi done cmd:%p op:%u, difsglcount:%u", cmnd,
- scsi_get_prot_op(cmnd), scsi_prot_sg_count(cmnd));
- }
-}
-
-void unf_scsi_done(struct unf_scsi_cmnd *scsi_cmd)
-{
- struct scsi_cmnd *cmd = NULL;
-
- cmd = (struct scsi_cmnd *)scsi_cmd->upper_cmnd;
- FC_CHECK_RETURN_VOID(scsi_cmd);
- FC_CHECK_RETURN_VOID(cmd);
- FC_CHECK_RETURN_VOID(cmd->scsi_done);
- scsi_set_resid(cmd, (int)scsi_cmd->resid);
-
- cmd->result = scsi_cmd->result;
- scsi_dma_unmap(cmd);
- unf_unmap_prot_sgl(cmd);
- return cmd->scsi_done(cmd);
-}
-
-static void unf_get_protect_op(struct scsi_cmnd *cmd,
- struct unf_dif_control_info *dif_control_info)
-{
- switch (scsi_get_prot_op(cmd)) {
- /* OS-HBA: Unprotected, HBA-Target: Protected */
- case SCSI_PROT_READ_STRIP:
- dif_control_info->protect_opcode |= UNF_DIF_ACTION_VERIFY_AND_DELETE;
- break;
- case SCSI_PROT_WRITE_INSERT:
- dif_control_info->protect_opcode |= UNF_DIF_ACTION_INSERT;
- break;
-
- /* OS-HBA: Protected, HBA-Target: Unprotected */
- case SCSI_PROT_READ_INSERT:
- dif_control_info->protect_opcode |= UNF_DIF_ACTION_INSERT;
- break;
- case SCSI_PROT_WRITE_STRIP:
- dif_control_info->protect_opcode |= UNF_DIF_ACTION_VERIFY_AND_DELETE;
- break;
-
- /* OS-HBA: Protected, HBA-Target: Protected */
- case SCSI_PROT_READ_PASS:
- case SCSI_PROT_WRITE_PASS:
- dif_control_info->protect_opcode |= UNF_DIF_ACTION_VERIFY_AND_FORWARD;
- break;
-
- default:
- dif_control_info->protect_opcode |= UNF_DIF_ACTION_VERIFY_AND_FORWARD;
- break;
- }
-}
-
-int unf_get_protect_mode(struct unf_lport *lport, struct scsi_cmnd *scsi_cmd,
- struct unf_scsi_cmnd *unf_scsi_cmd)
-{
- struct scsi_cmnd *cmd = NULL;
- int dif_seg_cnt = 0;
- struct unf_dif_control_info *dif_control_info = NULL;
-
- cmd = scsi_cmd;
- dif_control_info = &unf_scsi_cmd->dif_control;
-
- unf_get_protect_op(cmd, dif_control_info);
-
- if (dif_sgl_mode)
- dif_control_info->flags |= UNF_DIF_DOUBLE_SGL;
- dif_control_info->flags |= ((cmd->device->sector_size) == SECTOR_SIZE_4096)
- ? UNF_DIF_SECTSIZE_4KB : UNF_DIF_SECTSIZE_512;
- dif_control_info->protect_opcode |= UNF_VERIFY_CRC_MASK | UNF_VERIFY_LBA_MASK;
- dif_control_info->dif_sge_count = scsi_prot_sg_count(cmd);
- dif_control_info->dif_sgl = scsi_prot_sglist(cmd);
- dif_control_info->start_lba = cpu_to_le32(((uint32_t)(0xffffffff & scsi_get_lba(cmd))));
-
- if (cmd->device->sector_size == SECTOR_SIZE_4096)
- dif_control_info->start_lba = dif_control_info->start_lba >> UNF_SHIFT_3;
-
- if (scsi_prot_sg_count(cmd)) {
- dif_seg_cnt = dma_map_sg(&lport->low_level_func.dev->dev, scsi_prot_sglist(cmd),
- (int)scsi_prot_sg_count(cmd), cmd->sc_data_direction);
- if (unlikely(!dif_seg_cnt)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) cmd:%p map dif sgl err",
- lport->port_id, cmd);
- return UNF_RETURN_ERROR;
- }
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "build scsi cmd:%p op:%u,difsglcount:%u,difsegcnt:%u", cmd,
- scsi_get_prot_op(cmd), scsi_prot_sg_count(cmd),
- dif_seg_cnt);
- return RETURN_OK;
-}
-
-static u32 unf_get_rport_qos_level(struct scsi_cmnd *cmd, u32 scsi_id,
- struct unf_rport_scsi_id_image *scsi_image_table)
-{
- enum unf_rport_qos_level level = 0;
-
- if (!scsi_image_table->wwn_rport_info_table[scsi_id].lun_qos_level ||
- cmd->device->lun >= UNF_MAX_LUN_PER_TARGET) {
- level = 0;
- } else {
- level = (scsi_image_table->wwn_rport_info_table[scsi_id]
- .lun_qos_level[cmd->device->lun]);
- }
- return level;
-}
-
-u32 unf_get_frame_entry_buf(void *up_cmnd, void *driver_sgl, void **upper_sgl,
- u32 *port_id, u32 *index, char **buf, u32 *buf_len)
-{
-#define SPFC_MAX_DMA_LENGTH (0x20000 - 1)
- struct scatterlist *scsi_sgl = *upper_sgl;
-
- if (unlikely(!scsi_sgl)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Command(0x%p) can not get SGL.", up_cmnd);
- return RETURN_ERROR;
- }
- *buf = (char *)sg_dma_address(scsi_sgl);
- *buf_len = sg_dma_len(scsi_sgl);
- *upper_sgl = (void *)sg_next(scsi_sgl);
- if (unlikely((*buf_len > SPFC_MAX_DMA_LENGTH) || (*buf_len == 0))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Command(0x%p) dmalen:0x%x is not support.",
- up_cmnd, *buf_len);
- return RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-static void unf_init_scsi_cmnd(struct Scsi_Host *host, struct scsi_cmnd *cmd,
- struct unf_scsi_cmnd *scsi_cmnd,
- struct unf_rport_scsi_id_image *scsi_image_table,
- int datasegcnt)
-{
- static atomic64_t count;
- enum unf_rport_qos_level level = 0;
- u32 scsi_id = 0;
-
- scsi_id = (u32)((u64)cmd->device->hostdata);
- level = unf_get_rport_qos_level(cmd, scsi_id, scsi_image_table);
- scsi_cmnd->scsi_host_id = host->host_no; /* save host_no to scsi_cmnd->scsi_host_id */
- scsi_cmnd->scsi_id = scsi_id;
- scsi_cmnd->raw_lun_id = ((u64)cmd->device->lun << 16) & UNF_LUN_ID_MASK;
- scsi_cmnd->data_direction = cmd->sc_data_direction;
- scsi_cmnd->under_flow = cmd->underflow;
- scsi_cmnd->cmnd_len = cmd->cmd_len;
- scsi_cmnd->pcmnd = cmd->cmnd;
- scsi_cmnd->transfer_len = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
- scsi_cmnd->sense_buflen = UNF_SCSI_SENSE_BUFFERSIZE;
- scsi_cmnd->sense_buf = cmd->sense_buffer;
- scsi_cmnd->time_out = 0;
- scsi_cmnd->upper_cmnd = cmd;
- scsi_cmnd->drv_private = (void *)(*(u64 *)shost_priv(host));
- scsi_cmnd->entry_count = datasegcnt;
- scsi_cmnd->sgl = scsi_sglist(cmd);
- scsi_cmnd->unf_ini_get_sgl_entry = unf_get_frame_entry_buf;
- scsi_cmnd->done = unf_scsi_done;
- scsi_cmnd->lun_id = (u8 *)&scsi_cmnd->raw_lun_id;
- scsi_cmnd->err_code_table_cout = ini_err_code_table_cnt1;
- scsi_cmnd->err_code_table = ini_error_code_table1;
- scsi_cmnd->world_id = INVALID_WORLD_ID;
- scsi_cmnd->cmnd_sn = atomic64_inc_return(&count);
- scsi_cmnd->qos_level = level;
- if (unlikely(scsi_cmnd->cmnd_sn == 0))
- scsi_cmnd->cmnd_sn = atomic64_inc_return(&count);
-}
-
-static void unf_io_error_done(struct scsi_cmnd *cmd,
- struct unf_rport_scsi_id_image *scsi_image_table,
- u32 scsi_id, u32 result)
-{
- cmd->result = (int)(result << UNF_SHIFT_16);
- cmd->scsi_done(cmd);
- if (scsi_image_table)
- UNF_IO_RESULT_CNT(scsi_image_table, scsi_id, result);
-}
-
-static bool unf_scan_device_cmd(struct scsi_cmnd *cmd)
-{
- return ((cmd->cmnd[0] == INQUIRY) || (cmd->cmnd[0] == REPORT_LUNS));
-}
-
-static int unf_scsi_queue_cmd(struct Scsi_Host *phost, struct scsi_cmnd *pcmd)
-{
- struct Scsi_Host *host = NULL;
- struct scsi_cmnd *cmd = NULL;
- struct unf_scsi_cmnd scsi_cmd = {0};
- u32 scsi_id = 0;
- u32 scsi_state = 0;
- int ret = SCSI_MLQUEUE_HOST_BUSY;
- struct unf_lport *unf_lport = NULL;
- struct fc_rport *rport = NULL;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- struct unf_rport *unf_rport = NULL;
- u32 cmnd_result = 0;
- u32 rport_state_err = 0;
- bool scan_device_cmd = false;
- int datasegcnt = 0;
-
- host = phost;
- cmd = pcmd;
- FC_CHECK_RETURN_VALUE(host, RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(cmd, RETURN_ERROR);
-
- /* Get L_Port from scsi_cmd */
- unf_lport = (struct unf_lport *)host->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Check l_port failed, cmd(%p)", cmd);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- return 0;
- }
-
- /* Check device/session local state by device_id */
- scsi_id = (u32)((u64)cmd->device->hostdata);
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) scsi_id(0x%x) is max than %d",
- unf_lport->port_id, scsi_id, UNF_MAX_SCSI_ID);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- return 0;
- }
-
- scsi_image_table = &unf_lport->rport_scsi_table;
- UNF_SCSI_CMD_CNT(scsi_image_table, scsi_id, cmd->cmnd[0]);
-
- /* Get scsi r_port */
- rport = starget_to_rport(scsi_target(cmd->device));
- if (unlikely(!rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) cmd(%p) to get scsi rport failed",
- unf_lport->port_id, cmd);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- return 0;
- }
-
- if (unlikely(!scsi_image_table->wwn_rport_info_table)) {
- FC_DRV_PRINT(UNF_LOG_ABNORMAL, UNF_WARN,
- "[warn]LPort porid(0x%x) WwnRportInfoTable NULL",
- unf_lport->port_id);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- return 0;
- }
-
- if (unlikely(unf_lport->port_removing)) {
- FC_DRV_PRINT(UNF_LOG_ABNORMAL, UNF_WARN,
- "[warn]Port(0x%x) scsi_id(0x%x) rport(0x%p) target_id(0x%x) cmd(0x%p) unf_lport removing",
- unf_lport->port_id, scsi_id, rport, rport->scsi_target_id, cmd);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- return 0;
- }
-
- scsi_state = atomic_read(&scsi_image_table->wwn_rport_info_table[scsi_id].scsi_state);
- if (unlikely(scsi_state != UNF_SCSI_ST_ONLINE)) {
- if (scsi_state == UNF_SCSI_ST_OFFLINE) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) scsi_state(0x%x) scsi_id(0x%x) rport(0x%p) target_id(0x%x) cmd(0x%p), target is busy",
- unf_lport->port_id, scsi_state, scsi_id, rport,
- rport->scsi_target_id, cmd);
-
- scan_device_cmd = unf_scan_device_cmd(cmd);
- /* report lun or inquiry cmd, if send failed, do not
- * retry, prevent
- * the scan_mutex in scsi host locked up by eachother
- */
- if (scan_device_cmd) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) host(0x%x) scsi_id(0x%x) lun(0x%llx) cmd(0x%x) DID_NO_CONNECT",
- unf_lport->port_id, host->host_no, scsi_id,
- (u64)cmd->device->lun, cmd->cmnd[0]);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- return 0;
- }
-
- if (likely(scsi_image_table->wwn_rport_info_table)) {
- if (likely(scsi_image_table->wwn_rport_info_table[scsi_id]
- .dfx_counter)) {
- atomic64_inc(&(scsi_image_table
- ->wwn_rport_info_table[scsi_id]
- .dfx_counter->target_busy));
- }
- }
-
- /* Target busy: need scsi retry */
- return SCSI_MLQUEUE_TARGET_BUSY;
- }
- /* timeout(DEAD): scsi_done & return 0 & I/O error */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) scsi_id(0x%x) rport(0x%p) target_id(0x%x) cmd(0x%p), target is loss timeout",
- unf_lport->port_id, scsi_id, rport,
- rport->scsi_target_id, cmd);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- return 0;
- }
-
- if (scsi_sg_count(cmd)) {
- datasegcnt = dma_map_sg(&unf_lport->low_level_func.dev->dev, scsi_sglist(cmd),
- (int)scsi_sg_count(cmd), cmd->sc_data_direction);
- if (unlikely(!datasegcnt)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) scsi_id(0x%x) rport(0x%p) target_id(0x%x) cmd(0x%p), dma map sg err",
- unf_lport->port_id, scsi_id, rport,
- rport->scsi_target_id, cmd);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_BUS_BUSY);
- return SCSI_MLQUEUE_HOST_BUSY;
- }
- }
-
- /* Construct local SCSI CMND info */
- unf_init_scsi_cmnd(host, cmd, &scsi_cmd, scsi_image_table, datasegcnt);
-
- if ((scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) && spfc_dif_enable) {
- ret = unf_get_protect_mode(unf_lport, cmd, &scsi_cmd);
- if (ret != RETURN_OK) {
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_BUS_BUSY);
- scsi_dma_unmap(cmd);
- return SCSI_MLQUEUE_HOST_BUSY;
- }
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) host(0x%x) scsi_id(0x%x) lun(0x%llx) transfer length(0x%x) cmd_len(0x%x) direction(0x%x) cmd(0x%x) under_flow(0x%x) protect_opcode is (0x%x) dif_sgl_mode is %d, sector size(%d)",
- unf_lport->port_id, host->host_no, scsi_id, (u64)cmd->device->lun,
- scsi_cmd.transfer_len, scsi_cmd.cmnd_len, cmd->sc_data_direction,
- scsi_cmd.pcmnd[0], scsi_cmd.under_flow,
- scsi_cmd.dif_control.protect_opcode, dif_sgl_mode,
- (cmd->device->sector_size));
-
- /* Bind the Exchange address corresponding to scsi_cmd to
- * scsi_cmd->host_scribble
- */
- cmd->host_scribble = (unsigned char *)scsi_cmd.cmnd_sn;
- ret = unf_cm_queue_command(&scsi_cmd);
- if (ret != RETURN_OK) {
- unf_rport = unf_find_rport_by_scsi_id(unf_lport, ini_error_code_table1,
- ini_err_code_table_cnt1,
- scsi_id, &cmnd_result);
- rport_state_err = (!unf_rport) ||
- (unf_rport->lport_ini_state != UNF_PORT_STATE_LINKUP) ||
- (unf_rport->rp_state == UNF_RPORT_ST_CLOSING);
- scan_device_cmd = unf_scan_device_cmd(cmd);
-
- /* report lun or inquiry cmd if send failed, do not
- * retry,prevent the scan_mutex in scsi host locked up by
- * eachother
- */
- if (rport_state_err && scan_device_cmd) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) host(0x%x) scsi_id(0x%x) lun(0x%llx) cmd(0x%x) cmResult(0x%x) DID_NO_CONNECT",
- unf_lport->port_id, host->host_no, scsi_id,
- (u64)cmd->device->lun, cmd->cmnd[0],
- cmnd_result);
- unf_io_error_done(cmd, scsi_image_table, scsi_id, DID_NO_CONNECT);
- scsi_dma_unmap(cmd);
- unf_unmap_prot_sgl(cmd);
- return 0;
- }
-
- /* Host busy: scsi need to retry */
- ret = SCSI_MLQUEUE_HOST_BUSY;
- if (likely(scsi_image_table->wwn_rport_info_table)) {
- if (likely(scsi_image_table->wwn_rport_info_table[scsi_id].dfx_counter)) {
- atomic64_inc(&(scsi_image_table->wwn_rport_info_table[scsi_id]
- .dfx_counter->host_busy));
- }
- }
- scsi_dma_unmap(cmd);
- unf_unmap_prot_sgl(cmd);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) return(0x%x) to process INI IO falid",
- unf_lport->port_id, ret);
- }
- return ret;
-}
-
-static void unf_init_abts_tmf_scsi_cmd(struct scsi_cmnd *cmnd,
- struct unf_scsi_cmnd *scsi_cmd,
- bool abort_cmd)
-{
- struct Scsi_Host *scsi_host = NULL;
-
- scsi_host = cmnd->device->host;
- scsi_cmd->scsi_host_id = scsi_host->host_no;
- scsi_cmd->scsi_id = (u32)((u64)cmnd->device->hostdata);
- scsi_cmd->raw_lun_id = (u64)cmnd->device->lun;
- scsi_cmd->upper_cmnd = cmnd;
- scsi_cmd->drv_private = (void *)(*(u64 *)shost_priv(scsi_host));
- scsi_cmd->cmnd_sn = (u64)(cmnd->host_scribble);
- scsi_cmd->lun_id = (u8 *)&scsi_cmd->raw_lun_id;
- if (abort_cmd) {
- scsi_cmd->done = unf_scsi_done;
- scsi_cmd->world_id = INVALID_WORLD_ID;
- }
-}
-
-int unf_scsi_abort_scsi_cmnd(struct scsi_cmnd *cmnd)
-{
- /* SCSI ABORT Command --->>> FC ABTS */
- struct unf_scsi_cmnd scsi_cmd = {0};
- int ret = FAILED;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- struct unf_lport *unf_lport = NULL;
- u32 scsi_id = 0;
- u32 err_handle = 0;
-
- FC_CHECK_RETURN_VALUE(cmnd, FAILED);
-
- unf_lport = (struct unf_lport *)cmnd->device->host->hostdata[0];
- scsi_id = (u32)((u64)cmnd->device->hostdata);
-
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_ABORT_IO_TYPE;
- UNF_SCSI_ERROR_HANDLE_CNT(scsi_image_table, scsi_id, err_handle);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[abort]Port(0x%x) scsi_id(0x%x) lun_id(0x%x) cmnd_type(0x%x)",
- unf_lport->port_id, scsi_id,
- (u32)cmnd->device->lun, cmnd->cmnd[0]);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Lport(%p) is moving or null", unf_lport);
- return UNF_SCSI_ABORT_FAIL;
- }
-
- /* Check local SCSI_ID validity */
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]scsi_id(0x%x) is max than(0x%x)", scsi_id,
- UNF_MAX_SCSI_ID);
- return UNF_SCSI_ABORT_FAIL;
- }
-
- /* Block scsi (check rport state -> whether offline or not) */
- ret = fc_block_scsi_eh(cmnd);
- if (unlikely(ret != 0)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Block scsi eh failed(0x%x)", ret);
- return ret;
- }
-
- unf_init_abts_tmf_scsi_cmd(cmnd, &scsi_cmd, true);
- /* Process scsi Abort cmnd */
- ret = unf_cm_eh_abort_handler(&scsi_cmd);
- if (ret == UNF_SCSI_ABORT_SUCCESS) {
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_ABORT_IO_TYPE;
- UNF_SCSI_ERROR_HANDLE_RESULT_CNT(scsi_image_table,
- scsi_id, err_handle);
- }
- }
-
- return ret;
-}
-
-int unf_scsi_device_reset_handler(struct scsi_cmnd *cmnd)
-{
- /* LUN reset */
- struct unf_scsi_cmnd scsi_cmd = {0};
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- int ret = FAILED;
- struct unf_lport *unf_lport = NULL;
- u32 scsi_id = 0;
- u32 err_handle = 0;
-
- FC_CHECK_RETURN_VALUE(cmnd, FAILED);
-
- unf_lport = (struct unf_lport *)cmnd->device->host->hostdata[0];
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_DEVICE_RESET_TYPE;
- UNF_SCSI_ERROR_HANDLE_CNT(scsi_image_table, scsi_id, err_handle);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[device_reset]Port(0x%x) scsi_id(0x%x) lun_id(0x%x) cmnd_type(0x%x)",
- unf_lport->port_id, scsi_id, (u32)cmnd->device->lun, cmnd->cmnd[0]);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Port is invalid");
-
- return FAILED;
- }
-
- /* Check local SCSI_ID validity */
- scsi_id = (u32)((u64)cmnd->device->hostdata);
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]scsi_id(0x%x) is max than(0x%x)", scsi_id,
- UNF_MAX_SCSI_ID);
-
- return FAILED;
- }
-
- /* Block scsi (check rport state -> whether offline or not) */
- ret = fc_block_scsi_eh(cmnd);
- if (unlikely(ret != 0)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Block scsi eh failed(0x%x)", ret);
-
- return ret;
- }
-
- unf_init_abts_tmf_scsi_cmd(cmnd, &scsi_cmd, false);
- /* Process scsi device/LUN reset cmnd */
- ret = unf_cm_eh_device_reset_handler(&scsi_cmd);
- if (ret == UNF_SCSI_ABORT_SUCCESS) {
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_DEVICE_RESET_TYPE;
- UNF_SCSI_ERROR_HANDLE_RESULT_CNT(scsi_image_table,
- scsi_id, err_handle);
- }
- }
-
- return ret;
-}
-
-int unf_scsi_bus_reset_handler(struct scsi_cmnd *cmnd)
-{
- /* BUS Reset */
- struct unf_scsi_cmnd scsi_cmd = {0};
- struct unf_lport *unf_lport = NULL;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- int ret = FAILED;
- u32 scsi_id = 0;
- u32 err_handle = 0;
-
- FC_CHECK_RETURN_VALUE(cmnd, FAILED);
-
- unf_lport = (struct unf_lport *)cmnd->device->host->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port is null");
-
- return FAILED;
- }
-
- /* Check local SCSI_ID validity */
- scsi_id = (u32)((u64)cmnd->device->hostdata);
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]scsi_id(0x%x) is max than(0x%x)", scsi_id,
- UNF_MAX_SCSI_ID);
-
- return FAILED;
- }
-
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_BUS_RESET_TYPE;
- UNF_SCSI_ERROR_HANDLE_CNT(scsi_image_table, scsi_id, err_handle);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info][bus_reset]Port(0x%x) scsi_id(0x%x) lun_id(0x%x) cmnd_type(0x%x)",
- unf_lport->port_id, scsi_id, (u32)cmnd->device->lun,
- cmnd->cmnd[0]);
- }
-
- /* Block scsi (check rport state -> whether offline or not) */
- ret = fc_block_scsi_eh(cmnd);
- if (unlikely(ret != 0)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Block scsi eh failed(0x%x)", ret);
-
- return ret;
- }
-
- unf_init_abts_tmf_scsi_cmd(cmnd, &scsi_cmd, false);
- /* Process scsi BUS Reset cmnd */
- ret = unf_cm_bus_reset_handler(&scsi_cmd);
- if (ret == UNF_SCSI_ABORT_SUCCESS) {
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_BUS_RESET_TYPE;
- UNF_SCSI_ERROR_HANDLE_RESULT_CNT(scsi_image_table, scsi_id, err_handle);
- }
- }
-
- return ret;
-}
-
-int unf_scsi_target_reset_handler(struct scsi_cmnd *cmnd)
-{
- /* Session reset/delete */
- struct unf_scsi_cmnd scsi_cmd = {0};
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
- int ret = FAILED;
- struct unf_lport *unf_lport = NULL;
- u32 scsi_id = 0;
- u32 err_handle = 0;
-
- FC_CHECK_RETURN_VALUE(cmnd, RETURN_ERROR);
-
- unf_lport = (struct unf_lport *)cmnd->device->host->hostdata[0];
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port is null");
-
- return FAILED;
- }
-
- /* Check local SCSI_ID validity */
- scsi_id = (u32)((u64)cmnd->device->hostdata);
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]scsi_id(0x%x) is max than(0x%x)", scsi_id, UNF_MAX_SCSI_ID);
-
- return FAILED;
- }
-
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_TARGET_RESET_TYPE;
- UNF_SCSI_ERROR_HANDLE_CNT(scsi_image_table, scsi_id, err_handle);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[target_reset]Port(0x%x) scsi_id(0x%x) lun_id(0x%x) cmnd_type(0x%x)",
- unf_lport->port_id, scsi_id, (u32)cmnd->device->lun, cmnd->cmnd[0]);
- }
-
- /* Block scsi (check rport state -> whether offline or not) */
- ret = fc_block_scsi_eh(cmnd);
- if (unlikely(ret != 0)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Block scsi eh failed(0x%x)", ret);
-
- return ret;
- }
-
- unf_init_abts_tmf_scsi_cmd(cmnd, &scsi_cmd, false);
- /* Process scsi Target/Session reset/delete cmnd */
- ret = unf_cm_target_reset_handler(&scsi_cmd);
- if (ret == UNF_SCSI_ABORT_SUCCESS) {
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- err_handle = UNF_SCSI_TARGET_RESET_TYPE;
- UNF_SCSI_ERROR_HANDLE_RESULT_CNT(scsi_image_table, scsi_id, err_handle);
- }
- }
-
- return ret;
-}
-
-static int unf_scsi_slave_alloc(struct scsi_device *sdev)
-{
- struct fc_rport *rport = NULL;
- u32 scsi_id = 0;
- struct unf_lport *unf_lport = NULL;
- struct Scsi_Host *host = NULL;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
-
- /* About device */
- if (unlikely(!sdev)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]SDev is null");
- return -ENXIO;
- }
-
- /* About scsi rport */
- rport = starget_to_rport(scsi_target(sdev));
- if (unlikely(!rport || fc_remote_port_chkready(rport))) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]SCSI rport is null");
-
- if (rport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]SCSI rport is not ready(0x%x)",
- fc_remote_port_chkready(rport));
- }
-
- return -ENXIO;
- }
-
- /* About host */
- host = rport_to_shost(rport);
- if (unlikely(!host)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Host is null");
-
- return -ENXIO;
- }
-
- /* About Local Port */
- unf_lport = (struct unf_lport *)host->hostdata[0];
- if (unf_is_lport_valid(unf_lport) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Port is invalid");
-
- return -ENXIO;
- }
-
- /* About Local SCSI_ID */
- scsi_id =
- *(u32 *)rport->dd_data;
- if (unlikely(scsi_id >= UNF_MAX_SCSI_ID)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]scsi_id(0x%x) is max than(0x%x)", scsi_id, UNF_MAX_SCSI_ID);
-
- return -ENXIO;
- }
-
- scsi_image_table = &unf_lport->rport_scsi_table;
- if (scsi_image_table->wwn_rport_info_table[scsi_id].dfx_counter) {
- atomic_inc(&scsi_image_table->wwn_rport_info_table[scsi_id]
- .dfx_counter->device_alloc);
- }
- atomic_inc(&unf_lport->device_alloc);
- sdev->hostdata = (void *)(u64)scsi_id;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x) use scsi_id(%u) to alloc device[%u:%u:%u:%u]",
- unf_lport->port_id, scsi_id, host->host_no, sdev->channel, sdev->id,
- (u32)sdev->lun);
-
- return 0;
-}
-
-static void unf_scsi_destroy_slave(struct scsi_device *sdev)
-{
- /*
- * NOTE: about sdev->hostdata
- * --->>> pointing to local SCSI_ID
- * 1. Assignment during slave allocation
- * 2. Released when callback for slave destroy
- * 3. Used during: Queue_CMND, Abort CMND, Device Reset, Target Reset &
- * Bus Reset
- */
- struct fc_rport *rport = NULL;
- u32 scsi_id = 0;
- struct unf_lport *unf_lport = NULL;
- struct Scsi_Host *host = NULL;
- struct unf_rport_scsi_id_image *scsi_image_table = NULL;
-
- /* About scsi device */
- if (unlikely(!sdev)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]SDev is null");
-
- return;
- }
-
- /* About scsi rport */
- rport = starget_to_rport(scsi_target(sdev));
- if (unlikely(!rport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]SCSI rport is null or remote port is not ready");
- return;
- }
-
- /* About host */
- host = rport_to_shost(rport);
- if (unlikely(!host)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Host is null");
-
- return;
- }
-
- /* About L_Port */
- unf_lport = (struct unf_lport *)host->hostdata[0];
- if (unf_is_lport_valid(unf_lport) == RETURN_OK) {
- scsi_image_table = &unf_lport->rport_scsi_table;
- atomic_inc(&unf_lport->device_destroy);
-
- scsi_id = (u32)((u64)sdev->hostdata);
- if (scsi_id < UNF_MAX_SCSI_ID && scsi_image_table->wwn_rport_info_table) {
- if (scsi_image_table->wwn_rport_info_table[scsi_id].dfx_counter) {
- atomic_inc(&scsi_image_table->wwn_rport_info_table[scsi_id]
- .dfx_counter->device_destroy);
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x) with scsi_id(%u) to destroy slave device[%u:%u:%u:%u]",
- unf_lport->port_id, scsi_id, host->host_no,
- sdev->channel, sdev->id, (u32)sdev->lun);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[err]Port(0x%x) scsi_id(%u) is invalid and destroy device[%u:%u:%u:%u]",
- unf_lport->port_id, scsi_id, host->host_no,
- sdev->channel, sdev->id, (u32)sdev->lun);
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(%p) is invalid", unf_lport);
- }
-
- sdev->hostdata = NULL;
-}
-
-static int unf_scsi_slave_configure(struct scsi_device *sdev)
-{
-#define UNF_SCSI_DEV_DEPTH 32
- blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
-
- scsi_change_queue_depth(sdev, UNF_SCSI_DEV_DEPTH);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[event]Enter slave configure, set depth is %d, sdev->tagged_supported is (%d)",
- UNF_SCSI_DEV_DEPTH, sdev->tagged_supported);
-
- return 0;
-}
-
-static int unf_scsi_scan_finished(struct Scsi_Host *shost, unsigned long time)
-{
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[event]Scan finished");
-
- return 1;
-}
-
-static void unf_scsi_scan_start(struct Scsi_Host *shost)
-{
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[event]Start scsi scan...");
-}
-
-void unf_host_init_attr_setting(struct Scsi_Host *scsi_host)
-{
- struct unf_lport *unf_lport = NULL;
- u32 speed = FC_PORTSPEED_UNKNOWN;
-
- unf_lport = (struct unf_lport *)scsi_host->hostdata[0];
- fc_host_supported_classes(scsi_host) = FC_COS_CLASS3;
- fc_host_dev_loss_tmo(scsi_host) = (u32)unf_get_link_lose_tmo(unf_lport);
- fc_host_node_name(scsi_host) = unf_lport->node_name;
- fc_host_port_name(scsi_host) = unf_lport->port_name;
-
- fc_host_max_npiv_vports(scsi_host) = (u16)((unf_lport == unf_lport->root_lport) ?
- unf_lport->low_level_func.support_max_npiv_num
- : 0);
- fc_host_npiv_vports_inuse(scsi_host) = 0;
- fc_host_next_vport_number(scsi_host) = 0;
-
- /* About speed mode */
- if (unf_lport->low_level_func.fc_ser_max_speed == UNF_PORT_SPEED_32_G &&
- unf_lport->card_type == UNF_FC_SERVER_BOARD_32_G) {
- speed = FC_PORTSPEED_32GBIT | FC_PORTSPEED_16GBIT | FC_PORTSPEED_8GBIT;
- } else if (unf_lport->low_level_func.fc_ser_max_speed == UNF_PORT_SPEED_16_G &&
- unf_lport->card_type == UNF_FC_SERVER_BOARD_16_G) {
- speed = FC_PORTSPEED_16GBIT | FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT;
- } else if (unf_lport->low_level_func.fc_ser_max_speed == UNF_PORT_SPEED_8_G &&
- unf_lport->card_type == UNF_FC_SERVER_BOARD_8_G) {
- speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT;
- }
-
- fc_host_supported_speeds(scsi_host) = speed;
-}
-
-int unf_alloc_scsi_host(struct Scsi_Host **unf_scsi_host,
- struct unf_host_param *host_param)
-{
- int ret = RETURN_ERROR;
- struct Scsi_Host *scsi_host = NULL;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(unf_scsi_host, RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(host_param, RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR, "[event]Alloc scsi host...");
-
- /* Check L_Port validity */
- unf_lport = (struct unf_lport *)(host_param->lport);
- if (unlikely(!unf_lport)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port is NULL and return directly");
-
- return RETURN_ERROR;
- }
-
- scsi_host_template.can_queue = host_param->can_queue;
- scsi_host_template.cmd_per_lun = host_param->cmnd_per_lun;
- scsi_host_template.sg_tablesize = host_param->sg_table_size;
- scsi_host_template.max_sectors = host_param->max_sectors;
-
- /* Alloc scsi host */
- scsi_host = scsi_host_alloc(&scsi_host_template, sizeof(u64));
- if (unlikely(!scsi_host)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR, "[err]Register scsi host failed");
-
- return RETURN_ERROR;
- }
-
- scsi_host->max_channel = host_param->max_channel;
- scsi_host->max_lun = host_param->max_lun;
- scsi_host->max_cmd_len = host_param->max_cmnd_len;
- scsi_host->unchecked_isa_dma = 0;
- scsi_host->hostdata[0] = (unsigned long)(uintptr_t)unf_lport; /* save lport to scsi */
- scsi_host->unique_id = scsi_host->host_no;
- scsi_host->max_id = host_param->max_id;
- scsi_host->transportt = (unf_lport == unf_lport->root_lport)
- ? scsi_transport_template
- : scsi_transport_template_v;
-
- /* register DIF/DIX protection */
- if (spfc_dif_enable) {
- /* Enable DIF and DIX function */
- scsi_host_set_prot(scsi_host, spfc_dif_type);
-
- spfc_guard = SHOST_DIX_GUARD_CRC;
- /* Enable IP checksum algorithm in DIX */
- if (dix_flag)
- spfc_guard |= SHOST_DIX_GUARD_IP;
- scsi_host_set_guard(scsi_host, spfc_guard);
- }
-
- /* Add scsi host */
- ret = scsi_add_host(scsi_host, host_param->pdev);
- if (unlikely(ret)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Add scsi host failed with return value %d", ret);
-
- scsi_host_put(scsi_host);
- return RETURN_ERROR;
- }
-
- /* Set scsi host attribute */
- unf_host_init_attr_setting(scsi_host);
- *unf_scsi_host = scsi_host;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[event]Alloc and add scsi host(0x%llx) succeed",
- (u64)scsi_host);
-
- return RETURN_OK;
-}
-
-void unf_free_scsi_host(struct Scsi_Host *unf_scsi_host)
-{
- struct Scsi_Host *scsi_host = NULL;
-
- scsi_host = unf_scsi_host;
- fc_remove_host(scsi_host);
- scsi_remove_host(scsi_host);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[event]Remove scsi host(%u) succeed", scsi_host->host_no);
-
- scsi_host_put(scsi_host);
-}
-
-u32 unf_register_ini_transport(void)
-{
- /* Register INI Transport */
- scsi_transport_template = fc_attach_transport(&function_template);
-
- if (!scsi_transport_template) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Register FC transport to scsi failed");
-
- return RETURN_ERROR;
- }
-
- scsi_transport_template_v = fc_attach_transport(&function_template_v);
- if (!scsi_transport_template_v) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Register FC vport transport to scsi failed");
-
- fc_release_transport(scsi_transport_template);
-
- return RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[event]Register FC transport to scsi succeed");
-
- return RETURN_OK;
-}
-
-void unf_unregister_ini_transport(void)
-{
- fc_release_transport(scsi_transport_template);
- fc_release_transport(scsi_transport_template_v);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[event]Unregister FC transport succeed");
-}
-
-void unf_save_sense_data(void *scsi_cmd, const char *sense, int sens_len)
-{
- struct scsi_cmnd *cmd = NULL;
-
- FC_CHECK_RETURN_VOID(scsi_cmd);
- FC_CHECK_RETURN_VOID(sense);
-
- cmd = (struct scsi_cmnd *)scsi_cmd;
- memcpy(cmd->sense_buffer, sense, sens_len);
-}
diff --git a/drivers/scsi/spfc/common/unf_scsi_common.h b/drivers/scsi/spfc/common/unf_scsi_common.h
deleted file mode 100644
index f20cdd7f0479..000000000000
--- a/drivers/scsi/spfc/common/unf_scsi_common.h
+++ /dev/null
@@ -1,570 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_SCSI_COMMON_H
-#define UNF_SCSI_COMMON_H
-
-#include "unf_type.h"
-
-#define SCSI_SENSE_DATA_LEN 96
-#define DRV_SCSI_CDB_LEN 16
-#define DRV_SCSI_LUN_LEN 8
-
-#define DRV_ENTRY_PER_SGL 64 /* Size of an entry array in a hash table */
-
-#define UNF_DIF_AREA_SIZE (8)
-
-struct unf_dif_control_info {
- u16 app_tag;
- u16 flags;
- u32 protect_opcode;
- u32 fcp_dl;
- u32 start_lba;
- u8 actual_dif[UNF_DIF_AREA_SIZE];
- u8 expected_dif[UNF_DIF_AREA_SIZE];
- u32 dif_sge_count;
- void *dif_sgl;
-};
-
-struct dif_result_info {
- unsigned char actual_idf[UNF_DIF_AREA_SIZE];
- unsigned char expect_dif[UNF_DIF_AREA_SIZE];
-};
-
-struct drv_sge {
- char *buf;
- void *page_ctrl;
- u32 Length;
- u32 offset;
-};
-
-struct drv_scsi_cmd_result {
- u32 Status;
- u16 sense_data_length; /* sense data length */
- u8 sense_data[SCSI_SENSE_DATA_LEN]; /* fail sense info */
-};
-
-enum drv_io_direction {
- DRV_IO_BIDIRECTIONAL = 0,
- DRV_IO_DIRECTION_WRITE = 1,
- DRV_IO_DIRECTION_READ = 2,
- DRV_IO_DIRECTION_NONE = 3,
-};
-
-struct drv_sgl {
- struct drv_sgl *next_sgl; /* poin to SGL,SGL list */
- unsigned short num_sges_in_chain;
- unsigned short num_sges_in_sgl;
- u32 flag;
- u64 serial_num;
- struct drv_sge sge[DRV_ENTRY_PER_SGL];
- struct list_head node;
- u32 cpu_id;
-};
-
-struct dif_info {
-/* Indicates the result returned when the data protection
- *information is inconsistent,add by pangea
- */
- struct dif_result_info dif_result;
-/* Data protection information operation code
- * bit[31-24] other operation code
- * bit[23-16] Data Protection Information Operation
- * bit[15-8] Data protection information
- * verification bit[7-0] Data protection information
- * replace
- */
- u32 protect_opcode;
- unsigned short apptag;
- u64 start_lba; /* IO start LBA */
- struct drv_sgl *protection_sgl;
-};
-
-struct drv_device_address {
- u16 initiator_id; /* ini id */
- u16 bus_id; /* device bus id */
- u16 target_id; /* device target id,for PCIe SSD,device id */
- u16 function_id; /* function id */
-};
-
-struct drv_ini_cmd {
- struct drv_scsi_cmd_result result;
- void *upper; /* product private pointer */
- void *lower; /* driver private pointer */
- u8 cdb[DRV_SCSI_CDB_LEN]; /* CDB edit by product */
- u8 lun[DRV_SCSI_LUN_LEN];
- u16 cmd_len;
- u16 tag; /* SCSI cmd add by driver */
- enum drv_io_direction io_direciton;
- u32 data_length;
- u32 underflow;
- u32 overflow;
- u32 resid;
- u64 port_id;
- u64 cmd_sn;
- struct drv_device_address addr;
- struct drv_sgl *sgl;
- void *device;
- void (*done)(struct drv_ini_cmd *cmd); /* callback pointer */
- struct dif_info dif_info;
-};
-
-typedef void (*uplevel_cmd_done)(struct drv_ini_cmd *scsi_cmnd);
-
-#ifndef SUCCESS
-#define SUCCESS 0x2002
-#endif
-#ifndef FAILED
-#define FAILED 0x2003
-#endif
-
-#ifndef DRIVER_OK
-#define DRIVER_OK 0x00 /* Driver status */
-#endif
-
-#ifndef PCI_FUNC
-#define PCI_FUNC(devfn) ((devfn) & 0x07)
-#endif
-
-#define UNF_SCSI_ABORT_SUCCESS SUCCESS
-#define UNF_SCSI_ABORT_FAIL FAILED
-
-#define UNF_SCSI_STATUS(byte) (byte)
-#define UNF_SCSI_MSG(byte) ((byte) << 8)
-#define UNF_SCSI_HOST(byte) ((byte) << 16)
-#define UNF_SCSI_DRIVER(byte) ((byte) << 24)
-#define UNF_GET_SCSI_HOST_ID(scsi_host) ((scsi_host)->host_no)
-
-struct unf_ini_error_code {
- u32 drv_errcode; /* driver error code */
- u32 ap_errcode; /* up level error code */
-};
-
-typedef u32 (*ini_get_sgl_entry_buf)(void *upper_cmnd, void *driver_sgl,
- void **upper_sgl, u32 *req_index,
- u32 *index, char **buf,
- u32 *buf_len);
-
-#define UNF_SCSI_SENSE_BUFFERSIZE 96
-struct unf_scsi_cmnd {
- u32 scsi_host_id;
- u32 scsi_id; /* cmd->dev->id */
- u64 raw_lun_id;
- u64 port_id;
- u32 under_flow; /* Underflow */
- u32 transfer_len; /* Transfer Length */
- u32 resid; /* Resid */
- u32 sense_buflen;
- int result;
- u32 entry_count; /* IO Buffer counter */
- u32 abort;
- u32 err_code_table_cout; /* error code size */
- u64 cmnd_sn;
- ulong time_out; /* EPL driver add timer */
- u16 cmnd_len; /* Cdb length */
- u8 data_direction; /* data direction */
- u8 *pcmnd; /* SCSI CDB */
- u8 *sense_buf;
- void *drv_private; /* driver host pionter */
- void *driver_scribble; /* Xchg pionter */
- void *upper_cmnd; /* UpperCmnd pointer by driver */
- u8 *lun_id; /* new lunid */
- u32 world_id;
- struct unf_dif_control_info dif_control; /* DIF control */
- struct unf_ini_error_code *err_code_table; /* error code table */
- void *sgl; /* Sgl pointer */
- ini_get_sgl_entry_buf unf_ini_get_sgl_entry;
- void (*done)(struct unf_scsi_cmnd *cmd);
- uplevel_cmd_done uplevel_done;
- struct dif_info dif_info;
- u32 qos_level;
- void *pinitiator;
-};
-
-#ifndef FC_PORTSPEED_32GBIT
-#define FC_PORTSPEED_32GBIT 0x40
-#endif
-
-#define UNF_GID_PORT_CNT 2048
-#define UNF_RSCN_PAGE_SUM 255
-
-#define UNF_CPU_ENDIAN
-
-#define UNF_NPORTID_MASK 0x00FFFFFF
-#define UNF_DOMAIN_MASK 0x00FF0000
-#define UNF_AREA_MASK 0x0000FF00
-#define UNF_ALPA_MASK 0x000000FF
-
-struct unf_fc_head {
- u32 rctl_did; /* Routing control and Destination address of the seq */
- u32 csctl_sid; /* Class control and Source address of the sequence */
- u32 type_fctl; /* Data type and Initial frame control value of the seq
- */
- u32 seqid_dfctl_seqcnt; /* Seq ID, Data Field and Initial seq count */
- u32 oxid_rxid; /* Originator & Responder exchange IDs for the sequence
- */
- u32 parameter; /* Relative offset of the first frame of the sequence */
-};
-
-#define UNF_FCPRSP_CTL_LEN (24)
-#define UNF_MAX_RSP_INFO_LEN (8)
-#define UNF_RSP_LEN_VLD (1 << 0)
-#define UNF_SENSE_LEN_VLD (1 << 1)
-#define UNF_RESID_OVERRUN (1 << 2)
-#define UNF_RESID_UNDERRUN (1 << 3)
-#define UNF_FCP_CONF_REQ (1 << 4)
-
-/* T10: FCP2r.07 9.4.1 Overview and format of FCP_RSP IU */
-struct unf_fcprsp_iu {
- u32 reserved[2];
- u8 reserved2[2];
- u8 control;
- u8 fcp_status;
- u32 fcp_residual;
- u32 fcp_sense_len; /* Length of sense info field */
- u32 fcp_response_len; /* Length of response info field in bytes 0,4 or 8
- */
- u8 fcp_resp_info[UNF_MAX_RSP_INFO_LEN]; /* Buffer for response info */
- u8 fcp_sense_info[SCSI_SENSE_DATA_LEN]; /* Buffer for sense info */
-} __attribute__((packed));
-
-#define UNF_CMD_REF_MASK 0xFF000000
-#define UNF_TASK_ATTR_MASK 0x00070000
-#define UNF_TASK_MGMT_MASK 0x0000FF00
-#define UNF_FCP_WR_DATA 0x00000001
-#define UNF_FCP_RD_DATA 0x00000002
-#define UNF_CDB_LEN_MASK 0x0000007C
-#define UNF_FCP_CDB_LEN_16 (16)
-#define UNF_FCP_CDB_LEN_32 (32)
-#define UNF_FCP_LUNID_LEN_8 (8)
-
-/* FCP-4 :Table 27 - RSP_CODE field */
-#define UNF_FCP_TM_RSP_COMPLETE (0)
-#define UNF_FCP_TM_INVALID_CMND (0x2)
-#define UNF_FCP_TM_RSP_REJECT (0x4)
-#define UNF_FCP_TM_RSP_FAIL (0x5)
-#define UNF_FCP_TM_RSP_SUCCEED (0x8)
-#define UNF_FCP_TM_RSP_INCRECT_LUN (0x9)
-
-#define UNF_SET_TASK_MGMT_FLAGS(fcp_tm_code) ((fcp_tm_code) << 8)
-#define UNF_GET_TASK_MGMT_FLAGS(control) (((control) & UNF_TASK_MGMT_MASK) >> 8)
-
-enum unf_task_mgmt_cmd {
- UNF_FCP_TM_QUERY_TASK_SET = (1 << 0),
- UNF_FCP_TM_ABORT_TASK_SET = (1 << 1),
- UNF_FCP_TM_CLEAR_TASK_SET = (1 << 2),
- UNF_FCP_TM_QUERY_UNIT_ATTENTION = (1 << 3),
- UNF_FCP_TM_LOGICAL_UNIT_RESET = (1 << 4),
- UNF_FCP_TM_TARGET_RESET = (1 << 5),
- UNF_FCP_TM_CLEAR_ACA = (1 << 6),
- UNF_FCP_TM_TERMINATE_TASK = (1 << 7) /* obsolete */
-};
-
-struct unf_fcp_cmnd {
- u8 lun[UNF_FCP_LUNID_LEN_8]; /* Logical unit number */
- u32 control;
- u8 cdb[UNF_FCP_CDB_LEN_16]; /* Payload data containing cdb info */
- u32 data_length; /* Number of bytes expected to be transferred */
-} __attribute__((packed));
-
-struct unf_fcp_cmd_hdr {
- struct unf_fc_head frame_hdr; /* FCHS structure */
- struct unf_fcp_cmnd fcp_cmnd; /* Fcp Cmnd struct */
-};
-
-/* FC-LS-2 Common Service Parameter applicability */
-struct unf_fabric_coparm {
-#if defined(UNF_CPU_ENDIAN)
- u32 bb_credit : 16; /* 0 [0-15] */
- u32 lowest_version : 8; /* 0 [16-23] */
- u32 highest_version : 8; /* 0 [24-31] */
-#else
- u32 highest_version : 8; /* 0 [24-31] */
- u32 lowest_version : 8; /* 0 [16-23] */
- u32 bb_credit : 16; /* 0 [0-15] */
-#endif
-
-#if defined(UNF_CPU_ENDIAN)
- u32 bb_receive_data_field_size : 12; /* 1 [0-11] */
- u32 bbscn : 4; /* 1 [12-15] */
- u32 payload_length : 1; /* 1 [16] */
- u32 seq_cnt : 1; /* 1 [17] */
- u32 dynamic_half_duplex : 1; /* 1 [18] */
- u32 r_t_tov : 1; /* 1 [19] */
- u32 reserved_co2 : 6; /* 1 [20-25] */
- u32 e_d_tov_resolution : 1; /* 1 [26] */
- u32 alternate_bb_credit_mgmt : 1; /* 1 [27] */
- u32 nport : 1; /* 1 [28] */
- u32 mnid_assignment : 1; /* 1 [29] */
- u32 random_relative_offset : 1; /* 1 [30] */
- u32 clean_address : 1; /* 1 [31] */
-#else
- u32 reserved_co2 : 2; /* 1 [24-25] */
- u32 e_d_tov_resolution : 1; /* 1 [26] */
- u32 alternate_bb_credit_mgmt : 1; /* 1 [27] */
- u32 nport : 1; /* 1 [28] */
- u32 mnid_assignment : 1; /* 1 [29] */
- u32 random_relative_offset : 1; /* 1 [30] */
- u32 clean_address : 1; /* 1 [31] */
-
- u32 payload_length : 1; /* 1 [16] */
- u32 seq_cnt : 1; /* 1 [17] */
- u32 dynamic_half_duplex : 1; /* 1 [18] */
- u32 r_t_tov : 1; /* 1 [19] */
- u32 reserved_co5 : 4; /* 1 [20-23] */
-
- u32 bb_receive_data_field_size : 12; /* 1 [0-11] */
- u32 bbscn : 4; /* 1 [12-15] */
-#endif
- u32 r_a_tov; /* 2 [0-31] */
- u32 e_d_tov; /* 3 [0-31] */
-};
-
-/* FC-LS-2 Common Service Parameter applicability */
-/*Common Service Parameters - PLOGI and PLOGI LS_ACC */
-struct lgn_port_coparm {
-#if defined(UNF_CPU_ENDIAN)
- u32 bb_credit : 16; /* 0 [0-15] */
- u32 lowest_version : 8; /* 0 [16-23] */
- u32 highest_version : 8; /* 0 [24-31] */
-#else
- u32 highest_version : 8; /* 0 [24-31] */
- u32 lowest_version : 8; /* 0 [16-23] */
- u32 bb_credit : 16; /* 0 [0-15] */
-#endif
-
-#if defined(UNF_CPU_ENDIAN)
- u32 bb_receive_data_field_size : 12; /* 1 [0-11] */
- u32 bbscn : 4; /* 1 [12-15] */
- u32 payload_length : 1; /* 1 [16] */
- u32 seq_cnt : 1; /* 1 [17] */
- u32 dynamic_half_duplex : 1; /* 1 [18] */
- u32 reserved_co2 : 7; /* 1 [19-25] */
- u32 e_d_tov_resolution : 1; /* 1 [26] */
- u32 alternate_bb_credit_mgmt : 1; /* 1 [27] */
- u32 nport : 1; /* 1 [28] */
- u32 vendor_version_level : 1; /* 1 [29] */
- u32 random_relative_offset : 1; /* 1 [30] */
- u32 continuously_increasing : 1; /* 1 [31] */
-#else
- u32 reserved_co2 : 2; /* 1 [24-25] */
- u32 e_d_tov_resolution : 1; /* 1 [26] */
- u32 alternate_bb_credit_mgmt : 1; /* 1 [27] */
- u32 nport : 1; /* 1 [28] */
- u32 vendor_version_level : 1; /* 1 [29] */
- u32 random_relative_offset : 1; /* 1 [30] */
- u32 continuously_increasing : 1; /* 1 [31] */
-
- u32 payload_length : 1; /* 1 [16] */
- u32 seq_cnt : 1; /* 1 [17] */
- u32 dynamic_half_duplex : 1; /* 1 [18] */
- u32 reserved_co5 : 5; /* 1 [19-23] */
-
- u32 bb_receive_data_field_size : 12; /* 1 [0-11] */
- u32 reserved_co1 : 4; /* 1 [12-15] */
-#endif
-
-#if defined(UNF_CPU_ENDIAN)
- u32 relative_offset : 16; /* 2 [0-15] */
- u32 nport_total_concurrent_sequences : 16; /* 2 [16-31] */
-#else
- u32 nport_total_concurrent_sequences : 16; /* 2 [16-31] */
- u32 relative_offset : 16; /* 2 [0-15] */
-#endif
-
- u32 e_d_tov;
-};
-
-/* FC-LS-2 Class Service Parameters Applicability */
-struct unf_lgn_port_clparm {
-#if defined(UNF_CPU_ENDIAN)
- u32 reserved_cl1 : 6; /* 0 [0-5] */
- u32 ic_data_compression_history_buffer_size : 2; /* 0 [6-7] */
- u32 ic_data_compression_capable : 1; /* 0 [8] */
-
- u32 ic_ack_generation_assistance : 1; /* 0 [9] */
- u32 ic_ack_n_capable : 1; /* 0 [10] */
- u32 ic_ack_o_capable : 1; /* 0 [11] */
- u32 ic_initial_responder_processes_accociator : 2; /* 0 [12-13] */
- u32 ic_x_id_reassignment : 2; /* 0 [14-15] */
-
- u32 reserved_cl2 : 7; /* 0 [16-22] */
- u32 priority : 1; /* 0 [23] */
- u32 buffered_class : 1; /* 0 [24] */
- u32 camp_on : 1; /* 0 [25] */
- u32 dedicated_simplex : 1; /* 0 [26] */
- u32 sequential_delivery : 1; /* 0 [27] */
- u32 stacked_connect_request : 2; /* 0 [28-29] */
- u32 intermix_mode : 1; /* 0 [30] */
- u32 valid : 1; /* 0 [31] */
-#else
- u32 buffered_class : 1; /* 0 [24] */
- u32 camp_on : 1; /* 0 [25] */
- u32 dedicated_simplex : 1; /* 0 [26] */
- u32 sequential_delivery : 1; /* 0 [27] */
- u32 stacked_connect_request : 2; /* 0 [28-29] */
- u32 intermix_mode : 1; /* 0 [30] */
- u32 valid : 1; /* 0 [31] */
- u32 reserved_cl2 : 7; /* 0 [16-22] */
- u32 priority : 1; /* 0 [23] */
- u32 ic_data_compression_capable : 1; /* 0 [8] */
- u32 ic_ack_generation_assistance : 1; /* 0 [9] */
- u32 ic_ack_n_capable : 1; /* 0 [10] */
- u32 ic_ack_o_capable : 1; /* 0 [11] */
- u32 ic_initial_responder_processes_accociator : 2; /* 0 [12-13] */
- u32 ic_x_id_reassignment : 2; /* 0 [14-15] */
-
- u32 reserved_cl1 : 6; /* 0 [0-5] */
- u32 ic_data_compression_history_buffer_size : 2; /* 0 [6-7] */
-#endif
-
-#if defined(UNF_CPU_ENDIAN)
- u32 received_data_field_size : 16; /* 1 [0-15] */
-
- u32 reserved_cl3 : 5; /* 1 [16-20] */
- u32 rc_data_compression_history_buffer_size : 2; /* 1 [21-22] */
- u32 rc_data_compression_capable : 1; /* 1 [23] */
-
- u32 rc_data_categories_per_sequence : 2; /* 1 [24-25] */
- u32 reserved_cl4 : 1; /* 1 [26] */
- u32 rc_error_policy_supported : 2; /* 1 [27-28] */
- u32 rc_x_id_interlock : 1; /* 1 [29] */
- u32 rc_ack_n_capable : 1; /* 1 [30] */
- u32 rc_ack_o_capable : 1; /* 1 [31] */
-#else
- u32 rc_data_categories_per_sequence : 2; /* 1 [24-25] */
- u32 reserved_cl4 : 1; /* 1 [26] */
- u32 rc_error_policy_supported : 2; /* 1 [27-28] */
- u32 rc_x_id_interlock : 1; /* 1 [29] */
- u32 rc_ack_n_capable : 1; /* 1 [30] */
- u32 rc_ack_o_capable : 1; /* 1 [31] */
-
- u32 reserved_cl3 : 5; /* 1 [16-20] */
- u32 rc_data_compression_history_buffer_size : 2; /* 1 [21-22] */
- u32 rc_data_compression_capable : 1; /* 1 [23] */
-
- u32 received_data_field_size : 16; /* 1 [0-15] */
-#endif
-
-#if defined(UNF_CPU_ENDIAN)
- u32 nport_end_to_end_credit : 15; /* 2 [0-14] */
- u32 reserved_cl5 : 1; /* 2 [15] */
-
- u32 concurrent_sequences : 16; /* 2 [16-31] */
-#else
- u32 concurrent_sequences : 16; /* 2 [16-31] */
-
- u32 nport_end_to_end_credit : 15; /* 2 [0-14] */
- u32 reserved_cl5 : 1; /* 2 [15] */
-#endif
-
-#if defined(UNF_CPU_ENDIAN)
- u32 reserved_cl6 : 16; /* 3 [0-15] */
- u32 open_sequence_per_exchange : 16; /* 3 [16-31] */
-#else
- u32 open_sequence_per_exchange : 16; /* 3 [16-31] */
- u32 reserved_cl6 : 16; /* 3 [0-15] */
-#endif
-};
-
-struct unf_fabric_parm {
- struct unf_fabric_coparm co_parms;
- u32 high_port_name;
- u32 low_port_name;
- u32 high_node_name;
- u32 low_node_name;
- struct unf_lgn_port_clparm cl_parms[3];
- u32 reserved_1[4];
- u32 vendor_version_level[4];
-};
-
-struct unf_lgn_parm {
- struct lgn_port_coparm co_parms;
- u32 high_port_name;
- u32 low_port_name;
- u32 high_node_name;
- u32 low_node_name;
- struct unf_lgn_port_clparm cl_parms[3];
- u32 reserved_1[4];
- u32 vendor_version_level[4];
-};
-
-#define ELS_RJT 0x1
-#define ELS_ACC 0x2
-#define ELS_PLOGI 0x3
-#define ELS_FLOGI 0x4
-#define ELS_LOGO 0x5
-#define ELS_ECHO 0x10
-#define ELS_RRQ 0x12
-#define ELS_REC 0x13
-#define ELS_PRLI 0x20
-#define ELS_PRLO 0x21
-#define ELS_TPRLO 0x24
-#define ELS_PDISC 0x50
-#define ELS_FDISC 0x51
-#define ELS_ADISC 0x52
-#define ELS_RSCN 0x61 /* registered state change notification */
-#define ELS_SCR 0x62 /* state change registration */
-
-#define NS_GIEL 0X0101
-#define NS_GA_NXT 0X0100
-#define NS_GPN_ID 0x0112 /* get port name by ID */
-#define NS_GNN_ID 0x0113 /* get node name by ID */
-#define NS_GFF_ID 0x011f /* get FC-4 features by ID */
-#define NS_GID_PN 0x0121 /* get ID for port name */
-#define NS_GID_NN 0x0131 /* get IDs for node name */
-#define NS_GID_FT 0x0171 /* get IDs by FC4 type */
-#define NS_GPN_FT 0x0172 /* get port names by FC4 type */
-#define NS_GID_PT 0x01a1 /* get IDs by port type */
-#define NS_RFT_ID 0x0217 /* reg FC4 type for ID */
-#define NS_RPN_ID 0x0212 /* reg port name for ID */
-#define NS_RNN_ID 0x0213 /* reg node name for ID */
-#define NS_RSNPN 0x0218 /* reg symbolic port name */
-#define NS_RFF_ID 0x021f /* reg FC4 Features for ID */
-#define NS_RSNN 0x0239 /* reg symbolic node name */
-#define ST_NULL 0xffff /* reg symbolic node name */
-
-#define BLS_ABTS 0xA001 /* ABTS */
-
-#define FCP_SRR 0x14 /* Sequence Retransmission Request */
-#define UNF_FC_FID_DOM_MGR 0xfffc00 /* domain manager base */
-enum unf_fc_well_known_fabric_id {
- UNF_FC_FID_NONE = 0x000000, /* No destination */
- UNF_FC_FID_DOM_CTRL = 0xfffc01, /* domain controller */
- UNF_FC_FID_BCAST = 0xffffff, /* broadcast */
- UNF_FC_FID_FLOGI = 0xfffffe, /* fabric login */
- UNF_FC_FID_FCTRL = 0xfffffd, /* fabric controller */
- UNF_FC_FID_DIR_SERV = 0xfffffc, /* directory server */
- UNF_FC_FID_TIME_SERV = 0xfffffb, /* time server */
- UNF_FC_FID_MGMT_SERV = 0xfffffa, /* management server */
- UNF_FC_FID_QOS = 0xfffff9, /* QoS Facilitator */
- UNF_FC_FID_ALIASES = 0xfffff8, /* alias server (FC-PH2) */
- UNF_FC_FID_SEC_KEY = 0xfffff7, /* Security key dist. server */
- UNF_FC_FID_CLOCK = 0xfffff6, /* clock synch server */
- UNF_FC_FID_MCAST_SERV = 0xfffff5 /* multicast server */
-};
-
-#define INVALID_WORLD_ID 0xfffffffc
-
-struct unf_host_param {
- int can_queue;
- u16 sg_table_size;
- short cmnd_per_lun;
- u32 max_id;
- u32 max_lun;
- u32 max_channel;
- u16 max_cmnd_len;
- u16 max_sectors;
- u64 dma_boundary;
- u32 port_id;
- void *lport;
- struct device *pdev;
-};
-
-int unf_alloc_scsi_host(struct Scsi_Host **unf_scsi_host, struct unf_host_param *host_param);
-void unf_free_scsi_host(struct Scsi_Host *unf_scsi_host);
-u32 unf_register_ini_transport(void);
-void unf_unregister_ini_transport(void);
-void unf_save_sense_data(void *scsi_cmd, const char *sense, int sens_len);
-
-#endif
diff --git a/drivers/scsi/spfc/common/unf_service.c b/drivers/scsi/spfc/common/unf_service.c
deleted file mode 100644
index 9c86c99374c8..000000000000
--- a/drivers/scsi/spfc/common/unf_service.c
+++ /dev/null
@@ -1,1430 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "unf_service.h"
-#include "unf_log.h"
-#include "unf_rport.h"
-#include "unf_ls.h"
-#include "unf_gs.h"
-
-struct unf_els_handle_table els_handle_table[] = {
- {ELS_PLOGI, unf_plogi_handler}, {ELS_FLOGI, unf_flogi_handler},
- {ELS_LOGO, unf_logo_handler}, {ELS_ECHO, unf_echo_handler},
- {ELS_RRQ, unf_rrq_handler}, {ELS_REC, unf_rec_handler},
- {ELS_PRLI, unf_prli_handler}, {ELS_PRLO, unf_prlo_handler},
- {ELS_PDISC, unf_pdisc_handler}, {ELS_ADISC, unf_adisc_handler},
- {ELS_RSCN, unf_rscn_handler} };
-
-u32 max_frame_size = UNF_DEFAULT_FRAME_SIZE;
-
-#define UNF_NEED_BIG_RESPONSE_BUFF(cmnd_code) \
- (((cmnd_code) == ELS_ECHO) || ((cmnd_code) == NS_GID_PT) || \
- ((cmnd_code) == NS_GID_FT))
-
-#define NEED_REFRESH_NPORTID(pkg) \
- ((((pkg)->cmnd == ELS_PLOGI) || ((pkg)->cmnd == ELS_PDISC) || \
- ((pkg)->cmnd == ELS_ADISC)))
-
-void unf_select_sq(struct unf_xchg *xchg, struct unf_frame_pkg *pkg)
-{
- u32 ssq_index = 0;
- struct unf_rport *unf_rport = NULL;
-
- if (likely(xchg)) {
- unf_rport = xchg->rport;
-
- if (unf_rport) {
- ssq_index = (xchg->hotpooltag % UNF_SQ_NUM_PER_SESSION) +
- unf_rport->sqn_base;
- }
- }
-
- pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX] = ssq_index;
-}
-
-u32 unf_ls_gs_cmnd_send(struct unf_lport *lport, struct unf_frame_pkg *pkg,
- struct unf_xchg *xchg)
-{
- u32 ret = UNF_RETURN_ERROR;
- ulong time_out = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- if (unlikely(!lport->low_level_func.service_op.unf_ls_gs_send)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) LS/GS send function is NULL",
- lport->port_id);
-
- return ret;
- }
-
- if (pkg->type == UNF_PKG_GS_REQ)
- time_out = UNF_GET_GS_SFS_XCHG_TIMER(lport);
- else
- time_out = UNF_GET_ELS_SFS_XCHG_TIMER(lport);
-
- if (xchg->cmnd_code == ELS_RRQ) {
- time_out = ((ulong)UNF_GET_ELS_SFS_XCHG_TIMER(lport) > UNF_RRQ_MIN_TIMEOUT_INTERVAL)
- ? (ulong)UNF_GET_ELS_SFS_XCHG_TIMER(lport)
- : UNF_RRQ_MIN_TIMEOUT_INTERVAL;
- } else if (xchg->cmnd_code == ELS_LOGO) {
- time_out = UNF_LOGO_TIMEOUT_INTERVAL;
- }
-
- pkg->private_data[PKG_PRIVATE_XCHG_TIMEER] = (u32)time_out;
- lport->xchg_mgr_temp.unf_xchg_add_timer((void *)xchg, time_out, UNF_TIMER_TYPE_SFS);
-
- unf_select_sq(xchg, pkg);
-
- ret = lport->low_level_func.service_op.unf_ls_gs_send(lport->fc_port, pkg);
- if (unlikely(ret != RETURN_OK))
- lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
-
- return ret;
-}
-
-static u32 unf_bls_cmnd_send(struct unf_lport *lport, struct unf_frame_pkg *pkg,
- struct unf_xchg *xchg)
-{
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- pkg->private_data[PKG_PRIVATE_XCHG_TIMEER] = (u32)UNF_GET_BLS_SFS_XCHG_TIMER(lport);
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME];
-
- unf_select_sq(xchg, pkg);
-
- return lport->low_level_func.service_op.unf_bls_send(lport->fc_port, pkg);
-}
-
-void unf_fill_package(struct unf_frame_pkg *pkg, struct unf_xchg *xchg,
- struct unf_rport *rport)
-{
- /* v_pstRport maybe NULL */
- FC_CHECK_RETURN_VOID(pkg);
- FC_CHECK_RETURN_VOID(xchg);
-
- pkg->cmnd = xchg->cmnd_code;
- pkg->fcp_cmnd = &xchg->fcp_cmnd;
- pkg->frame_head.csctl_sid = xchg->sid;
- pkg->frame_head.rctl_did = xchg->did;
- pkg->frame_head.oxid_rxid = ((u32)xchg->oxid << UNF_SHIFT_16 | xchg->rxid);
- pkg->xchg_contex = xchg;
-
- FC_CHECK_RETURN_VOID(xchg->lport);
- pkg->private_data[PKG_PRIVATE_XCHG_VP_INDEX] = xchg->lport->vp_index;
-
- if (!rport) {
- pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] = UNF_RPORT_INVALID_INDEX;
- pkg->private_data[PKG_PRIVATE_RPORT_RX_SIZE] = INVALID_VALUE32;
- } else {
- if (likely(rport->nport_id != UNF_FC_FID_FLOGI))
- pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] = rport->rport_index;
- else
- pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] = SPFC_DEFAULT_RPORT_INDEX;
-
- pkg->private_data[PKG_PRIVATE_RPORT_RX_SIZE] = rport->max_frame_size;
- }
-
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = xchg->hotpooltag;
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME];
- pkg->private_data[PKG_PRIVATE_LOWLEVEL_XCHG_ADD] =
- xchg->private_data[PKG_PRIVATE_LOWLEVEL_XCHG_ADD];
- pkg->unf_cmnd_pload_bl.buffer_ptr =
- (u8 *)xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- pkg->unf_cmnd_pload_bl.buf_dma_addr =
- xchg->fcp_sfs_union.sfs_entry.sfs_buff_phy_addr;
-
- /* Low level need to know payload length if send ECHO response */
- pkg->unf_cmnd_pload_bl.length = xchg->fcp_sfs_union.sfs_entry.cur_offset;
-}
-
-struct unf_xchg *unf_get_sfs_free_xchg_and_init(struct unf_lport *lport, u32 did,
- struct unf_rport *rport,
- union unf_sfs_u **fc_entry)
-{
- struct unf_xchg *xchg = NULL;
- union unf_sfs_u *sfs_fc_entry = NULL;
-
- xchg = unf_cm_get_free_xchg(lport, UNF_XCHG_TYPE_SFS);
- if (!xchg)
- return NULL;
-
- xchg->did = did;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
- xchg->disc_rport = NULL;
- xchg->callback = NULL;
- xchg->ob_callback = NULL;
-
- sfs_fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!sfs_fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return NULL;
- }
-
- *fc_entry = sfs_fc_entry;
-
- return xchg;
-}
-
-void *unf_get_one_big_sfs_buf(struct unf_xchg *xchg)
-{
- struct unf_big_sfs *big_sfs = NULL;
- struct list_head *list_head = NULL;
- struct unf_xchg_mgr *xchg_mgr = NULL;
- ulong flag = 0;
- spinlock_t *big_sfs_pool_lock = NULL;
-
- FC_CHECK_RETURN_VALUE(xchg, NULL);
- xchg_mgr = xchg->xchg_mgr;
- FC_CHECK_RETURN_VALUE(xchg_mgr, NULL);
- big_sfs_pool_lock = &xchg_mgr->big_sfs_pool.big_sfs_pool_lock;
-
- spin_lock_irqsave(big_sfs_pool_lock, flag);
- if (!list_empty(&xchg_mgr->big_sfs_pool.list_freepool)) {
- /* from free to busy */
- list_head = UNF_OS_LIST_NEXT(&xchg_mgr->big_sfs_pool.list_freepool);
- list_del(list_head);
- xchg_mgr->big_sfs_pool.free_count--;
- list_add_tail(list_head, &xchg_mgr->big_sfs_pool.list_busypool);
- big_sfs = list_entry(list_head, struct unf_big_sfs, entry_bigsfs);
- } else {
- spin_unlock_irqrestore(big_sfs_pool_lock, flag);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Allocate big sfs buf failed, count(0x%x) exchange(0x%p) command(0x%x)",
- xchg_mgr->big_sfs_pool.free_count, xchg, xchg->cmnd_code);
-
- return NULL;
- }
- spin_unlock_irqrestore(big_sfs_pool_lock, flag);
-
- xchg->big_sfs_buf = big_sfs;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Allocate one big sfs buffer(0x%p), remaining count(0x%x) exchange(0x%p) command(0x%x)",
- big_sfs->addr, xchg_mgr->big_sfs_pool.free_count, xchg,
- xchg->cmnd_code);
-
- return big_sfs->addr;
-}
-
-static void unf_fill_rjt_pld(struct unf_els_rjt *els_rjt, u32 reason_code,
- u32 reason_explanation)
-{
- FC_CHECK_RETURN_VOID(els_rjt);
-
- els_rjt->cmnd = UNF_ELS_CMND_RJT;
- els_rjt->reason_code = (reason_code | reason_explanation);
-}
-
-u32 unf_send_abts(struct unf_lport *lport, struct unf_xchg *xchg)
-{
- struct unf_rport *unf_rport = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct unf_frame_pkg pkg;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- unf_rport = xchg->rport;
- FC_CHECK_RETURN_VALUE(unf_rport, UNF_RETURN_ERROR);
-
- /* set pkg info */
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
- pkg.type = UNF_PKG_BLS_REQ;
- pkg.frame_head.csctl_sid = xchg->sid;
- pkg.frame_head.rctl_did = xchg->did;
- pkg.frame_head.oxid_rxid = ((u32)xchg->oxid << UNF_SHIFT_16 | xchg->rxid);
- pkg.xchg_contex = xchg;
- pkg.unf_cmnd_pload_bl.buffer_ptr = (u8 *)xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
-
- pkg.unf_cmnd_pload_bl.buf_dma_addr = xchg->fcp_sfs_union.sfs_entry.sfs_buff_phy_addr;
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = xchg->hotpooltag;
-
- UNF_SET_XCHG_ALLOC_TIME(&pkg, xchg);
- UNF_SET_ABORT_INFO_IOTYPE(&pkg, xchg);
-
- pkg.private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] =
- xchg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX];
-
- /* Send ABTS frame to target */
- ret = unf_bls_cmnd_send(lport, &pkg, xchg);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Port(0x%x_0x%x) send ABTS %s. Abort exch(0x%p) Cmdsn:0x%lx, tag(0x%x) iotype(0x%x)",
- lport->port_id, lport->nport_id,
- (ret == UNF_RETURN_ERROR) ? "failed" : "succeed", xchg,
- (ulong)xchg->cmnd_sn, xchg->hotpooltag, xchg->data_direction);
-
- return ret;
-}
-
-u32 unf_send_els_rjt_by_rport(struct unf_lport *lport, struct unf_xchg *xchg,
- struct unf_rport *rport, struct unf_rjt_info *rjt_info)
-{
- struct unf_els_rjt *els_rjt = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_frame_pkg pkg = {0};
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport, UNF_RETURN_ERROR);
-
- xchg->cmnd_code = UNF_SET_ELS_RJT_TYPE(rjt_info->els_cmnd_code);
- xchg->did = rport->nport_id;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = rport;
- xchg->disc_rport = NULL;
-
- xchg->callback = NULL;
- xchg->ob_callback = NULL;
-
- unf_fill_package(&pkg, xchg, rport);
- pkg.class_mode = UNF_FC_PROTOCOL_CLASS_3;
- pkg.type = UNF_PKG_ELS_REPLY;
-
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- els_rjt = &fc_entry->els_rjt;
- memset(els_rjt, 0, sizeof(struct unf_els_rjt));
- unf_fill_rjt_pld(els_rjt, rjt_info->reason_code, rjt_info->reason_explanation);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Send LS_RJT for 0x%x %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- rjt_info->els_cmnd_code,
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id,
- rport->nport_id, ox_id, rx_id);
-
- return ret;
-}
-
-u32 unf_send_els_rjt_by_did(struct unf_lport *lport, struct unf_xchg *xchg,
- u32 did, struct unf_rjt_info *rjt_info)
-{
- struct unf_els_rjt *els_rjt = NULL;
- union unf_sfs_u *fc_entry = NULL;
- struct unf_frame_pkg pkg = {0};
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = 0;
- u16 rx_id = 0;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- xchg->cmnd_code = UNF_SET_ELS_RJT_TYPE(rjt_info->els_cmnd_code);
- xchg->did = did;
- xchg->sid = lport->nport_id;
- xchg->oid = xchg->sid;
- xchg->lport = lport;
- xchg->rport = NULL;
- xchg->disc_rport = NULL;
-
- xchg->callback = NULL;
- xchg->ob_callback = NULL;
-
- unf_fill_package(&pkg, xchg, NULL);
- pkg.class_mode = UNF_FC_PROTOCOL_CLASS_3;
- pkg.type = UNF_PKG_ELS_REPLY;
-
- if (rjt_info->reason_code == UNF_LS_RJT_CLASS_ERROR &&
- rjt_info->class_mode != UNF_FC_PROTOCOL_CLASS_3) {
- pkg.class_mode = rjt_info->class_mode;
- }
-
- fc_entry = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr;
- if (!fc_entry) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) entry can't be NULL with tag(0x%x)",
- lport->port_id, xchg->hotpooltag);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
-
- els_rjt = &fc_entry->els_rjt;
- memset(els_rjt, 0, sizeof(struct unf_els_rjt));
- unf_fill_rjt_pld(els_rjt, rjt_info->reason_code, rjt_info->reason_explanation);
- ox_id = xchg->oxid;
- rx_id = xchg->rxid;
-
- ret = unf_ls_gs_cmnd_send(lport, &pkg, xchg);
- if (ret != RETURN_OK)
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]LOGIN: Send LS_RJT %s. Port(0x%x)--->RPort(0x%x) with OX_ID(0x%x) RX_ID(0x%x)",
- (ret != RETURN_OK) ? "failed" : "succeed", lport->port_id, did, ox_id, rx_id);
-
- return ret;
-}
-
-static u32 unf_els_cmnd_default_handler(struct unf_lport *lport, struct unf_xchg *xchg, u32 sid,
- u32 els_cmnd_code)
-{
- struct unf_rport *unf_rport = NULL;
- struct unf_rjt_info rjt_info = {0};
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(xchg, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_ABNORMAL, UNF_KEVENT,
- "[info]Receive Unknown ELS command(0x%x). Port(0x%x)<---RPort(0x%x) with OX_ID(0x%x)",
- els_cmnd_code, lport->port_id, sid, xchg->oxid);
-
- memset(&rjt_info, 0, sizeof(struct unf_rjt_info));
- rjt_info.els_cmnd_code = els_cmnd_code;
- rjt_info.reason_code = UNF_LS_RJT_NOT_SUPPORTED;
-
- unf_rport = unf_get_rport_by_nport_id(lport, sid);
- if (unf_rport)
- ret = unf_send_els_rjt_by_rport(lport, xchg, unf_rport, &rjt_info);
- else
- ret = unf_send_els_rjt_by_did(lport, xchg, sid, &rjt_info);
-
- return ret;
-}
-
-static struct unf_xchg *unf_alloc_xchg_for_rcv_cmnd(struct unf_lport *lport,
- struct unf_frame_pkg *pkg)
-{
- struct unf_xchg *xchg = NULL;
- ulong flags = 0;
- u32 i = 0;
- u32 offset = 0;
- u8 *cmnd_pld = NULL;
- u32 first_dword = 0;
- u32 alloc_time = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(pkg, NULL);
-
- if (!pkg->xchg_contex) {
- xchg = unf_cm_get_free_xchg(lport, UNF_XCHG_TYPE_SFS);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[warn]Port(0x%x) get new exchange failed",
- lport->port_id);
-
- return NULL;
- }
-
- offset = (xchg->fcp_sfs_union.sfs_entry.cur_offset);
- cmnd_pld = (u8 *)xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->rscn.rscn_pld;
- first_dword = xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr
- ->sfs_common.frame_head.rctl_did;
-
- if (cmnd_pld || first_dword != 0 || offset != 0) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) exchange(0x%p) abnormal, maybe data overrun, start(%llu) command(0x%x)",
- lport->port_id, xchg, xchg->alloc_jif, pkg->cmnd);
-
- UNF_PRINT_SFS(UNF_INFO, lport->port_id,
- xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr,
- sizeof(union unf_sfs_u));
- }
-
- memset(xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr, 0, sizeof(union unf_sfs_u));
-
- pkg->xchg_contex = (void *)xchg;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- xchg->fcp_sfs_union.sfs_entry.cur_offset = 0;
- alloc_time = xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME];
- for (i = 0; i < PKG_MAX_PRIVATE_DATA_SIZE; i++)
- xchg->private_data[i] = pkg->private_data[i];
-
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = alloc_time;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- } else {
- xchg = (struct unf_xchg *)pkg->xchg_contex;
- }
-
- if (!xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr) {
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- return NULL;
- }
-
- return xchg;
-}
-
-static u8 *unf_calc_big_cmnd_pld_buffer(struct unf_xchg *xchg, u32 cmnd_code)
-{
- u8 *cmnd_pld = NULL;
- void *buf = NULL;
- u8 *dest = NULL;
-
- FC_CHECK_RETURN_VALUE(xchg, NULL);
-
- if (cmnd_code == ELS_RSCN)
- cmnd_pld = (u8 *)xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->rscn.rscn_pld;
- else
- cmnd_pld = (u8 *)xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo.echo_pld;
-
- if (!cmnd_pld) {
- buf = unf_get_one_big_sfs_buf(xchg);
- if (!buf)
- return NULL;
-
- if (cmnd_code == ELS_RSCN) {
- memset(buf, 0, sizeof(struct unf_rscn_pld));
- xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->rscn.rscn_pld = buf;
- } else {
- memset(buf, 0, sizeof(struct unf_echo_payload));
- xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo.echo_pld = buf;
- }
-
- dest = (u8 *)buf;
- } else {
- dest = (u8 *)(cmnd_pld + xchg->fcp_sfs_union.sfs_entry.cur_offset);
- }
-
- return dest;
-}
-
-static u8 *unf_calc_other_pld_buffer(struct unf_xchg *xchg)
-{
- u8 *dest = NULL;
- u32 offset = 0;
-
- FC_CHECK_RETURN_VALUE(xchg, NULL);
-
- offset = (sizeof(struct unf_fc_head)) + (xchg->fcp_sfs_union.sfs_entry.cur_offset);
- dest = (u8 *)((u8 *)(xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr) + offset);
-
- return dest;
-}
-
-struct unf_xchg *unf_mv_data_2_xchg(struct unf_lport *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_xchg *xchg = NULL;
- u8 *dest = NULL;
- u32 length = 0;
- ulong flags = 0;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
- FC_CHECK_RETURN_VALUE(pkg, NULL);
-
- xchg = unf_alloc_xchg_for_rcv_cmnd(lport, pkg);
- if (!xchg)
- return NULL;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
-
- memcpy(&xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->sfs_common.frame_head,
- &pkg->frame_head, sizeof(pkg->frame_head));
-
- if (pkg->cmnd == ELS_RSCN || pkg->cmnd == ELS_ECHO)
- dest = unf_calc_big_cmnd_pld_buffer(xchg, pkg->cmnd);
- else
- dest = unf_calc_other_pld_buffer(xchg);
-
- if (!dest) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- return NULL;
- }
-
- if (((xchg->fcp_sfs_union.sfs_entry.cur_offset +
- pkg->unf_cmnd_pload_bl.length) > (u32)sizeof(union unf_sfs_u)) &&
- pkg->cmnd != ELS_RSCN && pkg->cmnd != ELS_ECHO) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) excange(0x%p) command(0x%x,0x%x) copy payload overrun(0x%x:0x%x:0x%x)",
- lport->port_id, xchg, pkg->cmnd, xchg->hotpooltag,
- xchg->fcp_sfs_union.sfs_entry.cur_offset,
- pkg->unf_cmnd_pload_bl.length, (u32)sizeof(union unf_sfs_u));
-
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- unf_cm_free_xchg((void *)lport, (void *)xchg);
-
- return NULL;
- }
-
- length = pkg->unf_cmnd_pload_bl.length;
- if (length > 0)
- memcpy(dest, pkg->unf_cmnd_pload_bl.buffer_ptr, length);
-
- xchg->fcp_sfs_union.sfs_entry.cur_offset += length;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- return xchg;
-}
-
-static u32 unf_check_els_cmnd_valid(struct unf_lport *lport, struct unf_frame_pkg *pkg,
- struct unf_xchg *xchg)
-{
- struct unf_rjt_info rjt_info = {0};
- struct unf_lport *vport = NULL;
- u32 sid = 0;
- u32 did = 0;
-
- sid = (pkg->frame_head.csctl_sid) & UNF_NPORTID_MASK;
- did = (pkg->frame_head.rctl_did) & UNF_NPORTID_MASK;
-
- memset(&rjt_info, 0, sizeof(struct unf_rjt_info));
-
- if (pkg->class_mode != UNF_FC_PROTOCOL_CLASS_3) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) unsupport class 0x%x cmd 0x%x and send RJT",
- lport->port_id, pkg->class_mode, pkg->cmnd);
-
- rjt_info.reason_code = UNF_LS_RJT_CLASS_ERROR;
- rjt_info.els_cmnd_code = pkg->cmnd;
- rjt_info.class_mode = pkg->class_mode;
- (void)unf_send_els_rjt_by_did(lport, xchg, sid, &rjt_info);
-
- return UNF_RETURN_ERROR;
- }
-
- rjt_info.reason_code = UNF_LS_RJT_NOT_SUPPORTED;
-
- if (pkg->cmnd == ELS_FLOGI && lport->act_topo == UNF_ACT_TOP_PRIVATE_LOOP) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) receive FLOGI in top (0x%x) and send LS_RJT",
- lport->port_id, lport->act_topo);
-
- rjt_info.els_cmnd_code = ELS_FLOGI;
- (void)unf_send_els_rjt_by_did(lport, xchg, sid, &rjt_info);
-
- return UNF_RETURN_ERROR;
- }
-
- if (pkg->cmnd == ELS_PLOGI && did >= UNF_FC_FID_DOM_MGR) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x)receive PLOGI with wellknown address(0x%x) and Send LS_RJT",
- lport->port_id, did);
-
- rjt_info.els_cmnd_code = ELS_PLOGI;
- (void)unf_send_els_rjt_by_did(lport, xchg, sid, &rjt_info);
-
- return UNF_RETURN_ERROR;
- }
-
- if ((lport->nport_id == 0 || lport->nport_id == INVALID_VALUE32) &&
- (NEED_REFRESH_NPORTID(pkg))) {
- lport->nport_id = did;
- } else if ((lport->nport_id != did) && (pkg->cmnd != ELS_FLOGI)) {
- vport = unf_cm_lookup_vport_by_did(lport, did);
- if (!vport) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive ELS cmd(0x%x) with abnormal D_ID(0x%x)",
- lport->nport_id, pkg->cmnd, did);
-
- unf_cm_free_xchg(lport, xchg);
- return UNF_RETURN_ERROR;
- }
- }
-
- return RETURN_OK;
-}
-
-static u32 unf_rcv_els_cmnd_req(struct unf_lport *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_xchg *xchg = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 i = 0;
- u32 sid = 0;
- u32 did = 0;
- struct unf_lport *vport = NULL;
- u32 (*els_cmnd_handler)(struct unf_lport *, u32, struct unf_xchg *) = NULL;
-
- sid = (pkg->frame_head.csctl_sid) & UNF_NPORTID_MASK;
- did = (pkg->frame_head.rctl_did) & UNF_NPORTID_MASK;
-
- xchg = unf_mv_data_2_xchg(lport, pkg);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) receive ElsCmnd(0x%x), exchange is NULL",
- lport->port_id, pkg->cmnd);
- return UNF_RETURN_ERROR;
- }
-
- if (!pkg->last_pkg_flag) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Exchange(%u) waiting for last WQE",
- xchg->hotpooltag);
- return RETURN_OK;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Exchange(%u) get last WQE", xchg->hotpooltag);
-
- xchg->oxid = UNF_GET_OXID(pkg);
- xchg->abort_oxid = xchg->oxid;
- xchg->rxid = UNF_GET_RXID(pkg);
- xchg->cmnd_code = pkg->cmnd;
-
- ret = unf_check_els_cmnd_valid(lport, pkg, xchg);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
-
- if (lport->nport_id != did && pkg->cmnd != ELS_FLOGI) {
- vport = unf_cm_lookup_vport_by_did(lport, did);
- if (!vport) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) received unknown ELS command with S_ID(0x%x) D_ID(0x%x))",
- lport->port_id, sid, did);
- return UNF_RETURN_ERROR;
- }
- lport = vport;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]VPort(0x%x) received ELS command with S_ID(0x%x) D_ID(0x%x)",
- lport->port_id, sid, did);
- }
-
- do {
- if (pkg->cmnd == els_handle_table[i].cmnd) {
- els_cmnd_handler = els_handle_table[i].els_cmnd_handler;
- break;
- }
- i++;
- } while (i < (sizeof(els_handle_table) / sizeof(struct unf_els_handle_table)));
-
- if (els_cmnd_handler) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) receive ELS(0x%x) from RPort(0x%x) and process it",
- lport->port_id, pkg->cmnd, sid);
- ret = els_cmnd_handler(lport, sid, xchg);
- } else {
- ret = unf_els_cmnd_default_handler(lport, xchg, sid, pkg->cmnd);
- }
- return ret;
-}
-
-u32 unf_send_els_rsp_succ(struct unf_lport *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_xchg *xchg = NULL;
- u32 ret = RETURN_OK;
- u16 hot_pool_tag = 0;
- ulong flags = 0;
- void (*ob_callback)(struct unf_xchg *) = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- if (!lport->xchg_mgr_temp.unf_look_up_xchg_by_tag) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) lookup exchange by tag function is NULL",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- hot_pool_tag = (u16)(pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX]);
- xchg = (struct unf_xchg *)(lport->xchg_mgr_temp.unf_look_up_xchg_by_tag((void *)lport,
- hot_pool_tag));
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) find exhange by tag(0x%x) failed",
- lport->port_id, hot_pool_tag);
-
- return UNF_RETURN_ERROR;
- }
-
- lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if (xchg->ob_callback &&
- (!(xchg->io_state & TGT_IO_STATE_ABORT))) {
- ob_callback = xchg->ob_callback;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) with exchange(0x%p) tag(0x%x) do callback",
- lport->port_id, xchg, hot_pool_tag);
-
- ob_callback(xchg);
- } else {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- }
-
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- return ret;
-}
-
-static u8 *unf_calc_big_resp_pld_buffer(struct unf_xchg *xchg, u32 cmnd_code)
-{
- u8 *resp_pld = NULL;
- u8 *dest = NULL;
-
- FC_CHECK_RETURN_VALUE(xchg, NULL);
-
- if (cmnd_code == ELS_ECHO) {
- resp_pld = (u8 *)xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr->echo.echo_pld;
- } else {
- resp_pld = (u8 *)xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr
- ->get_id.gid_rsp.gid_acc_pld;
- }
-
- if (resp_pld)
- dest = (u8 *)(resp_pld + xchg->fcp_sfs_union.sfs_entry.cur_offset);
-
- return dest;
-}
-
-static u8 *unf_calc_other_resp_pld_buffer(struct unf_xchg *xchg)
-{
- u8 *dest = NULL;
- u32 offset = 0;
-
- FC_CHECK_RETURN_VALUE(xchg, NULL);
-
- offset = xchg->fcp_sfs_union.sfs_entry.cur_offset;
- dest = (u8 *)((u8 *)(xchg->fcp_sfs_union.sfs_entry.fc_sfs_entry_ptr) + offset);
-
- return dest;
-}
-
-u32 unf_mv_resp_2_xchg(struct unf_xchg *xchg, struct unf_frame_pkg *pkg)
-{
- u8 *dest = NULL;
- u32 length = 0;
- u32 offset = 0;
- u32 max_frame_len = 0;
- ulong flags = 0;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
-
- if (UNF_NEED_BIG_RESPONSE_BUFF(xchg->cmnd_code)) {
- dest = unf_calc_big_resp_pld_buffer(xchg, xchg->cmnd_code);
- offset = 0;
- max_frame_len = sizeof(struct unf_gid_acc_pld);
- } else if (NS_GA_NXT == xchg->cmnd_code || NS_GIEL == xchg->cmnd_code) {
- dest = unf_calc_big_resp_pld_buffer(xchg, xchg->cmnd_code);
- offset = 0;
- max_frame_len = xchg->fcp_sfs_union.sfs_entry.sfs_buff_len;
- } else {
- dest = unf_calc_other_resp_pld_buffer(xchg);
- offset = sizeof(struct unf_fc_head);
- max_frame_len = sizeof(union unf_sfs_u);
- }
-
- if (!dest) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- return UNF_RETURN_ERROR;
- }
-
- if (xchg->fcp_sfs_union.sfs_entry.cur_offset == 0) {
- xchg->fcp_sfs_union.sfs_entry.cur_offset += offset;
- dest = dest + offset;
- }
-
- length = pkg->unf_cmnd_pload_bl.length;
-
- if ((xchg->fcp_sfs_union.sfs_entry.cur_offset + length) >
- max_frame_len) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Exchange(0x%p) command(0x%x) hotpooltag(0x%x) OX_RX_ID(0x%x) S_ID(0x%x) D_ID(0x%x) copy payload overrun(0x%x:0x%x:0x%x)",
- xchg, xchg->cmnd_code, xchg->hotpooltag, pkg->frame_head.oxid_rxid,
- pkg->frame_head.csctl_sid & UNF_NPORTID_MASK,
- pkg->frame_head.rctl_did & UNF_NPORTID_MASK,
- xchg->fcp_sfs_union.sfs_entry.cur_offset,
- pkg->unf_cmnd_pload_bl.length, max_frame_len);
-
- length = max_frame_len - xchg->fcp_sfs_union.sfs_entry.cur_offset;
- }
-
- if (length > 0)
- memcpy(dest, pkg->unf_cmnd_pload_bl.buffer_ptr, length);
-
- xchg->fcp_sfs_union.sfs_entry.cur_offset += length;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- return RETURN_OK;
-}
-
-static void unf_ls_gs_do_callback(struct unf_xchg *xchg,
- struct unf_frame_pkg *pkg)
-{
- ulong flags = 0;
- void (*callback)(void *, void *, void *) = NULL;
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if (xchg->callback &&
- (xchg->cmnd_code == ELS_RRQ ||
- xchg->cmnd_code == ELS_LOGO ||
- !(xchg->io_state & TGT_IO_STATE_ABORT))) {
- callback = xchg->callback;
-
- if (xchg->cmnd_code == ELS_FLOGI || xchg->cmnd_code == ELS_FDISC)
- xchg->sid = pkg->frame_head.rctl_did & UNF_NPORTID_MASK;
-
- if (xchg->cmnd_code == ELS_ECHO) {
- xchg->private_data[PKG_PRIVATE_ECHO_CMD_RCV_TIME] =
- pkg->private_data[PKG_PRIVATE_ECHO_CMD_RCV_TIME];
- xchg->private_data[PKG_PRIVATE_ECHO_RSP_SND_TIME] =
- pkg->private_data[PKG_PRIVATE_ECHO_RSP_SND_TIME];
- xchg->private_data[PKG_PRIVATE_ECHO_CMD_SND_TIME] =
- pkg->private_data[PKG_PRIVATE_ECHO_CMD_SND_TIME];
- xchg->private_data[PKG_PRIVATE_ECHO_ACC_RCV_TIME] =
- pkg->private_data[PKG_PRIVATE_ECHO_ACC_RCV_TIME];
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- callback(xchg->lport, xchg->rport, xchg);
- } else {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- }
-}
-
-u32 unf_send_ls_gs_cmnd_succ(struct unf_lport *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_xchg *xchg = NULL;
- u32 ret = RETURN_OK;
- u16 hot_pool_tag = 0;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- unf_lport = lport;
-
- if (!unf_lport->xchg_mgr_temp.unf_look_up_xchg_by_tag) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) lookup exchange by tag function can't be NULL",
- unf_lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- hot_pool_tag = (u16)(pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX]);
- xchg = (struct unf_xchg *)(unf_lport->xchg_mgr_temp
- .unf_look_up_xchg_by_tag((void *)unf_lport, hot_pool_tag));
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) find exchange by tag(0x%x) failed",
- unf_lport->port_id, unf_lport->nport_id, hot_pool_tag);
-
- return UNF_RETURN_ERROR;
- }
-
- UNF_CHECK_ALLOCTIME_VALID(unf_lport, hot_pool_tag, xchg,
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME],
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME]);
-
- if ((pkg->frame_head.csctl_sid & UNF_NPORTID_MASK) != xchg->did) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) find exhange invalid, package S_ID(0x%x) exchange S_ID(0x%x) D_ID(0x%x)",
- unf_lport->port_id, pkg->frame_head.csctl_sid, xchg->sid, xchg->did);
-
- return UNF_RETURN_ERROR;
- }
-
- if (pkg->last_pkg_flag == UNF_PKG_NOT_LAST_RESPONSE) {
- ret = unf_mv_resp_2_xchg(xchg, pkg);
- return ret;
- }
-
- xchg->byte_orders = pkg->byte_orders;
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
- unf_ls_gs_do_callback(xchg, pkg);
- unf_cm_free_xchg((void *)unf_lport, (void *)xchg);
- return ret;
-}
-
-u32 unf_send_ls_gs_cmnd_failed(struct unf_lport *lport,
- struct unf_frame_pkg *pkg)
-{
- struct unf_xchg *xchg = NULL;
- u32 ret = RETURN_OK;
- u16 hot_pool_tag = 0;
- ulong flags = 0;
- void (*ob_callback)(struct unf_xchg *) = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- if (!lport->xchg_mgr_temp.unf_look_up_xchg_by_tag) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) lookup exchange by tag function can't be NULL",
- lport->port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- hot_pool_tag = (u16)(pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX]);
- xchg = (struct unf_xchg *)(lport->xchg_mgr_temp.unf_look_up_xchg_by_tag((void *)lport,
- hot_pool_tag));
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) find exhange by tag(0x%x) failed",
- lport->port_id, lport->nport_id, hot_pool_tag);
-
- return UNF_RETURN_ERROR;
- }
-
- UNF_CHECK_ALLOCTIME_VALID(lport, hot_pool_tag, xchg,
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME],
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME]);
-
- lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if (xchg->ob_callback &&
- (xchg->cmnd_code == ELS_RRQ || xchg->cmnd_code == ELS_LOGO ||
- (!(xchg->io_state & TGT_IO_STATE_ABORT)))) {
- ob_callback = xchg->ob_callback;
- xchg->ob_callback_sts = pkg->status;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- ob_callback(xchg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) exchange(0x%p) tag(0x%x) do callback",
- lport->port_id, xchg, hot_pool_tag);
- } else {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- }
-
- unf_cm_free_xchg((void *)lport, (void *)xchg);
- return ret;
-}
-
-static u32 unf_rcv_ls_gs_cmnd_reply(struct unf_lport *lport,
- struct unf_frame_pkg *pkg)
-{
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- if (pkg->status == UNF_IO_SUCCESS || pkg->status == UNF_IO_UNDER_FLOW)
- ret = unf_send_ls_gs_cmnd_succ(lport, pkg);
- else
- ret = unf_send_ls_gs_cmnd_failed(lport, pkg);
-
- return ret;
-}
-
-u32 unf_receive_ls_gs_pkg(void *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_lport *unf_lport = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- unf_lport = (struct unf_lport *)lport;
-
- switch (pkg->type) {
- case UNF_PKG_ELS_REQ_DONE:
- case UNF_PKG_GS_REQ_DONE:
- ret = unf_rcv_ls_gs_cmnd_reply(unf_lport, pkg);
- break;
-
- case UNF_PKG_ELS_REQ:
- ret = unf_rcv_els_cmnd_req(unf_lport, pkg);
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) with exchange type(0x%x) abnormal",
- unf_lport->port_id, unf_lport->nport_id, pkg->type);
- break;
- }
-
- return ret;
-}
-
-u32 unf_send_els_done(void *lport, struct unf_frame_pkg *pkg)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- if (pkg->type == UNF_PKG_ELS_REPLY_DONE) {
- if (pkg->status == UNF_IO_SUCCESS || pkg->status == UNF_IO_UNDER_FLOW)
- ret = unf_send_els_rsp_succ(lport, pkg);
- else
- ret = unf_send_ls_gs_cmnd_failed(lport, pkg);
- }
-
- return ret;
-}
-
-void unf_rport_immediate_link_down(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* Swap case: Report Link Down immediately & release R_Port */
- ulong flags = 0;
- struct unf_disc *disc = NULL;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&rport->rport_state_lock, flags);
- /* 1. Inc R_Port ref_cnt */
- if (unf_rport_ref_inc(rport) != RETURN_OK) {
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) Rport(0x%p,0x%x) is removing and no need process",
- lport->port_id, rport, rport->nport_id);
-
- return;
- }
-
- /* 2. R_PORT state update: Link Down Event --->>> closing state */
- unf_rport_state_ma(rport, UNF_EVENT_RPORT_LINK_DOWN);
- spin_unlock_irqrestore(&rport->rport_state_lock, flags);
-
- /* 3. Put R_Port from busy to destroy list */
- disc = &lport->disc;
- spin_lock_irqsave(&disc->rport_busy_pool_lock, flags);
- list_del_init(&rport->entry_rport);
- list_add_tail(&rport->entry_rport, &disc->list_destroy_rports);
- spin_unlock_irqrestore(&disc->rport_busy_pool_lock, flags);
-
- /* 4. Schedule Closing work (Enqueuing workqueue) */
- unf_schedule_closing_work(lport, rport);
-
- unf_rport_ref_dec(rport);
-}
-
-struct unf_rport *unf_find_rport(struct unf_lport *lport, u32 rport_nport_id,
- u64 lport_name)
-{
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, NULL);
-
- if (rport_nport_id >= UNF_FC_FID_DOM_MGR) {
- /* R_Port is Fabric: by N_Port_ID */
- unf_rport = unf_get_rport_by_nport_id(unf_lport, rport_nport_id);
- } else {
- /* Others: by WWPN & N_Port_ID */
- unf_rport = unf_find_valid_rport(unf_lport, lport_name, rport_nport_id);
- }
-
- return unf_rport;
-}
-
-void unf_process_logo_in_pri_loop(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* Send PLOGI or LOGO */
- struct unf_rport *unf_rport = rport;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI); /* PLOGI WAIT */
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- /* Private Loop with INI mode, Avoid COM Mode problem */
- unf_rport_delay_login(unf_rport);
-}
-
-void unf_process_logo_in_n2n(struct unf_lport *lport, struct unf_rport *rport)
-{
- /* Send PLOGI or LOGO */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- spin_lock_irqsave(&unf_rport->rport_state_lock, flag);
-
- unf_rport_state_ma(unf_rport, UNF_EVENT_RPORT_ENTER_PLOGI);
- spin_unlock_irqrestore(&unf_rport->rport_state_lock, flag);
-
- if (unf_lport->port_name > unf_rport->port_name) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x)'s WWN(0x%llx) is larger than(0x%llx), should be master",
- unf_lport->port_id, unf_lport->port_name, unf_rport->port_name);
-
- ret = unf_send_plogi(unf_lport, unf_rport);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]LOGIN: Port(0x%x) send PLOGI failed, enter recovery",
- lport->port_id);
-
- unf_rport_error_recovery(unf_rport);
- }
- } else {
- unf_rport_enter_logo(unf_lport, unf_rport);
- }
-}
-
-void unf_process_logo_in_fabric(struct unf_lport *lport,
- struct unf_rport *rport)
-{
- /* Send GFF_ID or LOGO */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
- struct unf_rport *sns_port = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- /* L_Port with INI Mode: Send GFF_ID */
- sns_port = unf_get_rport_by_nport_id(unf_lport, UNF_FC_FID_DIR_SERV);
- if (!sns_port) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't find fabric port",
- unf_lport->port_id);
- return;
- }
-
- ret = unf_get_and_post_disc_event(lport, sns_port, unf_rport->nport_id,
- UNF_DISC_GET_FEATURE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) add discovery event(0x%x) failed Rport(0x%x)",
- unf_lport->port_id, UNF_DISC_GET_FEATURE,
- unf_rport->nport_id);
-
- unf_rcv_gff_id_rsp_unknown(unf_lport, unf_rport->nport_id);
- }
-}
-
-void unf_process_rport_after_logo(struct unf_lport *lport, struct unf_rport *rport)
-{
- /*
- * 1. LOGO handler
- * 2. RPLO handler
- * 3. LOGO_CALL_BACK (send LOGO ACC) handler
- */
- struct unf_lport *unf_lport = lport;
- struct unf_rport *unf_rport = rport;
-
- FC_CHECK_RETURN_VOID(lport);
- FC_CHECK_RETURN_VOID(rport);
-
- if (unf_rport->nport_id < UNF_FC_FID_DOM_MGR) {
- /* R_Port is not fabric port (retry LOGIN or LOGO) */
- if (unf_lport->act_topo == UNF_ACT_TOP_PRIVATE_LOOP) {
- /* Private Loop: PLOGI or LOGO */
- unf_process_logo_in_pri_loop(unf_lport, unf_rport);
- } else if (unf_lport->act_topo == UNF_ACT_TOP_P2P_DIRECT) {
- /* Point to Point: LOGIN or LOGO */
- unf_process_logo_in_n2n(unf_lport, unf_rport);
- } else {
- /* Fabric or Public Loop: GFF_ID or LOGO */
- unf_process_logo_in_fabric(unf_lport, unf_rport);
- }
- } else {
- /* Rport is fabric port: link down now */
- unf_rport_linkdown(unf_lport, unf_rport);
- }
-}
-
-static u32 unf_rcv_bls_req_done(struct unf_lport *lport, struct unf_frame_pkg *pkg)
-{
- /*
- * About I/O resource:
- * 1. normal: Release I/O resource during RRQ processer
- * 2. exception: Release I/O resource immediately
- */
- struct unf_xchg *xchg = NULL;
- u16 hot_pool_tag = 0;
- ulong flags = 0;
- ulong time_ms = 0;
- u32 ret = RETURN_OK;
- struct unf_lport *unf_lport = NULL;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- unf_lport = lport;
-
- hot_pool_tag = (u16)pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX];
- xchg = (struct unf_xchg *)unf_cm_lookup_xchg_by_tag((void *)unf_lport, hot_pool_tag);
- if (!xchg) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) can't find exchange by tag(0x%x) when receiving ABTS response",
- unf_lport->port_id, hot_pool_tag);
- return UNF_RETURN_ERROR;
- }
-
- UNF_CHECK_ALLOCTIME_VALID(lport, hot_pool_tag, xchg,
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME],
- xchg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME]);
-
- ret = unf_xchg_ref_inc(xchg, TGT_ABTS_DONE);
- FC_CHECK_RETURN_VALUE((ret == RETURN_OK), UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- xchg->oxid = UNF_GET_OXID(pkg);
- xchg->rxid = UNF_GET_RXID(pkg);
- xchg->io_state |= INI_IO_STATE_DONE;
- xchg->abts_state |= ABTS_RESPONSE_RECEIVED;
- if (!(INI_IO_STATE_UPABORT & xchg->io_state)) {
- /* NOTE: I/O exchange has been released and used again */
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x_0x%x) SID(0x%x) exch(0x%p) (0x%x:0x%x:0x%x:0x%x) state(0x%x) is abnormal with cnt(0x%x)",
- unf_lport->port_id, unf_lport->nport_id, xchg->sid,
- xchg, xchg->hotpooltag, xchg->oxid, xchg->rxid,
- xchg->oid, xchg->io_state,
- atomic_read(&xchg->ref_cnt));
-
- unf_xchg_ref_dec(xchg, TGT_ABTS_DONE);
- return UNF_RETURN_ERROR;
- }
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- unf_lport->xchg_mgr_temp.unf_xchg_cancel_timer((void *)xchg);
- /*
- * Exchage I/O Status check: Succ-> Add RRQ Timer
- * ***** pkg->status --- to --->>> scsi_cmnd->result *****
- * *
- * FAILED: ERR_Code or X_ID is err, or BA_RSP type is err
- */
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if (pkg->status == UNF_IO_SUCCESS) {
- /* Succeed: PKG status -->> EXCH status -->> scsi status */
- UNF_SET_SCSI_CMND_RESULT(xchg, UNF_IO_SUCCESS);
- xchg->io_state |= INI_IO_STATE_WAIT_RRQ;
- xchg->rxid = UNF_GET_RXID(pkg);
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- /* Add RRQ timer */
- time_ms = (ulong)(unf_lport->ra_tov);
- unf_lport->xchg_mgr_temp.unf_xchg_add_timer((void *)xchg, time_ms,
- UNF_TIMER_TYPE_INI_RRQ);
- } else {
- /* Failed: PKG status -->> EXCH status -->> scsi status */
- UNF_SET_SCSI_CMND_RESULT(xchg, UNF_IO_FAILED);
- if (MARKER_STS_RECEIVED & xchg->abts_state) {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
-
- /* NOTE: release I/O resource immediately */
- unf_cm_free_xchg(unf_lport, xchg);
- } else {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) exch(0x%p) OX_RX(0x%x:0x%x) IOstate(0x%x) ABTSstate(0x%x) receive response abnormal ref(0x%x)",
- unf_lport->port_id, xchg, xchg->oxid, xchg->rxid,
- xchg->io_state, xchg->abts_state, atomic_read(&xchg->ref_cnt));
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- }
- }
-
- /*
- * If abts response arrived before
- * marker sts received just wake up abts marker sema
- */
- spin_lock_irqsave(&xchg->xchg_state_lock, flags);
- if (!(MARKER_STS_RECEIVED & xchg->abts_state)) {
- xchg->ucode_abts_state = pkg->status;
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- up(&xchg->task_sema);
- } else {
- spin_unlock_irqrestore(&xchg->xchg_state_lock, flags);
- }
-
- unf_xchg_ref_dec(xchg, TGT_ABTS_DONE);
- return ret;
-}
-
-u32 unf_receive_bls_pkg(void *lport, struct unf_frame_pkg *pkg)
-{
- struct unf_lport *unf_lport = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- unf_lport = (struct unf_lport *)lport;
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- if (pkg->type == UNF_PKG_BLS_REQ_DONE) {
- /* INI: RCVD BLS Req Done */
- ret = unf_rcv_bls_req_done(lport, pkg);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) received BLS packet type(%xh) is error",
- unf_lport->port_id, pkg->type);
-
- return UNF_RETURN_ERROR;
- }
-
- return ret;
-}
-
-static void unf_fill_free_xid_pkg(struct unf_xchg *xchg, struct unf_frame_pkg *pkg)
-{
- pkg->frame_head.csctl_sid = xchg->sid;
- pkg->frame_head.rctl_did = xchg->did;
- pkg->frame_head.oxid_rxid = (u32)(((u32)xchg->oxid << UNF_SHIFT_16) | xchg->rxid);
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = xchg->hotpooltag;
- UNF_SET_XCHG_ALLOC_TIME(pkg, xchg);
-
- if (xchg->xchg_type == UNF_XCHG_TYPE_SFS) {
- if (UNF_XCHG_IS_ELS_REPLY(xchg)) {
- pkg->type = UNF_PKG_ELS_REPLY;
- pkg->rx_or_ox_id = UNF_PKG_FREE_RXID;
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = INVALID_VALUE32;
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = INVALID_VALUE32;
- } else {
- pkg->type = UNF_PKG_ELS_REQ;
- pkg->rx_or_ox_id = UNF_PKG_FREE_OXID;
- }
- } else if (xchg->xchg_type == UNF_XCHG_TYPE_INI) {
- pkg->type = UNF_PKG_INI_IO;
- pkg->rx_or_ox_id = UNF_PKG_FREE_OXID;
- }
-}
-
-void unf_notify_chip_free_xid(struct unf_xchg *xchg)
-{
- struct unf_lport *unf_lport = NULL;
- u32 ret = RETURN_ERROR;
- struct unf_frame_pkg pkg = {0};
-
- FC_CHECK_RETURN_VOID(xchg);
- unf_lport = xchg->lport;
- FC_CHECK_RETURN_VOID(unf_lport);
-
- unf_fill_free_xid_pkg(xchg, &pkg);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Sid_Did(0x%x)(0x%x) Xchg(0x%p) RXorOX(0x%x) tag(0x%x) xid(0x%x) magic(0x%x) Stat(0x%x)type(0x%x) wait timeout.",
- xchg->sid, xchg->did, xchg, pkg.rx_or_ox_id,
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX], pkg.frame_head.oxid_rxid,
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME], xchg->io_state, pkg.type);
-
- ret = unf_lport->low_level_func.service_op.ll_release_xid(unf_lport->fc_port, &pkg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Free xid abnormal:Sid_Did(0x%x 0x%x) Xchg(0x%p) RXorOX(0x%x) xid(0x%x) Stat(0x%x) tag(0x%x) magic(0x%x) type(0x%x).",
- xchg->sid, xchg->did, xchg, pkg.rx_or_ox_id,
- pkg.frame_head.oxid_rxid, xchg->io_state,
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX],
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME],
- pkg.type);
- }
-}
diff --git a/drivers/scsi/spfc/common/unf_service.h b/drivers/scsi/spfc/common/unf_service.h
deleted file mode 100644
index 0dd2975c6a7b..000000000000
--- a/drivers/scsi/spfc/common/unf_service.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_SERVICE_H
-#define UNF_SERVICE_H
-
-#include "unf_type.h"
-#include "unf_exchg.h"
-#include "unf_rport.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-extern u32 max_frame_size;
-#define UNF_INIT_DISC 0x1 /* first time DISC */
-#define UNF_RSCN_DISC 0x2 /* RSCN Port Addr DISC */
-#define UNF_SET_ELS_ACC_TYPE(els_cmd) ((u32)(els_cmd) << 16 | ELS_ACC)
-#define UNF_SET_ELS_RJT_TYPE(els_cmd) ((u32)(els_cmd) << 16 | ELS_RJT)
-#define UNF_XCHG_IS_ELS_REPLY(xchg) \
- ((ELS_ACC == ((xchg)->cmnd_code & 0x0ffff)) || \
- (ELS_RJT == ((xchg)->cmnd_code & 0x0ffff)))
-
-struct unf_els_handle_table {
- u32 cmnd;
- u32 (*els_cmnd_handler)(struct unf_lport *lport, u32 sid, struct unf_xchg *xchg);
-};
-
-void unf_select_sq(struct unf_xchg *xchg, struct unf_frame_pkg *pkg);
-void unf_fill_package(struct unf_frame_pkg *pkg, struct unf_xchg *xchg,
- struct unf_rport *rport);
-struct unf_xchg *unf_get_sfs_free_xchg_and_init(struct unf_lport *lport,
- u32 did,
- struct unf_rport *rport,
- union unf_sfs_u **fc_entry);
-void *unf_get_one_big_sfs_buf(struct unf_xchg *xchg);
-u32 unf_mv_resp_2_xchg(struct unf_xchg *xchg, struct unf_frame_pkg *pkg);
-void unf_rport_immediate_link_down(struct unf_lport *lport,
- struct unf_rport *rport);
-struct unf_rport *unf_find_rport(struct unf_lport *lport, u32 rport_nport_id,
- u64 port_name);
-void unf_process_logo_in_fabric(struct unf_lport *lport,
- struct unf_rport *rport);
-void unf_notify_chip_free_xid(struct unf_xchg *xchg);
-
-u32 unf_ls_gs_cmnd_send(struct unf_lport *lport, struct unf_frame_pkg *pkg,
- struct unf_xchg *xchg);
-u32 unf_receive_ls_gs_pkg(void *lport, struct unf_frame_pkg *pkg);
-struct unf_xchg *unf_mv_data_2_xchg(struct unf_lport *lport,
- struct unf_frame_pkg *pkg);
-u32 unf_receive_bls_pkg(void *lport, struct unf_frame_pkg *pkg);
-u32 unf_send_els_done(void *lport, struct unf_frame_pkg *pkg);
-u32 unf_send_els_rjt_by_did(struct unf_lport *lport, struct unf_xchg *xchg,
- u32 did, struct unf_rjt_info *rjt_info);
-u32 unf_send_els_rjt_by_rport(struct unf_lport *lport, struct unf_xchg *xchg,
- struct unf_rport *rport,
- struct unf_rjt_info *rjt_info);
-u32 unf_send_abts(struct unf_lport *lport, struct unf_xchg *xchg);
-void unf_process_rport_after_logo(struct unf_lport *lport,
- struct unf_rport *rport);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __UNF_SERVICE_H__ */
diff --git a/drivers/scsi/spfc/common/unf_type.h b/drivers/scsi/spfc/common/unf_type.h
deleted file mode 100644
index 28e163d0543c..000000000000
--- a/drivers/scsi/spfc/common/unf_type.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef UNF_TYPE_H
-#define UNF_TYPE_H
-
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/version.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <linux/kref.h>
-#include <linux/scatterlist.h>
-#include <linux/crc-t10dif.h>
-#include <linux/ctype.h>
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/random.h>
-#include <linux/jiffies.h>
-#include <linux/cpufreq.h>
-#include <linux/semaphore.h>
-#include <linux/jiffies.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_transport_fc.h>
-#include <linux/sched/signal.h>
-
-#ifndef SPFC_FT
-#define SPFC_FT
-#endif
-
-#define BUF_LIST_PAGE_SIZE (PAGE_SIZE << 8)
-
-#define UNF_S_TO_NS (1000000000)
-#define UNF_S_TO_MS (1000)
-
-enum UNF_OS_THRD_PRI_E {
- UNF_OS_THRD_PRI_HIGHEST = 0,
- UNF_OS_THRD_PRI_HIGH,
- UNF_OS_THRD_PRI_SUBHIGH,
- UNF_OS_THRD_PRI_MIDDLE,
- UNF_OS_THRD_PRI_LOW,
- UNF_OS_THRD_PRI_BUTT
-};
-
-#define UNF_OS_LIST_NEXT(a) ((a)->next)
-#define UNF_OS_LIST_PREV(a) ((a)->prev)
-
-#define UNF_OS_PER_NS (1000000000)
-#define UNF_OS_MS_TO_NS (1000000)
-
-#ifndef MIN
-#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
-#endif
-
-#ifndef MAX
-#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
-#endif
-
-#ifndef INVALID_VALUE64
-#define INVALID_VALUE64 0xFFFFFFFFFFFFFFFFULL
-#endif /* INVALID_VALUE64 */
-
-#ifndef INVALID_VALUE32
-#define INVALID_VALUE32 0xFFFFFFFF
-#endif /* INVALID_VALUE32 */
-
-#ifndef INVALID_VALUE16
-#define INVALID_VALUE16 0xFFFF
-#endif /* INVALID_VALUE16 */
-
-#ifndef INVALID_VALUE8
-#define INVALID_VALUE8 0xFF
-#endif /* INVALID_VALUE8 */
-
-#ifndef RETURN_OK
-#define RETURN_OK 0
-#endif
-
-#ifndef RETURN_ERROR
-#define RETURN_ERROR (~0)
-#endif
-#define UNF_RETURN_ERROR (~0)
-
-/* define shift bits */
-#define UNF_SHIFT_1 1
-#define UNF_SHIFT_2 2
-#define UNF_SHIFT_3 3
-#define UNF_SHIFT_4 4
-#define UNF_SHIFT_6 6
-#define UNF_SHIFT_7 7
-#define UNF_SHIFT_8 8
-#define UNF_SHIFT_11 11
-#define UNF_SHIFT_12 12
-#define UNF_SHIFT_15 15
-#define UNF_SHIFT_16 16
-#define UNF_SHIFT_17 17
-#define UNF_SHIFT_19 19
-#define UNF_SHIFT_20 20
-#define UNF_SHIFT_23 23
-#define UNF_SHIFT_24 24
-#define UNF_SHIFT_25 25
-#define UNF_SHIFT_26 26
-#define UNF_SHIFT_28 28
-#define UNF_SHIFT_29 29
-#define UNF_SHIFT_32 32
-#define UNF_SHIFT_35 35
-#define UNF_SHIFT_37 37
-#define UNF_SHIFT_39 39
-#define UNF_SHIFT_40 40
-#define UNF_SHIFT_43 43
-#define UNF_SHIFT_48 48
-#define UNF_SHIFT_51 51
-#define UNF_SHIFT_56 56
-#define UNF_SHIFT_57 57
-#define UNF_SHIFT_59 59
-#define UNF_SHIFT_60 60
-#define UNF_SHIFT_61 61
-
-/* array index */
-#define ARRAY_INDEX_0 0
-#define ARRAY_INDEX_1 1
-#define ARRAY_INDEX_2 2
-#define ARRAY_INDEX_3 3
-#define ARRAY_INDEX_4 4
-#define ARRAY_INDEX_5 5
-#define ARRAY_INDEX_6 6
-#define ARRAY_INDEX_7 7
-#define ARRAY_INDEX_8 8
-#define ARRAY_INDEX_10 10
-#define ARRAY_INDEX_11 11
-#define ARRAY_INDEX_12 12
-#define ARRAY_INDEX_13 13
-
-/* define mask bits */
-#define UNF_MASK_BIT_7_0 0xff
-#define UNF_MASK_BIT_15_0 0x0000ffff
-#define UNF_MASK_BIT_31_16 0xffff0000
-
-#define UNF_IO_SUCCESS 0x00000000
-#define UNF_IO_ABORTED 0x00000001 /* the host system aborted the command */
-#define UNF_IO_FAILED 0x00000002
-#define UNF_IO_ABORT_ABTS 0x00000003
-#define UNF_IO_ABORT_LOGIN 0x00000004 /* abort login */
-#define UNF_IO_ABORT_REET 0x00000005 /* reset event aborted the transport */
-#define UNF_IO_ABORT_FAILED 0x00000006 /* abort failed */
-/* data out of order ,data reassembly error */
-#define UNF_IO_OUTOF_ORDER 0x00000007
-#define UNF_IO_FTO 0x00000008 /* frame time out */
-#define UNF_IO_LINK_FAILURE 0x00000009
-#define UNF_IO_OVER_FLOW 0x0000000a /* data over run */
-#define UNF_IO_RSP_OVER 0x0000000b
-#define UNF_IO_LOST_FRAME 0x0000000c
-#define UNF_IO_UNDER_FLOW 0x0000000d /* data under run */
-#define UNF_IO_HOST_PROG_ERROR 0x0000000e
-#define UNF_IO_SEST_PROG_ERROR 0x0000000f
-#define UNF_IO_INVALID_ENTRY 0x00000010
-#define UNF_IO_ABORT_SEQ_NOT 0x00000011
-#define UNF_IO_REJECT 0x00000012
-#define UNF_IO_RS_INFO 0x00000013
-#define UNF_IO_EDC_IN_ERROR 0x00000014
-#define UNF_IO_EDC_OUT_ERROR 0x00000015
-#define UNF_IO_UNINIT_KEK_ERR 0x00000016
-#define UNF_IO_DEK_OUTOF_RANGE 0x00000017
-#define UNF_IO_KEY_UNWRAP_ERR 0x00000018
-#define UNF_IO_KEY_TAG_ERR 0x00000019
-#define UNF_IO_KEY_ECC_ERR 0x0000001a
-#define UNF_IO_BLOCK_SIZE_ERROR 0x0000001b
-#define UNF_IO_ILLEGAL_CIPHER_MODE 0x0000001c
-#define UNF_IO_CLEAN_UP 0x0000001d
-#define UNF_SRR_RECEIVE 0x0000001e /* receive srr */
-/* The target device sent an ABTS to abort the I/O.*/
-#define UNF_IO_ABORTED_BY_TARGET 0x0000001f
-#define UNF_IO_TRANSPORT_ERROR 0x00000020
-#define UNF_IO_LINK_FLASH 0x00000021
-#define UNF_IO_TIMEOUT 0x00000022
-#define UNF_IO_PORT_UNAVAILABLE 0x00000023
-#define UNF_IO_PORT_LOGOUT 0x00000024
-#define UNF_IO_PORT_CFG_CHG 0x00000025
-#define UNF_IO_FIRMWARE_RES_UNAVAILABLE 0x00000026
-#define UNF_IO_TASK_MGT_OVERRUN 0x00000027
-#define UNF_IO_DMA_ERROR 0x00000028
-#define UNF_IO_DIF_ERROR 0x00000029
-#define UNF_IO_NO_LPORT 0x0000002a
-#define UNF_IO_NO_XCHG 0x0000002b
-#define UNF_IO_SOFT_ERR 0x0000002c
-#define UNF_IO_XCHG_ADD_ERROR 0x0000002d
-#define UNF_IO_NO_LOGIN 0x0000002e
-#define UNF_IO_NO_BUFFER 0x0000002f
-#define UNF_IO_DID_ERROR 0x00000030
-#define UNF_IO_UNSUPPORT 0x00000031
-#define UNF_IO_NOREADY 0x00000032
-#define UNF_IO_NPORTID_REUSED 0x00000033
-#define UNF_IO_NPORT_HANDLE_REUSED 0x00000034
-#define UNF_IO_NO_NPORT_HANDLE 0x00000035
-#define UNF_IO_ABORT_BY_FW 0x00000036
-#define UNF_IO_ABORT_PORT_REMOVING 0x00000037
-#define UNF_IO_INCOMPLETE 0x00000038
-#define UNF_IO_DIF_REF_ERROR 0x00000039
-#define UNF_IO_DIF_GEN_ERROR 0x0000003a
-
-#define UNF_IO_ERREND 0xFFFFFFFF
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_chipitf.c b/drivers/scsi/spfc/hw/spfc_chipitf.c
deleted file mode 100644
index be6073ff4dc0..000000000000
--- a/drivers/scsi/spfc/hw/spfc_chipitf.c
+++ /dev/null
@@ -1,1105 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "spfc_chipitf.h"
-#include "sphw_hw.h"
-#include "sphw_crm.h"
-
-#define SPFC_MBOX_TIME_SEC_MAX (60)
-
-#define SPFC_LINK_UP_COUNT 1
-#define SPFC_LINK_DOWN_COUNT 2
-#define SPFC_FC_DELETE_CMND_COUNT 3
-
-#define SPFC_MBX_MAX_TIMEOUT 10000
-
-u32 spfc_get_chip_msg(void *hba, void *mac)
-{
- struct spfc_hba_info *spfc_hba = NULL;
- struct unf_get_chip_info_argout *wwn = NULL;
- struct spfc_inmbox_get_chip_info get_chip_info;
- union spfc_outmbox_generic *get_chip_info_sts = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(mac, UNF_RETURN_ERROR);
-
- spfc_hba = (struct spfc_hba_info *)hba;
- wwn = (struct unf_get_chip_info_argout *)mac;
-
- memset(&get_chip_info, 0, sizeof(struct spfc_inmbox_get_chip_info));
-
- get_chip_info_sts = kmalloc(sizeof(union spfc_outmbox_generic), GFP_ATOMIC);
- if (!get_chip_info_sts) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]malloc outmbox memory failed");
- return UNF_RETURN_ERROR;
- }
- memset(get_chip_info_sts, 0, sizeof(union spfc_outmbox_generic));
-
- get_chip_info.header.cmnd_type = SPFC_MBOX_GET_CHIP_INFO;
- get_chip_info.header.length =
- SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_get_chip_info));
-
- if (spfc_mb_send_and_wait_mbox(spfc_hba, &get_chip_info,
- sizeof(struct spfc_inmbox_get_chip_info),
- get_chip_info_sts) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]spfc can't send and wait mailbox, command type: 0x%x.",
- get_chip_info.header.cmnd_type);
-
- goto exit;
- }
-
- if (get_chip_info_sts->get_chip_info_sts.status != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) mailbox status incorrect status(0x%x) .",
- spfc_hba->port_cfg.port_id,
- get_chip_info_sts->get_chip_info_sts.status);
-
- goto exit;
- }
-
- if (get_chip_info_sts->get_chip_info_sts.header.cmnd_type != SPFC_MBOX_GET_CHIP_INFO_STS) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) receive mailbox type incorrect type: 0x%x.",
- spfc_hba->port_cfg.port_id,
- get_chip_info_sts->get_chip_info_sts.header.cmnd_type);
-
- goto exit;
- }
-
- wwn->board_type = get_chip_info_sts->get_chip_info_sts.board_type;
- spfc_hba->card_info.card_type = get_chip_info_sts->get_chip_info_sts.board_type;
- wwn->wwnn = get_chip_info_sts->get_chip_info_sts.wwnn;
- wwn->wwpn = get_chip_info_sts->get_chip_info_sts.wwpn;
-
- ret = RETURN_OK;
-exit:
- kfree(get_chip_info_sts);
-
- return ret;
-}
-
-u32 spfc_get_chip_capability(void *hwdev_handle,
- struct spfc_chip_info *chip_info)
-{
- struct spfc_inmbox_get_chip_info get_chip_info;
- union spfc_outmbox_generic *get_chip_info_sts = NULL;
- u16 out_size = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hwdev_handle, UNF_RETURN_ERROR);
-
- memset(&get_chip_info, 0, sizeof(struct spfc_inmbox_get_chip_info));
-
- get_chip_info_sts = kmalloc(sizeof(union spfc_outmbox_generic), GFP_ATOMIC);
- if (!get_chip_info_sts) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "malloc outmbox memory failed");
- return UNF_RETURN_ERROR;
- }
- memset(get_chip_info_sts, 0, sizeof(union spfc_outmbox_generic));
-
- get_chip_info.header.cmnd_type = SPFC_MBOX_GET_CHIP_INFO;
- get_chip_info.header.length =
- SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_get_chip_info));
- get_chip_info.header.port_id = (u8)sphw_global_func_id(hwdev_handle);
- out_size = sizeof(union spfc_outmbox_generic);
-
- if (sphw_msg_to_mgmt_sync(hwdev_handle, COMM_MOD_FC, SPFC_MBOX_GET_CHIP_INFO,
- (void *)&get_chip_info.header,
- sizeof(struct spfc_inmbox_get_chip_info),
- (union spfc_outmbox_generic *)(get_chip_info_sts), &out_size,
- (SPFC_MBX_MAX_TIMEOUT), SPHW_CHANNEL_FC) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "spfc can't send and wait mailbox, command type: 0x%x.",
- SPFC_MBOX_GET_CHIP_INFO);
-
- goto exit;
- }
-
- if (get_chip_info_sts->get_chip_info_sts.status != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port mailbox status incorrect status(0x%x) .",
- get_chip_info_sts->get_chip_info_sts.status);
-
- goto exit;
- }
-
- if (get_chip_info_sts->get_chip_info_sts.header.cmnd_type != SPFC_MBOX_GET_CHIP_INFO_STS) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port receive mailbox type incorrect type: 0x%x.",
- get_chip_info_sts->get_chip_info_sts.header.cmnd_type);
-
- goto exit;
- }
-
- chip_info->wwnn = get_chip_info_sts->get_chip_info_sts.wwnn;
- chip_info->wwpn = get_chip_info_sts->get_chip_info_sts.wwpn;
-
- ret = RETURN_OK;
-exit:
- kfree(get_chip_info_sts);
-
- return ret;
-}
-
-u32 spfc_config_port_table(struct spfc_hba_info *hba)
-{
- struct spfc_inmbox_config_api config_api;
- union spfc_outmbox_generic *out_mbox = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- memset(&config_api, 0, sizeof(config_api));
- out_mbox = kmalloc(sizeof(union spfc_outmbox_generic), GFP_ATOMIC);
- if (!out_mbox) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]malloc outmbox memory failed");
- return UNF_RETURN_ERROR;
- }
- memset(out_mbox, 0, sizeof(union spfc_outmbox_generic));
-
- config_api.header.cmnd_type = SPFC_MBOX_CONFIG_API;
- config_api.header.length = SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_config_api));
-
- config_api.op_code = UNDEFINEOPCODE;
-
- /* change switching top cmd of CM to the cmd that up recognize */
- /* if the cmd equals UNF_TOP_P2P_MASK sending in CM means that it
- * should be changed into P2P top, LL using SPFC_TOP_NON_LOOP_MASK
- */
- if (((u8)(hba->port_topo_cfg)) == UNF_TOP_P2P_MASK) {
- config_api.topy_mode = 0x2;
- /* if the cmd equals UNF_TOP_LOOP_MASK sending in CM means that it
- *should be changed into loop top, LL using SPFC_TOP_LOOP_MASK
- */
- } else if (((u8)(hba->port_topo_cfg)) == UNF_TOP_LOOP_MASK) {
- config_api.topy_mode = 0x1;
- /* if the cmd equals UNF_TOP_AUTO_MASK sending in CM means that it
- *should be changed into loop top, LL using SPFC_TOP_AUTO_MASK
- */
- } else if (((u8)(hba->port_topo_cfg)) == UNF_TOP_AUTO_MASK) {
- config_api.topy_mode = 0x0;
- } else {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) topo cmd is error, command type: 0x%x",
- hba->port_cfg.port_id, (u8)(hba->port_topo_cfg));
-
- goto exit;
- }
-
- /* About speed */
- config_api.sfp_speed = (u8)(hba->port_speed_cfg);
- config_api.max_speed = (u8)(hba->max_support_speed);
-
- config_api.rx_6432g_bb_credit = SPFC_LOWLEVEL_DEFAULT_32G_BB_CREDIT;
- config_api.rx_16g_bb_credit = SPFC_LOWLEVEL_DEFAULT_16G_BB_CREDIT;
- config_api.rx_84g_bb_credit = SPFC_LOWLEVEL_DEFAULT_8G_BB_CREDIT;
- config_api.rdy_cnt_bf_fst_frm = SPFC_LOWLEVEL_DEFAULT_LOOP_BB_CREDIT;
- config_api.esch_32g_value = SPFC_LOWLEVEL_DEFAULT_32G_ESCH_VALUE;
- config_api.esch_16g_value = SPFC_LOWLEVEL_DEFAULT_16G_ESCH_VALUE;
- config_api.esch_8g_value = SPFC_LOWLEVEL_DEFAULT_8G_ESCH_VALUE;
- config_api.esch_4g_value = SPFC_LOWLEVEL_DEFAULT_8G_ESCH_VALUE;
- config_api.esch_64g_value = SPFC_LOWLEVEL_DEFAULT_8G_ESCH_VALUE;
- config_api.esch_bust_size = SPFC_LOWLEVEL_DEFAULT_ESCH_BUST_SIZE;
-
- /* default value:0xFF */
- config_api.hard_alpa = 0xFF;
- memcpy(config_api.port_name, hba->sys_port_name, UNF_WWN_LEN);
-
- /* if only for slave, the value is 1; if participate master choosing,
- * the value is 0
- */
- config_api.slave = hba->port_loop_role;
-
- /* 1:auto negotiate, 0:fixed mode negotiate */
- if (config_api.sfp_speed == 0)
- config_api.auto_sneg = 0x1;
- else
- config_api.auto_sneg = 0x0;
-
- if (spfc_mb_send_and_wait_mbox(hba, &config_api, sizeof(config_api),
- out_mbox) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[warn]Port(0x%x) SPFC can't send and wait mailbox, command type: 0x%x",
- hba->port_cfg.port_id,
- config_api.header.cmnd_type);
-
- goto exit;
- }
-
- if (out_mbox->config_api_sts.status != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "[err]Port(0x%x) receive mailbox type(0x%x) with status(0x%x) error",
- hba->port_cfg.port_id,
- out_mbox->config_api_sts.header.cmnd_type,
- out_mbox->config_api_sts.status);
-
- goto exit;
- }
-
- if (out_mbox->config_api_sts.header.cmnd_type != SPFC_MBOX_CONFIG_API_STS) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "[err]Port(0x%x) receive mailbox type(0x%x) error",
- hba->port_cfg.port_id,
- out_mbox->config_api_sts.header.cmnd_type);
-
- goto exit;
- }
-
- ret = RETURN_OK;
-exit:
- kfree(out_mbox);
-
- return ret;
-}
-
-u32 spfc_port_switch(struct spfc_hba_info *hba, bool turn_on)
-{
- struct spfc_inmbox_port_switch port_switch;
- union spfc_outmbox_generic *port_switch_sts = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- memset(&port_switch, 0, sizeof(port_switch));
-
- port_switch_sts = kmalloc(sizeof(union spfc_outmbox_generic), GFP_ATOMIC);
- if (!port_switch_sts) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]malloc outmbox memory failed");
- return UNF_RETURN_ERROR;
- }
- memset(port_switch_sts, 0, sizeof(union spfc_outmbox_generic));
-
- port_switch.header.cmnd_type = SPFC_MBOX_PORT_SWITCH;
- port_switch.header.length = SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_port_switch));
- port_switch.op_code = (u8)turn_on;
-
- if (spfc_mb_send_and_wait_mbox(hba, &port_switch, sizeof(port_switch),
- (union spfc_outmbox_generic *)((void *)port_switch_sts)) !=
- RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[warn]Port(0x%x) SPFC can't send and wait mailbox, command type(0x%x) opcode(0x%x)",
- hba->port_cfg.port_id,
- port_switch.header.cmnd_type, port_switch.op_code);
-
- goto exit;
- }
-
- if (port_switch_sts->port_switch_sts.status != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "[err]Port(0x%x) receive mailbox type(0x%x) status(0x%x) error",
- hba->port_cfg.port_id,
- port_switch_sts->port_switch_sts.header.cmnd_type,
- port_switch_sts->port_switch_sts.status);
-
- goto exit;
- }
-
- if (port_switch_sts->port_switch_sts.header.cmnd_type != SPFC_MBOX_PORT_SWITCH_STS) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "[err]Port(0x%x) receive mailbox type(0x%x) error",
- hba->port_cfg.port_id,
- port_switch_sts->port_switch_sts.header.cmnd_type);
-
- goto exit;
- }
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_MAJOR,
- "[event]Port(0x%x) switch succeed, turns to %s",
- hba->port_cfg.port_id, (turn_on) ? "on" : "off");
-
- ret = RETURN_OK;
-exit:
- kfree(port_switch_sts);
-
- return ret;
-}
-
-u32 spfc_config_login_api(struct spfc_hba_info *hba,
- struct unf_port_login_parms *login_parms)
-{
-#define SPFC_LOOP_RDYNUM 8
- int iret = RETURN_OK;
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_inmbox_config_login config_login;
- union spfc_outmbox_generic *cfg_login_sts = NULL;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- memset(&config_login, 0, sizeof(config_login));
- cfg_login_sts = kmalloc(sizeof(union spfc_outmbox_generic), GFP_ATOMIC);
- if (!cfg_login_sts) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]malloc outmbox memory failed");
- return UNF_RETURN_ERROR;
- }
- memset(cfg_login_sts, 0, sizeof(union spfc_outmbox_generic));
-
- config_login.header.cmnd_type = SPFC_MBOX_CONFIG_LOGIN_API;
- config_login.header.length = SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_config_login));
- config_login.header.port_id = hba->port_index;
-
- config_login.op_code = UNDEFINEOPCODE;
-
- config_login.tx_bb_credit = hba->remote_bb_credit;
-
- config_login.etov = hba->compared_edtov_val;
- config_login.rtov = hba->compared_ratov_val;
-
- config_login.rt_tov_tag = hba->remote_rttov_tag;
- config_login.ed_tov_tag = hba->remote_edtov_tag;
- config_login.bb_credit = hba->remote_bb_credit;
- config_login.bb_scn = SPFC_LSB(hba->compared_bb_scn);
-
- if (config_login.bb_scn) {
- config_login.lr_flag = (login_parms->els_cmnd_code == ELS_PLOGI) ? 0 : 1;
- ret = spfc_mb_send_and_wait_mbox(hba, &config_login, sizeof(config_login),
- (union spfc_outmbox_generic *)cfg_login_sts);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) SPFC can't send and wait mailbox, command type: 0x%x.",
- hba->port_cfg.port_id, config_login.header.cmnd_type);
-
- goto exit;
- }
-
- if (cfg_login_sts->config_login_sts.header.cmnd_type !=
- SPFC_MBOX_CONFIG_LOGIN_API_STS) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) Receive mailbox type incorrect. Type: 0x%x.",
- hba->port_cfg.port_id,
- cfg_login_sts->config_login_sts.header.cmnd_type);
-
- goto exit;
- }
-
- if (cfg_login_sts->config_login_sts.status != STATUS_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "Port(0x%x) Receive mailbox type(0x%x) status incorrect. Status: 0x%x.",
- hba->port_cfg.port_id,
- cfg_login_sts->config_login_sts.header.cmnd_type,
- cfg_login_sts->config_login_sts.status);
-
- goto exit;
- }
- } else {
- iret = sphw_msg_to_mgmt_async(hba->dev_handle, COMM_MOD_FC,
- SPFC_MBOX_CONFIG_LOGIN_API, &config_login,
- sizeof(config_login), SPHW_CHANNEL_FC);
-
- if (iret != 0) {
- SPFC_MAILBOX_STAT(hba, SPFC_SEND_CONFIG_LOGINAPI_FAIL);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) spfc can't send config login cmd to up,ret:%d.",
- hba->port_cfg.port_id, iret);
-
- goto exit;
- }
-
- SPFC_MAILBOX_STAT(hba, SPFC_SEND_CONFIG_LOGINAPI);
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "Port(0x%x) Topo(0x%x) Config login param to up: txbbcredit(0x%x), BB_SC_N(0x%x).",
- hba->port_cfg.port_id, hba->active_topo,
- config_login.tx_bb_credit, config_login.bb_scn);
-
- ret = RETURN_OK;
-exit:
- kfree(cfg_login_sts);
-
- return ret;
-}
-
-u32 spfc_mb_send_and_wait_mbox(struct spfc_hba_info *hba, const void *in_mbox,
- u16 in_size,
- union spfc_outmbox_generic *out_mbox)
-{
- void *handle = NULL;
- u16 out_size = 0;
- ulong time_out = 0;
- int ret = 0;
- struct spfc_mbox_header *header = NULL;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(in_mbox, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(out_mbox, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(hba->dev_handle, UNF_RETURN_ERROR);
- header = (struct spfc_mbox_header *)in_mbox;
- out_size = sizeof(union spfc_outmbox_generic);
- handle = hba->dev_handle;
- header->port_id = (u8)sphw_global_func_id(handle);
-
- /* Wait for las mailbox completion: */
- time_out = wait_for_completion_timeout(&hba->mbox_complete,
- (ulong)msecs_to_jiffies(SPFC_MBOX_TIME_SEC_MAX *
- UNF_S_TO_MS));
- if (time_out == SPFC_ZERO) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "[err]Port(0x%x) wait mailbox(0x%x) completion timeout: %d sec",
- hba->port_cfg.port_id, header->cmnd_type,
- SPFC_MBOX_TIME_SEC_MAX);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Send Msg to uP Sync: timer 10s */
- ret = sphw_msg_to_mgmt_sync(handle, COMM_MOD_FC, header->cmnd_type,
- (void *)in_mbox, in_size,
- (union spfc_outmbox_generic *)out_mbox,
- &out_size, (SPFC_MBX_MAX_TIMEOUT),
- SPHW_CHANNEL_FC);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[warn]Port(0x%x) can not send mailbox(0x%x) with ret:%d",
- hba->port_cfg.port_id, header->cmnd_type, ret);
-
- complete(&hba->mbox_complete);
- return UNF_RETURN_ERROR;
- }
-
- complete(&hba->mbox_complete);
-
- return RETURN_OK;
-}
-
-void spfc_initial_dynamic_info(struct spfc_hba_info *fc_port)
-{
- struct spfc_hba_info *hba = fc_port;
- ulong flag = 0;
-
- FC_CHECK_RETURN_VOID(hba);
-
- spin_lock_irqsave(&hba->hba_lock, flag);
- hba->active_port_speed = UNF_PORT_SPEED_UNKNOWN;
- hba->active_topo = UNF_ACT_TOP_UNKNOWN;
- hba->phy_link = UNF_PORT_LINK_DOWN;
- hba->queue_set_stage = SPFC_QUEUE_SET_STAGE_INIT;
- hba->loop_map_valid = LOOP_MAP_INVALID;
- hba->srq_delay_info.srq_delay_flag = 0;
- hba->srq_delay_info.root_rq_rcvd_flag = 0;
- spin_unlock_irqrestore(&hba->hba_lock, flag);
-}
-
-static u32 spfc_recv_fc_linkup(struct spfc_hba_info *hba, void *buf_in)
-{
-#define SPFC_LOOP_MASK 0x1
-#define SPFC_LOOPMAP_COUNT 128
-
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_link_event *link_event = NULL;
-
- link_event = (struct spfc_link_event *)buf_in;
- hba->phy_link = UNF_PORT_LINK_UP;
- hba->active_port_speed = link_event->speed;
- hba->led_states.green_speed_led = (u8)(link_event->green_speed_led);
- hba->led_states.yellow_speed_led = (u8)(link_event->yellow_speed_led);
- hba->led_states.ac_led = (u8)(link_event->ac_led);
-
- if (link_event->top_type == SPFC_LOOP_MASK &&
- (link_event->loop_map_info[ARRAY_INDEX_1] == UNF_FL_PORT_LOOP_ADDR ||
- link_event->loop_map_info[ARRAY_INDEX_2] == UNF_FL_PORT_LOOP_ADDR)) {
- hba->active_topo = UNF_ACT_TOP_PUBLIC_LOOP; /* Public Loop */
- hba->active_alpa = link_event->alpa_value; /* AL_PA */
- memcpy(hba->loop_map, link_event->loop_map_info, SPFC_LOOPMAP_COUNT);
- hba->loop_map_valid = LOOP_MAP_VALID;
- } else if (link_event->top_type == SPFC_LOOP_MASK) {
- hba->active_topo = UNF_ACT_TOP_PRIVATE_LOOP; /* Private Loop */
- hba->active_alpa = link_event->alpa_value; /* AL_PA */
- memcpy(hba->loop_map, link_event->loop_map_info, SPFC_LOOPMAP_COUNT);
- hba->loop_map_valid = LOOP_MAP_VALID;
- } else {
- hba->active_topo = UNF_TOP_P2P_MASK; /* P2P_D or P2P_F */
- }
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_KEVENT,
- "[event]Port(0x%x) receive link up event(0x%x) with speed(0x%x) uP_topo(0x%x) driver_topo(0x%x)",
- hba->port_cfg.port_id, link_event->link_event,
- link_event->speed, link_event->top_type, hba->active_topo);
-
- /* Set clear & flush state */
- spfc_set_hba_clear_state(hba, false);
- spfc_set_hba_flush_state(hba, false);
- spfc_set_rport_flush_state(hba, false);
-
- /* Report link up event to COM */
- UNF_LOWLEVEL_PORT_EVENT(ret, hba->lport, UNF_PORT_LINK_UP,
- &hba->active_port_speed);
-
- SPFC_LINK_EVENT_STAT(hba, SPFC_LINK_UP_COUNT);
-
- return ret;
-}
-
-static u32 spfc_recv_fc_linkdown(struct spfc_hba_info *hba, void *buf_in)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_link_event *link_event = NULL;
-
- link_event = (struct spfc_link_event *)buf_in;
-
- /* 1. Led state setting */
- hba->led_states.green_speed_led = (u8)(link_event->green_speed_led);
- hba->led_states.yellow_speed_led = (u8)(link_event->yellow_speed_led);
- hba->led_states.ac_led = (u8)(link_event->ac_led);
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_KEVENT,
- "[event]Port(0x%x) receive link down event(0x%x) reason(0x%x)",
- hba->port_cfg.port_id, link_event->link_event, link_event->reason);
-
- spfc_initial_dynamic_info(hba);
-
- /* 2. set HBA flush state */
- spfc_set_hba_flush_state(hba, true);
-
- /* 3. set R_Port (parent SQ) flush state */
- spfc_set_rport_flush_state(hba, true);
-
- /* 4. Report link down event to COM */
- UNF_LOWLEVEL_PORT_EVENT(ret, hba->lport, UNF_PORT_LINK_DOWN, 0);
-
- /* DFX setting */
- SPFC_LINK_REASON_STAT(hba, link_event->reason);
- SPFC_LINK_EVENT_STAT(hba, SPFC_LINK_DOWN_COUNT);
-
- return ret;
-}
-
-static u32 spfc_recv_fc_delcmd(struct spfc_hba_info *hba, void *buf_in)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_link_event *link_event = NULL;
-
- link_event = (struct spfc_link_event *)buf_in;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_KEVENT,
- "[event]Port(0x%x) receive delete cmd event(0x%x)",
- hba->port_cfg.port_id, link_event->link_event);
-
- /* Send buffer clear cmnd */
- ret = spfc_clear_fetched_sq_wqe(hba);
-
- hba->queue_set_stage = SPFC_QUEUE_SET_STAGE_SCANNING;
- SPFC_LINK_EVENT_STAT(hba, SPFC_FC_DELETE_CMND_COUNT);
-
- return ret;
-}
-
-static u32 spfc_recv_fc_error(struct spfc_hba_info *hba, void *buf_in)
-{
-#define FC_ERR_LEVEL_DEAD 0
-#define FC_ERR_LEVEL_HIGH 1
-#define FC_ERR_LEVEL_LOW 2
-
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_up_error_event *up_error_event = NULL;
-
- up_error_event = (struct spfc_up_error_event *)buf_in;
- if (up_error_event->error_type >= SPFC_UP_ERR_BUTT ||
- up_error_event->error_value >= SPFC_ERR_VALUE_BUTT) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) receive a unsupported UP Error Event Type(0x%x) Value(0x%x).",
- hba->port_cfg.port_id, up_error_event->error_type,
- up_error_event->error_value);
- return ret;
- }
-
- switch (up_error_event->error_level) {
- case FC_ERR_LEVEL_DEAD:
- ret = RETURN_OK;
- break;
-
- case FC_ERR_LEVEL_HIGH:
- /* port reset */
- UNF_LOWLEVEL_PORT_EVENT(ret, hba->lport,
- UNF_PORT_ABNORMAL_RESET, NULL);
- break;
-
- case FC_ERR_LEVEL_LOW:
- ret = RETURN_OK;
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) receive a unsupported UP Error Event Level(0x%x), Can not Process.",
- hba->port_cfg.port_id,
- up_error_event->error_level);
- return ret;
- }
- if (up_error_event->error_value < SPFC_ERR_VALUE_BUTT)
- SPFC_UP_ERR_EVENT_STAT(hba, up_error_event->error_value);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Port(0x%x) process UP Error Event Level(0x%x) Type(0x%x) Value(0x%x) %s.",
- hba->port_cfg.port_id, up_error_event->error_level,
- up_error_event->error_type, up_error_event->error_value,
- (ret == UNF_RETURN_ERROR) ? "ERROR" : "OK");
-
- return ret;
-}
-
-static struct spfc_up2drv_msg_handle up_msg_handle[] = {
- {SPFC_MBOX_RECV_FC_LINKUP, spfc_recv_fc_linkup},
- {SPFC_MBOX_RECV_FC_LINKDOWN, spfc_recv_fc_linkdown},
- {SPFC_MBOX_RECV_FC_DELCMD, spfc_recv_fc_delcmd},
- {SPFC_MBOX_RECV_FC_ERROR, spfc_recv_fc_error}
-};
-
-void spfc_up_msg2driver_proc(void *hwdev_handle, void *pri_handle, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 index = 0;
- struct spfc_hba_info *hba = NULL;
- struct spfc_mbox_header *mbx_header = NULL;
-
- FC_CHECK_RETURN_VOID(hwdev_handle);
- FC_CHECK_RETURN_VOID(pri_handle);
- FC_CHECK_RETURN_VOID(buf_in);
- FC_CHECK_RETURN_VOID(buf_out);
- FC_CHECK_RETURN_VOID(out_size);
-
- hba = (struct spfc_hba_info *)pri_handle;
- if (!hba) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_ERR, "[err]Hba is null");
- return;
- }
-
- mbx_header = (struct spfc_mbox_header *)buf_in;
- if (mbx_header->cmnd_type != cmd) {
- *out_size = sizeof(struct spfc_link_event);
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_ERR,
- "[err]Port(0x%x) cmd(0x%x) is not matched with header cmd type(0x%x)",
- hba->port_cfg.port_id, cmd, mbx_header->cmnd_type);
- return;
- }
-
- while (index < (sizeof(up_msg_handle) / sizeof(struct spfc_up2drv_msg_handle))) {
- if (up_msg_handle[index].cmd == cmd &&
- up_msg_handle[index].spfc_msg_up2driver_handler) {
- ret = up_msg_handle[index].spfc_msg_up2driver_handler(hba, buf_in);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_ERR,
- "[warn]Port(0x%x) process up cmd(0x%x) failed",
- hba->port_cfg.port_id, cmd);
- }
- *out_size = sizeof(struct spfc_link_event);
- return;
- }
- index++;
- }
-
- *out_size = sizeof(struct spfc_link_event);
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_ERR,
- "[err]Port(0x%x) process up cmd(0x%x) failed",
- hba->port_cfg.port_id, cmd);
-}
-
-u32 spfc_get_topo_act(void *hba, void *topo_act)
-{
- struct spfc_hba_info *spfc_hba = hba;
- enum unf_act_topo *pen_topo_act = topo_act;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(topo_act, UNF_RETURN_ERROR);
-
- /* Get topo from low_level */
- *pen_topo_act = spfc_hba->active_topo;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Get active topology: 0x%x", *pen_topo_act);
-
- return RETURN_OK;
-}
-
-u32 spfc_get_loop_alpa(void *hba, void *alpa)
-{
- ulong flags = 0;
- struct spfc_hba_info *spfc_hba = hba;
- u8 *alpa_temp = alpa;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(alpa, UNF_RETURN_ERROR);
-
- spin_lock_irqsave(&spfc_hba->hba_lock, flags);
- *alpa_temp = spfc_hba->active_alpa;
- spin_unlock_irqrestore(&spfc_hba->hba_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Get active AL_PA(0x%x)", *alpa_temp);
-
- return RETURN_OK;
-}
-
-static void spfc_get_fabric_login_params(struct spfc_hba_info *hba,
- struct unf_port_login_parms *params_addr)
-{
- ulong flag = 0;
-
- spin_lock_irqsave(&hba->hba_lock, flag);
- hba->active_topo = params_addr->act_topo;
- hba->compared_ratov_val = params_addr->compared_ratov_val;
- hba->compared_edtov_val = params_addr->compared_edtov_val;
- hba->compared_bb_scn = params_addr->compared_bbscn;
- hba->remote_edtov_tag = params_addr->remote_edtov_tag;
- hba->remote_rttov_tag = params_addr->remote_rttov_tag;
- hba->remote_bb_credit = params_addr->remote_bb_credit;
- spin_unlock_irqrestore(&hba->hba_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) topo(0x%x) get fabric params: R_A_TOV(0x%x) E_D_TOV(%u) BB_CREDIT(0x%x) BB_SC_N(0x%x)",
- hba->port_cfg.port_id, hba->active_topo,
- hba->compared_ratov_val, hba->compared_edtov_val,
- hba->remote_bb_credit, hba->compared_bb_scn);
-}
-
-static void spfc_get_port_login_params(struct spfc_hba_info *hba,
- struct unf_port_login_parms *params_addr)
-{
- ulong flag = 0;
-
- spin_lock_irqsave(&hba->hba_lock, flag);
- hba->compared_ratov_val = params_addr->compared_ratov_val;
- hba->compared_edtov_val = params_addr->compared_edtov_val;
- hba->compared_bb_scn = params_addr->compared_bbscn;
- hba->remote_edtov_tag = params_addr->remote_edtov_tag;
- hba->remote_rttov_tag = params_addr->remote_rttov_tag;
- hba->remote_bb_credit = params_addr->remote_bb_credit;
- spin_unlock_irqrestore(&hba->hba_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "Port(0x%x) Topo(0x%x) Get Port Params: R_A_TOV(0x%x), E_D_TOV(0x%x), BB_CREDIT(0x%x), BB_SC_N(0x%x).",
- hba->port_cfg.port_id, hba->active_topo,
- hba->compared_ratov_val, hba->compared_edtov_val,
- hba->remote_bb_credit, hba->compared_bb_scn);
-}
-
-u32 spfc_update_fabric_param(void *hba, void *para_in)
-{
- u32 ret = RETURN_OK;
- struct spfc_hba_info *spfc_hba = hba;
- struct unf_port_login_parms *login_coparms = para_in;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(para_in, UNF_RETURN_ERROR);
-
- spfc_get_fabric_login_params(spfc_hba, login_coparms);
-
- if (spfc_hba->active_topo == UNF_ACT_TOP_P2P_FABRIC ||
- spfc_hba->active_topo == UNF_ACT_TOP_PUBLIC_LOOP) {
- if (spfc_hba->work_mode == SPFC_SMARTIO_WORK_MODE_FC)
- ret = spfc_config_login_api(spfc_hba, login_coparms);
- }
-
- return ret;
-}
-
-u32 spfc_update_port_param(void *hba, void *para_in)
-{
- u32 ret = RETURN_OK;
- struct spfc_hba_info *spfc_hba = hba;
- struct unf_port_login_parms *login_coparms =
- (struct unf_port_login_parms *)para_in;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(para_in, UNF_RETURN_ERROR);
-
- if (spfc_hba->active_topo == UNF_ACT_TOP_PRIVATE_LOOP ||
- spfc_hba->active_topo == UNF_ACT_TOP_P2P_DIRECT) {
- spfc_get_port_login_params(spfc_hba, login_coparms);
- ret = spfc_config_login_api(spfc_hba, login_coparms);
- }
-
- spfc_save_login_parms_in_sq_info(spfc_hba, login_coparms);
-
- return ret;
-}
-
-u32 spfc_get_workable_bb_credit(void *hba, void *bb_credit)
-{
- u32 *bb_credit_temp = (u32 *)bb_credit;
- struct spfc_hba_info *spfc_hba = hba;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(bb_credit, UNF_RETURN_ERROR);
- if (spfc_hba->active_port_speed == UNF_PORT_SPEED_32_G)
- *bb_credit_temp = SPFC_LOWLEVEL_DEFAULT_32G_BB_CREDIT;
- else if (spfc_hba->active_port_speed == UNF_PORT_SPEED_16_G)
- *bb_credit_temp = SPFC_LOWLEVEL_DEFAULT_16G_BB_CREDIT;
- else
- *bb_credit_temp = SPFC_LOWLEVEL_DEFAULT_8G_BB_CREDIT;
-
- return RETURN_OK;
-}
-
-u32 spfc_get_workable_bb_scn(void *hba, void *bb_scn)
-{
- u32 *bb_scn_temp = (u32 *)bb_scn;
- struct spfc_hba_info *spfc_hba = (struct spfc_hba_info *)hba;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(bb_scn, UNF_RETURN_ERROR);
-
- *bb_scn_temp = spfc_hba->port_bb_scn_cfg;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Return BBSCN(0x%x) to CM", *bb_scn_temp);
-
- return RETURN_OK;
-}
-
-u32 spfc_get_loop_map(void *hba, void *buf)
-{
- ulong flags = 0;
- struct unf_buf *buf_temp = (struct unf_buf *)buf;
- struct spfc_hba_info *spfc_hba = hba;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buf_temp, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buf_temp->buf, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(buf_temp->buf_len, UNF_RETURN_ERROR);
-
- if (buf_temp->buf_len > UNF_LOOPMAP_COUNT)
- return UNF_RETURN_ERROR;
-
- spin_lock_irqsave(&spfc_hba->hba_lock, flags);
- if (spfc_hba->loop_map_valid != LOOP_MAP_VALID) {
- spin_unlock_irqrestore(&spfc_hba->hba_lock, flags);
- return UNF_RETURN_ERROR;
- }
- memcpy(buf_temp->buf, spfc_hba->loop_map, buf_temp->buf_len);
- spin_unlock_irqrestore(&spfc_hba->hba_lock, flags);
-
- return RETURN_OK;
-}
-
-u32 spfc_mb_reset_chip(struct spfc_hba_info *hba, u8 sub_type)
-{
- struct spfc_inmbox_port_reset port_reset;
- union spfc_outmbox_generic *port_reset_sts = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- memset(&port_reset, 0, sizeof(port_reset));
-
- port_reset_sts = kmalloc(sizeof(union spfc_outmbox_generic), GFP_ATOMIC);
- if (!port_reset_sts) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "malloc outmbox memory failed");
- return UNF_RETURN_ERROR;
- }
- memset(port_reset_sts, 0, sizeof(union spfc_outmbox_generic));
- port_reset.header.cmnd_type = SPFC_MBOX_PORT_RESET;
- port_reset.header.length = SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_port_reset));
- port_reset.op_code = sub_type;
-
- if (spfc_mb_send_and_wait_mbox(hba, &port_reset, sizeof(port_reset),
- port_reset_sts) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[warn]Port(0x%x) can't send and wait mailbox with command type(0x%x)",
- hba->port_cfg.port_id, port_reset.header.cmnd_type);
-
- goto exit;
- }
-
- if (port_reset_sts->port_reset_sts.status != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "[warn]Port(0x%x) receive mailbox type(0x%x) status(0x%x) incorrect",
- hba->port_cfg.port_id,
- port_reset_sts->port_reset_sts.header.cmnd_type,
- port_reset_sts->port_reset_sts.status);
-
- goto exit;
- }
-
- if (port_reset_sts->port_reset_sts.header.cmnd_type != SPFC_MBOX_PORT_RESET_STS) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "[warn]Port(0x%x) recv mailbox type(0x%x) incorrect",
- hba->port_cfg.port_id,
- port_reset_sts->port_reset_sts.header.cmnd_type);
-
- goto exit;
- }
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_MAJOR,
- "[info]Port(0x%x) reset chip mailbox success",
- hba->port_cfg.port_id);
-
- ret = RETURN_OK;
-exit:
- kfree(port_reset_sts);
-
- return ret;
-}
-
-u32 spfc_clear_sq_wqe_done(struct spfc_hba_info *hba)
-{
- int ret1 = RETURN_OK;
- u32 ret2 = RETURN_OK;
- struct spfc_inmbox_clear_done clear_done;
-
- clear_done.header.cmnd_type = SPFC_MBOX_BUFFER_CLEAR_DONE;
- clear_done.header.length = SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_clear_done));
- clear_done.header.port_id = hba->port_index;
-
- ret1 = sphw_msg_to_mgmt_async(hba->dev_handle, COMM_MOD_FC,
- SPFC_MBOX_BUFFER_CLEAR_DONE, &clear_done,
- sizeof(clear_done), SPHW_CHANNEL_FC);
-
- if (ret1 != 0) {
- SPFC_MAILBOX_STAT(hba, SPFC_SEND_CLEAR_DONE_FAIL);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC Port(0x%x) can't send clear done cmd to up, ret:%d",
- hba->port_cfg.port_id, ret1);
-
- return UNF_RETURN_ERROR;
- }
-
- SPFC_MAILBOX_STAT(hba, SPFC_SEND_CLEAR_DONE);
- hba->queue_set_stage = SPFC_QUEUE_SET_STAGE_FLUSHDONE;
- hba->next_clear_sq = 0;
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_KEVENT,
- "[info]Port(0x%x) clear done msg(0x%x) sent to up succeed with stage(0x%x)",
- hba->port_cfg.port_id, clear_done.header.cmnd_type,
- hba->queue_set_stage);
-
- return ret2;
-}
-
-u32 spfc_mbx_get_fw_clear_stat(struct spfc_hba_info *hba, u32 *clear_state)
-{
- struct spfc_inmbox_get_clear_state get_clr_state;
- union spfc_outmbox_generic *port_clear_state_sts = NULL;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(clear_state, UNF_RETURN_ERROR);
-
- memset(&get_clr_state, 0, sizeof(get_clr_state));
-
- port_clear_state_sts = kmalloc(sizeof(union spfc_outmbox_generic), GFP_ATOMIC);
- if (!port_clear_state_sts) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "malloc outmbox memory failed");
- return UNF_RETURN_ERROR;
- }
- memset(port_clear_state_sts, 0, sizeof(union spfc_outmbox_generic));
-
- get_clr_state.header.cmnd_type = SPFC_MBOX_GET_CLEAR_STATE;
- get_clr_state.header.length =
- SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_get_clear_state));
-
- if (spfc_mb_send_and_wait_mbox(hba, &get_clr_state, sizeof(get_clr_state),
- port_clear_state_sts) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "spfc can't send and wait mailbox, command type: 0x%x",
- get_clr_state.header.cmnd_type);
-
- goto exit;
- }
-
- if (port_clear_state_sts->get_clr_state_sts.status != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "Port(0x%x) Receive mailbox type(0x%x) status incorrect. Status: 0x%x, state 0x%x.",
- hba->port_cfg.port_id,
- port_clear_state_sts->get_clr_state_sts.header.cmnd_type,
- port_clear_state_sts->get_clr_state_sts.status,
- port_clear_state_sts->get_clr_state_sts.state);
-
- goto exit;
- }
-
- if (port_clear_state_sts->get_clr_state_sts.header.cmnd_type !=
- SPFC_MBOX_GET_CLEAR_STATE_STS) {
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_ERR,
- "Port(0x%x) recv mailbox type(0x%x) incorrect.",
- hba->port_cfg.port_id,
- port_clear_state_sts->get_clr_state_sts.header.cmnd_type);
-
- goto exit;
- }
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MAJOR,
- "Port(0x%x) get port clear state 0x%x.",
- hba->port_cfg.port_id,
- port_clear_state_sts->get_clr_state_sts.state);
-
- *clear_state = port_clear_state_sts->get_clr_state_sts.state;
-
- ret = RETURN_OK;
-exit:
- kfree(port_clear_state_sts);
-
- return ret;
-}
-
-u32 spfc_mbx_config_default_session(void *hba, u32 flag)
-{
- struct spfc_hba_info *spfc_hba = NULL;
- struct spfc_inmbox_default_sq_info default_sq_info;
- union spfc_outmbox_generic default_sq_info_sts;
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- spfc_hba = (struct spfc_hba_info *)hba;
-
- memset(&default_sq_info, 0, sizeof(struct spfc_inmbox_default_sq_info));
- memset(&default_sq_info_sts, 0, sizeof(union spfc_outmbox_generic));
-
- default_sq_info.header.cmnd_type = SPFC_MBOX_SEND_DEFAULT_SQ_INFO;
- default_sq_info.header.length =
- SPFC_BYTES_TO_DW_NUM(sizeof(struct spfc_inmbox_default_sq_info));
- default_sq_info.func_id = sphw_global_func_id(spfc_hba->dev_handle);
-
- /* When flag is 1, set default SQ info when probe, when 0, clear when
- * remove
- */
- if (flag) {
- default_sq_info.sq_cid = spfc_hba->default_sq_info.sq_cid;
- default_sq_info.sq_xid = spfc_hba->default_sq_info.sq_xid;
- default_sq_info.valid = 1;
- }
-
- ret =
- spfc_mb_send_and_wait_mbox(spfc_hba, &default_sq_info, sizeof(default_sq_info),
- (union spfc_outmbox_generic *)(void *)&default_sq_info_sts);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "spfc can't send and wait mailbox, command type: 0x%x.",
- default_sq_info.header.cmnd_type);
-
- return UNF_RETURN_ERROR;
- }
-
- if (default_sq_info_sts.default_sq_sts.status != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) mailbox status incorrect status(0x%x) .",
- spfc_hba->port_cfg.port_id,
- default_sq_info_sts.default_sq_sts.status);
-
- return UNF_RETURN_ERROR;
- }
-
- if (SPFC_MBOX_SEND_DEFAULT_SQ_INFO_STS !=
- default_sq_info_sts.default_sq_sts.header.cmnd_type) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Port(0x%x) receive mailbox type incorrect type: 0x%x.",
- spfc_hba->port_cfg.port_id,
- default_sq_info_sts.default_sq_sts.header.cmnd_type);
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_chipitf.h b/drivers/scsi/spfc/hw/spfc_chipitf.h
deleted file mode 100644
index acd770514edf..000000000000
--- a/drivers/scsi/spfc/hw/spfc_chipitf.h
+++ /dev/null
@@ -1,797 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_CHIPITF_H
-#define SPFC_CHIPITF_H
-
-#include "unf_type.h"
-#include "unf_log.h"
-#include "spfc_utils.h"
-#include "spfc_module.h"
-
-#include "spfc_service.h"
-
-/* CONF_API_CMND */
-#define SPFC_MBOX_CONFIG_API (0x00)
-#define SPFC_MBOX_CONFIG_API_STS (0xA0)
-
-/* GET_CHIP_INFO_API_CMD */
-#define SPFC_MBOX_GET_CHIP_INFO (0x01)
-#define SPFC_MBOX_GET_CHIP_INFO_STS (0xA1)
-
-/* PORT_RESET */
-#define SPFC_MBOX_PORT_RESET (0x02)
-#define SPFC_MBOX_PORT_RESET_STS (0xA2)
-
-/* SFP_SWITCH_API_CMND */
-#define SPFC_MBOX_PORT_SWITCH (0x03)
-#define SPFC_MBOX_PORT_SWITCH_STS (0xA3)
-
-/* CONF_AF_LOGIN_API_CMND */
-#define SPFC_MBOX_CONFIG_LOGIN_API (0x06)
-#define SPFC_MBOX_CONFIG_LOGIN_API_STS (0xA6)
-
-/* BUFFER_CLEAR_DONE_CMND */
-#define SPFC_MBOX_BUFFER_CLEAR_DONE (0x07)
-#define SPFC_MBOX_BUFFER_CLEAR_DONE_STS (0xA7)
-
-#define SPFC_MBOX_GET_UP_STATE (0x09)
-#define SPFC_MBOX_GET_UP_STATE_STS (0xA9)
-
-/* GET CLEAR DONE STATE */
-#define SPFC_MBOX_GET_CLEAR_STATE (0x0E)
-#define SPFC_MBOX_GET_CLEAR_STATE_STS (0xAE)
-
-/* CONFIG TIMER */
-#define SPFC_MBOX_CONFIG_TIMER (0x10)
-#define SPFC_MBOX_CONFIG_TIMER_STS (0xB0)
-
-/* Led Test */
-#define SPFC_MBOX_LED_TEST (0x12)
-#define SPFC_MBOX_LED_TEST_STS (0xB2)
-
-/* set esch */
-#define SPFC_MBOX_SET_ESCH (0x13)
-#define SPFC_MBOX_SET_ESCH_STS (0xB3)
-
-/* set get tx serdes */
-#define SPFC_MBOX_SET_GET_SERDES_TX (0x14)
-#define SPFC_MBOX_SET_GET_SERDES_TX_STS (0xB4)
-
-/* get rx serdes */
-#define SPFC_MBOX_GET_SERDES_RX (0x15)
-#define SPFC_MBOX_GET_SERDES_RX_STS (0xB5)
-
-/* i2c read write */
-#define SPFC_MBOX_I2C_WR_RD (0x16)
-#define SPFC_MBOX_I2C_WR_RD_STS (0xB6)
-
-/* GET UCODE STATS CMD */
-#define SPFC_MBOX_GET_UCODE_STAT (0x18)
-#define SPFC_MBOX_GET_UCODE_STAT_STS (0xB8)
-
-/* gpio read write */
-#define SPFC_MBOX_GPIO_WR_RD (0x19)
-#define SPFC_MBOX_GPIO_WR_RD_STS (0xB9)
-
-#define SPFC_MBOX_SEND_DEFAULT_SQ_INFO (0x26)
-#define SPFC_MBOX_SEND_DEFAULT_SQ_INFO_STS (0xc6)
-
-/* FC: DRV->UP */
-#define SPFC_MBOX_SEND_ELS_CMD (0x2A)
-#define SPFC_MBOX_SEND_VPORT_INFO (0x2B)
-
-/* FC: UP->DRV */
-#define SPFC_MBOX_RECV_FC_LINKUP (0x40)
-#define SPFC_MBOX_RECV_FC_LINKDOWN (0x41)
-#define SPFC_MBOX_RECV_FC_DELCMD (0x42)
-#define SPFC_MBOX_RECV_FC_ERROR (0x43)
-
-#define LOOP_MAP_VALID (1)
-#define LOOP_MAP_INVALID (0)
-
-#define SPFC_MBOX_SIZE (1024)
-#define SPFC_MBOX_HEADER_SIZE (4)
-
-#define UNDEFINEOPCODE (0)
-
-#define VALUEMASK_L 0x00000000FFFFFFFF
-#define VALUEMASK_H 0xFFFFFFFF00000000
-
-#define STATUS_OK (0)
-#define STATUS_FAIL (1)
-
-enum spfc_drv2up_unblock_msg_cmd_code {
- SPFC_SEND_ELS_CMD,
- SPFC_SEND_ELS_CMD_FAIL,
- SPFC_RCV_ELS_CMD_RSP,
- SPFC_SEND_CONFIG_LOGINAPI,
- SPFC_SEND_CONFIG_LOGINAPI_FAIL,
- SPFC_RCV_CONFIG_LOGIN_API_RSP,
- SPFC_SEND_CLEAR_DONE,
- SPFC_SEND_CLEAR_DONE_FAIL,
- SPFC_RCV_CLEAR_DONE_RSP,
- SPFC_SEND_VPORT_INFO_DONE,
- SPFC_SEND_VPORT_INFO_FAIL,
- SPFC_SEND_VPORT_INFO_RSP,
- SPFC_MBOX_CMD_BUTT
-};
-
-/* up to dirver cmd code */
-enum spfc_up2drv_msg_cmd_code {
- SPFC_UP2DRV_MSG_CMD_LINKUP = 0x1,
- SPFC_UP2DRV_MSG_CMD_LINKDOWN = 0x2,
- SPFC_UP2DRV_MSG_CMD_BUTT
-};
-
-/* up to driver handle templete */
-struct spfc_up2drv_msg_handle {
- u8 cmd;
- u32 (*spfc_msg_up2driver_handler)(struct spfc_hba_info *hba, void *buf_in);
-};
-
-/* tile to driver cmd code */
-enum spfc_tile2drv_msg_cmd_code {
- SPFC_TILE2DRV_MSG_CMD_SCAN_DONE,
- SPFC_TILE2DRV_MSG_CMD_FLUSH_DONE,
- SPFC_TILE2DRV_MSG_CMD_BUTT
-};
-
-/* tile to driver handle templete */
-struct spfc_tile2drv_msg_handle {
- u8 cmd;
- u32 (*spfc_msg_tile2driver_handler)(struct spfc_hba_info *hba, u8 cmd, u64 val);
-};
-
-/* Mbox Common Header */
-struct spfc_mbox_header {
- u8 cmnd_type;
- u8 length;
- u8 port_id;
- u8 reserved;
-};
-
-/* open or close the sfp */
-struct spfc_inmbox_port_switch {
- struct spfc_mbox_header header;
- u32 op_code : 8;
- u32 rsvd0 : 24;
- u32 rsvd1[6];
-};
-
-struct spfc_inmbox_send_vport_info {
- struct spfc_mbox_header header;
-
- u64 sys_port_wwn;
- u64 sys_node_name;
-
- u32 nport_id : 24;
- u32 vpi : 8;
-};
-
-struct spfc_outmbox_port_switch_sts {
- struct spfc_mbox_header header;
-
- u16 reserved1;
- u8 reserved2;
- u8 status;
-};
-
-/* config API */
-struct spfc_inmbox_config_api {
- struct spfc_mbox_header header;
-
- u32 op_code : 8;
- u32 reserved1 : 24;
-
- u8 topy_mode;
- u8 sfp_speed;
- u8 max_speed;
- u8 hard_alpa;
-
- u8 port_name[UNF_WWN_LEN];
-
- u32 slave : 1;
- u32 auto_sneg : 1;
- u32 reserved2 : 30;
-
- u32 rx_6432g_bb_credit : 16; /* 160 */
- u32 rx_16g_bb_credit : 16; /* 80 */
- u32 rx_84g_bb_credit : 16; /* 50 */
- u32 rdy_cnt_bf_fst_frm : 16; /* 8 */
-
- u32 esch_32g_value;
- u32 esch_16g_value;
- u32 esch_8g_value;
- u32 esch_4g_value;
- u32 esch_64g_value;
- u32 esch_bust_size;
-};
-
-struct spfc_outmbox_config_api_sts {
- struct spfc_mbox_header header;
- u16 reserved1;
- u8 reserved2;
- u8 status;
-};
-
-/* Get chip info */
-struct spfc_inmbox_get_chip_info {
- struct spfc_mbox_header header;
-};
-
-struct spfc_outmbox_get_chip_info_sts {
- struct spfc_mbox_header header;
- u8 status;
- u8 board_type;
- u8 rvsd0[2];
- u64 wwpn;
- u64 wwnn;
- u64 rsvd1;
-};
-
-/* Get reg info */
-struct spfc_inmbox_get_reg_info {
- struct spfc_mbox_header header;
- u32 op_code : 1;
- u32 reg_len : 8;
- u32 rsvd1 : 23;
- u32 reg_addr;
- u32 reg_value_l32;
- u32 reg_value_h32;
- u32 rsvd2[27];
-};
-
-/* Get reg info sts */
-struct spfc_outmbox_get_reg_info_sts {
- struct spfc_mbox_header header;
-
- u16 rsvd0;
- u8 rsvd1;
- u8 status;
- u32 reg_value_l32;
- u32 reg_value_h32;
- u32 rsvd2[28];
-};
-
-/* Config login API */
-struct spfc_inmbox_config_login {
- struct spfc_mbox_header header;
-
- u32 op_code : 8;
- u32 reserved1 : 24;
-
- u16 tx_bb_credit;
- u16 reserved2;
-
- u32 rtov;
- u32 etov;
-
- u32 rt_tov_tag : 1;
- u32 ed_tov_tag : 1;
- u32 bb_credit : 6;
- u32 bb_scn : 8;
- u32 lr_flag : 16;
-};
-
-struct spfc_outmbox_config_login_sts {
- struct spfc_mbox_header header;
-
- u16 reserved1;
- u8 reserved2;
- u8 status;
-};
-
-/* port reset */
-#define SPFC_MBOX_SUBTYPE_LIGHT_RESET (0x0)
-#define SPFC_MBOX_SUBTYPE_HEAVY_RESET (0x1)
-
-struct spfc_inmbox_port_reset {
- struct spfc_mbox_header header;
-
- u32 op_code : 8;
- u32 reserved : 24;
-};
-
-struct spfc_outmbox_port_reset_sts {
- struct spfc_mbox_header header;
-
- u16 reserved1;
- u8 reserved2;
- u8 status;
-};
-
-/* led test */
-struct spfc_inmbox_led_test {
- struct spfc_mbox_header header;
-
- /* 0->act type;1->low speed;1->high speed */
- u8 led_type;
- /* 0:twinkle;1:light on;2:light off;0xff:defalut */
- u8 led_mode;
- u8 resvd[ARRAY_INDEX_2];
-};
-
-struct spfc_outmbox_led_test_sts {
- struct spfc_mbox_header header;
-
- u16 rsvd1;
- u8 rsvd2;
- u8 status;
-};
-
-/* set esch */
-struct spfc_inmbox_set_esch {
- struct spfc_mbox_header header;
-
- u32 esch_value;
- u32 esch_bust_size;
-};
-
-struct spfc_outmbox_set_esch_sts {
- struct spfc_mbox_header header;
-
- u16 rsvd1;
- u8 rsvd2;
- u8 status;
-};
-
-struct spfc_inmbox_set_serdes_tx {
- struct spfc_mbox_header header;
-
- u8 swing; /* amplitude setting */
- char serdes_pre1; /* pre1 setting */
- char serdes_pre2; /* pre2 setting */
- char serdes_post; /* post setting */
- u8 serdes_main; /* main setting */
- u8 op_code; /* opcode,0:setting;1:read */
- u8 rsvd[ARRAY_INDEX_2];
-};
-
-struct spfc_outmbox_set_serdes_tx_sts {
- struct spfc_mbox_header header;
- u16 rvsd0;
- u8 rvsd1;
- u8 status;
- u8 swing;
- char serdes_pre1;
- char serdes_pre2;
- char serdes_post;
- u8 serdes_main;
- u8 rsvd2[ARRAY_INDEX_3];
-};
-
-struct spfc_inmbox_i2c_wr_rd {
- struct spfc_mbox_header header;
- u8 op_code; /* 0 write, 1 read */
- u8 rsvd[ARRAY_INDEX_3];
-
- u32 dev_addr;
- u32 offset;
- u32 wr_data;
-};
-
-struct spfc_outmbox_i2c_wr_rd_sts {
- struct spfc_mbox_header header;
- u8 status;
- u8 resvd[ARRAY_INDEX_3];
-
- u32 rd_data;
-};
-
-struct spfc_inmbox_gpio_wr_rd {
- struct spfc_mbox_header header;
- u8 op_code; /* 0 write,1 read */
- u8 rsvd[ARRAY_INDEX_3];
-
- u32 pin;
- u32 wr_data;
-};
-
-struct spfc_outmbox_gpio_wr_rd_sts {
- struct spfc_mbox_header header;
- u8 status;
- u8 resvd[ARRAY_INDEX_3];
-
- u32 rd_data;
-};
-
-struct spfc_inmbox_get_serdes_rx {
- struct spfc_mbox_header header;
-
- u8 op_code;
- u8 h16_macro;
- u8 h16_lane;
- u8 rsvd;
-};
-
-struct spfc_inmbox_get_serdes_rx_sts {
- struct spfc_mbox_header header;
- u16 rvsd0;
- u8 rvsd1;
- u8 status;
- int left_eye;
- int right_eye;
- int low_eye;
- int high_eye;
-};
-
-struct spfc_ser_op_m_l {
- u8 op_code;
- u8 h16_macro;
- u8 h16_lane;
- u8 rsvd;
-};
-
-/* get sfp info */
-#define SPFC_MBOX_GET_SFP_INFO_MB_LENGTH 1
-#define OFFSET_TWO_DWORD 2
-#define OFFSET_ONE_DWORD 1
-
-struct spfc_inmbox_get_sfp_info {
- struct spfc_mbox_header header;
-};
-
-struct spfc_outmbox_get_sfp_info_sts {
- struct spfc_mbox_header header;
-
- u32 rcvd : 8;
- u32 length : 16;
- u32 status : 8;
-};
-
-/* get ucode stats */
-#define SPFC_UCODE_STAT_NUM 64
-
-struct spfc_outmbox_get_ucode_stat {
- struct spfc_mbox_header header;
-};
-
-struct spfc_outmbox_get_ucode_stat_sts {
- struct spfc_mbox_header header;
-
- u16 rsvd;
- u8 rsvd2;
- u8 status;
-
- u32 ucode_stat[SPFC_UCODE_STAT_NUM];
-};
-
-/* uP-->Driver asyn event API */
-struct spfc_link_event {
- struct spfc_mbox_header header;
-
- u8 link_event;
- u8 reason;
- u8 speed;
- u8 top_type;
-
- u8 alpa_value;
- u8 reserved1;
- u16 paticpate : 1;
- u16 ac_led : 1;
- u16 yellow_speed_led : 1;
- u16 green_speed_led : 1;
- u16 reserved2 : 12;
-
- u8 loop_map_info[128];
-};
-
-enum spfc_up_err_type {
- SPFC_UP_ERR_DRV_PARA = 0,
- SPFC_UP_ERR_SFP = 1,
- SPFC_UP_ERR_32G_PUB = 2,
- SPFC_UP_ERR_32G_UA = 3,
- SPFC_UP_ERR_32G_MAC = 4,
- SPFC_UP_ERR_NON32G_DFX = 5,
- SPFC_UP_ERR_NON32G_MAC = 6,
- SPFC_UP_ERR_BUTT
-
-};
-
-enum spfc_up_err_value {
- /* ERR type 0 */
- SPFC_DRV_2_UP_PARA_ERR = 0,
-
- /* ERR type 1 */
- SPFC_SFP_SPEED_ERR,
-
- /* ERR type 2 */
- SPFC_32GPUB_UA_RXESCH_FIFO_OF,
- SPFC_32GPUB_UA_RXESCH_FIFO_UCERR,
-
- /* ERR type 3 */
- SPFC_32G_UA_UATX_LEN_ABN,
- SPFC_32G_UA_RXAFIFO_OF,
- SPFC_32G_UA_TXAFIFO_OF,
- SPFC_32G_UA_RXAFIFO_UCERR,
- SPFC_32G_UA_TXAFIFO_UCERR,
-
- /* ERR type 4 */
- SPFC_32G_MAC_RX_BBC_FATAL,
- SPFC_32G_MAC_TX_BBC_FATAL,
- SPFC_32G_MAC_TXFIFO_UF,
- SPFC_32G_MAC_PCS_TXFIFO_UF,
- SPFC_32G_MAC_RXBBC_CRDT_TO,
- SPFC_32G_MAC_PCS_RXAFIFO_OF,
- SPFC_32G_MAC_PCS_TXFIFO_OF,
- SPFC_32G_MAC_FC2P_RXFIFO_OF,
- SPFC_32G_MAC_FC2P_TXFIFO_OF,
- SPFC_32G_MAC_FC2P_CAFIFO_OF,
- SPFC_32G_MAC_PCS_RXRSFECM_UCEER,
- SPFC_32G_MAC_PCS_RXAFIFO_UCEER,
- SPFC_32G_MAC_PCS_TXFIFO_UCEER,
- SPFC_32G_MAC_FC2P_RXFIFO_UCEER,
- SPFC_32G_MAC_FC2P_TXFIFO_UCEER,
-
- /* ERR type 5 */
- SPFC_NON32G_DFX_FC1_DFX_BF_FIFO,
- SPFC_NON32G_DFX_FC1_DFX_BP_FIFO,
- SPFC_NON32G_DFX_FC1_DFX_RX_AFIFO_ERR,
- SPFC_NON32G_DFX_FC1_DFX_TX_AFIFO_ERR,
- SPFC_NON32G_DFX_FC1_DFX_DIRQ_RXBUF_FIFO1,
- SPFC_NON32G_DFX_FC1_DFX_DIRQ_RXBBC_TO,
- SPFC_NON32G_DFX_FC1_DFX_DIRQ_TXDAT_FIFO,
- SPFC_NON32G_DFX_FC1_DFX_DIRQ_TXCMD_FIFO,
- SPFC_NON32G_DFX_FC1_ERR_R_RDY,
-
- /* ERR type 6 */
- SPFC_NON32G_MAC_FC1_FAIRNESS_ERROR,
-
- SPFC_ERR_VALUE_BUTT
-
-};
-
-struct spfc_up_error_event {
- struct spfc_mbox_header header;
-
- u8 link_event;
- u8 error_level;
- u8 error_type;
- u8 error_value;
-};
-
-struct spfc_inmbox_clear_done {
- struct spfc_mbox_header header;
-};
-
-/* receive els cmd */
-struct spfc_inmbox_rcv_els {
- struct spfc_mbox_header header;
- u16 pkt_type;
- u16 pkt_len;
- u8 frame[ARRAY_INDEX_0];
-};
-
-/* FCF event type */
-enum spfc_fcf_event_type {
- SPFC_FCF_SELECTED = 0,
- SPFC_FCF_DEAD,
- SPFC_FCF_CLEAR_VLINK,
- SPFC_FCF_CLEAR_VLINK_APPOINTED
-};
-
-struct spfc_nport_id_info {
- u32 nport_id : 24;
- u32 vp_index : 8;
-};
-
-struct spfc_inmbox_fcf_event {
- struct spfc_mbox_header header;
-
- u8 fcf_map[ARRAY_INDEX_3];
- u8 event_type;
-
- u8 fcf_mac_h4[ARRAY_INDEX_4];
-
- u16 vlan_info;
- u8 fcf_mac_l2[ARRAY_INDEX_2];
-
- struct spfc_nport_id_info nport_id_info[UNF_SPFC_MAXNPIV_NUM + 1];
-};
-
-/* send els cmd */
-struct spfc_inmbox_send_els {
- struct spfc_mbox_header header;
-
- u8 oper_code;
- u8 rsvd[ARRAY_INDEX_3];
-
- u8 resvd;
- u8 els_cmd_type;
- u16 pkt_len;
-
- u8 fcf_mac_h4[ARRAY_INDEX_4];
-
- u16 vlan_info;
- u8 fcf_mac_l2[ARRAY_INDEX_2];
-
- u8 fc_frame[SPFC_FC_HEAD_LEN + UNF_FLOGI_PAYLOAD_LEN];
-};
-
-struct spfc_inmbox_send_els_sts {
- struct spfc_mbox_header header;
-
- u16 rx_id;
- u16 err_code;
-
- u16 ox_id;
- u16 rsvd;
-};
-
-struct spfc_inmbox_get_clear_state {
- struct spfc_mbox_header header;
- u32 resvd[31];
-};
-
-struct spfc_outmbox_get_clear_state_sts {
- struct spfc_mbox_header header;
- u16 rsvd1;
- u8 state; /* 1--clear doing. 0---clear done. */
- u8 status; /* 0--ok,!0---fail */
- u32 rsvd2[30];
-};
-
-#define SPFC_FIP_MODE_VN2VF (0)
-#define SPFC_FIP_MODE_VN2VN (1)
-
-/* get up state */
-struct spfc_inmbox_get_up_state {
- struct spfc_mbox_header header;
-
- u64 cur_jiff_time;
-};
-
-/* get port state */
-struct spfc_inmbox_get_port_info {
- struct spfc_mbox_header header;
-};
-
-struct spfc_outmbox_get_up_state_sts {
- struct spfc_mbox_header header;
-
- u8 status;
- u8 rsv0;
- u16 rsv1;
- struct unf_port_dynamic_info dymic_info;
-};
-
-struct spfc_outmbox_get_port_info_sts {
- struct spfc_mbox_header header;
-
- u32 status : 8;
- u32 fe_16g_cvis_tts : 8;
- u32 bb_scn : 8;
- u32 loop_credit : 8;
-
- u32 non_loop_rx_credit : 8;
- u32 non_loop_tx_credit : 8;
- u32 sfp_speed : 8;
- u32 present : 8;
-};
-
-struct spfc_inmbox_config_timer {
- struct spfc_mbox_header header;
-
- u16 op_code;
- u16 fun_id;
- u32 user_data;
-};
-
-struct spfc_inmbox_config_srqc {
- struct spfc_mbox_header header;
-
- u16 valid;
- u16 fun_id;
- u32 srqc_gpa_hi;
- u32 srqc_gpa_lo;
-};
-
-struct spfc_outmbox_config_timer_sts {
- struct spfc_mbox_header header;
-
- u8 status;
- u8 rsv[ARRAY_INDEX_3];
-};
-
-struct spfc_outmbox_config_srqc_sts {
- struct spfc_mbox_header header;
-
- u8 status;
- u8 rsv[ARRAY_INDEX_3];
-};
-
-struct spfc_inmbox_default_sq_info {
- struct spfc_mbox_header header;
- u32 sq_cid;
- u32 sq_xid;
- u16 func_id;
- u16 valid;
-};
-
-struct spfc_outmbox_default_sq_info_sts {
- struct spfc_mbox_header header;
- u8 status;
- u8 rsv[ARRAY_INDEX_3];
-};
-
-/* Generic Inmailbox and Outmailbox */
-union spfc_inmbox_generic {
- struct {
- struct spfc_mbox_header header;
- u32 rsvd[(SPFC_MBOX_SIZE - SPFC_MBOX_HEADER_SIZE) / sizeof(u32)];
- } generic;
-
- struct spfc_inmbox_port_switch port_switch;
- struct spfc_inmbox_config_api config_api;
- struct spfc_inmbox_get_chip_info get_chip_info;
- struct spfc_inmbox_config_login config_login;
- struct spfc_inmbox_port_reset port_reset;
- struct spfc_inmbox_set_esch esch_set;
- struct spfc_inmbox_led_test led_test;
- struct spfc_inmbox_get_sfp_info get_sfp_info;
- struct spfc_inmbox_clear_done clear_done;
- struct spfc_outmbox_get_ucode_stat get_ucode_stat;
- struct spfc_inmbox_get_clear_state get_clr_state;
- struct spfc_inmbox_send_vport_info send_vport_info;
- struct spfc_inmbox_get_up_state get_up_state;
- struct spfc_inmbox_config_timer timer_config;
- struct spfc_inmbox_config_srqc config_srqc;
- struct spfc_inmbox_get_port_info get_port_info;
-};
-
-union spfc_outmbox_generic {
- struct {
- struct spfc_mbox_header header;
- u32 rsvd[(SPFC_MBOX_SIZE - SPFC_MBOX_HEADER_SIZE) / sizeof(u32)];
- } generic;
-
- struct spfc_outmbox_port_switch_sts port_switch_sts;
- struct spfc_outmbox_config_api_sts config_api_sts;
- struct spfc_outmbox_get_chip_info_sts get_chip_info_sts;
- struct spfc_outmbox_get_reg_info_sts get_reg_info_sts;
- struct spfc_outmbox_config_login_sts config_login_sts;
- struct spfc_outmbox_port_reset_sts port_reset_sts;
- struct spfc_outmbox_led_test_sts led_test_sts;
- struct spfc_outmbox_set_esch_sts esch_set_sts;
- struct spfc_inmbox_get_serdes_rx_sts serdes_rx_get_sts;
- struct spfc_outmbox_set_serdes_tx_sts serdes_tx_set_sts;
- struct spfc_outmbox_i2c_wr_rd_sts i2c_wr_rd_sts;
- struct spfc_outmbox_gpio_wr_rd_sts gpio_wr_rd_sts;
- struct spfc_outmbox_get_sfp_info_sts get_sfp_info_sts;
- struct spfc_outmbox_get_ucode_stat_sts get_ucode_stat_sts;
- struct spfc_outmbox_get_clear_state_sts get_clr_state_sts;
- struct spfc_outmbox_get_up_state_sts get_up_state_sts;
- struct spfc_outmbox_config_timer_sts timer_config_sts;
- struct spfc_outmbox_config_srqc_sts config_srqc_sts;
- struct spfc_outmbox_get_port_info_sts get_port_info_sts;
- struct spfc_outmbox_default_sq_info_sts default_sq_sts;
-};
-
-u32 spfc_get_chip_msg(void *hba, void *mac);
-u32 spfc_config_port_table(struct spfc_hba_info *hba);
-u32 spfc_port_switch(struct spfc_hba_info *hba, bool turn_on);
-u32 spfc_get_loop_map(void *hba, void *buf);
-u32 spfc_get_workable_bb_credit(void *hba, void *bb_credit);
-u32 spfc_get_workable_bb_scn(void *hba, void *bb_scn);
-u32 spfc_get_port_current_info(void *hba, void *port_info);
-u32 spfc_get_port_fec(void *hba, void *para_out);
-
-u32 spfc_get_loop_alpa(void *hba, void *alpa);
-u32 spfc_get_topo_act(void *hba, void *topo_act);
-u32 spfc_config_login_api(struct spfc_hba_info *hba, struct unf_port_login_parms *login_parms);
-u32 spfc_mb_send_and_wait_mbox(struct spfc_hba_info *hba, const void *in_mbox, u16 in_size,
- union spfc_outmbox_generic *out_mbox);
-void spfc_up_msg2driver_proc(void *hwdev_handle, void *pri_handle, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out, u16 *out_size);
-
-u32 spfc_mb_reset_chip(struct spfc_hba_info *hba, u8 sub_type);
-u32 spfc_clear_sq_wqe_done(struct spfc_hba_info *hba);
-u32 spfc_update_fabric_param(void *hba, void *para_in);
-u32 spfc_update_port_param(void *hba, void *para_in);
-u32 spfc_update_fdisc_param(void *hba, void *vport_info);
-u32 spfc_mbx_get_fw_clear_stat(struct spfc_hba_info *hba, u32 *clear_state);
-u32 spfc_get_chip_capability(void *hwdev_handle, struct spfc_chip_info *chip_info);
-u32 spfc_mbx_config_default_session(void *hba, u32 flag);
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c b/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c
deleted file mode 100644
index 0c1d97d9e3e6..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c
+++ /dev/null
@@ -1,1611 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/gfp.h>
-#include "sphw_crm.h"
-#include "sphw_hw.h"
-#include "sphw_hwdev.h"
-#include "sphw_hwif.h"
-
-#include "spfc_cqm_object.h"
-#include "spfc_cqm_bitmap_table.h"
-#include "spfc_cqm_bat_cla.h"
-#include "spfc_cqm_main.h"
-
-static unsigned char cqm_ver = 8;
-module_param(cqm_ver, byte, 0644);
-MODULE_PARM_DESC(cqm_ver, "for cqm version control (default=8)");
-
-static void
-cqm_bat_fill_cla_common_gpa(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- struct cqm_bat_entry_standerd *bat_entry_standerd)
-{
- u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
- struct sphw_func_attr *func_attr = NULL;
- struct cqm_bat_entry_vf2pf gpa = {0};
- u32 cla_gpa_h = 0;
- dma_addr_t pa;
-
- if (cla_table->cla_lvl == CQM_CLA_LVL_0)
- pa = cla_table->cla_z_buf.buf_list[0].pa;
- else if (cla_table->cla_lvl == CQM_CLA_LVL_1)
- pa = cla_table->cla_y_buf.buf_list[0].pa;
- else
- pa = cla_table->cla_x_buf.buf_list[0].pa;
-
- gpa.cla_gpa_h = CQM_ADDR_HI(pa) & CQM_CHIP_GPA_HIMASK;
-
- /* On the SPU, the value of spu_en in the GPA address
- * in the BAT is determined by the host ID and fun IDx.
- */
- if (sphw_host_id(cqm_handle->ex_handle) == CQM_SPU_HOST_ID) {
- func_attr = &cqm_handle->func_attribute;
- gpa.acs_spu_en = func_attr->func_global_idx & 0x1;
- } else {
- gpa.acs_spu_en = 0;
- }
-
- memcpy(&cla_gpa_h, &gpa, sizeof(u32));
- bat_entry_standerd->cla_gpa_h = cla_gpa_h;
-
- /* GPA is valid when gpa[0] = 1.
- * CQM_BAT_ENTRY_T_REORDER does not support GPA validity check.
- */
- if (cla_table->type == CQM_BAT_ENTRY_T_REORDER)
- bat_entry_standerd->cla_gpa_l = CQM_ADDR_LW(pa);
- else
- bat_entry_standerd->cla_gpa_l = CQM_ADDR_LW(pa) | gpa_check_enable;
-}
-
-static void cqm_bat_fill_cla_common(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u8 *entry_base_addr)
-{
- struct cqm_bat_entry_standerd *bat_entry_standerd = NULL;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 cache_line = 0;
-
- if (cla_table->type == CQM_BAT_ENTRY_T_TIMER && cqm_ver == 8)
- cache_line = CQM_CHIP_TIMER_CACHELINE;
- else
- cache_line = CQM_CHIP_CACHELINE;
-
- if (cla_table->obj_num == 0) {
- cqm_info(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_num=0, don't init bat entry\n",
- cla_table->type);
- return;
- }
-
- bat_entry_standerd = (struct cqm_bat_entry_standerd *)entry_base_addr;
-
- /* The QPC value is 256/512/1024 and the timer value is 512.
- * The other cacheline value is 256B.
- * The conversion operation is performed inside the chip.
- */
- if (cla_table->obj_size > cache_line) {
- if (cla_table->obj_size == CQM_OBJECT_512)
- bat_entry_standerd->entry_size = CQM_BAT_ENTRY_SIZE_512;
- else
- bat_entry_standerd->entry_size = CQM_BAT_ENTRY_SIZE_1024;
- bat_entry_standerd->max_number = cla_table->max_buffer_size / cla_table->obj_size;
- } else {
- if (cache_line == CQM_CHIP_CACHELINE) {
- bat_entry_standerd->entry_size = CQM_BAT_ENTRY_SIZE_256;
- bat_entry_standerd->max_number = cla_table->max_buffer_size / cache_line;
- } else {
- bat_entry_standerd->entry_size = CQM_BAT_ENTRY_SIZE_512;
- bat_entry_standerd->max_number = cla_table->max_buffer_size / cache_line;
- }
- }
-
- bat_entry_standerd->max_number = bat_entry_standerd->max_number - 1;
-
- bat_entry_standerd->bypass = CQM_BAT_NO_BYPASS_CACHE;
- bat_entry_standerd->z = cla_table->cacheline_z;
- bat_entry_standerd->y = cla_table->cacheline_y;
- bat_entry_standerd->x = cla_table->cacheline_x;
- bat_entry_standerd->cla_level = cla_table->cla_lvl;
-
- cqm_bat_fill_cla_common_gpa(cqm_handle, cla_table, bat_entry_standerd);
-}
-
-static void cqm_bat_fill_cla_cfg(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- struct cqm_func_capability *func_cap = &cqm_handle->func_capability;
- struct cqm_bat_entry_cfg *bat_entry_cfg = NULL;
-
- bat_entry_cfg = (struct cqm_bat_entry_cfg *)(*entry_base_addr);
- bat_entry_cfg->cur_conn_cache = 0;
- bat_entry_cfg->max_conn_cache =
- func_cap->flow_table_based_conn_cache_number;
- bat_entry_cfg->cur_conn_num_h_4 = 0;
- bat_entry_cfg->cur_conn_num_l_16 = 0;
- bat_entry_cfg->max_conn_num = func_cap->flow_table_based_conn_number;
-
- /* Aligns with 64 buckets and shifts rightward by 6 bits.
- * The maximum value of this field is 16 bits. A maximum of 4M buckets
- * can be supported. The value is subtracted by 1. It is used for &hash
- * value.
- */
- if ((func_cap->hash_number >> CQM_HASH_NUMBER_UNIT) != 0) {
- bat_entry_cfg->bucket_num = ((func_cap->hash_number >>
- CQM_HASH_NUMBER_UNIT) - 1);
- }
- if (func_cap->bloomfilter_length != 0) {
- bat_entry_cfg->bloom_filter_len = func_cap->bloomfilter_length -
- 1;
- bat_entry_cfg->bloom_filter_addr = func_cap->bloomfilter_addr;
- }
-
- (*entry_base_addr) += sizeof(struct cqm_bat_entry_cfg);
-}
-
-static void cqm_bat_fill_cla_other(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- cqm_bat_fill_cla_common(cqm_handle, cla_table, *entry_base_addr);
-
- (*entry_base_addr) += sizeof(struct cqm_bat_entry_standerd);
-}
-
-static void cqm_bat_fill_cla_taskmap(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- struct cqm_bat_entry_taskmap *bat_entry_taskmap = NULL;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- int i;
-
- if (cqm_handle->func_capability.taskmap_number != 0) {
- bat_entry_taskmap =
- (struct cqm_bat_entry_taskmap *)(*entry_base_addr);
- for (i = 0; i < CQM_BAT_ENTRY_TASKMAP_NUM; i++) {
- bat_entry_taskmap->addr[i].gpa_h =
- (u32)(cla_table->cla_z_buf.buf_list[i].pa >>
- CQM_CHIP_GPA_HSHIFT);
- bat_entry_taskmap->addr[i].gpa_l =
- (u32)(cla_table->cla_z_buf.buf_list[i].pa &
- CQM_CHIP_GPA_LOMASK);
- cqm_info(handle->dev_hdl,
- "Cla alloc: taskmap bat entry: 0x%x 0x%x\n",
- bat_entry_taskmap->addr[i].gpa_h,
- bat_entry_taskmap->addr[i].gpa_l);
- }
- }
-
- (*entry_base_addr) += sizeof(struct cqm_bat_entry_taskmap);
-}
-
-static void cqm_bat_fill_cla_timer(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- /* Only the PPF allocates timer resources. */
- if (cqm_handle->func_attribute.func_type != CQM_PPF) {
- (*entry_base_addr) += CQM_BAT_ENTRY_SIZE;
- } else {
- cqm_bat_fill_cla_common(cqm_handle, cla_table, *entry_base_addr);
-
- (*entry_base_addr) += sizeof(struct cqm_bat_entry_standerd);
- }
-}
-
-static void cqm_bat_fill_cla_invalid(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- (*entry_base_addr) += CQM_BAT_ENTRY_SIZE;
-}
-
-static void cqm_bat_fill_cla(struct cqm_handle *cqm_handle)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_cla_table *cla_table = NULL;
- u32 entry_type = CQM_BAT_ENTRY_T_INVALID;
- u8 *entry_base_addr = NULL;
- u32 i = 0;
-
- /* Fills each item in the BAT table according to the BAT format. */
- entry_base_addr = bat_table->bat;
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- entry_type = bat_table->bat_entry_type[i];
- cla_table = &bat_table->entry[i];
-
- if (entry_type == CQM_BAT_ENTRY_T_CFG)
- cqm_bat_fill_cla_cfg(cqm_handle, cla_table, &entry_base_addr);
- else if (entry_type == CQM_BAT_ENTRY_T_TASKMAP)
- cqm_bat_fill_cla_taskmap(cqm_handle, cla_table, &entry_base_addr);
- else if (entry_type == CQM_BAT_ENTRY_T_INVALID)
- cqm_bat_fill_cla_invalid(cqm_handle, cla_table, &entry_base_addr);
- else if (entry_type == CQM_BAT_ENTRY_T_TIMER)
- cqm_bat_fill_cla_timer(cqm_handle, cla_table, &entry_base_addr);
- else
- cqm_bat_fill_cla_other(cqm_handle, cla_table, &entry_base_addr);
-
- /* Check whether entry_base_addr is out-of-bounds array. */
- if (entry_base_addr >= (bat_table->bat + CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE))
- break;
- }
-}
-
-u32 cqm_funcid2smfid(struct cqm_handle *cqm_handle)
-{
- u32 funcid = 0;
- u32 smf_sel = 0;
- u32 smf_id = 0;
- u32 smf_pg_partial = 0;
- /* SMF_Selection is selected based on
- * the lower two bits of the function id
- */
- u32 lbf_smfsel[4] = {0, 2, 1, 3};
- /* SMFID is selected based on SMF_PG[1:0] and SMF_Selection(0-1) */
- u32 smfsel_smfid01[4][2] = { {0, 0}, {0, 0}, {1, 1}, {0, 1} };
- /* SMFID is selected based on SMF_PG[3:2] and SMF_Selection(2-4) */
- u32 smfsel_smfid23[4][2] = { {2, 2}, {2, 2}, {3, 3}, {2, 3} };
-
- /* When the LB mode is disabled, SMF0 is always returned. */
- if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_NORMAL) {
- smf_id = 0;
- } else {
- funcid = cqm_handle->func_attribute.func_global_idx & 0x3;
- smf_sel = lbf_smfsel[funcid];
-
- if (smf_sel < 2) {
- smf_pg_partial = cqm_handle->func_capability.smf_pg & 0x3;
- smf_id = smfsel_smfid01[smf_pg_partial][smf_sel];
- } else {
- smf_pg_partial = (cqm_handle->func_capability.smf_pg >> 2) & 0x3;
- smf_id = smfsel_smfid23[smf_pg_partial][smf_sel - 2];
- }
- }
-
- return smf_id;
-}
-
-/* This function is used in LB mode 1/2. The timer spoker info
- * of independent space needs to be configured for 4 SMFs.
- */
-static void cqm_update_timer_gpa(struct cqm_handle *cqm_handle, u32 smf_id)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_cla_table *cla_table = NULL;
- u32 entry_type = CQM_BAT_ENTRY_T_INVALID;
- u8 *entry_base_addr = NULL;
- u32 i = 0;
-
- if (cqm_handle->func_attribute.func_type != CQM_PPF)
- return;
-
- if (cqm_handle->func_capability.lb_mode != CQM_LB_MODE_1 &&
- cqm_handle->func_capability.lb_mode != CQM_LB_MODE_2)
- return;
-
- cla_table = &bat_table->timer_entry[smf_id];
- entry_base_addr = bat_table->bat;
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- entry_type = bat_table->bat_entry_type[i];
-
- if (entry_type == CQM_BAT_ENTRY_T_TIMER) {
- cqm_bat_fill_cla_timer(cqm_handle, cla_table, &entry_base_addr);
- break;
- }
-
- if (entry_type == CQM_BAT_ENTRY_T_TASKMAP)
- entry_base_addr += sizeof(struct cqm_bat_entry_taskmap);
- else
- entry_base_addr += CQM_BAT_ENTRY_SIZE;
-
- /* Check whether entry_base_addr is out-of-bounds array. */
- if (entry_base_addr >=
- (bat_table->bat + CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE))
- break;
- }
-}
-
-static s32 cqm_bat_update_cmd(struct cqm_handle *cqm_handle, struct cqm_cmd_buf *buf_in,
- u32 smf_id, u32 func_id)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_cmdq_bat_update *bat_update_cmd = NULL;
- s32 ret = CQM_FAIL;
-
- bat_update_cmd = (struct cqm_cmdq_bat_update *)(buf_in->buf);
- bat_update_cmd->offset = 0;
-
- if (cqm_handle->bat_table.bat_size > CQM_BAT_MAX_SIZE) {
- cqm_err(handle->dev_hdl,
- "bat_size = %u, which is more than %d.\n",
- cqm_handle->bat_table.bat_size, CQM_BAT_MAX_SIZE);
- return CQM_FAIL;
- }
- bat_update_cmd->byte_len = cqm_handle->bat_table.bat_size;
-
- memcpy(bat_update_cmd->data, cqm_handle->bat_table.bat, bat_update_cmd->byte_len);
-
- bat_update_cmd->smf_id = smf_id;
- bat_update_cmd->func_id = func_id;
-
- cqm_info(handle->dev_hdl, "Bat update: smf_id=%u\n", bat_update_cmd->smf_id);
- cqm_info(handle->dev_hdl, "Bat update: func_id=%u\n", bat_update_cmd->func_id);
-
- cqm_swab32((u8 *)bat_update_cmd, sizeof(struct cqm_cmdq_bat_update) >> CQM_DW_SHIFT);
-
- ret = cqm3_send_cmd_box((void *)(cqm_handle->ex_handle), CQM_MOD_CQM,
- CQM_CMD_T_BAT_UPDATE, buf_in, NULL, NULL,
- CQM_CMD_TIMEOUT, SPHW_CHANNEL_DEFAULT);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm3_send_cmd_box));
- cqm_err(handle->dev_hdl, "%s: send_cmd_box ret=%d\n", __func__,
- ret);
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_bat_update(struct cqm_handle *cqm_handle)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_cmd_buf *buf_in = NULL;
- s32 ret = CQM_FAIL;
- u32 smf_id = 0;
- u32 func_id = 0;
- u32 i = 0;
-
- buf_in = cqm3_cmd_alloc((void *)(cqm_handle->ex_handle));
- CQM_PTR_CHECK_RET(buf_in, CQM_FAIL, CQM_ALLOC_FAIL(buf_in));
- buf_in->size = sizeof(struct cqm_cmdq_bat_update);
-
- /* In non-fake mode, func_id is set to 0xffff */
- func_id = 0xffff;
-
- /* The LB scenario is supported.
- * The normal mode is the traditional mode and is configured on SMF0.
- * In mode 0, load is balanced to four SMFs based on the func ID (except
- * the PPF func ID). The PPF in mode 0 needs to be configured on four
- * SMF, so the timer resources can be shared by the four timer engine.
- * Mode 1/2 is load balanced to four SMF by flow. Therefore, one
- * function needs to be configured to four SMF.
- */
- if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_NORMAL ||
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_0 &&
- cqm_handle->func_attribute.func_type != CQM_PPF)) {
- smf_id = cqm_funcid2smfid(cqm_handle);
- ret = cqm_bat_update_cmd(cqm_handle, buf_in, smf_id, func_id);
- } else if ((cqm_handle->func_capability.lb_mode == CQM_LB_MODE_1) ||
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_2) ||
- ((cqm_handle->func_capability.lb_mode == CQM_LB_MODE_0) &&
- (cqm_handle->func_attribute.func_type == CQM_PPF))) {
- for (i = 0; i < CQM_LB_SMF_MAX; i++) {
- cqm_update_timer_gpa(cqm_handle, i);
-
- /* The smf_pg variable stores the currently enabled SMF. */
- if (cqm_handle->func_capability.smf_pg & (1U << i)) {
- smf_id = i;
- ret = cqm_bat_update_cmd(cqm_handle, buf_in, smf_id, func_id);
- if (ret != CQM_SUCCESS)
- goto out;
- }
- }
- } else {
- cqm_err(handle->dev_hdl, "Bat update: unsupport lb mode=%u\n",
- cqm_handle->func_capability.lb_mode);
- ret = CQM_FAIL;
- }
-
-out:
- cqm3_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
- return ret;
-}
-
-s32 cqm_bat_init_ft(struct cqm_handle *cqm_handle, struct cqm_bat_table *bat_table,
- enum func_type function_type)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 i = 0;
-
- bat_table->bat_entry_type[CQM_BAT_INDEX0] = CQM_BAT_ENTRY_T_CFG;
- bat_table->bat_entry_type[CQM_BAT_INDEX1] = CQM_BAT_ENTRY_T_HASH;
- bat_table->bat_entry_type[CQM_BAT_INDEX2] = CQM_BAT_ENTRY_T_QPC;
- bat_table->bat_entry_type[CQM_BAT_INDEX3] = CQM_BAT_ENTRY_T_SCQC;
- bat_table->bat_entry_type[CQM_BAT_INDEX4] = CQM_BAT_ENTRY_T_LUN;
- bat_table->bat_entry_type[CQM_BAT_INDEX5] = CQM_BAT_ENTRY_T_TASKMAP;
-
- if (function_type == CQM_PF || function_type == CQM_PPF) {
- bat_table->bat_entry_type[CQM_BAT_INDEX6] = CQM_BAT_ENTRY_T_L3I;
- bat_table->bat_entry_type[CQM_BAT_INDEX7] = CQM_BAT_ENTRY_T_CHILDC;
- bat_table->bat_entry_type[CQM_BAT_INDEX8] = CQM_BAT_ENTRY_T_TIMER;
- bat_table->bat_entry_type[CQM_BAT_INDEX9] = CQM_BAT_ENTRY_T_XID2CID;
- bat_table->bat_entry_type[CQM_BAT_INDEX10] = CQM_BAT_ENTRY_T_REORDER;
- bat_table->bat_size = CQM_BAT_SIZE_FT_PF;
- } else if (function_type == CQM_VF) {
- bat_table->bat_size = CQM_BAT_SIZE_FT_VF;
- } else {
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = CQM_BAT_ENTRY_T_INVALID;
-
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(function_type));
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_bat_init(struct cqm_handle *cqm_handle)
-{
- struct cqm_func_capability *capability = &cqm_handle->func_capability;
- enum func_type function_type = cqm_handle->func_attribute.func_type;
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 i;
-
- memset(bat_table, 0, sizeof(struct cqm_bat_table));
-
- /* Initialize the type of each bat entry. */
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = CQM_BAT_ENTRY_T_INVALID;
-
- /* Select BATs based on service types. Currently,
- * feature-related resources of the VF are stored in the BATs of the VF.
- */
- if (capability->ft_enable)
- return cqm_bat_init_ft(cqm_handle, bat_table, function_type);
-
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(capability->ft_enable));
-
- return CQM_FAIL;
-}
-
-void cqm_bat_uninit(struct cqm_handle *cqm_handle)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 i;
-
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = CQM_BAT_ENTRY_T_INVALID;
-
- memset(bat_table->bat, 0, CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE);
-
- /* Instruct the chip to update the BAT table. */
- if (cqm_bat_update(cqm_handle) != CQM_SUCCESS)
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_update));
-}
-
-s32 cqm_cla_fill_buf(struct cqm_handle *cqm_handle, struct cqm_buf *cla_base_buf,
- struct cqm_buf *cla_sub_buf, u8 gpa_check_enable)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct sphw_func_attr *func_attr = NULL;
- dma_addr_t *base = NULL;
- u64 fake_en = 0;
- u64 spu_en = 0;
- u64 pf_id = 0;
- u32 i = 0;
- u32 addr_num;
- u32 buf_index = 0;
-
- /* Apply for space for base_buf */
- if (!cla_base_buf->buf_list) {
- if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) ==
- CQM_FAIL) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_base_buf));
- return CQM_FAIL;
- }
- }
-
- /* Apply for space for sub_buf */
- if (!cla_sub_buf->buf_list) {
- if (cqm_buf_alloc(cqm_handle, cla_sub_buf, false) == CQM_FAIL) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_sub_buf));
- cqm_buf_free(cla_base_buf, cqm_handle->dev);
- return CQM_FAIL;
- }
- }
-
- /* Fill base_buff with the gpa of sub_buf */
- addr_num = cla_base_buf->buf_size / sizeof(dma_addr_t);
- base = (dma_addr_t *)(cla_base_buf->buf_list[0].va);
- for (i = 0; i < cla_sub_buf->buf_number; i++) {
- /* The SPU SMF supports load balancing from the SMF to the CPI,
- * depending on the host ID and func ID.
- */
- if (sphw_host_id(cqm_handle->ex_handle) == CQM_SPU_HOST_ID) {
- func_attr = &cqm_handle->func_attribute;
- spu_en = (u64)(func_attr->func_global_idx & 0x1) << 63;
- } else {
- spu_en = 0;
- }
-
- *base = (((((cla_sub_buf->buf_list[i].pa & CQM_CHIP_GPA_MASK) |
- spu_en) |
- fake_en) |
- pf_id) |
- gpa_check_enable);
-
- cqm_swab64((u8 *)base, 1);
- if ((i + 1) % addr_num == 0) {
- buf_index++;
- if (buf_index < cla_base_buf->buf_number)
- base = cla_base_buf->buf_list[buf_index].va;
- } else {
- base++;
- }
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_cla_xyz_lvl1(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 trunk_size)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_buf *cla_y_buf = NULL;
- struct cqm_buf *cla_z_buf = NULL;
- s32 shift = 0;
- s32 ret = CQM_FAIL;
- u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
- u32 cache_line = 0;
-
- if (cla_table->type == CQM_BAT_ENTRY_T_TIMER && cqm_ver == 8)
- cache_line = CQM_CHIP_TIMER_CACHELINE;
- else
- cache_line = CQM_CHIP_CACHELINE;
-
- if (cla_table->type == CQM_BAT_ENTRY_T_REORDER)
- gpa_check_enable = 0;
-
- cla_table->cla_lvl = CQM_CLA_LVL_1;
-
- shift = cqm_shift(trunk_size / cla_table->obj_size);
- cla_table->z = shift ? (shift - 1) : (shift);
- cla_table->y = CQM_MAX_INDEX_BIT;
- cla_table->x = 0;
-
- if (cla_table->obj_size >= cache_line) {
- cla_table->cacheline_z = cla_table->z;
- cla_table->cacheline_y = cla_table->y;
- cla_table->cacheline_x = cla_table->x;
- } else {
- shift = cqm_shift(trunk_size / cache_line);
- cla_table->cacheline_z = shift ? (shift - 1) : (shift);
- cla_table->cacheline_y = CQM_MAX_INDEX_BIT;
- cla_table->cacheline_x = 0;
- }
-
- /* Applying for CLA_Y_BUF Space */
- cla_y_buf = &cla_table->cla_y_buf;
- cla_y_buf->buf_size = trunk_size;
- cla_y_buf->buf_number = 1;
- cla_y_buf->page_number = cla_y_buf->buf_number <<
- cla_table->trunk_order;
- ret = cqm_buf_alloc(cqm_handle, cla_y_buf, false);
- CQM_CHECK_EQUAL_RET(handle->dev_hdl, ret, CQM_SUCCESS, CQM_FAIL,
- CQM_ALLOC_FAIL(lvl_1_y_buf));
-
- /* Applying for CLA_Z_BUF Space */
- cla_z_buf = &cla_table->cla_z_buf;
- cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number =
- (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number <<
- cla_table->trunk_order;
- /* All buffer space must be statically allocated. */
- if (cla_table->alloc_static) {
- ret = cqm_cla_fill_buf(cqm_handle, cla_y_buf, cla_z_buf,
- gpa_check_enable);
- CQM_CHECK_EQUAL_RET(handle->dev_hdl, ret, CQM_SUCCESS, CQM_FAIL,
- CQM_FUNCTION_FAIL(cqm_cla_fill_buf));
- } else { /* Only the buffer list space is initialized. The buffer space
- * is dynamically allocated in services.
- */
- cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
- sizeof(struct cqm_buf_list));
- if (!cla_z_buf->buf_list) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_1_z_buf));
- cqm_buf_free(cla_y_buf, cqm_handle->dev);
- return CQM_FAIL;
- }
- memset(cla_z_buf->buf_list, 0,
- cla_z_buf->buf_number * sizeof(struct cqm_buf_list));
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_cla_xyz_lvl2(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 trunk_size)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_buf *cla_x_buf = NULL;
- struct cqm_buf *cla_y_buf = NULL;
- struct cqm_buf *cla_z_buf = NULL;
- s32 shift = 0;
- s32 ret = CQM_FAIL;
- u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
- u32 cache_line = 0;
-
- if (cla_table->type == CQM_BAT_ENTRY_T_TIMER && cqm_ver == 8)
- cache_line = CQM_CHIP_TIMER_CACHELINE;
- else
- cache_line = CQM_CHIP_CACHELINE;
-
- if (cla_table->type == CQM_BAT_ENTRY_T_REORDER)
- gpa_check_enable = 0;
-
- cla_table->cla_lvl = CQM_CLA_LVL_2;
-
- shift = cqm_shift(trunk_size / cla_table->obj_size);
- cla_table->z = shift ? (shift - 1) : (shift);
- shift = cqm_shift(trunk_size / sizeof(dma_addr_t));
- cla_table->y = cla_table->z + shift;
- cla_table->x = CQM_MAX_INDEX_BIT;
-
- if (cla_table->obj_size >= cache_line) {
- cla_table->cacheline_z = cla_table->z;
- cla_table->cacheline_y = cla_table->y;
- cla_table->cacheline_x = cla_table->x;
- } else {
- shift = cqm_shift(trunk_size / cache_line);
- cla_table->cacheline_z = shift ? (shift - 1) : (shift);
- shift = cqm_shift(trunk_size / sizeof(dma_addr_t));
- cla_table->cacheline_y = cla_table->cacheline_z + shift;
- cla_table->cacheline_x = CQM_MAX_INDEX_BIT;
- }
-
- /* Apply for CLA_X_BUF Space */
- cla_x_buf = &cla_table->cla_x_buf;
- cla_x_buf->buf_size = trunk_size;
- cla_x_buf->buf_number = 1;
- cla_x_buf->page_number = cla_x_buf->buf_number <<
- cla_table->trunk_order;
- ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
- CQM_CHECK_EQUAL_RET(handle->dev_hdl, ret, CQM_SUCCESS, CQM_FAIL,
- CQM_ALLOC_FAIL(lvl_2_x_buf));
-
- /* Apply for CLA_Z_BUF and CLA_Y_BUF Space */
- cla_z_buf = &cla_table->cla_z_buf;
- cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number =
- (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number <<
- cla_table->trunk_order;
-
- cla_y_buf = &cla_table->cla_y_buf;
- cla_y_buf->buf_size = trunk_size;
- cla_y_buf->buf_number =
- (ALIGN(cla_z_buf->buf_number * sizeof(dma_addr_t), trunk_size)) /
- trunk_size;
- cla_y_buf->page_number = cla_y_buf->buf_number <<
- cla_table->trunk_order;
- /* All buffer space must be statically allocated. */
- if (cla_table->alloc_static) {
- /* Apply for y buf and z buf, and fill the gpa of
- * z buf list in y buf
- */
- if (cqm_cla_fill_buf(cqm_handle, cla_y_buf, cla_z_buf,
- gpa_check_enable) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_cla_fill_buf));
- cqm_buf_free(cla_x_buf, cqm_handle->dev);
- return CQM_FAIL;
- }
-
- /* Fill the gpa of the y buf list into the x buf.
- * After the x and y bufs are applied for,
- * this function will not fail.
- * Use void to forcibly convert the return of the function.
- */
- (void)cqm_cla_fill_buf(cqm_handle, cla_x_buf, cla_y_buf,
- gpa_check_enable);
- } else { /* Only the buffer list space is initialized. The buffer space
- * is dynamically allocated in services.
- */
- cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
- sizeof(struct cqm_buf_list));
- if (!cla_z_buf->buf_list) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
- cqm_buf_free(cla_x_buf, cqm_handle->dev);
- return CQM_FAIL;
- }
- memset(cla_z_buf->buf_list, 0,
- cla_z_buf->buf_number * sizeof(struct cqm_buf_list));
-
- cla_y_buf->buf_list = vmalloc(cla_y_buf->buf_number *
- sizeof(struct cqm_buf_list));
- if (!cla_y_buf->buf_list) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
- cqm_buf_free(cla_z_buf, cqm_handle->dev);
- cqm_buf_free(cla_x_buf, cqm_handle->dev);
- return CQM_FAIL;
- }
- memset(cla_y_buf->buf_list, 0,
- cla_y_buf->buf_number * sizeof(struct cqm_buf_list));
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_cla_xyz_check(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 *size)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 trunk_size = 0;
-
- /* If the capability(obj_num) is set to 0, the CLA does not need to be
- * initialized and exits directly.
- */
- if (cla_table->obj_num == 0) {
- cqm_info(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_num=0, don't alloc buffer\n",
- cla_table->type);
- return CQM_SUCCESS;
- }
-
- cqm_info(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_num=0x%x, gpa_check_enable=%d\n",
- cla_table->type, cla_table->obj_num,
- cqm_handle->func_capability.gpa_check_enable);
-
- /* Check whether obj_size is 2^n-aligned. An error is reported when
- * obj_size is 0 or 1.
- */
- if (!cqm_check_align(cla_table->obj_size)) {
- cqm_err(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_size 0x%x is not align on 2^n\n",
- cla_table->type, cla_table->obj_size);
- return CQM_FAIL;
- }
-
- trunk_size = (u32)(PAGE_SIZE << cla_table->trunk_order);
-
- if (trunk_size < cla_table->obj_size) {
- cqm_err(handle->dev_hdl,
- "Cla alloc: cla type %u, obj_size 0x%x is out of trunk size\n",
- cla_table->type, cla_table->obj_size);
- return CQM_FAIL;
- }
-
- *size = trunk_size;
-
- return CQM_CONTINUE;
-}
-
-s32 cqm_cla_xyz(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_buf *cla_z_buf = NULL;
- u32 trunk_size = 0;
- s32 ret = CQM_FAIL;
-
- ret = cqm_cla_xyz_check(cqm_handle, cla_table, &trunk_size);
- if (ret != CQM_CONTINUE)
- return ret;
-
- /* Level-0 CLA occupies a small space.
- * Only CLA_Z_BUF can be allocated during initialization.
- */
- if (cla_table->max_buffer_size <= trunk_size) {
- cla_table->cla_lvl = CQM_CLA_LVL_0;
-
- cla_table->z = CQM_MAX_INDEX_BIT;
- cla_table->y = 0;
- cla_table->x = 0;
-
- cla_table->cacheline_z = cla_table->z;
- cla_table->cacheline_y = cla_table->y;
- cla_table->cacheline_x = cla_table->x;
-
- /* Applying for CLA_Z_BUF Space */
- cla_z_buf = &cla_table->cla_z_buf;
- cla_z_buf->buf_size = trunk_size; /* (u32)(PAGE_SIZE <<
- * cla_table->trunk_order);
- */
- cla_z_buf->buf_number = 1;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
- ret = cqm_buf_alloc(cqm_handle, cla_z_buf, false);
- CQM_CHECK_EQUAL_RET(handle->dev_hdl, ret, CQM_SUCCESS, CQM_FAIL,
- CQM_ALLOC_FAIL(lvl_0_z_buf));
- }
- /* Level-1 CLA
- * Allocates CLA_Y_BUF and CLA_Z_BUF during initialization.
- */
- else if (cla_table->max_buffer_size <= (trunk_size * (trunk_size / sizeof(dma_addr_t)))) {
- if (cqm_cla_xyz_lvl1(cqm_handle, cla_table, trunk_size) == CQM_FAIL) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_xyz_lvl1));
- return CQM_FAIL;
- }
- }
- /* Level-2 CLA
- * Allocates CLA_X_BUF, CLA_Y_BUF, and CLA_Z_BUF during initialization.
- */
- else if (cla_table->max_buffer_size <=
- (trunk_size * (trunk_size / sizeof(dma_addr_t)) *
- (trunk_size / sizeof(dma_addr_t)))) {
- if (cqm_cla_xyz_lvl2(cqm_handle, cla_table, trunk_size) ==
- CQM_FAIL) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_xyz_lvl2));
- return CQM_FAIL;
- }
- } else { /* The current memory management mode does not support such
- * a large buffer addressing. The order value needs to
- * be increased.
- */
- cqm_err(handle->dev_hdl,
- "Cla alloc: cla max_buffer_size 0x%x exceeds support range\n",
- cla_table->max_buffer_size);
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-void cqm_cla_init_entry_normal(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- struct cqm_func_capability *capability)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
-
- switch (cla_table->type) {
- case CQM_BAT_ENTRY_T_HASH:
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->hash_number * capability->hash_basic_size;
- cla_table->obj_size = capability->hash_basic_size;
- cla_table->obj_num = capability->hash_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_QPC:
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->qpc_number * capability->qpc_basic_size;
- cla_table->obj_size = capability->qpc_basic_size;
- cla_table->obj_num = capability->qpc_number;
- cla_table->alloc_static = capability->qpc_alloc_static;
- cqm_info(handle->dev_hdl, "Cla alloc: qpc alloc_static=%d\n",
- cla_table->alloc_static);
- break;
- case CQM_BAT_ENTRY_T_MPT:
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->mpt_number * capability->mpt_basic_size;
- cla_table->obj_size = capability->mpt_basic_size;
- cla_table->obj_num = capability->mpt_number;
- /* CCB decided. MPT uses only static application scenarios. */
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_SCQC:
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->scqc_number * capability->scqc_basic_size;
- cla_table->obj_size = capability->scqc_basic_size;
- cla_table->obj_num = capability->scqc_number;
- cla_table->alloc_static = capability->scqc_alloc_static;
- cqm_info(handle->dev_hdl, "Cla alloc: scqc alloc_static=%d\n",
- cla_table->alloc_static);
- break;
- case CQM_BAT_ENTRY_T_SRQC:
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->srqc_number * capability->srqc_basic_size;
- cla_table->obj_size = capability->srqc_basic_size;
- cla_table->obj_num = capability->srqc_number;
- cla_table->alloc_static = false;
- break;
- default:
- break;
- }
-}
-
-void cqm_cla_init_entry_extern(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- struct cqm_func_capability *capability)
-{
- switch (cla_table->type) {
- case CQM_BAT_ENTRY_T_GID:
- /* Level-0 CLA table required */
- cla_table->max_buffer_size = capability->gid_number * capability->gid_basic_size;
- cla_table->trunk_order =
- (u32)cqm_shift(ALIGN(cla_table->max_buffer_size, PAGE_SIZE) / PAGE_SIZE);
- cla_table->obj_size = capability->gid_basic_size;
- cla_table->obj_num = capability->gid_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_LUN:
- cla_table->trunk_order = CLA_TABLE_PAGE_ORDER;
- cla_table->max_buffer_size = capability->lun_number * capability->lun_basic_size;
- cla_table->obj_size = capability->lun_basic_size;
- cla_table->obj_num = capability->lun_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_TASKMAP:
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
- cla_table->max_buffer_size = capability->taskmap_number *
- capability->taskmap_basic_size;
- cla_table->obj_size = capability->taskmap_basic_size;
- cla_table->obj_num = capability->taskmap_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_L3I:
- cla_table->trunk_order = CLA_TABLE_PAGE_ORDER;
- cla_table->max_buffer_size = capability->l3i_number * capability->l3i_basic_size;
- cla_table->obj_size = capability->l3i_basic_size;
- cla_table->obj_num = capability->l3i_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_CHILDC:
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->childc_number *
- capability->childc_basic_size;
- cla_table->obj_size = capability->childc_basic_size;
- cla_table->obj_num = capability->childc_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_TIMER:
- /* Ensure that the basic size of the timer buffer page does not
- * exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
- * the function is complex.
- */
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
- cla_table->max_buffer_size = capability->timer_number *
- capability->timer_basic_size;
- cla_table->obj_size = capability->timer_basic_size;
- cla_table->obj_num = capability->timer_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_XID2CID:
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->xid2cid_number *
- capability->xid2cid_basic_size;
- cla_table->obj_size = capability->xid2cid_basic_size;
- cla_table->obj_num = capability->xid2cid_number;
- cla_table->alloc_static = true;
- break;
- case CQM_BAT_ENTRY_T_REORDER:
- /* This entry supports only IWARP and does not support GPA validity check. */
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->reorder_number *
- capability->reorder_basic_size;
- cla_table->obj_size = capability->reorder_basic_size;
- cla_table->obj_num = capability->reorder_number;
- cla_table->alloc_static = true;
- break;
- default:
- break;
- }
-}
-
-s32 cqm_cla_init_entry_condition(struct cqm_handle *cqm_handle, u32 entry_type)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_cla_table *cla_table = &bat_table->entry[entry_type];
- struct cqm_cla_table *cla_table_timer = NULL;
- u32 i;
-
- /* When the timer is in LB mode 1 or 2, the timer needs to be
- * configured for four SMFs and the address space is independent.
- */
- if (cla_table->type == CQM_BAT_ENTRY_T_TIMER &&
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_1 ||
- cqm_handle->func_capability.lb_mode == CQM_LB_MODE_2)) {
- for (i = 0; i < CQM_LB_SMF_MAX; i++) {
- cla_table_timer = &bat_table->timer_entry[i];
- memcpy(cla_table_timer, cla_table, sizeof(struct cqm_cla_table));
-
- if (cqm_cla_xyz(cqm_handle, cla_table_timer) == CQM_FAIL) {
- cqm_cla_uninit(cqm_handle, entry_type);
- return CQM_FAIL;
- }
- }
- }
-
- if (cqm_cla_xyz(cqm_handle, cla_table) == CQM_FAIL) {
- cqm_cla_uninit(cqm_handle, entry_type);
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_cla_init_entry(struct cqm_handle *cqm_handle,
- struct cqm_func_capability *capability)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_cla_table *cla_table = NULL;
- s32 ret;
- u32 i = 0;
-
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- cla_table->type = bat_table->bat_entry_type[i];
-
- cqm_cla_init_entry_normal(cqm_handle, cla_table, capability);
- cqm_cla_init_entry_extern(cqm_handle, cla_table, capability);
-
- /* Allocate CLA entry space at each level. */
- if (cla_table->type < CQM_BAT_ENTRY_T_HASH ||
- cla_table->type > CQM_BAT_ENTRY_T_REORDER) {
- mutex_init(&cla_table->lock);
- continue;
- }
-
- /* For the PPF, resources (8 wheels x 2k scales x 32B x
- * func_num) need to be applied for to the timer. The
- * structure of the timer entry in the BAT table needs
- * to be filled. For the PF, no resource needs to be
- * applied for the timer and no structure needs to be
- * filled in the timer entry in the BAT table.
- */
- if (!(cla_table->type == CQM_BAT_ENTRY_T_TIMER &&
- cqm_handle->func_attribute.func_type != CQM_PPF)) {
- ret = cqm_cla_init_entry_condition(cqm_handle, i);
- if (ret != CQM_SUCCESS)
- return CQM_FAIL;
- }
- mutex_init(&cla_table->lock);
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_cla_init(struct cqm_handle *cqm_handle)
-{
- struct cqm_func_capability *capability = &cqm_handle->func_capability;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- s32 ret;
-
- /* Applying for CLA Entries */
- ret = cqm_cla_init_entry(cqm_handle, capability);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_init_entry));
- return ret;
- }
-
- /* After the CLA entry is applied, the address is filled in the BAT table. */
- cqm_bat_fill_cla(cqm_handle);
-
- /* Instruct the chip to update the BAT table. */
- ret = cqm_bat_update(cqm_handle);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_update));
- goto err;
- }
-
- cqm_info(handle->dev_hdl, "Timer start: func_type=%d, timer_enable=%u\n",
- cqm_handle->func_attribute.func_type,
- cqm_handle->func_capability.timer_enable);
-
- if (cqm_handle->func_attribute.func_type == CQM_PPF &&
- cqm_handle->func_capability.timer_enable == CQM_TIMER_ENABLE) {
- /* Enable the timer after the timer resources are applied for */
- cqm_info(handle->dev_hdl, "Timer start: spfc ppf timer start\n");
- ret = sphw_ppf_tmr_start((void *)(cqm_handle->ex_handle));
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, "Timer start: spfc ppf timer start, ret=%d\n",
- ret);
- goto err;
- }
- }
-
- return CQM_SUCCESS;
-
-err:
- cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX);
- return CQM_FAIL;
-}
-
-void cqm_cla_uninit(struct cqm_handle *cqm_handle, u32 entry_numb)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_cla_table *cla_table = NULL;
- s32 inv_flag = 0;
- u32 i;
-
- for (i = 0; i < entry_numb; i++) {
- cla_table = &bat_table->entry[i];
- if (cla_table->type != CQM_BAT_ENTRY_T_INVALID) {
- cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_x_buf, &inv_flag);
- cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_y_buf, &inv_flag);
- cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_z_buf, &inv_flag);
- }
- }
-
- /* When the lb mode is 1/2, the timer space allocated to the 4 SMFs
- * needs to be released.
- */
- if (cqm_handle->func_attribute.func_type == CQM_PPF &&
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_1 ||
- cqm_handle->func_capability.lb_mode == CQM_LB_MODE_2)) {
- for (i = 0; i < CQM_LB_SMF_MAX; i++) {
- cla_table = &bat_table->timer_entry[i];
- cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_x_buf, &inv_flag);
- cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_y_buf, &inv_flag);
- cqm_buf_free_cache_inv(cqm_handle, &cla_table->cla_z_buf, &inv_flag);
- }
- }
-}
-
-s32 cqm_cla_update_cmd(struct cqm_handle *cqm_handle, struct cqm_cmd_buf *buf_in,
- struct cqm_cla_update_cmd *cmd)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_cla_update_cmd *cla_update_cmd = NULL;
- s32 ret = CQM_FAIL;
-
- cla_update_cmd = (struct cqm_cla_update_cmd *)(buf_in->buf);
-
- cla_update_cmd->gpa_h = cmd->gpa_h;
- cla_update_cmd->gpa_l = cmd->gpa_l;
- cla_update_cmd->value_h = cmd->value_h;
- cla_update_cmd->value_l = cmd->value_l;
- cla_update_cmd->smf_id = cmd->smf_id;
- cla_update_cmd->func_id = cmd->func_id;
-
- cqm_swab32((u8 *)cla_update_cmd,
- (sizeof(struct cqm_cla_update_cmd) >> CQM_DW_SHIFT));
-
- ret = cqm3_send_cmd_box((void *)(cqm_handle->ex_handle), CQM_MOD_CQM,
- CQM_CMD_T_CLA_UPDATE, buf_in, NULL, NULL,
- CQM_CMD_TIMEOUT, SPHW_CHANNEL_DEFAULT);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm3_send_cmd_box));
- cqm_err(handle->dev_hdl, "Cla alloc: cqm_cla_update, cqm3_send_cmd_box_ret=%d\n",
- ret);
- cqm_err(handle->dev_hdl, "Cla alloc: cqm_cla_update, cla_update_cmd: 0x%x 0x%x 0x%x 0x%x\n",
- cmd->gpa_h, cmd->gpa_l, cmd->value_h, cmd->value_l);
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_cla_update(struct cqm_handle *cqm_handle, struct cqm_buf_list *buf_node_parent,
- struct cqm_buf_list *buf_node_child, u32 child_index, u8 cla_update_mode)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_cmd_buf *buf_in = NULL;
- struct cqm_cla_update_cmd cmd;
- dma_addr_t pa = 0;
- s32 ret = CQM_FAIL;
- u8 gpa_check_enable = cqm_handle->func_capability.gpa_check_enable;
- u32 i = 0;
- u64 spu_en;
-
- buf_in = cqm3_cmd_alloc(cqm_handle->ex_handle);
- CQM_PTR_CHECK_RET(buf_in, CQM_FAIL, CQM_ALLOC_FAIL(buf_in));
- buf_in->size = sizeof(struct cqm_cla_update_cmd);
-
- /* Fill command format, convert to big endian. */
- /* SPU function sets bit63: acs_spu_en based on function id. */
- if (sphw_host_id(cqm_handle->ex_handle) == CQM_SPU_HOST_ID)
- spu_en = ((u64)(cqm_handle->func_attribute.func_global_idx &
- 0x1)) << 63;
- else
- spu_en = 0;
-
- pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- spu_en);
- cmd.gpa_h = CQM_ADDR_HI(pa);
- cmd.gpa_l = CQM_ADDR_LW(pa);
-
- pa = (buf_node_child->pa | spu_en);
- cmd.value_h = CQM_ADDR_HI(pa);
- cmd.value_l = CQM_ADDR_LW(pa);
-
- /* current CLA GPA CHECK */
- if (gpa_check_enable) {
- switch (cla_update_mode) {
- /* gpa[0]=1 means this GPA is valid */
- case CQM_CLA_RECORD_NEW_GPA:
- cmd.value_l |= 1;
- break;
- /* gpa[0]=0 means this GPA is valid */
- case CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID:
- case CQM_CLA_DEL_GPA_WITH_CACHE_INVALID:
- cmd.value_l &= (~1);
- break;
- default:
- cqm_err(handle->dev_hdl,
- "Cla alloc: %s, wrong cla_update_mode=%u\n",
- __func__, cla_update_mode);
- break;
- }
- }
-
- /* In non-fake mode, set func_id to 0xffff. */
- cmd.func_id = 0xffff;
-
- /* Mode 0 is hashed to 4 SMF engines (excluding PPF) by func ID. */
- if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_NORMAL ||
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_0 &&
- cqm_handle->func_attribute.func_type != CQM_PPF)) {
- cmd.smf_id = cqm_funcid2smfid(cqm_handle);
- ret = cqm_cla_update_cmd(cqm_handle, buf_in, &cmd);
- }
- /* Modes 1/2 are allocated to four SMF engines by flow.
- * Therefore, one function needs to be allocated to four SMF engines.
- */
- /* Mode 0 PPF needs to be configured on 4 engines,
- * and the timer resources need to be shared by the 4 engines.
- */
- else if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_1 ||
- cqm_handle->func_capability.lb_mode == CQM_LB_MODE_2 ||
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_0 &&
- cqm_handle->func_attribute.func_type == CQM_PPF)) {
- for (i = 0; i < CQM_LB_SMF_MAX; i++) {
- /* The smf_pg variable stores currently enabled SMF. */
- if (cqm_handle->func_capability.smf_pg & (1U << i)) {
- cmd.smf_id = i;
- ret = cqm_cla_update_cmd(cqm_handle, buf_in,
- &cmd);
- if (ret != CQM_SUCCESS)
- goto out;
- }
- }
- } else {
- cqm_err(handle->dev_hdl, "Cla update: unsupport lb mode=%u\n",
- cqm_handle->func_capability.lb_mode);
- ret = CQM_FAIL;
- }
-
-out:
- cqm3_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
- return ret;
-}
-
-s32 cqm_cla_alloc(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- struct cqm_buf_list *buf_node_parent,
- struct cqm_buf_list *buf_node_child, u32 child_index)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- s32 ret = CQM_FAIL;
-
- /* Apply for trunk page */
- buf_node_child->va = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
- cla_table->trunk_order);
- CQM_PTR_CHECK_RET(buf_node_child->va, CQM_FAIL, CQM_ALLOC_FAIL(va));
-
- /* PCI mapping */
- buf_node_child->pa = pci_map_single(cqm_handle->dev, buf_node_child->va,
- PAGE_SIZE << cla_table->trunk_order,
- PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(cqm_handle->dev, buf_node_child->pa)) {
- cqm_err(handle->dev_hdl, CQM_MAP_FAIL(buf_node_child->pa));
- goto err1;
- }
-
- /* Notify the chip of trunk_pa so that the chip fills in cla entry */
- ret = cqm_cla_update(cqm_handle, buf_node_parent, buf_node_child,
- child_index, CQM_CLA_RECORD_NEW_GPA);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_update));
- goto err2;
- }
-
- return CQM_SUCCESS;
-
-err2:
- pci_unmap_single(cqm_handle->dev, buf_node_child->pa,
- PAGE_SIZE << cla_table->trunk_order,
- PCI_DMA_BIDIRECTIONAL);
-err1:
- free_pages((ulong)(buf_node_child->va), cla_table->trunk_order);
- buf_node_child->va = NULL;
- return CQM_FAIL;
-}
-
-void cqm_cla_free(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- struct cqm_buf_list *buf_node_parent,
- struct cqm_buf_list *buf_node_child, u32 child_index, u8 cla_update_mode)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 trunk_size;
-
- if (cqm_cla_update(cqm_handle, buf_node_parent, buf_node_child,
- child_index, cla_update_mode) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_update));
- return;
- }
-
- if (cla_update_mode == CQM_CLA_DEL_GPA_WITH_CACHE_INVALID) {
- trunk_size = (u32)(PAGE_SIZE << cla_table->trunk_order);
- if (cqm_cla_cache_invalid(cqm_handle, buf_node_child->pa,
- trunk_size) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_cla_cache_invalid));
- return;
- }
- }
-
- /* Remove PCI mapping from the trunk page */
- pci_unmap_single(cqm_handle->dev, buf_node_child->pa,
- PAGE_SIZE << cla_table->trunk_order,
- PCI_DMA_BIDIRECTIONAL);
-
- /* Rlease trunk page */
- free_pages((ulong)(buf_node_child->va), cla_table->trunk_order);
- buf_node_child->va = NULL;
-}
-
-u8 *cqm_cla_get_unlock_lvl0(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- struct cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- u8 *ret_addr = NULL;
- u32 offset = 0;
-
- /* Level 0 CLA pages are statically allocated. */
- offset = index * cla_table->obj_size;
- ret_addr = (u8 *)(cla_z_buf->buf_list->va) + offset;
- *pa = cla_z_buf->buf_list->pa + offset;
-
- return ret_addr;
-}
-
-u8 *cqm_cla_get_unlock_lvl1(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- struct cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_buf_list *buf_node_y = NULL;
- struct cqm_buf_list *buf_node_z = NULL;
- u32 y_index = 0;
- u32 z_index = 0;
- u8 *ret_addr = NULL;
- u32 offset = 0;
-
- z_index = index & ((1U << (cla_table->z + 1)) - 1);
- y_index = index >> (cla_table->z + 1);
-
- if (y_index >= cla_z_buf->buf_number) {
- cqm_err(handle->dev_hdl,
- "Cla get: index exceeds buf_number, y_index %u, z_buf_number %u\n",
- y_index, cla_z_buf->buf_number);
- return NULL;
- }
- buf_node_z = &cla_z_buf->buf_list[y_index];
- buf_node_y = cla_y_buf->buf_list;
-
- /* The z buf node does not exist, applying for a page first. */
- if (!buf_node_z->va) {
- if (cqm_cla_alloc(cqm_handle, cla_table, buf_node_y, buf_node_z,
- y_index) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_cla_alloc));
- cqm_err(handle->dev_hdl,
- "Cla get: cla_table->type=%u\n",
- cla_table->type);
- return NULL;
- }
- }
-
- buf_node_z->refcount += count;
- offset = z_index * cla_table->obj_size;
- ret_addr = (u8 *)(buf_node_z->va) + offset;
- *pa = buf_node_z->pa + offset;
-
- return ret_addr;
-}
-
-u8 *cqm_cla_get_unlock_lvl2(struct cqm_handle *cqm_handle,
- struct cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- struct cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_buf_list *buf_node_x = NULL;
- struct cqm_buf_list *buf_node_y = NULL;
- struct cqm_buf_list *buf_node_z = NULL;
- u32 x_index = 0;
- u32 y_index = 0;
- u32 z_index = 0;
- u32 trunk_size = (u32)(PAGE_SIZE << cla_table->trunk_order);
- u8 *ret_addr = NULL;
- u32 offset = 0;
- u64 tmp;
-
- z_index = index & ((1U << (cla_table->z + 1)) - 1);
- y_index = (index >> (cla_table->z + 1)) &
- ((1U << (cla_table->y - cla_table->z)) - 1);
- x_index = index >> (cla_table->y + 1);
- tmp = x_index * (trunk_size / sizeof(dma_addr_t)) + y_index;
-
- if (x_index >= cla_y_buf->buf_number || tmp >= cla_z_buf->buf_number) {
- cqm_err(handle->dev_hdl,
- "Cla get: index exceeds buf_number, x_index %u, y_index %u, y_buf_number %u, z_buf_number %u\n",
- x_index, y_index, cla_y_buf->buf_number,
- cla_z_buf->buf_number);
- return NULL;
- }
-
- buf_node_x = cla_x_buf->buf_list;
- buf_node_y = &cla_y_buf->buf_list[x_index];
- buf_node_z = &cla_z_buf->buf_list[tmp];
-
- /* The y buf node does not exist, applying for pages for y node. */
- if (!buf_node_y->va) {
- if (cqm_cla_alloc(cqm_handle, cla_table, buf_node_x, buf_node_y,
- x_index) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_cla_alloc));
- return NULL;
- }
- }
-
- /* The z buf node does not exist, applying for pages for z node. */
- if (!buf_node_z->va) {
- if (cqm_cla_alloc(cqm_handle, cla_table, buf_node_y, buf_node_z,
- y_index) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_cla_alloc));
- if (buf_node_y->refcount == 0)
- /* To release node Y, cache_invalid is
- * required.
- */
- cqm_cla_free(cqm_handle, cla_table, buf_node_x, buf_node_y, x_index,
- CQM_CLA_DEL_GPA_WITH_CACHE_INVALID);
- return NULL;
- }
-
- /* reference counting of the y buffer node needs to increase
- * by 1.
- */
- buf_node_y->refcount++;
- }
-
- buf_node_z->refcount += count;
- offset = z_index * cla_table->obj_size;
- ret_addr = (u8 *)(buf_node_z->va) + offset;
- *pa = buf_node_z->pa + offset;
-
- return ret_addr;
-}
-
-u8 *cqm_cla_get_unlock(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- u8 *ret_addr = NULL;
-
- if (cla_table->cla_lvl == CQM_CLA_LVL_0)
- ret_addr = cqm_cla_get_unlock_lvl0(cqm_handle, cla_table, index,
- count, pa);
- else if (cla_table->cla_lvl == CQM_CLA_LVL_1)
- ret_addr = cqm_cla_get_unlock_lvl1(cqm_handle, cla_table, index,
- count, pa);
- else
- ret_addr = cqm_cla_get_unlock_lvl2(cqm_handle, cla_table, index,
- count, pa);
-
- return ret_addr;
-}
-
-u8 *cqm_cla_get_lock(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- u8 *ret_addr = NULL;
-
- mutex_lock(&cla_table->lock);
-
- ret_addr = cqm_cla_get_unlock(cqm_handle, cla_table, index, count, pa);
-
- mutex_unlock(&cla_table->lock);
-
- return ret_addr;
-}
-
-void cqm_cla_put(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 index, u32 count)
-{
- struct cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- struct cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_buf_list *buf_node_z = NULL;
- struct cqm_buf_list *buf_node_y = NULL;
- struct cqm_buf_list *buf_node_x = NULL;
- u32 x_index = 0;
- u32 y_index = 0;
- u32 trunk_size = (u32)(PAGE_SIZE << cla_table->trunk_order);
- u64 tmp;
-
- /* The buffer is applied statically, and the reference counting
- * does not need to be controlled.
- */
- if (cla_table->alloc_static)
- return;
-
- mutex_lock(&cla_table->lock);
-
- if (cla_table->cla_lvl == CQM_CLA_LVL_1) {
- y_index = index >> (cla_table->z + 1);
-
- if (y_index >= cla_z_buf->buf_number) {
- cqm_err(handle->dev_hdl,
- "Cla put: index exceeds buf_number, y_index %u, z_buf_number %u\n",
- y_index, cla_z_buf->buf_number);
- cqm_err(handle->dev_hdl,
- "Cla put: cla_table->type=%u\n",
- cla_table->type);
- mutex_unlock(&cla_table->lock);
- return;
- }
-
- buf_node_z = &cla_z_buf->buf_list[y_index];
- buf_node_y = cla_y_buf->buf_list;
-
- /* When the value of reference counting on the z node page is 0,
- * the z node page is released.
- */
- buf_node_z->refcount -= count;
- if (buf_node_z->refcount == 0)
- /* The cache invalid is not required for the Z node. */
- cqm_cla_free(cqm_handle, cla_table, buf_node_y,
- buf_node_z, y_index,
- CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID);
- } else if (cla_table->cla_lvl == CQM_CLA_LVL_2) {
- y_index = (index >> (cla_table->z + 1)) &
- ((1U << (cla_table->y - cla_table->z)) - 1);
- x_index = index >> (cla_table->y + 1);
- tmp = x_index * (trunk_size / sizeof(dma_addr_t)) + y_index;
-
- if (x_index >= cla_y_buf->buf_number || tmp >= cla_z_buf->buf_number) {
- cqm_err(handle->dev_hdl,
- "Cla put: index exceeds buf_number, x_index %u, y_index %u, y_buf_number %u, z_buf_number %u\n",
- x_index, y_index, cla_y_buf->buf_number,
- cla_z_buf->buf_number);
- mutex_unlock(&cla_table->lock);
- return;
- }
-
- buf_node_x = cla_x_buf->buf_list;
- buf_node_y = &cla_y_buf->buf_list[x_index];
- buf_node_z = &cla_z_buf->buf_list[tmp];
-
- /* When the value of reference counting on the z node page is 0,
- * the z node page is released.
- */
- buf_node_z->refcount -= count;
- if (buf_node_z->refcount == 0) {
- cqm_cla_free(cqm_handle, cla_table, buf_node_y,
- buf_node_z, y_index,
- CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID);
-
- /* When the value of reference counting on the y node
- * page is 0, the y node page is released.
- */
- buf_node_y->refcount--;
- if (buf_node_y->refcount == 0)
- /* Node y requires cache to be invalid. */
- cqm_cla_free(cqm_handle, cla_table, buf_node_x, buf_node_y, x_index,
- CQM_CLA_DEL_GPA_WITH_CACHE_INVALID);
- }
- }
-
- mutex_unlock(&cla_table->lock);
-}
-
-struct cqm_cla_table *cqm_cla_table_get(struct cqm_bat_table *bat_table, u32 entry_type)
-{
- struct cqm_cla_table *cla_table = NULL;
- u32 i = 0;
-
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- if (entry_type == cla_table->type)
- return cla_table;
- }
-
- return NULL;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.h b/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.h
deleted file mode 100644
index 85b060e7935c..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_bat_cla.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_CQM_BAT_CLA_H
-#define SPFC_CQM_BAT_CLA_H
-
-/* When the connection check is enabled, the maximum number of connections
- * supported by the chip is 1M - 63, which cannot reach 1M
- */
-#define CQM_BAT_MAX_CONN_NUM (0x100000 - 63)
-#define CQM_BAT_MAX_CACHE_CONN_NUM (0x100000 - 63)
-
-#define CLA_TABLE_PAGE_ORDER 0
-#define CQM_4K_PAGE_ORDER 0
-#define CQM_4K_PAGE_SIZE 4096
-
-#define CQM_BAT_ENTRY_MAX 16
-#define CQM_BAT_ENTRY_SIZE 16
-
-#define CQM_BAT_SIZE_FT_PF 192
-#define CQM_BAT_SIZE_FT_VF 112
-
-#define CQM_BAT_INDEX0 0
-#define CQM_BAT_INDEX1 1
-#define CQM_BAT_INDEX2 2
-#define CQM_BAT_INDEX3 3
-#define CQM_BAT_INDEX4 4
-#define CQM_BAT_INDEX5 5
-#define CQM_BAT_INDEX6 6
-#define CQM_BAT_INDEX7 7
-#define CQM_BAT_INDEX8 8
-#define CQM_BAT_INDEX9 9
-#define CQM_BAT_INDEX10 10
-#define CQM_BAT_INDEX11 11
-#define CQM_BAT_INDEX12 12
-#define CQM_BAT_INDEX13 13
-#define CQM_BAT_INDEX14 14
-#define CQM_BAT_INDEX15 15
-
-enum cqm_bat_entry_type {
- CQM_BAT_ENTRY_T_CFG = 0,
- CQM_BAT_ENTRY_T_HASH = 1,
- CQM_BAT_ENTRY_T_QPC = 2,
- CQM_BAT_ENTRY_T_SCQC = 3,
- CQM_BAT_ENTRY_T_SRQC = 4,
- CQM_BAT_ENTRY_T_MPT = 5,
- CQM_BAT_ENTRY_T_GID = 6,
- CQM_BAT_ENTRY_T_LUN = 7,
- CQM_BAT_ENTRY_T_TASKMAP = 8,
- CQM_BAT_ENTRY_T_L3I = 9,
- CQM_BAT_ENTRY_T_CHILDC = 10,
- CQM_BAT_ENTRY_T_TIMER = 11,
- CQM_BAT_ENTRY_T_XID2CID = 12,
- CQM_BAT_ENTRY_T_REORDER = 13,
- CQM_BAT_ENTRY_T_INVALID = 14,
- CQM_BAT_ENTRY_T_MAX = 15,
-};
-
-/* CLA update mode */
-#define CQM_CLA_RECORD_NEW_GPA 0
-#define CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID 1
-#define CQM_CLA_DEL_GPA_WITH_CACHE_INVALID 2
-
-#define CQM_CLA_LVL_0 0
-#define CQM_CLA_LVL_1 1
-#define CQM_CLA_LVL_2 2
-
-#define CQM_MAX_INDEX_BIT 19
-
-#define CQM_CHIP_CACHELINE 256
-#define CQM_CHIP_TIMER_CACHELINE 512
-#define CQM_OBJECT_256 256
-#define CQM_OBJECT_512 512
-#define CQM_OBJECT_1024 1024
-#define CQM_CHIP_GPA_MASK 0x1ffffffffffffff
-#define CQM_CHIP_GPA_HIMASK 0x1ffffff
-#define CQM_CHIP_GPA_LOMASK 0xffffffff
-#define CQM_CHIP_GPA_HSHIFT 32
-
-/* Aligns with 64 buckets and shifts rightward by 6 bits */
-#define CQM_HASH_NUMBER_UNIT 6
-
-struct cqm_cla_table {
- u32 type;
- u32 max_buffer_size;
- u32 obj_num;
- bool alloc_static; /* Whether the buffer is statically allocated */
- u32 cla_lvl;
- u32 cacheline_x; /* x value calculated based on cacheline, used by the chip */
- u32 cacheline_y; /* y value calculated based on cacheline, used by the chip */
- u32 cacheline_z; /* z value calculated based on cacheline, used by the chip */
- u32 x; /* x value calculated based on obj_size, used by software */
- u32 y; /* y value calculated based on obj_size, used by software */
- u32 z; /* z value calculated based on obj_size, used by software */
- struct cqm_buf cla_x_buf;
- struct cqm_buf cla_y_buf;
- struct cqm_buf cla_z_buf;
- u32 trunk_order; /* A continuous physical page contains 2^order pages */
- u32 obj_size;
- struct mutex lock; /* Lock for cla buffer allocation and free */
-
- struct cqm_bitmap bitmap;
-
- struct cqm_object_table obj_table; /* Mapping table between indexes and objects */
-};
-
-struct cqm_bat_entry_cfg {
- u32 cur_conn_num_h_4 : 4;
- u32 rsv1 : 4;
- u32 max_conn_num : 20;
- u32 rsv2 : 4;
-
- u32 max_conn_cache : 10;
- u32 rsv3 : 6;
- u32 cur_conn_num_l_16 : 16;
-
- u32 bloom_filter_addr : 16;
- u32 cur_conn_cache : 10;
- u32 rsv4 : 6;
-
- u32 bucket_num : 16;
- u32 bloom_filter_len : 16;
-};
-
-#define CQM_BAT_NO_BYPASS_CACHE 0
-#define CQM_BAT_BYPASS_CACHE 1
-
-#define CQM_BAT_ENTRY_SIZE_256 0
-#define CQM_BAT_ENTRY_SIZE_512 1
-#define CQM_BAT_ENTRY_SIZE_1024 2
-
-struct cqm_bat_entry_standerd {
- u32 entry_size : 2;
- u32 rsv1 : 6;
- u32 max_number : 20;
- u32 rsv2 : 4;
-
- u32 cla_gpa_h : 32;
-
- u32 cla_gpa_l : 32;
-
- u32 rsv3 : 8;
- u32 z : 5;
- u32 y : 5;
- u32 x : 5;
- u32 rsv24 : 1;
- u32 bypass : 1;
- u32 cla_level : 2;
- u32 rsv5 : 5;
-};
-
-struct cqm_bat_entry_vf2pf {
- u32 cla_gpa_h : 25;
- u32 pf_id : 5;
- u32 fake_vf_en : 1;
- u32 acs_spu_en : 1;
-};
-
-#define CQM_BAT_ENTRY_TASKMAP_NUM 4
-struct cqm_bat_entry_taskmap_addr {
- u32 gpa_h;
- u32 gpa_l;
-};
-
-struct cqm_bat_entry_taskmap {
- struct cqm_bat_entry_taskmap_addr addr[CQM_BAT_ENTRY_TASKMAP_NUM];
-};
-
-struct cqm_bat_table {
- u32 bat_entry_type[CQM_BAT_ENTRY_MAX];
- u8 bat[CQM_BAT_ENTRY_MAX * CQM_BAT_ENTRY_SIZE];
- struct cqm_cla_table entry[CQM_BAT_ENTRY_MAX];
- /* In LB mode 1, the timer needs to be configured in 4 SMFs,
- * and the GPAs must be different and independent.
- */
- struct cqm_cla_table timer_entry[4];
- u32 bat_size;
-};
-
-#define CQM_BAT_MAX_SIZE 256
-struct cqm_cmdq_bat_update {
- u32 offset;
- u32 byte_len;
- u8 data[CQM_BAT_MAX_SIZE];
- u32 smf_id;
- u32 func_id;
-};
-
-struct cqm_cla_update_cmd {
- /* Gpa address to be updated */
- u32 gpa_h;
- u32 gpa_l;
-
- /* Updated Value */
- u32 value_h;
- u32 value_l;
-
- u32 smf_id;
- u32 func_id;
-};
-
-s32 cqm_bat_init(struct cqm_handle *cqm_handle);
-void cqm_bat_uninit(struct cqm_handle *cqm_handle);
-s32 cqm_cla_init(struct cqm_handle *cqm_handle);
-void cqm_cla_uninit(struct cqm_handle *cqm_handle, u32 entry_numb);
-u8 *cqm_cla_get_unlock(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa);
-u8 *cqm_cla_get_lock(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa);
-void cqm_cla_put(struct cqm_handle *cqm_handle, struct cqm_cla_table *cla_table,
- u32 index, u32 count);
-struct cqm_cla_table *cqm_cla_table_get(struct cqm_bat_table *bat_table, u32 entry_type);
-u32 cqm_funcid2smfid(struct cqm_handle *cqm_handle);
-
-#endif /* SPFC_CQM_BAT_CLA_H */
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c b/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c
deleted file mode 100644
index 21100e8db8f4..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c
+++ /dev/null
@@ -1,885 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/mm.h>
-#include <linux/gfp.h>
-
-#include "sphw_crm.h"
-#include "sphw_hw.h"
-#include "sphw_hwdev.h"
-#include "sphw_hwif.h"
-
-#include "spfc_cqm_object.h"
-#include "spfc_cqm_bitmap_table.h"
-#include "spfc_cqm_bat_cla.h"
-#include "spfc_cqm_main.h"
-
-#define common_section
-
-void cqm_swab64(u8 *addr, u32 cnt)
-{
- u64 *temp = (u64 *)addr;
- u64 value = 0;
- u32 i;
-
- for (i = 0; i < cnt; i++) {
- value = __swab64(*temp);
- *temp = value;
- temp++;
- }
-}
-
-void cqm_swab32(u8 *addr, u32 cnt)
-{
- u32 *temp = (u32 *)addr;
- u32 value = 0;
- u32 i;
-
- for (i = 0; i < cnt; i++) {
- value = __swab32(*temp);
- *temp = value;
- temp++;
- }
-}
-
-s32 cqm_shift(u32 data)
-{
- s32 shift = -1;
-
- do {
- data >>= 1;
- shift++;
- } while (data);
-
- return shift;
-}
-
-bool cqm_check_align(u32 data)
-{
- if (data == 0)
- return false;
-
- do {
- /* When the value can be exactly divided by 2,
- * the value of data is shifted right by one bit, that is,
- * divided by 2.
- */
- if ((data & 0x1) == 0)
- data >>= 1;
- /* If the value cannot be divisible by 2, the value is
- * not 2^n-aligned and false is returned.
- */
- else
- return false;
- } while (data != 1);
-
- return true;
-}
-
-void *cqm_kmalloc_align(size_t size, gfp_t flags, u16 align_order)
-{
- void *orig_addr = NULL;
- void *align_addr = NULL;
- void *index_addr = NULL;
-
- orig_addr = kmalloc(size + ((u64)1 << align_order) + sizeof(void *),
- flags);
- if (!orig_addr)
- return NULL;
-
- index_addr = (void *)((char *)orig_addr + sizeof(void *));
- align_addr =
- (void *)((((u64)index_addr + ((u64)1 << align_order) - 1) >>
- align_order) << align_order);
-
- /* Record the original memory address for memory release. */
- index_addr = (void *)((char *)align_addr - sizeof(void *));
- *(void **)index_addr = orig_addr;
-
- return align_addr;
-}
-
-void cqm_kfree_align(void *addr)
-{
- void *index_addr = NULL;
-
- /* Release the original memory address. */
- index_addr = (void *)((char *)addr - sizeof(void *));
-
- kfree(*(void **)index_addr);
-}
-
-void cqm_write_lock(rwlock_t *lock, bool bh)
-{
- if (bh)
- write_lock_bh(lock);
- else
- write_lock(lock);
-}
-
-void cqm_write_unlock(rwlock_t *lock, bool bh)
-{
- if (bh)
- write_unlock_bh(lock);
- else
- write_unlock(lock);
-}
-
-void cqm_read_lock(rwlock_t *lock, bool bh)
-{
- if (bh)
- read_lock_bh(lock);
- else
- read_lock(lock);
-}
-
-void cqm_read_unlock(rwlock_t *lock, bool bh)
-{
- if (bh)
- read_unlock_bh(lock);
- else
- read_unlock(lock);
-}
-
-s32 cqm_buf_alloc_direct(struct cqm_handle *cqm_handle, struct cqm_buf *buf, bool direct)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct page **pages = NULL;
- u32 i, j, order;
-
- order = get_order(buf->buf_size);
-
- if (!direct) {
- buf->direct.va = NULL;
- return CQM_SUCCESS;
- }
-
- pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
- return CQM_FAIL;
- }
-
- for (i = 0; i < buf->buf_number; i++) {
- for (j = 0; j < ((u32)1 << order); j++)
- pages[(ulong)(unsigned int)((i << order) + j)] =
- (void *)virt_to_page((u8 *)(buf->buf_list[i].va) +
- (PAGE_SIZE * j));
- }
-
- buf->direct.va = vmap(pages, buf->page_number, VM_MAP, PAGE_KERNEL);
- vfree(pages);
- if (!buf->direct.va) {
- cqm_err(handle->dev_hdl, CQM_MAP_FAIL(buf->direct.va));
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_buf_alloc_page(struct cqm_handle *cqm_handle, struct cqm_buf *buf)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct page *newpage = NULL;
- u32 order;
- void *va = NULL;
- s32 i, node;
-
- order = get_order(buf->buf_size);
- /* Page for applying for each buffer for non-ovs */
- if (handle->board_info.service_mode != 0) {
- for (i = 0; i < (s32)buf->buf_number; i++) {
- va = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
- order);
- if (!va) {
- cqm_err(handle->dev_hdl,
- CQM_ALLOC_FAIL(buf_page));
- break;
- }
- /* Initialize the page after the page is applied for.
- * If hash entries are involved, the initialization
- * value must be 0.
- */
- memset(va, 0, buf->buf_size);
- buf->buf_list[i].va = va;
- }
- } else {
- node = dev_to_node(handle->dev_hdl);
- for (i = 0; i < (s32)buf->buf_number; i++) {
- newpage = alloc_pages_node(node,
- GFP_KERNEL | __GFP_ZERO,
- order);
- if (!newpage) {
- cqm_err(handle->dev_hdl,
- CQM_ALLOC_FAIL(buf_page));
- break;
- }
- va = (void *)page_address(newpage);
- /* Initialize the page after the page is applied for.
- * If hash entries are involved, the initialization
- * value must be 0.
- */
- memset(va, 0, buf->buf_size);
- buf->buf_list[i].va = va;
- }
- }
-
- if (i != buf->buf_number) {
- i--;
- for (; i >= 0; i--) {
- free_pages((ulong)(buf->buf_list[i].va), order);
- buf->buf_list[i].va = NULL;
- }
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_buf_alloc_map(struct cqm_handle *cqm_handle, struct cqm_buf *buf)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct pci_dev *dev = cqm_handle->dev;
- void *va = NULL;
- s32 i;
-
- for (i = 0; i < (s32)buf->buf_number; i++) {
- va = buf->buf_list[i].va;
- buf->buf_list[i].pa = pci_map_single(dev, va, buf->buf_size,
- PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(dev, buf->buf_list[i].pa)) {
- cqm_err(handle->dev_hdl, CQM_MAP_FAIL(buf_list));
- break;
- }
- }
-
- if (i != buf->buf_number) {
- i--;
- for (; i >= 0; i--)
- pci_unmap_single(dev, buf->buf_list[i].pa,
- buf->buf_size, PCI_DMA_BIDIRECTIONAL);
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_buf_alloc(struct cqm_handle *cqm_handle, struct cqm_buf *buf, bool direct)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct pci_dev *dev = cqm_handle->dev;
- u32 order;
- s32 i;
-
- order = get_order(buf->buf_size);
-
- /* Applying for the buffer list descriptor space */
- buf->buf_list = vmalloc(buf->buf_number * sizeof(struct cqm_buf_list));
- CQM_PTR_CHECK_RET(buf->buf_list, CQM_FAIL,
- CQM_ALLOC_FAIL(linux_buf_list));
- memset(buf->buf_list, 0, buf->buf_number * sizeof(struct cqm_buf_list));
-
- /* Page for applying for each buffer */
- if (cqm_buf_alloc_page(cqm_handle, buf) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(linux_cqm_buf_alloc_page));
- goto err1;
- }
-
- /* PCI mapping of the buffer */
- if (cqm_buf_alloc_map(cqm_handle, buf) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(linux_cqm_buf_alloc_map));
- goto err2;
- }
-
- /* direct remapping */
- if (cqm_buf_alloc_direct(cqm_handle, buf, direct) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_buf_alloc_direct));
- goto err3;
- }
-
- return CQM_SUCCESS;
-
-err3:
- for (i = 0; i < (s32)buf->buf_number; i++)
- pci_unmap_single(dev, buf->buf_list[i].pa, buf->buf_size,
- PCI_DMA_BIDIRECTIONAL);
-err2:
- for (i = 0; i < (s32)buf->buf_number; i++) {
- free_pages((ulong)(buf->buf_list[i].va), order);
- buf->buf_list[i].va = NULL;
- }
-err1:
- vfree(buf->buf_list);
- buf->buf_list = NULL;
- return CQM_FAIL;
-}
-
-void cqm_buf_free(struct cqm_buf *buf, struct pci_dev *dev)
-{
- u32 order;
- s32 i;
-
- order = get_order(buf->buf_size);
-
- if (buf->direct.va) {
- vunmap(buf->direct.va);
- buf->direct.va = NULL;
- }
-
- if (buf->buf_list) {
- for (i = 0; i < (s32)(buf->buf_number); i++) {
- if (buf->buf_list[i].va) {
- pci_unmap_single(dev, buf->buf_list[i].pa,
- buf->buf_size,
- PCI_DMA_BIDIRECTIONAL);
-
- free_pages((ulong)(buf->buf_list[i].va), order);
- buf->buf_list[i].va = NULL;
- }
- }
-
- vfree(buf->buf_list);
- buf->buf_list = NULL;
- }
-}
-
-s32 cqm_cla_cache_invalid_cmd(struct cqm_handle *cqm_handle, struct cqm_cmd_buf *buf_in,
- struct cqm_cla_cache_invalid_cmd *cmd)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_cla_cache_invalid_cmd *cla_cache_invalid_cmd = NULL;
- s32 ret;
-
- cla_cache_invalid_cmd = (struct cqm_cla_cache_invalid_cmd *)(buf_in->buf);
- cla_cache_invalid_cmd->gpa_h = cmd->gpa_h;
- cla_cache_invalid_cmd->gpa_l = cmd->gpa_l;
- cla_cache_invalid_cmd->cache_size = cmd->cache_size;
- cla_cache_invalid_cmd->smf_id = cmd->smf_id;
- cla_cache_invalid_cmd->func_id = cmd->func_id;
-
- cqm_swab32((u8 *)cla_cache_invalid_cmd,
- /* shift 2 bits by right to get length of dw(4B) */
- (sizeof(struct cqm_cla_cache_invalid_cmd) >> 2));
-
- /* Send the cmdq command. */
- ret = cqm3_send_cmd_box((void *)(cqm_handle->ex_handle), CQM_MOD_CQM,
- CQM_CMD_T_CLA_CACHE_INVALID, buf_in, NULL, NULL,
- CQM_CMD_TIMEOUT, SPHW_CHANNEL_DEFAULT);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm3_send_cmd_box));
- cqm_err(handle->dev_hdl,
- "Cla cache invalid: cqm3_send_cmd_box_ret=%d\n",
- ret);
- cqm_err(handle->dev_hdl,
- "Cla cache invalid: cla_cache_invalid_cmd: 0x%x 0x%x 0x%x\n",
- cmd->gpa_h, cmd->gpa_l, cmd->cache_size);
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_cla_cache_invalid(struct cqm_handle *cqm_handle, dma_addr_t gpa, u32 cache_size)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_cmd_buf *buf_in = NULL;
- struct cqm_cla_cache_invalid_cmd cmd;
- s32 ret = CQM_FAIL;
- u32 i;
-
- buf_in = cqm3_cmd_alloc((void *)(cqm_handle->ex_handle));
- CQM_PTR_CHECK_RET(buf_in, CQM_FAIL, CQM_ALLOC_FAIL(buf_in));
- buf_in->size = sizeof(struct cqm_cla_cache_invalid_cmd);
-
- /* Fill command and convert it to big endian */
- cmd.cache_size = cache_size;
- cmd.gpa_h = CQM_ADDR_HI(gpa);
- cmd.gpa_l = CQM_ADDR_LW(gpa);
-
- /* In non-fake mode, set func_id to 0xffff. */
- cmd.func_id = 0xffff;
-
- /* Mode 0 is hashed to 4 SMF engines (excluding PPF) by func ID. */
- if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_NORMAL ||
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_0 &&
- cqm_handle->func_attribute.func_type != CQM_PPF)) {
- cmd.smf_id = cqm_funcid2smfid(cqm_handle);
- ret = cqm_cla_cache_invalid_cmd(cqm_handle, buf_in, &cmd);
- }
- /* Mode 1/2 are allocated to 4 SMF engines by flow. Therefore,
- * one function needs to be allocated to 4 SMF engines.
- */
- /* The PPF in mode 0 needs to be configured on 4 engines,
- * and the timer resources need to be shared by the 4 engines.
- */
- else if (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_1 ||
- cqm_handle->func_capability.lb_mode == CQM_LB_MODE_2 ||
- (cqm_handle->func_capability.lb_mode == CQM_LB_MODE_0 &&
- cqm_handle->func_attribute.func_type == CQM_PPF)) {
- for (i = 0; i < CQM_LB_SMF_MAX; i++) {
- /* The smf_pg stored currently enabled SMF engine. */
- if (cqm_handle->func_capability.smf_pg & (1U << i)) {
- cmd.smf_id = i;
- ret = cqm_cla_cache_invalid_cmd(cqm_handle,
- buf_in, &cmd);
- if (ret != CQM_SUCCESS)
- goto out;
- }
- }
- } else {
- cqm_err(handle->dev_hdl, "Cla cache invalid: unsupport lb mode=%u\n",
- cqm_handle->func_capability.lb_mode);
- ret = CQM_FAIL;
- }
-
-out:
- cqm3_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
- return ret;
-}
-
-static void free_cache_inv(struct cqm_handle *cqm_handle, struct cqm_buf *buf,
- s32 *inv_flag)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 order;
- s32 i;
-
- order = get_order(buf->buf_size);
-
- if (!handle->chip_present_flag)
- return;
-
- if (!buf->buf_list)
- return;
-
- for (i = 0; i < (s32)(buf->buf_number); i++) {
- if (!buf->buf_list[i].va)
- continue;
-
- if (*inv_flag != CQM_SUCCESS)
- continue;
-
- /* In the Pangea environment, if the cmdq times out,
- * no subsequent message is sent.
- */
- *inv_flag = cqm_cla_cache_invalid(cqm_handle, buf->buf_list[i].pa,
- (u32)(PAGE_SIZE << order));
- if (*inv_flag != CQM_SUCCESS)
- cqm_err(handle->dev_hdl,
- "Buffer free: fail to invalid buf_list pa cache, inv_flag=%d\n",
- *inv_flag);
- }
-}
-
-void cqm_buf_free_cache_inv(struct cqm_handle *cqm_handle, struct cqm_buf *buf,
- s32 *inv_flag)
-{
- /* Send a command to the chip to kick out the cache. */
- free_cache_inv(cqm_handle, buf, inv_flag);
-
- /* Clear host resources */
- cqm_buf_free(buf, cqm_handle->dev);
-}
-
-#define bitmap_section
-
-s32 cqm_single_bitmap_init(struct cqm_bitmap *bitmap)
-{
- u32 bit_number;
-
- spin_lock_init(&bitmap->lock);
-
- /* Max_num of the bitmap is 8-aligned and then
- * shifted rightward by 3 bits to obtain the number of bytes required.
- */
- bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >> CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
- CQM_PTR_CHECK_RET(bitmap->table, CQM_FAIL, CQM_ALLOC_FAIL(bitmap->table));
- memset(bitmap->table, 0, bit_number);
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_bitmap_init(struct cqm_handle *cqm_handle)
-{
- struct cqm_func_capability *capability = &cqm_handle->func_capability;
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_cla_table *cla_table = NULL;
- struct cqm_bitmap *bitmap = NULL;
- s32 ret = CQM_SUCCESS;
- u32 i;
-
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- if (cla_table->obj_num == 0) {
- cqm_info(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_num=0, don't init bitmap\n",
- cla_table->type);
- continue;
- }
-
- bitmap = &cla_table->bitmap;
-
- switch (cla_table->type) {
- case CQM_BAT_ENTRY_T_QPC:
- bitmap->max_num = capability->qpc_number;
- bitmap->reserved_top = capability->qpc_reserved;
- bitmap->last = capability->qpc_reserved;
- cqm_info(handle->dev_hdl,
- "Bitmap init: cla_table_type=%u, max_num=0x%x\n",
- cla_table->type, bitmap->max_num);
- ret = cqm_single_bitmap_init(bitmap);
- break;
- case CQM_BAT_ENTRY_T_MPT:
- bitmap->max_num = capability->mpt_number;
- bitmap->reserved_top = capability->mpt_reserved;
- bitmap->last = capability->mpt_reserved;
- cqm_info(handle->dev_hdl,
- "Bitmap init: cla_table_type=%u, max_num=0x%x\n",
- cla_table->type, bitmap->max_num);
- ret = cqm_single_bitmap_init(bitmap);
- break;
- case CQM_BAT_ENTRY_T_SCQC:
- bitmap->max_num = capability->scqc_number;
- bitmap->reserved_top = capability->scq_reserved;
- bitmap->last = capability->scq_reserved;
- cqm_info(handle->dev_hdl,
- "Bitmap init: cla_table_type=%u, max_num=0x%x\n",
- cla_table->type, bitmap->max_num);
- ret = cqm_single_bitmap_init(bitmap);
- break;
- case CQM_BAT_ENTRY_T_SRQC:
- bitmap->max_num = capability->srqc_number;
- bitmap->reserved_top = capability->srq_reserved;
- bitmap->last = capability->srq_reserved;
- cqm_info(handle->dev_hdl,
- "Bitmap init: cla_table_type=%u, max_num=0x%x\n",
- cla_table->type, bitmap->max_num);
- ret = cqm_single_bitmap_init(bitmap);
- break;
- default:
- break;
- }
-
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- "Bitmap init: failed to init cla_table_type=%u, obj_num=0x%x\n",
- cla_table->type, cla_table->obj_num);
- goto err;
- }
- }
-
- return CQM_SUCCESS;
-
-err:
- cqm_bitmap_uninit(cqm_handle);
- return CQM_FAIL;
-}
-
-void cqm_bitmap_uninit(struct cqm_handle *cqm_handle)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_cla_table *cla_table = NULL;
- struct cqm_bitmap *bitmap = NULL;
- u32 i;
-
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- bitmap = &cla_table->bitmap;
- if (cla_table->type != CQM_BAT_ENTRY_T_INVALID) {
- if (bitmap->table) {
- vfree(bitmap->table);
- bitmap->table = NULL;
- }
- }
- }
-}
-
-u32 cqm_bitmap_check_range(const ulong *table, u32 step, u32 max_num, u32 begin,
- u32 count)
-{
- u32 end = (begin + (count - 1));
- u32 i;
-
- /* Single-bit check is not performed. */
- if (count == 1)
- return begin;
-
- /* The end value exceeds the threshold. */
- if (end >= max_num)
- return max_num;
-
- /* Bit check, the next bit is returned when a non-zero bit is found. */
- for (i = (begin + 1); i <= end; i++) {
- if (test_bit((s32)i, table))
- return i + 1;
- }
-
- /* Check whether it's in different steps. */
- if ((begin & (~(step - 1))) != (end & (~(step - 1))))
- return (end & (~(step - 1)));
-
- /* If the check succeeds, begin is returned. */
- return begin;
-}
-
-void cqm_bitmap_find(struct cqm_bitmap *bitmap, u32 *index, u32 last, u32 step, u32 count)
-{
- u32 max_num = bitmap->max_num;
- ulong *table = bitmap->table;
-
- do {
- *index = (u32)find_next_zero_bit(table, max_num, last);
- if (*index < max_num)
- last = cqm_bitmap_check_range(table, step, max_num,
- *index, count);
- else
- break;
- } while (last != *index);
-}
-
-u32 cqm_bitmap_alloc(struct cqm_bitmap *bitmap, u32 step, u32 count, bool update_last)
-{
- u32 index = 0;
- u32 max_num = bitmap->max_num;
- u32 last = bitmap->last;
- ulong *table = bitmap->table;
- u32 i;
-
- spin_lock(&bitmap->lock);
-
- /* Search for an idle bit from the last position. */
- cqm_bitmap_find(bitmap, &index, last, step, count);
-
- /* The preceding search fails. Search for an idle bit
- * from the beginning.
- */
- if (index >= max_num) {
- last = bitmap->reserved_top;
- cqm_bitmap_find(bitmap, &index, last, step, count);
- }
-
- /* Set the found bit to 1 and reset last. */
- if (index < max_num) {
- for (i = index; i < (index + count); i++)
- set_bit(i, table);
-
- if (update_last) {
- bitmap->last = (index + count);
- if (bitmap->last >= bitmap->max_num)
- bitmap->last = bitmap->reserved_top;
- }
- }
-
- spin_unlock(&bitmap->lock);
- return index;
-}
-
-u32 cqm_bitmap_alloc_reserved(struct cqm_bitmap *bitmap, u32 count, u32 index)
-{
- ulong *table = bitmap->table;
- u32 ret_index;
-
- if (index >= bitmap->reserved_top || index >= bitmap->max_num || count != 1)
- return CQM_INDEX_INVALID;
-
- spin_lock(&bitmap->lock);
-
- if (test_bit((s32)index, table)) {
- ret_index = CQM_INDEX_INVALID;
- } else {
- set_bit(index, table);
- ret_index = index;
- }
-
- spin_unlock(&bitmap->lock);
- return ret_index;
-}
-
-void cqm_bitmap_free(struct cqm_bitmap *bitmap, u32 index, u32 count)
-{
- u32 i;
-
- spin_lock(&bitmap->lock);
-
- for (i = index; i < (index + count); i++)
- clear_bit((s32)i, bitmap->table);
-
- spin_unlock(&bitmap->lock);
-}
-
-#define obj_table_section
-s32 cqm_single_object_table_init(struct cqm_object_table *obj_table)
-{
- rwlock_init(&obj_table->lock);
-
- obj_table->table = vmalloc(obj_table->max_num * sizeof(void *));
- CQM_PTR_CHECK_RET(obj_table->table, CQM_FAIL, CQM_ALLOC_FAIL(table));
- memset(obj_table->table, 0, obj_table->max_num * sizeof(void *));
- return CQM_SUCCESS;
-}
-
-s32 cqm_object_table_init(struct cqm_handle *cqm_handle)
-{
- struct cqm_func_capability *capability = &cqm_handle->func_capability;
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_object_table *obj_table = NULL;
- struct cqm_cla_table *cla_table = NULL;
- s32 ret = CQM_SUCCESS;
- u32 i;
-
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- if (cla_table->obj_num == 0) {
- cqm_info(handle->dev_hdl,
- "Obj table init: cla_table_type %u, obj_num=0, don't init obj table\n",
- cla_table->type);
- continue;
- }
-
- obj_table = &cla_table->obj_table;
-
- switch (cla_table->type) {
- case CQM_BAT_ENTRY_T_QPC:
- obj_table->max_num = capability->qpc_number;
- ret = cqm_single_object_table_init(obj_table);
- break;
- case CQM_BAT_ENTRY_T_MPT:
- obj_table->max_num = capability->mpt_number;
- ret = cqm_single_object_table_init(obj_table);
- break;
- case CQM_BAT_ENTRY_T_SCQC:
- obj_table->max_num = capability->scqc_number;
- ret = cqm_single_object_table_init(obj_table);
- break;
- case CQM_BAT_ENTRY_T_SRQC:
- obj_table->max_num = capability->srqc_number;
- ret = cqm_single_object_table_init(obj_table);
- break;
- default:
- break;
- }
-
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- "Obj table init: failed to init cla_table_type=%u, obj_num=0x%x\n",
- cla_table->type, cla_table->obj_num);
- goto err;
- }
- }
-
- return CQM_SUCCESS;
-
-err:
- cqm_object_table_uninit(cqm_handle);
- return CQM_FAIL;
-}
-
-void cqm_object_table_uninit(struct cqm_handle *cqm_handle)
-{
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_object_table *obj_table = NULL;
- struct cqm_cla_table *cla_table = NULL;
- u32 i;
-
- for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- obj_table = &cla_table->obj_table;
- if (cla_table->type != CQM_BAT_ENTRY_T_INVALID) {
- if (obj_table->table) {
- vfree(obj_table->table);
- obj_table->table = NULL;
- }
- }
- }
-}
-
-s32 cqm_object_table_insert(struct cqm_handle *cqm_handle,
- struct cqm_object_table *object_table,
- u32 index, struct cqm_object *obj, bool bh)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
-
- if (index >= object_table->max_num) {
- cqm_err(handle->dev_hdl,
- "Obj table insert: index 0x%x exceeds max_num 0x%x\n",
- index, object_table->max_num);
- return CQM_FAIL;
- }
-
- cqm_write_lock(&object_table->lock, bh);
-
- if (!object_table->table[index]) {
- object_table->table[index] = obj;
- cqm_write_unlock(&object_table->lock, bh);
- return CQM_SUCCESS;
- }
-
- cqm_write_unlock(&object_table->lock, bh);
- cqm_err(handle->dev_hdl,
- "Obj table insert: object_table->table[0x%x] has been inserted\n",
- index);
-
- return CQM_FAIL;
-}
-
-void cqm_object_table_remove(struct cqm_handle *cqm_handle,
- struct cqm_object_table *object_table,
- u32 index, const struct cqm_object *obj, bool bh)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
-
- if (index >= object_table->max_num) {
- cqm_err(handle->dev_hdl,
- "Obj table remove: index 0x%x exceeds max_num 0x%x\n",
- index, object_table->max_num);
- return;
- }
-
- cqm_write_lock(&object_table->lock, bh);
-
- if (object_table->table[index] && object_table->table[index] == obj)
- object_table->table[index] = NULL;
- else
- cqm_err(handle->dev_hdl,
- "Obj table remove: object_table->table[0x%x] has been removed\n",
- index);
-
- cqm_write_unlock(&object_table->lock, bh);
-}
-
-struct cqm_object *cqm_object_table_get(struct cqm_handle *cqm_handle,
- struct cqm_object_table *object_table,
- u32 index, bool bh)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_object *obj = NULL;
-
- if (index >= object_table->max_num) {
- cqm_err(handle->dev_hdl,
- "Obj table get: index 0x%x exceeds max_num 0x%x\n",
- index, object_table->max_num);
- return NULL;
- }
-
- cqm_read_lock(&object_table->lock, bh);
-
- obj = object_table->table[index];
- if (obj)
- atomic_inc(&obj->refcount);
-
- cqm_read_unlock(&object_table->lock, bh);
-
- return obj;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.h b/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.h
deleted file mode 100644
index 5ae554eac54a..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_CQM_BITMAP_TABLE_H
-#define SPFC_CQM_BITMAP_TABLE_H
-
-struct cqm_bitmap {
- ulong *table;
- u32 max_num;
- u32 last;
- u32 reserved_top; /* reserved index */
- spinlock_t lock;
-};
-
-struct cqm_object_table {
- /* Now is big array. Later will be optimized as a red-black tree. */
- struct cqm_object **table;
- u32 max_num;
- rwlock_t lock;
-};
-
-struct cqm_cla_cache_invalid_cmd {
- u32 gpa_h;
- u32 gpa_l;
-
- u32 cache_size; /* CLA cache size=4096B */
-
- u32 smf_id;
- u32 func_id;
-};
-
-struct cqm_handle;
-
-s32 cqm_bitmap_init(struct cqm_handle *cqm_handle);
-void cqm_bitmap_uninit(struct cqm_handle *cqm_handle);
-u32 cqm_bitmap_alloc(struct cqm_bitmap *bitmap, u32 step, u32 count, bool update_last);
-u32 cqm_bitmap_alloc_reserved(struct cqm_bitmap *bitmap, u32 count, u32 index);
-void cqm_bitmap_free(struct cqm_bitmap *bitmap, u32 index, u32 count);
-s32 cqm_object_table_init(struct cqm_handle *cqm_handle);
-void cqm_object_table_uninit(struct cqm_handle *cqm_handle);
-s32 cqm_object_table_insert(struct cqm_handle *cqm_handle,
- struct cqm_object_table *object_table,
- u32 index, struct cqm_object *obj, bool bh);
-void cqm_object_table_remove(struct cqm_handle *cqm_handle,
- struct cqm_object_table *object_table,
- u32 index, const struct cqm_object *obj, bool bh);
-struct cqm_object *cqm_object_table_get(struct cqm_handle *cqm_handle,
- struct cqm_object_table *object_table,
- u32 index, bool bh);
-
-void cqm_swab64(u8 *addr, u32 cnt);
-void cqm_swab32(u8 *addr, u32 cnt);
-bool cqm_check_align(u32 data);
-s32 cqm_shift(u32 data);
-s32 cqm_buf_alloc(struct cqm_handle *cqm_handle, struct cqm_buf *buf, bool direct);
-s32 cqm_buf_alloc_direct(struct cqm_handle *cqm_handle, struct cqm_buf *buf, bool direct);
-void cqm_buf_free(struct cqm_buf *buf, struct pci_dev *dev);
-void cqm_buf_free_cache_inv(struct cqm_handle *cqm_handle, struct cqm_buf *buf,
- s32 *inv_flag);
-s32 cqm_cla_cache_invalid(struct cqm_handle *cqm_handle, dma_addr_t gpa,
- u32 cache_size);
-void *cqm_kmalloc_align(size_t size, gfp_t flags, u16 align_order);
-void cqm_kfree_align(void *addr);
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_main.c b/drivers/scsi/spfc/hw/spfc_cqm_main.c
deleted file mode 100644
index 52cc2c7838e9..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_main.c
+++ /dev/null
@@ -1,987 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-
-#include "sphw_crm.h"
-#include "sphw_hw.h"
-#include "sphw_hw_cfg.h"
-#include "spfc_cqm_main.h"
-
-s32 cqm3_init(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
- s32 ret;
-
- CQM_PTR_CHECK_RET(ex_handle, CQM_FAIL, CQM_PTR_NULL(ex_handle));
-
- cqm_handle = kmalloc(sizeof(*cqm_handle), GFP_KERNEL | __GFP_ZERO);
- CQM_PTR_CHECK_RET(cqm_handle, CQM_FAIL, CQM_ALLOC_FAIL(cqm_handle));
-
- /* Clear the memory to prevent other systems from
- * not clearing the memory.
- */
- memset(cqm_handle, 0, sizeof(struct cqm_handle));
-
- cqm_handle->ex_handle = handle;
- cqm_handle->dev = (struct pci_dev *)(handle->pcidev_hdl);
- handle->cqm_hdl = (void *)cqm_handle;
-
- /* Clearing Statistics */
- memset(&handle->hw_stats.cqm_stats, 0, sizeof(struct cqm_stats));
-
- /* Reads VF/PF information. */
- cqm_handle->func_attribute = handle->hwif->attr;
- cqm_info(handle->dev_hdl, "Func init: function[%u] type %d(0:PF,1:VF,2:PPF)\n",
- cqm_handle->func_attribute.func_global_idx,
- cqm_handle->func_attribute.func_type);
-
- /* Read capability from configuration management module */
- ret = cqm_capability_init(ex_handle);
- if (ret == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_capability_init));
- goto err1;
- }
-
- /* Initialize memory entries such as BAT, CLA, and bitmap. */
- if (cqm_mem_init(ex_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_mem_init));
- goto err1;
- }
-
- /* Event callback initialization */
- if (cqm_event_init(ex_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_event_init));
- goto err2;
- }
-
- /* Doorbell initiation */
- if (cqm_db_init(ex_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_db_init));
- goto err3;
- }
-
- /* Initialize the bloom filter. */
- if (cqm_bloomfilter_init(ex_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_bloomfilter_init));
- goto err4;
- }
-
- /* The timer bitmap is set directly at the beginning of the CQM.
- * The ifconfig up/down command is not used to set or clear the bitmap.
- */
- if (sphw_func_tmr_bitmap_set(ex_handle, true) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, "Timer start: enable timer bitmap failed\n");
- goto err5;
- }
-
- return CQM_SUCCESS;
-
-err5:
- cqm_bloomfilter_uninit(ex_handle);
-err4:
- cqm_db_uninit(ex_handle);
-err3:
- cqm_event_uninit(ex_handle);
-err2:
- cqm_mem_uninit(ex_handle);
-err1:
- handle->cqm_hdl = NULL;
- kfree(cqm_handle);
- return CQM_FAIL;
-}
-
-void cqm3_uninit(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
- s32 ret;
-
- CQM_PTR_CHECK_NO_RET(ex_handle, CQM_PTR_NULL(ex_handle));
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- CQM_PTR_CHECK_NO_RET(cqm_handle, CQM_PTR_NULL(cqm_handle));
-
- /* The timer bitmap is set directly at the beginning of the CQM.
- * The ifconfig up/down command is not used to set or clear the bitmap.
- */
- cqm_info(handle->dev_hdl, "Timer stop: disable timer\n");
- if (sphw_func_tmr_bitmap_set(ex_handle, false) != CQM_SUCCESS)
- cqm_err(handle->dev_hdl, "Timer stop: disable timer bitmap failed\n");
-
- /* After the TMR timer stops, the system releases resources
- * after a delay of one or two milliseconds.
- */
- if (cqm_handle->func_attribute.func_type == CQM_PPF &&
- cqm_handle->func_capability.timer_enable == CQM_TIMER_ENABLE) {
- cqm_info(handle->dev_hdl, "Timer stop: spfc ppf timer stop\n");
- ret = sphw_ppf_tmr_stop(handle);
- if (ret != CQM_SUCCESS)
- /* The timer fails to be stopped,
- * and the resource release is not affected.
- */
- cqm_info(handle->dev_hdl, "Timer stop: spfc ppf timer stop, ret=%d\n",
- ret);
- /* Somebody requires a delay of 1 ms, which is inaccurate. */
- usleep_range(900, 1000);
- }
-
- /* Release Bloom Filter Table */
- cqm_bloomfilter_uninit(ex_handle);
-
- /* Release hardware doorbell */
- cqm_db_uninit(ex_handle);
-
- /* Cancel the callback of the event */
- cqm_event_uninit(ex_handle);
-
- /* Release various memory tables and require the service
- * to release all objects.
- */
- cqm_mem_uninit(ex_handle);
-
- /* Release cqm_handle */
- handle->cqm_hdl = NULL;
- kfree(cqm_handle);
-}
-
-void cqm_test_mode_init(struct cqm_handle *cqm_handle,
- struct service_cap *service_capability)
-{
- struct cqm_func_capability *func_cap = &cqm_handle->func_capability;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
-
- if (service_capability->test_mode == 0)
- return;
-
- cqm_info(handle->dev_hdl, "Enter CQM test mode\n");
-
- func_cap->qpc_number = service_capability->test_qpc_num;
- func_cap->qpc_reserved =
- GET_MAX(func_cap->qpc_reserved,
- service_capability->test_qpc_resvd_num);
- func_cap->xid_alloc_mode = service_capability->test_xid_alloc_mode;
- func_cap->gpa_check_enable = service_capability->test_gpa_check_enable;
- func_cap->pagesize_reorder = service_capability->test_page_size_reorder;
- func_cap->qpc_alloc_static =
- (bool)(service_capability->test_qpc_alloc_mode);
- func_cap->scqc_alloc_static =
- (bool)(service_capability->test_scqc_alloc_mode);
- func_cap->flow_table_based_conn_number =
- service_capability->test_max_conn_num;
- func_cap->flow_table_based_conn_cache_number =
- service_capability->test_max_cache_conn_num;
- func_cap->scqc_number = service_capability->test_scqc_num;
- func_cap->mpt_number = service_capability->test_mpt_num;
- func_cap->mpt_reserved = service_capability->test_mpt_recvd_num;
- func_cap->reorder_number = service_capability->test_reorder_num;
- /* 256K buckets, 256K*64B = 16MB */
- func_cap->hash_number = service_capability->test_hash_num;
-}
-
-void cqm_service_capability_update(struct cqm_handle *cqm_handle)
-{
- struct cqm_func_capability *func_cap = &cqm_handle->func_capability;
-
- func_cap->qpc_number = GET_MIN(CQM_MAX_QPC_NUM, func_cap->qpc_number);
- func_cap->scqc_number = GET_MIN(CQM_MAX_SCQC_NUM, func_cap->scqc_number);
- func_cap->srqc_number = GET_MIN(CQM_MAX_SRQC_NUM, func_cap->srqc_number);
- func_cap->childc_number = GET_MIN(CQM_MAX_CHILDC_NUM, func_cap->childc_number);
-}
-
-void cqm_service_valid_init(struct cqm_handle *cqm_handle,
- struct service_cap *service_capability)
-{
- enum cfg_svc_type_en type = service_capability->chip_svc_type;
- struct cqm_service *svc = cqm_handle->service;
-
- svc[CQM_SERVICE_T_FC].valid = ((u32)type & CFG_SVC_FC_BIT5) ? true : false;
-}
-
-void cqm_service_capability_init_fc(struct cqm_handle *cqm_handle, void *pra)
-{
- struct cqm_func_capability *func_cap = &cqm_handle->func_capability;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct fc_service_cap *fc_cap = &service_capability->fc_cap;
- struct dev_fc_svc_cap *dev_fc_cap = &fc_cap->dev_fc_cap;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
-
- cqm_info(handle->dev_hdl, "Cap init: fc is valid\n");
- cqm_info(handle->dev_hdl, "Cap init: fc qpc 0x%x, scqc 0x%x, srqc 0x%x\n",
- dev_fc_cap->max_parent_qpc_num, dev_fc_cap->scq_num,
- dev_fc_cap->srq_num);
- func_cap->hash_number += dev_fc_cap->max_parent_qpc_num;
- func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
- func_cap->qpc_number += dev_fc_cap->max_parent_qpc_num;
- func_cap->qpc_basic_size = GET_MAX(fc_cap->parent_qpc_size,
- func_cap->qpc_basic_size);
- func_cap->qpc_alloc_static = true;
- func_cap->scqc_number += dev_fc_cap->scq_num;
- func_cap->scqc_basic_size = GET_MAX(fc_cap->scqc_size,
- func_cap->scqc_basic_size);
- func_cap->srqc_number += dev_fc_cap->srq_num;
- func_cap->srqc_basic_size = GET_MAX(fc_cap->srqc_size,
- func_cap->srqc_basic_size);
- func_cap->lun_number = CQM_LUN_FC_NUM;
- func_cap->lun_basic_size = CQM_LUN_SIZE_8;
- func_cap->taskmap_number = CQM_TASKMAP_FC_NUM;
- func_cap->taskmap_basic_size = PAGE_SIZE;
- func_cap->childc_number += dev_fc_cap->max_child_qpc_num;
- func_cap->childc_basic_size = GET_MAX(fc_cap->child_qpc_size,
- func_cap->childc_basic_size);
- func_cap->pagesize_reorder = CQM_FC_PAGESIZE_ORDER;
-}
-
-void cqm_service_capability_init(struct cqm_handle *cqm_handle,
- struct service_cap *service_capability)
-{
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 i;
-
- for (i = 0; i < CQM_SERVICE_T_MAX; i++) {
- cqm_handle->service[i].valid = false;
- cqm_handle->service[i].has_register = false;
- cqm_handle->service[i].buf_order = 0;
- }
-
- cqm_service_valid_init(cqm_handle, service_capability);
-
- cqm_info(handle->dev_hdl, "Cap init: service type %d\n",
- service_capability->chip_svc_type);
-
- if (cqm_handle->service[CQM_SERVICE_T_FC].valid)
- cqm_service_capability_init_fc(cqm_handle, (void *)service_capability);
-}
-
-/* Set func_type in fake_cqm_handle to ppf, pf, or vf. */
-void cqm_set_func_type(struct cqm_handle *cqm_handle)
-{
- u32 idx = cqm_handle->func_attribute.func_global_idx;
-
- if (idx == 0)
- cqm_handle->func_attribute.func_type = CQM_PPF;
- else if (idx < CQM_MAX_PF_NUM)
- cqm_handle->func_attribute.func_type = CQM_PF;
- else
- cqm_handle->func_attribute.func_type = CQM_VF;
-}
-
-void cqm_lb_fake_mode_init(struct cqm_handle *cqm_handle, struct service_cap *svc_cap)
-{
- struct cqm_func_capability *func_cap = &cqm_handle->func_capability;
-
- func_cap->lb_mode = svc_cap->lb_mode;
-
- /* Initializing the LB Mode */
- if (func_cap->lb_mode == CQM_LB_MODE_NORMAL)
- func_cap->smf_pg = 0;
- else
- func_cap->smf_pg = svc_cap->smf_pg;
-
- func_cap->fake_cfg_number = 0;
- func_cap->fake_func_type = CQM_FAKE_FUNC_NORMAL;
-}
-
-s32 cqm_capability_init(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
- struct sphw_func_attr *func_attr = &cqm_handle->func_attribute;
- struct cqm_func_capability *func_cap = &cqm_handle->func_capability;
- u32 total_function_num = 0;
- int err = 0;
-
- /* Initializes the PPF capabilities: include timer, pf, vf. */
- if (func_attr->func_type == CQM_PPF) {
- total_function_num = service_capability->host_total_function;
- func_cap->timer_enable = service_capability->timer_en;
- func_cap->pf_num = service_capability->pf_num;
- func_cap->pf_id_start = service_capability->pf_id_start;
- func_cap->vf_num = service_capability->vf_num;
- func_cap->vf_id_start = service_capability->vf_id_start;
-
- cqm_info(handle->dev_hdl, "Cap init: total function num 0x%x\n",
- total_function_num);
- cqm_info(handle->dev_hdl, "Cap init: pf_num 0x%x, pf_id_start 0x%x, vf_num 0x%x, vf_id_start 0x%x\n",
- func_cap->pf_num, func_cap->pf_id_start,
- func_cap->vf_num, func_cap->vf_id_start);
- cqm_info(handle->dev_hdl, "Cap init: timer_enable %u (1: enable; 0: disable)\n",
- func_cap->timer_enable);
- }
-
- func_cap->flow_table_based_conn_number = service_capability->max_connect_num;
- func_cap->flow_table_based_conn_cache_number = service_capability->max_stick2cache_num;
- cqm_info(handle->dev_hdl, "Cap init: cfg max_conn_num 0x%x, max_cache_conn_num 0x%x\n",
- func_cap->flow_table_based_conn_number,
- func_cap->flow_table_based_conn_cache_number);
-
- func_cap->bloomfilter_enable = service_capability->bloomfilter_en;
- cqm_info(handle->dev_hdl, "Cap init: bloomfilter_enable %u (1: enable; 0: disable)\n",
- func_cap->bloomfilter_enable);
-
- if (func_cap->bloomfilter_enable) {
- func_cap->bloomfilter_length = service_capability->bfilter_len;
- func_cap->bloomfilter_addr =
- service_capability->bfilter_start_addr;
- if (func_cap->bloomfilter_length != 0 &&
- !cqm_check_align(func_cap->bloomfilter_length)) {
- cqm_err(handle->dev_hdl, "Cap init: bloomfilter_length %u is not the power of 2\n",
- func_cap->bloomfilter_length);
-
- err = CQM_FAIL;
- goto out;
- }
- }
-
- cqm_info(handle->dev_hdl, "Cap init: bloomfilter_length 0x%x, bloomfilter_addr 0x%x\n",
- func_cap->bloomfilter_length, func_cap->bloomfilter_addr);
-
- func_cap->qpc_reserved = 0;
- func_cap->mpt_reserved = 0;
- func_cap->scq_reserved = 0;
- func_cap->srq_reserved = 0;
- func_cap->qpc_alloc_static = false;
- func_cap->scqc_alloc_static = false;
-
- func_cap->l3i_number = CQM_L3I_COMM_NUM;
- func_cap->l3i_basic_size = CQM_L3I_SIZE_8;
-
- func_cap->timer_number = CQM_TIMER_ALIGN_SCALE_NUM * total_function_num;
- func_cap->timer_basic_size = CQM_TIMER_SIZE_32;
-
- func_cap->gpa_check_enable = true;
-
- cqm_lb_fake_mode_init(cqm_handle, service_capability);
- cqm_info(handle->dev_hdl, "Cap init: lb_mode=%u\n", func_cap->lb_mode);
- cqm_info(handle->dev_hdl, "Cap init: smf_pg=%u\n", func_cap->smf_pg);
- cqm_info(handle->dev_hdl, "Cap init: fake_func_type=%u\n", func_cap->fake_func_type);
- cqm_info(handle->dev_hdl, "Cap init: fake_cfg_number=%u\n", func_cap->fake_cfg_number);
-
- cqm_service_capability_init(cqm_handle, service_capability);
-
- cqm_test_mode_init(cqm_handle, service_capability);
-
- cqm_service_capability_update(cqm_handle);
-
- func_cap->ft_enable = service_capability->sf_svc_attr.ft_en;
- func_cap->rdma_enable = service_capability->sf_svc_attr.rdma_en;
-
- cqm_info(handle->dev_hdl, "Cap init: pagesize_reorder %u\n", func_cap->pagesize_reorder);
- cqm_info(handle->dev_hdl, "Cap init: xid_alloc_mode %d, gpa_check_enable %d\n",
- func_cap->xid_alloc_mode, func_cap->gpa_check_enable);
- cqm_info(handle->dev_hdl, "Cap init: qpc_alloc_mode %d, scqc_alloc_mode %d\n",
- func_cap->qpc_alloc_static, func_cap->scqc_alloc_static);
- cqm_info(handle->dev_hdl, "Cap init: hash_number 0x%x\n", func_cap->hash_number);
- cqm_info(handle->dev_hdl, "Cap init: qpc_number 0x%x, qpc_reserved 0x%x, qpc_basic_size 0x%x\n",
- func_cap->qpc_number, func_cap->qpc_reserved, func_cap->qpc_basic_size);
- cqm_info(handle->dev_hdl, "Cap init: scqc_number 0x%x scqc_reserved 0x%x, scqc_basic_size 0x%x\n",
- func_cap->scqc_number, func_cap->scq_reserved, func_cap->scqc_basic_size);
- cqm_info(handle->dev_hdl, "Cap init: srqc_number 0x%x, srqc_basic_size 0x%x\n",
- func_cap->srqc_number, func_cap->srqc_basic_size);
- cqm_info(handle->dev_hdl, "Cap init: mpt_number 0x%x, mpt_reserved 0x%x\n",
- func_cap->mpt_number, func_cap->mpt_reserved);
- cqm_info(handle->dev_hdl, "Cap init: gid_number 0x%x, lun_number 0x%x\n",
- func_cap->gid_number, func_cap->lun_number);
- cqm_info(handle->dev_hdl, "Cap init: taskmap_number 0x%x, l3i_number 0x%x\n",
- func_cap->taskmap_number, func_cap->l3i_number);
- cqm_info(handle->dev_hdl, "Cap init: timer_number 0x%x, childc_number 0x%x\n",
- func_cap->timer_number, func_cap->childc_number);
- cqm_info(handle->dev_hdl, "Cap init: childc_basic_size 0x%x\n",
- func_cap->childc_basic_size);
- cqm_info(handle->dev_hdl, "Cap init: xid2cid_number 0x%x, reorder_number 0x%x\n",
- func_cap->xid2cid_number, func_cap->reorder_number);
- cqm_info(handle->dev_hdl, "Cap init: ft_enable %d, rdma_enable %d\n",
- func_cap->ft_enable, func_cap->rdma_enable);
-
- return CQM_SUCCESS;
-
-out:
- if (func_attr->func_type == CQM_PPF)
- func_cap->timer_enable = 0;
-
- return err;
-}
-
-s32 cqm_mem_init(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
-
- if (cqm_bat_init(cqm_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bat_init));
- return CQM_FAIL;
- }
-
- if (cqm_cla_init(cqm_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_init));
- goto err1;
- }
-
- if (cqm_bitmap_init(cqm_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_bitmap_init));
- goto err2;
- }
-
- if (cqm_object_table_init(cqm_handle) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_object_table_init));
- goto err3;
- }
-
- return CQM_SUCCESS;
-
-err3:
- cqm_bitmap_uninit(cqm_handle);
-err2:
- cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX);
-err1:
- cqm_bat_uninit(cqm_handle);
- return CQM_FAIL;
-}
-
-void cqm_mem_uninit(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
-
- cqm_object_table_uninit(cqm_handle);
- cqm_bitmap_uninit(cqm_handle);
- cqm_cla_uninit(cqm_handle, CQM_BAT_ENTRY_MAX);
- cqm_bat_uninit(cqm_handle);
-}
-
-s32 cqm_event_init(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
-
- if (sphw_aeq_register_swe_cb(ex_handle, SPHW_STATEFULL_EVENT,
- cqm_aeq_callback) != CHIPIF_SUCCESS) {
- cqm_err(handle->dev_hdl, "Event: fail to register aeq callback\n");
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-void cqm_event_uninit(void *ex_handle)
-{
- sphw_aeq_unregister_swe_cb(ex_handle, SPHW_STATEFULL_EVENT);
-}
-
-u32 cqm_aeq_event2type(u8 event)
-{
- u32 service_type;
-
- /* Distributes events to different service modules
- * based on the event type.
- */
- if (event >= CQM_AEQ_BASE_T_FC && event < CQM_AEQ_MAX_T_FC)
- service_type = CQM_SERVICE_T_FC;
- else
- service_type = CQM_SERVICE_T_MAX;
-
- return service_type;
-}
-
-u8 cqm_aeq_callback(void *ex_handle, u8 event, u8 *data)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct service_register_template *service_template = NULL;
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
- u8 event_level = FAULT_LEVEL_MAX;
- u32 service_type;
-
- CQM_PTR_CHECK_RET(ex_handle, event_level,
- CQM_PTR_NULL(aeq_callback_ex_handle));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_aeq_callback_cnt[event]);
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- CQM_PTR_CHECK_RET(cqm_handle, event_level,
- CQM_PTR_NULL(aeq_callback_cqm_handle));
-
- /* Distributes events to different service modules
- * based on the event type.
- */
- service_type = cqm_aeq_event2type(event);
- if (service_type == CQM_SERVICE_T_MAX) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(event));
- return event_level;
- }
-
- service = &cqm_handle->service[service_type];
- service_template = &service->service_template;
-
- if (!service_template->aeq_level_callback)
- cqm_err(handle->dev_hdl, "Event: service_type %u aeq_level_callback unregistered\n",
- service_type);
- else
- event_level = service_template->aeq_level_callback(service_template->service_handle,
- event, data);
-
- if (!service_template->aeq_callback)
- cqm_err(handle->dev_hdl, "Event: service_type %u aeq_callback unregistered\n",
- service_type);
- else
- service_template->aeq_callback(service_template->service_handle,
- event, data);
-
- return event_level;
-}
-
-s32 cqm3_service_register(void *ex_handle, struct service_register_template *service_template)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
-
- CQM_PTR_CHECK_RET(ex_handle, CQM_FAIL, CQM_PTR_NULL(ex_handle));
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- CQM_PTR_CHECK_RET(cqm_handle, CQM_FAIL, CQM_PTR_NULL(cqm_handle));
- CQM_PTR_CHECK_RET(service_template, CQM_FAIL,
- CQM_PTR_NULL(service_template));
-
- if (service_template->service_type >= CQM_SERVICE_T_MAX) {
- cqm_err(handle->dev_hdl,
- CQM_WRONG_VALUE(service_template->service_type));
- return CQM_FAIL;
- }
- service = &cqm_handle->service[service_template->service_type];
- if (!service->valid) {
- cqm_err(handle->dev_hdl, "Service register: service_type %u is invalid\n",
- service_template->service_type);
- return CQM_FAIL;
- }
-
- if (service->has_register) {
- cqm_err(handle->dev_hdl, "Service register: service_type %u has registered\n",
- service_template->service_type);
- return CQM_FAIL;
- }
-
- service->has_register = true;
- (void)memcpy((void *)(&service->service_template),
- (void *)service_template,
- sizeof(struct service_register_template));
-
- return CQM_SUCCESS;
-}
-
-void cqm3_service_unregister(void *ex_handle, u32 service_type)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
-
- CQM_PTR_CHECK_NO_RET(ex_handle, CQM_PTR_NULL(ex_handle));
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- CQM_PTR_CHECK_NO_RET(cqm_handle, CQM_PTR_NULL(cqm_handle));
-
- if (service_type >= CQM_SERVICE_T_MAX) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
- return;
- }
-
- service = &cqm_handle->service[service_type];
- if (!service->valid)
- cqm_err(handle->dev_hdl, "Service unregister: service_type %u is disable\n",
- service_type);
-
- service->has_register = false;
- memset(&service->service_template, 0, sizeof(struct service_register_template));
-}
-
-struct cqm_cmd_buf *cqm3_cmd_alloc(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
-
- CQM_PTR_CHECK_RET(ex_handle, NULL, CQM_PTR_NULL(ex_handle));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_cmd_alloc_cnt);
-
- return (struct cqm_cmd_buf *)sphw_alloc_cmd_buf(ex_handle);
-}
-
-void cqm3_cmd_free(void *ex_handle, struct cqm_cmd_buf *cmd_buf)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
-
- CQM_PTR_CHECK_NO_RET(ex_handle, CQM_PTR_NULL(ex_handle));
- CQM_PTR_CHECK_NO_RET(cmd_buf, CQM_PTR_NULL(cmd_buf));
- CQM_PTR_CHECK_NO_RET(cmd_buf->buf, CQM_PTR_NULL(buf));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_cmd_free_cnt);
-
- sphw_free_cmd_buf(ex_handle, (struct sphw_cmd_buf *)cmd_buf);
-}
-
-s32 cqm3_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, struct cqm_cmd_buf *buf_in,
- struct cqm_cmd_buf *buf_out, u64 *out_param, u32 timeout,
- u16 channel)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
-
- CQM_PTR_CHECK_RET(ex_handle, CQM_FAIL, CQM_PTR_NULL(ex_handle));
- CQM_PTR_CHECK_RET(buf_in, CQM_FAIL, CQM_PTR_NULL(buf_in));
- CQM_PTR_CHECK_RET(buf_in->buf, CQM_FAIL, CQM_PTR_NULL(buf));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_send_cmd_box_cnt);
-
- return sphw_cmdq_detail_resp(ex_handle, mod, cmd,
- (struct sphw_cmd_buf *)buf_in,
- (struct sphw_cmd_buf *)buf_out,
- out_param, timeout, channel);
-}
-
-int cqm_alloc_fc_db_addr(void *hwdev, void __iomem **db_base,
- void __iomem **dwqe_base)
-{
- struct sphw_hwif *hwif = NULL;
- u32 idx = 0;
-#define SPFC_DB_ADDR_RSVD 12
-#define SPFC_DB_MASK 128
- u64 db_base_phy_fc;
-
- if (!hwdev || !db_base)
- return -EINVAL;
-
- hwif = ((struct sphw_hwdev *)hwdev)->hwif;
-
- db_base_phy_fc = hwif->db_base_phy >> SPFC_DB_ADDR_RSVD;
-
- if (db_base_phy_fc & (SPFC_DB_MASK - 1))
- idx = SPFC_DB_MASK - (db_base_phy_fc && (SPFC_DB_MASK - 1));
-
- *db_base = hwif->db_base + idx * SPHW_DB_PAGE_SIZE;
-
- if (!dwqe_base)
- return 0;
-
- *dwqe_base = (u8 *)*db_base + SPHW_DWQE_OFFSET;
-
- return 0;
-}
-
-s32 cqm3_db_addr_alloc(void *ex_handle, void __iomem **db_addr,
- void __iomem **dwqe_addr)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
-
- CQM_PTR_CHECK_RET(ex_handle, CQM_FAIL, CQM_PTR_NULL(ex_handle));
- CQM_PTR_CHECK_RET(db_addr, CQM_FAIL, CQM_PTR_NULL(db_addr));
- CQM_PTR_CHECK_RET(dwqe_addr, CQM_FAIL, CQM_PTR_NULL(dwqe_addr));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_db_addr_alloc_cnt);
-
- return cqm_alloc_fc_db_addr(ex_handle, db_addr, dwqe_addr);
-}
-
-s32 cqm_db_phy_addr_alloc(void *ex_handle, u64 *db_paddr, u64 *dwqe_addr)
-{
- return sphw_alloc_db_phy_addr(ex_handle, db_paddr, dwqe_addr);
-}
-
-void cqm3_db_addr_free(void *ex_handle, const void __iomem *db_addr,
- void __iomem *dwqe_addr)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
-
- CQM_PTR_CHECK_NO_RET(ex_handle, CQM_PTR_NULL(ex_handle));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_db_addr_free_cnt);
-
- sphw_free_db_addr(ex_handle, db_addr, dwqe_addr);
-}
-
-void cqm_db_phy_addr_free(void *ex_handle, u64 *db_paddr, u64 *dwqe_addr)
-{
- sphw_free_db_phy_addr(ex_handle, *db_paddr, *dwqe_addr);
-}
-
-s32 cqm_db_init(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
- s32 i;
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
-
- /* Allocate hardware doorbells to services. */
- for (i = 0; i < CQM_SERVICE_T_MAX; i++) {
- service = &cqm_handle->service[i];
- if (!service->valid)
- continue;
-
- if (cqm3_db_addr_alloc(ex_handle, &service->hardware_db_vaddr,
- &service->dwqe_vaddr) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm3_db_addr_alloc));
- break;
- }
-
- if (cqm_db_phy_addr_alloc(handle, &service->hardware_db_paddr,
- &service->dwqe_paddr) != CQM_SUCCESS) {
- cqm3_db_addr_free(ex_handle, service->hardware_db_vaddr,
- service->dwqe_vaddr);
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_db_phy_addr_alloc));
- break;
- }
- }
-
- if (i != CQM_SERVICE_T_MAX) {
- i--;
- for (; i >= 0; i--) {
- service = &cqm_handle->service[i];
- if (!service->valid)
- continue;
-
- cqm3_db_addr_free(ex_handle, service->hardware_db_vaddr,
- service->dwqe_vaddr);
- cqm_db_phy_addr_free(ex_handle,
- &service->hardware_db_paddr,
- &service->dwqe_paddr);
- }
- return CQM_FAIL;
- }
-
- return CQM_SUCCESS;
-}
-
-void cqm_db_uninit(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
- s32 i;
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
-
- /* Release hardware doorbell. */
- for (i = 0; i < CQM_SERVICE_T_MAX; i++) {
- service = &cqm_handle->service[i];
- if (service->valid)
- cqm3_db_addr_free(ex_handle, service->hardware_db_vaddr,
- service->dwqe_vaddr);
- }
-}
-
-s32 cqm3_ring_hardware_db_fc(void *ex_handle, u32 service_type, u8 db_count,
- u8 pagenum, u64 db)
-{
-#define SPFC_DB_FAKE_VF_OFFSET 32
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
- struct sphw_hwdev *handle = NULL;
- void *dbaddr = NULL;
-
- handle = (struct sphw_hwdev *)ex_handle;
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- service = &cqm_handle->service[service_type];
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
- wmb();
- dbaddr = (u8 *)service->hardware_db_vaddr +
- ((pagenum + SPFC_DB_FAKE_VF_OFFSET) * SPHW_DB_PAGE_SIZE);
- *((u64 *)dbaddr + db_count) = db;
- return CQM_SUCCESS;
-}
-
-s32 cqm_ring_direct_wqe_db_fc(void *ex_handle, u32 service_type,
- void *direct_wqe)
-{
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
- struct sphw_hwdev *handle = NULL;
- u64 *tmp = (u64 *)direct_wqe;
- int i;
-
- handle = (struct sphw_hwdev *)ex_handle;
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- service = &cqm_handle->service[service_type];
-
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
- wmb();
- *((u64 *)service->dwqe_vaddr + 0) = tmp[2];
- *((u64 *)service->dwqe_vaddr + 1) = tmp[3];
- *((u64 *)service->dwqe_vaddr + 2) = tmp[0];
- *((u64 *)service->dwqe_vaddr + 3) = tmp[1];
- tmp += 4;
-
- /* The FC use 256B WQE. The directwqe is written at block0,
- * and the length is 256B
- */
- for (i = 4; i < 32; i++)
- *((u64 *)service->dwqe_vaddr + i) = *tmp++;
-
- return CQM_SUCCESS;
-}
-
-static s32 bloomfilter_init_cmd(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- struct cqm_func_capability *capability = &cqm_handle->func_capability;
- struct cqm_bloomfilter_init_cmd *cmd = NULL;
- struct cqm_cmd_buf *buf_in = NULL;
- s32 ret;
-
- buf_in = cqm3_cmd_alloc((void *)(cqm_handle->ex_handle));
- CQM_PTR_CHECK_RET(buf_in, CQM_FAIL, CQM_ALLOC_FAIL(buf_in));
-
- /* Fill the command format and convert it to big-endian. */
- buf_in->size = sizeof(struct cqm_bloomfilter_init_cmd);
- cmd = (struct cqm_bloomfilter_init_cmd *)(buf_in->buf);
- cmd->bloom_filter_addr = capability->bloomfilter_addr;
- cmd->bloom_filter_len = capability->bloomfilter_length;
-
- cqm_swab32((u8 *)cmd, (sizeof(struct cqm_bloomfilter_init_cmd) >> CQM_DW_SHIFT));
-
- ret = cqm3_send_cmd_box((void *)(cqm_handle->ex_handle),
- CQM_MOD_CQM, CQM_CMD_T_BLOOMFILTER_INIT, buf_in,
- NULL, NULL, CQM_CMD_TIMEOUT,
- SPHW_CHANNEL_DEFAULT);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm3_send_cmd_box));
- cqm_err(handle->dev_hdl, "Bloomfilter: %s ret=%d\n", __func__,
- ret);
- cqm_err(handle->dev_hdl, "Bloomfilter: %s: 0x%x 0x%x\n",
- __func__, cmd->bloom_filter_addr,
- cmd->bloom_filter_len);
- cqm3_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
- return CQM_FAIL;
- }
- cqm3_cmd_free((void *)(cqm_handle->ex_handle), buf_in);
- return CQM_SUCCESS;
-}
-
-s32 cqm_bloomfilter_init(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_bloomfilter_table *bloomfilter_table = NULL;
- struct cqm_func_capability *capability = NULL;
- struct cqm_handle *cqm_handle = NULL;
- u32 array_size;
- s32 ret;
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- bloomfilter_table = &cqm_handle->bloomfilter_table;
- capability = &cqm_handle->func_capability;
-
- if (capability->bloomfilter_length == 0) {
- cqm_info(handle->dev_hdl,
- "Bloomfilter: bf_length=0, don't need to init bloomfilter\n");
- return CQM_SUCCESS;
- }
-
- /* The unit of bloomfilter_length is 64B(512bits). Each bit is a table
- * node. Therefore the value must be shift 9 bits to the left.
- */
- bloomfilter_table->table_size = capability->bloomfilter_length <<
- CQM_BF_LENGTH_UNIT;
- /* The unit of bloomfilter_length is 64B. The unit of array entryis 32B.
- */
- array_size = capability->bloomfilter_length << 1;
- if (array_size == 0 || array_size > CQM_BF_BITARRAY_MAX) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(array_size));
- return CQM_FAIL;
- }
-
- bloomfilter_table->array_mask = array_size - 1;
- /* This table is not a bitmap, it is the counter of corresponding bit.
- */
- bloomfilter_table->table = vmalloc(bloomfilter_table->table_size * (sizeof(u32)));
- CQM_PTR_CHECK_RET(bloomfilter_table->table, CQM_FAIL, CQM_ALLOC_FAIL(table));
-
- memset(bloomfilter_table->table, 0,
- (bloomfilter_table->table_size * sizeof(u32)));
-
- /* The the bloomfilter must be initialized to 0 by ucode,
- * because the bloomfilter is mem mode
- */
- if (cqm_handle->func_capability.bloomfilter_enable) {
- ret = bloomfilter_init_cmd(ex_handle);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- "Bloomfilter: bloomfilter_init_cmd ret=%d\n",
- ret);
- vfree(bloomfilter_table->table);
- bloomfilter_table->table = NULL;
- return CQM_FAIL;
- }
- }
-
- mutex_init(&bloomfilter_table->lock);
- return CQM_SUCCESS;
-}
-
-void cqm_bloomfilter_uninit(void *ex_handle)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_bloomfilter_table *bloomfilter_table = NULL;
- struct cqm_handle *cqm_handle = NULL;
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- bloomfilter_table = &cqm_handle->bloomfilter_table;
-
- if (bloomfilter_table->table) {
- vfree(bloomfilter_table->table);
- bloomfilter_table->table = NULL;
- }
-}
-
-s32 cqm_bloomfilter_cmd(void *ex_handle, u32 op, u32 k_flag, u64 id)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_cmd_buf *buf_in = NULL;
- struct cqm_bloomfilter_cmd *cmd = NULL;
- s32 ret;
-
- buf_in = cqm3_cmd_alloc(ex_handle);
- CQM_PTR_CHECK_RET(buf_in, CQM_FAIL, CQM_ALLOC_FAIL(buf_in));
-
- /* Fill the command format and convert it to big-endian. */
- buf_in->size = sizeof(struct cqm_bloomfilter_cmd);
- cmd = (struct cqm_bloomfilter_cmd *)(buf_in->buf);
- memset((void *)cmd, 0, sizeof(struct cqm_bloomfilter_cmd));
- cmd->k_en = k_flag;
- cmd->index_h = (u32)(id >> CQM_DW_OFFSET);
- cmd->index_l = (u32)(id & CQM_DW_MASK);
-
- cqm_swab32((u8 *)cmd, (sizeof(struct cqm_bloomfilter_cmd) >> CQM_DW_SHIFT));
-
- ret = cqm3_send_cmd_box(ex_handle, CQM_MOD_CQM, (u8)op, buf_in, NULL,
- NULL, CQM_CMD_TIMEOUT, SPHW_CHANNEL_DEFAULT);
- if (ret != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm3_send_cmd_box));
- cqm_err(handle->dev_hdl, "Bloomfilter: bloomfilter_cmd ret=%d\n", ret);
- cqm_err(handle->dev_hdl, "Bloomfilter: op=0x%x, cmd: 0x%x 0x%x 0x%x 0x%x\n",
- op, *((u32 *)cmd), *(((u32 *)cmd) + CQM_DW_INDEX1),
- *(((u32 *)cmd) + CQM_DW_INDEX2),
- *(((u32 *)cmd) + CQM_DW_INDEX3));
- cqm3_cmd_free(ex_handle, buf_in);
- return CQM_FAIL;
- }
-
- cqm3_cmd_free(ex_handle, buf_in);
-
- return CQM_SUCCESS;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_main.h b/drivers/scsi/spfc/hw/spfc_cqm_main.h
deleted file mode 100644
index cf10d7f5c339..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_main.h
+++ /dev/null
@@ -1,411 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_CQM_MAIN_H
-#define SPFC_CQM_MAIN_H
-
-#include "sphw_hwdev.h"
-#include "sphw_hwif.h"
-#include "spfc_cqm_object.h"
-#include "spfc_cqm_bitmap_table.h"
-#include "spfc_cqm_bat_cla.h"
-
-#define GET_MAX(a, b) ((a) > (b) ? (a) : (b))
-#define GET_MIN(a, b) ((a) < (b) ? (a) : (b))
-#define CQM_DW_SHIFT 2
-#define CQM_QW_SHIFT 3
-#define CQM_BYTE_BIT_SHIFT 3
-#define CQM_NUM_BIT_BYTE 8
-
-#define CHIPIF_SUCCESS 0
-#define CHIPIF_FAIL (-1)
-
-#define CQM_TIMER_ENABLE 1
-#define CQM_TIMER_DISABLE 0
-
-/* The value must be the same as that of sphw_service_type in sphw_crm.h. */
-#define CQM_SERVICE_T_FC SERVICE_T_FC
-#define CQM_SERVICE_T_MAX SERVICE_T_MAX
-
-struct cqm_service {
- bool valid; /* Whether to enable this service on the function. */
- bool has_register; /* Registered or Not */
- u64 hardware_db_paddr;
- void __iomem *hardware_db_vaddr;
- u64 dwqe_paddr;
- void __iomem *dwqe_vaddr;
- u32 buf_order; /* The size of each buf node is 2^buf_order pages. */
- struct service_register_template service_template;
-};
-
-struct cqm_fake_cfg {
- u32 parent_func; /* The parent func_id of the fake vfs. */
- u32 child_func_start; /* The start func_id of the child fake vfs. */
- u32 child_func_number; /* The number of the child fake vfs. */
-};
-
-#define CQM_MAX_FACKVF_GROUP 4
-
-struct cqm_func_capability {
- /* BAT_PTR table(SMLC) */
- bool ft_enable; /* BAT for flow table enable: support fc service
- */
- bool rdma_enable; /* BAT for rdma enable: support RoCE */
- /* VAT table(SMIR) */
- bool ft_pf_enable; /* Same as ft_enable. BAT entry for fc on pf
- */
- bool rdma_pf_enable; /* Same as rdma_enable. BAT entry for rdma on pf */
-
- /* Dynamic or static memory allocation during the application of
- * specified QPC/SCQC for each service.
- */
- bool qpc_alloc_static;
- bool scqc_alloc_static;
-
- u8 timer_enable; /* Whether the timer function is enabled */
- u8 bloomfilter_enable; /* Whether the bloomgfilter function is enabled */
- /* Maximum number of connections for fc, whitch cannot excedd qpc_number */
- u32 flow_table_based_conn_number;
- u32 flow_table_based_conn_cache_number; /* Maximum number of sticky caches */
- u32 bloomfilter_length; /* Size of the bloomfilter table, 64-byte aligned */
- u32 bloomfilter_addr; /* Start position of the bloomfilter table in the SMF main cache. */
- u32 qpc_reserved; /* Reserved bit in bitmap */
- u32 mpt_reserved; /* The ROCE/IWARP MPT also has a reserved bit. */
-
- /* All basic_size must be 2^n-aligned. */
- /* The number of hash bucket. The size of BAT table is aliaed with 64 bucket.
- *At least 64 buckets is required.
- */
- u32 hash_number;
- /* THe basic size of hash bucket is 64B, including 5 valid entry and one next entry. */
- u32 hash_basic_size;
- u32 qpc_number;
- u32 qpc_basic_size;
-
- /* NUmber of PFs/VFs on the current host */
- u32 pf_num;
- u32 pf_id_start;
- u32 vf_num;
- u32 vf_id_start;
-
- u32 lb_mode;
- /* Only lower 4bit is valid, indicating which SMFs are enabled.
- * For example, 0101B indicates that SMF0 and SMF2 are enabled.
- */
- u32 smf_pg;
-
- u32 fake_mode;
- /* Whether the current function belongs to the fake group (parent or child) */
- u32 fake_func_type;
- u32 fake_cfg_number; /* Number of current configuration groups */
- struct cqm_fake_cfg fake_cfg[CQM_MAX_FACKVF_GROUP];
-
- /* Note: for cqm specail test */
- u32 pagesize_reorder;
- bool xid_alloc_mode;
- bool gpa_check_enable;
- u32 scq_reserved;
- u32 srq_reserved;
-
- u32 mpt_number;
- u32 mpt_basic_size;
- u32 scqc_number;
- u32 scqc_basic_size;
- u32 srqc_number;
- u32 srqc_basic_size;
-
- u32 gid_number;
- u32 gid_basic_size;
- u32 lun_number;
- u32 lun_basic_size;
- u32 taskmap_number;
- u32 taskmap_basic_size;
- u32 l3i_number;
- u32 l3i_basic_size;
- u32 childc_number;
- u32 childc_basic_size;
- u32 child_qpc_id_start; /* FC service Child CTX is global addressing. */
- u32 childc_number_all_function; /* The chip supports a maximum of 8096 child CTXs. */
- u32 timer_number;
- u32 timer_basic_size;
- u32 xid2cid_number;
- u32 xid2cid_basic_size;
- u32 reorder_number;
- u32 reorder_basic_size;
-};
-
-#define CQM_PF TYPE_PF
-#define CQM_VF TYPE_VF
-#define CQM_PPF TYPE_PPF
-#define CQM_UNKNOWN TYPE_UNKNOWN
-#define CQM_MAX_PF_NUM 32
-
-#define CQM_LB_MODE_NORMAL 0xff
-#define CQM_LB_MODE_0 0
-#define CQM_LB_MODE_1 1
-#define CQM_LB_MODE_2 2
-
-#define CQM_LB_SMF_MAX 4
-
-#define CQM_FPGA_MODE 0
-#define CQM_EMU_MODE 1
-#define CQM_FAKE_MODE_DISABLE 0
-#define CQM_FAKE_CFUNC_START 32
-
-#define CQM_FAKE_FUNC_NORMAL 0
-#define CQM_FAKE_FUNC_PARENT 1
-#define CQM_FAKE_FUNC_CHILD 2
-#define CQM_FAKE_FUNC_CHILD_CONFLICT 3
-#define CQM_FAKE_FUNC_MAX 32
-
-#define CQM_SPU_HOST_ID 4
-
-#define CQM_QPC_ROCE_PER_DRCT 12
-#define CQM_QPC_NORMAL_RESERVE_DRC 0
-#define CQM_QPC_ROCEAA_ENABLE 1
-#define CQM_QPC_ROCE_VBS_MODE 2
-#define CQM_QPC_NORMAL_WITHOUT_RSERVER_DRC 3
-
-struct cqm_db_common {
- u32 rsvd1 : 23;
- u32 c : 1;
- u32 cos : 3;
- u32 service_type : 5;
-
- u32 rsvd2;
-};
-
-struct cqm_bloomfilter_table {
- u32 *table;
- u32 table_size; /* The unit is bit */
- u32 array_mask; /* The unit of array entry is 32B, used to address entry
- */
- struct mutex lock;
-};
-
-struct cqm_bloomfilter_init_cmd {
- u32 bloom_filter_len;
- u32 bloom_filter_addr;
-};
-
-struct cqm_bloomfilter_cmd {
- u32 rsv1;
-
- u32 k_en : 4;
- u32 rsv2 : 28;
-
- u32 index_h;
- u32 index_l;
-};
-
-struct cqm_handle {
- struct sphw_hwdev *ex_handle;
- struct pci_dev *dev;
- struct sphw_func_attr func_attribute; /* vf/pf attributes */
- struct cqm_func_capability func_capability; /* function capability set */
- struct cqm_service service[CQM_SERVICE_T_MAX]; /* Service-related structure */
- struct cqm_bat_table bat_table;
- struct cqm_bloomfilter_table bloomfilter_table;
- /* fake-vf-related structure */
- struct cqm_handle *fake_cqm_handle[CQM_FAKE_FUNC_MAX];
- struct cqm_handle *parent_cqm_handle;
-};
-
-enum cqm_cmd_type {
- CQM_CMD_T_INVALID = 0,
- CQM_CMD_T_BAT_UPDATE,
- CQM_CMD_T_CLA_UPDATE,
- CQM_CMD_T_CLA_CACHE_INVALID = 6,
- CQM_CMD_T_BLOOMFILTER_INIT,
- CQM_CMD_T_MAX
-};
-
-#define CQM_CQN_FROM_CEQE(data) ((data) & 0xfffff)
-#define CQM_XID_FROM_CEQE(data) ((data) & 0xfffff)
-#define CQM_QID_FROM_CEQE(data) (((data) >> 20) & 0x7)
-#define CQM_TYPE_FROM_CEQE(data) (((data) >> 23) & 0x7)
-
-#define CQM_HASH_BUCKET_SIZE_64 64
-
-#define CQM_MAX_QPC_NUM 0x100000
-#define CQM_MAX_SCQC_NUM 0x100000
-#define CQM_MAX_SRQC_NUM 0x100000
-#define CQM_MAX_CHILDC_NUM 0x100000
-
-#define CQM_QPC_SIZE_256 256
-#define CQM_QPC_SIZE_512 512
-#define CQM_QPC_SIZE_1024 1024
-
-#define CQM_SCQC_SIZE_32 32
-#define CQM_SCQC_SIZE_64 64
-#define CQM_SCQC_SIZE_128 128
-
-#define CQM_SRQC_SIZE_32 32
-#define CQM_SRQC_SIZE_64 64
-#define CQM_SRQC_SIZE_128 128
-
-#define CQM_MPT_SIZE_64 64
-
-#define CQM_GID_SIZE_32 32
-
-#define CQM_LUN_SIZE_8 8
-
-#define CQM_L3I_SIZE_8 8
-
-#define CQM_TIMER_SIZE_32 32
-
-#define CQM_XID2CID_SIZE_8 8
-
-#define CQM_XID2CID_SIZE_8K 8192
-
-#define CQM_REORDER_SIZE_256 256
-
-#define CQM_CHILDC_SIZE_256 256
-
-#define CQM_XID2CID_VBS_NUM (18 * 1024) /* 16K virtio VQ + 2K nvme Q */
-
-#define CQM_VBS_QPC_NUM 2048 /* 2K VOLQ */
-
-#define CQM_VBS_QPC_SIZE 512
-
-#define CQM_XID2CID_VIRTIO_NUM (16 * 1024)
-
-#define CQM_GID_RDMA_NUM 128
-
-#define CQM_LUN_FC_NUM 64
-
-#define CQM_TASKMAP_FC_NUM 4
-
-#define CQM_L3I_COMM_NUM 64
-
-#define CQM_CHILDC_ROCE_NUM (8 * 1024)
-#define CQM_CHILDC_OVS_VBS_NUM (8 * 1024)
-#define CQM_CHILDC_TOE_NUM 256
-#define CQM_CHILDC_IPSEC_NUM (4 * 1024)
-
-#define CQM_TIMER_SCALE_NUM (2 * 1024)
-#define CQM_TIMER_ALIGN_WHEEL_NUM 8
-#define CQM_TIMER_ALIGN_SCALE_NUM \
- (CQM_TIMER_SCALE_NUM * CQM_TIMER_ALIGN_WHEEL_NUM)
-
-#define CQM_QPC_OVS_RSVD (1024 * 1024)
-#define CQM_QPC_ROCE_RSVD 2
-#define CQM_QPC_ROCEAA_SWITCH_QP_NUM 4
-#define CQM_QPC_ROCEAA_RSVD \
- (4 * 1024 + CQM_QPC_ROCEAA_SWITCH_QP_NUM) /* 4096 Normal QP + 4 Switch QP */
-#define CQM_CQ_ROCEAA_RSVD 64
-#define CQM_SRQ_ROCEAA_RSVD 64
-#define CQM_QPC_ROCE_VBS_RSVD \
- (1024 + CQM_QPC_ROCE_RSVD) /* (204800 + CQM_QPC_ROCE_RSVD) */
-
-#define CQM_OVS_PAGESIZE_ORDER 8
-#define CQM_OVS_MAX_TIMER_FUNC 48
-
-#define CQM_FC_PAGESIZE_ORDER 0
-
-#define CQM_QHEAD_ALIGN_ORDER 6
-
-#define CQM_CMD_TIMEOUT 300000 /* ms */
-
-#define CQM_DW_MASK 0xffffffff
-#define CQM_DW_OFFSET 32
-#define CQM_DW_INDEX0 0
-#define CQM_DW_INDEX1 1
-#define CQM_DW_INDEX2 2
-#define CQM_DW_INDEX3 3
-
-/* The unit of bloomfilter_length is 64B(512bits). */
-#define CQM_BF_LENGTH_UNIT 9
-#define CQM_BF_BITARRAY_MAX BIT(17)
-
-typedef void (*serv_cap_init_cb)(struct cqm_handle *, void *);
-
-/* Only for llt test */
-s32 cqm_capability_init(void *ex_handle);
-/* Can be defined as static */
-s32 cqm_mem_init(void *ex_handle);
-void cqm_mem_uninit(void *ex_handle);
-s32 cqm_event_init(void *ex_handle);
-void cqm_event_uninit(void *ex_handle);
-u8 cqm_aeq_callback(void *ex_handle, u8 event, u8 *data);
-
-s32 cqm3_init(void *ex_handle);
-void cqm3_uninit(void *ex_handle);
-s32 cqm3_service_register(void *ex_handle, struct service_register_template *service_template);
-void cqm3_service_unregister(void *ex_handle, u32 service_type);
-
-struct cqm_cmd_buf *cqm3_cmd_alloc(void *ex_handle);
-void cqm3_cmd_free(void *ex_handle, struct cqm_cmd_buf *cmd_buf);
-s32 cqm3_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, struct cqm_cmd_buf *buf_in,
- struct cqm_cmd_buf *buf_out, u64 *out_param, u32 timeout,
- u16 channel);
-
-s32 cqm3_db_addr_alloc(void *ex_handle, void __iomem **db_addr, void __iomem **dwqe_addr);
-s32 cqm_db_phy_addr_alloc(void *ex_handle, u64 *db_paddr, u64 *dwqe_addr);
-s32 cqm_db_init(void *ex_handle);
-void cqm_db_uninit(void *ex_handle);
-
-s32 cqm_bloomfilter_cmd(void *ex_handle, u32 op, u32 k_flag, u64 id);
-s32 cqm_bloomfilter_init(void *ex_handle);
-void cqm_bloomfilter_uninit(void *ex_handle);
-
-#define CQM_LOG_ID 0
-
-#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
-#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
-#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
-#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
-#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
-
-#define cqm_err(dev, format, ...) dev_err(dev, "[CQM]" format, ##__VA_ARGS__)
-#define cqm_warn(dev, format, ...) dev_warn(dev, "[CQM]" format, ##__VA_ARGS__)
-#define cqm_notice(dev, format, ...) \
- dev_notice(dev, "[CQM]" format, ##__VA_ARGS__)
-#define cqm_info(dev, format, ...) dev_info(dev, "[CQM]" format, ##__VA_ARGS__)
-
-#define CQM_32_ALIGN_CHECK_RET(dev_hdl, x, ret, desc) \
- do { \
- if (unlikely(((x) & 0x1f) != 0)) { \
- cqm_err(dev_hdl, desc); \
- return ret; \
- } \
- } while (0)
-#define CQM_64_ALIGN_CHECK_RET(dev_hdl, x, ret, desc) \
- do { \
- if (unlikely(((x) & 0x3f) != 0)) { \
- cqm_err(dev_hdl, desc); \
- return ret; \
- } \
- } while (0)
-
-#define CQM_PTR_CHECK_RET(ptr, ret, desc) \
- do { \
- if (unlikely((ptr) == NULL)) { \
- pr_err("[CQM]" desc); \
- return ret; \
- } \
- } while (0)
-
-#define CQM_PTR_CHECK_NO_RET(ptr, desc) \
- do { \
- if (unlikely((ptr) == NULL)) { \
- pr_err("[CQM]" desc); \
- return; \
- } \
- } while (0)
-#define CQM_CHECK_EQUAL_RET(dev_hdl, actual, expect, ret, desc) \
- do { \
- if (unlikely((expect) != (actual))) { \
- cqm_err(dev_hdl, desc); \
- return ret; \
- } \
- } while (0)
-#define CQM_CHECK_EQUAL_NO_RET(dev_hdl, actual, expect, desc) \
- do { \
- if (unlikely((expect) != (actual))) { \
- cqm_err(dev_hdl, desc); \
- return; \
- } \
- } while (0)
-
-#endif /* SPFC_CQM_MAIN_H */
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_object.c b/drivers/scsi/spfc/hw/spfc_cqm_object.c
deleted file mode 100644
index 165794e9c7e5..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_object.c
+++ /dev/null
@@ -1,937 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/gfp.h>
-#include <linux/mm.h>
-
-#include "sphw_crm.h"
-#include "sphw_hw.h"
-#include "sphw_hwdev.h"
-#include "sphw_hwif.h"
-
-#include "spfc_cqm_object.h"
-#include "spfc_cqm_bitmap_table.h"
-#include "spfc_cqm_bat_cla.h"
-#include "spfc_cqm_main.h"
-
-s32 cqm_qpc_mpt_bitmap_alloc(struct cqm_object *object, struct cqm_cla_table *cla_table)
-{
- struct cqm_qpc_mpt *common = container_of(object, struct cqm_qpc_mpt, object);
- struct cqm_qpc_mpt_info *qpc_mpt_info = container_of(common,
- struct cqm_qpc_mpt_info,
- common);
- struct cqm_handle *cqm_handle = (struct cqm_handle *)object->cqm_handle;
- struct cqm_func_capability *func_cap = &cqm_handle->func_capability;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_bitmap *bitmap = &cla_table->bitmap;
- u32 index, count;
-
- count = (ALIGN(object->object_size, cla_table->obj_size)) / cla_table->obj_size;
- qpc_mpt_info->index_count = count;
-
- if (qpc_mpt_info->common.xid == CQM_INDEX_INVALID) {
- /* apply for an index normally */
- index = cqm_bitmap_alloc(bitmap, 1U << (cla_table->z + 1),
- count, func_cap->xid_alloc_mode);
- if (index < bitmap->max_num) {
- qpc_mpt_info->common.xid = index;
- } else {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_bitmap_alloc));
- return CQM_FAIL;
- }
- } else {
- /* apply for index to be reserved */
- index = cqm_bitmap_alloc_reserved(bitmap, count,
- qpc_mpt_info->common.xid);
- if (index != qpc_mpt_info->common.xid) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_bitmap_alloc_reserved));
- return CQM_FAIL;
- }
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_qpc_mpt_create(struct cqm_object *object)
-{
- struct cqm_qpc_mpt *common = container_of(object, struct cqm_qpc_mpt, object);
- struct cqm_qpc_mpt_info *qpc_mpt_info = container_of(common,
- struct cqm_qpc_mpt_info,
- common);
- struct cqm_handle *cqm_handle = (struct cqm_handle *)object->cqm_handle;
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_object_table *object_table = NULL;
- struct cqm_cla_table *cla_table = NULL;
- struct cqm_bitmap *bitmap = NULL;
- u32 index, count;
-
- /* find the corresponding cla table */
- if (object->object_type == CQM_OBJECT_SERVICE_CTX) {
- cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_QPC);
- } else {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->object_type));
- return CQM_FAIL;
- }
-
- CQM_PTR_CHECK_RET(cla_table, CQM_FAIL,
- CQM_FUNCTION_FAIL(cqm_cla_table_get));
-
- /* Bitmap applies for index. */
- if (cqm_qpc_mpt_bitmap_alloc(object, cla_table) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_qpc_mpt_bitmap_alloc));
- return CQM_FAIL;
- }
-
- bitmap = &cla_table->bitmap;
- index = qpc_mpt_info->common.xid;
- count = qpc_mpt_info->index_count;
-
- /* Find the trunk page from the BAT/CLA and allocate the buffer.
- * Ensure that the released buffer has been cleared.
- */
- if (cla_table->alloc_static)
- qpc_mpt_info->common.vaddr = cqm_cla_get_unlock(cqm_handle,
- cla_table,
- index, count,
- &common->paddr);
- else
- qpc_mpt_info->common.vaddr = cqm_cla_get_lock(cqm_handle,
- cla_table, index,
- count,
- &common->paddr);
-
- if (!qpc_mpt_info->common.vaddr) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_get_lock));
- cqm_err(handle->dev_hdl, "Qpc mpt init: qpc mpt vaddr is null, cla_table->alloc_static=%d\n",
- cla_table->alloc_static);
- goto err1;
- }
-
- /* Indexes are associated with objects, and FC is executed
- * in the interrupt context.
- */
- object_table = &cla_table->obj_table;
- if (object->service_type == CQM_SERVICE_T_FC) {
- if (cqm_object_table_insert(cqm_handle, object_table, index,
- object, false) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_object_table_insert));
- goto err2;
- }
- } else {
- if (cqm_object_table_insert(cqm_handle, object_table, index,
- object, true) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_object_table_insert));
- goto err2;
- }
- }
-
- return CQM_SUCCESS;
-
-err2:
- cqm_cla_put(cqm_handle, cla_table, index, count);
-err1:
- cqm_bitmap_free(bitmap, index, count);
- return CQM_FAIL;
-}
-
-struct cqm_qpc_mpt *cqm3_object_qpc_mpt_create(void *ex_handle, u32 service_type,
- enum cqm_object_type object_type,
- u32 object_size, void *object_priv,
- u32 index)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_qpc_mpt_info *qpc_mpt_info = NULL;
- struct cqm_handle *cqm_handle = NULL;
- s32 ret = CQM_FAIL;
-
- CQM_PTR_CHECK_RET(ex_handle, NULL, CQM_PTR_NULL(ex_handle));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_qpc_mpt_create_cnt);
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- CQM_PTR_CHECK_RET(cqm_handle, NULL, CQM_PTR_NULL(cqm_handle));
-
- if (service_type >= CQM_SERVICE_T_MAX) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
- return NULL;
- }
- /* exception of service registrion check */
- if (!cqm_handle->service[service_type].has_register) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
- return NULL;
- }
-
- if (object_type != CQM_OBJECT_SERVICE_CTX) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
- return NULL;
- }
-
- qpc_mpt_info = kmalloc(sizeof(*qpc_mpt_info), GFP_ATOMIC | __GFP_ZERO);
- CQM_PTR_CHECK_RET(qpc_mpt_info, NULL, CQM_ALLOC_FAIL(qpc_mpt_info));
-
- qpc_mpt_info->common.object.service_type = service_type;
- qpc_mpt_info->common.object.object_type = object_type;
- qpc_mpt_info->common.object.object_size = object_size;
- atomic_set(&qpc_mpt_info->common.object.refcount, 1);
- init_completion(&qpc_mpt_info->common.object.free);
- qpc_mpt_info->common.object.cqm_handle = cqm_handle;
- qpc_mpt_info->common.xid = index;
-
- qpc_mpt_info->common.priv = object_priv;
-
- ret = cqm_qpc_mpt_create(&qpc_mpt_info->common.object);
- if (ret == CQM_SUCCESS)
- return &qpc_mpt_info->common;
-
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_qpc_mpt_create));
- kfree(qpc_mpt_info);
- return NULL;
-}
-
-void cqm_linkwqe_fill(struct cqm_buf *buf, u32 wqe_per_buf, u32 wqe_size,
- u32 wqe_number, bool tail, u8 link_mode)
-{
- struct cqm_linkwqe_128B *linkwqe = NULL;
- struct cqm_linkwqe *wqe = NULL;
- dma_addr_t addr;
- u8 *tmp = NULL;
- u8 *va = NULL;
- u32 i;
-
- /* The linkwqe of other buffer except the last buffer
- * is directly filled to the tail.
- */
- for (i = 0; i < buf->buf_number; i++) {
- va = (u8 *)(buf->buf_list[i].va);
-
- if (i != (buf->buf_number - 1)) {
- wqe = (struct cqm_linkwqe *)(va + (u32)(wqe_size * wqe_per_buf));
- wqe->wf = CQM_WQE_WF_LINK;
- wqe->ctrlsl = CQM_LINK_WQE_CTRLSL_VALUE;
- wqe->lp = CQM_LINK_WQE_LP_INVALID;
- /* The valid value of link wqe needs to be set to 1.
- * Each service ensures that o-bit=1 indicates that
- * link wqe is valid and o-bit=0 indicates that
- * link wqe is invalid.
- */
- wqe->o = CQM_LINK_WQE_OWNER_VALID;
- addr = buf->buf_list[(u32)(i + 1)].pa;
- wqe->next_page_gpa_h = CQM_ADDR_HI(addr);
- wqe->next_page_gpa_l = CQM_ADDR_LW(addr);
- } else { /* linkwqe special padding of the last buffer */
- if (tail) {
- /* must be filled at the end of the page */
- tmp = va + (u32)(wqe_size * wqe_per_buf);
- wqe = (struct cqm_linkwqe *)tmp;
- } else {
- /* The last linkwqe is filled
- * following the last wqe.
- */
- tmp = va + (u32)(wqe_size * (wqe_number -
- wqe_per_buf *
- (buf->buf_number -
- 1)));
- wqe = (struct cqm_linkwqe *)tmp;
- }
- wqe->wf = CQM_WQE_WF_LINK;
- wqe->ctrlsl = CQM_LINK_WQE_CTRLSL_VALUE;
-
- /* In link mode, the last link WQE is invalid;
- * In ring mode, the last link wqe is valid, pointing to
- * the home page, and the lp is set.
- */
- if (link_mode == CQM_QUEUE_LINK_MODE) {
- wqe->o = CQM_LINK_WQE_OWNER_INVALID;
- } else {
- /* The lp field of the last link_wqe is set to
- * 1, indicating that the meaning of the o-bit
- * is reversed.
- */
- wqe->lp = CQM_LINK_WQE_LP_VALID;
- wqe->o = CQM_LINK_WQE_OWNER_VALID;
- addr = buf->buf_list[0].pa;
- wqe->next_page_gpa_h = CQM_ADDR_HI(addr);
- wqe->next_page_gpa_l = CQM_ADDR_LW(addr);
- }
- }
-
- if (wqe_size == CQM_LINKWQE_128B) {
- /* After the B800 version, the WQE obit scheme is
- * changed. The 64B bits before and after the 128B WQE
- * need to be assigned a value:
- * ifoe the 63rd bit from the end of the last 64B is
- * obit;
- * toe the 157th bit from the end of the last 64B is
- * obit.
- */
- linkwqe = (struct cqm_linkwqe_128B *)wqe;
- linkwqe->second64B.forth_16B.bs.ifoe_o = CQM_LINK_WQE_OWNER_VALID;
-
- /* shift 2 bits by right to get length of dw(4B) */
- cqm_swab32((u8 *)wqe, sizeof(struct cqm_linkwqe_128B) >> 2);
- } else {
- /* shift 2 bits by right to get length of dw(4B) */
- cqm_swab32((u8 *)wqe, sizeof(struct cqm_linkwqe) >> 2);
- }
- }
-}
-
-s32 cqm_nonrdma_queue_ctx_create(struct cqm_object *object)
-{
- struct cqm_queue *common = container_of(object, struct cqm_queue, object);
- struct cqm_nonrdma_qinfo *qinfo = container_of(common, struct cqm_nonrdma_qinfo,
- common);
- struct cqm_handle *cqm_handle = (struct cqm_handle *)object->cqm_handle;
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_object_table *object_table = NULL;
- struct cqm_cla_table *cla_table = NULL;
- struct cqm_bitmap *bitmap = NULL;
- s32 shift;
-
- if (object->object_type == CQM_OBJECT_NONRDMA_SRQ) {
- shift = cqm_shift(qinfo->q_ctx_size);
- common->q_ctx_vaddr = cqm_kmalloc_align(qinfo->q_ctx_size,
- GFP_KERNEL | __GFP_ZERO,
- (u16)shift);
- if (!common->q_ctx_vaddr) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
- return CQM_FAIL;
- }
-
- common->q_ctx_paddr = pci_map_single(cqm_handle->dev,
- common->q_ctx_vaddr,
- qinfo->q_ctx_size,
- PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(cqm_handle->dev,
- common->q_ctx_paddr)) {
- cqm_err(handle->dev_hdl, CQM_MAP_FAIL(q_ctx_vaddr));
- cqm_kfree_align(common->q_ctx_vaddr);
- common->q_ctx_vaddr = NULL;
- return CQM_FAIL;
- }
- } else if (object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
- /* find the corresponding cla table */
- cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_SCQC);
- if (!cla_table) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(nonrdma_cqm_cla_table_get));
- return CQM_FAIL;
- }
-
- /* bitmap applies for index */
- bitmap = &cla_table->bitmap;
- qinfo->index_count =
- (ALIGN(qinfo->q_ctx_size, cla_table->obj_size)) /
- cla_table->obj_size;
- qinfo->common.index = cqm_bitmap_alloc(bitmap, 1U << (cla_table->z + 1),
- qinfo->index_count,
- cqm_handle->func_capability.xid_alloc_mode);
- if (qinfo->common.index >= bitmap->max_num) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(nonrdma_cqm_bitmap_alloc));
- return CQM_FAIL;
- }
-
- /* find the trunk page from BAT/CLA and allocate the buffer */
- common->q_ctx_vaddr = cqm_cla_get_lock(cqm_handle, cla_table,
- qinfo->common.index,
- qinfo->index_count,
- &common->q_ctx_paddr);
- if (!common->q_ctx_vaddr) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(nonrdma_cqm_cla_get_lock));
- cqm_bitmap_free(bitmap, qinfo->common.index,
- qinfo->index_count);
- return CQM_FAIL;
- }
-
- /* index and object association */
- object_table = &cla_table->obj_table;
- if (object->service_type == CQM_SERVICE_T_FC) {
- if (cqm_object_table_insert(cqm_handle, object_table,
- qinfo->common.index, object,
- false) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(nonrdma_cqm_object_table_insert));
- cqm_cla_put(cqm_handle, cla_table,
- qinfo->common.index,
- qinfo->index_count);
- cqm_bitmap_free(bitmap, qinfo->common.index,
- qinfo->index_count);
- return CQM_FAIL;
- }
- } else {
- if (cqm_object_table_insert(cqm_handle, object_table,
- qinfo->common.index, object,
- true) != CQM_SUCCESS) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(nonrdma_cqm_object_table_insert));
- cqm_cla_put(cqm_handle, cla_table,
- qinfo->common.index,
- qinfo->index_count);
- cqm_bitmap_free(bitmap, qinfo->common.index,
- qinfo->index_count);
- return CQM_FAIL;
- }
- }
- }
-
- return CQM_SUCCESS;
-}
-
-s32 cqm_nonrdma_queue_create(struct cqm_object *object)
-{
- struct cqm_queue *common = container_of(object, struct cqm_queue, object);
- struct cqm_nonrdma_qinfo *qinfo = container_of(common, struct cqm_nonrdma_qinfo,
- common);
- struct cqm_handle *cqm_handle = (struct cqm_handle *)object->cqm_handle;
- struct cqm_service *service = cqm_handle->service + object->service_type;
- struct cqm_buf *q_room_buf = &common->q_room_buf_1;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- u32 wqe_number = qinfo->common.object.object_size;
- u32 wqe_size = qinfo->wqe_size;
- u32 order = service->buf_order;
- u32 buf_number, buf_size;
- bool tail = false; /* determine whether the linkwqe is at the end of the page */
-
- /* When creating a CQ/SCQ queue, the page size is 4 KB,
- * the linkwqe must be at the end of the page.
- */
- if (object->object_type == CQM_OBJECT_NONRDMA_EMBEDDED_CQ ||
- object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
- /* depth: 2^n-aligned; depth range: 256-32 K */
- if (wqe_number < CQM_CQ_DEPTH_MIN ||
- wqe_number > CQM_CQ_DEPTH_MAX) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(wqe_number));
- return CQM_FAIL;
- }
- if (!cqm_check_align(wqe_number)) {
- cqm_err(handle->dev_hdl, "Nonrdma queue alloc: wqe_number is not align on 2^n\n");
- return CQM_FAIL;
- }
-
- order = CQM_4K_PAGE_ORDER; /* wqe page 4k */
- tail = true; /* The linkwqe must be at the end of the page. */
- buf_size = CQM_4K_PAGE_SIZE;
- } else {
- buf_size = (u32)(PAGE_SIZE << order);
- }
-
- /* Calculate the total number of buffers required,
- * -1 indicates that the link wqe in a buffer is deducted.
- */
- qinfo->wqe_per_buf = (buf_size / wqe_size) - 1;
- /* number of linkwqes that are included in the depth transferred
- * by the service
- */
- buf_number = ALIGN((wqe_size * wqe_number), buf_size) / buf_size;
-
- /* apply for buffer */
- q_room_buf->buf_number = buf_number;
- q_room_buf->buf_size = buf_size;
- q_room_buf->page_number = buf_number << order;
- if (cqm_buf_alloc(cqm_handle, q_room_buf, false) == CQM_FAIL) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_buf_alloc));
- return CQM_FAIL;
- }
- /* fill link wqe, wqe_number - buf_number is the number of wqe without
- * link wqe
- */
- cqm_linkwqe_fill(q_room_buf, qinfo->wqe_per_buf, wqe_size,
- wqe_number - buf_number, tail,
- common->queue_link_mode);
-
- /* create queue header */
- qinfo->common.q_header_vaddr = cqm_kmalloc_align(sizeof(struct cqm_queue_header),
- GFP_KERNEL | __GFP_ZERO,
- CQM_QHEAD_ALIGN_ORDER);
- if (!qinfo->common.q_header_vaddr) {
- cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
- goto err1;
- }
-
- common->q_header_paddr = pci_map_single(cqm_handle->dev,
- qinfo->common.q_header_vaddr,
- sizeof(struct cqm_queue_header),
- PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(cqm_handle->dev, common->q_header_paddr)) {
- cqm_err(handle->dev_hdl, CQM_MAP_FAIL(q_header_vaddr));
- goto err2;
- }
-
- /* create queue ctx */
- if (cqm_nonrdma_queue_ctx_create(object) == CQM_FAIL) {
- cqm_err(handle->dev_hdl,
- CQM_FUNCTION_FAIL(cqm_nonrdma_queue_ctx_create));
- goto err3;
- }
-
- return CQM_SUCCESS;
-
-err3:
- pci_unmap_single(cqm_handle->dev, common->q_header_paddr,
- sizeof(struct cqm_queue_header), PCI_DMA_BIDIRECTIONAL);
-err2:
- cqm_kfree_align(qinfo->common.q_header_vaddr);
- qinfo->common.q_header_vaddr = NULL;
-err1:
- cqm_buf_free(q_room_buf, cqm_handle->dev);
- return CQM_FAIL;
-}
-
-struct cqm_queue *cqm3_object_fc_srq_create(void *ex_handle, u32 service_type,
- enum cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
- u32 valid_wqe_per_buffer;
- u32 wqe_sum; /* include linkwqe, normal wqe */
- u32 buf_size;
- u32 buf_num;
- s32 ret;
-
- CQM_PTR_CHECK_RET(ex_handle, NULL, CQM_PTR_NULL(ex_handle));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_fc_srq_create_cnt);
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- CQM_PTR_CHECK_RET(cqm_handle, NULL, CQM_PTR_NULL(cqm_handle));
-
- /* service_type must be fc */
- if (service_type != CQM_SERVICE_T_FC) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
- return NULL;
- }
-
- /* exception of service unregistered check */
- if (!cqm_handle->service[service_type].has_register) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
- return NULL;
- }
-
- /* wqe_size cannot exceed PAGE_SIZE and must be 2^n aligned. */
- if (wqe_size >= PAGE_SIZE || (!cqm_check_align(wqe_size))) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(wqe_size));
- return NULL;
- }
-
- /* FC RQ is SRQ. (Different from the SRQ concept of TOE, FC indicates
- * that packets received by all flows are placed on the same RQ.
- * The SRQ of TOE is similar to the RQ resource pool.)
- */
- if (object_type != CQM_OBJECT_NONRDMA_SRQ) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
- return NULL;
- }
-
- service = &cqm_handle->service[service_type];
- buf_size = (u32)(PAGE_SIZE << (service->buf_order));
- /* subtract 1 link wqe */
- valid_wqe_per_buffer = buf_size / wqe_size - 1;
- buf_num = wqe_number / valid_wqe_per_buffer;
- if (wqe_number % valid_wqe_per_buffer != 0)
- buf_num++;
-
- /* calculate the total number of WQEs */
- wqe_sum = buf_num * (valid_wqe_per_buffer + 1);
- nonrdma_qinfo = kmalloc(sizeof(*nonrdma_qinfo), GFP_KERNEL | __GFP_ZERO);
- CQM_PTR_CHECK_RET(nonrdma_qinfo, NULL, CQM_ALLOC_FAIL(nonrdma_qinfo));
-
- /* initialize object member */
- nonrdma_qinfo->common.object.service_type = service_type;
- nonrdma_qinfo->common.object.object_type = object_type;
- /* total number of WQEs */
- nonrdma_qinfo->common.object.object_size = wqe_sum;
- atomic_set(&nonrdma_qinfo->common.object.refcount, 1);
- init_completion(&nonrdma_qinfo->common.object.free);
- nonrdma_qinfo->common.object.cqm_handle = cqm_handle;
-
- /* Initialize the doorbell used by the current queue.
- * The default doorbell is the hardware doorbell.
- */
- nonrdma_qinfo->common.current_q_doorbell = CQM_HARDWARE_DOORBELL;
- /* Currently, the connection mode is fixed. In the future,
- * the service needs to transfer the connection mode.
- */
- nonrdma_qinfo->common.queue_link_mode = CQM_QUEUE_RING_MODE;
-
- /* initialize public members */
- nonrdma_qinfo->common.priv = object_priv;
- nonrdma_qinfo->common.valid_wqe_num = wqe_sum - buf_num;
-
- /* initialize internal private members */
- nonrdma_qinfo->wqe_size = wqe_size;
- /* RQ (also called SRQ of FC) created by FC services,
- * CTX needs to be created.
- */
- nonrdma_qinfo->q_ctx_size = service->service_template.srq_ctx_size;
-
- ret = cqm_nonrdma_queue_create(&nonrdma_qinfo->common.object);
- if (ret == CQM_SUCCESS)
- return &nonrdma_qinfo->common;
-
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fc_queue_create));
- kfree(nonrdma_qinfo);
- return NULL;
-}
-
-struct cqm_queue *cqm3_object_nonrdma_queue_create(void *ex_handle, u32 service_type,
- enum cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
- struct cqm_handle *cqm_handle = NULL;
- struct cqm_service *service = NULL;
- s32 ret;
-
- CQM_PTR_CHECK_RET(ex_handle, NULL, CQM_PTR_NULL(ex_handle));
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_nonrdma_queue_create_cnt);
-
- cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- CQM_PTR_CHECK_RET(cqm_handle, NULL, CQM_PTR_NULL(cqm_handle));
-
- /* exception of service registrion check */
- if (!cqm_handle->service[service_type].has_register) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
- return NULL;
- }
- /* wqe_size can't be more than PAGE_SIZE, can't be zero, must be power
- * of 2 the function of cqm_check_align is to check above
- */
- if (wqe_size >= PAGE_SIZE || (!cqm_check_align(wqe_size))) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(wqe_size));
- return NULL;
- }
-
- /* nonrdma supports: RQ, SQ, SRQ, CQ, SCQ */
- if (object_type < CQM_OBJECT_NONRDMA_EMBEDDED_RQ ||
- object_type > CQM_OBJECT_NONRDMA_SCQ) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object_type));
- return NULL;
- }
-
- nonrdma_qinfo = kmalloc(sizeof(*nonrdma_qinfo), GFP_KERNEL | __GFP_ZERO);
- CQM_PTR_CHECK_RET(nonrdma_qinfo, NULL, CQM_ALLOC_FAIL(nonrdma_qinfo));
-
- nonrdma_qinfo->common.object.service_type = service_type;
- nonrdma_qinfo->common.object.object_type = object_type;
- nonrdma_qinfo->common.object.object_size = wqe_number;
- atomic_set(&nonrdma_qinfo->common.object.refcount, 1);
- init_completion(&nonrdma_qinfo->common.object.free);
- nonrdma_qinfo->common.object.cqm_handle = cqm_handle;
-
- /* Initialize the doorbell used by the current queue.
- * The default value is hardware doorbell
- */
- nonrdma_qinfo->common.current_q_doorbell = CQM_HARDWARE_DOORBELL;
- /* Currently, the link mode is hardcoded and needs to be transferred by
- * the service side.
- */
- nonrdma_qinfo->common.queue_link_mode = CQM_QUEUE_RING_MODE;
-
- nonrdma_qinfo->common.priv = object_priv;
-
- /* Initialize internal private members */
- nonrdma_qinfo->wqe_size = wqe_size;
- service = &cqm_handle->service[service_type];
- switch (object_type) {
- case CQM_OBJECT_NONRDMA_SCQ:
- nonrdma_qinfo->q_ctx_size =
- service->service_template.scq_ctx_size;
- break;
- case CQM_OBJECT_NONRDMA_SRQ:
- /* Currently, the SRQ of the service is created through a
- * dedicated interface.
- */
- nonrdma_qinfo->q_ctx_size =
- service->service_template.srq_ctx_size;
- break;
- default:
- break;
- }
-
- ret = cqm_nonrdma_queue_create(&nonrdma_qinfo->common.object);
- if (ret == CQM_SUCCESS)
- return &nonrdma_qinfo->common;
-
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_nonrdma_queue_create));
- kfree(nonrdma_qinfo);
- return NULL;
-}
-
-void cqm_qpc_mpt_delete(struct cqm_object *object)
-{
- struct cqm_qpc_mpt *common = container_of(object, struct cqm_qpc_mpt, object);
- struct cqm_qpc_mpt_info *qpc_mpt_info = container_of(common,
- struct cqm_qpc_mpt_info,
- common);
- struct cqm_handle *cqm_handle = (struct cqm_handle *)object->cqm_handle;
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_object_table *object_table = NULL;
- struct cqm_cla_table *cla_table = NULL;
- u32 count = qpc_mpt_info->index_count;
- u32 index = qpc_mpt_info->common.xid;
- struct cqm_bitmap *bitmap = NULL;
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_qpc_mpt_delete_cnt);
-
- /* find the corresponding cla table */
- if (object->object_type == CQM_OBJECT_SERVICE_CTX) {
- cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_QPC);
- } else {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->object_type));
- return;
- }
-
- CQM_PTR_CHECK_NO_RET(cla_table,
- CQM_FUNCTION_FAIL(cqm_cla_table_get_qpc));
-
- /* disassociate index and object */
- object_table = &cla_table->obj_table;
- if (object->service_type == CQM_SERVICE_T_FC)
- cqm_object_table_remove(cqm_handle, object_table, index, object,
- false);
- else
- cqm_object_table_remove(cqm_handle, object_table, index, object,
- true);
-
- /* wait for completion to ensure that all references to
- * the QPC are complete
- */
- if (atomic_dec_and_test(&object->refcount))
- complete(&object->free);
- else
- cqm_err(handle->dev_hdl, "Qpc mpt del: object is referred by others, has to wait for completion\n");
-
- /* Static QPC allocation must be non-blocking.
- * Services ensure that the QPC is referenced
- * when the QPC is deleted.
- */
- if (!cla_table->alloc_static)
- wait_for_completion(&object->free);
-
- /* release qpc buffer */
- cqm_cla_put(cqm_handle, cla_table, index, count);
-
- /* release the index to the bitmap */
- bitmap = &cla_table->bitmap;
- cqm_bitmap_free(bitmap, index, count);
-}
-
-s32 cqm_qpc_mpt_delete_ret(struct cqm_object *object)
-{
- u32 object_type;
-
- object_type = object->object_type;
- switch (object_type) {
- case CQM_OBJECT_SERVICE_CTX:
- cqm_qpc_mpt_delete(object);
- return CQM_SUCCESS;
- default:
- return CQM_FAIL;
- }
-}
-
-void cqm_nonrdma_queue_delete(struct cqm_object *object)
-{
- struct cqm_queue *common = container_of(object, struct cqm_queue, object);
- struct cqm_nonrdma_qinfo *qinfo = container_of(common, struct cqm_nonrdma_qinfo,
- common);
- struct cqm_handle *cqm_handle = (struct cqm_handle *)object->cqm_handle;
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_buf *q_room_buf = &common->q_room_buf_1;
- struct sphw_hwdev *handle = cqm_handle->ex_handle;
- struct cqm_object_table *object_table = NULL;
- struct cqm_cla_table *cla_table = NULL;
- struct cqm_bitmap *bitmap = NULL;
- u32 index = qinfo->common.index;
- u32 count = qinfo->index_count;
-
- atomic_inc(&handle->hw_stats.cqm_stats.cqm_nonrdma_queue_delete_cnt);
-
- /* The SCQ has an independent SCQN association. */
- if (object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
- cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_SCQC);
- CQM_PTR_CHECK_NO_RET(cla_table, CQM_FUNCTION_FAIL(cqm_cla_table_get_queue));
-
- /* disassociate index and object */
- object_table = &cla_table->obj_table;
- if (object->service_type == CQM_SERVICE_T_FC)
- cqm_object_table_remove(cqm_handle, object_table, index,
- object, false);
- else
- cqm_object_table_remove(cqm_handle, object_table, index,
- object, true);
- }
-
- /* wait for completion to ensure that all references to
- * the QPC are complete
- */
- if (atomic_dec_and_test(&object->refcount))
- complete(&object->free);
- else
- cqm_err(handle->dev_hdl, "Nonrdma queue del: object is referred by others, has to wait for completion\n");
-
- wait_for_completion(&object->free);
-
- /* If the q header exists, release. */
- if (qinfo->common.q_header_vaddr) {
- pci_unmap_single(cqm_handle->dev, common->q_header_paddr,
- sizeof(struct cqm_queue_header),
- PCI_DMA_BIDIRECTIONAL);
-
- cqm_kfree_align(qinfo->common.q_header_vaddr);
- qinfo->common.q_header_vaddr = NULL;
- }
-
- cqm_buf_free(q_room_buf, cqm_handle->dev);
- /* SRQ and SCQ have independent CTXs and release. */
- if (object->object_type == CQM_OBJECT_NONRDMA_SRQ) {
- /* The CTX of the SRQ of the nordma is
- * applied for independently.
- */
- if (common->q_ctx_vaddr) {
- pci_unmap_single(cqm_handle->dev, common->q_ctx_paddr,
- qinfo->q_ctx_size,
- PCI_DMA_BIDIRECTIONAL);
-
- cqm_kfree_align(common->q_ctx_vaddr);
- common->q_ctx_vaddr = NULL;
- }
- } else if (object->object_type == CQM_OBJECT_NONRDMA_SCQ) {
- /* The CTX of the SCQ of the nordma is managed by BAT/CLA. */
- cqm_cla_put(cqm_handle, cla_table, index, count);
-
- /* release the index to the bitmap */
- bitmap = &cla_table->bitmap;
- cqm_bitmap_free(bitmap, index, count);
- }
-}
-
-s32 cqm_nonrdma_queue_delete_ret(struct cqm_object *object)
-{
- u32 object_type;
-
- object_type = object->object_type;
- switch (object_type) {
- case CQM_OBJECT_NONRDMA_EMBEDDED_RQ:
- case CQM_OBJECT_NONRDMA_EMBEDDED_SQ:
- case CQM_OBJECT_NONRDMA_EMBEDDED_CQ:
- case CQM_OBJECT_NONRDMA_SCQ:
- cqm_nonrdma_queue_delete(object);
- return CQM_SUCCESS;
- case CQM_OBJECT_NONRDMA_SRQ:
- cqm_nonrdma_queue_delete(object);
- return CQM_SUCCESS;
- default:
- return CQM_FAIL;
- }
-}
-
-void cqm3_object_delete(struct cqm_object *object)
-{
- struct cqm_handle *cqm_handle = NULL;
- struct sphw_hwdev *handle = NULL;
-
- CQM_PTR_CHECK_NO_RET(object, CQM_PTR_NULL(object));
- if (!object->cqm_handle) {
- pr_err("[CQM]object del: cqm_handle is null, service type %u, refcount %d\n",
- object->service_type, (int)object->refcount.counter);
- kfree(object);
- return;
- }
-
- cqm_handle = (struct cqm_handle *)object->cqm_handle;
-
- if (!cqm_handle->ex_handle) {
- pr_err("[CQM]object del: ex_handle is null, service type %u, refcount %d\n",
- object->service_type, (int)object->refcount.counter);
- kfree(object);
- return;
- }
-
- handle = cqm_handle->ex_handle;
-
- if (object->service_type >= CQM_SERVICE_T_MAX) {
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->service_type));
- kfree(object);
- return;
- }
-
- if (cqm_qpc_mpt_delete_ret(object) == CQM_SUCCESS) {
- kfree(object);
- return;
- }
-
- if (cqm_nonrdma_queue_delete_ret(object) == CQM_SUCCESS) {
- kfree(object);
- return;
- }
-
- cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(object->object_type));
- kfree(object);
-}
-
-struct cqm_object *cqm3_object_get(void *ex_handle, enum cqm_object_type object_type,
- u32 index, bool bh)
-{
- struct sphw_hwdev *handle = (struct sphw_hwdev *)ex_handle;
- struct cqm_handle *cqm_handle = (struct cqm_handle *)(handle->cqm_hdl);
- struct cqm_bat_table *bat_table = &cqm_handle->bat_table;
- struct cqm_object_table *object_table = NULL;
- struct cqm_cla_table *cla_table = NULL;
- struct cqm_object *object = NULL;
-
- /* The data flow path takes performance into consideration and
- * does not check input parameters.
- */
- switch (object_type) {
- case CQM_OBJECT_SERVICE_CTX:
- cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_QPC);
- break;
- case CQM_OBJECT_NONRDMA_SCQ:
- cla_table = cqm_cla_table_get(bat_table, CQM_BAT_ENTRY_T_SCQC);
- break;
- default:
- return NULL;
- }
-
- if (!cla_table) {
- cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_cla_table_get));
- return NULL;
- }
-
- object_table = &cla_table->obj_table;
- object = cqm_object_table_get(cqm_handle, object_table, index, bh);
- return object;
-}
-
-void cqm3_object_put(struct cqm_object *object)
-{
- /* The data flow path takes performance into consideration and
- * does not check input parameters.
- */
- if (atomic_dec_and_test(&object->refcount))
- complete(&object->free);
-}
diff --git a/drivers/scsi/spfc/hw/spfc_cqm_object.h b/drivers/scsi/spfc/hw/spfc_cqm_object.h
deleted file mode 100644
index 02a3e9070162..000000000000
--- a/drivers/scsi/spfc/hw/spfc_cqm_object.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_CQM_OBJECT_H
-#define SPFC_CQM_OBJECT_H
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif
-#endif /* __cplusplus */
-
-#define CQM_SUCCESS 0
-#define CQM_FAIL (-1)
-/* Ignore the return value and continue */
-#define CQM_CONTINUE 1
-
-/* type of WQE is LINK WQE */
-#define CQM_WQE_WF_LINK 1
-
-/* chain queue mode */
-#define CQM_QUEUE_LINK_MODE 0
-/* RING queue mode */
-#define CQM_QUEUE_RING_MODE 1
-
-#define CQM_CQ_DEPTH_MAX 32768
-#define CQM_CQ_DEPTH_MIN 256
-
-/* linkwqe */
-#define CQM_LINK_WQE_CTRLSL_VALUE 2
-#define CQM_LINK_WQE_LP_VALID 1
-#define CQM_LINK_WQE_LP_INVALID 0
-#define CQM_LINK_WQE_OWNER_VALID 1
-#define CQM_LINK_WQE_OWNER_INVALID 0
-
-#define CQM_ADDR_HI(addr) ((u32)((u64)(addr) >> 32))
-#define CQM_ADDR_LW(addr) ((u32)((u64)(addr) & 0xffffffff))
-
-#define CQM_QPC_LAYOUT_TABLE_SIZE 16
-
-#define CQM_MOD_CQM 8
-
-/* generic linkwqe structure */
-struct cqm_linkwqe {
- u32 rsv1 : 14; /* <reserved field */
- u32 wf : 1; /* <wf */
- u32 rsv2 : 14; /* <reserved field */
- u32 ctrlsl : 2; /* <ctrlsl */
- u32 o : 1; /* <o bit */
-
- u32 rsv3 : 31; /* <reserved field */
- u32 lp : 1; /* The lp field determines whether the o-bit meaning is reversed. */
- u32 next_page_gpa_h;
- u32 next_page_gpa_l;
- u32 next_buffer_addr_h;
- u32 next_buffer_addr_l;
-};
-
-/* SRQ linkwqe structure. The wqe size must not exceed the common RQE size. */
-struct cqm_srq_linkwqe {
- struct cqm_linkwqe linkwqe; /* <generic linkwqe structure */
- u32 current_buffer_gpa_h;
- u32 current_buffer_gpa_l;
- u32 current_buffer_addr_h;
- u32 current_buffer_addr_l;
-
- u32 fast_link_page_addr_h;
- u32 fast_link_page_addr_l;
-
- u32 fixed_next_buffer_addr_h;
- u32 fixed_next_buffer_addr_l;
-};
-
-#define CQM_LINKWQE_128B 128
-
-/* first 64B of standard 128B WQE */
-union cqm_linkwqe_first64B {
- struct cqm_linkwqe basic_linkwqe; /* <generic linkwqe structure */
- u32 value[16]; /* <reserved field */
-};
-
-/* second 64B of standard 128B WQE */
-struct cqm_linkwqe_second64B {
- u32 rsvd0[4]; /* <first 16B reserved field */
- u32 rsvd1[4]; /* <second 16B reserved field */
- u32 rsvd2[4];
-
- union {
- struct {
- u32 rsvd0[2];
- u32 rsvd1 : 31;
- u32 ifoe_o : 1; /* <o bit of ifoe */
- u32 rsvd2;
- } bs;
- u32 value[4];
- } forth_16B; /* <fourth 16B */
-};
-
-/* standard 128B WQE structure */
-struct cqm_linkwqe_128B {
- union cqm_linkwqe_first64B first64B; /* <first 64B of standard 128B WQE */
- struct cqm_linkwqe_second64B second64B; /* <back 64B of standard 128B WQE */
-};
-
-/* AEQ type definition */
-enum cqm_aeq_event_type {
- CQM_AEQ_BASE_T_FC = 48, /* <FC consists of 8 events:48~55 */
- CQM_AEQ_MAX_T_FC = 56
-};
-
-/* service registration template */
-struct service_register_template {
- u32 service_type; /* <service type */
- u32 srq_ctx_size; /* <SRQ context size */
- u32 scq_ctx_size; /* <SCQ context size */
- void *service_handle;
- u8 (*aeq_level_callback)(void *service_handle, u8 event_type, u8 *val);
- void (*aeq_callback)(void *service_handle, u8 event_type, u8 *val);
-};
-
-/* object operation type definition */
-enum cqm_object_type {
- CQM_OBJECT_ROOT_CTX = 0, /* <0:root context, which is compatible with root CTX management */
- CQM_OBJECT_SERVICE_CTX, /* <1:QPC, connection management object */
- CQM_OBJECT_NONRDMA_EMBEDDED_RQ = 10, /* <10:RQ of non-RDMA services, managed by LINKWQE */
- CQM_OBJECT_NONRDMA_EMBEDDED_SQ, /* <11:SQ of non-RDMA services, managed by LINKWQE */
- /* <12:SRQ of non-RDMA services, managed by MTT, but the CQM needs to apply for MTT. */
- CQM_OBJECT_NONRDMA_SRQ,
- /* <13:Embedded CQ for non-RDMA services, managed by LINKWQE */
- CQM_OBJECT_NONRDMA_EMBEDDED_CQ,
- CQM_OBJECT_NONRDMA_SCQ, /* <14:SCQ of non-RDMA services, managed by LINKWQE */
-};
-
-/* return value of the failure to apply for the BITMAP table */
-#define CQM_INDEX_INVALID (~(0U))
-
-/* doorbell mode selected by the current Q, hardware doorbell */
-#define CQM_HARDWARE_DOORBELL 1
-
-/* single-node structure of the CQM buffer */
-struct cqm_buf_list {
- void *va; /* <virtual address */
- dma_addr_t pa; /* <physical address */
- u32 refcount; /* <reference count of the buf, which is used for internal buf management. */
-};
-
-/* common management structure of the CQM buffer */
-struct cqm_buf {
- struct cqm_buf_list *buf_list; /* <buffer list */
- /* <map the discrete buffer list to a group of consecutive addresses */
- struct cqm_buf_list direct;
- u32 page_number; /* <buf_number in quantity of page_number=2^n */
- u32 buf_number; /* <number of buf_list nodes */
- u32 buf_size; /* <PAGE_SIZE in quantity of buf_size=2^n */
-};
-
-/* CQM object structure, which can be considered
- * as the base class abstracted from all queues/CTX.
- */
-struct cqm_object {
- u32 service_type; /* <service type */
- u32 object_type; /* <object type, such as context, queue, mpt, and mtt, etc */
- u32 object_size; /* <object Size, for queue/CTX/MPT, the unit is Byte*/
- atomic_t refcount; /* <reference counting */
- struct completion free; /* <release completed quantity */
- void *cqm_handle; /* <cqm_handle */
-};
-
-/* structure of the QPC and MPT objects of the CQM */
-struct cqm_qpc_mpt {
- struct cqm_object object;
- u32 xid;
- dma_addr_t paddr; /* <physical address of the QPC/MTT memory */
- void *priv; /* <private information about the object of the service driver. */
- u8 *vaddr; /* <virtual address of the QPC/MTT memory */
-};
-
-/* queue header structure */
-struct cqm_queue_header {
- u64 doorbell_record; /* <SQ/RQ DB content */
- u64 ci_record; /* <CQ DB content */
- u64 rsv1;
- u64 rsv2;
-};
-
-/* queue management structure: for queues of non-RDMA services, embedded queues
- * are managed by LinkWQE, SRQ and SCQ are managed by MTT, but MTT needs to be
- * applied by CQM; the queue of the RDMA service is managed by the MTT.
- */
-struct cqm_queue {
- struct cqm_object object; /* <object base class */
- /* <The embedded queue and QP do not have indexes, but the SRQ and SCQ do. */
- u32 index;
- /* <private information about the object of the service driver */
- void *priv;
- /* <doorbell type selected by the current queue. HW/SW are used for the roce QP. */
- u32 current_q_doorbell;
- u32 current_q_room;
- struct cqm_buf q_room_buf_1; /* <nonrdma:only q_room_buf_1 can be set to q_room_buf */
- struct cqm_buf q_room_buf_2; /* <The CQ of RDMA reallocates the size of the queue room. */
- struct cqm_queue_header *q_header_vaddr; /* <queue header virtual address */
- dma_addr_t q_header_paddr; /* <physical address of the queue header */
- u8 *q_ctx_vaddr; /* <CTX virtual addresses of SRQ and SCQ */
- dma_addr_t q_ctx_paddr; /* <CTX physical addresses of SRQ and SCQ */
- u32 valid_wqe_num; /* <number of valid WQEs that are successfully created */
- u8 *tail_container; /* <tail pointer of the SRQ container */
- u8 *head_container; /* <head pointer of SRQ container */
- /* <Determine the connection mode during queue creation, such as link and ring. */
- u8 queue_link_mode;
-};
-
-struct cqm_qpc_layout_table_node {
- u32 type;
- u32 size;
- u32 offset;
- struct cqm_object *object;
-};
-
-struct cqm_qpc_mpt_info {
- struct cqm_qpc_mpt common;
- /* Different service has different QPC.
- * The large QPC/mpt will occupy some continuous indexes in bitmap.
- */
- u32 index_count;
- struct cqm_qpc_layout_table_node qpc_layout_table[CQM_QPC_LAYOUT_TABLE_SIZE];
-};
-
-struct cqm_nonrdma_qinfo {
- struct cqm_queue common;
- u32 wqe_size;
- /* Number of WQEs in each buffer (excluding link WQEs)
- * For SRQ, the value is the number of WQEs contained in a container.
- */
- u32 wqe_per_buf;
- u32 q_ctx_size;
- /* When different services use CTXs of different sizes,
- * a large CTX occupies multiple consecutive indexes in the bitmap.
- */
- u32 index_count;
- /* add for srq */
- u32 container_size;
-};
-
-/* sending command structure */
-struct cqm_cmd_buf {
- void *buf;
- dma_addr_t dma;
- u16 size;
-};
-
-struct cqm_queue *cqm3_object_fc_srq_create(void *ex_handle, u32 service_type,
- enum cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv);
-struct cqm_qpc_mpt *cqm3_object_qpc_mpt_create(void *ex_handle, u32 service_type,
- enum cqm_object_type object_type,
- u32 object_size, void *object_priv,
- u32 index);
-struct cqm_queue *cqm3_object_nonrdma_queue_create(void *ex_handle, u32 service_type,
- enum cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv);
-void cqm3_object_delete(struct cqm_object *object);
-struct cqm_object *cqm3_object_get(void *ex_handle, enum cqm_object_type object_type,
- u32 index, bool bh);
-void cqm3_object_put(struct cqm_object *object);
-
-s32 cqm3_ring_hardware_db_fc(void *ex_handle, u32 service_type, u8 db_count,
- u8 pagenum, u64 db);
-s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count, void *direct_wqe);
-s32 cqm_ring_direct_wqe_db_fc(void *ex_handle, u32 service_type, void *direct_wqe);
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif
-#endif /* __cplusplus */
-
-#endif /* SPFC_CQM_OBJECT_H */
diff --git a/drivers/scsi/spfc/hw/spfc_hba.c b/drivers/scsi/spfc/hw/spfc_hba.c
deleted file mode 100644
index b033dcb78bb3..000000000000
--- a/drivers/scsi/spfc/hw/spfc_hba.c
+++ /dev/null
@@ -1,1751 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "spfc_hba.h"
-#include "spfc_module.h"
-#include "spfc_utils.h"
-#include "spfc_chipitf.h"
-#include "spfc_io.h"
-#include "spfc_lld.h"
-#include "sphw_hw.h"
-#include "spfc_cqm_main.h"
-
-struct spfc_hba_info *spfc_hba[SPFC_HBA_PORT_MAX_NUM];
-ulong probe_bit_map[SPFC_MAX_PROBE_PORT_NUM / SPFC_PORT_NUM_PER_TABLE];
-static ulong card_num_bit_map[SPFC_MAX_PROBE_PORT_NUM / SPFC_PORT_NUM_PER_TABLE];
-static struct spfc_card_num_manage card_num_manage[SPFC_MAX_CARD_NUM];
-spinlock_t probe_spin_lock;
-u32 max_parent_qpc_num;
-
-static int spfc_probe(struct spfc_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
-static void spfc_remove(struct spfc_lld_dev *lld_dev, void *uld_dev);
-static u32 spfc_initial_chip_access(struct spfc_hba_info *hba);
-static void spfc_release_chip_access(struct spfc_hba_info *hba);
-static u32 spfc_port_config_set(void *hba, enum unf_port_config_set_op opcode, void *var_in);
-static u32 spfc_port_config_get(void *hba, enum unf_port_cfg_get_op opcode, void *para_out);
-static u32 spfc_port_update_wwn(void *hba, void *para_in);
-static u32 spfc_get_chip_info(struct spfc_hba_info *hba);
-static u32 spfc_delete_scqc_via_cmdq_sync(struct spfc_hba_info *hba, u32 scqn);
-static u32 spfc_delete_srqc_via_cmdq_sync(struct spfc_hba_info *hba, u64 sqrc_gpa);
-static u32 spfc_get_hba_pcie_link_state(void *hba, void *link_state);
-static u32 spfc_port_check_fw_ready(struct spfc_hba_info *hba);
-static u32 spfc_set_port_state(void *hba, void *para_in);
-
-struct spfc_uld_info fc_uld_info = {
- .probe = spfc_probe,
- .remove = spfc_remove,
- .resume = NULL,
- .event = NULL,
- .suspend = NULL,
- .ioctl = NULL
-};
-
-struct service_register_template service_cqm_temp = {
- .service_type = SERVICE_T_FC,
- .scq_ctx_size = SPFC_SCQ_CNTX_SIZE,
- .srq_ctx_size = SPFC_SRQ_CNTX_SIZE, /* srq, scq context_size configuration */
- .aeq_callback = spfc_process_aeqe, /* the API of asynchronous event from TILE to driver */
-};
-
-/* default configuration: auto speed, auto topology, INI+TGT */
-static struct unf_cfg_item spfc_port_cfg_parm[] = {
- {"port_id", 0, 0x110000, 0xffffff},
- /* port mode:INI(0x20), TGT(0x10), BOTH(0x30) */
- {"port_mode", 0, 0x20, 0xff},
- /* port topology, 0x3: loop , 0xc:p2p, 0xf:auto, 0x10:vn2vn */
- {"port_topology", 0, 0xf, 0x20},
- {"port_alpa", 0, 0xdead, 0xffff}, /* alpa address of port */
- /* queue depth of originator registered to SCSI midlayer */
- {"max_queue_depth", 0, 512, 512},
- {"sest_num", 0, 2048, 2048},
- {"max_login", 0, 2048, 2048},
- /* nodename from 32 bit to 64 bit */
- {"node_name_high", 0, 0x1000286e, 0xffffffff},
- /* nodename from 0 bit to 31 bit */
- {"node_name_low", 0, 0xd4bbf12f, 0xffffffff},
- /* portname from 32 bit to 64 bit */
- {"port_name_high", 0, 0x2000286e, 0xffffffff},
- /* portname from 0 bit to 31 bit */
- {"port_name_low", 0, 0xd4bbf12f, 0xffffffff},
- /* port speed 0:auto 1:1Gbps 2:2Gbps 3:4Gbps 4:8Gbps 5:16Gbps */
- {"port_speed", 0, 0, 32},
- {"interrupt_delay", 0, 0, 100}, /* unit: us */
- {"tape_support", 0, 0, 1}, /* tape support */
- {"End", 0, 0, 0}
-};
-
-struct unf_low_level_functioon_op spfc_func_op = {
- .low_level_type = UNF_SPFC_FC,
- .name = "SPFC",
- .xchg_mgr_type = UNF_LOW_LEVEL_MGR_TYPE_PASSTIVE,
- .abts_xchg = UNF_NO_EXTRA_ABTS_XCHG,
- .passthrough_flag = UNF_LOW_LEVEL_PASS_THROUGH_PORT_LOGIN,
- .support_max_npiv_num = UNF_SPFC_MAXNPIV_NUM,
- .support_max_ssq_num = SPFC_MAX_SSQ_NUM - 1,
- .chip_id = 0,
- .support_max_speed = UNF_PORT_SPEED_32_G,
- .support_max_rport = UNF_SPFC_MAXRPORT_NUM,
- .sfp_type = UNF_PORT_TYPE_FC_SFP,
- .rport_release_type = UNF_LOW_LEVEL_RELEASE_RPORT_ASYNC,
- .sirt_page_mode = UNF_LOW_LEVEL_SIRT_PAGE_MODE_XCHG,
-
- /* Link service */
- .service_op = {
- .unf_ls_gs_send = spfc_send_ls_gs_cmnd,
- .unf_bls_send = spfc_send_bls_cmnd,
- .unf_cmnd_send = spfc_send_scsi_cmnd,
- .unf_release_rport_res = spfc_free_parent_resource,
- .unf_flush_ini_resp_que = spfc_flush_ini_resp_queue,
- .unf_alloc_rport_res = spfc_alloc_parent_resource,
- .ll_release_xid = spfc_free_xid,
- },
-
- /* Port Mgr */
- .port_mgr_op = {
- .ll_port_config_set = spfc_port_config_set,
- .ll_port_config_get = spfc_port_config_get,
- }
-};
-
-struct spfc_port_cfg_op {
- enum unf_port_config_set_op opcode;
- u32 (*spfc_operation)(void *hba, void *para);
-};
-
-struct spfc_port_cfg_op spfc_config_set_op[] = {
- {UNF_PORT_CFG_SET_PORT_SWITCH, spfc_sfp_switch},
- {UNF_PORT_CFG_UPDATE_WWN, spfc_port_update_wwn},
- {UNF_PORT_CFG_SET_PORT_STATE, spfc_set_port_state},
- {UNF_PORT_CFG_UPDATE_FABRIC_PARAM, spfc_update_fabric_param},
- {UNF_PORT_CFG_UPDATE_PLOGI_PARAM, spfc_update_port_param},
- {UNF_PORT_CFG_SET_BUTT, NULL}
-};
-
-struct spfc_port_cfg_get_op {
- enum unf_port_cfg_get_op opcode;
- u32 (*spfc_operation)(void *hba, void *para);
-};
-
-struct spfc_port_cfg_get_op spfc_config_get_op[] = {
- {UNF_PORT_CFG_GET_TOPO_ACT, spfc_get_topo_act},
- {UNF_PORT_CFG_GET_LOOP_MAP, spfc_get_loop_map},
- {UNF_PORT_CFG_GET_WORKBALE_BBCREDIT, spfc_get_workable_bb_credit},
- {UNF_PORT_CFG_GET_WORKBALE_BBSCN, spfc_get_workable_bb_scn},
- {UNF_PORT_CFG_GET_LOOP_ALPA, spfc_get_loop_alpa},
- {UNF_PORT_CFG_GET_MAC_ADDR, spfc_get_chip_msg},
- {UNF_PORT_CFG_GET_PCIE_LINK_STATE, spfc_get_hba_pcie_link_state},
- {UNF_PORT_CFG_GET_BUTT, NULL},
-};
-
-static u32 spfc_set_port_state(void *hba, void *para_in)
-{
- u32 ret = UNF_RETURN_ERROR;
- enum unf_port_config_state port_state = UNF_PORT_CONFIG_STATE_START;
-
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(para_in, UNF_RETURN_ERROR);
-
- port_state = *((enum unf_port_config_state *)para_in);
- switch (port_state) {
- case UNF_PORT_CONFIG_STATE_RESET:
- ret = (u32)spfc_port_reset(hba);
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Cannot set port_state(0x%x)", port_state);
- break;
- }
-
- return ret;
-
-}
-
-static u32 spfc_port_update_wwn(void *hba, void *para_in)
-{
- struct unf_port_wwn *port_wwn = NULL;
- struct spfc_hba_info *spfc_hba = hba;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(para_in, UNF_RETURN_ERROR);
-
- port_wwn = (struct unf_port_wwn *)para_in;
-
- /* Update it to the hba in the later */
- *(u64 *)spfc_hba->sys_node_name = port_wwn->sys_node_name;
- *(u64 *)spfc_hba->sys_port_name = port_wwn->sys_port_wwn;
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_INFO,
- "[info]Port(0x%x) updates WWNN(0x%llx) WWPN(0x%llx)",
- spfc_hba->port_cfg.port_id,
- *(u64 *)spfc_hba->sys_node_name,
- *(u64 *)spfc_hba->sys_port_name);
-
- return RETURN_OK;
-}
-
-static u32 spfc_port_config_set(void *hba, enum unf_port_config_set_op opcode,
- void *var_in)
-{
- u32 op_idx = 0;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- for (op_idx = 0; op_idx < sizeof(spfc_config_set_op) /
- sizeof(struct spfc_port_cfg_op); op_idx++) {
- if (opcode == spfc_config_set_op[op_idx].opcode) {
- if (!spfc_config_set_op[op_idx].spfc_operation) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Null operation for configuration, opcode(0x%x), operation ID(0x%x)",
- opcode, op_idx);
-
- return UNF_RETURN_ERROR;
- }
- return spfc_config_set_op[op_idx].spfc_operation(hba, var_in);
- }
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]No operation code for configuration, opcode(0x%x)",
- opcode);
-
- return UNF_RETURN_ERROR;
-}
-
-static u32 spfc_port_config_get(void *hba, enum unf_port_cfg_get_op opcode,
- void *para_out)
-{
- u32 op_idx = 0;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- for (op_idx = 0; op_idx < sizeof(spfc_config_get_op) /
- sizeof(struct spfc_port_cfg_get_op); op_idx++) {
- if (opcode == spfc_config_get_op[op_idx].opcode) {
- if (!spfc_config_get_op[op_idx].spfc_operation) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Null operation to get configuration, opcode(0x%x), operation ID(0x%x)",
- opcode, op_idx);
- return UNF_RETURN_ERROR;
- }
- return spfc_config_get_op[op_idx].spfc_operation(hba, para_out);
- }
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]No operation to get configuration, opcode(0x%x)",
- opcode);
-
- return UNF_RETURN_ERROR;
-}
-
-static u32 spfc_fc_mode_check(void *hw_dev_handle)
-{
- FC_CHECK_RETURN_VALUE(hw_dev_handle, UNF_RETURN_ERROR);
-
- if (!sphw_support_fc(hw_dev_handle, NULL)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Work mode is error");
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Selected work mode is FC");
-
- return RETURN_OK;
-}
-
-static u32 spfc_check_port_cfg(const struct spfc_port_cfg *port_cfg)
-{
- bool topo_condition = false;
- bool speed_condition = false;
- /* About Work Topology */
- topo_condition = ((port_cfg->port_topology != UNF_TOP_LOOP_MASK) &&
- (port_cfg->port_topology != UNF_TOP_P2P_MASK) &&
- (port_cfg->port_topology != UNF_TOP_AUTO_MASK));
- if (topo_condition) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Configured port topology(0x%x) is incorrect",
- port_cfg->port_topology);
-
- return UNF_RETURN_ERROR;
- }
-
- /* About Work Mode */
- if (port_cfg->port_mode != UNF_PORT_MODE_INI) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Configured port mode(0x%x) is incorrect",
- port_cfg->port_mode);
-
- return UNF_RETURN_ERROR;
- }
-
- /* About Work Speed */
- speed_condition = ((port_cfg->port_speed != UNF_PORT_SPEED_AUTO) &&
- (port_cfg->port_speed != UNF_PORT_SPEED_2_G) &&
- (port_cfg->port_speed != UNF_PORT_SPEED_4_G) &&
- (port_cfg->port_speed != UNF_PORT_SPEED_8_G) &&
- (port_cfg->port_speed != UNF_PORT_SPEED_16_G) &&
- (port_cfg->port_speed != UNF_PORT_SPEED_32_G));
- if (speed_condition) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Configured port speed(0x%x) is incorrect",
- port_cfg->port_speed);
-
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Check port configuration OK");
-
- return RETURN_OK;
-}
-
-static u32 spfc_get_port_cfg(struct spfc_hba_info *hba,
- struct spfc_chip_info *chip_info, u8 card_num)
-{
-#define UNF_CONFIG_ITEM_LEN 15
- /* Maximum length of a configuration item name, including the end
- * character
- */
-#define UNF_MAX_ITEM_NAME_LEN (32 + 1)
-
- /* Get and check parameters */
- char cfg_item[UNF_MAX_ITEM_NAME_LEN];
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_hba_info *spfc_hba = hba;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- memset((void *)cfg_item, 0, sizeof(cfg_item));
-
- spfc_hba->card_info.func_num = (sphw_global_func_id(hba->dev_handle)) & UNF_FUN_ID_MASK;
- spfc_hba->card_info.card_num = card_num;
-
- /* The range of PF of FC server is from PF1 to PF2 */
- snprintf(cfg_item, UNF_MAX_ITEM_NAME_LEN, "spfc_cfg_%1u", (spfc_hba->card_info.func_num));
-
- cfg_item[UNF_MAX_ITEM_NAME_LEN - 1] = 0;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Get port configuration: %s", cfg_item);
-
- /* Get configuration parameters from file */
- UNF_LOWLEVEL_GET_CFG_PARMS(ret, cfg_item, &spfc_port_cfg_parm[ARRAY_INDEX_0],
- (u32 *)(void *)(&spfc_hba->port_cfg),
- sizeof(spfc_port_cfg_parm) / sizeof(struct unf_cfg_item));
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) can't get configuration",
- spfc_hba->port_cfg.port_id);
-
- return ret;
- }
-
- if (max_parent_qpc_num <= SPFC_MAX_PARENT_QPC_NUM) {
- spfc_hba->port_cfg.sest_num = UNF_SPFC_MAXRPORT_NUM;
- spfc_hba->port_cfg.max_login = UNF_SPFC_MAXRPORT_NUM;
- }
-
- spfc_hba->port_cfg.port_id &= SPFC_PORT_ID_MASK;
- spfc_hba->port_cfg.port_id |= spfc_hba->card_info.card_num << UNF_SHIFT_8;
- spfc_hba->port_cfg.port_id |= spfc_hba->card_info.func_num;
- spfc_hba->port_cfg.tape_support = (u32)chip_info->tape_support;
-
- /* Parameters check */
- ret = spfc_check_port_cfg(&spfc_hba->port_cfg);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) check configuration incorrect",
- spfc_hba->port_cfg.port_id);
-
- return ret;
- }
-
- /* Set configuration which is got from file */
- spfc_hba->port_speed_cfg = spfc_hba->port_cfg.port_speed;
- spfc_hba->port_topo_cfg = spfc_hba->port_cfg.port_topology;
- spfc_hba->port_mode = (enum unf_port_mode)(spfc_hba->port_cfg.port_mode);
-
- return ret;
-}
-
-void spfc_generate_sys_wwn(struct spfc_hba_info *hba)
-{
- FC_CHECK_RETURN_VOID(hba);
-
- *(u64 *)hba->sys_node_name = (((u64)hba->port_cfg.node_name_hi << UNF_SHIFT_32) |
- (hba->port_cfg.node_name_lo));
- *(u64 *)hba->sys_port_name = (((u64)hba->port_cfg.port_name_hi << UNF_SHIFT_32) |
- (hba->port_cfg.port_name_lo));
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]NodeName = 0x%llx, PortName = 0x%llx",
- *(u64 *)hba->sys_node_name, *(u64 *)hba->sys_port_name);
-}
-
-static u32 spfc_create_queues(struct spfc_hba_info *hba)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- SPFC_FUNCTION_ENTER;
-
- /* Initialize shared resources of SCQ and SRQ in parent queue */
- ret = spfc_create_common_share_queues(hba);
- if (ret != RETURN_OK)
- goto out_create_common_queue_fail;
-
- /* Initialize parent queue manager resources */
- ret = spfc_alloc_parent_queue_mgr(hba);
- if (ret != RETURN_OK)
- goto out_free_share_queue_resource;
-
- /* Initialize shared WQE page pool in parent SQ */
- ret = spfc_alloc_parent_sq_wqe_page_pool(hba);
- if (ret != RETURN_OK)
- goto out_free_parent_queue_resource;
-
- ret = spfc_create_ssq(hba);
- if (ret != RETURN_OK)
- goto out_free_parent_wqe_page_pool;
-
- /*
- * Notice: the configuration of SQ and QID(default_sqid)
- * must be the same in FC
- */
- hba->next_clear_sq = 0;
- hba->default_sqid = SPFC_QID_SQ;
-
- SPFC_FUNCTION_RETURN;
- return RETURN_OK;
-out_free_parent_wqe_page_pool:
- spfc_free_parent_sq_wqe_page_pool(hba);
-
-out_free_parent_queue_resource:
- spfc_free_parent_queue_mgr(hba);
-
-out_free_share_queue_resource:
- spfc_flush_scq_ctx(hba);
- spfc_flush_srq_ctx(hba);
- spfc_destroy_common_share_queues(hba);
-
-out_create_common_queue_fail:
- SPFC_FUNCTION_RETURN;
-
- return ret;
-}
-
-static u32 spfc_alloc_dma_buffers(struct spfc_hba_info *hba)
-{
- struct pci_dev *pci_dev = NULL;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- pci_dev = hba->pci_dev;
- FC_CHECK_RETURN_VALUE(pci_dev, UNF_RETURN_ERROR);
-
- hba->sfp_buf = dma_alloc_coherent(&hba->pci_dev->dev,
- sizeof(struct unf_sfp_err_rome_info),
- &hba->sfp_dma_addr, GFP_KERNEL);
- if (!hba->sfp_buf) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) can't allocate SFP DMA buffer",
- hba->port_cfg.port_id);
-
- return UNF_RETURN_ERROR;
- }
- memset(hba->sfp_buf, 0, sizeof(struct unf_sfp_err_rome_info));
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) allocate sfp buffer(0x%p 0x%llx)",
- hba->port_cfg.port_id, hba->sfp_buf,
- (u64)hba->sfp_dma_addr);
-
- return RETURN_OK;
-}
-
-static void spfc_free_dma_buffers(struct spfc_hba_info *hba)
-{
- struct pci_dev *pci_dev = NULL;
-
- FC_CHECK_RETURN_VOID(hba);
- pci_dev = hba->pci_dev;
- FC_CHECK_RETURN_VOID(pci_dev);
-
- if (hba->sfp_buf) {
- dma_free_coherent(&pci_dev->dev, sizeof(struct unf_sfp_err_rome_info),
- hba->sfp_buf, hba->sfp_dma_addr);
-
- hba->sfp_buf = NULL;
- hba->sfp_dma_addr = 0;
- }
-}
-
-static void spfc_destroy_queues(struct spfc_hba_info *hba)
-{
- /* Free ssq */
- spfc_free_ssq(hba, SPFC_MAX_SSQ_NUM);
-
- /* Free parent queue resource */
- spfc_free_parent_queues(hba);
-
- /* Free queue manager resource */
- spfc_free_parent_queue_mgr(hba);
-
- /* Free linked List SQ and WQE page pool resource */
- spfc_free_parent_sq_wqe_page_pool(hba);
-
- /* Free shared SRQ and SCQ queue resource */
- spfc_destroy_common_share_queues(hba);
-}
-
-static u32 spfc_alloc_default_session(struct spfc_hba_info *hba)
-{
- struct unf_port_info rport_info = {0};
- u32 wait_sq_cnt = 0;
-
- rport_info.nport_id = 0xffffff;
- rport_info.rport_index = SPFC_DEFAULT_RPORT_INDEX;
- rport_info.local_nport_id = 0xffffff;
- rport_info.port_name = 0;
- rport_info.cs_ctrl = 0x81;
-
- if (spfc_alloc_parent_resource((void *)hba, &rport_info) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Alloc default session resource failed");
- goto failed;
- }
-
- for (;;) {
- if (hba->default_sq_info.default_sq_flag == 1)
- break;
-
- msleep(SPFC_WAIT_SESS_ENABLE_ONE_TIME_MS);
- wait_sq_cnt++;
- if (wait_sq_cnt >= SPFC_MAX_WAIT_LOOP_TIMES) {
- hba->default_sq_info.default_sq_flag = 0xF;
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Wait Default Session enable timeout");
- goto failed;
- }
- }
-
- if (spfc_mbx_config_default_session(hba, 1) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Notify up config default session table fail");
- goto failed;
- }
-
- return RETURN_OK;
-
-failed:
- spfc_sess_resource_free_sync((void *)hba, &rport_info);
- return UNF_RETURN_ERROR;
-}
-
-static u32 spfc_init_host_res(struct spfc_hba_info *hba)
-{
- u32 ret = RETURN_OK;
- struct spfc_hba_info *spfc_hba = hba;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
-
- SPFC_FUNCTION_ENTER;
-
- /* Initialize spin lock */
- spin_lock_init(&spfc_hba->hba_lock);
- spin_lock_init(&spfc_hba->flush_state_lock);
- spin_lock_init(&spfc_hba->clear_state_lock);
- spin_lock_init(&spfc_hba->spin_lock);
- spin_lock_init(&spfc_hba->srq_delay_info.srq_lock);
- /* Initialize init_completion */
- init_completion(&spfc_hba->hba_init_complete);
- init_completion(&spfc_hba->mbox_complete);
- init_completion(&spfc_hba->vpf_complete);
- init_completion(&spfc_hba->fcfi_complete);
- init_completion(&spfc_hba->get_sfp_complete);
- /* Step-1: initialize the communication channel between driver and uP */
- ret = spfc_initial_chip_access(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't initialize chip access",
- spfc_hba->port_cfg.port_id);
-
- goto out_unmap_memory;
- }
- /* Step-2: get chip configuration information before creating
- * queue resources
- */
- ret = spfc_get_chip_info(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't get chip information",
- spfc_hba->port_cfg.port_id);
-
- goto out_unmap_memory;
- }
-
- /* Step-3: create queue resources */
- ret = spfc_create_queues(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't create queues",
- spfc_hba->port_cfg.port_id);
-
- goto out_release_chip_access;
- }
- /* Allocate DMA buffer (SFP information) */
- ret = spfc_alloc_dma_buffers(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't allocate DMA buffers",
- spfc_hba->port_cfg.port_id);
-
- goto out_destroy_queues;
- }
- /* Initialize status parameters */
- spfc_hba->active_port_speed = UNF_PORT_SPEED_UNKNOWN;
- spfc_hba->active_topo = UNF_ACT_TOP_UNKNOWN;
- spfc_hba->sfp_on = false;
- spfc_hba->port_loop_role = UNF_LOOP_ROLE_MASTER_OR_SLAVE;
- spfc_hba->phy_link = UNF_PORT_LINK_DOWN;
- spfc_hba->queue_set_stage = SPFC_QUEUE_SET_STAGE_INIT;
-
- /* Initialize parameters referring to the lowlevel */
- spfc_hba->remote_rttov_tag = 0;
- spfc_hba->port_bb_scn_cfg = SPFC_LOWLEVEL_DEFAULT_BB_SCN;
-
- /* Initialize timer, and the unit of E_D_TOV is ms */
- spfc_hba->remote_edtov_tag = 0;
- spfc_hba->remote_bb_credit = 0;
- spfc_hba->compared_bb_scn = 0;
- spfc_hba->compared_edtov_val = UNF_DEFAULT_EDTOV;
- spfc_hba->compared_ratov_val = UNF_DEFAULT_RATOV;
- spfc_hba->removing = false;
- spfc_hba->dev_present = true;
-
- /* Initialize parameters about cos */
- spfc_hba->cos_bitmap = cos_bit_map;
- memset(spfc_hba->cos_rport_cnt, 0, SPFC_MAX_COS_NUM * sizeof(atomic_t));
-
- /* Mailbox access completion */
- complete(&spfc_hba->mbox_complete);
-
- ret = spfc_alloc_default_session(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't allocate Default Session",
- spfc_hba->port_cfg.port_id);
-
- goto out_destroy_dma_buff;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]SPFC port(0x%x) initialize host resources succeeded",
- spfc_hba->port_cfg.port_id);
-
- return ret;
-
-out_destroy_dma_buff:
- spfc_free_dma_buffers(spfc_hba);
-out_destroy_queues:
- spfc_flush_scq_ctx(spfc_hba);
- spfc_flush_srq_ctx(spfc_hba);
- spfc_destroy_queues(spfc_hba);
-
-out_release_chip_access:
- spfc_release_chip_access(spfc_hba);
-
-out_unmap_memory:
- return ret;
-}
-
-static u32 spfc_get_chip_info(struct spfc_hba_info *hba)
-{
- u32 ret = RETURN_OK;
- u32 exi_count = 0;
- u32 exi_base = 0;
- u32 exi_stride = 0;
- u32 fun_idx = 0;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- hba->vpid_start = hba->service_cap.dev_fc_cap.vp_id_start;
- hba->vpid_end = hba->service_cap.dev_fc_cap.vp_id_end;
- fun_idx = sphw_global_func_id(hba->dev_handle);
-
- exi_count = (max_parent_qpc_num <= SPFC_MAX_PARENT_QPC_NUM) ?
- exit_count >> UNF_SHIFT_1 : exit_count;
- exi_stride = (max_parent_qpc_num <= SPFC_MAX_PARENT_QPC_NUM) ?
- exit_stride >> UNF_SHIFT_1 : exit_stride;
- exi_base = exit_base;
-
- exi_base += (fun_idx * exi_stride);
- hba->exi_base = SPFC_LSW(exi_base);
- hba->exi_count = SPFC_LSW(exi_count);
- hba->max_support_speed = max_speed;
- hba->port_index = SPFC_LSB(fun_idx);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) base information: PortIndex=0x%x, ExiBase=0x%x, ExiCount=0x%x, VpIdStart=0x%x, VpIdEnd=0x%x, MaxSpeed=0x%x, Speed=0x%x, Topo=0x%x",
- hba->port_cfg.port_id, hba->port_index, hba->exi_base,
- hba->exi_count, hba->vpid_start, hba->vpid_end,
- hba->max_support_speed, hba->port_speed_cfg, hba->port_topo_cfg);
-
- return ret;
-}
-
-static u32 spfc_initial_chip_access(struct spfc_hba_info *hba)
-{
- int ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- /* 1. Initialize cqm access related with scq, emb cq, aeq(ucode-->driver) */
- service_cqm_temp.service_handle = hba;
-
- ret = cqm3_service_register(hba->dev_handle, &service_cqm_temp);
- if (ret != CQM_SUCCESS)
- return UNF_RETURN_ERROR;
-
- /* 2. Initialize mailbox(driver-->up), aeq(up--->driver) access */
- ret = sphw_register_mgmt_msg_cb(hba->dev_handle, COMM_MOD_FC, hba,
- spfc_up_msg2driver_proc);
- if (ret != CQM_SUCCESS)
- goto out_unreg_cqm;
-
- return RETURN_OK;
-
-out_unreg_cqm:
- cqm3_service_unregister(hba->dev_handle, SERVICE_T_FC);
-
- return UNF_RETURN_ERROR;
-}
-
-static void spfc_release_chip_access(struct spfc_hba_info *hba)
-{
- FC_CHECK_RETURN_VOID(hba);
- FC_CHECK_RETURN_VOID(hba->dev_handle);
-
- sphw_unregister_mgmt_msg_cb(hba->dev_handle, COMM_MOD_FC);
-
- cqm3_service_unregister(hba->dev_handle, SERVICE_T_FC);
-}
-
-static void spfc_update_lport_config(struct spfc_hba_info *hba,
- struct unf_low_level_functioon_op *lowlevel_func)
-{
-#define SPFC_MULTI_CONF_NONSUPPORT 0
-
- struct unf_lport_cfg_item *lport_cfg = NULL;
-
- lport_cfg = &lowlevel_func->lport_cfg_items;
-
- if (hba->port_cfg.max_login < lowlevel_func->support_max_rport)
- lport_cfg->max_login = hba->port_cfg.max_login;
- else
- lport_cfg->max_login = lowlevel_func->support_max_rport;
-
- if (hba->port_cfg.sest_num >> UNF_SHIFT_1 < UNF_RESERVE_SFS_XCHG)
- lport_cfg->max_io = hba->port_cfg.sest_num;
- else
- lport_cfg->max_io = hba->port_cfg.sest_num - UNF_RESERVE_SFS_XCHG;
-
- lport_cfg->max_sfs_xchg = UNF_MAX_SFS_XCHG;
- lport_cfg->port_id = hba->port_cfg.port_id;
- lport_cfg->port_mode = hba->port_cfg.port_mode;
- lport_cfg->port_topology = hba->port_cfg.port_topology;
- lport_cfg->max_queue_depth = hba->port_cfg.max_queue_depth;
-
- lport_cfg->port_speed = hba->port_cfg.port_speed;
- lport_cfg->tape_support = hba->port_cfg.tape_support;
-
- lowlevel_func->sys_port_name = *(u64 *)hba->sys_port_name;
- lowlevel_func->sys_node_name = *(u64 *)hba->sys_node_name;
-
- /* Update chip information */
- lowlevel_func->dev = hba->pci_dev;
- lowlevel_func->chip_info.chip_work_mode = hba->work_mode;
- lowlevel_func->chip_info.chip_type = hba->chip_type;
- lowlevel_func->chip_info.disable_err_flag = 0;
- lowlevel_func->support_max_speed = hba->max_support_speed;
- lowlevel_func->support_min_speed = hba->min_support_speed;
-
- lowlevel_func->chip_id = 0;
-
- lowlevel_func->sfp_type = UNF_PORT_TYPE_FC_SFP;
-
- lowlevel_func->multi_conf_support = SPFC_MULTI_CONF_NONSUPPORT;
- lowlevel_func->support_max_hot_tag_range = hba->port_cfg.sest_num;
- lowlevel_func->update_fw_reset_active = UNF_PORT_UNGRADE_FW_RESET_INACTIVE;
- lowlevel_func->port_type = 0; /* DRV_PORT_ENTITY_TYPE_PHYSICAL */
-
- if ((lport_cfg->port_id & UNF_FIRST_LPORT_ID_MASK) == lport_cfg->port_id)
- lowlevel_func->support_upgrade_report = UNF_PORT_SUPPORT_UPGRADE_REPORT;
- else
- lowlevel_func->support_upgrade_report = UNF_PORT_UNSUPPORT_UPGRADE_REPORT;
-}
-
-static u32 spfc_create_lport(struct spfc_hba_info *hba)
-{
- void *lport = NULL;
- struct unf_low_level_functioon_op lowlevel_func;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- spfc_func_op.dev = hba->pci_dev;
- memcpy(&lowlevel_func, &spfc_func_op, sizeof(struct unf_low_level_functioon_op));
-
- /* Update port configuration table */
- spfc_update_lport_config(hba, &lowlevel_func);
-
- /* Apply for lport resources */
- UNF_LOWLEVEL_ALLOC_LPORT(lport, hba, &lowlevel_func);
- if (!lport) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) can't allocate Lport",
- hba->port_cfg.port_id);
-
- return UNF_RETURN_ERROR;
- }
- hba->lport = lport;
-
- return RETURN_OK;
-}
-
-void spfc_release_probe_index(u32 probe_index)
-{
- if (probe_index >= SPFC_MAX_PROBE_PORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Probe index(0x%x) is invalid", probe_index);
-
- return;
- }
-
- spin_lock(&probe_spin_lock);
- if (!test_bit((int)probe_index, (const ulong *)probe_bit_map)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Probe index(0x%x) is not probed",
- probe_index);
-
- spin_unlock(&probe_spin_lock);
-
- return;
- }
-
- clear_bit((int)probe_index, probe_bit_map);
- spin_unlock(&probe_spin_lock);
-}
-
-static void spfc_delete_default_session(struct spfc_hba_info *hba)
-{
- struct unf_port_info rport_info = {0};
-
- rport_info.nport_id = 0xffffff;
- rport_info.rport_index = SPFC_DEFAULT_RPORT_INDEX;
- rport_info.local_nport_id = 0xffffff;
- rport_info.port_name = 0;
- rport_info.cs_ctrl = 0x81;
-
- /* Need config table to up first, then delete default session */
- (void)spfc_mbx_config_default_session(hba, 0);
- spfc_sess_resource_free_sync((void *)hba, &rport_info);
-}
-
-static void spfc_release_host_res(struct spfc_hba_info *hba)
-{
- spfc_free_dma_buffers(hba);
-
- spfc_destroy_queues(hba);
-
- spfc_release_chip_access(hba);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) release low level resource done",
- hba->port_cfg.port_id);
-}
-
-static struct spfc_hba_info *spfc_init_hba(struct pci_dev *pci_dev,
- void *hw_dev_handle,
- struct spfc_chip_info *chip_info,
- u8 card_num)
-{
- u32 ret = RETURN_OK;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VALUE(pci_dev, NULL);
- FC_CHECK_RETURN_VALUE(hw_dev_handle, NULL);
-
- /* Allocate HBA */
- hba = kmalloc(sizeof(struct spfc_hba_info), GFP_ATOMIC);
- FC_CHECK_RETURN_VALUE(hba, NULL);
- memset(hba, 0, sizeof(struct spfc_hba_info));
-
- /* Heartbeat default */
- hba->heart_status = 1;
- /* Private data in pciDev */
- hba->pci_dev = pci_dev;
- hba->dev_handle = hw_dev_handle;
-
- /* Work mode */
- hba->work_mode = chip_info->work_mode;
- /* Create work queue */
- hba->work_queue = create_singlethread_workqueue("spfc");
- if (!hba->work_queue) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Spfc creat workqueue failed");
-
- goto out_free_hba;
- }
- /* Init delay work */
- INIT_DELAYED_WORK(&hba->srq_delay_info.del_work, spfc_rcvd_els_from_srq_timeout);
- INIT_WORK(&hba->els_srq_clear_work, spfc_wq_destroy_els_srq);
-
- /* Notice: Only use FC features */
- (void)sphw_support_fc(hw_dev_handle, &hba->service_cap);
- /* Check parent context available */
- if (hba->service_cap.dev_fc_cap.max_parent_qpc_num == 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]FC parent context is not allocated in this function");
-
- goto out_destroy_workqueue;
- }
- max_parent_qpc_num = hba->service_cap.dev_fc_cap.max_parent_qpc_num;
-
- /* Get port configuration */
- ret = spfc_get_port_cfg(hba, chip_info, card_num);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Can't get port configuration");
-
- goto out_destroy_workqueue;
- }
- /* Get WWN */
- spfc_generate_sys_wwn(hba);
-
- /* Initialize host resources */
- ret = spfc_init_host_res(hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't initialize host resource",
- hba->port_cfg.port_id);
-
- goto out_destroy_workqueue;
- }
- /* Local Port create */
- ret = spfc_create_lport(hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't create lport",
- hba->port_cfg.port_id);
- goto out_release_host_res;
- }
- complete(&hba->hba_init_complete);
-
- /* Print reference count */
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[info]Port(0x%x) probe succeeded. Memory reference is 0x%x",
- hba->port_cfg.port_id, atomic_read(&fc_mem_ref));
-
- return hba;
-
-out_release_host_res:
- spfc_delete_default_session(hba);
- spfc_flush_scq_ctx(hba);
- spfc_flush_srq_ctx(hba);
- spfc_release_host_res(hba);
-
-out_destroy_workqueue:
- flush_workqueue(hba->work_queue);
- destroy_workqueue(hba->work_queue);
- hba->work_queue = NULL;
-
-out_free_hba:
- kfree(hba);
-
- return NULL;
-}
-
-void spfc_get_total_probed_num(u32 *probe_cnt)
-{
- u32 i = 0;
- u32 cnt = 0;
-
- spin_lock(&probe_spin_lock);
- for (i = 0; i < SPFC_MAX_PROBE_PORT_NUM; i++) {
- if (test_bit((int)i, (const ulong *)probe_bit_map))
- cnt++;
- }
-
- *probe_cnt = cnt;
- spin_unlock(&probe_spin_lock);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Probed port total number is 0x%x", cnt);
-}
-
-u32 spfc_assign_card_num(struct spfc_lld_dev *lld_dev,
- struct spfc_chip_info *chip_info, u8 *card_num)
-{
- u8 i = 0;
- u64 card_index = 0;
-
- card_index = (!pci_is_root_bus(lld_dev->pdev->bus)) ?
- lld_dev->pdev->bus->parent->number : lld_dev->pdev->bus->number;
-
- spin_lock(&probe_spin_lock);
-
- for (i = 0; i < SPFC_MAX_CARD_NUM; i++) {
- if (test_bit((int)i, (const ulong *)card_num_bit_map)) {
- if (card_num_manage[i].card_number ==
- card_index && !card_num_manage[i].is_removing
- ) {
- card_num_manage[i].port_count++;
- *card_num = i;
- spin_unlock(&probe_spin_lock);
- return RETURN_OK;
- }
- }
- }
-
- for (i = 0; i < SPFC_MAX_CARD_NUM; i++) {
- if (!test_bit((int)i, (const ulong *)card_num_bit_map)) {
- card_num_manage[i].card_number = card_index;
- card_num_manage[i].port_count = 1;
- card_num_manage[i].is_removing = false;
-
- *card_num = i;
- set_bit(i, card_num_bit_map);
-
- spin_unlock(&probe_spin_lock);
-
- return RETURN_OK;
- }
- }
-
- spin_unlock(&probe_spin_lock);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Have probe more than 0x%x port, probe failed", i);
-
- return UNF_RETURN_ERROR;
-}
-
-static void spfc_dec_and_free_card_num(u8 card_num)
-{
- /* 2 ports per card */
- if (card_num >= SPFC_MAX_CARD_NUM) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Card number(0x%x) is invalid", card_num);
-
- return;
- }
-
- spin_lock(&probe_spin_lock);
-
- if (test_bit((int)card_num, (const ulong *)card_num_bit_map)) {
- card_num_manage[card_num].port_count--;
- card_num_manage[card_num].is_removing = true;
-
- if (card_num_manage[card_num].port_count == 0) {
- card_num_manage[card_num].card_number = 0;
- card_num_manage[card_num].is_removing = false;
- clear_bit((int)card_num, card_num_bit_map);
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Can not find card number(0x%x)", card_num);
- }
-
- spin_unlock(&probe_spin_lock);
-}
-
-u32 spfc_assign_probe_index(u32 *probe_index)
-{
- u32 i = 0;
-
- spin_lock(&probe_spin_lock);
- for (i = 0; i < SPFC_MAX_PROBE_PORT_NUM; i++) {
- if (!test_bit((int)i, (const ulong *)probe_bit_map)) {
- *probe_index = i;
- set_bit(i, probe_bit_map);
-
- spin_unlock(&probe_spin_lock);
-
- return RETURN_OK;
- }
- }
- spin_unlock(&probe_spin_lock);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Have probe more than 0x%x port, probe failed", i);
-
- return UNF_RETURN_ERROR;
-}
-
-u32 spfc_get_probe_index_by_port_id(u32 port_id, u32 *probe_index)
-{
- u32 total_probe_num = 0;
- u32 i = 0;
- u32 probe_cnt = 0;
-
- spfc_get_total_probed_num(&total_probe_num);
-
- for (i = 0; i < SPFC_MAX_PROBE_PORT_NUM; i++) {
- if (!spfc_hba[i])
- continue;
-
- if (total_probe_num == probe_cnt)
- break;
-
- if (port_id == spfc_hba[i]->port_cfg.port_id) {
- *probe_index = spfc_hba[i]->probe_index;
-
- return RETURN_OK;
- }
-
- probe_cnt++;
- }
-
- return UNF_RETURN_ERROR;
-}
-
-static int spfc_probe(struct spfc_lld_dev *lld_dev, void **uld_dev,
- char *uld_dev_name)
-{
- struct pci_dev *pci_dev = NULL;
- struct spfc_hba_info *hba = NULL;
- u32 ret = UNF_RETURN_ERROR;
- const u8 work_mode = SPFC_SMARTIO_WORK_MODE_FC;
- u32 probe_index = 0;
- u32 probe_total_num = 0;
- u8 card_num = INVALID_VALUE8;
- struct spfc_chip_info chip_info;
-
- FC_CHECK_RETURN_VALUE(lld_dev, UNF_RETURN_ERROR_S32);
- FC_CHECK_RETURN_VALUE(lld_dev->hwdev, UNF_RETURN_ERROR_S32);
- FC_CHECK_RETURN_VALUE(lld_dev->pdev, UNF_RETURN_ERROR_S32);
- FC_CHECK_RETURN_VALUE(uld_dev, UNF_RETURN_ERROR_S32);
- FC_CHECK_RETURN_VALUE(uld_dev_name, UNF_RETURN_ERROR_S32);
-
- pci_dev = lld_dev->pdev;
- memset(&chip_info, 0, sizeof(struct spfc_chip_info));
- /* 1. Get & check Total_Probed_number */
- spfc_get_total_probed_num(&probe_total_num);
- if (probe_total_num >= allowed_probe_num) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Total probe num (0x%x) is larger than allowed number(0x%x)",
- probe_total_num, allowed_probe_num);
-
- return UNF_RETURN_ERROR_S32;
- }
- /* 2. Check device work mode */
- ret = spfc_fc_mode_check(lld_dev->hwdev);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR_S32;
-
- /* 3. Assign & Get new Probe index */
- ret = spfc_assign_probe_index(&probe_index);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]AssignProbeIndex fail");
-
- return UNF_RETURN_ERROR_S32;
- }
-
- ret = spfc_get_chip_capability((void *)lld_dev->hwdev, &chip_info);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]GetChipCapability fail");
- return UNF_RETURN_ERROR_S32;
- }
- chip_info.work_mode = work_mode;
-
- /* Assign & Get new Card number */
- ret = spfc_assign_card_num(lld_dev, &chip_info, &card_num);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]spfc_assign_card_num fail");
- spfc_release_probe_index(probe_index);
-
- return UNF_RETURN_ERROR_S32;
- }
-
- /* Init HBA resource */
- hba = spfc_init_hba(pci_dev, lld_dev->hwdev, &chip_info, card_num);
- if (!hba) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Probe HBA(0x%x) failed. Memory reference = 0x%x",
- probe_index, atomic_read(&fc_mem_ref));
-
- spfc_release_probe_index(probe_index);
- spfc_dec_and_free_card_num(card_num);
-
- return UNF_RETURN_ERROR_S32;
- }
-
- /* Name by the order of probe */
- *uld_dev = hba;
- snprintf(uld_dev_name, SPFC_PORT_NAME_STR_LEN, "%s%02x%02x",
- SPFC_PORT_NAME_LABEL, hba->card_info.card_num,
- hba->card_info.func_num);
- memcpy(hba->port_name, uld_dev_name, SPFC_PORT_NAME_STR_LEN);
- hba->probe_index = probe_index;
- spfc_hba[probe_index] = hba;
-
- return RETURN_OK;
-}
-
-u32 spfc_sfp_switch(void *hba, void *para_in)
-{
- struct spfc_hba_info *spfc_hba = (struct spfc_hba_info *)hba;
- bool turn_on = false;
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(para_in, UNF_RETURN_ERROR);
-
- /* Redundancy check */
- turn_on = *((bool *)para_in);
- if ((u32)turn_on == (u32)spfc_hba->sfp_on) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Port(0x%x) FC physical port is already %s",
- spfc_hba->port_cfg.port_id, (turn_on) ? "on" : "off");
-
- return ret;
- }
-
- if (turn_on) {
- ret = spfc_port_check_fw_ready(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Get port(0x%x) clear state failed, turn on fail",
- spfc_hba->port_cfg.port_id);
- return ret;
- }
- /* At first, configure port table info if necessary */
- ret = spfc_config_port_table(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) can't configurate port table",
- spfc_hba->port_cfg.port_id);
-
- return ret;
- }
- }
-
- /* Switch physical port */
- ret = spfc_port_switch(spfc_hba, turn_on);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Port(0x%x) switch failed",
- spfc_hba->port_cfg.port_id);
-
- return ret;
- }
-
- /* Update HBA's sfp state */
- spfc_hba->sfp_on = turn_on;
-
- return ret;
-}
-
-static u32 spfc_destroy_lport(struct spfc_hba_info *hba)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- UNF_LOWLEVEL_RELEASE_LOCAL_PORT(ret, hba->lport);
- hba->lport = NULL;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) destroy L_Port done",
- hba->port_cfg.port_id);
-
- return ret;
-}
-
-static u32 spfc_port_check_fw_ready(struct spfc_hba_info *hba)
-{
-#define SPFC_PORT_CLEAR_DONE 0
-#define SPFC_PORT_CLEAR_DOING 1
-#define SPFC_WAIT_ONE_TIME_MS 1000
-#define SPFC_LOOP_TIMES 30
-
- u32 clear_state = SPFC_PORT_CLEAR_DOING;
- u32 ret = RETURN_OK;
- u32 wait_timeout = 0;
-
- do {
- msleep(SPFC_WAIT_ONE_TIME_MS);
- wait_timeout += SPFC_WAIT_ONE_TIME_MS;
- ret = spfc_mbx_get_fw_clear_stat(hba, &clear_state);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
-
- /* Total time more than 30s retry more than 3 times failed */
- if (wait_timeout > SPFC_LOOP_TIMES * SPFC_WAIT_ONE_TIME_MS &&
- clear_state != SPFC_PORT_CLEAR_DONE)
- return UNF_RETURN_ERROR;
- } while (clear_state != SPFC_PORT_CLEAR_DONE);
-
- return RETURN_OK;
-}
-
-u32 spfc_port_reset(struct spfc_hba_info *hba)
-{
- u32 ret = RETURN_OK;
- ulong timeout = 0;
- bool sfp_before_reset = false;
- bool off_para_in = false;
- struct pci_dev *pci_dev = NULL;
- struct spfc_hba_info *spfc_hba = hba;
-
- FC_CHECK_RETURN_VALUE(spfc_hba, UNF_RETURN_ERROR);
- pci_dev = spfc_hba->pci_dev;
- FC_CHECK_RETURN_VALUE(pci_dev, UNF_RETURN_ERROR);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Port(0x%x) reset HBA begin",
- spfc_hba->port_cfg.port_id);
-
- /* Wait for last init/reset completion */
- timeout = wait_for_completion_timeout(&spfc_hba->hba_init_complete,
- (ulong)SPFC_PORT_INIT_TIME_SEC_MAX * HZ);
-
- if (timeout == SPFC_ZERO) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Last HBA initialize/reset timeout: %d second",
- SPFC_PORT_INIT_TIME_SEC_MAX);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Save current port state */
- sfp_before_reset = spfc_hba->sfp_on;
-
- /* Inform the reset event to CM level before beginning */
- UNF_LOWLEVEL_PORT_EVENT(ret, spfc_hba->lport, UNF_PORT_RESET_START, NULL);
- spfc_hba->reset_time = jiffies;
-
- /* Close SFP */
- ret = spfc_sfp_switch(spfc_hba, &off_para_in);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) can't close SFP",
- spfc_hba->port_cfg.port_id);
- spfc_hba->sfp_on = sfp_before_reset;
-
- complete(&spfc_hba->hba_init_complete);
-
- return ret;
- }
-
- ret = spfc_port_check_fw_ready(spfc_hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Get port(0x%x) clear state failed, hang port and report chip error",
- spfc_hba->port_cfg.port_id);
-
- complete(&spfc_hba->hba_init_complete);
-
- return ret;
- }
-
- spfc_queue_pre_process(spfc_hba, false);
-
- ret = spfc_mb_reset_chip(spfc_hba, SPFC_MBOX_SUBTYPE_LIGHT_RESET);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SPFC port(0x%x) can't reset chip mailbox",
- spfc_hba->port_cfg.port_id);
-
- UNF_LOWLEVEL_PORT_EVENT(ret, spfc_hba->lport, UNF_PORT_GET_FWLOG, NULL);
- UNF_LOWLEVEL_PORT_EVENT(ret, spfc_hba->lport, UNF_PORT_DEBUG_DUMP, NULL);
- }
-
- /* Inform the success to CM level */
- UNF_LOWLEVEL_PORT_EVENT(ret, spfc_hba->lport, UNF_PORT_RESET_END, NULL);
-
- /* Queue open */
- spfc_queue_post_process(spfc_hba);
-
- /* Open SFP */
- (void)spfc_sfp_switch(spfc_hba, &sfp_before_reset);
-
- complete(&spfc_hba->hba_init_complete);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[event]Port(0x%x) reset HBA done",
- spfc_hba->port_cfg.port_id);
-
- return ret;
-#undef SPFC_WAIT_LINKDOWN_EVENT_MS
-}
-
-static u32 spfc_delete_scqc_via_cmdq_sync(struct spfc_hba_info *hba, u32 scqn)
-{
- /* Via CMND Queue */
-#define SPFC_DEL_SCQC_TIMEOUT 3000
-
- int ret;
- struct spfc_cmdqe_delete_scqc del_scqc_cmd;
- struct sphw_cmd_buf *cmd_buf;
-
- /* Alloc cmd buffer */
- cmd_buf = sphw_alloc_cmd_buf(hba->dev_handle);
- if (!cmd_buf) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]cmdq in_cmd_buf alloc failed");
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_DEL_SCQC);
- return UNF_RETURN_ERROR;
- }
-
- /* Build & Send Cmnd */
- memset(&del_scqc_cmd, 0, sizeof(del_scqc_cmd));
- del_scqc_cmd.wd0.task_type = SPFC_TASK_T_DEL_SCQC;
- del_scqc_cmd.wd1.scqn = SPFC_LSW(scqn);
- spfc_cpu_to_big32(&del_scqc_cmd, sizeof(del_scqc_cmd));
- memcpy(cmd_buf->buf, &del_scqc_cmd, sizeof(del_scqc_cmd));
- cmd_buf->size = sizeof(del_scqc_cmd);
-
- ret = sphw_cmdq_detail_resp(hba->dev_handle, COMM_MOD_FC, 0, cmd_buf,
- NULL, NULL, SPFC_DEL_SCQC_TIMEOUT,
- SPHW_CHANNEL_FC);
-
- /* Free cmnd buffer */
- sphw_free_cmd_buf(hba->dev_handle, cmd_buf);
-
- if (ret) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Send del scqc via cmdq failed, ret=0x%x",
- ret);
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_DEL_SCQC);
- return UNF_RETURN_ERROR;
- }
-
- SPFC_IO_STAT(hba, SPFC_TASK_T_DEL_SCQC);
-
- return RETURN_OK;
-}
-
-static u32 spfc_delete_srqc_via_cmdq_sync(struct spfc_hba_info *hba, u64 sqrc_gpa)
-{
- /* Via CMND Queue */
-#define SPFC_DEL_SRQC_TIMEOUT 3000
-
- int ret;
- struct spfc_cmdqe_delete_srqc del_srqc_cmd;
- struct sphw_cmd_buf *cmd_buf;
-
- /* Alloc Cmnd buffer */
- cmd_buf = sphw_alloc_cmd_buf(hba->dev_handle);
- if (!cmd_buf) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]cmdq in_cmd_buf allocate failed");
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_DEL_SRQC);
- return UNF_RETURN_ERROR;
- }
-
- /* Build & Send Cmnd */
- memset(&del_srqc_cmd, 0, sizeof(del_srqc_cmd));
- del_srqc_cmd.wd0.task_type = SPFC_TASK_T_DEL_SRQC;
- del_srqc_cmd.srqc_gpa_h = SPFC_HIGH_32_BITS(sqrc_gpa);
- del_srqc_cmd.srqc_gpa_l = SPFC_LOW_32_BITS(sqrc_gpa);
- spfc_cpu_to_big32(&del_srqc_cmd, sizeof(del_srqc_cmd));
- memcpy(cmd_buf->buf, &del_srqc_cmd, sizeof(del_srqc_cmd));
- cmd_buf->size = sizeof(del_srqc_cmd);
-
- ret = sphw_cmdq_detail_resp(hba->dev_handle, COMM_MOD_FC, 0, cmd_buf,
- NULL, NULL, SPFC_DEL_SRQC_TIMEOUT,
- SPHW_CHANNEL_FC);
-
- /* Free Cmnd Buffer */
- sphw_free_cmd_buf(hba->dev_handle, cmd_buf);
-
- if (ret) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Send del srqc via cmdq failed, ret=0x%x",
- ret);
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_DEL_SRQC);
- return UNF_RETURN_ERROR;
- }
-
- SPFC_IO_STAT(hba, SPFC_TASK_T_DEL_SRQC);
-
- return RETURN_OK;
-}
-
-void spfc_flush_scq_ctx(struct spfc_hba_info *hba)
-{
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Start destroy total 0x%x SCQC", SPFC_TOTAL_SCQ_NUM);
-
- FC_CHECK_RETURN_VOID(hba);
-
- (void)spfc_delete_scqc_via_cmdq_sync(hba, 0);
-}
-
-void spfc_flush_srq_ctx(struct spfc_hba_info *hba)
-{
- struct spfc_srq_info *srq_info = NULL;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Start destroy ELS&IMMI SRQC");
-
- FC_CHECK_RETURN_VOID(hba);
-
- /* Check state to avoid to flush SRQC again */
- srq_info = &hba->els_srq_info;
- if (srq_info->srq_type == SPFC_SRQ_ELS && srq_info->enable) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[event]HBA(0x%x) flush ELS SRQC",
- hba->port_index);
-
- (void)spfc_delete_srqc_via_cmdq_sync(hba, srq_info->cqm_srq_info->q_ctx_paddr);
- }
-}
-
-void spfc_set_hba_flush_state(struct spfc_hba_info *hba, bool in_flush)
-{
- ulong flag = 0;
-
- spin_lock_irqsave(&hba->flush_state_lock, flag);
- hba->in_flushing = in_flush;
- spin_unlock_irqrestore(&hba->flush_state_lock, flag);
-}
-
-void spfc_set_hba_clear_state(struct spfc_hba_info *hba, bool clear_flag)
-{
- ulong flag = 0;
-
- spin_lock_irqsave(&hba->clear_state_lock, flag);
- hba->port_is_cleared = clear_flag;
- spin_unlock_irqrestore(&hba->clear_state_lock, flag);
-}
-
-bool spfc_hba_is_present(struct spfc_hba_info *hba)
-{
- int ret_val = RETURN_OK;
- bool present_flag = false;
- u32 vendor_id = 0;
-
- ret_val = pci_read_config_dword(hba->pci_dev, 0, &vendor_id);
- vendor_id &= SPFC_PCI_VENDOR_ID_MASK;
- if (ret_val == RETURN_OK && vendor_id == SPFC_PCI_VENDOR_ID_RAMAXEL) {
- present_flag = true;
- } else {
- present_flag = false;
- hba->dev_present = false;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[info]Port %s remove: vender_id=0x%x, ret=0x%x",
- present_flag ? "normal" : "surprise", vendor_id, ret_val);
-
- return present_flag;
-}
-
-static void spfc_exit(struct pci_dev *pci_dev, struct spfc_hba_info *hba)
-{
-#define SPFC_WAIT_CLR_RESOURCE_MS 1000
- u32 ret = UNF_RETURN_ERROR;
- bool sfp_switch = false;
- bool present_flag = true;
-
- FC_CHECK_RETURN_VOID(pci_dev);
- FC_CHECK_RETURN_VOID(hba);
-
- hba->removing = true;
-
- /* 1. Check HBA present or not */
- present_flag = spfc_hba_is_present(hba);
- if (present_flag) {
- if (hba->phy_link == UNF_PORT_LINK_DOWN)
- hba->queue_set_stage = SPFC_QUEUE_SET_STAGE_FLUSHDONE;
-
- /* At first, close sfp */
- sfp_switch = false;
- (void)spfc_sfp_switch((void *)hba, (void *)&sfp_switch);
- }
-
- /* 2. Report COM with HBA removing: delete route timer delay work */
- UNF_LOWLEVEL_PORT_EVENT(ret, hba->lport, UNF_PORT_BEGIN_REMOVE, NULL);
-
- /* 3. Report COM with HBA Nop, COM release I/O(s) & R_Port(s) forcely */
- UNF_LOWLEVEL_PORT_EVENT(ret, hba->lport, UNF_PORT_NOP, NULL);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]PCI device(%p) remove port(0x%x) failed",
- pci_dev, hba->port_index);
- }
-
- spfc_delete_default_session(hba);
-
- if (present_flag)
- /* 4.1 Wait for all SQ empty, free SRQ buffer & SRQC */
- spfc_queue_pre_process(hba, true);
-
- /* 5. Destroy L_Port */
- (void)spfc_destroy_lport(hba);
-
- /* 6. With HBA is present */
- if (present_flag) {
- /* Enable Queues dispatch */
- spfc_queue_post_process(hba);
-
- /* Need reset port if necessary */
- (void)spfc_mb_reset_chip(hba, SPFC_MBOX_SUBTYPE_HEAVY_RESET);
-
- /* Flush SCQ context */
- spfc_flush_scq_ctx(hba);
-
- /* Flush SRQ context */
- spfc_flush_srq_ctx(hba);
-
- sphw_func_rx_tx_flush(hba->dev_handle, SPHW_CHANNEL_FC);
-
- /* NOTE: while flushing txrx, hash bucket will be cached out in
- * UP. Wait to clear resources completely
- */
- msleep(SPFC_WAIT_CLR_RESOURCE_MS);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) flush scq & srq & root context done",
- hba->port_cfg.port_id);
- }
-
- /* 7. Release host resources */
- spfc_release_host_res(hba);
-
- /* 8. Destroy FC work queue */
- if (hba->work_queue) {
- flush_workqueue(hba->work_queue);
- destroy_workqueue(hba->work_queue);
- hba->work_queue = NULL;
- }
-
- /* 9. Release Probe index & Decrease card number */
- spfc_release_probe_index(hba->probe_index);
- spfc_dec_and_free_card_num((u8)hba->card_info.card_num);
-
- /* 10. Free HBA memory */
- kfree(hba);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[event]PCI device(%p) remove succeed, memory reference is 0x%x",
- pci_dev, atomic_read(&fc_mem_ref));
-}
-
-static void spfc_remove(struct spfc_lld_dev *lld_dev, void *uld_dev)
-{
- struct pci_dev *pci_dev = NULL;
- struct spfc_hba_info *hba = (struct spfc_hba_info *)uld_dev;
- u32 probe_total_num = 0;
- u32 probe_index = 0;
-
- FC_CHECK_RETURN_VOID(lld_dev);
- FC_CHECK_RETURN_VOID(uld_dev);
- FC_CHECK_RETURN_VOID(lld_dev->hwdev);
- FC_CHECK_RETURN_VOID(lld_dev->pdev);
-
- pci_dev = hba->pci_dev;
-
- /* Get total probed port number */
- spfc_get_total_probed_num(&probe_total_num);
- if (probe_total_num < 1) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port manager is empty and no need to remove");
- return;
- }
-
- /* check pci vendor id */
- if (pci_dev->vendor != SPFC_PCI_VENDOR_ID_RAMAXEL) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Wrong vendor id(0x%x) and exit",
- pci_dev->vendor);
- return;
- }
-
- /* Check function ability */
- if (!sphw_support_fc(lld_dev->hwdev, NULL)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]FC is not enable in this function");
- return;
- }
-
- /* Get probe index */
- probe_index = hba->probe_index;
-
- /* Parent context alloc check */
- if (hba->service_cap.dev_fc_cap.max_parent_qpc_num == 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]FC parent context not allocate in this function");
- return;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]HBA(0x%x) start removing...", hba->port_index);
-
- /* HBA removinig... */
- spfc_exit(pci_dev, hba);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Port(0x%x) pci device removed, vendorid(0x%04x) devid(0x%04x)",
- probe_index, pci_dev->vendor, pci_dev->device);
-
- /* Probe index check */
- if (probe_index < SPFC_HBA_PORT_MAX_NUM) {
- spfc_hba[probe_index] = NULL;
- } else {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Probe index(0x%x) is invalid and remove failed",
- probe_index);
- }
-
- spfc_get_total_probed_num(&probe_total_num);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[event]Removed index=%u, RemainNum=%u, AllowNum=%u",
- probe_index, probe_total_num, allowed_probe_num);
-}
-
-static u32 spfc_get_hba_pcie_link_state(void *hba, void *link_state)
-{
- bool *link_state_info = link_state;
- bool present_flag = true;
- struct spfc_hba_info *spfc_hba = hba;
- int ret;
- bool last_dev_state = true;
- bool cur_dev_state = true;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(link_state, UNF_RETURN_ERROR);
- last_dev_state = spfc_hba->dev_present;
- ret = sphw_get_card_present_state(spfc_hba->dev_handle, (bool *)&present_flag);
- if (ret || !present_flag) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]port(0x%x) is not present,ret:%d, present_flag:%d",
- spfc_hba->port_cfg.port_id, ret, present_flag);
- cur_dev_state = false;
- } else {
- cur_dev_state = true;
- }
-
- spfc_hba->dev_present = cur_dev_state;
-
- /* To prevent false alarms, the heartbeat is considered lost only
- * when the PCIe link is down for two consecutive times.
- */
- if (!last_dev_state && !cur_dev_state)
- spfc_hba->heart_status = false;
-
- *link_state_info = spfc_hba->dev_present;
-
- return RETURN_OK;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_hba.h b/drivers/scsi/spfc/hw/spfc_hba.h
deleted file mode 100644
index 937f00ea8fc7..000000000000
--- a/drivers/scsi/spfc/hw/spfc_hba.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_HBA_H
-#define SPFC_HBA_H
-
-#include "unf_type.h"
-#include "unf_common.h"
-#include "spfc_queue.h"
-#include "sphw_crm.h"
-#define SPFC_PCI_VENDOR_ID_MASK (0xffff)
-
-#define FW_VER_LEN (32)
-#define HW_VER_LEN (32)
-#define FW_SUB_VER_LEN (24)
-
-#define SPFC_LOWLEVEL_RTTOV_TAG 0
-#define SPFC_LOWLEVEL_EDTOV_TAG 0
-#define SPFC_LOWLEVEL_DEFAULT_LOOP_BB_CREDIT (8)
-#define SPFC_LOWLEVEL_DEFAULT_32G_BB_CREDIT (255)
-#define SPFC_LOWLEVEL_DEFAULT_16G_BB_CREDIT (255)
-#define SPFC_LOWLEVEL_DEFAULT_8G_BB_CREDIT (255)
-#define SPFC_LOWLEVEL_DEFAULT_BB_SCN 0
-#define SPFC_LOWLEVEL_DEFAULT_RA_TOV UNF_DEFAULT_RATOV
-#define SPFC_LOWLEVEL_DEFAULT_ED_TOV UNF_DEFAULT_EDTOV
-
-#define SPFC_LOWLEVEL_DEFAULT_32G_ESCH_VALUE 28081
-#define SPFC_LOWLEVEL_DEFAULT_16G_ESCH_VALUE 14100
-#define SPFC_LOWLEVEL_DEFAULT_8G_ESCH_VALUE 7000
-#define SPFC_LOWLEVEL_DEFAULT_ESCH_BUST_SIZE 0x2000
-
-#define SPFC_PCI_STATUS 0x06
-
-#define SPFC_SMARTIO_WORK_MODE_FC 0x1
-#define SPFC_SMARTIO_WORK_MODE_OTHER 0xF
-#define UNF_FUN_ID_MASK 0x07
-
-#define UNF_SPFC_FC (0x01)
-#define UNF_SPFC_MAXNPIV_NUM 64 /* If not support NPIV, Initialized to 0 */
-
-#define SPFC_MAX_COS_NUM (8)
-
-#define SPFC_INTR_ENABLE 0x5
-#define SPFC_INTR_DISABLE 0x0
-#define SPFC_CLEAR_FW_INTR 0x1
-#define SPFC_REG_ENABLE_INTR 0x00000200
-
-#define SPFC_PCI_VENDOR_ID_RAMAXEL 0x1E81
-
-#define SPFC_SCQ_CNTX_SIZE 32
-#define SPFC_SRQ_CNTX_SIZE 64
-
-#define SPFC_PORT_INIT_TIME_SEC_MAX 1
-
-#define SPFC_PORT_NAME_LABEL "spfc"
-#define SPFC_PORT_NAME_STR_LEN (16)
-
-#define SPFC_MAX_PROBE_PORT_NUM (64)
-#define SPFC_PORT_NUM_PER_TABLE (64)
-#define SPFC_MAX_CARD_NUM (32)
-
-#define SPFC_HBA_PORT_MAX_NUM SPFC_MAX_PROBE_PORT_NUM
-#define SPFC_SIRT_MIN_RXID 0
-#define SPFC_SIRT_MAX_RXID 255
-
-#define SPFC_GET_HBA_PORT_ID(hba) ((hba)->port_index)
-
-#define SPFC_MAX_WAIT_LOOP_TIMES 10000
-#define SPFC_WAIT_SESS_ENABLE_ONE_TIME_MS 1
-#define SPFC_WAIT_SESS_FREE_ONE_TIME_MS 1
-
-#define SPFC_PORT_ID_MASK 0xff0000
-
-#define SPFC_MAX_PARENT_QPC_NUM 2048
-struct spfc_port_cfg {
- u32 port_id; /* Port ID */
- u32 port_mode; /* Port mode:INI(0x20), TGT(0x10), BOTH(0x30) */
- u32 port_topology; /* Port topo:0x3:loop,0xc:p2p,0xf:auto */
- u32 port_alpa; /* Port ALPA */
- u32 max_queue_depth; /* Max Queue depth Registration to SCSI */
- u32 sest_num; /* IO burst num:512-4096 */
- u32 max_login; /* Max Login Session. */
- u32 node_name_hi; /* nodename high 32 bits */
- u32 node_name_lo; /* nodename low 32 bits */
- u32 port_name_hi; /* portname high 32 bits */
- u32 port_name_lo; /* portname low 32 bits */
- u32 port_speed; /* Port speed 0:auto 4:4Gbps 8:8Gbps 16:16Gbps */
- u32 interrupt_delay; /* Delay times(ms) in interrupt */
- u32 tape_support; /* tape support */
-};
-
-#define SPFC_VER_INFO_SIZE 128
-struct spfc_drv_version {
- char ver[SPFC_VER_INFO_SIZE];
-};
-
-struct spfc_card_info {
- u32 card_num : 8;
- u32 func_num : 8;
- u32 base_func : 8;
- /* Card type:UNF_FC_SERVER_BOARD_32_G(6) 32G mode,
- * UNF_FC_SERVER_BOARD_16_G(7)16G mode
- */
- u32 card_type : 8;
-};
-
-struct spfc_card_num_manage {
- bool is_removing;
- u32 port_count;
- u64 card_number;
-};
-
-struct spfc_sim_ini_err {
- u32 err_code;
- u32 times;
-};
-
-struct spfc_sim_pcie_err {
- u32 err_code;
- u32 times;
-};
-
-struct spfc_led_state {
- u8 green_speed_led;
- u8 yellow_speed_led;
- u8 ac_led;
- u8 rsvd;
-};
-
-enum spfc_led_activity {
- SPFC_LED_CFG_ACTVE_FRAME = 0,
- SPFC_LED_CFG_ACTVE_FC = 3
-};
-
-enum spfc_queue_set_stage {
- SPFC_QUEUE_SET_STAGE_INIT = 0,
- SPFC_QUEUE_SET_STAGE_SCANNING,
- SPFC_QUEUE_SET_STAGE_FLUSHING,
- SPFC_QUEUE_SET_STAGE_FLUSHDONE,
- SPFC_QUEUE_SET_STAGE_BUTT
-};
-
-struct spfc_vport_info {
- u64 node_name;
- u64 port_name;
- u32 port_mode; /* INI, TGT or both */
- u32 nport_id; /* maybe acquired by lowlevel and update to common */
- void *vport;
- u16 vp_index;
-};
-
-struct spfc_srq_delay_info {
- u8 srq_delay_flag; /* Check whether need to delay */
- u8 root_rq_rcvd_flag;
- u16 rsd;
-
- spinlock_t srq_lock;
- struct unf_frame_pkg frame_pkg;
-
- struct delayed_work del_work;
-};
-
-struct spfc_fw_ver_detail {
- u8 ucode_ver[SPFC_VER_LEN];
- u8 ucode_compile_time[SPFC_COMPILE_TIME_LEN];
-
- u8 up_ver[SPFC_VER_LEN];
- u8 up_compile_time[SPFC_COMPILE_TIME_LEN];
-
- u8 boot_ver[SPFC_VER_LEN];
- u8 boot_compile_time[SPFC_COMPILE_TIME_LEN];
-};
-
-/* get wwpn and wwnn */
-struct spfc_chip_info {
- u8 work_mode;
- u8 tape_support;
- u64 wwpn;
- u64 wwnn;
-};
-
-/* Default SQ info */
-struct spfc_default_sq_info {
- u32 sq_cid;
- u32 sq_xid;
- u32 fun_cid;
- u32 default_sq_flag;
-};
-
-struct spfc_hba_info {
- struct pci_dev *pci_dev;
- void *dev_handle;
-
- struct fc_service_cap service_cap; /* struct fc_service_cap pstFcoeServiceCap; */
-
- struct spfc_scq_info scq_info[SPFC_TOTAL_SCQ_NUM];
- struct spfc_srq_info els_srq_info;
-
- struct spfc_vport_info vport_info[UNF_SPFC_MAXNPIV_NUM + 1];
-
- /* PCI IO Memory */
- void __iomem *bar0;
- u32 bar0_len;
-
- struct spfc_parent_queue_mgr *parent_queue_mgr;
-
- /* Link list Sq WqePage Pool */
- struct spfc_sq_wqepage_pool sq_wpg_pool;
-
- enum spfc_queue_set_stage queue_set_stage;
- u32 next_clear_sq;
- u32 default_sqid;
-
- /* Port parameters, Obtained through firmware */
- u16 queue_set_max_count;
- u8 port_type; /* FC or FCoE Port */
- u8 port_index; /* Phy Port */
- u32 default_scqn;
- char fw_ver[FW_VER_LEN]; /* FW version */
- char hw_ver[HW_VER_LEN]; /* HW version */
- char mst_fw_ver[FW_SUB_VER_LEN];
- char fc_fw_ver[FW_SUB_VER_LEN];
- u8 chip_type; /* chiptype:Smart or fc */
- u8 work_mode;
- struct spfc_card_info card_info;
- char port_name[SPFC_PORT_NAME_STR_LEN];
- u32 probe_index;
-
- u16 exi_base;
- u16 exi_count;
- u16 vpf_count;
- u8 vpid_start;
- u8 vpid_end;
-
- spinlock_t flush_state_lock;
- bool in_flushing;
-
- spinlock_t clear_state_lock;
- bool port_is_cleared;
-
- struct spfc_port_cfg port_cfg; /* Obtained through Config */
-
- void *lport; /* Used in UNF level */
-
- u8 sys_node_name[UNF_WWN_LEN];
- u8 sys_port_name[UNF_WWN_LEN];
-
- struct completion hba_init_complete;
- struct completion mbox_complete;
- struct completion vpf_complete;
- struct completion fcfi_complete;
- struct completion get_sfp_complete;
-
- u16 init_stage;
- u16 removing;
- bool sfp_on;
- bool dev_present;
- bool heart_status;
- spinlock_t hba_lock;
- u32 port_topo_cfg;
- u32 port_bb_scn_cfg;
- u32 port_loop_role;
- u32 port_speed_cfg;
- u32 max_support_speed;
- u32 min_support_speed;
- u32 server_max_speed;
-
- u8 remote_rttov_tag;
- u8 remote_edtov_tag;
- u16 compared_bb_scn;
- u16 remote_bb_credit;
- u32 compared_edtov_val;
- u32 compared_ratov_val;
- enum unf_act_topo active_topo;
- u32 active_port_speed;
- u32 active_rxbb_credit;
- u32 active_bb_scn;
-
- u32 phy_link;
-
- enum unf_port_mode port_mode;
-
- u32 fcp_cfg;
-
- /* loop */
- u8 active_alpa;
- u8 loop_map_valid;
- u8 loop_map[UNF_LOOPMAP_COUNT];
-
- /* sfp info dma */
- void *sfp_buf;
- dma_addr_t sfp_dma_addr;
- u32 sfp_status;
- int chip_temp;
- u32 sfp_posion;
-
- u32 cos_bitmap;
- atomic_t cos_rport_cnt[SPFC_MAX_COS_NUM];
-
- /* fw debug dma buffer */
- void *debug_buf;
- dma_addr_t debug_buf_dma_addr;
- void *log_buf;
- dma_addr_t fw_log_dma_addr;
-
- void *dma_addr;
- dma_addr_t update_dma_addr;
-
- struct spfc_sim_ini_err sim_ini_err;
- struct spfc_sim_pcie_err sim_pcie_err;
-
- struct spfc_led_state led_states;
-
- u32 fec_status;
-
- struct workqueue_struct *work_queue;
- struct work_struct els_srq_clear_work;
- u64 reset_time;
-
- spinlock_t spin_lock;
-
- struct spfc_srq_delay_info srq_delay_info;
- struct spfc_fw_ver_detail hardinfo;
- struct spfc_default_sq_info default_sq_info;
-};
-
-extern struct spfc_hba_info *spfc_hba[SPFC_HBA_PORT_MAX_NUM];
-extern spinlock_t probe_spin_lock;
-extern ulong probe_bit_map[SPFC_MAX_PROBE_PORT_NUM / SPFC_PORT_NUM_PER_TABLE];
-
-u32 spfc_port_reset(struct spfc_hba_info *hba);
-void spfc_flush_scq_ctx(struct spfc_hba_info *hba);
-void spfc_flush_srq_ctx(struct spfc_hba_info *hba);
-void spfc_set_hba_flush_state(struct spfc_hba_info *hba, bool in_flush);
-void spfc_set_hba_clear_state(struct spfc_hba_info *hba, bool clear_flag);
-u32 spfc_get_probe_index_by_port_id(u32 port_id, u32 *probe_index);
-void spfc_get_total_probed_num(u32 *probe_cnt);
-u32 spfc_sfp_switch(void *hba, void *para_in);
-bool spfc_hba_is_present(struct spfc_hba_info *hba);
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_hw_wqe.h b/drivers/scsi/spfc/hw/spfc_hw_wqe.h
deleted file mode 100644
index e03d24a98579..000000000000
--- a/drivers/scsi/spfc/hw/spfc_hw_wqe.h
+++ /dev/null
@@ -1,1645 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_HW_WQE_H
-#define SPFC_HW_WQE_H
-
-#define FC_ICQ_EN
-#define FC_SCSI_CMDIU_LEN 48
-#define FC_NVME_CMDIU_LEN 96
-#define FC_LS_GS_USERID_CNT_MAX 10
-#define FC_SENSEDATA_USERID_CNT_MAX 2
-#define FC_INVALID_MAGIC_NUM 0xFFFFFFFF
-#define FC_INVALID_HOTPOOLTAG 0xFFFF
-
-/* TASK TYPE: in order to compatible wiht EDA, please add new type before BUTT. */
-enum spfc_task_type {
- SPFC_TASK_T_EMPTY = 0, /* SCQE TYPE: means task type not initialize */
-
- SPFC_TASK_T_IWRITE = 1, /* SQE TYPE: ini send FCP Write Command */
- SPFC_TASK_T_IREAD = 2, /* SQE TYPE: ini send FCP Read Command */
- SPFC_TASK_T_IRESP = 3, /* SCQE TYPE: ini recv fcp rsp for IREAD/IWRITE/ITMF */
- SPFC_TASK_T_TCMND = 4, /* NA */
- SPFC_TASK_T_TREAD = 5, /* SQE TYPE: tgt send FCP Read Command */
- SPFC_TASK_T_TWRITE = 6, /* SQE TYPE: tgt send FCP Write Command (XFER_RDY) */
- SPFC_TASK_T_TRESP = 7, /* SQE TYPE: tgt send fcp rsp of Read/Write */
- SPFC_TASK_T_TSTS = 8, /* SCQE TYPE: tgt sts for TREAD/TWRITE/TRESP */
- SPFC_TASK_T_ABTS = 9, /* SQE TYPE: ini send abts request Command */
- SPFC_TASK_T_IELS = 10, /* NA */
- SPFC_TASK_T_ITMF = 11, /* SQE TYPE: ini send tmf request Command */
- SPFC_TASK_T_CLEAN_UP = 12, /* NA */
- SPFC_TASK_T_CLEAN_UP_ALL = 13, /* NA */
- SPFC_TASK_T_UNSOLICITED = 14, /* NA */
- SPFC_TASK_T_ERR_WARN = 15, /* NA */
- SPFC_TASK_T_SESS_EN = 16, /* CMDQ TYPE: enable session */
- SPFC_TASK_T_SESS_DIS = 17, /* NA */
- SPFC_TASK_T_SESS_DEL = 18, /* NA */
- SPFC_TASK_T_RQE_REPLENISH = 19, /* NA */
-
- SPFC_TASK_T_RCV_TCMND = 20, /* SCQE TYPE: tgt recv fcp cmd */
- SPFC_TASK_T_RCV_ELS_CMD = 21, /* SCQE TYPE: tgt recv els cmd */
- SPFC_TASK_T_RCV_ABTS_CMD = 22, /* SCQE TYPE: tgt recv abts cmd */
- SPFC_TASK_T_RCV_IMMEDIATE = 23, /* SCQE TYPE: tgt recv immediate data */
- /* SQE TYPE: send ESL rsp. PLOGI_ACC, PRLI_ACC will carry the parent
- *context parameter indication.
- */
- SPFC_TASK_T_ELS_RSP = 24,
- SPFC_TASK_T_ELS_RSP_STS = 25, /* SCQE TYPE: ELS rsp sts */
- SPFC_TASK_T_ABTS_RSP = 26, /* CMDQ TYPE: tgt send abts rsp */
- SPFC_TASK_T_ABTS_RSP_STS = 27, /* SCQE TYPE: tgt abts rsp sts */
-
- SPFC_TASK_T_ABORT = 28, /* CMDQ TYPE: tgt send Abort Command */
- SPFC_TASK_T_ABORT_STS = 29, /* SCQE TYPE: Abort sts */
-
- SPFC_TASK_T_ELS = 30, /* SQE TYPE: send ELS request Command */
- SPFC_TASK_T_RCV_ELS_RSP = 31, /* SCQE TYPE: recv ELS response */
-
- SPFC_TASK_T_GS = 32, /* SQE TYPE: send GS request Command */
- SPFC_TASK_T_RCV_GS_RSP = 33, /* SCQE TYPE: recv GS response */
-
- SPFC_TASK_T_SESS_EN_STS = 34, /* SCQE TYPE: enable session sts */
- SPFC_TASK_T_SESS_DIS_STS = 35, /* NA */
- SPFC_TASK_T_SESS_DEL_STS = 36, /* NA */
-
- SPFC_TASK_T_RCV_ABTS_RSP = 37, /* SCQE TYPE: ini recv abts rsp */
-
- SPFC_TASK_T_BUFFER_CLEAR = 38, /* CMDQ TYPE: Buffer Clear */
- SPFC_TASK_T_BUFFER_CLEAR_STS = 39, /* SCQE TYPE: Buffer Clear sts */
- SPFC_TASK_T_FLUSH_SQ = 40, /* CMDQ TYPE: flush sq */
- SPFC_TASK_T_FLUSH_SQ_STS = 41, /* SCQE TYPE: flush sq sts */
-
- SPFC_TASK_T_SESS_RESET = 42, /* SQE TYPE: Reset session */
- SPFC_TASK_T_SESS_RESET_STS = 43, /* SCQE TYPE: Reset session sts */
- SPFC_TASK_T_RQE_REPLENISH_STS = 44, /* NA */
- SPFC_TASK_T_DUMP_EXCH = 45, /* CMDQ TYPE: dump exch */
- SPFC_TASK_T_INIT_SRQC = 46, /* CMDQ TYPE: init SRQC */
- SPFC_TASK_T_CLEAR_SRQ = 47, /* CMDQ TYPE: clear SRQ */
- SPFC_TASK_T_CLEAR_SRQ_STS = 48, /* SCQE TYPE: clear SRQ sts */
- SPFC_TASK_T_INIT_SCQC = 49, /* CMDQ TYPE: init SCQC */
- SPFC_TASK_T_DEL_SCQC = 50, /* CMDQ TYPE: delete SCQC */
- SPFC_TASK_T_TMF_RESP = 51, /* SQE TYPE: tgt send tmf rsp */
- SPFC_TASK_T_DEL_SRQC = 52, /* CMDQ TYPE: delete SRQC */
- SPFC_TASK_T_RCV_IMMI_CONTINUE = 53, /* SCQE TYPE: tgt recv continue immediate data */
-
- SPFC_TASK_T_ITMF_RESP = 54, /* SCQE TYPE: ini recv tmf rsp */
- SPFC_TASK_T_ITMF_MARKER_STS = 55, /* SCQE TYPE: tmf marker sts */
- SPFC_TASK_T_TACK = 56,
- SPFC_TASK_T_SEND_AEQERR = 57,
- SPFC_TASK_T_ABTS_MARKER_STS = 58, /* SCQE TYPE: abts marker sts */
- SPFC_TASK_T_FLR_CLEAR_IO = 59, /* FLR clear io type */
- SPFC_TASK_T_CREATE_SSQ_CONTEXT = 60,
- SPFC_TASK_T_CLEAR_SSQ_CONTEXT = 61,
- SPFC_TASK_T_EXCH_ID_FREE = 62,
- SPFC_TASK_T_DIFX_RESULT_STS = 63,
- SPFC_TASK_T_EXCH_ID_FREE_ABORT = 64,
- SPFC_TASK_T_EXCH_ID_FREE_ABORT_STS = 65,
- SPFC_TASK_T_PARAM_CHECK_FAIL = 66,
- SPFC_TASK_T_TGT_UNKNOWN = 67,
- SPFC_TASK_T_NVME_LS = 70, /* SQE TYPE: Snd Ls Req */
- SPFC_TASK_T_RCV_NVME_LS_RSP = 71, /* SCQE TYPE: Rcv Ls Rsp */
-
- SPFC_TASK_T_NVME_LS_RSP = 72, /* SQE TYPE: Snd Ls Rsp */
- SPFC_TASK_T_RCV_NVME_LS_RSP_STS = 73, /* SCQE TYPE: Rcv Ls Rsp sts */
-
- SPFC_TASK_T_RCV_NVME_LS_CMD = 74, /* SCQE TYPE: Rcv ls cmd */
-
- SPFC_TASK_T_NVME_IREAD = 75, /* SQE TYPE: Ini Snd Nvme Read Cmd */
- SPFC_TASK_T_NVME_IWRITE = 76, /* SQE TYPE: Ini Snd Nvme write Cmd */
-
- SPFC_TASK_T_NVME_TREAD = 77, /* SQE TYPE: Tgt Snd Nvme Read Cmd */
- SPFC_TASK_T_NVME_TWRITE = 78, /* SQE TYPE: Tgt Snd Nvme write Cmd */
-
- SPFC_TASK_T_NVME_IRESP = 79, /* SCQE TYPE: Ini recv nvme rsp for NVMEIREAD/NVMEIWRITE */
-
- SPFC_TASK_T_INI_IO_ABORT = 80, /* SQE type: INI Abort Cmd */
- SPFC_TASK_T_INI_IO_ABORT_STS = 81, /* SCQE type: INI Abort sts */
-
- SPFC_TASK_T_INI_LS_ABORT = 82, /* SQE type: INI ls abort Cmd */
- SPFC_TASK_T_INI_LS_ABORT_STS = 83, /* SCQE type: INI ls abort sts */
- SPFC_TASK_T_EXCHID_TIMEOUT_STS = 84, /* SCQE TYPE: EXCH_ID TIME OUT */
- SPFC_TASK_T_PARENT_ERR_STS = 85, /* SCQE TYPE: PARENT ERR */
-
- SPFC_TASK_T_NOP = 86,
- SPFC_TASK_T_NOP_STS = 87,
-
- SPFC_TASK_T_DFX_INFO = 126,
- SPFC_TASK_T_BUTT
-};
-
-/* error code for error report */
-
-enum spfc_err_code {
- FC_CQE_COMPLETED = 0, /* Successful */
- FC_SESS_HT_INSERT_FAIL = 1, /* Offload fail: hash insert fail */
- FC_SESS_HT_INSERT_DUPLICATE = 2, /* Offload fail: duplicate offload */
- FC_SESS_HT_BIT_SET_FAIL = 3, /* Offload fail: bloom filter set fail */
- FC_SESS_HT_DELETE_FAIL = 4, /* Offload fail: hash delete fail(duplicate delete) */
- FC_CQE_BUFFER_CLEAR_IO_COMPLETED = 5, /* IO done in buffer clear */
- FC_CQE_SESSION_ONLY_CLEAR_IO_COMPLETED = 6, /* IO done in session rst mode=1 */
- FC_CQE_SESSION_RST_CLEAR_IO_COMPLETED = 7, /* IO done in session rst mode=3 */
- FC_CQE_TMF_RSP_IO_COMPLETED = 8, /* IO done in tgt tmf rsp */
- FC_CQE_TMF_IO_COMPLETED = 9, /* IO done in ini tmf */
- FC_CQE_DRV_ABORT_IO_COMPLETED = 10, /* IO done in tgt abort */
- /*
- *IO done in fcp rsp process. Used for the sceanrio: 1.abort before cmd 2.
- *send fcp rsp directly after recv cmd.
- */
- FC_CQE_DRV_ABORT_IO_IN_RSP_COMPLETED = 11,
- /*
- *IO done in fcp cmd process. Used for the sceanrio: 1.abort before cmd 2.child setup fail.
- */
- FC_CQE_DRV_ABORT_IO_IN_CMD_COMPLETED = 12,
- FC_CQE_WQE_FLUSH_IO_COMPLETED = 13, /* IO done in FLUSH SQ */
- FC_ERROR_CODE_DATA_DIFX_FAILED = 14, /* fcp data format check: DIFX check error */
- /* fcp data format check: task_type is not read */
- FC_ERROR_CODE_DATA_TASK_TYPE_INCORRECT = 15,
- FC_ERROR_CODE_DATA_OOO_RO = 16, /* fcp data format check: data offset is not continuous */
- FC_ERROR_CODE_DATA_EXCEEDS_DATA2TRNS = 17, /* fcp data format check: data is over run */
- /* fcp rsp format check: payload is too short */
- FC_ERROR_CODE_FCP_RSP_INVALID_LENGTH_FIELD = 18,
- /* fcp rsp format check: fcp_conf need, but exch don't hold seq initiative */
- FC_ERROR_CODE_FCP_RSP_CONF_REQ_NOT_SUPPORTED_YET = 19,
- /* fcp rsp format check: fcp_conf is required, but it's the last seq */
- FC_ERROR_CODE_FCP_RSP_OPENED_SEQ = 20,
- /* xfer rdy format check: payload is too short */
- FC_ERROR_CODE_XFER_INVALID_PAYLOAD_SIZE = 21,
- /* xfer rdy format check: last data out havn't finished */
- FC_ERROR_CODE_XFER_PEND_XFER_SET = 22,
- /* xfer rdy format check: data offset is not continuous */
- FC_ERROR_CODE_XFER_OOO_RO = 23,
- FC_ERROR_CODE_XFER_NULL_BURST_LEN = 24, /* xfer rdy format check: burst len is 0 */
- FC_ERROR_CODE_REC_TIMER_EXPIRE = 25, /* Timer expire: REC_TIMER */
- FC_ERROR_CODE_E_D_TIMER_EXPIRE = 26, /* Timer expire: E_D_TIMER */
- FC_ERROR_CODE_ABORT_TIMER_EXPIRE = 27, /* Timer expire: Abort timer */
- FC_ERROR_CODE_ABORT_MAGIC_NUM_NOT_MATCH = 28, /* Abort IO magic number mismatch */
- FC_IMMI_CMDPKT_SETUP_FAIL = 29, /* RX immediate data cmd pkt child setup fail */
- FC_ERROR_CODE_DATA_SEQ_ID_NOT_EQUAL = 30, /* RX fcp data sequence id not equal */
- FC_ELS_GS_RSP_EXCH_CHECK_FAIL = 31, /* ELS/GS exch info check fail */
- FC_CQE_ELS_GS_SRQE_GET_FAIL = 32, /* ELS/GS process get SRQE fail */
- FC_CQE_DATA_DMA_REQ_FAIL = 33, /* SMF soli-childdma rsp error */
- FC_CQE_SESSION_CLOSED = 34, /* Session is closed */
- FC_SCQ_IS_FULL = 35, /* SCQ is full */
- FC_SRQ_IS_FULL = 36, /* SRQ is full */
- FC_ERROR_DUCHILDCTX_SETUP_FAIL = 37, /* dpchild ctx setup fail */
- FC_ERROR_INVALID_TXMFS = 38, /* invalid txmfs */
- FC_ERROR_OFFLOAD_LACKOF_SCQE_FAIL = 39, /* offload fail,lack of SCQE,through AEQ */
- FC_ERROR_INVALID_TASK_ID = 40, /* tx invlaid task id */
- FC_ERROR_INVALID_PKT_LEN = 41, /* tx els gs pakcet len check */
- FC_CQE_ELS_GS_REQ_CLR_IO_COMPLETED = 42, /* IO done in els gs tx */
- FC_CQE_ELS_RSP_CLR_IO_COMPLETED = 43, /* IO done in els rsp tx */
- FC_ERROR_CODE_RESID_UNDER_ERR = 44, /* FCP RSP RESID ERROR */
- FC_ERROR_EXCH_ID_FREE_ERR = 45, /* Abnormal free xid failed */
- FC_ALLOC_EXCH_ID_FAILED = 46, /* ucode alloc EXCH ID failed */
- FC_ERROR_DUPLICATE_IO_RECEIVED = 47, /* Duplicate tcmnd or tmf rsp received */
- FC_ERROR_RXID_MISCOMPARE = 48,
- FC_ERROR_FAILOVER_CLEAR_VALID_HOST = 49, /* Failover cleared valid host io */
- FC_ERROR_EXCH_ID_NOT_MATCH = 50, /* SCQ TYPE: xid not match */
- FC_ERROR_ABORT_FAIL = 51, /* SCQ TYPE: abort fail */
- FC_ERROR_SHARD_TABLE_OP_FAIL = 52, /* SCQ TYPE: shard table OP fail */
- FC_ERROR_E0E1_FAIL = 53,
- FC_INSERT_EXCH_ID_HASH_FAILED = 54, /* ucode INSERT EXCH ID HASH failed */
- FC_ERROR_CODE_FCP_RSP_UPDMA_FAILED = 55, /* up dma req failed,while fcp rsp is rcving */
- FC_ERROR_CODE_SID_DID_NOT_MATCH = 56, /* sid or did not match */
- FC_ERROR_DATA_NOT_REL_OFF = 57, /* data not rel off */
- FC_ERROR_CODE_EXCH_ID_TIMEOUT = 58, /* exch id timeout */
- FC_ERROR_PARENT_CHECK_FAIL = 59,
- FC_ERROR_RECV_REC_REJECT = 60, /* RECV REC RSP REJECT */
- FC_ERROR_RECV_SRR_REJECT = 61, /* RECV REC SRR REJECT */
- FC_ERROR_REC_NOT_FIND_EXID_INVALID = 62,
- FC_ERROR_RECV_REC_NO_ERR = 63,
- FC_ERROR_PARENT_CTX_ERR = 64
-};
-
-/* AEQ EVENT TYPE */
-enum spfc_aeq_evt_type {
- /* SCQ and SRQ not enough, HOST will initiate a operation to associated SCQ/SRQ */
- FC_AEQ_EVENT_QUEUE_ERROR = 48,
- FC_AEQ_EVENT_WQE_FATAL_ERROR = 49, /* WQE MSN check error,HOST will reset port */
- FC_AEQ_EVENT_CTX_FATAL_ERROR = 50, /* serious chip error, HOST will reset chip */
- FC_AEQ_EVENT_OFFLOAD_ERROR = 51,
- FC_FC_AEQ_EVENT_TYPE_LAST
-};
-
-enum spfc_protocol_class {
- FC_PROTOCOL_CLASS_3 = 0x0,
- FC_PROTOCOL_CLASS_2 = 0x1,
- FC_PROTOCOL_CLASS_1 = 0x2,
- FC_PROTOCOL_CLASS_F = 0x3,
- FC_PROTOCOL_CLASS_OTHER = 0x4
-};
-
-enum spfc_aeq_evt_err_code {
- /* detail type of resource lack */
- FC_SCQ_IS_FULL_ERR = 0,
- FC_SRQ_IS_FULL_ERR,
-
- /* detail type of FC_AEQ_EVENT_WQE_FATAL_ERROR */
- FC_SQE_CHILD_SETUP_WQE_MSN_ERR = 2,
- FC_SQE_CHILD_SETUP_WQE_GPA_ERR,
- FC_CMDPKT_CHILD_SETUP_INVALID_WQE_ERR_1,
- FC_CMDPKT_CHILD_SETUP_INVALID_WQE_ERR_2,
- FC_CLEAEQ_WQE_ERR,
- FC_WQEFETCH_WQE_MSN_ERR,
- FC_WQEFETCH_QUINFO_ERR,
-
- /* detail type of FC_AEQ_EVENT_CTX_FATAL_ERROR */
- FC_SCQE_ERR_BIT_ERR = 9,
- FC_UPDMA_ADDR_REQ_SRQ_ERR,
- FC_SOLICHILDDMA_ADDR_REQ_ERR,
- FC_UNSOLICHILDDMA_ADDR_REQ_ERR,
- FC_SQE_CHILD_SETUP_QINFO_ERR_1,
- FC_SQE_CHILD_SETUP_QINFO_ERR_2,
- FC_CMDPKT_CHILD_SETUP_QINFO_ERR_1,
- FC_CMDPKT_CHILD_SETUP_QINFO_ERR_2,
- FC_CMDPKT_CHILD_SETUP_PMSN_ERR,
- FC_CLEAEQ_CTX_ERR,
- FC_WQEFETCH_CTX_ERR,
- FC_FLUSH_QPC_ERR_LQP,
- FC_FLUSH_QPC_ERR_SMF,
- FC_PREFETCH_QPC_ERR_PCM_MHIT_LQP,
- FC_PREFETCH_QPC_ERR_PCM_MHIT_FQG,
- FC_PREFETCH_QPC_ERR_PCM_ABM_FQG,
- FC_PREFETCH_QPC_ERR_MAP_FQG,
- FC_PREFETCH_QPC_ERR_MAP_LQP,
- FC_PREFETCH_QPC_ERR_SMF_RTN,
- FC_PREFETCH_QPC_ERR_CFG,
- FC_PREFETCH_QPC_ERR_FLSH_HIT,
- FC_PREFETCH_QPC_ERR_FLSH_ACT,
- FC_PREFETCH_QPC_ERR_ABM_W_RSC,
- FC_PREFETCH_QPC_ERR_RW_ABM,
- FC_PREFETCH_QPC_ERR_DEFAULT,
- FC_CHILDHASH_INSERT_SW_ERR,
- FC_CHILDHASH_LOOKUP_SW_ERR,
- FC_CHILDHASH_DEL_SW_ERR,
- FC_EXCH_ID_FREE_SW_ERR,
- FC_FLOWHASH_INSERT_SW_ERR,
- FC_FLOWHASH_LOOKUP_SW_ERR,
- FC_FLOWHASH_DEL_SW_ERR,
- FC_FLUSH_QPC_ERR_USED,
- FC_FLUSH_QPC_ERR_OUTER_LOCK,
- FC_SETUP_SESSION_ERR,
-
- FC_AEQ_EVT_ERR_CODE_BUTT
-
-};
-
-/* AEQ data structure */
-struct spfc_aqe_data {
- union {
- struct {
- u32 conn_id : 16;
- u32 rsvd : 8;
- u32 evt_code : 8;
- } wd0;
-
- u32 data0;
- };
-
- union {
- struct {
- u32 xid : 20;
- u32 rsvd : 12;
- } wd1;
-
- u32 data1;
- };
-};
-
-/* Control Section: Common Header */
-struct spfc_wqe_ctrl_ch {
- union {
- struct {
- u32 bdsl : 8;
- u32 drv_sl : 2;
- u32 rsvd0 : 4;
- u32 wf : 1;
- u32 cf : 1;
- u32 tsl : 5;
- u32 va : 1;
- u32 df : 1;
- u32 cr : 1;
- u32 dif_sl : 3;
- u32 csl : 2;
- u32 ctrl_sl : 2;
- u32 owner : 1;
- } wd0;
-
- u32 ctrl_ch_val;
- };
-};
-
-/* Control Section: Queue Specific Field */
-struct spfc_wqe_ctrl_qsf {
- u32 wqe_sn : 16;
- u32 dump_wqe_sn : 16;
-};
-
-/* DIF info definition in WQE */
-struct spfc_fc_dif_info {
- struct {
- u32 app_tag_ctrl : 3; /* DIF/DIX APP TAG Control */
- /* Bit 0: scenario of the reference tag verify mode.
- *Bit 1: scenario of the reference tag insert/replace mode.
- */
- u32 ref_tag_mode : 2;
- /* 0: fixed; 1: increasement; */
- u32 ref_tag_ctrl : 3; /* The DIF/DIX Reference tag control */
- u32 grd_agm_ini_ctrl : 3;
- u32 grd_agm_ctrl : 2; /* Bit 0: DIF/DIX guard verify algorithm control */
- /* Bit 1: DIF/DIX guard replace or insert algorithm control */
- u32 grd_ctrl : 3; /* The DIF/DIX Guard control */
- u32 dif_verify_type : 2; /* verify type */
- u32 difx_ref_esc : 1; /* Check blocks whose reference tag contains 0xFFFF flag */
- u32 difx_app_esc : 1;/* Check blocks whose application tag contains 0xFFFF flag */
- u32 rsvd : 8;
- u32 sct_size : 1; /* Sector size, 1: 4K; 0: 512 */
- u32 smd_tp : 2;
- u32 difx_en : 1;
- } wd0;
-
- struct {
- u32 cmp_app_tag_msk : 16;
- u32 rsvd : 7;
- u32 lun_qos_en : 2;
- u32 vpid : 7;
- } wd1;
-
- u16 cmp_app_tag;
- u16 rep_app_tag;
-
- u32 cmp_ref_tag;
- u32 rep_ref_tag;
-};
-
-/* Task Section: TMF SQE for INI */
-struct spfc_tmf_info {
- union {
- struct {
- u32 reset_exch_end : 16;
- u32 reset_exch_start : 16;
- } bs;
- u32 value;
- } w0;
-
- union {
- struct {
- u32 reset_did : 24;
- u32 reset_type : 2;
- u32 marker_sts : 1;
- u32 rsvd0 : 5;
- } bs;
- u32 value;
- } w1;
-
- union {
- struct {
- u32 reset_sid : 24;
- u32 rsvd0 : 8;
- } bs;
- u32 value;
- } w2;
-
- u8 reset_lun[8];
-};
-
-/* Task Section: CMND SQE for INI */
-struct spfc_sqe_icmnd {
- u8 fcp_cmnd_iu[FC_SCSI_CMDIU_LEN];
- union {
- struct spfc_fc_dif_info dif_info;
- struct spfc_tmf_info tmf;
- } info;
-};
-
-/* Task Section: ABTS SQE */
-struct spfc_sqe_abts {
- u32 fh_parm_abts;
- u32 hotpooltag;
- u32 release_timer;
-};
-
-struct spfc_keys {
- struct {
- u32 smac1 : 8;
- u32 smac0 : 8;
- u32 rsv : 16;
- } wd0;
-
- u8 smac[4];
-
- u8 dmac[6];
- u8 sid[3];
- u8 did[3];
-
- struct {
- u32 port_id : 3;
- u32 host_id : 2;
- u32 rsvd : 27;
- } wd5;
- u32 rsvd;
-};
-
-/* BDSL: Session Enable WQE.keys field only use 26 bytes room */
-struct spfc_cmdqe_sess_en {
- struct {
- u32 rx_id : 16;
- u32 port_id : 8;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 cid : 20;
- u32 rsvd1 : 12;
- } wd1;
-
- struct {
- u32 conn_id : 16;
- u32 scqn : 16;
- } wd2;
-
- struct {
- u32 xid_p : 20;
- u32 rsvd3 : 12;
- } wd3;
-
- u32 context_gpa_hi;
- u32 context_gpa_lo;
- struct spfc_keys keys;
- u32 context[64];
-};
-
-/* Control Section */
-struct spfc_wqe_ctrl {
- struct spfc_wqe_ctrl_ch ch;
- struct spfc_wqe_ctrl_qsf qsf;
-};
-
-struct spfc_sqe_els_rsp {
- struct {
- u32 echo_flag : 16;
- u32 data_len : 16;
- } wd0;
-
- struct {
- u32 rsvd1 : 27;
- u32 offload_flag : 1;
- u32 lp_bflag : 1;
- u32 clr_io : 1;
- u32 para_update : 2;
- } wd1;
-
- struct {
- u32 seq_cnt : 1;
- u32 e_d_tov : 1;
- u32 rsvd2 : 6;
- u32 class_mode : 8; /* 0:class3, 1:class2*/
- u32 tx_mfs : 16;
- } wd2;
-
- u32 e_d_tov_timer_val;
-
- struct {
- u32 conf : 1;
- u32 rec : 1;
- u32 xfer_dis : 1;
- u32 immi_taskid_cnt : 13;
- u32 immi_taskid_start : 16;
- } wd4;
-
- u32 first_burst_len;
-
- struct {
- u32 reset_exch_end : 16;
- u32 reset_exch_start : 16;
- } wd6;
-
- struct {
- u32 scqn : 16;
- u32 hotpooltag : 16;
- } wd7;
-
- u32 magic_local;
- u32 magic_remote;
- u32 ts_rcv_echo_req;
- u32 sid;
- u32 did;
- u32 context_gpa_hi;
- u32 context_gpa_lo;
-};
-
-struct spfc_sqe_reset_session {
- struct {
- u32 reset_exch_end : 16;
- u32 reset_exch_start : 16;
- } wd0;
-
- struct {
- u32 reset_did : 24;
- u32 mode : 2;
- u32 rsvd : 6;
- } wd1;
-
- struct {
- u32 reset_sid : 24;
- u32 rsvd : 8;
- } wd2;
-
- struct {
- u32 scqn : 16;
- u32 rsvd : 16;
- } wd3;
-};
-
-struct spfc_sqe_nop_sq {
- struct {
- u32 scqn : 16;
- u32 rsvd : 16;
- } wd0;
- u32 magic_num;
-};
-
-struct spfc_sqe_t_els_gs {
- u16 echo_flag;
- u16 data_len;
-
- struct {
- u32 rsvd1 : 9;
- u32 offload_flag : 1;
- u32 origin_hottag : 16;
- u32 rec_flag : 1;
- u32 rec_support : 1;
- u32 lp_bflag : 1;
- u32 clr_io : 1;
- u32 para_update : 2;
- } wd4;
-
- struct {
- u32 seq_cnt : 1;
- u32 e_d_tov : 1;
- u32 rsvd2 : 14;
- u32 tx_mfs : 16;
- } wd5;
-
- u32 e_d_tov_timer_val;
-
- struct {
- u32 reset_exch_end : 16;
- u32 reset_exch_start : 16;
- } wd6;
-
- struct {
- u32 scqn : 16;
- u32 hotpooltag : 16; /* used for send ELS rsp */
- } wd7;
-
- u32 sid;
- u32 did;
- u32 context_gpa_hi;
- u32 context_gpa_lo;
- u32 origin_magicnum;
-};
-
-struct spfc_sqe_els_gs_elsrsp_comm {
- u16 rsvd;
- u16 data_len;
-};
-
-struct spfc_sqe_lpb_msg {
- struct {
- u32 reset_exch_end : 16;
- u32 reset_exch_start : 16;
- } w0;
-
- struct {
- u32 reset_did : 24;
- u32 reset_type : 2;
- u32 rsvd0 : 6;
- } w1;
-
- struct {
- u32 reset_sid : 24;
- u32 rsvd0 : 8;
- } w2;
-
- u16 tmf_exch_id;
- u16 rsvd1;
-
- u8 reset_lun[8];
-};
-
-/* SQE Task Section's Contents except Common Header */
-union spfc_sqe_ts_cont {
- struct spfc_sqe_icmnd icmnd;
- struct spfc_sqe_abts abts;
- struct spfc_sqe_els_rsp els_rsp;
- struct spfc_sqe_t_els_gs t_els_gs;
- struct spfc_sqe_els_gs_elsrsp_comm els_gs_elsrsp_comm;
- struct spfc_sqe_reset_session reset_session;
- struct spfc_sqe_lpb_msg lpb_msg;
- struct spfc_sqe_nop_sq nop_sq;
- u32 value[17];
-};
-
-struct spfc_sqe_nvme_icmnd_part2 {
- u8 nvme_cmnd_iu_part2_data[FC_NVME_CMDIU_LEN - FC_SCSI_CMDIU_LEN];
-};
-
-union spfc_sqe_ts_ex {
- struct spfc_sqe_nvme_icmnd_part2 nvme_icmnd_part2;
- u32 value[12];
-};
-
-struct spfc_sqe_ts {
- /* SQE Task Section's Common Header */
- u32 local_xid : 16; /* local exch_id, icmnd/els send used for hotpooltag */
- u32 crc_inj : 1;
- u32 immi_std : 1;
- u32 cdb_type : 1; /* cdb_type = 0:CDB_LEN = 16B, cdb_type = 1:CDB_LEN = 32B */
- u32 rsvd : 5; /* used for loopback saving bdsl's num */
- u32 task_type : 8;
-
- struct {
- u16 conn_id;
- u16 remote_xid;
- } wd0;
-
- u32 xid : 20;
- u32 sqn : 12;
- u32 cid;
- u32 magic_num;
- union spfc_sqe_ts_cont cont;
-};
-
-struct spfc_constant_sge {
- u32 buf_addr_hi;
- u32 buf_addr_lo;
-};
-
-struct spfc_variable_sge {
- u32 buf_addr_hi;
- u32 buf_addr_lo;
-
- struct {
- u32 buf_len : 31;
- u32 r_flag : 1;
- } wd0;
-
- struct {
- u32 buf_addr_gpa : 16;
- u32 xid : 14;
- u32 extension_flag : 1;
- u32 last_flag : 1;
- } wd1;
-};
-
-#define FC_WQE_SIZE 256
-/* SQE, should not be over 256B */
-struct spfc_sqe {
- struct spfc_wqe_ctrl ctrl_sl;
- u32 sid;
- u32 did;
- u64 wqe_gpa; /* gpa shift 6 bit to right*/
- u64 db_val;
- union spfc_sqe_ts_ex ts_ex;
- struct spfc_variable_sge esge[3];
- struct spfc_wqe_ctrl ectrl_sl;
- struct spfc_sqe_ts ts_sl;
- struct spfc_variable_sge sge[2];
-};
-
-struct spfc_rqe_ctrl {
- struct spfc_wqe_ctrl_ch ch;
-
- struct {
- u16 wqe_msn;
- u16 dump_wqe_msn;
- } wd0;
-};
-
-struct spfc_rqe_drv {
- struct {
- u32 rsvd0 : 16;
- u32 user_id : 16;
- } wd0;
-
- u32 rsvd1;
-};
-
-/* RQE,should not be over 32B */
-struct spfc_rqe {
- struct spfc_rqe_ctrl ctrl_sl;
- u32 cqe_gpa_h;
- u32 cqe_gpa_l;
- struct spfc_constant_sge bds_sl;
- struct spfc_rqe_drv drv_sl;
-};
-
-struct spfc_cmdqe_abort {
- struct {
- u32 rx_id : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 ox_id : 16;
- u32 rsvd1 : 12;
- u32 trsp_send : 1;
- u32 tcmd_send : 1;
- u32 immi : 1;
- u32 reply_sts : 1;
- } wd1;
-
- struct {
- u32 conn_id : 16;
- u32 scqn : 16;
- } wd2;
-
- struct {
- u32 xid : 20;
- u32 rsvd : 12;
- } wd3;
-
- struct {
- u32 cid : 20;
- u32 rsvd : 12;
- } wd4;
- struct {
- u32 hotpooltag : 16;
- u32 rsvd : 16;
- } wd5; /* v6 new define */
- /* abort time out. Used for abort and io cmd reach ucode in different path
- * and io cmd will not arrive.
- */
- u32 time_out;
- u32 magic_num;
-};
-
-struct spfc_cmdqe_abts_rsp {
- struct {
- u32 rx_id : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 ox_id : 16;
- u32 rsvd1 : 4;
- u32 port_id : 4;
- u32 payload_len : 7;
- u32 rsp_type : 1;
- } wd1;
-
- struct {
- u32 conn_id : 16;
- u32 scqn : 16;
- } wd2;
-
- struct {
- u32 xid : 20;
- u32 rsvd : 12;
- } wd3;
-
- struct {
- u32 cid : 20;
- u32 rsvd : 12;
- } wd4;
-
- struct {
- u32 req_rx_id : 16;
- u32 hotpooltag : 16;
- } wd5;
-
- /* payload length is according to rsp_type:1DWORD or 3DWORD */
- u32 payload[3];
-};
-
-struct spfc_cmdqe_buffer_clear {
- struct {
- u32 rsvd1 : 16;
- u32 rsvd0 : 8;
- u32 wqe_type : 8;
- } wd0;
-
- struct {
- u32 rx_id_end : 16;
- u32 rx_id_start : 16;
- } wd1;
-
- u32 scqn;
- u32 wd3;
-};
-
-struct spfc_cmdqe_flush_sq {
- struct {
- u32 entry_count : 16;
- u32 rsvd : 8;
- u32 wqe_type : 8;
- } wd0;
-
- struct {
- u32 scqn : 16;
- u32 port_id : 4;
- u32 pos : 11;
- u32 last_wqe : 1;
- } wd1;
-
- struct {
- u32 rsvd : 4;
- u32 clr_pos : 12;
- u32 pkt_ptr : 16;
- } wd2;
-
- struct {
- u32 first_sq_xid : 24;
- u32 sqqid_start_per_session : 4;
- u32 sqcnt_per_session : 4;
- } wd3;
-};
-
-struct spfc_cmdqe_dump_exch {
- struct {
- u32 rsvd1 : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- u16 oqid_wr;
- u16 oqid_rd;
-
- u32 host_id;
- u32 func_id;
- u32 cache_id;
- u32 exch_id;
-};
-
-struct spfc_cmdqe_creat_srqc {
- struct {
- u32 rsvd1 : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- u32 srqc_gpa_h;
- u32 srqc_gpa_l;
-
- u32 srqc[16]; /* srqc_size=64B */
-};
-
-struct spfc_cmdqe_delete_srqc {
- struct {
- u32 rsvd1 : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- u32 srqc_gpa_h;
- u32 srqc_gpa_l;
-};
-
-struct spfc_cmdqe_clr_srq {
- struct {
- u32 rsvd1 : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 scqn : 16;
- u32 srq_type : 16;
- } wd1;
-
- u32 srqc_gpa_h;
- u32 srqc_gpa_l;
-};
-
-struct spfc_cmdqe_creat_scqc {
- struct {
- u32 rsvd1 : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 scqn : 16;
- u32 rsvd2 : 16;
- } wd1;
-
- u32 scqc[16]; /* scqc_size=64B */
-};
-
-struct spfc_cmdqe_delete_scqc {
- struct {
- u32 rsvd1 : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 scqn : 16;
- u32 rsvd2 : 16;
- } wd1;
-};
-
-struct spfc_cmdqe_creat_ssqc {
- struct {
- u32 rsvd1 : 4;
- u32 xid : 20;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 scqn : 16;
- u32 rsvd2 : 16;
- } wd1;
- u32 context_gpa_hi;
- u32 context_gpa_lo;
-
- u32 ssqc[64]; /* ssqc_size=256B */
-};
-
-struct spfc_cmdqe_delete_ssqc {
- struct {
- u32 entry_count : 4;
- u32 xid : 20;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 scqn : 16;
- u32 rsvd2 : 16;
- } wd1;
- u32 context_gpa_hi;
- u32 context_gpa_lo;
-};
-
-/* add xid free via cmdq */
-struct spfc_cmdqe_exch_id_free {
- struct {
- u32 task_id : 16;
- u32 port_id : 8;
- u32 rsvd0 : 8;
- } wd0;
-
- u32 magic_num;
-
- struct {
- u32 scqn : 16;
- u32 hotpool_tag : 16;
- } wd2;
- struct {
- u32 rsvd1 : 31;
- u32 clear_abort_flag : 1;
- } wd3;
- u32 sid;
- u32 did;
- u32 type; /* ELS/ELS RSP/IO */
-};
-
-struct spfc_cmdqe_cmdqe_dfx {
- struct {
- u32 rsvd1 : 4;
- u32 xid : 20;
- u32 task_type : 8;
- } wd0;
-
- struct {
- u32 qid_crclen : 12;
- u32 cid : 20;
- } wd1;
- u32 context_gpa_hi;
- u32 context_gpa_lo;
- u32 dfx_type;
-
- u32 rsv[16];
-};
-
-struct spfc_sqe_t_rsp {
- struct {
- u32 rsvd1 : 16;
- u32 fcp_rsp_len : 8;
- u32 busy_rsp : 3;
- u32 immi : 1;
- u32 mode : 1;
- u32 conf : 1;
- u32 fill : 2;
- } wd0;
-
- u32 hotpooltag;
-
- union {
- struct {
- u32 addr_h;
- u32 addr_l;
- } gpa;
-
- struct {
- u32 data[23]; /* FCP_RESP payload buf, 92B rsvd */
- } buf;
- } payload;
-};
-
-struct spfc_sqe_tmf_t_rsp {
- struct {
- u32 scqn : 16;
- u32 fcp_rsp_len : 8;
- u32 pkt_nosnd_flag : 3; /* tmf rsp snd flag, 0:snd, 1: not snd, Driver ignore */
- u32 reset_type : 2;
- u32 conf : 1;
- u32 fill : 2;
- } wd0;
-
- struct {
- u32 reset_exch_end : 16;
- u32 reset_exch_start : 16;
- } wd1;
-
- struct {
- u16 hotpooltag; /*tmf rsp hotpooltag, Driver ignore */
- u16 rsvd;
- } wd2;
-
- u8 lun[8]; /* Lun ID */
- u32 data[20]; /* FCP_RESP payload buf, 80B rsvd */
-};
-
-struct spfc_sqe_tresp_ts {
- /* SQE Task Section's Common Header */
- u16 local_xid;
- u8 rsvd0;
- u8 task_type;
-
- struct {
- u16 conn_id;
- u16 remote_xid;
- } wd0;
-
- u32 xid : 20;
- u32 sqn : 12;
- u32 cid;
- u32 magic_num;
- struct spfc_sqe_t_rsp t_rsp;
-};
-
-struct spfc_sqe_tmf_resp_ts {
- /* SQE Task Section's Common Header */
- u16 local_xid;
- u8 rsvd0;
- u8 task_type;
-
- struct {
- u16 conn_id;
- u16 remote_xid;
- } wd0;
-
- u32 xid : 20;
- u32 sqn : 12;
- u32 cid;
- u32 magic_num; /* magic num */
- struct spfc_sqe_tmf_t_rsp tmf_rsp;
-};
-
-/* SQE for fcp response, max TSL is 120B */
-struct spfc_sqe_tresp {
- struct spfc_wqe_ctrl ctrl_sl;
- u64 taskrsvd;
- u64 wqe_gpa;
- u64 db_val;
- union spfc_sqe_ts_ex ts_ex;
- struct spfc_variable_sge esge[3];
- struct spfc_wqe_ctrl ectrl_sl;
- struct spfc_sqe_tresp_ts ts_sl;
-};
-
-/* SQE for tmf response, max TSL is 120B */
-struct spfc_sqe_tmf_rsp {
- struct spfc_wqe_ctrl ctrl_sl;
- u64 taskrsvd;
- u64 wqe_gpa;
- u64 db_val;
- union spfc_sqe_ts_ex ts_ex;
- struct spfc_variable_sge esge[3];
- struct spfc_wqe_ctrl ectrl_sl;
- struct spfc_sqe_tmf_resp_ts ts_sl;
-};
-
-/* SCQE Common Header */
-struct spfc_scqe_ch {
- struct {
- u32 task_type : 8;
- u32 sqn : 13;
- u32 cqe_remain_cnt : 3;
- u32 err_code : 7;
- u32 owner : 1;
- } wd0;
-};
-
-struct spfc_scqe_type {
- struct spfc_scqe_ch ch;
-
- u32 rsvd0;
-
- u16 conn_id;
- u16 rsvd4;
-
- u32 rsvd1[12];
-
- struct {
- u32 done : 1;
- u32 rsvd : 23;
- u32 dif_vry_rst : 8;
- } wd0;
-};
-
-struct spfc_scqe_sess_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 xid_qpn : 20;
- u32 rsvd1 : 12;
- } wd0;
-
- struct {
- u32 conn_id : 16;
- u32 rsvd3 : 16;
- } wd1;
-
- struct {
- u32 cid : 20;
- u32 rsvd2 : 12;
- } wd2;
-
- u64 rsvd3;
-};
-
-struct spfc_scqe_comm_rsp_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd0;
-
- struct {
- u32 conn_id : 16;
- u32 hotpooltag : 16; /* ucode return hotpooltag to drv */
- } wd1;
-
- u32 magic_num;
-};
-
-struct spfc_scqe_iresp {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd0;
-
- struct {
- u32 conn_id : 16;
- u32 rsvd0 : 3;
- u32 user_id_num : 8;
- u32 dif_info : 5;
- } wd1;
-
- struct {
- u32 scsi_status : 8;
- u32 fcp_flag : 8;
- u32 hotpooltag : 16; /* ucode return hotpooltag to drv */
- } wd2;
-
- u32 fcp_resid;
- u32 fcp_sns_len;
- u32 fcp_rsp_len;
- u32 magic_num;
- u16 user_id[FC_SENSEDATA_USERID_CNT_MAX];
- u32 rsv1;
-};
-
-struct spfc_scqe_nvme_iresp {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd0;
-
- struct {
- u32 conn_id : 16;
- u32 eresp_flag : 8;
- u32 user_id_num : 8;
- } wd1;
-
- struct {
- u32 scsi_status : 8;
- u32 fcp_flag : 8;
- u32 hotpooltag : 16; /* ucode return hotpooltag to drv */
- } wd2;
- u32 magic_num;
- u32 eresp[8];
-};
-
-#pragma pack(1)
-struct spfc_dif_result {
- u8 vrd_rpt;
- u16 pad;
- u8 rcv_pi_vb;
- u32 rcv_pi_h;
- u32 rcv_pi_l;
- u16 vrf_agm_imm;
- u16 ri_agm_imm;
-};
-
-#pragma pack()
-
-struct spfc_scqe_dif_result {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd0;
-
- struct {
- u32 conn_id : 16;
- u32 rsvd0 : 11;
- u32 dif_info : 5;
- } wd1;
-
- struct {
- u32 scsi_status : 8;
- u32 fcp_flag : 8;
- u32 hotpooltag : 16; /* ucode return hotpooltag to drv */
- } wd2;
-
- u32 fcp_resid;
- u32 fcp_sns_len;
- u32 fcp_rsp_len;
- u32 magic_num;
-
- u32 rsv1[3];
- struct spfc_dif_result difinfo;
-};
-
-struct spfc_scqe_rcv_abts_rsp {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd0;
-
- struct {
- u32 conn_id : 16;
- u32 hotpooltag : 16;
- } wd1;
-
- struct {
- u32 fh_rctrl : 8;
- u32 rsvd0 : 24;
- } wd2;
-
- struct {
- u32 did : 24;
- u32 rsvd1 : 8;
- } wd3;
-
- struct {
- u32 sid : 24;
- u32 rsvd2 : 8;
- } wd4;
-
- /* payload length is according to fh_rctrl:1DWORD or 3DWORD */
- u32 payload[3];
- u32 magic_num;
-};
-
-struct spfc_scqe_fcp_rsp_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd0;
-
- struct {
- u32 conn_id : 16;
- u32 rsvd0 : 10;
- u32 immi : 1;
- u32 dif_info : 5;
- } wd1;
-
- u32 magic_num;
- u32 hotpooltag;
- u32 xfer_rsp;
- u32 rsvd[5];
-
- u32 dif_tmp[4]; /* HW will overwrite it */
-};
-
-struct spfc_scqe_rcv_els_cmd {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 did : 24;
- u32 class_mode : 8; /* 0:class3, 1:class2 */
- } wd0;
-
- struct {
- u32 sid : 24;
- u32 rsvd1 : 8;
- } wd1;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd2;
-
- struct {
- u32 user_id_num : 16;
- u32 data_len : 16;
- } wd3;
- /* User ID of SRQ SGE, used for drvier buffer release */
- u16 user_id[FC_LS_GS_USERID_CNT_MAX];
- u32 ts;
-};
-
-struct spfc_scqe_param_check_scq {
- struct spfc_scqe_ch ch;
-
- u8 rsvd0[3];
- u8 port_id;
-
- u16 scqn;
- u16 check_item;
-
- u16 exch_id_load;
- u16 exch_id;
-
- u16 historty_type;
- u16 entry_count;
-
- u32 xid;
-
- u32 gpa_h;
- u32 gpa_l;
-
- u32 magic_num;
- u32 hotpool_tag;
-
- u32 payload_len;
- u32 sub_err;
-
- u32 rsvd2[3];
-};
-
-struct spfc_scqe_rcv_abts_cmd {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 did : 24;
- u32 rsvd0 : 8;
- } wd0;
-
- struct {
- u32 sid : 24;
- u32 rsvd1 : 8;
- } wd1;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd2;
-};
-
-struct spfc_scqe_rcv_els_gs_rsp {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd1;
-
- struct {
- u32 conn_id : 16;
- u32 data_len : 16; /* ELS/GS RSP Payload length */
- } wd2;
-
- struct {
- u32 did : 24;
- u32 rsvd : 6;
- u32 echo_rsp : 1;
- u32 end_rsp : 1;
- } wd3;
-
- struct {
- u32 sid : 24;
- u32 user_id_num : 8;
- } wd4;
-
- struct {
- u32 rsvd : 16;
- u32 hotpooltag : 16;
- } wd5;
-
- u32 magic_num;
- u16 user_id[FC_LS_GS_USERID_CNT_MAX];
-};
-
-struct spfc_scqe_rcv_flush_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rsvd0 : 4;
- u32 clr_pos : 12;
- u32 port_id : 8;
- u32 last_flush : 8;
- } wd0;
-};
-
-struct spfc_scqe_rcv_clear_buf_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rsvd0 : 24;
- u32 port_id : 8;
- } wd0;
-};
-
-struct spfc_scqe_clr_srq_rsp {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 srq_type : 16;
- u32 cur_wqe_msn : 16;
- } wd0;
-};
-
-struct spfc_scqe_itmf_marker_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd1;
-
- struct {
- u32 did : 24;
- u32 end_rsp : 8;
- } wd2;
-
- struct {
- u32 sid : 24;
- u32 rsvd1 : 8;
- } wd3;
-
- struct {
- u32 hotpooltag : 16;
- u32 rsvd : 16;
- } wd4;
-
- u32 magic_num;
-};
-
-struct spfc_scqe_abts_marker_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd1;
-
- struct {
- u32 did : 24;
- u32 end_rsp : 8;
- } wd2;
-
- struct {
- u32 sid : 24;
- u32 io_state : 8;
- } wd3;
-
- struct {
- u32 hotpooltag : 16;
- u32 rsvd : 16;
- } wd4;
-
- u32 magic_num;
-};
-
-struct spfc_scqe_ini_abort_sts {
- struct spfc_scqe_ch ch;
-
- struct {
- u32 rx_id : 16;
- u32 ox_id : 16;
- } wd1;
-
- struct {
- u32 did : 24;
- u32 rsvd : 8;
- } wd2;
-
- struct {
- u32 sid : 24;
- u32 io_state : 8;
- } wd3;
-
- struct {
- u32 hotpooltag : 16;
- u32 rsvd : 16;
- } wd4;
-
- u32 magic_num;
-};
-
-struct spfc_scqe_sq_nop_sts {
- struct spfc_scqe_ch ch;
- struct {
- u32 rsvd : 16;
- u32 sqn : 16;
- } wd0;
- struct {
- u32 rsvd : 16;
- u32 conn_id : 16;
- } wd1;
- u32 magic_num;
-};
-
-/* SCQE, should not be over 64B */
-#define FC_SCQE_SIZE 64
-union spfc_scqe {
- struct spfc_scqe_type common;
- struct spfc_scqe_sess_sts sess_sts; /* session enable/disable/delete sts */
- struct spfc_scqe_comm_rsp_sts comm_sts; /* aborts/abts_rsp/els rsp sts */
- struct spfc_scqe_rcv_clear_buf_sts clear_sts; /* clear buffer sts */
- struct spfc_scqe_rcv_flush_sts flush_sts; /* flush sq sts */
- struct spfc_scqe_iresp iresp;
- struct spfc_scqe_rcv_abts_rsp rcv_abts_rsp; /* recv abts rsp */
- struct spfc_scqe_fcp_rsp_sts fcp_rsp_sts; /* Read/Write/Rsp sts */
- struct spfc_scqe_rcv_els_cmd rcv_els_cmd; /* recv els cmd */
- struct spfc_scqe_rcv_abts_cmd rcv_abts_cmd; /* recv abts cmd */
- struct spfc_scqe_rcv_els_gs_rsp rcv_els_gs_rsp; /* recv els/gs rsp */
- struct spfc_scqe_clr_srq_rsp clr_srq_sts;
- struct spfc_scqe_itmf_marker_sts itmf_marker_sts; /* tmf marker */
- struct spfc_scqe_abts_marker_sts abts_marker_sts; /* abts marker */
- struct spfc_scqe_dif_result dif_result;
- struct spfc_scqe_param_check_scq param_check_sts;
- struct spfc_scqe_nvme_iresp nvme_iresp;
- struct spfc_scqe_ini_abort_sts ini_abort_sts;
- struct spfc_scqe_sq_nop_sts sq_nop_sts;
-};
-
-struct spfc_cmdqe_type {
- struct {
- u32 rx_id : 16;
- u32 rsvd0 : 8;
- u32 task_type : 8;
- } wd0;
-};
-
-struct spfc_cmdqe_send_ack {
- struct {
- u32 rx_id : 16;
- u32 immi_stand : 1;
- u32 rsvd0 : 7;
- u32 task_type : 8;
- } wd0;
-
- u32 xid;
- u32 cid;
-};
-
-struct spfc_cmdqe_send_aeq_err {
- struct {
- u32 errorevent : 8;
- u32 errortype : 8;
- u32 portid : 8;
- u32 task_type : 8;
- } wd0;
-};
-
-/* CMDQE, variable length */
-union spfc_cmdqe {
- struct spfc_cmdqe_type common;
- struct spfc_cmdqe_sess_en session_enable;
- struct spfc_cmdqe_abts_rsp snd_abts_rsp;
- struct spfc_cmdqe_abort snd_abort;
- struct spfc_cmdqe_buffer_clear buffer_clear;
- struct spfc_cmdqe_flush_sq flush_sq;
- struct spfc_cmdqe_dump_exch dump_exch;
- struct spfc_cmdqe_creat_srqc create_srqc;
- struct spfc_cmdqe_delete_srqc delete_srqc;
- struct spfc_cmdqe_clr_srq clear_srq;
- struct spfc_cmdqe_creat_scqc create_scqc;
- struct spfc_cmdqe_delete_scqc delete_scqc;
- struct spfc_cmdqe_send_ack send_ack;
- struct spfc_cmdqe_send_aeq_err send_aeqerr;
- struct spfc_cmdqe_creat_ssqc createssqc;
- struct spfc_cmdqe_delete_ssqc deletessqc;
- struct spfc_cmdqe_cmdqe_dfx dfx_info;
- struct spfc_cmdqe_exch_id_free xid_free;
-};
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_io.c b/drivers/scsi/spfc/hw/spfc_io.c
deleted file mode 100644
index 7184eb6a10af..000000000000
--- a/drivers/scsi/spfc/hw/spfc_io.c
+++ /dev/null
@@ -1,1193 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "spfc_io.h"
-#include "spfc_module.h"
-#include "spfc_service.h"
-
-#define SPFC_SGE_WD1_XID_MASK 0x3fff
-
-u32 dif_protect_opcode = INVALID_VALUE32;
-u32 dif_app_esc_check = SPFC_DIF_APP_REF_ESC_CHECK;
-u32 dif_ref_esc_check = SPFC_DIF_APP_REF_ESC_CHECK;
-u32 grd_agm_ini_ctrl = SPFC_DIF_CRC_CS_INITIAL_CONFIG_BY_BIT0_1;
-u32 ref_tag_no_increase;
-u32 dix_flag;
-u32 grd_ctrl;
-u32 grd_agm_ctrl = SPFC_DIF_GUARD_VERIFY_ALGORITHM_CTL_T10_CRC16;
-u32 cmp_app_tag_mask = 0xffff;
-u32 app_tag_ctrl;
-u32 ref_tag_ctrl;
-u32 ref_tag_mod = INVALID_VALUE32;
-u32 rep_ref_tag;
-u32 rx_rep_ref_tag;
-u16 cmp_app_tag;
-u16 rep_app_tag;
-
-static void spfc_dif_err_count(struct spfc_hba_info *hba, u8 info)
-{
- u8 dif_info = info;
-
- if (dif_info & SPFC_TX_DIF_ERROR_FLAG) {
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_SEND_DIFERR_ALL);
- if (dif_info & SPFC_DIF_ERROR_CODE_CRC)
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_SEND_DIFERR_CRC);
-
- if (dif_info & SPFC_DIF_ERROR_CODE_APP)
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_SEND_DIFERR_APP);
-
- if (dif_info & SPFC_DIF_ERROR_CODE_REF)
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_SEND_DIFERR_REF);
- } else {
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_RECV_DIFERR_ALL);
- if (dif_info & SPFC_DIF_ERROR_CODE_CRC)
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_RECV_DIFERR_CRC);
-
- if (dif_info & SPFC_DIF_ERROR_CODE_APP)
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_RECV_DIFERR_APP);
-
- if (dif_info & SPFC_DIF_ERROR_CODE_REF)
- SPFC_DIF_ERR_STAT(hba, SPFC_DIF_RECV_DIFERR_REF);
- }
-}
-
-void spfc_build_no_dif_control(struct unf_frame_pkg *pkg,
- struct spfc_fc_dif_info *info)
-{
- struct spfc_fc_dif_info *dif_info = info;
-
- /* dif enable or disable */
- dif_info->wd0.difx_en = SPFC_DIF_DISABLE;
-
- dif_info->wd1.vpid = pkg->qos_level;
- dif_info->wd1.lun_qos_en = 1;
-}
-
-void spfc_dif_action_forward(struct spfc_fc_dif_info *dif_info_l1,
- struct unf_dif_control_info *dif_ctrl_u1)
-{
- dif_info_l1->wd0.grd_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_VERIFY_CRC_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_VERIFY
- : SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.grd_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_REPLACE_CRC_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_REPLACE
- : SPFC_DIF_GARD_REF_APP_CTRL_FORWARD;
-
- dif_info_l1->wd0.ref_tag_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_VERIFY_LBA_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_VERIFY
- : SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.ref_tag_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_REPLACE_LBA_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_REPLACE
- : SPFC_DIF_GARD_REF_APP_CTRL_FORWARD;
-
- dif_info_l1->wd0.app_tag_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_VERIFY_APP_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_VERIFY
- : SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.app_tag_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_REPLACE_APP_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_REPLACE
- : SPFC_DIF_GARD_REF_APP_CTRL_FORWARD;
-}
-
-void spfc_dif_action_delete(struct spfc_fc_dif_info *dif_info_l1,
- struct unf_dif_control_info *dif_ctrl_u1)
-{
- dif_info_l1->wd0.grd_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_VERIFY_CRC_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_VERIFY
- : SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.grd_ctrl |= SPFC_DIF_GARD_REF_APP_CTRL_DELETE;
-
- dif_info_l1->wd0.ref_tag_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_VERIFY_LBA_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_VERIFY
- : SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.ref_tag_ctrl |= SPFC_DIF_GARD_REF_APP_CTRL_DELETE;
-
- dif_info_l1->wd0.app_tag_ctrl |=
- (dif_ctrl_u1->protect_opcode & UNF_VERIFY_APP_MASK)
- ? SPFC_DIF_GARD_REF_APP_CTRL_VERIFY
- : SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.app_tag_ctrl |= SPFC_DIF_GARD_REF_APP_CTRL_DELETE;
-}
-
-static void spfc_convert_dif_action(struct unf_dif_control_info *dif_ctrl,
- struct spfc_fc_dif_info *dif_info)
-{
- struct spfc_fc_dif_info *dif_info_l1 = NULL;
- struct unf_dif_control_info *dif_ctrl_u1 = NULL;
-
- dif_info_l1 = dif_info;
- dif_ctrl_u1 = dif_ctrl;
-
- switch (UNF_DIF_ACTION_MASK & dif_ctrl_u1->protect_opcode) {
- case UNF_DIF_ACTION_VERIFY_AND_REPLACE:
- case UNF_DIF_ACTION_VERIFY_AND_FORWARD:
- spfc_dif_action_forward(dif_info_l1, dif_ctrl_u1);
- break;
-
- case UNF_DIF_ACTION_INSERT:
- dif_info_l1->wd0.grd_ctrl |=
- SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.grd_ctrl |= SPFC_DIF_GARD_REF_APP_CTRL_INSERT;
- dif_info_l1->wd0.ref_tag_ctrl |=
- SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.ref_tag_ctrl |=
- SPFC_DIF_GARD_REF_APP_CTRL_INSERT;
- dif_info_l1->wd0.app_tag_ctrl |=
- SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY;
- dif_info_l1->wd0.app_tag_ctrl |=
- SPFC_DIF_GARD_REF_APP_CTRL_INSERT;
- break;
-
- case UNF_DIF_ACTION_VERIFY_AND_DELETE:
- spfc_dif_action_delete(dif_info_l1, dif_ctrl_u1);
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "Unknown dif protect opcode 0x%x",
- dif_ctrl_u1->protect_opcode);
- break;
- }
-}
-
-void spfc_get_dif_info_l1(struct spfc_fc_dif_info *dif_info_l1,
- struct unf_dif_control_info *dif_ctrl_u1)
-{
- dif_info_l1->wd1.cmp_app_tag_msk = cmp_app_tag_mask;
-
- dif_info_l1->rep_app_tag = dif_ctrl_u1->app_tag;
- dif_info_l1->rep_ref_tag = dif_ctrl_u1->start_lba;
-
- dif_info_l1->cmp_app_tag = dif_ctrl_u1->app_tag;
- dif_info_l1->cmp_ref_tag = dif_ctrl_u1->start_lba;
-
- if (cmp_app_tag != 0)
- dif_info_l1->cmp_app_tag = cmp_app_tag;
-
- if (rep_app_tag != 0)
- dif_info_l1->rep_app_tag = rep_app_tag;
-
- if (rep_ref_tag != 0)
- dif_info_l1->rep_ref_tag = rep_ref_tag;
-}
-
-void spfc_build_dif_control(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg,
- struct spfc_fc_dif_info *dif_info)
-{
- struct spfc_fc_dif_info *dif_info_l1 = NULL;
- struct unf_dif_control_info *dif_ctrl_u1 = NULL;
-
- dif_info_l1 = dif_info;
- dif_ctrl_u1 = &pkg->dif_control;
-
- /* dif enable or disable */
- dif_info_l1->wd0.difx_en = SPFC_DIF_ENABLE;
-
- dif_info_l1->wd1.vpid = pkg->qos_level;
- dif_info_l1->wd1.lun_qos_en = 1;
-
- /* 512B + 8 size mode */
- dif_info_l1->wd0.sct_size = (dif_ctrl_u1->flags & UNF_DIF_SECTSIZE_4KB)
- ? SPFC_DIF_SECTOR_4KB_MODE
- : SPFC_DIF_SECTOR_512B_MODE;
-
- /* dif type 1 */
- dif_info_l1->wd0.dif_verify_type = dif_type;
-
- /* Check whether the 0xffff app or ref domain is isolated */
- /* If all ff messages are displayed in type1 app, checkcheck sector
- * dif_info_l1->wd0.difx_app_esc = SPFC_DIF_APP_REF_ESC_CHECK
- */
-
- dif_info_l1->wd0.difx_app_esc = dif_app_esc_check;
-
- /* type1 ref tag If all ff is displayed, check sector is required */
- dif_info_l1->wd0.difx_ref_esc = dif_ref_esc_check;
-
- /* Currently, only t10 crc is supported */
- dif_info_l1->wd0.grd_agm_ctrl = 0;
-
- /* Set this parameter based on the values of bit zero and bit one.
- * The initial value is 0, and the value is UNF_DEFAULT_CRC_GUARD_SEED
- */
- dif_info_l1->wd0.grd_agm_ini_ctrl = grd_agm_ini_ctrl;
- dif_info_l1->wd0.app_tag_ctrl = 0;
- dif_info_l1->wd0.grd_ctrl = 0;
- dif_info_l1->wd0.ref_tag_ctrl = 0;
-
- /* Convert the verify operation, replace, forward, insert,
- * and delete operations based on the actual operation code of the upper
- * layer
- */
- if (dif_protect_opcode != INVALID_VALUE32) {
- dif_ctrl_u1->protect_opcode =
- dif_protect_opcode |
- (dif_ctrl_u1->protect_opcode & UNF_DIF_ACTION_MASK);
- }
-
- spfc_convert_dif_action(dif_ctrl_u1, dif_info_l1);
- dif_info_l1->wd0.app_tag_ctrl |= app_tag_ctrl;
-
- /* Address self-increase mode */
- dif_info_l1->wd0.ref_tag_mode =
- (dif_ctrl_u1->protect_opcode & UNF_DIF_ACTION_NO_INCREASE_REFTAG)
- ? (BOTH_NONE)
- : (BOTH_INCREASE);
-
- if (ref_tag_mod != INVALID_VALUE32)
- dif_info_l1->wd0.ref_tag_mode = ref_tag_mod;
-
- /* This parameter is used only when type 3 is set to 0xffff. */
- spfc_get_dif_info_l1(dif_info_l1, dif_ctrl_u1);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) sid_did(0x%x_0x%x) package type(0x%x) apptag(0x%x) flag(0x%x) opcode(0x%x) fcpdl(0x%x) statlba(0x%x)",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did, pkg->type, pkg->dif_control.app_tag,
- pkg->dif_control.flags, pkg->dif_control.protect_opcode,
- pkg->dif_control.fcp_dl, pkg->dif_control.start_lba);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) cover dif control info, app:cmp_tag(0x%x) cmp_tag_mask(0x%x) rep_tag(0x%x), ref:tag_mode(0x%x) cmp_tag(0x%x) rep_tag(0x%x).",
- hba->port_cfg.port_id, dif_info_l1->cmp_app_tag,
- dif_info_l1->wd1.cmp_app_tag_msk, dif_info_l1->rep_app_tag,
- dif_info_l1->wd0.ref_tag_mode, dif_info_l1->cmp_ref_tag,
- dif_info_l1->rep_ref_tag);
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "Port(0x%x) cover dif control info, ctrl:grd(0x%x) ref(0x%x) app(0x%x).",
- hba->port_cfg.port_id, dif_info_l1->wd0.grd_ctrl,
- dif_info_l1->wd0.ref_tag_ctrl,
- dif_info_l1->wd0.app_tag_ctrl);
-}
-
-static u32 spfc_fill_external_sgl_page(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg,
- struct unf_esgl_page *esgl_page,
- u32 sge_num, int direction,
- u32 context_id, u32 dif_flag)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 index = 0;
- u32 sge_num_per_page = 0;
- u32 buffer_addr = 0;
- u32 buf_len = 0;
- char *buf = NULL;
- ulong phys = 0;
- struct unf_esgl_page *unf_esgl_page = NULL;
- struct spfc_variable_sge *sge = NULL;
-
- unf_esgl_page = esgl_page;
- while (sge_num > 0) {
- /* Obtains the initial address of the sge page */
- sge = (struct spfc_variable_sge *)unf_esgl_page->page_address;
-
- /* Calculate the number of sge on each page */
- sge_num_per_page = (unf_esgl_page->page_size) / sizeof(struct spfc_variable_sge);
-
- /* Fill in sgl page. The last sge of each page is link sge by
- * default
- */
- for (index = 0; index < (sge_num_per_page - 1); index++) {
- UNF_GET_SGL_ENTRY(ret, (void *)pkg, &buf, &buf_len, dif_flag);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
- phys = (ulong)buf;
- sge[index].buf_addr_hi = UNF_DMA_HI32(phys);
- sge[index].buf_addr_lo = UNF_DMA_LO32(phys);
- sge[index].wd0.buf_len = buf_len;
- sge[index].wd0.r_flag = 0;
- sge[index].wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sge[index].wd1.last_flag = SPFC_WQE_SGE_NOT_LAST_FLAG;
-
- /* Parity bit */
- sge[index].wd1.buf_addr_gpa = (sge[index].buf_addr_lo >> UNF_SHIFT_16);
- sge[index].wd1.xid = (context_id & SPFC_SGE_WD1_XID_MASK);
-
- spfc_cpu_to_big32(&sge[index], sizeof(struct spfc_variable_sge));
-
- sge_num--;
- if (sge_num == 0)
- break;
- }
-
- /* sge Set the end flag on the last sge of the page if all the
- * pages have been filled.
- */
- if (sge_num == 0) {
- sge[index].wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sge[index].wd1.last_flag = SPFC_WQE_SGE_LAST_FLAG;
-
- /* Parity bit */
- buffer_addr = be32_to_cpu(sge[index].buf_addr_lo);
- sge[index].wd1.buf_addr_gpa = (buffer_addr >> UNF_SHIFT_16);
- sge[index].wd1.xid = (context_id & SPFC_SGE_WD1_XID_MASK);
-
- spfc_cpu_to_big32(&sge[index].wd1, SPFC_DWORD_BYTE);
- }
- /* If only one sge is left empty, the sge reserved on the page
- * is used for filling.
- */
- else if (sge_num == 1) {
- UNF_GET_SGL_ENTRY(ret, (void *)pkg, &buf, &buf_len,
- dif_flag);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
- phys = (ulong)buf;
- sge[index].buf_addr_hi = UNF_DMA_HI32(phys);
- sge[index].buf_addr_lo = UNF_DMA_LO32(phys);
- sge[index].wd0.buf_len = buf_len;
- sge[index].wd0.r_flag = 0;
- sge[index].wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sge[index].wd1.last_flag = SPFC_WQE_SGE_LAST_FLAG;
-
- /* Parity bit */
- sge[index].wd1.buf_addr_gpa = (sge[index].buf_addr_lo >> UNF_SHIFT_16);
- sge[index].wd1.xid = (context_id & SPFC_SGE_WD1_XID_MASK);
-
- spfc_cpu_to_big32(&sge[index], sizeof(struct spfc_variable_sge));
-
- sge_num--;
- } else {
- /* Apply for a new sgl page and fill in link sge */
- UNF_GET_FREE_ESGL_PAGE(unf_esgl_page, hba->lport, pkg);
- if (!unf_esgl_page) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Get free esgl page failed.");
- return UNF_RETURN_ERROR;
- }
- phys = unf_esgl_page->esgl_phy_addr;
- sge[index].buf_addr_hi = UNF_DMA_HI32(phys);
- sge[index].buf_addr_lo = UNF_DMA_LO32(phys);
-
- /* For the cascaded wqe, you only need to enter the
- * cascading buffer address and extension flag, and do
- * not need to fill in other fields
- */
- sge[index].wd0.buf_len = 0;
- sge[index].wd0.r_flag = 0;
- sge[index].wd1.extension_flag = SPFC_WQE_SGE_EXTEND_FLAG;
- sge[index].wd1.last_flag = SPFC_WQE_SGE_NOT_LAST_FLAG;
-
- /* parity bit */
- sge[index].wd1.buf_addr_gpa = (sge[index].buf_addr_lo >> UNF_SHIFT_16);
- sge[index].wd1.xid = (context_id & SPFC_SGE_WD1_XID_MASK);
-
- spfc_cpu_to_big32(&sge[index], sizeof(struct spfc_variable_sge));
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]Port(0x%x) SID(0x%x) DID(0x%x) RXID(0x%x) build esgl left sge num: %u.",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did,
- pkg->frame_head.oxid_rxid, sge_num);
- }
-
- return RETURN_OK;
-}
-
-static u32 spfc_build_local_dif_sgl(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, struct spfc_sqe *sqe,
- int direction, u32 bd_sge_num)
-{
- u32 ret = UNF_RETURN_ERROR;
- char *buf = NULL;
- u32 buf_len = 0;
- ulong phys = 0;
- u32 dif_sge_place = 0;
-
- /* DIF SGE must be followed by BD SGE */
- dif_sge_place = ((bd_sge_num <= pkg->entry_count) ? bd_sge_num : pkg->entry_count);
-
- /* The entry_count= 0 needs to be specially processed and does not need
- * to be mounted. As long as len is set to zero, Last-bit is set to one,
- * and E-bit is set to 0.
- */
- if (pkg->dif_control.dif_sge_count == 0) {
- sqe->sge[dif_sge_place].buf_addr_hi = 0;
- sqe->sge[dif_sge_place].buf_addr_lo = 0;
- sqe->sge[dif_sge_place].wd0.buf_len = 0;
- } else {
- UNF_CM_GET_DIF_SGL_ENTRY(ret, (void *)pkg, &buf, &buf_len);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "DOUBLE DIF Get Dif Buf Fail.");
- return UNF_RETURN_ERROR;
- }
- phys = (ulong)buf;
- sqe->sge[dif_sge_place].buf_addr_hi = UNF_DMA_HI32(phys);
- sqe->sge[dif_sge_place].buf_addr_lo = UNF_DMA_LO32(phys);
- sqe->sge[dif_sge_place].wd0.buf_len = buf_len;
- }
-
- /* rdma flag. If the fc is not used, enter 0. */
- sqe->sge[dif_sge_place].wd0.r_flag = 0;
-
- /* parity bit */
- sqe->sge[dif_sge_place].wd1.buf_addr_gpa = 0;
- sqe->sge[dif_sge_place].wd1.xid = 0;
-
- /* The local sgl does not use the cascading SGE. Therefore, the value of
- * this field is always 0.
- */
- sqe->sge[dif_sge_place].wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sqe->sge[dif_sge_place].wd1.last_flag = SPFC_WQE_SGE_LAST_FLAG;
-
- spfc_cpu_to_big32(&sqe->sge[dif_sge_place], sizeof(struct spfc_variable_sge));
-
- return RETURN_OK;
-}
-
-static u32 spfc_build_external_dif_sgl(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg,
- struct spfc_sqe *sqe, int direction,
- u32 bd_sge_num)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct unf_esgl_page *esgl_page = NULL;
- ulong phys = 0;
- u32 left_sge_num = 0;
- u32 dif_sge_place = 0;
- struct spfc_parent_ssq_info *ssq = NULL;
- u32 ssqn = 0;
-
- ssqn = (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
- ssq = &hba->parent_queue_mgr->shared_queue[ssqn].parent_ssq_info;
-
- /* DIF SGE must be followed by BD SGE */
- dif_sge_place = ((bd_sge_num <= pkg->entry_count) ? bd_sge_num : pkg->entry_count);
-
- /* Allocate the first page first */
- UNF_GET_FREE_ESGL_PAGE(esgl_page, hba->lport, pkg);
- if (!esgl_page) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "DOUBLE DIF Get External Page Fail.");
- return UNF_RETURN_ERROR;
- }
-
- phys = esgl_page->esgl_phy_addr;
-
- /* Configuring the Address of the Cascading Page */
- sqe->sge[dif_sge_place].buf_addr_hi = UNF_DMA_HI32(phys);
- sqe->sge[dif_sge_place].buf_addr_lo = UNF_DMA_LO32(phys);
-
- /* Configuring Control Information About the Cascading Page */
- sqe->sge[dif_sge_place].wd0.buf_len = 0;
- sqe->sge[dif_sge_place].wd0.r_flag = 0;
- sqe->sge[dif_sge_place].wd1.extension_flag = SPFC_WQE_SGE_EXTEND_FLAG;
- sqe->sge[dif_sge_place].wd1.last_flag = SPFC_WQE_SGE_NOT_LAST_FLAG;
-
- /* parity bit */
- sqe->sge[dif_sge_place].wd1.buf_addr_gpa = 0;
- sqe->sge[dif_sge_place].wd1.xid = 0;
-
- spfc_cpu_to_big32(&sqe->sge[dif_sge_place], sizeof(struct spfc_variable_sge));
-
- /* Fill in the sge information on the cascading page */
- left_sge_num = pkg->dif_control.dif_sge_count;
- ret = spfc_fill_external_sgl_page(hba, pkg, esgl_page, left_sge_num,
- direction, ssq->context_id, true);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
-
- return RETURN_OK;
-}
-
-static u32 spfc_build_local_sgl(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, struct spfc_sqe *sqe,
- int direction)
-{
- u32 ret = UNF_RETURN_ERROR;
- char *buf = NULL;
- u32 buf_len = 0;
- u32 index = 0;
- ulong phys = 0;
-
- for (index = 0; index < pkg->entry_count; index++) {
- UNF_CM_GET_SGL_ENTRY(ret, (void *)pkg, &buf, &buf_len);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
-
- phys = (ulong)buf;
- sqe->sge[index].buf_addr_hi = UNF_DMA_HI32(phys);
- sqe->sge[index].buf_addr_lo = UNF_DMA_LO32(phys);
- sqe->sge[index].wd0.buf_len = buf_len;
-
- /* rdma flag. If the fc is not used, enter 0. */
- sqe->sge[index].wd0.r_flag = 0;
-
- /* parity bit */
- sqe->sge[index].wd1.buf_addr_gpa = SPFC_ZEROCOPY_PCIE_TEMPLATE_VALUE;
- sqe->sge[index].wd1.xid = 0;
-
- /* The local sgl does not use the cascading SGE. Therefore, the
- * value of this field is always 0.
- */
- sqe->sge[index].wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sqe->sge[index].wd1.last_flag = SPFC_WQE_SGE_NOT_LAST_FLAG;
-
- if (index == (pkg->entry_count - 1)) {
- /* Sets the last WQE end flag 1 */
- sqe->sge[index].wd1.last_flag = SPFC_WQE_SGE_LAST_FLAG;
- }
-
- spfc_cpu_to_big32(&sqe->sge[index], sizeof(struct spfc_variable_sge));
- }
-
- /* Adjust the length of the BDSL field in the CTRL domain. */
- SPFC_ADJUST_DATA(sqe->ctrl_sl.ch.wd0.bdsl,
- SPFC_BYTES_TO_QW_NUM((pkg->entry_count *
- sizeof(struct spfc_variable_sge))));
-
- /* The entry_count= 0 needs to be specially processed and does not need
- * to be mounted. As long as len is set to zero, Last-bit is set to one,
- * and E-bit is set to 0.
- */
- if (pkg->entry_count == 0) {
- sqe->sge[ARRAY_INDEX_0].buf_addr_hi = 0;
- sqe->sge[ARRAY_INDEX_0].buf_addr_lo = 0;
- sqe->sge[ARRAY_INDEX_0].wd0.buf_len = 0;
-
- /* rdma flag. This field is not used in fc. Set it to 0. */
- sqe->sge[ARRAY_INDEX_0].wd0.r_flag = 0;
-
- /* parity bit */
- sqe->sge[ARRAY_INDEX_0].wd1.buf_addr_gpa = SPFC_ZEROCOPY_PCIE_TEMPLATE_VALUE;
- sqe->sge[ARRAY_INDEX_0].wd1.xid = 0;
-
- /* The local sgl does not use the cascading SGE. Therefore, the
- * value of this field is always 0.
- */
- sqe->sge[ARRAY_INDEX_0].wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sqe->sge[ARRAY_INDEX_0].wd1.last_flag = SPFC_WQE_SGE_LAST_FLAG;
-
- spfc_cpu_to_big32(&sqe->sge[ARRAY_INDEX_0], sizeof(struct spfc_variable_sge));
-
- /* Adjust the length of the BDSL field in the CTRL domain. */
- SPFC_ADJUST_DATA(sqe->ctrl_sl.ch.wd0.bdsl,
- SPFC_BYTES_TO_QW_NUM(sizeof(struct spfc_variable_sge)));
- }
-
- return RETURN_OK;
-}
-
-static u32 spfc_build_external_sgl(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, struct spfc_sqe *sqe,
- int direction, u32 bd_sge_num)
-{
- u32 ret = UNF_RETURN_ERROR;
- char *buf = NULL;
- struct unf_esgl_page *esgl_page = NULL;
- ulong phys = 0;
- u32 buf_len = 0;
- u32 index = 0;
- u32 left_sge_num = 0;
- u32 local_sge_num = 0;
- struct spfc_parent_ssq_info *ssq = NULL;
- u16 ssqn = 0;
-
- ssqn = (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
- ssq = &hba->parent_queue_mgr->shared_queue[ssqn].parent_ssq_info;
-
- /* Ensure that the value of bd_sge_num is greater than or equal to one
- */
- local_sge_num = bd_sge_num - 1;
-
- for (index = 0; index < local_sge_num; index++) {
- UNF_CM_GET_SGL_ENTRY(ret, (void *)pkg, &buf, &buf_len);
- if (unlikely(ret != RETURN_OK))
- return UNF_RETURN_ERROR;
-
- phys = (ulong)buf;
-
- sqe->sge[index].buf_addr_hi = UNF_DMA_HI32(phys);
- sqe->sge[index].buf_addr_lo = UNF_DMA_LO32(phys);
- sqe->sge[index].wd0.buf_len = buf_len;
-
- /* RDMA flag, which is not used by FC. */
- sqe->sge[index].wd0.r_flag = 0;
- sqe->sge[index].wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sqe->sge[index].wd1.last_flag = SPFC_WQE_SGE_NOT_LAST_FLAG;
-
- /* parity bit */
- sqe->sge[index].wd1.buf_addr_gpa = SPFC_ZEROCOPY_PCIE_TEMPLATE_VALUE;
- sqe->sge[index].wd1.xid = 0;
-
- spfc_cpu_to_big32(&sqe->sge[index], sizeof(struct spfc_variable_sge));
- }
-
- /* Calculate the number of remaining sge. */
- left_sge_num = pkg->entry_count - local_sge_num;
- /* Adjust the length of the BDSL field in the CTRL domain. */
- SPFC_ADJUST_DATA(sqe->ctrl_sl.ch.wd0.bdsl,
- SPFC_BYTES_TO_QW_NUM((bd_sge_num * sizeof(struct spfc_variable_sge))));
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "alloc extended sgl page,leftsge:%d", left_sge_num);
- /* Allocating the first cascading page */
- UNF_GET_FREE_ESGL_PAGE(esgl_page, hba->lport, pkg);
- if (unlikely(!esgl_page))
- return UNF_RETURN_ERROR;
-
- phys = esgl_page->esgl_phy_addr;
-
- /* Configuring the Address of the Cascading Page */
- sqe->sge[index].buf_addr_hi = (u32)UNF_DMA_HI32(phys);
- sqe->sge[index].buf_addr_lo = (u32)UNF_DMA_LO32(phys);
-
- /* Configuring Control Information About the Cascading Page */
- sqe->sge[index].wd0.buf_len = 0;
- sqe->sge[index].wd0.r_flag = 0;
- sqe->sge[index].wd1.extension_flag = SPFC_WQE_SGE_EXTEND_FLAG;
- sqe->sge[index].wd1.last_flag = SPFC_WQE_SGE_NOT_LAST_FLAG;
-
- /* parity bit */
- sqe->sge[index].wd1.buf_addr_gpa = SPFC_ZEROCOPY_PCIE_TEMPLATE_VALUE;
- sqe->sge[index].wd1.xid = 0;
-
- spfc_cpu_to_big32(&sqe->sge[index], sizeof(struct spfc_variable_sge));
-
- /* Fill in the sge information on the cascading page. */
- ret = spfc_fill_external_sgl_page(hba, pkg, esgl_page, left_sge_num,
- direction, ssq->context_id, false);
- if (ret != RETURN_OK)
- return UNF_RETURN_ERROR;
- /* Copy the extended data sge to the extended sge of the extended wqe.*/
- if (left_sge_num > 0) {
- memcpy(sqe->esge, (void *)esgl_page->page_address,
- SPFC_WQE_MAX_ESGE_NUM * sizeof(struct spfc_variable_sge));
- }
-
- return RETURN_OK;
-}
-
-u32 spfc_build_sgl_by_local_sge_num(struct unf_frame_pkg *pkg,
- struct spfc_hba_info *hba, struct spfc_sqe *sqe,
- int direction, u32 bd_sge_num)
-{
- u32 ret = RETURN_OK;
-
- if (pkg->entry_count <= bd_sge_num)
- ret = spfc_build_local_sgl(hba, pkg, sqe, direction);
- else
- ret = spfc_build_external_sgl(hba, pkg, sqe, direction, bd_sge_num);
-
- return ret;
-}
-
-u32 spfc_conf_dual_sgl_info(struct unf_frame_pkg *pkg,
- struct spfc_hba_info *hba, struct spfc_sqe *sqe,
- int direction, u32 bd_sge_num, bool double_sgl)
-{
- u32 ret = RETURN_OK;
-
- if (double_sgl) {
- /* Adjust the length of the DIF_SL field in the CTRL domain */
- SPFC_ADJUST_DATA(sqe->ctrl_sl.ch.wd0.dif_sl,
- SPFC_BYTES_TO_QW_NUM(sizeof(struct spfc_variable_sge)));
-
- if (pkg->dif_control.dif_sge_count <= SPFC_WQE_SGE_DIF_ENTRY_NUM)
- ret = spfc_build_local_dif_sgl(hba, pkg, sqe, direction, bd_sge_num);
- else
- ret = spfc_build_external_dif_sgl(hba, pkg, sqe, direction, bd_sge_num);
- }
-
- return ret;
-}
-
-u32 spfc_build_sgl(struct spfc_hba_info *hba, struct unf_frame_pkg *pkg,
- struct spfc_sqe *sqe, int direction, u32 dif_flag)
-{
-#define SPFC_ESGE_CNT 3
- u32 ret = RETURN_OK;
- u32 bd_sge_num = SPFC_WQE_SGE_ENTRY_NUM;
- bool double_sgl = false;
-
- if (dif_flag != 0 && (pkg->dif_control.flags & UNF_DIF_DOUBLE_SGL)) {
- bd_sge_num = SPFC_WQE_SGE_ENTRY_NUM - SPFC_WQE_SGE_DIF_ENTRY_NUM;
- double_sgl = true;
- }
-
- /* Only one wqe local sge can be loaded. If more than one wqe local sge
- * is used, use the esgl
- */
- ret = spfc_build_sgl_by_local_sge_num(pkg, hba, sqe, direction, bd_sge_num);
-
- if (unlikely(ret != RETURN_OK))
- return ret;
-
- /* Configuring Dual SGL Information for DIF */
- ret = spfc_conf_dual_sgl_info(pkg, hba, sqe, direction, bd_sge_num, double_sgl);
-
- return ret;
-}
-
-void spfc_adjust_dix(struct unf_frame_pkg *pkg, struct spfc_fc_dif_info *dif_info,
- u8 task_type)
-{
- u8 tasktype = task_type;
- struct spfc_fc_dif_info *dif_info_l1 = NULL;
-
- dif_info_l1 = dif_info;
-
- if (dix_flag == 1) {
- if (tasktype == SPFC_SQE_FCP_IWRITE ||
- tasktype == SPFC_SQE_FCP_TRD) {
- if ((UNF_DIF_ACTION_MASK & pkg->dif_control.protect_opcode) ==
- UNF_DIF_ACTION_VERIFY_AND_FORWARD) {
- dif_info_l1->wd0.grd_ctrl |=
- SPFC_DIF_GARD_REF_APP_CTRL_REPLACE;
- dif_info_l1->wd0.grd_agm_ctrl =
- SPFC_DIF_GUARD_VERIFY_IP_CHECKSUM_REPLACE_CRC16;
- }
-
- if ((UNF_DIF_ACTION_MASK & pkg->dif_control.protect_opcode) ==
- UNF_DIF_ACTION_VERIFY_AND_DELETE) {
- dif_info_l1->wd0.grd_agm_ctrl =
- SPFC_DIF_GUARD_VERIFY_IP_CHECKSUM_REPLACE_CRC16;
- }
- }
-
- if (tasktype == SPFC_SQE_FCP_IREAD ||
- tasktype == SPFC_SQE_FCP_TWR) {
- if ((UNF_DIF_ACTION_MASK &
- pkg->dif_control.protect_opcode) ==
- UNF_DIF_ACTION_VERIFY_AND_FORWARD) {
- dif_info_l1->wd0.grd_ctrl |=
- SPFC_DIF_GARD_REF_APP_CTRL_REPLACE;
- dif_info_l1->wd0.grd_agm_ctrl =
- SPFC_DIF_GUARD_VERIFY_CRC16_REPLACE_IP_CHECKSUM;
- }
-
- if ((UNF_DIF_ACTION_MASK &
- pkg->dif_control.protect_opcode) ==
- UNF_DIF_ACTION_INSERT) {
- dif_info_l1->wd0.grd_agm_ctrl =
- SPFC_DIF_GUARD_VERIFY_CRC16_REPLACE_IP_CHECKSUM;
- }
- }
- }
-
- if (grd_agm_ctrl != 0)
- dif_info_l1->wd0.grd_agm_ctrl = grd_agm_ctrl;
-
- if (grd_ctrl != 0)
- dif_info_l1->wd0.grd_ctrl = grd_ctrl;
-}
-
-void spfc_get_dma_direction_by_fcp_cmnd(const struct unf_fcp_cmnd *fcp_cmnd,
- int *dma_direction, u8 *task_type)
-{
- if (UNF_FCP_WR_DATA & fcp_cmnd->control) {
- *task_type = SPFC_SQE_FCP_IWRITE;
- *dma_direction = DMA_TO_DEVICE;
- } else if (UNF_GET_TASK_MGMT_FLAGS(fcp_cmnd->control) != 0) {
- *task_type = SPFC_SQE_FCP_ITMF;
- *dma_direction = DMA_FROM_DEVICE;
- } else {
- *task_type = SPFC_SQE_FCP_IREAD;
- *dma_direction = DMA_FROM_DEVICE;
- }
-}
-
-static inline u32 spfc_build_icmnd_wqe(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg,
- struct spfc_sqe *sge)
-{
- u32 ret = RETURN_OK;
- int direction = 0;
- u8 tasktype = 0;
- struct unf_fcp_cmnd *fcp_cmnd = NULL;
- struct spfc_sqe *sqe = sge;
- u32 dif_flag = 0;
-
- fcp_cmnd = pkg->fcp_cmnd;
- if (unlikely(!fcp_cmnd)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Package's FCP commond pointer is NULL.");
-
- return UNF_RETURN_ERROR;
- }
-
- spfc_get_dma_direction_by_fcp_cmnd(fcp_cmnd, &direction, &tasktype);
-
- spfc_build_icmnd_wqe_ts_header(pkg, sqe, tasktype, hba->exi_base, hba->port_index);
-
- spfc_build_icmnd_wqe_ctrls(pkg, sqe);
-
- spfc_build_icmnd_wqe_ts(hba, pkg, &sqe->ts_sl, &sqe->ts_ex);
-
- if (sqe->ts_sl.task_type != SPFC_SQE_FCP_ITMF) {
- if (pkg->dif_control.protect_opcode == UNF_DIF_ACTION_NONE) {
- dif_flag = 0;
- spfc_build_no_dif_control(pkg, &sqe->ts_sl.cont.icmnd.info.dif_info);
- } else {
- dif_flag = 1;
- spfc_build_dif_control(hba, pkg, &sqe->ts_sl.cont.icmnd.info.dif_info);
- spfc_adjust_dix(pkg,
- &sqe->ts_sl.cont.icmnd.info.dif_info,
- tasktype);
- }
- }
-
- ret = spfc_build_sgl(hba, pkg, sqe, direction, dif_flag);
-
- sqe->sid = UNF_GET_SID(pkg);
- sqe->did = UNF_GET_DID(pkg);
-
- return ret;
-}
-
-u32 spfc_send_scsi_cmnd(void *hba, struct unf_frame_pkg *pkg)
-{
- struct spfc_hba_info *spfc_hba = NULL;
- struct spfc_parent_sq_info *parent_sq = NULL;
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_sqe sqe;
- u16 ssqn;
- struct spfc_parent_queue_info *parent_queue = NULL;
-
- /* input param check */
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
-
- SPFC_CHECK_PKG_ALLOCTIME(pkg);
- memset(&sqe, 0, sizeof(struct spfc_sqe));
- spfc_hba = hba;
-
- /* 1. find parent sq for scsi_cmnd(pkg) */
- parent_sq = spfc_find_parent_sq_by_pkg(spfc_hba, pkg);
- if (unlikely(!parent_sq)) {
- /* Do not need to print info */
- return UNF_RETURN_ERROR;
- }
-
- pkg->qos_level += spfc_hba->vpid_start;
-
- /* 2. build cmnd wqe (to sqe) for scsi_cmnd(pkg) */
- ret = spfc_build_icmnd_wqe(spfc_hba, pkg, &sqe);
- if (unlikely(ret != RETURN_OK)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[fail]Port(0x%x) Build WQE failed, SID(0x%x) DID(0x%x) pkg type(0x%x) hottag(0x%x).",
- spfc_hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did, pkg->type, UNF_GET_XCHG_TAG(pkg));
-
- return ret;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "Port(0x%x) RPort(0x%x) send FCP_CMND TYPE(0x%x) Local_Xid(0x%x) hottag(0x%x) LBA(0x%llx)",
- spfc_hba->port_cfg.port_id, parent_sq->rport_index,
- sqe.ts_sl.task_type, sqe.ts_sl.local_xid,
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX],
- *((u64 *)pkg->fcp_cmnd->cdb));
-
- ssqn = (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
- if (sqe.ts_sl.task_type == SPFC_SQE_FCP_ITMF) {
- parent_queue = container_of(parent_sq, struct spfc_parent_queue_info,
- parent_sq_info);
- ret = spfc_suspend_sqe_and_send_nop(spfc_hba, parent_queue, &sqe, pkg);
- return ret;
- }
- /* 3. En-Queue Parent SQ for scsi_cmnd(pkg) sqe */
- ret = spfc_parent_sq_enqueue(parent_sq, &sqe, ssqn);
-
- return ret;
-}
-
-static void spfc_ini_status_default_handler(struct spfc_scqe_iresp *iresp,
- struct unf_frame_pkg *pkg)
-{
- u8 control = 0;
- u16 com_err_code = 0;
-
- control = iresp->wd2.fcp_flag & SPFC_CTRL_MASK;
-
- if (iresp->fcp_resid != 0) {
- com_err_code = UNF_IO_FAILED;
- pkg->residus_len = iresp->fcp_resid;
- } else {
- com_err_code = UNF_IO_SUCCESS;
- pkg->residus_len = 0;
- }
-
- pkg->status = spfc_fill_pkg_status(com_err_code, control, iresp->wd2.scsi_status);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]Fill package with status: 0x%x, residus len: 0x%x",
- pkg->status, pkg->residus_len);
-}
-
-static void spfc_check_fcp_rsp_iu(struct spfc_scqe_iresp *iresp,
- struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg)
-{
- u8 scsi_status = 0;
- u8 control = 0;
-
- control = (u8)iresp->wd2.fcp_flag;
- scsi_status = (u8)iresp->wd2.scsi_status;
-
- /* FcpRspIU with Little End from IOB WQE to COM's pkg also */
- if (control & FCP_RESID_UNDER_MASK) {
- /* under flow: usually occurs in inquiry */
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]I_STS IOB posts under flow with residus len: %u, FCP residue: %u.",
- pkg->residus_len, iresp->fcp_resid);
-
- if (pkg->residus_len != iresp->fcp_resid)
- pkg->status = spfc_fill_pkg_status(UNF_IO_FAILED, control, scsi_status);
- else
- pkg->status = spfc_fill_pkg_status(UNF_IO_UNDER_FLOW, control, scsi_status);
- }
-
- if (control & FCP_RESID_OVER_MASK) {
- /* over flow: error happened */
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]I_STS IOB posts over flow with residus len: %u, FCP residue: %u.",
- pkg->residus_len, iresp->fcp_resid);
-
- if (pkg->residus_len != iresp->fcp_resid)
- pkg->status = spfc_fill_pkg_status(UNF_IO_FAILED, control, scsi_status);
- else
- pkg->status = spfc_fill_pkg_status(UNF_IO_OVER_FLOW, control, scsi_status);
- }
-
- pkg->unf_rsp_pload_bl.length = 0;
- pkg->unf_sense_pload_bl.length = 0;
-
- if (control & FCP_RSP_LEN_VALID_MASK) {
- /* dma by chip */
- pkg->unf_rsp_pload_bl.buffer_ptr = NULL;
-
- pkg->unf_rsp_pload_bl.length = iresp->fcp_rsp_len;
- pkg->byte_orders |= UNF_BIT_3;
- }
-
- if (control & FCP_SNS_LEN_VALID_MASK) {
- /* dma by chip */
- pkg->unf_sense_pload_bl.buffer_ptr = NULL;
-
- pkg->unf_sense_pload_bl.length = iresp->fcp_sns_len;
- pkg->byte_orders |= UNF_BIT_4;
- }
-
- if (iresp->wd1.user_id_num == 1 &&
- (pkg->unf_sense_pload_bl.length + pkg->unf_rsp_pload_bl.length > 0)) {
- pkg->unf_rsp_pload_bl.buffer_ptr =
- (u8 *)spfc_get_els_buf_by_user_id(hba, (u16)iresp->user_id[ARRAY_INDEX_0]);
- } else if (iresp->wd1.user_id_num > 1) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]receive buff num 0x%x > 1 0x%x",
- iresp->wd1.user_id_num, control);
- }
-}
-
-u16 spfc_get_com_err_code(struct unf_frame_pkg *pkg)
-{
- u16 com_err_code = UNF_IO_FAILED;
- u32 status_subcode = 0;
-
- status_subcode = pkg->status_sub_code;
-
- if (likely(status_subcode == 0))
- com_err_code = 0;
- else if (status_subcode == UNF_DIF_CRC_ERR)
- com_err_code = UNF_IO_DIF_ERROR;
- else if (status_subcode == UNF_DIF_LBA_ERR)
- com_err_code = UNF_IO_DIF_REF_ERROR;
- else if (status_subcode == UNF_DIF_APP_ERR)
- com_err_code = UNF_IO_DIF_GEN_ERROR;
-
- return com_err_code;
-}
-
-void spfc_process_ini_fail_io(struct spfc_hba_info *hba, union spfc_scqe *iresp,
- struct unf_frame_pkg *pkg)
-{
- u16 com_err_code = UNF_IO_FAILED;
-
- /* 1. error stats process */
- if (SPFC_GET_SCQE_STATUS((union spfc_scqe *)(void *)iresp) != 0) {
- switch (SPFC_GET_SCQE_STATUS((union spfc_scqe *)(void *)iresp)) {
- /* I/O not complete: 1.session reset; 2.clear buffer */
- case FC_CQE_BUFFER_CLEAR_IO_COMPLETED:
- case FC_CQE_SESSION_RST_CLEAR_IO_COMPLETED:
- case FC_CQE_SESSION_ONLY_CLEAR_IO_COMPLETED:
- case FC_CQE_WQE_FLUSH_IO_COMPLETED:
- com_err_code = UNF_IO_CLEAN_UP;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[warn]Port(0x%x) INI IO not complete, OX_ID(0x%x) RX_ID(0x%x) status(0x%x)",
- hba->port_cfg.port_id,
- ((struct spfc_scqe_iresp *)iresp)->wd0.ox_id,
- ((struct spfc_scqe_iresp *)iresp)->wd0.rx_id,
- com_err_code);
-
- break;
- /* Allocate task id(oxid) fail */
- case FC_ERROR_INVALID_TASK_ID:
- com_err_code = UNF_IO_NO_XCHG;
- break;
- case FC_ALLOC_EXCH_ID_FAILED:
- com_err_code = UNF_IO_NO_XCHG;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[warn]Port(0x%x) INI IO, tag 0x%x alloc oxid fail.",
- hba->port_cfg.port_id,
- ((struct spfc_scqe_iresp *)iresp)->wd2.hotpooltag);
- break;
- case FC_ERROR_CODE_DATA_DIFX_FAILED:
- com_err_code = pkg->status >> UNF_SHIFT_16;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[warn]Port(0x%x) INI IO, tag 0x%x tx dif error.",
- hba->port_cfg.port_id,
- ((struct spfc_scqe_iresp *)iresp)->wd2.hotpooltag);
- break;
- /* any other: I/O failed --->>> DID error */
- default:
- com_err_code = UNF_IO_FAILED;
- break;
- }
-
- /* fill pkg status & return directly */
- pkg->status =
- spfc_fill_pkg_status(com_err_code,
- ((struct spfc_scqe_iresp *)iresp)->wd2.fcp_flag,
- ((struct spfc_scqe_iresp *)iresp)->wd2.scsi_status);
-
- return;
- }
-
- /* 2. default stats process */
- spfc_ini_status_default_handler((struct spfc_scqe_iresp *)iresp, pkg);
-
- /* 3. FCP RSP IU check */
- spfc_check_fcp_rsp_iu((struct spfc_scqe_iresp *)iresp, hba, pkg);
-}
-
-void spfc_process_dif_result(struct spfc_hba_info *hba, union spfc_scqe *wqe,
- struct unf_frame_pkg *pkg)
-{
- u16 com_err_code = UNF_IO_FAILED;
- u8 dif_info = 0;
-
- dif_info = wqe->common.wd0.dif_vry_rst;
- if (dif_info == SPFC_TX_DIF_ERROR_FLAG) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[error]Port(0x%x) TGT recv tx dif result abnormal.",
- hba->port_cfg.port_id);
- }
-
- pkg->status_sub_code =
- (dif_info & SPFC_DIF_ERROR_CODE_CRC)
- ? UNF_DIF_CRC_ERR
- : ((dif_info & SPFC_DIF_ERROR_CODE_REF)
- ? UNF_DIF_LBA_ERR
- : ((dif_info & SPFC_DIF_ERROR_CODE_APP) ? UNF_DIF_APP_ERR : 0));
- com_err_code = spfc_get_com_err_code(pkg);
- pkg->status = (u32)(com_err_code) << UNF_SHIFT_16;
-
- if (unlikely(com_err_code != 0)) {
- spfc_dif_err_count(hba, dif_info);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[error]Port(0x%x) INI io status with dif result(0x%x),subcode(0x%x) pkg->status(0x%x)",
- hba->port_cfg.port_id, dif_info,
- pkg->status_sub_code, pkg->status);
- }
-}
-
-u32 spfc_scq_recv_iresp(struct spfc_hba_info *hba, union spfc_scqe *wqe)
-{
-#define SPFC_IRSP_USERID_LEN ((FC_SENSEDATA_USERID_CNT_MAX + 1) / 2)
- struct spfc_scqe_iresp *iresp = NULL;
- struct unf_frame_pkg pkg;
- u32 ret = RETURN_OK;
- u16 hot_tag;
-
- FC_CHECK_RETURN_VALUE((hba), UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE((wqe), UNF_RETURN_ERROR);
-
- iresp = (struct spfc_scqe_iresp *)(void *)wqe;
-
- /* 1. Constraints: I_STS remain cnt must be zero */
- if (unlikely(SPFC_GET_SCQE_REMAIN_CNT(wqe) != 0)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) ini_wqe(OX_ID:0x%x RX_ID:0x%x) HotTag(0x%x) remain_cnt(0x%x) abnormal, status(0x%x)",
- hba->port_cfg.port_id, iresp->wd0.ox_id,
- iresp->wd0.rx_id, iresp->wd2.hotpooltag,
- SPFC_GET_SCQE_REMAIN_CNT(wqe),
- SPFC_GET_SCQE_STATUS(wqe));
-
- UNF_PRINT_SFS_LIMIT(UNF_MAJOR, hba->port_cfg.port_id, wqe, sizeof(union spfc_scqe));
-
- /* return directly */
- return UNF_RETURN_ERROR;
- }
-
- spfc_swap_16_in_32((u32 *)iresp->user_id, SPFC_IRSP_USERID_LEN);
-
- memset(&pkg, 0, sizeof(struct unf_frame_pkg));
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = iresp->magic_num;
- pkg.frame_head.oxid_rxid = (((iresp->wd0.ox_id) << UNF_SHIFT_16) | (iresp->wd0.rx_id));
-
- hot_tag = (u16)iresp->wd2.hotpooltag;
- /* 2. HotTag validity check */
- if (likely(hot_tag >= hba->exi_base && (hot_tag < hba->exi_base + hba->exi_count))) {
- pkg.status = UNF_IO_SUCCESS;
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] =
- hot_tag - hba->exi_base;
- } else {
- /* OX_ID error: return by COM */
- pkg.status = UNF_IO_FAILED;
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = INVALID_VALUE16;
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) ini_cmnd_wqe(OX_ID:0x%x RX_ID:0x%x) ox_id invalid, status(0x%x)",
- hba->port_cfg.port_id, iresp->wd0.ox_id, iresp->wd0.rx_id,
- SPFC_GET_SCQE_STATUS(wqe));
-
- UNF_PRINT_SFS_LIMIT(UNF_MAJOR, hba->port_cfg.port_id, wqe,
- sizeof(union spfc_scqe));
- }
-
- /* process dif result */
- spfc_process_dif_result(hba, wqe, &pkg);
-
- /* 3. status check */
- if (unlikely(SPFC_GET_SCQE_STATUS(wqe) ||
- iresp->wd2.scsi_status != 0 || iresp->fcp_resid != 0 ||
- ((iresp->wd2.fcp_flag & SPFC_CTRL_MASK) != 0))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[warn]Port(0x%x) scq_status(0x%x) scsi_status(0x%x) fcp_resid(0x%x) fcp_flag(0x%x)",
- hba->port_cfg.port_id, SPFC_GET_SCQE_STATUS(wqe),
- iresp->wd2.scsi_status, iresp->fcp_resid,
- iresp->wd2.fcp_flag);
-
- /* set pkg status & check fcp_rsp IU */
- spfc_process_ini_fail_io(hba, (union spfc_scqe *)iresp, &pkg);
- }
-
- /* 4. LL_Driver ---to--->>> COM_Driver */
- UNF_LOWLEVEL_SCSI_COMPLETED(ret, hba->lport, &pkg);
- if (iresp->wd1.user_id_num == 1 &&
- (pkg.unf_sense_pload_bl.length + pkg.unf_rsp_pload_bl.length > 0)) {
- spfc_post_els_srq_wqe(&hba->els_srq_info, (u16)iresp->user_id[ARRAY_INDEX_0]);
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Port(0x%x) rport(0x%x) recv(%s) hottag(0x%x) OX_ID(0x%x) RX_ID(0x%x) return(%s)",
- hba->port_cfg.port_id, iresp->wd1.conn_id,
- (SPFC_SCQE_FCP_IRSP == (SPFC_GET_SCQE_TYPE(wqe)) ? "IRESP" : "ITMF_RSP"),
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX], iresp->wd0.ox_id,
- iresp->wd0.rx_id, (ret == RETURN_OK) ? "OK" : "ERROR");
-
- return ret;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_io.h b/drivers/scsi/spfc/hw/spfc_io.h
deleted file mode 100644
index 26d10a51bbe4..000000000000
--- a/drivers/scsi/spfc/hw/spfc_io.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_IO_H
-#define SPFC_IO_H
-
-#include "unf_type.h"
-#include "unf_common.h"
-#include "spfc_hba.h"
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif
-#endif /* __cplusplus */
-
-#define BYTE_PER_DWORD 4
-#define SPFC_TRESP_DIRECT_CARRY_LEN (23 * 4)
-#define FCP_RESP_IU_LEN_BYTE_GOOD_STATUS 24
-#define SPFC_TRSP_IU_CONTROL_OFFSET 2
-#define SPFC_TRSP_IU_FCP_CONF_REP (1 << 12)
-
-struct spfc_dif_io_param {
- u32 all_len;
- u32 buf_len;
- char **buf;
- char *in_buf;
- int drect;
-};
-
-enum dif_mode_type {
- DIF_MODE_NONE = 0x0,
- DIF_MODE_INSERT = 0x1,
- DIF_MODE_REMOVE = 0x2,
- DIF_MODE_FORWARD_OR_REPLACE = 0x3
-};
-
-enum ref_tag_mode_type {
- BOTH_NONE = 0x0,
- RECEIVE_INCREASE = 0x1,
- REPLACE_INCREASE = 0x2,
- BOTH_INCREASE = 0x3
-};
-
-#define SPFC_DIF_DISABLE 0
-#define SPFC_DIF_ENABLE 1
-#define SPFC_DIF_SINGLE_SGL 0
-#define SPFC_DIF_DOUBLE_SGL 1
-#define SPFC_DIF_SECTOR_512B_MODE 0
-#define SPFC_DIF_SECTOR_4KB_MODE 1
-#define SPFC_DIF_TYPE1 0x01
-#define SPFC_DIF_TYPE3 0x03
-#define SPFC_DIF_GUARD_VERIFY_ALGORITHM_CTL_T10_CRC16 0x0
-#define SPFC_DIF_GUARD_VERIFY_CRC16_REPLACE_IP_CHECKSUM 0x1
-#define SPFC_DIF_GUARD_VERIFY_IP_CHECKSUM_REPLACE_CRC16 0x2
-#define SPFC_DIF_GUARD_VERIFY_ALGORITHM_CTL_IP_CHECKSUM 0x3
-#define SPFC_DIF_CRC16_INITIAL_SELECTOR_DEFAUL 0
-#define SPFC_DIF_CRC_CS_INITIAL_CONFIG_BY_REGISTER 0
-#define SPFC_DIF_CRC_CS_INITIAL_CONFIG_BY_BIT0_1 0x4
-
-#define SPFC_DIF_GARD_REF_APP_CTRL_VERIFY 0x4
-#define SPFC_DIF_GARD_REF_APP_CTRL_NOT_VERIFY 0x0
-#define SPFC_DIF_GARD_REF_APP_CTRL_INSERT 0x0
-#define SPFC_DIF_GARD_REF_APP_CTRL_DELETE 0x1
-#define SPFC_DIF_GARD_REF_APP_CTRL_FORWARD 0x2
-#define SPFC_DIF_GARD_REF_APP_CTRL_REPLACE 0x3
-
-#define SPFC_BUILD_RESPONSE_INFO_NON_GAP_MODE0 0
-#define SPFC_BUILD_RESPONSE_INFO_GPA_MODE1 1
-#define SPFC_CONF_SUPPORT 1
-#define SPFC_CONF_NOT_SUPPORT 0
-#define SPFC_XID_INTERVAL 2048
-
-#define SPFC_DIF_ERROR_CODE_MASK 0xe
-#define SPFC_DIF_ERROR_CODE_CRC 0x2
-#define SPFC_DIF_ERROR_CODE_REF 0x4
-#define SPFC_DIF_ERROR_CODE_APP 0x8
-#define SPFC_TX_DIF_ERROR_FLAG (1 << 7)
-
-#define SPFC_DIF_PAYLOAD_TYPE (1 << 0)
-#define SPFC_DIF_CRC_TYPE (1 << 1)
-#define SPFC_DIF_APP_TYPE (1 << 2)
-#define SPFC_DIF_REF_TYPE (1 << 3)
-
-#define SPFC_DIF_SEND_DIFERR_ALL (0)
-#define SPFC_DIF_SEND_DIFERR_CRC (1)
-#define SPFC_DIF_SEND_DIFERR_APP (2)
-#define SPFC_DIF_SEND_DIFERR_REF (3)
-#define SPFC_DIF_RECV_DIFERR_ALL (4)
-#define SPFC_DIF_RECV_DIFERR_CRC (5)
-#define SPFC_DIF_RECV_DIFERR_APP (6)
-#define SPFC_DIF_RECV_DIFERR_REF (7)
-#define SPFC_DIF_ERR_ENABLE (382855)
-#define SPFC_DIF_ERR_DISABLE (0)
-
-#define SPFC_DIF_LENGTH (8)
-#define SPFC_SECT_SIZE_512 (512)
-#define SPFC_SECT_SIZE_4096 (4096)
-#define SPFC_SECT_SIZE_512_8 (520)
-#define SPFC_SECT_SIZE_4096_8 (4104)
-#define SPFC_DIF_SECT_SIZE_APP_OFFSET (2)
-#define SPFC_DIF_SECT_SIZE_LBA_OFFSET (4)
-
-#define SPFC_MAX_IO_TAG (2048)
-#define SPFC_PRINT_WORD (8)
-
-extern u32 dif_protect_opcode;
-extern u32 dif_sect_size;
-extern u32 no_dif_sect_size;
-extern u32 grd_agm_ini_ctrl;
-extern u32 ref_tag_mod;
-extern u32 grd_ctrl;
-extern u32 grd_agm_ctrl;
-extern u32 cmp_app_tag_mask;
-extern u32 app_tag_ctrl;
-extern u32 ref_tag_ctrl;
-extern u32 rep_ref_tag;
-extern u32 rx_rep_ref_tag;
-extern u16 cmp_app_tag;
-extern u16 rep_app_tag;
-
-#define spfc_fill_pkg_status(com_err_code, control, scsi_status) \
- (((u32)(com_err_code) << 16) | ((u32)(control) << 8) | \
- (u32)(scsi_status))
-#define SPFC_CTRL_MASK 0x1f
-
-u32 spfc_send_scsi_cmnd(void *hba, struct unf_frame_pkg *pkg);
-u32 spfc_scq_recv_iresp(struct spfc_hba_info *hba, union spfc_scqe *wqe);
-void spfc_process_dif_result(struct spfc_hba_info *hba, union spfc_scqe *wqe,
- struct unf_frame_pkg *pkg);
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif
-#endif /* __cplusplus */
-
-#endif /* __SPFC_IO_H__ */
diff --git a/drivers/scsi/spfc/hw/spfc_lld.c b/drivers/scsi/spfc/hw/spfc_lld.c
deleted file mode 100644
index a35484f1c917..000000000000
--- a/drivers/scsi/spfc/hw/spfc_lld.c
+++ /dev/null
@@ -1,997 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/device.h>
-#include <linux/io-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/inetdevice.h>
-#include <net/addrconf.h>
-#include <linux/time.h>
-#include <linux/timex.h>
-#include <linux/rtc.h>
-#include <linux/aer.h>
-#include <linux/debugfs.h>
-
-#include "spfc_lld.h"
-#include "sphw_hw.h"
-#include "sphw_mt.h"
-#include "sphw_hw_cfg.h"
-#include "sphw_hw_comm.h"
-#include "sphw_common.h"
-#include "spfc_cqm_main.h"
-#include "spfc_module.h"
-
-#define SPFC_DRV_NAME "spfc"
-#define SPFC_CHIP_NAME "spfc"
-
-#define PCI_VENDOR_ID_RAMAXEL 0x1E81
-#define SPFC_DEV_ID_PF_STD 0x9010
-#define SPFC_DEV_ID_VF 0x9008
-
-#define SPFC_VF_PCI_CFG_REG_BAR 0
-#define SPFC_PF_PCI_CFG_REG_BAR 1
-
-#define SPFC_PCI_INTR_REG_BAR 2
-#define SPFC_PCI_MGMT_REG_BAR 3
-#define SPFC_PCI_DB_BAR 4
-
-#define SPFC_SECOND_BASE (1000)
-#define SPFC_SYNC_YEAR_OFFSET (1900)
-#define SPFC_SYNC_MONTH_OFFSET (1)
-#define SPFC_MINUTE_BASE (60)
-#define SPFC_WAIT_TOOL_CNT_TIMEOUT 10000
-
-#define SPFC_MIN_TIME_IN_USECS 900
-#define SPFC_MAX_TIME_IN_USECS 1000
-#define SPFC_MAX_LOOP_TIMES 10000
-
-#define SPFC_TOOL_MIN_TIME_IN_USECS 9900
-#define SPFC_TOOL_MAX_TIME_IN_USECS 10000
-
-#define SPFC_EVENT_PROCESS_TIMEOUT 10000
-
-#define FIND_BIT(num, n) (((num) & (1UL << (n))) ? 1 : 0)
-#define SET_BIT(num, n) ((num) | (1UL << (n)))
-#define CLEAR_BIT(num, n) ((num) & (~(1UL << (n))))
-
-#define MAX_CARD_ID 64
-static unsigned long card_bit_map;
-LIST_HEAD(g_spfc_chip_list);
-struct spfc_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
-
-struct unf_cm_handle_op spfc_cm_op_handle = {0};
-
-u32 allowed_probe_num = SPFC_MAX_PORT_NUM;
-u32 dif_sgl_mode;
-u32 max_speed = SPFC_SPEED_32G;
-u32 accum_db_num = 1;
-u32 dif_type = 0x1;
-u32 wqe_page_size = 4096;
-u32 wqe_pre_load = 6;
-u32 combo_length = 128;
-u32 cos_bit_map = 0x1f;
-u32 spfc_dif_type;
-u32 spfc_dif_enable;
-u8 spfc_guard;
-int link_lose_tmo = 30;
-
-u32 exit_count = 4096;
-u32 exit_stride = 4096;
-u32 exit_base;
-
-/* dfx counter */
-atomic64_t rx_tx_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-atomic64_t rx_tx_err[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-atomic64_t scq_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-atomic64_t aeq_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-atomic64_t dif_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-atomic64_t mail_box_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-atomic64_t up_err_event_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-u64 link_event_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_LINK_EVENT_CNT];
-u64 link_reason_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_LINK_REASON_CNT];
-u64 hba_stat[SPFC_MAX_PORT_NUM][SPFC_HBA_STAT_BUTT];
-atomic64_t com_up_event_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-
-#ifndef MAX_SIZE
-#define MAX_SIZE (16)
-#endif
-
-struct spfc_lld_lock g_lld_lock;
-
-/* g_device_mutex */
-struct mutex g_device_mutex;
-
-/* pci device initialize lock */
-struct mutex g_pci_init_mutex;
-
-#define WAIT_LLD_DEV_HOLD_TIMEOUT (10 * 60 * 1000) /* 10minutes */
-#define WAIT_LLD_DEV_NODE_CHANGED (10 * 60 * 1000) /* 10minutes */
-#define WAIT_LLD_DEV_REF_CNT_EMPTY (2 * 60 * 1000) /* 2minutes */
-
-void lld_dev_cnt_init(struct spfc_pcidev *pci_adapter)
-{
- atomic_set(&pci_adapter->ref_cnt, 0);
-}
-
-void lld_dev_hold(struct spfc_lld_dev *dev)
-{
- struct spfc_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
-
- atomic_inc(&pci_adapter->ref_cnt);
-}
-
-void lld_dev_put(struct spfc_lld_dev *dev)
-{
- struct spfc_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
-
- atomic_dec(&pci_adapter->ref_cnt);
-}
-
-static void spfc_sync_time_to_fmw(struct spfc_pcidev *pdev_pri)
-{
- struct tm tm = {0};
- u64 tv_msec;
- int err;
-
- tv_msec = ktime_to_ms(ktime_get_real());
- err = sphw_sync_time(pdev_pri->hwdev, tv_msec);
- if (err) {
- sdk_err(&pdev_pri->pcidev->dev, "Synchronize UTC time to firmware failed, errno:%d.\n",
- err);
- } else {
- time64_to_tm(tv_msec / MSEC_PER_SEC, 0, &tm);
- sdk_info(&pdev_pri->pcidev->dev, "Synchronize UTC time to firmware succeed. UTC time %ld-%02d-%02d %02d:%02d:%02d.\n",
- tm.tm_year + 1900, tm.tm_mon + 1,
- tm.tm_mday, tm.tm_hour,
- tm.tm_min, tm.tm_sec);
- }
-}
-
-void wait_lld_dev_unused(struct spfc_pcidev *pci_adapter)
-{
- u32 loop_cnt = 0;
-
- while (loop_cnt < SPFC_WAIT_TOOL_CNT_TIMEOUT) {
- if (!atomic_read(&pci_adapter->ref_cnt))
- return;
-
- usleep_range(SPFC_TOOL_MIN_TIME_IN_USECS, SPFC_TOOL_MAX_TIME_IN_USECS);
- loop_cnt++;
- }
-}
-
-static void lld_lock_chip_node(void)
-{
- u32 loop_cnt;
-
- mutex_lock(&g_lld_lock.lld_mutex);
-
- loop_cnt = 0;
- while (loop_cnt < WAIT_LLD_DEV_NODE_CHANGED) {
- if (!test_and_set_bit(SPFC_NODE_CHANGE, &g_lld_lock.status))
- break;
-
- loop_cnt++;
-
- if (loop_cnt % SPFC_MAX_LOOP_TIMES == 0)
- pr_warn("[warn]Wait for lld node change complete for %us",
- loop_cnt / UNF_S_TO_MS);
-
- usleep_range(SPFC_MIN_TIME_IN_USECS, SPFC_MAX_TIME_IN_USECS);
- }
-
- if (loop_cnt == WAIT_LLD_DEV_NODE_CHANGED)
- pr_warn("[warn]Wait for lld node change complete timeout when try to get lld lock");
-
- loop_cnt = 0;
- while (loop_cnt < WAIT_LLD_DEV_REF_CNT_EMPTY) {
- if (!atomic_read(&g_lld_lock.dev_ref_cnt))
- break;
-
- loop_cnt++;
-
- if (loop_cnt % SPFC_MAX_LOOP_TIMES == 0)
- pr_warn("[warn]Wait for lld dev unused for %us, reference count: %d",
- loop_cnt / UNF_S_TO_MS, atomic_read(&g_lld_lock.dev_ref_cnt));
-
- usleep_range(SPFC_MIN_TIME_IN_USECS, SPFC_MAX_TIME_IN_USECS);
- }
-
- if (loop_cnt == WAIT_LLD_DEV_REF_CNT_EMPTY)
- pr_warn("[warn]Wait for lld dev unused timeout");
-
- mutex_unlock(&g_lld_lock.lld_mutex);
-}
-
-static void lld_unlock_chip_node(void)
-{
- clear_bit(SPFC_NODE_CHANGE, &g_lld_lock.status);
-}
-
-void lld_hold(void)
-{
- u32 loop_cnt = 0;
-
- /* ensure there have not any chip node in changing */
- mutex_lock(&g_lld_lock.lld_mutex);
-
- while (loop_cnt < WAIT_LLD_DEV_HOLD_TIMEOUT) {
- if (!test_bit(SPFC_NODE_CHANGE, &g_lld_lock.status))
- break;
-
- loop_cnt++;
-
- if (loop_cnt % SPFC_MAX_LOOP_TIMES == 0)
- pr_warn("[warn]Wait lld node change complete for %u",
- loop_cnt / UNF_S_TO_MS);
-
- usleep_range(SPFC_MIN_TIME_IN_USECS, SPFC_MAX_TIME_IN_USECS);
- }
-
- if (loop_cnt == WAIT_LLD_DEV_HOLD_TIMEOUT)
- pr_warn("[warn]Wait lld node change complete timeout when try to hode lld dev %u",
- loop_cnt / UNF_S_TO_MS);
-
- atomic_inc(&g_lld_lock.dev_ref_cnt);
-
- mutex_unlock(&g_lld_lock.lld_mutex);
-}
-
-void lld_put(void)
-{
- atomic_dec(&g_lld_lock.dev_ref_cnt);
-}
-
-static void spfc_lld_lock_init(void)
-{
- mutex_init(&g_lld_lock.lld_mutex);
- atomic_set(&g_lld_lock.dev_ref_cnt, 0);
-}
-
-static void spfc_realease_cmo_op_handle(void)
-{
- memset(&spfc_cm_op_handle, 0, sizeof(struct unf_cm_handle_op));
-}
-
-static void spfc_check_module_para(void)
-{
- if (spfc_dif_enable) {
- dif_sgl_mode = true;
- spfc_dif_type = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIX_TYPE1_PROTECTION;
- dix_flag = 1;
- }
-
- if (dif_sgl_mode != 0)
- dif_sgl_mode = 1;
-}
-
-void spfc_event_process(void *adapter, struct sphw_event_info *event)
-{
- struct spfc_pcidev *dev = adapter;
-
- if (test_and_set_bit(SERVICE_T_FC, &dev->state)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[WARN]Event: fc is in detach");
- return;
- }
-
- if (g_uld_info[SERVICE_T_FC].event)
- g_uld_info[SERVICE_T_FC].event(&dev->lld_dev, dev->uld_dev[SERVICE_T_FC], event);
-
- clear_bit(SERVICE_T_FC, &dev->state);
-}
-
-int spfc_stateful_init(void *hwdev)
-{
- struct sphw_hwdev *dev = hwdev;
- int stateful_en;
- int err;
-
- if (!dev)
- return -EINVAL;
-
- if (dev->statufull_ref_cnt++)
- return 0;
-
- stateful_en = IS_FT_TYPE(dev) | IS_RDMA_TYPE(dev);
- if (stateful_en && SPHW_IS_PPF(dev)) {
- err = sphw_ppf_ext_db_init(dev);
- if (err)
- goto out;
- }
-
- err = cqm3_init(dev);
- if (err) {
- sdk_err(dev->dev_hdl, "Failed to init cqm, err: %d\n", err);
- goto init_cqm_err;
- }
-
- sdk_info(dev->dev_hdl, "Initialize statefull resource success\n");
-
- return 0;
-
-init_cqm_err:
- if (stateful_en)
- sphw_ppf_ext_db_deinit(dev);
-
-out:
- dev->statufull_ref_cnt--;
-
- return err;
-}
-
-void spfc_stateful_deinit(void *hwdev)
-{
- struct sphw_hwdev *dev = hwdev;
- u32 stateful_en;
-
- if (!dev || !dev->statufull_ref_cnt)
- return;
-
- if (--dev->statufull_ref_cnt)
- return;
-
- cqm3_uninit(hwdev);
-
- stateful_en = IS_FT_TYPE(dev) | IS_RDMA_TYPE(dev);
- if (stateful_en)
- sphw_ppf_ext_db_deinit(hwdev);
-
- sdk_info(dev->dev_hdl, "Clear statefull resource success\n");
-}
-
-static int attach_uld(struct spfc_pcidev *dev, struct spfc_uld_info *uld_info)
-{
- void *uld_dev = NULL;
- int err;
-
- mutex_lock(&dev->pdev_mutex);
- if (dev->uld_dev[SERVICE_T_FC]) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]fc driver has attached to pcie device");
- err = 0;
- goto out_unlock;
- }
-
- err = spfc_stateful_init(dev->hwdev);
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to initialize statefull resources");
- goto out_unlock;
- }
-
- err = uld_info->probe(&dev->lld_dev, &uld_dev,
- dev->uld_dev_name[SERVICE_T_FC]);
- if (err || !uld_dev) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to add object for fc driver to pcie device");
- goto probe_failed;
- }
-
- dev->uld_dev[SERVICE_T_FC] = uld_dev;
- mutex_unlock(&dev->pdev_mutex);
-
- return RETURN_OK;
-
-probe_failed:
- spfc_stateful_deinit(dev->hwdev);
-
-out_unlock:
- mutex_unlock(&dev->pdev_mutex);
-
- return err;
-}
-
-static void detach_uld(struct spfc_pcidev *dev)
-{
- struct spfc_uld_info *uld_info = &g_uld_info[SERVICE_T_FC];
- u32 cnt = 0;
-
- mutex_lock(&dev->pdev_mutex);
- if (!dev->uld_dev[SERVICE_T_FC]) {
- mutex_unlock(&dev->pdev_mutex);
- return;
- }
-
- while (cnt < SPFC_EVENT_PROCESS_TIMEOUT) {
- if (!test_and_set_bit(SERVICE_T_FC, &dev->state))
- break;
- usleep_range(900, 1000);
- cnt++;
- }
-
- uld_info->remove(&dev->lld_dev, dev->uld_dev[SERVICE_T_FC]);
- dev->uld_dev[SERVICE_T_FC] = NULL;
- spfc_stateful_deinit(dev->hwdev);
- if (cnt < SPFC_EVENT_PROCESS_TIMEOUT)
- clear_bit(SERVICE_T_FC, &dev->state);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "Detach fc driver from pcie device succeed");
- mutex_unlock(&dev->pdev_mutex);
-}
-
-int spfc_register_uld(struct spfc_uld_info *uld_info)
-{
- memset(g_uld_info, 0, sizeof(g_uld_info));
- spfc_lld_lock_init();
- mutex_init(&g_device_mutex);
- mutex_init(&g_pci_init_mutex);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Module Init Success, wait for pci init and probe");
-
- if (!uld_info || !uld_info->probe || !uld_info->remove) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Invalid information of fc driver to register");
- return -EINVAL;
- }
-
- lld_hold();
-
- if (g_uld_info[SERVICE_T_FC].probe) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]fc driver has registered");
- lld_put();
- return -EINVAL;
- }
-
- memcpy(&g_uld_info[SERVICE_T_FC], uld_info, sizeof(*uld_info));
-
- lld_put();
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[KEVENT]Register spfc driver succeed");
- return RETURN_OK;
-}
-
-void spfc_unregister_uld(void)
-{
- struct spfc_uld_info *uld_info = NULL;
-
- lld_hold();
- uld_info = &g_uld_info[SERVICE_T_FC];
- memset(uld_info, 0, sizeof(*uld_info));
- lld_put();
-}
-
-static int spfc_pci_init(struct pci_dev *pdev)
-{
- struct spfc_pcidev *pci_adapter = NULL;
- int err = 0;
-
- pci_adapter = kzalloc(sizeof(*pci_adapter), GFP_KERNEL);
- if (!pci_adapter) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to alloc pci device adapter");
- return -ENOMEM;
- }
- pci_adapter->pcidev = pdev;
- mutex_init(&pci_adapter->pdev_mutex);
-
- pci_set_drvdata(pdev, pci_adapter);
-
- err = pci_enable_device(pdev);
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to enable PCI device");
- goto pci_enable_err;
- }
-
- err = pci_request_regions(pdev, SPFC_DRV_NAME);
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to request regions");
- goto pci_regions_err;
- }
-
- pci_enable_pcie_error_reporting(pdev);
-
- pci_set_master(pdev);
-
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Couldn't set 64-bit DMA mask");
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_ERR, "[err]Failed to set DMA mask");
- goto dma_mask_err;
- }
- }
-
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Couldn't set 64-bit coherent DMA mask");
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_ERR,
- "[err]Failed to set coherent DMA mask");
- goto dma_consistnet_mask_err;
- }
- }
-
- return 0;
-
-dma_consistnet_mask_err:
-dma_mask_err:
- pci_clear_master(pdev);
- pci_release_regions(pdev);
-
-pci_regions_err:
- pci_disable_device(pdev);
-
-pci_enable_err:
- pci_set_drvdata(pdev, NULL);
- kfree(pci_adapter);
-
- return err;
-}
-
-static void spfc_pci_deinit(struct pci_dev *pdev)
-{
- struct spfc_pcidev *pci_adapter = pci_get_drvdata(pdev);
-
- pci_clear_master(pdev);
- pci_release_regions(pdev);
- pci_disable_pcie_error_reporting(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- kfree(pci_adapter);
-}
-
-static int alloc_chip_node(struct spfc_pcidev *pci_adapter)
-{
- struct card_node *chip_node = NULL;
- unsigned char i;
- unsigned char bus_number = 0;
-
- if (!pci_is_root_bus(pci_adapter->pcidev->bus))
- bus_number = pci_adapter->pcidev->bus->number;
-
- if (bus_number != 0) {
- list_for_each_entry(chip_node, &g_spfc_chip_list, node) {
- if (chip_node->bus_num == bus_number) {
- pci_adapter->chip_node = chip_node;
- return 0;
- }
- }
- } else if (pci_adapter->pcidev->device == SPFC_DEV_ID_VF) {
- list_for_each_entry(chip_node, &g_spfc_chip_list, node) {
- if (chip_node) {
- pci_adapter->chip_node = chip_node;
- return 0;
- }
- }
- }
-
- for (i = 0; i < MAX_CARD_ID; i++) {
- if (!test_and_set_bit(i, &card_bit_map))
- break;
- }
-
- if (i == MAX_CARD_ID) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to alloc card id");
- return -EFAULT;
- }
-
- chip_node = kzalloc(sizeof(*chip_node), GFP_KERNEL);
- if (!chip_node) {
- clear_bit(i, &card_bit_map);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to alloc chip node");
- return -ENOMEM;
- }
-
- /* bus number */
- chip_node->bus_num = bus_number;
-
- snprintf(chip_node->chip_name, IFNAMSIZ, "%s%d", SPFC_CHIP_NAME, i);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[INFO]Add new chip %s to global list succeed",
- chip_node->chip_name);
-
- list_add_tail(&chip_node->node, &g_spfc_chip_list);
-
- INIT_LIST_HEAD(&chip_node->func_list);
- pci_adapter->chip_node = chip_node;
-
- return 0;
-}
-
-#ifdef CONFIG_X86
-void cfg_order_reg(struct spfc_pcidev *pci_adapter)
-{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
-
- if (sphw_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
-
- cpuinfo = &cpu_data(0);
-
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- sphw_set_pcie_order_cfg(pci_adapter->hwdev);
- }
-}
-#endif
-
-static int mapping_bar(struct pci_dev *pdev, struct spfc_pcidev *pci_adapter)
-{
- int cfg_bar;
-
- cfg_bar = pdev->is_virtfn ? SPFC_VF_PCI_CFG_REG_BAR : SPFC_PF_PCI_CFG_REG_BAR;
-
- pci_adapter->cfg_reg_base = pci_ioremap_bar(pdev, cfg_bar);
- if (!pci_adapter->cfg_reg_base) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Failed to map configuration regs");
- return -ENOMEM;
- }
-
- pci_adapter->intr_reg_base = pci_ioremap_bar(pdev, SPFC_PCI_INTR_REG_BAR);
- if (!pci_adapter->intr_reg_base) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Failed to map interrupt regs");
- goto map_intr_bar_err;
- }
-
- if (!pdev->is_virtfn) {
- pci_adapter->mgmt_reg_base = pci_ioremap_bar(pdev, SPFC_PCI_MGMT_REG_BAR);
- if (!pci_adapter->mgmt_reg_base) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_ERR, "Failed to map mgmt regs");
- goto map_mgmt_bar_err;
- }
- }
-
- pci_adapter->db_base_phy = pci_resource_start(pdev, SPFC_PCI_DB_BAR);
- pci_adapter->db_dwqe_len = pci_resource_len(pdev, SPFC_PCI_DB_BAR);
- pci_adapter->db_base = pci_ioremap_bar(pdev, SPFC_PCI_DB_BAR);
- if (!pci_adapter->db_base) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "Failed to map doorbell regs");
- goto map_db_err;
- }
-
- return 0;
-
-map_db_err:
- if (!pdev->is_virtfn)
- iounmap(pci_adapter->mgmt_reg_base);
-
-map_mgmt_bar_err:
- iounmap(pci_adapter->intr_reg_base);
-
-map_intr_bar_err:
- iounmap(pci_adapter->cfg_reg_base);
-
- return -ENOMEM;
-}
-
-static void unmapping_bar(struct spfc_pcidev *pci_adapter)
-{
- iounmap(pci_adapter->db_base);
-
- if (!pci_adapter->pcidev->is_virtfn)
- iounmap(pci_adapter->mgmt_reg_base);
-
- iounmap(pci_adapter->intr_reg_base);
- iounmap(pci_adapter->cfg_reg_base);
-}
-
-static int spfc_func_init(struct pci_dev *pdev, struct spfc_pcidev *pci_adapter)
-{
- struct sphw_init_para init_para = {0};
- int err;
-
- init_para.adapter_hdl = pci_adapter;
- init_para.pcidev_hdl = pdev;
- init_para.dev_hdl = &pdev->dev;
- init_para.cfg_reg_base = pci_adapter->cfg_reg_base;
- init_para.intr_reg_base = pci_adapter->intr_reg_base;
- init_para.mgmt_reg_base = pci_adapter->mgmt_reg_base;
- init_para.db_base = pci_adapter->db_base;
- init_para.db_base_phy = pci_adapter->db_base_phy;
- init_para.db_dwqe_len = pci_adapter->db_dwqe_len;
- init_para.hwdev = &pci_adapter->hwdev;
- init_para.chip_node = pci_adapter->chip_node;
- err = sphw_init_hwdev(&init_para);
- if (err) {
- pci_adapter->hwdev = NULL;
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to initialize hardware device");
- return -EFAULT;
- }
-
- pci_adapter->lld_dev.pdev = pdev;
- pci_adapter->lld_dev.hwdev = pci_adapter->hwdev;
-
- sphw_event_register(pci_adapter->hwdev, pci_adapter, spfc_event_process);
-
- if (sphw_func_type(pci_adapter->hwdev) != TYPE_VF)
- spfc_sync_time_to_fmw(pci_adapter);
- lld_lock_chip_node();
- list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
- lld_unlock_chip_node();
- err = attach_uld(pci_adapter, &g_uld_info[SERVICE_T_FC]);
-
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Spfc3 attach uld fail");
- goto attach_fc_err;
- }
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
-
- return 0;
-
-attach_fc_err:
- lld_lock_chip_node();
- list_del(&pci_adapter->node);
- lld_unlock_chip_node();
- wait_lld_dev_unused(pci_adapter);
-
- return err;
-}
-
-static void spfc_func_deinit(struct pci_dev *pdev)
-{
- struct spfc_pcidev *pci_adapter = pci_get_drvdata(pdev);
-
- lld_lock_chip_node();
- list_del(&pci_adapter->node);
- lld_unlock_chip_node();
- wait_lld_dev_unused(pci_adapter);
-
- detach_uld(pci_adapter);
- sphw_disable_mgmt_msg_report(pci_adapter->hwdev);
- sphw_flush_mgmt_workq(pci_adapter->hwdev);
- sphw_event_unregister(pci_adapter->hwdev);
- sphw_free_hwdev(pci_adapter->hwdev);
-}
-
-static void free_chip_node(struct spfc_pcidev *pci_adapter)
-{
- struct card_node *chip_node = pci_adapter->chip_node;
- int id, err;
-
- if (list_empty(&chip_node->func_list)) {
- list_del(&chip_node->node);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[INFO]Delete chip %s from global list succeed",
- chip_node->chip_name);
- err = sscanf(chip_node->chip_name, SPFC_CHIP_NAME "%d", &id);
- if (err < 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_ERR, "[err]Failed to get spfc id");
- }
-
- clear_bit(id, &card_bit_map);
-
- kfree(chip_node);
- }
-}
-
-static int spfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- struct spfc_pcidev *pci_adapter = NULL;
- int err;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[event]Spfc3 Pcie device probe begin");
-
- mutex_lock(&g_pci_init_mutex);
- err = spfc_pci_init(pdev);
- if (err) {
- mutex_unlock(&g_pci_init_mutex);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]pci init fail, return %d", err);
- return err;
- }
- pci_adapter = pci_get_drvdata(pdev);
- err = mapping_bar(pdev, pci_adapter);
- if (err) {
- mutex_unlock(&g_pci_init_mutex);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to map bar");
- goto map_bar_failed;
- }
- mutex_unlock(&g_pci_init_mutex);
- pci_adapter->id = *id;
- lld_dev_cnt_init(pci_adapter);
-
- /* if chip information of pcie function exist, add the function into chip */
- lld_lock_chip_node();
- err = alloc_chip_node(pci_adapter);
- if (err) {
- lld_unlock_chip_node();
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Failed to add new chip node to global list");
- goto alloc_chip_node_fail;
- }
-
- lld_unlock_chip_node();
- err = spfc_func_init(pdev, pci_adapter);
- if (err) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]spfc func init fail");
- goto func_init_err;
- }
-
- return 0;
-
-func_init_err:
- lld_lock_chip_node();
- free_chip_node(pci_adapter);
- lld_unlock_chip_node();
-
-alloc_chip_node_fail:
- unmapping_bar(pci_adapter);
-
-map_bar_failed:
- spfc_pci_deinit(pdev);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Pcie device probe failed");
- return err;
-}
-
-static void spfc_remove(struct pci_dev *pdev)
-{
- struct spfc_pcidev *pci_adapter = pci_get_drvdata(pdev);
-
- if (!pci_adapter)
- return;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[INFO]Pcie device remove begin");
- sphw_detect_hw_present(pci_adapter->hwdev);
- spfc_func_deinit(pdev);
- lld_lock_chip_node();
- free_chip_node(pci_adapter);
- lld_unlock_chip_node();
- unmapping_bar(pci_adapter);
- mutex_lock(&g_pci_init_mutex);
- spfc_pci_deinit(pdev);
- mutex_unlock(&g_pci_init_mutex);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[INFO]Pcie device removed");
-}
-
-static void spfc_shutdown(struct pci_dev *pdev)
-{
- struct spfc_pcidev *pci_adapter = pci_get_drvdata(pdev);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Shutdown device");
-
- if (pci_adapter)
- sphw_shutdown_hwdev(pci_adapter->hwdev);
-
- pci_disable_device(pdev);
-}
-
-static pci_ers_result_t spfc_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
-{
- struct spfc_pcidev *pci_adapter = NULL;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Uncorrectable error detected, log and cleanup error status: 0x%08x",
- state);
-
- pci_aer_clear_nonfatal_status(pdev);
- pci_adapter = pci_get_drvdata(pdev);
-
- if (pci_adapter)
- sphw_record_pcie_error(pci_adapter->hwdev);
-
- return PCI_ERS_RESULT_CAN_RECOVER;
-}
-
-static int unf_global_value_init(void)
-{
- memset(rx_tx_stat, 0, sizeof(rx_tx_stat));
- memset(rx_tx_err, 0, sizeof(rx_tx_err));
- memset(scq_err_stat, 0, sizeof(scq_err_stat));
- memset(aeq_err_stat, 0, sizeof(aeq_err_stat));
- memset(dif_err_stat, 0, sizeof(dif_err_stat));
- memset(link_event_stat, 0, sizeof(link_event_stat));
- memset(link_reason_stat, 0, sizeof(link_reason_stat));
- memset(hba_stat, 0, sizeof(hba_stat));
- memset(&spfc_cm_op_handle, 0, sizeof(struct unf_cm_handle_op));
- memset(up_err_event_stat, 0, sizeof(up_err_event_stat));
- memset(mail_box_stat, 0, sizeof(mail_box_stat));
- memset(spfc_hba, 0, sizeof(spfc_hba));
-
- spin_lock_init(&probe_spin_lock);
-
- /* 4. Get COM Handlers used for low_level */
- if (unf_get_cm_handle_ops(&spfc_cm_op_handle) != RETURN_OK) {
- spfc_realease_cmo_op_handle();
- return RETURN_ERROR_S32;
- }
-
- return RETURN_OK;
-}
-
-static const struct pci_device_id spfc_pci_table[] = {
- {PCI_VDEVICE(RAMAXEL, SPFC_DEV_ID_PF_STD), 0},
- {0, 0}
-};
-
-MODULE_DEVICE_TABLE(pci, spfc_pci_table);
-
-static struct pci_error_handlers spfc_err_handler = {
- .error_detected = spfc_io_error_detected,
-};
-
-static struct pci_driver spfc_driver = {.name = SPFC_DRV_NAME,
- .id_table = spfc_pci_table,
- .probe = spfc_probe,
- .remove = spfc_remove,
- .shutdown = spfc_shutdown,
- .err_handler = &spfc_err_handler};
-
-static __init int spfc_lld_init(void)
-{
- if (unf_common_init() != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]UNF_Common_init failed");
- return RETURN_ERROR_S32;
- }
-
- spfc_check_module_para();
-
- if (unf_global_value_init() != RETURN_OK)
- return RETURN_ERROR_S32;
-
- spfc_register_uld(&fc_uld_info);
- return pci_register_driver(&spfc_driver);
-}
-
-static __exit void spfc_lld_exit(void)
-{
- pci_unregister_driver(&spfc_driver);
- spfc_unregister_uld();
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[event]SPFC module removing...");
-
- spfc_realease_cmo_op_handle();
-
- /* 2. Unregister FC COM module(level) */
- unf_common_exit();
-}
-
-module_init(spfc_lld_init);
-module_exit(spfc_lld_exit);
-
-MODULE_AUTHOR("Ramaxel Memory Technology, Ltd");
-MODULE_DESCRIPTION(SPFC_DRV_DESC);
-MODULE_VERSION(SPFC_DRV_VERSION);
-MODULE_LICENSE("GPL");
-
-module_param(allowed_probe_num, uint, 0444);
-module_param(dif_sgl_mode, uint, 0444);
-module_param(max_speed, uint, 0444);
-module_param(wqe_page_size, uint, 0444);
-module_param(combo_length, uint, 0444);
-module_param(cos_bit_map, uint, 0444);
-module_param(spfc_dif_enable, uint, 0444);
-MODULE_PARM_DESC(spfc_dif_enable, "set dif enable/disable(1/0), default is 0(disable).");
-module_param(link_lose_tmo, uint, 0444);
-MODULE_PARM_DESC(link_lose_tmo, "set link time out, default is 30s.");
diff --git a/drivers/scsi/spfc/hw/spfc_lld.h b/drivers/scsi/spfc/hw/spfc_lld.h
deleted file mode 100644
index f7b4a5e5ce07..000000000000
--- a/drivers/scsi/spfc/hw/spfc_lld.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_LLD_H
-#define SPFC_LLD_H
-
-#include "sphw_crm.h"
-
-struct spfc_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct spfc_uld_info {
- /* uld_dev: should not return null even the function capability
- * is not support the up layer driver
- * uld_dev_name: NIC driver should copy net device name.
- * FC driver could copy fc device name.
- * other up layer driver don`t need copy anything
- */
- int (*probe)(struct spfc_lld_dev *lld_dev, void **uld_dev,
- char *uld_dev_name);
- void (*remove)(struct spfc_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct spfc_lld_dev *lld_dev, void *uld_dev,
- pm_message_t state);
- int (*resume)(struct spfc_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct spfc_lld_dev *lld_dev, void *uld_dev,
- struct sphw_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* Structure pcidev private */
-struct spfc_pcidev {
- struct pci_dev *pcidev;
- void *hwdev;
- struct card_node *chip_node;
- struct spfc_lld_dev lld_dev;
- /* such as fc_dev */
- void *uld_dev[SERVICE_T_MAX];
- /* Record the service object name */
- char uld_dev_name[SERVICE_T_MAX][IFNAMSIZ];
- /* It is a the global variable for driver to manage
- * all function device linked list
- */
- struct list_head node;
- void __iomem *cfg_reg_base;
- void __iomem *intr_reg_base;
- void __iomem *mgmt_reg_base;
- u64 db_dwqe_len;
- u64 db_base_phy;
- void __iomem *db_base;
- /* lock for attach/detach uld */
- struct mutex pdev_mutex;
- /* setted when uld driver processing event */
- unsigned long state;
- struct pci_device_id id;
- atomic_t ref_cnt;
-};
-
-enum spfc_lld_status {
- SPFC_NODE_CHANGE = BIT(0),
-};
-
-struct spfc_lld_lock {
- /* lock for chip list */
- struct mutex lld_mutex;
- unsigned long status;
- atomic_t dev_ref_cnt;
-};
-
-#ifndef MAX_SIZE
-#define MAX_SIZE (16)
-#endif
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_module.h b/drivers/scsi/spfc/hw/spfc_module.h
deleted file mode 100644
index 153d59955339..000000000000
--- a/drivers/scsi/spfc/hw/spfc_module.h
+++ /dev/null
@@ -1,297 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_MODULE_H
-#define SPFC_MODULE_H
-#include "unf_type.h"
-#include "unf_log.h"
-#include "unf_common.h"
-#include "spfc_utils.h"
-#include "spfc_hba.h"
-
-#define SPFC_FT_ENABLE (1)
-#define SPFC_FC_DISABLE (0)
-
-#define SPFC_P2P_DIRECT (0)
-#define SPFC_P2P_FABRIC (1)
-#define SPFC_LOOP (2)
-#define SPFC_ATUOSPEED (1)
-#define SPFC_FIXEDSPEED (0)
-#define SPFC_AUTOTOPO (0)
-#define SPFC_P2PTOPO (0x2)
-#define SPFC_LOOPTOPO (0x1)
-#define SPFC_SPEED_2G (0x2)
-#define SPFC_SPEED_4G (0x4)
-#define SPFC_SPEED_8G (0x8)
-#define SPFC_SPEED_16G (0x10)
-#define SPFC_SPEED_32G (0x20)
-
-#define SPFC_MAX_PORT_NUM SPFC_MAX_PROBE_PORT_NUM
-#define SPFC_MAX_PORT_TASK_TYPE_STAT_NUM (128)
-#define SPFC_MAX_LINK_EVENT_CNT (4)
-#define SPFC_MAX_LINK_REASON_CNT (256)
-
-#define SPFC_MML_LOGCTRO_NUM (14)
-
-#define WWN_SIZE 8 /* Size of WWPN, WWN & WWNN */
-
-/*
- * Define the data type
- */
-struct spfc_log_ctrl {
- char *log_option;
- u32 state;
-};
-
-/*
- * Declare the global function.
- */
-extern struct unf_cm_handle_op spfc_cm_op_handle;
-extern struct spfc_uld_info fc_uld_info;
-extern u32 allowed_probe_num;
-extern u32 max_speed;
-extern u32 accum_db_num;
-extern u32 wqe_page_size;
-extern u32 dif_type;
-extern u32 wqe_pre_load;
-extern u32 combo_length;
-extern u32 cos_bit_map;
-extern u32 exit_count;
-extern u32 exit_stride;
-extern u32 exit_base;
-
-extern atomic64_t rx_tx_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern atomic64_t rx_tx_err[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern atomic64_t scq_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern atomic64_t aeq_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern atomic64_t dif_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern atomic64_t mail_box_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern atomic64_t com_up_event_err_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern u64 link_event_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_LINK_EVENT_CNT];
-extern u64 link_reason_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_LINK_REASON_CNT];
-extern atomic64_t up_err_event_stat[SPFC_MAX_PORT_NUM][SPFC_MAX_PORT_TASK_TYPE_STAT_NUM];
-extern u64 hba_stat[SPFC_MAX_PORT_NUM][SPFC_HBA_STAT_BUTT];
-#define SPFC_LINK_EVENT_STAT(hba, link_ent) \
- (link_event_stat[(hba)->probe_index][link_ent]++)
-#define SPFC_LINK_REASON_STAT(hba, link_rsn) \
- (link_reason_stat[(hba)->probe_index][link_rsn]++)
-#define SPFC_HBA_STAT(hba, hba_stat_type) \
- (hba_stat[(hba)->probe_index][hba_stat_type]++)
-
-#define SPFC_UP_ERR_EVENT_STAT(hba, err_type) \
- (atomic64_inc(&up_err_event_stat[(hba)->probe_index][err_type]))
-#define SPFC_UP_ERR_EVENT_STAT_READ(probe_index, io_type) \
- (atomic64_read(&up_err_event_stat[probe_index][io_type]))
-#define SPFC_DIF_ERR_STAT(hba, dif_err) \
- (atomic64_inc(&dif_err_stat[(hba)->probe_index][dif_err]))
-#define SPFC_DIF_ERR_STAT_READ(probe_index, dif_err) \
- (atomic64_read(&dif_err_stat[probe_index][dif_err]))
-
-#define SPFC_IO_STAT(hba, io_type) \
- (atomic64_inc(&rx_tx_stat[(hba)->probe_index][io_type]))
-#define SPFC_IO_STAT_READ(probe_index, io_type) \
- (atomic64_read(&rx_tx_stat[probe_index][io_type]))
-
-#define SPFC_ERR_IO_STAT(hba, io_type) \
- (atomic64_inc(&rx_tx_err[(hba)->probe_index][io_type]))
-#define SPFC_ERR_IO_STAT_READ(probe_index, io_type) \
- (atomic64_read(&rx_tx_err[probe_index][io_type]))
-
-#define SPFC_SCQ_ERR_TYPE_STAT(hba, err_type) \
- (atomic64_inc(&scq_err_stat[(hba)->probe_index][err_type]))
-#define SPFC_SCQ_ERR_TYPE_STAT_READ(probe_index, io_type) \
- (atomic64_read(&scq_err_stat[probe_index][io_type]))
-#define SPFC_AEQ_ERR_TYPE_STAT(hba, err_type) \
- (atomic64_inc(&aeq_err_stat[(hba)->probe_index][err_type]))
-#define SPFC_AEQ_ERR_TYPE_STAT_READ(probe_index, io_type) \
- (atomic64_read(&aeq_err_stat[probe_index][io_type]))
-
-#define SPFC_MAILBOX_STAT(hba, io_type) \
- (atomic64_inc(&mail_box_stat[(hba)->probe_index][io_type]))
-#define SPFC_MAILBOX_STAT_READ(probe_index, io_type) \
- (atomic64_read(&mail_box_stat[probe_index][io_type]))
-
-#define SPFC_COM_UP_ERR_EVENT_STAT(hba, err_type) \
- (atomic64_inc( \
- &com_up_event_err_stat[(hba)->probe_index][err_type]))
-#define SPFC_COM_UP_ERR_EVENT_STAT_READ(probe_index, err_type) \
- (atomic64_read(&com_up_event_err_stat[probe_index][err_type]))
-
-#define UNF_LOWLEVEL_ALLOC_LPORT(lport, fc_port, low_level) \
- do { \
- if (spfc_cm_op_handle.unf_alloc_local_port) { \
- lport = spfc_cm_op_handle.unf_alloc_local_port( \
- (fc_port), (low_level)); \
- } else { \
- lport = NULL; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_RECEIVE_LS_GS_PKG(ret, fc_port, pkg) \
- do { \
- if (spfc_cm_op_handle.unf_receive_ls_gs_pkg) { \
- ret = spfc_cm_op_handle.unf_receive_ls_gs_pkg( \
- (fc_port), (pkg)); \
- } else { \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_SEND_ELS_DONE(ret, fc_port, pkg) \
- do { \
- if (spfc_cm_op_handle.unf_send_els_done) { \
- ret = spfc_cm_op_handle.unf_send_els_done((fc_port), \
- (pkg)); \
- } else { \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_GET_CFG_PARMS(ret, section_name, cfg_parm, cfg_value, \
- item_num) \
- do { \
- if (spfc_cm_op_handle.unf_get_cfg_parms) { \
- ret = (u32)spfc_cm_op_handle.unf_get_cfg_parms( \
- (section_name), (cfg_parm), (cfg_value), \
- (item_num)); \
- } else { \
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN, \
- "Get config parameter function is NULL."); \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_RELEASE_LOCAL_PORT(ret, lport) \
- do { \
- if (unlikely(!spfc_cm_op_handle.unf_release_local_port)) { \
- ret = UNF_RETURN_ERROR; \
- } else { \
- ret = \
- spfc_cm_op_handle.unf_release_local_port(lport); \
- } \
- } while (0)
-
-#define UNF_CM_GET_SGL_ENTRY(ret, pkg, buf, buf_len) \
- do { \
- if (unlikely(!spfc_cm_op_handle.unf_cm_get_sgl_entry)) { \
- ret = UNF_RETURN_ERROR; \
- } else { \
- ret = spfc_cm_op_handle.unf_cm_get_sgl_entry( \
- pkg, buf, buf_len); \
- } \
- } while (0)
-
-#define UNF_CM_GET_DIF_SGL_ENTRY(ret, pkg, buf, buf_len) \
- do { \
- if (unlikely(!spfc_cm_op_handle.unf_cm_get_dif_sgl_entry)) { \
- ret = UNF_RETURN_ERROR; \
- } else { \
- ret = spfc_cm_op_handle.unf_cm_get_dif_sgl_entry( \
- pkg, buf, buf_len); \
- } \
- } while (0)
-
-#define UNF_GET_SGL_ENTRY(ret, pkg, buf, buf_len, dif_flag) \
- do { \
- if (dif_flag) { \
- UNF_CM_GET_DIF_SGL_ENTRY(ret, pkg, buf, buf_len); \
- } else { \
- UNF_CM_GET_SGL_ENTRY(ret, pkg, buf, buf_len); \
- } \
- } while (0)
-
-#define UNF_GET_FREE_ESGL_PAGE(ret, lport, pkg) \
- do { \
- if (unlikely( \
- !spfc_cm_op_handle.unf_get_one_free_esgl_page)) { \
- ret = NULL; \
- } else { \
- ret = \
- spfc_cm_op_handle.unf_get_one_free_esgl_page( \
- lport, pkg); \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_FCP_CMND_RECEIVED(ret, lport, pkg) \
- do { \
- if (unlikely(!spfc_cm_op_handle.unf_process_fcp_cmnd)) { \
- ret = UNF_RETURN_ERROR; \
- } else { \
- ret = spfc_cm_op_handle.unf_process_fcp_cmnd(lport, \
- pkg); \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_SCSI_COMPLETED(ret, lport, pkg) \
- do { \
- if (unlikely(NULL == \
- spfc_cm_op_handle.unf_receive_ini_response)) { \
- ret = UNF_RETURN_ERROR; \
- } else { \
- ret = spfc_cm_op_handle.unf_receive_ini_response( \
- lport, pkg); \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_PORT_EVENT(ret, lport, event, input) \
- do { \
- if (unlikely(!spfc_cm_op_handle.unf_fc_port_event)) { \
- ret = UNF_RETURN_ERROR; \
- } else { \
- ret = spfc_cm_op_handle.unf_fc_port_event( \
- lport, event, input); \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_RECEIVE_FC4LS_PKG(ret, fc_port, pkg) \
- do { \
- if (spfc_cm_op_handle.unf_receive_fc4ls_pkg) { \
- ret = spfc_cm_op_handle.unf_receive_fc4ls_pkg( \
- (fc_port), (pkg)); \
- } else { \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_SEND_FC4LS_DONE(ret, lport, pkg) \
- do { \
- if (spfc_cm_op_handle.unf_send_fc4ls_done) { \
- ret = spfc_cm_op_handle.unf_send_fc4ls_done((lport), \
- (pkg)); \
- } else { \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_RECEIVE_BLS_PKG(ret, lport, pkg) \
- do { \
- if (spfc_cm_op_handle.unf_receive_bls_pkg) { \
- ret = spfc_cm_op_handle.unf_receive_bls_pkg((lport), \
- (pkg)); \
- } else { \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_RECEIVE_MARKER_STS(ret, lport, pkg) \
- do { \
- if (spfc_cm_op_handle.unf_receive_marker_status) { \
- ret = spfc_cm_op_handle.unf_receive_marker_status( \
- (lport), (pkg)); \
- } else { \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#define UNF_LOWLEVEL_RECEIVE_ABTS_MARKER_STS(ret, lport, pkg) \
- do { \
- if (spfc_cm_op_handle.unf_receive_abts_marker_status) { \
- ret = \
- spfc_cm_op_handle.unf_receive_abts_marker_status( \
- (lport), (pkg)); \
- } else { \
- ret = UNF_RETURN_ERROR; \
- } \
- } while (0)
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_parent_context.h b/drivers/scsi/spfc/hw/spfc_parent_context.h
deleted file mode 100644
index dc4baffe5c44..000000000000
--- a/drivers/scsi/spfc/hw/spfc_parent_context.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_PARENT_CONTEXT_H
-#define SPFC_PARENT_CONTEXT_H
-
-enum fc_parent_status {
- FC_PARENT_STATUS_INVALID = 0,
- FC_PARENT_STATUS_NORMAL,
- FC_PARENT_STATUS_CLOSING
-};
-
-#define SPFC_PARENT_CONTEXT_KEY_ALIGN_SIZE (48)
-
-#define SPFC_PARENT_CONTEXT_TIMER_SIZE (32) /* 24+2*N,N=timer count */
-
-#define FC_CALC_CID(_xid) \
- (((((_xid) >> 5) & 0x1ff) << 11) | ((((_xid) >> 5) & 0x1ff) << 2) | \
- (((_xid) >> 3) & 0x3))
-
-#define MAX_PKT_SIZE_PER_DISPATCH (fc_child_ctx_ex->per_xmit_data_size)
-
-/* immediate data DIF info definition in parent context */
-struct immi_dif_info {
- union {
- u32 value;
- struct {
- u32 app_tag_ctrl : 3; /* DIF/DIX APP TAG Control */
- u32 ref_tag_mode : 2; /* Bit 0: scenario of the reference tag verify mode */
- /* Bit 1: scenario of the reference tag insert/replace
- * mode 0: fixed; 1: increasement;
- */
- u32 ref_tag_ctrl : 3; /* The DIF/DIX Reference tag control */
- u32 grd_agm_ini_ctrl : 3;
- u32 grd_agm_ctrl : 2; /* Bit 0: DIF/DIX guard verify algorithm control */
- /* Bit 1: DIF/DIX guard replace or insert algorithm control */
- u32 grd_ctrl : 3; /* The DIF/DIX Guard control */
- u32 dif_verify_type : 2; /* verify type */
- /* Check blocks whose reference tag contains 0xFFFF flag */
- u32 difx_ref_esc : 1;
- /* Check blocks whose application tag contains 0xFFFF flag */
- u32 difx_app_esc : 1;
- u32 rsvd : 8;
- u32 sct_size : 1; /* Sector size, 1: 4K; 0: 512 */
- u32 smd_tp : 2;
- u32 difx_en : 1;
- } info;
- } dif_dw3;
-
- u32 cmp_app_tag : 16;
- u32 rep_app_tag : 16;
- /* The ref tag value for verify compare, do not support replace or insert ref tag */
- u32 cmp_ref_tag;
- u32 rep_ref_tag;
-
- u32 rsv1 : 16;
- u32 cmp_app_tag_msk : 16;
-};
-
-/* parent context SW section definition: SW(80B) */
-struct spfc_sw_section {
- u16 scq_num_rcv_cmd;
- u16 scq_num_max_scqn;
-
- struct {
- u32 xid : 13;
- u32 vport : 7;
- u32 csctrl : 8;
- u32 rsvd0 : 4;
- } sw_ctxt_vport_xid;
-
- u32 scq_num_scqn_mask : 12;
- u32 cid : 20; /* ucode init */
-
- u16 conn_id;
- u16 immi_rq_page_size;
-
- u16 immi_taskid_min;
- u16 immi_taskid_max;
-
- union {
- u32 pctxt_val0;
- struct {
- u32 srv_type : 5; /* driver init */
- u32 srr_support : 2; /* sequence retransmition support flag */
- u32 rsvd1 : 5;
- u32 port_id : 4; /* driver init */
- u32 vlan_id : 16; /* driver init */
- } dw;
- } sw_ctxt_misc;
-
- u32 rsvd2;
- u32 per_xmit_data_size;
-
- /* RW fields */
- u32 cmd_scq_gpa_h;
- u32 cmd_scq_gpa_l;
- u32 e_d_tov_timer_val; /* E_D_TOV timer value: value should be set on ms by driver */
- u16 mfs_unaligned_bytes; /* mfs unalined bytes of per 64KB dispatch*/
- u16 tx_mfs; /* remote port max receive fc payload length */
- u32 xfer_rdy_dis_max_len_remote; /* max data len allowed in xfer_rdy dis scenario */
- u32 xfer_rdy_dis_max_len_local;
-
- union {
- struct {
- u32 priority : 3; /* vlan priority */
- u32 rsvd4 : 2;
- u32 status : 8; /* status of flow */
- u32 cos : 3; /* doorbell cos value */
- u32 oq_cos_data : 3; /* esch oq cos for data */
- u32 oq_cos_cmd : 3; /* esch oq cos for cmd/xferrdy/rsp */
- /* used for parent context cache Consistency judgment,1: done */
- u32 flush_done : 1;
- u32 work_mode : 2; /* 0:Target, 1:Initiator, 2:Target&Initiator */
- u32 seq_cnt : 1; /* seq_cnt */
- u32 e_d_tov : 1; /* E_D_TOV resolution */
- u32 vlan_enable : 1; /* Vlan enable flag */
- u32 conf_support : 1; /* Response confirm support flag */
- u32 rec_support : 1; /* REC support flag */
- u32 write_xfer_rdy : 1; /* WRITE Xfer_Rdy disable or enable */
- u32 sgl_num : 1; /* Double or single SGL, 1: double; 0: single */
- } dw;
- u32 pctxt_val1;
- } sw_ctxt_config;
- struct immi_dif_info immi_dif_info; /* immediate data dif control info(20B) */
-};
-
-struct spfc_hw_rsvd_queue {
- /* bitmap[0]:255-192 */
- /* bitmap[1]:191-128 */
- /* bitmap[2]:127-64 */
- /* bitmap[3]:63-0 */
- u64 seq_id_bitmap[4];
- struct {
- u64 last_req_seq_id : 8;
- u64 xid : 20;
- u64 rsvd0 : 36;
- } wd0;
-};
-
-struct spfc_sq_qinfo {
- u64 rsvd_0 : 10;
- u64 pmsn_type : 1; /* 0: get pmsn from queue header; 1: get pmsn from ucode */
- u64 rsvd_1 : 4;
- u64 cur_wqe_o : 1; /* should be opposite from loop_o */
- u64 rsvd_2 : 48;
-
- u64 cur_sqe_gpa;
- u64 pmsn_gpa; /* sq's queue header gpa */
-
- u64 sqe_dmaattr_idx : 6;
- u64 sq_so_ro : 2;
- u64 rsvd_3 : 2;
- u64 ring : 1; /* 0: link; 1: ring */
- u64 loop_o : 1; /* init to be the first round o-bit */
- u64 rsvd_4 : 4;
- u64 zerocopy_dmaattr_idx : 6;
- u64 zerocopy_so_ro : 2;
- u64 parity : 8;
- u64 r : 1;
- u64 s : 1;
- u64 enable_256 : 1;
- u64 rsvd_5 : 23;
- u64 pcie_template : 6;
-};
-
-struct spfc_cq_qinfo {
- u64 pcie_template_hi : 3;
- u64 parity_2 : 1;
- u64 cur_cqe_gpa : 60;
-
- u64 pi : 15;
- u64 pi_o : 1;
- u64 ci : 15;
- u64 ci_o : 1;
- u64 c_eqn_msi_x : 10; /* if init_mode = 2, is msi/msi-x; other the low-5-bit means c_eqn */
- u64 parity_1 : 1;
- u64 ci_type : 1; /* 0: get ci from queue header; 1: get ci from ucode */
- u64 cq_depth : 3; /* valid when ring = 1 */
- u64 armq : 1; /* 0: IDLE state; 1: NEXT state */
- u64 cur_cqe_cnt : 8;
- u64 cqe_max_cnt : 8;
-
- u64 cqe_dmaattr_idx : 6;
- u64 cq_so_ro : 2;
- u64 init_mode : 2; /* 1: armQ; 2: msi/msi-x; others: rsvd */
- u64 next_o : 1; /* next pate valid o-bit */
- u64 loop_o : 1; /* init to be the first round o-bit */
- u64 next_cq_wqe_page_gpa : 52;
-
- u64 pcie_template_lo : 3;
- u64 parity_0 : 1;
- u64 ci_gpa : 60; /* cq's queue header gpa */
-};
-
-struct spfc_scq_qinfo {
- union {
- struct {
- u64 scq_n : 20; /* scq number */
- u64 sq_min_preld_cache_num : 4;
- u64 sq_th0_preld_cache_num : 5;
- u64 sq_th1_preld_cache_num : 5;
- u64 sq_th2_preld_cache_num : 5;
- u64 rq_min_preld_cache_num : 4;
- u64 rq_th0_preld_cache_num : 5;
- u64 rq_th1_preld_cache_num : 5;
- u64 rq_th2_preld_cache_num : 5;
- u64 parity : 6;
- } info;
-
- u64 pctxt_val1;
- } hw_scqc_config;
-};
-
-struct spfc_srq_qinfo {
- u64 parity : 4;
- u64 srqc_gpa : 60;
-};
-
-/* here is the layout of service type 12/13 */
-struct spfc_parent_context {
- u8 key[SPFC_PARENT_CONTEXT_KEY_ALIGN_SIZE];
- struct spfc_scq_qinfo resp_scq_qinfo;
- struct spfc_srq_qinfo imm_srq_info;
- struct spfc_sq_qinfo sq_qinfo;
- u8 timer_section[SPFC_PARENT_CONTEXT_TIMER_SIZE];
- struct spfc_hw_rsvd_queue hw_rsvdq;
- struct spfc_srq_qinfo els_srq_info;
- struct spfc_sw_section sw_section;
-};
-
-/* here is the layout of service type 13 */
-struct spfc_ssq_parent_context {
- u8 rsvd0[64];
- struct spfc_sq_qinfo sq1_qinfo;
- u8 rsvd1[32];
- struct spfc_sq_qinfo sq2_qinfo;
- u8 rsvd2[32];
- struct spfc_sq_qinfo sq3_qinfo;
- struct spfc_scq_qinfo sq_pretchinfo;
- u8 rsvd3[24];
-};
-
-/* FC Key Section */
-struct spfc_fc_key_section {
- u32 xid_h : 4;
- u32 key_size : 2;
- u32 rsvd1 : 1;
- u32 srv_type : 5;
- u32 csize : 2;
- u32 rsvd0 : 17;
- u32 v : 1;
-
- u32 tag_fp_h : 4;
- u32 rsvd2 : 12;
- u32 xid_l : 16;
-
- u16 tag_fp_l;
- u8 smac[6]; /* Source MAC */
- u8 dmac[6]; /* Dest MAC */
- u8 sid[3]; /* Source FC ID */
- u8 did[3]; /* Dest FC ID */
- u8 svlan[4]; /* Svlan */
- u8 cvlan[4]; /* Cvlan */
-
- u32 next_ptr_h;
-};
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_queue.c b/drivers/scsi/spfc/hw/spfc_queue.c
deleted file mode 100644
index fa4295832da7..000000000000
--- a/drivers/scsi/spfc/hw/spfc_queue.c
+++ /dev/null
@@ -1,4852 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "spfc_queue.h"
-#include "unf_log.h"
-#include "unf_lport.h"
-#include "spfc_module.h"
-#include "spfc_utils.h"
-#include "spfc_service.h"
-#include "spfc_chipitf.h"
-#include "spfc_parent_context.h"
-#include "sphw_hw.h"
-#include "sphw_crm.h"
-
-#define SPFC_UCODE_CMD_MODIFY_QUEUE_CONTEXT 0
-
-#define SPFC_DONE_MASK (0x00000001)
-#define SPFC_OWNER_MASK (0x80000000)
-
-#define SPFC_SQ_LINK_PRE (1 << 2)
-
-#define SPFC_SQ_HEADER_ADDR_ALIGN_SIZE (64)
-#define SPFC_SQ_HEADER_ADDR_ALIGN_SIZE_MASK (SPFC_SQ_HEADER_ADDR_ALIGN_SIZE - 1)
-
-#define SPFC_ADDR_64_ALIGN(addr) \
- (((addr) + (SPFC_SQ_HEADER_ADDR_ALIGN_SIZE_MASK)) & \
- ~(SPFC_SQ_HEADER_ADDR_ALIGN_SIZE_MASK))
-
-u32 spfc_get_parity_value(u64 *src_data, u32 row, u32 col)
-{
- u32 i = 0;
- u32 j = 0;
- u32 offset = 0;
- u32 group = 0;
- u32 bit_offset = 0;
- u32 bit_val = 0;
- u32 tmp_val = 0;
- u32 dest_data = 0;
-
- for (i = 0; i < row; i++) {
- for (j = 0; j < col; j++) {
- offset = (row * j + i);
- group = offset / (sizeof(src_data[ARRAY_INDEX_0]) * UNF_BITS_PER_BYTE);
- bit_offset = offset % (sizeof(src_data[ARRAY_INDEX_0]) * UNF_BITS_PER_BYTE);
- tmp_val = (src_data[group] >> bit_offset) & SPFC_PARITY_MASK;
-
- if (j == 0) {
- bit_val = tmp_val;
- continue;
- }
-
- bit_val ^= tmp_val;
- }
-
- bit_val = (~bit_val) & SPFC_PARITY_MASK;
-
- dest_data |= (bit_val << i);
- }
-
- return dest_data;
-}
-
-static void spfc_update_producer_info(u16 q_depth, u16 *pus_pi, u16 *pus_owner)
-{
- u16 current_pi = 0;
- u16 next_pi = 0;
- u16 owner = 0;
-
- current_pi = *pus_pi;
- next_pi = current_pi + 1;
-
- if (next_pi < q_depth) {
- *pus_pi = next_pi;
- } else {
- /* PI reversal */
- *pus_pi = 0;
-
- /* obit reversal */
- owner = *pus_owner;
- *pus_owner = !owner;
- }
-}
-
-static void spfc_update_consumer_info(u16 q_depth, u16 *pus_ci, u16 *pus_owner)
-{
- u16 current_ci = 0;
- u16 next_ci = 0;
- u16 owner = 0;
-
- current_ci = *pus_ci;
- next_ci = current_ci + 1;
-
- if (next_ci < q_depth) {
- *pus_ci = next_ci;
- } else {
- /* CI reversal */
- *pus_ci = 0;
-
- /* obit reversal */
- owner = *pus_owner;
- *pus_owner = !owner;
- }
-}
-
-static inline void spfc_update_cq_header(struct ci_record *ci_record, u16 ci,
- u16 owner)
-{
- u32 size = 0;
- struct ci_record record = {0};
-
- size = sizeof(struct ci_record);
- memcpy(&record, ci_record, size);
- spfc_big_to_cpu64(&record, size);
- record.cmsn = ci + (u16)(owner << SPFC_CQ_HEADER_OWNER_SHIFT);
- record.dump_cmsn = record.cmsn;
- spfc_cpu_to_big64(&record, size);
-
- wmb();
- memcpy(ci_record, &record, size);
-}
-
-static void spfc_update_srq_header(struct db_record *pmsn_record, u16 pmsn)
-{
- u32 size = 0;
- struct db_record record = {0};
-
- size = sizeof(struct db_record);
- memcpy(&record, pmsn_record, size);
- spfc_big_to_cpu64(&record, size);
- record.pmsn = pmsn;
- record.dump_pmsn = record.pmsn;
- spfc_cpu_to_big64(&record, sizeof(struct db_record));
-
- wmb();
- memcpy(pmsn_record, &record, size);
-}
-
-static void spfc_set_srq_wqe_owner_be(struct spfc_wqe_ctrl *sqe_ctrl_in_wp,
- u32 owner)
-{
- struct spfc_wqe_ctrl_ch wqe_ctrl_ch;
-
- mb();
-
- wqe_ctrl_ch.ctrl_ch_val = be32_to_cpu(sqe_ctrl_in_wp->ch.ctrl_ch_val);
- wqe_ctrl_ch.wd0.owner = owner;
- sqe_ctrl_in_wp->ch.ctrl_ch_val = cpu_to_be32(wqe_ctrl_ch.ctrl_ch_val);
-
- mb();
-}
-
-static inline void spfc_set_sq_wqe_owner_be(void *sqe)
-{
- u32 *sqe_dw = (u32 *)sqe;
- u32 *e_sqe_dw = (u32 *)((u8 *)sqe + SPFC_EXTEND_WQE_OFFSET);
-
- /* Ensure that the write of WQE is complete */
- mb();
- e_sqe_dw[SPFC_SQE_SECOND_OBIT_DW_POS] |= SPFC_SQE_OBIT_SET_MASK_BE;
- e_sqe_dw[SPFC_SQE_FIRST_OBIT_DW_POS] |= SPFC_SQE_OBIT_SET_MASK_BE;
- sqe_dw[SPFC_SQE_SECOND_OBIT_DW_POS] |= SPFC_SQE_OBIT_SET_MASK_BE;
- sqe_dw[SPFC_SQE_FIRST_OBIT_DW_POS] |= SPFC_SQE_OBIT_SET_MASK_BE;
- mb();
-}
-
-void spfc_clear_sq_wqe_owner_be(struct spfc_sqe *sqe)
-{
- u32 *sqe_dw = (u32 *)sqe;
- u32 *e_sqe_dw = (u32 *)((u8 *)sqe + SPFC_EXTEND_WQE_OFFSET);
-
- mb();
- sqe_dw[SPFC_SQE_SECOND_OBIT_DW_POS] &= SPFC_SQE_OBIT_CLEAR_MASK_BE;
- mb();
- sqe_dw[SPFC_SQE_FIRST_OBIT_DW_POS] &= SPFC_SQE_OBIT_CLEAR_MASK_BE;
- e_sqe_dw[SPFC_SQE_SECOND_OBIT_DW_POS] &= SPFC_SQE_OBIT_CLEAR_MASK_BE;
- e_sqe_dw[SPFC_SQE_FIRST_OBIT_DW_POS] &= SPFC_SQE_OBIT_CLEAR_MASK_BE;
-}
-
-static void spfc_set_direct_wqe_owner_be(void *sqe, u16 owner)
-{
- if (owner)
- spfc_set_sq_wqe_owner_be(sqe);
- else
- spfc_clear_sq_wqe_owner_be(sqe);
-}
-
-static void spfc_set_srq_link_wqe_owner_be(struct spfc_linkwqe *link_wqe,
- u32 owner, u16 pmsn)
-{
- struct spfc_linkwqe local_lw;
-
- mb();
- local_lw.val_wd1 = be32_to_cpu(link_wqe->val_wd1);
- local_lw.wd1.msn = pmsn;
- local_lw.wd1.dump_msn = (local_lw.wd1.msn & SPFC_LOCAL_LW_WD1_DUMP_MSN_MASK);
- link_wqe->val_wd1 = cpu_to_be32(local_lw.val_wd1);
-
- local_lw.val_wd0 = be32_to_cpu(link_wqe->val_wd0);
- local_lw.wd0.o = owner;
- link_wqe->val_wd0 = cpu_to_be32(local_lw.val_wd0);
- mb();
-}
-
-static inline bool spfc_is_scq_link_wqe(struct spfc_scq_info *scq_info)
-{
- u16 custom_scqe_num = 0;
-
- custom_scqe_num = scq_info->ci + 1;
-
- if ((custom_scqe_num % scq_info->wqe_num_per_buf == 0) ||
- scq_info->valid_wqe_num == custom_scqe_num)
- return true;
- else
- return false;
-}
-
-static struct spfc_wqe_page *
-spfc_add_tail_wqe_page(struct spfc_parent_ssq_info *ssq)
-{
- struct spfc_hba_info *hba = NULL;
- struct spfc_wqe_page *esgl = NULL;
- struct list_head *free_list_head = NULL;
- ulong flag = 0;
-
- hba = (struct spfc_hba_info *)ssq->hba;
-
- spin_lock_irqsave(&hba->sq_wpg_pool.wpg_pool_lock, flag);
-
- /* Get a WqePage from hba->sq_wpg_pool.list_free_wpg_pool, and add to
- * sq.list_SqTailWqePage
- */
- if (!list_empty(&hba->sq_wpg_pool.list_free_wpg_pool)) {
- free_list_head = UNF_OS_LIST_NEXT(&hba->sq_wpg_pool.list_free_wpg_pool);
- list_del(free_list_head);
- list_add_tail(free_list_head, &ssq->list_linked_list_sq);
- esgl = list_entry(free_list_head, struct spfc_wqe_page, entry_wpg);
-
- /* WqePage Pool counter */
- atomic_inc(&hba->sq_wpg_pool.wpg_in_use);
- } else {
- esgl = NULL;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]SQ pool is empty when SQ(0x%x) try to get wqe page",
- ssq->sqn);
- SPFC_HBA_STAT(hba, SPFC_STAT_SQ_POOL_EMPTY);
- }
-
- spin_unlock_irqrestore(&hba->sq_wpg_pool.wpg_pool_lock, flag);
-
- return esgl;
-}
-
-static inline struct spfc_sqe *spfc_get_wqe_page_entry(struct spfc_wqe_page *wpg,
- u32 wqe_offset)
-{
- struct spfc_sqe *sqe_wpg = NULL;
-
- sqe_wpg = (struct spfc_sqe *)(wpg->wpg_addr);
- sqe_wpg += wqe_offset;
-
- return sqe_wpg;
-}
-
-static void spfc_free_head_wqe_page(struct spfc_parent_ssq_info *ssq)
-{
- struct spfc_hba_info *hba = NULL;
- struct spfc_wqe_page *sq_wpg = NULL;
- struct list_head *entry_head_wqe_page = NULL;
- ulong flag = 0;
-
- atomic_dec(&ssq->wqe_page_cnt);
-
- hba = (struct spfc_hba_info *)ssq->hba;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "Port(0x%x) free wqe page nowpagecnt:%d",
- hba->port_cfg.port_id,
- atomic_read(&ssq->wqe_page_cnt));
- sq_wpg = SPFC_GET_SQ_HEAD(ssq);
-
- memset((void *)sq_wpg->wpg_addr, WQE_MARKER_0, hba->sq_wpg_pool.wpg_size);
-
- spin_lock_irqsave(&hba->sq_wpg_pool.wpg_pool_lock, flag);
- entry_head_wqe_page = &sq_wpg->entry_wpg;
- list_del(entry_head_wqe_page);
- list_add_tail(entry_head_wqe_page, &hba->sq_wpg_pool.list_free_wpg_pool);
-
- /* WqePage Pool counter */
- atomic_dec(&hba->sq_wpg_pool.wpg_in_use);
- spin_unlock_irqrestore(&hba->sq_wpg_pool.wpg_pool_lock, flag);
-}
-
-static void spfc_free_link_list_wpg(struct spfc_parent_ssq_info *ssq)
-{
- ulong flag = 0;
- struct spfc_hba_info *hba = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct list_head *entry_head_wqe_page = NULL;
- struct spfc_wqe_page *sq_wpg = NULL;
-
- hba = (struct spfc_hba_info *)ssq->hba;
-
- list_for_each_safe(node, next_node, &ssq->list_linked_list_sq) {
- sq_wpg = list_entry(node, struct spfc_wqe_page, entry_wpg);
- memset((void *)sq_wpg->wpg_addr, WQE_MARKER_0, hba->sq_wpg_pool.wpg_size);
-
- spin_lock_irqsave(&hba->sq_wpg_pool.wpg_pool_lock, flag);
- entry_head_wqe_page = &sq_wpg->entry_wpg;
- list_del(entry_head_wqe_page);
- list_add_tail(entry_head_wqe_page, &hba->sq_wpg_pool.list_free_wpg_pool);
-
- /* WqePage Pool counter */
- atomic_dec(&ssq->wqe_page_cnt);
- atomic_dec(&hba->sq_wpg_pool.wpg_in_use);
-
- spin_unlock_irqrestore(&hba->sq_wpg_pool.wpg_pool_lock, flag);
- }
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]Port(0x%x) RPort(0x%x) Sq(0x%x) link list destroyed, Sq.WqePageCnt=0x%x, SqWpgPool.wpg_in_use=0x%x",
- hba->port_cfg.port_id, ssq->sqn, ssq->context_id,
- atomic_read(&ssq->wqe_page_cnt), atomic_read(&hba->sq_wpg_pool.wpg_in_use));
-}
-
-struct spfc_wqe_page *
-spfc_add_one_wqe_page(struct spfc_parent_ssq_info *ssq)
-{
- u32 wqe_inx = 0;
- struct spfc_wqe_page *wqe_page = NULL;
- struct spfc_sqe *sqe_in_wp = NULL;
- struct spfc_linkwqe *link_wqe_in_wpg = NULL;
- struct spfc_linkwqe link_wqe;
-
- /* Add a new Wqe Page */
- wqe_page = spfc_add_tail_wqe_page(ssq);
-
- if (!wqe_page)
- return NULL;
-
- for (wqe_inx = 0; wqe_inx <= ssq->wqe_num_per_buf; wqe_inx++) {
- sqe_in_wp = spfc_get_wqe_page_entry(wqe_page, wqe_inx);
- sqe_in_wp->ctrl_sl.ch.ctrl_ch_val = 0;
- sqe_in_wp->ectrl_sl.ch.ctrl_ch_val = 0;
- }
-
- /* Set last WqePage as linkwqe */
- link_wqe_in_wpg = (struct spfc_linkwqe *)spfc_get_wqe_page_entry(wqe_page,
- ssq->wqe_num_per_buf);
- link_wqe.val_wd0 = 0;
- link_wqe.val_wd1 = 0;
- link_wqe.next_page_addr_hi = (ssq->queue_style == SPFC_QUEUE_RING_STYLE)
- ? SPFC_MSD(wqe_page->wpg_phy_addr)
- : 0;
- link_wqe.next_page_addr_lo = (ssq->queue_style == SPFC_QUEUE_RING_STYLE)
- ? SPFC_LSD(wqe_page->wpg_phy_addr)
- : 0;
- link_wqe.wd0.wf = CQM_WQE_WF_LINK;
- link_wqe.wd0.ctrlsl = CQM_LINK_WQE_CTRLSL_VALUE;
- link_wqe.wd0.o = !(ssq->last_pi_owner);
- link_wqe.wd1.lp = (ssq->queue_style == SPFC_QUEUE_RING_STYLE)
- ? CQM_LINK_WQE_LP_VALID
- : CQM_LINK_WQE_LP_INVALID;
- spfc_cpu_to_big32(&link_wqe, sizeof(struct spfc_linkwqe));
- memcpy(link_wqe_in_wpg, &link_wqe, sizeof(struct spfc_linkwqe));
- memcpy((u8 *)link_wqe_in_wpg + SPFC_EXTEND_WQE_OFFSET,
- &link_wqe, sizeof(struct spfc_linkwqe));
-
- return wqe_page;
-}
-
-static inline struct spfc_scqe_type *
-spfc_get_scq_entry(struct spfc_scq_info *scq_info)
-{
- u32 buf_id = 0;
- u16 buf_offset = 0;
- u16 ci = 0;
- struct cqm_buf_list *buf = NULL;
-
- FC_CHECK_RETURN_VALUE(scq_info, NULL);
-
- ci = scq_info->ci;
- buf_id = ci / scq_info->wqe_num_per_buf;
- buf = &scq_info->cqm_scq_info->q_room_buf_1.buf_list[buf_id];
- buf_offset = (u16)(ci % scq_info->wqe_num_per_buf);
-
- return (struct spfc_scqe_type *)(buf->va) + buf_offset;
-}
-
-static inline bool spfc_is_cqe_done(u32 *done, u32 *owner, u16 driver_owner)
-{
- return ((((u16)(!!(*done & SPFC_DONE_MASK)) == driver_owner) &&
- ((u16)(!!(*owner & SPFC_OWNER_MASK)) == driver_owner)) ? true : false);
-}
-
-u32 spfc_process_scq_cqe_entity(ulong info, u32 proc_cnt)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 index = 0;
- struct wq_header *queue_header = NULL;
- struct spfc_scqe_type *scqe = NULL;
- struct spfc_scqe_type tmp_scqe;
- struct spfc_scq_info *scq_info = (struct spfc_scq_info *)info;
-
- FC_CHECK_RETURN_VALUE(scq_info, ret);
- SPFC_FUNCTION_ENTER;
-
- queue_header = (struct wq_header *)(void *)(scq_info->cqm_scq_info->q_header_vaddr);
-
- for (index = 0; index < proc_cnt;) {
- /* If linked wqe, then update CI */
- if (spfc_is_scq_link_wqe(scq_info)) {
- spfc_update_consumer_info(scq_info->valid_wqe_num,
- &scq_info->ci,
- &scq_info->ci_owner);
- spfc_update_cq_header(&queue_header->ci_record,
- scq_info->ci, scq_info->ci_owner);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_INFO,
- "[info]Current wqe is a linked wqe");
- continue;
- }
-
- /* Get SCQE and then check obit & donebit whether been set */
- scqe = spfc_get_scq_entry(scq_info);
- if (unlikely(!scqe)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Scqe is NULL");
- break;
- }
-
- if (!spfc_is_cqe_done((u32 *)(void *)&scqe->wd0,
- (u32 *)(void *)&scqe->ch.wd0,
- scq_info->ci_owner)) {
- atomic_set(&scq_info->flush_stat, SPFC_QUEUE_FLUSH_DONE);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_INFO, "[info]Now has no valid scqe");
- break;
- }
-
- /* rmb & do memory copy */
- rmb();
- memcpy(&tmp_scqe, scqe, sizeof(struct spfc_scqe_type));
- /* process SCQ entry */
- ret = spfc_rcv_scq_entry_from_scq(scq_info->hba, (void *)&tmp_scqe,
- scq_info->queue_id);
- if (unlikely(ret != RETURN_OK)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]QueueId(0x%x) scqn(0x%x) scqe process error at CI(0x%x)",
- scq_info->queue_id, scq_info->scqn, scq_info->ci);
- }
-
- /* Update Driver's CI & Obit */
- spfc_update_consumer_info(scq_info->valid_wqe_num,
- &scq_info->ci, &scq_info->ci_owner);
- spfc_update_cq_header(&queue_header->ci_record, scq_info->ci,
- scq_info->ci_owner);
- index++;
- }
-
- /* Re-schedule again if necessary */
- if (index == proc_cnt)
- tasklet_schedule(&scq_info->tasklet);
-
- SPFC_FUNCTION_RETURN;
-
- return index;
-}
-
-void spfc_set_scq_irg_cfg(struct spfc_hba_info *hba, u32 mode, u16 msix_index)
-{
-#define SPFC_POLLING_MODE_ITERRUPT_PENDING_CNT 5
-#define SPFC_POLLING_MODE_ITERRUPT_COALESC_TIMER_CFG 10
- u8 pending_limt = 0;
- u8 coalesc_timer_cfg = 0;
-
- struct interrupt_info info = {0};
-
- if (mode != SPFC_SCQ_INTR_LOW_LATENCY_MODE) {
- pending_limt = SPFC_POLLING_MODE_ITERRUPT_PENDING_CNT;
- coalesc_timer_cfg =
- SPFC_POLLING_MODE_ITERRUPT_COALESC_TIMER_CFG;
- }
-
- memset(&info, 0, sizeof(info));
- info.interrupt_coalesc_set = 1;
- info.lli_set = 0;
- info.pending_limt = pending_limt;
- info.coalesc_timer_cfg = coalesc_timer_cfg;
- info.resend_timer_cfg = 0;
- info.msix_index = msix_index;
-
- sphw_set_interrupt_cfg(hba->dev_handle, info, SPHW_CHANNEL_FC);
-}
-
-void spfc_process_scq_cqe(ulong info)
-{
- struct spfc_scq_info *scq_info = (struct spfc_scq_info *)info;
-
- FC_CHECK_RETURN_VOID(scq_info);
-
- spfc_process_scq_cqe_entity(info, SPFC_CQE_MAX_PROCESS_NUM_PER_INTR);
-}
-
-irqreturn_t spfc_scq_irq(int irq, void *scq_info)
-{
- SPFC_FUNCTION_ENTER;
-
- FC_CHECK_RETURN_VALUE(scq_info, IRQ_NONE);
-
- tasklet_schedule(&((struct spfc_scq_info *)scq_info)->tasklet);
-
- SPFC_FUNCTION_RETURN;
-
- return IRQ_HANDLED;
-}
-
-static u32 spfc_alloc_scq_int(struct spfc_scq_info *scq_info)
-{
- int ret = UNF_RETURN_ERROR_S32;
- u16 act_num = 0;
- struct irq_info irq_info;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VALUE(scq_info, UNF_RETURN_ERROR);
-
- /* 1. Alloc & check SCQ IRQ */
- hba = (struct spfc_hba_info *)(scq_info->hba);
- ret = sphw_alloc_irqs(hba->dev_handle, SERVICE_T_FC, SPFC_INT_NUM_PER_QUEUE,
- &irq_info, &act_num);
- if (ret != RETURN_OK || act_num != SPFC_INT_NUM_PER_QUEUE) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate scq irq failed, return %d", ret);
- return UNF_RETURN_ERROR;
- }
-
- if (irq_info.msix_entry_idx >= SPFC_SCQ_INT_ID_MAX) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SCQ irq id exceed %d, msix_entry_idx %d",
- SPFC_SCQ_INT_ID_MAX, irq_info.msix_entry_idx);
- sphw_free_irq(hba->dev_handle, SERVICE_T_FC, irq_info.irq_id);
- return UNF_RETURN_ERROR;
- }
-
- scq_info->irq_id = (u32)(irq_info.irq_id);
- scq_info->msix_entry_idx = (u16)(irq_info.msix_entry_idx);
-
- snprintf(scq_info->irq_name, SPFC_IRQ_NAME_MAX, "fc_scq%u_%x_msix%u",
- scq_info->queue_id, hba->port_cfg.port_id, scq_info->msix_entry_idx);
-
- /* 2. SCQ IRQ tasklet init */
- tasklet_init(&scq_info->tasklet, spfc_process_scq_cqe, (ulong)(uintptr_t)scq_info);
-
- /* 3. Request IRQ for SCQ */
- ret = request_irq(scq_info->irq_id, spfc_scq_irq, 0, scq_info->irq_name, scq_info);
-
- sphw_set_msix_state(hba->dev_handle, scq_info->msix_entry_idx, SPHW_MSIX_ENABLE);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Request SCQ irq failed, SCQ Index = %u, return %d",
- scq_info->queue_id, ret);
- sphw_free_irq(hba->dev_handle, SERVICE_T_FC, scq_info->irq_id);
- memset(scq_info->irq_name, 0, SPFC_IRQ_NAME_MAX);
- scq_info->irq_id = 0;
- scq_info->msix_entry_idx = 0;
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-static void spfc_free_scq_int(struct spfc_scq_info *scq_info)
-{
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VOID(scq_info);
-
- hba = (struct spfc_hba_info *)(scq_info->hba);
- sphw_set_msix_state(hba->dev_handle, scq_info->msix_entry_idx, SPHW_MSIX_DISABLE);
- free_irq(scq_info->irq_id, scq_info);
- tasklet_kill(&scq_info->tasklet);
- sphw_free_irq(hba->dev_handle, SERVICE_T_FC, scq_info->irq_id);
- memset(scq_info->irq_name, 0, SPFC_IRQ_NAME_MAX);
- scq_info->irq_id = 0;
- scq_info->msix_entry_idx = 0;
-}
-
-static void spfc_init_scq_info(struct spfc_hba_info *hba, struct cqm_queue *cqm_scq,
- u32 queue_id, struct spfc_scq_info **scq_info)
-{
- FC_CHECK_RETURN_VOID(hba);
- FC_CHECK_RETURN_VOID(cqm_scq);
- FC_CHECK_RETURN_VOID(scq_info);
-
- *scq_info = &hba->scq_info[queue_id];
- (*scq_info)->queue_id = queue_id;
- (*scq_info)->scqn = cqm_scq->index;
- (*scq_info)->hba = (void *)hba;
-
- (*scq_info)->cqm_scq_info = cqm_scq;
- (*scq_info)->wqe_num_per_buf =
- cqm_scq->q_room_buf_1.buf_size / SPFC_SCQE_SIZE;
- (*scq_info)->wqe_size = SPFC_SCQE_SIZE;
- (*scq_info)->valid_wqe_num = (SPFC_SCQ_IS_STS(queue_id) ? SPFC_STS_SCQ_DEPTH
- : SPFC_CMD_SCQ_DEPTH);
- (*scq_info)->scqc_cq_depth = (SPFC_SCQ_IS_STS(queue_id) ? SPFC_STS_SCQC_CQ_DEPTH
- : SPFC_CMD_SCQC_CQ_DEPTH);
- (*scq_info)->scqc_ci_type = SPFC_STS_SCQ_CI_TYPE;
- (*scq_info)->ci = 0;
- (*scq_info)->ci_owner = 1;
-}
-
-static void spfc_init_scq_header(struct wq_header *queue_header)
-{
- FC_CHECK_RETURN_VOID(queue_header);
-
- memset(queue_header, 0, sizeof(struct wq_header));
-
- /* Obit default is 1 */
- queue_header->db_record.pmsn = 1 << UNF_SHIFT_15;
- queue_header->db_record.dump_pmsn = queue_header->db_record.pmsn;
- queue_header->ci_record.cmsn = 1 << UNF_SHIFT_15;
- queue_header->ci_record.dump_cmsn = queue_header->ci_record.cmsn;
-
- /* Big endian convert */
- spfc_cpu_to_big64((void *)queue_header, sizeof(struct wq_header));
-}
-
-static void spfc_cfg_scq_ctx(struct spfc_scq_info *scq_info,
- struct spfc_cq_qinfo *scq_ctx)
-{
- struct cqm_queue *cqm_scq_info = NULL;
- struct spfc_queue_info_bus queue_bus;
- u64 parity = 0;
-
- FC_CHECK_RETURN_VOID(scq_info);
-
- cqm_scq_info = scq_info->cqm_scq_info;
-
- scq_ctx->pcie_template_hi = 0;
- scq_ctx->cur_cqe_gpa = cqm_scq_info->q_room_buf_1.buf_list->pa >> SPFC_CQE_GPA_SHIFT;
- scq_ctx->pi = 0;
- scq_ctx->pi_o = 1;
- scq_ctx->ci = scq_info->ci;
- scq_ctx->ci_o = scq_info->ci_owner;
- scq_ctx->c_eqn_msi_x = scq_info->msix_entry_idx;
- scq_ctx->ci_type = scq_info->scqc_ci_type;
- scq_ctx->cq_depth = scq_info->scqc_cq_depth;
- scq_ctx->armq = SPFC_ARMQ_IDLE;
- scq_ctx->cur_cqe_cnt = 0;
- scq_ctx->cqe_max_cnt = 0;
- scq_ctx->cqe_dmaattr_idx = 0;
- scq_ctx->cq_so_ro = 0;
- scq_ctx->init_mode = SPFC_CQ_INT_MODE;
- scq_ctx->next_o = 1;
- scq_ctx->loop_o = 1;
- scq_ctx->next_cq_wqe_page_gpa = cqm_scq_info->q_room_buf_1.buf_list[ARRAY_INDEX_1].pa >>
- SPFC_NEXT_CQE_GPA_SHIFT;
- scq_ctx->pcie_template_lo = 0;
-
- scq_ctx->ci_gpa = (cqm_scq_info->q_header_paddr + offsetof(struct wq_header, ci_record)) >>
- SPFC_CQE_GPA_SHIFT;
-
- memset(&queue_bus, 0, sizeof(struct spfc_queue_info_bus));
- queue_bus.bus[ARRAY_INDEX_0] |= ((u64)(scq_info->scqn & SPFC_SCQN_MASK)); /* bits 20 */
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(scq_ctx->pcie_template_lo)) << UNF_SHIFT_20);
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(scq_ctx->ci_gpa & SPFC_SCQ_CTX_CI_GPA_MASK)) <<
- UNF_SHIFT_23); /* bits 28 */
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(scq_ctx->cqe_dmaattr_idx)) << UNF_SHIFT_51);
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(scq_ctx->cq_so_ro)) << UNF_SHIFT_57); /* bits 2 */
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(scq_ctx->init_mode)) << UNF_SHIFT_59); /* bits 2 */
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(scq_ctx->c_eqn_msi_x &
- SPFC_SCQ_CTX_C_EQN_MSI_X_MASK)) << UNF_SHIFT_61);
- queue_bus.bus[ARRAY_INDEX_1] |= ((u64)(scq_ctx->c_eqn_msi_x >> UNF_SHIFT_3)); /* bits 7 */
- queue_bus.bus[ARRAY_INDEX_1] |= (((u64)(scq_ctx->ci_type)) << UNF_SHIFT_7); /* bits 1 */
- queue_bus.bus[ARRAY_INDEX_1] |= (((u64)(scq_ctx->cq_depth)) << UNF_SHIFT_8); /* bits 3 */
- queue_bus.bus[ARRAY_INDEX_1] |= (((u64)(scq_ctx->cqe_max_cnt)) << UNF_SHIFT_11);
- queue_bus.bus[ARRAY_INDEX_1] |= (((u64)(scq_ctx->pcie_template_hi)) << UNF_SHIFT_19);
-
- parity = spfc_get_parity_value(queue_bus.bus, SPFC_SCQC_BUS_ROW, SPFC_SCQC_BUS_COL);
- scq_ctx->parity_0 = parity & SPFC_PARITY_MASK;
- scq_ctx->parity_1 = (parity >> UNF_SHIFT_1) & SPFC_PARITY_MASK;
- scq_ctx->parity_2 = (parity >> UNF_SHIFT_2) & SPFC_PARITY_MASK;
-
- spfc_cpu_to_big64((void *)scq_ctx, sizeof(struct spfc_cq_qinfo));
-}
-
-static u32 spfc_creat_scqc_via_cmdq_sync(struct spfc_hba_info *hba,
- struct spfc_cq_qinfo *scqc, u32 scqn)
-{
-#define SPFC_INIT_SCQC_TIMEOUT 3000
- int ret;
- u32 covrt_size;
- struct spfc_cmdqe_creat_scqc init_scqc_cmd;
- struct sphw_cmd_buf *cmdq_in_buf;
-
- cmdq_in_buf = sphw_alloc_cmd_buf(hba->dev_handle);
- if (!cmdq_in_buf) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]cmdq in_cmd_buf alloc failed");
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_INIT_SCQC);
- return UNF_RETURN_ERROR;
- }
-
- memset(&init_scqc_cmd, 0, sizeof(init_scqc_cmd));
- init_scqc_cmd.wd0.task_type = SPFC_TASK_T_INIT_SCQC;
- init_scqc_cmd.wd1.scqn = SPFC_LSW(scqn);
- covrt_size = sizeof(init_scqc_cmd) - sizeof(init_scqc_cmd.scqc);
- spfc_cpu_to_big32(&init_scqc_cmd, covrt_size);
-
- /* scqc is already big endian */
- memcpy(init_scqc_cmd.scqc, scqc, sizeof(*scqc));
- memcpy(cmdq_in_buf->buf, &init_scqc_cmd, sizeof(init_scqc_cmd));
- cmdq_in_buf->size = sizeof(init_scqc_cmd);
-
- ret = sphw_cmdq_detail_resp(hba->dev_handle, COMM_MOD_FC, 0,
- cmdq_in_buf, NULL, NULL,
- SPFC_INIT_SCQC_TIMEOUT, SPHW_CHANNEL_FC);
- sphw_free_cmd_buf(hba->dev_handle, cmdq_in_buf);
- if (ret) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Send creat scqc via cmdq failed, ret=%d",
- ret);
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_INIT_SCQC);
- return UNF_RETURN_ERROR;
- }
-
- SPFC_IO_STAT(hba, SPFC_TASK_T_INIT_SCQC);
-
- return RETURN_OK;
-}
-
-static u32 spfc_delete_ssqc_via_cmdq_sync(struct spfc_hba_info *hba, u32 xid,
- u64 context_gpa, u32 entry_count)
-{
-#define SPFC_DELETE_SSQC_TIMEOUT 3000
- int ret = RETURN_OK;
- struct spfc_cmdqe_delete_ssqc delete_ssqc_cmd;
- struct sphw_cmd_buf *cmdq_in_buf = NULL;
-
- cmdq_in_buf = sphw_alloc_cmd_buf(hba->dev_handle);
- if (!cmdq_in_buf) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]cmdq in_cmd_buf alloc failed");
- return UNF_RETURN_ERROR;
- }
-
- memset(&delete_ssqc_cmd, 0, sizeof(delete_ssqc_cmd));
- delete_ssqc_cmd.wd0.task_type = SPFC_TASK_T_CLEAR_SSQ_CONTEXT;
- delete_ssqc_cmd.wd0.xid = xid;
- delete_ssqc_cmd.wd0.entry_count = entry_count;
- delete_ssqc_cmd.wd1.scqn = SPFC_LSW(0);
- delete_ssqc_cmd.context_gpa_hi = SPFC_HIGH_32_BITS(context_gpa);
- delete_ssqc_cmd.context_gpa_lo = SPFC_LOW_32_BITS(context_gpa);
- spfc_cpu_to_big32(&delete_ssqc_cmd, sizeof(delete_ssqc_cmd));
- memcpy(cmdq_in_buf->buf, &delete_ssqc_cmd, sizeof(delete_ssqc_cmd));
- cmdq_in_buf->size = sizeof(delete_ssqc_cmd);
-
- ret = sphw_cmdq_detail_resp(hba->dev_handle, COMM_MOD_FC, 0,
- cmdq_in_buf, NULL, NULL,
- SPFC_DELETE_SSQC_TIMEOUT,
- SPHW_CHANNEL_FC);
-
- sphw_free_cmd_buf(hba->dev_handle, cmdq_in_buf);
-
- return ret;
-}
-
-static void spfc_free_ssq_qpc(struct spfc_hba_info *hba, u32 free_sq_num)
-{
- u32 global_sq_index = 0;
- u32 qid = 0;
- struct spfc_parent_shared_queue_info *ssq_info = NULL;
-
- SPFC_FUNCTION_ENTER;
- for (global_sq_index = 0; global_sq_index < free_sq_num;) {
- for (qid = 1; qid <= SPFC_SQ_NUM_PER_QPC; qid++) {
- ssq_info = &hba->parent_queue_mgr->shared_queue[global_sq_index];
- if (qid == SPFC_SQ_NUM_PER_QPC ||
- global_sq_index == free_sq_num - 1) {
- if (ssq_info->parent_ctx.cqm_parent_ctx_obj) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[INFO]qid 0x%x, global_sq_index 0x%x, free_sq_num 0x%x",
- qid, global_sq_index, free_sq_num);
- cqm3_object_delete(&ssq_info->parent_ctx
- .cqm_parent_ctx_obj->object);
- ssq_info->parent_ctx.cqm_parent_ctx_obj = NULL;
- }
- }
- global_sq_index++;
- if (global_sq_index >= free_sq_num)
- break;
- }
- }
-}
-
-void spfc_free_ssq(void *handle, u32 free_sq_num)
-{
-#define SPFC_FREE_SSQ_WAIT_MS 1000
- u32 global_sq_index = 0;
- u32 qid = 0;
- struct spfc_parent_shared_queue_info *ssq_info = NULL;
- struct spfc_parent_ssq_info *sq_ctrl = NULL;
- struct cqm_qpc_mpt *prnt_ctx = NULL;
- u32 ret = UNF_RETURN_ERROR;
- u32 entry_count = 0;
- struct spfc_hba_info *hba = NULL;
-
- SPFC_FUNCTION_ENTER;
-
- hba = (struct spfc_hba_info *)handle;
- for (global_sq_index = 0; global_sq_index < free_sq_num;) {
- for (qid = 1; qid <= SPFC_SQ_NUM_PER_QPC; qid++) {
- ssq_info = &hba->parent_queue_mgr->shared_queue[global_sq_index];
- sq_ctrl = &ssq_info->parent_ssq_info;
- /* Free data cos */
- spfc_free_link_list_wpg(sq_ctrl);
- if (sq_ctrl->queue_head_original) {
- pci_unmap_single(hba->pci_dev,
- sq_ctrl->queue_hdr_phy_addr_original,
- sizeof(struct spfc_queue_header) +
- SPFC_SQ_HEADER_ADDR_ALIGN_SIZE,
- DMA_BIDIRECTIONAL);
- kfree(sq_ctrl->queue_head_original);
- sq_ctrl->queue_head_original = NULL;
- }
- if (qid == SPFC_SQ_NUM_PER_QPC || global_sq_index == free_sq_num - 1) {
- if (ssq_info->parent_ctx.cqm_parent_ctx_obj) {
- prnt_ctx = ssq_info->parent_ctx.cqm_parent_ctx_obj;
- entry_count = (qid == SPFC_SQ_NUM_PER_QPC ?
- SPFC_SQ_NUM_PER_QPC :
- free_sq_num - global_sq_index);
- ret = spfc_delete_ssqc_via_cmdq_sync(hba, prnt_ctx->xid,
- prnt_ctx->paddr,
- entry_count);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]ucode delete ssq fail, glbindex 0x%x, qid 0x%x, glsqindex 0x%x",
- global_sq_index, qid, free_sq_num);
- }
- }
- }
- global_sq_index++;
- if (global_sq_index >= free_sq_num)
- break;
- }
- }
-
- msleep(SPFC_FREE_SSQ_WAIT_MS);
-
- spfc_free_ssq_qpc(hba, free_sq_num);
-}
-
-u32 spfc_creat_ssqc_via_cmdq_sync(struct spfc_hba_info *hba,
- struct spfc_ssq_parent_context *ssqc,
- u32 xid, u64 context_gpa)
-{
-#define SPFC_INIT_SSQC_TIMEOUT 3000
- int ret;
- u32 covrt_size;
- struct spfc_cmdqe_creat_ssqc create_ssqc_cmd;
- struct sphw_cmd_buf *cmdq_in_buf = NULL;
-
- cmdq_in_buf = sphw_alloc_cmd_buf(hba->dev_handle);
- if (!cmdq_in_buf) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]cmdq in_cmd_buf alloc failed");
- return UNF_RETURN_ERROR;
- }
-
- memset(&create_ssqc_cmd, 0, sizeof(create_ssqc_cmd));
- create_ssqc_cmd.wd0.task_type = SPFC_TASK_T_CREATE_SSQ_CONTEXT;
- create_ssqc_cmd.wd0.xid = xid;
- create_ssqc_cmd.wd1.scqn = SPFC_LSW(0);
- create_ssqc_cmd.context_gpa_hi = SPFC_HIGH_32_BITS(context_gpa);
- create_ssqc_cmd.context_gpa_lo = SPFC_LOW_32_BITS(context_gpa);
- covrt_size = sizeof(create_ssqc_cmd) - sizeof(create_ssqc_cmd.ssqc);
- spfc_cpu_to_big32(&create_ssqc_cmd, covrt_size);
-
- /* scqc is already big endian */
- memcpy(create_ssqc_cmd.ssqc, ssqc, sizeof(*ssqc));
- memcpy(cmdq_in_buf->buf, &create_ssqc_cmd, sizeof(create_ssqc_cmd));
- cmdq_in_buf->size = sizeof(create_ssqc_cmd);
- ret = sphw_cmdq_detail_resp(hba->dev_handle, COMM_MOD_FC, 0,
- cmdq_in_buf, NULL, NULL,
- SPFC_INIT_SSQC_TIMEOUT, SPHW_CHANNEL_FC);
- sphw_free_cmd_buf(hba->dev_handle, cmdq_in_buf);
- if (ret)
- return UNF_RETURN_ERROR;
- return RETURN_OK;
-}
-
-void spfc_init_sq_prnt_ctxt_sq_qinfo(struct spfc_sq_qinfo *sq_info,
- struct spfc_parent_ssq_info *ssq)
-{
- struct spfc_wqe_page *head_wqe_page = NULL;
- struct spfc_sq_qinfo *prnt_sq_ctx = NULL;
- struct spfc_queue_info_bus queue_bus;
-
- SPFC_FUNCTION_ENTER;
-
- /* Obtains the Parent Context address */
- head_wqe_page = SPFC_GET_SQ_HEAD(ssq);
-
- prnt_sq_ctx = sq_info;
-
- /* The PMSN is updated by the host driver */
- prnt_sq_ctx->pmsn_type = SPFC_PMSN_CI_TYPE_FROM_HOST;
-
- /* Indicates the value of O of the valid SQE in the current round of SQ.
- * * The value of Linked List SQ is always one, and the value of 0 is
- * invalid.
- */
- prnt_sq_ctx->loop_o =
- SPFC_OWNER_DRIVER_PRODUCT; /* current valid o-bit */
-
- /* should be opposite from loop_o */
- prnt_sq_ctx->cur_wqe_o = ~(prnt_sq_ctx->loop_o);
-
- /* the first sqe's gpa */
- prnt_sq_ctx->cur_sqe_gpa = head_wqe_page->wpg_phy_addr;
-
- /* Indicates the GPA of the Queue header that is initialized to the SQ
- * in * the Host memory. The value must be 16-byte aligned.
- */
- prnt_sq_ctx->pmsn_gpa = ssq->queue_hdr_phy_addr;
- if (wqe_pre_load != 0)
- prnt_sq_ctx->pmsn_gpa |= SPFC_SQ_LINK_PRE;
-
- /* This field is used to fill in the dmaattr_idx field of the ComboDMA.
- * The default value is 0
- */
- prnt_sq_ctx->sqe_dmaattr_idx = SPFC_DMA_ATTR_OFST;
-
- /* This field is filled using the value of RO_SO in the SGL0 of the
- * ComboDMA
- */
- prnt_sq_ctx->sq_so_ro = SPFC_PCIE_RELAXED_ORDERING;
-
- prnt_sq_ctx->ring = ssq->queue_style;
-
- /* This field is used to set the SGL0 field of the Child solicDMA */
- prnt_sq_ctx->zerocopy_dmaattr_idx = SPFC_DMA_ATTR_OFST;
-
- prnt_sq_ctx->zerocopy_so_ro = SPFC_PCIE_RELAXED_ORDERING;
- prnt_sq_ctx->enable_256 = SPFC_256BWQE_ENABLE;
-
- /* PCIe attribute information */
- prnt_sq_ctx->pcie_template = SPFC_PCIE_TEMPLATE;
-
- memset(&queue_bus, 0, sizeof(struct spfc_queue_info_bus));
- queue_bus.bus[ARRAY_INDEX_0] |= ((u64)(ssq->context_id & SPFC_SSQ_CTX_MASK)); /* bits 20 */
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(prnt_sq_ctx->sqe_dmaattr_idx)) << UNF_SHIFT_20);
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(prnt_sq_ctx->sq_so_ro)) << UNF_SHIFT_26);
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(prnt_sq_ctx->ring)) << UNF_SHIFT_28); /* bits 1 */
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(prnt_sq_ctx->zerocopy_dmaattr_idx))
- << UNF_SHIFT_29); /* bits 6 */
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(prnt_sq_ctx->zerocopy_so_ro)) << UNF_SHIFT_35);
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(prnt_sq_ctx->pcie_template)) << UNF_SHIFT_37);
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(prnt_sq_ctx->pmsn_gpa >> UNF_SHIFT_4))
- << UNF_SHIFT_43); /* bits 21 */
- queue_bus.bus[ARRAY_INDEX_1] |= ((u64)(prnt_sq_ctx->pmsn_gpa >> UNF_SHIFT_25));
- queue_bus.bus[ARRAY_INDEX_1] |= (((u64)(prnt_sq_ctx->pmsn_type)) << UNF_SHIFT_39);
- prnt_sq_ctx->parity = spfc_get_parity_value(queue_bus.bus, SPFC_SQC_BUS_ROW,
- SPFC_SQC_BUS_COL);
- spfc_cpu_to_big64(prnt_sq_ctx, sizeof(struct spfc_sq_qinfo));
-
- SPFC_FUNCTION_RETURN;
-}
-
-u32 spfc_create_ssq(void *handle)
-{
- u32 ret = RETURN_OK;
- u32 global_sq_index = 0;
- u32 qid = 0;
- struct cqm_qpc_mpt *prnt_ctx = NULL;
- struct spfc_parent_shared_queue_info *ssq_info = NULL;
- struct spfc_parent_ssq_info *sq_ctrl = NULL;
- u32 queue_header_alloc_size = 0;
- struct spfc_wqe_page *head_wpg = NULL;
- struct spfc_ssq_parent_context prnt_ctx_info;
- struct spfc_sq_qinfo *sq_info = NULL;
- struct spfc_scq_qinfo *psq_pretchinfo = NULL;
- struct spfc_queue_info_bus queue_bus;
- struct spfc_fc_key_section *keysection = NULL;
- struct spfc_hba_info *hba = NULL;
- dma_addr_t origin_addr;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
- hba = (struct spfc_hba_info *)handle;
- for (global_sq_index = 0; global_sq_index < SPFC_MAX_SSQ_NUM;) {
- qid = 0;
- prnt_ctx = cqm3_object_qpc_mpt_create(hba->dev_handle, SERVICE_T_FC,
- CQM_OBJECT_SERVICE_CTX,
- SPFC_CNTX_SIZE_256B, NULL,
- CQM_INDEX_INVALID);
- if (!prnt_ctx) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Create ssq context failed, CQM_INDEX is 0x%x",
- CQM_INDEX_INVALID);
- goto ssq_ctx_create_fail;
- }
- memset(&prnt_ctx_info, 0, sizeof(prnt_ctx_info));
- keysection = (struct spfc_fc_key_section *)&prnt_ctx_info;
- keysection->xid_h = (prnt_ctx->xid >> UNF_SHIFT_16) & SPFC_KEYSECTION_XID_H_MASK;
- keysection->xid_l = prnt_ctx->xid & SPFC_KEYSECTION_XID_L_MASK;
- spfc_cpu_to_big32(keysection, sizeof(struct spfc_fc_key_section));
- for (qid = 0; qid < SPFC_SQ_NUM_PER_QPC; qid++) {
- sq_info = (struct spfc_sq_qinfo *)((u8 *)(&prnt_ctx_info) + ((qid + 1) *
- SPFC_SQ_SPACE_OFFSET));
- ssq_info = &hba->parent_queue_mgr->shared_queue[global_sq_index];
- ssq_info->parent_ctx.cqm_parent_ctx_obj = prnt_ctx;
- /* Initialize struct spfc_parent_sq_info */
- sq_ctrl = &ssq_info->parent_ssq_info;
- sq_ctrl->hba = (void *)hba;
- sq_ctrl->context_id = prnt_ctx->xid;
- sq_ctrl->sq_queue_id = qid + SPFC_SQ_QID_START_PER_QPC;
- sq_ctrl->cache_id = FC_CALC_CID(prnt_ctx->xid);
- sq_ctrl->sqn = global_sq_index;
- sq_ctrl->max_sqe_num = hba->exi_count;
- /* Reduce one Link Wqe */
- sq_ctrl->wqe_num_per_buf = hba->sq_wpg_pool.wqe_per_wpg - 1;
- sq_ctrl->wqe_size = SPFC_SQE_SIZE;
- sq_ctrl->wqe_offset = 0;
- sq_ctrl->head_start_cmsn = 0;
- sq_ctrl->head_end_cmsn = SPFC_GET_WP_END_CMSN(0, sq_ctrl->wqe_num_per_buf);
- sq_ctrl->last_pmsn = 0;
- /* Linked List SQ Owner Bit 1 valid,0 invalid */
- sq_ctrl->last_pi_owner = 1;
- atomic_set(&sq_ctrl->sq_valid, true);
- sq_ctrl->accum_wqe_cnt = 0;
- sq_ctrl->service_type = SPFC_SERVICE_TYPE_FC_SQ;
- sq_ctrl->queue_style = (global_sq_index == SPFC_DIRECTWQE_SQ_INDEX) ?
- SPFC_QUEUE_RING_STYLE : SPFC_QUEUE_LINK_STYLE;
- INIT_LIST_HEAD(&sq_ctrl->list_linked_list_sq);
- atomic_set(&sq_ctrl->wqe_page_cnt, 0);
- atomic_set(&sq_ctrl->sq_db_cnt, 0);
- atomic_set(&sq_ctrl->sqe_minus_cqe_cnt, 1);
- atomic_set(&sq_ctrl->sq_wqe_cnt, 0);
- atomic_set(&sq_ctrl->sq_cqe_cnt, 0);
- spin_lock_init(&sq_ctrl->parent_sq_enqueue_lock);
- memset(sq_ctrl->io_stat, 0, sizeof(sq_ctrl->io_stat));
-
- /* Allocate and initialize the Queue Header space. 64B
- * alignment is required. * Additional 64B is applied
- * for alignment
- */
- queue_header_alloc_size = sizeof(struct spfc_queue_header) +
- SPFC_SQ_HEADER_ADDR_ALIGN_SIZE;
- sq_ctrl->queue_head_original = kmalloc(queue_header_alloc_size, GFP_ATOMIC);
- if (!sq_ctrl->queue_head_original) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SQ(0x%x) create SQ queue header failed",
- global_sq_index);
- goto ssq_qheader_create_fail;
- }
-
- memset((u8 *)sq_ctrl->queue_head_original, 0, queue_header_alloc_size);
-
- sq_ctrl->queue_hdr_phy_addr_original =
- pci_map_single(hba->pci_dev, sq_ctrl->queue_head_original,
- queue_header_alloc_size, DMA_BIDIRECTIONAL);
- origin_addr = sq_ctrl->queue_hdr_phy_addr_original;
- if (pci_dma_mapping_error(hba->pci_dev, origin_addr)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]SQ(0x%x) SQ queue header DMA mapping failed",
- global_sq_index);
- goto ssq_qheader_dma_map_fail;
- }
-
- /* Obtains the 64B alignment address */
- sq_ctrl->queue_header = (struct spfc_queue_header *)(uintptr_t)
- SPFC_ADDR_64_ALIGN((u64)((uintptr_t)(sq_ctrl->queue_head_original)));
- sq_ctrl->queue_hdr_phy_addr = SPFC_ADDR_64_ALIGN(origin_addr);
-
- /* Each SQ is allocated with a Wqe Page by default. The
- * WqePageCnt is incremented by one
- */
- head_wpg = spfc_add_one_wqe_page(sq_ctrl);
- if (!head_wpg) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]SQ(0x%x) create SQ first wqe page failed",
- global_sq_index);
- goto ssq_headwpg_create_fail;
- }
-
- atomic_inc(&sq_ctrl->wqe_page_cnt);
- spfc_init_sq_prnt_ctxt_sq_qinfo(sq_info, sq_ctrl);
- global_sq_index++;
- if (global_sq_index == SPFC_MAX_SSQ_NUM)
- break;
- }
- psq_pretchinfo = &prnt_ctx_info.sq_pretchinfo;
- psq_pretchinfo->hw_scqc_config.info.rq_th2_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.rq_th1_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.rq_th0_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.rq_min_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.sq_th2_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.sq_th1_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.sq_th0_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.sq_min_preld_cache_num = wqe_pre_load;
- psq_pretchinfo->hw_scqc_config.info.scq_n = (u64)0;
- psq_pretchinfo->hw_scqc_config.info.parity = 0;
-
- memset(&queue_bus, 0, sizeof(struct spfc_queue_info_bus));
- queue_bus.bus[ARRAY_INDEX_0] = psq_pretchinfo->hw_scqc_config.pctxt_val1;
- psq_pretchinfo->hw_scqc_config.info.parity =
- spfc_get_parity_value(queue_bus.bus, SPFC_HW_SCQC_BUS_ROW,
- SPFC_HW_SCQC_BUS_COL);
- spfc_cpu_to_big64(psq_pretchinfo, sizeof(struct spfc_scq_qinfo));
- ret = spfc_creat_ssqc_via_cmdq_sync(hba, &prnt_ctx_info,
- prnt_ctx->xid, prnt_ctx->paddr);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]SQ(0x%x) create ssqc failed.",
- global_sq_index);
- goto ssq_cmdqsync_fail;
- }
- }
-
- return RETURN_OK;
-
-ssq_headwpg_create_fail:
- pci_unmap_single(hba->pci_dev, sq_ctrl->queue_hdr_phy_addr_original,
- queue_header_alloc_size, DMA_BIDIRECTIONAL);
-
-ssq_qheader_dma_map_fail:
- kfree(sq_ctrl->queue_head_original);
- sq_ctrl->queue_head_original = NULL;
-
-ssq_qheader_create_fail:
- cqm3_object_delete(&prnt_ctx->object);
- ssq_info->parent_ctx.cqm_parent_ctx_obj = NULL;
- if (qid > 0) {
- while (qid--) {
- ssq_info = &hba->parent_queue_mgr->shared_queue[global_sq_index - qid];
- ssq_info->parent_ctx.cqm_parent_ctx_obj = NULL;
- }
- }
-
-ssq_ctx_create_fail:
-ssq_cmdqsync_fail:
- if (global_sq_index > 0)
- spfc_free_ssq(hba, global_sq_index);
-
- return UNF_RETURN_ERROR;
-}
-
-static u32 spfc_create_scq(struct spfc_hba_info *hba)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 scq_index = 0;
- u32 scq_cfg_num = 0;
- struct cqm_queue *cqm_scq = NULL;
- void *handle = NULL;
- struct spfc_scq_info *scq_info = NULL;
- struct spfc_cq_qinfo cq_qinfo;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- handle = hba->dev_handle;
- /* Create SCQ by CQM interface */
- for (scq_index = 0; scq_index < SPFC_TOTAL_SCQ_NUM; scq_index++) {
- /*
- * 1. Create/Allocate SCQ
- * *
- * Notice: SCQ[0, 2, 4 ...]--->CMD SCQ,
- * SCQ[1, 3, 5 ...]--->STS SCQ,
- * SCQ[SPFC_TOTAL_SCQ_NUM-1]--->Defaul SCQ
- */
- cqm_scq = cqm3_object_nonrdma_queue_create(handle, SERVICE_T_FC,
- CQM_OBJECT_NONRDMA_SCQ,
- SPFC_SCQ_IS_STS(scq_index) ?
- SPFC_STS_SCQ_DEPTH :
- SPFC_CMD_SCQ_DEPTH,
- SPFC_SCQE_SIZE, hba);
- if (!cqm_scq) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_WARN, "[err]Create scq failed");
-
- goto free_scq;
- }
-
- /* 2. Initialize SCQ (info) */
- spfc_init_scq_info(hba, cqm_scq, scq_index, &scq_info);
-
- /* 3. Allocate & Initialize SCQ interrupt */
- ret = spfc_alloc_scq_int(scq_info);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate scq interrupt failed");
-
- cqm3_object_delete(&cqm_scq->object);
- memset(scq_info, 0, sizeof(struct spfc_scq_info));
- goto free_scq;
- }
-
- /* 4. Initialize SCQ queue header */
- spfc_init_scq_header((struct wq_header *)(void *)cqm_scq->q_header_vaddr);
-
- /* 5. Initialize & Create SCQ CTX */
- memset(&cq_qinfo, 0, sizeof(cq_qinfo));
- spfc_cfg_scq_ctx(scq_info, &cq_qinfo);
- ret = spfc_creat_scqc_via_cmdq_sync(hba, &cq_qinfo, scq_info->scqn);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Create scq context failed");
-
- cqm3_object_delete(&cqm_scq->object);
- memset(scq_info, 0, sizeof(struct spfc_scq_info));
- goto free_scq;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Create SCQ[%u] Scqn=%u WqeNum=%u WqeSize=%u WqePerBuf=%u CqDepth=%u CiType=%u irq=%u msix=%u",
- scq_info->queue_id, scq_info->scqn,
- scq_info->valid_wqe_num, scq_info->wqe_size,
- scq_info->wqe_num_per_buf, scq_info->scqc_cq_depth,
- scq_info->scqc_ci_type, scq_info->irq_id,
- scq_info->msix_entry_idx);
- }
-
- /* Last SCQ is used to handle SCQE delivery access when clearing buffer
- */
- hba->default_scqn = scq_info->scqn;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Default Scqn=%u CqmScqIndex=%u", hba->default_scqn,
- cqm_scq->index);
-
- return RETURN_OK;
-
-free_scq:
- spfc_flush_scq_ctx(hba);
-
- scq_cfg_num = scq_index;
- for (scq_index = 0; scq_index < scq_cfg_num; scq_index++) {
- scq_info = &hba->scq_info[scq_index];
- spfc_free_scq_int(scq_info);
- cqm_scq = scq_info->cqm_scq_info;
- cqm3_object_delete(&cqm_scq->object);
- memset(scq_info, 0, sizeof(struct spfc_scq_info));
- }
-
- return UNF_RETURN_ERROR;
-}
-
-static void spfc_destroy_scq(struct spfc_hba_info *hba)
-{
- u32 scq_index = 0;
- struct cqm_queue *cqm_scq = NULL;
- struct spfc_scq_info *scq_info = NULL;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Start destroy total %d SCQ", SPFC_TOTAL_SCQ_NUM);
-
- FC_CHECK_RETURN_VOID(hba);
-
- /* Use CQM to delete SCQ */
- for (scq_index = 0; scq_index < SPFC_TOTAL_SCQ_NUM; scq_index++) {
- scq_info = &hba->scq_info[scq_index];
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ALL,
- "[info]Destroy SCQ%u, Scqn=%u, Irq=%u, msix=%u, name=%s",
- scq_index, scq_info->scqn, scq_info->irq_id,
- scq_info->msix_entry_idx, scq_info->irq_name);
-
- spfc_free_scq_int(scq_info);
- cqm_scq = scq_info->cqm_scq_info;
- cqm3_object_delete(&cqm_scq->object);
- memset(scq_info, 0, sizeof(struct spfc_scq_info));
- }
-}
-
-static void spfc_init_srq_info(struct spfc_hba_info *hba, struct cqm_queue *cqm_srq,
- struct spfc_srq_info *srq_info)
-{
- FC_CHECK_RETURN_VOID(hba);
- FC_CHECK_RETURN_VOID(cqm_srq);
- FC_CHECK_RETURN_VOID(srq_info);
-
- srq_info->hba = (void *)hba;
-
- srq_info->cqm_srq_info = cqm_srq;
- srq_info->wqe_num_per_buf = cqm_srq->q_room_buf_1.buf_size / SPFC_SRQE_SIZE - 1;
- srq_info->wqe_size = SPFC_SRQE_SIZE;
- srq_info->valid_wqe_num = cqm_srq->valid_wqe_num;
- srq_info->pi = 0;
- srq_info->pi_owner = SPFC_SRQ_INIT_LOOP_O;
- srq_info->pmsn = 0;
- srq_info->srqn = cqm_srq->index;
- srq_info->first_rqe_recv_dma = 0;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Init srq info(srq index 0x%x) valid wqe num 0x%x, buffer size 0x%x, wqe num per buf 0x%x",
- cqm_srq->index, srq_info->valid_wqe_num,
- cqm_srq->q_room_buf_1.buf_size, srq_info->wqe_num_per_buf);
-}
-
-static void spfc_init_srq_header(struct wq_header *queue_header)
-{
- FC_CHECK_RETURN_VOID(queue_header);
-
- memset(queue_header, 0, sizeof(struct wq_header));
-}
-
-/*
- *Function Name : spfc_get_srq_entry
- *Function Description: Obtain RQE in SRQ via PI.
- *Input Parameters : *srq_info,
- * **linked_rqe,
- * position
- *Output Parameters : N/A
- *Return Type : struct spfc_rqe*
- */
-static struct spfc_rqe *spfc_get_srq_entry(struct spfc_srq_info *srq_info,
- struct spfc_rqe **linked_rqe, u16 position)
-{
- u32 buf_id = 0;
- u32 wqe_num_per_buf = 0;
- u16 buf_offset = 0;
- struct cqm_buf_list *buf = NULL;
-
- FC_CHECK_RETURN_VALUE(srq_info, NULL);
-
- wqe_num_per_buf = srq_info->wqe_num_per_buf;
-
- buf_id = position / wqe_num_per_buf;
- buf = &srq_info->cqm_srq_info->q_room_buf_1.buf_list[buf_id];
- buf_offset = position % ((u16)wqe_num_per_buf);
-
- if (buf_offset + 1 == wqe_num_per_buf)
- *linked_rqe = (struct spfc_rqe *)(buf->va) + wqe_num_per_buf;
- else
- *linked_rqe = NULL;
-
- return (struct spfc_rqe *)(buf->va) + buf_offset;
-}
-
-void spfc_post_els_srq_wqe(struct spfc_srq_info *srq_info, u16 buf_id)
-{
- struct spfc_rqe *rqe = NULL;
- struct spfc_rqe tmp_rqe;
- struct spfc_rqe *linked_rqe = NULL;
- struct wq_header *wq_header = NULL;
- struct spfc_drq_buff_entry *buff_entry = NULL;
-
- FC_CHECK_RETURN_VOID(srq_info);
- FC_CHECK_RETURN_VOID(buf_id < srq_info->valid_wqe_num);
-
- buff_entry = srq_info->els_buff_entry_head + buf_id;
-
- spin_lock(&srq_info->srq_spin_lock);
-
- /* Obtain RQE, not include link wqe */
- rqe = spfc_get_srq_entry(srq_info, &linked_rqe, srq_info->pi);
- if (!rqe) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]post els srq,get srqe failed, valid wqe num 0x%x, pi 0x%x, pmsn 0x%x",
- srq_info->valid_wqe_num, srq_info->pi,
- srq_info->pmsn);
-
- spin_unlock(&srq_info->srq_spin_lock);
- return;
- }
-
- /* Initialize RQE */
- /* cs section is not used */
- memset(&tmp_rqe, 0, sizeof(struct spfc_rqe));
-
- /* default Obit is invalid, and set valid finally */
- spfc_build_srq_wqe_ctrls(&tmp_rqe, !srq_info->pi_owner, srq_info->pmsn + 1);
-
- tmp_rqe.bds_sl.buf_addr_hi = SPFC_HIGH_32_BITS(buff_entry->buff_dma);
- tmp_rqe.bds_sl.buf_addr_lo = SPFC_LOW_32_BITS(buff_entry->buff_dma);
- tmp_rqe.drv_sl.wd0.user_id = buf_id;
-
- /* convert to big endian */
- spfc_cpu_to_big32(&tmp_rqe, sizeof(struct spfc_rqe));
-
- memcpy(rqe, &tmp_rqe, sizeof(struct spfc_rqe));
-
- /* reset Obit */
- spfc_set_srq_wqe_owner_be((struct spfc_wqe_ctrl *)(void *)(&rqe->ctrl_sl),
- srq_info->pi_owner);
-
- if (linked_rqe) {
- /* Update Obit in linked WQE */
- spfc_set_srq_link_wqe_owner_be((struct spfc_linkwqe *)(void *)linked_rqe,
- srq_info->pi_owner, srq_info->pmsn + 1);
- }
-
- /* Update PI and PMSN */
- spfc_update_producer_info((u16)(srq_info->valid_wqe_num),
- &srq_info->pi, &srq_info->pi_owner);
-
- /* pmsn is 16bit. The value is added to the maximum value and is
- * automatically reversed
- */
- srq_info->pmsn++;
-
- /* Update pmsn in queue header */
- wq_header = (struct wq_header *)(void *)srq_info->cqm_srq_info->q_header_vaddr;
- spfc_update_srq_header(&wq_header->db_record, srq_info->pmsn);
-
- spin_unlock(&srq_info->srq_spin_lock);
-}
-
-/*
- *Function Name : spfc_cfg_srq_ctx
- *Function Description: Initialize the CTX of the SRQ that receives the
- * immediate data. The RQE of the SRQ
- * needs to be
- *initialized when the RQE is filled. Input Parameters : *srq_info, *srq_ctx,
- * sge_size,
- * rqe_gpa
- *Output Parameters : N/A
- *Return Type : void
- */
-static void spfc_cfg_srq_ctx(struct spfc_srq_info *srq_info,
- struct spfc_srq_ctx *ctx, u32 sge_size,
- u64 rqe_gpa)
-{
- struct spfc_srq_ctx *srq_ctx = NULL;
- struct cqm_queue *cqm_srq_info = NULL;
- struct spfc_queue_info_bus queue_bus;
-
- FC_CHECK_RETURN_VOID(srq_info);
- FC_CHECK_RETURN_VOID(ctx);
-
- cqm_srq_info = srq_info->cqm_srq_info;
- srq_ctx = ctx;
- srq_ctx->last_rq_pmsn = 0;
- srq_ctx->cur_rqe_msn = 0;
- srq_ctx->pcie_template = 0;
- /* The value of CTX needs to be updated
- *when RQE is configured
- */
- srq_ctx->cur_rqe_gpa = rqe_gpa;
- srq_ctx->cur_sge_v = 0;
- srq_ctx->cur_sge_l = 0;
- /* The information received by the SRQ is reported through the
- *SCQ. The interrupt and ArmCQ are disabled.
- */
- srq_ctx->int_mode = 0;
- srq_ctx->ceqn_msix = 0;
- srq_ctx->cur_sge_remain_len = 0;
- srq_ctx->cur_sge_id = 0;
- srq_ctx->consant_sge_len = sge_size;
- srq_ctx->cur_wqe_o = 0;
- srq_ctx->pmsn_type = SPFC_PMSN_CI_TYPE_FROM_HOST;
- srq_ctx->bdsl = 0;
- srq_ctx->cr = 0;
- srq_ctx->csl = 0;
- srq_ctx->cf = 0;
- srq_ctx->ctrl_sl = 0;
- srq_ctx->cur_sge_gpa = 0;
- srq_ctx->cur_pmsn_gpa = cqm_srq_info->q_header_paddr;
- srq_ctx->prefetch_max_masn = 0;
- srq_ctx->cqe_max_cnt = 0;
- srq_ctx->cur_cqe_cnt = 0;
- srq_ctx->arm_q = 0;
- srq_ctx->cq_so_ro = 0;
- srq_ctx->cqe_dma_attr_idx = 0;
- srq_ctx->rq_so_ro = 0;
- srq_ctx->rqe_dma_attr_idx = 0;
- srq_ctx->loop_o = SPFC_SRQ_INIT_LOOP_O;
- srq_ctx->ring = SPFC_QUEUE_RING;
-
- memset(&queue_bus, 0, sizeof(struct spfc_queue_info_bus));
- queue_bus.bus[ARRAY_INDEX_0] |= ((u64)(cqm_srq_info->q_ctx_paddr >> UNF_SHIFT_4));
- queue_bus.bus[ARRAY_INDEX_0] |= (((u64)(srq_ctx->rqe_dma_attr_idx &
- SPFC_SRQ_CTX_rqe_dma_attr_idx_MASK))
- << UNF_SHIFT_60); /* bits 4 */
-
- queue_bus.bus[ARRAY_INDEX_1] |= ((u64)(srq_ctx->rqe_dma_attr_idx >> UNF_SHIFT_4));
- queue_bus.bus[ARRAY_INDEX_1] |= (((u64)(srq_ctx->rq_so_ro)) << UNF_SHIFT_2); /* bits 2 */
- queue_bus.bus[ARRAY_INDEX_1] |= (((u64)(srq_ctx->cur_pmsn_gpa >> UNF_SHIFT_4))
- << UNF_SHIFT_4); /* bits 60 */
-
- queue_bus.bus[ARRAY_INDEX_2] |= ((u64)(srq_ctx->consant_sge_len)); /* bits 17 */
- queue_bus.bus[ARRAY_INDEX_2] |= (((u64)(srq_ctx->pcie_template)) << UNF_SHIFT_17);
-
- srq_ctx->parity = spfc_get_parity_value((void *)queue_bus.bus, SPFC_SRQC_BUS_ROW,
- SPFC_SRQC_BUS_COL);
-
- spfc_cpu_to_big64((void *)srq_ctx, sizeof(struct spfc_srq_ctx));
-}
-
-static u32 spfc_creat_srqc_via_cmdq_sync(struct spfc_hba_info *hba,
- struct spfc_srq_ctx *srqc,
- u64 ctx_gpa)
-{
-#define SPFC_INIT_SRQC_TIMEOUT 3000
-
- int ret;
- u32 covrt_size;
- struct spfc_cmdqe_creat_srqc init_srq_cmd;
- struct sphw_cmd_buf *cmdq_in_buf;
-
- cmdq_in_buf = sphw_alloc_cmd_buf(hba->dev_handle);
- if (!cmdq_in_buf) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]cmdq in_cmd_buf alloc failed");
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_INIT_SRQC);
- return UNF_RETURN_ERROR;
- }
-
- memset(&init_srq_cmd, 0, sizeof(init_srq_cmd));
- init_srq_cmd.wd0.task_type = SPFC_TASK_T_INIT_SRQC;
- init_srq_cmd.srqc_gpa_h = SPFC_HIGH_32_BITS(ctx_gpa);
- init_srq_cmd.srqc_gpa_l = SPFC_LOW_32_BITS(ctx_gpa);
- covrt_size = sizeof(init_srq_cmd) - sizeof(init_srq_cmd.srqc);
- spfc_cpu_to_big32(&init_srq_cmd, covrt_size);
-
- /* srqc is already big-endian */
- memcpy(init_srq_cmd.srqc, srqc, sizeof(*srqc));
- memcpy(cmdq_in_buf->buf, &init_srq_cmd, sizeof(init_srq_cmd));
- cmdq_in_buf->size = sizeof(init_srq_cmd);
-
- ret = sphw_cmdq_detail_resp(hba->dev_handle, COMM_MOD_FC, 0,
- cmdq_in_buf, NULL, NULL,
- SPFC_INIT_SRQC_TIMEOUT, SPHW_CHANNEL_FC);
-
- sphw_free_cmd_buf(hba->dev_handle, cmdq_in_buf);
-
- if (ret) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Send creat srqc via cmdq failed, ret=%d",
- ret);
-
- SPFC_ERR_IO_STAT(hba, SPFC_TASK_T_INIT_SRQC);
- return UNF_RETURN_ERROR;
- }
-
- SPFC_IO_STAT(hba, SPFC_TASK_T_INIT_SRQC);
-
- return RETURN_OK;
-}
-
-static void spfc_init_els_srq_wqe(struct spfc_srq_info *srq_info)
-{
- u32 rqe_index = 0;
- struct spfc_drq_buff_entry *buf_entry = NULL;
-
- FC_CHECK_RETURN_VOID(srq_info);
-
- for (rqe_index = 0; rqe_index < srq_info->valid_wqe_num - 1; rqe_index++) {
- buf_entry = srq_info->els_buff_entry_head + rqe_index;
- spfc_post_els_srq_wqe(srq_info, buf_entry->buff_id);
- }
-}
-
-static void spfc_free_els_srq_buff(struct spfc_hba_info *hba, u32 srq_valid_wqe)
-{
- u32 buff_index = 0;
- struct spfc_srq_info *srq_info = NULL;
- struct spfc_drq_buff_entry *buff_entry = NULL;
-
- FC_CHECK_RETURN_VOID(hba);
-
- srq_info = &hba->els_srq_info;
-
- if (!srq_info->els_buff_entry_head)
- return;
-
- for (buff_index = 0; buff_index < srq_valid_wqe; buff_index++) {
- buff_entry = &srq_info->els_buff_entry_head[buff_index];
- buff_entry->buff_addr = NULL;
- }
-
- if (srq_info->buf_list.buflist) {
- for (buff_index = 0; buff_index < srq_info->buf_list.buf_num;
- buff_index++) {
- if (srq_info->buf_list.buflist[buff_index].paddr != 0) {
- pci_unmap_single(hba->pci_dev,
- srq_info->buf_list.buflist[buff_index].paddr,
- srq_info->buf_list.buf_size,
- DMA_FROM_DEVICE);
- srq_info->buf_list.buflist[buff_index].paddr = 0;
- }
- kfree(srq_info->buf_list.buflist[buff_index].vaddr);
- srq_info->buf_list.buflist[buff_index].vaddr = NULL;
- }
-
- kfree(srq_info->buf_list.buflist);
- srq_info->buf_list.buflist = NULL;
- }
-
- kfree(srq_info->els_buff_entry_head);
- srq_info->els_buff_entry_head = NULL;
-}
-
-static u32 spfc_alloc_els_srq_buff(struct spfc_hba_info *hba, u32 srq_valid_wqe)
-{
- u32 req_buff_size = 0;
- u32 buff_index = 0;
- struct spfc_srq_info *srq_info = NULL;
- struct spfc_drq_buff_entry *buff_entry = NULL;
- u32 buf_total_size;
- u32 buf_num;
- u32 alloc_idx;
- u32 cur_buf_idx = 0;
- u32 cur_buf_offset = 0;
- u32 buf_cnt_perhugebuf;
-
- srq_info = &hba->els_srq_info;
-
- /* Apply for entry buffer */
- req_buff_size = (u32)(srq_valid_wqe * sizeof(struct spfc_drq_buff_entry));
- srq_info->els_buff_entry_head = (struct spfc_drq_buff_entry *)kmalloc(req_buff_size,
- GFP_KERNEL);
- if (!srq_info->els_buff_entry_head) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate ELS Srq receive buffer entries failed");
-
- return UNF_RETURN_ERROR;
- }
- memset(srq_info->els_buff_entry_head, 0, req_buff_size);
-
- buf_total_size = SPFC_SRQ_ELS_SGE_LEN * srq_valid_wqe;
-
- srq_info->buf_list.buf_size = buf_total_size > BUF_LIST_PAGE_SIZE
- ? BUF_LIST_PAGE_SIZE
- : buf_total_size;
- buf_cnt_perhugebuf = srq_info->buf_list.buf_size / SPFC_SRQ_ELS_SGE_LEN;
- buf_num = srq_valid_wqe % buf_cnt_perhugebuf ?
- srq_valid_wqe / buf_cnt_perhugebuf + 1 :
- srq_valid_wqe / buf_cnt_perhugebuf;
- srq_info->buf_list.buflist = (struct buff_list *)kmalloc(buf_num * sizeof(struct buff_list),
- GFP_KERNEL);
- srq_info->buf_list.buf_num = buf_num;
-
- if (!srq_info->buf_list.buflist) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate ELS buf list failed out of memory");
- goto free_buff;
- }
- memset(srq_info->buf_list.buflist, 0, buf_num * sizeof(struct buff_list));
-
- for (alloc_idx = 0; alloc_idx < buf_num; alloc_idx++) {
- srq_info->buf_list.buflist[alloc_idx].vaddr = kmalloc(srq_info->buf_list.buf_size,
- GFP_KERNEL);
- if (!srq_info->buf_list.buflist[alloc_idx].vaddr)
- goto free_buff;
-
- memset(srq_info->buf_list.buflist[alloc_idx].vaddr, 0, srq_info->buf_list.buf_size);
-
- srq_info->buf_list.buflist[alloc_idx].paddr =
- pci_map_single(hba->pci_dev, srq_info->buf_list.buflist[alloc_idx].vaddr,
- srq_info->buf_list.buf_size, DMA_FROM_DEVICE);
- if (pci_dma_mapping_error(hba->pci_dev,
- srq_info->buf_list.buflist[alloc_idx].paddr)) {
- srq_info->buf_list.buflist[alloc_idx].paddr = 0;
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Map els srq buffer failed");
-
- goto free_buff;
- }
- }
-
- /* Apply for receiving buffer and attach it to the free linked list */
- for (buff_index = 0; buff_index < srq_valid_wqe; buff_index++) {
- buff_entry = &srq_info->els_buff_entry_head[buff_index];
- cur_buf_idx = buff_index / buf_cnt_perhugebuf;
- cur_buf_offset = SPFC_SRQ_ELS_SGE_LEN * (buff_index % buf_cnt_perhugebuf);
- buff_entry->buff_addr = srq_info->buf_list.buflist[cur_buf_idx].vaddr +
- cur_buf_offset;
- buff_entry->buff_dma = srq_info->buf_list.buflist[cur_buf_idx].paddr +
- cur_buf_offset;
- buff_entry->buff_id = (u16)buff_index;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[EVENT]Allocate bufnum:%u,buf_total_size:%u", buf_num,
- buf_total_size);
-
- return RETURN_OK;
-
-free_buff:
- spfc_free_els_srq_buff(hba, srq_valid_wqe);
- return UNF_RETURN_ERROR;
-}
-
-void spfc_send_clear_srq_cmd(struct spfc_hba_info *hba,
- struct spfc_srq_info *srq_info)
-{
- union spfc_cmdqe cmdqe;
- struct cqm_queue *cqm_fcp_srq = NULL;
- ulong flag = 0;
-
- memset(&cmdqe, 0, sizeof(union spfc_cmdqe));
-
- spin_lock_irqsave(&srq_info->srq_spin_lock, flag);
- cqm_fcp_srq = srq_info->cqm_srq_info;
- if (!cqm_fcp_srq) {
- srq_info->state = SPFC_CLEAN_DONE;
- spin_unlock_irqrestore(&srq_info->srq_spin_lock, flag);
- return;
- }
-
- cmdqe.clear_srq.wd0.task_type = SPFC_TASK_T_CLEAR_SRQ;
- cmdqe.clear_srq.wd1.scqn = SPFC_LSW(hba->default_scqn);
- cmdqe.clear_srq.wd1.srq_type = srq_info->srq_type;
- cmdqe.clear_srq.srqc_gpa_h = SPFC_HIGH_32_BITS(cqm_fcp_srq->q_ctx_paddr);
- cmdqe.clear_srq.srqc_gpa_l = SPFC_LOW_32_BITS(cqm_fcp_srq->q_ctx_paddr);
-
- (void)queue_delayed_work(hba->work_queue, &srq_info->del_work,
- (ulong)msecs_to_jiffies(SPFC_SRQ_DEL_STAGE_TIMEOUT_MS));
- spin_unlock_irqrestore(&srq_info->srq_spin_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port 0x%x begin to clear srq 0x%x(0x%x,0x%llx)",
- hba->port_cfg.port_id, srq_info->srq_type,
- SPFC_LSW(hba->default_scqn),
- (u64)cqm_fcp_srq->q_ctx_paddr);
-
- /* Run the ROOT CMDQ command to issue the clear srq command. If the
- * command fails to be delivered, retry upon timeout.
- */
- (void)spfc_root_cmdq_enqueue(hba, &cmdqe, sizeof(cmdqe.clear_srq));
-}
-
-/*
- *Function Name : spfc_srq_clr_timeout
- *Function Description: Delete srq when timeout.
- *Input Parameters : *work
- *Output Parameters : N/A
- *Return Type : void
- */
-static void spfc_srq_clr_timeout(struct work_struct *work)
-{
-#define SPFC_MAX_DEL_SRQ_RETRY_TIMES 2
- struct spfc_srq_info *srq = NULL;
- struct spfc_hba_info *hba = NULL;
- struct cqm_queue *cqm_fcp_imm_srq = NULL;
- ulong flag = 0;
-
- srq = container_of(work, struct spfc_srq_info, del_work.work);
-
- spin_lock_irqsave(&srq->srq_spin_lock, flag);
- hba = srq->hba;
- cqm_fcp_imm_srq = srq->cqm_srq_info;
- spin_unlock_irqrestore(&srq->srq_spin_lock, flag);
-
- if (hba && cqm_fcp_imm_srq) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port 0x%x clear srq 0x%x stat 0x%x timeout",
- hba->port_cfg.port_id, srq->srq_type, srq->state);
-
- /* If the delivery fails or the execution times out after the
- * delivery, try again once
- */
- srq->del_retry_time++;
- if (srq->del_retry_time < SPFC_MAX_DEL_SRQ_RETRY_TIMES)
- spfc_send_clear_srq_cmd(hba, srq);
- else
- srq->del_retry_time = 0;
- }
-}
-
-static u32 spfc_create_els_srq(struct spfc_hba_info *hba)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct cqm_queue *cqm_srq = NULL;
- struct wq_header *wq_header = NULL;
- struct spfc_srq_info *srq_info = NULL;
- struct spfc_srq_ctx srq_ctx = {0};
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- cqm_srq = cqm3_object_fc_srq_create(hba->dev_handle, SERVICE_T_FC,
- CQM_OBJECT_NONRDMA_SRQ, SPFC_SRQ_ELS_DATA_DEPTH,
- SPFC_SRQE_SIZE, hba);
- if (!cqm_srq) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Create Els Srq failed");
-
- return UNF_RETURN_ERROR;
- }
-
- /* Initialize SRQ */
- srq_info = &hba->els_srq_info;
- spfc_init_srq_info(hba, cqm_srq, srq_info);
- srq_info->srq_type = SPFC_SRQ_ELS;
- srq_info->enable = true;
- srq_info->state = SPFC_CLEAN_DONE;
- srq_info->del_retry_time = 0;
-
- /* The srq lock is initialized and can be created repeatedly */
- spin_lock_init(&srq_info->srq_spin_lock);
- srq_info->spin_lock_init = true;
-
- /* Initialize queue header */
- wq_header = (struct wq_header *)(void *)cqm_srq->q_header_vaddr;
- spfc_init_srq_header(wq_header);
- INIT_DELAYED_WORK(&srq_info->del_work, spfc_srq_clr_timeout);
-
- /* Apply for RQ buffer */
- ret = spfc_alloc_els_srq_buff(hba, srq_info->valid_wqe_num);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate Els Srq buffer failed");
-
- cqm3_object_delete(&cqm_srq->object);
- memset(srq_info, 0, sizeof(struct spfc_srq_info));
- return UNF_RETURN_ERROR;
- }
-
- /* Fill RQE, update queue header */
- spfc_init_els_srq_wqe(srq_info);
-
- /* Fill SRQ CTX */
- memset(&srq_ctx, 0, sizeof(srq_ctx));
- spfc_cfg_srq_ctx(srq_info, &srq_ctx, SPFC_SRQ_ELS_SGE_LEN,
- srq_info->cqm_srq_info->q_room_buf_1.buf_list->pa);
-
- ret = spfc_creat_srqc_via_cmdq_sync(hba, &srq_ctx, srq_info->cqm_srq_info->q_ctx_paddr);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Creat Els Srqc failed");
-
- spfc_free_els_srq_buff(hba, srq_info->valid_wqe_num);
- cqm3_object_delete(&cqm_srq->object);
- memset(srq_info, 0, sizeof(struct spfc_srq_info));
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-void spfc_wq_destroy_els_srq(struct work_struct *work)
-{
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VOID(work);
- hba =
- container_of(work, struct spfc_hba_info, els_srq_clear_work);
- spfc_destroy_els_srq(hba);
-}
-
-void spfc_destroy_els_srq(void *handle)
-{
- /*
- * Receive clear els srq sts
- * ---then--->>> destroy els srq
- */
- struct spfc_srq_info *srq_info = NULL;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VOID(handle);
-
- hba = (struct spfc_hba_info *)handle;
- srq_info = &hba->els_srq_info;
-
- /* release receive buffer */
- spfc_free_els_srq_buff(hba, srq_info->valid_wqe_num);
-
- /* release srq info */
- if (srq_info->cqm_srq_info) {
- cqm3_object_delete(&srq_info->cqm_srq_info->object);
- srq_info->cqm_srq_info = NULL;
- }
- if (srq_info->spin_lock_init)
- srq_info->spin_lock_init = false;
- srq_info->hba = NULL;
- srq_info->enable = false;
- srq_info->state = SPFC_CLEAN_DONE;
-}
-
-/*
- *Function Name : spfc_create_srq
- *Function Description: Create SRQ, which contains four SRQ for receiving
- * instant data and a SRQ for receiving
- * ELS data.
- *Input Parameters : *hba Output Parameters : N/A Return Type :u32
- */
-static u32 spfc_create_srq(struct spfc_hba_info *hba)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
-
- /* Create ELS SRQ */
- ret = spfc_create_els_srq(hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Create Els Srq failed");
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-/*
- *Function Name : spfc_destroy_srq
- *Function Description: Release the SRQ resource, including the SRQ for
- * receiving the immediate data and the
- * SRQ forreceiving the ELS data.
- *Input Parameters : *hba Output Parameters : N/A
- *Return Type : void
- */
-static void spfc_destroy_srq(struct spfc_hba_info *hba)
-{
- FC_CHECK_RETURN_VOID(hba);
-
- spfc_destroy_els_srq(hba);
-}
-
-u32 spfc_create_common_share_queues(void *handle)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
- hba = (struct spfc_hba_info *)handle;
- /* Create & Init 8 pairs SCQ */
- ret = spfc_create_scq(hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Create scq failed");
-
- return UNF_RETURN_ERROR;
- }
-
- /* Alloc SRQ resource for SIRT & ELS */
- ret = spfc_create_srq(hba);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Create srq failed");
-
- spfc_flush_scq_ctx(hba);
- spfc_destroy_scq(hba);
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-void spfc_destroy_common_share_queues(void *hba)
-{
- FC_CHECK_RETURN_VOID(hba);
-
- spfc_destroy_scq((struct spfc_hba_info *)hba);
- spfc_destroy_srq((struct spfc_hba_info *)hba);
-}
-
-static u8 spfc_map_fcp_data_cos(struct spfc_hba_info *hba)
-{
- u8 i = 0;
- u8 min_cnt_index = SPFC_PACKET_COS_FC_DATA;
- bool get_init_index = false;
-
- for (i = 0; i < SPFC_MAX_COS_NUM; i++) {
- /* Check whether the CoS is valid for the FC and cannot be
- * occupied by the CMD
- */
- if ((!(hba->cos_bitmap & ((u32)1 << i))) || i == SPFC_PACKET_COS_FC_CMD)
- continue;
-
- if (!get_init_index) {
- min_cnt_index = i;
- get_init_index = true;
- continue;
- }
-
- if (atomic_read(&hba->cos_rport_cnt[i]) <
- atomic_read(&hba->cos_rport_cnt[min_cnt_index]))
- min_cnt_index = i;
- }
-
- atomic_inc(&hba->cos_rport_cnt[min_cnt_index]);
-
- return min_cnt_index;
-}
-
-static void spfc_update_cos_rport_cnt(struct spfc_hba_info *hba, u8 cos_index)
-{
- if (cos_index >= SPFC_MAX_COS_NUM ||
- cos_index == SPFC_PACKET_COS_FC_CMD ||
- (!(hba->cos_bitmap & ((u32)1 << cos_index))) ||
- (atomic_read(&hba->cos_rport_cnt[cos_index]) == 0))
- return;
-
- atomic_dec(&hba->cos_rport_cnt[cos_index]);
-}
-
-void spfc_invalid_parent_sq(struct spfc_parent_sq_info *sq_info)
-{
- sq_info->rport_index = INVALID_VALUE32;
- sq_info->context_id = INVALID_VALUE32;
- sq_info->sq_queue_id = INVALID_VALUE32;
- sq_info->cache_id = INVALID_VALUE32;
- sq_info->local_port_id = INVALID_VALUE32;
- sq_info->remote_port_id = INVALID_VALUE32;
- sq_info->hba = NULL;
- sq_info->del_start_jiff = INVALID_VALUE64;
- sq_info->port_in_flush = false;
- sq_info->sq_in_sess_rst = false;
- sq_info->oqid_rd = INVALID_VALUE16;
- sq_info->oqid_wr = INVALID_VALUE16;
- sq_info->srq_ctx_addr = 0;
- sq_info->sqn_base = 0;
- atomic_set(&sq_info->sq_cached, false);
- sq_info->vport_id = 0;
- sq_info->sirt_dif_control.protect_opcode = UNF_DIF_ACTION_NONE;
- sq_info->need_offloaded = INVALID_VALUE8;
- atomic_set(&sq_info->sq_valid, false);
- atomic_set(&sq_info->flush_done_wait_cnt, 0);
- memset(&sq_info->delay_sqe, 0, sizeof(struct spfc_delay_sqe_ctrl_info));
- memset(sq_info->io_stat, 0, sizeof(sq_info->io_stat));
-}
-
-static void spfc_parent_sq_opreate_timeout(struct work_struct *work)
-{
- ulong flag = 0;
- struct spfc_parent_sq_info *parent_sq = NULL;
- struct spfc_parent_queue_info *parent_queue = NULL;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VOID(work);
-
- parent_sq = container_of(work, struct spfc_parent_sq_info, del_work.work);
- parent_queue = container_of(parent_sq, struct spfc_parent_queue_info, parent_sq_info);
- hba = (struct spfc_hba_info *)parent_sq->hba;
- FC_CHECK_RETURN_VOID(hba);
-
- spin_lock_irqsave(&parent_queue->parent_queue_state_lock, flag);
- if (parent_queue->offload_state == SPFC_QUEUE_STATE_DESTROYING) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "Port(0x%x) sq rport index(0x%x) local nportid(0x%x),remote nportid(0x%x) reset timeout.",
- hba->port_cfg.port_id, parent_sq->rport_index,
- parent_sq->local_port_id,
- parent_sq->remote_port_id);
- }
- spin_unlock_irqrestore(&parent_queue->parent_queue_state_lock, flag);
-}
-
-static void spfc_parent_sq_wait_flush_done_timeout(struct work_struct *work)
-{
- ulong flag = 0;
- struct spfc_parent_sq_info *parent_sq = NULL;
- struct spfc_parent_queue_info *parent_queue = NULL;
- struct spfc_hba_info *hba = NULL;
- u32 ctx_flush_done;
- u32 *ctx_dw = NULL;
- int ret;
- int sq_state = SPFC_STAT_PARENT_SQ_QUEUE_DELAYED_WORK;
- spinlock_t *prtq_state_lock = NULL;
-
- FC_CHECK_RETURN_VOID(work);
-
- parent_sq = container_of(work, struct spfc_parent_sq_info, flush_done_timeout_work.work);
-
- FC_CHECK_RETURN_VOID(parent_sq);
-
- parent_queue = container_of(parent_sq, struct spfc_parent_queue_info, parent_sq_info);
- prtq_state_lock = &parent_queue->parent_queue_state_lock;
- hba = (struct spfc_hba_info *)parent_sq->hba;
- FC_CHECK_RETURN_VOID(hba);
- FC_CHECK_RETURN_VOID(parent_queue);
-
- spin_lock_irqsave(prtq_state_lock, flag);
- if (parent_queue->offload_state != SPFC_QUEUE_STATE_DESTROYING) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) sq rport index(0x%x) is not destroying status,offloadsts is %d",
- hba->port_cfg.port_id, parent_sq->rport_index,
- parent_queue->offload_state);
- spin_unlock_irqrestore(prtq_state_lock, flag);
- return;
- }
-
- if (parent_queue->parent_ctx.cqm_parent_ctx_obj) {
- ctx_dw = (u32 *)((void *)(parent_queue->parent_ctx.cqm_parent_ctx_obj->vaddr));
- ctx_flush_done = ctx_dw[SPFC_CTXT_FLUSH_DONE_DW_POS] & SPFC_CTXT_FLUSH_DONE_MASK_BE;
- if (ctx_flush_done == 0) {
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- if (atomic_read(&parent_queue->parent_sq_info.flush_done_wait_cnt) <
- SPFC_SQ_WAIT_FLUSH_DONE_TIMEOUT_CNT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[info]Port(0x%x) sq rport index(0x%x) wait flush done timeout %d times",
- hba->port_cfg.port_id, parent_sq->rport_index,
- atomic_read(&(parent_queue->parent_sq_info
- .flush_done_wait_cnt)));
-
- atomic_inc(&parent_queue->parent_sq_info.flush_done_wait_cnt);
-
- /* Delay Free Sq info */
- ret = queue_delayed_work(hba->work_queue,
- &(parent_queue->parent_sq_info
- .flush_done_timeout_work),
- (ulong)msecs_to_jiffies((u32)
- SPFC_SQ_WAIT_FLUSH_DONE_TIMEOUT_MS));
- if (!ret) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) rport(0x%x) queue delayed work failed ret:%d",
- hba->port_cfg.port_id,
- parent_sq->rport_index, ret);
- SPFC_HBA_STAT(hba, sq_state);
- }
-
- return;
- }
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) sq rport index(0x%x) has wait flush done %d times,do not free sq",
- hba->port_cfg.port_id,
- parent_sq->rport_index,
- atomic_read(&(parent_queue->parent_sq_info
- .flush_done_wait_cnt)));
-
- SPFC_HBA_STAT(hba, SPFC_STAT_CTXT_FLUSH_DONE);
- return;
- }
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) sq rport index(0x%x) flush done bit is ok,free sq now",
- hba->port_cfg.port_id, parent_sq->rport_index);
-
- spfc_free_parent_queue_info(hba, parent_queue);
-}
-
-static void spfc_free_parent_sq(struct spfc_hba_info *hba,
- struct spfc_parent_queue_info *parq_info)
-{
-#define SPFC_WAIT_PRT_CTX_FUSH_DONE_LOOP_TIMES 100
- u32 ctx_flush_done = 0;
- u32 *ctx_dw = NULL;
- struct spfc_parent_sq_info *sq_info = NULL;
- u32 uidelaycnt = 0;
- struct list_head *list = NULL;
- struct spfc_suspend_sqe_info *suspend_sqe = NULL;
-
- sq_info = &parq_info->parent_sq_info;
-
- while (!list_empty(&sq_info->suspend_sqe_list)) {
- list = UNF_OS_LIST_NEXT(&sq_info->suspend_sqe_list);
- list_del(list);
- suspend_sqe = list_entry(list, struct spfc_suspend_sqe_info, list_sqe_entry);
- if (suspend_sqe) {
- if (!cancel_delayed_work(&suspend_sqe->timeout_work)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[warn]reset worker timer maybe timeout");
- }
-
- kfree(suspend_sqe);
- }
- }
-
- /* Free data cos */
- spfc_update_cos_rport_cnt(hba, parq_info->queue_data_cos);
-
- if (parq_info->parent_ctx.cqm_parent_ctx_obj) {
- ctx_dw = (u32 *)((void *)(parq_info->parent_ctx.cqm_parent_ctx_obj->vaddr));
- ctx_flush_done = ctx_dw[SPFC_CTXT_FLUSH_DONE_DW_POS] & SPFC_CTXT_FLUSH_DONE_MASK_BE;
- mb();
- if (parq_info->offload_state == SPFC_QUEUE_STATE_DESTROYING &&
- ctx_flush_done == 0) {
- do {
- ctx_flush_done = ctx_dw[SPFC_CTXT_FLUSH_DONE_DW_POS] &
- SPFC_CTXT_FLUSH_DONE_MASK_BE;
- mb();
- if (ctx_flush_done != 0)
- break;
- uidelaycnt++;
- } while (uidelaycnt < SPFC_WAIT_PRT_CTX_FUSH_DONE_LOOP_TIMES);
-
- if (ctx_flush_done == 0) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) Rport(0x%x) flush done is not set",
- hba->port_cfg.port_id,
- sq_info->rport_index);
- }
- }
-
- cqm3_object_delete(&parq_info->parent_ctx.cqm_parent_ctx_obj->object);
- parq_info->parent_ctx.cqm_parent_ctx_obj = NULL;
- }
-
- spfc_invalid_parent_sq(sq_info);
-}
-
-u32 spfc_alloc_parent_sq(struct spfc_hba_info *hba,
- struct spfc_parent_queue_info *parq_info,
- struct unf_port_info *rport_info)
-{
- struct spfc_parent_sq_info *sq_ctrl = NULL;
- struct cqm_qpc_mpt *prnt_ctx = NULL;
- ulong flag = 0;
-
- /* Craete parent context via CQM */
- prnt_ctx = cqm3_object_qpc_mpt_create(hba->dev_handle, SERVICE_T_FC,
- CQM_OBJECT_SERVICE_CTX, SPFC_CNTX_SIZE_256B,
- parq_info, CQM_INDEX_INVALID);
- if (!prnt_ctx) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Create parent context failed, CQM_INDEX is 0x%x",
- CQM_INDEX_INVALID);
- goto parent_create_fail;
- }
-
- parq_info->parent_ctx.cqm_parent_ctx_obj = prnt_ctx;
- /* Initialize struct spfc_parent_sq_info */
- sq_ctrl = &parq_info->parent_sq_info;
- sq_ctrl->hba = (void *)hba;
- sq_ctrl->rport_index = rport_info->rport_index;
- sq_ctrl->sqn_base = rport_info->sqn_base;
- sq_ctrl->context_id = prnt_ctx->xid;
- sq_ctrl->sq_queue_id = SPFC_QID_SQ;
- sq_ctrl->cache_id = INVALID_VALUE32;
- sq_ctrl->local_port_id = INVALID_VALUE32;
- sq_ctrl->remote_port_id = INVALID_VALUE32;
- sq_ctrl->sq_in_sess_rst = false;
- atomic_set(&sq_ctrl->sq_valid, true);
- sq_ctrl->del_start_jiff = INVALID_VALUE64;
- sq_ctrl->service_type = SPFC_SERVICE_TYPE_FC;
- sq_ctrl->vport_id = (u8)rport_info->qos_level;
- sq_ctrl->cs_ctrl = (u8)rport_info->cs_ctrl;
- sq_ctrl->sirt_dif_control.protect_opcode = UNF_DIF_ACTION_NONE;
- sq_ctrl->need_offloaded = INVALID_VALUE8;
- atomic_set(&sq_ctrl->flush_done_wait_cnt, 0);
-
- /* Check whether the HBA is in the Linkdown state. Note that
- * offload_state must be in the non-FREE state.
- */
- spin_lock_irqsave(&hba->flush_state_lock, flag);
- sq_ctrl->port_in_flush = hba->in_flushing;
- spin_unlock_irqrestore(&hba->flush_state_lock, flag);
- memset(sq_ctrl->io_stat, 0, sizeof(sq_ctrl->io_stat));
-
- INIT_DELAYED_WORK(&sq_ctrl->del_work, spfc_parent_sq_opreate_timeout);
- INIT_DELAYED_WORK(&sq_ctrl->flush_done_timeout_work,
- spfc_parent_sq_wait_flush_done_timeout);
- INIT_LIST_HEAD(&sq_ctrl->suspend_sqe_list);
-
- memset(&sq_ctrl->delay_sqe, 0, sizeof(struct spfc_delay_sqe_ctrl_info));
-
- return RETURN_OK;
-
-parent_create_fail:
- parq_info->parent_ctx.cqm_parent_ctx_obj = NULL;
-
- return UNF_RETURN_ERROR;
-}
-
-static void
-spfc_init_prnt_ctxt_scq_qinfo(void *hba,
- struct spfc_parent_queue_info *prnt_qinfo)
-{
- u32 resp_scqn = 0;
- struct spfc_parent_context *ctx = NULL;
- struct spfc_scq_qinfo *resp_prnt_scq_ctxt = NULL;
- struct spfc_queue_info_bus queue_bus;
-
- /* Obtains the queue id of the scq returned by the CQM when the SCQ is
- * created
- */
- resp_scqn = prnt_qinfo->parent_sts_scq_info.cqm_queue_id;
-
- /* Obtains the Parent Context address */
- ctx = (struct spfc_parent_context *)(prnt_qinfo->parent_ctx.parent_ctx);
-
- resp_prnt_scq_ctxt = &ctx->resp_scq_qinfo;
- resp_prnt_scq_ctxt->hw_scqc_config.info.rq_th2_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.rq_th1_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.rq_th0_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.rq_min_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.sq_th2_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.sq_th1_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.sq_th0_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.sq_min_preld_cache_num = wqe_pre_load;
- resp_prnt_scq_ctxt->hw_scqc_config.info.scq_n = (u64)resp_scqn;
- resp_prnt_scq_ctxt->hw_scqc_config.info.parity = 0;
-
- memset(&queue_bus, 0, sizeof(struct spfc_queue_info_bus));
- queue_bus.bus[ARRAY_INDEX_0] = resp_prnt_scq_ctxt->hw_scqc_config.pctxt_val1;
- resp_prnt_scq_ctxt->hw_scqc_config.info.parity = spfc_get_parity_value(queue_bus.bus,
- SPFC_HW_SCQC_BUS_ROW,
- SPFC_HW_SCQC_BUS_COL
- );
- spfc_cpu_to_big64(resp_prnt_scq_ctxt, sizeof(struct spfc_scq_qinfo));
-}
-
-static void
-spfc_init_prnt_ctxt_srq_qinfo(void *handle, struct spfc_parent_queue_info *prnt_qinfo)
-{
- struct spfc_parent_context *ctx = NULL;
- struct cqm_queue *cqm_els_srq = NULL;
- struct spfc_parent_sq_info *sq = NULL;
- struct spfc_queue_info_bus queue_bus;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- /* Obtains the SQ address */
- sq = &prnt_qinfo->parent_sq_info;
-
- /* Obtains the Parent Context address */
- ctx = (struct spfc_parent_context *)(prnt_qinfo->parent_ctx.parent_ctx);
-
- cqm_els_srq = hba->els_srq_info.cqm_srq_info;
-
- /* Initialize the Parent SRQ INFO used when the ELS is received */
- ctx->els_srq_info.srqc_gpa = cqm_els_srq->q_ctx_paddr >> UNF_SHIFT_4;
-
- memset(&queue_bus, 0, sizeof(struct spfc_queue_info_bus));
- queue_bus.bus[ARRAY_INDEX_0] = ctx->els_srq_info.srqc_gpa;
- ctx->els_srq_info.parity = spfc_get_parity_value(queue_bus.bus, SPFC_HW_SRQC_BUS_ROW,
- SPFC_HW_SRQC_BUS_COL);
- spfc_cpu_to_big64(&ctx->els_srq_info, sizeof(struct spfc_srq_qinfo));
-
- ctx->imm_srq_info.srqc_gpa = 0;
- sq->srq_ctx_addr = 0;
-}
-
-static u16 spfc_get_max_sequence_id(void)
-{
- return SPFC_HRQI_SEQ_ID_MAX;
-}
-
-static void spfc_init_prnt_rsvd_qinfo(struct spfc_parent_queue_info *prnt_qinfo)
-{
- struct spfc_parent_context *ctx = NULL;
- struct spfc_hw_rsvd_queue *hw_rsvd_qinfo = NULL;
- u16 max_seq = 0;
- u32 each = 0, seq_index = 0;
-
- /* Obtains the Parent Context address */
- ctx = (struct spfc_parent_context *)(prnt_qinfo->parent_ctx.parent_ctx);
- hw_rsvd_qinfo = (struct spfc_hw_rsvd_queue *)&ctx->hw_rsvdq;
- memset(hw_rsvd_qinfo->seq_id_bitmap, 0, sizeof(hw_rsvd_qinfo->seq_id_bitmap));
-
- max_seq = spfc_get_max_sequence_id();
-
- /* special set for sequence id 0, which is always kept by ucode for
- * sending fcp-cmd
- */
- hw_rsvd_qinfo->seq_id_bitmap[SPFC_HRQI_SEQ_SEPCIAL_ID] = 1;
- seq_index = SPFC_HRQI_SEQ_SEPCIAL_ID - (max_seq >> SPFC_HRQI_SEQ_INDEX_SHIFT);
-
- /* Set the unavailable mask to start from max + 1 */
- for (each = (max_seq % SPFC_HRQI_SEQ_INDEX_MAX) + 1;
- each < SPFC_HRQI_SEQ_INDEX_MAX; each++) {
- hw_rsvd_qinfo->seq_id_bitmap[seq_index] |= ((u64)0x1) << each;
- }
-
- hw_rsvd_qinfo->seq_id_bitmap[seq_index] =
- cpu_to_be64(hw_rsvd_qinfo->seq_id_bitmap[seq_index]);
-
- /* sepcial set for sequence id 0 */
- if (seq_index != SPFC_HRQI_SEQ_SEPCIAL_ID)
- hw_rsvd_qinfo->seq_id_bitmap[SPFC_HRQI_SEQ_SEPCIAL_ID] =
- cpu_to_be64(hw_rsvd_qinfo->seq_id_bitmap[SPFC_HRQI_SEQ_SEPCIAL_ID]);
-
- for (each = 0; each < seq_index; each++)
- hw_rsvd_qinfo->seq_id_bitmap[each] = SPFC_HRQI_SEQ_INVALID_ID;
-
- /* no matter what the range of seq id, last_req_seq_id is fixed value
- * 0xff
- */
- hw_rsvd_qinfo->wd0.last_req_seq_id = SPFC_HRQI_SEQ_ID_MAX;
- hw_rsvd_qinfo->wd0.xid = prnt_qinfo->parent_sq_info.context_id;
-
- *(u64 *)&hw_rsvd_qinfo->wd0 =
- cpu_to_be64(*(u64 *)&hw_rsvd_qinfo->wd0);
-}
-
-/*
- *Function Name : spfc_init_prnt_sw_section_info
- *Function Description: Initialize the SW Section area that can be accessed by
- * the Parent Context uCode.
- *Input Parameters : *hba,
- * *prnt_qinfo
- *Output Parameters : N/A
- *Return Type : void
- */
-static void spfc_init_prnt_sw_section_info(struct spfc_hba_info *hba,
- struct spfc_parent_queue_info *prnt_qinfo)
-{
-#define SPFC_VLAN_ENABLE (1)
-#define SPFC_MB_PER_KB 1024
- u16 rport_index;
- struct spfc_parent_context *ctx = NULL;
- struct spfc_sw_section *sw_setion = NULL;
- u16 total_scq_num = SPFC_TOTAL_SCQ_NUM;
- u32 queue_id;
- dma_addr_t queue_hdr_paddr;
-
- /* Obtains the Parent Context address */
- ctx = (struct spfc_parent_context *)(prnt_qinfo->parent_ctx.parent_ctx);
- sw_setion = &ctx->sw_section;
-
- /* xid+vPortId */
- sw_setion->sw_ctxt_vport_xid.xid = prnt_qinfo->parent_sq_info.context_id;
- spfc_cpu_to_big32(&sw_setion->sw_ctxt_vport_xid, sizeof(sw_setion->sw_ctxt_vport_xid));
-
- /* conn_id */
- rport_index = SPFC_LSW(prnt_qinfo->parent_sq_info.rport_index);
- sw_setion->conn_id = cpu_to_be16(rport_index);
-
- /* Immediate parameters */
- sw_setion->immi_rq_page_size = 0;
-
- /* Parent SCQ INFO used for sending packets to the Cmnd */
- sw_setion->scq_num_rcv_cmd = cpu_to_be16((u16)prnt_qinfo->parent_cmd_scq_info.cqm_queue_id);
- sw_setion->scq_num_max_scqn = cpu_to_be16(total_scq_num);
-
- /* sw_ctxt_misc */
- sw_setion->sw_ctxt_misc.dw.srv_type = prnt_qinfo->parent_sq_info.service_type;
- sw_setion->sw_ctxt_misc.dw.port_id = hba->port_index;
-
- /* only the VN2VF mode is supported */
- sw_setion->sw_ctxt_misc.dw.vlan_id = 0;
- spfc_cpu_to_big32(&sw_setion->sw_ctxt_misc.pctxt_val0,
- sizeof(sw_setion->sw_ctxt_misc.pctxt_val0));
-
- /* Configuring the combo length */
- sw_setion->per_xmit_data_size = cpu_to_be32(combo_length * SPFC_MB_PER_KB);
- sw_setion->sw_ctxt_config.dw.work_mode = SPFC_PORT_MODE_INI;
- sw_setion->sw_ctxt_config.dw.status = FC_PARENT_STATUS_INVALID;
- sw_setion->sw_ctxt_config.dw.cos = 0;
- sw_setion->sw_ctxt_config.dw.oq_cos_cmd = SPFC_PACKET_COS_FC_CMD;
- sw_setion->sw_ctxt_config.dw.oq_cos_data = prnt_qinfo->queue_data_cos;
- sw_setion->sw_ctxt_config.dw.priority = 0;
- sw_setion->sw_ctxt_config.dw.vlan_enable = SPFC_VLAN_ENABLE;
- sw_setion->sw_ctxt_config.dw.sgl_num = dif_sgl_mode;
- spfc_cpu_to_big32(&sw_setion->sw_ctxt_config.pctxt_val1,
- sizeof(sw_setion->sw_ctxt_config.pctxt_val1));
- spfc_cpu_to_big32(&sw_setion->immi_dif_info, sizeof(sw_setion->immi_dif_info));
-
- queue_id = prnt_qinfo->parent_cmd_scq_info.local_queue_id;
- queue_hdr_paddr = hba->scq_info[queue_id].cqm_scq_info->q_header_paddr;
- sw_setion->cmd_scq_gpa_h = SPFC_HIGH_32_BITS(queue_hdr_paddr);
- sw_setion->cmd_scq_gpa_l = SPFC_LOW_32_BITS(queue_hdr_paddr);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[info]Port(0x%x) RPort(0x%x) CmdLocalScqn(0x%x) QheaderGpaH(0x%x) QheaderGpaL(0x%x)",
- hba->port_cfg.port_id, prnt_qinfo->parent_sq_info.rport_index, queue_id,
- sw_setion->cmd_scq_gpa_h, sw_setion->cmd_scq_gpa_l);
-
- spfc_cpu_to_big32(&sw_setion->cmd_scq_gpa_h, sizeof(sw_setion->cmd_scq_gpa_h));
- spfc_cpu_to_big32(&sw_setion->cmd_scq_gpa_l, sizeof(sw_setion->cmd_scq_gpa_l));
-}
-
-static void spfc_init_parent_context(void *hba, struct spfc_parent_queue_info *prnt_qinfo)
-{
- struct spfc_parent_context *ctx = NULL;
-
- ctx = (struct spfc_parent_context *)(prnt_qinfo->parent_ctx.parent_ctx);
-
- /* Initialize Parent Context */
- memset(ctx, 0, SPFC_CNTX_SIZE_256B);
-
- /* Initialize the Queue Info hardware area */
- spfc_init_prnt_ctxt_scq_qinfo(hba, prnt_qinfo);
- spfc_init_prnt_ctxt_srq_qinfo(hba, prnt_qinfo);
- spfc_init_prnt_rsvd_qinfo(prnt_qinfo);
-
- /* Initialize Software Section */
- spfc_init_prnt_sw_section_info(hba, prnt_qinfo);
-}
-
-void spfc_map_shared_queue_qid(struct spfc_hba_info *hba,
- struct spfc_parent_queue_info *parent_queue_info,
- u32 rport_index)
-{
- u32 cmd_scqn_local = 0;
- u32 sts_scqn_local = 0;
-
- /* The SCQ is used for each connection based on the balanced *
- * distribution of commands and responses
- */
- cmd_scqn_local = SPFC_RPORTID_TO_CMD_SCQN(rport_index);
- sts_scqn_local = SPFC_RPORTID_TO_STS_SCQN(rport_index);
- parent_queue_info->parent_cmd_scq_info.local_queue_id = cmd_scqn_local;
- parent_queue_info->parent_sts_scq_info.local_queue_id = sts_scqn_local;
- parent_queue_info->parent_cmd_scq_info.cqm_queue_id =
- hba->scq_info[cmd_scqn_local].scqn;
- parent_queue_info->parent_sts_scq_info.cqm_queue_id =
- hba->scq_info[sts_scqn_local].scqn;
-
- /* Each session share with immediate SRQ and ElsSRQ */
- parent_queue_info->parent_els_srq_info.local_queue_id = 0;
- parent_queue_info->parent_els_srq_info.cqm_queue_id = hba->els_srq_info.srqn;
-
- /* Allocate fcp data cos value */
- parent_queue_info->queue_data_cos = spfc_map_fcp_data_cos(hba);
-
- /* Allocate Parent SQ vPort */
- parent_queue_info->parent_sq_info.vport_id += parent_queue_info->queue_vport_id;
-}
-
-u32 spfc_send_session_enable(struct spfc_hba_info *hba, struct unf_port_info *rport_info)
-{
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- dma_addr_t ctx_phy_addr = 0;
- void *ctx_addr = NULL;
- union spfc_cmdqe session_enable;
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_parent_context *ctx = NULL;
- struct spfc_sw_section *sw_setion = NULL;
- struct spfc_host_keys key;
- u32 tx_mfs = 2048;
- u32 edtov_timer = 2000;
- ulong flag = 0;
- spinlock_t *prtq_state_lock = NULL;
- u32 index;
-
- memset(&session_enable, 0, sizeof(union spfc_cmdqe));
- memset(&key, 0, sizeof(struct spfc_host_keys));
- index = rport_info->rport_index;
- parent_queue_info = &hba->parent_queue_mgr->parent_queue[index];
- prtq_state_lock = &parent_queue_info->parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- ctx = (struct spfc_parent_context *)(parent_queue_info->parent_ctx.parent_ctx);
- sw_setion = &ctx->sw_section;
-
- sw_setion->tx_mfs = cpu_to_be16((u16)(tx_mfs));
- sw_setion->e_d_tov_timer_val = cpu_to_be32(edtov_timer);
-
- spfc_big_to_cpu32(&sw_setion->sw_ctxt_misc.pctxt_val0,
- sizeof(sw_setion->sw_ctxt_misc.pctxt_val0));
- sw_setion->sw_ctxt_misc.dw.port_id = SPFC_GET_NETWORK_PORT_ID(hba);
- spfc_cpu_to_big32(&sw_setion->sw_ctxt_misc.pctxt_val0,
- sizeof(sw_setion->sw_ctxt_misc.pctxt_val0));
-
- spfc_big_to_cpu32(&sw_setion->sw_ctxt_config.pctxt_val1,
- sizeof(sw_setion->sw_ctxt_config.pctxt_val1));
- spfc_cpu_to_big32(&sw_setion->sw_ctxt_config.pctxt_val1,
- sizeof(sw_setion->sw_ctxt_config.pctxt_val1));
-
- parent_queue_info->parent_sq_info.rport_index = rport_info->rport_index;
- parent_queue_info->parent_sq_info.local_port_id = rport_info->local_nport_id;
- parent_queue_info->parent_sq_info.remote_port_id = rport_info->nport_id;
- parent_queue_info->parent_sq_info.context_id =
- parent_queue_info->parent_ctx.cqm_parent_ctx_obj->xid;
-
- /* Fill in contex to the chip */
- ctx_phy_addr = parent_queue_info->parent_ctx.cqm_parent_ctx_obj->paddr;
- ctx_addr = parent_queue_info->parent_ctx.cqm_parent_ctx_obj->vaddr;
- memcpy(ctx_addr, parent_queue_info->parent_ctx.parent_ctx,
- sizeof(struct spfc_parent_context));
- session_enable.session_enable.wd0.task_type = SPFC_TASK_T_SESS_EN;
- session_enable.session_enable.wd2.conn_id = rport_info->rport_index;
- session_enable.session_enable.wd2.scqn = hba->default_scqn;
- session_enable.session_enable.wd3.xid_p =
- parent_queue_info->parent_ctx.cqm_parent_ctx_obj->xid;
- session_enable.session_enable.context_gpa_hi = SPFC_HIGH_32_BITS(ctx_phy_addr);
- session_enable.session_enable.context_gpa_lo = SPFC_LOW_32_BITS(ctx_phy_addr);
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- key.wd3.sid_2 = (rport_info->local_nport_id & SPFC_KEY_WD3_SID_2_MASK) >> UNF_SHIFT_16;
- key.wd3.sid_1 = (rport_info->local_nport_id & SPFC_KEY_WD3_SID_1_MASK) >> UNF_SHIFT_8;
- key.wd4.sid_0 = rport_info->local_nport_id & SPFC_KEY_WD3_SID_0_MASK;
- key.wd4.did_0 = rport_info->nport_id & SPFC_KEY_WD4_DID_0_MASK;
- key.wd4.did_1 = (rport_info->nport_id & SPFC_KEY_WD4_DID_1_MASK) >> UNF_SHIFT_8;
- key.wd4.did_2 = (rport_info->nport_id & SPFC_KEY_WD4_DID_2_MASK) >> UNF_SHIFT_16;
- key.wd5.host_id = 0;
- key.wd5.port_id = hba->port_index;
-
- memcpy(&session_enable.session_enable.keys, &key, sizeof(struct spfc_host_keys));
-
- memcpy((void *)(uintptr_t)session_enable.session_enable.context,
- parent_queue_info->parent_ctx.parent_ctx,
- sizeof(struct spfc_parent_context));
- spfc_big_to_cpu32((void *)(uintptr_t)session_enable.session_enable.context,
- sizeof(struct spfc_parent_context));
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_MAJOR,
- "[info] xid:0x%x, sid:0x%x,did:0x%x parentcontext:",
- parent_queue_info->parent_ctx.cqm_parent_ctx_obj->xid,
- rport_info->local_nport_id, rport_info->nport_id);
-
- ret = spfc_root_cmdq_enqueue(hba, &session_enable, sizeof(session_enable.session_enable));
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]RootCMDQEnqueue Error, free default session parent resource");
- return UNF_RETURN_ERROR;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) send default session enable success,rport index(0x%x),context id(0x%x) SID=(0x%x), DID=(0x%x)",
- hba->port_cfg.port_id, rport_info->rport_index,
- parent_queue_info->parent_sq_info.context_id,
- rport_info->local_nport_id, rport_info->nport_id);
-
- return RETURN_OK;
-}
-
-u32 spfc_alloc_parent_resource(void *handle, struct unf_port_info *rport_info)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_hba_info *hba = NULL;
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- ulong flag = 0;
- spinlock_t *prtq_state_lock = NULL;
- u32 index;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport_info, UNF_RETURN_ERROR);
-
- hba = (struct spfc_hba_info *)handle;
- if (!hba->parent_queue_mgr) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) cannot find parent queue pool",
- hba->port_cfg.port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- index = rport_info->rport_index;
- if (index >= UNF_SPFC_MAXRPORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) allocate parent resource failed, invlaid rport index(0x%x),rport nportid(0x%x)",
- hba->port_cfg.port_id, index,
- rport_info->nport_id);
-
- return UNF_RETURN_ERROR;
- }
-
- parent_queue_info = &hba->parent_queue_mgr->parent_queue[index];
- prtq_state_lock = &parent_queue_info->parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- if (parent_queue_info->offload_state != SPFC_QUEUE_STATE_FREE) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) allocate parent resource failed, invlaid rport index(0x%x),rport nportid(0x%x), offload state(0x%x)",
- hba->port_cfg.port_id, index, rport_info->nport_id,
- parent_queue_info->offload_state);
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
- return UNF_RETURN_ERROR;
- }
-
- parent_queue_info->offload_state = SPFC_QUEUE_STATE_INITIALIZED;
- /* Create Parent Context and Link List SQ */
- ret = spfc_alloc_parent_sq(hba, parent_queue_info, rport_info);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "Port(0x%x) alloc session resoure failed.rport index(0x%x),rport nportid(0x%x).",
- hba->port_cfg.port_id, index,
- rport_info->nport_id);
-
- parent_queue_info->offload_state = SPFC_QUEUE_STATE_FREE;
- spfc_invalid_parent_sq(&parent_queue_info->parent_sq_info);
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Allocate the corresponding queue xid to each parent */
- spfc_map_shared_queue_qid(hba, parent_queue_info, rport_info->rport_index);
-
- /* Initialize Parent Context, including hardware area and ucode area */
- spfc_init_parent_context(hba, parent_queue_info);
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- /* Only default enable session obviously, other will enable secertly */
- if (unlikely(rport_info->rport_index == SPFC_DEFAULT_RPORT_INDEX))
- return spfc_send_session_enable(handle, rport_info);
-
- parent_queue_info->parent_sq_info.local_port_id = rport_info->local_nport_id;
- parent_queue_info->parent_sq_info.remote_port_id = rport_info->nport_id;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) allocate parent sq success,rport index(0x%x),rport nportid(0x%x),context id(0x%x)",
- hba->port_cfg.port_id, rport_info->rport_index,
- rport_info->nport_id,
- parent_queue_info->parent_sq_info.context_id);
-
- return ret;
-}
-
-u32 spfc_free_parent_resource(void *handle, struct unf_port_info *rport_info)
-{
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- ulong flag = 0;
- ulong rst_flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- enum spfc_session_reset_mode mode = SPFC_SESS_RST_DELETE_IO_CONN_BOTH;
- struct spfc_hba_info *hba = NULL;
- spinlock_t *prtq_state_lock = NULL;
- spinlock_t *sq_enq_lock = NULL;
- u32 index;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(rport_info, UNF_RETURN_ERROR);
-
- hba = (struct spfc_hba_info *)handle;
- if (!hba->parent_queue_mgr) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]Port(0x%x) cannot find parent queue pool",
- hba->port_cfg.port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- /* get parent queue info (by rport index) */
- if (rport_info->rport_index >= UNF_SPFC_MAXRPORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]Port(0x%x) free parent resource failed, invlaid rport_index(%u) rport_nport_id(0x%x)",
- hba->port_cfg.port_id, rport_info->rport_index, rport_info->nport_id);
-
- return UNF_RETURN_ERROR;
- }
-
- index = rport_info->rport_index;
- parent_queue_info = &hba->parent_queue_mgr->parent_queue[index];
- prtq_state_lock = &parent_queue_info->parent_queue_state_lock;
- sq_enq_lock = &parent_queue_info->parent_sq_info.parent_sq_enqueue_lock;
-
- spin_lock_irqsave(prtq_state_lock, flag);
- /* 1. for has been offload */
- if (parent_queue_info->offload_state == SPFC_QUEUE_STATE_OFFLOADED) {
- parent_queue_info->offload_state = SPFC_QUEUE_STATE_DESTROYING;
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- /* set reset state, in order to prevent I/O in_SQ */
- spin_lock_irqsave(sq_enq_lock, rst_flag);
- parent_queue_info->parent_sq_info.sq_in_sess_rst = true;
- spin_unlock_irqrestore(sq_enq_lock, rst_flag);
-
- /* check pcie device state */
- if (!hba->dev_present) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) hba is not present, free directly. rport_index(0x%x:0x%x) local_nportid(0x%x) remote_nportid(0x%x:0x%x)",
- hba->port_cfg.port_id, rport_info->rport_index,
- parent_queue_info->parent_sq_info.rport_index,
- parent_queue_info->parent_sq_info.local_port_id,
- rport_info->nport_id,
- parent_queue_info->parent_sq_info.remote_port_id);
-
- spfc_free_parent_queue_info(hba, parent_queue_info);
- return RETURN_OK;
- }
-
- parent_queue_info->parent_sq_info.del_start_jiff = jiffies;
- (void)queue_delayed_work(hba->work_queue,
- &parent_queue_info->parent_sq_info.del_work,
- (ulong)msecs_to_jiffies((u32)
- SPFC_SQ_DEL_STAGE_TIMEOUT_MS));
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) begin to reset parent session, rport_index(0x%x:0x%x) local_nportid(0x%x) remote_nportid(0x%x:0x%x)",
- hba->port_cfg.port_id, rport_info->rport_index,
- parent_queue_info->parent_sq_info.rport_index,
- parent_queue_info->parent_sq_info.local_port_id,
- rport_info->nport_id,
- parent_queue_info->parent_sq_info.remote_port_id);
- /* Forcibly set both mode */
- mode = SPFC_SESS_RST_DELETE_IO_CONN_BOTH;
- ret = spfc_send_session_rst_cmd(hba, parent_queue_info, mode);
-
- return ret;
- } else if (parent_queue_info->offload_state == SPFC_QUEUE_STATE_INITIALIZED) {
- /* 2. for resource has been alloc, but not offload */
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) parent sq is not offloaded, free directly. rport_index(0x%x:0x%x) local_nportid(0x%x) remote_nportid(0x%x:0x%x)",
- hba->port_cfg.port_id, rport_info->rport_index,
- parent_queue_info->parent_sq_info.rport_index,
- parent_queue_info->parent_sq_info.local_port_id,
- rport_info->nport_id,
- parent_queue_info->parent_sq_info.remote_port_id);
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
- spfc_free_parent_queue_info(hba, parent_queue_info);
-
- return RETURN_OK;
- } else if (parent_queue_info->offload_state ==
- SPFC_QUEUE_STATE_OFFLOADING) {
- /* 3. for driver has offloading CMND to uCode */
- spfc_push_destroy_parent_queue_sqe(hba, parent_queue_info, rport_info);
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) parent sq is offloading, push to delay free. rport_index(0x%x:0x%x) local_nportid(0x%x) remote_nportid(0x%x:0x%x)",
- hba->port_cfg.port_id, rport_info->rport_index,
- parent_queue_info->parent_sq_info.rport_index,
- parent_queue_info->parent_sq_info.local_port_id,
- rport_info->nport_id,
- parent_queue_info->parent_sq_info.remote_port_id);
-
- return RETURN_OK;
- }
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) parent sq is not created, do not need free state(0x%x) rport_index(0x%x:0x%x) local_nportid(0x%x) remote_nportid(0x%x:0x%x)",
- hba->port_cfg.port_id, parent_queue_info->offload_state,
- rport_info->rport_index,
- parent_queue_info->parent_sq_info.rport_index,
- parent_queue_info->parent_sq_info.local_port_id,
- rport_info->nport_id,
- parent_queue_info->parent_sq_info.remote_port_id);
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- return RETURN_OK;
-}
-
-void spfc_free_parent_queue_mgr(void *handle)
-{
- u32 index = 0;
- struct spfc_parent_queue_mgr *parent_queue_mgr = NULL;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VOID(handle);
-
- hba = (struct spfc_hba_info *)handle;
- if (!hba->parent_queue_mgr)
- return;
- parent_queue_mgr = hba->parent_queue_mgr;
-
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- if (parent_queue_mgr->parent_queue[index].parent_ctx.parent_ctx)
- parent_queue_mgr->parent_queue[index].parent_ctx.parent_ctx = NULL;
- }
-
- if (parent_queue_mgr->parent_sq_buf_list.buflist) {
- for (index = 0; index < parent_queue_mgr->parent_sq_buf_list.buf_num; index++) {
- if (parent_queue_mgr->parent_sq_buf_list.buflist[index].paddr != 0) {
- pci_unmap_single(hba->pci_dev,
- parent_queue_mgr->parent_sq_buf_list
- .buflist[index].paddr,
- parent_queue_mgr->parent_sq_buf_list.buf_size,
- DMA_BIDIRECTIONAL);
- parent_queue_mgr->parent_sq_buf_list.buflist[index].paddr = 0;
- }
- kfree(parent_queue_mgr->parent_sq_buf_list.buflist[index].vaddr);
- parent_queue_mgr->parent_sq_buf_list.buflist[index].vaddr = NULL;
- }
-
- kfree(parent_queue_mgr->parent_sq_buf_list.buflist);
- parent_queue_mgr->parent_sq_buf_list.buflist = NULL;
- }
-
- vfree(parent_queue_mgr);
- hba->parent_queue_mgr = NULL;
-}
-
-void spfc_free_parent_queues(void *handle)
-{
- u32 index = 0;
- ulong flag = 0;
- struct spfc_parent_queue_mgr *parent_queue_mgr = NULL;
- struct spfc_hba_info *hba = NULL;
- spinlock_t *prtq_state_lock = NULL;
-
- FC_CHECK_RETURN_VOID(handle);
-
- hba = (struct spfc_hba_info *)handle;
- parent_queue_mgr = hba->parent_queue_mgr;
-
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- prtq_state_lock = &parent_queue_mgr->parent_queue[index].parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- if (SPFC_QUEUE_STATE_DESTROYING ==
- parent_queue_mgr->parent_queue[index].offload_state) {
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- (void)cancel_delayed_work_sync(&parent_queue_mgr->parent_queue[index]
- .parent_sq_info.del_work);
- (void)cancel_delayed_work_sync(&parent_queue_mgr->parent_queue[index]
- .parent_sq_info.flush_done_timeout_work);
-
- /* free parent queue */
- spfc_free_parent_queue_info(hba, &parent_queue_mgr->parent_queue[index]);
- continue;
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
- }
-}
-
-/*
- *Function Name : spfc_alloc_parent_queue_mgr
- *Function Description: Allocate and initialize parent queue manager.
- *Input Parameters : *handle
- *Output Parameters : N/A
- *Return Type : void
- */
-u32 spfc_alloc_parent_queue_mgr(void *handle)
-{
- u32 index = 0;
- struct spfc_parent_queue_mgr *parent_queue_mgr = NULL;
- u32 buf_total_size;
- u32 buf_num;
- u32 alloc_idx;
- u32 cur_buf_idx = 0;
- u32 cur_buf_offset = 0;
- u32 prt_ctx_size = sizeof(struct spfc_parent_context);
- u32 buf_cnt_perhugebuf;
- struct spfc_hba_info *hba = NULL;
- u32 init_val = INVALID_VALUE32;
- dma_addr_t paddr;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
-
- hba = (struct spfc_hba_info *)handle;
- parent_queue_mgr = (struct spfc_parent_queue_mgr *)vmalloc(sizeof
- (struct spfc_parent_queue_mgr));
- if (!parent_queue_mgr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) cannot allocate queue manager",
- hba->port_cfg.port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- hba->parent_queue_mgr = parent_queue_mgr;
- memset(parent_queue_mgr, 0, sizeof(struct spfc_parent_queue_mgr));
-
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- spin_lock_init(&parent_queue_mgr->parent_queue[index].parent_queue_state_lock);
- parent_queue_mgr->parent_queue[index].offload_state = SPFC_QUEUE_STATE_FREE;
- spin_lock_init(&(parent_queue_mgr->parent_queue[index]
- .parent_sq_info.parent_sq_enqueue_lock));
- parent_queue_mgr->parent_queue[index].parent_cmd_scq_info.cqm_queue_id = init_val;
- parent_queue_mgr->parent_queue[index].parent_sts_scq_info.cqm_queue_id = init_val;
- parent_queue_mgr->parent_queue[index].parent_els_srq_info.cqm_queue_id = init_val;
- parent_queue_mgr->parent_queue[index].parent_sq_info.del_start_jiff = init_val;
- parent_queue_mgr->parent_queue[index].queue_vport_id = hba->vpid_start;
- }
-
- buf_total_size = prt_ctx_size * UNF_SPFC_MAXRPORT_NUM;
- parent_queue_mgr->parent_sq_buf_list.buf_size = buf_total_size > BUF_LIST_PAGE_SIZE ?
- BUF_LIST_PAGE_SIZE : buf_total_size;
- buf_cnt_perhugebuf = parent_queue_mgr->parent_sq_buf_list.buf_size / prt_ctx_size;
- buf_num = UNF_SPFC_MAXRPORT_NUM % buf_cnt_perhugebuf ?
- UNF_SPFC_MAXRPORT_NUM / buf_cnt_perhugebuf + 1 :
- UNF_SPFC_MAXRPORT_NUM / buf_cnt_perhugebuf;
- parent_queue_mgr->parent_sq_buf_list.buflist =
- (struct buff_list *)kmalloc(buf_num * sizeof(struct buff_list), GFP_KERNEL);
- parent_queue_mgr->parent_sq_buf_list.buf_num = buf_num;
-
- if (!parent_queue_mgr->parent_sq_buf_list.buflist) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Allocate QueuMgr buf list failed out of memory");
- goto free_parent_queue;
- }
- memset(parent_queue_mgr->parent_sq_buf_list.buflist, 0, buf_num * sizeof(struct buff_list));
-
- for (alloc_idx = 0; alloc_idx < buf_num; alloc_idx++) {
- parent_queue_mgr->parent_sq_buf_list.buflist[alloc_idx].vaddr =
- kmalloc(parent_queue_mgr->parent_sq_buf_list.buf_size, GFP_KERNEL);
- if (!parent_queue_mgr->parent_sq_buf_list.buflist[alloc_idx].vaddr)
- goto free_parent_queue;
-
- memset(parent_queue_mgr->parent_sq_buf_list.buflist[alloc_idx].vaddr, 0,
- parent_queue_mgr->parent_sq_buf_list.buf_size);
-
- parent_queue_mgr->parent_sq_buf_list.buflist[alloc_idx].paddr =
- pci_map_single(hba->pci_dev,
- parent_queue_mgr->parent_sq_buf_list.buflist[alloc_idx].vaddr,
- parent_queue_mgr->parent_sq_buf_list.buf_size,
- DMA_BIDIRECTIONAL);
- paddr = parent_queue_mgr->parent_sq_buf_list.buflist[alloc_idx].paddr;
- if (pci_dma_mapping_error(hba->pci_dev, paddr)) {
- parent_queue_mgr->parent_sq_buf_list.buflist[alloc_idx].paddr = 0;
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[err]Map QueuMgr address failed");
-
- goto free_parent_queue;
- }
- }
-
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- cur_buf_idx = index / buf_cnt_perhugebuf;
- cur_buf_offset = prt_ctx_size * (index % buf_cnt_perhugebuf);
-
- parent_queue_mgr->parent_queue[index].parent_ctx.parent_ctx =
- parent_queue_mgr->parent_sq_buf_list.buflist[cur_buf_idx].vaddr +
- cur_buf_offset;
- parent_queue_mgr->parent_queue[index].parent_ctx.parent_ctx_addr =
- parent_queue_mgr->parent_sq_buf_list.buflist[cur_buf_idx].paddr +
- cur_buf_offset;
- }
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_INFO,
- "[EVENT]Allocate bufnum:%u,buf_total_size:%u", buf_num, buf_total_size);
-
- return RETURN_OK;
-
-free_parent_queue:
- spfc_free_parent_queue_mgr(hba);
- return UNF_RETURN_ERROR;
-}
-
-static void spfc_rlease_all_wqe_pages(struct spfc_hba_info *hba)
-{
- u32 index;
- struct spfc_wqe_page *wpg = NULL;
-
- FC_CHECK_RETURN_VOID((hba));
-
- wpg = hba->sq_wpg_pool.wpg_pool_addr;
-
- for (index = 0; index < hba->sq_wpg_pool.wpg_cnt; index++) {
- if (wpg->wpg_addr) {
- dma_pool_free(hba->sq_wpg_pool.wpg_dma_pool,
- wpg->wpg_addr, wpg->wpg_phy_addr);
- wpg->wpg_addr = NULL;
- wpg->wpg_phy_addr = 0;
- }
-
- wpg++;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port[%u] free total %u wqepages", hba->port_index,
- index);
-}
-
-u32 spfc_alloc_parent_sq_wqe_page_pool(void *handle)
-{
- u32 index = 0;
- struct spfc_sq_wqepage_pool *wpg_pool = NULL;
- struct spfc_wqe_page *wpg = NULL;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- wpg_pool = &hba->sq_wpg_pool;
-
- INIT_LIST_HEAD(&wpg_pool->list_free_wpg_pool);
- spin_lock_init(&wpg_pool->wpg_pool_lock);
- atomic_set(&wpg_pool->wpg_in_use, 0);
-
- /* Calculate the number of Wqe Page required in the pool */
- wpg_pool->wpg_size = wqe_page_size;
- wpg_pool->wpg_cnt = SPFC_MIN_WP_NUM * SPFC_MAX_SSQ_NUM +
- ((hba->exi_count * SPFC_SQE_SIZE) / wpg_pool->wpg_size);
- wpg_pool->wqe_per_wpg = wpg_pool->wpg_size / SPFC_SQE_SIZE;
-
- /* Craete DMA POOL */
- wpg_pool->wpg_dma_pool = dma_pool_create("spfc_wpg_pool",
- &hba->pci_dev->dev,
- wpg_pool->wpg_size,
- SPFC_SQE_SIZE, 0);
- if (!wpg_pool->wpg_dma_pool) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Cannot allocate SQ WqePage DMA pool");
-
- goto out_create_dma_pool_err;
- }
-
- /* Allocate arrays to record all WqePage addresses */
- wpg_pool->wpg_pool_addr = (struct spfc_wqe_page *)vmalloc(wpg_pool->wpg_cnt *
- sizeof(struct spfc_wqe_page));
- if (!wpg_pool->wpg_pool_addr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Allocate SQ WqePageAddr array failed");
-
- goto out_alloc_wpg_array_err;
- }
- wpg = wpg_pool->wpg_pool_addr;
- memset(wpg, 0, wpg_pool->wpg_cnt * sizeof(struct spfc_wqe_page));
-
- for (index = 0; index < wpg_pool->wpg_cnt; index++) {
- wpg->wpg_addr = dma_pool_alloc(wpg_pool->wpg_dma_pool, GFP_KERNEL,
- (u64 *)&wpg->wpg_phy_addr);
- if (!wpg->wpg_addr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_ERR, "[err]Dma pool allocated failed");
- break;
- }
-
- /* To ensure security, clear the memory */
- memset(wpg->wpg_addr, 0, wpg_pool->wpg_size);
-
- /* Add to the idle linked list */
- INIT_LIST_HEAD(&wpg->entry_wpg);
- list_add_tail(&wpg->entry_wpg, &wpg_pool->list_free_wpg_pool);
-
- wpg++;
- }
- /* ALL allocated successfully */
- if (wpg_pool->wpg_cnt == index)
- return RETURN_OK;
-
- spfc_rlease_all_wqe_pages(hba);
- vfree(wpg_pool->wpg_pool_addr);
- wpg_pool->wpg_pool_addr = NULL;
-
-out_alloc_wpg_array_err:
- dma_pool_destroy(wpg_pool->wpg_dma_pool);
- wpg_pool->wpg_dma_pool = NULL;
-
-out_create_dma_pool_err:
- return UNF_RETURN_ERROR;
-}
-
-void spfc_free_parent_sq_wqe_page_pool(void *handle)
-{
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VOID((handle));
- hba = (struct spfc_hba_info *)handle;
- spfc_rlease_all_wqe_pages(hba);
- hba->sq_wpg_pool.wpg_cnt = 0;
-
- if (hba->sq_wpg_pool.wpg_pool_addr) {
- vfree(hba->sq_wpg_pool.wpg_pool_addr);
- hba->sq_wpg_pool.wpg_pool_addr = NULL;
- }
-
- dma_pool_destroy(hba->sq_wpg_pool.wpg_dma_pool);
- hba->sq_wpg_pool.wpg_dma_pool = NULL;
-}
-
-static u32 spfc_parent_sq_ring_direct_wqe_doorbell(struct spfc_parent_ssq_info *sq, u8 *direct_wqe)
-{
- u32 ret = RETURN_OK;
- int ravl;
- u16 pmsn;
- u64 queue_hdr_db_val;
- struct spfc_hba_info *hba;
-
- hba = (struct spfc_hba_info *)sq->hba;
- pmsn = sq->last_pmsn;
-
- if (sq->cache_id == INVALID_VALUE32) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]SQ(0x%x) invalid cid", sq->context_id);
- return RETURN_ERROR;
- }
- /* Fill Doorbell Record */
- queue_hdr_db_val = sq->queue_header->door_bell_record;
- queue_hdr_db_val &= (u64)(~(0xFFFFFFFF));
- queue_hdr_db_val |= (u64)((u64)pmsn << UNF_SHIFT_16 | pmsn);
- sq->queue_header->door_bell_record =
- cpu_to_be64(queue_hdr_db_val);
-
- ravl = cqm_ring_direct_wqe_db_fc(hba->dev_handle, SERVICE_T_FC, direct_wqe);
- if (unlikely(ravl != CQM_SUCCESS)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]SQ(0x%x) send DB failed", sq->context_id);
-
- ret = RETURN_ERROR;
- }
-
- atomic_inc(&sq->sq_db_cnt);
-
- return ret;
-}
-
-u32 spfc_parent_sq_ring_doorbell(struct spfc_parent_ssq_info *sq, u8 qos_level, u32 c)
-{
- u32 ret = RETURN_OK;
- int ravl;
- u16 pmsn;
- u8 pmsn_lo;
- u8 pmsn_hi;
- u64 db_val_qw;
- struct spfc_hba_info *hba;
- struct spfc_parent_sq_db door_bell;
-
- hba = (struct spfc_hba_info *)sq->hba;
- pmsn = sq->last_pmsn;
- /* Obtain the low 8 Bit of PMSN */
- pmsn_lo = (u8)(pmsn & SPFC_PMSN_MASK);
- /* Obtain the high 8 Bit of PMSN */
- pmsn_hi = (u8)((pmsn >> UNF_SHIFT_8) & SPFC_PMSN_MASK);
- door_bell.wd0.service_type = SPFC_LSW(sq->service_type);
- door_bell.wd0.cos = 0;
- /* c = 0 data type, c = 1 control type, two type are different in mqm */
- door_bell.wd0.c = c;
- door_bell.wd0.arm = SPFC_DB_ARM_DISABLE;
- door_bell.wd0.cntx_size = SPFC_CNTX_SIZE_T_256B;
- door_bell.wd0.xid = sq->context_id;
- door_bell.wd1.sm_data = sq->cache_id;
- door_bell.wd1.qid = sq->sq_queue_id;
- door_bell.wd1.pi_hi = (u32)pmsn_hi;
-
- if (sq->cache_id == INVALID_VALUE32) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]SQ(0x%x) invalid cid", sq->context_id);
- return UNF_RETURN_ERROR;
- }
- /* Fill Doorbell Record */
- db_val_qw = sq->queue_header->door_bell_record;
- db_val_qw &= (u64)(~(SPFC_DB_VAL_MASK));
- db_val_qw |= (u64)((u64)pmsn << UNF_SHIFT_16 | pmsn);
- sq->queue_header->door_bell_record = cpu_to_be64(db_val_qw);
-
- /* ring doorbell */
- db_val_qw = *(u64 *)&door_bell;
- ravl = cqm3_ring_hardware_db_fc(hba->dev_handle, SERVICE_T_FC, pmsn_lo,
- (qos_level & SPFC_QOS_LEVEL_MASK),
- db_val_qw);
- if (unlikely(ravl != CQM_SUCCESS)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]SQ(0x%x) send DB(0x%llx) failed",
- sq->context_id, db_val_qw);
-
- ret = UNF_RETURN_ERROR;
- }
-
- /* Doorbell success counter */
- atomic_inc(&sq->sq_db_cnt);
-
- return ret;
-}
-
-u32 spfc_direct_sq_enqueue(struct spfc_parent_ssq_info *ssq, struct spfc_sqe *io_sqe, u8 wqe_type)
-{
- u32 ret = RETURN_OK;
- u32 msn_wd = INVALID_VALUE32;
- u16 link_wqe_msn = 0;
- ulong flag = 0;
- struct spfc_wqe_page *tail_wpg = NULL;
- struct spfc_sqe *sqe_in_wp = NULL;
- struct spfc_linkwqe *link_wqe = NULL;
- struct spfc_linkwqe *link_wqe_last_part = NULL;
- u64 wqe_gpa;
- struct spfc_direct_wqe_db dre_door_bell;
-
- spin_lock_irqsave(&ssq->parent_sq_enqueue_lock, flag);
- tail_wpg = SPFC_GET_SQ_TAIL(ssq);
- if (ssq->wqe_offset == ssq->wqe_num_per_buf) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_INFO,
- "[info]Ssq(0x%x), xid(0x%x) qid(0x%x) add wqepage at Pmsn(0x%x), sqe_minus_cqe_cnt(0x%x)",
- ssq->sqn, ssq->context_id, ssq->sq_queue_id,
- ssq->last_pmsn,
- atomic_read(&ssq->sqe_minus_cqe_cnt));
-
- link_wqe_msn = SPFC_MSN_DEC(ssq->last_pmsn);
- link_wqe = (struct spfc_linkwqe *)spfc_get_wqe_page_entry(tail_wpg,
- ssq->wqe_offset);
- msn_wd = be32_to_cpu(link_wqe->val_wd1);
- msn_wd |= ((u32)(link_wqe_msn & SPFC_MSNWD_L_MASK));
- msn_wd |= (((u32)(link_wqe_msn & SPFC_MSNWD_H_MASK)) << UNF_SHIFT_16);
- link_wqe->val_wd1 = cpu_to_be32(msn_wd);
- link_wqe_last_part = (struct spfc_linkwqe *)((u8 *)link_wqe +
- SPFC_EXTEND_WQE_OFFSET);
- link_wqe_last_part->val_wd1 = link_wqe->val_wd1;
- spfc_set_direct_wqe_owner_be(link_wqe, ssq->last_pi_owner);
- ssq->wqe_offset = 0;
- ssq->last_pi_owner = !ssq->last_pi_owner;
- }
- sqe_in_wp =
- (struct spfc_sqe *)spfc_get_wqe_page_entry(tail_wpg, ssq->wqe_offset);
- spfc_build_wqe_owner_pmsn(io_sqe, (ssq->last_pi_owner), ssq->last_pmsn);
- SPFC_IO_STAT((struct spfc_hba_info *)ssq->hba, wqe_type);
-
- wqe_gpa = tail_wpg->wpg_phy_addr + (ssq->wqe_offset * sizeof(struct spfc_sqe));
- io_sqe->wqe_gpa = (wqe_gpa >> UNF_SHIFT_6);
-
- dre_door_bell.wd0.ddb = IWARP_FC_DDB_TYPE;
- dre_door_bell.wd0.cos = 0;
- dre_door_bell.wd0.c = 0;
- dre_door_bell.wd0.pi_hi =
- (u32)(ssq->last_pmsn >> UNF_SHIFT_12) & SPFC_DB_WD0_PI_H_MASK;
- dre_door_bell.wd0.cntx_size = SPFC_CNTX_SIZE_T_256B;
- dre_door_bell.wd0.xid = ssq->context_id;
- dre_door_bell.wd1.sm_data = ssq->cache_id;
- dre_door_bell.wd1.pi_lo = (u32)(ssq->last_pmsn & SPFC_DB_WD0_PI_L_MASK);
- io_sqe->db_val = *(u64 *)&dre_door_bell;
-
- spfc_convert_parent_wqe_to_big_endian(io_sqe);
- memcpy(sqe_in_wp, io_sqe, sizeof(struct spfc_sqe));
- spfc_set_direct_wqe_owner_be(sqe_in_wp, ssq->last_pi_owner);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_INFO,
- "[INFO]Ssq(0x%x) xid:0x%x,qid:0x%x wqegpa:0x%llx,o:0x%x,outstandind:0x%x,pmsn:0x%x,cmsn:0x%x",
- ssq->sqn, ssq->context_id, ssq->sq_queue_id, wqe_gpa,
- ssq->last_pi_owner, atomic_read(&ssq->sqe_minus_cqe_cnt),
- ssq->last_pmsn, SPFC_GET_QUEUE_CMSN(ssq));
-
- ssq->accum_wqe_cnt++;
- if (ssq->accum_wqe_cnt == accum_db_num) {
- ret = spfc_parent_sq_ring_direct_wqe_doorbell(ssq, (void *)sqe_in_wp);
- if (unlikely(ret != RETURN_OK))
- SPFC_ERR_IO_STAT((struct spfc_hba_info *)ssq->hba, wqe_type);
- ssq->accum_wqe_cnt = 0;
- }
-
- ssq->wqe_offset += 1;
- ssq->last_pmsn = SPFC_MSN_INC(ssq->last_pmsn);
- atomic_inc(&ssq->sq_wqe_cnt);
- atomic_inc(&ssq->sqe_minus_cqe_cnt);
- SPFC_SQ_IO_STAT(ssq, wqe_type);
- spin_unlock_irqrestore(&ssq->parent_sq_enqueue_lock, flag);
- return ret;
-}
-
-u32 spfc_parent_ssq_enqueue(struct spfc_parent_ssq_info *ssq, struct spfc_sqe *io_sqe, u8 wqe_type)
-{
- u32 ret = RETURN_OK;
- u32 addr_wd = INVALID_VALUE32;
- u32 msn_wd = INVALID_VALUE32;
- u16 link_wqe_msn = 0;
- ulong flag = 0;
- struct spfc_wqe_page *new_wqe_page = NULL;
- struct spfc_wqe_page *tail_wpg = NULL;
- struct spfc_sqe *sqe_in_wp = NULL;
- struct spfc_linkwqe *link_wqe = NULL;
- struct spfc_linkwqe *link_wqe_last_part = NULL;
- u32 cur_cmsn = 0;
- u8 qos_level = (u8)io_sqe->ts_sl.cont.icmnd.info.dif_info.wd1.vpid;
- u32 c = SPFC_DB_C_BIT_CONTROL_TYPE;
-
- if (ssq->queue_style == SPFC_QUEUE_RING_STYLE)
- return spfc_direct_sq_enqueue(ssq, io_sqe, wqe_type);
-
- spin_lock_irqsave(&ssq->parent_sq_enqueue_lock, flag);
- tail_wpg = SPFC_GET_SQ_TAIL(ssq);
- if (ssq->wqe_offset == ssq->wqe_num_per_buf) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_INFO,
- "[info]Ssq(0x%x), xid(0x%x) qid(0x%x) add wqepage at Pmsn(0x%x), WpgCnt(0x%x)",
- ssq->sqn, ssq->context_id, ssq->sq_queue_id,
- ssq->last_pmsn,
- atomic_read(&ssq->wqe_page_cnt));
- cur_cmsn = SPFC_GET_QUEUE_CMSN(ssq);
- spfc_free_sq_wqe_page(ssq, cur_cmsn);
- new_wqe_page = spfc_add_one_wqe_page(ssq);
- if (unlikely(!new_wqe_page)) {
- SPFC_ERR_IO_STAT((struct spfc_hba_info *)ssq->hba, wqe_type);
- spin_unlock_irqrestore(&ssq->parent_sq_enqueue_lock, flag);
- return UNF_RETURN_ERROR;
- }
- link_wqe = (struct spfc_linkwqe *)spfc_get_wqe_page_entry(tail_wpg,
- ssq->wqe_offset);
- addr_wd = SPFC_MSD(new_wqe_page->wpg_phy_addr);
- link_wqe->next_page_addr_hi = cpu_to_be32(addr_wd);
- addr_wd = SPFC_LSD(new_wqe_page->wpg_phy_addr);
- link_wqe->next_page_addr_lo = cpu_to_be32(addr_wd);
- link_wqe_msn = SPFC_MSN_DEC(ssq->last_pmsn);
- msn_wd = be32_to_cpu(link_wqe->val_wd1);
- msn_wd |= ((u32)(link_wqe_msn & SPFC_MSNWD_L_MASK));
- msn_wd |= (((u32)(link_wqe_msn & SPFC_MSNWD_H_MASK)) << UNF_SHIFT_16);
- link_wqe->val_wd1 = cpu_to_be32(msn_wd);
- link_wqe_last_part = (struct spfc_linkwqe *)((u8 *)link_wqe +
- SPFC_EXTEND_WQE_OFFSET);
- link_wqe_last_part->next_page_addr_hi = link_wqe->next_page_addr_hi;
- link_wqe_last_part->next_page_addr_lo = link_wqe->next_page_addr_lo;
- link_wqe_last_part->val_wd1 = link_wqe->val_wd1;
- spfc_set_sq_wqe_owner_be(link_wqe);
- ssq->wqe_offset = 0;
- tail_wpg = SPFC_GET_SQ_TAIL(ssq);
- atomic_inc(&ssq->wqe_page_cnt);
- }
-
- spfc_build_wqe_owner_pmsn(io_sqe, !(ssq->last_pi_owner), ssq->last_pmsn);
- SPFC_IO_STAT((struct spfc_hba_info *)ssq->hba, wqe_type);
- spfc_convert_parent_wqe_to_big_endian(io_sqe);
- sqe_in_wp = (struct spfc_sqe *)spfc_get_wqe_page_entry(tail_wpg, ssq->wqe_offset);
- memcpy(sqe_in_wp, io_sqe, sizeof(struct spfc_sqe));
- spfc_set_sq_wqe_owner_be(sqe_in_wp);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_INFO,
- "[INFO]Ssq(0x%x) xid:0x%x,qid:0x%x wqegpa:0x%llx, qos_level:0x%x, c:0x%x",
- ssq->sqn, ssq->context_id, ssq->sq_queue_id,
- virt_to_phys(sqe_in_wp), qos_level, c);
-
- ssq->accum_wqe_cnt++;
- if (ssq->accum_wqe_cnt == accum_db_num) {
- ret = spfc_parent_sq_ring_doorbell(ssq, qos_level, c);
- if (unlikely(ret != RETURN_OK))
- SPFC_ERR_IO_STAT((struct spfc_hba_info *)ssq->hba, wqe_type);
- ssq->accum_wqe_cnt = 0;
- }
- ssq->wqe_offset += 1;
- ssq->last_pmsn = SPFC_MSN_INC(ssq->last_pmsn);
- atomic_inc(&ssq->sq_wqe_cnt);
- atomic_inc(&ssq->sqe_minus_cqe_cnt);
- SPFC_SQ_IO_STAT(ssq, wqe_type);
- spin_unlock_irqrestore(&ssq->parent_sq_enqueue_lock, flag);
- return ret;
-}
-
-u32 spfc_parent_sq_enqueue(struct spfc_parent_sq_info *sq, struct spfc_sqe *io_sqe, u16 ssqn)
-{
- u8 wqe_type = 0;
- struct spfc_hba_info *hba = (struct spfc_hba_info *)sq->hba;
- struct spfc_parent_ssq_info *ssq = NULL;
-
- if (unlikely(ssqn >= SPFC_MAX_SSQ_NUM)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Ssqn 0x%x is invalid.", ssqn);
-
- return UNF_RETURN_ERROR;
- }
-
- wqe_type = (u8)SPFC_GET_WQE_TYPE(io_sqe);
-
- /* Serial enqueue */
- io_sqe->ts_sl.xid = sq->context_id;
- io_sqe->ts_sl.cid = sq->cache_id;
- io_sqe->ts_sl.sqn = ssqn;
-
- /* Choose SSQ */
- ssq = &hba->parent_queue_mgr->shared_queue[ssqn].parent_ssq_info;
-
- /* If the SQ is invalid, the wqe is discarded */
- if (unlikely(!atomic_read(&sq->sq_valid))) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]SQ is invalid, reject wqe(0x%x)", wqe_type);
-
- return UNF_RETURN_ERROR;
- }
-
- /* The heartbeat detection status is 0, which allows control sessions
- * enqueuing
- */
- if (unlikely(!hba->heart_status && SPFC_WQE_IS_IO(io_sqe))) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]Heart status is false");
-
- return UNF_RETURN_ERROR;
- }
-
- if (sq->need_offloaded != SPFC_NEED_DO_OFFLOAD) {
- /* Ensure to be offloaded */
- if (unlikely(!atomic_read(&sq->sq_cached))) {
- SPFC_ERR_IO_STAT((struct spfc_hba_info *)sq->hba, wqe_type);
- SPFC_HBA_STAT((struct spfc_hba_info *)sq->hba,
- SPFC_STAT_PARENT_SQ_NOT_OFFLOADED);
-
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[err]RPort(0x%x) Session(0x%x) is not offloaded, reject wqe(0x%x)",
- sq->rport_index, sq->context_id, wqe_type);
-
- return UNF_RETURN_ERROR;
- }
- }
-
- /* Whether the SQ is in the flush state. Temporarily allow the control
- * sessions to enqueue.
- */
- if (unlikely(sq->port_in_flush && SPFC_WQE_IS_IO(io_sqe))) {
- SPFC_ERR_IO_STAT((struct spfc_hba_info *)sq->hba, wqe_type);
- SPFC_HBA_STAT((struct spfc_hba_info *)sq->hba, SPFC_STAT_PARENT_IO_FLUSHED);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Session(0x%x) in flush, Sqn(0x%x) cmsn(0x%x), reject wqe(0x%x)",
- sq->context_id, ssqn, SPFC_GET_QUEUE_CMSN(ssq),
- wqe_type);
-
- return UNF_RETURN_ERROR;
- }
-
- /* If the SQ is in the Seesion deletion state and is the WQE of the I/O
- * path, * the I/O failure is directly returned
- */
- if (unlikely(sq->sq_in_sess_rst && SPFC_WQE_IS_IO(io_sqe))) {
- SPFC_ERR_IO_STAT((struct spfc_hba_info *)sq->hba, wqe_type);
- SPFC_HBA_STAT((struct spfc_hba_info *)sq->hba, SPFC_STAT_PARENT_IO_FLUSHED);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Session(0x%x) in session reset, reject wqe(0x%x)",
- sq->context_id, wqe_type);
-
- return UNF_RETURN_ERROR;
- }
-
- return spfc_parent_ssq_enqueue(ssq, io_sqe, wqe_type);
-}
-
-static bool spfc_msn_in_wqe_page(u32 start_msn, u32 end_msn, u32 cur_cmsn)
-{
- bool ret = true;
-
- if (end_msn >= start_msn) {
- if (cur_cmsn < start_msn || cur_cmsn > end_msn)
- ret = false;
- else
- ret = true;
- } else {
- if (cur_cmsn > end_msn && cur_cmsn < start_msn)
- ret = false;
- else
- ret = true;
- }
-
- return ret;
-}
-
-void spfc_free_sq_wqe_page(struct spfc_parent_ssq_info *ssq, u32 cur_cmsn)
-{
- u16 wpg_start_cmsn = 0;
- u16 wpg_end_cmsn = 0;
- bool wqe_page_in_use = false;
-
- /* If there is only zero or one Wqe Page, no release is required */
- if (atomic_read(&ssq->wqe_page_cnt) <= SPFC_MIN_WP_NUM)
- return;
-
- /* Check whether the current MSN is within the MSN range covered by the
- * WqePage
- */
- wpg_start_cmsn = ssq->head_start_cmsn;
- wpg_end_cmsn = ssq->head_end_cmsn;
- wqe_page_in_use = spfc_msn_in_wqe_page(wpg_start_cmsn, wpg_end_cmsn, cur_cmsn);
-
- /* If the value of CMSN is within the current Wqe Page, no release is
- * required
- */
- if (wqe_page_in_use)
- return;
-
- /* If the next WqePage is available and the CMSN is not in the current
- * WqePage, * the current WqePage is released
- */
- while (!wqe_page_in_use &&
- (atomic_read(&ssq->wqe_page_cnt) > SPFC_MIN_WP_NUM)) {
- /* Free WqePage */
- spfc_free_head_wqe_page(ssq);
-
- /* Obtain the start MSN of the next WqePage */
- wpg_start_cmsn = SPFC_MSN_INC(wpg_end_cmsn);
-
- /* obtain the end MSN of the next WqePage */
- wpg_end_cmsn =
- SPFC_GET_WP_END_CMSN(wpg_start_cmsn, ssq->wqe_num_per_buf);
-
- /* Set new MSN range */
- ssq->head_start_cmsn = wpg_start_cmsn;
- ssq->head_end_cmsn = wpg_end_cmsn;
- cur_cmsn = SPFC_GET_QUEUE_CMSN(ssq);
- /* Check whether the current MSN is within the MSN range covered
- * by the WqePage
- */
- wqe_page_in_use = spfc_msn_in_wqe_page(wpg_start_cmsn, wpg_end_cmsn, cur_cmsn);
- }
-}
-
-/*
- *Function Name : SPFC_UpdateSqCompletionStat
- *Function Description: Update the calculation statistics of the CQE
- *corresponding to the WQE on the connection SQ.
- *Input Parameters : *sq, *scqe
- *Output Parameters : N/A
- *Return Type : void
- */
-static void spfc_update_sq_wqe_completion_stat(struct spfc_parent_ssq_info *ssq,
- union spfc_scqe *scqe)
-{
- struct spfc_scqe_rcv_els_gs_rsp *els_gs_rsp = NULL;
-
- els_gs_rsp = (struct spfc_scqe_rcv_els_gs_rsp *)scqe;
-
- /* For the ELS/GS RSP intermediate frame and the CQE that is more than
- * the ELS_GS_RSP_EXCH_CHECK_FAIL, no statistics are required
- */
- if (unlikely(SPFC_GET_SCQE_TYPE(scqe) == SPFC_SCQE_ELS_RSP) ||
- (SPFC_GET_SCQE_TYPE(scqe) == SPFC_SCQE_GS_RSP)) {
- if (!els_gs_rsp->wd3.end_rsp || !SPFC_SCQE_ERR_TO_CM(scqe))
- return;
- }
-
- /* When the SQ statistics are updated, the PlogiAcc or PlogiAccSts that
- * is * implicitly unloaded will enter here, and one more CQE count is
- * added
- */
- atomic_inc(&ssq->sq_cqe_cnt);
- atomic_dec(&ssq->sqe_minus_cqe_cnt);
- SPFC_SQ_IO_STAT(ssq, SPFC_GET_SCQE_TYPE(scqe));
-}
-
-/*
- *Function Name : spfc_reclaim_sq_wqe_page
- *Function Description: Reclaim the Wqe Pgae that has been used up in the Linked
- * List SQ.
- *Input Parameters : *handle,
- * *scqe
- *Output Parameters : N/A
- *Return Type : u32
- */
-u32 spfc_reclaim_sq_wqe_page(void *handle, union spfc_scqe *scqe)
-{
- u32 ret = RETURN_OK;
- u32 cur_cmsn = 0;
- u32 sqn = INVALID_VALUE32;
- struct spfc_parent_ssq_info *ssq = NULL;
- struct spfc_parent_shared_queue_info *parent_queue_info = NULL;
- struct spfc_hba_info *hba = NULL;
- ulong flag = 0;
-
- hba = (struct spfc_hba_info *)handle;
- sqn = SPFC_GET_SCQE_SQN(scqe);
- if (sqn >= SPFC_MAX_SSQ_NUM) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) do not have sqn: 0x%x",
- hba->port_cfg.port_id, sqn);
-
- return UNF_RETURN_ERROR;
- }
-
- parent_queue_info = &hba->parent_queue_mgr->shared_queue[sqn];
- ssq = &parent_queue_info->parent_ssq_info;
- /* If there is only zero or one Wqe Page, no release is required */
- if (atomic_read(&ssq->wqe_page_cnt) <= SPFC_MIN_WP_NUM) {
- spfc_update_sq_wqe_completion_stat(ssq, scqe);
- return RETURN_OK;
- }
-
- spin_lock_irqsave(&ssq->parent_sq_enqueue_lock, flag);
- cur_cmsn = SPFC_GET_QUEUE_CMSN(ssq);
- spfc_free_sq_wqe_page(ssq, cur_cmsn);
- spin_unlock_irqrestore(&ssq->parent_sq_enqueue_lock, flag);
-
- spfc_update_sq_wqe_completion_stat(ssq, scqe);
-
- return ret;
-}
-
-u32 spfc_root_cmdq_enqueue(void *handle, union spfc_cmdqe *cmdqe, u16 cmd_len)
-{
-#define SPFC_ROOTCMDQ_TIMEOUT_MS 3000
- u8 wqe_type = 0;
- int cmq_ret = 0;
- struct sphw_cmd_buf *cmd_buf = NULL;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- wqe_type = (u8)cmdqe->common.wd0.task_type;
- SPFC_IO_STAT(hba, wqe_type);
-
- cmd_buf = sphw_alloc_cmd_buf(hba->dev_handle);
- if (!cmd_buf) {
- SPFC_ERR_IO_STAT(hba, wqe_type);
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) CqmHandle(0x%p) allocate cmdq buffer failed",
- hba->port_cfg.port_id, hba->dev_handle);
-
- return UNF_RETURN_ERROR;
- }
-
- memcpy(cmd_buf->buf, cmdqe, cmd_len);
- spfc_cpu_to_big32(cmd_buf->buf, cmd_len);
- cmd_buf->size = cmd_len;
-
- cmq_ret = sphw_cmdq_async(hba->dev_handle, COMM_MOD_FC, 0, cmd_buf, SPHW_CHANNEL_FC);
-
- if (cmq_ret != RETURN_OK) {
- sphw_free_cmd_buf(hba->dev_handle, cmd_buf);
- SPFC_ERR_IO_STAT(hba, wqe_type);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) CqmHandle(0x%p) send buff clear cmnd failed(0x%x)",
- hba->port_cfg.port_id, hba->dev_handle, cmq_ret);
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-struct spfc_parent_queue_info *
-spfc_find_parent_queue_info_by_pkg(void *handle, struct unf_frame_pkg *pkg)
-{
- u32 rport_index = 0;
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- rport_index = pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX];
-
- if (unlikely(rport_index >= UNF_SPFC_MAXRPORT_NUM)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[warn]Port(0x%x) send pkg sid_did(0x%x_0x%x), but uplevel allocate invalid rport index: 0x%x",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did, rport_index);
-
- return NULL;
- }
-
- /* parent -->> session */
- parent_queue_info = &hba->parent_queue_mgr->parent_queue[rport_index];
-
- return parent_queue_info;
-}
-
-struct spfc_parent_queue_info *spfc_find_parent_queue_info_by_id(struct spfc_hba_info *hba,
- u32 local_id, u32 remote_id)
-{
- u32 index = 0;
- ulong flag = 0;
- struct spfc_parent_queue_mgr *parent_queue_mgr = NULL;
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- spinlock_t *prtq_state_lock = NULL;
- u32 lport_id;
- u32 rport_id;
-
- parent_queue_mgr = hba->parent_queue_mgr;
- if (!parent_queue_mgr)
- return NULL;
-
- /* rport_number -->> parent_number -->> session_number */
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- prtq_state_lock = &parent_queue_mgr->parent_queue[index].parent_queue_state_lock;
- lport_id = parent_queue_mgr->parent_queue[index].parent_sq_info.local_port_id;
- rport_id = parent_queue_mgr->parent_queue[index].parent_sq_info.remote_port_id;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- /* local_id & remote_id & offload */
- if (local_id == lport_id && remote_id == rport_id &&
- parent_queue_mgr->parent_queue[index].offload_state ==
- SPFC_QUEUE_STATE_OFFLOADED) {
- parent_queue_info = &parent_queue_mgr->parent_queue[index];
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- return parent_queue_info;
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
- }
-
- return NULL;
-}
-
-struct spfc_parent_queue_info *spfc_find_offload_parent_queue(void *handle, u32 local_id,
- u32 remote_id, u32 rport_index)
-{
- u32 index = 0;
- ulong flag = 0;
- struct spfc_parent_queue_mgr *parent_queue_mgr = NULL;
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- struct spfc_hba_info *hba = NULL;
- spinlock_t *prtq_state_lock = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- parent_queue_mgr = hba->parent_queue_mgr;
- if (!parent_queue_mgr)
- return NULL;
-
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- if (rport_index == index)
- continue;
- prtq_state_lock = &parent_queue_mgr->parent_queue[index].parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- if (local_id == parent_queue_mgr->parent_queue[index]
- .parent_sq_info.local_port_id &&
- remote_id == parent_queue_mgr->parent_queue[index]
- .parent_sq_info.remote_port_id &&
- parent_queue_mgr->parent_queue[index].offload_state !=
- SPFC_QUEUE_STATE_FREE &&
- parent_queue_mgr->parent_queue[index].offload_state !=
- SPFC_QUEUE_STATE_INITIALIZED) {
- parent_queue_info = &parent_queue_mgr->parent_queue[index];
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- return parent_queue_info;
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
- }
-
- return NULL;
-}
-
-struct spfc_parent_sq_info *spfc_find_parent_sq_by_pkg(void *handle, struct unf_frame_pkg *pkg)
-{
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- struct cqm_qpc_mpt *cqm_parent_ctxt_obj = NULL;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- parent_queue_info = spfc_find_parent_queue_info_by_pkg(hba, pkg);
- if (unlikely(!parent_queue_info)) {
- parent_queue_info = spfc_find_parent_queue_info_by_id(hba,
- pkg->frame_head.csctl_sid &
- UNF_NPORTID_MASK,
- pkg->frame_head.rctl_did &
- UNF_NPORTID_MASK);
- if (!parent_queue_info) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[err]Port(0x%x) send pkg sid_did(0x%x_0x%x), get a null parent queue information",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
-
- return NULL;
- }
- }
-
- cqm_parent_ctxt_obj = (parent_queue_info->parent_ctx.cqm_parent_ctx_obj);
- if (unlikely(!cqm_parent_ctxt_obj)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[err]Port(0x%x) send pkg sid_did(0x%x_0x%x) with this rport has not alloc parent sq information",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
-
- return NULL;
- }
-
- return &parent_queue_info->parent_sq_info;
-}
-
-u32 spfc_check_all_parent_queue_free(struct spfc_hba_info *hba)
-{
- u32 index = 0;
- ulong flag = 0;
- struct spfc_parent_queue_mgr *parent_queue_mgr = NULL;
- spinlock_t *prtq_state_lock = NULL;
-
- parent_queue_mgr = hba->parent_queue_mgr;
- if (!parent_queue_mgr) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[err]Port(0x%x) get a null parent queue mgr",
- hba->port_cfg.port_id);
-
- return UNF_RETURN_ERROR;
- }
-
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- prtq_state_lock = &parent_queue_mgr->parent_queue[index].parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- if (parent_queue_mgr->parent_queue[index].offload_state != SPFC_QUEUE_STATE_FREE) {
- spin_unlock_irqrestore(prtq_state_lock, flag);
- return UNF_RETURN_ERROR;
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
- }
-
- return RETURN_OK;
-}
-
-void spfc_flush_specific_scq(struct spfc_hba_info *hba, u32 index)
-{
- /* The software interrupt is scheduled and processed during the second
- * timeout period
- */
- struct spfc_scq_info *scq_info = NULL;
- u32 flush_done_time = 0;
-
- scq_info = &hba->scq_info[index];
- atomic_set(&scq_info->flush_stat, SPFC_QUEUE_FLUSH_DOING);
- tasklet_schedule(&scq_info->tasklet);
-
- /* Wait for a maximum of 2 seconds. If the SCQ soft interrupt is not
- * scheduled * within 2 seconds, only timeout is returned
- */
- while ((atomic_read(&scq_info->flush_stat) != SPFC_QUEUE_FLUSH_DONE) &&
- (flush_done_time < SPFC_QUEUE_FLUSH_WAIT_TIMEOUT_MS)) {
- msleep(SPFC_QUEUE_FLUSH_WAIT_MS);
- flush_done_time += SPFC_QUEUE_FLUSH_WAIT_MS;
- tasklet_schedule(&scq_info->tasklet);
- }
-
- if (atomic_read(&scq_info->flush_stat) != SPFC_QUEUE_FLUSH_DONE) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "[warn]Port(0x%x) special scq(0x%x) flush timeout",
- hba->port_cfg.port_id, index);
- }
-}
-
-static void spfc_flush_cmd_scq(struct spfc_hba_info *hba)
-{
- u32 index = 0;
-
- for (index = SPFC_CMD_SCQN_START; index < SPFC_SESSION_SCQ_NUM;
- index += SPFC_SCQS_PER_SESSION) {
- spfc_flush_specific_scq(hba, index);
- }
-}
-
-static void spfc_flush_sts_scq(struct spfc_hba_info *hba)
-{
- u32 index = 0;
-
- /* for each STS SCQ */
- for (index = SPFC_STS_SCQN_START; index < SPFC_SESSION_SCQ_NUM;
- index += SPFC_SCQS_PER_SESSION) {
- spfc_flush_specific_scq(hba, index);
- }
-}
-
-static void spfc_flush_all_scq(struct spfc_hba_info *hba)
-{
- spfc_flush_cmd_scq(hba);
- spfc_flush_sts_scq(hba);
- /* Flush Default SCQ */
- spfc_flush_specific_scq(hba, SPFC_SESSION_SCQ_NUM);
-}
-
-void spfc_wait_all_queues_empty(struct spfc_hba_info *hba)
-{
- spfc_flush_all_scq(hba);
-}
-
-void spfc_set_rport_flush_state(void *handle, bool in_flush)
-{
- u32 index = 0;
- ulong flag = 0;
- struct spfc_parent_queue_mgr *parent_queue_mgr = NULL;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- parent_queue_mgr = hba->parent_queue_mgr;
- if (!parent_queue_mgr) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) parent queue manager is empty",
- hba->port_cfg.port_id);
- return;
- }
-
- /*
- * for each HBA's R_Port(SQ),
- * set state with been flushing or flush done
- */
- for (index = 0; index < UNF_SPFC_MAXRPORT_NUM; index++) {
- spin_lock_irqsave(&parent_queue_mgr->parent_queue[index]
- .parent_sq_info.parent_sq_enqueue_lock, flag);
- if (parent_queue_mgr->parent_queue[index].offload_state != SPFC_QUEUE_STATE_FREE) {
- parent_queue_mgr->parent_queue[index]
- .parent_sq_info.port_in_flush = in_flush;
- }
- spin_unlock_irqrestore(&parent_queue_mgr->parent_queue[index]
- .parent_sq_info.parent_sq_enqueue_lock, flag);
- }
-}
-
-u32 spfc_clear_fetched_sq_wqe(void *handle)
-{
- u32 ret = UNF_RETURN_ERROR;
- union spfc_cmdqe cmdqe;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
-
- hba = (struct spfc_hba_info *)handle;
- /*
- * The ROOT SQ cannot control the WQE in the empty queue of the ROOT SQ.
- * Therefore, the ROOT SQ does not enqueue the WQE after the hardware
- * obtains the. Link down after the wait mode is used. Therefore, the
- * WQE of the hardware driver needs to enter the WQE of the queue after
- * the Link down of the Link down is reported.
- */
- memset(&cmdqe, 0, sizeof(union spfc_cmdqe));
- spfc_build_cmdqe_common(&cmdqe, SPFC_TASK_T_BUFFER_CLEAR, 0);
- cmdqe.buffer_clear.wd1.rx_id_start = hba->exi_base;
- cmdqe.buffer_clear.wd1.rx_id_end = hba->exi_base + hba->exi_count - 1;
- cmdqe.buffer_clear.scqn = hba->default_scqn;
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MAJOR,
- "[info]Port(0x%x) start clear all fetched wqe in start(0x%x) - end(0x%x) scqn(0x%x) stage(0x%x)",
- hba->port_cfg.port_id, cmdqe.buffer_clear.wd1.rx_id_start,
- cmdqe.buffer_clear.wd1.rx_id_end, cmdqe.buffer_clear.scqn,
- hba->queue_set_stage);
-
- /* Send BUFFER_CLEAR command via ROOT CMDQ */
- ret = spfc_root_cmdq_enqueue(hba, &cmdqe, sizeof(cmdqe.buffer_clear));
-
- return ret;
-}
-
-u32 spfc_clear_pending_sq_wqe(void *handle)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 cmdqe_len = 0;
- ulong flag = 0;
- struct spfc_parent_ssq_info *ssq_info = NULL;
- union spfc_cmdqe cmdqe;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- memset(&cmdqe, 0, sizeof(union spfc_cmdqe));
- spfc_build_cmdqe_common(&cmdqe, SPFC_TASK_T_FLUSH_SQ, 0);
- cmdqe.flush_sq.wd0.wqe_type = SPFC_TASK_T_FLUSH_SQ;
- cmdqe.flush_sq.wd1.scqn = SPFC_LSW(hba->default_scqn);
- cmdqe.flush_sq.wd1.port_id = hba->port_index;
-
- ssq_info = &hba->parent_queue_mgr->shared_queue[ARRAY_INDEX_0].parent_ssq_info;
-
- spin_lock_irqsave(&ssq_info->parent_sq_enqueue_lock, flag);
- cmdqe.flush_sq.wd3.first_sq_xid = ssq_info->context_id;
- spin_unlock_irqrestore(&ssq_info->parent_sq_enqueue_lock, flag);
- cmdqe.flush_sq.wd0.entry_count = SPFC_MAX_SSQ_NUM;
- cmdqe.flush_sq.wd3.sqqid_start_per_session = SPFC_SQ_QID_START_PER_QPC;
- cmdqe.flush_sq.wd3.sqcnt_per_session = SPFC_SQ_NUM_PER_QPC;
- cmdqe.flush_sq.wd1.last_wqe = 1;
-
- /* Clear pending Queue */
- cmdqe_len = (u32)(sizeof(cmdqe.flush_sq));
- ret = spfc_root_cmdq_enqueue(hba, &cmdqe, (u16)cmdqe_len);
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MAJOR,
- "[info]Port(0x%x) clear total 0x%x SQ in this CMDQE(last=%u), stage (0x%x)",
- hba->port_cfg.port_id, SPFC_MAX_SSQ_NUM,
- cmdqe.flush_sq.wd1.last_wqe, hba->queue_set_stage);
-
- return ret;
-}
-
-u32 spfc_wait_queue_set_flush_done(struct spfc_hba_info *hba)
-{
- u32 flush_done_time = 0;
- u32 ret = RETURN_OK;
-
- while ((hba->queue_set_stage != SPFC_QUEUE_SET_STAGE_FLUSHDONE) &&
- (flush_done_time < SPFC_QUEUE_FLUSH_WAIT_TIMEOUT_MS)) {
- msleep(SPFC_QUEUE_FLUSH_WAIT_MS);
- flush_done_time += SPFC_QUEUE_FLUSH_WAIT_MS;
- }
-
- if (hba->queue_set_stage != SPFC_QUEUE_SET_STAGE_FLUSHDONE) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "[warn]Port(0x%x) queue sets flush timeout with stage(0x%x)",
- hba->port_cfg.port_id, hba->queue_set_stage);
-
- ret = UNF_RETURN_ERROR;
- }
-
- return ret;
-}
-
-void spfc_disable_all_scq_schedule(struct spfc_hba_info *hba)
-{
- struct spfc_scq_info *scq_info = NULL;
- u32 index = 0;
-
- for (index = 0; index < SPFC_TOTAL_SCQ_NUM; index++) {
- scq_info = &hba->scq_info[index];
- tasklet_disable(&scq_info->tasklet);
- }
-}
-
-void spfc_disable_queues_dispatch(struct spfc_hba_info *hba)
-{
- spfc_disable_all_scq_schedule(hba);
-}
-
-void spfc_enable_all_scq_schedule(struct spfc_hba_info *hba)
-{
- struct spfc_scq_info *scq_info = NULL;
- u32 index = 0;
-
- for (index = 0; index < SPFC_TOTAL_SCQ_NUM; index++) {
- scq_info = &hba->scq_info[index];
- tasklet_enable(&scq_info->tasklet);
- }
-}
-
-void spfc_enalbe_queues_dispatch(void *handle)
-{
- spfc_enable_all_scq_schedule((struct spfc_hba_info *)handle);
-}
-
-/*
- *Function Name : spfc_clear_els_srq
- *Function Description: When the port is used as the remove, the resources
- *related to the els srq are deleted.
- *Input Parameters : *hba Output Parameters
- *Return Type : void
- */
-void spfc_clear_els_srq(struct spfc_hba_info *hba)
-{
-#define SPFC_WAIT_CLR_SRQ_CTX_MS 500
-#define SPFC_WAIT_CLR_SRQ_CTX_LOOP_TIMES 60
-
- u32 index = 0;
- ulong flag = 0;
- struct spfc_srq_info *srq_info = NULL;
-
- srq_info = &hba->els_srq_info;
-
- spin_lock_irqsave(&srq_info->srq_spin_lock, flag);
- if (!srq_info->enable || srq_info->state == SPFC_CLEAN_DOING) {
- spin_unlock_irqrestore(&srq_info->srq_spin_lock, flag);
-
- return;
- }
- srq_info->enable = false;
- srq_info->state = SPFC_CLEAN_DOING;
- spin_unlock_irqrestore(&srq_info->srq_spin_lock, flag);
-
- spfc_send_clear_srq_cmd(hba, &hba->els_srq_info);
-
- /* wait for uCode to clear SRQ context, the timer is 30S */
- while ((srq_info->state != SPFC_CLEAN_DONE) &&
- (index < SPFC_WAIT_CLR_SRQ_CTX_LOOP_TIMES)) {
- msleep(SPFC_WAIT_CLR_SRQ_CTX_MS);
- index++;
- }
-
- if (srq_info->state != SPFC_CLEAN_DONE) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_WARN,
- "[warn]SPFC Port(0x%x) clear els srq timeout",
- hba->port_cfg.port_id);
- }
-}
-
-u32 spfc_wait_all_parent_queue_free(struct spfc_hba_info *hba)
-{
-#define SPFC_MAX_LOOP_TIMES 6000
-#define SPFC_WAIT_ONE_TIME_MS 5
- u32 index = 0;
- u32 ret = UNF_RETURN_ERROR;
-
- do {
- ret = spfc_check_all_parent_queue_free(hba);
- if (ret == RETURN_OK)
- break;
-
- index++;
- msleep(SPFC_WAIT_ONE_TIME_MS);
- } while (index < SPFC_MAX_LOOP_TIMES);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ERR,
- "[warn]Port(0x%x) wait all parent queue state free timeout",
- hba->port_cfg.port_id);
- }
-
- return ret;
-}
-
-/*
- *Function Name : spfc_queue_pre_process
- *Function Description: When the port functions as the remove, the queue needs
- * to be preprocessed.
- *Input Parameters : *handle,
- * clean
- *Output Parameters : N/A
- *Return Type : void
- */
-void spfc_queue_pre_process(void *handle, bool clean)
-{
-#define SPFC_WAIT_LINKDOWN_EVENT_MS 500
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- /* From port reset & port remove */
- /* 1. Wait for 2s and wait for QUEUE to be FLUSH Done. */
- if (spfc_wait_queue_set_flush_done(hba) != RETURN_OK) {
- /*
- * During the process of removing the card, if the port is
- * disabled and the flush done is not available, the chip is
- * powered off or the pcie link is disconnected. In this case,
- * you can proceed with the next step.
- */
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]SPFC Port(0x%x) clean queue sets timeout",
- hba->port_cfg.port_id);
- }
-
- /*
- * 2. Port remove:
- * 2.1 free parent queue
- * 2.2 clear & destroy ELS/SIRT SRQ
- */
- if (clean) {
- if (spfc_wait_all_parent_queue_free(hba) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT,
- UNF_WARN,
- "[warn]SPFC Port(0x%x) free all parent queue timeout",
- hba->port_cfg.port_id);
- }
-
- /* clear & than destroy ELS/SIRT SRQ */
- spfc_clear_els_srq(hba);
- }
-
- msleep(SPFC_WAIT_LINKDOWN_EVENT_MS);
-
- /*
- * 3. The internal resources of the port chip are flush done. However,
- * there may be residual scqe or rq in the queue. The scheduling is
- * forcibly refreshed once.
- */
- spfc_wait_all_queues_empty(hba);
-
- /* 4. Disable tasklet scheduling for upstream queues on the software
- * layer
- */
- spfc_disable_queues_dispatch(hba);
-}
-
-void spfc_queue_post_process(void *hba)
-{
- spfc_enalbe_queues_dispatch((struct spfc_hba_info *)hba);
-}
-
-/*
- *Function Name : spfc_push_delay_sqe
- *Function Description: Check whether there is a sq that is being deleted.
- * If yes, add the sq to the sq.
- *Input Parameters : *hba,
- * *offload_parent_queue,
- * *sqe,
- * *pkg
- *Output Parameters : N/A
- *Return Type : u32
- */
-u32 spfc_push_delay_sqe(void *hba,
- struct spfc_parent_queue_info *offload_parent_queue,
- struct spfc_sqe *sqe, struct unf_frame_pkg *pkg)
-{
- ulong flag = 0;
- spinlock_t *prtq_state_lock = NULL;
-
- prtq_state_lock = &offload_parent_queue->parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- if (offload_parent_queue->offload_state != SPFC_QUEUE_STATE_INITIALIZED &&
- offload_parent_queue->offload_state != SPFC_QUEUE_STATE_FREE) {
- memcpy(&offload_parent_queue->parent_sq_info.delay_sqe.sqe,
- sqe, sizeof(struct spfc_sqe));
- offload_parent_queue->parent_sq_info.delay_sqe.start_jiff = jiffies;
- offload_parent_queue->parent_sq_info.delay_sqe.time_out =
- pkg->private_data[PKG_PRIVATE_XCHG_TIMEER];
- offload_parent_queue->parent_sq_info.delay_sqe.valid = true;
- offload_parent_queue->parent_sq_info.delay_sqe.rport_index =
- pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX];
- offload_parent_queue->parent_sq_info.delay_sqe.sid =
- pkg->frame_head.csctl_sid & UNF_NPORTID_MASK;
- offload_parent_queue->parent_sq_info.delay_sqe.did =
- pkg->frame_head.rctl_did & UNF_NPORTID_MASK;
- offload_parent_queue->parent_sq_info.delay_sqe.xid =
- sqe->ts_sl.xid;
- offload_parent_queue->parent_sq_info.delay_sqe.ssqn =
- (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) RPort(0x%x) delay send ELS, OXID(0x%x), RXID(0x%x)",
- ((struct spfc_hba_info *)hba)->port_cfg.port_id,
- pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX],
- UNF_GET_OXID(pkg), UNF_GET_RXID(pkg));
-
- return RETURN_OK;
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- return UNF_RETURN_ERROR;
-}
-
-static u32 spfc_pop_session_valid_check(struct spfc_hba_info *hba,
- struct spfc_delay_sqe_ctrl_info *sqe_info, u32 rport_index)
-{
- if (!sqe_info->valid)
- return UNF_RETURN_ERROR;
-
- if (jiffies_to_msecs(jiffies - sqe_info->start_jiff) >= sqe_info->time_out) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) pop delay enable session failed, start time 0x%llx, timeout value 0x%x",
- hba->port_cfg.port_id, sqe_info->start_jiff,
- sqe_info->time_out);
-
- return UNF_RETURN_ERROR;
- }
-
- if (rport_index >= UNF_SPFC_MAXRPORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) pop delay enable session failed, rport index(0x%x) is invalid",
- hba->port_cfg.port_id, rport_index);
-
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-/*
- *Function Name : spfc_pop_delay_sqe
- *Function Description: The sqe that is delayed due to the deletion of the old
- * connection is sent to the root sq for
- *processing. Input Parameters : *hba, *sqe_info Output Parameters : N/A
- *Return Type : void
- */
-static void spfc_pop_delay_sqe(struct spfc_hba_info *hba,
- struct spfc_delay_sqe_ctrl_info *sqe_info)
-{
- ulong flag;
- u32 delay_rport_index = INVALID_VALUE32;
- struct spfc_parent_queue_info *parent_queue = NULL;
- enum spfc_parent_queue_state offload_state =
- SPFC_QUEUE_STATE_DESTROYING;
- struct spfc_delay_destroy_ctrl_info destroy_sqe_info;
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_parent_sq_info *sq_info = NULL;
- spinlock_t *prtq_state_lock = NULL;
-
- memset(&destroy_sqe_info, 0, sizeof(struct spfc_delay_destroy_ctrl_info));
- delay_rport_index = sqe_info->rport_index;
-
- /* According to the sequence, the rport index id is reported and then
- * the sqe of the new link setup request is delivered.
- */
- ret = spfc_pop_session_valid_check(hba, sqe_info, delay_rport_index);
-
- if (ret != RETURN_OK)
- return;
-
- parent_queue = &hba->parent_queue_mgr->parent_queue[delay_rport_index];
- sq_info = &parent_queue->parent_sq_info;
- prtq_state_lock = &parent_queue->parent_queue_state_lock;
- /* Before the root sq is delivered, check the status again to
- * ensure that the initialization status is not uninstalled. Other
- * states are not processed and are discarded directly.
- */
- spin_lock_irqsave(prtq_state_lock, flag);
- offload_state = parent_queue->offload_state;
-
- /* Before re-enqueuing the rootsq, check whether the offload status and
- * connection information is consistent to prevent the old request from
- * being sent after the connection status is changed.
- */
- if (offload_state == SPFC_QUEUE_STATE_INITIALIZED &&
- parent_queue->parent_sq_info.local_port_id == sqe_info->sid &&
- parent_queue->parent_sq_info.remote_port_id == sqe_info->did &&
- SPFC_CHECK_XID_MATCHED(parent_queue->parent_sq_info.context_id,
- sqe_info->sqe.ts_sl.xid)) {
- parent_queue->offload_state = SPFC_QUEUE_STATE_OFFLOADING;
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) pop up delay session enable, sqe start time 0x%llx, timeout value 0x%x, rport index 0x%x, offload state 0x%x",
- hba->port_cfg.port_id, sqe_info->start_jiff,
- sqe_info->time_out, delay_rport_index, offload_state);
-
- if (spfc_parent_sq_enqueue(sq_info, &sqe_info->sqe, sqe_info->ssqn) != RETURN_OK) {
- spin_lock_irqsave(prtq_state_lock, flag);
-
- if (parent_queue->offload_state == SPFC_QUEUE_STATE_OFFLOADING)
- parent_queue->offload_state = offload_state;
-
- if (parent_queue->parent_sq_info.destroy_sqe.valid) {
- memcpy(&destroy_sqe_info,
- &parent_queue->parent_sq_info.destroy_sqe,
- sizeof(struct spfc_delay_destroy_ctrl_info));
-
- parent_queue->parent_sq_info.destroy_sqe.valid = false;
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- spfc_pop_destroy_parent_queue_sqe((void *)hba, &destroy_sqe_info);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) pop up delay session enable fail, recover offload state 0x%x",
- hba->port_cfg.port_id, parent_queue->offload_state);
- return;
- }
- } else {
- spin_unlock_irqrestore(prtq_state_lock, flag);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port 0x%x pop delay session enable failed, sqe start time 0x%llx, timeout value 0x%x, rport index 0x%x, offload state 0x%x",
- hba->port_cfg.port_id, sqe_info->start_jiff,
- sqe_info->time_out, delay_rport_index,
- offload_state);
- }
-}
-
-void spfc_push_destroy_parent_queue_sqe(void *hba,
- struct spfc_parent_queue_info *offloading_parent_queue,
- struct unf_port_info *rport_info)
-{
- offloading_parent_queue->parent_sq_info.destroy_sqe.valid = true;
- offloading_parent_queue->parent_sq_info.destroy_sqe.rport_index = rport_info->rport_index;
- offloading_parent_queue->parent_sq_info.destroy_sqe.time_out =
- SPFC_SQ_DEL_STAGE_TIMEOUT_MS;
- offloading_parent_queue->parent_sq_info.destroy_sqe.start_jiff = jiffies;
- offloading_parent_queue->parent_sq_info.destroy_sqe.rport_info.nport_id =
- rport_info->nport_id;
- offloading_parent_queue->parent_sq_info.destroy_sqe.rport_info.rport_index =
- rport_info->rport_index;
- offloading_parent_queue->parent_sq_info.destroy_sqe.rport_info.port_name =
- rport_info->port_name;
-}
-
-/*
- *Function Name : spfc_pop_destroy_parent_queue_sqe
- *Function Description: The deletion connection sqe that is delayed due to
- * connection uninstallation is sent to
- *the parent sq for processing. Input Parameters : *handle, *destroy_sqe_info
- *Output Parameters : N/A
- *Return Type : void
- */
-void spfc_pop_destroy_parent_queue_sqe(void *handle,
- struct spfc_delay_destroy_ctrl_info *destroy_sqe_info)
-{
- u32 ret = UNF_RETURN_ERROR;
- ulong flag;
- u32 index = INVALID_VALUE32;
- struct spfc_parent_queue_info *parent_queue = NULL;
- enum spfc_parent_queue_state offload_state =
- SPFC_QUEUE_STATE_DESTROYING;
- struct spfc_hba_info *hba = NULL;
- spinlock_t *prtq_state_lock = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- if (!destroy_sqe_info->valid)
- return;
-
- if (jiffies_to_msecs(jiffies - destroy_sqe_info->start_jiff) < destroy_sqe_info->time_out) {
- index = destroy_sqe_info->rport_index;
- parent_queue = &hba->parent_queue_mgr->parent_queue[index];
- prtq_state_lock = &parent_queue->parent_queue_state_lock;
- /* Before delivery, check the status again to ensure that the
- * initialization status is not uninstalled. Other states are
- * not processed and are discarded directly.
- */
- spin_lock_irqsave(prtq_state_lock, flag);
-
- offload_state = parent_queue->offload_state;
- if (offload_state == SPFC_QUEUE_STATE_OFFLOADED ||
- offload_state == SPFC_QUEUE_STATE_INITIALIZED) {
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port 0x%x pop up delay destroy parent sq, sqe start time 0x%llx, timeout value 0x%x, rport index 0x%x, offload state 0x%x",
- hba->port_cfg.port_id,
- destroy_sqe_info->start_jiff,
- destroy_sqe_info->time_out,
- index, offload_state);
- ret = spfc_free_parent_resource(hba, &destroy_sqe_info->rport_info);
- } else {
- ret = UNF_RETURN_ERROR;
- spin_unlock_irqrestore(prtq_state_lock, flag);
- }
- }
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port 0x%x pop delay destroy parent sq failed, sqe start time 0x%llx, timeout value 0x%x, rport index 0x%x, rport nport id 0x%x,offload state 0x%x",
- hba->port_cfg.port_id, destroy_sqe_info->start_jiff,
- destroy_sqe_info->time_out, index,
- destroy_sqe_info->rport_info.nport_id, offload_state);
- }
-}
-
-void spfc_free_parent_queue_info(void *handle, struct spfc_parent_queue_info *parent_queue_info)
-{
- ulong flag = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 rport_index = INVALID_VALUE32;
- struct spfc_hba_info *hba = NULL;
- struct spfc_delay_sqe_ctrl_info sqe_info;
- spinlock_t *prtq_state_lock = NULL;
-
- memset(&sqe_info, 0, sizeof(struct spfc_delay_sqe_ctrl_info));
- hba = (struct spfc_hba_info *)handle;
- prtq_state_lock = &parent_queue_info->parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) begin to free parent sq, rport_index(0x%x)",
- hba->port_cfg.port_id, parent_queue_info->parent_sq_info.rport_index);
-
- if (parent_queue_info->offload_state == SPFC_QUEUE_STATE_FREE) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[info]Port(0x%x) duplicate free parent sq, rport_index(0x%x)",
- hba->port_cfg.port_id,
- parent_queue_info->parent_sq_info.rport_index);
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
- return;
- }
-
- if (parent_queue_info->parent_sq_info.delay_sqe.valid) {
- memcpy(&sqe_info, &parent_queue_info->parent_sq_info.delay_sqe,
- sizeof(struct spfc_delay_sqe_ctrl_info));
- }
-
- rport_index = parent_queue_info->parent_sq_info.rport_index;
-
- /* The Parent Contexe and SQ information is released. After
- * initialization, the Parent Contexe and SQ information is associated
- * with the sq in the queue of the parent
- */
-
- spfc_free_parent_sq(hba, parent_queue_info);
-
- /* The initialization of all queue id is invalid */
- parent_queue_info->parent_cmd_scq_info.cqm_queue_id = INVALID_VALUE32;
- parent_queue_info->parent_sts_scq_info.cqm_queue_id = INVALID_VALUE32;
- parent_queue_info->parent_els_srq_info.cqm_queue_id = INVALID_VALUE32;
- parent_queue_info->offload_state = SPFC_QUEUE_STATE_FREE;
-
- spin_unlock_irqrestore(prtq_state_lock, flag);
-
- UNF_LOWLEVEL_PORT_EVENT(ret, hba->lport, UNF_PORT_RELEASE_RPORT_INDEX,
- (void *)&rport_index);
-
- spfc_pop_delay_sqe(hba, &sqe_info);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]Port(0x%x) free parent sq with rport_index(0x%x) failed",
- hba->port_cfg.port_id, rport_index);
- }
-}
-
-static void spfc_do_port_reset(struct work_struct *work)
-{
- struct spfc_suspend_sqe_info *suspend_sqe = NULL;
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VOID(work);
-
- suspend_sqe = container_of(work, struct spfc_suspend_sqe_info,
- timeout_work.work);
- hba = (struct spfc_hba_info *)suspend_sqe->hba;
- FC_CHECK_RETURN_VOID(hba);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) magic num (0x%x)do port reset.",
- hba->port_cfg.port_id, suspend_sqe->magic_num);
-
- spfc_port_reset(hba);
-}
-
-static void
-spfc_push_sqe_suspend(void *hba, struct spfc_parent_queue_info *parent_queue,
- struct spfc_sqe *sqe, struct unf_frame_pkg *pkg, u32 magic_num)
-{
-#define SPFC_SQ_NOP_TIMEOUT_MS 1000
- ulong flag = 0;
- u32 sqn_base;
- struct spfc_parent_sq_info *sq = NULL;
- struct spfc_suspend_sqe_info *suspend_sqe = NULL;
-
- sq = &parent_queue->parent_sq_info;
- suspend_sqe =
- kmalloc(sizeof(struct spfc_suspend_sqe_info), GFP_ATOMIC);
- if (!suspend_sqe) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[err]alloc suspend sqe memory failed");
- return;
- }
- memset(suspend_sqe, 0, sizeof(struct spfc_suspend_sqe_info));
- memcpy(&suspend_sqe->sqe, sqe, sizeof(struct spfc_sqe));
- suspend_sqe->magic_num = magic_num;
- suspend_sqe->old_offload_sts = sq->need_offloaded;
- suspend_sqe->hba = sq->hba;
-
- if (pkg) {
- memcpy(&suspend_sqe->pkg, pkg, sizeof(struct unf_frame_pkg));
- } else {
- sqn_base = sq->sqn_base;
- suspend_sqe->pkg.private_data[PKG_PRIVATE_XCHG_SSQ_INDEX] =
- sqn_base;
- }
-
- INIT_DELAYED_WORK(&suspend_sqe->timeout_work, spfc_do_port_reset);
- INIT_LIST_HEAD(&suspend_sqe->list_sqe_entry);
-
- spin_lock_irqsave(&parent_queue->parent_queue_state_lock, flag);
- list_add_tail(&suspend_sqe->list_sqe_entry, &sq->suspend_sqe_list);
- spin_unlock_irqrestore(&parent_queue->parent_queue_state_lock, flag);
-
- (void)queue_delayed_work(((struct spfc_hba_info *)hba)->work_queue,
- &suspend_sqe->timeout_work,
- (ulong)msecs_to_jiffies((u32)SPFC_SQ_NOP_TIMEOUT_MS));
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) magic num(0x%x)suspend sqe",
- ((struct spfc_hba_info *)hba)->port_cfg.port_id, magic_num);
-}
-
-u32 spfc_pop_suspend_sqe(void *handle, struct spfc_parent_queue_info *parent_queue,
- struct spfc_suspend_sqe_info *suspen_sqe)
-{
- ulong flag;
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_parent_sq_info *sq = NULL;
- u16 ssqn;
- struct unf_frame_pkg *pkg = NULL;
- struct spfc_hba_info *hba = (struct spfc_hba_info *)handle;
- u8 task_type;
- spinlock_t *prtq_state_lock = NULL;
-
- sq = &parent_queue->parent_sq_info;
- task_type = suspen_sqe->sqe.ts_sl.task_type;
- pkg = &suspen_sqe->pkg;
- if (!pkg) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR, "[error]pkt is null.");
- return UNF_RETURN_ERROR;
- }
-
- ssqn = (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) pop up suspend wqe sqn (0x%x) TaskType(0x%x)",
- hba->port_cfg.port_id, ssqn, task_type);
-
- prtq_state_lock = &parent_queue->parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flag);
- if (SPFC_RPORT_NOT_OFFLOADED(parent_queue) &&
- (task_type == SPFC_SQE_ELS_RSP ||
- task_type == SPFC_TASK_T_ELS)) {
- spin_unlock_irqrestore(prtq_state_lock, flag);
- /* Send PLOGI or PLOGI ACC or SCR if session not offload */
- ret = spfc_send_els_via_default_session(hba, &suspen_sqe->sqe, pkg, parent_queue);
- } else {
- spin_unlock_irqrestore(prtq_state_lock, flag);
- ret = spfc_parent_sq_enqueue(sq, &suspen_sqe->sqe, ssqn);
- }
- return ret;
-}
-
-static void spfc_build_nop_sqe(struct spfc_hba_info *hba, struct spfc_parent_sq_info *sq,
- struct spfc_sqe *sqe, u32 magic_num, u32 scqn)
-{
- sqe->ts_sl.task_type = SPFC_SQE_NOP;
- sqe->ts_sl.wd0.conn_id = (u16)(sq->rport_index);
- sqe->ts_sl.cont.nop_sq.wd0.scqn = scqn;
- sqe->ts_sl.cont.nop_sq.magic_num = magic_num;
- spfc_build_common_wqe_ctrls(&sqe->ctrl_sl,
- sizeof(struct spfc_sqe_ts) / SPFC_WQE_SECTION_CHUNK_SIZE);
-}
-
-u32 spfc_send_nop_cmd(void *handle, struct spfc_parent_sq_info *parent_sq_info,
- u32 magic_num, u16 sqn)
-{
- struct spfc_sqe empty_sq_sqe;
- struct spfc_hba_info *hba = (struct spfc_hba_info *)handle;
- u32 ret;
-
- memset(&empty_sq_sqe, 0, sizeof(struct spfc_sqe));
-
- spfc_build_nop_sqe(hba, parent_sq_info, &empty_sq_sqe, magic_num, hba->default_scqn);
- ret = spfc_parent_sq_enqueue(parent_sq_info, &empty_sq_sqe, sqn);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]send nop cmd scqn(0x%x) sq(0x%x).",
- hba->default_scqn, sqn);
- return ret;
-}
-
-u32 spfc_suspend_sqe_and_send_nop(void *handle,
- struct spfc_parent_queue_info *parent_queue,
- struct spfc_sqe *sqe, struct unf_frame_pkg *pkg)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 magic_num;
- struct spfc_hba_info *hba = (struct spfc_hba_info *)handle;
- struct spfc_parent_sq_info *parent_sq = &parent_queue->parent_sq_info;
- struct unf_lport *lport = (struct unf_lport *)hba->lport;
-
- FC_CHECK_RETURN_VALUE(lport, UNF_RETURN_ERROR);
-
- if (pkg) {
- magic_num = pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME];
- } else {
- magic_num = (u32)atomic64_inc_return(&((struct unf_lport *)
- lport->root_lport)->exchg_index);
- }
-
- spfc_push_sqe_suspend(hba, parent_queue, sqe, pkg, magic_num);
- if (SPFC_RPORT_NOT_OFFLOADED(parent_queue))
- parent_sq->need_offloaded = SPFC_NEED_DO_OFFLOAD;
-
- ret = spfc_send_nop_cmd(hba, parent_sq, magic_num,
- (u16)parent_sq->sqn_base);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[err]Port(0x%x) rport_index(0x%x)send sq empty failed.",
- hba->port_cfg.port_id, parent_sq->rport_index);
- }
- return ret;
-}
-
-void spfc_build_session_rst_wqe(void *handle, struct spfc_parent_sq_info *sq,
- struct spfc_sqe *sqe, enum spfc_session_reset_mode mode, u32 scqn)
-{
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- /* The reset session command does not occupy xid. Therefore,
- * 0xffff can be used to align with the microcode.
- */
- sqe->ts_sl.task_type = SPFC_SQE_SESS_RST;
- sqe->ts_sl.local_xid = 0xffff;
- sqe->ts_sl.wd0.conn_id = (u16)(sq->rport_index);
- sqe->ts_sl.wd0.remote_xid = 0xffff;
- sqe->ts_sl.cont.reset_session.wd0.reset_exch_start = hba->exi_base;
- sqe->ts_sl.cont.reset_session.wd0.reset_exch_end = hba->exi_base + (hba->exi_count - 1);
- sqe->ts_sl.cont.reset_session.wd1.reset_did = sq->remote_port_id;
- sqe->ts_sl.cont.reset_session.wd1.mode = mode;
- sqe->ts_sl.cont.reset_session.wd2.reset_sid = sq->local_port_id;
- sqe->ts_sl.cont.reset_session.wd3.scqn = scqn;
-
- spfc_build_common_wqe_ctrls(&sqe->ctrl_sl,
- sizeof(struct spfc_sqe_ts) / SPFC_WQE_SECTION_CHUNK_SIZE);
-}
-
-u32 spfc_send_session_rst_cmd(void *handle,
- struct spfc_parent_queue_info *parent_queue_info,
- enum spfc_session_reset_mode mode)
-{
- struct spfc_parent_sq_info *sq = NULL;
- struct spfc_sqe rst_sess_sqe;
- u32 ret = UNF_RETURN_ERROR;
- u32 sts_scqn = 0;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
- memset(&rst_sess_sqe, 0, sizeof(struct spfc_sqe));
- sq = &parent_queue_info->parent_sq_info;
- sts_scqn = hba->default_scqn;
-
- spfc_build_session_rst_wqe(hba, sq, &rst_sess_sqe, mode, sts_scqn);
- ret = spfc_suspend_sqe_and_send_nop(hba, parent_queue_info, &rst_sess_sqe, NULL);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]RPort(0x%x) send SESS_RST(%d) start_exch_id(0x%x) end_exch_id(0x%x), scqn(0x%x) ctx_id(0x%x) cid(0x%x)",
- sq->rport_index, mode,
- rst_sess_sqe.ts_sl.cont.reset_session.wd0.reset_exch_start,
- rst_sess_sqe.ts_sl.cont.reset_session.wd0.reset_exch_end,
- rst_sess_sqe.ts_sl.cont.reset_session.wd3.scqn,
- sq->context_id, sq->cache_id);
- return ret;
-}
-
-void spfc_rcvd_els_from_srq_timeout(struct work_struct *work)
-{
- struct spfc_hba_info *hba = NULL;
-
- hba = container_of(work, struct spfc_hba_info, srq_delay_info.del_work.work);
-
- /* If the frame is not processed, the frame is pushed to the CM layer:
- * The frame may have been processed when the root rq receives data.
- */
- if (hba->srq_delay_info.srq_delay_flag) {
- spfc_recv_els_cmnd(hba, &hba->srq_delay_info.frame_pkg,
- hba->srq_delay_info.frame_pkg.unf_cmnd_pload_bl.buffer_ptr,
- 0, false);
- hba->srq_delay_info.srq_delay_flag = 0;
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) srq delay work timeout, send saved plgoi to CM",
- hba->port_cfg.port_id);
- }
-}
-
-u32 spfc_flush_ini_resp_queue(void *handle)
-{
- struct spfc_hba_info *hba = NULL;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
- hba = (struct spfc_hba_info *)handle;
-
- spfc_flush_sts_scq(hba);
-
- return RETURN_OK;
-}
-
-static void spfc_handle_aeq_queue_error(struct spfc_hba_info *hba,
- struct spfc_aqe_data *aeq_msg)
-{
- u32 sts_scqn_local = 0;
- u32 full_ci = INVALID_VALUE32;
- u32 full_ci_owner = INVALID_VALUE32;
- struct spfc_scq_info *scq_info = NULL;
-
- sts_scqn_local = SPFC_RPORTID_TO_STS_SCQN(aeq_msg->wd0.conn_id);
- scq_info = &hba->scq_info[sts_scqn_local];
- full_ci = scq_info->ci;
- full_ci_owner = scq_info->ci_owner;
-
- /* Currently, Flush is forcibly set to StsScq. No matter whether scq is
- * processed, AEQE is returned
- */
- tasklet_schedule(&scq_info->tasklet);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) RPort(0x%x) LocalScqn(0x%x) CqmScqn(0x%x) is full, force flush CI from (%u|0x%x) to (%u|0x%x)",
- hba->port_cfg.port_id, aeq_msg->wd0.conn_id,
- sts_scqn_local, scq_info->scqn, full_ci_owner, full_ci,
- scq_info->ci_owner, scq_info->ci);
-}
-
-void spfc_process_aeqe(void *handle, u8 event_type, u8 *val)
-{
- u32 ret = RETURN_OK;
- struct spfc_hba_info *hba = (struct spfc_hba_info *)handle;
- struct spfc_aqe_data aeq_msg;
- u8 event_code = INVALID_VALUE8;
- u64 event_val = *((u64 *)val);
-
- FC_CHECK_RETURN_VOID(hba);
-
- memcpy(&aeq_msg, (struct spfc_aqe_data *)&event_val, sizeof(struct spfc_aqe_data));
- event_code = (u8)aeq_msg.wd0.evt_code;
-
- switch (event_type) {
- case FC_AEQ_EVENT_QUEUE_ERROR:
- spfc_handle_aeq_queue_error(hba, &aeq_msg);
- break;
-
- case FC_AEQ_EVENT_WQE_FATAL_ERROR:
- UNF_LOWLEVEL_PORT_EVENT(ret, hba->lport,
- UNF_PORT_ABNORMAL_RESET, NULL);
- break;
-
- case FC_AEQ_EVENT_CTX_FATAL_ERROR:
- break;
-
- case FC_AEQ_EVENT_OFFLOAD_ERROR:
- ret = spfc_handle_aeq_off_load_err(hba, &aeq_msg);
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[warn]Port(0x%x) receive a unsupported AEQ EventType(0x%x) EventVal(0x%llx).",
- hba->port_cfg.port_id, event_type, (u64)event_val);
- return;
- }
-
- if (event_code < FC_AEQ_EVT_ERR_CODE_BUTT)
- SPFC_AEQ_ERR_TYPE_STAT(hba, aeq_msg.wd0.evt_code);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_KEVENT,
- "[info]Port(0x%x) receive AEQ EventType(0x%x) EventVal(0x%llx) EvtCode(0x%x) Conn_id(0x%x) Xid(0x%x) %s",
- hba->port_cfg.port_id, event_type, (u64)event_val, event_code,
- aeq_msg.wd0.conn_id, aeq_msg.wd1.xid,
- (ret == UNF_RETURN_ERROR) ? "ERROR" : "OK");
-}
-
-void spfc_sess_resource_free_sync(void *handle,
- struct unf_port_info *rport_info)
-{
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- ulong flag = 0;
- u32 wait_sq_cnt = 0;
- struct spfc_hba_info *hba = NULL;
- spinlock_t *prtq_state_lock = NULL;
- u32 index = SPFC_DEFAULT_RPORT_INDEX;
-
- FC_CHECK_RETURN_VOID(handle);
- FC_CHECK_RETURN_VOID(rport_info);
-
- hba = (struct spfc_hba_info *)handle;
- parent_queue_info = &hba->parent_queue_mgr->parent_queue[index];
- prtq_state_lock = &parent_queue_info->parent_queue_state_lock;
- (void)spfc_free_parent_resource((void *)hba, rport_info);
-
- for (;;) {
- spin_lock_irqsave(prtq_state_lock, flag);
- if (parent_queue_info->offload_state == SPFC_QUEUE_STATE_FREE) {
- spin_unlock_irqrestore(prtq_state_lock, flag);
- break;
- }
- spin_unlock_irqrestore(prtq_state_lock, flag);
- msleep(SPFC_WAIT_SESS_FREE_ONE_TIME_MS);
- wait_sq_cnt++;
- if (wait_sq_cnt >= SPFC_MAX_WAIT_LOOP_TIMES)
- break;
- }
-}
diff --git a/drivers/scsi/spfc/hw/spfc_queue.h b/drivers/scsi/spfc/hw/spfc_queue.h
deleted file mode 100644
index c09f098e7324..000000000000
--- a/drivers/scsi/spfc/hw/spfc_queue.h
+++ /dev/null
@@ -1,711 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_QUEUE_H
-#define SPFC_QUEUE_H
-
-#include "unf_type.h"
-#include "spfc_wqe.h"
-#include "spfc_cqm_main.h"
-#define SPFC_MIN_WP_NUM (2)
-#define SPFC_EXTEND_WQE_OFFSET (128)
-#define SPFC_SQE_SIZE (256)
-#define WQE_MARKER_0 (0x0)
-#define WQE_MARKER_6B (0x6b)
-
-/* PARENT SQ & Context defines */
-#define SPFC_MAX_MSN (65535)
-#define SPFC_MSN_MASK (0xffff000000000000LL)
-#define SPFC_SQE_TS_SIZE (72)
-#define SPFC_SQE_FIRST_OBIT_DW_POS (0)
-#define SPFC_SQE_SECOND_OBIT_DW_POS (30)
-#define SPFC_SQE_OBIT_SET_MASK_BE (0x80)
-#define SPFC_SQE_OBIT_CLEAR_MASK_BE (0xffffff7f)
-#define SPFC_MAX_SQ_TASK_TYPE_CNT (128)
-#define SPFC_SQ_NUM_PER_QPC (3)
-#define SPFC_SQ_QID_START_PER_QPC 0
-#define SPFC_SQ_SPACE_OFFSET (64)
-#define SPFC_MAX_SSQ_NUM (SPFC_SQ_NUM_PER_QPC * 63 + 1) /* must be a multiple of 3 */
-#define SPFC_DIRECTWQE_SQ_INDEX (SPFC_MAX_SSQ_NUM - 1)
-
-/* Note: if the location of flush done bit changes, the definition must be
- * modifyed again
- */
-#define SPFC_CTXT_FLUSH_DONE_DW_POS (58)
-#define SPFC_CTXT_FLUSH_DONE_MASK_BE (0x4000)
-#define SPFC_CTXT_FLUSH_DONE_MASK_LE (0x400000)
-
-#define SPFC_PCIE_TEMPLATE (0)
-#define SPFC_DMA_ATTR_OFST (0)
-
-/*
- *When driver assembles WQE SGE, the GPA parity bit is multiplexed as follows:
- * {rsvd'2,zerocopysoro'2,zerocopy_dmaattr_idx'6,pcie_template'6}
- */
-#define SPFC_PCIE_TEMPLATE_OFFSET 0
-#define SPFC_PCIE_ZEROCOPY_DMAATTR_IDX_OFFSET 6
-#define SPFC_PCIE_ZEROCOPY_SO_RO_OFFSET 12
-#define SPFC_PCIE_RELAXED_ORDERING (1)
-#define SPFC_ZEROCOPY_PCIE_TEMPLATE_VALUE \
- (SPFC_PCIE_RELAXED_ORDERING << SPFC_PCIE_ZEROCOPY_SO_RO_OFFSET | \
- SPFC_DMA_ATTR_OFST << SPFC_PCIE_ZEROCOPY_DMAATTR_IDX_OFFSET | \
- SPFC_PCIE_TEMPLATE)
-
-#define SPFC_GET_SQ_HEAD(sq) \
- list_entry(UNF_OS_LIST_NEXT(&(sq)->list_linked_list_sq), \
- struct spfc_wqe_page, entry_wpg)
-#define SPFC_GET_SQ_TAIL(sq) \
- list_entry(UNF_OS_LIST_PREV(&(sq)->list_linked_list_sq), \
- struct spfc_wqe_page, entry_wpg)
-#define SPFC_SQ_IO_STAT(ssq, io_type) \
- (atomic_inc(&(ssq)->io_stat[io_type]))
-#define SPFC_SQ_IO_STAT_READ(ssq, io_type) \
- (atomic_read(&(ssq)->io_stat[io_type]))
-#define SPFC_GET_QUEUE_CMSN(ssq) \
- ((u32)(be64_to_cpu(((((ssq)->queue_header)->ci_record) & SPFC_MSN_MASK))))
-#define SPFC_GET_WP_END_CMSN(head_start_cmsn, wqe_num_per_buf) \
- ((u16)(((u32)(head_start_cmsn) + (u32)(wqe_num_per_buf) - 1) % (SPFC_MAX_MSN + 1)))
-#define SPFC_MSN_INC(msn) (((SPFC_MAX_MSN) == (msn)) ? 0 : ((msn) + 1))
-#define SPFC_MSN_DEC(msn) (((msn) == 0) ? (SPFC_MAX_MSN) : ((msn) - 1))
-#define SPFC_QUEUE_MSN_OFFSET(start_cmsn, end_cmsn) \
- ((u32)((((u32)(end_cmsn) + (SPFC_MAX_MSN)) - (u32)(start_cmsn)) % (SPFC_MAX_MSN + 1)))
-#define SPFC_MSN32_ADD(msn, inc) (((msn) + (inc)) % (SPFC_MAX_MSN + 1))
-
-/*
- *SCQ defines
- */
-#define SPFC_INT_NUM_PER_QUEUE (1)
-#define SPFC_SCQ_INT_ID_MAX (2048) /* 11BIT */
-#define SPFC_SCQE_SIZE (64)
-#define SPFC_CQE_GPA_SHIFT (4)
-#define SPFC_NEXT_CQE_GPA_SHIFT (12)
-/* 1-Update Ci by Tile, 0-Update Ci by Hardware */
-#define SPFC_PMSN_CI_TYPE_FROM_HOST (0)
-#define SPFC_PMSN_CI_TYPE_FROM_UCODE (1)
-#define SPFC_ARMQ_IDLE (0)
-#define SPFC_CQ_INT_MODE (2)
-#define SPFC_CQ_HEADER_OWNER_SHIFT (15)
-
-/* SCQC_CQ_DEPTH 0-256, 1-512, 2-1k, 3-2k, 4-4k, 5-8k, 6-16k, 7-32k.
- * include LinkWqe
- */
-#define SPFC_CMD_SCQ_DEPTH (4096)
-#define SPFC_STS_SCQ_DEPTH (8192)
-
-#define SPFC_CMD_SCQC_CQ_DEPTH (spfc_log2n(SPFC_CMD_SCQ_DEPTH >> 8))
-#define SPFC_STS_SCQC_CQ_DEPTH (spfc_log2n(SPFC_STS_SCQ_DEPTH >> 8))
-#define SPFC_STS_SCQ_CI_TYPE SPFC_PMSN_CI_TYPE_FROM_HOST
-
-#define SPFC_CMD_SCQ_CI_TYPE SPFC_PMSN_CI_TYPE_FROM_UCODE
-
-#define SPFC_SCQ_INTR_LOW_LATENCY_MODE 0
-#define SPFC_SCQ_INTR_POLLING_MODE 1
-#define SPFC_SCQ_PROC_CNT_PER_SECOND_THRESHOLD (30000)
-
-#define SPFC_CQE_MAX_PROCESS_NUM_PER_INTR (128)
-#define SPFC_SESSION_SCQ_NUM (16)
-
-/* SCQ[0, 2, 4 ...]CMD SCQ,SCQ[1, 3, 5 ...]STS
- * SCQ,SCQ[SPFC_TOTAL_SCQ_NUM-1]Defaul SCQ
- */
-#define SPFC_CMD_SCQN_START (0)
-#define SPFC_STS_SCQN_START (1)
-#define SPFC_SCQS_PER_SESSION (2)
-
-#define SPFC_TOTAL_SCQ_NUM (SPFC_SESSION_SCQ_NUM + 1)
-
-#define SPFC_SCQ_IS_STS(scq_index) \
- (((scq_index) % SPFC_SCQS_PER_SESSION) || ((scq_index) == SPFC_SESSION_SCQ_NUM))
-#define SPFC_SCQ_IS_CMD(scq_index) (!SPFC_SCQ_IS_STS(scq_index))
-#define SPFC_RPORTID_TO_CMD_SCQN(rport_index) \
- (((rport_index) * SPFC_SCQS_PER_SESSION) % SPFC_SESSION_SCQ_NUM)
-#define SPFC_RPORTID_TO_STS_SCQN(rport_index) \
- ((((rport_index) * SPFC_SCQS_PER_SESSION) + 1) % SPFC_SESSION_SCQ_NUM)
-
-/*
- *SRQ defines
- */
-#define SPFC_SRQE_SIZE (32)
-#define SPFC_SRQ_INIT_LOOP_O (1)
-#define SPFC_QUEUE_RING (1)
-#define SPFC_SRQ_ELS_DATA_NUM (1)
-#define SPFC_SRQ_ELS_SGE_LEN (256)
-#define SPFC_SRQ_ELS_DATA_DEPTH (31750) /* depth should Divide 127 */
-
-#define SPFC_IRQ_NAME_MAX (30)
-
-/* Support 2048 sessions(xid) */
-#define SPFC_CQM_XID_MASK (0x7ff)
-
-#define SPFC_QUEUE_FLUSH_DOING (0)
-#define SPFC_QUEUE_FLUSH_DONE (1)
-#define SPFC_QUEUE_FLUSH_WAIT_TIMEOUT_MS (2000)
-#define SPFC_QUEUE_FLUSH_WAIT_MS (2)
-
-/*
- *RPort defines
- */
-#define SPFC_RPORT_OFFLOADED(prnt_qinfo) \
- ((prnt_qinfo)->offload_state == SPFC_QUEUE_STATE_OFFLOADED)
-#define SPFC_RPORT_NOT_OFFLOADED(prnt_qinfo) \
- ((prnt_qinfo)->offload_state != SPFC_QUEUE_STATE_OFFLOADED)
-#define SPFC_RPORT_FLUSH_NOT_NEEDED(prnt_qinfo) \
- (((prnt_qinfo)->offload_state == SPFC_QUEUE_STATE_INITIALIZED) || \
- ((prnt_qinfo)->offload_state == SPFC_QUEUE_STATE_OFFLOADING) || \
- ((prnt_qinfo)->offload_state == SPFC_QUEUE_STATE_FREE))
-#define SPFC_CHECK_XID_MATCHED(sq_xid, sqe_xid) \
- (((sq_xid) & SPFC_CQM_XID_MASK) == ((sqe_xid) & SPFC_CQM_XID_MASK))
-#define SPFC_PORT_MODE_TGT (0) /* Port mode */
-#define SPFC_PORT_MODE_INI (1)
-#define SPFC_PORT_MODE_BOTH (2)
-
-/*
- *Hardware Reserved Queue Info defines
- */
-#define SPFC_HRQI_SEQ_ID_MAX (255)
-#define SPFC_HRQI_SEQ_INDEX_MAX (64)
-#define SPFC_HRQI_SEQ_INDEX_SHIFT (6)
-#define SPFC_HRQI_SEQ_SEPCIAL_ID (3)
-#define SPFC_HRQI_SEQ_INVALID_ID (~0LL)
-
-enum spfc_session_reset_mode {
- SPFC_SESS_RST_DELETE_IO_ONLY = 1,
- SPFC_SESS_RST_DELETE_CONN_ONLY = 2,
- SPFC_SESS_RST_DELETE_IO_CONN_BOTH = 3,
- SPFC_SESS_RST_MODE_BUTT
-};
-
-/* linkwqe */
-#define CQM_LINK_WQE_CTRLSL_VALUE 2
-#define CQM_LINK_WQE_LP_VALID 1
-#define CQM_LINK_WQE_LP_INVALID 0
-
-/* bit mask */
-#define SPFC_SCQN_MASK 0xfffff
-#define SPFC_SCQ_CTX_CI_GPA_MASK 0xfffffff
-#define SPFC_SCQ_CTX_C_EQN_MSI_X_MASK 0x7
-#define SPFC_PARITY_MASK 0x1
-#define SPFC_KEYSECTION_XID_H_MASK 0xf
-#define SPFC_KEYSECTION_XID_L_MASK 0xffff
-#define SPFC_SRQ_CTX_rqe_dma_attr_idx_MASK 0xf
-#define SPFC_SSQ_CTX_MASK 0xfffff
-#define SPFC_KEY_WD3_SID_2_MASK 0x00ff0000
-#define SPFC_KEY_WD3_SID_1_MASK 0x00ff00
-#define SPFC_KEY_WD3_SID_0_MASK 0x0000ff
-#define SPFC_KEY_WD4_DID_2_MASK 0x00ff0000
-#define SPFC_KEY_WD4_DID_1_MASK 0x00ff00
-#define SPFC_KEY_WD4_DID_0_MASK 0x0000ff
-#define SPFC_LOCAL_LW_WD1_DUMP_MSN_MASK 0x7fff
-#define SPFC_PMSN_MASK 0xff
-#define SPFC_QOS_LEVEL_MASK 0x3
-#define SPFC_DB_VAL_MASK 0xFFFFFFFF
-#define SPFC_MSNWD_L_MASK 0xffff
-#define SPFC_MSNWD_H_MASK 0x7fff
-#define SPFC_DB_WD0_PI_H_MASK 0xf
-#define SPFC_DB_WD0_PI_L_MASK 0xfff
-
-#define SPFC_DB_C_BIT_DATA_TYPE 0
-#define SPFC_DB_C_BIT_CONTROL_TYPE 1
-
-#define SPFC_OWNER_DRIVER_PRODUCT (1)
-
-#define SPFC_256BWQE_ENABLE (1)
-#define SPFC_DB_ARM_DISABLE (0)
-
-#define SPFC_CNTX_SIZE_T_256B (0)
-#define SPFC_CNTX_SIZE_256B (256)
-
-#define SPFC_SERVICE_TYPE_FC (12)
-#define SPFC_SERVICE_TYPE_FC_SQ (13)
-
-#define SPFC_PACKET_COS_FC_CMD (0)
-#define SPFC_PACKET_COS_FC_DATA (1)
-
-#define SPFC_QUEUE_LINK_STYLE (0)
-#define SPFC_QUEUE_RING_STYLE (1)
-
-#define SPFC_NEED_DO_OFFLOAD (1)
-#define SPFC_QID_SQ (0)
-
-/*
- *SCQ defines
- */
-struct spfc_scq_info {
- struct cqm_queue *cqm_scq_info;
- u32 wqe_num_per_buf;
- u32 wqe_size;
- u32 scqc_cq_depth; /* 0-256, 1-512, 2-1k, 3-2k, 4-4k, 5-8k, 6-16k, 7-32k */
- u16 scqc_ci_type;
- u16 valid_wqe_num; /* ScQ depth include link wqe */
- u16 ci;
- u16 ci_owner;
- u32 queue_id;
- u32 scqn;
- char irq_name[SPFC_IRQ_NAME_MAX];
- u16 msix_entry_idx;
- u32 irq_id;
- struct tasklet_struct tasklet;
- atomic_t flush_stat;
- void *hba;
- u32 reserved;
- struct task_struct *delay_task;
- bool task_exit;
- u32 intr_mode;
-};
-
-struct spfc_srq_ctx {
- /* DW0 */
- u64 pcie_template : 6;
- u64 rsvd0 : 2;
- u64 parity : 8;
- u64 cur_rqe_usr_id : 16;
- u64 cur_rqe_msn : 16;
- u64 last_rq_pmsn : 16;
-
- /* DW1 */
- u64 cur_rqe_gpa;
-
- /* DW2 */
- u64 ctrl_sl : 1;
- u64 cf : 1;
- u64 csl : 2;
- u64 cr : 1;
- u64 bdsl : 4;
- u64 pmsn_type : 1;
- u64 cur_wqe_o : 1;
- u64 consant_sge_len : 17;
- u64 cur_sge_id : 4;
- u64 cur_sge_remain_len : 17;
- u64 ceqn_msix : 11;
- u64 int_mode : 2;
- u64 cur_sge_l : 1;
- u64 cur_sge_v : 1;
-
- /* DW3 */
- u64 cur_sge_gpa;
-
- /* DW4 */
- u64 cur_pmsn_gpa;
-
- /* DW5 */
- u64 rsvd3 : 5;
- u64 ring : 1;
- u64 loop_o : 1;
- u64 rsvd2 : 1;
- u64 rqe_dma_attr_idx : 6;
- u64 rq_so_ro : 2;
- u64 cqe_dma_attr_idx : 6;
- u64 cq_so_ro : 2;
- u64 rsvd1 : 7;
- u64 arm_q : 1;
- u64 cur_cqe_cnt : 8;
- u64 cqe_max_cnt : 8;
- u64 prefetch_max_masn : 16;
-
- /* DW6~DW7 */
- u64 rsvd4;
- u64 rsvd5;
-};
-
-struct spfc_drq_buff_entry {
- u16 buff_id;
- void *buff_addr;
- dma_addr_t buff_dma;
-};
-
-enum spfc_clean_state { SPFC_CLEAN_DONE, SPFC_CLEAN_DOING, SPFC_CLEAN_BUTT };
-enum spfc_srq_type { SPFC_SRQ_ELS = 1, SPFC_SRQ_IMMI, SPFC_SRQ_BUTT };
-
-struct spfc_srq_info {
- enum spfc_srq_type srq_type;
-
- struct cqm_queue *cqm_srq_info;
- u32 wqe_num_per_buf; /* Wqe number per buf, dont't inlcude link wqe */
- u32 wqe_size;
- u32 valid_wqe_num; /* valid wqe number, dont't include link wqe */
- u16 pi;
- u16 pi_owner;
- u16 pmsn;
- u16 ci;
- u16 cmsn;
- u32 srqn;
-
- dma_addr_t first_rqe_recv_dma;
-
- struct spfc_drq_buff_entry *els_buff_entry_head;
- struct buf_describe buf_list;
- spinlock_t srq_spin_lock;
- bool spin_lock_init;
- bool enable;
- enum spfc_clean_state state;
-
- atomic_t ref;
-
- struct delayed_work del_work;
- u32 del_retry_time;
- void *hba;
-};
-
-/*
- * The doorbell record keeps PI of WQE, which will be produced next time.
- * The PI is 15 bits width o-bit
- */
-struct db_record {
- u64 pmsn : 16;
- u64 dump_pmsn : 16;
- u64 rsvd0 : 32;
-};
-
-/*
- * The ci record keeps CI of WQE, which will be consumed next time.
- * The ci is 15 bits width with 1 o-bit
- */
-struct ci_record {
- u64 cmsn : 16;
- u64 dump_cmsn : 16;
- u64 rsvd0 : 32;
-};
-
-/* The accumulate data in WQ header */
-struct accumulate {
- u64 data_2_uc;
- u64 data_2_drv;
-};
-
-/* The WQ header structure */
-struct wq_header {
- struct db_record db_record;
- struct ci_record ci_record;
- struct accumulate soft_data;
-};
-
-/* Link list Sq WqePage Pool */
-/* queue header struct */
-struct spfc_queue_header {
- u64 door_bell_record;
- u64 ci_record;
- u64 rsv1;
- u64 rsv2;
-};
-
-/* WPG-WQEPAGE, LLSQ-LINKED LIST SQ */
-struct spfc_wqe_page {
- struct list_head entry_wpg;
-
- /* Wqe Page virtual addr */
- void *wpg_addr;
-
- /* Wqe Page physical addr */
- u64 wpg_phy_addr;
-};
-
-struct spfc_sq_wqepage_pool {
- u32 wpg_cnt;
- u32 wpg_size;
- u32 wqe_per_wpg;
-
- /* PCI DMA Pool */
- struct dma_pool *wpg_dma_pool;
- struct spfc_wqe_page *wpg_pool_addr;
- struct list_head list_free_wpg_pool;
- spinlock_t wpg_pool_lock;
- atomic_t wpg_in_use;
-};
-
-#define SPFC_SQ_DEL_STAGE_TIMEOUT_MS (3 * 1000)
-#define SPFC_SRQ_DEL_STAGE_TIMEOUT_MS (10 * 1000)
-#define SPFC_SQ_WAIT_FLUSH_DONE_TIMEOUT_MS (10 * 1000)
-#define SPFC_SQ_WAIT_FLUSH_DONE_TIMEOUT_CNT (3)
-
-#define SPFC_SRQ_PROCESS_DELAY_MS (20)
-
-/* PLOGI parameters */
-struct spfc_plogi_copram {
- u32 seq_cnt : 1;
- u32 ed_tov : 1;
- u32 rsvd : 14;
- u32 tx_mfs : 16;
- u32 ed_tov_time;
-};
-
-struct spfc_delay_sqe_ctrl_info {
- bool valid;
- u32 rport_index;
- u32 time_out;
- u64 start_jiff;
- u32 sid;
- u32 did;
- u32 xid;
- u16 ssqn;
- struct spfc_sqe sqe;
-};
-
-struct spfc_suspend_sqe_info {
- void *hba;
- u32 magic_num;
- u8 old_offload_sts;
- struct unf_frame_pkg pkg;
- struct spfc_sqe sqe;
- struct delayed_work timeout_work;
- struct list_head list_sqe_entry;
-};
-
-struct spfc_delay_destroy_ctrl_info {
- bool valid;
- u32 rport_index;
- u32 time_out;
- u64 start_jiff;
- struct unf_port_info rport_info;
-};
-
-/* PARENT SQ Info */
-struct spfc_parent_sq_info {
- void *hba;
- spinlock_t parent_sq_enqueue_lock;
- u32 rport_index;
- u32 context_id;
- /* Fixed value,used for Doorbell */
- u32 sq_queue_id;
- /* When a session is offloaded, tile will return the CacheId to the
- * driver,which is used for Doorbell
- */
- u32 cache_id;
- /* service type, fc or fc */
- u32 service_type;
- /* OQID */
- u16 oqid_rd;
- u16 oqid_wr;
- u32 local_port_id;
- u32 remote_port_id;
- u32 sqn_base;
- bool port_in_flush;
- bool sq_in_sess_rst;
- atomic_t sq_valid;
- /* Used by NPIV QoS */
- u8 vport_id;
- /* Used by NPIV QoS */
- u8 cs_ctrl;
- struct delayed_work del_work;
- struct delayed_work flush_done_timeout_work;
- u64 del_start_jiff;
- dma_addr_t srq_ctx_addr;
- atomic_t sq_cached;
- atomic_t flush_done_wait_cnt;
- struct spfc_plogi_copram plogi_co_parms;
- /* dif control info for immi */
- struct unf_dif_control_info sirt_dif_control;
- struct spfc_delay_sqe_ctrl_info delay_sqe;
- struct spfc_delay_destroy_ctrl_info destroy_sqe;
- struct list_head suspend_sqe_list;
- atomic_t io_stat[SPFC_MAX_SQ_TASK_TYPE_CNT];
- u8 need_offloaded;
-};
-
-/* parent context doorbell */
-struct spfc_parent_sq_db {
- struct {
- u32 xid : 20;
- u32 cntx_size : 2;
- u32 arm : 1;
- u32 c : 1;
- u32 cos : 3;
- u32 service_type : 5;
- } wd0;
-
- struct {
- u32 pi_hi : 8;
- u32 sm_data : 20;
- u32 qid : 4;
- } wd1;
-};
-
-#define IWARP_FC_DDB_TYPE 3
-
-/* direct wqe doorbell */
-struct spfc_direct_wqe_db {
- struct {
- u32 xid : 20;
- u32 cntx_size : 2;
- u32 pi_hi : 4;
- u32 c : 1;
- u32 cos : 3;
- u32 ddb : 2;
- } wd0;
-
- struct {
- u32 pi_lo : 12;
- u32 sm_data : 20;
- } wd1;
-};
-
-struct spfc_parent_cmd_scq_info {
- u32 cqm_queue_id;
- u32 local_queue_id;
-};
-
-struct spfc_parent_st_scq_info {
- u32 cqm_queue_id;
- u32 local_queue_id;
-};
-
-struct spfc_parent_els_srq_info {
- u32 cqm_queue_id;
- u32 local_queue_id;
-};
-
-enum spfc_parent_queue_state {
- SPFC_QUEUE_STATE_INITIALIZED = 0,
- SPFC_QUEUE_STATE_OFFLOADING = 1,
- SPFC_QUEUE_STATE_OFFLOADED = 2,
- SPFC_QUEUE_STATE_DESTROYING = 3,
- SPFC_QUEUE_STATE_FREE = 4,
- SPFC_QUEUE_STATE_BUTT
-};
-
-struct spfc_parent_ctx {
- dma_addr_t parent_ctx_addr;
- void *parent_ctx;
- struct cqm_qpc_mpt *cqm_parent_ctx_obj;
-};
-
-struct spfc_parent_queue_info {
- spinlock_t parent_queue_state_lock;
- struct spfc_parent_ctx parent_ctx;
- enum spfc_parent_queue_state offload_state;
- struct spfc_parent_sq_info parent_sq_info;
- struct spfc_parent_cmd_scq_info parent_cmd_scq_info;
- struct spfc_parent_st_scq_info
- parent_sts_scq_info;
- struct spfc_parent_els_srq_info parent_els_srq_info;
- u8 queue_vport_id;
- u8 queue_data_cos;
-};
-
-struct spfc_parent_ssq_info {
- void *hba;
- spinlock_t parent_sq_enqueue_lock;
- atomic_t wqe_page_cnt;
- u32 context_id;
- u32 cache_id;
- u32 sq_queue_id;
- u32 sqn;
- u32 service_type;
- u32 max_sqe_num; /* SQ depth */
- u32 wqe_num_per_buf;
- u32 wqe_size;
- u32 accum_wqe_cnt;
- u32 wqe_offset;
- u16 head_start_cmsn;
- u16 head_end_cmsn;
- u16 last_pmsn;
- u16 last_pi_owner;
- u32 queue_style;
- atomic_t sq_valid;
- void *queue_head_original;
- struct spfc_queue_header *queue_header;
- dma_addr_t queue_hdr_phy_addr_original;
- dma_addr_t queue_hdr_phy_addr;
- struct list_head list_linked_list_sq;
- atomic_t sq_db_cnt;
- atomic_t sq_wqe_cnt;
- atomic_t sq_cqe_cnt;
- atomic_t sqe_minus_cqe_cnt;
- atomic_t io_stat[SPFC_MAX_SQ_TASK_TYPE_CNT];
-};
-
-struct spfc_parent_shared_queue_info {
- struct spfc_parent_ctx parent_ctx;
- struct spfc_parent_ssq_info parent_ssq_info;
-};
-
-struct spfc_parent_queue_mgr {
- struct spfc_parent_queue_info parent_queue[UNF_SPFC_MAXRPORT_NUM];
- struct spfc_parent_shared_queue_info shared_queue[SPFC_MAX_SSQ_NUM];
- struct buf_describe parent_sq_buf_list;
-};
-
-#define SPFC_SRQC_BUS_ROW 8
-#define SPFC_SRQC_BUS_COL 19
-#define SPFC_SQC_BUS_ROW 8
-#define SPFC_SQC_BUS_COL 13
-#define SPFC_HW_SCQC_BUS_ROW 6
-#define SPFC_HW_SCQC_BUS_COL 10
-#define SPFC_HW_SRQC_BUS_ROW 4
-#define SPFC_HW_SRQC_BUS_COL 15
-#define SPFC_SCQC_BUS_ROW 3
-#define SPFC_SCQC_BUS_COL 29
-
-#define SPFC_QUEUE_INFO_BUS_NUM 4
-struct spfc_queue_info_bus {
- u64 bus[SPFC_QUEUE_INFO_BUS_NUM];
-};
-
-u32 spfc_free_parent_resource(void *handle, struct unf_port_info *rport_info);
-u32 spfc_alloc_parent_resource(void *handle, struct unf_port_info *rport_info);
-u32 spfc_alloc_parent_queue_mgr(void *handle);
-void spfc_free_parent_queue_mgr(void *handle);
-u32 spfc_create_common_share_queues(void *handle);
-u32 spfc_create_ssq(void *handle);
-void spfc_destroy_common_share_queues(void *v_pstHba);
-u32 spfc_alloc_parent_sq_wqe_page_pool(void *handle);
-void spfc_free_parent_sq_wqe_page_pool(void *handle);
-struct spfc_parent_queue_info *
-spfc_find_parent_queue_info_by_pkg(void *handle, struct unf_frame_pkg *pkg);
-struct spfc_parent_sq_info *
-spfc_find_parent_sq_by_pkg(void *handle, struct unf_frame_pkg *pkg);
-u32 spfc_root_cmdq_enqueue(void *handle, union spfc_cmdqe *cmdqe, u16 cmd_len);
-void spfc_process_scq_cqe(ulong scq_info);
-u32 spfc_process_scq_cqe_entity(ulong scq_info, u32 proc_cnt);
-void spfc_post_els_srq_wqe(struct spfc_srq_info *srq_info, u16 buf_id);
-void spfc_process_aeqe(void *handle, u8 event_type, u8 *event_val);
-u32 spfc_parent_sq_enqueue(struct spfc_parent_sq_info *sq, struct spfc_sqe *io_sqe,
- u16 ssqn);
-u32 spfc_parent_ssq_enqueue(struct spfc_parent_ssq_info *ssq,
- struct spfc_sqe *io_sqe, u8 wqe_type);
-void spfc_free_sq_wqe_page(struct spfc_parent_ssq_info *ssq, u32 cur_cmsn);
-u32 spfc_reclaim_sq_wqe_page(void *handle, union spfc_scqe *scqe);
-void spfc_set_rport_flush_state(void *handle, bool in_flush);
-u32 spfc_clear_fetched_sq_wqe(void *handle);
-u32 spfc_clear_pending_sq_wqe(void *handle);
-void spfc_free_parent_queues(void *handle);
-void spfc_free_ssq(void *handle, u32 free_sq_num);
-void spfc_enalbe_queues_dispatch(void *handle);
-void spfc_queue_pre_process(void *handle, bool clean);
-void spfc_queue_post_process(void *handle);
-void spfc_free_parent_queue_info(void *handle, struct spfc_parent_queue_info *parent_queue_info);
-u32 spfc_send_session_rst_cmd(void *handle,
- struct spfc_parent_queue_info *parent_queue_info,
- enum spfc_session_reset_mode mode);
-u32 spfc_send_nop_cmd(void *handle, struct spfc_parent_sq_info *parent_sq_info,
- u32 magic_num, u16 sqn);
-void spfc_build_session_rst_wqe(void *handle, struct spfc_parent_sq_info *sq,
- struct spfc_sqe *sqe,
- enum spfc_session_reset_mode mode, u32 scqn);
-void spfc_wq_destroy_els_srq(struct work_struct *work);
-void spfc_destroy_els_srq(void *handle);
-u32 spfc_push_delay_sqe(void *hba,
- struct spfc_parent_queue_info *offload_parent_queue,
- struct spfc_sqe *sqe, struct unf_frame_pkg *pkg);
-void spfc_push_destroy_parent_queue_sqe(void *hba,
- struct spfc_parent_queue_info *offloading_parent_queue,
- struct unf_port_info *rport_info);
-void spfc_pop_destroy_parent_queue_sqe(void *handle,
- struct spfc_delay_destroy_ctrl_info *destroy_sqe_info);
-struct spfc_parent_queue_info *spfc_find_offload_parent_queue(void *handle,
- u32 local_id,
- u32 remote_id,
- u32 rport_index);
-u32 spfc_flush_ini_resp_queue(void *handle);
-void spfc_rcvd_els_from_srq_timeout(struct work_struct *work);
-u32 spfc_send_aeq_info_via_cmdq(void *hba, u32 aeq_error_type);
-u32 spfc_parent_sq_ring_doorbell(struct spfc_parent_ssq_info *sq, u8 qos_level,
- u32 c);
-void spfc_sess_resource_free_sync(void *handle,
- struct unf_port_info *rport_info);
-u32 spfc_suspend_sqe_and_send_nop(void *handle,
- struct spfc_parent_queue_info *parent_queue,
- struct spfc_sqe *sqe, struct unf_frame_pkg *pkg);
-u32 spfc_pop_suspend_sqe(void *handle,
- struct spfc_parent_queue_info *parent_queue,
- struct spfc_suspend_sqe_info *suspen_sqe);
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_service.c b/drivers/scsi/spfc/hw/spfc_service.c
deleted file mode 100644
index 1da58e3f9fbe..000000000000
--- a/drivers/scsi/spfc/hw/spfc_service.c
+++ /dev/null
@@ -1,2170 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "spfc_service.h"
-#include "unf_log.h"
-#include "spfc_io.h"
-#include "spfc_chipitf.h"
-
-#define SPFC_ELS_SRQ_BUF_NUM (0x9)
-#define SPFC_LS_GS_USERID_LEN ((FC_LS_GS_USERID_CNT_MAX + 1) / 2)
-
-struct unf_scqe_handle_table {
- u32 scqe_type; /* ELS type */
- bool reclaim_sq_wpg;
- u32 (*scqe_handle_func)(struct spfc_hba_info *hba, union spfc_scqe *scqe);
-};
-
-static u32 spfc_get_els_rsp_pld_len(u16 els_type, u16 els_cmnd,
- u32 *els_acc_pld_len)
-{
- u32 ret = RETURN_OK;
-
- FC_CHECK_RETURN_VALUE(els_acc_pld_len, UNF_RETURN_ERROR);
-
- /* RJT */
- if (els_type == ELS_RJT) {
- *els_acc_pld_len = UNF_ELS_ACC_RJT_LEN;
- return RETURN_OK;
- }
-
- /* ACC */
- switch (els_cmnd) {
- /* uses the same PAYLOAD length as PLOGI. */
- case ELS_FLOGI:
- case ELS_PDISC:
- case ELS_PLOGI:
- *els_acc_pld_len = UNF_PLOGI_ACC_PAYLOAD_LEN;
- break;
-
- case ELS_PRLI:
- /* If sirt is enabled, The PRLI ACC payload extends 12 bytes */
- *els_acc_pld_len = (UNF_PRLI_ACC_PAYLOAD_LEN - UNF_PRLI_SIRT_EXTRA_SIZE);
-
- break;
-
- case ELS_LOGO:
- *els_acc_pld_len = UNF_LOGO_ACC_PAYLOAD_LEN;
- break;
-
- case ELS_PRLO:
- *els_acc_pld_len = UNF_PRLO_ACC_PAYLOAD_LEN;
- break;
-
- case ELS_RSCN:
- *els_acc_pld_len = UNF_RSCN_ACC_PAYLOAD_LEN;
- break;
-
- case ELS_ADISC:
- *els_acc_pld_len = UNF_ADISC_ACC_PAYLOAD_LEN;
- break;
-
- case ELS_RRQ:
- *els_acc_pld_len = UNF_RRQ_ACC_PAYLOAD_LEN;
- break;
-
- case ELS_SCR:
- *els_acc_pld_len = UNF_SCR_RSP_PAYLOAD_LEN;
- break;
-
- case ELS_ECHO:
- *els_acc_pld_len = UNF_ECHO_ACC_PAYLOAD_LEN;
- break;
-
- case ELS_REC:
- *els_acc_pld_len = UNF_REC_ACC_PAYLOAD_LEN;
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_WARN, "[warn]Unknown ELS command(0x%x)",
- els_cmnd);
- ret = UNF_RETURN_ERROR;
- break;
- }
-
- return ret;
-}
-
-struct unf_els_cmd_paylod_table {
- u16 els_cmnd; /* ELS type */
- u32 els_req_pld_len;
- u32 els_rsp_pld_len;
-};
-
-static const struct unf_els_cmd_paylod_table els_pld_table_map[] = {
- {ELS_FDISC, UNF_FDISC_PAYLOAD_LEN, UNF_FDISC_ACC_PAYLOAD_LEN},
- {ELS_FLOGI, UNF_FLOGI_PAYLOAD_LEN, UNF_FLOGI_ACC_PAYLOAD_LEN},
- {ELS_PLOGI, UNF_PLOGI_PAYLOAD_LEN, UNF_PLOGI_ACC_PAYLOAD_LEN},
- {ELS_SCR, UNF_SCR_PAYLOAD_LEN, UNF_SCR_RSP_PAYLOAD_LEN},
- {ELS_PDISC, UNF_PDISC_PAYLOAD_LEN, UNF_PDISC_ACC_PAYLOAD_LEN},
- {ELS_LOGO, UNF_LOGO_PAYLOAD_LEN, UNF_LOGO_ACC_PAYLOAD_LEN},
- {ELS_PRLO, UNF_PRLO_PAYLOAD_LEN, UNF_PRLO_ACC_PAYLOAD_LEN},
- {ELS_ADISC, UNF_ADISC_PAYLOAD_LEN, UNF_ADISC_ACC_PAYLOAD_LEN},
- {ELS_RRQ, UNF_RRQ_PAYLOAD_LEN, UNF_RRQ_ACC_PAYLOAD_LEN},
- {ELS_RSCN, 0, UNF_RSCN_ACC_PAYLOAD_LEN},
- {ELS_ECHO, UNF_ECHO_PAYLOAD_LEN, UNF_ECHO_ACC_PAYLOAD_LEN},
- {ELS_REC, UNF_REC_PAYLOAD_LEN, UNF_REC_ACC_PAYLOAD_LEN}
-};
-
-static u32 spfc_get_els_req_acc_pld_len(u16 els_cmnd, u32 *req_pld_len, u32 *rsp_pld_len)
-{
- u32 ret = RETURN_OK;
- u32 i;
-
- FC_CHECK_RETURN_VALUE(req_pld_len, UNF_RETURN_ERROR);
-
- for (i = 0; i < (sizeof(els_pld_table_map) /
- sizeof(struct unf_els_cmd_paylod_table));
- i++) {
- if (els_pld_table_map[i].els_cmnd == els_cmnd) {
- *req_pld_len = els_pld_table_map[i].els_req_pld_len;
- *rsp_pld_len = els_pld_table_map[i].els_rsp_pld_len;
- return ret;
- }
- }
-
- switch (els_cmnd) {
- case ELS_PRLI:
- /* If sirt is enabled, The PRLI ACC payload extends 12 bytes */
- *req_pld_len = SPFC_GET_PRLI_PAYLOAD_LEN;
- *rsp_pld_len = SPFC_GET_PRLI_PAYLOAD_LEN;
-
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Unknown ELS_CMD(0x%x)", els_cmnd);
- ret = UNF_RETURN_ERROR;
- break;
- }
-
- return ret;
-}
-
-static u32 spfc_check_parent_qinfo_valid(struct spfc_hba_info *hba, struct unf_frame_pkg *pkg,
- struct spfc_parent_queue_info **prt_qinfo)
-{
- if (!*prt_qinfo) {
- if (pkg->type == UNF_PKG_ELS_REQ || pkg->type == UNF_PKG_ELS_REPLY) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send LS SID(0x%x) DID(0x%x) with null prtqinfo",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
- pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX] = SPFC_DEFAULT_RPORT_INDEX;
- *prt_qinfo = spfc_find_parent_queue_info_by_pkg(hba, pkg);
- if (!*prt_qinfo)
- return UNF_RETURN_ERROR;
- } else {
- return UNF_RETURN_ERROR;
- }
- }
-
- if (pkg->type == UNF_PKG_GS_REQ && SPFC_RPORT_NOT_OFFLOADED(*prt_qinfo)) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[info]Port(0x%x) send GS SID(0x%x) DID(0x%x), send GS Request before PLOGI",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
- return UNF_RETURN_ERROR;
- }
- return RETURN_OK;
-}
-
-static void spfc_get_pkt_cmnd_type_code(struct unf_frame_pkg *pkg,
- u16 *ls_gs_cmnd_code,
- u16 *ls_gs_cmnd_type)
-{
- *ls_gs_cmnd_type = SPFC_GET_LS_GS_CMND_CODE(pkg->cmnd);
- if (SPFC_PKG_IS_ELS_RSP(*ls_gs_cmnd_type)) {
- *ls_gs_cmnd_code = SPFC_GET_ELS_RSP_CODE(pkg->cmnd);
- } else if (pkg->type == UNF_PKG_GS_REQ) {
- *ls_gs_cmnd_code = *ls_gs_cmnd_type;
- } else {
- *ls_gs_cmnd_code = *ls_gs_cmnd_type;
- *ls_gs_cmnd_type = ELS_CMND;
- }
-}
-
-static u32 spfc_get_gs_req_rsp_pld_len(u16 cmnd_code, u32 *gs_pld_len, u32 *gs_rsp_pld_len)
-{
- FC_CHECK_RETURN_VALUE(gs_pld_len, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(gs_rsp_pld_len, UNF_RETURN_ERROR);
-
- switch (cmnd_code) {
- case NS_GPN_ID:
- *gs_pld_len = UNF_GPNID_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_GPNID_RSP_PAYLOAD_LEN;
- break;
-
- case NS_GNN_ID:
- *gs_pld_len = UNF_GNNID_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_GNNID_RSP_PAYLOAD_LEN;
- break;
-
- case NS_GFF_ID:
- *gs_pld_len = UNF_GFFID_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_GFFID_RSP_PAYLOAD_LEN;
- break;
-
- case NS_GID_FT:
- case NS_GID_PT:
- *gs_pld_len = UNF_GID_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_GID_ACC_PAYLOAD_LEN;
- break;
-
- case NS_RFT_ID:
- *gs_pld_len = UNF_RFTID_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_RFTID_RSP_PAYLOAD_LEN;
- break;
-
- case NS_RFF_ID:
- *gs_pld_len = UNF_RFFID_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_RFFID_RSP_PAYLOAD_LEN;
- break;
- case NS_GA_NXT:
- *gs_pld_len = UNF_GID_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_GID_ACC_PAYLOAD_LEN;
- break;
-
- case NS_GIEL:
- *gs_pld_len = UNF_RFTID_RSP_PAYLOAD_LEN;
- *gs_rsp_pld_len = UNF_GID_ACC_PAYLOAD_LEN;
- break;
-
- default:
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Unknown GS commond type(0x%x)", cmnd_code);
- return UNF_RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-static void *spfc_get_els_frame_addr(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg,
- u16 els_cmnd_code, u16 els_cmnd_type,
- u64 *phy_addr)
-{
- void *frame_pld_addr = NULL;
- dma_addr_t els_frame_addr = 0;
-
- if (els_cmnd_code == ELS_ECHO) {
- frame_pld_addr = (void *)UNF_GET_ECHO_PAYLOAD(pkg);
- els_frame_addr = UNF_GET_ECHO_PAYLOAD_PHYADDR(pkg);
- } else if (els_cmnd_code == ELS_RSCN) {
- if (els_cmnd_type == ELS_CMND) {
- /* Not Support */
- frame_pld_addr = NULL;
- els_frame_addr = 0;
- } else {
- frame_pld_addr = (void *)UNF_GET_RSCN_ACC_PAYLOAD(pkg);
- els_frame_addr = pkg->unf_cmnd_pload_bl.buf_dma_addr +
- sizeof(struct unf_fc_head);
- }
- } else {
- frame_pld_addr = (void *)SPFC_GET_CMND_PAYLOAD_ADDR(pkg);
- els_frame_addr = pkg->unf_cmnd_pload_bl.buf_dma_addr +
- sizeof(struct unf_fc_head);
- }
- *phy_addr = els_frame_addr;
- return frame_pld_addr;
-}
-
-static u32 spfc_get_frame_info(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, void **frame_pld_addr,
- u32 *frame_pld_len, u64 *frame_phy_addr,
- u32 *acc_pld_len)
-{
- u32 ret = RETURN_OK;
- u16 ls_gs_cmnd_code = SPFC_ZERO;
- u16 ls_gs_cmnd_type = SPFC_ZERO;
-
- spfc_get_pkt_cmnd_type_code(pkg, &ls_gs_cmnd_code, &ls_gs_cmnd_type);
-
- if (pkg->type == UNF_PKG_GS_REQ) {
- ret = spfc_get_gs_req_rsp_pld_len(ls_gs_cmnd_code,
- frame_pld_len, acc_pld_len);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) send GS SID(0x%x) DID(0x%x), get error GS request and response payload length",
- hba->port_cfg.port_id,
- pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
-
- return ret;
- }
- *frame_pld_addr = (void *)(SPFC_GET_CMND_PAYLOAD_ADDR(pkg));
- *frame_phy_addr = pkg->unf_cmnd_pload_bl.buf_dma_addr + sizeof(struct unf_fc_head);
- if (ls_gs_cmnd_code == NS_GID_FT || ls_gs_cmnd_code == NS_GID_PT)
- *frame_pld_addr = (void *)(UNF_GET_GID_PAYLOAD(pkg));
- } else {
- *frame_pld_addr = spfc_get_els_frame_addr(hba, pkg, ls_gs_cmnd_code,
- ls_gs_cmnd_type, frame_phy_addr);
- if (SPFC_PKG_IS_ELS_RSP(ls_gs_cmnd_type)) {
- ret = spfc_get_els_rsp_pld_len(ls_gs_cmnd_type, ls_gs_cmnd_code,
- frame_pld_len);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) get els cmd (0x%x) rsp len failed.",
- hba->port_cfg.port_id,
- ls_gs_cmnd_code);
- return ret;
- }
- } else {
- ret = spfc_get_els_req_acc_pld_len(ls_gs_cmnd_code, frame_pld_len,
- acc_pld_len);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) get els cmd (0x%x) req and acc len failed.",
- hba->port_cfg.port_id,
- ls_gs_cmnd_code);
- return ret;
- }
- }
- }
- return ret;
-}
-
-static u32
-spfc_send_ls_gs_via_parent(struct spfc_hba_info *hba, struct unf_frame_pkg *pkg,
- struct spfc_parent_queue_info *prt_queue_info)
-{
- u32 ret = UNF_RETURN_ERROR;
- u16 ls_gs_cmnd_code = SPFC_ZERO;
- u16 ls_gs_cmnd_type = SPFC_ZERO;
- u16 remote_exid = 0;
- u16 hot_tag = 0;
- struct spfc_parent_sq_info *parent_sq_info = NULL;
- struct spfc_sqe tmp_sqe;
- struct spfc_sqe *sqe = NULL;
- void *frame_pld_addr = NULL;
- u32 frame_pld_len = 0;
- u32 acc_pld_len = 0;
- u64 frame_pa = 0;
- ulong flags = 0;
- u16 ssqn = 0;
- spinlock_t *prtq_state_lock = NULL;
-
- ssqn = (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
- sqe = &tmp_sqe;
- memset(sqe, 0, sizeof(struct spfc_sqe));
-
- parent_sq_info = &prt_queue_info->parent_sq_info;
- hot_tag = (u16)UNF_GET_HOTPOOL_TAG(pkg) + hba->exi_base;
-
- spfc_get_pkt_cmnd_type_code(pkg, &ls_gs_cmnd_code, &ls_gs_cmnd_type);
-
- ret = spfc_get_frame_info(hba, pkg, &frame_pld_addr, &frame_pld_len,
- &frame_pa, &acc_pld_len);
- if (ret != RETURN_OK)
- return ret;
-
- if (SPFC_PKG_IS_ELS_RSP(ls_gs_cmnd_type)) {
- remote_exid = UNF_GET_OXID(pkg);
- spfc_build_els_wqe_ts_rsp(sqe, prt_queue_info, pkg,
- frame_pld_addr, ls_gs_cmnd_type,
- ls_gs_cmnd_code);
-
- /* Assemble the SQE Task Section Els Common part */
- spfc_build_service_wqe_ts_common(&sqe->ts_sl, parent_sq_info->rport_index,
- UNF_GET_RXID(pkg), remote_exid,
- SPFC_LSW(frame_pld_len));
- } else {
- remote_exid = UNF_GET_RXID(pkg);
- /* send els req ,only use local_xid for hotpooltag */
- spfc_build_els_wqe_ts_req(sqe, parent_sq_info,
- prt_queue_info->parent_sts_scq_info.cqm_queue_id,
- frame_pld_addr, pkg);
- spfc_build_service_wqe_ts_common(&sqe->ts_sl, parent_sq_info->rport_index, hot_tag,
- remote_exid, SPFC_LSW(frame_pld_len));
- }
- /* Assemble the SQE Control Section part */
- spfc_build_service_wqe_ctrl_section(&sqe->ctrl_sl, SPFC_BYTES_TO_QW_NUM(SPFC_SQE_TS_SIZE),
- SPFC_BYTES_TO_QW_NUM(sizeof(struct spfc_variable_sge)));
-
- /* Build SGE */
- spfc_build_els_gs_wqe_sge(sqe, frame_pld_addr, frame_pa, frame_pld_len,
- parent_sq_info->context_id, hba);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) RPort(0x%x) send ELS/GS Type(0x%x) Code(0x%x) HotTag(0x%x)",
- hba->port_cfg.port_id, parent_sq_info->rport_index, ls_gs_cmnd_type,
- ls_gs_cmnd_code, hot_tag);
- if (ls_gs_cmnd_code == ELS_PLOGI || ls_gs_cmnd_code == ELS_LOGO) {
- ret = spfc_suspend_sqe_and_send_nop(hba, prt_queue_info, sqe, pkg);
- return ret;
- }
- prtq_state_lock = &prt_queue_info->parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flags);
- if (SPFC_RPORT_NOT_OFFLOADED(prt_queue_info)) {
- spin_unlock_irqrestore(prtq_state_lock, flags);
- /* Send PLOGI or PLOGI ACC or SCR if session not offload */
- ret = spfc_send_els_via_default_session(hba, sqe, pkg, prt_queue_info);
- } else {
- spin_unlock_irqrestore(prtq_state_lock, flags);
- ret = spfc_parent_sq_enqueue(parent_sq_info, sqe, ssqn);
- }
-
- return ret;
-}
-
-u32 spfc_send_ls_gs_cmnd(void *handle, struct unf_frame_pkg *pkg)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_hba_info *hba = NULL;
- struct spfc_parent_queue_info *prt_qinfo = NULL;
- u16 ls_gs_cmnd_code = SPFC_ZERO;
- union unf_sfs_u *sfs_entry = NULL;
- struct unf_rrq *rrq_pld = NULL;
- u16 ox_id = 0;
- u16 rx_id = 0;
-
- /* Check Parameters */
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(UNF_GET_SFS_ENTRY(pkg), UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(SPFC_GET_CMND_PAYLOAD_ADDR(pkg), UNF_RETURN_ERROR);
-
- SPFC_CHECK_PKG_ALLOCTIME(pkg);
- hba = (struct spfc_hba_info *)handle;
- ls_gs_cmnd_code = SPFC_GET_LS_GS_CMND_CODE(pkg->cmnd);
-
- /* If RRQ Req, Special processing */
- if (ls_gs_cmnd_code == ELS_RRQ) {
- sfs_entry = UNF_GET_SFS_ENTRY(pkg);
- rrq_pld = &sfs_entry->rrq;
- ox_id = (u16)(rrq_pld->oxid_rxid >> UNF_SHIFT_16);
- rx_id = (u16)(rrq_pld->oxid_rxid & SPFC_RXID_MASK);
- rrq_pld->oxid_rxid = (u32)ox_id << UNF_SHIFT_16 | rx_id;
- }
-
- prt_qinfo = spfc_find_parent_queue_info_by_pkg(hba, pkg);
- ret = spfc_check_parent_qinfo_valid(hba, pkg, &prt_qinfo);
-
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_MAJOR,
- "[error]Port(0x%x) send ELS/GS SID(0x%x) DID(0x%x) check qinfo invalid",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
- return UNF_RETURN_ERROR;
- }
-
- ret = spfc_send_ls_gs_via_parent(hba, pkg, prt_qinfo);
-
- return ret;
-}
-
-void spfc_save_login_parms_in_sq_info(struct spfc_hba_info *hba,
- struct unf_port_login_parms *login_params)
-{
- u32 rport_index = login_params->rport_index;
- struct spfc_parent_sq_info *parent_sq_info = NULL;
-
- if (rport_index >= UNF_SPFC_MAXRPORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[err]Port(0x%x) save login parms,but uplevel alloc invalid rport index: 0x%x",
- hba->port_cfg.port_id, rport_index);
-
- return;
- }
-
- parent_sq_info = &hba->parent_queue_mgr->parent_queue[rport_index].parent_sq_info;
-
- parent_sq_info->plogi_co_parms.seq_cnt = login_params->seq_cnt;
- parent_sq_info->plogi_co_parms.ed_tov = login_params->ed_tov;
- parent_sq_info->plogi_co_parms.tx_mfs = (login_params->tx_mfs <
- SPFC_DEFAULT_TX_MAX_FREAM_SIZE) ?
- SPFC_DEFAULT_TX_MAX_FREAM_SIZE :
- login_params->tx_mfs;
- parent_sq_info->plogi_co_parms.ed_tov_time = login_params->ed_tov_timer_val;
-}
-
-static void
-spfc_recover_offloading_state(struct spfc_parent_queue_info *prt_queue_info,
- enum spfc_parent_queue_state offload_state)
-{
- ulong flags = 0;
-
- spin_lock_irqsave(&prt_queue_info->parent_queue_state_lock, flags);
-
- if (prt_queue_info->offload_state == SPFC_QUEUE_STATE_OFFLOADING)
- prt_queue_info->offload_state = offload_state;
-
- spin_unlock_irqrestore(&prt_queue_info->parent_queue_state_lock, flags);
-}
-
-static bool spfc_check_need_delay_offload(void *hba, struct unf_frame_pkg *pkg, u32 rport_index,
- struct spfc_parent_queue_info *cur_prt_queue_info,
- struct spfc_parent_queue_info **offload_prt_queue_info)
-{
- ulong flags = 0;
- struct spfc_parent_queue_info *prt_queue_info = NULL;
- spinlock_t *prtq_state_lock = NULL;
-
- prtq_state_lock = &cur_prt_queue_info->parent_queue_state_lock;
- spin_lock_irqsave(prtq_state_lock, flags);
-
- if (cur_prt_queue_info->offload_state == SPFC_QUEUE_STATE_OFFLOADING) {
- spin_unlock_irqrestore(prtq_state_lock, flags);
-
- prt_queue_info = spfc_find_offload_parent_queue(hba, pkg->frame_head.csctl_sid &
- UNF_NPORTID_MASK,
- pkg->frame_head.rctl_did &
- UNF_NPORTID_MASK, rport_index);
- if (prt_queue_info) {
- *offload_prt_queue_info = prt_queue_info;
- return true;
- }
- } else {
- spin_unlock_irqrestore(prtq_state_lock, flags);
- }
-
- return false;
-}
-
-static u16 spfc_build_wqe_with_offload(struct spfc_hba_info *hba, struct spfc_sqe *sqe,
- struct spfc_parent_queue_info *prt_queue_info,
- struct unf_frame_pkg *pkg,
- enum spfc_parent_queue_state last_offload_state)
-{
- u32 tx_mfs = 2048;
- u32 edtov_timer = 2000;
- dma_addr_t ctx_pa = 0;
- u16 els_cmnd_type = SPFC_ZERO;
- u16 els_cmnd_code = SPFC_ZERO;
- void *ctx_va = NULL;
- struct spfc_parent_context *parent_ctx_info = NULL;
- struct spfc_sw_section *sw_setction = NULL;
- struct spfc_parent_sq_info *parent_sq_info = &prt_queue_info->parent_sq_info;
- u16 offload_flag = 0;
-
- els_cmnd_type = SPFC_GET_ELS_RSP_TYPE(pkg->cmnd);
- if (SPFC_PKG_IS_ELS_RSP(els_cmnd_type)) {
- els_cmnd_code = SPFC_GET_ELS_RSP_CODE(pkg->cmnd);
- } else {
- els_cmnd_code = els_cmnd_type;
- els_cmnd_type = ELS_CMND;
- }
-
- offload_flag = SPFC_CHECK_NEED_OFFLOAD(els_cmnd_code, els_cmnd_type, last_offload_state);
-
- parent_ctx_info = (struct spfc_parent_context *)(prt_queue_info->parent_ctx.parent_ctx);
- sw_setction = &parent_ctx_info->sw_section;
-
- sw_setction->tx_mfs = cpu_to_be16((u16)(tx_mfs));
- sw_setction->e_d_tov_timer_val = cpu_to_be32(edtov_timer);
-
- spfc_big_to_cpu32(&sw_setction->sw_ctxt_misc.pctxt_val0,
- sizeof(sw_setction->sw_ctxt_misc.pctxt_val0));
- sw_setction->sw_ctxt_misc.dw.port_id = SPFC_GET_NETWORK_PORT_ID(hba);
- spfc_cpu_to_big32(&sw_setction->sw_ctxt_misc.pctxt_val0,
- sizeof(sw_setction->sw_ctxt_misc.pctxt_val0));
-
- spfc_big_to_cpu32(&sw_setction->sw_ctxt_config.pctxt_val1,
- sizeof(sw_setction->sw_ctxt_config.pctxt_val1));
- spfc_cpu_to_big32(&sw_setction->sw_ctxt_config.pctxt_val1,
- sizeof(sw_setction->sw_ctxt_config.pctxt_val1));
-
- /* Fill in contex to the chip */
- ctx_pa = prt_queue_info->parent_ctx.cqm_parent_ctx_obj->paddr;
- ctx_va = prt_queue_info->parent_ctx.cqm_parent_ctx_obj->vaddr;
-
- /* No need write key and no need do BIG TO CPU32 */
- memcpy(ctx_va, prt_queue_info->parent_ctx.parent_ctx, sizeof(struct spfc_parent_context));
-
- if (SPFC_PKG_IS_ELS_RSP(els_cmnd_type)) {
- sqe->ts_sl.cont.els_rsp.context_gpa_hi = SPFC_HIGH_32_BITS(ctx_pa);
- sqe->ts_sl.cont.els_rsp.context_gpa_lo = SPFC_LOW_32_BITS(ctx_pa);
- sqe->ts_sl.cont.els_rsp.wd1.offload_flag = offload_flag;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]sid 0x%x, did 0x%x, GPA HIGH 0x%x,GPA LOW 0x%x, scq 0x%x,offload flag 0x%x",
- parent_sq_info->local_port_id,
- parent_sq_info->remote_port_id,
- sqe->ts_sl.cont.els_rsp.context_gpa_hi,
- sqe->ts_sl.cont.els_rsp.context_gpa_lo,
- prt_queue_info->parent_sts_scq_info.cqm_queue_id,
- offload_flag);
- } else {
- sqe->ts_sl.cont.t_els_gs.context_gpa_hi = SPFC_HIGH_32_BITS(ctx_pa);
- sqe->ts_sl.cont.t_els_gs.context_gpa_lo = SPFC_LOW_32_BITS(ctx_pa);
- sqe->ts_sl.cont.t_els_gs.wd4.offload_flag = offload_flag;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]sid 0x%x, did 0x%x, GPA HIGH 0x%x,GPA LOW 0x%x, scq 0x%x,offload flag 0x%x",
- parent_sq_info->local_port_id,
- parent_sq_info->remote_port_id,
- sqe->ts_sl.cont.t_els_gs.context_gpa_hi,
- sqe->ts_sl.cont.t_els_gs.context_gpa_lo,
- prt_queue_info->parent_sts_scq_info.cqm_queue_id,
- offload_flag);
- }
-
- if (offload_flag) {
- prt_queue_info->offload_state = SPFC_QUEUE_STATE_OFFLOADING;
- parent_sq_info->need_offloaded = SPFC_NEED_DO_OFFLOAD;
- }
-
- return offload_flag;
-}
-
-u32 spfc_send_els_via_default_session(struct spfc_hba_info *hba, struct spfc_sqe *io_sqe,
- struct unf_frame_pkg *pkg,
- struct spfc_parent_queue_info *prt_queue_info)
-{
- ulong flags = 0;
- bool sqe_delay = false;
- u32 ret = UNF_RETURN_ERROR;
- u16 els_cmnd_code = SPFC_ZERO;
- u16 els_cmnd_type = SPFC_ZERO;
- u16 ssqn = (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
- u32 rport_index = pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX];
- struct spfc_sqe *sqe = io_sqe;
- struct spfc_parent_queue_info *default_prt_queue_info = NULL;
- struct spfc_parent_sq_info *parent_sq_info = &prt_queue_info->parent_sq_info;
- struct spfc_parent_queue_info *offload_queue_info = NULL;
- enum spfc_parent_queue_state last_offload_state = SPFC_QUEUE_STATE_INITIALIZED;
- struct spfc_delay_destroy_ctrl_info delay_ctl_info;
- u16 offload_flag = 0;
- u32 default_index = SPFC_DEFAULT_RPORT_INDEX;
-
- memset(&delay_ctl_info, 0, sizeof(struct spfc_delay_destroy_ctrl_info));
- /* Determine the ELS type in pkg */
- els_cmnd_type = SPFC_GET_LS_GS_CMND_CODE(pkg->cmnd);
-
- if (SPFC_PKG_IS_ELS_RSP(els_cmnd_type)) {
- els_cmnd_code = SPFC_GET_ELS_RSP_CODE(pkg->cmnd);
- } else {
- els_cmnd_code = els_cmnd_type;
- els_cmnd_type = ELS_CMND;
- }
-
- spin_lock_irqsave(&prt_queue_info->parent_queue_state_lock, flags);
-
- last_offload_state = prt_queue_info->offload_state;
-
- offload_flag = spfc_build_wqe_with_offload(hba, sqe, prt_queue_info,
- pkg, last_offload_state);
-
- spin_unlock_irqrestore(&prt_queue_info->parent_queue_state_lock, flags);
-
- if (!offload_flag) {
- default_prt_queue_info = &hba->parent_queue_mgr->parent_queue[default_index];
- if (!default_prt_queue_info) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_ERR,
- "[ERR]cmd(0x%x), type(0x%x) send fail, default session null",
- els_cmnd_code, els_cmnd_type);
- return UNF_RETURN_ERROR;
- }
- parent_sq_info = &default_prt_queue_info->parent_sq_info;
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]cmd(0x%x), type(0x%x) send via default session",
- els_cmnd_code, els_cmnd_type);
- } else {
- /* Need this xid to judge delay offload, when Sqe Enqueue will
- * write again
- */
- sqe->ts_sl.xid = parent_sq_info->context_id;
- sqe_delay = spfc_check_need_delay_offload(hba, pkg, rport_index, prt_queue_info,
- &offload_queue_info);
-
- if (sqe_delay) {
- ret = spfc_push_delay_sqe(hba, offload_queue_info, sqe, pkg);
- if (ret == RETURN_OK) {
- spfc_recover_offloading_state(prt_queue_info, last_offload_state);
- return ret;
- }
- }
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_INFO,
- "[info]cmd(0x%x), type(0x%x) do secretly offload",
- els_cmnd_code, els_cmnd_type);
- }
-
- ret = spfc_parent_sq_enqueue(parent_sq_info, sqe, ssqn);
-
- if (ret != RETURN_OK) {
- spfc_recover_offloading_state(prt_queue_info, last_offload_state);
-
- spin_lock_irqsave(&prt_queue_info->parent_queue_state_lock,
- flags);
-
- if (prt_queue_info->parent_sq_info.destroy_sqe.valid) {
- memcpy(&delay_ctl_info, &prt_queue_info->parent_sq_info.destroy_sqe,
- sizeof(struct spfc_delay_destroy_ctrl_info));
-
- prt_queue_info->parent_sq_info.destroy_sqe.valid = false;
- }
-
- spin_unlock_irqrestore(&prt_queue_info->parent_queue_state_lock, flags);
-
- spfc_pop_destroy_parent_queue_sqe((void *)hba, &delay_ctl_info);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_WARN,
- "[warn]Port(0x%x) RPort(0x%x) send ELS Type(0x%x) Code(0x%x) fail,recover offloadstatus(%u)",
- hba->port_cfg.port_id, rport_index, els_cmnd_type,
- els_cmnd_code, prt_queue_info->offload_state);
- }
-
- return ret;
-}
-
-static u32 spfc_rcv_ls_gs_rsp_payload(struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 hot_tag,
- u8 *els_pld_buf, u32 pld_len)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = hot_tag;
- if (pkg->type == UNF_PKG_GS_REQ_DONE)
- spfc_big_to_cpu32(els_pld_buf, pld_len);
- else
- pkg->byte_orders |= SPFC_BIT_2;
-
- pkg->unf_cmnd_pload_bl.buffer_ptr = els_pld_buf;
- pkg->unf_cmnd_pload_bl.length = pld_len;
-
- pkg->last_pkg_flag = UNF_PKG_NOT_LAST_RESPONSE;
-
- UNF_LOWLEVEL_RECEIVE_LS_GS_PKG(ret, hba->lport, pkg);
-
- return ret;
-}
-
-u32 spfc_scq_recv_abts_rsp(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- /* Default path, which is sent from SCQ to the driver */
- u8 status = 0;
- u32 ret = UNF_RETURN_ERROR;
- u32 ox_id = INVALID_VALUE32;
- u32 hot_tag = INVALID_VALUE32;
- struct unf_frame_pkg pkg = {0};
- struct spfc_scqe_rcv_abts_rsp *abts_rsp = NULL;
-
- abts_rsp = &scqe->rcv_abts_rsp;
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = abts_rsp->magic_num;
-
- ox_id = (u32)(abts_rsp->wd0.ox_id);
-
- hot_tag = abts_rsp->wd1.hotpooltag;
- if (unlikely(hot_tag < (u32)hba->exi_base ||
- hot_tag >= (u32)(hba->exi_base + hba->exi_count))) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) has bad HotTag(0x%x) for bls_rsp",
- hba->port_cfg.port_id, hot_tag);
-
- status = UNF_IO_FAILED;
- hot_tag = INVALID_VALUE32;
- } else {
- hot_tag -= hba->exi_base;
- if (unlikely(SPFC_SCQE_HAS_ERRCODE(scqe))) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) BLS response has error code(0x%x) tag(0x%x)",
- hba->port_cfg.port_id,
- SPFC_GET_SCQE_STATUS(scqe), (u32)hot_tag);
-
- status = UNF_IO_FAILED;
- } else {
- pkg.frame_head.rctl_did = abts_rsp->wd3.did;
- pkg.frame_head.csctl_sid = abts_rsp->wd4.sid;
- pkg.frame_head.oxid_rxid = (u32)(abts_rsp->wd0.rx_id) | ox_id <<
- UNF_SHIFT_16;
-
- /* BLS_ACC/BLS_RJT: IO_succeed */
- if (abts_rsp->wd2.fh_rctrl == SPFC_RCTL_BLS_ACC) {
- status = UNF_IO_SUCCESS;
- } else if (abts_rsp->wd2.fh_rctrl == SPFC_RCTL_BLS_RJT) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) ABTS RJT: %08x-%08x-%08x",
- hba->port_cfg.port_id,
- abts_rsp->payload[ARRAY_INDEX_0],
- abts_rsp->payload[ARRAY_INDEX_1],
- abts_rsp->payload[ARRAY_INDEX_2]);
-
- status = UNF_IO_SUCCESS;
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) BLS response RCTL is error",
- hba->port_cfg.port_id);
- SPFC_ERR_IO_STAT(hba, SPFC_SCQE_ABTS_RSP);
- status = UNF_IO_FAILED;
- }
- }
- }
-
- /* Set PKG/exchange status & Process BLS_RSP */
- pkg.status = status;
- ret = spfc_rcv_bls_rsp(hba, &pkg, hot_tag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) recv ABTS rsp OX_ID(0x%x) RX_ID(0x%x) HotTag(0x%x) SID(0x%x) DID(0x%x) %s",
- hba->port_cfg.port_id, ox_id, abts_rsp->wd0.rx_id, hot_tag,
- abts_rsp->wd4.sid, abts_rsp->wd3.did,
- (ret == RETURN_OK) ? "OK" : "ERROR");
-
- return ret;
-}
-
-u32 spfc_recv_els_cmnd(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u8 *els_pld, u32 pld_len,
- bool first)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- /* Convert Payload to small endian */
- spfc_big_to_cpu32(els_pld, pld_len);
-
- pkg->type = UNF_PKG_ELS_REQ;
-
- pkg->unf_cmnd_pload_bl.buffer_ptr = els_pld;
-
- /* Payload length */
- pkg->unf_cmnd_pload_bl.length = pld_len;
-
- /* Obtain the Cmnd type from the Paylaod. The Cmnd is in small endian */
- if (first)
- pkg->cmnd = UNF_GET_FC_PAYLOAD_ELS_CMND(pkg->unf_cmnd_pload_bl.buffer_ptr);
-
- /* Errors have been processed in SPFC_RecvElsError */
- pkg->status = UNF_IO_SUCCESS;
-
- /* Send PKG to the CM layer */
- UNF_LOWLEVEL_RECEIVE_LS_GS_PKG(ret, hba->lport, pkg);
-
- if (ret != RETURN_OK) {
- pkg->rx_or_ox_id = UNF_PKG_FREE_RXID;
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = INVALID_VALUE32;
- pkg->private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = INVALID_VALUE32;
- ret = spfc_free_xid((void *)hba, pkg);
-
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) recv %s ox_id(0x%x) RXID(0x%x) PldLen(0x%x) failed, Free xid %s",
- hba->port_cfg.port_id,
- UNF_GET_FC_HEADER_RCTL(&pkg->frame_head) == SPFC_FC_RCTL_ELS_REQ ?
- "ELS REQ" : "ELS RSP",
- UNF_GET_OXID(pkg), UNF_GET_RXID(pkg), pld_len,
- (ret == RETURN_OK) ? "OK" : "ERROR");
- }
-
- return ret;
-}
-
-u32 spfc_rcv_ls_gs_rsp(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 hot_tag)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = hot_tag;
- if (pkg->type == UNF_PKG_ELS_REQ_DONE)
- pkg->byte_orders |= SPFC_BIT_2;
-
- pkg->last_pkg_flag = UNF_PKG_LAST_RESPONSE;
-
- UNF_LOWLEVEL_RECEIVE_LS_GS_PKG(ret, hba->lport, pkg);
-
- return ret;
-}
-
-u32 spfc_rcv_els_rsp_sts(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 hot_tag)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- pkg->type = UNF_PKG_ELS_REPLY_DONE;
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = hot_tag;
-
- UNF_LOWLEVEL_SEND_ELS_DONE(ret, hba->lport, pkg);
-
- return ret;
-}
-
-u32 spfc_rcv_bls_rsp(const struct spfc_hba_info *hba, struct unf_frame_pkg *pkg,
- u32 hot_tag)
-{
- /*
- * 1. SCQ (normal)
- * 2. from Root RQ (parent no existence)
- * *
- * single frame, single sequence
- */
- u32 ret = UNF_RETURN_ERROR;
-
- pkg->type = UNF_PKG_BLS_REQ_DONE;
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = hot_tag;
- pkg->last_pkg_flag = UNF_PKG_LAST_RESPONSE;
-
- UNF_LOWLEVEL_RECEIVE_BLS_PKG(ret, hba->lport, pkg);
-
- return ret;
-}
-
-u32 spfc_rsv_bls_rsp_sts(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 rx_id)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- pkg->type = UNF_PKG_BLS_REPLY_DONE;
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = rx_id;
-
- UNF_LOWLEVEL_RECEIVE_BLS_PKG(ret, hba->lport, pkg);
-
- return ret;
-}
-
-u32 spfc_rcv_tmf_marker_sts(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 hot_tag)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = hot_tag;
-
- /* Send PKG info to COM */
- UNF_LOWLEVEL_RECEIVE_MARKER_STS(ret, hba->lport, pkg);
-
- return ret;
-}
-
-u32 spfc_rcv_abts_marker_sts(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 hot_tag)
-{
- u32 ret = UNF_RETURN_ERROR;
-
- pkg->private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = hot_tag;
-
- UNF_LOWLEVEL_RECEIVE_ABTS_MARKER_STS(ret, hba->lport, pkg);
-
- return ret;
-}
-
-static void spfc_scqe_error_pre_proc(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- /* Currently, only printing and statistics collection are performed */
- SPFC_ERR_IO_STAT(hba, SPFC_GET_SCQE_TYPE(scqe));
- SPFC_SCQ_ERR_TYPE_STAT(hba, SPFC_GET_SCQE_STATUS(scqe));
-
- FC_DRV_PRINT(UNF_LOG_ABNORMAL, UNF_WARN,
- "[warn]Port(0x%x)-Task_type(%u) SCQE contain error code(%u),additional info(0x%x)",
- hba->port_cfg.port_id, scqe->common.ch.wd0.task_type,
- scqe->common.ch.wd0.err_code, scqe->common.conn_id);
-}
-
-void *spfc_get_els_buf_by_user_id(struct spfc_hba_info *hba, u16 user_id)
-{
- struct spfc_drq_buff_entry *srq_buf_entry = NULL;
- struct spfc_srq_info *srq_info = NULL;
-
- FC_CHECK_RETURN_VALUE(hba, NULL);
-
- srq_info = &hba->els_srq_info;
- FC_CHECK_RETURN_VALUE(user_id < srq_info->valid_wqe_num, NULL);
-
- srq_buf_entry = &srq_info->els_buff_entry_head[user_id];
-
- return srq_buf_entry->buff_addr;
-}
-
-static u32 spfc_check_srq_buf_valid(struct spfc_hba_info *hba,
- u16 *buf_id_array, u32 buf_num)
-{
- u32 index = 0;
- u32 buf_id = 0;
- void *srq_buf = NULL;
-
- for (index = 0; index < buf_num; index++) {
- buf_id = buf_id_array[index];
-
- if (buf_id < hba->els_srq_info.valid_wqe_num)
- srq_buf = spfc_get_els_buf_by_user_id(hba, (u16)buf_id);
- else
- srq_buf = NULL;
-
- if (!srq_buf) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) get srq buffer user id(0x%x) is null",
- hba->port_cfg.port_id, buf_id);
-
- return UNF_RETURN_ERROR;
- }
- }
-
- return RETURN_OK;
-}
-
-static void spfc_reclaim_srq_buf(struct spfc_hba_info *hba, u16 *buf_id_array,
- u32 buf_num)
-{
- u32 index = 0;
- u32 buf_id = 0;
- void *srq_buf = NULL;
-
- for (index = 0; index < buf_num; index++) {
- buf_id = buf_id_array[index];
- if (buf_id < hba->els_srq_info.valid_wqe_num)
- srq_buf = spfc_get_els_buf_by_user_id(hba, (u16)buf_id);
- else
- srq_buf = NULL;
-
- /* If the value of buffer is NULL, it indicates that the value
- * of buffer is invalid. In this case, exit directly.
- */
- if (!srq_buf)
- break;
-
- spfc_post_els_srq_wqe(&hba->els_srq_info, (u16)buf_id);
- }
-}
-
-static u32 spfc_check_ls_gs_valid(struct spfc_hba_info *hba, union spfc_scqe *scqe,
- struct unf_frame_pkg *pkg, u16 *buf_id_array,
- u32 buf_num, u32 frame_len)
-{
- u32 hot_tag;
-
- hot_tag = UNF_GET_HOTPOOL_TAG(pkg);
-
- /* The ELS CMD returns an error code and discards it directly */
- if ((sizeof(struct spfc_fc_frame_header) > frame_len) ||
- (SPFC_SCQE_HAS_ERRCODE(scqe)) || buf_num > SPFC_ELS_SRQ_BUF_NUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) get scqe type(0x%x) payload len(0x%x),scq status(0x%x),user id num(0x%x) abnormal",
- hba->port_cfg.port_id, SPFC_GET_SCQE_TYPE(scqe), frame_len,
- SPFC_GET_SCQE_STATUS(scqe), buf_num);
-
- /* ELS RSP Special Processing */
- if (SPFC_GET_SCQE_TYPE(scqe) == SPFC_SCQE_ELS_RSP ||
- SPFC_GET_SCQE_TYPE(scqe) == SPFC_SCQE_GS_RSP) {
- if (SPFC_SCQE_ERR_TO_CM(scqe)) {
- pkg->status = UNF_IO_FAILED;
- (void)spfc_rcv_ls_gs_rsp(hba, pkg, hot_tag);
- } else {
- if (SPFC_GET_SCQE_TYPE(scqe) == SPFC_SCQE_ELS_RSP)
- SPFC_HBA_STAT(hba, SPFC_STAT_ELS_RSP_EXCH_REUSE);
- else
- SPFC_HBA_STAT(hba, SPFC_STAT_GS_RSP_EXCH_REUSE);
- }
- }
-
- /* Reclaim srq */
- if (buf_num <= SPFC_ELS_SRQ_BUF_NUM)
- spfc_reclaim_srq_buf(hba, buf_id_array, buf_num);
-
- return UNF_RETURN_ERROR;
- }
-
- /* ELS CMD Check the validity of the buffer sent by the ucode */
- if (SPFC_GET_SCQE_TYPE(scqe) == SPFC_SCQE_ELS_CMND) {
- if (spfc_check_srq_buf_valid(hba, buf_id_array, buf_num) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) get els cmnd scqe user id num(0x%x) abnormal, as some srq buff is null",
- hba->port_cfg.port_id, buf_num);
-
- spfc_reclaim_srq_buf(hba, buf_id_array, buf_num);
-
- return UNF_RETURN_ERROR;
- }
- }
-
- return RETURN_OK;
-}
-
-u32 spfc_scq_recv_els_cmnd(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 ret = RETURN_OK;
- u32 pld_len = 0;
- u32 header_len = 0;
- u32 frame_len = 0;
- u32 rcv_data_len = 0;
- u32 max_buf_num = 0;
- u16 buf_id = 0;
- u32 index = 0;
- u8 *pld_addr = NULL;
- struct unf_frame_pkg pkg = {0};
- struct spfc_scqe_rcv_els_cmd *els_cmd = NULL;
- struct spfc_fc_frame_header *els_frame = NULL;
- struct spfc_fc_frame_header tmp_frame = {0};
- void *els_buf = NULL;
- bool first = false;
-
- els_cmd = &scqe->rcv_els_cmd;
- frame_len = els_cmd->wd3.data_len;
- max_buf_num = els_cmd->wd3.user_id_num;
- spfc_swap_16_in_32((u32 *)els_cmd->user_id, SPFC_LS_GS_USERID_LEN);
-
- pkg.xchg_contex = NULL;
- pkg.status = UNF_IO_SUCCESS;
-
- /* Check the validity of error codes and buff. If an exception occurs,
- * discard the error code
- */
- ret = spfc_check_ls_gs_valid(hba, scqe, &pkg, els_cmd->user_id,
- max_buf_num, frame_len);
- if (ret != RETURN_OK) {
- pkg.rx_or_ox_id = UNF_PKG_FREE_RXID;
- pkg.frame_head.oxid_rxid =
- (u32)(els_cmd->wd2.rx_id) | (u32)(els_cmd->wd2.ox_id) << UNF_SHIFT_16;
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = INVALID_VALUE32;
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = INVALID_VALUE32;
- pkg.frame_head.csctl_sid = els_cmd->wd1.sid;
- pkg.frame_head.rctl_did = els_cmd->wd0.did;
- spfc_free_xid((void *)hba, &pkg);
- return RETURN_OK;
- }
-
- /* Send data to COM cyclically */
- for (index = 0; index < max_buf_num; index++) {
- /* Exception record, which is not processed currently */
- if (rcv_data_len >= frame_len) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) get els cmd date len(0x%x) is bigger than fream len(0x%x)",
- hba->port_cfg.port_id, rcv_data_len, frame_len);
- }
-
- buf_id = (u16)els_cmd->user_id[index];
- els_buf = spfc_get_els_buf_by_user_id(hba, buf_id);
-
- /* Obtain playload address */
- pld_addr = (u8 *)(els_buf);
- header_len = 0;
- first = false;
- if (index == 0) {
- els_frame = (struct spfc_fc_frame_header *)els_buf;
- pld_addr = (u8 *)(els_frame + 1);
-
- header_len = sizeof(struct spfc_fc_frame_header);
- first = true;
-
- memcpy(&tmp_frame, els_frame, sizeof(struct spfc_fc_frame_header));
- spfc_big_to_cpu32(&tmp_frame, sizeof(struct spfc_fc_frame_header));
- memcpy(&pkg.frame_head, &tmp_frame, sizeof(pkg.frame_head));
- pkg.frame_head.oxid_rxid = (u32)((pkg.frame_head.oxid_rxid &
- SPFC_OXID_MASK) | (els_cmd->wd2.rx_id));
- }
-
- /* Calculate the playload length */
- pkg.last_pkg_flag = 0;
- pld_len = SPFC_SRQ_ELS_SGE_LEN;
-
- if ((rcv_data_len + SPFC_SRQ_ELS_SGE_LEN) >= frame_len) {
- pkg.last_pkg_flag = 1;
- pld_len = frame_len - rcv_data_len;
- }
-
- pkg.class_mode = els_cmd->wd0.class_mode;
-
- /* Push data to COM */
- if (ret == RETURN_OK) {
- ret = spfc_recv_els_cmnd(hba, &pkg, pld_addr,
- (pld_len - header_len), first);
- }
-
- /* Reclaim srq buffer */
- spfc_post_els_srq_wqe(&hba->els_srq_info, buf_id);
-
- rcv_data_len += pld_len;
- }
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) recv ELS Type(0x%x) Cmnd(0x%x) ox_id(0x%x) RXID(0x%x) SID(0x%x) DID(0x%x) %u",
- hba->port_cfg.port_id, pkg.type, pkg.cmnd, els_cmd->wd2.ox_id,
- els_cmd->wd2.rx_id, els_cmd->wd1.sid, els_cmd->wd0.did, ret);
-
- return ret;
-}
-
-static u32 spfc_get_ls_gs_pld_len(struct spfc_hba_info *hba, u32 rcv_data_len, u32 frame_len)
-{
- u32 pld_len;
-
- /* Exception record, which is not processed currently */
- if (rcv_data_len >= frame_len) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) get els rsp data len(0x%x) is bigger than fream len(0x%x)",
- hba->port_cfg.port_id, rcv_data_len, frame_len);
- }
-
- pld_len = SPFC_SRQ_ELS_SGE_LEN;
- if ((rcv_data_len + SPFC_SRQ_ELS_SGE_LEN) >= frame_len)
- pld_len = frame_len - rcv_data_len;
-
- return pld_len;
-}
-
-u32 spfc_scq_recv_ls_gs_rsp(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 ret = RETURN_OK;
- u32 pld_len = 0;
- u32 header_len = 0;
- u32 frame_len = 0;
- u32 rcv_data_len = 0;
- u32 max_buf_num = 0;
- u16 buf_id = 0;
- u32 hot_tag = INVALID_VALUE32;
- u32 index = 0;
- u32 ox_id = (~0);
- struct unf_frame_pkg pkg = {0};
- struct spfc_scqe_rcv_els_gs_rsp *ls_gs_rsp_scqe = NULL;
- struct spfc_fc_frame_header *els_frame = NULL;
- void *ls_gs_buf = NULL;
- u8 *pld_addr = NULL;
- u8 task_type;
-
- ls_gs_rsp_scqe = &scqe->rcv_els_gs_rsp;
- frame_len = ls_gs_rsp_scqe->wd2.data_len;
- max_buf_num = ls_gs_rsp_scqe->wd4.user_id_num;
- spfc_swap_16_in_32((u32 *)ls_gs_rsp_scqe->user_id, SPFC_LS_GS_USERID_LEN);
-
- ox_id = ls_gs_rsp_scqe->wd1.ox_id;
- hot_tag = ((u16)ls_gs_rsp_scqe->wd5.hotpooltag) - hba->exi_base;
- pkg.frame_head.oxid_rxid = (u32)(ls_gs_rsp_scqe->wd1.rx_id) | ox_id << UNF_SHIFT_16;
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = ls_gs_rsp_scqe->magic_num;
- pkg.private_data[PKG_PRIVATE_XCHG_HOT_POOL_INDEX] = hot_tag;
- pkg.frame_head.csctl_sid = ls_gs_rsp_scqe->wd4.sid;
- pkg.frame_head.rctl_did = ls_gs_rsp_scqe->wd3.did;
- pkg.status = UNF_IO_SUCCESS;
- pkg.type = UNF_PKG_ELS_REQ_DONE;
-
- task_type = SPFC_GET_SCQE_TYPE(scqe);
- if (task_type == SPFC_SCQE_GS_RSP) {
- if (ls_gs_rsp_scqe->wd3.end_rsp)
- SPFC_HBA_STAT(hba, SPFC_STAT_LAST_GS_SCQE);
- pkg.type = UNF_PKG_GS_REQ_DONE;
- }
-
- /* Handle the exception first. The LS/GS RSP returns the error code.
- * Only the ox_id can submit the error code to the CM layer.
- */
- ret = spfc_check_ls_gs_valid(hba, scqe, &pkg, ls_gs_rsp_scqe->user_id,
- max_buf_num, frame_len);
- if (ret != RETURN_OK)
- return RETURN_OK;
-
- if (ls_gs_rsp_scqe->wd3.echo_rsp) {
- pkg.private_data[PKG_PRIVATE_ECHO_CMD_RCV_TIME] =
- ls_gs_rsp_scqe->user_id[ARRAY_INDEX_5];
- pkg.private_data[PKG_PRIVATE_ECHO_RSP_SND_TIME] =
- ls_gs_rsp_scqe->user_id[ARRAY_INDEX_6];
- pkg.private_data[PKG_PRIVATE_ECHO_CMD_SND_TIME] =
- ls_gs_rsp_scqe->user_id[ARRAY_INDEX_7];
- pkg.private_data[PKG_PRIVATE_ECHO_ACC_RCV_TIME] =
- ls_gs_rsp_scqe->user_id[ARRAY_INDEX_8];
- }
-
- /* Send data to COM cyclically */
- for (index = 0; index < max_buf_num; index++) {
- /* Obtain buffer address */
- ls_gs_buf = NULL;
- buf_id = (u16)ls_gs_rsp_scqe->user_id[index];
- ls_gs_buf = spfc_get_els_buf_by_user_id(hba, buf_id);
-
- if (unlikely(!ls_gs_buf)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) ox_id(0x%x) RXID(0x%x) SID(0x%x) DID(0x%x) Index(0x%x) get els rsp buff user id(0x%x) abnormal",
- hba->port_cfg.port_id, ox_id,
- ls_gs_rsp_scqe->wd1.rx_id, ls_gs_rsp_scqe->wd4.sid,
- ls_gs_rsp_scqe->wd3.did, index, buf_id);
-
- if (index == 0) {
- pkg.status = UNF_IO_FAILED;
- ret = spfc_rcv_ls_gs_rsp(hba, &pkg, hot_tag);
- }
-
- return ret;
- }
-
- header_len = 0;
- pld_addr = (u8 *)(ls_gs_buf);
- if (index == 0) {
- header_len = sizeof(struct spfc_fc_frame_header);
- els_frame = (struct spfc_fc_frame_header *)ls_gs_buf;
- pld_addr = (u8 *)(els_frame + 1);
- }
-
- /* Calculate the playload length */
- pld_len = spfc_get_ls_gs_pld_len(hba, rcv_data_len, frame_len);
-
- /* Push data to COM */
- if (ret == RETURN_OK) {
- ret = spfc_rcv_ls_gs_rsp_payload(hba, &pkg, hot_tag, pld_addr,
- (pld_len - header_len));
- }
-
- /* Reclaim srq buffer */
- spfc_post_els_srq_wqe(&hba->els_srq_info, buf_id);
-
- rcv_data_len += pld_len;
- }
-
- if (ls_gs_rsp_scqe->wd3.end_rsp && ret == RETURN_OK)
- ret = spfc_rcv_ls_gs_rsp(hba, &pkg, hot_tag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) receive LS/GS RSP ox_id(0x%x) RXID(0x%x) SID(0x%x) DID(0x%x) end_rsp(0x%x) user_num(0x%x)",
- hba->port_cfg.port_id, ox_id, ls_gs_rsp_scqe->wd1.rx_id,
- ls_gs_rsp_scqe->wd4.sid, ls_gs_rsp_scqe->wd3.did,
- ls_gs_rsp_scqe->wd3.end_rsp,
- ls_gs_rsp_scqe->wd4.user_id_num);
-
- return ret;
-}
-
-u32 spfc_scq_recv_els_rsp_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 rx_id = INVALID_VALUE32;
- u32 hot_tag = INVALID_VALUE32;
- struct unf_frame_pkg pkg = {0};
- struct spfc_scqe_comm_rsp_sts *els_rsp_sts_scqe = NULL;
-
- els_rsp_sts_scqe = &scqe->comm_sts;
- rx_id = (u32)els_rsp_sts_scqe->wd0.rx_id;
-
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] =
- els_rsp_sts_scqe->magic_num;
- pkg.frame_head.oxid_rxid = rx_id | (u32)(els_rsp_sts_scqe->wd0.ox_id) << UNF_SHIFT_16;
- hot_tag = (u32)(els_rsp_sts_scqe->wd1.hotpooltag - hba->exi_base);
-
- if (unlikely(SPFC_SCQE_HAS_ERRCODE(scqe)))
- pkg.status = UNF_IO_FAILED;
- else
- pkg.status = UNF_IO_SUCCESS;
-
- ret = spfc_rcv_els_rsp_sts(hba, &pkg, hot_tag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) recv ELS RSP STS ox_id(0x%x) RXID(0x%x) HotTag(0x%x) %s",
- hba->port_cfg.port_id, els_rsp_sts_scqe->wd0.ox_id, rx_id,
- hot_tag, (ret == RETURN_OK) ? "OK" : "ERROR");
-
- return ret;
-}
-
-static u32 spfc_check_rport_valid(const struct spfc_parent_queue_info *prt_queue_info, u32 scqe_xid)
-{
- if (prt_queue_info->parent_ctx.cqm_parent_ctx_obj) {
- if ((prt_queue_info->parent_sq_info.context_id & SPFC_CQM_XID_MASK) ==
- (scqe_xid & SPFC_CQM_XID_MASK)) {
- return RETURN_OK;
- }
- }
-
- return UNF_RETURN_ERROR;
-}
-
-u32 spfc_scq_recv_offload_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 valid = UNF_RETURN_ERROR;
- u32 rport_index = 0;
- u32 cid = 0;
- u32 xid = 0;
- ulong flags = 0;
- struct spfc_parent_queue_info *prt_qinfo = NULL;
- struct spfc_parent_sq_info *parent_sq_info = NULL;
- struct spfc_scqe_sess_sts *offload_sts_scqe = NULL;
- struct spfc_delay_destroy_ctrl_info delay_ctl_info;
-
- memset(&delay_ctl_info, 0, sizeof(struct spfc_delay_destroy_ctrl_info));
- offload_sts_scqe = &scqe->sess_sts;
- rport_index = offload_sts_scqe->wd1.conn_id;
- cid = offload_sts_scqe->wd2.cid;
- xid = offload_sts_scqe->wd0.xid_qpn;
-
- if (rport_index >= UNF_SPFC_MAXRPORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) receive an error offload status: rport(0x%x) is invalid, cacheid(0x%x)",
- hba->port_cfg.port_id, rport_index, cid);
-
- return UNF_RETURN_ERROR;
- }
-
- if (rport_index == SPFC_DEFAULT_RPORT_INDEX &&
- hba->default_sq_info.default_sq_flag == 0xF) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) default session timeout: rport(0x%x) cacheid(0x%x)",
- hba->port_cfg.port_id, rport_index, cid);
- return UNF_RETURN_ERROR;
- }
-
- prt_qinfo = &hba->parent_queue_mgr->parent_queue[rport_index];
- parent_sq_info = &prt_qinfo->parent_sq_info;
-
- valid = spfc_check_rport_valid(prt_qinfo, xid);
- if (valid != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) receive an error offload status: rport(0x%x), context id(0x%x) is invalid",
- hba->port_cfg.port_id, rport_index, xid);
-
- return UNF_RETURN_ERROR;
- }
-
- /* Offload failed */
- if (SPFC_GET_SCQE_STATUS(scqe) != SPFC_COMPLETION_STATUS_SUCCESS) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x), rport(0x%x), context id(0x%x), cache id(0x%x), offload failed",
- hba->port_cfg.port_id, rport_index, xid, cid);
-
- spin_lock_irqsave(&prt_qinfo->parent_queue_state_lock, flags);
- if (prt_qinfo->offload_state != SPFC_QUEUE_STATE_OFFLOADED) {
- prt_qinfo->offload_state = SPFC_QUEUE_STATE_INITIALIZED;
- parent_sq_info->need_offloaded = INVALID_VALUE8;
- }
- spin_unlock_irqrestore(&prt_qinfo->parent_queue_state_lock,
- flags);
-
- return UNF_RETURN_ERROR;
- }
-
- spin_lock_irqsave(&prt_qinfo->parent_queue_state_lock, flags);
- prt_qinfo->parent_sq_info.cache_id = cid;
- prt_qinfo->offload_state = SPFC_QUEUE_STATE_OFFLOADED;
- parent_sq_info->need_offloaded = SPFC_HAVE_OFFLOAD;
- atomic_set(&prt_qinfo->parent_sq_info.sq_cached, true);
-
- if (prt_qinfo->parent_sq_info.destroy_sqe.valid) {
- delay_ctl_info.valid = prt_qinfo->parent_sq_info.destroy_sqe.valid;
- delay_ctl_info.rport_index = prt_qinfo->parent_sq_info.destroy_sqe.rport_index;
- delay_ctl_info.time_out = prt_qinfo->parent_sq_info.destroy_sqe.time_out;
- delay_ctl_info.start_jiff = prt_qinfo->parent_sq_info.destroy_sqe.start_jiff;
- delay_ctl_info.rport_info.nport_id =
- prt_qinfo->parent_sq_info.destroy_sqe.rport_info.nport_id;
- delay_ctl_info.rport_info.rport_index =
- prt_qinfo->parent_sq_info.destroy_sqe.rport_info.rport_index;
- delay_ctl_info.rport_info.port_name =
- prt_qinfo->parent_sq_info.destroy_sqe.rport_info.port_name;
- prt_qinfo->parent_sq_info.destroy_sqe.valid = false;
- }
- spin_unlock_irqrestore(&prt_qinfo->parent_queue_state_lock, flags);
-
- if (rport_index == SPFC_DEFAULT_RPORT_INDEX) {
- hba->default_sq_info.sq_cid = cid;
- hba->default_sq_info.sq_xid = xid;
- hba->default_sq_info.default_sq_flag = 1;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_MAJOR, "[info]Receive default Session info");
- }
-
- spfc_pop_destroy_parent_queue_sqe((void *)hba, &delay_ctl_info);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) offload success: rport index(0x%x),rport nportid(0x%x),context id(0x%x),cache id(0x%x).",
- hba->port_cfg.port_id, rport_index,
- prt_qinfo->parent_sq_info.remote_port_id, xid, cid);
-
- return RETURN_OK;
-}
-
-static u32 spfc_send_bls_via_parent(struct spfc_hba_info *hba, struct unf_frame_pkg *pkg)
-{
- u32 ret = UNF_RETURN_ERROR;
- u16 ox_id = INVALID_VALUE16;
- u16 rx_id = INVALID_VALUE16;
- struct spfc_sqe tmp_sqe;
- struct spfc_sqe *sqe = NULL;
- struct spfc_parent_sq_info *parent_sq_info = NULL;
- struct spfc_parent_queue_info *prt_qinfo = NULL;
- u16 ssqn;
-
- FC_CHECK_RETURN_VALUE((pkg->type == UNF_PKG_BLS_REQ), UNF_RETURN_ERROR);
-
- sqe = &tmp_sqe;
- memset(sqe, 0, sizeof(struct spfc_sqe));
-
- prt_qinfo = spfc_find_parent_queue_info_by_pkg(hba, pkg);
- if (!prt_qinfo) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send BLS SID_DID(0x%x_0x%x) with null parent queue information",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
-
- return ret;
- }
-
- parent_sq_info = spfc_find_parent_sq_by_pkg(hba, pkg);
- if (!parent_sq_info) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send ABTS SID_DID(0x%x_0x%x) with null parent queue information",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
-
- return ret;
- }
-
- rx_id = UNF_GET_RXID(pkg);
- ox_id = UNF_GET_OXID(pkg);
-
- /* Assemble the SQE Control Section part. The ABTS does not have
- * Payload. bdsl=0
- */
- spfc_build_service_wqe_ctrl_section(&sqe->ctrl_sl, SPFC_BYTES_TO_QW_NUM(SPFC_SQE_TS_SIZE),
- 0);
-
- /* Assemble the SQE Task Section BLS Common part. The value of DW2 of
- * BLS WQE is Rsvd, and the value of DW2 is 0
- */
- spfc_build_service_wqe_ts_common(&sqe->ts_sl, parent_sq_info->rport_index, ox_id, rx_id, 0);
-
- /* Assemble the special part of the ABTS */
- spfc_build_bls_wqe_ts_req(sqe, pkg, hba);
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) RPort(0x%x) send ABTS_REQ ox_id(0x%x) RXID(0x%x), HotTag(0x%x)",
- hba->port_cfg.port_id, parent_sq_info->rport_index, ox_id,
- rx_id, (u16)(UNF_GET_HOTPOOL_TAG(pkg) + hba->exi_base));
-
- ssqn = (u16)pkg->private_data[PKG_PRIVATE_XCHG_SSQ_INDEX];
- ret = spfc_parent_sq_enqueue(parent_sq_info, sqe, ssqn);
-
- return ret;
-}
-
-u32 spfc_send_bls_cmnd(void *handle, struct unf_frame_pkg *pkg)
-{
- u32 ret = UNF_RETURN_ERROR;
- struct spfc_hba_info *hba = NULL;
- ulong flags = 0;
- struct spfc_parent_queue_info *prt_qinfo = NULL;
-
- FC_CHECK_RETURN_VALUE(handle, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg->type == UNF_PKG_BLS_REQ || pkg->type == UNF_PKG_BLS_REPLY,
- UNF_RETURN_ERROR);
-
- SPFC_CHECK_PKG_ALLOCTIME(pkg);
- hba = (struct spfc_hba_info *)handle;
-
- prt_qinfo = spfc_find_parent_queue_info_by_pkg(hba, pkg);
- if (!prt_qinfo) {
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[warn]Port(0x%x) send BLS SID_DID(0x%x_0x%x) with null parent queue information",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
-
- return ret;
- }
-
- spin_lock_irqsave(&prt_qinfo->parent_queue_state_lock, flags);
-
- if (SPFC_RPORT_OFFLOADED(prt_qinfo)) {
- spin_unlock_irqrestore(&prt_qinfo->parent_queue_state_lock, flags);
- ret = spfc_send_bls_via_parent(hba, pkg);
- } else {
- spin_unlock_irqrestore(&prt_qinfo->parent_queue_state_lock, flags);
- FC_DRV_PRINT(UNF_LOG_IO_ATT, UNF_WARN,
- "[error]Port(0x%x) send BLS SID_DID(0x%x_0x%x) with no offloaded, do noting",
- hba->port_cfg.port_id, pkg->frame_head.csctl_sid,
- pkg->frame_head.rctl_did);
- }
-
- return ret;
-}
-
-static u32 spfc_scq_rcv_flush_sq_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- /*
- * RCVD sq flush sts
- * --->>> continue flush or clear done
- */
- u32 ret = UNF_RETURN_ERROR;
-
- if (scqe->flush_sts.wd0.port_id != hba->port_index) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_CRITICAL,
- "[err]Port(0x%x) clear_sts_port_idx(0x%x) not match hba_port_idx(0x%x), stage(0x%x)",
- hba->port_cfg.port_id, scqe->clear_sts.wd0.port_id,
- hba->port_index, hba->queue_set_stage);
-
- return UNF_RETURN_ERROR;
- }
-
- if (scqe->flush_sts.wd0.last_flush) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_INFO,
- "[info]Port(0x%x) flush sq(0x%x) done, stage(0x%x)",
- hba->port_cfg.port_id, hba->next_clear_sq, hba->queue_set_stage);
-
- /* If the Flush STS is last one, send cmd done */
- ret = spfc_clear_sq_wqe_done(hba);
- } else {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_MAJOR,
- "[info]Port(0x%x) continue flush sq(0x%x), stage(0x%x)",
- hba->port_cfg.port_id, hba->next_clear_sq, hba->queue_set_stage);
-
- ret = spfc_clear_pending_sq_wqe(hba);
- }
-
- return ret;
-}
-
-static u32 spfc_scq_rcv_buf_clear_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- /*
- * clear: fetched sq wqe
- * ---to--->>> pending sq wqe
- */
- u32 ret = UNF_RETURN_ERROR;
-
- if (scqe->clear_sts.wd0.port_id != hba->port_index) {
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_CRITICAL,
- "[err]Port(0x%x) clear_sts_port_idx(0x%x) not match hba_port_idx(0x%x), stage(0x%x)",
- hba->port_cfg.port_id, scqe->clear_sts.wd0.port_id,
- hba->port_index, hba->queue_set_stage);
-
- return UNF_RETURN_ERROR;
- }
-
- /* set port with I/O cleared state */
- spfc_set_hba_clear_state(hba, true);
-
- FC_DRV_PRINT(UNF_LOG_EVENT, UNF_KEVENT,
- "[info]Port(0x%x) cleared all fetched wqe, start clear sq pending wqe, stage (0x%x)",
- hba->port_cfg.port_id, hba->queue_set_stage);
-
- hba->queue_set_stage = SPFC_QUEUE_SET_STAGE_FLUSHING;
- ret = spfc_clear_pending_sq_wqe(hba);
-
- return ret;
-}
-
-u32 spfc_scq_recv_sess_rst_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 rport_index = INVALID_VALUE32;
- ulong flags = 0;
- struct spfc_parent_queue_info *parent_queue_info = NULL;
- struct spfc_scqe_sess_sts *sess_sts_scqe = (struct spfc_scqe_sess_sts *)(void *)scqe;
- u32 flush_done;
- u32 *ctx_array = NULL;
- int ret;
- spinlock_t *prtq_state_lock = NULL;
-
- rport_index = sess_sts_scqe->wd1.conn_id;
- if (rport_index >= UNF_SPFC_MAXRPORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) receive reset session cmd sts failed, invlaid rport(0x%x) status_code(0x%x) remain_cnt(0x%x)",
- hba->port_cfg.port_id, rport_index,
- sess_sts_scqe->ch.wd0.err_code,
- sess_sts_scqe->ch.wd0.cqe_remain_cnt);
-
- return UNF_RETURN_ERROR;
- }
-
- parent_queue_info = &hba->parent_queue_mgr->parent_queue[rport_index];
- prtq_state_lock = &parent_queue_info->parent_queue_state_lock;
- /*
- * If only session reset is used, the offload status of sq remains
- * unchanged. If a link is deleted, the offload status is set to
- * destroying and is irreversible.
- */
- spin_lock_irqsave(prtq_state_lock, flags);
-
- /*
- * According to the fault tolerance principle, even if the connection
- * deletion times out and the sts returns to delete the connection, one
- * indicates that the cancel timer is successful, and 0 indicates that
- * the timer is being processed.
- */
- if (!cancel_delayed_work(&parent_queue_info->parent_sq_info.del_work)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) rport_index(0x%x) delete rport timer maybe timeout",
- hba->port_cfg.port_id, rport_index);
- }
-
- /*
- * If the SessRstSts is returned too late and the Parent Queue Info
- * resource is released, OK is returned.
- */
- if (parent_queue_info->offload_state != SPFC_QUEUE_STATE_DESTROYING) {
- spin_unlock_irqrestore(prtq_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[info]Port(0x%x) reset session cmd complete, no need to free parent qinfo, rport(0x%x) status_code(0x%x) remain_cnt(0x%x)",
- hba->port_cfg.port_id, rport_index,
- sess_sts_scqe->ch.wd0.err_code,
- sess_sts_scqe->ch.wd0.cqe_remain_cnt);
-
- return RETURN_OK;
- }
-
- if (parent_queue_info->parent_ctx.cqm_parent_ctx_obj) {
- ctx_array = (u32 *)((void *)(parent_queue_info->parent_ctx
- .cqm_parent_ctx_obj->vaddr));
- flush_done = ctx_array[SPFC_CTXT_FLUSH_DONE_DW_POS] & SPFC_CTXT_FLUSH_DONE_MASK_BE;
- mb();
- if (flush_done == 0) {
- spin_unlock_irqrestore(prtq_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) rport(0x%x) flushdone is not set, delay to free parent session",
- hba->port_cfg.port_id, rport_index);
-
- /* If flushdone bit is not set,delay free Sq info */
- ret = queue_delayed_work(hba->work_queue,
- &(parent_queue_info->parent_sq_info
- .flush_done_timeout_work),
- (ulong)msecs_to_jiffies((u32)
- SPFC_SQ_WAIT_FLUSH_DONE_TIMEOUT_MS));
- if (!ret) {
- SPFC_HBA_STAT(hba, SPFC_STAT_PARENT_SQ_QUEUE_DELAYED_WORK);
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) rport(0x%x) queue delayed work failed ret:%d",
- hba->port_cfg.port_id, rport_index,
- ret);
- }
-
- return RETURN_OK;
- }
- }
-
- spin_unlock_irqrestore(prtq_state_lock, flags);
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) begin to free parent session with rport(0x%x)",
- hba->port_cfg.port_id, rport_index);
-
- spfc_free_parent_queue_info(hba, parent_queue_info);
-
- return RETURN_OK;
-}
-
-static u32 spfc_scq_rcv_clear_srq_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- /*
- * clear ELS/Immi SRQ
- * ---then--->>> Destroy SRQ
- */
- struct spfc_srq_info *srq_info = NULL;
-
- if (SPFC_GET_SCQE_STATUS(scqe) != 0) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) clear srq failed, status(0x%x)",
- hba->port_cfg.port_id, SPFC_GET_SCQE_STATUS(scqe));
-
- return RETURN_OK;
- }
-
- srq_info = &hba->els_srq_info;
-
- /*
- * 1: cancel timer succeed
- * 0: the timer is being processed, the SQ is released when the timer
- * times out
- */
- if (cancel_delayed_work(&srq_info->del_work))
- queue_work(hba->work_queue, &hba->els_srq_clear_work);
-
- return RETURN_OK;
-}
-
-u32 spfc_scq_recv_marker_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 ox_id = INVALID_VALUE32;
- u32 rx_id = INVALID_VALUE32;
- u32 hot_tag = INVALID_VALUE32;
- struct unf_frame_pkg pkg = {0};
- struct spfc_scqe_itmf_marker_sts *tmf_marker_sts_scqe = NULL;
-
- tmf_marker_sts_scqe = &scqe->itmf_marker_sts;
- ox_id = (u32)tmf_marker_sts_scqe->wd1.ox_id;
- rx_id = (u32)tmf_marker_sts_scqe->wd1.rx_id;
- hot_tag = tmf_marker_sts_scqe->wd4.hotpooltag - hba->exi_base;
- pkg.frame_head.oxid_rxid = rx_id | (u32)(ox_id) << UNF_SHIFT_16;
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = tmf_marker_sts_scqe->magic_num;
- pkg.frame_head.csctl_sid = tmf_marker_sts_scqe->wd3.sid;
- pkg.frame_head.rctl_did = tmf_marker_sts_scqe->wd2.did;
-
- /* 1. set pkg status */
- if (unlikely(SPFC_SCQE_HAS_ERRCODE(scqe)))
- pkg.status = UNF_IO_FAILED;
- else
- pkg.status = UNF_IO_SUCCESS;
-
- /* 2 .process rcvd marker STS: set exchange state */
- ret = spfc_rcv_tmf_marker_sts(hba, &pkg, hot_tag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[event]Port(0x%x) recv marker STS OX_ID(0x%x) RX_ID(0x%x) HotTag(0x%x) result %s",
- hba->port_cfg.port_id, ox_id, rx_id, hot_tag,
- (ret == RETURN_OK) ? "succeed" : "failed");
-
- return ret;
-}
-
-u32 spfc_scq_recv_abts_marker_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 ret = UNF_RETURN_ERROR;
- u32 ox_id = INVALID_VALUE32;
- u32 rx_id = INVALID_VALUE32;
- u32 hot_tag = INVALID_VALUE32;
- struct unf_frame_pkg pkg = {0};
- struct spfc_scqe_abts_marker_sts *abts_marker_sts_scqe = NULL;
-
- abts_marker_sts_scqe = &scqe->abts_marker_sts;
- if (!abts_marker_sts_scqe) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]ABTS marker STS is NULL");
- return ret;
- }
-
- ox_id = (u32)abts_marker_sts_scqe->wd1.ox_id;
- rx_id = (u32)abts_marker_sts_scqe->wd1.rx_id;
- hot_tag = abts_marker_sts_scqe->wd4.hotpooltag - hba->exi_base;
- pkg.frame_head.oxid_rxid = rx_id | (u32)(ox_id) << UNF_SHIFT_16;
- pkg.frame_head.csctl_sid = abts_marker_sts_scqe->wd3.sid;
- pkg.frame_head.rctl_did = abts_marker_sts_scqe->wd2.did;
- pkg.abts_maker_status = (u32)abts_marker_sts_scqe->wd3.io_state;
- pkg.private_data[PKG_PRIVATE_XCHG_ALLOC_TIME] = abts_marker_sts_scqe->magic_num;
-
- if (unlikely(SPFC_SCQE_HAS_ERRCODE(scqe)))
- pkg.status = UNF_IO_FAILED;
- else
- pkg.status = UNF_IO_SUCCESS;
-
- ret = spfc_rcv_abts_marker_sts(hba, &pkg, hot_tag);
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_MAJOR,
- "[info]Port(0x%x) recv abts marker STS ox_id(0x%x) RXID(0x%x) HotTag(0x%x) %s",
- hba->port_cfg.port_id, ox_id, rx_id, hot_tag,
- (ret == RETURN_OK) ? "SUCCEED" : "FAILED");
-
- return ret;
-}
-
-u32 spfc_handle_aeq_off_load_err(struct spfc_hba_info *hba, struct spfc_aqe_data *aeq_msg)
-{
- u32 ret = RETURN_OK;
- u32 rport_index = 0;
- u32 xid = 0;
- struct spfc_parent_queue_info *prt_qinfo = NULL;
- struct spfc_delay_destroy_ctrl_info delay_ctl_info;
- ulong flags = 0;
-
- memset(&delay_ctl_info, 0, sizeof(struct spfc_delay_destroy_ctrl_info));
-
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) receive Offload Err Event, EvtCode(0x%x) Conn_id(0x%x) Xid(0x%x)",
- hba->port_cfg.port_id, aeq_msg->wd0.evt_code,
- aeq_msg->wd0.conn_id, aeq_msg->wd1.xid);
-
- /* Currently, only the offload failure caused by insufficient scqe is
- * processed. Other errors are not processed temporarily.
- */
- if (unlikely(aeq_msg->wd0.evt_code != FC_ERROR_OFFLOAD_LACKOF_SCQE_FAIL)) {
- FC_DRV_PRINT(UNF_LOG_REG_ATT, UNF_ERR,
- "[err]Port(0x%x) receive an unsupported error code of AEQ Event,EvtCode(0x%x) Conn_id(0x%x)",
- hba->port_cfg.port_id, aeq_msg->wd0.evt_code,
- aeq_msg->wd0.conn_id);
-
- return UNF_RETURN_ERROR;
- }
- SPFC_SCQ_ERR_TYPE_STAT(hba, FC_ERROR_OFFLOAD_LACKOF_SCQE_FAIL);
-
- rport_index = aeq_msg->wd0.conn_id;
- xid = aeq_msg->wd1.xid;
-
- if (rport_index >= UNF_SPFC_MAXRPORT_NUM) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) receive an error offload status: rport(0x%x) is invalid, Xid(0x%x)",
- hba->port_cfg.port_id, rport_index, aeq_msg->wd1.xid);
-
- return UNF_RETURN_ERROR;
- }
-
- prt_qinfo = &hba->parent_queue_mgr->parent_queue[rport_index];
- if (spfc_check_rport_valid(prt_qinfo, xid) != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) receive an error offload status: rport(0x%x), context id(0x%x) is invalid",
- hba->port_cfg.port_id, rport_index, xid);
-
- return UNF_RETURN_ERROR;
- }
-
- /* The offload status is restored only when the offload status is offloading */
- spin_lock_irqsave(&prt_qinfo->parent_queue_state_lock, flags);
- if (prt_qinfo->offload_state == SPFC_QUEUE_STATE_OFFLOADING)
- prt_qinfo->offload_state = SPFC_QUEUE_STATE_INITIALIZED;
- spin_unlock_irqrestore(&prt_qinfo->parent_queue_state_lock, flags);
-
- if (prt_qinfo->parent_sq_info.destroy_sqe.valid) {
- delay_ctl_info.valid = prt_qinfo->parent_sq_info.destroy_sqe.valid;
- delay_ctl_info.rport_index = prt_qinfo->parent_sq_info.destroy_sqe.rport_index;
- delay_ctl_info.time_out = prt_qinfo->parent_sq_info.destroy_sqe.time_out;
- delay_ctl_info.start_jiff = prt_qinfo->parent_sq_info.destroy_sqe.start_jiff;
- delay_ctl_info.rport_info.nport_id =
- prt_qinfo->parent_sq_info.destroy_sqe.rport_info.nport_id;
- delay_ctl_info.rport_info.rport_index =
- prt_qinfo->parent_sq_info.destroy_sqe.rport_info.rport_index;
- delay_ctl_info.rport_info.port_name =
- prt_qinfo->parent_sq_info.destroy_sqe.rport_info.port_name;
- prt_qinfo->parent_sq_info.destroy_sqe.valid = false;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[info]Port(0x%x) pop up delay sqe, start:0x%llx, timeout:0x%x, rport:0x%x, offload state:0x%x",
- hba->port_cfg.port_id, delay_ctl_info.start_jiff,
- delay_ctl_info.time_out,
- prt_qinfo->parent_sq_info.destroy_sqe.rport_info.rport_index,
- SPFC_QUEUE_STATE_INITIALIZED);
-
- ret = spfc_free_parent_resource(hba, &delay_ctl_info.rport_info);
- if (ret != RETURN_OK) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[err]Port(0x%x) pop delay destroy parent sq failed, rport(0x%x), rport nport id 0x%x",
- hba->port_cfg.port_id,
- delay_ctl_info.rport_info.rport_index,
- delay_ctl_info.rport_info.nport_id);
- }
- }
-
- return ret;
-}
-
-u32 spfc_free_xid(void *handle, struct unf_frame_pkg *pkg)
-{
- u32 ret = RETURN_ERROR;
- u16 rx_id = INVALID_VALUE16;
- u16 ox_id = INVALID_VALUE16;
- u16 hot_tag = INVALID_VALUE16;
- struct spfc_hba_info *hba = (struct spfc_hba_info *)handle;
- union spfc_cmdqe tmp_cmd_wqe;
- union spfc_cmdqe *cmd_wqe = NULL;
-
- FC_CHECK_RETURN_VALUE(hba, RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(pkg, RETURN_ERROR);
- SPFC_CHECK_PKG_ALLOCTIME(pkg);
-
- cmd_wqe = &tmp_cmd_wqe;
- memset(cmd_wqe, 0, sizeof(union spfc_cmdqe));
-
- rx_id = UNF_GET_RXID(pkg);
- ox_id = UNF_GET_OXID(pkg);
- if (UNF_GET_HOTPOOL_TAG(pkg) != INVALID_VALUE32)
- hot_tag = (u16)UNF_GET_HOTPOOL_TAG(pkg) + hba->exi_base;
-
- spfc_build_cmdqe_common(cmd_wqe, SPFC_TASK_T_EXCH_ID_FREE, rx_id);
- cmd_wqe->xid_free.wd2.hotpool_tag = hot_tag;
- cmd_wqe->xid_free.magic_num = UNF_GETXCHGALLOCTIME(pkg);
- cmd_wqe->xid_free.sid = pkg->frame_head.csctl_sid;
- cmd_wqe->xid_free.did = pkg->frame_head.rctl_did;
- cmd_wqe->xid_free.type = pkg->type;
-
- if (pkg->rx_or_ox_id == UNF_PKG_FREE_OXID)
- cmd_wqe->xid_free.wd0.task_id = ox_id;
- else
- cmd_wqe->xid_free.wd0.task_id = rx_id;
-
- cmd_wqe->xid_free.wd0.port_id = hba->port_index;
- cmd_wqe->xid_free.wd2.scqn = hba->default_scqn;
- ret = spfc_root_cmdq_enqueue(hba, cmd_wqe, sizeof(cmd_wqe->xid_free));
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_INFO,
- "[info]Port(0x%x) ox_id(0x%x) RXID(0x%x) hottag(0x%x) magic_num(0x%x) Sid(0x%x) Did(0x%x), send free xid %s",
- hba->port_cfg.port_id, ox_id, rx_id, hot_tag,
- cmd_wqe->xid_free.magic_num, cmd_wqe->xid_free.sid,
- cmd_wqe->xid_free.did,
- (ret == RETURN_OK) ? "OK" : "ERROR");
-
- return ret;
-}
-
-u32 spfc_scq_free_xid_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 hot_tag = INVALID_VALUE32;
- u32 magic_num = INVALID_VALUE32;
- u32 ox_id = INVALID_VALUE32;
- u32 rx_id = INVALID_VALUE32;
- struct spfc_scqe_comm_rsp_sts *free_xid_sts_scqe = NULL;
-
- free_xid_sts_scqe = &scqe->comm_sts;
- magic_num = free_xid_sts_scqe->magic_num;
- ox_id = (u32)free_xid_sts_scqe->wd0.ox_id;
- rx_id = (u32)free_xid_sts_scqe->wd0.rx_id;
-
- if (free_xid_sts_scqe->wd1.hotpooltag != INVALID_VALUE16) {
- hot_tag = free_xid_sts_scqe->wd1.hotpooltag - hba->exi_base;
- }
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_INFO,
- "Port(0x%x) hottag(0x%x) magicnum(0x%x) ox_id(0x%x) rxid(0x%x) sts(%d)",
- hba->port_cfg.port_id, hot_tag, magic_num, ox_id, rx_id,
- SPFC_GET_SCQE_STATUS(scqe));
-
- return RETURN_OK;
-}
-
-u32 spfc_scq_exchg_timeout_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- u32 hot_tag = INVALID_VALUE32;
- u32 magic_num = INVALID_VALUE32;
- u32 ox_id = INVALID_VALUE32;
- u32 rx_id = INVALID_VALUE32;
- struct spfc_scqe_comm_rsp_sts *time_out_scqe = NULL;
-
- time_out_scqe = &scqe->comm_sts;
- magic_num = time_out_scqe->magic_num;
- ox_id = (u32)time_out_scqe->wd0.ox_id;
- rx_id = (u32)time_out_scqe->wd0.rx_id;
-
- if (time_out_scqe->wd1.hotpooltag != INVALID_VALUE16)
- hot_tag = time_out_scqe->wd1.hotpooltag - hba->exi_base;
-
- FC_DRV_PRINT(UNF_LOG_EQUIP_ATT, UNF_INFO,
- "Port(0x%x) recv timer time out sts hotpooltag(0x%x) magicnum(0x%x) ox_id(0x%x) rxid(0x%x) sts(%d)",
- hba->port_cfg.port_id, hot_tag, magic_num, ox_id, rx_id,
- SPFC_GET_SCQE_STATUS(scqe));
-
- return RETURN_OK;
-}
-
-u32 spfc_scq_rcv_sq_nop_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe)
-{
- struct spfc_scqe_sq_nop_sts *sq_nop_scqe = NULL;
- struct spfc_parent_queue_info *prt_qinfo = NULL;
- struct spfc_parent_sq_info *parent_sq_info = NULL;
- struct list_head *node = NULL;
- struct list_head *next_node = NULL;
- struct spfc_suspend_sqe_info *suspend_sqe = NULL;
- struct spfc_suspend_sqe_info *sqe = NULL;
- u32 rport_index = 0;
- u32 magic_num;
- u16 sqn;
- u32 sqn_base;
- u32 sqn_max;
- u32 ret = RETURN_OK;
- ulong flags = 0;
-
- sq_nop_scqe = &scqe->sq_nop_sts;
- rport_index = sq_nop_scqe->wd1.conn_id;
- magic_num = sq_nop_scqe->magic_num;
- sqn = sq_nop_scqe->wd0.sqn;
- prt_qinfo = &hba->parent_queue_mgr->parent_queue[rport_index];
- parent_sq_info = &prt_qinfo->parent_sq_info;
- sqn_base = parent_sq_info->sqn_base;
- sqn_max = sqn_base + UNF_SQ_NUM_PER_SESSION - 1;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) rport(0x%x), magic_num(0x%x) receive nop sq sts form sq(0x%x)",
- hba->port_cfg.port_id, rport_index, magic_num, sqn);
-
- spin_lock_irqsave(&prt_qinfo->parent_queue_state_lock, flags);
- list_for_each_safe(node, next_node, &parent_sq_info->suspend_sqe_list) {
- sqe = list_entry(node, struct spfc_suspend_sqe_info, list_sqe_entry);
- if (sqe->magic_num != magic_num)
- continue;
- suspend_sqe = sqe;
- if (sqn == sqn_max)
- list_del(node);
- break;
- }
- spin_unlock_irqrestore(&prt_qinfo->parent_queue_state_lock, flags);
-
- if (suspend_sqe) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) rport_index(0x%x) find suspend sqe.",
- hba->port_cfg.port_id, rport_index);
- if ((sqn < sqn_max) && (sqn >= sqn_base)) {
- ret = spfc_send_nop_cmd(hba, parent_sq_info, magic_num, sqn + 1);
- } else if (sqn == sqn_max) {
- if (!cancel_delayed_work(&suspend_sqe->timeout_work)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "[warn]Port(0x%x) rport(0x%x) reset worker timer maybe timeout",
- hba->port_cfg.port_id, rport_index);
- }
- parent_sq_info->need_offloaded = suspend_sqe->old_offload_sts;
- ret = spfc_pop_suspend_sqe(hba, prt_qinfo, suspend_sqe);
- kfree(suspend_sqe);
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) rport(0x%x) rcv error sqn(0x%x)",
- hba->port_cfg.port_id, rport_index, sqn);
- }
- } else {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_WARN,
- "[warn]Port(0x%x) rport(0x%x) magicnum(0x%x)can't find suspend sqe",
- hba->port_cfg.port_id, rport_index, magic_num);
- }
- return ret;
-}
-
-static const struct unf_scqe_handle_table scqe_handle_table[] = {
- {/* INI rcvd FCP RSP */
- SPFC_SCQE_FCP_IRSP, true, spfc_scq_recv_iresp},
- {/* INI/TGT rcvd ELS_CMND */
- SPFC_SCQE_ELS_CMND, false, spfc_scq_recv_els_cmnd},
- {/* INI/TGT rcvd ELS_RSP */
- SPFC_SCQE_ELS_RSP, true, spfc_scq_recv_ls_gs_rsp},
- {/* INI/TGT rcvd GS_RSP */
- SPFC_SCQE_GS_RSP, true, spfc_scq_recv_ls_gs_rsp},
- {/* INI rcvd BLS_RSP */
- SPFC_SCQE_ABTS_RSP, true, spfc_scq_recv_abts_rsp},
- {/* INI/TGT rcvd ELS_RSP STS(Done) */
- SPFC_SCQE_ELS_RSP_STS, true, spfc_scq_recv_els_rsp_sts},
- {/* INI or TGT rcvd Session enable STS */
- SPFC_SCQE_SESS_EN_STS, false, spfc_scq_recv_offload_sts},
- {/* INI or TGT rcvd flush (pending) SQ STS */
- SPFC_SCQE_FLUSH_SQ_STS, false, spfc_scq_rcv_flush_sq_sts},
- {/* INI or TGT rcvd Buffer clear STS */
- SPFC_SCQE_BUF_CLEAR_STS, false, spfc_scq_rcv_buf_clear_sts},
- {/* INI or TGT rcvd session reset STS */
- SPFC_SCQE_SESS_RST_STS, false, spfc_scq_recv_sess_rst_sts},
- {/* ELS/IMMI SRQ */
- SPFC_SCQE_CLEAR_SRQ_STS, false, spfc_scq_rcv_clear_srq_sts},
- {/* INI rcvd TMF RSP */
- SPFC_SCQE_FCP_ITMF_RSP, true, spfc_scq_recv_iresp},
- {/* INI rcvd TMF Marker STS */
- SPFC_SCQE_ITMF_MARKER_STS, false, spfc_scq_recv_marker_sts},
- {/* INI rcvd ABTS Marker STS */
- SPFC_SCQE_ABTS_MARKER_STS, false, spfc_scq_recv_abts_marker_sts},
- {SPFC_SCQE_XID_FREE_ABORT_STS, false, spfc_scq_free_xid_sts},
- {SPFC_SCQE_EXCHID_TIMEOUT_STS, false, spfc_scq_exchg_timeout_sts},
- {SPFC_SQE_NOP_STS, true, spfc_scq_rcv_sq_nop_sts},
-
-};
-
-u32 spfc_rcv_scq_entry_from_scq(struct spfc_hba_info *hba, union spfc_scqe *scqe, u32 scqn)
-{
- u32 ret = UNF_RETURN_ERROR;
- bool reclaim = false;
- u32 index = 0;
- u32 total = 0;
-
- FC_CHECK_RETURN_VALUE(hba, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(scqe, UNF_RETURN_ERROR);
- FC_CHECK_RETURN_VALUE(scqn < SPFC_TOTAL_SCQ_NUM, UNF_RETURN_ERROR);
-
- SPFC_IO_STAT(hba, SPFC_GET_SCQE_TYPE(scqe));
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_INFO,
- "[info]Port(0x%x) receive scqe type %d from SCQ[%u]",
- hba->port_cfg.port_id, SPFC_GET_SCQE_TYPE(scqe), scqn);
-
- /* 1. error code cheking */
- if (unlikely(SPFC_SCQE_HAS_ERRCODE(scqe))) {
- /* So far, just print & counter */
- spfc_scqe_error_pre_proc(hba, scqe);
- }
-
- /* 2. Process SCQE by corresponding processer */
- total = sizeof(scqe_handle_table) / sizeof(struct unf_scqe_handle_table);
- while (index < total) {
- if (SPFC_GET_SCQE_TYPE(scqe) == scqe_handle_table[index].scqe_type) {
- ret = scqe_handle_table[index].scqe_handle_func(hba, scqe);
- reclaim = scqe_handle_table[index].reclaim_sq_wpg;
-
- break;
- }
-
- index++;
- }
-
- /* 3. SCQE type check */
- if (unlikely(total == index)) {
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_ERR,
- "[warn]Unknown SCQE type %d",
- SPFC_GET_SCQE_TYPE(scqe));
-
- UNF_PRINT_SFS_LIMIT(UNF_ERR, hba->port_cfg.port_id, scqe, sizeof(union spfc_scqe));
- }
-
- /* 4. If SCQE is for SQ-WQE then recovery Link List SQ free page */
- if (reclaim) {
- if (SPFC_GET_SCQE_SQN(scqe) < SPFC_MAX_SSQ_NUM) {
- ret = spfc_reclaim_sq_wqe_page(hba, scqe);
- } else {
- /* NOTE: for buffer clear, the SCQE conn_id is 0xFFFF,count with HBA */
- SPFC_HBA_STAT((struct spfc_hba_info *)hba, SPFC_STAT_SQ_IO_BUFFER_CLEARED);
- }
- }
-
- return ret;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_service.h b/drivers/scsi/spfc/hw/spfc_service.h
deleted file mode 100644
index e2555c55f4d1..000000000000
--- a/drivers/scsi/spfc/hw/spfc_service.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_SERVICE_H
-#define SPFC_SERVICE_H
-
-#include "unf_type.h"
-#include "unf_common.h"
-#include "unf_scsi_common.h"
-#include "spfc_hba.h"
-
-#define SPFC_HAVE_OFFLOAD (0)
-
-/* FC txmfs */
-#define SPFC_DEFAULT_TX_MAX_FREAM_SIZE (256)
-
-#define SPFC_GET_NETWORK_PORT_ID(hba) \
- (((hba)->port_index > 1) ? ((hba)->port_index + 2) : (hba)->port_index)
-
-#define SPFC_GET_PRLI_PAYLOAD_LEN \
- (UNF_PRLI_PAYLOAD_LEN - UNF_PRLI_SIRT_EXTRA_SIZE)
-/* Start addr of the header/payloed of the cmnd buffer in the pkg */
-#define SPFC_FC_HEAD_LEN (sizeof(struct unf_fc_head))
-#define SPFC_PAYLOAD_OFFSET (sizeof(struct unf_fc_head))
-#define SPFC_GET_CMND_PAYLOAD_ADDR(pkg) UNF_GET_FLOGI_PAYLOAD(pkg)
-#define SPFC_GET_CMND_HEADER_ADDR(pkg) \
- ((pkg)->unf_cmnd_pload_bl.buffer_ptr)
-#define SPFC_GET_RSP_HEADER_ADDR(pkg) \
- ((pkg)->unf_rsp_pload_bl.buffer_ptr)
-#define SPFC_GET_RSP_PAYLOAD_ADDR(pkg) \
- ((pkg)->unf_rsp_pload_bl.buffer_ptr + SPFC_PAYLOAD_OFFSET)
-#define SPFC_GET_CMND_FC_HEADER(pkg) \
- (&(UNF_GET_SFS_ENTRY(pkg)->sfs_common.frame_head))
-#define SPFC_PKG_IS_ELS_RSP(cmd_type) \
- (((cmd_type) == ELS_ACC) || ((cmd_type) == ELS_RJT))
-#define SPFC_XID_IS_VALID(exid, base, exi_count) \
- (((exid) >= (base)) && ((exid) < ((base) + (exi_count))))
-#define SPFC_CHECK_NEED_OFFLOAD(cmd_code, cmd_type, offload_state) \
- (((cmd_code) == ELS_PLOGI) && ((cmd_type) != ELS_RJT) && \
- ((offload_state) == SPFC_QUEUE_STATE_INITIALIZED))
-
-#define UNF_FC_PAYLOAD_ELS_MASK (0xFF000000)
-#define UNF_FC_PAYLOAD_ELS_SHIFT (24)
-#define UNF_FC_PAYLOAD_ELS_DWORD (0)
-
-/* Note: this pfcpayload is little endian */
-#define UNF_GET_FC_PAYLOAD_ELS_CMND(pfcpayload) \
- UNF_GET_SHIFTMASK(((u32 *)(void *)(pfcpayload))[UNF_FC_PAYLOAD_ELS_DWORD], \
- UNF_FC_PAYLOAD_ELS_SHIFT, UNF_FC_PAYLOAD_ELS_MASK)
-
-/* Note: this pfcpayload is big endian */
-#define SPFC_GET_FC_PAYLOAD_ELS_CMND(pfcpayload) \
- UNF_GET_SHIFTMASK(be32_to_cpu(((u32 *)(void *)(pfcpayload))[UNF_FC_PAYLOAD_ELS_DWORD]), \
- UNF_FC_PAYLOAD_ELS_SHIFT, UNF_FC_PAYLOAD_ELS_MASK)
-
-#define UNF_FC_PAYLOAD_RX_SZ_MASK (0x00000FFF)
-#define UNF_FC_PAYLOAD_RX_SZ_SHIFT (16)
-#define UNF_FC_PAYLOAD_RX_SZ_DWORD (2)
-
-/* Note: this pfcpayload is little endian */
-#define UNF_GET_FC_PAYLOAD_RX_SZ(pfcpayload) \
- ((u16)(((u32 *)(void *)(pfcpayload))[UNF_FC_PAYLOAD_RX_SZ_DWORD] & \
- UNF_FC_PAYLOAD_RX_SZ_MASK))
-
-/* Note: this pfcpayload is big endian */
-#define SPFC_GET_FC_PAYLOAD_RX_SZ(pfcpayload) \
- (be32_to_cpu((u16)(((u32 *)(void *)(pfcpayload))[UNF_FC_PAYLOAD_RX_SZ_DWORD]) & \
- UNF_FC_PAYLOAD_RX_SZ_MASK))
-
-#define SPFC_GET_RA_TOV_FROM_PAYLOAD(pfcpayload) \
- (((struct unf_flogi_fdisc_payload *)(pfcpayload))->fabric_parms.co_parms.r_a_tov)
-#define SPFC_GET_RT_TOV_FROM_PAYLOAD(pfcpayload) \
- (((struct unf_flogi_fdisc_payload *)(pfcpayload))->fabric_parms.co_parms.r_t_tov)
-#define SPFC_GET_E_D_TOV_FROM_PAYLOAD(pfcpayload) \
- (((struct unf_flogi_fdisc_payload *)(pfcpayload))->fabric_parms.co_parms.e_d_tov)
-#define SPFC_GET_E_D_TOV_RESOLUTION_FROM_PAYLOAD(pfcpayload) \
- (((struct unf_flogi_fdisc_payload *)(pfcpayload))->fabric_parms.co_parms.e_d_tov_resolution)
-#define SPFC_GET_BB_SC_N_FROM_PAYLOAD(pfcpayload) \
- (((struct unf_flogi_fdisc_payload *)(pfcpayload))->fabric_parms.co_parms.bbscn)
-#define SPFC_GET_BB_CREDIT_FROM_PAYLOAD(pfcpayload) \
- (((struct unf_flogi_fdisc_payload *)(pfcpayload))->fabric_parms.co_parms.bb_credit)
-
-#define SPFC_GET_RA_TOV_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.r_a_tov)
-#define SPFC_GET_RT_TOV_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.r_t_tov)
-#define SPFC_GET_E_D_TOV_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.e_d_tov)
-#define SPFC_GET_E_D_TOV_RESOLUTION_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.e_d_tov_resolution)
-#define SPFC_GET_BB_SC_N_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.bbscn)
-#define SPFC_GET_BB_CREDIT_FROM_PARAMS(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.bb_credit)
-#define SPFC_CHECK_NPORT_FPORT_BIT(pfcparams) \
- (((struct unf_fabric_parm *)(pfcparams))->co_parms.nport)
-
-#define UNF_FC_RCTL_BLS_MASK (0x80)
-#define SPFC_UNSOLICITED_FRAME_IS_BLS(hdr) (UNF_GET_FC_HEADER_RCTL(hdr) & UNF_FC_RCTL_BLS_MASK)
-
-#define SPFC_LOW_SEQ_CNT (0)
-#define SPFC_HIGH_SEQ_CNT (0xFFFF)
-
-/* struct unf_frame_pkg.cmnd meaning:
- * The least significant 16 bits indicate whether to send ELS CMND or ELS RSP
- * (ACC or RJT). The most significant 16 bits indicate the corresponding ELS
- * CMND when the lower 16 bits are ELS RSP.
- */
-#define SPFC_ELS_CMND_MASK (0xffff)
-#define SPFC_ELS_CMND__RELEVANT_SHIFT (16UL)
-#define SPFC_GET_LS_GS_CMND_CODE(cmnd) ((u16)((cmnd) & SPFC_ELS_CMND_MASK))
-#define SPFC_GET_ELS_RSP_TYPE(cmnd) ((u16)((cmnd) & SPFC_ELS_CMND_MASK))
-#define SPFC_GET_ELS_RSP_CODE(cmnd) \
- ((u16)((cmnd) >> SPFC_ELS_CMND__RELEVANT_SHIFT & SPFC_ELS_CMND_MASK))
-
-/* ELS CMND Request */
-#define ELS_CMND (0)
-
-/* fh_f_ctl - Frame control flags. */
-#define SPFC_FC_EX_CTX BIT(23) /* sent by responder to exchange */
-#define SPFC_FC_SEQ_CTX BIT(22) /* sent by responder to sequence */
-#define SPFC_FC_FIRST_SEQ BIT(21) /* first sequence of this exchange */
-#define SPFC_FC_LAST_SEQ BIT(20) /* last sequence of this exchange */
-#define SPFC_FC_END_SEQ BIT(19) /* last frame of sequence */
-#define SPFC_FC_END_CONN BIT(18) /* end of class 1 connection pending */
-#define SPFC_FC_RES_B17 BIT(17) /* reserved */
-#define SPFC_FC_SEQ_INIT BIT(16) /* transfer of sequence initiative */
-#define SPFC_FC_X_ID_REASS BIT(15) /* exchange ID has been changed */
-#define SPFC_FC_X_ID_INVAL BIT(14) /* exchange ID invalidated */
-#define SPFC_FC_ACK_1 BIT(12) /* 13:12 = 1: ACK_1 expected */
-#define SPFC_FC_ACK_N (2 << 12) /* 13:12 = 2: ACK_N expected */
-#define SPFC_FC_ACK_0 (3 << 12) /* 13:12 = 3: ACK_0 expected */
-#define SPFC_FC_RES_B11 BIT(11) /* reserved */
-#define SPFC_FC_RES_B10 BIT(10) /* reserved */
-#define SPFC_FC_RETX_SEQ BIT(9) /* retransmitted sequence */
-#define SPFC_FC_UNI_TX BIT(8) /* unidirectional transmit (class 1) */
-#define SPFC_FC_CONT_SEQ(i) ((i) << 6)
-#define SPFC_FC_ABT_SEQ(i) ((i) << 4)
-#define SPFC_FC_REL_OFF BIT(3) /* parameter is relative offset */
-#define SPFC_FC_RES2 BIT(2) /* reserved */
-#define SPFC_FC_FILL(i) ((i) & 3) /* 1:0: bytes of trailing fill */
-
-#define SPFC_FCTL_REQ (SPFC_FC_FIRST_SEQ | SPFC_FC_END_SEQ | SPFC_FC_SEQ_INIT)
-#define SPFC_FCTL_RESP \
- (SPFC_FC_EX_CTX | SPFC_FC_LAST_SEQ | SPFC_FC_END_SEQ | SPFC_FC_SEQ_INIT)
-#define SPFC_RCTL_BLS_REQ (0x81)
-#define SPFC_RCTL_BLS_ACC (0x84)
-#define SPFC_RCTL_BLS_RJT (0x85)
-
-#define PHY_PORT_TYPE_FC 0x1 /* Physical port type of FC */
-#define PHY_PORT_TYPE_FCOE 0x2 /* Physical port type of FCoE */
-#define SPFC_FC_COS_VALUE (0X4)
-
-#define SPFC_CDB16_LBA_MASK 0xffff
-#define SPFC_CDB16_TRANSFERLEN_MASK 0xff
-#define SPFC_RXID_MASK 0xffff
-#define SPFC_OXID_MASK 0xffff0000
-
-enum spfc_fc_fh_type {
- SPFC_FC_TYPE_BLS = 0x00, /* basic link service */
- SPFC_FC_TYPE_ELS = 0x01, /* extended link service */
- SPFC_FC_TYPE_IP = 0x05, /* IP over FC, RFC 4338 */
- SPFC_FC_TYPE_FCP = 0x08, /* SCSI FCP */
- SPFC_FC_TYPE_CT = 0x20, /* Fibre Channel Services (FC-CT) */
- SPFC_FC_TYPE_ILS = 0x22 /* internal link service */
-};
-
-enum spfc_fc_fh_rctl {
- SPFC_FC_RCTL_DD_UNCAT = 0x00, /* uncategorized information */
- SPFC_FC_RCTL_DD_SOL_DATA = 0x01, /* solicited data */
- SPFC_FC_RCTL_DD_UNSOL_CTL = 0x02, /* unsolicited control */
- SPFC_FC_RCTL_DD_SOL_CTL = 0x03, /* solicited control or reply */
- SPFC_FC_RCTL_DD_UNSOL_DATA = 0x04, /* unsolicited data */
- SPFC_FC_RCTL_DD_DATA_DESC = 0x05, /* data descriptor */
- SPFC_FC_RCTL_DD_UNSOL_CMD = 0x06, /* unsolicited command */
- SPFC_FC_RCTL_DD_CMD_STATUS = 0x07, /* command status */
-
-#define SPFC_FC_RCTL_ILS_REQ SPFC_FC_RCTL_DD_UNSOL_CTL /* ILS request */
-#define SPFC_FC_RCTL_ILS_REP SPFC_FC_RCTL_DD_SOL_CTL /* ILS reply */
-
- /*
- * Extended Link_Data
- */
- SPFC_FC_RCTL_ELS_REQ = 0x22, /* extended link services request */
- SPFC_FC_RCTL_ELS_RSP = 0x23, /* extended link services reply */
- SPFC_FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */
- SPFC_FC_RCTL_ELS4_RSP = 0x33, /* FC-4 ELS reply */
- /*
- * Optional Extended Headers
- */
- SPFC_FC_RCTL_VFTH = 0x50, /* virtual fabric tagging header */
- SPFC_FC_RCTL_IFRH = 0x51, /* inter-fabric routing header */
- SPFC_FC_RCTL_ENCH = 0x52, /* encapsulation header */
- /*
- * Basic Link Services fh_r_ctl values.
- */
- SPFC_FC_RCTL_BA_NOP = 0x80, /* basic link service NOP */
- SPFC_FC_RCTL_BA_ABTS = 0x81, /* basic link service abort */
- SPFC_FC_RCTL_BA_RMC = 0x82, /* remove connection */
- SPFC_FC_RCTL_BA_ACC = 0x84, /* basic accept */
- SPFC_FC_RCTL_BA_RJT = 0x85, /* basic reject */
- SPFC_FC_RCTL_BA_PRMT = 0x86, /* dedicated connection preempted */
- /*
- * Link Control Information.
- */
- SPFC_FC_RCTL_ACK_1 = 0xc0, /* acknowledge_1 */
- SPFC_FC_RCTL_ACK_0 = 0xc1, /* acknowledge_0 */
- SPFC_FC_RCTL_P_RJT = 0xc2, /* port reject */
- SPFC_FC_RCTL_F_RJT = 0xc3, /* fabric reject */
- SPFC_FC_RCTL_P_BSY = 0xc4, /* port busy */
- SPFC_FC_RCTL_F_BSY = 0xc5, /* fabric busy to data frame */
- SPFC_FC_RCTL_F_BSYL = 0xc6, /* fabric busy to link control frame */
- SPFC_FC_RCTL_LCR = 0xc7, /* link credit reset */
- SPFC_FC_RCTL_END = 0xc9 /* end */
-};
-
-struct spfc_fc_frame_header {
- u8 rctl; /* routing control */
- u8 did[ARRAY_INDEX_3]; /* Destination ID */
-
- u8 cs_ctrl; /* class of service control / pri */
- u8 sid[ARRAY_INDEX_3]; /* Source ID */
-
- u8 type; /* see enum fc_fh_type below */
- u8 frame_ctrl[ARRAY_INDEX_3]; /* frame control */
-
- u8 seq_id; /* sequence ID */
- u8 df_ctrl; /* data field control */
- u16 seq_cnt; /* sequence count */
-
- u16 oxid; /* originator exchange ID */
- u16 rxid; /* responder exchange ID */
- u32 param_offset; /* parameter or relative offset */
-};
-
-u32 spfc_recv_els_cmnd(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u8 *els_pld, u32 pld_len,
- bool first);
-u32 spfc_rcv_ls_gs_rsp(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 hot_tag);
-u32 spfc_rcv_els_rsp_sts(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 hot_tag);
-u32 spfc_rcv_bls_rsp(const struct spfc_hba_info *hba, struct unf_frame_pkg *pkg,
- u32 hot_tag);
-u32 spfc_rsv_bls_rsp_sts(const struct spfc_hba_info *hba,
- struct unf_frame_pkg *pkg, u32 rx_id);
-void spfc_save_login_parms_in_sq_info(struct spfc_hba_info *hba,
- struct unf_port_login_parms *login_params);
-u32 spfc_handle_aeq_off_load_err(struct spfc_hba_info *hba,
- struct spfc_aqe_data *aeq_msg);
-u32 spfc_free_xid(void *handle, struct unf_frame_pkg *pkg);
-u32 spfc_scq_free_xid_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe);
-u32 spfc_scq_exchg_timeout_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe);
-u32 spfc_scq_rcv_sq_nop_sts(struct spfc_hba_info *hba, union spfc_scqe *scqe);
-u32 spfc_send_els_via_default_session(struct spfc_hba_info *hba, struct spfc_sqe *io_sqe,
- struct unf_frame_pkg *pkg,
- struct spfc_parent_queue_info *prt_queue_info);
-u32 spfc_send_ls_gs_cmnd(void *handle, struct unf_frame_pkg *pkg);
-u32 spfc_send_bls_cmnd(void *handle, struct unf_frame_pkg *pkg);
-
-/* Receive Frame from SCQ */
-u32 spfc_rcv_scq_entry_from_scq(struct spfc_hba_info *hba,
- union spfc_scqe *scqe, u32 scqn);
-void *spfc_get_els_buf_by_user_id(struct spfc_hba_info *hba, u16 user_id);
-
-#define SPFC_CHECK_PKG_ALLOCTIME(pkg) \
- do { \
- if (unlikely(UNF_GETXCHGALLOCTIME(pkg) == 0)) { \
- FC_DRV_PRINT(UNF_LOG_NORMAL, \
- UNF_WARN, \
- "[warn]Invalid MagicNum,S_ID(0x%x) " \
- "D_ID(0x%x) OXID(0x%x) " \
- "RX_ID(0x%x) Pkg type(0x%x) hot " \
- "pooltag(0x%x)", \
- UNF_GET_SID(pkg), UNF_GET_DID(pkg), \
- UNF_GET_OXID(pkg), UNF_GET_RXID(pkg), \
- ((struct unf_frame_pkg *)(pkg))->type, \
- UNF_GET_XCHG_TAG(pkg)); \
- } \
- } while (0)
-
-#endif
diff --git a/drivers/scsi/spfc/hw/spfc_utils.c b/drivers/scsi/spfc/hw/spfc_utils.c
deleted file mode 100644
index 328c388c95fe..000000000000
--- a/drivers/scsi/spfc/hw/spfc_utils.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "spfc_utils.h"
-#include "unf_log.h"
-#include "unf_common.h"
-
-void spfc_cpu_to_big64(void *addr, u32 size)
-{
- u32 index = 0;
- u32 cnt = 0;
- u64 *temp = NULL;
-
- FC_CHECK_VALID(addr, dump_stack(); return);
- FC_CHECK_VALID((size % SPFC_QWORD_BYTE) == 0, dump_stack(); return);
-
- temp = (u64 *)addr;
- cnt = SPFC_SHIFT_TO_U64(size);
-
- for (index = 0; index < cnt; index++) {
- *temp = cpu_to_be64(*temp);
- temp++;
- }
-}
-
-void spfc_big_to_cpu64(void *addr, u32 size)
-{
- u32 index = 0;
- u32 cnt = 0;
- u64 *temp = NULL;
-
- FC_CHECK_VALID(addr, dump_stack(); return);
- FC_CHECK_VALID((size % SPFC_QWORD_BYTE) == 0, dump_stack(); return);
-
- temp = (u64 *)addr;
- cnt = SPFC_SHIFT_TO_U64(size);
-
- for (index = 0; index < cnt; index++) {
- *temp = be64_to_cpu(*temp);
- temp++;
- }
-}
-
-void spfc_cpu_to_big32(void *addr, u32 size)
-{
- unf_cpu_to_big_end(addr, size);
-}
-
-void spfc_big_to_cpu32(void *addr, u32 size)
-{
- if (size % UNF_BYTES_OF_DWORD)
- dump_stack();
-
- unf_big_end_to_cpu(addr, size);
-}
-
-void spfc_cpu_to_be24(u8 *data, u32 value)
-{
- data[ARRAY_INDEX_0] = (value >> UNF_SHIFT_16) & UNF_MASK_BIT_7_0;
- data[ARRAY_INDEX_1] = (value >> UNF_SHIFT_8) & UNF_MASK_BIT_7_0;
- data[ARRAY_INDEX_2] = value & UNF_MASK_BIT_7_0;
-}
-
-u32 spfc_big_to_cpu24(u8 *data)
-{
- return (data[ARRAY_INDEX_0] << UNF_SHIFT_16) |
- (data[ARRAY_INDEX_1] << UNF_SHIFT_8) | data[ARRAY_INDEX_2];
-}
-
-void spfc_print_buff(u32 dbg_level, void *buff, u32 size)
-{
- u32 *spfc_buff = NULL;
- u32 loop = 0;
- u32 index = 0;
-
- FC_CHECK_VALID(buff, dump_stack(); return);
- FC_CHECK_VALID(0 == (size % SPFC_DWORD_BYTE), dump_stack(); return);
-
- if ((dbg_level) <= unf_dgb_level) {
- spfc_buff = (u32 *)buff;
- loop = size / SPFC_DWORD_BYTE;
-
- for (index = 0; index < loop; index++) {
- spfc_buff = (u32 *)buff + index;
- FC_DRV_PRINT(UNF_LOG_NORMAL,
- UNF_MAJOR, "Buff DW%u 0x%08x.", index, *spfc_buff);
- }
- }
-}
-
-u32 spfc_log2n(u32 val)
-{
- u32 result = 0;
- u32 logn = (val >> UNF_SHIFT_1);
-
- while (logn) {
- logn >>= UNF_SHIFT_1;
- result++;
- }
-
- return result;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_utils.h b/drivers/scsi/spfc/hw/spfc_utils.h
deleted file mode 100644
index 6b4330da3f1d..000000000000
--- a/drivers/scsi/spfc/hw/spfc_utils.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_UTILS_H
-#define SPFC_UTILS_H
-
-#include "unf_type.h"
-#include "unf_log.h"
-
-#define SPFC_ZERO (0)
-
-#define SPFC_BIT(n) (0x1UL << (n))
-#define SPFC_BIT_0 SPFC_BIT(0)
-#define SPFC_BIT_1 SPFC_BIT(1)
-#define SPFC_BIT_2 SPFC_BIT(2)
-#define SPFC_BIT_3 SPFC_BIT(3)
-#define SPFC_BIT_4 SPFC_BIT(4)
-#define SPFC_BIT_5 SPFC_BIT(5)
-#define SPFC_BIT_6 SPFC_BIT(6)
-#define SPFC_BIT_7 SPFC_BIT(7)
-#define SPFC_BIT_8 SPFC_BIT(8)
-#define SPFC_BIT_9 SPFC_BIT(9)
-#define SPFC_BIT_10 SPFC_BIT(10)
-#define SPFC_BIT_11 SPFC_BIT(11)
-#define SPFC_BIT_12 SPFC_BIT(12)
-#define SPFC_BIT_13 SPFC_BIT(13)
-#define SPFC_BIT_14 SPFC_BIT(14)
-#define SPFC_BIT_15 SPFC_BIT(15)
-#define SPFC_BIT_16 SPFC_BIT(16)
-#define SPFC_BIT_17 SPFC_BIT(17)
-#define SPFC_BIT_18 SPFC_BIT(18)
-#define SPFC_BIT_19 SPFC_BIT(19)
-#define SPFC_BIT_20 SPFC_BIT(20)
-#define SPFC_BIT_21 SPFC_BIT(21)
-#define SPFC_BIT_22 SPFC_BIT(22)
-#define SPFC_BIT_23 SPFC_BIT(23)
-#define SPFC_BIT_24 SPFC_BIT(24)
-#define SPFC_BIT_25 SPFC_BIT(25)
-#define SPFC_BIT_26 SPFC_BIT(26)
-#define SPFC_BIT_27 SPFC_BIT(27)
-#define SPFC_BIT_28 SPFC_BIT(28)
-#define SPFC_BIT_29 SPFC_BIT(29)
-#define SPFC_BIT_30 SPFC_BIT(30)
-#define SPFC_BIT_31 SPFC_BIT(31)
-
-#define SPFC_GET_BITS(data, mask) ((data) & (mask)) /* Obtains the bit */
-#define SPFC_SET_BITS(data, mask) ((data) |= (mask)) /* set the bit */
-#define SPFC_CLR_BITS(data, mask) ((data) &= ~(mask)) /* clear the bit */
-
-#define SPFC_LSB(x) ((u8)(x))
-#define SPFC_MSB(x) ((u8)((u16)(x) >> 8))
-
-#define SPFC_LSW(x) ((u16)(x))
-#define SPFC_MSW(x) ((u16)((u32)(x) >> 16))
-
-#define SPFC_LSD(x) ((u32)((u64)(x)))
-#define SPFC_MSD(x) ((u32)((((u64)(x)) >> 16) >> 16))
-
-#define SPFC_BYTES_TO_QW_NUM(x) ((x) >> 3)
-#define SPFC_BYTES_TO_DW_NUM(x) ((x) >> 2)
-
-#define UNF_GET_SHIFTMASK(__src, __shift, __mask) (((__src) & (__mask)) >> (__shift))
-#define UNF_FC_SET_SHIFTMASK(__des, __val, __shift, __mask) \
- ((__des) = (((__des) & ~(__mask)) | (((__val) << (__shift)) & (__mask))))
-
-/* R_CTL */
-#define UNF_FC_HEADER_RCTL_MASK (0xFF000000)
-#define UNF_FC_HEADER_RCTL_SHIFT (24)
-#define UNF_FC_HEADER_RCTL_DWORD (0)
-#define UNF_GET_FC_HEADER_RCTL(__pfcheader) \
- UNF_GET_SHIFTMASK(((u32 *)(void *)(__pfcheader))[UNF_FC_HEADER_RCTL_DWORD], \
- UNF_FC_HEADER_RCTL_SHIFT, UNF_FC_HEADER_RCTL_MASK)
-
-#define UNF_SET_FC_HEADER_RCTL(__pfcheader, __val) \
- do { \
- UNF_FC_SET_SHIFTMASK(((u32 *)(void *)(__pfcheader)[UNF_FC_HEADER_RCTL_DWORD], \
- __val, UNF_FC_HEADER_RCTL_SHIFT, UNF_FC_HEADER_RCTL_MASK) \
- } while (0)
-
-/* PRLI PARAM 3 */
-#define SPFC_PRLI_PARAM_WXFER_ENABLE_MASK (0x00000001)
-#define SPFC_PRLI_PARAM_WXFER_ENABLE_SHIFT (0)
-#define SPFC_PRLI_PARAM_WXFER_DWORD (3)
-#define SPFC_GET_PRLI_PARAM_WXFER(__pfcheader) \
- UNF_GET_SHIFTMASK(((u32 *)(void *)(__pfcheader))[SPFC_PRLI_PARAM_WXFER_DWORD], \
- SPFC_PRLI_PARAM_WXFER_ENABLE_SHIFT, \
- SPFC_PRLI_PARAM_WXFER_ENABLE_MASK)
-
-#define SPFC_PRLI_PARAM_CONF_ENABLE_MASK (0x00000080)
-#define SPFC_PRLI_PARAM_CONF_ENABLE_SHIFT (7)
-#define SPFC_PRLI_PARAM_CONF_DWORD (3)
-#define SPFC_GET_PRLI_PARAM_CONF(__pfcheader) \
- UNF_GET_SHIFTMASK(((u32 *)(void *)(__pfcheader))[SPFC_PRLI_PARAM_CONF_DWORD], \
- SPFC_PRLI_PARAM_CONF_ENABLE_SHIFT, \
- SPFC_PRLI_PARAM_CONF_ENABLE_MASK)
-
-#define SPFC_PRLI_PARAM_REC_ENABLE_MASK (0x00000400)
-#define SPFC_PRLI_PARAM_REC_ENABLE_SHIFT (10)
-#define SPFC_PRLI_PARAM_CONF_REC (3)
-#define SPFC_GET_PRLI_PARAM_REC(__pfcheader) \
- UNF_GET_SHIFTMASK(((u32 *)(void *)(__pfcheader))[SPFC_PRLI_PARAM_CONF_REC], \
- SPFC_PRLI_PARAM_REC_ENABLE_SHIFT, SPFC_PRLI_PARAM_REC_ENABLE_MASK)
-
-#define SPFC_FUNCTION_ENTER \
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ALL, \
- "%s Enter.", __func__)
-#define SPFC_FUNCTION_RETURN \
- FC_DRV_PRINT(UNF_LOG_NORMAL, UNF_ALL, \
- "%s Return.", __func__)
-
-#define SPFC_SPIN_LOCK_IRQSAVE(interrupt, hw_adapt_lock, flags) \
- do { \
- if ((interrupt) == false) { \
- spin_lock_irqsave(&(hw_adapt_lock), flags); \
- } \
- } while (0)
-
-#define SPFC_SPIN_UNLOCK_IRQRESTORE(interrupt, hw_adapt_lock, flags) \
- do { \
- if ((interrupt) == false) { \
- spin_unlock_irqrestore(&(hw_adapt_lock), flags); \
- } \
- } while (0)
-
-#define FC_CHECK_VALID(condition, fail_do) \
- do { \
- if (unlikely(!(condition))) { \
- FC_DRV_PRINT(UNF_LOG_REG_ATT, \
- UNF_ERR, "Para check(%s) invalid", \
- #condition); \
- fail_do; \
- } \
- } while (0)
-
-#define RETURN_ERROR_S32 (-1)
-#define UNF_RETURN_ERROR_S32 (-1)
-
-enum SPFC_LOG_CTRL_E {
- SPFC_LOG_ALL = 0,
- SPFC_LOG_SCQE_RX,
- SPFC_LOG_ELS_TX,
- SPFC_LOG_ELS_RX,
- SPFC_LOG_GS_TX,
- SPFC_LOG_GS_RX,
- SPFC_LOG_BLS_TX,
- SPFC_LOG_BLS_RX,
- SPFC_LOG_FCP_TX,
- SPFC_LOG_FCP_RX,
- SPFC_LOG_SESS_TX,
- SPFC_LOG_SESS_RX,
- SPFC_LOG_DIF_TX,
- SPFC_LOG_DIF_RX
-};
-
-extern u32 spfc_log_en;
-#define SPFC_LOG_EN(hba, log_ctrl) (spfc_log_en + (log_ctrl))
-
-enum SPFC_HBA_ERR_STAT_E {
- SPFC_STAT_CTXT_FLUSH_DONE = 0,
- SPFC_STAT_SQ_WAIT_EMPTY,
- SPFC_STAT_LAST_GS_SCQE,
- SPFC_STAT_SQ_POOL_EMPTY,
- SPFC_STAT_PARENT_IO_FLUSHED,
- SPFC_STAT_ROOT_IO_FLUSHED, /* 5 */
- SPFC_STAT_ROOT_SQ_FULL,
- SPFC_STAT_ELS_RSP_EXCH_REUSE,
- SPFC_STAT_GS_RSP_EXCH_REUSE,
- SPFC_STAT_SQ_IO_BUFFER_CLEARED,
- SPFC_STAT_PARENT_SQ_NOT_OFFLOADED, /* 10 */
- SPFC_STAT_PARENT_SQ_QUEUE_DELAYED_WORK,
- SPFC_STAT_PARENT_SQ_INVALID_CACHED_ID,
- SPFC_HBA_STAT_BUTT
-};
-
-#define SPFC_DWORD_BYTE (4)
-#define SPFC_QWORD_BYTE (8)
-#define SPFC_SHIFT_TO_U64(x) ((x) >> 3)
-#define SPFC_SHIFT_TO_U32(x) ((x) >> 2)
-
-void spfc_cpu_to_big64(void *addr, u32 size);
-void spfc_big_to_cpu64(void *addr, u32 size);
-void spfc_cpu_to_big32(void *addr, u32 size);
-void spfc_big_to_cpu32(void *addr, u32 size);
-void spfc_cpu_to_be24(u8 *data, u32 value);
-u32 spfc_big_to_cpu24(u8 *data);
-
-void spfc_print_buff(u32 dbg_level, void *buff, u32 size);
-
-u32 spfc_log2n(u32 val);
-
-static inline void spfc_swap_16_in_32(u32 *paddr, u32 length)
-{
- u32 i;
-
- for (i = 0; i < length; i++) {
- paddr[i] =
- ((((paddr[i]) & UNF_MASK_BIT_31_16) >> UNF_SHIFT_16) |
- (((paddr[i]) & UNF_MASK_BIT_15_0) << UNF_SHIFT_16));
- }
-}
-
-#endif /* __SPFC_UTILS_H__ */
diff --git a/drivers/scsi/spfc/hw/spfc_wqe.c b/drivers/scsi/spfc/hw/spfc_wqe.c
deleted file mode 100644
index 61909c51bc8c..000000000000
--- a/drivers/scsi/spfc/hw/spfc_wqe.c
+++ /dev/null
@@ -1,646 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#include "spfc_wqe.h"
-#include "spfc_module.h"
-#include "spfc_service.h"
-
-void spfc_build_tmf_rsp_wqe_ts_header(struct unf_frame_pkg *pkg,
- struct spfc_sqe_tmf_rsp *sqe, u16 exi_base,
- u32 scqn)
-{
- sqe->ts_sl.task_type = SPFC_SQE_FCP_TMF_TRSP;
- sqe->ts_sl.wd0.conn_id =
- (u16)(pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX]);
-
- if (UNF_GET_RXID(pkg) == INVALID_VALUE16)
- sqe->ts_sl.local_xid = INVALID_VALUE16;
- else
- sqe->ts_sl.local_xid = UNF_GET_RXID(pkg) + exi_base;
-
- sqe->ts_sl.tmf_rsp.wd0.scqn = scqn;
- sqe->ts_sl.magic_num = UNF_GETXCHGALLOCTIME(pkg);
-}
-
-void spfc_build_common_wqe_ctrls(struct spfc_wqe_ctrl *ctrl_sl, u8 task_len)
-{
- /* "BDSL" field of CtrlS - defines the size of BDS, which varies from 0
- * to 2040 bytes (8 bits of 8 bytes' chunk)
- */
- ctrl_sl->ch.wd0.bdsl = 0;
-
- /* "DrvSL" field of CtrlS - defines the size of DrvS, which varies from
- * 0 to 24 bytes
- */
- ctrl_sl->ch.wd0.drv_sl = 0;
-
- /* a.
- * b1 - linking WQE, which will be only used in linked page architecture
- * instead of ring, it's a special control WQE which does not contain
- * any buffer or inline data information, and will only be consumed by
- * hardware. The size is aligned to WQEBB/WQE b0 - normal WQE, either
- * normal SEG WQE or inline data WQE
- */
- ctrl_sl->ch.wd0.wf = 0;
-
- /*
- * "CF" field of CtrlS - Completion Format - defines the format of CS.
- * a. b0 - Status information is embedded inside of Completion Section
- * b. b1 - Completion Section keeps SGL, where Status information
- * should be written. (For the definition of SGLs see ?4.1
- * .)
- */
- ctrl_sl->ch.wd0.cf = 0;
-
- /* "TSL" field of CtrlS - defines the size of TS, which varies from 0 to
- * 248 bytes
- */
- ctrl_sl->ch.wd0.tsl = task_len;
-
- /*
- * Variable length SGE (vSGE). The size of SGE is 16 bytes. The vSGE
- * format is of two types, which are defined by "VA " field of CtrlS.
- * "VA" stands for Virtual Address: o b0. SGE comprises 64-bits
- * buffer's pointer and 31-bits Length, each SGE can only support up to
- * 2G-1B, it can guarantee each single SGE length can not exceed 2GB by
- * nature, A byte count value of zero means a 0byte data transfer. o b1.
- * SGE comprises 64-bits buffer's pointer, 31-bits Length and 30-bits
- * Key of the Translation table , each SGE can only support up to 2G-1B,
- * it can guarantee each single SGE length can not exceed 2GB by nature,
- * A byte count value of zero means a 0byte data transfer
- */
- ctrl_sl->ch.wd0.va = 0;
-
- /*
- * "DF" field of CtrlS - Data Format - defines the format of BDS
- * a. b0 - BDS carries the list of SGEs (SGL)
- * b. b1 - BDS carries the inline data
- */
- ctrl_sl->ch.wd0.df = 0;
-
- /* "CR" - Completion is Required - marks CQE generation request per WQE
- */
- ctrl_sl->ch.wd0.cr = 1;
-
- /* "DIFSL" field of CtrlS - defines the size of DIFS, which varies from
- * 0 to 56 bytes
- */
- ctrl_sl->ch.wd0.dif_sl = 0;
-
- /* "CSL" field of CtrlS - defines the size of CS, which varies from 0 to
- * 24 bytes
- */
- ctrl_sl->ch.wd0.csl = 0;
-
- /* CtrlSL describes the size of CtrlS in 8 bytes chunks. The
- * value Zero is not valid
- */
- ctrl_sl->ch.wd0.ctrl_sl = 1;
-
- /* "O" - Owner - marks ownership of WQE */
- ctrl_sl->ch.wd0.owner = 0;
-}
-
-void spfc_build_trd_twr_wqe_ctrls(struct unf_frame_pkg *pkg, struct spfc_sqe *sqe)
-{
- /* "BDSL" field of CtrlS - defines the size of BDS, which varies from 0
- * to 2040 bytes (8 bits of 8 bytes' chunk)
- */
- /* TrdWqe carry 2 SGE defaultly, 4DW per SGE, the value is 4 because
- * unit is 2DW, in double SGL mode, bdsl is 2
- */
- sqe->ctrl_sl.ch.wd0.bdsl = SPFC_T_RD_WR_WQE_CTR_BDSL_SIZE;
-
- /* "DrvSL" field of CtrlS - defines the size of DrvS, which varies from
- * 0 to 24 bytes
- */
- /* DrvSL = 0 */
- sqe->ctrl_sl.ch.wd0.drv_sl = 0;
-
- /* a.
- * b1 - linking WQE, which will be only used in linked page architecture
- * instead of ring, it's a special control WQE which does not contain
- * any buffer or inline data information, and will only be consumed by
- * hardware. The size is aligned to WQEBB/WQE b0 - normal WQE, either
- * normal SEG WQE or inline data WQE
- */
- /* normal wqe */
- sqe->ctrl_sl.ch.wd0.wf = 0;
-
- /*
- * "CF" field of CtrlS - Completion Format - defines the format of CS.
- * a. b0 - Status information is embedded inside of Completion Section
- * b. b1 - Completion Section keeps SGL, where Status information
- * should be written. (For the definition of SGLs see ?4.1)
- */
- /* by SCQE mode, the value is ignored */
- sqe->ctrl_sl.ch.wd0.cf = 0;
-
- /* "TSL" field of CtrlS - defines the size of TS, which varies from 0 to
- * 248 bytes
- */
- /* TSL is configured by 56 bytes */
- sqe->ctrl_sl.ch.wd0.tsl =
- sizeof(struct spfc_sqe_ts) / SPFC_WQE_SECTION_CHUNK_SIZE;
-
- /*
- * Variable length SGE (vSGE). The size of SGE is 16 bytes. The vSGE
- * format is of two types, which are defined by "VA " field of CtrlS.
- * "VA" stands for Virtual Address: o b0. SGE comprises 64-bits buffer's
- * pointer and 31-bits Length, each SGE can only support up to 2G-1B, it
- * can guarantee each single SGE length can not exceed 2GB by nature, A
- * byte count value of zero means a 0byte data transfer. o b1. SGE
- * comprises 64-bits buffer's pointer, 31-bits Length and 30-bits Key of
- * the Translation table , each SGE can only support up to 2G-1B, it can
- * guarantee each single SGE length can not exceed 2GB by nature, A byte
- * count value of zero means a 0byte data transfer
- */
- sqe->ctrl_sl.ch.wd0.va = 0;
-
- /*
- * "DF" field of CtrlS - Data Format - defines the format of BDS
- * a. b0 - BDS carries the list of SGEs (SGL)
- * b. b1 - BDS carries the inline data
- */
- sqe->ctrl_sl.ch.wd0.df = 0;
-
- /* "CR" - Completion is Required - marks CQE generation request per WQE
- */
- /* by SCQE mode, this value is ignored */
- sqe->ctrl_sl.ch.wd0.cr = 1;
-
- /* "DIFSL" field of CtrlS - defines the size of DIFS, which varies from
- * 0 to 56 bytes.
- */
- sqe->ctrl_sl.ch.wd0.dif_sl = 0;
-
- /* "CSL" field of CtrlS - defines the size of CS, which varies from 0 to
- * 24 bytes
- */
- sqe->ctrl_sl.ch.wd0.csl = 0;
-
- /* CtrlSL describes the size of CtrlS in 8 bytes chunks. The
- * value Zero is not valid.
- */
- sqe->ctrl_sl.ch.wd0.ctrl_sl = SPFC_T_RD_WR_WQE_CTR_CTRLSL_SIZE;
-
- /* "O" - Owner - marks ownership of WQE */
- sqe->ctrl_sl.ch.wd0.owner = 0;
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_service_wqe_ts_common
- * Function Description : Construct the DW1~DW3 field in the Parent SQ WQE
- * request of the ELS and ELS_RSP requests.
- * Input Parameters : struct spfc_sqe_ts *sqe_ts u32 rport_index u16 local_xid
- * u16 remote_xid u16 data_len
- * Output Parameters : N/A
- * Return Type : void
- ****************************************************************************
- */
-void spfc_build_service_wqe_ts_common(struct spfc_sqe_ts *sqe_ts, u32 rport_index,
- u16 local_xid, u16 remote_xid, u16 data_len)
-{
- sqe_ts->local_xid = local_xid;
-
- sqe_ts->wd0.conn_id = (u16)rport_index;
- sqe_ts->wd0.remote_xid = remote_xid;
-
- sqe_ts->cont.els_gs_elsrsp_comm.data_len = data_len;
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_els_gs_wqe_sge
- * Function Description : Construct the SGE field of the ELS and ELS_RSP WQE.
- * The SGE and frame content have been converted to large ends in this
- * function.
- * Input Parameters: struct spfc_sqe *sqe void *buf_addr u32 buf_len u32 xid
- * Output Parameters : N/A
- * Return Type : void
- ****************************************************************************
- */
-void spfc_build_els_gs_wqe_sge(struct spfc_sqe *sqe, void *buf_addr, u64 phy_addr,
- u32 buf_len, u32 xid, void *handle)
-{
- u64 els_rsp_phy_addr;
- struct spfc_variable_sge *sge = NULL;
-
- /* Fill in SGE and convert it to big-endian. */
- sge = &sqe->sge[ARRAY_INDEX_0];
- els_rsp_phy_addr = phy_addr;
- sge->buf_addr_hi = SPFC_HIGH_32_BITS(els_rsp_phy_addr);
- sge->buf_addr_lo = SPFC_LOW_32_BITS(els_rsp_phy_addr);
- sge->wd0.buf_len = buf_len;
- sge->wd0.r_flag = 0;
- sge->wd1.extension_flag = SPFC_WQE_SGE_NOT_EXTEND_FLAG;
- sge->wd1.buf_addr_gpa = SPFC_ZEROCOPY_PCIE_TEMPLATE_VALUE;
- sge->wd1.xid = 0;
- sge->wd1.last_flag = SPFC_WQE_SGE_LAST_FLAG;
- spfc_cpu_to_big32(sge, sizeof(*sge));
-
- /* Converts the payload of an FC frame into a big end. */
- if (buf_addr)
- spfc_cpu_to_big32(buf_addr, buf_len);
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_els_wqe_ts_rsp
- * Function Description : Construct the DW2~DW6 field in the Parent SQ WQE
- * of the ELS_RSP request.
- * Input Parameters : struct spfc_sqe *sqe void *sq_info void *frame_pld
- * u16 type u16 cmnd u32 scqn
- * Output Parameters: N/A
- * Return Type : void
- ****************************************************************************
- */
-void spfc_build_els_wqe_ts_rsp(struct spfc_sqe *sqe, void *info,
- struct unf_frame_pkg *pkg, void *frame_pld,
- u16 type, u16 cmnd)
-{
- struct unf_prli_payload *prli_acc_pld = NULL;
- struct spfc_sqe_els_rsp *els_rsp = NULL;
- struct spfc_sqe_ts *sqe_ts = NULL;
- struct spfc_parent_sq_info *sq_info = NULL;
- struct spfc_hba_info *hba = NULL;
- struct unf_fc_head *pkg_fc_hdr_info = NULL;
- struct spfc_parent_queue_info *prnt_q_info = (struct spfc_parent_queue_info *)info;
-
- FC_CHECK_RETURN_VOID(sqe);
- FC_CHECK_RETURN_VOID(frame_pld);
-
- sqe_ts = &sqe->ts_sl;
- els_rsp = &sqe_ts->cont.els_rsp;
- sqe_ts->task_type = SPFC_SQE_ELS_RSP;
-
- /* The default chip does not need to update parameters. */
- els_rsp->wd1.para_update = 0x0;
-
- sq_info = &prnt_q_info->parent_sq_info;
- hba = (struct spfc_hba_info *)sq_info->hba;
-
- pkg_fc_hdr_info = &pkg->frame_head;
- els_rsp->sid = pkg_fc_hdr_info->csctl_sid;
- els_rsp->did = pkg_fc_hdr_info->rctl_did;
- els_rsp->wd7.hotpooltag = UNF_GET_HOTPOOL_TAG(pkg) + hba->exi_base;
- els_rsp->wd2.class_mode = FC_PROTOCOL_CLASS_3;
-
- if (type == ELS_RJT)
- els_rsp->wd2.class_mode = pkg->class_mode;
-
- /* When the PLOGI request is sent, the microcode needs to be instructed
- * to clear the I/O related to the link to avoid data inconsistency
- * caused by the disorder of the IO.
- */
- if ((cmnd == ELS_LOGO || cmnd == ELS_PLOGI)) {
- els_rsp->wd1.clr_io = 1;
- els_rsp->wd6.reset_exch_start = hba->exi_base;
- els_rsp->wd6.reset_exch_end =
- hba->exi_base + (hba->exi_count - 1);
- els_rsp->wd7.scqn =
- prnt_q_info->parent_sts_scq_info.cqm_queue_id;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "Port(0x%x) send cmd(0x%x) to RPort(0x%x),rport index(0x%x), notify clean io start 0x%x, end 0x%x, scqn 0x%x.",
- sq_info->local_port_id, cmnd, sq_info->remote_port_id,
- sq_info->rport_index, els_rsp->wd6.reset_exch_start,
- els_rsp->wd6.reset_exch_end, els_rsp->wd7.scqn);
-
- return;
- }
-
- if (type == ELS_RJT)
- return;
-
- /* Enter WQE in the PrliAcc negotiation parameter, and fill in the
- * Update flag in WQE.
- */
- if (cmnd == ELS_PRLI) {
- /* The chip updates the PLOGI ACC negotiation parameters. */
- els_rsp->wd2.seq_cnt = sq_info->plogi_co_parms.seq_cnt;
- els_rsp->wd2.e_d_tov = sq_info->plogi_co_parms.ed_tov;
- els_rsp->wd2.tx_mfs = sq_info->plogi_co_parms.tx_mfs;
- els_rsp->e_d_tov_timer_val = sq_info->plogi_co_parms.ed_tov_time;
-
- /* The chip updates the PRLI ACC parameter. */
- prli_acc_pld = (struct unf_prli_payload *)frame_pld;
- els_rsp->wd4.xfer_dis = SPFC_GET_PRLI_PARAM_WXFER(prli_acc_pld->parms);
- els_rsp->wd4.conf = SPFC_GET_PRLI_PARAM_CONF(prli_acc_pld->parms);
- els_rsp->wd4.rec = SPFC_GET_PRLI_PARAM_REC(prli_acc_pld->parms);
-
- els_rsp->wd1.para_update = 0x03;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "Port(0x%x) save rport index(0x%x) login parms,seqcnt:0x%x,e_d_tov:0x%x,txmfs:0x%x,e_d_tovtimerval:0x%x, xfer_dis:0x%x,conf:0x%x,rec:0x%x.",
- sq_info->local_port_id, sq_info->rport_index,
- els_rsp->wd2.seq_cnt, els_rsp->wd2.e_d_tov,
- els_rsp->wd2.tx_mfs, els_rsp->e_d_tov_timer_val,
- els_rsp->wd4.xfer_dis, els_rsp->wd4.conf, els_rsp->wd4.rec);
- }
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_els_wqe_ts_req
- * Function Description: Construct the DW2~DW4 field in the Parent SQ WQE
- * of the ELS request.
- * Input Parameters: struct spfc_sqe *sqe void *sq_info u16 cmnd u32 scqn
- * Output Parameters: N/A
- * Return Type: void
- ****************************************************************************
- */
-void spfc_build_els_wqe_ts_req(struct spfc_sqe *sqe, void *info, u32 scqn,
- void *frame_pld, struct unf_frame_pkg *pkg)
-{
- struct spfc_sqe_ts *sqe_ts = NULL;
- struct spfc_sqe_t_els_gs *els_req = NULL;
- struct spfc_parent_sq_info *sq_info = NULL;
- struct spfc_hba_info *hba = NULL;
- struct unf_fc_head *pkg_fc_hdr_info = NULL;
- u16 cmnd;
-
- cmnd = SPFC_GET_LS_GS_CMND_CODE(pkg->cmnd);
-
- sqe_ts = &sqe->ts_sl;
- if (pkg->type == UNF_PKG_GS_REQ)
- sqe_ts->task_type = SPFC_SQE_GS_CMND;
- else
- sqe_ts->task_type = SPFC_SQE_ELS_CMND;
-
- sqe_ts->magic_num = UNF_GETXCHGALLOCTIME(pkg);
-
- els_req = &sqe_ts->cont.t_els_gs;
- pkg_fc_hdr_info = &pkg->frame_head;
-
- sq_info = (struct spfc_parent_sq_info *)info;
- hba = (struct spfc_hba_info *)sq_info->hba;
- els_req->sid = pkg_fc_hdr_info->csctl_sid;
- els_req->did = pkg_fc_hdr_info->rctl_did;
-
- /* When the PLOGI request is sent, the microcode needs to be instructed
- * to clear the I/O related to the link to avoid data inconsistency
- * caused by the disorder of the IO.
- */
- if ((cmnd == ELS_LOGO || cmnd == ELS_PLOGI) && hba) {
- els_req->wd4.clr_io = 1;
- els_req->wd6.reset_exch_start = hba->exi_base;
- els_req->wd6.reset_exch_end = hba->exi_base + (hba->exi_count - 1);
- els_req->wd7.scqn = scqn;
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "Port(0x%x) Rport(0x%x) SID(0x%x) send %s to DID(0x%x), notify clean io start 0x%x, end 0x%x, scqn 0x%x.",
- hba->port_cfg.port_id, sq_info->rport_index,
- sq_info->local_port_id, (cmnd == ELS_PLOGI) ? "PLOGI" : "LOGO",
- sq_info->remote_port_id, els_req->wd6.reset_exch_start,
- els_req->wd6.reset_exch_end, scqn);
-
- return;
- }
-
- /* The chip updates the PLOGI ACC negotiation parameters. */
- if (cmnd == ELS_PRLI) {
- els_req->wd5.seq_cnt = sq_info->plogi_co_parms.seq_cnt;
- els_req->wd5.e_d_tov = sq_info->plogi_co_parms.ed_tov;
- els_req->wd5.tx_mfs = sq_info->plogi_co_parms.tx_mfs;
- els_req->e_d_tov_timer_val = sq_info->plogi_co_parms.ed_tov_time;
-
- els_req->wd4.rec_support = hba->port_cfg.tape_support ? 1 : 0;
- els_req->wd4.para_update = 0x01;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT,
- UNF_INFO,
- "Port(0x%x) save rport index(0x%x) login parms,seqcnt:0x%x,e_d_tov:0x%x,txmfs:0x%x,e_d_tovtimerval:0x%x.",
- sq_info->local_port_id, sq_info->rport_index,
- els_req->wd5.seq_cnt, els_req->wd5.e_d_tov,
- els_req->wd5.tx_mfs, els_req->e_d_tov_timer_val);
- }
-
- if (cmnd == ELS_ECHO)
- els_req->echo_flag = true;
-
- if (cmnd == ELS_REC) {
- els_req->wd4.rec_flag = 1;
- els_req->wd4.origin_hottag = pkg->origin_hottag + hba->exi_base;
- els_req->origin_magicnum = pkg->origin_magicnum;
-
- FC_DRV_PRINT(UNF_LOG_LOGIN_ATT, UNF_MAJOR,
- "Port(0x%x) Rport(0x%x) SID(0x%x) send Rec to DID(0x%x), origin_hottag 0x%x",
- hba->port_cfg.port_id, sq_info->rport_index,
- sq_info->local_port_id, sq_info->remote_port_id,
- els_req->wd4.origin_hottag);
- }
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_bls_wqe_ts_req
- * Function Description: Construct the DW2 field in the Parent SQ WQE of
- * the ELS request, that is, ABTS parameter.
- * Input Parameters:struct unf_frame_pkg *pkg void *hba
- * Output Parameters: N/A
- * Return Type: void
- ****************************************************************************
- */
-void spfc_build_bls_wqe_ts_req(struct spfc_sqe *sqe, struct unf_frame_pkg *pkg, void *handle)
-{
- struct spfc_sqe_abts *abts;
-
- sqe->ts_sl.task_type = SPFC_SQE_BLS_CMND;
- sqe->ts_sl.magic_num = UNF_GETXCHGALLOCTIME(pkg);
-
- abts = &sqe->ts_sl.cont.abts;
- abts->fh_parm_abts = pkg->frame_head.parameter;
- abts->hotpooltag = UNF_GET_HOTPOOL_TAG(pkg) +
- ((struct spfc_hba_info *)handle)->exi_base;
- abts->release_timer = UNF_GET_XID_RELEASE_TIMER(pkg);
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_service_wqe_ctrl_section
- * Function Description: fill Parent SQ WQE and Root SQ WQE's Control Section
- * Input Parameters : struct spfc_wqe_ctrl *wqe_cs u32 ts_size u32 bdsl
- * Output Parameters : N/A
- * Return Type : void
- ****************************************************************************
- */
-void spfc_build_service_wqe_ctrl_section(struct spfc_wqe_ctrl *wqe_cs, u32 ts_size,
- u32 bdsl)
-{
- wqe_cs->ch.wd0.bdsl = bdsl;
- wqe_cs->ch.wd0.drv_sl = 0;
- wqe_cs->ch.wd0.rsvd0 = 0;
- wqe_cs->ch.wd0.wf = 0;
- wqe_cs->ch.wd0.cf = 0;
- wqe_cs->ch.wd0.tsl = ts_size;
- wqe_cs->ch.wd0.va = 0;
- wqe_cs->ch.wd0.df = 0;
- wqe_cs->ch.wd0.cr = 1;
- wqe_cs->ch.wd0.dif_sl = 0;
- wqe_cs->ch.wd0.csl = 0;
- wqe_cs->ch.wd0.ctrl_sl = SPFC_BYTES_TO_QW_NUM(sizeof(*wqe_cs)); /* divided by 8 */
- wqe_cs->ch.wd0.owner = 0;
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_wqe_owner_pmsn
- * Function Description: This field is filled using the value of Control
- * Section of Parent SQ WQE.
- * Input Parameters: struct spfc_wqe_ctrl *wqe_cs u16 owner u16 pmsn
- * Output Parameters : N/A
- * Return Type: void
- ****************************************************************************
- */
-void spfc_build_wqe_owner_pmsn(struct spfc_sqe *io_sqe, u16 owner, u16 pmsn)
-{
- struct spfc_wqe_ctrl *wqe_cs = &io_sqe->ctrl_sl;
- struct spfc_wqe_ctrl *wqee_cs = &io_sqe->ectrl_sl;
-
- wqe_cs->qsf.wqe_sn = pmsn;
- wqe_cs->qsf.dump_wqe_sn = wqe_cs->qsf.wqe_sn;
- wqe_cs->ch.wd0.owner = (u32)owner;
- wqee_cs->ch.ctrl_ch_val = wqe_cs->ch.ctrl_ch_val;
- wqee_cs->qsf.wqe_sn = wqe_cs->qsf.wqe_sn;
- wqee_cs->qsf.dump_wqe_sn = wqe_cs->qsf.dump_wqe_sn;
-}
-
-/* ****************************************************************************
- * Function Name : spfc_convert_parent_wqe_to_big_endian
- * Function Description: Set the Done field of Parent SQ WQE and convert
- * Control Section and Task Section to big-endian.
- * Input Parameters:struct spfc_sqe *sqe
- * Output Parameters : N/A
- * Return Type : void
- ****************************************************************************
- */
-void spfc_convert_parent_wqe_to_big_endian(struct spfc_sqe *sqe)
-{
- if (likely(sqe->ts_sl.task_type != SPFC_TASK_T_TRESP &&
- sqe->ts_sl.task_type != SPFC_TASK_T_TMF_RESP)) {
- /* Convert Control Secton and Task Section to big-endian. Before
- * the SGE enters the queue, the upper-layer driver converts the
- * SGE and Task Section to the big-endian mode.
- */
- spfc_cpu_to_big32(&sqe->ctrl_sl, sizeof(sqe->ctrl_sl));
- spfc_cpu_to_big32(&sqe->ts_sl, sizeof(sqe->ts_sl));
- spfc_cpu_to_big32(&sqe->ectrl_sl, sizeof(sqe->ectrl_sl));
- spfc_cpu_to_big32(&sqe->sid, sizeof(sqe->sid));
- spfc_cpu_to_big32(&sqe->did, sizeof(sqe->did));
- spfc_cpu_to_big32(&sqe->wqe_gpa, sizeof(sqe->wqe_gpa));
- spfc_cpu_to_big32(&sqe->db_val, sizeof(sqe->db_val));
- } else {
- /* The SPFC_TASK_T_TRESP may use the SGE as the Task Section to
- * convert the entire SQE into a large end.
- */
- spfc_cpu_to_big32(sqe, sizeof(struct spfc_sqe_tresp));
- }
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_cmdqe_common
- * Function Description : Assemble the Cmdqe Common part.
- * Input Parameters: union spfc_cmdqe *cmd_qe enum spfc_task_type task_type u16 rxid
- * Output Parameters : N/A
- * Return Type: void
- ****************************************************************************
- */
-void spfc_build_cmdqe_common(union spfc_cmdqe *cmd_qe, enum spfc_task_type task_type,
- u16 rxid)
-{
- cmd_qe->common.wd0.task_type = task_type;
- cmd_qe->common.wd0.rx_id = rxid;
- cmd_qe->common.wd0.rsvd0 = 0;
-}
-
-#define SPFC_STANDARD_SIRT_ENABLE (1)
-#define SPFC_STANDARD_SIRT_DISABLE (0)
-#define SPFC_UNKNOWN_ID (0xFFFF)
-
-void spfc_build_icmnd_wqe_ts_header(struct unf_frame_pkg *pkg, struct spfc_sqe *sqe,
- u8 task_type, u16 exi_base, u8 port_idx)
-{
- sqe->ts_sl.local_xid = (u16)UNF_GET_HOTPOOL_TAG(pkg) + exi_base;
- sqe->ts_sl.task_type = task_type;
- sqe->ts_sl.wd0.conn_id =
- (u16)(pkg->private_data[PKG_PRIVATE_XCHG_RPORT_INDEX]);
-
- sqe->ts_sl.wd0.remote_xid = SPFC_UNKNOWN_ID;
- sqe->ts_sl.magic_num = UNF_GETXCHGALLOCTIME(pkg);
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_icmnd_wqe_ts
- * Function Description : Constructing the TS Domain of the ICmnd
- * Input Parameters: void *hba struct unf_frame_pkg *pkg
- * struct spfc_sqe_ts *sqe_ts
- * Output Parameters :N/A
- * Return Type : void
- ****************************************************************************
- */
-void spfc_build_icmnd_wqe_ts(void *handle, struct unf_frame_pkg *pkg,
- struct spfc_sqe_ts *sqe_ts, union spfc_sqe_ts_ex *sqe_tsex)
-{
- struct spfc_sqe_icmnd *icmnd = &sqe_ts->cont.icmnd;
- struct spfc_hba_info *hba = NULL;
-
- hba = (struct spfc_hba_info *)handle;
-
- sqe_ts->cdb_type = 0;
- memcpy(icmnd->fcp_cmnd_iu, pkg->fcp_cmnd, sizeof(struct unf_fcp_cmnd));
-
- if (sqe_ts->task_type == SPFC_SQE_FCP_ITMF) {
- icmnd->info.tmf.w0.bs.reset_exch_start = hba->exi_base;
- icmnd->info.tmf.w0.bs.reset_exch_end = hba->exi_base + hba->exi_count - 1;
-
- icmnd->info.tmf.w1.bs.reset_did = UNF_GET_DID(pkg);
- /* delivers the marker status flag to the microcode. */
- icmnd->info.tmf.w1.bs.marker_sts = 1;
- SPFC_GET_RESET_TYPE(UNF_GET_TASK_MGMT_FLAGS(pkg->fcp_cmnd->control),
- icmnd->info.tmf.w1.bs.reset_type);
-
- icmnd->info.tmf.w2.bs.reset_sid = UNF_GET_SID(pkg);
-
- memcpy(icmnd->info.tmf.reset_lun, pkg->fcp_cmnd->lun,
- sizeof(icmnd->info.tmf.reset_lun));
- }
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_icmnd_wqe_ctrls
- * Function Description : The CtrlS domain of the ICmnd is constructed. The
- * analysis result is the same as that of the TWTR.
- * Input Parameters: struct unf_frame_pkg *pkg struct spfc_sqe *sqe
- * Output Parameters: N/A
- * Return Type: void
- ****************************************************************************
- */
-void spfc_build_icmnd_wqe_ctrls(struct unf_frame_pkg *pkg, struct spfc_sqe *sqe)
-{
- spfc_build_trd_twr_wqe_ctrls(pkg, sqe);
-}
-
-/* ****************************************************************************
- * Function Name : spfc_build_srq_wqe_ctrls
- * Function Description : Construct the CtrlS domain of the ICmnd. The analysis
- * result is the same as that of the TWTR.
- * Input Parameters : struct spfc_rqe *rqe u16 owner u16 pmsn
- * Output Parameters : N/A
- * Return Type : void
- ****************************************************************************
- */
-void spfc_build_srq_wqe_ctrls(struct spfc_rqe *rqe, u16 owner, u16 pmsn)
-{
- struct spfc_wqe_ctrl_ch *wqe_ctrls = NULL;
-
- wqe_ctrls = &rqe->ctrl_sl.ch;
- wqe_ctrls->wd0.owner = owner;
- wqe_ctrls->wd0.ctrl_sl = sizeof(struct spfc_wqe_ctrl) >> UNF_SHIFT_3;
- wqe_ctrls->wd0.csl = 1;
- wqe_ctrls->wd0.dif_sl = 0;
- wqe_ctrls->wd0.cr = 1;
- wqe_ctrls->wd0.df = 0;
- wqe_ctrls->wd0.va = 0;
- wqe_ctrls->wd0.tsl = 0;
- wqe_ctrls->wd0.cf = 0;
- wqe_ctrls->wd0.wf = 0;
- wqe_ctrls->wd0.drv_sl = sizeof(struct spfc_rqe_drv) >> UNF_SHIFT_3;
- wqe_ctrls->wd0.bdsl = sizeof(struct spfc_constant_sge) >> UNF_SHIFT_3;
-
- rqe->ctrl_sl.wd0.wqe_msn = pmsn;
- rqe->ctrl_sl.wd0.dump_wqe_msn = rqe->ctrl_sl.wd0.wqe_msn;
-}
diff --git a/drivers/scsi/spfc/hw/spfc_wqe.h b/drivers/scsi/spfc/hw/spfc_wqe.h
deleted file mode 100644
index ec6d7bbdf8f9..000000000000
--- a/drivers/scsi/spfc/hw/spfc_wqe.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */
-
-#ifndef SPFC_WQE_H
-#define SPFC_WQE_H
-
-#include "unf_type.h"
-#include "unf_common.h"
-#include "spfc_hw_wqe.h"
-#include "spfc_parent_context.h"
-
-/* TGT WQE type */
-/* DRV->uCode via Parent SQ */
-#define SPFC_SQE_FCP_TRD SPFC_TASK_T_TREAD
-#define SPFC_SQE_FCP_TWR SPFC_TASK_T_TWRITE
-#define SPFC_SQE_FCP_TRSP SPFC_TASK_T_TRESP
-#define SPFC_SQE_FCP_TACK SPFC_TASK_T_TACK
-#define SPFC_SQE_ELS_CMND SPFC_TASK_T_ELS
-#define SPFC_SQE_ELS_RSP SPFC_TASK_T_ELS_RSP
-#define SPFC_SQE_GS_CMND SPFC_TASK_T_GS
-#define SPFC_SQE_BLS_CMND SPFC_TASK_T_ABTS
-#define SPFC_SQE_FCP_IREAD SPFC_TASK_T_IREAD
-#define SPFC_SQE_FCP_IWRITE SPFC_TASK_T_IWRITE
-#define SPFC_SQE_FCP_ITMF SPFC_TASK_T_ITMF
-#define SPFC_SQE_SESS_RST SPFC_TASK_T_SESS_RESET
-#define SPFC_SQE_FCP_TMF_TRSP SPFC_TASK_T_TMF_RESP
-#define SPFC_SQE_NOP SPFC_TASK_T_NOP
-/* DRV->uCode Via CMDQ */
-#define SPFC_CMDQE_ABTS_RSP SPFC_TASK_T_ABTS_RSP
-#define SPFC_CMDQE_ABORT SPFC_TASK_T_ABORT
-#define SPFC_CMDQE_SESS_DIS SPFC_TASK_T_SESS_DIS
-#define SPFC_CMDQE_SESS_DEL SPFC_TASK_T_SESS_DEL
-
-/* uCode->Drv Via CMD SCQ */
-#define SPFC_SCQE_FCP_TCMND SPFC_TASK_T_RCV_TCMND
-#define SPFC_SCQE_ELS_CMND SPFC_TASK_T_RCV_ELS_CMD
-#define SPFC_SCQE_ABTS_CMD SPFC_TASK_T_RCV_ABTS_CMD
-#define SPFC_SCQE_FCP_IRSP SPFC_TASK_T_IRESP
-#define SPFC_SCQE_FCP_ITMF_RSP SPFC_TASK_T_ITMF_RESP
-
-/* uCode->Drv Via STS SCQ */
-#define SPFC_SCQE_FCP_TSTS SPFC_TASK_T_TSTS
-#define SPFC_SCQE_GS_RSP SPFC_TASK_T_RCV_GS_RSP
-#define SPFC_SCQE_ELS_RSP SPFC_TASK_T_RCV_ELS_RSP
-#define SPFC_SCQE_ABTS_RSP SPFC_TASK_T_RCV_ABTS_RSP
-#define SPFC_SCQE_ELS_RSP_STS SPFC_TASK_T_ELS_RSP_STS
-#define SPFC_SCQE_ABORT_STS SPFC_TASK_T_ABORT_STS
-#define SPFC_SCQE_SESS_EN_STS SPFC_TASK_T_SESS_EN_STS
-#define SPFC_SCQE_SESS_DIS_STS SPFC_TASK_T_SESS_DIS_STS
-#define SPFC_SCQE_SESS_DEL_STS SPFC_TASK_T_SESS_DEL_STS
-#define SPFC_SCQE_SESS_RST_STS SPFC_TASK_T_SESS_RESET_STS
-#define SPFC_SCQE_ITMF_MARKER_STS SPFC_TASK_T_ITMF_MARKER_STS
-#define SPFC_SCQE_ABTS_MARKER_STS SPFC_TASK_T_ABTS_MARKER_STS
-#define SPFC_SCQE_FLUSH_SQ_STS SPFC_TASK_T_FLUSH_SQ_STS
-#define SPFC_SCQE_BUF_CLEAR_STS SPFC_TASK_T_BUFFER_CLEAR_STS
-#define SPFC_SCQE_CLEAR_SRQ_STS SPFC_TASK_T_CLEAR_SRQ_STS
-#define SPFC_SCQE_DIFX_RESULT_STS SPFC_TASK_T_DIFX_RESULT_STS
-#define SPFC_SCQE_XID_FREE_ABORT_STS SPFC_TASK_T_EXCH_ID_FREE_ABORT_STS
-#define SPFC_SCQE_EXCHID_TIMEOUT_STS SPFC_TASK_T_EXCHID_TIMEOUT_STS
-#define SPFC_SQE_NOP_STS SPFC_TASK_T_NOP_STS
-
-#define SPFC_LOW_32_BITS(__addr) ((u32)((u64)(__addr) & 0xffffffff))
-#define SPFC_HIGH_32_BITS(__addr) ((u32)(((u64)(__addr) >> 32) & 0xffffffff))
-
-/* Error Code from SCQ */
-#define SPFC_COMPLETION_STATUS_SUCCESS FC_CQE_COMPLETED
-#define SPFC_COMPLETION_STATUS_ABORTED_SETUP_FAIL FC_IMMI_CMDPKT_SETUP_FAIL
-
-#define SPFC_COMPLETION_STATUS_TIMEOUT FC_ERROR_CODE_E_D_TIMER_EXPIRE
-#define SPFC_COMPLETION_STATUS_DIF_ERROR FC_ERROR_CODE_DATA_DIFX_FAILED
-#define SPFC_COMPLETION_STATUS_DATA_OOO FC_ERROR_CODE_DATA_OOO_RO
-#define SPFC_COMPLETION_STATUS_DATA_OVERFLOW \
- FC_ERROR_CODE_DATA_EXCEEDS_DATA2TRNS
-
-#define SPFC_SCQE_INVALID_CONN_ID (0xffff)
-#define SPFC_GET_SCQE_TYPE(scqe) ((scqe)->common.ch.wd0.task_type)
-#define SPFC_GET_SCQE_STATUS(scqe) ((scqe)->common.ch.wd0.err_code)
-#define SPFC_GET_SCQE_REMAIN_CNT(scqe) ((scqe)->common.ch.wd0.cqe_remain_cnt)
-#define SPFC_GET_SCQE_CONN_ID(scqe) ((scqe)->common.conn_id)
-#define SPFC_GET_SCQE_SQN(scqe) ((scqe)->common.ch.wd0.sqn)
-#define SPFC_GET_WQE_TYPE(wqe) ((wqe)->ts_sl.task_type)
-
-#define SPFC_WQE_IS_IO(wqe) \
- ((SPFC_GET_WQE_TYPE(wqe) != SPFC_SQE_SESS_RST) && \
- (SPFC_GET_WQE_TYPE(wqe) != SPFC_SQE_NOP))
-#define SPFC_SCQE_HAS_ERRCODE(scqe) \
- (SPFC_GET_SCQE_STATUS(scqe) != SPFC_COMPLETION_STATUS_SUCCESS)
-#define SPFC_SCQE_ERR_TO_CM(scqe) \
- (SPFC_GET_SCQE_STATUS(scqe) != FC_ELS_GS_RSP_EXCH_CHECK_FAIL)
-#define SPFC_SCQE_EXCH_ABORTED(scqe) \
- ((SPFC_GET_SCQE_STATUS(scqe) >= \
- FC_CQE_BUFFER_CLEAR_IO_COMPLETED) && \
- (SPFC_GET_SCQE_STATUS(scqe) <= FC_CQE_WQE_FLUSH_IO_COMPLETED))
-#define SPFC_SCQE_CONN_ID_VALID(scqe) \
- (SPFC_GET_SCQE_CONN_ID(scqe) != SPFC_SCQE_INVALID_CONN_ID)
-
-/*
- * checksum error bitmap define
- */
-#define NIC_RX_CSUM_HW_BYPASS_ERR (1)
-#define NIC_RX_CSUM_IP_CSUM_ERR (1 << 1)
-#define NIC_RX_CSUM_TCP_CSUM_ERR (1 << 2)
-#define NIC_RX_CSUM_UDP_CSUM_ERR (1 << 3)
-#define NIC_RX_CSUM_SCTP_CRC_ERR (1 << 4)
-
-#define SPFC_WQE_SECTION_CHUNK_SIZE 8 /* 8 bytes' chunk */
-#define SPFC_T_RESP_WQE_CTR_TSL_SIZE 15 /* 8 bytes' chunk */
-#define SPFC_T_RD_WR_WQE_CTR_TSL_SIZE 9 /* 8 bytes' chunk */
-#define SPFC_T_RD_WR_WQE_CTR_BDSL_SIZE 4 /* 8 bytes' chunk */
-#define SPFC_T_RD_WR_WQE_CTR_CTRLSL_SIZE 1 /* 8 bytes' chunk */
-
-#define SPFC_WQE_MAX_ESGE_NUM 3 /* 3 ESGE In Extended wqe */
-#define SPFC_WQE_SGE_ENTRY_NUM 2 /* BD SGE and DIF SGE count */
-#define SPFC_WQE_SGE_DIF_ENTRY_NUM 1 /* DIF SGE count */
-#define SPFC_WQE_SGE_LAST_FLAG 1
-#define SPFC_WQE_SGE_NOT_LAST_FLAG 0
-#define SPFC_WQE_SGE_EXTEND_FLAG 1
-#define SPFC_WQE_SGE_NOT_EXTEND_FLAG 0
-
-#define SPFC_FCP_TMF_PORT_RESET (0)
-#define SPFC_FCP_TMF_LUN_RESET (1)
-#define SPFC_FCP_TMF_TGT_RESET (2)
-#define SPFC_FCP_TMF_RSVD (3)
-
-#define SPFC_ADJUST_DATA(old_va, new_va) \
- { \
- (old_va) = new_va; \
- }
-
-#define SPFC_GET_RESET_TYPE(tmf_flag, reset_flag) \
- { \
- switch (tmf_flag) { \
- case UNF_FCP_TM_ABORT_TASK_SET: \
- case UNF_FCP_TM_LOGICAL_UNIT_RESET: \
- (reset_flag) = SPFC_FCP_TMF_LUN_RESET; \
- break; \
- case UNF_FCP_TM_TARGET_RESET: \
- (reset_flag) = SPFC_FCP_TMF_TGT_RESET; \
- break; \
- case UNF_FCP_TM_CLEAR_TASK_SET: \
- (reset_flag) = SPFC_FCP_TMF_PORT_RESET; \
- break; \
- default: \
- (reset_flag) = SPFC_FCP_TMF_RSVD; \
- } \
- }
-
-/* Link WQE structure */
-struct spfc_linkwqe {
- union {
- struct {
- u32 rsv1 : 14;
- u32 wf : 1;
- u32 rsv2 : 14;
- u32 ctrlsl : 2;
- u32 o : 1;
- } wd0;
-
- u32 val_wd0;
- };
-
- union {
- struct {
- u32 msn : 16;
- u32 dump_msn : 15;
- u32 lp : 1; /* lp means whether O bit is overturn */
- } wd1;
-
- u32 val_wd1;
- };
-
- u32 next_page_addr_hi;
- u32 next_page_addr_lo;
-};
-
-/* Session Enable */
-struct spfc_host_keys {
- struct {
- u32 smac1 : 8;
- u32 smac0 : 8;
- u32 rsv : 16;
- } wd0;
-
- u8 smac[ARRAY_INDEX_4];
-
- u8 dmac[ARRAY_INDEX_4];
- struct {
- u8 sid_1;
- u8 sid_2;
- u8 dmac_rvd[ARRAY_INDEX_2];
- } wd3;
- struct {
- u8 did_0;
- u8 did_1;
- u8 did_2;
- u8 sid_0;
- } wd4;
-
- struct {
- u32 port_id : 3;
- u32 host_id : 2;
- u32 rsvd : 27;
- } wd5;
- u32 rsvd;
-};
-
-/* Parent SQ WQE Related function */
-void spfc_build_service_wqe_ctrl_section(struct spfc_wqe_ctrl *wqe_cs, u32 ts_size,
- u32 bdsl);
-void spfc_build_service_wqe_ts_common(struct spfc_sqe_ts *sqe_ts, u32 rport_index,
- u16 local_xid, u16 remote_xid,
- u16 data_len);
-void spfc_build_els_gs_wqe_sge(struct spfc_sqe *sqe, void *buf_addr, u64 phy_addr,
- u32 buf_len, u32 xid, void *handle);
-void spfc_build_els_wqe_ts_req(struct spfc_sqe *sqe, void *info, u32 scqn,
- void *frame_pld, struct unf_frame_pkg *pkg);
-void spfc_build_els_wqe_ts_rsp(struct spfc_sqe *sqe, void *info,
- struct unf_frame_pkg *pkg, void *frame_pld,
- u16 type, u16 cmnd);
-void spfc_build_bls_wqe_ts_req(struct spfc_sqe *sqe, struct unf_frame_pkg *pkg,
- void *handle);
-void spfc_build_trd_twr_wqe_ctrls(struct unf_frame_pkg *pkg, struct spfc_sqe *sqe);
-void spfc_build_wqe_owner_pmsn(struct spfc_sqe *io_sqe, u16 owner, u16 pmsn);
-void spfc_convert_parent_wqe_to_big_endian(struct spfc_sqe *sqe);
-void spfc_build_icmnd_wqe_ctrls(struct unf_frame_pkg *pkg, struct spfc_sqe *sqe);
-void spfc_build_icmnd_wqe_ts(void *handle, struct unf_frame_pkg *pkg,
- struct spfc_sqe_ts *sqe_ts, union spfc_sqe_ts_ex *sqe_tsex);
-void spfc_build_icmnd_wqe_ts_header(struct unf_frame_pkg *pkg, struct spfc_sqe *sqe,
- u8 task_type, u16 exi_base, u8 port_idx);
-
-void spfc_build_cmdqe_common(union spfc_cmdqe *cmd_qe, enum spfc_task_type task_type,
- u16 rxid);
-void spfc_build_srq_wqe_ctrls(struct spfc_rqe *rqe, u16 owner, u16 pmsn);
-void spfc_build_common_wqe_ctrls(struct spfc_wqe_ctrl *ctrl_sl, u8 task_len);
-void spfc_build_tmf_rsp_wqe_ts_header(struct unf_frame_pkg *pkg,
- struct spfc_sqe_tmf_rsp *sqe, u16 exi_base,
- u32 scqn);
-
-#endif
diff --git a/drivers/scsi/spfc/sphw_api_cmd.c b/drivers/scsi/spfc/sphw_api_cmd.c
deleted file mode 120000
index 27c7c0770fa3..000000000000
--- a/drivers/scsi/spfc/sphw_api_cmd.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_api_cmd.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_cmdq.c b/drivers/scsi/spfc/sphw_cmdq.c
deleted file mode 120000
index 5ac779ba274b..000000000000
--- a/drivers/scsi/spfc/sphw_cmdq.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_common.c b/drivers/scsi/spfc/sphw_common.c
deleted file mode 120000
index a1a30a4840e1..000000000000
--- a/drivers/scsi/spfc/sphw_common.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_common.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_eqs.c b/drivers/scsi/spfc/sphw_eqs.c
deleted file mode 120000
index 74430dcb9dc5..000000000000
--- a/drivers/scsi/spfc/sphw_eqs.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_eqs.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_hw_cfg.c b/drivers/scsi/spfc/sphw_hw_cfg.c
deleted file mode 120000
index 4f43d68624c1..000000000000
--- a/drivers/scsi/spfc/sphw_hw_cfg.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_hw_comm.c b/drivers/scsi/spfc/sphw_hw_comm.c
deleted file mode 120000
index c943b3b2933a..000000000000
--- a/drivers/scsi/spfc/sphw_hw_comm.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_hw_comm.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_hwdev.c b/drivers/scsi/spfc/sphw_hwdev.c
deleted file mode 120000
index b7279f17eaa2..000000000000
--- a/drivers/scsi/spfc/sphw_hwdev.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_hwif.c b/drivers/scsi/spfc/sphw_hwif.c
deleted file mode 120000
index d40ef71f9033..000000000000
--- a/drivers/scsi/spfc/sphw_hwif.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_hwif.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_mbox.c b/drivers/scsi/spfc/sphw_mbox.c
deleted file mode 120000
index 1b00fe7289cc..000000000000
--- a/drivers/scsi/spfc/sphw_mbox.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_mbox.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_mgmt.c b/drivers/scsi/spfc/sphw_mgmt.c
deleted file mode 120000
index fd18a73e9d3a..000000000000
--- a/drivers/scsi/spfc/sphw_mgmt.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_prof_adap.c b/drivers/scsi/spfc/sphw_prof_adap.c
deleted file mode 120000
index fbc7db05dd27..000000000000
--- a/drivers/scsi/spfc/sphw_prof_adap.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_prof_adap.c
\ No newline at end of file
diff --git a/drivers/scsi/spfc/sphw_wq.c b/drivers/scsi/spfc/sphw_wq.c
deleted file mode 120000
index cdfcb3a610c0..000000000000
--- a/drivers/scsi/spfc/sphw_wq.c
+++ /dev/null
@@ -1 +0,0 @@
-../../net/ethernet/ramaxel/spnic/hw/sphw_wq.c
\ No newline at end of file
--
2.20.1
1
1

[PATCH OLK-5.10 0/2] apply to delete some files of spfc and spnic drivers in architecture
by Yanling Song 26 Mar '22
by Yanling Song 26 Mar '22
26 Mar '22
There are some issues of drivers that cannot be fixed now. The drivers are not good enought for the LTS quality requirements of openEuler,so apply to remove.
Yanling Song (1):
net/spnic: Remove spnic driver.
Yun Xu (1):
SCSI: spfc: remove SPFC driver
arch/arm64/configs/openeuler_defconfig | 3 -
arch/x86/configs/openeuler_defconfig | 3 -
drivers/net/ethernet/Kconfig | 1 -
drivers/net/ethernet/Makefile | 1 -
drivers/net/ethernet/ramaxel/Kconfig | 20 -
drivers/net/ethernet/ramaxel/Makefile | 6 -
drivers/net/ethernet/ramaxel/spnic/Kconfig | 14 -
drivers/net/ethernet/ramaxel/spnic/Makefile | 39 -
.../ethernet/ramaxel/spnic/hw/sphw_api_cmd.c | 1165 ----
.../ethernet/ramaxel/spnic/hw/sphw_api_cmd.h | 277 -
.../ethernet/ramaxel/spnic/hw/sphw_cfg_cmd.h | 127 -
.../net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c | 1573 ------
.../net/ethernet/ramaxel/spnic/hw/sphw_cmdq.h | 195 -
.../ethernet/ramaxel/spnic/hw/sphw_comm_cmd.h | 60 -
.../ramaxel/spnic/hw/sphw_comm_msg_intf.h | 273 -
.../ethernet/ramaxel/spnic/hw/sphw_common.c | 88 -
.../ethernet/ramaxel/spnic/hw/sphw_common.h | 106 -
.../net/ethernet/ramaxel/spnic/hw/sphw_crm.h | 982 ----
.../net/ethernet/ramaxel/spnic/hw/sphw_csr.h | 158 -
.../net/ethernet/ramaxel/spnic/hw/sphw_eqs.c | 1272 -----
.../net/ethernet/ramaxel/spnic/hw/sphw_eqs.h | 157 -
.../net/ethernet/ramaxel/spnic/hw/sphw_hw.h | 643 ---
.../ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c | 1341 -----
.../ethernet/ramaxel/spnic/hw/sphw_hw_cfg.h | 329 --
.../ethernet/ramaxel/spnic/hw/sphw_hw_comm.c | 1280 -----
.../ethernet/ramaxel/spnic/hw/sphw_hw_comm.h | 45 -
.../ethernet/ramaxel/spnic/hw/sphw_hwdev.c | 1324 -----
.../ethernet/ramaxel/spnic/hw/sphw_hwdev.h | 93 -
.../net/ethernet/ramaxel/spnic/hw/sphw_hwif.c | 886 ---
.../net/ethernet/ramaxel/spnic/hw/sphw_hwif.h | 102 -
.../net/ethernet/ramaxel/spnic/hw/sphw_mbox.c | 1792 ------
.../net/ethernet/ramaxel/spnic/hw/sphw_mbox.h | 271 -
.../net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c | 895 ---
.../net/ethernet/ramaxel/spnic/hw/sphw_mgmt.h | 106 -
.../ramaxel/spnic/hw/sphw_mgmt_msg_base.h | 19 -
.../net/ethernet/ramaxel/spnic/hw/sphw_mt.h | 533 --
.../ramaxel/spnic/hw/sphw_prof_adap.c | 94 -
.../ramaxel/spnic/hw/sphw_prof_adap.h | 49 -
.../ethernet/ramaxel/spnic/hw/sphw_profile.h | 36 -
.../net/ethernet/ramaxel/spnic/hw/sphw_wq.c | 152 -
.../net/ethernet/ramaxel/spnic/hw/sphw_wq.h | 119 -
.../net/ethernet/ramaxel/spnic/spnic_dbg.c | 752 ---
.../net/ethernet/ramaxel/spnic/spnic_dcb.c | 965 ----
.../net/ethernet/ramaxel/spnic/spnic_dcb.h | 56 -
.../ethernet/ramaxel/spnic/spnic_dev_mgmt.c | 811 ---
.../ethernet/ramaxel/spnic/spnic_dev_mgmt.h | 78 -
.../ethernet/ramaxel/spnic/spnic_ethtool.c | 994 ----
.../ramaxel/spnic/spnic_ethtool_stats.c | 1035 ----
.../net/ethernet/ramaxel/spnic/spnic_filter.c | 411 --
.../net/ethernet/ramaxel/spnic/spnic_irq.c | 178 -
.../net/ethernet/ramaxel/spnic/spnic_lld.c | 937 ----
.../net/ethernet/ramaxel/spnic/spnic_lld.h | 75 -
.../ethernet/ramaxel/spnic/spnic_mag_cfg.c | 778 ---
.../ethernet/ramaxel/spnic/spnic_mag_cmd.h | 643 ---
.../net/ethernet/ramaxel/spnic/spnic_main.c | 924 ----
.../ramaxel/spnic/spnic_mgmt_interface.h | 605 --
.../ethernet/ramaxel/spnic/spnic_netdev_ops.c | 1526 ------
.../net/ethernet/ramaxel/spnic/spnic_nic.h | 148 -
.../ethernet/ramaxel/spnic/spnic_nic_cfg.c | 1334 -----
.../ethernet/ramaxel/spnic/spnic_nic_cfg.h | 709 ---
.../ethernet/ramaxel/spnic/spnic_nic_cfg_vf.c | 658 ---
.../ethernet/ramaxel/spnic/spnic_nic_cmd.h | 105 -
.../ethernet/ramaxel/spnic/spnic_nic_dbg.c | 151 -
.../ethernet/ramaxel/spnic/spnic_nic_dbg.h | 16 -
.../ethernet/ramaxel/spnic/spnic_nic_dev.h | 354 --
.../ethernet/ramaxel/spnic/spnic_nic_event.c | 506 --
.../net/ethernet/ramaxel/spnic/spnic_nic_io.c | 1123 ----
.../net/ethernet/ramaxel/spnic/spnic_nic_io.h | 305 -
.../net/ethernet/ramaxel/spnic/spnic_nic_qp.h | 416 --
.../net/ethernet/ramaxel/spnic/spnic_ntuple.c | 841 ---
.../ethernet/ramaxel/spnic/spnic_pci_id_tbl.h | 12 -
.../net/ethernet/ramaxel/spnic/spnic_rss.c | 741 ---
.../net/ethernet/ramaxel/spnic/spnic_rss.h | 50 -
.../ethernet/ramaxel/spnic/spnic_rss_cfg.c | 333 --
drivers/net/ethernet/ramaxel/spnic/spnic_rx.c | 1238 -----
drivers/net/ethernet/ramaxel/spnic/spnic_rx.h | 118 -
.../net/ethernet/ramaxel/spnic/spnic_sriov.c | 200 -
.../net/ethernet/ramaxel/spnic/spnic_sriov.h | 24 -
drivers/net/ethernet/ramaxel/spnic/spnic_tx.c | 877 ---
drivers/net/ethernet/ramaxel/spnic/spnic_tx.h | 129 -
drivers/scsi/Kconfig | 1 -
drivers/scsi/Makefile | 1 -
drivers/scsi/spfc/Kconfig | 16 -
drivers/scsi/spfc/Makefile | 47 -
drivers/scsi/spfc/common/unf_common.h | 1753 ------
drivers/scsi/spfc/common/unf_disc.c | 1276 -----
drivers/scsi/spfc/common/unf_disc.h | 51 -
drivers/scsi/spfc/common/unf_event.c | 517 --
drivers/scsi/spfc/common/unf_event.h | 83 -
drivers/scsi/spfc/common/unf_exchg.c | 2317 --------
drivers/scsi/spfc/common/unf_exchg.h | 436 --
drivers/scsi/spfc/common/unf_exchg_abort.c | 825 ---
drivers/scsi/spfc/common/unf_exchg_abort.h | 23 -
drivers/scsi/spfc/common/unf_fcstruct.h | 459 --
drivers/scsi/spfc/common/unf_gs.c | 2521 ---------
drivers/scsi/spfc/common/unf_gs.h | 58 -
drivers/scsi/spfc/common/unf_init.c | 353 --
drivers/scsi/spfc/common/unf_io.c | 1219 ----
drivers/scsi/spfc/common/unf_io.h | 96 -
drivers/scsi/spfc/common/unf_io_abnormal.c | 986 ----
drivers/scsi/spfc/common/unf_io_abnormal.h | 19 -
drivers/scsi/spfc/common/unf_log.h | 178 -
drivers/scsi/spfc/common/unf_lport.c | 1008 ----
drivers/scsi/spfc/common/unf_lport.h | 519 --
drivers/scsi/spfc/common/unf_ls.c | 4883 -----------------
drivers/scsi/spfc/common/unf_ls.h | 61 -
drivers/scsi/spfc/common/unf_npiv.c | 1005 ----
drivers/scsi/spfc/common/unf_npiv.h | 47 -
drivers/scsi/spfc/common/unf_npiv_portman.c | 360 --
drivers/scsi/spfc/common/unf_npiv_portman.h | 17 -
drivers/scsi/spfc/common/unf_portman.c | 2431 --------
drivers/scsi/spfc/common/unf_portman.h | 96 -
drivers/scsi/spfc/common/unf_rport.c | 2286 --------
drivers/scsi/spfc/common/unf_rport.h | 301 -
drivers/scsi/spfc/common/unf_scsi.c | 1462 -----
drivers/scsi/spfc/common/unf_scsi_common.h | 570 --
drivers/scsi/spfc/common/unf_service.c | 1430 -----
drivers/scsi/spfc/common/unf_service.h | 66 -
drivers/scsi/spfc/common/unf_type.h | 216 -
drivers/scsi/spfc/hw/spfc_chipitf.c | 1105 ----
drivers/scsi/spfc/hw/spfc_chipitf.h | 797 ---
drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c | 1611 ------
drivers/scsi/spfc/hw/spfc_cqm_bat_cla.h | 215 -
drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c | 885 ---
drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.h | 65 -
drivers/scsi/spfc/hw/spfc_cqm_main.c | 987 ----
drivers/scsi/spfc/hw/spfc_cqm_main.h | 411 --
drivers/scsi/spfc/hw/spfc_cqm_object.c | 937 ----
drivers/scsi/spfc/hw/spfc_cqm_object.h | 279 -
drivers/scsi/spfc/hw/spfc_hba.c | 1751 ------
drivers/scsi/spfc/hw/spfc_hba.h | 341 --
drivers/scsi/spfc/hw/spfc_hw_wqe.h | 1645 ------
drivers/scsi/spfc/hw/spfc_io.c | 1193 ----
drivers/scsi/spfc/hw/spfc_io.h | 138 -
drivers/scsi/spfc/hw/spfc_lld.c | 997 ----
drivers/scsi/spfc/hw/spfc_lld.h | 76 -
drivers/scsi/spfc/hw/spfc_module.h | 297 -
drivers/scsi/spfc/hw/spfc_parent_context.h | 269 -
drivers/scsi/spfc/hw/spfc_queue.c | 4852 ----------------
drivers/scsi/spfc/hw/spfc_queue.h | 711 ---
drivers/scsi/spfc/hw/spfc_service.c | 2170 --------
drivers/scsi/spfc/hw/spfc_service.h | 282 -
drivers/scsi/spfc/hw/spfc_utils.c | 102 -
drivers/scsi/spfc/hw/spfc_utils.h | 202 -
drivers/scsi/spfc/hw/spfc_wqe.c | 646 ---
drivers/scsi/spfc/hw/spfc_wqe.h | 239 -
drivers/scsi/spfc/sphw_api_cmd.c | 1 -
drivers/scsi/spfc/sphw_cmdq.c | 1 -
drivers/scsi/spfc/sphw_common.c | 1 -
drivers/scsi/spfc/sphw_eqs.c | 1 -
drivers/scsi/spfc/sphw_hw_cfg.c | 1 -
drivers/scsi/spfc/sphw_hw_comm.c | 1 -
drivers/scsi/spfc/sphw_hwdev.c | 1 -
drivers/scsi/spfc/sphw_hwif.c | 1 -
drivers/scsi/spfc/sphw_mbox.c | 1 -
drivers/scsi/spfc/sphw_mgmt.c | 1 -
drivers/scsi/spfc/sphw_prof_adap.c | 1 -
drivers/scsi/spfc/sphw_wq.c | 1 -
158 files changed, 90993 deletions(-)
delete mode 100644 drivers/net/ethernet/ramaxel/Kconfig
delete mode 100644 drivers/net/ethernet/ramaxel/Makefile
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/Kconfig
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/Makefile
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_api_cmd.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_api_cmd.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_cfg_cmd.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_cmdq.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_comm_cmd.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_common.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_common.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_crm.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_csr.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_eqs.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_cfg.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_comm.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hw_comm.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwdev.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwif.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_hwif.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_mbox.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_mt.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_prof_adap.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_prof_adap.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_profile.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_wq.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/hw/sphw_wq.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_dbg.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_dcb.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_dcb.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_dev_mgmt.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_dev_mgmt.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_ethtool.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_ethtool_stats.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_filter.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_irq.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_lld.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_lld.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_mag_cfg.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_mag_cmd.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_main.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_mgmt_interface.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_netdev_ops.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_cfg.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_cfg.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_cfg_vf.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_cmd.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_dbg.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_dbg.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_dev.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_event.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_io.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_io.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_nic_qp.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_ntuple.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_pci_id_tbl.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_rss.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_rss.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_rss_cfg.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_rx.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_rx.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_sriov.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_sriov.h
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_tx.c
delete mode 100644 drivers/net/ethernet/ramaxel/spnic/spnic_tx.h
delete mode 100644 drivers/scsi/spfc/Kconfig
delete mode 100644 drivers/scsi/spfc/Makefile
delete mode 100644 drivers/scsi/spfc/common/unf_common.h
delete mode 100644 drivers/scsi/spfc/common/unf_disc.c
delete mode 100644 drivers/scsi/spfc/common/unf_disc.h
delete mode 100644 drivers/scsi/spfc/common/unf_event.c
delete mode 100644 drivers/scsi/spfc/common/unf_event.h
delete mode 100644 drivers/scsi/spfc/common/unf_exchg.c
delete mode 100644 drivers/scsi/spfc/common/unf_exchg.h
delete mode 100644 drivers/scsi/spfc/common/unf_exchg_abort.c
delete mode 100644 drivers/scsi/spfc/common/unf_exchg_abort.h
delete mode 100644 drivers/scsi/spfc/common/unf_fcstruct.h
delete mode 100644 drivers/scsi/spfc/common/unf_gs.c
delete mode 100644 drivers/scsi/spfc/common/unf_gs.h
delete mode 100644 drivers/scsi/spfc/common/unf_init.c
delete mode 100644 drivers/scsi/spfc/common/unf_io.c
delete mode 100644 drivers/scsi/spfc/common/unf_io.h
delete mode 100644 drivers/scsi/spfc/common/unf_io_abnormal.c
delete mode 100644 drivers/scsi/spfc/common/unf_io_abnormal.h
delete mode 100644 drivers/scsi/spfc/common/unf_log.h
delete mode 100644 drivers/scsi/spfc/common/unf_lport.c
delete mode 100644 drivers/scsi/spfc/common/unf_lport.h
delete mode 100644 drivers/scsi/spfc/common/unf_ls.c
delete mode 100644 drivers/scsi/spfc/common/unf_ls.h
delete mode 100644 drivers/scsi/spfc/common/unf_npiv.c
delete mode 100644 drivers/scsi/spfc/common/unf_npiv.h
delete mode 100644 drivers/scsi/spfc/common/unf_npiv_portman.c
delete mode 100644 drivers/scsi/spfc/common/unf_npiv_portman.h
delete mode 100644 drivers/scsi/spfc/common/unf_portman.c
delete mode 100644 drivers/scsi/spfc/common/unf_portman.h
delete mode 100644 drivers/scsi/spfc/common/unf_rport.c
delete mode 100644 drivers/scsi/spfc/common/unf_rport.h
delete mode 100644 drivers/scsi/spfc/common/unf_scsi.c
delete mode 100644 drivers/scsi/spfc/common/unf_scsi_common.h
delete mode 100644 drivers/scsi/spfc/common/unf_service.c
delete mode 100644 drivers/scsi/spfc/common/unf_service.h
delete mode 100644 drivers/scsi/spfc/common/unf_type.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_chipitf.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_chipitf.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bat_cla.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bat_cla.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_bitmap_table.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_main.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_main.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_object.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_cqm_object.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_hba.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_hba.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_hw_wqe.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_io.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_io.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_lld.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_lld.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_module.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_parent_context.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_queue.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_queue.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_service.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_service.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_utils.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_utils.h
delete mode 100644 drivers/scsi/spfc/hw/spfc_wqe.c
delete mode 100644 drivers/scsi/spfc/hw/spfc_wqe.h
delete mode 120000 drivers/scsi/spfc/sphw_api_cmd.c
delete mode 120000 drivers/scsi/spfc/sphw_cmdq.c
delete mode 120000 drivers/scsi/spfc/sphw_common.c
delete mode 120000 drivers/scsi/spfc/sphw_eqs.c
delete mode 120000 drivers/scsi/spfc/sphw_hw_cfg.c
delete mode 120000 drivers/scsi/spfc/sphw_hw_comm.c
delete mode 120000 drivers/scsi/spfc/sphw_hwdev.c
delete mode 120000 drivers/scsi/spfc/sphw_hwif.c
delete mode 120000 drivers/scsi/spfc/sphw_mbox.c
delete mode 120000 drivers/scsi/spfc/sphw_mgmt.c
delete mode 120000 drivers/scsi/spfc/sphw_prof_adap.c
delete mode 120000 drivers/scsi/spfc/sphw_wq.c
--
2.32.0
1
2
Fix CWE-457 bug: Use of an uninitialized variable
1
0

[PATCH openEuler-1.0-LTS 1/4] arm64/mpam: fix __mpam_device_create() section mismatch error
by Laibin Qiu 26 Mar '22
by Laibin Qiu 26 Mar '22
26 Mar '22
From: Xingang Wang <wangxingang5(a)huawei.com>
ascend inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2
CVE: NA
---------------------------------------------------
Fix modpost Section mismatch error in __mpam_device_create() and others.
These warnings will occur in high version gcc, for example 10.1.0.
[...]
WARNING: vmlinux.o(.text+0x2ed88): Section mismatch in reference from the
function __mpam_device_create() to the function .init.text:mpam_device_alloc()
The function __mpam_device_create() references
the function __init mpam_device_alloc().
This is often because __mpam_device_create lacks a __init
annotation or the annotation of mpam_device_alloc is wrong.
WARNING: vmlinux.o(.text.unlikely+0xa5c): Section mismatch in reference from
the function mpam_resctrl_init() to the function .init.text:mpam_init_padding()
The function mpam_resctrl_init() references
the function __init mpam_init_padding().
This is often because mpam_resctrl_init lacks a __init
annotation or the annotation of mpam_init_padding is wrong.
WARNING: vmlinux.o(.text.unlikely+0x5a9c): Section mismatch in reference from
the function resctrl_group_init() to the function .init.text:resctrl_group_setup_root()
The function resctrl_group_init() references
the function __init resctrl_group_setup_root().
This is often because resctrl_group_init lacks a __init
annotation or the annotation of resctrl_group_setup_root is wrong.
[...]
Fixes: c5e27c395a70 ("arm64/mpam: remove __init macro to support driver probe")
Signed-off-by: Xingang Wang <wangxingang5(a)huawei.com>
Signed-off-by: Wang ShaoBo <bobo.shaobowang(a)huawei.com>
Reviewed-by: Cheng Jian <cj.chengjian(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
arch/arm64/kernel/mpam/mpam_device.c | 8 ++++----
arch/arm64/kernel/mpam/mpam_resctrl.c | 2 +-
fs/resctrlfs.c | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c
index 4e882e81cf41..5d34751f8c3e 100644
--- a/arch/arm64/kernel/mpam/mpam_device.c
+++ b/arch/arm64/kernel/mpam/mpam_device.c
@@ -621,7 +621,7 @@ static void mpam_failed(struct work_struct *work)
mutex_unlock(&mpam_cpuhp_lock);
}
-static struct mpam_device * __init
+static struct mpam_device *
mpam_device_alloc(struct mpam_component *comp)
{
struct mpam_device *dev;
@@ -656,7 +656,7 @@ static void mpam_devices_destroy(struct mpam_component *comp)
}
}
-static struct mpam_component * __init mpam_component_alloc(int id)
+static struct mpam_component *mpam_component_alloc(int id)
{
struct mpam_component *comp;
@@ -694,7 +694,7 @@ struct mpam_component *mpam_component_get(struct mpam_class *class, int id,
return comp;
}
-static struct mpam_class * __init mpam_class_alloc(u8 level_idx,
+static struct mpam_class *mpam_class_alloc(u8 level_idx,
enum mpam_class_types type)
{
struct mpam_class *class;
@@ -733,7 +733,7 @@ static void mpam_class_destroy(struct mpam_class *class)
}
}
-static struct mpam_class * __init mpam_class_get(u8 level_idx,
+static struct mpam_class *mpam_class_get(u8 level_idx,
enum mpam_class_types type,
bool alloc)
{
diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c
index fe2dcf92100f..183c83d4274f 100644
--- a/arch/arm64/kernel/mpam/mpam_resctrl.c
+++ b/arch/arm64/kernel/mpam/mpam_resctrl.c
@@ -1135,7 +1135,7 @@ void closid_free(int closid)
* Choose a width for the resource name and resource data based on the
* resource that has widest name and cbm.
*/
-static __init void mpam_init_padding(void)
+static void mpam_init_padding(void)
{
int cl;
struct mpam_resctrl_res *res;
diff --git a/fs/resctrlfs.c b/fs/resctrlfs.c
index ea9df7d77b95..0e6753012140 100644
--- a/fs/resctrlfs.c
+++ b/fs/resctrlfs.c
@@ -989,7 +989,7 @@ static void resctrl_group_default_init(struct resctrl_group *r)
r->type = RDTCTRL_GROUP;
}
-static int __init resctrl_group_setup_root(void)
+static int resctrl_group_setup_root(void)
{
int ret;
--
2.22.0
1
3

[PATCH openEuler-5.10 1/2] block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern
by Zheng Zengkai 23 Mar '22
by Zheng Zengkai 23 Mar '22
23 Mar '22
From: Haimin Zhang <tcs.kernel(a)gmail.com>
mainline inclusion
from mainline-v5.17-rc5
commit cc8f7fe1f5eab010191aa4570f27641876fa1267
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4Z2IA
CVE: CVE-2022-0494
--------------------------------
Add __GFP_ZERO flag for alloc_page in function bio_copy_kern to initialize
the buffer of a bio.
Signed-off-by: Haimin Zhang <tcs.kernel(a)gmail.com>
Reviewed-by: Chaitanya Kulkarni <kch(a)nvidia.com>
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Link: https://lore.kernel.org/r/20220216084038.15635-1-tcs.kernel@gmail.com
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
Conflict: commit ce288e053568 ("block: remove BLK_BOUNCE_ISA support")
is not backported.
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Reviewed-by: Jason Yan <yanaijie(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
block/blk-map.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/blk-map.c b/block/blk-map.c
index 21630dccac62..ede73f4f7014 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -488,7 +488,7 @@ static struct bio *bio_copy_kern(struct request_queue *q, void *data,
if (bytes > len)
bytes = len;
- page = alloc_page(q->bounce_gfp | gfp_mask);
+ page = alloc_page(q->bounce_gfp | __GFP_ZERO | gfp_mask);
if (!page)
goto cleanup;
--
2.20.1
1
1

22 Mar '22
From: eillon <yezhenyu2(a)huawei.com>
euleros inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4YW86
--------------------------------
When building with defconfig on arm32, we got a compile error:
./include/linux/page-flags-layout.h:95:2: error: #error "Not enough bits in page flags"
95 | #error "Not enough bits in page flags"
| ^~~~~
Limit PG_reserve_pgflag_0 and PG_reserve_pgflag_1 to compile only on
X86_64 and ARM64 to resolve this issue.
Fixes: afdf2a6cdee7 ("kabi: Add reserved page and gfp flags for future extension")
Signed-off-by: eillon <yezhenyu2(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
include/linux/page-flags.h | 2 ++
include/trace/events/mmflags.h | 10 +++++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index e1af0a6c8165..65e1cbe1d1ce 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -150,8 +150,10 @@ enum pageflags {
* flags which backported from kernel upstream, please place them
* behind the reserved page flags.
*/
+#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
PG_reserve_pgflag_0,
PG_reserve_pgflag_1,
+#endif
__NR_PAGEFLAGS,
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index b50012bea1ef..366d972ce735 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -89,8 +89,12 @@
#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
#define IF_HAVE_PG_POOL(flag,string) ,{1UL << flag, string}
+#define IF_HAVE_PG_RESERVE0(flag,string) ,{1UL << flag, string}
+#define IF_HAVE_PG_RESERVE1(flag,string) ,{1UL << flag, string}
#else
#define IF_HAVE_PG_POOL(flag,string)
+#define IF_HAVE_PG_RESERVE0(flag,string)
+#define IF_HAVE_PG_RESERVE1(flag,string)
#endif
#ifdef CONFIG_PIN_MEMORY
@@ -128,9 +132,9 @@ IF_HAVE_PG_IDLE(PG_young, "young" ) \
IF_HAVE_PG_IDLE(PG_idle, "idle" ) \
IF_HAVE_PG_ARCH_2(PG_arch_2, "arch_2" ) \
IF_HAVE_PG_POOL(PG_pool, "pool" ) \
-IF_HAVE_PG_HOTREPLACE(PG_hotreplace, "hotreplace" ), \
- {1UL << PG_reserve_pgflag_0, "reserve_pgflag_0"}, \
- {1UL << PG_reserve_pgflag_1, "reserve_pgflag_1"}
+IF_HAVE_PG_HOTREPLACE(PG_hotreplace, "hotreplace" ) \
+IF_HAVE_PG_RESERVE0(PG_reserve_pgflag_0,"reserve_pgflag_0") \
+IF_HAVE_PG_RESERVE1(PG_reserve_pgflag_1,"reserve_pgflag_1")
#define show_page_flags(flags) \
(flags) ? __print_flags(flags, "|", \
--
2.20.1
1
2
From: eillon <yezhenyu2(a)huawei.com>
euleros inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4YW86
--------------------------------
When building with defconfig on arm32, we got a compile error:
./include/linux/page-flags-layout.h:95:2: error: #error "Not enough bits in page flags"
95 | #error "Not enough bits in page flags"
| ^~~~~
Limit PG_reserve_pgflag_0 and PG_reserve_pgflag_1 to compile only on
X86_64 and ARM64 to resolve this issue.
Fixes: afdf2a6cdee7 ("kabi: Add reserved page and gfp flags for future extension")
Signed-off-by: eillon <yezhenyu2(a)huawei.com>
---
include/linux/page-flags.h | 2 ++
include/trace/events/mmflags.h | 10 +++++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index e1af0a6c8165..65e1cbe1d1ce 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -150,8 +150,10 @@ enum pageflags {
* flags which backported from kernel upstream, please place them
* behind the reserved page flags.
*/
+#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
PG_reserve_pgflag_0,
PG_reserve_pgflag_1,
+#endif
__NR_PAGEFLAGS,
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index b50012bea1ef..366d972ce735 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -89,8 +89,12 @@
#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
#define IF_HAVE_PG_POOL(flag,string) ,{1UL << flag, string}
+#define IF_HAVE_PG_RESERVE0(flag,string) ,{1UL << flag, string}
+#define IF_HAVE_PG_RESERVE1(flag,string) ,{1UL << flag, string}
#else
#define IF_HAVE_PG_POOL(flag,string)
+#define IF_HAVE_PG_RESERVE0(flag,string)
+#define IF_HAVE_PG_RESERVE1(flag,string)
#endif
#ifdef CONFIG_PIN_MEMORY
@@ -128,9 +132,9 @@ IF_HAVE_PG_IDLE(PG_young, "young" ) \
IF_HAVE_PG_IDLE(PG_idle, "idle" ) \
IF_HAVE_PG_ARCH_2(PG_arch_2, "arch_2" ) \
IF_HAVE_PG_POOL(PG_pool, "pool" ) \
-IF_HAVE_PG_HOTREPLACE(PG_hotreplace, "hotreplace" ), \
- {1UL << PG_reserve_pgflag_0, "reserve_pgflag_0"}, \
- {1UL << PG_reserve_pgflag_1, "reserve_pgflag_1"}
+IF_HAVE_PG_HOTREPLACE(PG_hotreplace, "hotreplace" ) \
+IF_HAVE_PG_RESERVE0(PG_reserve_pgflag_0,"reserve_pgflag_0") \
+IF_HAVE_PG_RESERVE1(PG_reserve_pgflag_1,"reserve_pgflag_1")
#define show_page_flags(flags) \
(flags) ? __print_flags(flags, "|", \
--
2.27.0
2
1

[PATCH openEuler-5.10] mm/dynamic_hugetlb: only compile PG_pool on X86_64 and ARM64
by Zheng Zengkai 22 Mar '22
by Zheng Zengkai 22 Mar '22
22 Mar '22
From: Liu Shixin <liushixin2(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I4YXOA
--------------------------------
When building with defconfig on arm32, we got a compile error:
./include/linux/page-flags-layout.h:95:2: error: #error "Not enough bits in page flags"
95 | #error "Not enough bits in page flags"
| ^~~~~
Limit PG_pool to compile only on X86_64 and ARM64 to resolve this issue.
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
fs/proc/page.c | 2 ++
include/linux/page-flags.h | 6 ++++++
include/trace/events/mmflags.h | 10 ++++++++--
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/fs/proc/page.c b/fs/proc/page.c
index d00c23d543fe..4c5bef99ec10 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -220,7 +220,9 @@ u64 stable_page_flags(struct page *page)
#ifdef CONFIG_64BIT
u |= kpf_copy_bit(k, KPF_ARCH_2, PG_arch_2);
#endif
+#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
u |= kpf_copy_bit(k, KPF_POOL, PG_pool);
+#endif
return u;
};
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index eb2fe22bc0e9..e1af0a6c8165 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -139,7 +139,9 @@ enum pageflags {
#ifdef CONFIG_64BIT
PG_arch_2,
#endif
+#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
PG_pool, /* Used to track page allocated from dynamic hugetlb pool */
+#endif
#ifdef CONFIG_PIN_MEMORY
PG_hotreplace,
#endif
@@ -474,7 +476,11 @@ __PAGEFLAG(Reported, reported, PF_NO_COMPOUND)
/*
* PagePool() is used to track page allocated from hpool.
*/
+#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
PAGEFLAG(Pool, pool, PF_NO_TAIL)
+#else
+PAGEFLAG_FALSE(Pool)
+#endif
/*
* On an anonymous page mapped into a user virtual memory area,
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index dc1805fbf893..b50012bea1ef 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -87,6 +87,12 @@
#define IF_HAVE_PG_ARCH_2(flag,string)
#endif
+#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64)
+#define IF_HAVE_PG_POOL(flag,string) ,{1UL << flag, string}
+#else
+#define IF_HAVE_PG_POOL(flag,string)
+#endif
+
#ifdef CONFIG_PIN_MEMORY
#define IF_HAVE_PG_HOTREPLACE(flag, string) ,{1UL << flag, string}
#else
@@ -114,14 +120,14 @@
{1UL << PG_mappedtodisk, "mappedtodisk" }, \
{1UL << PG_reclaim, "reclaim" }, \
{1UL << PG_swapbacked, "swapbacked" }, \
- {1UL << PG_unevictable, "unevictable" }, \
- {1UL << PG_pool, "pool" } \
+ {1UL << PG_unevictable, "unevictable" } \
IF_HAVE_PG_MLOCK(PG_mlocked, "mlocked" ) \
IF_HAVE_PG_UNCACHED(PG_uncached, "uncached" ) \
IF_HAVE_PG_HWPOISON(PG_hwpoison, "hwpoison" ) \
IF_HAVE_PG_IDLE(PG_young, "young" ) \
IF_HAVE_PG_IDLE(PG_idle, "idle" ) \
IF_HAVE_PG_ARCH_2(PG_arch_2, "arch_2" ) \
+IF_HAVE_PG_POOL(PG_pool, "pool" ) \
IF_HAVE_PG_HOTREPLACE(PG_hotreplace, "hotreplace" ), \
{1UL << PG_reserve_pgflag_0, "reserve_pgflag_0"}, \
{1UL << PG_reserve_pgflag_1, "reserve_pgflag_1"}
--
2.20.1
1
0
2
5

21 Mar '22
From: Miklos Szeredi <mszeredi(a)redhat.com>
mainline inclusion
from mainline-v5.17-rc8
commit 0c4bcfdecb1ac0967619ee7ff44871d93c08c909
category: bugfix
bugzilla: 186448, https://gitee.com/openeuler/kernel/issues/I4YS7O
CVE: CVE-2022-1011
--------------------------------
In FOPEN_DIRECT_IO mode, fuse_file_write_iter() calls
fuse_direct_write_iter(), which normally calls fuse_direct_io(), which then
imports the write buffer with fuse_get_user_pages(), which uses
iov_iter_get_pages() to grab references to userspace pages instead of
actually copying memory.
On the filesystem device side, these pages can then either be read to
userspace (via fuse_dev_read()), or splice()d over into a pipe using
fuse_dev_splice_read() as pipe buffers with &nosteal_pipe_buf_ops.
This is wrong because after fuse_dev_do_read() unlocks the FUSE request,
the userspace filesystem can mark the request as completed, causing write()
to return. At that point, the userspace filesystem should no longer have
access to the pipe buffer.
Fix by copying pages coming from the user address space to new pipe
buffers.
Reported-by: Jann Horn <jannh(a)google.com>
Fixes: c3021629a0d8 ("fuse: support splice() reading from fuse device")
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi(a)redhat.com>
Signed-off-by: Zhang Wensheng <zhangwensheng5(a)huawei.com>
Reviewed-by: Hou Tao <houtao1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
fs/fuse/dev.c | 12 +++++++++++-
fs/fuse/file.c | 1 +
fs/fuse/fuse_i.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index d100b5dfedbd..8ac91ba05d6d 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -945,7 +945,17 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
while (count) {
if (cs->write && cs->pipebufs && page) {
- return fuse_ref_page(cs, page, offset, count);
+ /*
+ * Can't control lifetime of pipe buffers, so always
+ * copy user pages.
+ */
+ if (cs->req->args->user_pages) {
+ err = fuse_copy_fill(cs);
+ if (err)
+ return err;
+ } else {
+ return fuse_ref_page(cs, page, offset, count);
+ }
} else if (!cs->len) {
if (cs->move_pages && page &&
offset == 0 && count == PAGE_SIZE) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index e63ce8443c96..a869c3a527a8 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1433,6 +1433,7 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
(PAGE_SIZE - ret) & (PAGE_SIZE - 1);
}
+ ap->args.user_pages = true;
if (write)
ap->args.in_pages = true;
else
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index d31fc48c6afa..0686788e4283 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -266,6 +266,7 @@ struct fuse_args {
bool nocreds:1;
bool in_pages:1;
bool out_pages:1;
+ bool user_pages:1;
bool out_argvar:1;
bool page_zeroing:1;
bool page_replace:1;
--
2.20.1
1
1

[PATCH openEuler-5.10 1/4] blk-mq: add exception handling when srcu->sda alloc failed
by Zheng Zengkai 21 Mar '22
by Zheng Zengkai 21 Mar '22
21 Mar '22
From: Laibin Qiu <qiulaibin(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 186352, https://gitee.com/openeuler/kernel/issues/I4YADX
CVE: NA
--------------------------------
In case of BLK_MQ_F_BLOCKING, per-hctx srcu is used to protect dispatch
critical area. But the current process is not aware when memory of srcu
allocation failed in blk_mq_alloc_hctx, which will leads to illegal
address BUG. Add return value validation to avoid this problem.
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
Reviewed-by: Hou Tao <houtao1(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
block/blk-mq.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index c3beaca1f4fb..9ae1663348ac 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2852,12 +2852,16 @@ blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set,
if (!hctx->fq)
goto free_bitmap;
- if (hctx->flags & BLK_MQ_F_BLOCKING)
- init_srcu_struct(hctx->srcu);
+ if (hctx->flags & BLK_MQ_F_BLOCKING) {
+ if (init_srcu_struct(hctx->srcu) != 0)
+ goto free_flush_queue;
+ }
blk_mq_hctx_kobj_init(hctx);
return hctx;
+ free_flush_queue:
+ blk_free_flush_queue(hctx->fq);
free_bitmap:
sbitmap_free(&hctx->ctx_map);
free_ctxs:
--
2.20.1
1
3
Update openEuler-22.03-LTS KABI whitelists.
1
0

20 Mar '22
Patch 1 fixes a bug found in earlier version.
Patch 2,3,4 are potential vulnerability discovered during code analysis.
Patch 5 is an optimization.
Patch 7 is a feature limitation.
Patch 6,8,9 are three bugfix discovered during code analysis.
Liu Shixin (9):
mm/dynamic_hugetlb: check free_pages_prepares when split pages
mm/dynamic_hugetlb: improve the initialization of huge pages
mm/dynamic_hugetlb: use pfn to traverse subpages
mm/dynamic_hugetlb: check page using check_new_page
mm/dynamic_hugetlb: use mem_cgroup_force_empty to reclaim pages
mm/dynamic_hugetlb: hold the lock until pages back to hugetlb
mm/dynamic_hugetlb: only support to merge 2M dynamicly
mm/dynamic_hugetlb: set/clear HPageFreed
mm/dynamic_hugetlb: initialize subpages before merging
include/linux/memcontrol.h | 2 +
mm/dynamic_hugetlb.c | 156 ++++++++++++++++++++++++-------------
mm/internal.h | 1 +
mm/memcontrol.c | 2 +-
mm/page_alloc.c | 2 +-
5 files changed, 109 insertions(+), 54 deletions(-)
--
2.20.1
1
9

[PATCH openEuler-1.0-LTS] blk-mq: add exception handling when srcu->sda alloc failed
by Laibin Qiu 18 Mar '22
by Laibin Qiu 18 Mar '22
18 Mar '22
hulk inclusion
category: bugfix
bugzilla: 186352, https://gitee.com/openeuler/kernel/issues/I4YADX
DTS: DTS2022031707143
CVE: NA
--------------------------------
In case of BLK_MQ_F_BLOCKING, per-hctx srcu is used to protect dispatch
critical area. But the current process is not aware when memory of srcu
allocation failed in blk_mq_alloc_hctx, which will leads to illegal
address BUG. Add return value validation to avoid this problem.
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
Reviewed-by: Hou Tao <houtao1(a)huawei.com>
---
block/blk-mq.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 0732bcc65f88..9604d2b39745 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2459,12 +2459,16 @@ blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set,
if (!hctx->fq)
goto free_bitmap;
- if (hctx->flags & BLK_MQ_F_BLOCKING)
- init_srcu_struct(hctx->srcu);
+ if (hctx->flags & BLK_MQ_F_BLOCKING) {
+ if (init_srcu_struct(hctx->srcu) != 0)
+ goto free_flush_queue;
+ }
blk_mq_hctx_kobj_init(hctx);
return hctx;
+ free_flush_queue:
+ blk_free_flush_queue(hctx->fq);
free_bitmap:
sbitmap_free(&hctx->ctx_map);
free_ctxs:
--
2.22.0
1
0

[PATCH openEuler-1.0-LTS] irqchip/gic-phytium-2500: Fix issue that interrupts are concentrated in one cpu
by Laibin Qiu 18 Mar '22
by Laibin Qiu 18 Mar '22
18 Mar '22
From: Mao HongBo <maohongbo(a)phytium.com.cn>
Phytium inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I41AUQ
CVE: NA
-------------------------------------------------
Fix the issue that interrupts are concentrated in one cpu
for Phytium S2500 server.
Signed-off-by: Mao HongBo <maohongbo(a)phytium.com.cn>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Hanjun Guo <guohanjun(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
drivers/irqchip/irq-gic-phytium-2500-its.c | 3 +--
drivers/irqchip/irq-gic-phytium-2500.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/irqchip/irq-gic-phytium-2500-its.c b/drivers/irqchip/irq-gic-phytium-2500-its.c
index fff1c8546d23..dd24af3793ca 100644
--- a/drivers/irqchip/irq-gic-phytium-2500-its.c
+++ b/drivers/irqchip/irq-gic-phytium-2500-its.c
@@ -1181,8 +1181,7 @@ static int its_cpumask_select(struct its_device *its_dev,
}
cpu = cpumask_any_and(mask_val, cpu_mask);
- if ((cpu > cpus) && (cpu < (cpus + skt_cpu_cnt[skt_id])))
- cpus = cpu;
+ cpus = cpus + cpu % skt_cpu_cnt[skt_id];
if (is_kdump_kernel()) {
skt = (cpu_logical_map(cpu) >> 16) & 0xff;
diff --git a/drivers/irqchip/irq-gic-phytium-2500.c b/drivers/irqchip/irq-gic-phytium-2500.c
index 8674463a08c6..103e97f5855e 100644
--- a/drivers/irqchip/irq-gic-phytium-2500.c
+++ b/drivers/irqchip/irq-gic-phytium-2500.c
@@ -1123,8 +1123,7 @@ static int gic_cpumask_select(struct irq_data *d, const struct cpumask *mask_val
}
cpu = cpumask_any_and(mask_val, cpu_online_mask);
- if ((cpu > cpus) && (cpu < (cpus + skt_cpu_cnt[irq_skt])))
- cpus = cpu;
+ cpus = cpus + cpu % skt_cpu_cnt[irq_skt];
if (is_kdump_kernel()) {
skt = (cpu_logical_map(cpu) >> 16) & 0xff;
--
2.22.0
1
0

[PATCH openEuler-1.0-LTS 1/3] veth: Do not record rx queue hint in veth_xmit
by Laibin Qiu 17 Mar '22
by Laibin Qiu 17 Mar '22
17 Mar '22
From: Daniel Borkmann <daniel(a)iogearbox.net>
stable inclusion
from linux-4.19.226
commit bd6e97e2b6f59a19894c7032a83f03ad38ede28e
--------------------------------
commit 710ad98c363a66a0cd8526465426c5c5f8377ee0 upstream.
Laurent reported that they have seen a significant amount of TCP retransmissions
at high throughput from applications residing in network namespaces talking to
the outside world via veths. The drops were seen on the qdisc layer (fq_codel,
as per systemd default) of the phys device such as ena or virtio_net due to all
traffic hitting a _single_ TX queue _despite_ multi-queue device. (Note that the
setup was _not_ using XDP on veths as the issue is generic.)
More specifically, after edbea9220251 ("veth: Store queue_mapping independently
of XDP prog presence") which made it all the way back to v4.19.184+,
skb_record_rx_queue() would set skb->queue_mapping to 1 (given 1 RX and 1 TX
queue by default for veths) instead of leaving at 0.
This is eventually retained and callbacks like ena_select_queue() will also pick
single queue via netdev_core_pick_tx()'s ndo_select_queue() once all the traffic
is forwarded to that device via upper stack or other means. Similarly, for others
not implementing ndo_select_queue() if XPS is disabled, netdev_pick_tx() might
call into the skb_tx_hash() and check for prior skb_rx_queue_recorded() as well.
In general, it is a _bad_ idea for virtual devices like veth to mess around with
queue selection [by default]. Given dev->real_num_tx_queues is by default 1,
the skb->queue_mapping was left untouched, and so prior to edbea9220251 the
netdev_core_pick_tx() could do its job upon __dev_queue_xmit() on the phys device.
Unbreak this and restore prior behavior by removing the skb_record_rx_queue()
from veth_xmit() altogether.
If the veth peer has an XDP program attached, then it would return the first RX
queue index in xdp_md->rx_queue_index (unless configured in non-default manner).
However, this is still better than breaking the generic case.
Fixes: edbea9220251 ("veth: Store queue_mapping independently of XDP prog presence")
Fixes: 638264dc9022 ("veth: Support per queue XDP ring")
Reported-by: Laurent Bernaille <laurent.bernaille(a)datadoghq.com>
Signed-off-by: Daniel Borkmann <daniel(a)iogearbox.net>
Cc: Maciej Fijalkowski <maciej.fijalkowski(a)intel.com>
Cc: Toshiaki Makita <toshiaki.makita1(a)gmail.com>
Cc: Eric Dumazet <eric.dumazet(a)gmail.com>
Cc: Paolo Abeni <pabeni(a)redhat.com>
Cc: John Fastabend <john.fastabend(a)gmail.com>
Cc: Willem de Bruijn <willemb(a)google.com>
Acked-by: John Fastabend <john.fastabend(a)gmail.com>
Reviewed-by: Eric Dumazet <edumazet(a)google.com>
Acked-by: Toshiaki Makita <toshiaki.makita1(a)gmail.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
drivers/net/veth.c
Signed-off-by: Ziyang Xuan <william.xuanziyang(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
drivers/net/veth.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 41a00cd76955..749faa6fcd82 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -197,8 +197,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
if (rxq < rcv->real_num_rx_queues) {
rq = &rcv_priv->rq[rxq];
rcv_xdp = rcu_access_pointer(rq->xdp_prog);
- if (rcv_xdp)
- skb_record_rx_queue(skb, rxq);
}
if (likely(veth_forward_skb(rcv, skb, rq, rcv_xdp) == NET_RX_SUCCESS)) {
--
2.22.0
1
2