]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/names.c
2 * The PCI Library -- ID to Name Translation
4 * Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
16 static char *id_lookup(struct pci_access
*a
, int flags
, int cat
, int id1
, int id2
, int id3
, int id4
)
20 while (!(name
= pci_id_lookup(a
, flags
, cat
, id1
, id2
, id3
, id4
)))
22 if ((flags
& PCI_LOOKUP_CACHE
) && !a
->id_cache_status
)
24 if (pci_id_cache_load(a
, flags
))
27 if (flags
& PCI_LOOKUP_NETWORK
)
29 if (name
= pci_id_net_lookup(a
, cat
, id1
, id2
, id3
, id4
))
31 pci_id_insert(a
, cat
, id1
, id2
, id3
, id4
, name
, SRC_NET
);
33 pci_id_cache_dirty(a
);
36 pci_id_insert(a
, cat
, id1
, id2
, id3
, id4
, "", SRC_NET
);
37 /* We want to iterate the lookup to get the allocated ID entry from the hash */
42 return (name
[0] ? name
: NULL
);
46 id_lookup_subsys(struct pci_access
*a
, int flags
, int iv
, int id
, int isv
, int isd
)
49 if (iv
> 0 && id
> 0) /* Per-device lookup */
50 d
= id_lookup(a
, flags
, ID_SUBSYSTEM
, iv
, id
, isv
, isd
);
51 if (!d
) /* Generic lookup */
52 d
= id_lookup(a
, flags
, ID_GEN_SUBSYSTEM
, isv
, isd
, 0, 0);
53 if (!d
&& iv
== isv
&& id
== isd
) /* Check for subsystem == device */
54 d
= id_lookup(a
, flags
, ID_DEVICE
, iv
, id
, 0, 0);
59 format_name(char *buf
, int size
, int flags
, char *name
, char *num
, char *unknown
)
62 if ((flags
& PCI_LOOKUP_NO_NUMBERS
) && !name
)
64 else if (flags
& PCI_LOOKUP_NUMERIC
)
65 res
= snprintf(buf
, size
, "%s", num
);
67 res
= snprintf(buf
, size
, ((flags
& PCI_LOOKUP_MIXED
) ? "%s [%s]" : "%s %s"), unknown
, num
);
68 else if (!(flags
& PCI_LOOKUP_MIXED
))
69 res
= snprintf(buf
, size
, "%s", name
);
71 res
= snprintf(buf
, size
, "%s [%s]", name
, num
);
72 if (res
>= size
&& size
>= 4)
73 buf
[size
-2] = buf
[size
-3] = buf
[size
-4] = '.';
74 else if (res
< 0 || res
>= size
)
75 return "<pci_lookup_name: buffer too small>";
80 format_name_pair(char *buf
, int size
, int flags
, char *v
, char *d
, char *num
)
83 if ((flags
& PCI_LOOKUP_NO_NUMBERS
) && (!v
|| !d
))
85 if (flags
& PCI_LOOKUP_NUMERIC
)
86 res
= snprintf(buf
, size
, "%s", num
);
87 else if (flags
& PCI_LOOKUP_MIXED
)
90 res
= snprintf(buf
, size
, "%s %s [%s]", v
, d
, num
);
92 res
= snprintf(buf
, size
, "Device [%s]", num
);
94 res
= snprintf(buf
, size
, "%s Device [%s]", v
, num
);
99 res
= snprintf(buf
, size
, "%s %s", v
, d
);
101 res
= snprintf(buf
, size
, "Device %s", num
);
103 res
= snprintf(buf
, size
, "%s Device %s", v
, num
+5);
105 if (res
>= size
&& size
>= 4)
106 buf
[size
-2] = buf
[size
-3] = buf
[size
-4] = '.';
107 else if (res
< 0 || res
>= size
)
108 return "<pci_lookup_name: buffer too small>";
113 pci_lookup_name(struct pci_access
*a
, char *buf
, int size
, int flags
, ...)
116 char *v
, *d
, *cls
, *pif
;
117 int iv
, id
, isv
, isd
, icls
, ipif
;
118 char numbuf
[16], pifbuf
[32];
120 va_start(args
, flags
);
122 flags
|= a
->id_lookup_mode
;
123 if (!(flags
& PCI_LOOKUP_NO_NUMBERS
))
125 if (a
->numeric_ids
> 1)
126 flags
|= PCI_LOOKUP_MIXED
;
127 else if (a
->numeric_ids
)
128 flags
|= PCI_LOOKUP_NUMERIC
;
130 if (flags
& PCI_LOOKUP_MIXED
)
131 flags
&= ~PCI_LOOKUP_NUMERIC
;
133 if (!a
->id_hash
&& !(flags
& (PCI_LOOKUP_NUMERIC
| PCI_LOOKUP_SKIP_LOCAL
)) && !a
->id_load_failed
)
134 pci_load_name_list(a
);
136 switch (flags
& 0xffff)
138 case PCI_LOOKUP_VENDOR
:
139 iv
= va_arg(args
, int);
140 sprintf(numbuf
, "%04x", iv
);
141 return format_name(buf
, size
, flags
, id_lookup(a
, flags
, ID_VENDOR
, iv
, 0, 0, 0), numbuf
, "Vendor");
142 case PCI_LOOKUP_DEVICE
:
143 iv
= va_arg(args
, int);
144 id
= va_arg(args
, int);
145 sprintf(numbuf
, "%04x", id
);
146 return format_name(buf
, size
, flags
, id_lookup(a
, flags
, ID_DEVICE
, iv
, id
, 0, 0), numbuf
, "Device");
147 case PCI_LOOKUP_VENDOR
| PCI_LOOKUP_DEVICE
:
148 iv
= va_arg(args
, int);
149 id
= va_arg(args
, int);
150 sprintf(numbuf
, "%04x:%04x", iv
, id
);
151 v
= id_lookup(a
, flags
, ID_VENDOR
, iv
, 0, 0, 0);
152 d
= id_lookup(a
, flags
, ID_DEVICE
, iv
, id
, 0, 0);
153 return format_name_pair(buf
, size
, flags
, v
, d
, numbuf
);
154 case PCI_LOOKUP_SUBSYSTEM
| PCI_LOOKUP_VENDOR
:
155 isv
= va_arg(args
, int);
156 sprintf(numbuf
, "%04x", isv
);
157 v
= id_lookup(a
, flags
, ID_VENDOR
, isv
, 0, 0, 0);
158 return format_name(buf
, size
, flags
, v
, numbuf
, "Unknown vendor");
159 case PCI_LOOKUP_SUBSYSTEM
| PCI_LOOKUP_DEVICE
:
160 iv
= va_arg(args
, int);
161 id
= va_arg(args
, int);
162 isv
= va_arg(args
, int);
163 isd
= va_arg(args
, int);
164 sprintf(numbuf
, "%04x", isd
);
165 return format_name(buf
, size
, flags
, id_lookup_subsys(a
, flags
, iv
, id
, isv
, isd
), numbuf
, "Device");
166 case PCI_LOOKUP_VENDOR
| PCI_LOOKUP_DEVICE
| PCI_LOOKUP_SUBSYSTEM
:
167 iv
= va_arg(args
, int);
168 id
= va_arg(args
, int);
169 isv
= va_arg(args
, int);
170 isd
= va_arg(args
, int);
171 v
= id_lookup(a
, flags
, ID_VENDOR
, isv
, 0, 0, 0);
172 d
= id_lookup_subsys(a
, flags
, iv
, id
, isv
, isd
);
173 sprintf(numbuf
, "%04x:%04x", isv
, isd
);
174 return format_name_pair(buf
, size
, flags
, v
, d
, numbuf
);
175 case PCI_LOOKUP_CLASS
:
176 icls
= va_arg(args
, int);
177 sprintf(numbuf
, "%04x", icls
);
178 cls
= id_lookup(a
, flags
, ID_SUBCLASS
, icls
>> 8, icls
& 0xff, 0, 0);
179 if (!cls
&& (cls
= id_lookup(a
, flags
, ID_CLASS
, icls
>> 8, 0, 0, 0)))
181 if (!(flags
& PCI_LOOKUP_NUMERIC
)) /* Include full class number */
182 flags
|= PCI_LOOKUP_MIXED
;
184 return format_name(buf
, size
, flags
, cls
, numbuf
, "Class");
185 case PCI_LOOKUP_PROGIF
:
186 icls
= va_arg(args
, int);
187 ipif
= va_arg(args
, int);
188 sprintf(numbuf
, "%02x", ipif
);
189 pif
= id_lookup(a
, flags
, ID_PROGIF
, icls
>> 8, icls
& 0xff, ipif
, 0);
190 if (!pif
&& icls
== 0x0101 && !(ipif
& 0x70))
192 /* IDE controllers have complex prog-if semantics */
193 sprintf(pifbuf
, "%s%s%s%s%s",
194 (ipif
& 0x80) ? " Master" : "",
195 (ipif
& 0x08) ? " SecP" : "",
196 (ipif
& 0x04) ? " SecO" : "",
197 (ipif
& 0x02) ? " PriP" : "",
198 (ipif
& 0x01) ? " PriO" : "");
203 return format_name(buf
, size
, flags
, pif
, numbuf
, "ProgIf");
205 return "<pci_lookup_name: invalid request>";