1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or
5f08c3bdfSopenharmony_ci * modify it under the terms of the GNU General Public License as
6f08c3bdfSopenharmony_ci * published by the Free Software Foundation; either version 2 of
7f08c3bdfSopenharmony_ci * the License, or (at your option) any later version.
8f08c3bdfSopenharmony_ci *
9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful,
10f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12f08c3bdfSopenharmony_ci * GNU General Public License for more details.
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License
15f08c3bdfSopenharmony_ci * along with this program; if not, write the Free Software Foundation,
16f08c3bdfSopenharmony_ci * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17f08c3bdfSopenharmony_ci *
18f08c3bdfSopenharmony_ci * Author: Alexey Kodanev <alexey.kodanev@oracle.com>
19f08c3bdfSopenharmony_ci */
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_ci#include <stdio.h>
22f08c3bdfSopenharmony_ci#include <stdlib.h>
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_ci#include "test.h"
25f08c3bdfSopenharmony_ci#include "old_module.h"
26f08c3bdfSopenharmony_ci#include "safe_macros.h"
27f08c3bdfSopenharmony_ci
28f08c3bdfSopenharmony_ci#include "ltp_acpi.h"
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_cichar *TCID = "ltp_acpi";
31f08c3bdfSopenharmony_ciint TST_TOTAL = ACPI_TC_NUM;
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_cistatic const char dev_result[]	= "/sys/devices/" ACPI_TEST_NAME "/result";
34f08c3bdfSopenharmony_cistatic const char dev_path[]	= "/sys/devices/" ACPI_TEST_NAME "/path";
35f08c3bdfSopenharmony_cistatic const char dev_str[]	= "/sys/devices/" ACPI_TEST_NAME "/str";
36f08c3bdfSopenharmony_cistatic const char dev_tcase[]	= "/sys/devices/" ACPI_TEST_NAME "/tcase";
37f08c3bdfSopenharmony_cistatic const char dev_acpi_disabled[] = "/sys/devices/" ACPI_TEST_NAME "/acpi_disabled";
38f08c3bdfSopenharmony_cistatic const char module_name[]	= "ltp_acpi_cmds.ko";
39f08c3bdfSopenharmony_cistatic int module_loaded;
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_cistatic void cleanup(void)
42f08c3bdfSopenharmony_ci{
43f08c3bdfSopenharmony_ci	if (module_loaded)
44f08c3bdfSopenharmony_ci		tst_module_unload(NULL, module_name);
45f08c3bdfSopenharmony_ci}
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_cistatic int read_sysfs_file(const char *name, char *buf, int size)
48f08c3bdfSopenharmony_ci{
49f08c3bdfSopenharmony_ci	FILE *f = SAFE_FOPEN(cleanup, name, "r");
50f08c3bdfSopenharmony_ci	char *res = fgets(buf, size, f);
51f08c3bdfSopenharmony_ci	SAFE_FCLOSE(cleanup, f);
52f08c3bdfSopenharmony_ci	return (res) ? 0 : 1;
53f08c3bdfSopenharmony_ci}
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_cistatic int tc_acpi_str(void)
56f08c3bdfSopenharmony_ci{
57f08c3bdfSopenharmony_ci	int res, ret = 0;
58f08c3bdfSopenharmony_ci	char descr[4096], sysfs_path[4096];
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci	while (1) {
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci		SAFE_FILE_PRINTF(cleanup, dev_tcase, "%d", ACPI_TRAVERSE);
63f08c3bdfSopenharmony_ci		SAFE_FILE_SCANF(cleanup, dev_result, "%d", &res);
64f08c3bdfSopenharmony_ci		if (res)
65f08c3bdfSopenharmony_ci			return TFAIL;
66f08c3bdfSopenharmony_ci		/*
67f08c3bdfSopenharmony_ci		 * if device has _STR object, we should get
68f08c3bdfSopenharmony_ci		 * a valid string from 'str' sysfs file and then can
69f08c3bdfSopenharmony_ci		 * find it in sysfs.
70f08c3bdfSopenharmony_ci		 */
71f08c3bdfSopenharmony_ci		if (read_sysfs_file(dev_str, descr, 4096)) {
72f08c3bdfSopenharmony_ci			/* None of left devices has _STR */
73f08c3bdfSopenharmony_ci			break;
74f08c3bdfSopenharmony_ci		}
75f08c3bdfSopenharmony_ci		tst_resm(TINFO, "read description %s", descr);
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci		/* device's sysfs path */
78f08c3bdfSopenharmony_ci		strcpy(sysfs_path, "/sys");
79f08c3bdfSopenharmony_ci		if (read_sysfs_file(dev_path, sysfs_path + 4, 4092)) {
80f08c3bdfSopenharmony_ci			/*
81f08c3bdfSopenharmony_ci			 * Device doesn't have sysfs entry
82f08c3bdfSopenharmony_ci			 * continue, because others might have it
83f08c3bdfSopenharmony_ci			 */
84f08c3bdfSopenharmony_ci			continue;
85f08c3bdfSopenharmony_ci		}
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_ci		strcat(sysfs_path, "/description");
88f08c3bdfSopenharmony_ci		if (access(sysfs_path, R_OK)) {
89f08c3bdfSopenharmony_ci			tst_resm(TINFO, "can't find description file '%s'",
90f08c3bdfSopenharmony_ci				sysfs_path);
91f08c3bdfSopenharmony_ci			return TFAIL;
92f08c3bdfSopenharmony_ci		}
93f08c3bdfSopenharmony_ci		tst_resm(TINFO, "found description file '%s'", sysfs_path);
94f08c3bdfSopenharmony_ci
95f08c3bdfSopenharmony_ci		char sysfs_descr[4096];
96f08c3bdfSopenharmony_ci		if (read_sysfs_file(sysfs_path, sysfs_descr, 4096))
97f08c3bdfSopenharmony_ci			return TFAIL;
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_ci		/*
100f08c3bdfSopenharmony_ci		 * Compare sysfs file and description from test driver
101f08c3bdfSopenharmony_ci		 */
102f08c3bdfSopenharmony_ci		int res = strncmp(descr, sysfs_descr, strlen(descr));
103f08c3bdfSopenharmony_ci
104f08c3bdfSopenharmony_ci		ret |= res ? TFAIL : TPASS;
105f08c3bdfSopenharmony_ci	}
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_ci	return ret;
108f08c3bdfSopenharmony_ci}
109f08c3bdfSopenharmony_ci
110f08c3bdfSopenharmony_cistatic void test_run(void)
111f08c3bdfSopenharmony_ci{
112f08c3bdfSopenharmony_ci	int i, res;
113f08c3bdfSopenharmony_ci
114f08c3bdfSopenharmony_ci	for (i = 0; i < TST_TOTAL; ++i) {
115f08c3bdfSopenharmony_ci
116f08c3bdfSopenharmony_ci		if (i == ACPI_TRAVERSE) {
117f08c3bdfSopenharmony_ci			res = tc_acpi_str();
118f08c3bdfSopenharmony_ci		} else {
119f08c3bdfSopenharmony_ci			SAFE_FILE_PRINTF(cleanup, dev_tcase, "%d", i);
120f08c3bdfSopenharmony_ci			SAFE_FILE_SCANF(cleanup, dev_result, "%d", &res);
121f08c3bdfSopenharmony_ci			res = res ? TFAIL : TPASS;
122f08c3bdfSopenharmony_ci		}
123f08c3bdfSopenharmony_ci
124f08c3bdfSopenharmony_ci		tst_resm(res, "Test-case '%d'", i);
125f08c3bdfSopenharmony_ci	}
126f08c3bdfSopenharmony_ci}
127f08c3bdfSopenharmony_ci
128f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
129f08c3bdfSopenharmony_ci{
130f08c3bdfSopenharmony_ci	int acpi_disabled;
131f08c3bdfSopenharmony_ci
132f08c3bdfSopenharmony_ci	tst_parse_opts(argc, argv, NULL, NULL);
133f08c3bdfSopenharmony_ci
134f08c3bdfSopenharmony_ci	tst_require_root();
135f08c3bdfSopenharmony_ci
136f08c3bdfSopenharmony_ci	tst_sig(FORK, DEF_HANDLER, cleanup);
137f08c3bdfSopenharmony_ci
138f08c3bdfSopenharmony_ci	tst_module_load(NULL, module_name, NULL);
139f08c3bdfSopenharmony_ci	module_loaded = 1;
140f08c3bdfSopenharmony_ci
141f08c3bdfSopenharmony_ci	SAFE_FILE_SCANF(cleanup, dev_acpi_disabled, "%d", &acpi_disabled);
142f08c3bdfSopenharmony_ci	if (acpi_disabled)
143f08c3bdfSopenharmony_ci		tst_brkm(TCONF, cleanup, "ACPI is disabled on the system");
144f08c3bdfSopenharmony_ci
145f08c3bdfSopenharmony_ci	test_run();
146f08c3bdfSopenharmony_ci
147f08c3bdfSopenharmony_ci	cleanup();
148f08c3bdfSopenharmony_ci
149f08c3bdfSopenharmony_ci	tst_exit();
150f08c3bdfSopenharmony_ci}
151