1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/bsd/helpers.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
10 const unsigned char subclass_id
;
11 const char *subclass_name
;
15 const unsigned char class_id
;
16 const PCI_SUBCLASS
*subclass_list
;
17 const unsigned int subclass_entries
;
18 const char *class_name
;
21 static const PCI_SUBCLASS unclassified
[] = {
22 { 0x00, "Non-VGA device" },
23 { 0x01, "VGA compatible device" }
26 static const PCI_SUBCLASS mass_storage
[] = {
27 { 0x00, "SCSI storage controller" },
28 { 0x01, "IDE interface" },
29 { 0x02, "Floppy disk controller" },
30 { 0x03, "IPI bus controller" },
31 { 0x04, "RAID bus controller" },
32 { 0x05, "ATA controller" },
33 { 0x06, "SATA controller" },
34 { 0x07, "Serial Attached SCSI controller" },
35 { 0x08, "Non-Volatile memory controller" },
36 { 0x09, "Universal Flash Storage controller" },
37 { 0x80, "Mass storage controller" }
40 static const PCI_SUBCLASS network
[] = {
41 { 0x00, "Ethernet controller" },
42 { 0x01, "Token ring network controller" },
43 { 0x02, "FDDI network controller" },
44 { 0x03, "ATM network controller" },
45 { 0x04, "ISDN controller" },
46 { 0x05, "WorldFip controller" },
47 { 0x06, "PICMG controller" },
48 { 0x07, "InfiniBand Controller" },
49 { 0x08, "Host fabric controller" },
50 { 0x80, "Network controller" }
53 static const PCI_SUBCLASS display
[] = {
54 { 0x00, "VGA compatible controller" },
55 { 0x01, "XGA compatible controller" },
56 { 0x02, "3D controller" },
57 { 0x80, "Display controller" }
60 static const PCI_SUBCLASS multimedia
[] = {
61 { 0x00, "Multimedia video controller" },
62 { 0x01, "Multimedia audio controller" },
63 { 0x02, "Computer telephony device" },
64 { 0x03, "Audio device" },
65 { 0x80, "Multimedia controller" }
68 static const PCI_SUBCLASS memory
[] = {
69 { 0x00, "RAM memory" },
70 { 0x01, "FLASH memory" },
71 { 0x80, "Memory controller" }
74 static const PCI_SUBCLASS bridge
[] = {
75 { 0x00, "Host bridge" },
76 { 0x01, "ISA bridge" },
77 { 0x02, "EISA bridge" },
78 { 0x03, "MicroChannel bridge" },
79 { 0x04, "PCI bridge" },
80 { 0x05, "PCMCIA bridge" },
81 { 0x06, "NuBus bridge" },
82 { 0x07, "CardBus bridge" },
83 { 0x08, "RACEway bridge" },
84 { 0x09, "Semi-transparent PCI-to-PCI bridge" },
85 { 0x0a, "InfiniBand to PCI host bridge" },
86 { 0x0b, "Advanced Switching to PCI host bridge" },
90 static const PCI_SUBCLASS communication
[] = {
91 { 0x00, "Serial controller" },
92 { 0x01, "Parallel controller" },
93 { 0x02, "Multiport serial controller" },
95 { 0x04, "GPIB controller" },
96 { 0x05, "Smart Card controller" },
97 { 0x80, "Communication controller" }
100 static const PCI_SUBCLASS generic
[] = {
102 { 0x01, "DMA controller" },
105 { 0x04, "PCI Hot-plug controller" },
106 { 0x05, "SD Host controller" },
108 { 0x07, "Root Complex Event Collector" },
109 { 0x80, "System peripheral" }
112 static const PCI_SUBCLASS input_device
[] = {
113 { 0x00, "Keyboard controller" },
114 { 0x01, "Digitizer Pen" },
115 { 0x02, "Mouse controller" },
116 { 0x03, "Scanner controller" },
117 { 0x04, "Gameport controller" },
118 { 0x80, "Input device controller" }
121 static const PCI_SUBCLASS docking_station
[] = {
122 { 0x00, "Generic Docking Station" },
123 { 0x80, "Docking Station" }
126 static const PCI_SUBCLASS processor
[] = {
131 { 0x20, "Power PC" },
133 { 0x40, "Co-processor" },
134 { 0x80, "Processor" }
137 static const PCI_SUBCLASS serial_bus
[] = {
138 { 0x00, "FireWire (IEEE 1394)" },
139 { 0x01, "ACCESS Bus" },
141 { 0x03, "USB controller" },
142 { 0x04, "Fibre Channel" },
144 { 0x06, "InfiniBand" },
145 { 0x07, "IPMI SMIC interface" },
146 { 0x08, "SERCOS interface" },
148 { 0x0a, "MIPI I3C SM Host Controller Interface" },
149 { 0x80, "Serial Bus Controller" }
152 static const PCI_SUBCLASS wireless
[] = {
153 { 0x00, "IRDA controller" },
154 { 0x01, "Consumer IR controller" },
155 { 0x10, "RF controller" },
156 { 0x11, "Bluetooth" },
157 { 0x12, "Broadband" },
158 { 0x20, "802.1a controller" },
159 { 0x21, "802.1b controller" },
160 { 0x40, "Cellular controller/modem" },
161 { 0x41, "Cellular controller/modem plus Ethernet (802.11)" },
162 { 0x80, "Wireless controller" }
165 static const PCI_SUBCLASS intellegient_controller
[] = {
169 static const PCI_SUBCLASS satellite_controller
[] = {
170 { 0x01, "Satellite TV controller" },
171 { 0x02, "Satellite audio communication controller" },
172 { 0x03, "Satellite voice communication controller" },
173 { 0x04, "Satellite data communication controller" }
176 static const PCI_SUBCLASS encryption
[] = {
177 { 0x00, "Network and computing encryption device" },
178 { 0x10, "Entertainment encryption device" },
179 { 0x80, "Encryption controller" }
182 static const PCI_SUBCLASS signal_processing
[] = {
183 { 0x00, "DPIO module" },
184 { 0x01, "Performance counters" },
185 { 0x10, "Communication synchronizer" },
186 { 0x20, "Signal processing management" },
187 { 0x80, "Signal processing controller" }
190 static const PCI_CLASS class_list
[] = {
191 { 0x00, &unclassified
[0], ARRAY_SIZE(unclassified
),
192 "Unclassified device" },
193 { 0x01, &mass_storage
[0], ARRAY_SIZE(mass_storage
), "Mass storage" },
194 { 0x02, &network
[0], ARRAY_SIZE(network
), "Network" },
195 { 0x03, &display
[0], ARRAY_SIZE(display
), "Display" },
196 { 0x04, &multimedia
[0], ARRAY_SIZE(multimedia
), "Multimedia" },
197 { 0x05, &memory
[0], ARRAY_SIZE(memory
), "Memory" },
198 { 0x06, &bridge
[0], ARRAY_SIZE(bridge
), "Bridge" },
199 { 0x07, &communication
[0], ARRAY_SIZE(communication
), "Communication" },
200 { 0x08, &generic
[0], ARRAY_SIZE(generic
), "Generic system peripheral" },
201 { 0x09, &input_device
[0], ARRAY_SIZE(input_device
), "Input device" },
202 { 0x0a, &docking_station
[0], ARRAY_SIZE(docking_station
),
204 { 0x0b, &processor
[0], ARRAY_SIZE(processor
), "Processor" },
205 { 0x0c, &serial_bus
[0], ARRAY_SIZE(serial_bus
), "Serial bus" },
206 { 0x0d, &wireless
[0], ARRAY_SIZE(wireless
), "Wireless" },
207 { 0x0e, &intellegient_controller
[0],
208 ARRAY_SIZE(intellegient_controller
),
209 "Intelligent controller" },
210 { 0x0f, &satellite_controller
[0], ARRAY_SIZE(satellite_controller
),
211 "Satellite communications" },
212 { 0x10, &encryption
[0], ARRAY_SIZE(encryption
), "Encryption" },
213 { 0x11, &signal_processing
[0], ARRAY_SIZE(signal_processing
),
214 "Signal processing" },
215 { 0xff, NULL
, 0, "Unassigned class" }
217 static const unsigned int class_entries
= ARRAY_SIZE(class_list
);
219 static const PCI_CLASS
*get_pci_class_entry(struct device
*dev
)
222 const PCI_CLASS
*class_entry
;
223 const PCI_CLASS
*class_list_end
;
225 /* Get the PCI device class */
226 class = pci_read_config8(dev
, PCI_CLASS_DEVICE
+1);
228 /* Locate the class entry */
229 class_entry
= &class_list
[0];
230 class_list_end
= &class_entry
[class_entries
];
231 while (class_list_end
> class_entry
) {
232 if (class_entry
->class_id
== class)
239 const char *get_pci_class_name(struct device
*dev
)
241 const PCI_CLASS
*class_entry
;
243 class_entry
= get_pci_class_entry(dev
);
244 return class_entry
? class_entry
->class_name
: "???";
247 const char *get_pci_subclass_name(struct device
*dev
)
249 const PCI_CLASS
*class_entry
;
250 unsigned char subclass
;
251 const PCI_SUBCLASS
*subclass_entry
;
252 const PCI_SUBCLASS
*subclass_list_end
;
253 const char *subclass_name
;
255 /* Get the PCI device subclass */
256 subclass
= pci_read_config8(dev
, PCI_CLASS_DEVICE
);
258 /* Locate the subclass name */
259 subclass_name
= "???";
260 class_entry
= get_pci_class_entry(dev
);
261 subclass_entry
= class_entry
? class_entry
->subclass_list
: NULL
;
262 if (subclass_entry
!= NULL
) {
264 &subclass_entry
[class_entry
->subclass_entries
];
265 while (subclass_list_end
> subclass_entry
) {
266 if (subclass_entry
->subclass_id
== subclass
) {
267 subclass_name
= subclass_entry
->subclass_name
;
273 return subclass_name
;