1 /* 2 * The PCI Library -- Initialization and related things 3 * 4 * Copyright (c) 1997--2018 Martin Mares <[email protected]> 5 * 6 * Can be freely distributed and used under the terms of the GNU GPL v2+. 7 * 8 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <stdarg.h> 14 #include <string.h> 15 16 #include "internal.h" 17 18 #ifdef PCI_OS_DJGPP 19 #include <crt0.h> /* for __dos_argv0 */ 20 #endif 21 22 #ifdef PCI_OS_WINDOWS 23 24 #include <windows.h> 25 26 /* Force usage of ANSI (char*) variant of GetModuleFileName() function */ 27 #ifdef _WIN32 28 #ifdef GetModuleFileName 29 #undef GetModuleFileName 30 #endif 31 #define GetModuleFileName GetModuleFileNameA 32 #endif 33 34 /* Define __ImageBase for all linkers */ 35 #ifdef _WIN32 36 /* GNU LD provides __ImageBase symbol since 2.19, in previous versions it is 37 * under name _image_base__, so add weak alias for compatibility. */ 38 #ifdef __GNUC__ 39 asm(".weak\t" PCI_STRINGIFY(__MINGW_USYMBOL(__ImageBase)) "\n\t" 40 ".set\t" PCI_STRINGIFY(__MINGW_USYMBOL(__ImageBase)) "," PCI_STRINGIFY(__MINGW_USYMBOL(_image_base__))); 41 #endif 42 /* 43 * MSVC link.exe provides __ImageBase symbol since 12.00 (MSVC 6.0), for 44 * previous versions resolve it at runtime via GetModuleHandleA() which 45 * returns base for main executable or via VirtualQuery() for DLL builds. 46 */ 47 #if defined(_MSC_VER) && _MSC_VER < 1200 48 static HMODULE 49 get_current_module_handle(void) 50 { 51 #ifdef PCI_SHARED_LIB 52 MEMORY_BASIC_INFORMATION info; 53 size_t len = VirtualQuery(&get_current_module_handle, &info, sizeof(info)); 54 if (len != sizeof(info)) 55 return NULL; 56 return (HMODULE)info.AllocationBase; 57 #else 58 return GetModuleHandleA(NULL); 59 #endif 60 } 61 #define __ImageBase (*(IMAGE_DOS_HEADER *)get_current_module_handle()) 62 #else 63 extern IMAGE_DOS_HEADER __ImageBase; 64 #endif 65 #endif 66 67 #if defined(_WINDLL) 68 extern HINSTANCE _hModule; 69 #elif defined(_WINDOWS) 70 extern HINSTANCE _hInstance; 71 #endif 72 73 #endif 74 75 static struct pci_methods *pci_methods[PCI_ACCESS_MAX] = { 76 NULL, 77 #ifdef PCI_HAVE_PM_LINUX_SYSFS 78 &pm_linux_sysfs, 79 #else 80 NULL, 81 #endif 82 #ifdef PCI_HAVE_PM_LINUX_PROC 83 &pm_linux_proc, 84 #else 85 NULL, 86 #endif 87 #ifdef PCI_HAVE_PM_INTEL_CONF 88 &pm_intel_conf1, 89 &pm_intel_conf2, 90 #else 91 NULL, 92 NULL, 93 #endif 94 #ifdef PCI_HAVE_PM_FBSD_DEVICE 95 &pm_fbsd_device, 96 #else 97 NULL, 98 #endif 99 #ifdef PCI_HAVE_PM_AIX_DEVICE 100 &pm_aix_device, 101 #else 102 NULL, 103 #endif 104 #ifdef PCI_HAVE_PM_NBSD_LIBPCI 105 &pm_nbsd_libpci, 106 #else 107 NULL, 108 #endif 109 #ifdef PCI_HAVE_PM_OBSD_DEVICE 110 &pm_obsd_device, 111 #else 112 NULL, 113 #endif 114 #ifdef PCI_HAVE_PM_DUMP 115 &pm_dump, 116 #else 117 NULL, 118 #endif 119 #ifdef PCI_HAVE_PM_DARWIN_DEVICE 120 &pm_darwin, 121 #else 122 NULL, 123 #endif 124 #ifdef PCI_HAVE_PM_SYLIXOS_DEVICE 125 &pm_sylixos_device, 126 #else 127 NULL, 128 #endif 129 #ifdef PCI_HAVE_PM_HURD_CONF 130 &pm_hurd, 131 #else 132 NULL, 133 #endif 134 #ifdef PCI_HAVE_PM_WIN32_CFGMGR32 135 &pm_win32_cfgmgr32, 136 #else 137 NULL, 138 #endif 139 #ifdef PCI_HAVE_PM_WIN32_KLDBG 140 &pm_win32_kldbg, 141 #else 142 NULL, 143 #endif 144 #ifdef PCI_HAVE_PM_WIN32_SYSDBG 145 &pm_win32_sysdbg, 146 #else 147 NULL, 148 #endif 149 #ifdef PCI_HAVE_PM_MMIO_CONF 150 &pm_mmio_conf1, 151 &pm_mmio_conf1_ext, 152 #else 153 NULL, 154 NULL, 155 #endif 156 #if defined(PCI_HAVE_PM_ECAM) 157 &pm_ecam, 158 #else 159 NULL, 160 #endif 161 #if defined(PCI_HAVE_PM_AOS_EXPANSION) 162 &pm_aos_expansion, 163 #else 164 NULL, 165 #endif 166 }; 167 168 // If PCI_ACCESS_AUTO is selected, we probe the access methods in this order 169 static int probe_sequence[] = { 170 // System-specific methods 171 PCI_ACCESS_SYS_BUS_PCI, 172 PCI_ACCESS_PROC_BUS_PCI, 173 PCI_ACCESS_FBSD_DEVICE, 174 PCI_ACCESS_AIX_DEVICE, 175 PCI_ACCESS_NBSD_LIBPCI, 176 PCI_ACCESS_OBSD_DEVICE, 177 PCI_ACCESS_DARWIN, 178 PCI_ACCESS_SYLIXOS_DEVICE, 179 PCI_ACCESS_HURD, 180 PCI_ACCESS_WIN32_CFGMGR32, 181 PCI_ACCESS_WIN32_KLDBG, 182 PCI_ACCESS_WIN32_SYSDBG, 183 PCI_ACCESS_AOS_EXPANSION, 184 // Low-level methods poking the hardware directly 185 PCI_ACCESS_ECAM, 186 PCI_ACCESS_I386_TYPE1, 187 PCI_ACCESS_I386_TYPE2, 188 PCI_ACCESS_MMIO_TYPE1_EXT, 189 PCI_ACCESS_MMIO_TYPE1, 190 -1, 191 }; 192 193 static void PCI_NONRET 194 pci_generic_error(char *msg, ...) 195 { 196 va_list args; 197 198 va_start(args, msg); 199 fputs("pcilib: ", stderr); 200 vfprintf(stderr, msg, args); 201 va_end(args); 202 fputc('\n', stderr); 203 exit(1); 204 } 205 206 static void 207 pci_generic_warn(char *msg, ...) 208 { 209 va_list args; 210 211 va_start(args, msg); 212 fputs("pcilib: ", stderr); 213 vfprintf(stderr, msg, args); 214 va_end(args); 215 fputc('\n', stderr); 216 } 217 218 static void 219 pci_generic_debug(char *msg, ...) 220 { 221 va_list args; 222 223 va_start(args, msg); 224 vfprintf(stdout, msg, args); 225 va_end(args); 226 } 227 228 static void 229 pci_null_debug(char *msg UNUSED, ...) 230 { 231 } 232 233 // Memory allocation functions are safe to call if pci_access is not fully initalized or even NULL 234 235 void * 236 pci_malloc(struct pci_access *a, int size) 237 { 238 void *x = malloc(size); 239 240 if (!x) 241 (a && a->error ? a->error : pci_generic_error)("Out of memory (allocation of %d bytes failed)", size); 242 return x; 243 } 244 245 void 246 pci_mfree(void *x) 247 { 248 if (x) 249 free(x); 250 } 251 252 char * 253 pci_strdup(struct pci_access *a, const char *s) 254 { 255 int len = strlen(s) + 1; 256 char *t = pci_malloc(a, len); 257 memcpy(t, s, len); 258 return t; 259 } 260 261 int 262 pci_lookup_method(char *name) 263 { 264 int i; 265 266 for (i=0; i<PCI_ACCESS_MAX; i++) 267 if (pci_methods[i] && !strcmp(pci_methods[i]->name, name)) 268 return i; 269 return -1; 270 } 271 272 char * 273 pci_get_method_name(int index) 274 { 275 if (index < 0 || index >= PCI_ACCESS_MAX) 276 return NULL; 277 else if (!pci_methods[index]) 278 return ""; 279 else 280 return pci_methods[index]->name; 281 } 282 283 #if defined(PCI_OS_WINDOWS) || defined(PCI_OS_DJGPP) 284 285 static void 286 pci_init_name_list_path(struct pci_access *a) 287 { 288 if ((PCI_PATH_IDS_DIR)[0]) 289 pci_set_name_list_path(a, PCI_PATH_IDS_DIR "\\" PCI_IDS, 0); 290 else 291 { 292 char *path, *sep; 293 size_t len; 294 295 #if defined(PCI_OS_WINDOWS) && (defined(_WIN32) || defined(_WINDLL) || defined(_WINDOWS)) 296 297 HMODULE module; 298 size_t size; 299 300 #if defined(_WIN32) 301 module = (HINSTANCE)&__ImageBase; 302 #elif defined(_WINDLL) 303 module = _hModule; 304 #elif defined(_WINDOWS) 305 module = _hInstance; 306 #endif 307 308 /* 309 * Module file name can have arbitrary length despite all MS examples say 310 * about MAX_PATH upper limit. This limit does not apply for example when 311 * executable is running from network disk with very long UNC paths or 312 * when using "\\??\\" prefix for specifying executable binary path. 313 * Function GetModuleFileName() returns passed size argument when passed 314 * buffer is too small and does not signal any error. In this case retry 315 * again with larger buffer. 316 */ 317 size = 256; /* initial buffer size (more than sizeof(PCI_IDS)-4) */ 318 retry: 319 path = pci_malloc(a, size); 320 len = GetModuleFileName(module, path, size-sizeof(PCI_IDS)-4); /* 4 for "\\\\?\\" */ 321 if (len >= size-sizeof(PCI_IDS)-4) 322 { 323 free(path); 324 size *= 2; 325 goto retry; 326 } 327 else if (len == 0) 328 path[0] = '\0'; 329 330 /* 331 * GetModuleFileName() has bugs. On Windows 10 it prepends current drive 332 * letter if path is just pure NT namespace (with "\\??\\" prefix). Such 333 * extra drive letter makes path fully invalid and unusable. So remove 334 * extra drive letter to make path valid again. 335 * Reproduce: CreateProcessW("\\??\\C:\\lspci.exe", ...) 336 */ 337 if (((path[0] >= 'a' && path[0] <= 'z') || 338 (path[0] >= 'A' && path[0] <= 'Z')) && 339 strncmp(path+1, ":\\??\\", 5) == 0) 340 { 341 memmove(path, path+2, len-2); 342 len -= 2; 343 path[len] = '\0'; 344 } 345 346 /* 347 * GetModuleFileName() has bugs. On Windows 10 it does not add "\\\\?\\" 348 * prefix when path is in native NT UNC namespace. Such path is treated by 349 * WinAPI/DOS functions as standard DOS path relative to the current 350 * directory, hence something completely different. So prepend missing 351 * "\\\\?\\" prefix to make path valid again. 352 * Reproduce: CreateProcessW("\\??\\UNC\\10.0.2.4\\qemu\\lspci.exe", ...) 353 * 354 * If path starts with DOS drive letter and with appended PCI_IDS is 355 * longer than 260 bytes and is without "\\\\?\\" prefix then append it. 356 * This prefix is required for paths and file names with DOS drive letter 357 * longer than 260 bytes. 358 */ 359 if (strncmp(path, "\\UNC\\", 5) == 0 || 360 strncmp(path, "UNC\\", 4) == 0 || 361 (((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z')) && 362 len + sizeof(PCI_IDS) >= 260)) 363 { 364 memmove(path+4, path, len); 365 memcpy(path, "\\\\?\\", 4); 366 len += 4; 367 path[len] = '\0'; 368 } 369 370 #elif defined(PCI_OS_DJGPP) || defined(PCI_OS_WINDOWS) 371 372 const char *exe_path; 373 374 #ifdef PCI_OS_DJGPP 375 exe_path = __dos_argv0; 376 #else 377 exe_path = _pgmptr; 378 #endif 379 380 len = strlen(exe_path); 381 path = pci_malloc(a, len+sizeof(PCI_IDS)); 382 memcpy(path, exe_path, len+1); 383 384 #endif 385 386 sep = strrchr(path, '\\'); 387 if (!sep) 388 { 389 /* 390 * If current module path (current executable for static builds or 391 * current DLL library for shared build) cannot be determined then 392 * fallback to the current directory. 393 */ 394 free(path); 395 pci_set_name_list_path(a, PCI_IDS, 0); 396 } 397 else 398 { 399 memcpy(sep+1, PCI_IDS, sizeof(PCI_IDS)); 400 pci_set_name_list_path(a, path, 1); 401 } 402 } 403 404 #elif defined PCI_OS_AMIGAOS 405 406 static void 407 pci_init_name_list_path(struct pci_access *a) 408 { 409 int len = strlen(PCI_PATH_IDS_DIR); 410 411 if (!len) 412 pci_set_name_list_path(a, PCI_IDS, 0); 413 else 414 { 415 char last_char = PCI_PATH_IDS_DIR[len - 1]; 416 if (last_char == ':' || last_char == '/') // root or parent char 417 pci_set_name_list_path(a, PCI_PATH_IDS_DIR PCI_IDS, 0); 418 else 419 pci_set_name_list_path(a, PCI_PATH_IDS_DIR "/" PCI_IDS, 0); 420 } 421 } 422 423 #else 424 425 static void 426 pci_init_name_list_path(struct pci_access *a) 427 { 428 pci_set_name_list_path(a, PCI_PATH_IDS_DIR "/" PCI_IDS, 0); 429 } 430 431 #endif 432 433 struct pci_access * 434 pci_alloc(void) 435 { 436 struct pci_access *a = pci_malloc(NULL, sizeof(struct pci_access)); 437 int i; 438 439 memset(a, 0, sizeof(*a)); 440 pci_init_name_list_path(a); 441 #ifdef PCI_USE_DNS 442 pci_define_param(a, "net.domain", PCI_ID_DOMAIN, "DNS domain used for resolving of ID's"); 443 pci_define_param(a, "net.cache_name", "~/.pciids-cache", "Name of the ID cache file"); 444 a->id_lookup_mode = PCI_LOOKUP_CACHE; 445 #endif 446 #ifdef PCI_HAVE_HWDB 447 pci_define_param(a, "hwdb.disable", "0", "Do not look up names in UDEV's HWDB if non-zero"); 448 #endif 449 for (i=0; i<PCI_ACCESS_MAX; i++) 450 if (pci_methods[i] && pci_methods[i]->config) 451 pci_methods[i]->config(a); 452 return a; 453 } 454 455 int 456 pci_init_internal(struct pci_access *a, int skip_method) 457 { 458 if (!a->error) 459 a->error = pci_generic_error; 460 if (!a->warning) 461 a->warning = pci_generic_warn; 462 if (!a->debug) 463 a->debug = pci_generic_debug; 464 if (!a->debugging) 465 a->debug = pci_null_debug; 466 467 if (a->method != PCI_ACCESS_AUTO) 468 { 469 if (a->method >= PCI_ACCESS_MAX || !pci_methods[a->method]) 470 a->error("This access method is not supported."); 471 a->methods = pci_methods[a->method]; 472 } 473 else 474 { 475 unsigned int i; 476 for (i=0; probe_sequence[i] >= 0; i++) 477 { 478 struct pci_methods *m = pci_methods[probe_sequence[i]]; 479 if (!m) 480 continue; 481 if (skip_method == probe_sequence[i]) 482 continue; 483 a->debug("Trying method %s...", m->name); 484 if (m->detect(a)) 485 { 486 a->debug("...OK\n"); 487 a->methods = m; 488 a->method = probe_sequence[i]; 489 break; 490 } 491 a->debug("...No.\n"); 492 } 493 if (!a->methods) 494 return 0; 495 } 496 a->debug("Decided to use %s\n", a->methods->name); 497 a->methods->init(a); 498 return 1; 499 } 500 501 void 502 pci_init_v35(struct pci_access *a) 503 { 504 if (!pci_init_internal(a, -1)) 505 a->error("Cannot find any working access method."); 506 } 507 508 STATIC_ALIAS(void pci_init(struct pci_access *a), pci_init_v35(a)); 509 DEFINE_ALIAS(void pci_init_v30(struct pci_access *a), pci_init_v35); 510 SYMBOL_VERSION(pci_init_v30, pci_init@LIBPCI_3.0); 511 SYMBOL_VERSION(pci_init_v35, pci_init@@LIBPCI_3.5); 512 513 struct pci_access * 514 pci_clone_access(struct pci_access *a) 515 { 516 struct pci_access *b = pci_alloc(); 517 518 b->writeable = a->writeable; 519 b->buscentric = a->buscentric; 520 b->debugging = a->debugging; 521 b->error = a->error; 522 b->warning = a->warning; 523 b->debug = a->debug; 524 525 return b; 526 } 527 528 void 529 pci_cleanup(struct pci_access *a) 530 { 531 struct pci_dev *d, *e; 532 533 for (d=a->devices; d; d=e) 534 { 535 e = d->next; 536 pci_free_dev(d); 537 } 538 if (a->methods) 539 a->methods->cleanup(a); 540 pci_free_name_list(a); 541 pci_free_params(a); 542 pci_set_name_list_path(a, NULL, 0); 543 pci_mfree(a); 544 } 545