bus/pci: ignore missing NUMA node on Windows
[dpdk.git] / drivers / bus / pci / windows / pci_netuio.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation.
3  */
4
5 #include <rte_windows.h>
6 #include <rte_errno.h>
7 #include <rte_log.h>
8 #include <rte_eal.h>
9
10 #include "private.h"
11 #include "pci_netuio.h"
12
13 static int
14 send_ioctl(HANDLE f, DWORD ioctl,
15         void *in_buf, DWORD in_buf_size, void *out_buf, DWORD out_buf_size)
16 {
17         BOOL res;
18         DWORD bytes_ret = 0;
19
20         res = DeviceIoControl(f, ioctl, in_buf, in_buf_size,
21                 out_buf, out_buf_size, &bytes_ret, NULL);
22         if (!res) {
23                 RTE_LOG_WIN32_ERR("DeviceIoControl:IOCTL query failed");
24                 return -1;
25         }
26
27         return ERROR_SUCCESS;
28 }
29
30 static HDEVINFO
31 get_netuio_device_information_set(HDEVINFO dev_info,
32         PSP_DEVINFO_DATA dev_info_data)
33 {
34         BOOL res;
35         DWORD required_size = 0;
36         TCHAR dev_instance_id[MAX_DEVICENAME_SZ];
37         HDEVINFO di_set = INVALID_HANDLE_VALUE;
38
39         /* obtain the driver interface for this device */
40         res = SetupDiGetDeviceInstanceId(dev_info, dev_info_data,
41                 dev_instance_id, sizeof(dev_instance_id), &required_size);
42         if (!res) {
43                 RTE_LOG_WIN32_ERR("SetupDiGetDeviceInstanceId");
44                 goto end;
45         }
46
47         /* return the device information set for this device */
48         di_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_NETUIO,
49                 dev_instance_id, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
50         if (di_set == INVALID_HANDLE_VALUE) {
51                 RTE_LOG_WIN32_ERR("SetupDiGetClassDevs(device information set)");
52                 goto end;
53         }
54 end:
55         return di_set;
56 }
57
58 static PSP_DEVICE_INTERFACE_DETAIL_DATA
59 get_netuio_device_interface_detail(HDEVINFO di_set)
60 {
61         BOOL res;
62         DWORD required_size = 0;
63         SP_DEVICE_INTERFACE_DATA  dev_ifx_data = { 0 };
64         PSP_DEVICE_INTERFACE_DETAIL_DATA dev_ifx_detail = NULL;
65
66         dev_ifx_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
67
68         /* enumerate the netUIO interfaces for this device information set */
69         res = SetupDiEnumDeviceInterfaces(di_set, 0, &GUID_DEVINTERFACE_NETUIO,
70                 0, &dev_ifx_data);
71         if (!res) {
72                 RTE_LOG_WIN32_ERR("SetupDiEnumDeviceInterfaces: no device interface");
73                 goto end;
74         }
75
76         /* request and allocate required size for the device interface detail */
77         required_size = 0;
78         res = SetupDiGetDeviceInterfaceDetail(di_set, &dev_ifx_data, NULL, 0,
79                 &required_size, NULL);
80         if (!res) {
81                 /* ERROR_INSUFFICIENT_BUFFER is expected */
82                 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
83                         RTE_LOG_WIN32_ERR("SetupDiGetDeviceInterfaceDetail");
84                         goto end;
85                 }
86         }
87
88         dev_ifx_detail = malloc(required_size);
89         if (!dev_ifx_detail) {
90                 RTE_LOG(ERR, EAL, "Could not allocate memory for dev interface.\n");
91                 goto end;
92         }
93         dev_ifx_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
94
95         res = SetupDiGetDeviceInterfaceDetail(di_set, &dev_ifx_data,
96                 dev_ifx_detail, required_size, NULL, NULL);
97         if (!res) {
98                 RTE_LOG_WIN32_ERR("SetupDiGetDeviceInterfaceDetail");
99                 free(dev_ifx_detail);
100                 dev_ifx_detail = NULL;
101                 goto end;
102         }
103
104 end:
105         return dev_ifx_detail;
106 }
107
108 /*
109  * get device resource information by sending ioctl to netuio driver
110  */
111 int
112 get_netuio_device_info(HDEVINFO dev_info, PSP_DEVINFO_DATA dev_info_data,
113         struct rte_pci_device *dev)
114 {
115         int ret = -1;
116         HDEVINFO di_set = INVALID_HANDLE_VALUE;
117         PSP_DEVICE_INTERFACE_DETAIL_DATA dev_ifx_detail = NULL;
118         HANDLE netuio = INVALID_HANDLE_VALUE;
119         struct device_info hw_info = { 0 };
120         unsigned int idx;
121
122         /* obtain the device information set for this device */
123         di_set = get_netuio_device_information_set(dev_info, dev_info_data);
124         if (di_set == INVALID_HANDLE_VALUE)
125                 goto end;
126
127         /* obtain the device interface detail for this device */
128         dev_ifx_detail = get_netuio_device_interface_detail(di_set);
129         if (!dev_ifx_detail)
130                 goto end;
131
132         /* open the kernel driver */
133         netuio = CreateFile(dev_ifx_detail->DevicePath,
134                 GENERIC_READ | GENERIC_WRITE,
135                 FILE_SHARE_READ | FILE_SHARE_WRITE,
136                 NULL,
137                 OPEN_EXISTING,
138                 FILE_ATTRIBUTE_NORMAL,
139                 NULL);
140         if (netuio == INVALID_HANDLE_VALUE) {
141                 RTE_LOG_WIN32_ERR("CreateFile");
142                 RTE_LOG(ERR, EAL, "Unable to open driver file \"%s\".\n",
143                         dev_ifx_detail->DevicePath);
144                 goto end;
145         }
146
147         /* send ioctl to retrieve device information */
148         if (send_ioctl(netuio, IOCTL_NETUIO_MAP_HW_INTO_USERSPACE, NULL, 0,
149                 &hw_info, sizeof(hw_info)) != ERROR_SUCCESS) {
150                 RTE_LOG(ERR, EAL, "Unable to send ioctl to driver.\n");
151                 goto end;
152         }
153
154         /* set relevant values into the dev structure */
155         for (idx = 0; idx < PCI_MAX_RESOURCE; idx++) {
156                 dev->mem_resource[idx].phys_addr =
157                     hw_info.hw[idx].phys_addr.QuadPart;
158                 dev->mem_resource[idx].addr =
159                     hw_info.hw[idx].user_mapped_virt_addr;
160                 dev->mem_resource[idx].len = hw_info.hw[idx].size;
161         }
162
163         ret = ERROR_SUCCESS;
164 end:
165         if (ret != ERROR_SUCCESS) {
166                 /* Only close the handle to the driver in case of an error.
167                  * Otherwise, we want to keep the handle open. Closing it
168                  * here will cause the driver to unmap all the process-mapped
169                  * values resulting in invalid addresses.
170                  */
171                 if (netuio != INVALID_HANDLE_VALUE)
172                         CloseHandle(netuio);
173         }
174
175         if (dev_ifx_detail)
176                 free(dev_ifx_detail);
177
178         if (di_set != INVALID_HANDLE_VALUE)
179                 SetupDiDestroyDeviceInfoList(di_set);
180
181         return ret;
182 }