summaryrefslogtreecommitdiff
path: root/lib/igt_kmod.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-02-07 16:08:10 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2017-02-08 11:52:34 +0000
commit8b5453b1e2af9d8bc660916a78e005fd6dab0a31 (patch)
tree37692c16d0796981642fd278706340bcdfe5c3f2 /lib/igt_kmod.c
parent164051347421710b8fa7fe79afec2ef1ffd97d30 (diff)
lib/kselftests: Split up igt_kselftests()
To make it easier to reuse, split up the the single function up into stages. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'lib/igt_kmod.c')
-rw-r--r--lib/igt_kmod.c251
1 files changed, 149 insertions, 102 deletions
diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c
index 5981700c..4b8ea81a 100644
--- a/lib/igt_kmod.c
+++ b/lib/igt_kmod.c
@@ -341,16 +341,9 @@ static void kmsg_dump(int fd)
}
}
-struct test_list {
- struct igt_list link;
- unsigned int number;
- char *name;
- char param[];
-};
-
-static void tests_add(struct test_list *tl, struct igt_list *list)
+static void tests_add(struct igt_kselftest_list *tl, struct igt_list *list)
{
- struct test_list *pos;
+ struct igt_kselftest_list *pos;
igt_list_for_each(pos, list, link)
if (pos->number > tl->number)
@@ -359,6 +352,57 @@ static void tests_add(struct test_list *tl, struct igt_list *list)
igt_list_add_tail(&tl->link, &pos->link);
}
+void igt_kselftest_get_tests(struct kmod_module *kmod,
+ const char *filter,
+ struct igt_list *tests)
+{
+ const char *param_prefix = "igt__";
+ const int prefix_len = strlen(param_prefix);
+ struct kmod_list *d, *pre;
+ struct igt_kselftest_list *tl;
+
+ pre = NULL;
+ if (!kmod_module_get_info(kmod, &pre))
+ return;
+
+ kmod_list_foreach(d, pre) {
+ const char *key, *val;
+ char *colon;
+ int offset;
+
+ key = kmod_module_info_get_key(d);
+ if (strcmp(key, "parmtype"))
+ continue;
+
+ val = kmod_module_info_get_value(d);
+ if (!val || strncmp(val, param_prefix, prefix_len))
+ continue;
+
+ offset = strlen(val) + 1;
+ tl = malloc(sizeof(*tl) + offset);
+ if (!tl)
+ continue;
+
+ memcpy(tl->param, val, offset);
+ colon = strchr(tl->param, ':');
+ *colon = '\0';
+
+ tl->number = 0;
+ tl->name = tl->param + prefix_len;
+ if (sscanf(tl->name, "%u__%n",
+ &tl->number, &offset) == 1)
+ tl->name += offset;
+
+ if (filter && strncmp(tl->name, filter, strlen(filter))) {
+ free(tl);
+ continue;
+ }
+
+ tests_add(tl, tests);
+ }
+ kmod_module_info_free_list(pre);
+}
+
static int open_parameters(const char *module_name)
{
char path[256];
@@ -367,109 +411,112 @@ static int open_parameters(const char *module_name)
return open(path, O_RDONLY);
}
-void igt_kselftests(const char *module_name,
- const char *module_options,
- const char *result,
- const char *filter)
+int igt_kselftest_init(struct igt_kselftest *tst,
+ const char *module_name)
{
- const char *param_prefix = "igt__";
- const int prefix_len = strlen(param_prefix);
- IGT_LIST(tests);
- char options[1024];
- struct kmod_ctx *ctx = kmod_ctx();
- struct kmod_module *kmod;
- struct kmod_list *d, *pre;
- struct test_list *tl, *tn;
- int err, kmsg = -1;
+ int err;
- igt_require(kmod_module_new_from_name(ctx, module_name, &kmod) == 0);
- igt_fixture {
- if (strcmp(module_name, "i915") == 0)
- igt_i915_driver_unload();
+ memset(tst, 0, sizeof(*tst));
- err = kmod_module_remove_module(kmod, KMOD_REMOVE_FORCE);
- igt_require(err == 0 || err == -ENOENT);
+ tst->module_name = strdup(module_name);
+ igt_assert(tst->module_name);
- kmsg = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
- }
+ tst->kmsg = -1;
- pre = NULL;
- if (kmod_module_get_info(kmod, &pre)) {
- kmod_list_foreach(d, pre) {
- const char *key, *val;
- char *colon;
- int offset;
-
- key = kmod_module_info_get_key(d);
- if (strcmp(key, "parmtype"))
- continue;
-
- val = kmod_module_info_get_value(d);
- if (!val || strncmp(val, param_prefix, prefix_len))
- continue;
-
- offset = strlen(val) + 1;
- tl = malloc(sizeof(*tl) + offset);
- if (!tl)
- continue;
-
- memcpy(tl->param, val, offset);
- colon = strchr(tl->param, ':');
- *colon = '\0';
-
- tl->number = 0;
- tl->name = tl->param + prefix_len;
- if (sscanf(tl->name, "%u__%n",
- &tl->number, &offset) == 1)
- tl->name += offset;
-
- if (filter &&
- strncmp(tl->name, filter, strlen(filter))) {
- free(tl);
- continue;
- }
+ err = kmod_module_new_from_name(kmod_ctx(), module_name, &tst->kmod);
+ if (err)
+ return err;
- tests_add(tl, &tests);
- }
- kmod_module_info_free_list(pre);
-
- igt_list_for_each_safe(tl, tn, &tests, link) {
- igt_subtest_f("%s", tl->name) {
- lseek(kmsg, 0, SEEK_END);
-
- snprintf(options, sizeof(options), "%s=1 %s",
- tl->param, module_options ?: "");
-
- err = modprobe(kmod, options);
- if (err == 0 && result) {
- int dir = open_parameters(module_name);
- igt_sysfs_scanf(dir, result, "%d", &err);
- close(dir);
- }
- if (err == -ENOTTY) /* special case */
- err = 0;
- if (err)
- kmsg_dump(kmsg);
-
- kmod_module_remove_module(kmod, 0);
-
- errno = 0;
- igt_assert_f(err == 0,
- "kselftest \"%s %s\" failed: %s [%d]\n",
- module_name, options,
- strerror(-err), -err);
- }
- free(tl);
- }
+ return 0;
+}
+
+int igt_kselftest_begin(struct igt_kselftest *tst)
+{
+ int err;
+
+ if (strcmp(tst->module_name, "i915") == 0)
+ igt_i915_driver_unload();
+
+ err = kmod_module_remove_module(tst->kmod, KMOD_REMOVE_FORCE);
+ igt_require(err == 0 || err == -ENOENT);
+
+ tst->kmsg = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
+
+ return 0;
+}
+
+int igt_kselftest_execute(struct igt_kselftest *tst,
+ struct igt_kselftest_list *tl,
+ const char *options,
+ const char *result)
+{
+ char buf[1024];
+ int err;
+
+ lseek(tst->kmsg, 0, SEEK_END);
+
+ snprintf(buf, sizeof(buf), "%s=1 %s", tl->param, options ?: "");
+
+ err = modprobe(tst->kmod, buf);
+ if (err == 0 && result) {
+ int dir = open_parameters(tst->module_name);
+ igt_sysfs_scanf(dir, result, "%d", &err);
+ close(dir);
}
+ if (err == -ENOTTY) /* special case */
+ err = 0;
+ if (err)
+ kmsg_dump(tst->kmsg);
- igt_fixture {
- close(kmsg);
- kmod_module_remove_module(kmod, KMOD_REMOVE_FORCE);
+ kmod_module_remove_module(tst->kmod, 0);
- if (strcmp(module_name, "i915") == 0)
- igt_i915_driver_load(NULL);
+ errno = 0;
+ igt_assert_f(err == 0,
+ "kselftest \"%s %s\" failed: %s [%d]\n",
+ tst->module_name, buf, strerror(-err), -err);
+
+ return err;
+}
+void igt_kselftest_end(struct igt_kselftest *tst)
+{
+ kmod_module_remove_module(tst->kmod, KMOD_REMOVE_FORCE);
+ close(tst->kmsg);
+
+ if (strcmp(tst->module_name, "i915") == 0)
+ igt_i915_driver_load(NULL);
+}
+
+void igt_kselftest_fini(struct igt_kselftest *tst)
+{
+ free(tst->module_name);
+ kmod_module_unref(tst->kmod);
+}
+
+void igt_kselftests(const char *module_name,
+ const char *options,
+ const char *result,
+ const char *filter)
+{
+ struct igt_kselftest tst;
+ IGT_LIST(tests);
+ struct igt_kselftest_list *tl, *tn;
+
+ igt_require(igt_kselftest_init(&tst, module_name) == 0);
+ igt_fixture
+ igt_require(igt_kselftest_begin(&tst) == 0);
+
+ igt_kselftest_get_tests(tst.kmod, filter, &tests);
+ igt_list_for_each_safe(tl, tn, &tests, link) {
+ igt_subtest_f("%s", tl->name)
+ igt_kselftest_execute(&tst, tl, options, result);
+ free(tl);
+ }
+
+ igt_fixture {
+ igt_kselftest_end(&tst);
igt_require(!igt_list_empty(&tests));
}
+
+ igt_kselftest_fini(&tst);
}