root/drivers/misc/pci_endpoint_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pci_endpoint_test_readl
  2. pci_endpoint_test_writel
  3. pci_endpoint_test_bar_readl
  4. pci_endpoint_test_bar_writel
  5. pci_endpoint_test_irqhandler
  6. pci_endpoint_test_free_irq_vectors
  7. pci_endpoint_test_alloc_irq_vectors
  8. pci_endpoint_test_release_irq
  9. pci_endpoint_test_request_irq
  10. pci_endpoint_test_bar
  11. pci_endpoint_test_legacy_irq
  12. pci_endpoint_test_msi_irq
  13. pci_endpoint_test_copy
  14. pci_endpoint_test_write
  15. pci_endpoint_test_read
  16. pci_endpoint_test_set_irq
  17. pci_endpoint_test_ioctl
  18. pci_endpoint_test_probe
  19. pci_endpoint_test_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /**
   3  * Host side test driver to test endpoint functionality
   4  *
   5  * Copyright (C) 2017 Texas Instruments
   6  * Author: Kishon Vijay Abraham I <kishon@ti.com>
   7  */
   8 
   9 #include <linux/crc32.h>
  10 #include <linux/delay.h>
  11 #include <linux/fs.h>
  12 #include <linux/io.h>
  13 #include <linux/interrupt.h>
  14 #include <linux/irq.h>
  15 #include <linux/miscdevice.h>
  16 #include <linux/module.h>
  17 #include <linux/mutex.h>
  18 #include <linux/random.h>
  19 #include <linux/slab.h>
  20 #include <linux/pci.h>
  21 #include <linux/pci_ids.h>
  22 
  23 #include <linux/pci_regs.h>
  24 
  25 #include <uapi/linux/pcitest.h>
  26 
  27 #define DRV_MODULE_NAME                         "pci-endpoint-test"
  28 
  29 #define IRQ_TYPE_UNDEFINED                      -1
  30 #define IRQ_TYPE_LEGACY                         0
  31 #define IRQ_TYPE_MSI                            1
  32 #define IRQ_TYPE_MSIX                           2
  33 
  34 #define PCI_ENDPOINT_TEST_MAGIC                 0x0
  35 
  36 #define PCI_ENDPOINT_TEST_COMMAND               0x4
  37 #define COMMAND_RAISE_LEGACY_IRQ                BIT(0)
  38 #define COMMAND_RAISE_MSI_IRQ                   BIT(1)
  39 #define COMMAND_RAISE_MSIX_IRQ                  BIT(2)
  40 #define COMMAND_READ                            BIT(3)
  41 #define COMMAND_WRITE                           BIT(4)
  42 #define COMMAND_COPY                            BIT(5)
  43 
  44 #define PCI_ENDPOINT_TEST_STATUS                0x8
  45 #define STATUS_READ_SUCCESS                     BIT(0)
  46 #define STATUS_READ_FAIL                        BIT(1)
  47 #define STATUS_WRITE_SUCCESS                    BIT(2)
  48 #define STATUS_WRITE_FAIL                       BIT(3)
  49 #define STATUS_COPY_SUCCESS                     BIT(4)
  50 #define STATUS_COPY_FAIL                        BIT(5)
  51 #define STATUS_IRQ_RAISED                       BIT(6)
  52 #define STATUS_SRC_ADDR_INVALID                 BIT(7)
  53 #define STATUS_DST_ADDR_INVALID                 BIT(8)
  54 
  55 #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR        0x0c
  56 #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR        0x10
  57 
  58 #define PCI_ENDPOINT_TEST_LOWER_DST_ADDR        0x14
  59 #define PCI_ENDPOINT_TEST_UPPER_DST_ADDR        0x18
  60 
  61 #define PCI_ENDPOINT_TEST_SIZE                  0x1c
  62 #define PCI_ENDPOINT_TEST_CHECKSUM              0x20
  63 
  64 #define PCI_ENDPOINT_TEST_IRQ_TYPE              0x24
  65 #define PCI_ENDPOINT_TEST_IRQ_NUMBER            0x28
  66 
  67 #define PCI_DEVICE_ID_TI_AM654                  0xb00c
  68 
  69 #define is_am654_pci_dev(pdev)          \
  70                 ((pdev)->device == PCI_DEVICE_ID_TI_AM654)
  71 
  72 static DEFINE_IDA(pci_endpoint_test_ida);
  73 
  74 #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
  75                                             miscdev)
  76 
  77 static bool no_msi;
  78 module_param(no_msi, bool, 0444);
  79 MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test");
  80 
  81 static int irq_type = IRQ_TYPE_MSI;
  82 module_param(irq_type, int, 0444);
  83 MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - Legacy, 1 - MSI, 2 - MSI-X)");
  84 
  85 enum pci_barno {
  86         BAR_0,
  87         BAR_1,
  88         BAR_2,
  89         BAR_3,
  90         BAR_4,
  91         BAR_5,
  92 };
  93 
  94 struct pci_endpoint_test {
  95         struct pci_dev  *pdev;
  96         void __iomem    *base;
  97         void __iomem    *bar[6];
  98         struct completion irq_raised;
  99         int             last_irq;
 100         int             num_irqs;
 101         int             irq_type;
 102         /* mutex to protect the ioctls */
 103         struct mutex    mutex;
 104         struct miscdevice miscdev;
 105         enum pci_barno test_reg_bar;
 106         size_t alignment;
 107 };
 108 
 109 struct pci_endpoint_test_data {
 110         enum pci_barno test_reg_bar;
 111         size_t alignment;
 112         int irq_type;
 113 };
 114 
 115 static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
 116                                           u32 offset)
 117 {
 118         return readl(test->base + offset);
 119 }
 120 
 121 static inline void pci_endpoint_test_writel(struct pci_endpoint_test *test,
 122                                             u32 offset, u32 value)
 123 {
 124         writel(value, test->base + offset);
 125 }
 126 
 127 static inline u32 pci_endpoint_test_bar_readl(struct pci_endpoint_test *test,
 128                                               int bar, int offset)
 129 {
 130         return readl(test->bar[bar] + offset);
 131 }
 132 
 133 static inline void pci_endpoint_test_bar_writel(struct pci_endpoint_test *test,
 134                                                 int bar, u32 offset, u32 value)
 135 {
 136         writel(value, test->bar[bar] + offset);
 137 }
 138 
 139 static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
 140 {
 141         struct pci_endpoint_test *test = dev_id;
 142         u32 reg;
 143 
 144         reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
 145         if (reg & STATUS_IRQ_RAISED) {
 146                 test->last_irq = irq;
 147                 complete(&test->irq_raised);
 148                 reg &= ~STATUS_IRQ_RAISED;
 149         }
 150         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS,
 151                                  reg);
 152 
 153         return IRQ_HANDLED;
 154 }
 155 
 156 static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
 157 {
 158         struct pci_dev *pdev = test->pdev;
 159 
 160         pci_free_irq_vectors(pdev);
 161         test->irq_type = IRQ_TYPE_UNDEFINED;
 162 }
 163 
 164 static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
 165                                                 int type)
 166 {
 167         int irq = -1;
 168         struct pci_dev *pdev = test->pdev;
 169         struct device *dev = &pdev->dev;
 170         bool res = true;
 171 
 172         switch (type) {
 173         case IRQ_TYPE_LEGACY:
 174                 irq = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY);
 175                 if (irq < 0)
 176                         dev_err(dev, "Failed to get Legacy interrupt\n");
 177                 break;
 178         case IRQ_TYPE_MSI:
 179                 irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
 180                 if (irq < 0)
 181                         dev_err(dev, "Failed to get MSI interrupts\n");
 182                 break;
 183         case IRQ_TYPE_MSIX:
 184                 irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX);
 185                 if (irq < 0)
 186                         dev_err(dev, "Failed to get MSI-X interrupts\n");
 187                 break;
 188         default:
 189                 dev_err(dev, "Invalid IRQ type selected\n");
 190         }
 191 
 192         if (irq < 0) {
 193                 irq = 0;
 194                 res = false;
 195         }
 196 
 197         test->irq_type = type;
 198         test->num_irqs = irq;
 199 
 200         return res;
 201 }
 202 
 203 static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
 204 {
 205         int i;
 206         struct pci_dev *pdev = test->pdev;
 207         struct device *dev = &pdev->dev;
 208 
 209         for (i = 0; i < test->num_irqs; i++)
 210                 devm_free_irq(dev, pci_irq_vector(pdev, i), test);
 211 
 212         test->num_irqs = 0;
 213 }
 214 
 215 static bool pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
 216 {
 217         int i;
 218         int err;
 219         struct pci_dev *pdev = test->pdev;
 220         struct device *dev = &pdev->dev;
 221 
 222         for (i = 0; i < test->num_irqs; i++) {
 223                 err = devm_request_irq(dev, pci_irq_vector(pdev, i),
 224                                        pci_endpoint_test_irqhandler,
 225                                        IRQF_SHARED, DRV_MODULE_NAME, test);
 226                 if (err)
 227                         goto fail;
 228         }
 229 
 230         return true;
 231 
 232 fail:
 233         switch (irq_type) {
 234         case IRQ_TYPE_LEGACY:
 235                 dev_err(dev, "Failed to request IRQ %d for Legacy\n",
 236                         pci_irq_vector(pdev, i));
 237                 break;
 238         case IRQ_TYPE_MSI:
 239                 dev_err(dev, "Failed to request IRQ %d for MSI %d\n",
 240                         pci_irq_vector(pdev, i),
 241                         i + 1);
 242                 break;
 243         case IRQ_TYPE_MSIX:
 244                 dev_err(dev, "Failed to request IRQ %d for MSI-X %d\n",
 245                         pci_irq_vector(pdev, i),
 246                         i + 1);
 247                 break;
 248         }
 249 
 250         return false;
 251 }
 252 
 253 static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
 254                                   enum pci_barno barno)
 255 {
 256         int j;
 257         u32 val;
 258         int size;
 259         struct pci_dev *pdev = test->pdev;
 260 
 261         if (!test->bar[barno])
 262                 return false;
 263 
 264         size = pci_resource_len(pdev, barno);
 265 
 266         if (barno == test->test_reg_bar)
 267                 size = 0x4;
 268 
 269         for (j = 0; j < size; j += 4)
 270                 pci_endpoint_test_bar_writel(test, barno, j, 0xA0A0A0A0);
 271 
 272         for (j = 0; j < size; j += 4) {
 273                 val = pci_endpoint_test_bar_readl(test, barno, j);
 274                 if (val != 0xA0A0A0A0)
 275                         return false;
 276         }
 277 
 278         return true;
 279 }
 280 
 281 static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
 282 {
 283         u32 val;
 284 
 285         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
 286                                  IRQ_TYPE_LEGACY);
 287         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
 288         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
 289                                  COMMAND_RAISE_LEGACY_IRQ);
 290         val = wait_for_completion_timeout(&test->irq_raised,
 291                                           msecs_to_jiffies(1000));
 292         if (!val)
 293                 return false;
 294 
 295         return true;
 296 }
 297 
 298 static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
 299                                        u16 msi_num, bool msix)
 300 {
 301         u32 val;
 302         struct pci_dev *pdev = test->pdev;
 303 
 304         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
 305                                  msix == false ? IRQ_TYPE_MSI :
 306                                  IRQ_TYPE_MSIX);
 307         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
 308         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
 309                                  msix == false ? COMMAND_RAISE_MSI_IRQ :
 310                                  COMMAND_RAISE_MSIX_IRQ);
 311         val = wait_for_completion_timeout(&test->irq_raised,
 312                                           msecs_to_jiffies(1000));
 313         if (!val)
 314                 return false;
 315 
 316         if (pci_irq_vector(pdev, msi_num - 1) == test->last_irq)
 317                 return true;
 318 
 319         return false;
 320 }
 321 
 322 static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
 323 {
 324         bool ret = false;
 325         void *src_addr;
 326         void *dst_addr;
 327         dma_addr_t src_phys_addr;
 328         dma_addr_t dst_phys_addr;
 329         struct pci_dev *pdev = test->pdev;
 330         struct device *dev = &pdev->dev;
 331         void *orig_src_addr;
 332         dma_addr_t orig_src_phys_addr;
 333         void *orig_dst_addr;
 334         dma_addr_t orig_dst_phys_addr;
 335         size_t offset;
 336         size_t alignment = test->alignment;
 337         int irq_type = test->irq_type;
 338         u32 src_crc32;
 339         u32 dst_crc32;
 340 
 341         if (size > SIZE_MAX - alignment)
 342                 goto err;
 343 
 344         if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
 345                 dev_err(dev, "Invalid IRQ type option\n");
 346                 goto err;
 347         }
 348 
 349         orig_src_addr = dma_alloc_coherent(dev, size + alignment,
 350                                            &orig_src_phys_addr, GFP_KERNEL);
 351         if (!orig_src_addr) {
 352                 dev_err(dev, "Failed to allocate source buffer\n");
 353                 ret = false;
 354                 goto err;
 355         }
 356 
 357         if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) {
 358                 src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment);
 359                 offset = src_phys_addr - orig_src_phys_addr;
 360                 src_addr = orig_src_addr + offset;
 361         } else {
 362                 src_phys_addr = orig_src_phys_addr;
 363                 src_addr = orig_src_addr;
 364         }
 365 
 366         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
 367                                  lower_32_bits(src_phys_addr));
 368 
 369         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
 370                                  upper_32_bits(src_phys_addr));
 371 
 372         get_random_bytes(src_addr, size);
 373         src_crc32 = crc32_le(~0, src_addr, size);
 374 
 375         orig_dst_addr = dma_alloc_coherent(dev, size + alignment,
 376                                            &orig_dst_phys_addr, GFP_KERNEL);
 377         if (!orig_dst_addr) {
 378                 dev_err(dev, "Failed to allocate destination address\n");
 379                 ret = false;
 380                 goto err_orig_src_addr;
 381         }
 382 
 383         if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) {
 384                 dst_phys_addr = PTR_ALIGN(orig_dst_phys_addr, alignment);
 385                 offset = dst_phys_addr - orig_dst_phys_addr;
 386                 dst_addr = orig_dst_addr + offset;
 387         } else {
 388                 dst_phys_addr = orig_dst_phys_addr;
 389                 dst_addr = orig_dst_addr;
 390         }
 391 
 392         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
 393                                  lower_32_bits(dst_phys_addr));
 394         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
 395                                  upper_32_bits(dst_phys_addr));
 396 
 397         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
 398                                  size);
 399 
 400         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
 401         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
 402         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
 403                                  COMMAND_COPY);
 404 
 405         wait_for_completion(&test->irq_raised);
 406 
 407         dst_crc32 = crc32_le(~0, dst_addr, size);
 408         if (dst_crc32 == src_crc32)
 409                 ret = true;
 410 
 411         dma_free_coherent(dev, size + alignment, orig_dst_addr,
 412                           orig_dst_phys_addr);
 413 
 414 err_orig_src_addr:
 415         dma_free_coherent(dev, size + alignment, orig_src_addr,
 416                           orig_src_phys_addr);
 417 
 418 err:
 419         return ret;
 420 }
 421 
 422 static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
 423 {
 424         bool ret = false;
 425         u32 reg;
 426         void *addr;
 427         dma_addr_t phys_addr;
 428         struct pci_dev *pdev = test->pdev;
 429         struct device *dev = &pdev->dev;
 430         void *orig_addr;
 431         dma_addr_t orig_phys_addr;
 432         size_t offset;
 433         size_t alignment = test->alignment;
 434         int irq_type = test->irq_type;
 435         u32 crc32;
 436 
 437         if (size > SIZE_MAX - alignment)
 438                 goto err;
 439 
 440         if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
 441                 dev_err(dev, "Invalid IRQ type option\n");
 442                 goto err;
 443         }
 444 
 445         orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
 446                                        GFP_KERNEL);
 447         if (!orig_addr) {
 448                 dev_err(dev, "Failed to allocate address\n");
 449                 ret = false;
 450                 goto err;
 451         }
 452 
 453         if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
 454                 phys_addr =  PTR_ALIGN(orig_phys_addr, alignment);
 455                 offset = phys_addr - orig_phys_addr;
 456                 addr = orig_addr + offset;
 457         } else {
 458                 phys_addr = orig_phys_addr;
 459                 addr = orig_addr;
 460         }
 461 
 462         get_random_bytes(addr, size);
 463 
 464         crc32 = crc32_le(~0, addr, size);
 465         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
 466                                  crc32);
 467 
 468         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
 469                                  lower_32_bits(phys_addr));
 470         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
 471                                  upper_32_bits(phys_addr));
 472 
 473         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
 474 
 475         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
 476         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
 477         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
 478                                  COMMAND_READ);
 479 
 480         wait_for_completion(&test->irq_raised);
 481 
 482         reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
 483         if (reg & STATUS_READ_SUCCESS)
 484                 ret = true;
 485 
 486         dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr);
 487 
 488 err:
 489         return ret;
 490 }
 491 
 492 static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
 493 {
 494         bool ret = false;
 495         void *addr;
 496         dma_addr_t phys_addr;
 497         struct pci_dev *pdev = test->pdev;
 498         struct device *dev = &pdev->dev;
 499         void *orig_addr;
 500         dma_addr_t orig_phys_addr;
 501         size_t offset;
 502         size_t alignment = test->alignment;
 503         int irq_type = test->irq_type;
 504         u32 crc32;
 505 
 506         if (size > SIZE_MAX - alignment)
 507                 goto err;
 508 
 509         if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) {
 510                 dev_err(dev, "Invalid IRQ type option\n");
 511                 goto err;
 512         }
 513 
 514         orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr,
 515                                        GFP_KERNEL);
 516         if (!orig_addr) {
 517                 dev_err(dev, "Failed to allocate destination address\n");
 518                 ret = false;
 519                 goto err;
 520         }
 521 
 522         if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
 523                 phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
 524                 offset = phys_addr - orig_phys_addr;
 525                 addr = orig_addr + offset;
 526         } else {
 527                 phys_addr = orig_phys_addr;
 528                 addr = orig_addr;
 529         }
 530 
 531         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
 532                                  lower_32_bits(phys_addr));
 533         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
 534                                  upper_32_bits(phys_addr));
 535 
 536         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
 537 
 538         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
 539         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
 540         pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
 541                                  COMMAND_WRITE);
 542 
 543         wait_for_completion(&test->irq_raised);
 544 
 545         crc32 = crc32_le(~0, addr, size);
 546         if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
 547                 ret = true;
 548 
 549         dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr);
 550 err:
 551         return ret;
 552 }
 553 
 554 static bool pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
 555                                       int req_irq_type)
 556 {
 557         struct pci_dev *pdev = test->pdev;
 558         struct device *dev = &pdev->dev;
 559 
 560         if (req_irq_type < IRQ_TYPE_LEGACY || req_irq_type > IRQ_TYPE_MSIX) {
 561                 dev_err(dev, "Invalid IRQ type option\n");
 562                 return false;
 563         }
 564 
 565         if (test->irq_type == req_irq_type)
 566                 return true;
 567 
 568         pci_endpoint_test_release_irq(test);
 569         pci_endpoint_test_free_irq_vectors(test);
 570 
 571         if (!pci_endpoint_test_alloc_irq_vectors(test, req_irq_type))
 572                 goto err;
 573 
 574         if (!pci_endpoint_test_request_irq(test))
 575                 goto err;
 576 
 577         return true;
 578 
 579 err:
 580         pci_endpoint_test_free_irq_vectors(test);
 581         return false;
 582 }
 583 
 584 static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
 585                                     unsigned long arg)
 586 {
 587         int ret = -EINVAL;
 588         enum pci_barno bar;
 589         struct pci_endpoint_test *test = to_endpoint_test(file->private_data);
 590         struct pci_dev *pdev = test->pdev;
 591 
 592         mutex_lock(&test->mutex);
 593         switch (cmd) {
 594         case PCITEST_BAR:
 595                 bar = arg;
 596                 if (bar < 0 || bar > 5)
 597                         goto ret;
 598                 if (is_am654_pci_dev(pdev) && bar == BAR_0)
 599                         goto ret;
 600                 ret = pci_endpoint_test_bar(test, bar);
 601                 break;
 602         case PCITEST_LEGACY_IRQ:
 603                 ret = pci_endpoint_test_legacy_irq(test);
 604                 break;
 605         case PCITEST_MSI:
 606         case PCITEST_MSIX:
 607                 ret = pci_endpoint_test_msi_irq(test, arg, cmd == PCITEST_MSIX);
 608                 break;
 609         case PCITEST_WRITE:
 610                 ret = pci_endpoint_test_write(test, arg);
 611                 break;
 612         case PCITEST_READ:
 613                 ret = pci_endpoint_test_read(test, arg);
 614                 break;
 615         case PCITEST_COPY:
 616                 ret = pci_endpoint_test_copy(test, arg);
 617                 break;
 618         case PCITEST_SET_IRQTYPE:
 619                 ret = pci_endpoint_test_set_irq(test, arg);
 620                 break;
 621         case PCITEST_GET_IRQTYPE:
 622                 ret = irq_type;
 623                 break;
 624         }
 625 
 626 ret:
 627         mutex_unlock(&test->mutex);
 628         return ret;
 629 }
 630 
 631 static const struct file_operations pci_endpoint_test_fops = {
 632         .owner = THIS_MODULE,
 633         .unlocked_ioctl = pci_endpoint_test_ioctl,
 634 };
 635 
 636 static int pci_endpoint_test_probe(struct pci_dev *pdev,
 637                                    const struct pci_device_id *ent)
 638 {
 639         int err;
 640         int id;
 641         char name[24];
 642         enum pci_barno bar;
 643         void __iomem *base;
 644         struct device *dev = &pdev->dev;
 645         struct pci_endpoint_test *test;
 646         struct pci_endpoint_test_data *data;
 647         enum pci_barno test_reg_bar = BAR_0;
 648         struct miscdevice *misc_device;
 649 
 650         if (pci_is_bridge(pdev))
 651                 return -ENODEV;
 652 
 653         test = devm_kzalloc(dev, sizeof(*test), GFP_KERNEL);
 654         if (!test)
 655                 return -ENOMEM;
 656 
 657         test->test_reg_bar = 0;
 658         test->alignment = 0;
 659         test->pdev = pdev;
 660         test->irq_type = IRQ_TYPE_UNDEFINED;
 661 
 662         if (no_msi)
 663                 irq_type = IRQ_TYPE_LEGACY;
 664 
 665         data = (struct pci_endpoint_test_data *)ent->driver_data;
 666         if (data) {
 667                 test_reg_bar = data->test_reg_bar;
 668                 test->test_reg_bar = test_reg_bar;
 669                 test->alignment = data->alignment;
 670                 irq_type = data->irq_type;
 671         }
 672 
 673         init_completion(&test->irq_raised);
 674         mutex_init(&test->mutex);
 675 
 676         err = pci_enable_device(pdev);
 677         if (err) {
 678                 dev_err(dev, "Cannot enable PCI device\n");
 679                 return err;
 680         }
 681 
 682         err = pci_request_regions(pdev, DRV_MODULE_NAME);
 683         if (err) {
 684                 dev_err(dev, "Cannot obtain PCI resources\n");
 685                 goto err_disable_pdev;
 686         }
 687 
 688         pci_set_master(pdev);
 689 
 690         if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type))
 691                 goto err_disable_irq;
 692 
 693         if (!pci_endpoint_test_request_irq(test))
 694                 goto err_disable_irq;
 695 
 696         for (bar = BAR_0; bar <= BAR_5; bar++) {
 697                 if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
 698                         base = pci_ioremap_bar(pdev, bar);
 699                         if (!base) {
 700                                 dev_err(dev, "Failed to read BAR%d\n", bar);
 701                                 WARN_ON(bar == test_reg_bar);
 702                         }
 703                         test->bar[bar] = base;
 704                 }
 705         }
 706 
 707         test->base = test->bar[test_reg_bar];
 708         if (!test->base) {
 709                 err = -ENOMEM;
 710                 dev_err(dev, "Cannot perform PCI test without BAR%d\n",
 711                         test_reg_bar);
 712                 goto err_iounmap;
 713         }
 714 
 715         pci_set_drvdata(pdev, test);
 716 
 717         id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL);
 718         if (id < 0) {
 719                 err = id;
 720                 dev_err(dev, "Unable to get id\n");
 721                 goto err_iounmap;
 722         }
 723 
 724         snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
 725         misc_device = &test->miscdev;
 726         misc_device->minor = MISC_DYNAMIC_MINOR;
 727         misc_device->name = kstrdup(name, GFP_KERNEL);
 728         if (!misc_device->name) {
 729                 err = -ENOMEM;
 730                 goto err_ida_remove;
 731         }
 732         misc_device->fops = &pci_endpoint_test_fops,
 733 
 734         err = misc_register(misc_device);
 735         if (err) {
 736                 dev_err(dev, "Failed to register device\n");
 737                 goto err_kfree_name;
 738         }
 739 
 740         return 0;
 741 
 742 err_kfree_name:
 743         kfree(misc_device->name);
 744 
 745 err_ida_remove:
 746         ida_simple_remove(&pci_endpoint_test_ida, id);
 747 
 748 err_iounmap:
 749         for (bar = BAR_0; bar <= BAR_5; bar++) {
 750                 if (test->bar[bar])
 751                         pci_iounmap(pdev, test->bar[bar]);
 752         }
 753         pci_endpoint_test_release_irq(test);
 754 
 755 err_disable_irq:
 756         pci_endpoint_test_free_irq_vectors(test);
 757         pci_release_regions(pdev);
 758 
 759 err_disable_pdev:
 760         pci_disable_device(pdev);
 761 
 762         return err;
 763 }
 764 
 765 static void pci_endpoint_test_remove(struct pci_dev *pdev)
 766 {
 767         int id;
 768         enum pci_barno bar;
 769         struct pci_endpoint_test *test = pci_get_drvdata(pdev);
 770         struct miscdevice *misc_device = &test->miscdev;
 771 
 772         if (sscanf(misc_device->name, DRV_MODULE_NAME ".%d", &id) != 1)
 773                 return;
 774         if (id < 0)
 775                 return;
 776 
 777         misc_deregister(&test->miscdev);
 778         kfree(misc_device->name);
 779         ida_simple_remove(&pci_endpoint_test_ida, id);
 780         for (bar = BAR_0; bar <= BAR_5; bar++) {
 781                 if (test->bar[bar])
 782                         pci_iounmap(pdev, test->bar[bar]);
 783         }
 784 
 785         pci_endpoint_test_release_irq(test);
 786         pci_endpoint_test_free_irq_vectors(test);
 787 
 788         pci_release_regions(pdev);
 789         pci_disable_device(pdev);
 790 }
 791 
 792 static const struct pci_endpoint_test_data am654_data = {
 793         .test_reg_bar = BAR_2,
 794         .alignment = SZ_64K,
 795         .irq_type = IRQ_TYPE_MSI,
 796 };
 797 
 798 static const struct pci_device_id pci_endpoint_test_tbl[] = {
 799         { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
 800         { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
 801         { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) },
 802         { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
 803         { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
 804           .driver_data = (kernel_ulong_t)&am654_data
 805         },
 806         { }
 807 };
 808 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
 809 
 810 static struct pci_driver pci_endpoint_test_driver = {
 811         .name           = DRV_MODULE_NAME,
 812         .id_table       = pci_endpoint_test_tbl,
 813         .probe          = pci_endpoint_test_probe,
 814         .remove         = pci_endpoint_test_remove,
 815 };
 816 module_pci_driver(pci_endpoint_test_driver);
 817 
 818 MODULE_DESCRIPTION("PCI ENDPOINT TEST HOST DRIVER");
 819 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
 820 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */