Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/* SPDX-License-Identifier: MIT */
  2
  3/*
  4 * Copyright © 2019 Intel Corporation
  5 */
  6
  7#include <linux/compiler.h>
  8#include <linux/kernel.h>
  9#include <linux/module.h>
 10#include <linux/sched/signal.h>
 11#include <linux/slab.h>
 12
 13#include "selftest.h"
 14
 15enum {
 16#define selftest(n, func) __idx_##n,
 17#include "selftests.h"
 18#undef selftest
 19};
 20
 21#define selftest(n, f) [__idx_##n] = { .name = #n, .func = f },
 22static struct selftest {
 23	bool enabled;
 24	const char *name;
 25	int (*func)(void);
 26} selftests[] = {
 27#include "selftests.h"
 28};
 29#undef selftest
 30
 31/* Embed the line number into the parameter name so that we can order tests */
 32#define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n))
 33#define selftest_0(n, func, id) \
 34module_param_named(id, selftests[__idx_##n].enabled, bool, 0400);
 35#define selftest(n, func) selftest_0(n, func, param(n))
 36#include "selftests.h"
 37#undef selftest
 38
 39int __sanitycheck__(void)
 40{
 41	pr_debug("Hello World!\n");
 42	return 0;
 43}
 44
 45static char *__st_filter;
 46
 47static bool apply_subtest_filter(const char *caller, const char *name)
 48{
 49	char *filter, *sep, *tok;
 50	bool result = true;
 51
 52	filter = kstrdup(__st_filter, GFP_KERNEL);
 53	for (sep = filter; (tok = strsep(&sep, ","));) {
 54		bool allow = true;
 55		char *sl;
 56
 57		if (*tok == '!') {
 58			allow = false;
 59			tok++;
 60		}
 61
 62		if (*tok == '\0')
 63			continue;
 64
 65		sl = strchr(tok, '/');
 66		if (sl) {
 67			*sl++ = '\0';
 68			if (strcmp(tok, caller)) {
 69				if (allow)
 70					result = false;
 71				continue;
 72			}
 73			tok = sl;
 74		}
 75
 76		if (strcmp(tok, name)) {
 77			if (allow)
 78				result = false;
 79			continue;
 80		}
 81
 82		result = allow;
 83		break;
 84	}
 85	kfree(filter);
 86
 87	return result;
 88}
 89
 90int
 91__subtests(const char *caller, const struct subtest *st, int count, void *data)
 92{
 93	int err;
 94
 95	for (; count--; st++) {
 96		cond_resched();
 97		if (signal_pending(current))
 98			return -EINTR;
 99
100		if (!apply_subtest_filter(caller, st->name))
101			continue;
102
103		pr_info("dma-buf: Running %s/%s\n", caller, st->name);
104
105		err = st->func(data);
106		if (err && err != -EINTR) {
107			pr_err("dma-buf/%s: %s failed with error %d\n",
108			       caller, st->name, err);
109			return err;
110		}
111	}
112
113	return 0;
114}
115
116static void set_default_test_all(struct selftest *st, unsigned long count)
117{
118	unsigned long i;
119
120	for (i = 0; i < count; i++)
121		if (st[i].enabled)
122			return;
123
124	for (i = 0; i < count; i++)
125		st[i].enabled = true;
126}
127
128static int run_selftests(struct selftest *st, unsigned long count)
129{
130	int err = 0;
131
132	set_default_test_all(st, count);
133
134	/* Tests are listed in natural order in selftests.h */
135	for (; count--; st++) {
136		if (!st->enabled)
137			continue;
138
139		pr_info("dma-buf: Running %s\n", st->name);
140		err = st->func();
141		if (err)
142			break;
143	}
144
145	if (WARN(err > 0 || err == -ENOTTY,
146		 "%s returned %d, conflicting with selftest's magic values!\n",
147		 st->name, err))
148		err = -1;
149
150	return err;
151}
152
153static int __init st_init(void)
154{
155	return run_selftests(selftests, ARRAY_SIZE(selftests));
156}
157
158static void __exit st_exit(void)
159{
160}
161
162module_param_named(st_filter, __st_filter, charp, 0400);
163module_init(st_init);
164module_exit(st_exit);
165
166MODULE_DESCRIPTION("Self-test harness for dma-buf");
167MODULE_LICENSE("GPL and additional rights");