]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - ls-kernel.c
2 * The PCI Utilities -- Show Kernel Drivers
4 * Copyright (c) 1997--2013 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
16 #include <sys/utsname.h>
18 #ifdef PCI_USE_LIBKMOD
22 static struct kmod_ctx
*kmod_ctx
;
25 show_kernel_init(void)
27 static int show_kernel_inited
= -1;
28 if (show_kernel_inited
>= 0)
29 return show_kernel_inited
;
31 kmod_ctx
= kmod_new(NULL
, NULL
);
34 fprintf(stderr
, "lspci: Unable to initialize libkmod context\n");
39 if ((err
= kmod_load_resources(kmod_ctx
)) < 0)
41 fprintf(stderr
, "lspci: Unable to load libkmod resources: error %d\n", err
);
45 show_kernel_inited
= 1;
49 show_kernel_inited
= 0;
54 show_kernel_cleanup(void)
60 static const char *next_module(struct device
*d
)
62 static struct kmod_list
*klist
, *kcurrent
;
63 static struct kmod_module
*kmodule
;
67 kmod_module_unref(kmodule
);
73 pci_fill_info(d
->dev
, PCI_FILL_MODULE_ALIAS
);
74 if (!d
->dev
->module_alias
)
76 int err
= kmod_module_new_from_lookup(kmod_ctx
, d
->dev
->module_alias
, &klist
);
79 fprintf(stderr
, "lspci: libkmod lookup failed: error %d\n", err
);
85 kcurrent
= kmod_list_next(klist
, kcurrent
);
89 kmodule
= kmod_module_get_module(kcurrent
);
90 return kmod_module_get_name(kmodule
);
93 kmod_module_unref_list(klist
);
100 struct pcimap_entry
{
101 struct pcimap_entry
*next
;
102 unsigned int vendor
, device
;
103 unsigned int subvendor
, subdevice
;
104 unsigned int class, class_mask
;
108 static struct pcimap_entry
*pcimap_head
;
111 show_kernel_init(void)
113 static int tried_pcimap
;
115 char *name
, line
[1024];
122 if (name
= opt_pcimap
)
124 f
= fopen(name
, "r");
126 die("Cannot open pcimap file %s: %m", name
);
131 die("uname() failed: %m");
132 name
= alloca(64 + strlen(uts
.release
));
133 sprintf(name
, "/lib/modules/%s/modules.pcimap", uts
.release
);
134 f
= fopen(name
, "r");
139 while (fgets(line
, sizeof(line
), f
))
141 char *c
= strchr(line
, '\n');
142 struct pcimap_entry
*e
;
145 die("Unterminated or too long line in %s", name
);
147 if (!line
[0] || line
[0] == '#')
151 while (*c
&& *c
!= ' ' && *c
!= '\t')
154 continue; /* FIXME: Emit warnings! */
157 e
= xmalloc(sizeof(*e
) + strlen(line
));
158 if (sscanf(c
, "%i%i%i%i%i%i",
159 &e
->vendor
, &e
->device
,
160 &e
->subvendor
, &e
->subdevice
,
161 &e
->class, &e
->class_mask
) != 6)
163 e
->next
= pcimap_head
;
165 strcpy(e
->module
, line
);
173 match_pcimap(struct device
*d
, struct pcimap_entry
*e
)
175 struct pci_dev
*dev
= d
->dev
;
176 unsigned int class = (((unsigned int)dev
->device_class
<< 8) | dev
->prog_if
);
178 #define MATCH(x, y) ((y) > 0xffff || (x) == (y))
180 MATCH(dev
->vendor_id
, e
->vendor
) &&
181 MATCH(dev
->device_id
, e
->device
) &&
182 MATCH(dev
->subsys_vendor_id
, e
->subvendor
) &&
183 MATCH(dev
->subsys_id
, e
->subdevice
) &&
184 (class & e
->class_mask
) == e
->class;
188 static const char *next_module(struct device
*d
)
190 static struct pcimap_entry
*current
;
193 current
= pcimap_head
;
195 current
= current
->next
;
199 if (match_pcimap(d
, current
))
200 return current
->module
;
201 current
= current
->next
;
208 show_kernel_cleanup(void)
215 next_module_filtered(struct device
*d
)
217 static char prev_module
[256];
220 while (module
= next_module(d
))
222 if (strcmp(module
, prev_module
))
224 strncpy(prev_module
, module
, sizeof(prev_module
));
225 prev_module
[sizeof(prev_module
) - 1] = 0;
234 show_kernel(struct device
*d
)
236 const char *driver
, *module
;
238 pci_fill_info(d
->dev
, PCI_FILL_DRIVER
);
239 if (driver
= pci_get_string_property(d
->dev
, PCI_FILL_DRIVER
))
240 printf("\tKernel driver in use: %s\n", driver
);
242 if (!show_kernel_init())
246 while (module
= next_module_filtered(d
))
247 printf("%s %s", (cnt
++ ? "," : "\tKernel modules:"), module
);
253 show_kernel_machine(struct device
*d
)
255 const char *driver
, *module
;
257 pci_fill_info(d
->dev
, PCI_FILL_DRIVER
);
258 if (driver
= pci_get_string_property(d
->dev
, PCI_FILL_DRIVER
))
259 printf("Driver:\t%s\n", driver
);
261 if (!show_kernel_init())
264 while (module
= next_module_filtered(d
))
265 printf("Module:\t%s\n", module
);
271 show_kernel(struct device
*d
)
275 pci_fill_info(d
->dev
, PCI_FILL_DRIVER
);
276 if (driver
= pci_get_string_property(d
->dev
, PCI_FILL_DRIVER
))
277 printf("\tDriver in use: %s\n", driver
);
281 show_kernel_machine(struct device
*d
)
285 pci_fill_info(d
->dev
, PCI_FILL_DRIVER
);
286 if (driver
= pci_get_string_property(d
->dev
, PCI_FILL_DRIVER
))
287 printf("Driver:\t%s\n", driver
);
291 show_kernel_cleanup(void)