From c22c314a322e2243983d2f356a5f0532b2d846a5 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 14 Oct 2018 22:47:53 +0200 Subject: [PATCH] libpci is now able to find a specific instance of a capability --- lib/caps.c | 37 +++++++++++++++++++++++++++++++++++-- lib/libpci.ver | 5 +++++ lib/pci.h | 2 ++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/caps.c b/lib/caps.c index 9a2e0a5..4f41589 100644 --- a/lib/caps.c +++ b/lib/caps.c @@ -103,12 +103,45 @@ pci_free_caps(struct pci_dev *d) struct pci_cap * pci_find_cap(struct pci_dev *d, unsigned int id, unsigned int type) +{ + return pci_find_cap_nr(d, id, type, NULL); +} + +/** + * Finds a particular capability of a device + * + * To select one capability if there are more than one with the same id you + * can provide a pointer to an unsigned int that contains the index which you + * want as cap_number. If you don't care and are fine with the first one you + * can supply NULL. To cap_number the acutal number of capablities with that id + * will be written. + * + * @param d Which device to target + * @param id Capability ID + * @param type PCI_FILL_CAPS or PCI_FILL_EXT_CAPS + * @param cap_number Which instance of a capability to target + * @returns pointer to capability structure or NULL if not found + */ +struct pci_cap * +pci_find_cap_nr(struct pci_dev *d, unsigned int id, unsigned int type, + unsigned int *cap_number) { struct pci_cap *c; + unsigned int target = 0; + if (cap_number != NULL) + { + target = *cap_number; + *cap_number = 0; + } - pci_fill_info_v35(d, ((type == PCI_CAP_NORMAL) ? PCI_FILL_CAPS : PCI_FILL_EXT_CAPS)); + pci_fill_info_v35(d, ((type == PCI_CAP_NORMAL) + ? PCI_FILL_CAPS + : PCI_FILL_EXT_CAPS)); for (c=d->first_cap; c; c=c->next) if (c->type == type && c->id == id) - return c; + if (cap_number == NULL || target == *cap_number) + return c; + else + (*cap_number)++; return NULL; } diff --git a/lib/libpci.ver b/lib/libpci.ver index d15e678..e20c3f5 100644 --- a/lib/libpci.ver +++ b/lib/libpci.ver @@ -77,3 +77,8 @@ LIBPCI_3.6 { global: pci_get_string_property; }; + +LIBPCI_3.7 { + global: + pci_find_cap_nr; +}; diff --git a/lib/pci.h b/lib/pci.h index 548aa69..ae9689d 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -211,6 +211,8 @@ struct pci_cap { #define PCI_CAP_EXTENDED 2 /* PCIe extended capabilities */ struct pci_cap *pci_find_cap(struct pci_dev *, unsigned int id, unsigned int type) PCI_ABI; +struct pci_cap *pci_find_cap_nr(struct pci_dev *, unsigned int id, unsigned int type, + unsigned int *cap_number) PCI_ABI; /* * Filters -- 2.39.2