OSDN Git Service

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
[uclinux-h8/linux.git] / tools / pci / pcitest.c
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 static char *irq[] = { "LEGACY", "MSI", "MSI-X" };
35
36 struct pci_test {
37         char            *device;
38         char            barnum;
39         bool            legacyirq;
40         unsigned int    msinum;
41         unsigned int    msixnum;
42         int             irqtype;
43         bool            set_irqtype;
44         bool            get_irqtype;
45         bool            read;
46         bool            write;
47         bool            copy;
48         unsigned long   size;
49 };
50
51 static int run_test(struct pci_test *test)
52 {
53         long ret;
54         int fd;
55         struct timespec start, end;
56         double time;
57
58         fd = open(test->device, O_RDWR);
59         if (fd < 0) {
60                 perror("can't open PCI Endpoint Test device");
61                 return fd;
62         }
63
64         if (test->barnum >= 0 && test->barnum <= 5) {
65                 ret = ioctl(fd, PCITEST_BAR, test->barnum);
66                 fprintf(stdout, "BAR%d:\t\t", test->barnum);
67                 if (ret < 0)
68                         fprintf(stdout, "TEST FAILED\n");
69                 else
70                         fprintf(stdout, "%s\n", result[ret]);
71         }
72
73         if (test->set_irqtype) {
74                 ret = ioctl(fd, PCITEST_SET_IRQTYPE, test->irqtype);
75                 fprintf(stdout, "SET IRQ TYPE TO %s:\t\t", irq[test->irqtype]);
76                 if (ret < 0)
77                         fprintf(stdout, "FAILED\n");
78                 else
79                         fprintf(stdout, "%s\n", result[ret]);
80         }
81
82         if (test->get_irqtype) {
83                 ret = ioctl(fd, PCITEST_GET_IRQTYPE);
84                 fprintf(stdout, "GET IRQ TYPE:\t\t");
85                 if (ret < 0)
86                         fprintf(stdout, "FAILED\n");
87                 else
88                         fprintf(stdout, "%s\n", irq[ret]);
89         }
90
91         if (test->legacyirq) {
92                 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
93                 fprintf(stdout, "LEGACY IRQ:\t");
94                 if (ret < 0)
95                         fprintf(stdout, "TEST FAILED\n");
96                 else
97                         fprintf(stdout, "%s\n", result[ret]);
98         }
99
100         if (test->msinum > 0 && test->msinum <= 32) {
101                 ret = ioctl(fd, PCITEST_MSI, test->msinum);
102                 fprintf(stdout, "MSI%d:\t\t", test->msinum);
103                 if (ret < 0)
104                         fprintf(stdout, "TEST FAILED\n");
105                 else
106                         fprintf(stdout, "%s\n", result[ret]);
107         }
108
109         if (test->msixnum > 0 && test->msixnum <= 2048) {
110                 ret = ioctl(fd, PCITEST_MSIX, test->msixnum);
111                 fprintf(stdout, "MSI-X%d:\t\t", test->msixnum);
112                 if (ret < 0)
113                         fprintf(stdout, "TEST FAILED\n");
114                 else
115                         fprintf(stdout, "%s\n", result[ret]);
116         }
117
118         if (test->write) {
119                 ret = ioctl(fd, PCITEST_WRITE, test->size);
120                 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
121                 if (ret < 0)
122                         fprintf(stdout, "TEST FAILED\n");
123                 else
124                         fprintf(stdout, "%s\n", result[ret]);
125         }
126
127         if (test->read) {
128                 ret = ioctl(fd, PCITEST_READ, test->size);
129                 fprintf(stdout, "READ (%7ld bytes):\t\t", test->size);
130                 if (ret < 0)
131                         fprintf(stdout, "TEST FAILED\n");
132                 else
133                         fprintf(stdout, "%s\n", result[ret]);
134         }
135
136         if (test->copy) {
137                 ret = ioctl(fd, PCITEST_COPY, test->size);
138                 fprintf(stdout, "COPY (%7ld bytes):\t\t", test->size);
139                 if (ret < 0)
140                         fprintf(stdout, "TEST FAILED\n");
141                 else
142                         fprintf(stdout, "%s\n", result[ret]);
143         }
144
145         fflush(stdout);
146 }
147
148 int main(int argc, char **argv)
149 {
150         int c;
151         struct pci_test *test;
152
153         test = calloc(1, sizeof(*test));
154         if (!test) {
155                 perror("Fail to allocate memory for pci_test\n");
156                 return -ENOMEM;
157         }
158
159         /* since '0' is a valid BAR number, initialize it to -1 */
160         test->barnum = -1;
161
162         /* set default size as 100KB */
163         test->size = 0x19000;
164
165         /* set default endpoint device */
166         test->device = "/dev/pci-endpoint-test.0";
167
168         while ((c = getopt(argc, argv, "D:b:m:x:i:Ilrwcs:")) != EOF)
169         switch (c) {
170         case 'D':
171                 test->device = optarg;
172                 continue;
173         case 'b':
174                 test->barnum = atoi(optarg);
175                 if (test->barnum < 0 || test->barnum > 5)
176                         goto usage;
177                 continue;
178         case 'l':
179                 test->legacyirq = true;
180                 continue;
181         case 'm':
182                 test->msinum = atoi(optarg);
183                 if (test->msinum < 1 || test->msinum > 32)
184                         goto usage;
185                 continue;
186         case 'x':
187                 test->msixnum = atoi(optarg);
188                 if (test->msixnum < 1 || test->msixnum > 2048)
189                         goto usage;
190                 continue;
191         case 'i':
192                 test->irqtype = atoi(optarg);
193                 if (test->irqtype < 0 || test->irqtype > 2)
194                         goto usage;
195                 test->set_irqtype = true;
196                 continue;
197         case 'I':
198                 test->get_irqtype = true;
199                 continue;
200         case 'r':
201                 test->read = true;
202                 continue;
203         case 'w':
204                 test->write = true;
205                 continue;
206         case 'c':
207                 test->copy = true;
208                 continue;
209         case 's':
210                 test->size = strtoul(optarg, NULL, 0);
211                 continue;
212         case '?':
213         case 'h':
214         default:
215 usage:
216                 fprintf(stderr,
217                         "usage: %s [options]\n"
218                         "Options:\n"
219                         "\t-D <dev>             PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n"
220                         "\t-b <bar num>         BAR test (bar number between 0..5)\n"
221                         "\t-m <msi num>         MSI test (msi number between 1..32)\n"
222                         "\t-x <msix num>        \tMSI-X test (msix number between 1..2048)\n"
223                         "\t-i <irq type>        \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n"
224                         "\t-I                   Get current IRQ type configured\n"
225                         "\t-l                   Legacy IRQ test\n"
226                         "\t-r                   Read buffer test\n"
227                         "\t-w                   Write buffer test\n"
228                         "\t-c                   Copy buffer test\n"
229                         "\t-s <size>            Size of buffer {default: 100KB}\n",
230                         argv[0]);
231                 return -EINVAL;
232         }
233
234         run_test(test);
235         return 0;
236 }