]> mj.ucw.cz Git - pciutils.git/blob - lib/names-hwdb.c
Released as 3.9.0
[pciutils.git] / lib / names-hwdb.c
1 /*
2  *      The PCI Library -- Looking up Names via UDEV and HWDB
3  *
4  *      Copyright (c) 2013--2014 Tom Gundersen <teg@jklm.no>
5  *      Copyright (c) 2014 Martin Mares <mj@ucw.cz>
6  *
7  *      Can be freely distributed and used under the terms of the GNU GPL.
8  */
9
10 #include <string.h>
11
12 #include "internal.h"
13 #include "names.h"
14
15 #ifdef PCI_HAVE_HWDB
16
17 #include <libudev.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 char *
22 pci_id_hwdb_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4)
23 {
24   char modalias[64];
25   const char *key = NULL;
26
27   const char *disabled = pci_get_param(a, "hwdb.disable");
28   if (disabled && atoi(disabled))
29     return NULL;
30
31   switch (cat)
32     {
33     case ID_VENDOR:
34       sprintf(modalias, "pci:v%08X*", id1);
35       key = "ID_VENDOR_FROM_DATABASE";
36       break;
37     case ID_DEVICE:
38       sprintf(modalias, "pci:v%08Xd%08X*", id1, id2);
39       key = "ID_MODEL_FROM_DATABASE";
40       break;
41     case ID_SUBSYSTEM:
42       sprintf(modalias, "pci:v%08Xd%08Xsv%08Xsd%08X*", id1, id2, id3, id4);
43       key = "ID_MODEL_FROM_DATABASE";
44       break;
45     case ID_GEN_SUBSYSTEM:
46       sprintf(modalias, "pci:v*d*sv%08Xsd%08X*", id1, id2);
47       key = "ID_MODEL_FROM_DATABASE";
48       break;
49     case ID_CLASS:
50       sprintf(modalias, "pci:v*d*sv*sd*bc%02X*", id1);
51       key = "ID_PCI_CLASS_FROM_DATABASE";
52       break;
53     case ID_SUBCLASS:
54       sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02X*", id1, id2);
55       key = "ID_PCI_SUBCLASS_FROM_DATABASE";
56       break;
57     case ID_PROGIF:
58       sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02Xi%02X*", id1, id2, id3);
59       key = "ID_PCI_INTERFACE_FROM_DATABASE";
60       break;
61     }
62
63   if (key)
64     {
65       if (!a->id_udev_hwdb)
66         {
67           a->debug("Initializing UDEV HWDB\n");
68           a->id_udev = udev_new();
69           a->id_udev_hwdb = udev_hwdb_new(a->id_udev);
70         }
71
72       struct udev_list_entry *entry;
73       udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(a->id_udev_hwdb, modalias, 0))
74         {
75           const char *entry_name = udev_list_entry_get_name(entry);
76           if (entry_name && !strcmp(entry_name, key))
77             {
78               const char *entry_value = udev_list_entry_get_value(entry);
79               if (entry_value)
80                 return pci_strdup(a, entry_value);
81             }
82         }
83     }
84
85   return NULL;
86 }
87
88 void
89 pci_id_hwdb_free(struct pci_access *a)
90 {
91   if (a->id_udev_hwdb)
92     {
93       udev_hwdb_unref(a->id_udev_hwdb);
94       a->id_udev_hwdb = NULL;
95     }
96   if (a->id_udev)
97     {
98       udev_unref(a->id_udev);
99       a->id_udev = NULL;
100     }
101 }
102
103 #else
104
105 char *
106 pci_id_hwdb_lookup(struct pci_access *a UNUSED, int cat UNUSED, int id1 UNUSED, int id2 UNUSED, int id3 UNUSED, int id4 UNUSED)
107 {
108   return NULL;
109 }
110
111 void
112 pci_id_hwdb_free(struct pci_access *a UNUSED)
113 {
114 }
115
116 #endif