133031608STal Shnaiderman /* SPDX-License-Identifier: BSD-3-Clause 233031608STal Shnaiderman * Copyright 2020 Mellanox Technologies, Ltd 333031608STal Shnaiderman */ 4b762221aSTal Shnaiderman #include <rte_windows.h> 533031608STal Shnaiderman #include <rte_errno.h> 633031608STal Shnaiderman #include <rte_log.h> 733031608STal Shnaiderman #include <rte_eal_memconfig.h> 8b762221aSTal Shnaiderman #include <rte_eal.h> 933031608STal Shnaiderman 1033031608STal Shnaiderman #include "private.h" 1133031608STal Shnaiderman 12b762221aSTal Shnaiderman #include <devpkey.h> 13b762221aSTal Shnaiderman 14b762221aSTal Shnaiderman #ifdef RTE_TOOLCHAIN_GCC 15b762221aSTal Shnaiderman #include <devpropdef.h> 16b762221aSTal Shnaiderman DEFINE_DEVPROPKEY(DEVPKEY_Device_Numa_Node, 0x540b947e, 0x8b40, 0x45bc, 17b762221aSTal Shnaiderman 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 3); 18b762221aSTal Shnaiderman #endif 19b762221aSTal Shnaiderman 20b762221aSTal Shnaiderman /* 21b762221aSTal Shnaiderman * This code is used to simulate a PCI probe by parsing information in 22b762221aSTal Shnaiderman * the registry hive for PCI devices. 23b762221aSTal Shnaiderman */ 24b762221aSTal Shnaiderman 2533031608STal Shnaiderman /* The functions below are not implemented on Windows, 2633031608STal Shnaiderman * but need to be defined for compilation purposes 2733031608STal Shnaiderman */ 2833031608STal Shnaiderman 2933031608STal Shnaiderman /* Map pci device */ 3033031608STal Shnaiderman int 3133031608STal Shnaiderman rte_pci_map_device(struct rte_pci_device *dev __rte_unused) 3233031608STal Shnaiderman { 3333031608STal Shnaiderman /* This function is not implemented on Windows. 3433031608STal Shnaiderman * We really should short-circuit the call to these functions by 3533031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 3633031608STal Shnaiderman * in the rte_pci_driver flags. 3733031608STal Shnaiderman */ 3833031608STal Shnaiderman return 0; 3933031608STal Shnaiderman } 4033031608STal Shnaiderman 4133031608STal Shnaiderman /* Unmap pci device */ 4233031608STal Shnaiderman void 4333031608STal Shnaiderman rte_pci_unmap_device(struct rte_pci_device *dev __rte_unused) 4433031608STal Shnaiderman { 4533031608STal Shnaiderman /* This function is not implemented on Windows. 4633031608STal Shnaiderman * We really should short-circuit the call to these functions by 4733031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 4833031608STal Shnaiderman * in the rte_pci_driver flags. 4933031608STal Shnaiderman */ 5033031608STal Shnaiderman } 5133031608STal Shnaiderman 5233031608STal Shnaiderman int 5333031608STal Shnaiderman pci_update_device(const struct rte_pci_addr *addr __rte_unused) 5433031608STal Shnaiderman { 5533031608STal Shnaiderman /* This function is not implemented on Windows. 5633031608STal Shnaiderman * We really should short-circuit the call to these functions by 5733031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 5833031608STal Shnaiderman * in the rte_pci_driver flags. 5933031608STal Shnaiderman */ 6033031608STal Shnaiderman return 0; 6133031608STal Shnaiderman } 6233031608STal Shnaiderman 6333031608STal Shnaiderman /* Read PCI config space. */ 6433031608STal Shnaiderman int 6533031608STal Shnaiderman rte_pci_read_config(const struct rte_pci_device *dev __rte_unused, 6633031608STal Shnaiderman void *buf __rte_unused, size_t len __rte_unused, 6733031608STal Shnaiderman off_t offset __rte_unused) 6833031608STal Shnaiderman { 6933031608STal Shnaiderman /* This function is not implemented on Windows. 7033031608STal Shnaiderman * We really should short-circuit the call to these functions by 7133031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 7233031608STal Shnaiderman * in the rte_pci_driver flags. 7333031608STal Shnaiderman */ 7433031608STal Shnaiderman return 0; 7533031608STal Shnaiderman } 7633031608STal Shnaiderman 7733031608STal Shnaiderman /* Write PCI config space. */ 7833031608STal Shnaiderman int 7933031608STal Shnaiderman rte_pci_write_config(const struct rte_pci_device *dev __rte_unused, 8033031608STal Shnaiderman const void *buf __rte_unused, size_t len __rte_unused, 8133031608STal Shnaiderman off_t offset __rte_unused) 8233031608STal Shnaiderman { 8333031608STal Shnaiderman /* This function is not implemented on Windows. 8433031608STal Shnaiderman * We really should short-circuit the call to these functions by 8533031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 8633031608STal Shnaiderman * in the rte_pci_driver flags. 8733031608STal Shnaiderman */ 8833031608STal Shnaiderman return 0; 8933031608STal Shnaiderman } 9033031608STal Shnaiderman 9133031608STal Shnaiderman enum rte_iova_mode 9233031608STal Shnaiderman pci_device_iova_mode(const struct rte_pci_driver *pdrv __rte_unused, 9333031608STal Shnaiderman const struct rte_pci_device *pdev __rte_unused) 9433031608STal Shnaiderman { 9533031608STal Shnaiderman /* This function is not implemented on Windows. 9633031608STal Shnaiderman * We really should short-circuit the call to these functions by 9733031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 9833031608STal Shnaiderman * in the rte_pci_driver flags. 9933031608STal Shnaiderman */ 10033031608STal Shnaiderman return RTE_IOVA_DC; 10133031608STal Shnaiderman } 10233031608STal Shnaiderman 10333031608STal Shnaiderman int 10433031608STal Shnaiderman rte_pci_ioport_map(struct rte_pci_device *dev __rte_unused, 10533031608STal Shnaiderman int bar __rte_unused, struct rte_pci_ioport *p __rte_unused) 10633031608STal Shnaiderman { 10733031608STal Shnaiderman /* This function is not implemented on Windows. 10833031608STal Shnaiderman * We really should short-circuit the call to these functions by 10933031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 11033031608STal Shnaiderman * in the rte_pci_driver flags. 11133031608STal Shnaiderman */ 11233031608STal Shnaiderman return -1; 11333031608STal Shnaiderman } 11433031608STal Shnaiderman 11533031608STal Shnaiderman 11633031608STal Shnaiderman void 11733031608STal Shnaiderman rte_pci_ioport_read(struct rte_pci_ioport *p __rte_unused, 11833031608STal Shnaiderman void *data __rte_unused, size_t len __rte_unused, 11933031608STal Shnaiderman off_t offset __rte_unused) 12033031608STal Shnaiderman { 12133031608STal Shnaiderman /* This function is not implemented on Windows. 12233031608STal Shnaiderman * We really should short-circuit the call to these functions by 12333031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 12433031608STal Shnaiderman * in the rte_pci_driver flags. 12533031608STal Shnaiderman */ 12633031608STal Shnaiderman } 12733031608STal Shnaiderman 12833031608STal Shnaiderman int 12933031608STal Shnaiderman rte_pci_ioport_unmap(struct rte_pci_ioport *p __rte_unused) 13033031608STal Shnaiderman { 13133031608STal Shnaiderman /* This function is not implemented on Windows. 13233031608STal Shnaiderman * We really should short-circuit the call to these functions by 13333031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 13433031608STal Shnaiderman * in the rte_pci_driver flags. 13533031608STal Shnaiderman */ 13633031608STal Shnaiderman return -1; 13733031608STal Shnaiderman } 13833031608STal Shnaiderman 13933031608STal Shnaiderman bool 14033031608STal Shnaiderman pci_device_iommu_support_va(const struct rte_pci_device *dev __rte_unused) 14133031608STal Shnaiderman { 14233031608STal Shnaiderman /* This function is not implemented on Windows. 14333031608STal Shnaiderman * We really should short-circuit the call to these functions by 14433031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 14533031608STal Shnaiderman * in the rte_pci_driver flags. 14633031608STal Shnaiderman */ 14733031608STal Shnaiderman return false; 14833031608STal Shnaiderman } 14933031608STal Shnaiderman 15033031608STal Shnaiderman void 15133031608STal Shnaiderman rte_pci_ioport_write(struct rte_pci_ioport *p __rte_unused, 15233031608STal Shnaiderman const void *data __rte_unused, size_t len __rte_unused, 15333031608STal Shnaiderman off_t offset __rte_unused) 15433031608STal Shnaiderman { 15533031608STal Shnaiderman /* This function is not implemented on Windows. 15633031608STal Shnaiderman * We really should short-circuit the call to these functions by 15733031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 15833031608STal Shnaiderman * in the rte_pci_driver flags. 15933031608STal Shnaiderman */ 16033031608STal Shnaiderman } 16133031608STal Shnaiderman 16233031608STal Shnaiderman /* remap the PCI resource of a PCI device in anonymous virtual memory */ 16333031608STal Shnaiderman int 16433031608STal Shnaiderman pci_uio_remap_resource(struct rte_pci_device *dev __rte_unused) 16533031608STal Shnaiderman { 16633031608STal Shnaiderman /* This function is not implemented on Windows. 16733031608STal Shnaiderman * We really should short-circuit the call to these functions by 16833031608STal Shnaiderman * clearing the RTE_PCI_DRV_NEED_MAPPING flag 16933031608STal Shnaiderman * in the rte_pci_driver flags. 17033031608STal Shnaiderman */ 17133031608STal Shnaiderman return -1; 17233031608STal Shnaiderman } 173b762221aSTal Shnaiderman 174b762221aSTal Shnaiderman static int 175b762221aSTal Shnaiderman get_device_pci_address(HDEVINFO dev_info, 176b762221aSTal Shnaiderman PSP_DEVINFO_DATA device_info_data, struct rte_pci_addr *addr) 177b762221aSTal Shnaiderman { 178b762221aSTal Shnaiderman BOOL res; 179b762221aSTal Shnaiderman ULONG bus_num, dev_and_func; 180b762221aSTal Shnaiderman 181b762221aSTal Shnaiderman res = SetupDiGetDeviceRegistryProperty(dev_info, device_info_data, 182b762221aSTal Shnaiderman SPDRP_BUSNUMBER, NULL, (PBYTE)&bus_num, sizeof(bus_num), NULL); 183b762221aSTal Shnaiderman if (!res) { 184b762221aSTal Shnaiderman RTE_LOG_WIN32_ERR( 185b762221aSTal Shnaiderman "SetupDiGetDeviceRegistryProperty(SPDRP_BUSNUMBER)"); 186b762221aSTal Shnaiderman return -1; 187b762221aSTal Shnaiderman } 188b762221aSTal Shnaiderman 189b762221aSTal Shnaiderman res = SetupDiGetDeviceRegistryProperty(dev_info, device_info_data, 190b762221aSTal Shnaiderman SPDRP_ADDRESS, NULL, (PBYTE)&dev_and_func, sizeof(dev_and_func), 191b762221aSTal Shnaiderman NULL); 192b762221aSTal Shnaiderman if (!res) { 193b762221aSTal Shnaiderman RTE_LOG_WIN32_ERR( 194b762221aSTal Shnaiderman "SetupDiGetDeviceRegistryProperty(SPDRP_ADDRESS)"); 195b762221aSTal Shnaiderman return -1; 196b762221aSTal Shnaiderman } 197b762221aSTal Shnaiderman 198*c3adf814STal Shnaiderman addr->domain = bus_num >> 8; 199*c3adf814STal Shnaiderman addr->bus = bus_num & 0xff; 200b762221aSTal Shnaiderman addr->devid = dev_and_func >> 16; 201b762221aSTal Shnaiderman addr->function = dev_and_func & 0xffff; 202b762221aSTal Shnaiderman return 0; 203b762221aSTal Shnaiderman } 204b762221aSTal Shnaiderman 205b762221aSTal Shnaiderman static int 206b762221aSTal Shnaiderman get_device_resource_info(HDEVINFO dev_info, 207b762221aSTal Shnaiderman PSP_DEVINFO_DATA dev_info_data, struct rte_pci_device *dev) 208b762221aSTal Shnaiderman { 209b762221aSTal Shnaiderman DEVPROPTYPE property_type; 210b762221aSTal Shnaiderman DWORD numa_node; 211b762221aSTal Shnaiderman BOOL res; 212b762221aSTal Shnaiderman 213b762221aSTal Shnaiderman switch (dev->kdrv) { 2147c0d798aSDavid Marchand case RTE_PCI_KDRV_NONE: 215b762221aSTal Shnaiderman /* Get NUMA node using DEVPKEY_Device_Numa_Node */ 216b762221aSTal Shnaiderman res = SetupDiGetDevicePropertyW(dev_info, dev_info_data, 217b762221aSTal Shnaiderman &DEVPKEY_Device_Numa_Node, &property_type, 218b762221aSTal Shnaiderman (BYTE *)&numa_node, sizeof(numa_node), NULL, 0); 219b762221aSTal Shnaiderman if (!res) { 220b762221aSTal Shnaiderman RTE_LOG_WIN32_ERR( 221b762221aSTal Shnaiderman "SetupDiGetDevicePropertyW" 222b762221aSTal Shnaiderman "(DEVPKEY_Device_Numa_Node)"); 223b762221aSTal Shnaiderman return -1; 224b762221aSTal Shnaiderman } 225b762221aSTal Shnaiderman dev->device.numa_node = numa_node; 2267c0d798aSDavid Marchand /* mem_resource - Unneeded for RTE_PCI_KDRV_NONE */ 227b762221aSTal Shnaiderman dev->mem_resource[0].phys_addr = 0; 228b762221aSTal Shnaiderman dev->mem_resource[0].len = 0; 229b762221aSTal Shnaiderman dev->mem_resource[0].addr = NULL; 230b762221aSTal Shnaiderman break; 231b762221aSTal Shnaiderman default: 232b762221aSTal Shnaiderman /* kernel driver type is unsupported */ 233b762221aSTal Shnaiderman RTE_LOG(DEBUG, EAL, 234b762221aSTal Shnaiderman "Kernel driver type for PCI device " PCI_PRI_FMT "," 235b762221aSTal Shnaiderman " is unsupported", 236b762221aSTal Shnaiderman dev->addr.domain, dev->addr.bus, 237b762221aSTal Shnaiderman dev->addr.devid, dev->addr.function); 238b762221aSTal Shnaiderman return -1; 239b762221aSTal Shnaiderman } 240b762221aSTal Shnaiderman 241b762221aSTal Shnaiderman return ERROR_SUCCESS; 242b762221aSTal Shnaiderman } 243b762221aSTal Shnaiderman 244b762221aSTal Shnaiderman /* 245b762221aSTal Shnaiderman * get string that contains the list of hardware IDs for a device 246b762221aSTal Shnaiderman */ 247b762221aSTal Shnaiderman static int 248b762221aSTal Shnaiderman get_pci_hardware_id(HDEVINFO dev_info, PSP_DEVINFO_DATA device_info_data, 249b762221aSTal Shnaiderman char *pci_device_info, size_t pci_device_info_len) 250b762221aSTal Shnaiderman { 251b762221aSTal Shnaiderman BOOL res; 252b762221aSTal Shnaiderman 253b762221aSTal Shnaiderman /* Retrieve PCI device IDs */ 254b762221aSTal Shnaiderman res = SetupDiGetDeviceRegistryPropertyA(dev_info, device_info_data, 255b762221aSTal Shnaiderman SPDRP_HARDWAREID, NULL, (BYTE *)pci_device_info, 256b762221aSTal Shnaiderman pci_device_info_len, NULL); 257b762221aSTal Shnaiderman if (!res) { 258b762221aSTal Shnaiderman RTE_LOG_WIN32_ERR( 259b762221aSTal Shnaiderman "SetupDiGetDeviceRegistryPropertyA(SPDRP_HARDWAREID)"); 260b762221aSTal Shnaiderman return -1; 261b762221aSTal Shnaiderman } 262b762221aSTal Shnaiderman 263b762221aSTal Shnaiderman return 0; 264b762221aSTal Shnaiderman } 265b762221aSTal Shnaiderman 266b762221aSTal Shnaiderman /* 267b762221aSTal Shnaiderman * parse the SPDRP_HARDWAREID output and assign to rte_pci_id 268b762221aSTal Shnaiderman */ 269b762221aSTal Shnaiderman static int 270b762221aSTal Shnaiderman parse_pci_hardware_id(const char *buf, struct rte_pci_id *pci_id) 271b762221aSTal Shnaiderman { 272b762221aSTal Shnaiderman int ids = 0; 2732dceae68STal Shnaiderman uint16_t vendor_id, device_id; 2742dceae68STal Shnaiderman uint32_t subvendor_id = 0; 275b762221aSTal Shnaiderman 2762dceae68STal Shnaiderman ids = sscanf_s(buf, "PCI\\VEN_%" PRIx16 "&DEV_%" PRIx16 "&SUBSYS_%" 2772dceae68STal Shnaiderman PRIx32, &vendor_id, &device_id, &subvendor_id); 278b762221aSTal Shnaiderman if (ids != 3) 279b762221aSTal Shnaiderman return -1; 280b762221aSTal Shnaiderman 281b762221aSTal Shnaiderman pci_id->vendor_id = vendor_id; 282b762221aSTal Shnaiderman pci_id->device_id = device_id; 2832dceae68STal Shnaiderman pci_id->subsystem_device_id = subvendor_id >> 16; 2842dceae68STal Shnaiderman pci_id->subsystem_vendor_id = subvendor_id & 0xffff; 285b762221aSTal Shnaiderman return 0; 286b762221aSTal Shnaiderman } 287b762221aSTal Shnaiderman 288b762221aSTal Shnaiderman static void 289b762221aSTal Shnaiderman get_kernel_driver_type(struct rte_pci_device *dev) 290b762221aSTal Shnaiderman { 291b762221aSTal Shnaiderman /* 292b762221aSTal Shnaiderman * If another kernel driver is supported the relevant checking 293b762221aSTal Shnaiderman * functions should be here 294b762221aSTal Shnaiderman */ 2957c0d798aSDavid Marchand dev->kdrv = RTE_PCI_KDRV_NONE; 296b762221aSTal Shnaiderman } 297b762221aSTal Shnaiderman 298b762221aSTal Shnaiderman static int 299b762221aSTal Shnaiderman pci_scan_one(HDEVINFO dev_info, PSP_DEVINFO_DATA device_info_data) 300b762221aSTal Shnaiderman { 301b762221aSTal Shnaiderman struct rte_pci_device *dev; 302b762221aSTal Shnaiderman int ret = -1; 303b762221aSTal Shnaiderman char pci_device_info[PATH_MAX]; 304b762221aSTal Shnaiderman struct rte_pci_addr addr; 305b762221aSTal Shnaiderman struct rte_pci_id pci_id; 306b762221aSTal Shnaiderman 307b762221aSTal Shnaiderman dev = malloc(sizeof(*dev)); 308b762221aSTal Shnaiderman if (dev == NULL) 309b762221aSTal Shnaiderman goto end; 310b762221aSTal Shnaiderman 311b762221aSTal Shnaiderman memset(dev, 0, sizeof(*dev)); 312b762221aSTal Shnaiderman 313b762221aSTal Shnaiderman ret = get_pci_hardware_id(dev_info, device_info_data, 314b762221aSTal Shnaiderman pci_device_info, PATH_MAX); 315b762221aSTal Shnaiderman if (ret != 0) 316b762221aSTal Shnaiderman goto end; 317b762221aSTal Shnaiderman 318b762221aSTal Shnaiderman ret = parse_pci_hardware_id((const char *)&pci_device_info, &pci_id); 319b762221aSTal Shnaiderman if (ret != 0) { 320b762221aSTal Shnaiderman /* 321b762221aSTal Shnaiderman * We won't add this device, but we want to continue 322b762221aSTal Shnaiderman * looking for supported devices 323b762221aSTal Shnaiderman */ 324b762221aSTal Shnaiderman ret = ERROR_CONTINUE; 325b762221aSTal Shnaiderman goto end; 326b762221aSTal Shnaiderman } 327b762221aSTal Shnaiderman 328b762221aSTal Shnaiderman ret = get_device_pci_address(dev_info, device_info_data, &addr); 329b762221aSTal Shnaiderman if (ret != 0) 330b762221aSTal Shnaiderman goto end; 331b762221aSTal Shnaiderman 332b762221aSTal Shnaiderman dev->addr = addr; 333b762221aSTal Shnaiderman dev->id = pci_id; 334b762221aSTal Shnaiderman dev->max_vfs = 0; /* TODO: get max_vfs */ 335b762221aSTal Shnaiderman 336b762221aSTal Shnaiderman pci_name_set(dev); 337b762221aSTal Shnaiderman 338b762221aSTal Shnaiderman get_kernel_driver_type(dev); 339b762221aSTal Shnaiderman 340b762221aSTal Shnaiderman /* get resources */ 341b762221aSTal Shnaiderman if (get_device_resource_info(dev_info, device_info_data, dev) 342b762221aSTal Shnaiderman != ERROR_SUCCESS) { 343b762221aSTal Shnaiderman goto end; 344b762221aSTal Shnaiderman } 345b762221aSTal Shnaiderman 346b762221aSTal Shnaiderman /* device is valid, add in list (sorted) */ 347b762221aSTal Shnaiderman if (TAILQ_EMPTY(&rte_pci_bus.device_list)) { 348b762221aSTal Shnaiderman rte_pci_add_device(dev); 349b762221aSTal Shnaiderman } else { 350b762221aSTal Shnaiderman struct rte_pci_device *dev2 = NULL; 351b762221aSTal Shnaiderman int ret; 352b762221aSTal Shnaiderman 353b762221aSTal Shnaiderman TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) { 354b762221aSTal Shnaiderman ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr); 355b762221aSTal Shnaiderman if (ret > 0) { 356b762221aSTal Shnaiderman continue; 357b762221aSTal Shnaiderman } else if (ret < 0) { 358b762221aSTal Shnaiderman rte_pci_insert_device(dev2, dev); 359b762221aSTal Shnaiderman } else { /* already registered */ 360b762221aSTal Shnaiderman dev2->kdrv = dev->kdrv; 361b762221aSTal Shnaiderman dev2->max_vfs = dev->max_vfs; 362b762221aSTal Shnaiderman memmove(dev2->mem_resource, dev->mem_resource, 363b762221aSTal Shnaiderman sizeof(dev->mem_resource)); 364b762221aSTal Shnaiderman free(dev); 365b762221aSTal Shnaiderman } 366b762221aSTal Shnaiderman return 0; 367b762221aSTal Shnaiderman } 368b762221aSTal Shnaiderman rte_pci_add_device(dev); 369b762221aSTal Shnaiderman } 370b762221aSTal Shnaiderman 371b762221aSTal Shnaiderman return 0; 372b762221aSTal Shnaiderman end: 373b762221aSTal Shnaiderman if (dev) 374b762221aSTal Shnaiderman free(dev); 375b762221aSTal Shnaiderman return ret; 376b762221aSTal Shnaiderman } 377b762221aSTal Shnaiderman 37833031608STal Shnaiderman /* 37933031608STal Shnaiderman * Scan the contents of the PCI bus 38033031608STal Shnaiderman * and add all network class devices into the devices list. 38133031608STal Shnaiderman */ 38233031608STal Shnaiderman int 38333031608STal Shnaiderman rte_pci_scan(void) 38433031608STal Shnaiderman { 385b762221aSTal Shnaiderman int ret = -1; 386b762221aSTal Shnaiderman DWORD device_index = 0, found_device = 0; 387b762221aSTal Shnaiderman HDEVINFO dev_info; 388b762221aSTal Shnaiderman SP_DEVINFO_DATA device_info_data; 389b762221aSTal Shnaiderman 390b762221aSTal Shnaiderman /* for debug purposes, PCI can be disabled */ 391b762221aSTal Shnaiderman if (!rte_eal_has_pci()) 39233031608STal Shnaiderman return 0; 393b762221aSTal Shnaiderman 394b762221aSTal Shnaiderman dev_info = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, TEXT("PCI"), NULL, 395b762221aSTal Shnaiderman DIGCF_PRESENT); 396b762221aSTal Shnaiderman if (dev_info == INVALID_HANDLE_VALUE) { 397b762221aSTal Shnaiderman RTE_LOG_WIN32_ERR("SetupDiGetClassDevs(pci_scan)"); 398b762221aSTal Shnaiderman RTE_LOG(ERR, EAL, "Unable to enumerate PCI devices.\n"); 399b762221aSTal Shnaiderman goto end; 400b762221aSTal Shnaiderman } 401b762221aSTal Shnaiderman 402b762221aSTal Shnaiderman device_info_data.cbSize = sizeof(SP_DEVINFO_DATA); 403b762221aSTal Shnaiderman device_index = 0; 404b762221aSTal Shnaiderman 405b762221aSTal Shnaiderman while (SetupDiEnumDeviceInfo(dev_info, device_index, 406b762221aSTal Shnaiderman &device_info_data)) { 407b762221aSTal Shnaiderman device_index++; 408b762221aSTal Shnaiderman ret = pci_scan_one(dev_info, &device_info_data); 409b762221aSTal Shnaiderman if (ret == ERROR_SUCCESS) 410b762221aSTal Shnaiderman found_device++; 411b762221aSTal Shnaiderman else if (ret != ERROR_CONTINUE) 412b762221aSTal Shnaiderman goto end; 413b762221aSTal Shnaiderman 414b762221aSTal Shnaiderman memset(&device_info_data, 0, sizeof(SP_DEVINFO_DATA)); 415b762221aSTal Shnaiderman device_info_data.cbSize = sizeof(SP_DEVINFO_DATA); 416b762221aSTal Shnaiderman } 417b762221aSTal Shnaiderman 418b762221aSTal Shnaiderman RTE_LOG(DEBUG, EAL, "PCI scan found %lu devices\n", found_device); 419b762221aSTal Shnaiderman ret = 0; 420b762221aSTal Shnaiderman end: 421b762221aSTal Shnaiderman if (dev_info != INVALID_HANDLE_VALUE) 422b762221aSTal Shnaiderman SetupDiDestroyDeviceInfoList(dev_info); 423b762221aSTal Shnaiderman 424b762221aSTal Shnaiderman return ret; 42533031608STal Shnaiderman } 426