pcitest.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. #include <errno.h>
  20. #include <fcntl.h>
  21. #include <stdbool.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <sys/ioctl.h>
  25. #include <time.h>
  26. #include <unistd.h>
  27. #include <linux/pcitest.h>
  28. #define BILLION 1E9
  29. static char *result[] = { "NOT OKAY", "OKAY" };
  30. struct pci_test {
  31. char *device;
  32. char barnum;
  33. bool legacyirq;
  34. unsigned int msinum;
  35. bool read;
  36. bool write;
  37. bool copy;
  38. unsigned long size;
  39. };
  40. static int run_test(struct pci_test *test)
  41. {
  42. long ret;
  43. int fd;
  44. struct timespec start, end;
  45. double time;
  46. fd = open(test->device, O_RDWR);
  47. if (fd < 0) {
  48. perror("can't open PCI Endpoint Test device");
  49. return fd;
  50. }
  51. if (test->barnum >= 0 && test->barnum <= 5) {
  52. ret = ioctl(fd, PCITEST_BAR, test->barnum);
  53. fprintf(stdout, "BAR%d:\t\t", test->barnum);
  54. if (ret < 0)
  55. fprintf(stdout, "TEST FAILED\n");
  56. else
  57. fprintf(stdout, "%s\n", result[ret]);
  58. }
  59. if (test->legacyirq) {
  60. ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
  61. fprintf(stdout, "LEGACY IRQ:\t");
  62. if (ret < 0)
  63. fprintf(stdout, "TEST FAILED\n");
  64. else
  65. fprintf(stdout, "%s\n", result[ret]);
  66. }
  67. if (test->msinum > 0 && test->msinum <= 32) {
  68. ret = ioctl(fd, PCITEST_MSI, test->msinum);
  69. fprintf(stdout, "MSI%d:\t\t", test->msinum);
  70. if (ret < 0)
  71. fprintf(stdout, "TEST FAILED\n");
  72. else
  73. fprintf(stdout, "%s\n", result[ret]);
  74. }
  75. if (test->write) {
  76. ret = ioctl(fd, PCITEST_WRITE, test->size);
  77. fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
  78. if (ret < 0)
  79. fprintf(stdout, "TEST FAILED\n");
  80. else
  81. fprintf(stdout, "%s\n", result[ret]);
  82. }
  83. if (test->read) {
  84. ret = ioctl(fd, PCITEST_READ, test->size);
  85. fprintf(stdout, "READ (%7ld bytes):\t\t", test->size);
  86. if (ret < 0)
  87. fprintf(stdout, "TEST FAILED\n");
  88. else
  89. fprintf(stdout, "%s\n", result[ret]);
  90. }
  91. if (test->copy) {
  92. ret = ioctl(fd, PCITEST_COPY, test->size);
  93. fprintf(stdout, "COPY (%7ld bytes):\t\t", test->size);
  94. if (ret < 0)
  95. fprintf(stdout, "TEST FAILED\n");
  96. else
  97. fprintf(stdout, "%s\n", result[ret]);
  98. }
  99. fflush(stdout);
  100. }
  101. int main(int argc, char **argv)
  102. {
  103. int c;
  104. struct pci_test *test;
  105. test = calloc(1, sizeof(*test));
  106. if (!test) {
  107. perror("Fail to allocate memory for pci_test\n");
  108. return -ENOMEM;
  109. }
  110. /* since '0' is a valid BAR number, initialize it to -1 */
  111. test->barnum = -1;
  112. /* set default size as 100KB */
  113. test->size = 0x19000;
  114. /* set default endpoint device */
  115. test->device = "/dev/pci-endpoint-test.0";
  116. while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF)
  117. switch (c) {
  118. case 'D':
  119. test->device = optarg;
  120. continue;
  121. case 'b':
  122. test->barnum = atoi(optarg);
  123. if (test->barnum < 0 || test->barnum > 5)
  124. goto usage;
  125. continue;
  126. case 'l':
  127. test->legacyirq = true;
  128. continue;
  129. case 'm':
  130. test->msinum = atoi(optarg);
  131. if (test->msinum < 1 || test->msinum > 32)
  132. goto usage;
  133. continue;
  134. case 'r':
  135. test->read = true;
  136. continue;
  137. case 'w':
  138. test->write = true;
  139. continue;
  140. case 'c':
  141. test->copy = true;
  142. continue;
  143. case 's':
  144. test->size = strtoul(optarg, NULL, 0);
  145. continue;
  146. case '?':
  147. case 'h':
  148. default:
  149. usage:
  150. fprintf(stderr,
  151. "usage: %s [options]\n"
  152. "Options:\n"
  153. "\t-D <dev> pci endpoint test device {default: /dev/pci-endpoint-test.0}\n"
  154. "\t-b <bar num> BAR test (bar number between 0..5)\n"
  155. "\t-m <msi num> MSI test (msi number between 1..32)\n"
  156. "\t-r Read buffer test\n"
  157. "\t-w Write buffer test\n"
  158. "\t-c Copy buffer test\n"
  159. "\t-s <size> Size of buffer {default: 100KB}\n",
  160. argv[0]);
  161. return -EINVAL;
  162. }
  163. run_test(test);
  164. return 0;
  165. }