xref: /illumos-gate/usr/src/uts/common/io/pciex/pci_props.c (revision 06799660fe6583cc262452cdff8c51d98d8733a2)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2023 Oxide Computer company
14  */
15 
16 /*
17  * This file consolidates the basic devinfo properties that exist in the system
18  * for PCI and PCI Express devices and attempts to ensure that there is only one
19  * place to set these items. There are a bunch of different historical
20  * considerations that are taken into account here.
21  *
22  * PCI Compatible Aliases
23  * ----------------------
24  *
25  * The set of aliases that we put on devices is used in the 'compatible'
26  * property to attach device drivers to nodes. These are ordered from more
27  * specific aliases to less specific aliases. The original set of aliases that
28  * was used was defined by Open Firmware for PCI and discussed in the PCI and
29  * later the PCI Express bindings as part of IEEE 1275. Originally those
30  * bindings consisted of aliases which we could describe as:
31  *
32  * pci<vendor id>,<device id>.<subsystem vendor>.<subsytem id>.<revision>
33  * pci<vendor id>,<device id>.<subsystem vendor>.<subsytem id>
34  * pci<subsystem vendor>,<subsytem id>
35  * pci<vendor id>,<device id>.<revision>
36  * pci<vendor id>,<device id>
37  * pciclass,<class code><subclass><programming interface>
38  * pciclass,<class code><subclass>
39  *
40  * When it came time to move to PCI Express, Sun had published a draft document
41  * for how to adopt IEEE 1275 bindings to PCI Express. Most notably it dropped
42  * the pci<subsystem vendor>.<subsytem id> entry and instead prefixed everything
43  * with 'pciex' instead of 'pci'. The reason that this was dropped was because
44  * of the fact that while the early days assumed that subsystem IDs were in a
45  * shared namespace with device IDs, they ended up overlapping and therefore
46  * have not proven to be unique. Because that ID syntax overlapped with
47  * pci<vendor id>,<device id> this has led to problems where IDs are reused and
48  * incorrect bindings occur. We already maintain a deny list where there are
49  * known conflicts.
50  *
51  * To deal with the ambiguity here while trying to avoid the challenges of the
52  * figuring out what IDs were meant to be subsystem IDs and which were primary
53  * IDs (a non-obvious task given that some device drivers are almost exclusively
54  * identified by standalone subsystem IDs -- see smrt(4D) and cpqary3(4D)), we
55  * added two additional aliases for PCI (but not PCI Express) that allow drivers
56  * to express what we call disambiguated IDs. These take the form:
57  *
58  * pci<subsystem vendor>,<subsystem id>,s
59  * pci<vendor id>,<device id>,p
60  *
61  * Were that this was our only challenge. The next bit that we have to deal with
62  * is another artifact of history. While Sun proposed the different PCIe
63  * bindings in a draft, the original intent was just that the aliases would all
64  * take the form of 'pciex' as above and that was it. However, the x86
65  * implementation didn't actually roll with the plan. Instead, it placed the set
66  * of PCI Express aliases and then followed it with the traditional PCI aliases.
67  * As such, they have double the aliases. We still maintain this on x86, but do
68  * not extend the double aliases to other platforms. Because these are specific
69  * to the platform and not the instruction set architecture, whether this is
70  * required or not is indicated by the PCI PRD compat flags interface
71  * pci_prd_compat_flags().
72  *
73  * The last current wrinkle here is that of bridge IDs. Originally PCI bridges
74  * didn't have any form of subsystem ID defined. In the PCI-PCI bridge
75  * specification version 1.2, published in 2003, they eventually added an
76  * optional capability to define a bridge's subsystem. This meant that for most
77  * of PCI's existence this did not exist. In particular, until 2023 we did not
78  * try to search for the capability and add it to a device's compatible
79  * properties. Because of this lapse and having to deal with the above ID
80  * disambiguation, we only add the disambiguated ,s subsystem ID for PCI. Both
81  * PCI Express and PCI still have the fully qualified subsystem IDs added for
82  * bridges.
83  *
84  * Our final set of aliases that we assign to all nodes is in the table below
85  * called 'pci_alias_table'. This table has flags which control the behavior of
86  * the ID generation. To summarize what a platform can control is:
87  *
88  *   o Whether or not both PCIe and PCI aliases are generated. This is
89  *     controlled via PCI_PRD_COMPAT_PCI_NODE_NAME which also influences the
90  *     node name below.
91  *   o For PCI, whether or not we should generate the ambiguous subsystem ID
92  *     alias. This is controlled by PCI_PRD_COMPAT_SUBSYS. We will always
93  *     generate the disambiguated IDs for PCI to stick with IEEE 1275
94  *     expectations across the system. PCI Express will not generate either of
95  *     the standalone subsystem ID forms.
96  *
97  * Node Naming
98  * -----------
99  *
100  * When we name devinfo names we generally do so in the form <type><subsystem
101  * vendor id>,<subsystem id>. If there is no subsystem ID then we use
102  * <type><vendor id>,<device id>. Type 1 headers do not have a subsystem ID.
103  * They are instead found in an optional capability. Type 0 headers do have a
104  * subsystem ID. If the subsystem vendor ID is zero, that indicates that the
105  * subsystem ID is not present and we fall back to the vendor and device ID.
106  *
107  * x86 is again a land of exceptions. Because we never had subsystem IDs present
108  * for bridges, they always use the vendor and device variant for compatibility
109  * purposes. Similarly, x86 always sets the type to "pci" for compatibility.
110  * Other platforms will set the type to "pciex" if it is a PCI Express device or
111  * "pci" otherwise.
112  *
113  * Traditionally, node naming was originally driven by the PROM on SPARC which
114  * used IEEE 1275 Open Firmware device class names instead of just the device
115  * IDs that we have settled on. On our platforms there are two exceptions to
116  * this. If we find an ISA compatible system and the PCI PRD indicates that the
117  * platform supports ISA, then we will override that. In addition, a subset of
118  * the display class codes have historically been used to name a device node
119  * "display".
120  *
121  * Our order for naming device nodes is:
122  *
123  * 1. Check for display.
124  * 2. Check for ISA.
125  * 3. Attempt to use the subsystem.
126  * 4. Fall back to the normal vendor and device.
127  *
128  * Platforms can influence this in the following ways:
129  *
130  *   o ISA is only considered if PCI_PRD_COMPAT_ISA is set.
131  *   o Bridges will not use the subsystem IDs if PCI_PRD_COMPAT_SUBSYS is set.
132  *   o The node name will always start with "pci" if
133  *     PCI_PRD_COMPAT_PCI_NODE_NAME is set.
134  *
135  * Unit Address
136  * ------------
137  *
138  * The unit address for a PCI device has historically been its device number.
139  * For multi-function devices, everything past function zero is the device
140  * number followed by the function number. ARI devices technically don't have a
141  * device number. If we encounter such a device, we just set the device portion
142  * of the unit address to 0.
143  */
144 
145 #include <sys/ddi.h>
146 #include <sys/sunddi.h>
147 #include <sys/sunndi.h>
148 #include <sys/cmn_err.h>
149 #include <sys/pci.h>
150 #include <sys/pcie.h>
151 #include <sys/pci_cfgspace.h>
152 #include <sys/pci_props.h>
153 #include <sys/sysmacros.h>
154 #include <sys/plat/pci_prd.h>
155 #include <pci_strings.h>
156 
157 typedef struct {
158 	uint8_t ppc_class;
159 	uint8_t ppc_subclass;
160 	uint8_t ppc_pi;
161 } pci_prop_class_t;
162 
163 static boolean_t
164 pci_prop_class_match(const pci_prop_data_t *prop, const pci_prop_class_t *class,
165     const size_t nclass, boolean_t check_pi)
166 {
167 	for (size_t i = 0; i < nclass; i++) {
168 		if (prop->ppd_class == class[i].ppc_class &&
169 		    prop->ppd_subclass == class[i].ppc_subclass &&
170 		    (!check_pi || prop->ppd_pi == class[i].ppc_pi)) {
171 			return (B_TRUE);
172 		}
173 	}
174 
175 	return (B_FALSE);
176 }
177 
178 /*
179  * This is used to determine if a given set of data indicates that we have
180  * encountered a VGA class code which should be given the "display" name. The
181  * following tuples of class, subclass, programming interface are VGA
182  * compatible:
183  *
184  * 0x00, 0x01, 0x00: The pre-class code VGA device
185  * 0x03, 0x00, 0x00: A VGA Compatible controller
186  * 0x03, 0x00, 0x01: A 8514 compatible controller
187  */
188 static const pci_prop_class_t pci_prop_vga_classes[] = {
189 	{ PCI_CLASS_NONE, PCI_NONE_VGA, 0x00 },
190 	{ PCI_CLASS_DISPLAY, PCI_DISPLAY_VGA, PCI_DISPLAY_IF_VGA },
191 	{ PCI_CLASS_DISPLAY, PCI_DISPLAY_VGA, PCI_DISPLAY_IF_8514 }
192 };
193 
194 static const pci_prop_class_t pci_prop_ioapic_classes[] = {
195 	{ PCI_CLASS_PERIPH, PCI_PERIPH_PIC, PCI_PERIPH_PIC_IF_IO_APIC },
196 	{ PCI_CLASS_PERIPH, PCI_PERIPH_PIC, PCI_PERIPH_PIC_IF_IOX_APIC },
197 };
198 
199 static const pci_prop_class_t pci_prop_isa_classes[] = {
200 	{ PCI_CLASS_BRIDGE, PCI_BRIDGE_ISA, 0 }
201 };
202 
203 static const pci_prop_class_t pci_prop_pcibridge_classes[] = {
204 	{ PCI_CLASS_BRIDGE, PCI_BRIDGE_PCI, 0 }
205 };
206 
207 boolean_t
208 pci_prop_class_is_vga(const pci_prop_data_t *prop)
209 {
210 	return (pci_prop_class_match(prop, pci_prop_vga_classes,
211 	    ARRAY_SIZE(pci_prop_vga_classes), B_TRUE));
212 }
213 
214 boolean_t
215 pci_prop_class_is_ioapic(const pci_prop_data_t *prop)
216 {
217 	return (pci_prop_class_match(prop, pci_prop_ioapic_classes,
218 	    ARRAY_SIZE(pci_prop_ioapic_classes), B_TRUE));
219 }
220 
221 /*
222  * Determine if a class indicates that it is ISA. Technically this should be
223  * checking the programming interface as only PI 0x00 is defined; however, this
224  * is the check that has historically been done and the PCI-SIG is unlikely to
225  * define additional programming interfaces for an ISA bridge.
226  */
227 boolean_t
228 pci_prop_class_is_isa(const pci_prop_data_t *prop)
229 {
230 	return (pci_prop_class_match(prop, pci_prop_isa_classes,
231 	    ARRAY_SIZE(pci_prop_isa_classes), B_FALSE));
232 }
233 
234 /*
235  * We don't check the programming class here because callers don't care if this
236  * is subtractive or not.
237  */
238 boolean_t
239 pci_prop_class_is_pcibridge(const pci_prop_data_t *prop)
240 {
241 	return (pci_prop_class_match(prop, pci_prop_pcibridge_classes,
242 	    ARRAY_SIZE(pci_prop_pcibridge_classes), B_FALSE));
243 }
244 
245 static const char *
246 pci_prop_nodename_prefix(const pci_prop_data_t *prop,
247     pci_prd_compat_flags_t flags)
248 {
249 	if ((flags & PCI_PRD_COMPAT_PCI_NODE_NAME) != 0) {
250 		return ("pci");
251 	}
252 
253 	if ((prop->ppd_flags & PCI_PROP_F_PCIE) != 0) {
254 		return ("pciex");
255 	} else {
256 		return ("pci");
257 	}
258 }
259 
260 static boolean_t
261 pci_prop_use_subsystem(const pci_prop_data_t *prop,
262     pci_prd_compat_flags_t flags)
263 {
264 	if ((flags & PCI_PRD_COMPAT_SUBSYS) != 0 &&
265 	    prop->ppd_header == PCI_HEADER_PPB) {
266 		return (B_FALSE);
267 	}
268 
269 	return (prop->ppd_subvid != 0);
270 }
271 
272 /*
273  * Name a device node per the theory statement.
274  */
275 pci_prop_failure_t
276 pci_prop_name_node(dev_info_t *dip, const pci_prop_data_t *prop)
277 {
278 	char buf[64];
279 	pci_prd_compat_flags_t flags = pci_prd_compat_flags();
280 
281 	if (pci_prop_class_is_vga(prop)) {
282 		(void) snprintf(buf, sizeof (buf), "display");
283 	} else if (pci_prop_class_is_isa(prop) &&
284 	    (flags & PCI_PRD_COMPAT_ISA) != 0) {
285 		(void) snprintf(buf, sizeof (buf), "isa");
286 	} else {
287 		const char *prefix = pci_prop_nodename_prefix(prop, flags);
288 
289 		if (pci_prop_use_subsystem(prop, flags)) {
290 			(void) snprintf(buf, sizeof (buf), "%s%x,%x", prefix,
291 			    prop->ppd_subvid, prop->ppd_subsys);
292 		} else {
293 			(void) snprintf(buf, sizeof (buf), "%s%x,%x", prefix,
294 			    prop->ppd_vendid, prop->ppd_devid);
295 		}
296 	}
297 
298 	if (ndi_devi_set_nodename(dip, buf, 0) != NDI_SUCCESS) {
299 		return (PCI_PROP_E_NDI);
300 	}
301 	return (PCI_PROP_OK);
302 }
303 
304 static uint8_t
305 pci_prop_get8(ddi_acc_handle_t acc, const pci_prop_data_t *prop, uint16_t off)
306 {
307 	if (acc == NULL) {
308 		return ((*pci_getb_func)(prop->ppd_bus, prop->ppd_dev,
309 		    prop->ppd_func, off));
310 	} else {
311 		return (pci_config_get8(acc, off));
312 	}
313 }
314 
315 static uint16_t
316 pci_prop_get16(ddi_acc_handle_t acc, const pci_prop_data_t *prop, uint16_t off)
317 {
318 	if (acc == NULL) {
319 		return ((*pci_getw_func)(prop->ppd_bus, prop->ppd_dev,
320 		    prop->ppd_func, off));
321 	} else {
322 		return (pci_config_get16(acc, off));
323 	}
324 }
325 
326 static uint32_t
327 pci_prop_get32(ddi_acc_handle_t acc, const pci_prop_data_t *prop, uint16_t off)
328 {
329 	if (acc == NULL) {
330 		return ((*pci_getl_func)(prop->ppd_bus, prop->ppd_dev,
331 		    prop->ppd_func, off));
332 	} else {
333 		return (pci_config_get32(acc, off));
334 	}
335 }
336 
337 static pci_prop_failure_t
338 pci_prop_data_fill_pcie(ddi_acc_handle_t acc, pci_prop_data_t *prop,
339     uint8_t cap_base)
340 {
341 	uint16_t pciecap;
342 	uint32_t slotcap;
343 	uint8_t vers;
344 
345 	pciecap = pci_prop_get16(acc, prop, cap_base + PCIE_PCIECAP);
346 	vers = pciecap & PCIE_PCIECAP_VER_MASK;
347 	switch (vers) {
348 	case PCIE_PCIECAP_VER_1_0:
349 	case PCIE_PCIECAP_VER_2_0:
350 		break;
351 	default:
352 		cmn_err(CE_WARN, "found device at b/d/f 0x%x/0x%x/0x%x with "
353 		    "PCIe capability with unsupported capability version: 0x%x",
354 		    prop->ppd_bus, prop->ppd_dev, prop->ppd_func, vers);
355 		return (PCI_PROP_E_BAD_PCIE_CAP);
356 	}
357 
358 	prop->ppd_flags |= PCI_PROP_F_PCIE;
359 	prop->ppd_pcie_type = pciecap & PCIE_PCIECAP_DEV_TYPE_MASK;
360 
361 	if ((pciecap & PCIE_PCIECAP_SLOT_IMPL) == 0) {
362 		return (PCI_PROP_OK);
363 	}
364 
365 	slotcap = pci_prop_get32(acc, prop, cap_base + PCIE_SLOTCAP);
366 	prop->ppd_slotno = PCIE_SLOTCAP_PHY_SLOT_NUM(slotcap);
367 	prop->ppd_flags |= PCI_PROP_F_SLOT_VALID;
368 	return (PCI_PROP_OK);
369 }
370 
371 /*
372  * Obtain basic information about a device and store it for future processing
373  * and for other code's general usage. This may be called early in boot before
374  * we feel like we should use the normal access routines or later in boot where
375  * the system opts to use normal DDI accesses. We accept either and make do with
376  * the rest.
377  *
378  * We err on the side of trying to be lenient with devices that are potentially
379  * a bit odd. Not all devices in the wild actually follow the spec.
380  */
381 pci_prop_failure_t
382 pci_prop_data_fill(ddi_acc_handle_t acc, uint8_t bus, uint8_t dev, uint8_t func,
383     pci_prop_data_t *prop)
384 {
385 	uint8_t htype, cap_off, max_cap = PCI_CAP_MAX_PTR;
386 	uint16_t status;
387 
388 	bzero(prop, sizeof (pci_prop_data_t));
389 	prop->ppd_bus = bus;
390 	prop->ppd_dev = dev;
391 	prop->ppd_func = func;
392 
393 	/*
394 	 * To fill this out, begin with getting things that are always going to
395 	 * be the same between different header types. We check the validity of
396 	 * the vendor ID as a proxy for hardware being present.
397 	 */
398 	prop->ppd_vendid = pci_prop_get16(acc, prop, PCI_CONF_VENID);
399 	if (prop->ppd_vendid == PCI_EINVAL16) {
400 		return (PCI_PROP_E_BAD_READ);
401 	}
402 	prop->ppd_devid = pci_prop_get16(acc, prop, PCI_CONF_DEVID);
403 	prop->ppd_rev = pci_prop_get8(acc, prop, PCI_CONF_REVID);
404 	prop->ppd_class = pci_prop_get8(acc, prop, PCI_CONF_BASCLASS);
405 	prop->ppd_subclass = pci_prop_get8(acc, prop, PCI_CONF_SUBCLASS);
406 	prop->ppd_pi = pci_prop_get8(acc, prop, PCI_CONF_PROGCLASS);
407 
408 	htype = pci_prop_get8(acc, prop, PCI_CONF_HEADER);
409 	prop->ppd_header = htype & PCI_HEADER_TYPE_M;
410 	if ((htype & PCI_HEADER_MULTI) != 0) {
411 		prop->ppd_flags |= PCI_PROP_F_MULT_FUNC;
412 	}
413 
414 
415 	/*
416 	 * Next, we get fields from the header that vary between device types or
417 	 * are specific to a given device type. Bridges do not have a subsystem
418 	 * ID at this point, instead we will fetch it out when we walk the basic
419 	 * capabilities.
420 	 */
421 	switch (prop->ppd_header) {
422 	case PCI_HEADER_ZERO:
423 		prop->ppd_subvid = pci_prop_get16(acc, prop,
424 		    PCI_CONF_SUBVENID);
425 		prop->ppd_subsys =  pci_prop_get16(acc, prop,
426 		    PCI_CONF_SUBSYSID);
427 		prop->ppd_mingrt = pci_prop_get8(acc, prop, PCI_CONF_MIN_G);
428 		prop->ppd_maxlat = pci_prop_get8(acc, prop, PCI_CONF_MAX_L);
429 		break;
430 	case PCI_HEADER_CARDBUS:
431 		prop->ppd_subvid = pci_prop_get16(acc, prop,
432 		    PCI_CBUS_SUBVENID);
433 		prop->ppd_subsys =  pci_prop_get16(acc, prop,
434 		    PCI_CBUS_SUBSYSID);
435 		break;
436 	case PCI_HEADER_PPB:
437 		break;
438 	default:
439 		return (PCI_PROP_E_UNKNOWN_HEADER);
440 	}
441 
442 	/*
443 	 * Capture registers which are used to derive various devinfo
444 	 * properties and are shared between all device types.
445 	 */
446 	prop->ppd_ipin = pci_prop_get8(acc, prop, PCI_CONF_IPIN);
447 	prop->ppd_status = pci_prop_get16(acc, prop, PCI_CONF_STAT);
448 
449 	/*
450 	 * If there are no capabilities, there is nothing else for us to do.
451 	 */
452 	status = pci_prop_get16(acc, prop, PCI_CONF_STAT);
453 	if ((status & PCI_STAT_CAP) == 0)
454 		return (PCI_PROP_OK);
455 
456 	cap_off = pci_prop_get8(acc, prop, PCI_CONF_CAP_PTR);
457 	for (; max_cap > 0 && cap_off >= PCI_CAP_PTR_OFF; max_cap--) {
458 		uint8_t cap_addr = cap_off & PCI_CAP_PTR_MASK;
459 		uint8_t cap_id = pci_prop_get8(acc, prop, cap_addr);
460 		pci_prop_failure_t ret;
461 
462 		/*
463 		 * Look for an invalid read as a proxy for this being in illegal
464 		 * capability and that we're done. We don't treat this as fatal
465 		 * as some devices will place the caps at weird places.
466 		 */
467 		if (cap_id == PCI_EINVAL8) {
468 			return (PCI_PROP_OK);
469 		}
470 
471 		switch (cap_id) {
472 		case PCI_CAP_ID_PCI_E:
473 			ret = pci_prop_data_fill_pcie(acc, prop, cap_addr);
474 			if (ret != PCI_PROP_OK) {
475 				return (ret);
476 			}
477 			break;
478 		case PCI_CAP_ID_P2P_SUBSYS:
479 			/*
480 			 * This is only legal in a type 1 header configuration
481 			 * space. If we encounter it elsewhere, warn about it,
482 			 * but don't fail.
483 			 */
484 			if (prop->ppd_header != PCI_HEADER_PPB) {
485 				cmn_err(CE_WARN, "found device at b/d/f "
486 				    "0x%x/0x%x/0x%x with PCI subsystem "
487 				    "capability, but wrong header type: 0x%x",
488 				    bus, dev, func, prop->ppd_header);
489 				break;
490 			}
491 
492 			prop->ppd_subvid = pci_prop_get16(acc, prop, cap_addr +
493 			    PCI_SUBSYSCAP_SUBVID);
494 			prop->ppd_subsys = pci_prop_get16(acc, prop, cap_addr +
495 			    PCI_SUBSYSCAP_SUBSYS);
496 			break;
497 		default:
498 			break;
499 		}
500 
501 		/*
502 		 * Again, we check for invalid capability offsets to try to flag
503 		 * the case of an invalid read. If we have a zero representing
504 		 * the end of the list, then we'll break out up above.
505 		 */
506 		cap_off = pci_prop_get8(acc, prop, cap_addr + PCI_CAP_NEXT_PTR);
507 		if (cap_off == PCI_EINVAL8) {
508 			return (PCI_PROP_OK);
509 		}
510 	}
511 
512 	return (PCI_PROP_OK);
513 }
514 
515 /*
516  * The IEEE 1275 slot-names property has a unique construction. It starts off
517  * with a uint32_t which is a bitmask of names for each device. Then there is a
518  * number of strings ordered based on the bitfield. The NDI doesn't have a great
519  * way to represent this combination of types so we are bound by history which
520  * says to use an int array. Yes, this is gross.
521  *
522  * For PCIe this is at least somewhat straightforward. We only ever have one
523  * device so our bitfield value is always 0x1. The name we use is also always
524  * "pcie<slot>".
525  */
526 static void
527 pci_prop_set_pciex_slot_name(dev_info_t *dip, uint16_t slotno)
528 {
529 	uint32_t slot[32];
530 	size_t len;
531 
532 	bzero(slot, sizeof (slot));
533 	slot[0] = 1;
534 
535 	/*
536 	 * We need to calculate the number of uint32_t's that we used. We round
537 	 * up the number of bytes used for the name, convert that to a number of
538 	 * uint32_t's and then add one for the bitfield.
539 	 */
540 	len = snprintf((char *)&slot[1], sizeof (slot) - sizeof (slot[0]),
541 	    "pcie%u", slotno) + 1;
542 	len = P2ROUNDUP(len, sizeof (uint32_t));
543 	len /= sizeof (uint32_t);
544 	len += 1;
545 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "slot-names",
546 	    (int *)slot, len);
547 }
548 
549 pci_prop_failure_t
550 pci_prop_set_common_props(dev_info_t *dip, const pci_prop_data_t *prop)
551 {
552 	int class;
553 	char unitaddr[16];
554 	pci_prd_compat_flags_t flags = pci_prd_compat_flags();
555 
556 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id",
557 	    prop->ppd_vendid);
558 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id",
559 	    prop->ppd_devid);
560 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "revision-id",
561 	    prop->ppd_rev);
562 
563 	class = (prop->ppd_class << 16) | (prop->ppd_subclass << 8) |
564 	    prop->ppd_pi;
565 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "class-code", class);
566 
567 	if (prop->ppd_subvid != 0) {
568 		(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
569 		    "subsystem-vendor-id", prop->ppd_subvid);
570 		(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "subsystem-id",
571 		    prop->ppd_subsys);
572 	}
573 
574 	if (prop->ppd_func > 0) {
575 		(void) snprintf(unitaddr, sizeof (unitaddr), "%x,%x",
576 		    prop->ppd_dev, prop->ppd_func);
577 	} else {
578 		(void) snprintf(unitaddr, sizeof (unitaddr), "%x",
579 		    prop->ppd_dev);
580 	}
581 	(void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "unit-address",
582 	    unitaddr);
583 
584 	/*
585 	 * Set properties specific to the device class (i.e. PCI or PCIe).
586 	 * While devsel-speed is meaningless for PCIe, this is still set
587 	 * anyways for it to match tradition.
588 	 */
589 	if ((prop->ppd_flags & PCI_PROP_F_PCIE) == 0) {
590 		if ((prop->ppd_status & PCI_STAT_FBBC) != 0) {
591 			(void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
592 			    "fast-back-to-back");
593 		}
594 
595 		if ((prop->ppd_status & PCI_STAT_66MHZ) != 0) {
596 			(void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
597 			    "66mhz-capable");
598 		}
599 
600 		if ((prop->ppd_status & PCI_STAT_UDF) != 0) {
601 			(void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
602 			    "udf-supported");
603 		}
604 
605 		if (prop->ppd_header == PCI_HEADER_ZERO) {
606 			(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
607 			    "min-grant", prop->ppd_mingrt);
608 
609 			(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
610 			    "max-latency", prop->ppd_maxlat);
611 		}
612 	} else {
613 		if ((prop->ppd_flags & PCI_PROP_F_SLOT_VALID) != 0) {
614 			(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
615 			    "physical-slot#", prop->ppd_slotno);
616 			if (prop->ppd_pcie_type !=
617 			    PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
618 				pci_prop_set_pciex_slot_name(dip,
619 				    prop->ppd_slotno);
620 			}
621 		}
622 	}
623 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "devsel-speed",
624 	    (prop->ppd_status & PCI_STAT_DEVSELT) >> 9);
625 
626 	/*
627 	 * The ipin indicates which INTx value a device should have. Zero
628 	 * indicates no INTx has been assigned.
629 	 */
630 	if (prop->ppd_ipin != 0) {
631 		(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "interrupts",
632 		    prop->ppd_ipin);
633 	}
634 
635 	/*
636 	 * VGA class devices have required specific device_type and related
637 	 * properties to be set. The same is true of ISA. Parent bridges and the
638 	 * synthetic nexus nodes that represent root complexes ala npe, pci,
639 	 * pcieb, etc. set the device type to either "pci" or "pciex", but that
640 	 * is not done universally at this time. We should consider that for the
641 	 * future.
642 	 */
643 	if (pci_prop_class_is_vga(prop)) {
644 		(void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
645 		    "device_type", "display");
646 	} else if (pci_prop_class_is_isa(prop) &&
647 	    (flags & PCI_PRD_COMPAT_ISA) != 0) {
648 		(void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
649 		    "device_type", "isa");
650 	}
651 
652 	/*
653 	 * Go through and add the model property. This utilizes the common PCI
654 	 * class codes. Traditionally a PCIe->PCI bridge was treated specially
655 	 * and given a unique label because of the fact it was crossing between
656 	 * the protocols (though the opposite wasn't true for PCI->PCIe
657 	 * bridges).
658 	 *
659 	 * The other traditional gotcha here is that any device whose class and
660 	 * subclass indicated it was an IDE controller got that name.
661 	 */
662 	if ((prop->ppd_flags & PCI_PROP_F_PCIE) != 0 &&
663 	    prop->ppd_pcie_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
664 		(void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
665 		    (char *)"PCIe-PCI bridge");
666 	} else if (prop->ppd_class == PCI_CLASS_MASS &&
667 	    prop->ppd_subclass == PCI_MASS_IDE) {
668 		(void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
669 		    (char *)"IDE controller");
670 	} else {
671 		const char *desc = NULL;
672 
673 		for (int i = 0; i < class_pci_items; i++) {
674 			if (prop->ppd_class == class_pci[i].base_class &&
675 			    prop->ppd_subclass == class_pci[i].sub_class &&
676 			    prop->ppd_pi == class_pci[i].prog_class) {
677 				desc = class_pci[i].actual_desc;
678 				break;
679 			}
680 		}
681 
682 		if (desc == NULL) {
683 			/*
684 			 * Yes, we're not dealing with PNP strictly any more,
685 			 * but this is the string we've traditionally used.
686 			 */
687 			desc = "Unknown class of pci/pnpbios device";
688 		}
689 
690 		(void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
691 		    (char *)desc);
692 	}
693 
694 	return (PCI_PROP_OK);
695 }
696 
697 
698 /*
699  * This enumeration encodes the different possible forms of the alias
700  * properties. In these definitions, the following groups of letters have
701  * different means:
702  *
703  * "VD": Vendor ID,Device ID (1234,5678)
704  * "SVSI": Subsystem Vendor ID, Subsystem ID
705  * "R": Revision
706  * "S": The string ,s to represent the disambiguated PCI subsystem alias
707  * "P": The string ,p to represent the disambiguated PCI primary alias
708  * "CSPI": Class, subclass, and Programming Interface
709  * "CS": Class, subclass
710  */
711 typedef enum {
712 	PCI_ALIAS_VD_SVSI_R,
713 	PCI_ALIAS_VD_SVSI,
714 	PCI_ALIAS_SVSI_S,
715 	PCI_ALIAS_SVSI,
716 	PCI_ALIAS_VD_R,
717 	PCI_ALIAS_VD_P,
718 	PCI_ALIAS_VD,
719 	PCI_ALIAS_CSPI,
720 	PCI_ALIAS_CS,
721 	PCI_ALIAS_MAX
722 } pci_alias_t;
723 
724 /*
725  * The upper bound on aliases is if everything is used once for PCIe and then
726  * again for PCI. This is more than should be used.
727  */
728 #define	PCI_MAX_ALIASES	(2 * PCI_ALIAS_MAX)
729 
730 typedef enum {
731 	/*
732 	 * This flag indicates that a given alias should only be used for PCI
733 	 * devices.
734 	 */
735 	PCI_ALIAS_F_PCI_ONLY		= 1 << 0,
736 	/*
737 	 * This flag indicates that this value should not be used for any device
738 	 * with a type 1 header, aka PCI-PCI bridges.
739 	 */
740 	PCI_ALIAS_F_SKIP_BRIDGE		= 1 << 1,
741 	/*
742 	 * This flag indicates that we should create subsystem compatibility
743 	 * IDs. We only expect this to be done on x86 (and SPARC historically).
744 	 */
745 	PCI_ALIAS_F_COMPAT		= 1 << 2,
746 	/*
747 	 * This flag indicates that we need to check whether we've banned the
748 	 * subsystem ID due to duplication. This is still something we do even
749 	 * when we don't have PCI_ALIAS_F_COMPAT set for the disambiguated
750 	 * subsystem ID.
751 	 */
752 	PCI_ALIAS_F_CHECK_SUBSYS	= 1 << 3
753 } pci_alias_flags_t;
754 
755 typedef struct {
756 	pci_alias_t pad_type;
757 	pci_alias_flags_t pad_flags;
758 } pci_alias_data_t;
759 
760 static const pci_alias_data_t pci_alias_table[] = {
761 	{ PCI_ALIAS_VD_SVSI_R, 0 },
762 	{ PCI_ALIAS_VD_SVSI, 0 },
763 	{ PCI_ALIAS_SVSI_S, PCI_ALIAS_F_PCI_ONLY | PCI_ALIAS_F_CHECK_SUBSYS },
764 	{ PCI_ALIAS_SVSI, PCI_ALIAS_F_PCI_ONLY | PCI_ALIAS_F_SKIP_BRIDGE |
765 	    PCI_ALIAS_F_COMPAT | PCI_ALIAS_F_CHECK_SUBSYS },
766 	{ PCI_ALIAS_VD_R, 0 },
767 	{ PCI_ALIAS_VD_P, PCI_ALIAS_F_PCI_ONLY },
768 	{ PCI_ALIAS_VD, 0 },
769 	{ PCI_ALIAS_CSPI, 0 },
770 	{ PCI_ALIAS_CS, 0 },
771 };
772 
773 /*
774  * Our big theory statement talks about cases where we already know that PCI IDs
775  * have had overlap with subsystems and them not being appropriate. The
776  * following table describes how to match
777  */
778 typedef enum {
779 	PCI_PROP_NSM_VID_CLASS,
780 	PCI_PROP_NSM_SUBSYS
781 } pci_prop_no_subsys_match_t;
782 
783 typedef boolean_t (*pci_prop_no_subsys_class_f)(const pci_prop_data_t *);
784 typedef struct pci_prop_no_subsys {
785 	pci_prop_no_subsys_match_t	ppnsm_type;
786 	uint16_t			ppnsm_vid;
787 	uint16_t			ppnsm_did;
788 	uint16_t			ppnsm_subvid;
789 	uint16_t			ppnsm_subsys;
790 	pci_prop_no_subsys_class_f	ppnsm_class;
791 } pci_prop_no_subsys_t;
792 
793 static const pci_prop_no_subsys_t pci_prop_no_subsys[] = {
794 	/*
795 	 * We've historically blocked nVidia subsystems because of subsystem
796 	 * reuse.
797 	 */
798 	{ .ppnsm_type = PCI_PROP_NSM_VID_CLASS, .ppnsm_vid = 0x10de,
799 	    .ppnsm_class = pci_prop_class_is_vga },
800 	/*
801 	 * 8086,166 is the Ivy Bridge built-in graphics controller on some
802 	 * models. Unfortunately 8086,2044 is the Skylake Server processor
803 	 * memory channel device. The Ivy Bridge device uses the Skylake
804 	 * ID as its sub-device ID. The GPU is not a memory controller DIMM
805 	 * channel.
806 	 */
807 	{ .ppnsm_type = PCI_PROP_NSM_SUBSYS, .ppnsm_vid = 0x8086,
808 	    .ppnsm_did = 0x166, .ppnsm_subvid = 0x8086, .ppnsm_subsys = 0x2044 }
809 };
810 
811 static boolean_t
812 pci_prop_skip_subsys(const pci_prop_data_t *prop)
813 {
814 	for (size_t i = 0; i < ARRAY_SIZE(pci_prop_no_subsys); i++) {
815 		const pci_prop_no_subsys_t *p = &pci_prop_no_subsys[i];
816 		switch (p->ppnsm_type) {
817 		case PCI_PROP_NSM_VID_CLASS:
818 			if (prop->ppd_vendid == p->ppnsm_vid &&
819 			    p->ppnsm_class(prop)) {
820 				return (B_TRUE);
821 			}
822 			break;
823 		case PCI_PROP_NSM_SUBSYS:
824 			if (prop->ppd_vendid == p->ppnsm_vid &&
825 			    prop->ppd_devid == p->ppnsm_did &&
826 			    prop->ppd_subvid == p->ppnsm_subvid &&
827 			    prop->ppd_subsys == p->ppnsm_subsys) {
828 				return (B_TRUE);
829 			}
830 			break;
831 		}
832 	}
833 	return (B_FALSE);
834 }
835 
836 static void
837 pci_prop_alias_pass(const pci_prop_data_t *prop, char **alias, uint_t *nalias,
838     pci_prd_compat_flags_t compat, boolean_t force_pci)
839 {
840 	boolean_t is_pci = force_pci ||
841 	    (prop->ppd_flags & PCI_PROP_F_PCIE) == 0;
842 	const char *prefix = is_pci ? "pci" : "pciex";
843 	boolean_t subsys_valid = prop->ppd_subvid != 0;
844 
845 	for (size_t i = 0; i < ARRAY_SIZE(pci_alias_table); i++) {
846 		const pci_alias_data_t *a = &pci_alias_table[i];
847 
848 		if ((a->pad_flags & PCI_ALIAS_F_PCI_ONLY) != 0 && !is_pci) {
849 			continue;
850 		}
851 
852 		if ((a->pad_flags & PCI_ALIAS_F_SKIP_BRIDGE) != 0 &&
853 		    prop->ppd_header == PCI_HEADER_PPB) {
854 			continue;
855 		}
856 
857 		if ((a->pad_flags & PCI_ALIAS_F_COMPAT) != 0 &&
858 		    (compat & PCI_PRD_COMPAT_SUBSYS) == 0) {
859 			continue;
860 		}
861 
862 		if ((a->pad_flags & PCI_ALIAS_F_CHECK_SUBSYS) != 0 &&
863 		    pci_prop_skip_subsys(prop)) {
864 			continue;
865 		}
866 
867 		switch (a->pad_type) {
868 		case PCI_ALIAS_VD_SVSI_R:
869 			if (!subsys_valid)
870 				continue;
871 			alias[*nalias] = kmem_asprintf("%s%x,%x.%x.%x.%x",
872 			    prefix, prop->ppd_vendid, prop->ppd_devid,
873 			    prop->ppd_subvid, prop->ppd_subsys,
874 			    prop->ppd_rev);
875 			break;
876 		case PCI_ALIAS_VD_SVSI:
877 			if (!subsys_valid)
878 				continue;
879 			alias[*nalias] = kmem_asprintf("%s%x,%x.%x.%x", prefix,
880 			    prop->ppd_vendid, prop->ppd_devid,
881 			    prop->ppd_subvid, prop->ppd_subsys);
882 			break;
883 		case PCI_ALIAS_SVSI_S:
884 			if (!subsys_valid)
885 				continue;
886 			alias[*nalias] = kmem_asprintf("%s%x,%x,s", prefix,
887 			    prop->ppd_subvid, prop->ppd_subsys);
888 			break;
889 		case PCI_ALIAS_SVSI:
890 			if (!subsys_valid)
891 				continue;
892 			alias[*nalias] = kmem_asprintf("%s%x,%x", prefix,
893 			    prop->ppd_subvid, prop->ppd_subsys);
894 			break;
895 		case PCI_ALIAS_VD_R:
896 			alias[*nalias] = kmem_asprintf("%s%x,%x.%x", prefix,
897 			    prop->ppd_vendid, prop->ppd_devid, prop->ppd_rev);
898 			break;
899 		case PCI_ALIAS_VD_P:
900 			alias[*nalias] = kmem_asprintf("%s%x,%x,p", prefix,
901 			    prop->ppd_vendid, prop->ppd_devid);
902 			break;
903 		case PCI_ALIAS_VD:
904 			alias[*nalias] = kmem_asprintf("%s%x,%x", prefix,
905 			    prop->ppd_vendid, prop->ppd_devid);
906 			break;
907 		case PCI_ALIAS_CSPI:
908 			alias[*nalias] = kmem_asprintf("%sclass,%02x%02x%02x",
909 			    prefix, prop->ppd_class, prop->ppd_subclass,
910 			    prop->ppd_pi);
911 			break;
912 		case PCI_ALIAS_CS:
913 			alias[*nalias] = kmem_asprintf("%sclass,%02x%02x",
914 			    prefix, prop->ppd_class, prop->ppd_subclass);
915 			break;
916 		default:
917 			panic("encountered unknown alias type: 0x%x",
918 			    a->pad_type);
919 		}
920 
921 		*nalias = *nalias + 1;
922 		ASSERT3U(*nalias, <=, PCI_MAX_ALIASES);
923 	}
924 }
925 
926 /*
927  * Go through the messy process of creating the compatible property. See the
928  * theory statement for more info.
929  */
930 pci_prop_failure_t
931 pci_prop_set_compatible(dev_info_t *dip, const pci_prop_data_t *prop)
932 {
933 	char *alias[PCI_MAX_ALIASES];
934 	uint_t nalias = 0;
935 	pci_prd_compat_flags_t compat = pci_prd_compat_flags();
936 	boolean_t two_sets = (compat & PCI_PRD_COMPAT_PCI_NODE_NAME) != 0;
937 
938 	pci_prop_alias_pass(prop, alias, &nalias, compat, B_FALSE);
939 	if (two_sets && (prop->ppd_flags & PCI_PROP_F_PCIE) != 0) {
940 		pci_prop_alias_pass(prop, alias, &nalias, compat, B_TRUE);
941 	}
942 
943 	(void) ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, "compatible",
944 	    alias, nalias);
945 	for (uint_t i = 0; i < nalias; i++) {
946 		strfree(alias[i]);
947 	}
948 	return (PCI_PROP_OK);
949 }
950