Linux Test Project
 help / color / mirror / Atom feed
From: Andrea Cervesato <andrea.cervesato@suse.de>
To: Linux Test Project <ltp@lists.linux.it>
Subject: [LTP] [PATCH v3 1/3] fw_load: Modernize ltp_fw_load kernel module
Date: Wed, 10 Jun 2026 19:07:04 +0200	[thread overview]
Message-ID: <20260610-fw_load-v3-1-eef32edfe8d5@suse.com> (raw)
In-Reply-To: <20260610-fw_load-v3-0-eef32edfe8d5@suse.com>

From: Andrea Cervesato <andrea.cervesato@suse.com>

Fix VLA (banned since kernel v4.20), replace sscanf() with
kstrtoint(), reset test_result between invocations, make the
loop variable local and pass expected data explicitly.

Update license headers, fix brace style, drop obsolete README
in favour of the in-source documentation.

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/firmware/fw_load_kernel/Makefile  |  16 +--
 testcases/kernel/firmware/fw_load_kernel/README    |  16 ---
 .../kernel/firmware/fw_load_kernel/ltp_fw_load.c   | 114 ++++++++++++---------
 3 files changed, 66 insertions(+), 80 deletions(-)

diff --git a/testcases/kernel/firmware/fw_load_kernel/Makefile b/testcases/kernel/firmware/fw_load_kernel/Makefile
index 73996996f3397fb0a7f4616457168213587e654f..e81b300faaa6b4056d4b5f3d1417c381a000256d 100644
--- a/testcases/kernel/firmware/fw_load_kernel/Makefile
+++ b/testcases/kernel/firmware/fw_load_kernel/Makefile
@@ -1,18 +1,6 @@
 # Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it would be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write the Free Software Foundation,
-# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+# Copyright (c) Linux Test Project, 2026
+# SPDX-License-Identifier: GPL-2.0-or-later
 
 ifneq ($(KERNELRELEASE),)
 
diff --git a/testcases/kernel/firmware/fw_load_kernel/README b/testcases/kernel/firmware/fw_load_kernel/README
deleted file mode 100644
index 97507fd99aa3bead708cd4bf599f4abf9ec6e2da..0000000000000000000000000000000000000000
--- a/testcases/kernel/firmware/fw_load_kernel/README
+++ /dev/null
@@ -1,16 +0,0 @@
-The aim of the test is to check device firmware loading. Since kernel 3.7
-firmware loading changed to direct loading (by-pass udev). The test consists
-of the two parts:
- - userspace part
- - kernelspace part
-
-This is a kernel module, which is a part of the device firmware loading test.
-It allows to call request_firmware kernel function with specified parameters.
-Template firmware file name and expected firmware file's data size are passed
-as the insmod command line parameters. Then, the number of firmware test files
-should be written to sysfs file 'fwnum' (the maximum number is 32). This write
-will initiate request firmware procedure. In the end, results can be read from
-'result' device sysfs file. Also, some information regarding module loading,
-can be obtained by looking at kernel log file.
-
-It is automatically used by userspace part of the test.
diff --git a/testcases/kernel/firmware/fw_load_kernel/ltp_fw_load.c b/testcases/kernel/firmware/fw_load_kernel/ltp_fw_load.c
index b7397e8f13154a16c2626517545c3c14d153a043..6018e9a630d2f2328c8023568f2b61f7b80831fe 100644
--- a/testcases/kernel/firmware/fw_load_kernel/ltp_fw_load.c
+++ b/testcases/kernel/firmware/fw_load_kernel/ltp_fw_load.c
@@ -1,25 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ * Author: Alexey Kodanev <alexey.kodanev@oracle.com>
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
+ * Copyright (c) 2026 Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*
+ * Kernel module helper for the fw_load test.
  *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Registers a virtual device (ltp_fw_load) that exposes two sysfs
+ * attributes:
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *   fwnum  (write-only) - accepts the number of firmware files to
+ *           request (1-32). Writing triggers request_firmware() for
+ *           each file named n<i>_<fw_name> (i = 0 .. fwnum-1).
+ *           Each loaded blob is verified against the expected size
+ *           (fw_size) and byte pattern (every byte == i).
  *
- * Author:
- * Alexey Kodanev <alexey.kodanev@oracle.com>
+ *   result (read-only)  - bitmask of per-file pass/fail results.
+ *           Bit i is set when n<i>_<fw_name> was loaded and
+ *           verified successfully.
  *
