diff options
author | Thierry Vignaud <tv@mandriva.org> | 2007-02-26 13:48:16 +0000 |
---|---|---|
committer | Thierry Vignaud <tv@mandriva.org> | 2007-02-26 13:48:16 +0000 |
commit | 5dbdaf465c4d848dce965706616d9bfbf38f2bbe (patch) | |
tree | d55930e18bc10c9636c3fb5e7d82b5546dbd4f5c | |
parent | 6f030aabed59d4e1c9f1217838d0344c5757bba6 (diff) | |
download | ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar.gz ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar.bz2 ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar.xz ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.zip |
switch to pciutils as PCI listing backend
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | pci.c | 100 |
2 files changed, 39 insertions, 63 deletions
@@ -20,7 +20,7 @@ build: $(binaries) $(libraries) lspcidrake: lspcidrake.c libldetect.so $(lib_major).$(LIB_MINOR): common.o pciusb.o pci.o usb.o pciclass.o usbclass.o dmi.o - $(CC) -shared -Wl,-soname,$(lib_major) -o $@ $^ + $(CC) -shared -Wl,-soname,$(lib_major) -o $@ $^ -lpci $(lib_major): $(lib_major).$(LIB_MINOR) ln -sf $< $@ libldetect.so: $(lib_major) @@ -1,5 +1,6 @@ #define _GNU_SOURCE #include <stdio.h> +#include <stdarg.h> #include <stdlib.h> #include <string.h> #include <pci/pci.h> @@ -8,99 +9,74 @@ #include <fcntl.h> #include <unistd.h> #include <dirent.h> +#include <pci/pci.h> #include "common.h" static char *proc_pci_path_default = "/proc/bus/pci/devices"; char *proc_pci_path = NULL; -#define MAX_PCI_DOMAINS 256 -static int pci_domains[MAX_PCI_DOMAINS] = { 0, }; - -static int probe_domains(void) +void __attribute__((noreturn)) error_and_die(char *msg, ...) { - static int n_pci_domains = -1; - if (n_pci_domains == -1) { - int i; - DIR *dir; - n_pci_domains = 0; - for (i = 0; i < MAX_PCI_DOMAINS; i++) - pci_domains[i] = 0; - if ((dir = opendir("/proc/bus/pci")) != NULL) { - struct dirent *dent; - while ((dent = readdir(dir)) != NULL) { - int domain, bus, ret; - ret = sscanf(dent->d_name, "%x:%x", &domain, &bus); - if (ret == 2) { - if (domain < MAX_PCI_DOMAINS) - pci_domains[domain] = 1; - } - } - closedir(dir); - for (i = 0; i < MAX_PCI_DOMAINS; i++) { - if (pci_domains[i]) - pci_domains[n_pci_domains++] = i; - } - } - } - return n_pci_domains; + va_list args; + + va_start(args, msg); + fprintf(stderr, "%s: ", "lspcidrake"); + vfprintf(stderr, msg, args); + fputc('\n', stderr); + exit(1); } extern struct pciusb_entries pci_probe(void) { - FILE *f; int devf; + int devf; char buf[BUF_SIZE]; unsigned short *bufi = (unsigned short *) &buf; - unsigned short devbusfn; - unsigned int id; struct pciusb_entries r; char file[32]; - int n_pci_domains; - n_pci_domains = probe_domains(); + static struct pci_access *pacc; + struct pci_dev *dev; + char vendorbuf[128], devbuf[128]; - r.nb = 0; - if (!(f = fopen(proc_pci_path ? proc_pci_path : proc_pci_path_default, "r"))) { - if (proc_pci_path) { - char *err_msg; - asprintf(&err_msg, "unable to open \"%s\"\n" - "You may have passed a wrong argument to the \"-p\" option.\n" - "fopen() sets errno to", proc_pci_path); - perror(err_msg); - free(err_msg); - } - r.nb = 0; - r.entries = NULL; // is that needed? - return r; + pacc = pci_alloc(); + + if (proc_pci_path) { + pacc->method_params[PCI_ACCESS_PROC_BUS_PCI] = proc_pci_path; + pacc->method = PCI_ACCESS_PROC_BUS_PCI; } + + + pci_init(pacc); + pacc->error = error_and_die; + pci_scan_bus(pacc); + + r.nb = 0; r.entries = malloc(sizeof(struct pciusb_entry) * MAX_DEVICES); - for (; fgets(buf, sizeof(buf) - 1, f) && r.nb < MAX_DEVICES; r.nb++) { + for (dev = pacc->devices; dev; dev = dev->next, r.nb++) { + struct pciusb_entry *e = &r.entries[r.nb]; unsigned char class_prog = 0; + pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS); + pciusb_initialize(e); - sscanf(buf, "%hx %x", &devbusfn, &id); - e->vendor = id >> 16; - e->device = id & 0xffff; - e->pci_bus = devbusfn >> 8; - e->pci_device = (devbusfn & 0xff) >> 3; - e->pci_function = (devbusfn & 0xff) & 0x07; + e->vendor = dev->vendor_id; + e->device = dev->device_id; + e->pci_bus = dev->bus; + e->pci_device = dev->dev; + e->pci_function = dev->func; snprintf(file, sizeof(file), "/proc/bus/pci/%02x/%02x.%d", e->pci_bus, e->pci_device, e->pci_function); if ((devf = open(file, O_RDONLY)) == -1) { /* try with pci domains */ int found = 0; - if (n_pci_domains) { - int i; - for (i = 0; !found && i < n_pci_domains; i++) { - snprintf(file, sizeof(file), "/proc/bus/pci/%04x:%02x/%02x.%d", pci_domains[i], e->pci_bus, e->pci_device, e->pci_function); + snprintf(file, sizeof(file), "/proc/bus/pci/%04x:%02x/%02x.%d", dev->domain, e->pci_bus, e->pci_device, e->pci_function); if ((devf = open(file, O_RDONLY)) >= 0) found = 1; - } - } if (!found) continue; } read(devf, &buf, 0x30); /* these files're 256 bytes but we only need first 48 bytes*/ - e->class_ = bufi[0x5]; + e->class_ = dev->device_class; e->subvendor = bufi[0x16]; e->subdevice = bufi[0x17]; @@ -153,8 +129,8 @@ extern struct pciusb_entries pci_probe(void) { close(devf); } - fclose(f); realloc(r.entries, sizeof(struct pciusb_entry) * r.nb); + pci_cleanup(pacc); if (pciusb_find_modules(&r, "pcitable")) return r; |