X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ls-kernel.c;h=c939c52867e61ac76c67fddd12dcc7b043bc328f;hb=7ec58f1c9dc011f334863e07917e349d95748d51;hp=15aa46ac083da890f5572998b2d9c989b411b546;hpb=17ec7e70ea71a3ccbccf9f3b9cfe846eb1200e0d;p=pciutils.git diff --git a/ls-kernel.c b/ls-kernel.c index 15aa46a..c939c52 100644 --- a/ls-kernel.c +++ b/ls-kernel.c @@ -3,12 +3,13 @@ * * Copyright (c) 1997--2013 Martin Mares * - * Can be freely distributed and used under the terms of the GNU GPL. + * Can be freely distributed and used under the terms of the GNU GPL v2+. + * + * SPDX-License-Identifier: GPL-2.0-or-later */ #include #include -#include #include "lspci.h" @@ -29,13 +30,7 @@ show_kernel_init(void) if (show_kernel_inited >= 0) return show_kernel_inited; - struct utsname uts; - if (uname(&uts) < 0) - die("uname() failed: %m"); - char *name = alloca(64 + strlen(uts.release)); - sprintf(name, "/lib/modules/%s", uts.release); - - kmod_ctx = kmod_new(name, NULL); + kmod_ctx = kmod_new(NULL, NULL); if (!kmod_ctx) { fprintf(stderr, "lspci: Unable to initialize libkmod context\n"); @@ -180,35 +175,30 @@ static int match_pcimap(struct device *d, struct pcimap_entry *e) { struct pci_dev *dev = d->dev; - unsigned int class = get_conf_long(d, PCI_REVISION_ID) >> 8; - word subv, subd; + unsigned int class = (((unsigned int)dev->device_class << 8) | dev->prog_if); #define MATCH(x, y) ((y) > 0xffff || (x) == (y)) - get_subid(d, &subv, &subd); return MATCH(dev->vendor_id, e->vendor) && MATCH(dev->device_id, e->device) && - MATCH(subv, e->subvendor) && - MATCH(subd, e->subdevice) && + MATCH(dev->subsys_vendor_id, e->subvendor) && + MATCH(dev->subsys_id, e->subdevice) && (class & e->class_mask) == e->class; #undef MATCH } static const char *next_module(struct device *d) { - static struct pcimap_entry *current, *last_printed; + static struct pcimap_entry *current; if (!current) - { - current = pcimap_head; - last_printed = NULL; - } + current = pcimap_head; else current = current->next; while (current) { - if (match_pcimap(d, current) && (!last_printed || strcmp(last_printed->module, current->module))) + if (match_pcimap(d, current)) return current->module; current = current->next; } @@ -223,54 +213,39 @@ show_kernel_cleanup(void) #endif -#define DRIVER_BUF_SIZE 1024 - -static char * -find_driver(struct device *d, char *buf) +static const char * +next_module_filtered(struct device *d) { - struct pci_dev *dev = d->dev; - char name[1024], *drv, *base; - int n; - - if (dev->access->method != PCI_ACCESS_SYS_BUS_PCI) - return NULL; - - base = pci_get_param(dev->access, "sysfs.path"); - if (!base || !base[0]) - return NULL; - - n = snprintf(name, sizeof(name), "%s/devices/%04x:%02x:%02x.%d/driver", - base, dev->domain, dev->bus, dev->dev, dev->func); - if (n < 0 || n >= (int)sizeof(name)) - die("show_driver: sysfs device name too long, why?"); - - n = readlink(name, buf, DRIVER_BUF_SIZE); - if (n < 0) - return NULL; - if (n >= DRIVER_BUF_SIZE) - return ""; - buf[n] = 0; - - if (drv = strrchr(buf, '/')) - return drv+1; - else - return buf; + static char prev_module[256]; + const char *module; + + while (module = next_module(d)) + { + if (strcmp(module, prev_module)) + { + strncpy(prev_module, module, sizeof(prev_module)); + prev_module[sizeof(prev_module) - 1] = 0; + return module; + } + } + prev_module[0] = 0; + return NULL; } void show_kernel(struct device *d) { - char buf[DRIVER_BUF_SIZE]; const char *driver, *module; - if (driver = find_driver(d, buf)) + pci_fill_info(d->dev, PCI_FILL_DRIVER); + if (driver = pci_get_string_property(d->dev, PCI_FILL_DRIVER)) printf("\tKernel driver in use: %s\n", driver); if (!show_kernel_init()) return; int cnt = 0; - while (module = next_module(d)) + while (module = next_module_filtered(d)) printf("%s %s", (cnt++ ? "," : "\tKernel modules:"), module); if (cnt) putchar('\n'); @@ -279,29 +254,39 @@ show_kernel(struct device *d) void show_kernel_machine(struct device *d) { - char buf[DRIVER_BUF_SIZE]; const char *driver, *module; - if (driver = find_driver(d, buf)) + pci_fill_info(d->dev, PCI_FILL_DRIVER); + if (driver = pci_get_string_property(d->dev, PCI_FILL_DRIVER)) printf("Driver:\t%s\n", driver); if (!show_kernel_init()) return; - while (module = next_module(d)) + while (module = next_module_filtered(d)) printf("Module:\t%s\n", module); } #else void -show_kernel(struct device *d UNUSED) +show_kernel(struct device *d) { + const char *driver; + + pci_fill_info(d->dev, PCI_FILL_DRIVER); + if (driver = pci_get_string_property(d->dev, PCI_FILL_DRIVER)) + printf("\tDriver in use: %s\n", driver); } void -show_kernel_machine(struct device *d UNUSED) +show_kernel_machine(struct device *d) { + const char *driver; + + pci_fill_info(d->dev, PCI_FILL_DRIVER); + if (driver = pci_get_string_property(d->dev, PCI_FILL_DRIVER)) + printf("Driver:\t%s\n", driver); } void