From: Martin Mares Date: Mon, 1 Apr 2013 13:40:10 +0000 (+0200) Subject: Detection of module aliases (Linux sysfs only) X-Git-Tag: v3.2.1~29 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=b1861a8de540b160f6e1254d7ca5fe8a35eab59b;p=pciutils.git Detection of module aliases (Linux sysfs only) This will be needed to support libkmod. --- diff --git a/lib/access.c b/lib/access.c index 691df39..faad7c4 100644 --- a/lib/access.c +++ b/lib/access.c @@ -59,6 +59,7 @@ void pci_free_dev(struct pci_dev *d) if (d->methods->cleanup_dev) d->methods->cleanup_dev(d); pci_free_caps(d); + pci_mfree(d->module_alias); pci_mfree(d->phy_slot); pci_mfree(d); } diff --git a/lib/pci.h b/lib/pci.h index 7a5a6b8..148b055 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -1,7 +1,7 @@ /* * The PCI Library * - * Copyright (c) 1997--2009 Martin Mares + * Copyright (c) 1997--2013 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -130,6 +130,7 @@ struct pci_dev { pciaddr_t rom_size; /* Expansion ROM size */ struct pci_cap *first_cap; /* List of capabilities */ char *phy_slot; /* Physical slot */ + char *module_alias; /* Linux kernel module alias */ /* Fields used internally: */ struct pci_access *access; @@ -165,6 +166,7 @@ int pci_fill_info(struct pci_dev *, int flags) PCI_ABI; /* Fill in device inform #define PCI_FILL_CAPS 64 #define PCI_FILL_EXT_CAPS 128 #define PCI_FILL_PHYS_SLOT 256 +#define PCI_FILL_MODULE_ALIAS 512 #define PCI_FILL_RESCAN 0x10000 void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI; diff --git a/lib/sysfs.c b/lib/sysfs.c index 2197fab..fb1b521 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -85,24 +85,39 @@ sysfs_obj_name(struct pci_dev *d, char *object, char *buf) d->access->error("File name too long"); } +#define OBJBUFSIZE 1024 + static int -sysfs_get_value(struct pci_dev *d, char *object) +sysfs_get_string(struct pci_dev *d, char *object, char *buf, int mandatory) { struct pci_access *a = d->access; int fd, n; - char namebuf[OBJNAMELEN], buf[256]; + char namebuf[OBJNAMELEN]; sysfs_obj_name(d, object, namebuf); fd = open(namebuf, O_RDONLY); if (fd < 0) - a->error("Cannot open %s: %s", namebuf, strerror(errno)); - n = read(fd, buf, sizeof(buf)); + { + if (mandatory) + a->error("Cannot open %s: %s", namebuf, strerror(errno)); + return 0; + } + n = read(fd, buf, OBJBUFSIZE); close(fd); if (n < 0) a->error("Error reading %s: %s", namebuf, strerror(errno)); - if (n >= (int) sizeof(buf)) + if (n >= OBJBUFSIZE) a->error("Value in %s too long", namebuf); buf[n] = 0; + return 1; +} + +static int +sysfs_get_value(struct pci_dev *d, char *object) +{ + char buf[OBJBUFSIZE]; + + sysfs_get_string(d, object, buf, 1); return strtol(buf, NULL, 0); } @@ -235,10 +250,7 @@ sysfs_fill_slots(struct pci_access *a) { for (d = a->devices; d; d = d->next) if (dom == d->domain && bus == d->bus && dev == d->dev && !d->phy_slot) - { - d->phy_slot = pci_malloc(a, strlen(entry->d_name) + 1); - strcpy(d->phy_slot, entry->d_name); - } + d->phy_slot = pci_strdup(a, entry->d_name); } fclose(file); } @@ -255,6 +267,14 @@ sysfs_fill_info(struct pci_dev *d, int flags) for (pd = d->access->devices; pd; pd = pd->next) pd->known_fields |= PCI_FILL_PHYS_SLOT; } + + if ((flags & PCI_FILL_MODULE_ALIAS) && !(d->known_fields & PCI_FILL_MODULE_ALIAS)) + { + char buf[OBJBUFSIZE]; + if (sysfs_get_string(d, "modalias", buf, 0)) + d->module_alias = pci_strdup(d->access, buf); + } + return pci_generic_fill_info(d, flags); }