* [LTP] [PATCH v2] fw_load: new test of device firmware loading
@ 2013-06-14 11:17 Alexey Kodanev
2013-06-14 13:48 ` Jan Stancek
0 siblings, 1 reply; 6+ messages in thread
From: Alexey Kodanev @ 2013-06-14 11:17 UTC (permalink / raw)
To: ltp-list; +Cc: vasily.isaenko, Alexey Kodanev
This test checks that from kernel 3.7 firmware can be loaded directly
(by-pass udev) or as usual. The test consists of the two parts: userspace
and kernelspace.
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
runtest/syscalls | 2 +
testcases/kernel/Makefile | 1 +
testcases/kernel/firmware/Makefile | 45 +++
.../kernel/firmware/fw_load_kernel/.gitignore | 1 +
testcases/kernel/firmware/fw_load_kernel/Makefile | 37 +++
testcases/kernel/firmware/fw_load_kernel/README | 14 +
testcases/kernel/firmware/fw_load_kernel/fw_load.c | 162 ++++++++++
testcases/kernel/firmware/fw_load_user/.gitignore | 1 +
testcases/kernel/firmware/fw_load_user/Makefile | 20 ++
testcases/kernel/firmware/fw_load_user/README | 11 +
testcases/kernel/firmware/fw_load_user/fw_load.c | 325 ++++++++++++++++++++
11 files changed, 619 insertions(+), 0 deletions(-)
create mode 100644 testcases/kernel/firmware/Makefile
create mode 100644 testcases/kernel/firmware/fw_load_kernel/.gitignore
create mode 100644 testcases/kernel/firmware/fw_load_kernel/Makefile
create mode 100644 testcases/kernel/firmware/fw_load_kernel/README
create mode 100644 testcases/kernel/firmware/fw_load_kernel/fw_load.c
create mode 100644 testcases/kernel/firmware/fw_load_user/.gitignore
create mode 100644 testcases/kernel/firmware/fw_load_user/Makefile
create mode 100644 testcases/kernel/firmware/fw_load_user/README
create mode 100644 testcases/kernel/firmware/fw_load_user/fw_load.c
diff --git a/runtest/syscalls b/runtest/syscalls
index e6ce29c..c11379c 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -314,6 +314,8 @@ ftruncate04_64 ftruncate04.sh 64
#futimesat test cases
futimesat01 futimesat01
+fw_load fw_load
+
getcontext01 getcontext01
getcpu01 getcpu01
diff --git a/testcases/kernel/Makefile b/testcases/kernel/Makefile
index 4b4800d..256a574 100644
--- a/testcases/kernel/Makefile
+++ b/testcases/kernel/Makefile
@@ -38,6 +38,7 @@ ifneq ($(UCLINUX),1)
SUBDIRS += connectors \
containers \
controllers \
+ firmware \
fs \
hotplug \
io \
diff --git a/testcases/kernel/firmware/Makefile b/testcases/kernel/firmware/Makefile
new file mode 100644
index 0000000..f6db454
--- /dev/null
+++ b/testcases/kernel/firmware/Makefile
@@ -0,0 +1,45 @@
+# 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
+
+top_srcdir ?= ../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+SUBDIRS =
+PROCEED = 0
+REQ_VERSION_MAJOR = 3
+REQ_VERSION_MINOR = 7
+
+ifeq ($(MAKECMDGOALS),clean)
+proceed = 1
+endif
+
+ifeq ($(WITH_MODULES),yes)
+proceed = $(shell expr $(LINUX_VERSION_MAJOR) '>' $(REQ_VERSION_MAJOR))
+ifeq ($(proceed),0)
+proceed = $(shell expr $(LINUX_VERSION_MAJOR) '=' $(REQ_VERSION_MAJOR))
+ifeq ($(proceed),1)
+proceed = $(shell expr $(LINUX_PATCHLEVEL) '>=' $(REQ_VERSION_MINOR))
+endif
+endif
+endif
+
+ifeq ($(proceed),1)
+SUBDIRS += fw_load_kernel
+SUBDIRS += fw_load_user
+endif
+
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/kernel/firmware/fw_load_kernel/.gitignore b/testcases/kernel/firmware/fw_load_kernel/.gitignore
new file mode 100644
index 0000000..fdb463d
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_kernel/.gitignore
@@ -0,0 +1 @@
+/fw_load.ko
diff --git a/testcases/kernel/firmware/fw_load_kernel/Makefile b/testcases/kernel/firmware/fw_load_kernel/Makefile
new file mode 100644
index 0000000..e8d12be
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_kernel/Makefile
@@ -0,0 +1,37 @@
+# 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
+
+MODULE := fw_load
+
+ifneq ($(KERNELRELEASE),)
+
+obj-m := $(MODULE).o
+
+else
+
+top_srcdir ?= ../../../..
+include $(top_srcdir)/include/mk/env_pre.mk
+
+MAKE_TARGETS := $(MODULE).ko
+$(MODULE).ko:
+ -$(MAKE) -C $(LINUX_DIR) M=$(abs_srcdir)
+ -mv $(MODULE).ko $(MODULE).ko~
+ -$(MAKE) -C $(LINUX_DIR) M=$(abs_srcdir) clean
+ -mv $(MODULE).ko~ $(MODULE).ko
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+endif
diff --git a/testcases/kernel/firmware/fw_load_kernel/README b/testcases/kernel/firmware/fw_load_kernel/README
new file mode 100644
index 0000000..78343d3
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_kernel/README
@@ -0,0 +1,14 @@
+The aim of the test is to check that after kernel 3.7 firmware can be loaded
+directly (by-pass udev) or as usual. 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.
+The parameters passed with the insmod command. They include template firmware
+file name, number of firmware files to request, and expected data size in the
+firmware files. In the end, the device will create sysfs file, that can be
+read to get request firmware results. Also, some information regarding module
+loading, can be obtained by looking at kernel log file.
+
+It is automatically used by user space part of the test.
diff --git a/testcases/kernel/firmware/fw_load_kernel/fw_load.c b/testcases/kernel/firmware/fw_load_kernel/fw_load.c
new file mode 100644
index 0000000..47bd78f
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_kernel/fw_load.c
@@ -0,0 +1,162 @@
+/*
+ * 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
+ *
+ * Author:
+ * Alexey Kodanev <alexey.kodanev@oracle.com>
+ *
+ * This module is trying to load external test firmware files (load_tst_#.fw).
+ * In the end, it writes results to sys/devices/fw_load_tst/result file.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/firmware.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexey Kodanev <alexey.kodanev@oracle.com>");
+MODULE_DESCRIPTION("This module is checking firmware loading process");
+
+#define TCID "fw_load"
+
+/* number of firmware files to check in the test */
+static int fw_num = 8;
+static char *fw_name = "load_tst.fw";
+static int fw_size = 0x1000;
+static int max_name = 64;
+static int fw;
+
+module_param(fw_num, int, 0444);
+MODULE_PARM_DESC(fw_num, "Number of firmwares to check");
+
+module_param(fw_name, charp, 0444);
+MODULE_PARM_DESC(fw_name, "Template firmware file: n#_name");
+
+module_param(fw_size, int, 0444);
+MODULE_PARM_DESC(fw_size, "Firmware file size");
+
+/*
+ * bit mask for each test-case,
+ * if test is passed, bit will be set to 1
+ */
+static int test_result;
+
+/* read and print firmware data */
+static int fw_read(const u8 *data, size_t size);
+
+static void device_release(struct device *dev);
+
+static struct device tdev = {
+ .init_name = TCID,
+ .release = device_release,
+};
+
+static int try_request_fw(const char *name);
+
+/* print test result to sysfs file */
+static ssize_t sys_result(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static DEVICE_ATTR(result, S_IRUSR, sys_result, NULL);
+
+
+static int test_init(void)
+{
+ int err;
+
+ err = device_register(&tdev);
+
+ if (err) {
+ pr_err(TCID ": Unable to register device\n");
+ return err;
+ }
+ pr_info(TCID ": device registered\n");
+
+ 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);
+ test_result |= (err == 0) << fw;
+ }
+
+ err = device_create_file(&tdev, &dev_attr_result);
+ if (err != 0)
+ pr_info(TCID ": Can't create sysfs file\n");
+
+ return err;
+}
+
+static void test_exit(void)
+{
+ device_remove_file(&tdev, &dev_attr_result);
+ device_unregister(&tdev);
+ pr_info(TCID ": module exited\n");
+}
+
+static void device_release(struct device *dev)
+{
+ pr_info(TCID ": device released\n");
+}
+
+static ssize_t sys_result(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", test_result);
+}
+
+static int fw_read(const u8 *data, size_t size)
+{
+ size_t i;
+
+ pr_info(TCID ": Firmware has size '%d'\n", (unsigned int) size);
+
+ if (size != fw_size) {
+ pr_err(TCID ": Expected firmware size '%d'\n",
+ (unsigned int) fw_size);
+ return -1;
+ }
+
+ for (i = 0; i < size; ++i) {
+ if (data[i] != (u8)fw) {
+ pr_err(TCID ": Unexpected firmware data\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int try_request_fw(const char *name)
+{
+ 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);
+
+ release_firmware(fw_entry);
+
+ return err;
+}
+
+module_init(test_init);
+module_exit(test_exit);
diff --git a/testcases/kernel/firmware/fw_load_user/.gitignore b/testcases/kernel/firmware/fw_load_user/.gitignore
new file mode 100644
index 0000000..1d08149
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_user/.gitignore
@@ -0,0 +1 @@
+/fw_load
diff --git a/testcases/kernel/firmware/fw_load_user/Makefile b/testcases/kernel/firmware/fw_load_user/Makefile
new file mode 100644
index 0000000..effd5da
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_user/Makefile
@@ -0,0 +1,20 @@
+# 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
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/firmware/fw_load_user/README b/testcases/kernel/firmware/fw_load_user/README
new file mode 100644
index 0000000..41c2bf9
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_user/README
@@ -0,0 +1,11 @@
+The aim of the test is to check that after kernel 3.7 firmware can be loaded
+directly (by-pass udev) or as usual. The test consists of the two parts:
+ - userspace part
+ - kernelspace part
+
+This is the userspace part, its tasks are:
+ - create firmware files in the searched paths by udev and kernels
+ - replace udev's searched paths to tmp directory (firmware.sh)
+ - load the module and wait for results
+ - read device's result file and print test results
+ - clean up tmp directory and unload the module.
diff --git a/testcases/kernel/firmware/fw_load_user/fw_load.c b/testcases/kernel/firmware/fw_load_user/fw_load.c
new file mode 100644
index 0000000..900144b
--- /dev/null
+++ b/testcases/kernel/firmware/fw_load_user/fw_load.c
@@ -0,0 +1,325 @@
+/*
+ * 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
+ *
+ * Author:
+ * Alexey Kodanev <alexey.kodanev@oracle.com>
+ *
+ * Test checks following preconditions:
+ * Linux kernels from version 3.7 are loading firmware files directly
+ * using hard coded paths. In case the firmware not found, loading will
+ * be proceeded as usual (udev).
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+#include <sys/utsname.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+/* number of test firmware files */
+#define FW_FILES 9
+
+char *TCID = "fw_load";
+int TST_TOTAL = FW_FILES;
+
+#define MAX_CMD_LEN 256
+/* hard coded paths in the kernel */
+#define FW_PATHS_NUM 4
+
+static int fw_size = 0x1000;
+
+static const char fw_name[] = "load_tst.fw";
+static const char module_name[] = "fw_load.ko";
+static const char udev_script[] = "/lib/udev/firmware.sh";
+
+enum load_mode {
+ DIRECT_LOAD = 0,
+ UDEV_LOAD
+};
+
+struct fw_file_info {
+ char file[PATH_MAX];
+ char dir[PATH_MAX];
+ int mode;
+ int fake;
+ int remove_dir;
+ int remove_file;
+};
+
+static struct fw_file_info fw[FW_FILES];
+static int fw_num;
+
+/* related firmware paths which are searched by kernel and udev */
+static char fw_paths[FW_PATHS_NUM][PATH_MAX];
+static char tmp_dir[PATH_MAX];
+static char mod_path[PATH_MAX];
+
+/* test options */
+static char *narg;
+static int nflag;
+static int skip_cleanup;
+static int verbose;
+static const option_t options[] = {
+ {"n:", &nflag, &narg},
+ {"s", &skip_cleanup, NULL},
+ {"v", &verbose, NULL},
+ {NULL, NULL, NULL}
+};
+
+static void help(void);
+static void setup(int argc, char *argv[]);
+static void test_run(void);
+static void cleanup(void);
+
+/*
+ * create firmware files in the fw_paths
+ * @path: start directory
+ * @mode: can be DIRECT_LOAD or UDEV_LOAD
+ */
+static void create_firmware(const char *path, int mode);
+/* make a string from another by adding escape '\' before each '/' */
+static void reg_path(char *dst, const char *src);
+/* replace a string with another string in a file */
+static void str_replace(const char *file, const char *old, const char *new);
+
+int main(int argc, char *argv[])
+{
+ setup(argc, argv);
+
+ test_run();
+
+ cleanup();
+
+ tst_exit();
+}
+
+static void help(void)
+{
+ printf(" -n x Write x bytes to firmware file, default is %d\n",
+ fw_size);
+ printf(" -s Skip cleanup\n");
+ printf(" -v Verbose\n");
+}
+
+/* cleanup flags */
+static int fw_script_changed;
+static int fw_rules_copied;
+static int module_registered;
+
+void setup(int argc, char *argv[])
+{
+ char *msg;
+ msg = parse_opts(argc, argv, options, help);
+ if (msg != NULL)
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+ if (nflag) {
+ if (sscanf(narg, "%i", &fw_size) != 1)
+ tst_brkm(TBROK, NULL, "-n option arg is not a number");
+ if (fw_size < 0)
+ tst_brkm(TBROK, NULL, "-n option arg is less than 0");
+ }
+
+ tst_require_root(NULL);
+
+ if (tst_kvercmp(3, 7, 0) < 0) {
+ tst_brkm(TCONF, NULL,
+ "Test must be run with kernel 3.7 or newer");
+ }
+
+ if (access(module_name, F_OK) == -1) {
+ tst_brkm(TCONF, NULL,
+ "Test requires kernel module '%s'", module_name);
+ }
+
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ /* add firmware rule to udev */
+ if (access("/etc/udev/rules.d/50-firmware.rules", 0) == -1) {
+ SAFE_CP(cleanup, "/lib/udev/rules.d/50-firmware.rules",
+ "/etc/udev/rules.d/");
+ fw_rules_copied = 1;
+
+ if (system("udevadm control --reload-rules") != 0)
+ tst_resm(TWARN, "Can't update udev rules");
+ }
+
+ /* get current Linux version and make firmware paths */
+ struct utsname uts_name;
+ uname(&uts_name);
+ strcpy(fw_paths[0], "firmware");
+ strcpy(fw_paths[1], "firmware/updates");
+ snprintf(fw_paths[2], PATH_MAX, "firmware/%s", uts_name.release);
+ snprintf(fw_paths[3], PATH_MAX, "firmware/updates/%s",
+ uts_name.release);
+
+ /* copy firmware to direct firmware search paths */
+ create_firmware("/lib", DIRECT_LOAD);
+
+ /* save module path to mod_path */
+ SAFE_GETCWD(cleanup, mod_path, PATH_MAX);
+ int offset = strlen(mod_path);
+ snprintf(mod_path + offset, PATH_MAX - offset, "/%s", module_name);
+
+ tst_tmpdir();
+
+ char *cwd = get_tst_tmpdir();
+ snprintf(tmp_dir, PATH_MAX, cwd);
+ free(cwd);
+
+ /* replace udev's firmware search path in firmware.sh */
+ str_replace(udev_script, "/lib", tmp_dir);
+ fw_script_changed = 1;
+
+ /* create firmware in the udev firmware search paths */
+ create_firmware(tmp_dir, UDEV_LOAD);
+
+ /* make non-existent firmware file */
+ snprintf(fw[fw_num].file, PATH_MAX, "n%d_%s", fw_num, fw_name);
+ fw[fw_num].fake = 1;
+ fw[fw_num].mode = UDEV_LOAD;
+ ++fw_num;
+}
+
+static void test_run()
+{
+ /* load test module */
+ char cmd[MAX_CMD_LEN];
+ snprintf(cmd, MAX_CMD_LEN,
+ "insmod %s fw_name=%s fw_num=%d fw_size=%d",
+ mod_path, fw_name, fw_num, fw_size);
+ if (system(cmd) != 0)
+ tst_brkm(TBROK, cleanup, "Failed to insert %s", module_name);
+ module_registered = 1;
+
+ /* get module results */
+ char dev_path[PATH_MAX];
+ snprintf(dev_path, PATH_MAX, "/sys/devices/%s/result", TCID);
+
+ int result = 0;
+ /* read result bit mask */
+ SAFE_FILE_SCANF(cleanup, dev_path, "%d", &result);
+
+ int i, fail;
+ for (i = 0; i < fw_num; ++i) {
+ fail = (result & (1 << i)) == 0 && !fw[i].fake;
+
+ tst_resm((fail) ? TFAIL : TPASS,
+ "Expect: %s load firmware '...%s', %s used",
+ (fw[i].fake) ? "can't" : "can",
+ fw[i].file + strlen(fw[i].dir),
+ (fw[i].mode == UDEV_LOAD) ? "udev" : "kernel");
+ }
+}
+
+static void cleanup(void)
+{
+ if (skip_cleanup)
+ return;
+
+ if (fw_rules_copied)
+ remove("/etc/udev/rules.d/50-firmware.rules");
+
+ if (fw_script_changed)
+ str_replace(udev_script, tmp_dir, "/lib");
+
+ int i;
+ for (i = fw_num - 1; i >= 0; --i) {
+ if (fw[i].remove_file && remove(fw[i].file) == -1)
+ tst_resm(TWARN, "Can't remove: %s", fw[i].file);
+
+ if (fw[i].remove_dir && remove(fw[i].dir) == -1)
+ tst_resm(TWARN, "Can't remove %s", fw[i].dir);
+ }
+
+ if (module_registered) {
+ char cmd[MAX_CMD_LEN];
+ snprintf(cmd, MAX_CMD_LEN, "rmmod %s", mod_path);
+ if (system(cmd) != 0)
+ tst_brkm(TBROK, NULL, "Can't remove %s", module_name);
+ }
+
+ tst_rmdir();
+ TEST_CLEANUP;
+}
+
+static void create_firmware(const char *path, int mode)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(fw_paths); ++i) {
+ struct fw_file_info *f = &fw[fw_num];
+ f->mode = mode;
+ snprintf(f->dir, PATH_MAX, "%s/%s", path, fw_paths[i]);
+ if (access(f->dir, X_OK) == -1) {
+ /* create dir */
+ SAFE_MKDIR(cleanup, f->dir, 0755);
+ f->remove_dir = mode == DIRECT_LOAD;
+ }
+
+ /* create test firmware file */
+ snprintf(f->file, PATH_MAX, "%s/n%d_%s",
+ f->dir, fw_num, fw_name);
+
+ FILE *fd = fopen(f->file, "w");
+ if (fd == NULL)
+ tst_brkm(TBROK, cleanup, "Failed to create firmware");
+ int k;
+ for (k = 0; k < fw_size; ++k)
+ fputc(fw_num, fd);
+ fclose(fd);
+
+ f->remove_file = mode == DIRECT_LOAD;
+ ++fw_num;
+ }
+}
+
+static void reg_path(char *dst, const char *src)
+{
+ const char *p = src;
+ while ((p = strchr(src, '/')) != NULL) {
+ int len = p - src;
+ strncpy(dst, src, len);
+ dst += len;
+ strcpy(dst, "\\/");
+ dst += 2;
+ src = p + 1;
+ }
+ strcpy(dst, src);
+}
+
+static void str_replace(const char *file, const char *old, const char *new)
+{
+ char cmd[MAX_CMD_LEN], reg_old[PATH_MAX], reg_new[PATH_MAX];
+
+ reg_path(reg_old, old);
+ reg_path(reg_new, new);
+
+ snprintf(cmd, MAX_CMD_LEN, "sed -i 's/%s/%s/g' %s",
+ reg_old, reg_new, file);
+ if (system(cmd) != 0)
+ tst_brkm(TBROK, cleanup, "Can't replace strings");
+}
--
1.7.1
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [LTP] [PATCH v2] fw_load: new test of device firmware loading
2013-06-14 11:17 [LTP] [PATCH v2] fw_load: new test of device firmware loading Alexey Kodanev
@ 2013-06-14 13:48 ` Jan Stancek
2013-06-14 14:44 ` alexey.kodanev
0 siblings, 1 reply; 6+ messages in thread
From: Jan Stancek @ 2013-06-14 13:48 UTC (permalink / raw)
To: Alexey Kodanev; +Cc: vasily isaenko, ltp-list
Hi,
I ran this on older kernel, which worked fine - it skipped the build.
Then I tried RHEL7 alpha, which has more recent kernel: 3.10.0-0.rc4,
but it failed:
# ./fw_load
cp: cannot stat ‘/lib/udev/rules.d/50-firmware.rules’: No such file or directory
fw_load 1 TBROK : Failed to copy '/lib/udev/rules.d/50-firmware.rules' to '/etc/udev/rules.d/' at fw_load.c:164
fw_load 2 TBROK : Remaining cases broken
fw_load 0 TWARN : tst_rmdir: TESTDIR was NULL; no removal attempted
I'll see if I can find out what happened to 50-firmware.rules,
it could some side-effect of systemd.
I found this initialization a little confusing, since your test
always relies on passing it from user-space (which passes 9):
> +static int fw_num = 8;
Regards,
Jan
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2] fw_load: new test of device firmware loading
2013-06-14 13:48 ` Jan Stancek
@ 2013-06-14 14:44 ` alexey.kodanev
2013-06-14 15:16 ` Jan Stancek
0 siblings, 1 reply; 6+ messages in thread
From: alexey.kodanev @ 2013-06-14 14:44 UTC (permalink / raw)
To: Jan Stancek; +Cc: vasily isaenko, ltp-list
Hi!
On 06/14/2013 05:48 PM, Jan Stancek wrote:
> Hi,
>
> I ran this on older kernel, which worked fine - it skipped the build.
> Then I tried RHEL7 alpha, which has more recent kernel: 3.10.0-0.rc4,
> but it failed:
>
> # ./fw_load
> cp: cannot stat ‘/lib/udev/rules.d/50-firmware.rules’: No such file or directory
> fw_load 1 TBROK : Failed to copy '/lib/udev/rules.d/50-firmware.rules' to '/etc/udev/rules.d/' at fw_load.c:164
> fw_load 2 TBROK : Remaining cases broken
> fw_load 0 TWARN : tst_rmdir: TESTDIR was NULL; no removal attempted
>
> I'll see if I can find out what happened to 50-firmware.rules,
> it could some side-effect of systemd.
>
Would it be better to change failed copy command to just TWARN, and
continue testing? After that, test will completed with udev failed
test-cases, or if udev has those rules in the other configuration files,
everything will be fine.
I just checked it on my machine, output will be:
fw_load 1 TPASS : Expect: can load firmware '.../n0_load_tst.fw',
kernel used
fw_load 2 TPASS : Expect: can load firmware '.../n1_load_tst.fw',
kernel used
fw_load 3 TPASS : Expect: can load firmware '.../n2_load_tst.fw',
kernel used
fw_load 4 TPASS : Expect: can load firmware '.../n3_load_tst.fw',
kernel used
fw_load 5 TFAIL : Expect: can load firmware '.../n4_load_tst.fw',
udev used
fw_load 6 TFAIL : Expect: can load firmware '.../n5_load_tst.fw',
udev used
fw_load 7 TFAIL : Expect: can load firmware '.../n6_load_tst.fw',
udev used
fw_load 8 TFAIL : Expect: can load firmware '.../n7_load_tst.fw',
udev used
fw_load 9 TPASS : Expect: can't load firmware
'...n8_load_tst.fw', udev used
Interestingly, but in that case (udev doesn't have add firmware rule)
udev doing it so long (test-cases 5 - 9), it is not surprisingly that
right now firmware loading by-pass udev!
> I found this initialization a little confusing, since your test
> always relies on passing it from user-space (which passes 9):
>
>> +static int fw_num = 8;
It is default value, and never used in the test (always replaced by
module parameter)... OK, I will change it, also I will skip fw_num
parameter in the userspace test as it will become useless.
Thanks,
Alexey
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2] fw_load: new test of device firmware loading
2013-06-14 14:44 ` alexey.kodanev
@ 2013-06-14 15:16 ` Jan Stancek
2013-06-17 8:39 ` alexey.kodanev
0 siblings, 1 reply; 6+ messages in thread
From: Jan Stancek @ 2013-06-14 15:16 UTC (permalink / raw)
To: alexey kodanev; +Cc: vasily isaenko, ltp-list
----- Original Message -----
> From: "alexey kodanev" <alexey.kodanev@oracle.com>
> To: "Jan Stancek" <jstancek@redhat.com>
> Cc: ltp-list@lists.sourceforge.net, "vasily isaenko" <vasily.isaenko@oracle.com>
> Sent: Friday, 14 June, 2013 4:44:40 PM
> Subject: Re: [LTP] [PATCH v2] fw_load: new test of device firmware loading
>
> Hi!
>
> On 06/14/2013 05:48 PM, Jan Stancek wrote:
> > Hi,
> >
> > I ran this on older kernel, which worked fine - it skipped the build.
> > Then I tried RHEL7 alpha, which has more recent kernel: 3.10.0-0.rc4,
> > but it failed:
> >
> > # ./fw_load
> > cp: cannot stat ‘/lib/udev/rules.d/50-firmware.rules’: No such file or
> > directory
> > fw_load 1 TBROK : Failed to copy
> > '/lib/udev/rules.d/50-firmware.rules' to '/etc/udev/rules.d/' at
> > fw_load.c:164
> > fw_load 2 TBROK : Remaining cases broken
> > fw_load 0 TWARN : tst_rmdir: TESTDIR was NULL; no removal attempted
> >
> > I'll see if I can find out what happened to 50-firmware.rules,
> > it could some side-effect of systemd.
> >
> Would it be better to change failed copy command to just TWARN, and
> continue testing? After that, test will completed with udev failed
> test-cases, or if udev has those rules in the other configuration files,
> everything will be fine.
I'd go with TCONF or skip udev testcases if we can't be sure that udev is running
and properly configured.
I'm also missing firmware.sh, in new udev (now merged with systemd tree),
50-firmware.rules file depends on some compile switch. Even when enabled
the rule looks like this:
http://cgit.freedesktop.org/systemd/systemd/tree/rules/50-firmware.rules
firmware.sh appears to be converted to .c now:
http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-firmware.c
Regards,
Jan
> I just checked it on my machine, output will be:
> fw_load 1 TPASS : Expect: can load firmware '.../n0_load_tst.fw',
> kernel used
> fw_load 2 TPASS : Expect: can load firmware '.../n1_load_tst.fw',
> kernel used
> fw_load 3 TPASS : Expect: can load firmware '.../n2_load_tst.fw',
> kernel used
> fw_load 4 TPASS : Expect: can load firmware '.../n3_load_tst.fw',
> kernel used
> fw_load 5 TFAIL : Expect: can load firmware '.../n4_load_tst.fw',
> udev used
> fw_load 6 TFAIL : Expect: can load firmware '.../n5_load_tst.fw',
> udev used
> fw_load 7 TFAIL : Expect: can load firmware '.../n6_load_tst.fw',
> udev used
> fw_load 8 TFAIL : Expect: can load firmware '.../n7_load_tst.fw',
> udev used
> fw_load 9 TPASS : Expect: can't load firmware
> '...n8_load_tst.fw', udev used
>
> Interestingly, but in that case (udev doesn't have add firmware rule)
> udev doing it so long (test-cases 5 - 9), it is not surprisingly that
> right now firmware loading by-pass udev!
> > I found this initialization a little confusing, since your test
> > always relies on passing it from user-space (which passes 9):
> >
> >> +static int fw_num = 8;
> It is default value, and never used in the test (always replaced by
> module parameter)... OK, I will change it, also I will skip fw_num
> parameter in the userspace test as it will become useless.
>
> Thanks,
> Alexey
>
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2] fw_load: new test of device firmware loading
2013-06-14 15:16 ` Jan Stancek
@ 2013-06-17 8:39 ` alexey.kodanev
2013-06-17 8:50 ` Jan Stancek
0 siblings, 1 reply; 6+ messages in thread
From: alexey.kodanev @ 2013-06-17 8:39 UTC (permalink / raw)
To: Jan Stancek; +Cc: vasily isaenko, ltp-list
[-- Attachment #1.1: Type: text/plain, Size: 2083 bytes --]
On 06/14/2013 07:16 PM, Jan Stancek wrote:
>
>>> I ran this on older kernel, which worked fine - it skipped the build.
>>> Then I tried RHEL7 alpha, which has more recent kernel: 3.10.0-0.rc4,
>>> but it failed:
>>>
>>> # ./fw_load
>>> cp: cannot stat ‘/lib/udev/rules.d/50-firmware.rules’: No such file or
>>> directory
>>> fw_load 1 TBROK : Failed to copy
>>> '/lib/udev/rules.d/50-firmware.rules' to '/etc/udev/rules.d/' at
>>> fw_load.c:164
>>> fw_load 2 TBROK : Remaining cases broken
>>> fw_load 0 TWARN : tst_rmdir: TESTDIR was NULL; no removal attempted
>>>
>>> I'll see if I can find out what happened to 50-firmware.rules,
>>> it could some side-effect of systemd.
>>>
>> Would it be better to change failed copy command to just TWARN, and
>> continue testing? After that, test will completed with udev failed
>> test-cases, or if udev has those rules in the other configuration files,
>> everything will be fine.
> I'd go with TCONF or skip udev testcases if we can't be sure that udev is running
> and properly configured.
>
> I'm also missing firmware.sh, in new udev (now merged with systemd tree),
> 50-firmware.rules file depends on some compile switch. Even when enabled
> the rule looks like this:
> http://cgit.freedesktop.org/systemd/systemd/tree/rules/50-firmware.rules
>
> firmware.sh appears to be converted to .c now:
> http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-firmware.
I see now, I think it is better to skip udev in the test entirely,
because there is a tendency
in kernel community to disable user-mode helper firmware loading (udev).
It is already guarded with
CONFIG_FW_LOADER_USER_HELPER option in firmware code: firmware: Make
user-mode helper optional
<http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b1269f778782d2f42994a74bf4014d0cbebbf9f>.
There is only one use of it: loading firmware from non-standard path. It
might also go away as soon as
configuring paths support had been added to kernel.
Thanks,
Alexey
[-- Attachment #1.2: Type: text/html, Size: 2925 bytes --]
[-- Attachment #2: Type: text/plain, Size: 184 bytes --]
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
[-- Attachment #3: Type: text/plain, Size: 155 bytes --]
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2] fw_load: new test of device firmware loading
2013-06-17 8:39 ` alexey.kodanev
@ 2013-06-17 8:50 ` Jan Stancek
0 siblings, 0 replies; 6+ messages in thread
From: Jan Stancek @ 2013-06-17 8:50 UTC (permalink / raw)
To: alexey kodanev; +Cc: vasily isaenko, ltp-list
----- Original Message -----
> From: "alexey kodanev" <alexey.kodanev@oracle.com>
> To: "Jan Stancek" <jstancek@redhat.com>
> Cc: ltp-list@lists.sourceforge.net, "vasily isaenko" <vasily.isaenko@oracle.com>
> Sent: Monday, 17 June, 2013 10:39:03 AM
> Subject: Re: [LTP] [PATCH v2] fw_load: new test of device firmware loading
>
>
> On 06/14/2013 07:16 PM, Jan Stancek wrote:
> >
> >>> I ran this on older kernel, which worked fine - it skipped the build.
> >>> Then I tried RHEL7 alpha, which has more recent kernel: 3.10.0-0.rc4,
> >>> but it failed:
> >>>
> >>> # ./fw_load
> >>> cp: cannot stat ‘/lib/udev/rules.d/50-firmware.rules’: No such file or
> >>> directory
> >>> fw_load 1 TBROK : Failed to copy
> >>> '/lib/udev/rules.d/50-firmware.rules' to '/etc/udev/rules.d/' at
> >>> fw_load.c:164
> >>> fw_load 2 TBROK : Remaining cases broken
> >>> fw_load 0 TWARN : tst_rmdir: TESTDIR was NULL; no removal
> >>> attempted
> >>>
> >>> I'll see if I can find out what happened to 50-firmware.rules,
> >>> it could some side-effect of systemd.
> >>>
> >> Would it be better to change failed copy command to just TWARN, and
> >> continue testing? After that, test will completed with udev failed
> >> test-cases, or if udev has those rules in the other configuration files,
> >> everything will be fine.
> > I'd go with TCONF or skip udev testcases if we can't be sure that udev is
> > running
> > and properly configured.
> >
> > I'm also missing firmware.sh, in new udev (now merged with systemd tree),
> > 50-firmware.rules file depends on some compile switch. Even when enabled
> > the rule looks like this:
> > http://cgit.freedesktop.org/systemd/systemd/tree/rules/50-firmware.rules
> >
> > firmware.sh appears to be converted to .c now:
> > http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-firmware.
> I see now, I think it is better to skip udev in the test entirely,
> because there is a tendency
> in kernel community to disable user-mode helper firmware loading (udev).
> It is already guarded with
> CONFIG_FW_LOADER_USER_HELPER option in firmware code: firmware: Make
> user-mode helper optional
> <http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b1269f778782d2f42994a74bf4014d0cbebbf9f>.
> There is only one use of it: loading firmware from non-standard path. It
> might also go away as soon as
> configuring paths support had been added to kernel.
I noticed that too, because my udev wasn't getting any events -
kernel I'm using has that option turned off.
I also came across this article: http://lwn.net/Articles/518942/
which says: "No events for a specific device, they decided,
would be processed until the process of loading the driver module
for that device had completed", but this one could be fixed easily
in fw_load kernel module.
Regards,
Jan
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-06-17 8:50 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-14 11:17 [LTP] [PATCH v2] fw_load: new test of device firmware loading Alexey Kodanev
2013-06-14 13:48 ` Jan Stancek
2013-06-14 14:44 ` alexey.kodanev
2013-06-14 15:16 ` Jan Stancek
2013-06-17 8:39 ` alexey.kodanev
2013-06-17 8:50 ` Jan Stancek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox