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