- * This module is trying to load external test firmware files (n#_load_tst.fw).
- * In the end, it writes results to /sys/devices/ltp_fw_load/result file.
+ * Module parameters:
+ *   fw_name  - template firmware file name (default: load_tst.fw)
+ *   fw_size  - expected firmware blob size  (default: 0x1000)
  */
 
 #include <linux/module.h>
@@ -33,12 +38,11 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alexey Kodanev <alexey.kodanev@oracle.com>");
 MODULE_DESCRIPTION("This module is checking device firmware loading");
 
-#define TCID	"ltp_fw_load"
+#define MODULE_NAME	"ltp_fw_load"
+#define MAX_NAME	64
 
 static char *fw_name	= "load_tst.fw";
 static int fw_size	= 0x1000;
-static int max_name	= 64;
-static int fw;
 
 module_param(fw_name, charp, 0444);
 MODULE_PARM_DESC(fw_name, "Template firmware file name: n#_name");
@@ -54,47 +58,53 @@ static int test_result;
 
 static void device_release(struct device *dev)
 {
-	pr_info(TCID ": device released\n");
+	pr_info(MODULE_NAME ": device released\n");
 }
 
 static struct device tdev = {
-	.init_name	= TCID,
+	.init_name	= MODULE_NAME,
 	.release	= device_release,
 };
 
-/* read and print firmware data */
-static int fw_read(const u8 *data, size_t size)
+/* read and verify firmware data */
+static int fw_read(const u8 *data, size_t size, u8 expected)
 {
 	size_t i;
-	pr_info(TCID ": Firmware has size '%zu'\n", size);
+
+	pr_info(MODULE_NAME ": Firmware has size '%zu'\n", size);
 	if (size != fw_size) {
-		pr_err(TCID ": Expected firmware size '%d'\n", fw_size);
+		pr_err(MODULE_NAME ": Expected firmware size '%d'\n", fw_size);
 		return -1;
 	}
+
 	for (i = 0; i < size; ++i) {
-		if (data[i] != (u8)fw) {
-			pr_err(TCID ": Unexpected firmware data\n");
+		if (data[i] != expected) {
+			pr_err(MODULE_NAME ": Unexpected firmware data\n");
 			return -1;
 		}
 	}
+
 	return 0;
 }
 
-static int try_request_fw(const char *name)
+static int try_request_fw(const char *name, u8 expected)
 {
 	int err;
 	const struct firmware *fw_entry = NULL;
+
 	err = request_firmware(&fw_entry, name, &tdev);
 	if (!err) {
-		pr_info(TCID ": firmware '%s' requested\n", name);
-		err = fw_read(fw_entry->data, fw_entry->size);
-	} else
-		pr_err(TCID ": Can't request firmware '%s'\n", name);
+		pr_info(MODULE_NAME ": firmware '%s' requested\n", name);
+		err = fw_read(fw_entry->data, fw_entry->size, expected);
+	} else {
+		pr_err(MODULE_NAME ": Can't request firmware '%s'\n", name);
+	}
+
 	release_firmware(fw_entry);
 	return err;
 }
 
-/* print test result to sysfs file */
+/* Print test result to sysfs file. */
 static ssize_t sys_result(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
@@ -102,26 +112,28 @@ static ssize_t sys_result(struct device *dev,
 }
 static DEVICE_ATTR(result, S_IRUSR, sys_result, NULL);
 
-/*
- * get the number of firmware files and
- * perform firmware requests
- */
+/* Get the number of firmware files and perform firmware requests. */
 static ssize_t sys_fwnum(struct device *dev,
-	struct device_attribute *attr,  const char *buf, size_t count)
+	struct device_attribute *attr, const char *buf, size_t count)
 {
-	int err, fw_num = 0;
+	int err, fw, fw_num;
 
-	sscanf(buf, "%d", &fw_num);
-	if (fw_num <= 0 || fw_num > 32) {
-		pr_err(TCID ": Unexpected number of firmwares '%d'", fw_num);
-		return count;
+	err = kstrtoint(buf, 10, &fw_num);
+	if (err || fw_num <= 0 || fw_num > 32) {
+		pr_err(MODULE_NAME ": Unexpected number of firmwares '%s'", buf);
+		return err ? err : -EINVAL;
 	}
+
+	test_result = 0;
+
 	for (fw = 0; fw < fw_num; ++fw) {
-		char name[max_name];
-		snprintf(name, max_name, "n%d_%s", fw, fw_name);
-		err = try_request_fw(name);
+		char name[MAX_NAME];
+
+		snprintf(name, sizeof(name), "n%d_%s", fw, fw_name);
+		err = try_request_fw(name, (u8)fw);
 		test_result |= (err == 0) << fw;
 	}
+
 	return count;
 }
 static DEVICE_ATTR(fwnum, S_IWUSR, NULL, sys_fwnum);
@@ -132,23 +144,25 @@ static int test_init(void)
 
 	err = device_register(&tdev);
 	if (err) {
-		pr_err(TCID ": Unable to register device\n");
+		pr_err(MODULE_NAME ": Unable to register device\n");
 		return err;
 	}
-	pr_info(TCID ": device registered\n");
+	pr_info(MODULE_NAME ": device registered\n");
 
 	err = device_create_file(&tdev, &dev_attr_result);
 	if (err) {
-		pr_err(TCID ": Can't create sysfs file 'result'\n");
+		pr_err(MODULE_NAME ": Can't create sysfs file 'result'\n");
 		device_unregister(&tdev);
 		return err;
 	}
+
 	err = device_create_file(&tdev, &dev_attr_fwnum);
 	if (err) {
-		pr_err(TCID ": Can't create sysfs file 'fwnum'\n");
+		pr_err(MODULE_NAME ": Can't create sysfs file 'fwnum'\n");
 		device_remove_file(&tdev, &dev_attr_result);
 		device_unregister(&tdev);
 	}
+
 	return err;
 }
 module_init(test_init);
@@ -159,6 +173,6 @@ static void test_exit(void)
 	device_remove_file(&tdev, &dev_attr_fwnum);
 
 	device_unregister(&tdev);
-	pr_info(TCID ": module exited\n");
+	pr_info(MODULE_NAME ": module exited\n");
 }
 module_exit(test_exit);

-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  reply	other threads:[~2026-06-10 17:07 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10 17:07 [LTP] [PATCH v3 0/3] Rewrite fw_load test using new API Andrea Cervesato
2026-06-10 17:07 ` Andrea Cervesato [this message]
2026-06-10 19:44   ` [LTP] fw_load: Modernize ltp_fw_load kernel module linuxtestproject.agent
2026-06-10 17:07 ` [LTP] [PATCH v3 2/3] firmware/fw_load: rewrite firmware loading test using new LTP API Andrea Cervesato
2026-06-10 17:07 ` [LTP] [PATCH v3 3/3] firmware/fw_load: add fw_load02 for custom firmware path Andrea Cervesato

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260610-fw_load-v3-1-eef32edfe8d5@suse.com \
    --to=andrea.cervesato@suse.de \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox