xref: /illumos-gate/usr/src/uts/intel/io/pci/pci_pci.c (revision 6ba597c5)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * PCI to PCI bus bridge nexus driver
28  */
29 
30 #include <sys/conf.h>
31 #include <sys/kmem.h>
32 #include <sys/debug.h>
33 #include <sys/modctl.h>
34 #include <sys/autoconf.h>
35 #include <sys/ddi_impldefs.h>
36 #include <sys/pci.h>
37 #include <sys/pci_impl.h>
38 #include <sys/pcie_impl.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/sunndi.h>
42 #include <sys/ddifm.h>
43 #include <sys/ndifm.h>
44 #include <sys/fm/protocol.h>
45 #include <sys/hotplug/pci/pcie_hp.h>
46 #include <sys/hotplug/pci/pcihp.h>
47 #include <sys/pci_intr_lib.h>
48 #include <sys/psm.h>
49 #include <sys/pci_cap.h>
50 
51 /*
52  * The variable controls the default setting of the command register
53  * for pci devices.  See ppb_initchild() for details.
54  */
55 static ushort_t ppb_command_default = PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO;
56 
57 
58 static int	ppb_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
59 		    off_t, off_t, caddr_t *);
60 static int	ppb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
61 		    void *, void *);
62 static int	ppb_fm_init(dev_info_t *, dev_info_t *, int,
63 		    ddi_iblock_cookie_t *);
64 static int	ppb_fm_callback(dev_info_t *, ddi_fm_error_t *, const void *);
65 static int	ppb_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
66 		    ddi_intr_handle_impl_t *, void *);
67 
68 /*
69  * ppb_support_msi: Flag that controls MSI support across P2P Bridges.
70  * By default, MSI is not supported except for special cases like HT
71  * bridges/tunnels that have HT MSI mapping enabled.
72  *
73  * However, MSI support behavior can be patched on a system by changing
74  * the value of this flag as shown below:-
75  *	 0 = default value, MSI is allowed by this driver for special cases
76  *	 1 = MSI supported without any checks for this driver
77  *	-1 = MSI not supported at all
78  */
79 int ppb_support_msi = 0;
80 
81 /*
82  * Controls the usage of the Hypertransport MSI mapping capability
83  *	0 = default value, leave hardware function as it is
84  *	1 = always enable HT MSI mapping
85  *     -1 = always disable HT MSI mapping
86  */
87 int ppb_support_ht_msimap = 0;
88 
89 struct bus_ops ppb_bus_ops = {
90 	BUSO_REV,
91 	ppb_bus_map,
92 	0,
93 	0,
94 	0,
95 	i_ddi_map_fault,
96 	ddi_dma_map,
97 	ddi_dma_allochdl,
98 	ddi_dma_freehdl,
99 	ddi_dma_bindhdl,
100 	ddi_dma_unbindhdl,
101 	ddi_dma_flush,
102 	ddi_dma_win,
103 	ddi_dma_mctl,
104 	ppb_ctlops,
105 	ddi_bus_prop_op,
106 	0,			/* (*bus_get_eventcookie)();	*/
107 	0,			/* (*bus_add_eventcall)();	*/
108 	0,			/* (*bus_remove_eventcall)();	*/
109 	0,			/* (*bus_post_event)();		*/
110 	0,			/* (*bus_intr_ctl)();		*/
111 	0,			/* (*bus_config)(); 		*/
112 	0,			/* (*bus_unconfig)(); 		*/
113 	ppb_fm_init,		/* (*bus_fm_init)(); 		*/
114 	NULL,			/* (*bus_fm_fini)(); 		*/
115 	NULL,			/* (*bus_fm_access_enter)(); 	*/
116 	NULL,			/* (*bus_fm_access_exit)(); 	*/
117 	NULL,			/* (*bus_power)(); 	*/
118 	ppb_intr_ops,		/* (*bus_intr_op)(); 		*/
119 	pcie_hp_common_ops	/* (*bus_hp_op)(); 		*/
120 };
121 
122 /*
123  * The goal here is to leverage off of the pcihp.c source without making
124  * changes to it.  Call into it's cb_ops directly if needed.
125  */
126 static int	ppb_open(dev_t *, int, int, cred_t *);
127 static int	ppb_close(dev_t, int, int, cred_t *);
128 static int	ppb_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
129 static int	ppb_prop_op(dev_t, dev_info_t *, ddi_prop_op_t, int, char *,
130 		    caddr_t, int *);
131 static int	ppb_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
132 static void	ppb_peekpoke_cb(dev_info_t *, ddi_fm_error_t *);
133 
134 struct cb_ops ppb_cb_ops = {
135 	ppb_open,			/* open */
136 	ppb_close,			/* close */
137 	nodev,				/* strategy */
138 	nodev,				/* print */
139 	nodev,				/* dump */
140 	nodev,				/* read */
141 	nodev,				/* write */
142 	ppb_ioctl,			/* ioctl */
143 	nodev,				/* devmap */
144 	nodev,				/* mmap */
145 	nodev,				/* segmap */
146 	nochpoll,			/* poll */
147 	ppb_prop_op,			/* cb_prop_op */
148 	NULL,				/* streamtab */
149 	D_NEW | D_MP | D_HOTPLUG,	/* Driver compatibility flag */
150 	CB_REV,				/* rev */
151 	nodev,				/* int (*cb_aread)() */
152 	nodev				/* int (*cb_awrite)() */
153 };
154 
155 
156 static int ppb_probe(dev_info_t *);
157 static int ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
158 static int ppb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
159 
160 struct dev_ops ppb_ops = {
161 	DEVO_REV,		/* devo_rev */
162 	0,			/* refcnt  */
163 	ppb_info,		/* info */
164 	nulldev,		/* identify */
165 	ppb_probe,		/* probe */
166 	ppb_attach,		/* attach */
167 	ppb_detach,		/* detach */
168 	nulldev,		/* reset */
169 	&ppb_cb_ops,		/* driver operations */
170 	&ppb_bus_ops,		/* bus operations */
171 	NULL,			/* power */
172 	ddi_quiesce_not_needed,		/* quiesce */
173 };
174 
175 /*
176  * Module linkage information for the kernel.
177  */
178 
179 static struct modldrv modldrv = {
180 	&mod_driverops, /* Type of module */
181 	"Standard PCI to PCI bridge nexus driver",
182 	&ppb_ops,	/* driver ops */
183 };
184 
185 static struct modlinkage modlinkage = {
186 	MODREV_1,
187 	(void *)&modldrv,
188 	NULL
189 };
190 
191 /*
192  * soft state pointer and structure template:
193  */
194 static void *ppb_state;
195 
196 typedef struct {
197 	dev_info_t *dip;
198 	int ppb_fmcap;
199 	ddi_iblock_cookie_t ppb_fm_ibc;
200 	kmutex_t ppb_mutex;
201 	kmutex_t ppb_peek_poke_mutex;
202 	kmutex_t ppb_err_mutex;
203 
204 	/*
205 	 * cpr support:
206 	 */
207 	uint_t config_state_index;
208 	struct {
209 		dev_info_t *dip;
210 		ushort_t command;
211 		uchar_t cache_line_size;
212 		uchar_t latency_timer;
213 		uchar_t header_type;
214 		uchar_t sec_latency_timer;
215 		ushort_t bridge_control;
216 	} config_state[PCI_MAX_CHILDREN];
217 
218 	uint16_t parent_bus;
219 } ppb_devstate_t;
220 
221 
222 /*
223  * forward function declarations:
224  */
225 static void	ppb_removechild(dev_info_t *);
226 static int	ppb_initchild(dev_info_t *child);
227 static void	ppb_save_config_regs(ppb_devstate_t *ppb_p);
228 static void	ppb_restore_config_regs(ppb_devstate_t *ppb_p);
229 static boolean_t	ppb_ht_msimap_check(ddi_acc_handle_t cfg_hdl);
230 static int	ppb_ht_msimap_set(ddi_acc_handle_t cfg_hdl, int cmd);
231 
232 /*
233  * for <cmd> in ppb_ht_msimap_set
234  */
235 #define	HT_MSIMAP_ENABLE	1
236 #define	HT_MSIMAP_DISABLE	0
237 
238 
239 int
240 _init(void)
241 {
242 	int e;
243 
244 	if ((e = ddi_soft_state_init(&ppb_state, sizeof (ppb_devstate_t),
245 	    1)) == 0 && (e = mod_install(&modlinkage)) != 0)
246 		ddi_soft_state_fini(&ppb_state);
247 	return (e);
248 }
249 
250 int
251 _fini(void)
252 {
253 	int e;
254 
255 	if ((e = mod_remove(&modlinkage)) == 0)
256 		ddi_soft_state_fini(&ppb_state);
257 	return (e);
258 }
259 
260 int
261 _info(struct modinfo *modinfop)
262 {
263 	return (mod_info(&modlinkage, modinfop));
264 }
265 
266 /*ARGSUSED*/
267 static int
268 ppb_probe(dev_info_t *devi)
269 {
270 	return (DDI_PROBE_SUCCESS);
271 }
272 
273 /*ARGSUSED*/
274 static int
275 ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
276 {
277 	dev_info_t *root = ddi_root_node();
278 	int instance;
279 	ppb_devstate_t *ppb;
280 	dev_info_t *pdip;
281 	ddi_acc_handle_t config_handle;
282 	char *bus;
283 	int ret;
284 
285 	switch (cmd) {
286 	case DDI_ATTACH:
287 
288 		/*
289 		 * Make sure the "device_type" property exists.
290 		 */
291 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
292 		    "device_type", "pci");
293 
294 		/*
295 		 * Allocate and get soft state structure.
296 		 */
297 		instance = ddi_get_instance(devi);
298 		if (ddi_soft_state_zalloc(ppb_state, instance) != DDI_SUCCESS)
299 			return (DDI_FAILURE);
300 		ppb = ddi_get_soft_state(ppb_state, instance);
301 		ppb->dip = devi;
302 
303 		/*
304 		 * don't enable ereports if immediate child of npe
305 		 */
306 		if (strcmp(ddi_driver_name(ddi_get_parent(devi)), "npe") == 0)
307 			ppb->ppb_fmcap = DDI_FM_ERRCB_CAPABLE |
308 			    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
309 		else
310 			ppb->ppb_fmcap = DDI_FM_EREPORT_CAPABLE |
311 			    DDI_FM_ERRCB_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
312 			    DDI_FM_DMACHK_CAPABLE;
313 
314 		ddi_fm_init(devi, &ppb->ppb_fmcap, &ppb->ppb_fm_ibc);
315 		mutex_init(&ppb->ppb_mutex, NULL, MUTEX_DRIVER, NULL);
316 		mutex_init(&ppb->ppb_err_mutex, NULL, MUTEX_DRIVER,
317 		    (void *)ppb->ppb_fm_ibc);
318 		mutex_init(&ppb->ppb_peek_poke_mutex, NULL, MUTEX_DRIVER,
319 		    (void *)ppb->ppb_fm_ibc);
320 
321 		if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
322 		    DDI_FM_EREPORT_CAPABLE))
323 			pci_ereport_setup(devi);
324 		if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
325 			ddi_fm_handler_register(devi, ppb_fm_callback, NULL);
326 
327 		if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) {
328 			if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
329 				ddi_fm_handler_unregister(devi);
330 			if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
331 			    DDI_FM_EREPORT_CAPABLE))
332 				pci_ereport_teardown(devi);
333 			ddi_fm_fini(devi);
334 			ddi_soft_state_free(ppb_state, instance);
335 			return (DDI_FAILURE);
336 		}
337 
338 		ppb->parent_bus = PCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO;
339 		for (pdip = ddi_get_parent(devi); pdip && (pdip != root) &&
340 		    (ppb->parent_bus != PCIE_PCIECAP_DEV_TYPE_PCIE_DEV);
341 		    pdip = ddi_get_parent(pdip)) {
342 			if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
343 			    DDI_PROP_DONTPASS, "device_type", &bus) !=
344 			    DDI_PROP_SUCCESS)
345 				break;
346 
347 			if (strcmp(bus, "pciex") == 0)
348 				ppb->parent_bus =
349 				    PCIE_PCIECAP_DEV_TYPE_PCIE_DEV;
350 
351 			ddi_prop_free(bus);
352 		}
353 
354 		if (ppb_support_ht_msimap == 1)
355 			(void) ppb_ht_msimap_set(config_handle,
356 			    HT_MSIMAP_ENABLE);
357 		else if (ppb_support_ht_msimap == -1)
358 			(void) ppb_ht_msimap_set(config_handle,
359 			    HT_MSIMAP_DISABLE);
360 
361 		pci_config_teardown(&config_handle);
362 
363 		/*
364 		 * Initialize hotplug support on this bus.
365 		 */
366 		if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
367 			ret = pcie_init(devi, NULL);
368 		else
369 			ret = pcihp_init(devi);
370 
371 		if (ret != DDI_SUCCESS) {
372 			cmn_err(CE_WARN,
373 			    "pci: Failed to setup hotplug framework");
374 			(void) ppb_detach(devi, DDI_DETACH);
375 			return (ret);
376 		}
377 
378 		ddi_report_dev(devi);
379 		return (DDI_SUCCESS);
380 
381 	case DDI_RESUME:
382 
383 		/*
384 		 * Get the soft state structure for the bridge.
385 		 */
386 		ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
387 		ppb_restore_config_regs(ppb);
388 		return (DDI_SUCCESS);
389 
390 	default:
391 		break;
392 	}
393 	return (DDI_FAILURE);
394 }
395 
396 /*ARGSUSED*/
397 static int
398 ppb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
399 {
400 	ppb_devstate_t *ppb;
401 	int		ret;
402 
403 	switch (cmd) {
404 	case DDI_DETACH:
405 		(void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "device_type");
406 
407 		ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
408 		if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
409 			ddi_fm_handler_unregister(devi);
410 		if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
411 		    DDI_FM_EREPORT_CAPABLE))
412 			pci_ereport_teardown(devi);
413 
414 		/*
415 		 * Uninitialize hotplug support on this bus.
416 		 */
417 		ret = (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) ?
418 		    pcie_uninit(devi) : pcihp_uninit(devi);
419 		if (ret != DDI_SUCCESS)
420 			return (DDI_FAILURE);
421 
422 		mutex_destroy(&ppb->ppb_peek_poke_mutex);
423 		mutex_destroy(&ppb->ppb_err_mutex);
424 		mutex_destroy(&ppb->ppb_mutex);
425 		ddi_fm_fini(devi);
426 
427 		/*
428 		 * And finally free the per-pci soft state.
429 		 */
430 		ddi_soft_state_free(ppb_state, ddi_get_instance(devi));
431 
432 		return (DDI_SUCCESS);
433 
434 	case DDI_SUSPEND:
435 		ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
436 		ppb_save_config_regs(ppb);
437 		return (DDI_SUCCESS);
438 
439 	default:
440 		break;
441 	}
442 	return (DDI_FAILURE);
443 }
444 
445 /*ARGSUSED*/
446 static int
447 ppb_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
448 	off_t offset, off_t len, caddr_t *vaddrp)
449 {
450 	dev_info_t *pdip;
451 	ppb_devstate_t *ppb = ddi_get_soft_state(ppb_state,
452 	    ddi_get_instance(dip));
453 
454 	if (strcmp(ddi_driver_name(ddi_get_parent(dip)), "npe") == 0 &&
455 	    mp->map_handlep != NULL) {
456 		ddi_acc_impl_t *hdlp =
457 		    (ddi_acc_impl_t *)(mp->map_handlep)->ah_platform_private;
458 		hdlp->ahi_err_mutexp = &ppb->ppb_err_mutex;
459 		hdlp->ahi_peekpoke_mutexp = &ppb->ppb_peek_poke_mutex;
460 		hdlp->ahi_scan_dip = dip;
461 		hdlp->ahi_scan = ppb_peekpoke_cb;
462 	}
463 	pdip = (dev_info_t *)DEVI(dip)->devi_parent;
464 	return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)(pdip,
465 	    rdip, mp, offset, len, vaddrp));
466 }
467 
468 /*ARGSUSED*/
469 static int
470 ppb_ctlops(dev_info_t *dip, dev_info_t *rdip,
471 	ddi_ctl_enum_t ctlop, void *arg, void *result)
472 {
473 	pci_regspec_t *drv_regp;
474 	int	reglen;
475 	int	rn;
476 	int	totreg;
477 	ppb_devstate_t *ppb = ddi_get_soft_state(ppb_state,
478 	    ddi_get_instance(dip));
479 	struct detachspec *dsp;
480 	struct attachspec *asp;
481 
482 	switch (ctlop) {
483 	case DDI_CTLOPS_REPORTDEV:
484 		if (rdip == (dev_info_t *)0)
485 			return (DDI_FAILURE);
486 		cmn_err(CE_CONT, "?PCI-device: %s@%s, %s%d\n",
487 		    ddi_node_name(rdip), ddi_get_name_addr(rdip),
488 		    ddi_driver_name(rdip),
489 		    ddi_get_instance(rdip));
490 		return (DDI_SUCCESS);
491 
492 	case DDI_CTLOPS_INITCHILD:
493 		return (ppb_initchild((dev_info_t *)arg));
494 
495 	case DDI_CTLOPS_UNINITCHILD:
496 		ppb_removechild((dev_info_t *)arg);
497 		return (DDI_SUCCESS);
498 
499 	case DDI_CTLOPS_SIDDEV:
500 		return (DDI_SUCCESS);
501 
502 	case DDI_CTLOPS_REGSIZE:
503 	case DDI_CTLOPS_NREGS:
504 		if (rdip == (dev_info_t *)0)
505 			return (DDI_FAILURE);
506 		break;
507 
508 	/* X86 systems support PME wakeup from suspend */
509 	case DDI_CTLOPS_ATTACH:
510 		if (!pcie_is_child(dip, rdip))
511 			return (DDI_SUCCESS);
512 
513 		asp = (struct attachspec *)arg;
514 		if ((ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) &&
515 		    (asp->when == DDI_POST) && (asp->result == DDI_SUCCESS))
516 			pf_init(rdip, (void *)ppb->ppb_fm_ibc, asp->cmd);
517 
518 		if (asp->cmd == DDI_RESUME && asp->when == DDI_PRE)
519 			if (pci_pre_resume(rdip) != DDI_SUCCESS)
520 				return (DDI_FAILURE);
521 
522 		return (DDI_SUCCESS);
523 
524 	case DDI_CTLOPS_DETACH:
525 		if (!pcie_is_child(dip, rdip))
526 			return (DDI_SUCCESS);
527 
528 		dsp = (struct detachspec *)arg;
529 		if ((ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) &&
530 		    (dsp->when == DDI_PRE))
531 			pf_fini(rdip, dsp->cmd);
532 
533 		if (dsp->cmd == DDI_SUSPEND && dsp->when == DDI_POST)
534 			if (pci_post_suspend(rdip) != DDI_SUCCESS)
535 				return (DDI_FAILURE);
536 
537 		return (DDI_SUCCESS);
538 
539 	case DDI_CTLOPS_PEEK:
540 	case DDI_CTLOPS_POKE:
541 		if (strcmp(ddi_driver_name(ddi_get_parent(dip)), "npe") != 0)
542 			return (ddi_ctlops(dip, rdip, ctlop, arg, result));
543 		return (pci_peekpoke_check(dip, rdip, ctlop, arg, result,
544 		    ddi_ctlops, &ppb->ppb_err_mutex,
545 		    &ppb->ppb_peek_poke_mutex, ppb_peekpoke_cb));
546 
547 	default:
548 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
549 	}
550 
551 	*(int *)result = 0;
552 	if (ddi_getlongprop(DDI_DEV_T_ANY, rdip,
553 	    DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg",
554 	    (caddr_t)&drv_regp, &reglen) != DDI_SUCCESS)
555 		return (DDI_FAILURE);
556 
557 	totreg = reglen / sizeof (pci_regspec_t);
558 	if (ctlop == DDI_CTLOPS_NREGS)
559 		*(int *)result = totreg;
560 	else if (ctlop == DDI_CTLOPS_REGSIZE) {
561 		rn = *(int *)arg;
562 		if (rn >= totreg) {
563 			kmem_free(drv_regp, reglen);
564 			return (DDI_FAILURE);
565 		}
566 		*(off_t *)result = drv_regp[rn].pci_size_low;
567 	}
568 
569 	kmem_free(drv_regp, reglen);
570 	return (DDI_SUCCESS);
571 }
572 
573 static int
574 ppb_name_child(dev_info_t *child, char *name, int namelen)
575 {
576 	pci_regspec_t *pci_rp;
577 	uint_t slot, func;
578 	char **unit_addr;
579 	uint_t n;
580 
581 	/*
582 	 * For .conf nodes, use unit-address property as name
583 	 */
584 	if (ndi_dev_is_persistent_node(child) == 0) {
585 		if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child,
586 		    DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) !=
587 		    DDI_PROP_SUCCESS) {
588 			cmn_err(CE_WARN,
589 			    "cannot find unit-address in %s.conf",
590 			    ddi_driver_name(child));
591 			return (DDI_FAILURE);
592 		}
593 		if (n != 1 || *unit_addr == NULL || **unit_addr == 0) {
594 			cmn_err(CE_WARN, "unit-address property in %s.conf"
595 			    " not well-formed", ddi_driver_name(child));
596 			ddi_prop_free(unit_addr);
597 			return (DDI_SUCCESS);
598 		}
599 		(void) snprintf(name, namelen, "%s", *unit_addr);
600 		ddi_prop_free(unit_addr);
601 		return (DDI_SUCCESS);
602 	}
603 
604 	/* get child "reg" property */
605 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child,
606 	    DDI_PROP_DONTPASS, "reg", (int **)&pci_rp, &n) != DDI_SUCCESS) {
607 		return (DDI_FAILURE);
608 	}
609 
610 	/* copy the device identifications */
611 	slot = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
612 	func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
613 
614 	if (func != 0)
615 		(void) snprintf(name, namelen, "%x,%x", slot, func);
616 	else
617 		(void) snprintf(name, namelen, "%x", slot);
618 
619 	ddi_prop_free(pci_rp);
620 	return (DDI_SUCCESS);
621 }
622 
623 static int
624 ppb_initchild(dev_info_t *child)
625 {
626 	struct ddi_parent_private_data *pdptr;
627 	ppb_devstate_t *ppb;
628 	char name[MAXNAMELEN];
629 	ddi_acc_handle_t config_handle;
630 	ushort_t command_preserve, command;
631 
632 	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
633 	    ddi_get_instance(ddi_get_parent(child)));
634 
635 	if (ppb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
636 		return (DDI_FAILURE);
637 	ddi_set_name_addr(child, name);
638 
639 	/*
640 	 * Pseudo nodes indicate a prototype node with per-instance
641 	 * properties to be merged into the real h/w device node.
642 	 * The interpretation of the unit-address is DD[,F]
643 	 * where DD is the device id and F is the function.
644 	 */
645 	if (ndi_dev_is_persistent_node(child) == 0) {
646 		extern int pci_allow_pseudo_children;
647 
648 		ddi_set_parent_data(child, NULL);
649 
650 		/*
651 		 * Try to merge the properties from this prototype
652 		 * node into real h/w nodes.
653 		 */
654 		if (ndi_merge_node(child, ppb_name_child) == DDI_SUCCESS) {
655 			/*
656 			 * Merged ok - return failure to remove the node.
657 			 */
658 			ddi_set_name_addr(child, NULL);
659 			return (DDI_FAILURE);
660 		}
661 
662 		/* workaround for ddivs to run under PCI */
663 		if (pci_allow_pseudo_children)
664 			return (DDI_SUCCESS);
665 
666 		/*
667 		 * The child was not merged into a h/w node,
668 		 * but there's not much we can do with it other
669 		 * than return failure to cause the node to be removed.
670 		 */
671 		cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
672 		    ddi_driver_name(child), ddi_get_name_addr(child),
673 		    ddi_driver_name(child));
674 		ddi_set_name_addr(child, NULL);
675 		return (DDI_NOT_WELL_FORMED);
676 	}
677 
678 	ddi_set_parent_data(child, NULL);
679 
680 	/*
681 	 * PCIe FMA specific
682 	 *
683 	 * Note: parent_data for parent is created only if this is PCI-E
684 	 * platform, for which, SG take a different route to handle device
685 	 * errors.
686 	 */
687 	if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
688 		if (pcie_init_cfghdl(child) != DDI_SUCCESS)
689 			return (DDI_FAILURE);
690 		pcie_init_dom(child);
691 	}
692 
693 	/* transfer select properties from PROM to kernel */
694 	if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS,
695 	    "interrupts", -1) != -1) {
696 		pdptr = kmem_zalloc((sizeof (struct ddi_parent_private_data) +
697 		    sizeof (struct intrspec)), KM_SLEEP);
698 		pdptr->par_intr = (struct intrspec *)(pdptr + 1);
699 		pdptr->par_nintr = 1;
700 		ddi_set_parent_data(child, pdptr);
701 	} else
702 		ddi_set_parent_data(child, NULL);
703 
704 	if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) {
705 		pcie_fini_dom(child);
706 		return (DDI_FAILURE);
707 	}
708 
709 	/*
710 	 * Support for the "command-preserve" property.
711 	 */
712 	command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
713 	    DDI_PROP_DONTPASS, "command-preserve", 0);
714 	command = pci_config_get16(config_handle, PCI_CONF_COMM);
715 	command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
716 	command |= (ppb_command_default & ~command_preserve);
717 	pci_config_put16(config_handle, PCI_CONF_COMM, command);
718 
719 	pci_config_teardown(&config_handle);
720 	return (DDI_SUCCESS);
721 }
722 
723 static void
724 ppb_removechild(dev_info_t *dip)
725 {
726 	struct ddi_parent_private_data *pdptr;
727 	ppb_devstate_t *ppb;
728 
729 	ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
730 	    ddi_get_instance(ddi_get_parent(dip)));
731 
732 	if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
733 		pcie_fini_dom(dip);
734 		pcie_fini_cfghdl(dip);
735 	} else if ((pdptr = ddi_get_parent_data(dip)) != NULL) {
736 		kmem_free(pdptr, (sizeof (*pdptr) + sizeof (struct intrspec)));
737 		ddi_set_parent_data(dip, NULL);
738 	}
739 	ddi_set_name_addr(dip, NULL);
740 
741 	/*
742 	 * Strip the node to properly convert it back to prototype form
743 	 */
744 	ddi_remove_minor_node(dip, NULL);
745 
746 	impl_rem_dev_props(dip);
747 }
748 
749 /*
750  * ppb_save_config_regs
751  *
752  * This routine saves the state of the configuration registers of all
753  * the child nodes of each PBM.
754  *
755  * used by: ppb_detach() on suspends
756  *
757  * return value: none
758  */
759 static void
760 ppb_save_config_regs(ppb_devstate_t *ppb_p)
761 {
762 	int i;
763 	dev_info_t *dip;
764 	ddi_acc_handle_t config_handle;
765 
766 	for (i = 0, dip = ddi_get_child(ppb_p->dip); dip != NULL;
767 	    i++, dip = ddi_get_next_sibling(dip)) {
768 
769 		if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
770 			cmn_err(CE_WARN, "%s%d: can't config space for %s%d\n",
771 			    ddi_driver_name(ppb_p->dip),
772 			    ddi_get_instance(ppb_p->dip),
773 			    ddi_driver_name(dip),
774 			    ddi_get_instance(dip));
775 			continue;
776 		}
777 
778 		ppb_p->config_state[i].dip = dip;
779 		ppb_p->config_state[i].command =
780 		    pci_config_get16(config_handle, PCI_CONF_COMM);
781 		pci_config_teardown(&config_handle);
782 	}
783 	ppb_p->config_state_index = i;
784 }
785 
786 
787 /*
788  * ppb_restore_config_regs
789  *
790  * This routine restores the state of the configuration registers of all
791  * the child nodes of each PBM.
792  *
793  * used by: ppb_attach() on resume
794  *
795  * return value: none
796  */
797 static void
798 ppb_restore_config_regs(ppb_devstate_t *ppb_p)
799 {
800 	int i;
801 	dev_info_t *dip;
802 	ddi_acc_handle_t config_handle;
803 
804 	for (i = 0; i < ppb_p->config_state_index; i++) {
805 		dip = ppb_p->config_state[i].dip;
806 		if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
807 			cmn_err(CE_WARN, "%s%d: can't config space for %s%d\n",
808 			    ddi_driver_name(ppb_p->dip),
809 			    ddi_get_instance(ppb_p->dip),
810 			    ddi_driver_name(dip),
811 			    ddi_get_instance(dip));
812 			continue;
813 		}
814 		pci_config_put16(config_handle, PCI_CONF_COMM,
815 		    ppb_p->config_state[i].command);
816 		pci_config_teardown(&config_handle);
817 	}
818 }
819 
820 
821 static boolean_t
822 ppb_ht_msimap_check(ddi_acc_handle_t cfg_hdl)
823 {
824 	uint16_t ptr;
825 
826 	if (pci_htcap_locate(cfg_hdl,
827 	    PCI_HTCAP_TYPE_MASK | PCI_HTCAP_MSIMAP_ENABLE_MASK,
828 	    PCI_HTCAP_MSIMAP_TYPE | PCI_HTCAP_MSIMAP_ENABLE, &ptr) !=
829 	    DDI_SUCCESS)
830 		return (B_FALSE);
831 
832 	return (B_TRUE);
833 }
834 
835 
836 static int
837 ppb_ht_msimap_set(ddi_acc_handle_t cfg_hdl, int cmd)
838 {
839 	uint16_t ptr;
840 	uint16_t reg;
841 
842 	if (pci_htcap_locate(cfg_hdl, PCI_HTCAP_TYPE_MASK,
843 	    PCI_HTCAP_MSIMAP_TYPE, &ptr) != DDI_SUCCESS)
844 		return (0);
845 
846 	reg = pci_config_get16(cfg_hdl, ptr + PCI_CAP_ID_REGS_OFF);
847 	switch (cmd) {
848 	case HT_MSIMAP_ENABLE:
849 		reg |= PCI_HTCAP_MSIMAP_ENABLE;
850 		break;
851 	case HT_MSIMAP_DISABLE:
852 	default:
853 		reg &= ~(uint16_t)PCI_HTCAP_MSIMAP_ENABLE;
854 	}
855 
856 	pci_config_put16(cfg_hdl, ptr + PCI_CAP_ID_REGS_OFF, reg);
857 	return (1);
858 }
859 
860 
861 /*
862  * intercept certain interrupt services to handle special cases
863  */
864 static int
865 ppb_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t intr_op,
866     ddi_intr_handle_impl_t *hdlp, void *result)
867 {
868 	ddi_acc_handle_t cfg_hdl;
869 	int rv = DDI_SUCCESS;
870 
871 	if (intr_op != DDI_INTROP_SUPPORTED_TYPES)
872 		return (i_ddi_intr_ops(pdip, rdip, intr_op, hdlp, result));
873 
874 	DDI_INTR_NEXDBG((CE_CONT,
875 	    "ppb_intr_ops: pdip 0x%p, rdip 0x%p, op %x handle 0x%p\n",
876 	    (void *)pdip, (void *)rdip, intr_op, (void *)hdlp));
877 
878 	/* Fixed interrupt is supported by default */
879 	*(int *)result = DDI_INTR_TYPE_FIXED;
880 
881 	if (ppb_support_msi == -1) {
882 		DDI_INTR_NEXDBG((CE_CONT,
883 		    "ppb_intr_ops: MSI is not allowed\n"));
884 		goto OUT;
885 	}
886 
887 	if (ppb_support_msi == 1) {
888 		DDI_INTR_NEXDBG((CE_CONT,
889 		    "ppb_intr_ops: MSI is always allowed\n"));
890 		rv = i_ddi_intr_ops(pdip, rdip, intr_op, hdlp, result);
891 		goto OUT;
892 	}
893 
894 	if (pci_config_setup(pdip, &cfg_hdl) != DDI_SUCCESS) {
895 		DDI_INTR_NEXDBG((CE_CONT,
896 		    "ppb_intr_ops: pci_config_setup() failed\n"));
897 		goto OUT;
898 	}
899 
900 	/*
901 	 * check for hypertransport msi mapping capability
902 	 */
903 	if (ppb_ht_msimap_check(cfg_hdl)) {
904 		DDI_INTR_NEXDBG((CE_CONT,
905 		    "ppb_intr_ops: HT MSI mapping enabled\n"));
906 		rv = i_ddi_intr_ops(pdip, rdip, intr_op, hdlp, result);
907 	}
908 
909 	/*
910 	 * if we add failure conditions after pci_config_setup, move this to
911 	 * OUT and use an extra flag to indicate the need to teardown cfg_hdl
912 	 */
913 	pci_config_teardown(&cfg_hdl);
914 
915 OUT:
916 	DDI_INTR_NEXDBG((CE_CONT,
917 	    "ppb_intr_ops: rdip 0x%p, returns supported types: 0x%x\n",
918 	    (void *)rdip, *(int *)result));
919 	return (rv);
920 }
921 
922 /* ARGSUSED */
923 static int
924 ppb_open(dev_t *devp, int flags, int otyp, cred_t *credp)
925 {
926 	int		instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(*devp));
927 	ppb_devstate_t	*ppb_p = ddi_get_soft_state(ppb_state, instance);
928 	int	rv;
929 
930 	if (ppb_p == NULL)
931 		return (ENXIO);
932 
933 	/*
934 	 * Ioctls will be handled by PCI Express framework for all
935 	 * PCIe platforms
936 	 */
937 	if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
938 		mutex_enter(&ppb_p->ppb_mutex);
939 		rv = pcie_open(ppb_p->dip, devp, flags, otyp, credp);
940 		mutex_exit(&ppb_p->ppb_mutex);
941 		return (rv);
942 	}
943 
944 	return ((pcihp_get_cb_ops())->cb_open(devp, flags, otyp, credp));
945 }
946 
947 /* ARGSUSED */
948 static int
949 ppb_close(dev_t dev, int flags, int otyp, cred_t *credp)
950 {
951 	int		instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev));
952 	ppb_devstate_t	*ppb_p = ddi_get_soft_state(ppb_state, instance);
953 	int	rv;
954 
955 	if (ppb_p == NULL)
956 		return (ENXIO);
957 
958 	mutex_enter(&ppb_p->ppb_mutex);
959 	/*
960 	 * Ioctls will be handled by PCI Express framework for all
961 	 * PCIe platforms
962 	 */
963 	if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
964 		rv = pcie_close(ppb_p->dip, dev, flags, otyp, credp);
965 		mutex_exit(&ppb_p->ppb_mutex);
966 		return (rv);
967 	}
968 
969 	mutex_exit(&ppb_p->ppb_mutex);
970 	return ((pcihp_get_cb_ops())->cb_close(dev, flags, otyp, credp));
971 }
972 
973 /*
974  * ppb_ioctl: devctl hotplug controls
975  */
976 /* ARGSUSED */
977 static int
978 ppb_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
979 	int *rvalp)
980 {
981 	int		instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev));
982 	ppb_devstate_t	*ppb_p = ddi_get_soft_state(ppb_state, instance);
983 
984 	if (ppb_p == NULL)
985 		return (ENXIO);
986 
987 	/*
988 	 * Ioctls will be handled by PCI Express framework for all
989 	 * PCIe platforms
990 	 */
991 	if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
992 		return (pcie_ioctl(ppb_p->dip, dev, cmd, arg, mode, credp,
993 		    rvalp));
994 
995 	return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd, arg, mode, credp,
996 	    rvalp));
997 }
998 
999 static int
1000 ppb_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int flags,
1001     char *name, caddr_t valuep, int *lengthp)
1002 {
1003 	int		instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev));
1004 	ppb_devstate_t	*ppb_p = ddi_get_soft_state(ppb_state, instance);
1005 
1006 	if (ppb_p == NULL)
1007 		return (ENXIO);
1008 
1009 	if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
1010 		return (pcie_prop_op(dev, dip, prop_op, flags, name,
1011 		    valuep, lengthp));
1012 
1013 	return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip, prop_op, flags,
1014 	    name, valuep, lengthp));
1015 }
1016 
1017 static int
1018 ppb_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
1019 {
1020 	minor_t		minor = getminor((dev_t)arg);
1021 	int		instance = PCI_MINOR_NUM_TO_INSTANCE(minor);
1022 	ppb_devstate_t	*ppb_p = ddi_get_soft_state(ppb_state, instance);
1023 
1024 	if (ppb_p == NULL)
1025 		return (DDI_FAILURE);
1026 
1027 	if (ppb_p->parent_bus != PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
1028 		return (pcihp_info(dip, cmd, arg, result));
1029 
1030 	switch (cmd) {
1031 	default:
1032 		return (DDI_FAILURE);
1033 
1034 	case DDI_INFO_DEVT2INSTANCE:
1035 		*result = (void *)(uintptr_t)instance;
1036 		return (DDI_SUCCESS);
1037 
1038 	case DDI_INFO_DEVT2DEVINFO:
1039 		if (ppb_p == NULL)
1040 			return (DDI_FAILURE);
1041 		*result = (void *)ppb_p->dip;
1042 		return (DDI_SUCCESS);
1043 	}
1044 }
1045 
1046 void ppb_peekpoke_cb(dev_info_t *dip, ddi_fm_error_t *derr) {
1047 	(void) pci_ereport_post(dip, derr, NULL);
1048 }
1049 
1050 /*ARGSUSED*/
1051 static int
1052 ppb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
1053     ddi_iblock_cookie_t *ibc)
1054 {
1055 	ppb_devstate_t  *ppb = ddi_get_soft_state(ppb_state,
1056 	    ddi_get_instance(dip));
1057 
1058 	ASSERT(ibc != NULL);
1059 	*ibc = ppb->ppb_fm_ibc;
1060 
1061 	return (ppb->ppb_fmcap);
1062 }
1063 
1064 /*ARGSUSED*/
1065 static int
1066 ppb_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used)
1067 {
1068 	ppb_devstate_t  *ppb = ddi_get_soft_state(ppb_state,
1069 	    ddi_get_instance(dip));
1070 
1071 	mutex_enter(&ppb->ppb_err_mutex);
1072 	pci_ereport_post(dip, derr, NULL);
1073 	mutex_exit(&ppb->ppb_err_mutex);
1074 	return (derr->fme_status);
1075 }
1076