]> git.ipfire.org Git - thirdparty/pciutils.git/blame - lib/init.c
Settings of the resolving and caching mechanism are now passed as parameters.
[thirdparty/pciutils.git] / lib / init.c
CommitLineData
4dd39346
MM
1/*
2 * The PCI Library -- Initialization and related things
3 *
4 * Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <stdarg.h>
12#include <string.h>
13
14#include "internal.h"
15
16static struct pci_methods *pci_methods[PCI_ACCESS_MAX] = {
17 NULL,
18#ifdef PCI_HAVE_PM_LINUX_SYSFS
19 &pm_linux_sysfs,
20#else
21 NULL,
22#endif
23#ifdef PCI_HAVE_PM_LINUX_PROC
24 &pm_linux_proc,
25#else
26 NULL,
27#endif
28#ifdef PCI_HAVE_PM_INTEL_CONF
29 &pm_intel_conf1,
30 &pm_intel_conf2,
31#else
32 NULL,
33 NULL,
34#endif
35#ifdef PCI_HAVE_PM_FBSD_DEVICE
36 &pm_fbsd_device,
37#else
38 NULL,
39#endif
40#ifdef PCI_HAVE_PM_AIX_DEVICE
41 &pm_aix_device,
42#else
43 NULL,
44#endif
45#ifdef PCI_HAVE_PM_NBSD_LIBPCI
46 &pm_nbsd_libpci,
47#else
48 NULL,
49#endif
50#ifdef PCI_HAVE_PM_OBSD_DEVICE
51 &pm_obsd_device,
52#else
53 NULL,
54#endif
55#ifdef PCI_HAVE_PM_DUMP
56 &pm_dump,
57#else
58 NULL,
59#endif
60};
61
62struct pci_access *
63pci_alloc(void)
64{
65 struct pci_access *a = malloc(sizeof(struct pci_access));
66 int i;
67
68 memset(a, 0, sizeof(*a));
69 pci_set_name_list_path(a, PCI_PATH_IDS_DIR "/" PCI_IDS, 0);
98ccf6d6
MM
70#ifdef PCI_USE_DNS
71 pci_define_param(a, "net.domain", PCI_ID_DOMAIN);
72 pci_define_param(a, "net.cache_path", "~/.pciids-cache");
4dd39346 73 a->id_lookup_mode = PCI_LOOKUP_CACHE;
98ccf6d6 74#endif
4dd39346
MM
75 for(i=0; i<PCI_ACCESS_MAX; i++)
76 if (pci_methods[i] && pci_methods[i]->config)
77 pci_methods[i]->config(a);
78 return a;
79}
80
81void *
82pci_malloc(struct pci_access *a, int size)
83{
84 void *x = malloc(size);
85
86 if (!x)
87 a->error("Out of memory (allocation of %d bytes failed)", size);
88 return x;
89}
90
91void
92pci_mfree(void *x)
93{
94 if (x)
95 free(x);
96}
97
fa182368
MM
98char *
99pci_strdup(struct pci_access *a, char *s)
100{
101 int len = strlen(s) + 1;
102 char *t = pci_malloc(a, len);
103 memcpy(t, s, len);
104 return t;
105}
106
4dd39346
MM
107static void
108pci_generic_error(char *msg, ...)
109{
110 va_list args;
111
112 va_start(args, msg);
113 fputs("pcilib: ", stderr);
114 vfprintf(stderr, msg, args);
115 fputc('\n', stderr);
116 exit(1);
117}
118
119static void
120pci_generic_warn(char *msg, ...)
121{
122 va_list args;
123
124 va_start(args, msg);
125 fputs("pcilib: ", stderr);
126 vfprintf(stderr, msg, args);
127 fputc('\n', stderr);
128}
129
130static void
131pci_generic_debug(char *msg, ...)
132{
133 va_list args;
134
135 va_start(args, msg);
136 vfprintf(stdout, msg, args);
137 va_end(args);
138}
139
140static void
141pci_null_debug(char *msg UNUSED, ...)
142{
143}
144
fa182368
MM
145char *
146pci_get_param(struct pci_access *acc, char *param)
147{
148 struct pci_param *p;
149
150 for (p=acc->params; p; p=p->next)
151 if (!strcmp(p->param, param))
152 return p->value;
153 return NULL;
154}
155
156void
157pci_define_param(struct pci_access *acc, char *param, char *value)
158{
159 struct pci_param *p = pci_malloc(acc, sizeof(*p));
160
161 p->next = acc->params;
162 acc->params = p;
163 p->param = param;
164 p->value = value;
165 p->value_malloced = 0;
166}
167
168int
98ccf6d6 169pci_set_param_internal(struct pci_access *acc, char *param, char *value, int copy)
fa182368
MM
170{
171 struct pci_param *p;
172
173 for (p=acc->params; p; p=p->next)
174 if (!strcmp(p->param, param))
175 {
176 if (p->value_malloced)
177 pci_mfree(p->value);
98ccf6d6
MM
178 p->value_malloced = copy;
179 if (copy)
180 p->value = pci_strdup(acc, value);
181 else
182 p->value = value;
fa182368
MM
183 return 0;
184 }
185 return -1;
186}
187
98ccf6d6
MM
188int
189pci_set_param(struct pci_access *acc, char *param, char *value)
190{
191 return pci_set_param_internal(acc, param, value, 1);
192}
193
fa182368
MM
194static void
195pci_free_params(struct pci_access *acc)
196{
197 struct pci_param *p;
198
199 while (p = acc->params)
200 {
201 acc->params = p->next;
202 if (p->value_malloced)
203 pci_mfree(p->value);
204 pci_mfree(p);
205 }
206}
207
208struct pci_param *
209pci_walk_params(struct pci_access *acc, struct pci_param *prev)
210{
211 /* So far, the params form a simple linked list, but this can change in the future */
212 if (!prev)
213 return acc->params;
214 else
215 return prev->next;
216}
217
4dd39346
MM
218void
219pci_init(struct pci_access *a)
220{
221 if (!a->error)
222 a->error = pci_generic_error;
223 if (!a->warning)
224 a->warning = pci_generic_warn;
225 if (!a->debug)
226 a->debug = pci_generic_debug;
227 if (!a->debugging)
228 a->debug = pci_null_debug;
229
230 if (a->method)
231 {
232 if (a->method >= PCI_ACCESS_MAX || !pci_methods[a->method])
233 a->error("This access method is not supported.");
234 a->methods = pci_methods[a->method];
235 }
236 else
237 {
238 unsigned int i;
239 for(i=0; i<PCI_ACCESS_MAX; i++)
240 if (pci_methods[i])
241 {
242 a->debug("Trying method %d...", i);
243 if (pci_methods[i]->detect(a))
244 {
245 a->debug("...OK\n");
246 a->methods = pci_methods[i];
247 a->method = i;
248 break;
249 }
250 a->debug("...No.\n");
251 }
252 if (!a->methods)
253 a->error("Cannot find any working access method.");
254 }
255 a->debug("Decided to use %s\n", a->methods->name);
256 a->methods->init(a);
257}
258
259void
260pci_cleanup(struct pci_access *a)
261{
262 struct pci_dev *d, *e;
263
264 for(d=a->devices; d; d=e)
265 {
266 e = d->next;
267 pci_free_dev(d);
268 }
269 if (a->methods)
270 a->methods->cleanup(a);
271 pci_free_name_list(a);
fa182368 272 pci_free_params(a);
4dd39346 273 pci_set_name_list_path(a, NULL, 0);
4dd39346
MM
274 pci_mfree(a);
275}