summaryrefslogtreecommitdiffstats
path: root/pci.c
diff options
context:
space:
mode:
authorThierry Vignaud <tv@mandriva.org>2007-02-26 13:48:16 +0000
committerThierry Vignaud <tv@mandriva.org>2007-02-26 13:48:16 +0000
commit5dbdaf465c4d848dce965706616d9bfbf38f2bbe (patch)
treed55930e18bc10c9636c3fb5e7d82b5546dbd4f5c /pci.c
parent6f030aabed59d4e1c9f1217838d0344c5757bba6 (diff)
downloadldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar
ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar.gz
ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar.bz2
ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.tar.xz
ldetect-5dbdaf465c4d848dce965706616d9bfbf38f2bbe.zip
switch to pciutils as PCI listing backend
Diffstat (limited to 'pci.c')
-rw-r--r--pci.c100
1 files changed, 38 insertions, 62 deletions
diff --git a/pci.c b/pci.c
index e53dee7..193bcd1 100644
--- a/pci.c
+++ b/pci.c
@@ -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;