2 * The PCI Library -- Initialization and related things
4 * Copyright (c) 1997--2018 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
20 static struct pci_methods
*pci_methods
[PCI_ACCESS_MAX
] = {
22 #ifdef PCI_HAVE_PM_LINUX_SYSFS
27 #ifdef PCI_HAVE_PM_LINUX_PROC
32 #ifdef PCI_HAVE_PM_INTEL_CONF
39 #ifdef PCI_HAVE_PM_FBSD_DEVICE
44 #ifdef PCI_HAVE_PM_AIX_DEVICE
49 #ifdef PCI_HAVE_PM_NBSD_LIBPCI
54 #ifdef PCI_HAVE_PM_OBSD_DEVICE
59 #ifdef PCI_HAVE_PM_DUMP
64 #ifdef PCI_HAVE_PM_DARWIN_DEVICE
69 #ifdef PCI_HAVE_PM_SYLIXOS_DEVICE
74 #ifdef PCI_HAVE_PM_HURD_CONF
81 // If PCI_ACCESS_AUTO is selected, we probe the access methods in this order
82 static int probe_sequence
[] = {
83 // System-specific methods
84 PCI_ACCESS_SYS_BUS_PCI
,
85 PCI_ACCESS_PROC_BUS_PCI
,
86 PCI_ACCESS_FBSD_DEVICE
,
87 PCI_ACCESS_AIX_DEVICE
,
88 PCI_ACCESS_NBSD_LIBPCI
,
89 PCI_ACCESS_OBSD_DEVICE
,
91 PCI_ACCESS_SYLIXOS_DEVICE
,
93 // Low-level methods poking the hardware directly
94 PCI_ACCESS_I386_TYPE1
,
95 PCI_ACCESS_I386_TYPE2
,
99 static void PCI_NONRET
100 pci_generic_error(char *msg
, ...)
105 fputs("pcilib: ", stderr
);
106 vfprintf(stderr
, msg
, args
);
113 pci_generic_warn(char *msg
, ...)
118 fputs("pcilib: ", stderr
);
119 vfprintf(stderr
, msg
, args
);
125 pci_generic_debug(char *msg
, ...)
130 vfprintf(stdout
, msg
, args
);
135 pci_null_debug(char *msg UNUSED
, ...)
139 // Memory allocation functions are safe to call if pci_access is not fully initalized or even NULL
142 pci_malloc(struct pci_access
*a
, int size
)
144 void *x
= malloc(size
);
147 (a
&& a
->error
? a
->error
: pci_generic_error
)("Out of memory (allocation of %d bytes failed)", size
);
159 pci_strdup(struct pci_access
*a
, const char *s
)
161 int len
= strlen(s
) + 1;
162 char *t
= pci_malloc(a
, len
);
168 pci_lookup_method(char *name
)
172 for (i
=0; i
<PCI_ACCESS_MAX
; i
++)
173 if (pci_methods
[i
] && !strcmp(pci_methods
[i
]->name
, name
))
179 pci_get_method_name(int index
)
181 if (index
< 0 || index
>= PCI_ACCESS_MAX
)
183 else if (!pci_methods
[index
])
186 return pci_methods
[index
]->name
;
189 #ifdef PCI_OS_WINDOWS
192 pci_init_name_list_path(struct pci_access
*a
)
194 if ((PCI_PATH_IDS_DIR
)[0])
195 pci_set_name_list_path(a
, PCI_PATH_IDS_DIR
"\\" PCI_IDS
, 0);
201 path
= pci_malloc(a
, MAX_PATH
+1);
202 len
= GetModuleFileNameA(NULL
, path
, MAX_PATH
+1);
203 sep
= (len
> 0) ? strrchr(path
, '\\') : NULL
;
204 if (len
== 0 || len
== MAX_PATH
+1 || !sep
|| MAX_PATH
-(size_t)(sep
+1-path
) < sizeof(PCI_IDS
))
208 memcpy(sep
+1, PCI_IDS
, sizeof(PCI_IDS
));
209 pci_set_name_list_path(a
, path
, 1);
217 pci_init_name_list_path(struct pci_access
*a
)
219 pci_set_name_list_path(a
, PCI_PATH_IDS_DIR
"/" PCI_IDS
, 0);
227 struct pci_access
*a
= pci_malloc(NULL
, sizeof(struct pci_access
));
230 memset(a
, 0, sizeof(*a
));
231 pci_init_name_list_path(a
);
233 pci_define_param(a
, "net.domain", PCI_ID_DOMAIN
, "DNS domain used for resolving of ID's");
234 pci_define_param(a
, "net.cache_name", "~/.pciids-cache", "Name of the ID cache file");
235 a
->id_lookup_mode
= PCI_LOOKUP_CACHE
;
238 pci_define_param(a
, "hwdb.disable", "0", "Do not look up names in UDEV's HWDB if non-zero");
240 for (i
=0; i
<PCI_ACCESS_MAX
; i
++)
241 if (pci_methods
[i
] && pci_methods
[i
]->config
)
242 pci_methods
[i
]->config(a
);
247 pci_init_v35(struct pci_access
*a
)
250 a
->error
= pci_generic_error
;
252 a
->warning
= pci_generic_warn
;
254 a
->debug
= pci_generic_debug
;
256 a
->debug
= pci_null_debug
;
260 if (a
->method
>= PCI_ACCESS_MAX
|| !pci_methods
[a
->method
])
261 a
->error("This access method is not supported.");
262 a
->methods
= pci_methods
[a
->method
];
267 for (i
=0; probe_sequence
[i
] >= 0; i
++)
269 struct pci_methods
*m
= pci_methods
[probe_sequence
[i
]];
272 a
->debug("Trying method %s...", m
->name
);
277 a
->method
= probe_sequence
[i
];
280 a
->debug("...No.\n");
283 a
->error("Cannot find any working access method.");
285 a
->debug("Decided to use %s\n", a
->methods
->name
);
289 STATIC_ALIAS(void pci_init(struct pci_access
*a
), pci_init_v35(a
));
290 DEFINE_ALIAS(void pci_init_v30(struct pci_access
*a
), pci_init_v35
);
291 SYMBOL_VERSION(pci_init_v30
, pci_init@LIBPCI_3
.0
);
292 SYMBOL_VERSION(pci_init_v35
, pci_init@@LIBPCI_3
.5
);
295 pci_cleanup(struct pci_access
*a
)
297 struct pci_dev
*d
, *e
;
299 for (d
=a
->devices
; d
; d
=e
)
305 a
->methods
->cleanup(a
);
306 pci_free_name_list(a
);
308 pci_set_name_list_path(a
, NULL
, 0);