1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <dirent.h> 7 8 #include <rte_log.h> 9 #include <rte_bus.h> 10 #include <rte_pci.h> 11 #include <rte_bus_pci.h> 12 #include <rte_malloc.h> 13 #include <rte_devargs.h> 14 #include <rte_memcpy.h> 15 #include <rte_vfio.h> 16 17 #include "eal_filesystem.h" 18 19 #include "private.h" 20 #include "pci_init.h" 21 22 /** 23 * @file 24 * PCI probing under linux 25 * 26 * This code is used to simulate a PCI probe by parsing information in sysfs. 27 * When a registered device matches a driver, it is then initialized with 28 * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it). 29 */ 30 31 extern struct rte_pci_bus rte_pci_bus; 32 33 static int 34 pci_get_kernel_driver_by_path(const char *filename, char *dri_name, 35 size_t len) 36 { 37 int count; 38 char path[PATH_MAX]; 39 char *name; 40 41 if (!filename || !dri_name) 42 return -1; 43 44 count = readlink(filename, path, PATH_MAX); 45 if (count >= PATH_MAX) 46 return -1; 47 48 /* For device does not have a driver */ 49 if (count < 0) 50 return 1; 51 52 path[count] = '\0'; 53 54 name = strrchr(path, '/'); 55 if (name) { 56 strlcpy(dri_name, name + 1, len); 57 return 0; 58 } 59 60 return -1; 61 } 62 63 /* Map pci device */ 64 int 65 rte_pci_map_device(struct rte_pci_device *dev) 66 { 67 int ret = -1; 68 69 /* try mapping the NIC resources using VFIO if it exists */ 70 switch (dev->kdrv) { 71 case RTE_KDRV_VFIO: 72 #ifdef VFIO_PRESENT 73 if (pci_vfio_is_enabled()) 74 ret = pci_vfio_map_resource(dev); 75 #endif 76 break; 77 case RTE_KDRV_IGB_UIO: 78 case RTE_KDRV_UIO_GENERIC: 79 if (rte_eal_using_phys_addrs()) { 80 /* map resources for devices that use uio */ 81 ret = pci_uio_map_resource(dev); 82 } 83 break; 84 default: 85 RTE_LOG(DEBUG, EAL, 86 " Not managed by a supported kernel driver, skipped\n"); 87 ret = 1; 88 break; 89 } 90 91 return ret; 92 } 93 94 /* Unmap pci device */ 95 void 96 rte_pci_unmap_device(struct rte_pci_device *dev) 97 { 98 /* try unmapping the NIC resources using VFIO if it exists */ 99 switch (dev->kdrv) { 100 case RTE_KDRV_VFIO: 101 #ifdef VFIO_PRESENT 102 if (pci_vfio_is_enabled()) 103 pci_vfio_unmap_resource(dev); 104 #endif 105 break; 106 case RTE_KDRV_IGB_UIO: 107 case RTE_KDRV_UIO_GENERIC: 108 /* unmap resources for devices that use uio */ 109 pci_uio_unmap_resource(dev); 110 break; 111 default: 112 RTE_LOG(DEBUG, EAL, 113 " Not managed by a supported kernel driver, skipped\n"); 114 break; 115 } 116 } 117 118 static int 119 find_max_end_va(const struct rte_memseg_list *msl, void *arg) 120 { 121 size_t sz = msl->len; 122 void *end_va = RTE_PTR_ADD(msl->base_va, sz); 123 void **max_va = arg; 124 125 if (*max_va < end_va) 126 *max_va = end_va; 127 return 0; 128 } 129 130 void * 131 pci_find_max_end_va(void) 132 { 133 void *va = NULL; 134 135 rte_memseg_list_walk(find_max_end_va, &va); 136 return va; 137 } 138 139 140 /* parse one line of the "resource" sysfs file (note that the 'line' 141 * string is modified) 142 */ 143 int 144 pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr, 145 uint64_t *end_addr, uint64_t *flags) 146 { 147 union pci_resource_info { 148 struct { 149 char *phys_addr; 150 char *end_addr; 151 char *flags; 152 }; 153 char *ptrs[PCI_RESOURCE_FMT_NVAL]; 154 } res_info; 155 156 if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) { 157 RTE_LOG(ERR, EAL, 158 "%s(): bad resource format\n", __func__); 159 return -1; 160 } 161 errno = 0; 162 *phys_addr = strtoull(res_info.phys_addr, NULL, 16); 163 *end_addr = strtoull(res_info.end_addr, NULL, 16); 164 *flags = strtoull(res_info.flags, NULL, 16); 165 if (errno != 0) { 166 RTE_LOG(ERR, EAL, 167 "%s(): bad resource format\n", __func__); 168 return -1; 169 } 170 171 return 0; 172 } 173 174 /* parse the "resource" sysfs file */ 175 static int 176 pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev) 177 { 178 FILE *f; 179 char buf[BUFSIZ]; 180 int i; 181 uint64_t phys_addr, end_addr, flags; 182 183 f = fopen(filename, "r"); 184 if (f == NULL) { 185 RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n"); 186 return -1; 187 } 188 189 for (i = 0; i<PCI_MAX_RESOURCE; i++) { 190 191 if (fgets(buf, sizeof(buf), f) == NULL) { 192 RTE_LOG(ERR, EAL, 193 "%s(): cannot read resource\n", __func__); 194 goto error; 195 } 196 if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr, 197 &end_addr, &flags) < 0) 198 goto error; 199 200 if (flags & IORESOURCE_MEM) { 201 dev->mem_resource[i].phys_addr = phys_addr; 202 dev->mem_resource[i].len = end_addr - phys_addr + 1; 203 /* not mapped for now */ 204 dev->mem_resource[i].addr = NULL; 205 } 206 } 207 fclose(f); 208 return 0; 209 210 error: 211 fclose(f); 212 return -1; 213 } 214 215 /* Scan one pci sysfs entry, and fill the devices list from it. */ 216 static int 217 pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) 218 { 219 char filename[PATH_MAX]; 220 unsigned long tmp; 221 struct rte_pci_device *dev; 222 char driver[PATH_MAX]; 223 int ret; 224 225 dev = malloc(sizeof(*dev)); 226 if (dev == NULL) 227 return -1; 228 229 memset(dev, 0, sizeof(*dev)); 230 dev->device.bus = &rte_pci_bus.bus; 231 dev->addr = *addr; 232 233 /* get vendor id */ 234 snprintf(filename, sizeof(filename), "%s/vendor", dirname); 235 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 236 free(dev); 237 return -1; 238 } 239 dev->id.vendor_id = (uint16_t)tmp; 240 241 /* get device id */ 242 snprintf(filename, sizeof(filename), "%s/device", dirname); 243 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 244 free(dev); 245 return -1; 246 } 247 dev->id.device_id = (uint16_t)tmp; 248 249 /* get subsystem_vendor id */ 250 snprintf(filename, sizeof(filename), "%s/subsystem_vendor", 251 dirname); 252 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 253 free(dev); 254 return -1; 255 } 256 dev->id.subsystem_vendor_id = (uint16_t)tmp; 257 258 /* get subsystem_device id */ 259 snprintf(filename, sizeof(filename), "%s/subsystem_device", 260 dirname); 261 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 262 free(dev); 263 return -1; 264 } 265 dev->id.subsystem_device_id = (uint16_t)tmp; 266 267 /* get class_id */ 268 snprintf(filename, sizeof(filename), "%s/class", 269 dirname); 270 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 271 free(dev); 272 return -1; 273 } 274 /* the least 24 bits are valid: class, subclass, program interface */ 275 dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID; 276 277 /* get max_vfs */ 278 dev->max_vfs = 0; 279 snprintf(filename, sizeof(filename), "%s/max_vfs", dirname); 280 if (!access(filename, F_OK) && 281 eal_parse_sysfs_value(filename, &tmp) == 0) 282 dev->max_vfs = (uint16_t)tmp; 283 else { 284 /* for non igb_uio driver, need kernel version >= 3.8 */ 285 snprintf(filename, sizeof(filename), 286 "%s/sriov_numvfs", dirname); 287 if (!access(filename, F_OK) && 288 eal_parse_sysfs_value(filename, &tmp) == 0) 289 dev->max_vfs = (uint16_t)tmp; 290 } 291 292 /* get numa node, default to 0 if not present */ 293 snprintf(filename, sizeof(filename), "%s/numa_node", 294 dirname); 295 296 if (access(filename, F_OK) != -1) { 297 if (eal_parse_sysfs_value(filename, &tmp) == 0) 298 dev->device.numa_node = tmp; 299 else 300 dev->device.numa_node = -1; 301 } else { 302 dev->device.numa_node = 0; 303 } 304 305 pci_name_set(dev); 306 307 /* parse resources */ 308 snprintf(filename, sizeof(filename), "%s/resource", dirname); 309 if (pci_parse_sysfs_resource(filename, dev) < 0) { 310 RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__); 311 free(dev); 312 return -1; 313 } 314 315 /* parse driver */ 316 snprintf(filename, sizeof(filename), "%s/driver", dirname); 317 ret = pci_get_kernel_driver_by_path(filename, driver, sizeof(driver)); 318 if (ret < 0) { 319 RTE_LOG(ERR, EAL, "Fail to get kernel driver\n"); 320 free(dev); 321 return -1; 322 } 323 324 if (!ret) { 325 if (!strcmp(driver, "vfio-pci")) 326 dev->kdrv = RTE_KDRV_VFIO; 327 else if (!strcmp(driver, "igb_uio")) 328 dev->kdrv = RTE_KDRV_IGB_UIO; 329 else if (!strcmp(driver, "uio_pci_generic")) 330 dev->kdrv = RTE_KDRV_UIO_GENERIC; 331 else 332 dev->kdrv = RTE_KDRV_UNKNOWN; 333 } else 334 dev->kdrv = RTE_KDRV_NONE; 335 336 /* device is valid, add in list (sorted) */ 337 if (TAILQ_EMPTY(&rte_pci_bus.device_list)) { 338 rte_pci_add_device(dev); 339 } else { 340 struct rte_pci_device *dev2; 341 int ret; 342 343 TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) { 344 ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr); 345 if (ret > 0) 346 continue; 347 348 if (ret < 0) { 349 rte_pci_insert_device(dev2, dev); 350 } else { /* already registered */ 351 if (!rte_dev_is_probed(&dev2->device)) { 352 dev2->kdrv = dev->kdrv; 353 dev2->max_vfs = dev->max_vfs; 354 pci_name_set(dev2); 355 memmove(dev2->mem_resource, 356 dev->mem_resource, 357 sizeof(dev->mem_resource)); 358 } else { 359 /** 360 * If device is plugged and driver is 361 * probed already, (This happens when 362 * we call rte_dev_probe which will 363 * scan all device on the bus) we don't 364 * need to do anything here unless... 365 **/ 366 if (dev2->kdrv != dev->kdrv || 367 dev2->max_vfs != dev->max_vfs) 368 /* 369 * This should not happens. 370 * But it is still possible if 371 * we unbind a device from 372 * vfio or uio before hotplug 373 * remove and rebind it with 374 * a different configure. 375 * So we just print out the 376 * error as an alarm. 377 */ 378 RTE_LOG(ERR, EAL, "Unexpected device scan at %s!\n", 379 filename); 380 else if (dev2->device.devargs != 381 dev->device.devargs) { 382 rte_devargs_remove(dev2->device.devargs); 383 pci_name_set(dev2); 384 } 385 } 386 free(dev); 387 } 388 return 0; 389 } 390 391 rte_pci_add_device(dev); 392 } 393 394 return 0; 395 } 396 397 int 398 pci_update_device(const struct rte_pci_addr *addr) 399 { 400 char filename[PATH_MAX]; 401 402 snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT, 403 rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid, 404 addr->function); 405 406 return pci_scan_one(filename, addr); 407 } 408 409 /* 410 * split up a pci address into its constituent parts. 411 */ 412 static int 413 parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr) 414 { 415 /* first split on ':' */ 416 union splitaddr { 417 struct { 418 char *domain; 419 char *bus; 420 char *devid; 421 char *function; 422 }; 423 char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */ 424 } splitaddr; 425 426 char *buf_copy = strndup(buf, bufsize); 427 if (buf_copy == NULL) 428 return -1; 429 430 if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':') 431 != PCI_FMT_NVAL - 1) 432 goto error; 433 /* final split is on '.' between devid and function */ 434 splitaddr.function = strchr(splitaddr.devid,'.'); 435 if (splitaddr.function == NULL) 436 goto error; 437 *splitaddr.function++ = '\0'; 438 439 /* now convert to int values */ 440 errno = 0; 441 addr->domain = strtoul(splitaddr.domain, NULL, 16); 442 addr->bus = strtoul(splitaddr.bus, NULL, 16); 443 addr->devid = strtoul(splitaddr.devid, NULL, 16); 444 addr->function = strtoul(splitaddr.function, NULL, 10); 445 if (errno != 0) 446 goto error; 447 448 free(buf_copy); /* free the copy made with strdup */ 449 return 0; 450 error: 451 free(buf_copy); 452 return -1; 453 } 454 455 /* 456 * Scan the content of the PCI bus, and the devices in the devices 457 * list 458 */ 459 int 460 rte_pci_scan(void) 461 { 462 struct dirent *e; 463 DIR *dir; 464 char dirname[PATH_MAX]; 465 struct rte_pci_addr addr; 466 467 /* for debug purposes, PCI can be disabled */ 468 if (!rte_eal_has_pci()) 469 return 0; 470 471 #ifdef VFIO_PRESENT 472 if (!pci_vfio_is_enabled()) 473 RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n"); 474 #endif 475 476 dir = opendir(rte_pci_get_sysfs_path()); 477 if (dir == NULL) { 478 RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n", 479 __func__, strerror(errno)); 480 return -1; 481 } 482 483 while ((e = readdir(dir)) != NULL) { 484 if (e->d_name[0] == '.') 485 continue; 486 487 if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0) 488 continue; 489 490 if (rte_pci_ignore_device(&addr)) 491 continue; 492 493 snprintf(dirname, sizeof(dirname), "%s/%s", 494 rte_pci_get_sysfs_path(), e->d_name); 495 496 if (pci_scan_one(dirname, &addr) < 0) 497 goto error; 498 } 499 closedir(dir); 500 return 0; 501 502 error: 503 closedir(dir); 504 return -1; 505 } 506 507 #if defined(RTE_ARCH_X86) 508 bool 509 pci_device_iommu_support_va(const struct rte_pci_device *dev) 510 { 511 #define VTD_CAP_MGAW_SHIFT 16 512 #define VTD_CAP_MGAW_MASK (0x3fULL << VTD_CAP_MGAW_SHIFT) 513 const struct rte_pci_addr *addr = &dev->addr; 514 char filename[PATH_MAX]; 515 FILE *fp; 516 uint64_t mgaw, vtd_cap_reg = 0; 517 518 snprintf(filename, sizeof(filename), 519 "%s/" PCI_PRI_FMT "/iommu/intel-iommu/cap", 520 rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid, 521 addr->function); 522 523 fp = fopen(filename, "r"); 524 if (fp == NULL) { 525 /* We don't have an Intel IOMMU, assume VA supported */ 526 if (errno == ENOENT) 527 return true; 528 529 RTE_LOG(ERR, EAL, "%s(): can't open %s: %s\n", 530 __func__, filename, strerror(errno)); 531 return false; 532 } 533 534 /* We have an Intel IOMMU */ 535 if (fscanf(fp, "%" PRIx64, &vtd_cap_reg) != 1) { 536 RTE_LOG(ERR, EAL, "%s(): can't read %s\n", __func__, filename); 537 fclose(fp); 538 return false; 539 } 540 541 fclose(fp); 542 543 mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1; 544 545 /* 546 * Assuming there is no limitation by now. We can not know at this point 547 * because the memory has not been initialized yet. Setting the dma mask 548 * will force a check once memory initialization is done. We can not do 549 * a fallback to IOVA PA now, but if the dma check fails, the error 550 * message should advice for using '--iova-mode pa' if IOVA VA is the 551 * current mode. 552 */ 553 rte_mem_set_dma_mask(mgaw); 554 return true; 555 } 556 #elif defined(RTE_ARCH_PPC_64) 557 bool 558 pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev) 559 { 560 /* 561 * IOMMU is always present on a PowerNV host (IOMMUv2). 562 * IOMMU is also present in a KVM/QEMU VM (IOMMUv1) but is not 563 * currently supported by DPDK. Test for our current environment 564 * and report VA support as appropriate. 565 */ 566 567 char *line = NULL; 568 size_t len = 0; 569 char filename[PATH_MAX] = "/proc/cpuinfo"; 570 FILE *fp = fopen(filename, "r"); 571 bool ret = false; 572 573 if (fp == NULL) { 574 RTE_LOG(ERR, EAL, "%s(): can't open %s: %s\n", 575 __func__, filename, strerror(errno)); 576 return ret; 577 } 578 579 /* Check for a PowerNV platform */ 580 while (getline(&line, &len, fp) != -1) { 581 if (strstr(line, "platform") != NULL) 582 continue; 583 584 if (strstr(line, "PowerNV") != NULL) { 585 RTE_LOG(DEBUG, EAL, "Running on a PowerNV system\n"); 586 ret = true; 587 break; 588 } 589 } 590 591 free(line); 592 fclose(fp); 593 return ret; 594 } 595 #else 596 bool 597 pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev) 598 { 599 return true; 600 } 601 #endif 602 603 enum rte_iova_mode 604 pci_device_iova_mode(const struct rte_pci_driver *pdrv, 605 const struct rte_pci_device *pdev) 606 { 607 enum rte_iova_mode iova_mode = RTE_IOVA_DC; 608 609 switch (pdev->kdrv) { 610 case RTE_KDRV_VFIO: { 611 #ifdef VFIO_PRESENT 612 static int is_vfio_noiommu_enabled = -1; 613 614 if (is_vfio_noiommu_enabled == -1) { 615 if (rte_vfio_noiommu_is_enabled() == 1) 616 is_vfio_noiommu_enabled = 1; 617 else 618 is_vfio_noiommu_enabled = 0; 619 } 620 if (is_vfio_noiommu_enabled != 0) 621 iova_mode = RTE_IOVA_PA; 622 else if ((pdrv->drv_flags & RTE_PCI_DRV_NEED_IOVA_AS_VA) != 0) 623 iova_mode = RTE_IOVA_VA; 624 #endif 625 break; 626 } 627 628 case RTE_KDRV_IGB_UIO: 629 case RTE_KDRV_UIO_GENERIC: 630 iova_mode = RTE_IOVA_PA; 631 break; 632 633 default: 634 if ((pdrv->drv_flags & RTE_PCI_DRV_NEED_IOVA_AS_VA) != 0) 635 iova_mode = RTE_IOVA_VA; 636 break; 637 } 638 return iova_mode; 639 } 640 641 /* Read PCI config space. */ 642 int rte_pci_read_config(const struct rte_pci_device *device, 643 void *buf, size_t len, off_t offset) 644 { 645 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 646 const struct rte_intr_handle *intr_handle = &device->intr_handle; 647 648 switch (device->kdrv) { 649 case RTE_KDRV_IGB_UIO: 650 case RTE_KDRV_UIO_GENERIC: 651 return pci_uio_read_config(intr_handle, buf, len, offset); 652 #ifdef VFIO_PRESENT 653 case RTE_KDRV_VFIO: 654 return pci_vfio_read_config(intr_handle, buf, len, offset); 655 #endif 656 default: 657 rte_pci_device_name(&device->addr, devname, 658 RTE_DEV_NAME_MAX_LEN); 659 RTE_LOG(ERR, EAL, 660 "Unknown driver type for %s\n", devname); 661 return -1; 662 } 663 } 664 665 /* Write PCI config space. */ 666 int rte_pci_write_config(const struct rte_pci_device *device, 667 const void *buf, size_t len, off_t offset) 668 { 669 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 670 const struct rte_intr_handle *intr_handle = &device->intr_handle; 671 672 switch (device->kdrv) { 673 case RTE_KDRV_IGB_UIO: 674 case RTE_KDRV_UIO_GENERIC: 675 return pci_uio_write_config(intr_handle, buf, len, offset); 676 #ifdef VFIO_PRESENT 677 case RTE_KDRV_VFIO: 678 return pci_vfio_write_config(intr_handle, buf, len, offset); 679 #endif 680 default: 681 rte_pci_device_name(&device->addr, devname, 682 RTE_DEV_NAME_MAX_LEN); 683 RTE_LOG(ERR, EAL, 684 "Unknown driver type for %s\n", devname); 685 return -1; 686 } 687 } 688 689 #if defined(RTE_ARCH_X86) 690 static int 691 pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused, 692 struct rte_pci_ioport *p) 693 { 694 uint16_t start, end; 695 FILE *fp; 696 char *line = NULL; 697 char pci_id[16]; 698 int found = 0; 699 size_t linesz; 700 701 if (rte_eal_iopl_init() != 0) { 702 RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n", 703 __func__, dev->name); 704 return -1; 705 } 706 707 snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT, 708 dev->addr.domain, dev->addr.bus, 709 dev->addr.devid, dev->addr.function); 710 711 fp = fopen("/proc/ioports", "r"); 712 if (fp == NULL) { 713 RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__); 714 return -1; 715 } 716 717 while (getdelim(&line, &linesz, '\n', fp) > 0) { 718 char *ptr = line; 719 char *left; 720 int n; 721 722 n = strcspn(ptr, ":"); 723 ptr[n] = 0; 724 left = &ptr[n + 1]; 725 726 while (*left && isspace(*left)) 727 left++; 728 729 if (!strncmp(left, pci_id, strlen(pci_id))) { 730 found = 1; 731 732 while (*ptr && isspace(*ptr)) 733 ptr++; 734 735 sscanf(ptr, "%04hx-%04hx", &start, &end); 736 737 break; 738 } 739 } 740 741 free(line); 742 fclose(fp); 743 744 if (!found) 745 return -1; 746 747 p->base = start; 748 RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start); 749 750 return 0; 751 } 752 #endif 753 754 int 755 rte_pci_ioport_map(struct rte_pci_device *dev, int bar, 756 struct rte_pci_ioport *p) 757 { 758 int ret = -1; 759 760 switch (dev->kdrv) { 761 #ifdef VFIO_PRESENT 762 case RTE_KDRV_VFIO: 763 if (pci_vfio_is_enabled()) 764 ret = pci_vfio_ioport_map(dev, bar, p); 765 break; 766 #endif 767 case RTE_KDRV_IGB_UIO: 768 ret = pci_uio_ioport_map(dev, bar, p); 769 break; 770 case RTE_KDRV_UIO_GENERIC: 771 #if defined(RTE_ARCH_X86) 772 ret = pci_ioport_map(dev, bar, p); 773 #else 774 ret = pci_uio_ioport_map(dev, bar, p); 775 #endif 776 break; 777 case RTE_KDRV_NONE: 778 #if defined(RTE_ARCH_X86) 779 ret = pci_ioport_map(dev, bar, p); 780 #endif 781 break; 782 default: 783 break; 784 } 785 786 if (!ret) 787 p->dev = dev; 788 789 return ret; 790 } 791 792 void 793 rte_pci_ioport_read(struct rte_pci_ioport *p, 794 void *data, size_t len, off_t offset) 795 { 796 switch (p->dev->kdrv) { 797 #ifdef VFIO_PRESENT 798 case RTE_KDRV_VFIO: 799 pci_vfio_ioport_read(p, data, len, offset); 800 break; 801 #endif 802 case RTE_KDRV_IGB_UIO: 803 pci_uio_ioport_read(p, data, len, offset); 804 break; 805 case RTE_KDRV_UIO_GENERIC: 806 pci_uio_ioport_read(p, data, len, offset); 807 break; 808 case RTE_KDRV_NONE: 809 #if defined(RTE_ARCH_X86) 810 pci_uio_ioport_read(p, data, len, offset); 811 #endif 812 break; 813 default: 814 break; 815 } 816 } 817 818 void 819 rte_pci_ioport_write(struct rte_pci_ioport *p, 820 const void *data, size_t len, off_t offset) 821 { 822 switch (p->dev->kdrv) { 823 #ifdef VFIO_PRESENT 824 case RTE_KDRV_VFIO: 825 pci_vfio_ioport_write(p, data, len, offset); 826 break; 827 #endif 828 case RTE_KDRV_IGB_UIO: 829 pci_uio_ioport_write(p, data, len, offset); 830 break; 831 case RTE_KDRV_UIO_GENERIC: 832 pci_uio_ioport_write(p, data, len, offset); 833 break; 834 case RTE_KDRV_NONE: 835 #if defined(RTE_ARCH_X86) 836 pci_uio_ioport_write(p, data, len, offset); 837 #endif 838 break; 839 default: 840 break; 841 } 842 } 843 844 int 845 rte_pci_ioport_unmap(struct rte_pci_ioport *p) 846 { 847 int ret = -1; 848 849 switch (p->dev->kdrv) { 850 #ifdef VFIO_PRESENT 851 case RTE_KDRV_VFIO: 852 if (pci_vfio_is_enabled()) 853 ret = pci_vfio_ioport_unmap(p); 854 break; 855 #endif 856 case RTE_KDRV_IGB_UIO: 857 ret = pci_uio_ioport_unmap(p); 858 break; 859 case RTE_KDRV_UIO_GENERIC: 860 #if defined(RTE_ARCH_X86) 861 ret = 0; 862 #else 863 ret = pci_uio_ioport_unmap(p); 864 #endif 865 break; 866 case RTE_KDRV_NONE: 867 #if defined(RTE_ARCH_X86) 868 ret = 0; 869 #endif 870 break; 871 default: 872 break; 873 } 874 875 return ret; 876 } 877