diff options
Diffstat (limited to 'tools/pci/pcitest.c')
-rw-r--r-- | tools/pci/pcitest.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c new file mode 100644 index 000000000000..ad54a58d7dda --- /dev/null +++ b/tools/pci/pcitest.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /** | ||
2 | * Userspace PCI Endpoint Test Module | ||
3 | * | ||
4 | * Copyright (C) 2017 Texas Instruments | ||
5 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | ||
6 | * | ||
7 | * This program is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 of | ||
9 | * the License as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <errno.h> | ||
21 | #include <fcntl.h> | ||
22 | #include <stdbool.h> | ||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <sys/ioctl.h> | ||
26 | #include <time.h> | ||
27 | #include <unistd.h> | ||
28 | |||
29 | #include <linux/pcitest.h> | ||
30 | |||
31 | #define BILLION 1E9 | ||
32 | |||
33 | static char *result[] = { "NOT OKAY", "OKAY" }; | ||
34 | |||
35 | struct pci_test { | ||
36 | char *device; | ||
37 | char barnum; | ||
38 | bool legacyirq; | ||
39 | unsigned int msinum; | ||
40 | bool read; | ||
41 | bool write; | ||
42 | bool copy; | ||
43 | unsigned long size; | ||
44 | }; | ||
45 | |||
46 | static int run_test(struct pci_test *test) | ||
47 | { | ||
48 | long ret; | ||
49 | int fd; | ||
50 | struct timespec start, end; | ||
51 | double time; | ||
52 | |||
53 | fd = open(test->device, O_RDWR); | ||
54 | if (fd < 0) { | ||
55 | perror("can't open PCI Endpoint Test device"); | ||
56 | return fd; | ||
57 | } | ||
58 | |||
59 | if (test->barnum >= 0 && test->barnum <= 5) { | ||
60 | ret = ioctl(fd, PCITEST_BAR, test->barnum); | ||
61 | fprintf(stdout, "BAR%d:\t\t", test->barnum); | ||
62 | if (ret < 0) | ||
63 | fprintf(stdout, "TEST FAILED\n"); | ||
64 | else | ||
65 | fprintf(stdout, "%s\n", result[ret]); | ||
66 | } | ||
67 | |||
68 | if (test->legacyirq) { | ||
69 | ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0); | ||
70 | fprintf(stdout, "LEGACY IRQ:\t"); | ||
71 | if (ret < 0) | ||
72 | fprintf(stdout, "TEST FAILED\n"); | ||
73 | else | ||
74 | fprintf(stdout, "%s\n", result[ret]); | ||
75 | } | ||
76 | |||
77 | if (test->msinum > 0 && test->msinum <= 32) { | ||
78 | ret = ioctl(fd, PCITEST_MSI, test->msinum); | ||
79 | fprintf(stdout, "MSI%d:\t\t", test->msinum); | ||
80 | if (ret < 0) | ||
81 | fprintf(stdout, "TEST FAILED\n"); | ||
82 | else | ||
83 | fprintf(stdout, "%s\n", result[ret]); | ||
84 | } | ||
85 | |||
86 | if (test->write) { | ||
87 | ret = ioctl(fd, PCITEST_WRITE, test->size); | ||
88 | fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size); | ||
89 | if (ret < 0) | ||
90 | fprintf(stdout, "TEST FAILED\n"); | ||
91 | else | ||
92 | fprintf(stdout, "%s\n", result[ret]); | ||
93 | } | ||
94 | |||
95 | if (test->read) { | ||
96 | ret = ioctl(fd, PCITEST_READ, test->size); | ||
97 | fprintf(stdout, "READ (%7ld bytes):\t\t", test->size); | ||
98 | if (ret < 0) | ||
99 | fprintf(stdout, "TEST FAILED\n"); | ||
100 | else | ||
101 | fprintf(stdout, "%s\n", result[ret]); | ||
102 | } | ||
103 | |||
104 | if (test->copy) { | ||
105 | ret = ioctl(fd, PCITEST_COPY, test->size); | ||
106 | fprintf(stdout, "COPY (%7ld bytes):\t\t", test->size); | ||
107 | if (ret < 0) | ||
108 | fprintf(stdout, "TEST FAILED\n"); | ||
109 | else | ||
110 | fprintf(stdout, "%s\n", result[ret]); | ||
111 | } | ||
112 | |||
113 | fflush(stdout); | ||
114 | } | ||
115 | |||
116 | int main(int argc, char **argv) | ||
117 | { | ||
118 | int c; | ||
119 | struct pci_test *test; | ||
120 | |||
121 | test = calloc(1, sizeof(*test)); | ||
122 | if (!test) { | ||
123 | perror("Fail to allocate memory for pci_test\n"); | ||
124 | return -ENOMEM; | ||
125 | } | ||
126 | |||
127 | /* since '0' is a valid BAR number, initialize it to -1 */ | ||
128 | test->barnum = -1; | ||
129 | |||
130 | /* set default size as 100KB */ | ||
131 | test->size = 0x19000; | ||
132 | |||
133 | /* set default endpoint device */ | ||
134 | test->device = "/dev/pci-endpoint-test.0"; | ||
135 | |||
136 | while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF) | ||
137 | switch (c) { | ||
138 | case 'D': | ||
139 | test->device = optarg; | ||
140 | continue; | ||
141 | case 'b': | ||
142 | test->barnum = atoi(optarg); | ||
143 | if (test->barnum < 0 || test->barnum > 5) | ||
144 | goto usage; | ||
145 | continue; | ||
146 | case 'l': | ||
147 | test->legacyirq = true; | ||
148 | continue; | ||
149 | case 'm': | ||
150 | test->msinum = atoi(optarg); | ||
151 | if (test->msinum < 1 || test->msinum > 32) | ||
152 | goto usage; | ||
153 | continue; | ||
154 | case 'r': | ||
155 | test->read = true; | ||
156 | continue; | ||
157 | case 'w': | ||
158 | test->write = true; | ||
159 | continue; | ||
160 | case 'c': | ||
161 | test->copy = true; | ||
162 | continue; | ||
163 | case 's': | ||
164 | test->size = strtoul(optarg, NULL, 0); | ||
165 | continue; | ||
166 | case '?': | ||
167 | case 'h': | ||
168 | default: | ||
169 | usage: | ||
170 | fprintf(stderr, | ||
171 | "usage: %s [options]\n" | ||
172 | "Options:\n" | ||
173 | "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" | ||
174 | "\t-b <bar num> BAR test (bar number between 0..5)\n" | ||
175 | "\t-m <msi num> MSI test (msi number between 1..32)\n" | ||
176 | "\t-r Read buffer test\n" | ||
177 | "\t-w Write buffer test\n" | ||
178 | "\t-c Copy buffer test\n" | ||
179 | "\t-s <size> Size of buffer {default: 100KB}\n", | ||
180 | argv[0]); | ||
181 | return -EINVAL; | ||
182 | } | ||
183 | |||
184 | run_test(test); | ||
185 | return 0; | ||
186 | } | ||