| /* |
| * The PCI Library -- Looking up Names via UDEV and HWDB |
| * |
| * Copyright (c) 2013--2014 Tom Gundersen <teg@jklm.no> |
| * Copyright (c) 2014 Martin Mares <mj@ucw.cz> |
| * |
| * Can be freely distributed and used under the terms of the GNU GPL. |
| */ |
| |
| #include <string.h> |
| |
| #include "internal.h" |
| #include "names.h" |
| |
| #ifdef PCI_HAVE_HWDB |
| |
| #include <libudev.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| char * |
| pci_id_hwdb_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4) |
| { |
| char modalias[64]; |
| const char *key = NULL; |
| |
| const char *disabled = pci_get_param(a, "hwdb.disable"); |
| if (disabled && atoi(disabled)) |
| return NULL; |
| |
| switch (cat) |
| { |
| case ID_VENDOR: |
| sprintf(modalias, "pci:v%08X*", id1); |
| key = "ID_VENDOR_FROM_DATABASE"; |
| break; |
| case ID_DEVICE: |
| sprintf(modalias, "pci:v%08Xd%08X*", id1, id2); |
| key = "ID_MODEL_FROM_DATABASE"; |
| break; |
| case ID_SUBSYSTEM: |
| sprintf(modalias, "pci:v%08Xd%08Xsv%08Xsd%08X*", id1, id2, id3, id4); |
| key = "ID_MODEL_FROM_DATABASE"; |
| break; |
| case ID_GEN_SUBSYSTEM: |
| sprintf(modalias, "pci:v*d*sv%08Xsd%08X*", id1, id2); |
| key = "ID_MODEL_FROM_DATABASE"; |
| break; |
| case ID_CLASS: |
| sprintf(modalias, "pci:v*d*sv*sd*bc%02X*", id1); |
| key = "ID_PCI_CLASS_FROM_DATABASE"; |
| break; |
| case ID_SUBCLASS: |
| sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02X*", id1, id2); |
| key = "ID_PCI_SUBCLASS_FROM_DATABASE"; |
| break; |
| case ID_PROGIF: |
| sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02Xi%02X*", id1, id2, id3); |
| key = "ID_PCI_INTERFACE_FROM_DATABASE"; |
| break; |
| } |
| |
| if (key) |
| { |
| if (!a->id_udev_hwdb) |
| { |
| a->debug("Initializing UDEV HWDB\n"); |
| a->id_udev = udev_new(); |
| a->id_udev_hwdb = udev_hwdb_new(a->id_udev); |
| } |
| |
| struct udev_list_entry *entry; |
| udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(a->id_udev_hwdb, modalias, 0)) |
| if (strcmp(udev_list_entry_get_name(entry), key) == 0) |
| return pci_strdup(a, udev_list_entry_get_value(entry)); |
| } |
| |
| return NULL; |
| } |
| |
| void |
| pci_id_hwdb_free(struct pci_access *a) |
| { |
| if (a->id_udev_hwdb) |
| { |
| udev_hwdb_unref(a->id_udev_hwdb); |
| a->id_udev_hwdb = NULL; |
| } |
| if (a->id_udev) |
| { |
| udev_unref(a->id_udev); |
| a->id_udev = NULL; |
| } |
| } |
| |
| #else |
| |
| char * |
| pci_id_hwdb_lookup(struct pci_access *a UNUSED, int cat UNUSED, int id1 UNUSED, int id2 UNUSED, int id3 UNUSED, int id4 UNUSED) |
| { |
| return NULL; |
| } |
| |
| void |
| pci_id_hwdb_free(struct pci_access *a UNUSED) |
| { |
| } |
| |
| #endif |