linux/tools/pci/pcitest.c
<<
>>
Prefs
   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
  33static char *result[] = { "NOT OKAY", "OKAY" };
  34static char *irq[] = { "LEGACY", "MSI", "MSI-X" };
  35
  36struct 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
  51static 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
 148int 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:
 215usage:
 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}
 237