xref: /illumos-gate/usr/src/uts/sun4u/io/pci/db21554.c (revision 88b44bf4e73233af70877930178dbff7f1c2992b)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
27  */
28 
29 
30 /*
31  *	Intel 21554 PCI to PCI bus bridge nexus driver for sun4u platforms.
32  *	Please note that 21554 is not a transparent bridge.
33  *	This driver can be used when the 21554 bridge is used like a
34  *	transparent bridge. The host OBP or the OS PCI Resource Allocator
35  *	(during a hotplug/hotswap operation) must represent this device
36  *	as a nexus and do the device tree representation of the child
37  *	nodes underneath.
38  *	Interrupt routing of the children must be done as per the PCI
39  *	specifications recommendation similar to that of a transparent
40  *	bridge.
41  *	Address translations from secondary across primary can be 1:1
42  *	or non 1:1. Currently only 1:1 translations are supported.
43  *	Configuration cycles are indirect. Memory and IO cycles are direct.
44  */
45 
46 /*
47  * INCLUDES
48  */
49 #include <sys/stat.h>
50 #include <sys/conf.h>
51 #include <sys/kmem.h>
52 #include <sys/debug.h>
53 #include <sys/modctl.h>
54 #include <sys/autoconf.h>
55 #include <sys/ddi_impldefs.h>
56 #include <sys/ddi_subrdefs.h>
57 #include <sys/pci.h>
58 #include <sys/pci/pci_nexus.h>
59 #include <sys/pci/pci_regs.h>
60 #include <sys/pci/db21554_config.h> /* 21554 configuration space registers */
61 #include <sys/pci/db21554_csr.h> /* 21554 control status register layout */
62 #include <sys/pci/db21554_ctrl.h> /* driver private control structure	*/
63 #include <sys/pci/db21554_debug.h> /* driver debug declarations		*/
64 #include <sys/ddi.h>
65 #include <sys/sunddi.h>
66 #include <sys/sunndi.h>
67 #include <sys/fm/protocol.h>
68 #include <sys/ddifm.h>
69 #include <sys/promif.h>
70 #include <sys/file.h>
71 #include <sys/hotplug/pci/pcihp.h>
72 
73 /*
74  * DEFINES.
75  */
76 #define	DB_DEBUG
77 #define	DB_MODINFO_DESCRIPTION	"Intel/21554 pci-pci nexus"
78 #define	DB_DVMA_START		0xc0000000
79 #define	DB_DVMA_LEN		0x20000000
80 
81 #ifdef	DB_DEBUG
82 /* ioctl definitions */
83 #define	DB_PCI_READ_CONF_HEADER		1
84 #define	DEF_INVALID_REG_VAL		-1
85 
86 /* Default values for secondary cache line and latency timer */
87 #define	DB_SEC_LATENCY_TIMER_VAL	0x40
88 #define	DB_SEC_CACHELN_SIZE_VAL		0x10
89 
90 /* complete chip status information */
91 typedef struct db_pci_data {
92 	char		name[256];
93 	uint32_t	instance;
94 	db_pci_header_t pri_hdr;
95 	db_pci_header_t sec_hdr;
96 	db_conf_regs_t	conf_regs;
97 } db_pci_data_t;
98 #endif
99 
100 /*
101  * LOCALS
102  */
103 
104 /*
105  * The next set of variables are control parameters for debug purposes only.
106  * Changing the default values as assigned below are not recommended.
107  * In some cases, the non-default values are mostly application specific and
108  * hence may not have been tested yet.
109  *
110  *	db_conf_map_mode : specifies the access method used for generating
111  *			   configuration cycles. Default value indicates
112  *			   the indirect configuration method.
113  *	db_io_map_mode	 : specifies the access method used for generating
114  *			   IO cycles. Default value indicates the direct
115  *			   method.
116  *	db_pci_own_wait	 : For indirect cycles, indicates the wait period
117  *			   for acquiring the bus, when the bus is busy.
118  *	db_pci_release_wait:For indirect cycles, indicates the wait period
119  *			    for releasing the bus when the bus is busy.
120  *	db_pci_max_wait  : max. wait time when bus is busy for indirect cycles
121  *	db_set_latency_timer_register :
122  *			   when 1, the driver overwrites the OBP assigned
123  *			   latency timer register setting for every child
124  *			   device during child initialization.
125  *	db_set_cache_line_size_register :
126  *			   when 1, the driver overwrites the OBP assigned
127  *			   cache line register setting for every child
128  *			   device during child initialization.
129  *	db_use_config_own_bit:
130  *			   when 1, the driver will use the "config own bit"
131  *			   for accessing the configuration address and data
132  *			   registers.
133  */
134 static uint32_t	db_pci_own_wait = DB_PCI_WAIT_MS;
135 static uint32_t	db_pci_release_wait = DB_PCI_WAIT_MS;
136 static uint32_t	db_pci_max_wait = DB_PCI_TIMEOUT;
137 static uint32_t	db_conf_map_mode = DB_CONF_MAP_INDIRECT_CONF;
138 static uint32_t	db_io_map_mode = DB_IO_MAP_DIRECT;
139 static uint32_t	db_set_latency_timer_register = 1;
140 static uint32_t	db_set_cache_line_size_register = 1;
141 static uint32_t	db_use_config_own_bit = 0;
142 
143 /*
144  * Properties that can be set via .conf files.
145  */
146 
147 /*
148  * By default, we forward SERR# from secondary to primary. This behavior
149  * can be controlled via a property "serr-fwd-enable", type integer.
150  * Values are 0 or 1.
151  * 0 means 'do not forward SERR#'.
152  * 1 means forwards SERR# to the host. Should be the default.
153  */
154 static uint32_t	db_serr_fwd_enable = 1;
155 
156 /*
157  * The next set of parameters are performance tuning parameters.
158  * These are in the form of properties settable through a .conf file.
159  * In case if the properties are absent the following defaults are assumed.
160  * These initial default values can be overwritten via /etc/system also.
161  *
162  * -1 means no setting is done ie. we either get OBP assigned value
163  * or reset values (at hotplug time for example).
164  */
165 
166 /* primary latency timer: property "p-latency-timer" : type integer */
167 static int8_t	p_latency_timer = DEF_INVALID_REG_VAL;
168 
169 /* secondary latency timer: property "s-latency-timer": type integer */
170 /*
171  * Currently on the secondary side the latency timer  is not
172  * set by the serial PROM which causes performance degradation.
173  * Set the secondary latency timer register.
174  */
175 static int8_t	s_latency_timer = DB_SEC_LATENCY_TIMER_VAL;
176 
177 /* primary cache line size: property "p-cache-line-size" : type integer */
178 static int8_t	p_cache_line_size = DEF_INVALID_REG_VAL;
179 
180 /* secondary cache line size: property "s-cache-line-size" : type integer */
181 /*
182  * Currently on the secondary side the cache line size is not
183  * set by the serial PROM which causes performance degradation.
184  * Set the secondary cache line size register.
185  */
186 static int8_t	s_cache_line_size = DB_SEC_CACHELN_SIZE_VAL;
187 
188 /*
189  * control primary posted write queue threshold limit:
190  * property "p-pwrite-threshold" : type integer : values are 0 or 1.
191  * 1 enables control. 0 does not, and is the default reset value.
192  */
193 static int8_t	p_pwrite_threshold = DEF_INVALID_REG_VAL;
194 
195 /*
196  * control secondary posted write queue threshold limit:
197  * property "s-pwrite-threshold" : type integer : values are 0 or 1.
198  * 1 enables control. 0 does not, and is the default reset value.
199  */
200 static int8_t	s_pwrite_threshold = DEF_INVALID_REG_VAL;
201 
202 /*
203  * control read queue threshold for initiating delayed read transaction
204  * on primary bus.
205  * property "p-dread-threshold" : type integer: values are
206  *
207  * 0 : reset value, default behavior: at least 8DWords free for all MR
208  * 1 : reserved
209  * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR
210  * 3 : at least one cache line free for all MR
211  */
212 static int8_t	p_dread_threshold = DEF_INVALID_REG_VAL;
213 
214 /*
215  * control read queue threshold for initiating delayed read transaction
216  * on secondary bus.
217  * property "s-dread-threshold" : type integer: values are
218  *
219  * 0 : reset value, default behavior: at least 8DWords free for all MR
220  * 1 : reserved
221  * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR
222  * 3 : at least one cache line free for all MR
223  */
224 static int8_t	s_dread_threshold = DEF_INVALID_REG_VAL;
225 
226 /*
227  * control how 21554 issues delayed transactions on the target bus.
228  * property "delayed-trans-order" : type integer: values are 0 or 1.
229  * 1 means repeat transaction on same target on target retries.
230  * 0 is the reset/default value, and means enable round robin based
231  * reads on  other targets in read queue on any target retries.
232  */
233 static int8_t	delayed_trans_order = DEF_INVALID_REG_VAL;
234 
235 /*
236  * In case if the system DVMA information is not available, as it is
237  * prior to s28q1, the system dvma range can be set via these parameters.
238  */
239 static uint32_t	db_dvma_start = DB_DVMA_START;
240 static uint32_t	db_dvma_len = DB_DVMA_LEN;
241 
242 /*
243  * Default command register settings for all PCI nodes this nexus initializes.
244  */
245 static uint16_t	db_command_default =
246 			PCI_COMM_SERR_ENABLE |
247 			PCI_COMM_PARITY_DETECT |
248 			PCI_COMM_ME |
249 			PCI_COMM_MAE |
250 			PCI_COMM_IO |
251 			PCI_COMM_BACK2BACK_ENAB |
252 			PCI_COMM_MEMWR_INVAL;
253 
254 static int	db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
255 static int	db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
256 static void	db_get_perf_parameters(db_ctrl_t *dbp);
257 static void	db_set_perf_parameters(db_ctrl_t *dbp);
258 static void	db_enable_io(db_ctrl_t *dbp);
259 static void	db_orientation(db_ctrl_t *dbp);
260 static void	db_set_dvma_range(db_ctrl_t *dbp);
261 static int	db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
262 			void **result);
263 static int	db_pci_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
264 			off_t, off_t, caddr_t *);
265 static int	db_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
266 			void *, void *);
267 static int	db_intr_ops(dev_info_t *dip, dev_info_t *rdip,
268 			ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp,
269 			void *result);
270 static dev_info_t *db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip);
271 static int db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap,
272 		ddi_iblock_cookie_t *ibc);
273 static void db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle);
274 static void db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle);
275 
276 struct bus_ops db_bus_ops = {
277 	BUSO_REV,
278 	db_pci_map,
279 	0,
280 	0,
281 	0,
282 	i_ddi_map_fault,
283 	0,
284 	ddi_dma_allochdl,
285 	ddi_dma_freehdl,
286 	ddi_dma_bindhdl,
287 	ddi_dma_unbindhdl,
288 	ddi_dma_flush,
289 	ddi_dma_win,
290 	ddi_dma_mctl,
291 	db_ctlops,
292 	ddi_bus_prop_op,
293 	ndi_busop_get_eventcookie,
294 	ndi_busop_add_eventcall,
295 	ndi_busop_remove_eventcall,
296 	ndi_post_event,
297 	0,
298 	0,
299 	0,
300 	db_fm_init_child,
301 	NULL,
302 	db_bus_enter,
303 	db_bus_exit,
304 	0,
305 	db_intr_ops
306 };
307 
308 static int	db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p);
309 static int	db_close(dev_t dev, int flag, int otyp, cred_t *cred_p);
310 static int	db_ioctl(dev_t dev, int cmd, intptr_t arg, int flag,
311 			cred_t *cred_p, int *rval_p);
312 #ifdef	DB_DEBUG
313 static dev_info_t *db_lookup_child_name(db_ctrl_t *dbp, char *name,
314 			int instance);
315 static void	db_pci_get_header(ddi_acc_handle_t config_handle,
316 			db_pci_header_t *ph, off_t hdr_off);
317 static void	db_pci_get_conf_regs(ddi_acc_handle_t config_handle,
318 			db_conf_regs_t *cr);
319 #endif	/* DB_DEBUG */
320 
321 #ifdef DEBUG
322 static void
323 db_debug(uint64_t func_id, dev_info_t *dip, char *fmt,
324 	uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5);
325 #endif
326 
327 static int db_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
328     int flags, char *name, caddr_t valuep, int *lengthp);
329 
330 static struct cb_ops db_cb_ops = {
331 	db_open,			/* open */
332 	db_close,			/* close */
333 	nulldev,			/* strategy */
334 	nulldev,			/* print */
335 	nulldev,			/* dump */
336 	nulldev,			/* read */
337 	nulldev,			/* write */
338 	db_ioctl,			/* ioctl */
339 	nodev,				/* devmap */
340 	nodev,				/* mmap */
341 	nodev,				/* segmap */
342 	nochpoll,			/* poll */
343 	db_prop_op,			/* cb_prop_op */
344 	NULL,				/* streamtab */
345 	D_NEW | D_MP | D_HOTPLUG,	/* Driver compatibility flag */
346 	CB_REV,				/* rev */
347 	nodev,				/* int (*cb_aread)() */
348 	nodev				/* int (*cb_awrite)() */
349 };
350 
351 static uint8_t 	db_ddi_get8(ddi_acc_impl_t *handle, uint8_t *addr);
352 static uint16_t db_ddi_get16(ddi_acc_impl_t *handle, uint16_t *addr);
353 static uint32_t db_ddi_get32(ddi_acc_impl_t *handle, uint32_t *addr);
354 static uint64_t db_ddi_get64(ddi_acc_impl_t *handle, uint64_t *addr);
355 static void 	db_ddi_put8(ddi_acc_impl_t *handle, uint8_t *addr,
356 			uint8_t data);
357 static void 	db_ddi_put16(ddi_acc_impl_t *handle, uint16_t *addr,
358 			uint16_t data);
359 static void 	db_ddi_put32(ddi_acc_impl_t *handle, uint32_t *addr,
360 			uint32_t data);
361 static void 	db_ddi_put64(ddi_acc_impl_t *handle, uint64_t *addr,
362 			uint64_t data);
363 static void 	db_ddi_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr,
364 			uint8_t *dev_addr, size_t repcount, uint_t flags);
365 static void 	db_ddi_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr,
366 			uint16_t *dev_addr, size_t repcount, uint_t flags);
367 static void 	db_ddi_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr,
368 			uint32_t *dev_addr, size_t repcount, uint_t flags);
369 static void 	db_ddi_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr,
370 			uint64_t *dev_addr, size_t repcount, uint_t flags);
371 static void 	db_ddi_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr,
372 			uint8_t *dev_addr, size_t repcount, uint_t flags);
373 static void 	db_ddi_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr,
374 			uint16_t *dev_addr, size_t repcount, uint_t flags);
375 static void 	db_ddi_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr,
376 			uint32_t *dev_addr, size_t repcount, uint_t flags);
377 static void 	db_ddi_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr,
378 			uint64_t *dev_addr, size_t repcount, uint_t flags);
379 
380 static struct dev_ops db_dev_ops = {
381 	DEVO_REV,		/* devo_rev */
382 	0,			/* refcnt  */
383 	db_getinfo,		/* info */
384 	nulldev,		/* identify */
385 	nulldev,		/* probe */
386 	db_attach,		/* attach */
387 	db_detach,		/* detach */
388 	nulldev,		/* reset */
389 	&db_cb_ops,		/* driver operations */
390 	&db_bus_ops,		/* bus operations */
391 	ddi_power,
392 	ddi_quiesce_not_supported,	/* devo_quiesce */
393 };
394 
395 
396 /*
397  * Module linkage information for the kernel.
398  */
399 
400 static struct modldrv modldrv = {
401 	&mod_driverops, /* Type of module */
402 	DB_MODINFO_DESCRIPTION,
403 	&db_dev_ops	/* driver ops */
404 };
405 
406 static struct modlinkage modlinkage = {
407 	MODREV_1,
408 	(void *)&modldrv,
409 	NULL
410 };
411 
412 /* soft state pointer and structure template. */
413 static void 	*db_state;
414 
415 /*
416  * forward function declarations:
417  */
418 static void	db_uninitchild(dev_info_t *);
419 static int 	db_initchild(dev_info_t *child);
420 static int 	db_create_pci_prop(dev_info_t *child);
421 static int 	db_save_config_regs(db_ctrl_t *dbp);
422 static int 	db_restore_config_regs(db_ctrl_t *dbp);
423 
424 /*
425  * FMA error callback
426  * Register error handling callback with our parent. We will just call
427  * our children's error callbacks and return their status.
428  */
429 static int db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr,
430 		const void *impl_data);
431 
432 /*
433  * init/fini routines to alloc/dealloc fm structures and
434  * register/unregister our callback.
435  */
436 static void db_fm_init(db_ctrl_t *db_p);
437 static void db_fm_fini(db_ctrl_t *db_p);
438 
439 int
440 _init(void)
441 {
442 	int rc;
443 
444 	DB_DEBUG0(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "enter\n");
445 	if (((rc = ddi_soft_state_init(&db_state,
446 	    sizeof (db_ctrl_t), 1)) == 0) &&
447 	    ((rc = mod_install(&modlinkage)) != 0))
448 		ddi_soft_state_fini(&db_state);
449 	DB_DEBUG1(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc);
450 	return (rc);
451 }
452 
453 
454 int
455 _fini(void)
456 {
457 	int rc;
458 
459 	DB_DEBUG0(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "enter\n");
460 	if ((rc = mod_remove(&modlinkage)) == 0)
461 		ddi_soft_state_fini(&db_state);
462 	DB_DEBUG1(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc);
463 	return (rc);
464 }
465 
466 int
467 _info(struct modinfo *modinfop)
468 {
469 	int rc;
470 	rc = mod_info(&modlinkage, modinfop);
471 	DB_DEBUG1(DB_INFO|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc);
472 	return (rc);
473 }
474 
475 /*ARGSUSED*/
476 static int
477 db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
478 {
479 	db_ctrl_t *dbp;
480 	int rc = DDI_FAILURE;
481 	minor_t		minor = getminor((dev_t)arg);
482 	int		instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
483 
484 	DB_DEBUG1(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip, "enter:cmd=%d\n",
485 	    infocmd);
486 
487 	switch (infocmd) {
488 		case DDI_INFO_DEVT2DEVINFO:
489 
490 			if ((dbp = ddi_get_soft_state(db_state,
491 			    instance)) != NULL) {
492 				*result = dbp->dip;
493 				rc = DDI_SUCCESS;
494 			} else
495 				*result = NULL;
496 			break;
497 
498 		case DDI_INFO_DEVT2INSTANCE:
499 			*result = (void *)(uintptr_t)instance;
500 			rc = DDI_SUCCESS;
501 			break;
502 
503 		default:
504 			break;
505 	}
506 	DB_DEBUG2(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip,
507 	    "exit: result=%x, rc=%d\n", *result, rc);
508 
509 	return (rc);
510 }
511 
512 static int
513 db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
514 {
515 	int instance = ddi_get_instance(dip);
516 	db_ctrl_t	*dbp;
517 	int		rc = DDI_SUCCESS;
518 	ddi_device_acc_attr_t db_csr_attr = {	/* CSR map attributes */
519 		DDI_DEVICE_ATTR_V0,
520 		DDI_STRUCTURE_LE_ACC,
521 		DDI_STRICTORDER_ACC
522 	};
523 	off_t bar_size;
524 	int range_size;
525 	char name[32];
526 
527 	DB_DEBUG1(DB_ATTACH, dip, "enter: cmd=%d\n", cmd);
528 	switch (cmd) {
529 
530 	case DDI_ATTACH:
531 		if (ddi_soft_state_zalloc(db_state, instance) != DDI_SUCCESS) {
532 			rc = DDI_FAILURE;
533 			break;
534 		}
535 
536 		dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
537 
538 		dbp->dip = dip;
539 		mutex_init(&dbp->db_mutex, NULL, MUTEX_DRIVER, NULL);
540 		dbp->db_soft_state = DB_SOFT_STATE_CLOSED;
541 
542 		/*
543 		 * Cannot use pci_config_setup here as we'd need
544 		 * to get a pointer to the address map to be able
545 		 * to set the bus private handle during child map
546 		 * operation.
547 		 */
548 		if ((rc = ddi_regs_map_setup(dip, DB_PCI_CONF_RNUMBER,
549 		    (caddr_t *)&dbp->conf_io, DB_PCI_CONF_OFFSET,
550 		    PCI_CONF_HDR_SIZE, &db_csr_attr, &dbp->conf_handle))
551 		    != DDI_SUCCESS) {
552 
553 			cmn_err(CE_WARN,
554 			    "%s#%d: cannot map configuration space",
555 			    ddi_driver_name(dip), ddi_get_instance(dip));
556 			mutex_destroy(&dbp->db_mutex);
557 			ddi_soft_state_free(db_state, instance);
558 			rc = DDI_FAILURE;
559 			break;
560 		}
561 
562 		db_get_perf_parameters(dbp);
563 
564 		if (ddi_dev_regsize(dip, DB_CSR_MEMBAR_RNUMBER, &bar_size)
565 		    != DDI_SUCCESS) {
566 			cmn_err(CE_WARN, "%s#%d: cannot get memory CSR size",
567 			    ddi_driver_name(dbp->dip),
568 			    ddi_get_instance(dbp->dip));
569 			ddi_regs_map_free(&dbp->conf_handle);
570 			mutex_destroy(&dbp->db_mutex);
571 			ddi_soft_state_free(db_state, instance);
572 			rc = DDI_FAILURE;
573 			break;
574 		}
575 
576 		/* map memory CSR space */
577 		if (ddi_regs_map_setup(dip, DB_CSR_MEMBAR_RNUMBER,
578 		    (caddr_t *)&dbp->csr_mem, DB_CSR_MEM_OFFSET, bar_size,
579 		    &db_csr_attr, &dbp->csr_mem_handle) != DDI_SUCCESS) {
580 
581 			cmn_err(CE_WARN, "%s#%d: cannot map memory CSR space",
582 			    ddi_driver_name(dbp->dip),
583 			    ddi_get_instance(dbp->dip));
584 			ddi_regs_map_free(&dbp->conf_handle);
585 			mutex_destroy(&dbp->db_mutex);
586 			ddi_soft_state_free(db_state, instance);
587 			rc = DDI_FAILURE;
588 			break;
589 		}
590 
591 		if (ddi_dev_regsize(dip, DB_CSR_IOBAR_RNUMBER, &bar_size)
592 		    != DDI_SUCCESS) {
593 			cmn_err(CE_WARN, "%s#%d: cannot get IO CSR size",
594 			    ddi_driver_name(dbp->dip),
595 			    ddi_get_instance(dbp->dip));
596 			ddi_regs_map_free(&dbp->csr_mem_handle);
597 			ddi_regs_map_free(&dbp->conf_handle);
598 			mutex_destroy(&dbp->db_mutex);
599 			ddi_soft_state_free(db_state, instance);
600 			rc = DDI_FAILURE;
601 			break;
602 		}
603 
604 		/*
605 		 * map IO CSR space. We need this map to initiate
606 		 * indirect configuration transactions as this is a better
607 		 * option than doing through configuration space map.
608 		 */
609 		if (ddi_regs_map_setup(dip, DB_CSR_IOBAR_RNUMBER,
610 		    (caddr_t *)&dbp->csr_io, DB_CSR_IO_OFFSET, bar_size,
611 		    &db_csr_attr, &dbp->csr_io_handle) != DDI_SUCCESS) {
612 
613 			cmn_err(CE_WARN, "%s#%d: cannot map IO CSR space",
614 			    ddi_driver_name(dbp->dip),
615 			    ddi_get_instance(dbp->dip));
616 			ddi_regs_map_free(&dbp->csr_mem_handle);
617 			ddi_regs_map_free(&dbp->conf_handle);
618 			mutex_destroy(&dbp->db_mutex);
619 			ddi_soft_state_free(db_state, instance);
620 			rc = DDI_FAILURE;
621 			break;
622 		}
623 
624 		db_orientation(dbp);
625 
626 		if (dbp->dev_state & DB_SECONDARY_NEXUS) {
627 			if (pcihp_init(dip) != DDI_SUCCESS)
628 				cmn_err(CE_WARN,
629 				    "%s#%d: could not register with hotplug",
630 				    ddi_driver_name(dbp->dip),
631 				    ddi_get_instance(dbp->dip));
632 		} else {
633 			/*
634 			 * create minor node for devctl interfaces
635 			 */
636 			if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
637 			    PCIHP_AP_MINOR_NUM(instance, PCIHP_DEVCTL_MINOR),
638 			    DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
639 				ddi_regs_map_free(&dbp->csr_io_handle);
640 				ddi_regs_map_free(&dbp->csr_mem_handle);
641 				ddi_regs_map_free(&dbp->conf_handle);
642 				mutex_destroy(&dbp->db_mutex);
643 				ddi_soft_state_free(db_state, instance);
644 				rc = DDI_FAILURE;
645 				break;
646 			}
647 		}
648 
649 		db_enable_io(dbp);
650 
651 		range_size = sizeof (dbp->range);
652 		if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
653 		    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&dbp->range,
654 		    &range_size) != DDI_SUCCESS) {
655 
656 			cmn_err(CE_WARN,
657 			    "%s#%d: cannot get bus-range property",
658 			    ddi_driver_name(dip), ddi_get_instance(dip));
659 
660 			if (dbp->dev_state & DB_SECONDARY_NEXUS)
661 				(void) pcihp_uninit(dip);
662 			else
663 				ddi_remove_minor_node(dip, "devctl");
664 
665 			ddi_regs_map_free(&dbp->csr_mem_handle);
666 			ddi_regs_map_free(&dbp->csr_io_handle);
667 			ddi_regs_map_free(&dbp->conf_handle);
668 			mutex_destroy(&dbp->db_mutex);
669 			ddi_soft_state_free(db_state, instance);
670 			rc = DDI_FAILURE;
671 			break;
672 		}
673 
674 		(void) sprintf(name, "%d", instance);
675 
676 		if (ddi_create_minor_node(dip, name, S_IFCHR,
677 		    PCIHP_AP_MINOR_NUM(instance, PCIHP_DEBUG_MINOR),
678 		    NULL, NULL) == DDI_FAILURE) {
679 			cmn_err(CE_NOTE, "%s#%d: node creation failure",
680 			    ddi_driver_name(dbp->dip), instance);
681 		}
682 
683 		mutex_init(&dbp->db_busown, NULL, MUTEX_DRIVER, NULL);
684 
685 		db_fm_init(dbp);
686 		ddi_report_dev(dip);
687 		dbp->dev_state |= DB_ATTACHED;
688 
689 		break;
690 
691 	case DDI_RESUME:
692 
693 		/*
694 		 * Get the soft state structure for the bridge.
695 		 */
696 		dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
697 		db_enable_io(dbp);
698 		(void) db_restore_config_regs(dbp);
699 		dbp->dev_state &= ~DB_SUSPENDED;
700 		break;
701 
702 	default:
703 		rc = DDI_FAILURE;	/* not supported yet */
704 		break;
705 	}
706 
707 	DB_DEBUG1(DB_ATTACH, dip, "exit: rc=%d\n", rc);
708 	return (rc);
709 }
710 
711 static int
712 db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
713 {
714 	int instance = ddi_get_instance(dip);
715 	db_ctrl_t	*dbp;
716 	int		rc = DDI_SUCCESS;
717 	char		name[32];
718 
719 	dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
720 
721 	DB_DEBUG1(DB_DETACH, dip, "enter: cmd=%d\n", cmd);
722 
723 	switch (cmd) {
724 
725 	case DDI_DETACH :
726 		db_fm_fini(dbp);
727 		if (dbp->dev_state & DB_SECONDARY_NEXUS)
728 			if (pcihp_uninit(dip) == DDI_FAILURE)
729 				return (DDI_FAILURE);
730 		else
731 			ddi_remove_minor_node(dip, "devctl");
732 
733 		mutex_destroy(&dbp->db_busown);
734 		ddi_regs_map_free(&dbp->csr_mem_handle);
735 		ddi_regs_map_free(&dbp->csr_io_handle);
736 
737 		ddi_regs_map_free(&dbp->conf_handle);
738 		dbp->dev_state &= ~DB_ATTACHED;
739 		(void) sprintf(name, "%d", instance);
740 		ddi_remove_minor_node(dip, name);
741 		mutex_destroy(&dbp->db_mutex);
742 		ddi_soft_state_free(db_state, instance);
743 		break;
744 
745 	case DDI_SUSPEND :
746 		if (db_save_config_regs(dbp) != DDI_SUCCESS) {
747 			cmn_err(CE_WARN,
748 			    "%s#%d: Ignoring Child state Suspend Error",
749 			    ddi_driver_name(dbp->dip),
750 			    ddi_get_instance(dbp->dip));
751 		}
752 		dbp->dev_state |= DB_SUSPENDED;
753 		break;
754 
755 	default :
756 		rc = DDI_FAILURE;
757 		break;
758 	}
759 
760 	DB_DEBUG1(DB_DETACH, dip, "exit: rc=%d\n", rc);
761 	return (rc);
762 }
763 
764 static void
765 db_get_perf_parameters(db_ctrl_t *dbp)
766 {
767 	dbp->p_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
768 	    dbp->dip, 0, "p-latency-timer", p_latency_timer);
769 	dbp->s_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
770 	    dbp->dip, 0, "s-latency-timer", s_latency_timer);
771 	dbp->p_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
772 	    dbp->dip, 0, "p-cache-line-size", p_cache_line_size);
773 	dbp->s_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
774 	    dbp->dip, 0, "s-cache-line-size", s_cache_line_size);
775 	dbp->p_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
776 	    dbp->dip, 0, "p-pwrite-threshold", p_pwrite_threshold);
777 	dbp->s_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
778 	    dbp->dip, 0, "s-pwrite-threshold", s_pwrite_threshold);
779 	dbp->p_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
780 	    dbp->dip, 0, "p-dread-threshold", p_dread_threshold);
781 	dbp->s_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
782 	    dbp->dip, 0, "s-dread-threshold", s_dread_threshold);
783 	dbp->delayed_trans_order = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
784 	    dbp->dip, 0, "delayed-trans-order", delayed_trans_order);
785 }
786 
787 static void
788 db_set_perf_parameters(db_ctrl_t *dbp)
789 {
790 	uint_t	poffset = 0, soffset = 0;
791 
792 	if (dbp->dev_state & DB_SECONDARY_NEXUS)
793 		poffset = DB_SCONF_PRI_HDR_OFF;
794 	else
795 		soffset = DB_PCONF_SEC_HDR_OFF;
796 
797 	if ((dbp->p_latency_timer != (int8_t)DEF_INVALID_REG_VAL) &&
798 	    (dbp->p_latency_timer != -1))
799 		ddi_put8(dbp->conf_handle,
800 		    (uint8_t *)dbp->conf_io+poffset+PCI_CONF_LATENCY_TIMER,
801 		    dbp->p_latency_timer);
802 	if ((dbp->s_latency_timer != (int8_t)DEF_INVALID_REG_VAL) &&
803 	    (dbp->s_latency_timer != -1))
804 		ddi_put8(dbp->conf_handle,
805 		    (uint8_t *)dbp->conf_io+soffset+PCI_CONF_LATENCY_TIMER,
806 		    dbp->s_latency_timer);
807 	if ((dbp->p_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) &&
808 	    (dbp->p_cache_line_size != -1))
809 		ddi_put8(dbp->conf_handle,
810 		    (uint8_t *)dbp->conf_io+poffset+PCI_CONF_CACHE_LINESZ,
811 		    dbp->p_cache_line_size);
812 	if ((dbp->s_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) &&
813 	    (dbp->s_cache_line_size != -1))
814 		ddi_put8(dbp->conf_handle,
815 		    (uint8_t *)dbp->conf_io+soffset+PCI_CONF_CACHE_LINESZ,
816 		    dbp->s_cache_line_size);
817 	if ((dbp->p_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
818 	    (dbp->p_pwrite_threshold != -1))
819 		ddi_put16(dbp->conf_handle, (uint16_t *)
820 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
821 		    (ddi_get16(dbp->conf_handle, (uint16_t *)
822 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
823 		    ~P_PW_THRESHOLD) |
824 		    (dbp->p_pwrite_threshold?P_PW_THRESHOLD:0));
825 	if ((dbp->s_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
826 	    (dbp->s_pwrite_threshold != -1))
827 		ddi_put16(dbp->conf_handle, (uint16_t *)
828 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
829 		    (ddi_get16(dbp->conf_handle, (uint16_t *)
830 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
831 		    ~S_PW_THRESHOLD) |
832 		    (dbp->s_pwrite_threshold?S_PW_THRESHOLD:0));
833 	/* primary delayed read threshold. 0x01 is reserved ?. */
834 	if ((dbp->p_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
835 	    (dbp->p_dread_threshold != -1))
836 		ddi_put16(dbp->conf_handle, (uint16_t *)
837 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
838 		    ((ddi_get16(dbp->conf_handle, (uint16_t *)
839 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
840 		    ~P_DREAD_THRESHOLD_MASK) |
841 		    ((dbp->p_dread_threshold &
842 		    DREAD_THRESHOLD_VALBITS)<<2)));
843 	/* secondary delayed read threshold. 0x01 is reserved ?. */
844 	if ((dbp->s_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
845 	    (dbp->s_dread_threshold != -1))
846 		ddi_put16(dbp->conf_handle, (uint16_t *)
847 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
848 		    ((ddi_get16(dbp->conf_handle, (uint16_t *)
849 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
850 		    ~S_DREAD_THRESHOLD_MASK) |
851 		    ((dbp->s_dread_threshold &
852 		    DREAD_THRESHOLD_VALBITS)<<4)));
853 	if ((dbp->delayed_trans_order != (int8_t)DEF_INVALID_REG_VAL) &&
854 	    (dbp->delayed_trans_order != -1))
855 		ddi_put16(dbp->conf_handle, (uint16_t *)
856 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0),
857 		    (ddi_get16(dbp->conf_handle, (uint16_t *)
858 		    ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0)) &
859 		    ~DELAYED_TRANS_ORDER) |
860 		    (dbp->delayed_trans_order?DELAYED_TRANS_ORDER:0));
861 }
862 
863 static void
864 db_orientation(db_ctrl_t *dbp)
865 {
866 	dev_info_t	*dip = dbp->dip;
867 	uint8_t		pif;
868 	uint32_t	mem1;
869 	uint32_t	newval;
870 
871 	/*
872 	 * determine orientation of drawbridge and enable
873 	 * Upstream or Downstream path.
874 	 */
875 
876 	/*
877 	 * if PIF is set correctly, use it to determine orientation
878 	 */
879 	pif = ddi_get8(dbp->conf_handle, (uchar_t *)dbp->conf_io +
880 	    PCI_CONF_PROGCLASS);
881 	if (pif & 0xff) {
882 		if (pif & DB_PIF_SECONDARY_TO_HOST) {
883 			dbp->dev_state = DB_SECONDARY_NEXUS;
884 			DB_DEBUG0(DB_ATTACH, dip,
885 			    "db_orientation: pif secondary\n");
886 			return;
887 		}
888 		if (pif & DB_PIF_PRIMARY_TO_HOST) {
889 			dbp->dev_state = DB_PRIMARY_NEXUS;
890 			DB_DEBUG0(DB_ATTACH, dip,
891 			    "db_orientation: pif primary\n");
892 			return;
893 		}
894 		/* otherwise, fall through */
895 	}
896 
897 	/*
898 	 * otherwise, test the chip directly by trying to write
899 	 * downstream mem1 setup register, only writeable from
900 	 * secondary.
901 	 */
902 	mem1 = ddi_get32(dbp->conf_handle,
903 	    (uint32_t *)((uchar_t *)dbp->conf_io +
904 	    DB_CONF_DS_IO_MEM1_SETUP));
905 
906 	ddi_put32(dbp->conf_handle,
907 	    (uint32_t *)((uchar_t *)(dbp->conf_io +
908 	    DB_CONF_DS_IO_MEM1_SETUP)), ~mem1);
909 
910 	newval = ddi_get32(dbp->conf_handle,
911 	    (uint32_t *)((uchar_t *)dbp->conf_io +
912 	    DB_CONF_DS_IO_MEM1_SETUP));
913 
914 	if (newval == mem1)
915 		/* we couldn't write it, orientation is primary */
916 		dbp->dev_state =  DB_PRIMARY_NEXUS;
917 	else {
918 		/*
919 		 * we could write it, therefore orientation secondary.
920 		 * restore mem1 value.
921 		 */
922 		dbp->dev_state =  DB_SECONDARY_NEXUS;
923 		ddi_put32(dbp->conf_handle,
924 		    (uint32_t *)((uchar_t *)(dbp->conf_io +
925 		    DB_CONF_DS_IO_MEM1_SETUP)), mem1);
926 	}
927 
928 
929 	if (dbp->dev_state & DB_PRIMARY_NEXUS) {
930 		DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip primary\n");
931 	} else  {
932 		DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip secondary\n");
933 	}
934 }
935 
936 static void
937 db_enable_io(db_ctrl_t *dbp)
938 {
939 	dev_info_t	*dip = dbp->dip;
940 	pci_regspec_t	*reg;
941 	int		rcount, length, i;
942 	uint32_t	offset;
943 	uint32_t	p_offset, s_offset;
944 	uint16_t	regval;
945 	uint16_t	enable;
946 
947 	/*
948 	 * Step 0:
949 	 *	setup the primary and secondary offset and enable
950 	 *	values based on the orientation of 21554.
951 	 */
952 	if (dbp->dev_state & DB_PRIMARY_NEXUS) {
953 		DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: primary\n");
954 		p_offset = 0;
955 		s_offset = DB_SCONF_HDR_OFF;
956 		enable = DS_ENABLE;
957 	} else {
958 		DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: secondary\n");
959 		p_offset = DB_SCONF_HDR_OFF;
960 		s_offset = 0;
961 		enable = US_ENABLE;
962 	}
963 
964 	db_set_perf_parameters(dbp);
965 	db_set_dvma_range(dbp);
966 
967 	/*
968 	 * Step 1:
969 	 *	setup latency timer and cache line size parameters
970 	 *	which are used for child initialization.
971 	 */
972 	dbp->latency_timer = ddi_get8(dbp->conf_handle, (uint8_t *)
973 	    ((caddr_t)dbp->conf_io+PCI_CONF_LATENCY_TIMER));
974 
975 	dbp->cache_line_size = ddi_get8(dbp->conf_handle, (uint8_t *)
976 	    ((caddr_t)dbp->conf_io+PCI_CONF_CACHE_LINESZ));
977 
978 	DB_DEBUG2(DB_ATTACH, dip,
979 	    "db_enable_io: latency %d, cache line size %d\n",
980 	    dbp->latency_timer, dbp->cache_line_size);
981 
982 	/*
983 	 * Step 2: program command reg on both primary and secondary
984 	 *	   interfaces.
985 	 */
986 	ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io +
987 	    (off_t)(p_offset + PCI_CONF_COMM)), db_command_default);
988 
989 	ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io +
990 	    (off_t)(s_offset + PCI_CONF_COMM)), db_command_default);
991 
992 	/*
993 	 * Step 3:
994 	 *	set up translated base registers, using the primary/
995 	 *  secondary interface pci configuration Base Address
996 	 *  Registers (BAR's).
997 	 */
998 
999 	/* mem0 translated base is setup for primary orientation only. */
1000 	if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1001 		/*
1002 		 * And only if the 21554 device node property indicates
1003 		 * the size of base0 register to be larger than csr map
1004 		 * space, DB_CSR_SIZE=4K.
1005 		 *
1006 		 * Note : Setting up 1:1 translations only (for now:), i.e.
1007 		 *	  no look up table.
1008 		 */
1009 		if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1010 		    DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
1011 		    &length) != DDI_PROP_SUCCESS) {
1012 			DB_DEBUG0(DB_ATTACH, dip,
1013 			    "Failed to read reg property\n");
1014 			return;
1015 		}
1016 
1017 		/* Find device node's base0 reg property and check its size */
1018 		rcount = length / sizeof (pci_regspec_t);
1019 		for (i = 0; i < rcount; i++) {
1020 			offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
1021 			if ((offset == PCI_CONF_BASE0) &&
1022 			    (reg[i].pci_size_low > DB_CSR_SIZE))
1023 					break;
1024 		}
1025 
1026 		/*
1027 		 * set up mem0 translated base, if base0 register was
1028 		 * found and its size was larger than csr map space.
1029 		 */
1030 		if (i != rcount) {
1031 			DB_DEBUG0(DB_ATTACH, dip,
1032 			    "db_enable_io: setting up MEM0_TR_BASE\n");
1033 			DB_DEBUG1(DB_ATTACH, dip, "BASE0 register = %x\n",
1034 			    pci_config_get32(dbp->conf_handle,
1035 			    (off_t)(p_offset + PCI_CONF_BASE0)));
1036 
1037 			pci_config_put32(dbp->conf_handle,
1038 			    (off_t)DB_CONF_DS_MEM0_TR_BASE,
1039 			    pci_config_get32(dbp->conf_handle,
1040 			    (off_t)(p_offset + PCI_CONF_BASE0)));
1041 
1042 			DB_DEBUG1(DB_ATTACH, dip,
1043 			    "db_enable_io: MEM0_TR_BASE set value = %x\n",
1044 			    pci_config_get32(dbp->conf_handle,
1045 			    (off_t)DB_CONF_DS_MEM0_TR_BASE));
1046 		}
1047 		kmem_free(reg, length);
1048 	}
1049 
1050 	pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_IO_MEM1_TR_BASE,
1051 	    ((pci_config_get32(dbp->conf_handle,
1052 	    (off_t)(p_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT));
1053 
1054 	pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM2_TR_BASE,
1055 	    ((pci_config_get32(dbp->conf_handle,
1056 	    (off_t)(p_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT));
1057 
1058 	pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM3_TR_BASE,
1059 	    ((pci_config_get32(dbp->conf_handle,
1060 	    (off_t)(p_offset + PCI_CONF_BASE4))) & ~DB_IO_BIT));
1061 
1062 	pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_IO_MEM0_TR_BASE,
1063 	    ((pci_config_get32(dbp->conf_handle,
1064 	    (off_t)(s_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT));
1065 
1066 	pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_MEM1_TR_BASE,
1067 	    ((pci_config_get32(dbp->conf_handle,
1068 	    (off_t)(s_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT));
1069 
1070 	/*
1071 	 * Step 4: enable downstream (for primary orientation) or upstream
1072 	 *	   (for secondary orientation) bits in Configuration Control
1073 	 *	   and Status register, if not already enabled.
1074 	 */
1075 	regval = pci_config_get16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR);
1076 
1077 	DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value before: %x\n",
1078 	    regval);
1079 
1080 	if (!(regval & enable)) {
1081 		/* enable down/upstream configuration transactions */
1082 		regval |= enable;
1083 		pci_config_put16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR,
1084 		    regval);
1085 		regval = pci_config_get16(dbp->conf_handle,
1086 		    (off_t)DB_CONF_CONF_CSR);
1087 	}
1088 	DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value after: %x\n",
1089 	    regval);
1090 
1091 	/*
1092 	 * Step 5: enable downstream/upstream I/O (through CSR space)
1093 	 */
1094 	regval = ddi_get16(dbp->csr_mem_handle,
1095 	    (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR));
1096 
1097 	DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value before: %x\n",
1098 	    regval);
1099 	if (!(regval & enable)) {
1100 		regval |= enable;
1101 		ddi_put16(dbp->csr_mem_handle,
1102 		    (uint16_t *)((uchar_t *)dbp->csr_mem +
1103 		    DB_CSR_IO_CSR), regval);
1104 
1105 		regval = ddi_get16(dbp->csr_mem_handle,
1106 		    (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR));
1107 	}
1108 	DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value after: %x\n",
1109 	    regval);
1110 
1111 	/*
1112 	 * Step 6: if 21554 orientation is primary to host,
1113 	 *	   forward SERR# to host.
1114 	 */
1115 	if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1116 		dbp->serr_fwd_enable = ddi_prop_get_int(DDI_DEV_T_ANY,
1117 		    dbp->dip, 0, "serr-fwd-enable", db_serr_fwd_enable);
1118 
1119 		regval = ddi_get16(dbp->conf_handle,
1120 		    (uint16_t *)((uchar_t *)dbp->conf_io +
1121 		    DB_CONF_CHIP_CTRL0));
1122 
1123 		DB_DEBUG1(DB_ATTACH, dip,
1124 		    "db_enable_io: CHIP_CTRL0 value before: %x\n", regval);
1125 
1126 		ddi_put16(dbp->conf_handle,
1127 		    (uint16_t *)((uchar_t *)dbp->conf_io +
1128 		    DB_CONF_CHIP_CTRL0),
1129 		    (regval & ~SERR_FWD) |
1130 		    (dbp->serr_fwd_enable?SERR_FWD:0));
1131 
1132 		regval = ddi_get16(dbp->conf_handle,
1133 		    (uint16_t *)((uchar_t *)dbp->conf_io +
1134 		    DB_CONF_CHIP_CTRL0));
1135 
1136 		DB_DEBUG1(DB_ATTACH, dip,
1137 		    "db_enable_io: CHIP_CTRL0 value after: %x\n", regval);
1138 	}
1139 
1140 	/*
1141 	 * Step 7: if orientation is secondary, make sure primary lockout
1142 	 *	   disable is reset.
1143 	 */
1144 
1145 	if (dbp->dev_state & DB_SECONDARY_NEXUS) {
1146 		regval = pci_config_get16(dbp->conf_handle,
1147 		    (off_t)DB_CONF_CHIP_CTRL0);
1148 		DB_DEBUG1(DB_ATTACH, dip,
1149 		    "db_enable_io: chip ctrl (0x%x) before\n", regval);
1150 		if (regval & PLOCKOUT)
1151 			pci_config_put16(dbp->conf_handle,
1152 			    (off_t)DB_CONF_CHIP_CTRL0,
1153 			    (regval & ~PLOCKOUT));
1154 		regval = pci_config_get16(dbp->conf_handle,
1155 		    (off_t)DB_CONF_CHIP_CTRL0);
1156 		DB_DEBUG1(DB_ATTACH, dip,
1157 		    "db_enable_io: chip ctrl (0x%x) after\n", regval);
1158 	}
1159 }
1160 
1161 /*
1162  * Set DVMA Address Range.
1163  * This code is common to both orientations of the nexus driver.
1164  */
1165 static void
1166 db_set_dvma_range(db_ctrl_t *dbp)
1167 {
1168 	uint32_t	dvma_start = 0;
1169 	uint32_t	dvma_len = 0;
1170 	uint64_t	db_allocd = 0;
1171 	uint32_t	*dvma_prop;
1172 	uint32_t	dvma_size[2];	/* dvma size may span over 2 BARs */
1173 	uint32_t	dvma_bar[2];	/* dvma range may span over 2 BARs */
1174 	int		dvma_prop_len;
1175 	uint64_t	new_dvma_start, new_dvma_len, new_dvma_end;
1176 
1177 	/*
1178 	 * Need to traverse up the tree looking for a
1179 	 * "virtual-dma" property that specifies the
1180 	 * HPB DVMA range.
1181 	 */
1182 	if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_get_parent(dbp->dip), 0,
1183 	    "virtual-dma", (caddr_t)&dvma_prop, &dvma_prop_len)
1184 	    == DDI_SUCCESS) {
1185 		dvma_start = dvma_prop[0];
1186 		dvma_len = dvma_prop[1];
1187 		kmem_free((caddr_t)dvma_prop, dvma_prop_len);
1188 	} else {
1189 		/*
1190 		 * For initial implementation, lets avoid a warning since this
1191 		 * change has not been implemented in the host-pci nexus
1192 		 * driver.
1193 		 */
1194 		cmn_err(CE_WARN,
1195 		    "%s#%d: Could not get \"virtual-dma\" property",
1196 		    ddi_driver_name(dbp->dip),
1197 		    ddi_get_instance(dbp->dip));
1198 		dvma_start = db_dvma_start;
1199 		dvma_len = db_dvma_len;
1200 	}
1201 
1202 	DB_DEBUG2(DB_DVMA, dbp->dip,
1203 	    "DVMA Range is %lx,%lx\n", dvma_start, dvma_len);
1204 
1205 	dvma_size[0] = dvma_size[1] = 0;
1206 	/* Validate DVMA size programming and system requirements. */
1207 	if (dbp->dev_state & DB_SECONDARY_NEXUS) {
1208 		dvma_size[0] = pci_config_get32(dbp->conf_handle,
1209 		    DB_CONF_DS_IO_MEM1_SETUP);
1210 		if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */
1211 			dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000;
1212 		else
1213 			dvma_size[0] = 0;
1214 		dvma_size[1] = db_dvma_len;
1215 	} else {
1216 		dvma_size[0] = pci_config_get32(dbp->conf_handle,
1217 		    DB_CONF_US_IO_MEM0_SETUP);
1218 		if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */
1219 			dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000;
1220 		else
1221 			dvma_size[0] = 0;
1222 		dvma_size[1] = ((~(pci_config_get32(dbp->conf_handle,
1223 		    DB_CONF_US_MEM1_SETUP))) + 1) & 0xfffff000;
1224 	}
1225 	DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA size register pair %lx, %lx\n",
1226 	    dvma_size[0], dvma_size[1]);
1227 
1228 #ifdef	DEBUG
1229 	if ((dvma_size[0] + dvma_size[1]) < dvma_len)
1230 		cmn_err(CE_WARN, "%s#%d: DVMA window (%u) does not coincide"
1231 		    " with system requirements",
1232 		    ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip),
1233 		    (dvma_size[0] + dvma_size[1]));
1234 #endif
1235 	dvma_bar[0] = dvma_bar[1] = 0xFFFFFFFF;
1236 	db_allocd = 0;
1237 	new_dvma_start = dvma_start;
1238 	new_dvma_len = dvma_len;
1239 
1240 	/* now, program the correct DVMA range over the 2 BARs. Max 4GB */
1241 	if (dvma_size[0]) {
1242 		dvma_bar[0] = (uint32_t)(dvma_start & (~(dvma_size[0] - 1)));
1243 		new_dvma_end =  (uint64_t)((uint64_t)dvma_bar[0] +
1244 		    (uint64_t)dvma_size[0]);
1245 		if (new_dvma_end > (new_dvma_start + new_dvma_len))
1246 			new_dvma_end = new_dvma_start + new_dvma_len;
1247 		db_allocd += (new_dvma_end - new_dvma_start);
1248 		new_dvma_start = new_dvma_end;
1249 		new_dvma_len = dvma_len - db_allocd;
1250 	}
1251 	/*
1252 	 * It does not serve any purpose to set the other DVMA register
1253 	 * when we have already met the memory requirements so leave it
1254 	 * disabled.
1255 	 */
1256 	if ((db_allocd != dvma_len) && dvma_size[1]) {
1257 		dvma_bar[1] = (uint32_t)((dvma_start + db_allocd) &
1258 		    (~(dvma_size[1] - 1)));
1259 		new_dvma_end =  (uint64_t)((uint64_t)dvma_bar[1] +
1260 		    (uint64_t)dvma_size[1]);
1261 		if (new_dvma_end > (new_dvma_start + new_dvma_len))
1262 			new_dvma_end = new_dvma_start + new_dvma_len;
1263 		db_allocd += (new_dvma_end - new_dvma_start);
1264 	}
1265 
1266 	/* In case of secondary orientation, DVMA BAR0 is 0. */
1267 	if (dbp->dev_state & DB_SECONDARY_NEXUS)
1268 		dvma_bar[0] = 0;
1269 
1270 	if (db_allocd != dvma_len) {
1271 		cmn_err(CE_WARN, "%s#%d: dvma range error!",
1272 		    ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip));
1273 	}
1274 
1275 	DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA BARs set as %x, %x\n",
1276 	    dvma_bar[0], dvma_bar[1]);
1277 
1278 	/* configure the setup register and DVMA BARs. */
1279 	if (dbp->dev_state & DB_SECONDARY_NEXUS) {
1280 		if (dvma_bar[0] != 0xFFFFFFFF) {
1281 #ifdef	DB_SEC_SETUP_WRITE
1282 			/*
1283 			 * No need to program the setup register
1284 			 * as the PROM would have done it.
1285 			 */
1286 			pci_config_put32(dbp->conf_handle,
1287 			    DB_CONF_DS_MEM1_SETUP,
1288 			    (uint32_t)(((~(dvma_size[0] - 1)) |
1289 			    (pci_config_get32(dbp->conf_handle,
1290 			    DB_CONF_DS_MEM1_SETUP) & 0xF)) | 0x80000000));
1291 #endif
1292 			/*
1293 			 * when translations are to be provided, this will
1294 			 * change.
1295 			 */
1296 			pci_config_put32(dbp->conf_handle,
1297 			    DB_CONF_DS_IO_MEM1_TR_BASE,
1298 			    (uint32_t)dvma_bar[0]);
1299 			pci_config_put32(dbp->conf_handle,
1300 			    DB_SCONF_DS_IO_MEM1, dvma_bar[0]);
1301 		}
1302 		if (dvma_bar[1] != 0xFFFFFFFF) {
1303 #ifdef	DB_SEC_SETUP_WRITE
1304 			/*
1305 			 * No need to program the setup register
1306 			 * as the PROM would have done it.
1307 			 */
1308 			pci_config_put32(dbp->conf_handle,
1309 			    DB_CONF_DS_MEM2_SETUP,
1310 			    (uint32_t)(((~(dvma_size[1] - 1)) |
1311 			    (pci_config_get32(dbp->conf_handle,
1312 			    DB_CONF_DS_MEM2_SETUP) & 0xF)) | 0x80000000));
1313 #endif
1314 			/*
1315 			 * when translations are to be provided, this will
1316 			 * change.
1317 			 */
1318 			pci_config_put32(dbp->conf_handle,
1319 			    DB_CONF_DS_MEM2_TR_BASE, (uint32_t)dvma_bar[1]);
1320 			pci_config_put32(dbp->conf_handle,
1321 			    DB_SCONF_DS_MEM2, dvma_bar[1]);
1322 		}
1323 
1324 	} else {
1325 		if (dvma_bar[0] != 0xFFFFFFFF) {
1326 #ifdef DB_CONF_P2S_WRITE_ENABLED	/* primary to secondary write enabled */
1327 			/*
1328 			 * We have a problem with this setup, because the
1329 			 * US_MEM1 setup register cannot be written from the
1330 			 * primary interface...!!! Hence in this configuration,
1331 			 * we cannot dynamically program the DVMA range!
1332 			 */
1333 			pci_config_put32(dbp->conf_handle,
1334 			    DB_CONF_US_IO_MEM0_SETUP,
1335 			    (uint32_t)(((~(dvma_size[0] - 1)) |
1336 			    (pci_config_get32(dbp->conf_handle,
1337 			    DB_CONF_US_IO_MEM0_SETUP) & 0xF)) |
1338 			    0x80000000));
1339 #endif
1340 			/*
1341 			 * when translations are to be provided, this will
1342 			 * change.
1343 			 */
1344 			pci_config_put32(dbp->conf_handle,
1345 			    DB_CONF_US_IO_MEM0_TR_BASE,
1346 			    (uint32_t)dvma_bar[0]);
1347 			pci_config_put32(dbp->conf_handle,
1348 			    DB_PCONF_US_IO_MEM0, dvma_bar[0]);
1349 		}
1350 		if (dvma_bar[1] != 0xFFFFFFFF) {
1351 #ifdef DB_CONF_P2S_WRITE_ENABLED	/* primary to secondary write enabled */
1352 			/*
1353 			 * We have a problem with this setup, because the
1354 			 * US_MEM1 setup register cannot be written from the
1355 			 * primary interface...!!! Hence in this configuration,
1356 			 * we cannot dynamically program the DVMA range!
1357 			 */
1358 			pci_config_put32(dbp->conf_handle,
1359 			    DB_CONF_US_MEM1_SETUP,
1360 			    (uint32_t)(((~(dvma_size[1] - 1)) |
1361 			    (pci_config_get32(dbp->conf_handle,
1362 			    DB_CONF_US_MEM1_SETUP) & 0xF)) | 0x80000000));
1363 #endif
1364 			/*
1365 			 * when translations are to be provided, this will
1366 			 * change.
1367 			 */
1368 			pci_config_put32(dbp->conf_handle,
1369 			    DB_CONF_US_MEM1_TR_BASE, (uint32_t)dvma_bar[1]);
1370 			pci_config_put32(dbp->conf_handle,
1371 			    DB_PCONF_US_MEM1, dvma_bar[1]);
1372 		}
1373 	}
1374 }
1375 
1376 /*ARGSUSED*/
1377 static int
1378 db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
1379 {
1380 	minor_t		minor = getminor(*dev_p);
1381 	int		instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
1382 	db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
1383 
1384 	if (dbp == (db_ctrl_t *)NULL)
1385 		return (ENXIO);
1386 
1387 	/*
1388 	 * check for debug node
1389 	 */
1390 	if ((minor & 0xff) == 0xfe)
1391 		return (0);
1392 
1393 	if (dbp->dev_state & DB_SECONDARY_NEXUS)
1394 		return ((pcihp_get_cb_ops())->cb_open(dev_p, flag,
1395 		    otyp, cred_p));
1396 	/*
1397 	 * Handle the open by tracking the device state.
1398 	 */
1399 	mutex_enter(&dbp->db_mutex);
1400 	if (flag & FEXCL) {
1401 		if (dbp->db_soft_state != DB_SOFT_STATE_CLOSED) {
1402 			mutex_exit(&dbp->db_mutex);
1403 			return (EBUSY);
1404 		}
1405 		dbp->db_soft_state = DB_SOFT_STATE_OPEN_EXCL;
1406 	} else {
1407 		if (dbp->db_soft_state == DB_SOFT_STATE_OPEN_EXCL) {
1408 			mutex_exit(&dbp->db_mutex);
1409 			return (EBUSY);
1410 		}
1411 		dbp->db_soft_state = DB_SOFT_STATE_OPEN;
1412 	}
1413 	mutex_exit(&dbp->db_mutex);
1414 	return (0);
1415 }
1416 
1417 /*ARGSUSED*/
1418 static int
1419 db_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
1420 {
1421 	minor_t		minor = getminor(dev);
1422 	int		instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
1423 	db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
1424 
1425 	if (dbp == (db_ctrl_t *)NULL)
1426 		return (ENXIO);
1427 
1428 	/*
1429 	 * check for debug node
1430 	 */
1431 	if ((minor & 0xff) == 0xfe)
1432 		return (0);
1433 
1434 	if (dbp->dev_state & DB_SECONDARY_NEXUS)
1435 		return ((pcihp_get_cb_ops())->cb_close(dev, flag,
1436 		    otyp, cred_p));
1437 	mutex_enter(&dbp->db_mutex);
1438 	dbp->db_soft_state = DB_SOFT_STATE_CLOSED;
1439 	mutex_exit(&dbp->db_mutex);
1440 	return (0);
1441 }
1442 
1443 /*ARGSUSED*/
1444 static int
1445 db_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
1446 		int *rval_p)
1447 {
1448 	int		rc = DDI_SUCCESS;
1449 #ifdef	DB_DEBUG
1450 	ddi_acc_handle_t	config_handle;
1451 	db_pci_data_t	pci_data;
1452 	dev_info_t	*child_dip;
1453 #endif
1454 	dev_info_t	*self;
1455 	minor_t		minor = getminor(dev);
1456 	int		instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
1457 	struct devctl_iocdata *dcp;
1458 	uint_t		bus_state;
1459 	db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
1460 
1461 #ifdef	DB_DEBUG
1462 	/*
1463 	 * try this first whether were SECONDARY_NEXUS or not
1464 	 */
1465 	if (cmd == DB_PCI_READ_CONF_HEADER) {
1466 		if (ddi_copyin((caddr_t)arg, (caddr_t)&pci_data,
1467 		    sizeof (db_pci_data_t), mode)) {
1468 			rc = EFAULT;
1469 			return (rc);
1470 		}
1471 
1472 		if (strcmp(pci_data.name, "") == 0) {
1473 			child_dip = dbp->dip;
1474 			(void) strcpy(pci_data.name,
1475 			    ddi_get_name(dbp->dip));
1476 		} else {
1477 
1478 			if ((child_dip = db_lookup_child_name(dbp,
1479 			    pci_data.name, pci_data.instance))
1480 			    == (dev_info_t *)NULL) {
1481 				rc = ENXIO;
1482 				return (rc);
1483 			} else {
1484 				if (ddi_getprop(DDI_DEV_T_ANY,
1485 				    child_dip, DDI_PROP_DONTPASS,
1486 				    "vendor-id", DB_INVAL_VEND)
1487 				    == DB_INVAL_VEND) {
1488 					/* non PCI device */
1489 					rc = EINVAL;
1490 					return (rc);
1491 				}
1492 			}
1493 		}
1494 		pci_data.instance = ddi_get_instance(child_dip);
1495 		(void) pci_config_setup(child_dip, &config_handle);
1496 		db_pci_get_header(config_handle, &pci_data.pri_hdr, 0);
1497 
1498 		/* if it is the drawbridge itself, read sec header */
1499 		if (child_dip == dbp->dip) {
1500 			db_pci_get_header(config_handle,
1501 			    &pci_data.sec_hdr, DB_PCONF_SEC_HDR_OFF);
1502 			db_pci_get_conf_regs(config_handle,
1503 			    &pci_data.conf_regs);
1504 		}
1505 		pci_config_teardown(&config_handle);
1506 
1507 		if (ddi_copyout((caddr_t)&pci_data, (caddr_t)arg,
1508 		    sizeof (db_pci_data_t), mode)) {
1509 			rc = EFAULT;
1510 			return (rc);
1511 		}
1512 
1513 		return (rc);
1514 	}
1515 #endif	/* DB_DEBUG */
1516 
1517 	/*
1518 	 * if secondary nexus (hotplug), then use pcihp_ioctl to do everything
1519 	 */
1520 	if (dbp->dev_state & DB_SECONDARY_NEXUS)
1521 		return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd,
1522 		    arg, mode, cred_p, rval_p));
1523 
1524 	/*
1525 	 * if not secondary nexus, we do DEVCTL_DEVICE and DEVCTL_BUS ourselves
1526 	 */
1527 	self = dbp->dip;
1528 
1529 	/*
1530 	 * We can use the generic implementation for these ioctls
1531 	 */
1532 	switch (cmd) {
1533 	case DEVCTL_DEVICE_GETSTATE:
1534 	case DEVCTL_DEVICE_ONLINE:
1535 	case DEVCTL_DEVICE_OFFLINE:
1536 	case DEVCTL_BUS_GETSTATE:
1537 		return (ndi_devctl_ioctl(self, cmd, arg, mode, 0));
1538 	}
1539 
1540 	/*
1541 	 * read devctl ioctl data
1542 	 */
1543 	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1544 		return (EFAULT);
1545 
1546 	switch (cmd) {
1547 
1548 	case DEVCTL_DEVICE_RESET:
1549 		rc = ENOTSUP;
1550 		break;
1551 
1552 
1553 	case DEVCTL_BUS_QUIESCE:
1554 		if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1555 			if (bus_state == BUS_QUIESCED)
1556 				break;
1557 		(void) ndi_set_bus_state(self, BUS_QUIESCED);
1558 		break;
1559 
1560 	case DEVCTL_BUS_UNQUIESCE:
1561 		if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1562 			if (bus_state == BUS_ACTIVE)
1563 				break;
1564 		(void) ndi_set_bus_state(self, BUS_ACTIVE);
1565 		break;
1566 
1567 	case DEVCTL_BUS_RESET:
1568 		rc = ENOTSUP;
1569 		break;
1570 
1571 	case DEVCTL_BUS_RESETALL:
1572 		rc = ENOTSUP;
1573 		break;
1574 
1575 	default:
1576 		rc = ENOTTY;
1577 	}
1578 
1579 	ndi_dc_freehdl(dcp);
1580 	return (rc);
1581 }
1582 
1583 #ifdef	DB_DEBUG
1584 static dev_info_t *
1585 db_lookup_child_name(db_ctrl_t *dbp, char *name, int instance)
1586 {
1587 	dev_info_t *cdip, *pdip = dbp->dip;
1588 
1589 	for (cdip = ddi_get_child(pdip); cdip;
1590 	    cdip = ddi_get_next_sibling(pdip)) {
1591 
1592 		do {
1593 			if (strcmp(ddi_node_name(cdip), name) == 0) {
1594 				if (instance != -1) {
1595 					if (ddi_get_instance(cdip) == instance)
1596 						return (cdip);
1597 				} else
1598 					return (cdip);
1599 			}
1600 			pdip = cdip;
1601 		} while ((cdip = ddi_get_child(pdip)));
1602 		cdip = ddi_get_next_sibling(pdip);
1603 		if (cdip == NULL) {
1604 			pdip = ddi_get_parent(pdip);
1605 			if (pdip == dbp->dip)
1606 				break;
1607 		}
1608 	}
1609 	return (NULL);
1610 }
1611 
1612 static void
1613 db_pci_get_header(ddi_acc_handle_t config_handle, db_pci_header_t *ph,
1614     off_t hdr_off)
1615 {
1616 	ph->venid = pci_config_get16(config_handle, hdr_off + PCI_CONF_VENID);
1617 	ph->devid = pci_config_get16(config_handle, hdr_off + PCI_CONF_DEVID);
1618 	ph->command = pci_config_get16(config_handle, hdr_off + PCI_CONF_COMM);
1619 	ph->status = pci_config_get16(config_handle, hdr_off + PCI_CONF_STAT);
1620 	ph->revid = pci_config_get8(config_handle, hdr_off + PCI_CONF_REVID);
1621 	ph->pif = pci_config_get8(config_handle, hdr_off + PCI_CONF_PROGCLASS);
1622 	ph->subclass = pci_config_get8(config_handle,
1623 	    hdr_off + PCI_CONF_SUBCLASS);
1624 	ph->class = pci_config_get8(config_handle,
1625 	    hdr_off + PCI_CONF_BASCLASS);
1626 	ph->cacheline = pci_config_get8(config_handle,
1627 	    hdr_off + PCI_CONF_CACHE_LINESZ);
1628 	ph->lat = pci_config_get8(config_handle,
1629 	    hdr_off + PCI_CONF_LATENCY_TIMER);
1630 	ph->hdr_type = pci_config_get8(config_handle,
1631 	    hdr_off + PCI_CONF_HEADER);
1632 	ph->bist = pci_config_get8(config_handle, hdr_off + PCI_CONF_BIST);
1633 	ph->bar0 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE0);
1634 	ph->bar1 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE1);
1635 	ph->bar2 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE2);
1636 	ph->bar3 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE3);
1637 	ph->bar4 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE4);
1638 	ph->bar5 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE5);
1639 	ph->cardbus_cisp = pci_config_get32(config_handle,
1640 	    hdr_off + PCI_CONF_CIS);
1641 	ph->sub_venid = pci_config_get16(config_handle,
1642 	    hdr_off + PCI_CONF_SUBVENID);
1643 	ph->sub_devid = pci_config_get16(config_handle,
1644 	    hdr_off + PCI_CONF_SUBSYSID);
1645 	ph->exprom_bar = pci_config_get32(config_handle,
1646 	    hdr_off + PCI_CONF_ROM);
1647 	ph->int_line = pci_config_get8(config_handle, hdr_off + PCI_CONF_ILINE);
1648 	ph->int_pin = pci_config_get8(config_handle, hdr_off + PCI_CONF_IPIN);
1649 	ph->min_gnt = pci_config_get8(config_handle, hdr_off + PCI_CONF_MIN_G);
1650 	ph->max_lat = pci_config_get8(config_handle, hdr_off + PCI_CONF_MAX_L);
1651 }
1652 
1653 static void
1654 db_pci_get_conf_regs(ddi_acc_handle_t config_handle, db_conf_regs_t *cr)
1655 {
1656 	cr->ds_mem0_tr_base = pci_config_get32(config_handle,
1657 	    DB_CONF_DS_MEM0_TR_BASE);
1658 	cr->ds_io_mem1_tr_base = pci_config_get32(config_handle,
1659 	    DB_CONF_DS_IO_MEM1_TR_BASE);
1660 	cr->ds_mem2_tr_base = pci_config_get32(config_handle,
1661 	    DB_CONF_DS_MEM2_TR_BASE);
1662 	cr->ds_mem3_tr_base = pci_config_get32(config_handle,
1663 	    DB_CONF_DS_MEM3_TR_BASE);
1664 	cr->us_io_mem0_tr_base = pci_config_get32(config_handle,
1665 	    DB_CONF_US_IO_MEM0_TR_BASE);
1666 	cr->us_mem1_tr_base = pci_config_get32(config_handle,
1667 	    DB_CONF_US_MEM1_TR_BASE);
1668 	cr->ds_mem0_setup_reg = pci_config_get32(config_handle,
1669 	    DB_CONF_DS_MEM0_SETUP);
1670 	cr->ds_io_mem1_setup_reg = pci_config_get32(config_handle,
1671 	    DB_CONF_DS_IO_MEM1_SETUP);
1672 	cr->ds_mem2_setup_reg = pci_config_get32(config_handle,
1673 	    DB_CONF_DS_MEM2_SETUP);
1674 	cr->ds_mem3_setup_reg = pci_config_get64(config_handle,
1675 	    DB_CONF_DS_MEM3_SETUP);
1676 	cr->p_exp_rom_setup = pci_config_get32(config_handle,
1677 	    DB_CONF_PRIM_EXP_ROM_SETUP);
1678 	cr->us_io_mem0_setup_reg = pci_config_get32(config_handle,
1679 	    DB_CONF_US_IO_MEM0_SETUP);
1680 	cr->us_mem1_setup_reg = pci_config_get32(config_handle,
1681 	    DB_CONF_US_MEM1_SETUP);
1682 	cr->chip_control0 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL0);
1683 	cr->chip_control1 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL1);
1684 	cr->chip_status = pci_config_get16(config_handle, DB_CONF_STATUS);
1685 	cr->arb_control = pci_config_get16(config_handle, DB_CONF_ARBITER_CTRL);
1686 	cr->p_serr_disables = pci_config_get8(config_handle,
1687 	    DB_CONF_PRIM_SERR_DISABLES);
1688 	cr->s_serr_disables = pci_config_get8(config_handle,
1689 	    DB_CONF_PRIM_SERR_DISABLES);
1690 	cr->config_csr = pci_config_get16(config_handle, DB_CONF_CONF_CSR);
1691 	cr->reset_control = pci_config_get32(config_handle, DB_CONF_RESET_CTRL);
1692 	cr->pm_cap = pci_config_get16(config_handle, DB_CONF_PM_CAP);
1693 	cr->pm_csr = pci_config_get16(config_handle, DB_CONF_PM_CSR);
1694 	cr->hs_csr = pci_config_get8(config_handle, DB_CONF_HS_CSR);
1695 }
1696 #endif	/* DB_DEBUG */
1697 
1698 /*
1699  * Function: db_pci_map
1700  *
1701  * Note:  	Only memory accesses are direct. IO could be direct
1702  * 		or indirect. Config accesses are always indirect.
1703  * 		The question here is, does the "assigned-addresses"
1704  * 		property entry represents the addresses in the
1705  * 		local domain or the host domain itself.
1706  * 		Strictly speaking, the assumption should be that
1707  * 		it is in the local domain, as the transactions
1708  * 		upstream or downstream are automatically
1709  * 		translated by the bridge chip anyway.
1710  *
1711  * Return values:
1712  *		DDI_SUCCESS: map call by child device success
1713  *		DDI_FAILURE: map operation failed.
1714  */
1715 
1716 static int
1717 db_pci_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
1718 				off_t offset, off_t len, caddr_t *addrp)
1719 {
1720 	register dev_info_t *pdip;
1721 	int reg_proplen, num_regs, rnumber;
1722 	uint_t	addr_space_type;
1723 	pci_regspec_t *pci_regsetp, pci_reg;
1724 	db_ctrl_t *dbp;
1725 	db_acc_pvt_t	*db_pvt;
1726 	ddi_acc_impl_t *ap;
1727 	ddi_acc_hdl_t *hp;
1728 	db_acc_cfg_addr_t *pci_addr;
1729 	int instance = ddi_get_instance(dip);
1730 
1731 	DB_DEBUG0(DB_PCI_MAP, dip, "enter\n");
1732 
1733 	/* get map type. check for config space */
1734 	switch (mp->map_type) {
1735 
1736 		case DDI_MT_RNUMBER :
1737 			/* get the reg number */
1738 			rnumber = mp->map_obj.rnumber;
1739 
1740 			if (ddi_getlongprop(DDI_DEV_T_ANY, rdip,
1741 			    DDI_PROP_DONTPASS, "reg",
1742 			    (caddr_t)&pci_regsetp, &reg_proplen)
1743 			    != DDI_SUCCESS)
1744 					return (DDI_FAILURE);
1745 
1746 			num_regs = reg_proplen / (int)sizeof (pci_regspec_t);
1747 			if (rnumber >= num_regs) {
1748 				/* this is a DDI_ME_RNUMBER_RANGE error */
1749 				kmem_free(pci_regsetp, reg_proplen);
1750 				return (DDI_FAILURE);
1751 			}
1752 
1753 			pci_reg = pci_regsetp[rnumber];
1754 			kmem_free(pci_regsetp, reg_proplen);
1755 			/* FALLTHROUGH */
1756 		case DDI_MT_REGSPEC :
1757 			if (mp->map_type == DDI_MT_REGSPEC)
1758 				pci_reg = *(pci_regspec_t *)mp->map_obj.rp;
1759 
1760 			/*
1761 			 * Intercept config space accesses only. All other
1762 			 * requests go to the parent.
1763 			 */
1764 			addr_space_type = pci_reg.pci_phys_hi & PCI_ADDR_MASK;
1765 
1766 			DB_DEBUG3(DB_PCI_MAP, dip, "rdip=%lx, rnum=%d(%d)\n",
1767 			    rdip, rnumber, num_regs);
1768 
1769 			/* if we do direct map IO, then lets break here */
1770 			if ((db_io_map_mode & DB_IO_MAP_DIRECT) &&
1771 			    (addr_space_type == PCI_ADDR_IO))
1772 					break;
1773 
1774 			if ((addr_space_type != PCI_ADDR_CONFIG) &&
1775 			    (addr_space_type != PCI_ADDR_IO))
1776 				break;
1777 
1778 			/*
1779 			 * User mapping requests not legal for indirect
1780 			 * IO/Config Space
1781 			 */
1782 			if (mp->map_op == DDI_MO_MAP_HANDLE)
1783 				return (DDI_FAILURE);
1784 
1785 			dbp = (db_ctrl_t *)ddi_get_soft_state(db_state,
1786 			    instance);
1787 			/* get our common access handle */
1788 			hp = (ddi_acc_hdl_t *)mp->map_handlep;
1789 
1790 			/* Check for unmap operation */
1791 			if ((mp->map_op == DDI_MO_UNMAP) ||
1792 			    (mp->map_op == DDI_MO_UNLOCK)) {
1793 					/*
1794 					 * free up memory allocated for our
1795 					 * private access handle.
1796 					 */
1797 					db_pvt = (db_acc_pvt_t *)
1798 					    hp->ah_bus_private;
1799 					DB_DEBUG1(DB_PCI_MAP, dip,
1800 					    "unmap rdip=%lx\n", rdip);
1801 					kmem_free((void *)db_pvt,
1802 					    sizeof (db_acc_pvt_t));
1803 
1804 					/*
1805 					 * unmap operation of PCI IO/config
1806 					 * space.
1807 					 */
1808 					return (DDI_SUCCESS);
1809 			}
1810 
1811 			if (addr_space_type == PCI_ADDR_CONFIG) {
1812 				/* Config space access range check */
1813 				if ((offset >= PCI_CONF_HDR_SIZE) ||
1814 				    (len > PCI_CONF_HDR_SIZE) ||
1815 				    (offset + len > PCI_CONF_HDR_SIZE)) {
1816 
1817 					return (DDI_FAILURE);
1818 				}
1819 			}
1820 
1821 			/* define the complete access handle */
1822 			hp = (ddi_acc_hdl_t *)mp->map_handlep;
1823 
1824 			ap = (ddi_acc_impl_t *)hp->ah_platform_private;
1825 
1826 			ap->ahi_get8 = db_ddi_get8;
1827 			ap->ahi_get16 = db_ddi_get16;
1828 			ap->ahi_get32 = db_ddi_get32;
1829 			ap->ahi_get64 = db_ddi_get64;
1830 			ap->ahi_put8 = db_ddi_put8;
1831 			ap->ahi_put16 = db_ddi_put16;
1832 			ap->ahi_put32 = db_ddi_put32;
1833 			ap->ahi_put64 = db_ddi_put64;
1834 			ap->ahi_rep_get8 = db_ddi_rep_get8;
1835 			ap->ahi_rep_get16 = db_ddi_rep_get16;
1836 			ap->ahi_rep_get32 = db_ddi_rep_get32;
1837 			ap->ahi_rep_get64 = db_ddi_rep_get64;
1838 			ap->ahi_rep_put8 = db_ddi_rep_put8;
1839 			ap->ahi_rep_put16 = db_ddi_rep_put16;
1840 			ap->ahi_rep_put32 = db_ddi_rep_put32;
1841 			ap->ahi_rep_put64 = db_ddi_rep_put64;
1842 
1843 			/* Initialize to default check/notify functions */
1844 			ap->ahi_fault = 0;
1845 			ap->ahi_fault_check = i_ddi_acc_fault_check;
1846 			ap->ahi_fault_notify = i_ddi_acc_fault_notify;
1847 
1848 			/* allocate memory for our private handle */
1849 			db_pvt = kmem_zalloc(sizeof (db_acc_pvt_t), KM_SLEEP);
1850 			hp->ah_bus_private = (void *)db_pvt;
1851 			db_pvt->dbp = dbp;
1852 
1853 			/* record the device address for future use */
1854 			pci_addr = &db_pvt->dev_addr;
1855 			pci_addr->c_busnum =
1856 			    PCI_REG_BUS_G(pci_reg.pci_phys_hi);
1857 			pci_addr->c_devnum =
1858 			    PCI_REG_DEV_G(pci_reg.pci_phys_hi);
1859 			pci_addr->c_funcnum =
1860 			    PCI_REG_FUNC_G(pci_reg.pci_phys_hi);
1861 			/*
1862 			 * We should keep the upstream or
1863 			 * downstream info in our own ah_bus_private
1864 			 * structure, so that we do not waste our
1865 			 * time in the actual IO routines, figuring out
1866 			 * if we should use upstream or downstream
1867 			 * configuration addr/data register.
1868 			 * So, check orientation and setup registers
1869 			 * right now.
1870 			 */
1871 			switch (addr_space_type) {
1872 
1873 			case PCI_ADDR_CONFIG :
1874 				if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1875 					DB_DEBUG0(DB_PCI_MAP, dip, "primary\n");
1876 					db_pvt->mask = DS8_CONF_OWN;
1877 					if (db_conf_map_mode &
1878 					    DB_CONF_MAP_INDIRECT_IO) {
1879 						DB_DEBUG0(DB_PCI_MAP, dip,
1880 						    "INDIRECT_CONF\n");
1881 
1882 						db_pvt->handle =
1883 						    dbp->csr_io_handle;
1884 						db_pvt->addr =
1885 						    (uint32_t *)
1886 						    ((uchar_t *)dbp->csr_io
1887 						    + DB_CSR_DS_CONF_ADDR);
1888 						db_pvt->data =
1889 						    (uint32_t *)
1890 						    ((uchar_t *)dbp->csr_io
1891 						    + DB_CSR_DS_CONF_DATA);
1892 						db_pvt->bus_own =
1893 						    (uint8_t *)
1894 						    ((uchar_t *)dbp->csr_io
1895 						    + DB_CSR8_DS_CONF_OWN);
1896 						db_pvt->bus_release =
1897 						    (uint8_t *)
1898 						    ((uchar_t *)dbp->csr_io
1899 						    + DB_CSR8_DS_CONF_CSR);
1900 					} else {
1901 						DB_DEBUG0(DB_PCI_MAP, dip,
1902 						    "DIRECT_CONF\n");
1903 
1904 						db_pvt->handle =
1905 						    dbp->conf_handle;
1906 						db_pvt->addr =
1907 						    (uint32_t *)
1908 						    ((uchar_t *)dbp->conf_io
1909 						    + DB_CONF_DS_CONF_ADDR);
1910 						db_pvt->data = (uint32_t *)
1911 						    ((uchar_t *)dbp->conf_io
1912 						    + DB_CONF_DS_CONF_DATA);
1913 						db_pvt->bus_own =
1914 						    (uint8_t *)
1915 						    ((uchar_t *)dbp->conf_io
1916 						    + DB_CONF8_DS_CONF_OWN);
1917 						db_pvt->bus_release =
1918 						    (uint8_t *)
1919 						    ((uchar_t *)dbp->conf_io
1920 						    + DB_CONF8_DS_CONF_CSR);
1921 					}
1922 				} else {
1923 					DB_DEBUG0(DB_PCI_MAP, dip,
1924 					    "secondary\n");
1925 					db_pvt->mask = US8_CONF_OWN;
1926 					if (db_conf_map_mode &
1927 					    DB_CONF_MAP_INDIRECT_IO) {
1928 						DB_DEBUG0(DB_PCI_MAP, dip,
1929 						    "INDIRECT_CONF\n");
1930 
1931 						db_pvt->handle =
1932 						    dbp->csr_io_handle;
1933 						db_pvt->addr =
1934 						    (uint32_t *)
1935 						    ((uchar_t *)dbp->csr_io
1936 						    + DB_CSR_US_CONF_ADDR);
1937 						db_pvt->data =
1938 						    (uint32_t *)
1939 						    ((uchar_t *)dbp->csr_io
1940 						    + DB_CSR_US_CONF_DATA);
1941 						db_pvt->bus_own =
1942 						    (uint8_t *)
1943 						    ((uchar_t *)dbp->csr_io
1944 						    + DB_CSR8_US_CONF_OWN);
1945 						db_pvt->bus_release =
1946 						    (uint8_t *)
1947 						    ((uchar_t *)dbp->csr_io
1948 						    + DB_CSR8_US_CONF_CSR);
1949 					} else {
1950 						DB_DEBUG0(DB_PCI_MAP, dip,
1951 						    "DIRECT_CONF\n");
1952 
1953 						db_pvt->handle =
1954 						    dbp->conf_handle;
1955 						db_pvt->addr =
1956 						    (uint32_t *)
1957 						    ((uchar_t *)dbp->conf_io
1958 						    + DB_CONF_US_CONF_ADDR);
1959 						db_pvt->data =
1960 						    (uint32_t *)
1961 						    ((uchar_t *)dbp->conf_io
1962 						    + DB_CONF_US_CONF_DATA);
1963 						db_pvt->bus_own =
1964 						    (uint8_t *)
1965 						    ((uchar_t *)dbp->conf_io
1966 						    + DB_CONF8_US_CONF_OWN);
1967 						db_pvt->bus_release =
1968 						    (uint8_t *)
1969 						    ((uchar_t *)dbp->conf_io
1970 						    + DB_CONF8_US_CONF_CSR);
1971 					}
1972 				}
1973 				break;
1974 
1975 			case PCI_ADDR_IO :
1976 				DB_DEBUG0(DB_PCI_MAP, dip, "PCI_ADDR_IO\n");
1977 
1978 				/* ap->ahi_acc_attr |= DDI_ACCATTR_IO_SPACE; */
1979 				db_pvt->handle = dbp->csr_io_handle;
1980 				if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1981 					DB_DEBUG0(DB_PCI_MAP, dip, "primary\n");
1982 					db_pvt->addr = (uint32_t *)
1983 					    ((uchar_t *)dbp->csr_io
1984 					    + DB_CSR_DS_IO_ADDR);
1985 					db_pvt->data = (uint32_t *)
1986 					    ((uchar_t *)dbp->csr_io
1987 					    + DB_CSR_DS_IO_DATA);
1988 					db_pvt->bus_own = (uint8_t *)
1989 					    ((uchar_t *)dbp->csr_io
1990 					    + DB_CSR8_DS_IO_OWN);
1991 					db_pvt->bus_release = (uint8_t *)
1992 					    ((uchar_t *)dbp->csr_io
1993 					    + DB_CSR8_DS_IO_CSR);
1994 					db_pvt->mask = DS8_IO_OWN;
1995 				} else {
1996 					DB_DEBUG0(DB_PCI_MAP, dip,
1997 					    "secondary\n");
1998 					db_pvt->addr = (uint32_t *)
1999 					    ((uchar_t *)dbp->csr_io
2000 					    + DB_CSR_US_IO_ADDR);
2001 					db_pvt->data = (uint32_t *)
2002 					    ((uchar_t *)dbp->csr_io
2003 					    + DB_CSR_US_IO_DATA);
2004 					db_pvt->bus_own = (uint8_t *)
2005 					    ((uchar_t *)dbp->csr_io
2006 					    + DB_CSR8_US_IO_OWN);
2007 					db_pvt->bus_release = (uint8_t *)
2008 					    ((uchar_t *)dbp->csr_io
2009 					    + DB_CSR8_US_IO_CSR);
2010 					db_pvt->mask = US8_IO_OWN;
2011 				}
2012 				break;
2013 
2014 			default :
2015 				DB_DEBUG0(DB_PCI_MAP, dip,
2016 				    "PCI_ADDR unknown\n");
2017 				break;
2018 			}
2019 
2020 			/* make and store a type 0/1 address in the *addrp */
2021 			if (pci_addr->c_busnum == dbp->range.lo) {
2022 				*addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE0(
2023 				    pci_addr->c_busnum,
2024 				    pci_addr->c_devnum,
2025 				    pci_addr->c_funcnum,
2026 				    offset);
2027 				db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE0;
2028 				DB_DEBUG0(DB_PCI_MAP, dip,
2029 				    "access mode type 0\n");
2030 			} else {
2031 				*addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE1(
2032 				    pci_addr->c_busnum,
2033 				    pci_addr->c_devnum,
2034 				    pci_addr->c_funcnum,
2035 				    offset);
2036 				db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE1;
2037 				DB_DEBUG0(DB_PCI_MAP, dip,
2038 				    "access mode type 1\n");
2039 			}
2040 			DB_DEBUG4(DB_PCI_MAP, dip, "addrp<%x,%x,%x> = %lx\n",
2041 			    pci_addr->c_busnum, pci_addr->c_devnum,
2042 			    pci_addr->c_funcnum, *addrp);
2043 
2044 			return (DDI_SUCCESS);
2045 
2046 		default :
2047 				DB_DEBUG1(DB_PCI_MAP, dip, "DDI other %x\n",
2048 				    mp->map_type);
2049 				break;
2050 	}
2051 	DB_DEBUG0(DB_PCI_MAP, dip, "exit\n");
2052 
2053 	pdip = (dev_info_t *)DEVI(dip)->devi_parent;
2054 	return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)
2055 	    (pdip, rdip, mp, offset, len, addrp));
2056 }
2057 
2058 #ifdef DB_DEBUG
2059 char *db_ctlop_name[] = {
2060 	"DDI_CTLOPS_DMAPMAPC",
2061 	"DDI_CTLOPS_INITCHILD",
2062 	"DDI_CTLOPS_UNINITCHILD",
2063 	"DDI_CTLOPS_REPORTDEV",
2064 	"DDI_CTLOPS_REPORTINT",
2065 	"DDI_CTLOPS_REGSIZE",
2066 	"DDI_CTLOPS_NREGS",
2067 	"DDI_CTLOPS_RESERVED0",
2068 	"DDI_CTLOPS_SIDDEV",
2069 	"DDI_CTLOPS_SLAVEONLY",
2070 	"DDI_CTLOPS_AFFINITY",
2071 	"DDI_CTLOPS_IOMIN",
2072 	"DDI_CTLOPS_PTOB",
2073 	"DDI_CTLOPS_BTOP",
2074 	"DDI_CTLOPS_BTOPR",
2075 	"DDI_CTLOPS_RESERVED1",
2076 	"DDI_CTLOPS_RESERVED2",
2077 	"DDI_CTLOPS_RESERVED3",
2078 	"DDI_CTLOPS_RESERVED4",
2079 	"DDI_CTLOPS_RESERVED5",
2080 	"DDI_CTLOPS_DVMAPAGESIZE",
2081 	"DDI_CTLOPS_POWER",
2082 	"DDI_CTLOPS_ATTACH",
2083 	"DDI_CTLOPS_DETACH",
2084 	"DDI_CTLOPS_POKE",
2085 	"DDI_CTLOPS_PEEK"
2086 };
2087 #endif
2088 
2089 static int
2090 db_ctlops(dev_info_t *dip, dev_info_t *rdip,
2091 	ddi_ctl_enum_t ctlop, void *arg, void *result)
2092 {
2093 
2094 	if ((ctlop >= DDI_CTLOPS_DMAPMAPC) &&
2095 	    (ctlop <= DDI_CTLOPS_DETACH)) {
2096 		DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%s\n", db_ctlop_name[ctlop]);
2097 	} else {
2098 		DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%d\n", ctlop);
2099 	}
2100 
2101 	switch (ctlop) {
2102 	case DDI_CTLOPS_REPORTDEV :
2103 		if (rdip == (dev_info_t *)0)
2104 			return (DDI_FAILURE);
2105 		cmn_err(CE_CONT, "?PCI-device: %s@%s, %s#%d\n",
2106 		    ddi_node_name(rdip), ddi_get_name_addr(rdip),
2107 		    ddi_driver_name(rdip),
2108 		    ddi_get_instance(rdip));
2109 		return (DDI_SUCCESS);
2110 
2111 	case DDI_CTLOPS_INITCHILD :
2112 		return (db_initchild((dev_info_t *)arg));
2113 
2114 	case DDI_CTLOPS_UNINITCHILD :
2115 		db_uninitchild((dev_info_t *)arg);
2116 		return (DDI_SUCCESS);
2117 
2118 	case DDI_CTLOPS_SIDDEV :
2119 		return (DDI_SUCCESS);
2120 
2121 	case DDI_CTLOPS_REGSIZE :
2122 	case DDI_CTLOPS_NREGS :
2123 		if (rdip == (dev_info_t *)0)
2124 			return (DDI_FAILURE);
2125 		/* fall through */
2126 
2127 	default :
2128 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
2129 	}
2130 
2131 }
2132 
2133 static dev_info_t *
2134 db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip)
2135 {
2136 	dev_info_t *cdip = rdip;
2137 
2138 	for (; ddi_get_parent(cdip) != dip; cdip = ddi_get_parent(cdip))
2139 		;
2140 
2141 	return (cdip);
2142 }
2143 
2144 static int
2145 db_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
2146     ddi_intr_handle_impl_t *hdlp, void *result)
2147 {
2148 	dev_info_t	*cdip = rdip;
2149 	pci_regspec_t	*pci_rp;
2150 	int		reglen, len;
2151 	uint32_t	d, intr;
2152 
2153 	DB_DEBUG1(DB_INTR_OPS, dip, "intr_op=%d\n",  intr_op);
2154 
2155 	if ((intr_op == DDI_INTROP_SUPPORTED_TYPES) ||
2156 	    (hdlp->ih_type != DDI_INTR_TYPE_FIXED))
2157 		goto done;
2158 
2159 	/*
2160 	 * If the interrupt-map property is defined at this
2161 	 * node, it will have performed the interrupt
2162 	 * translation as part of the property, so no
2163 	 * rotation needs to be done.
2164 	 */
2165 
2166 	if (ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2167 	    "interrupt-map", &len) == DDI_PROP_SUCCESS)
2168 		goto done;
2169 
2170 	cdip = db_get_my_childs_dip(dip, rdip);
2171 
2172 	/*
2173 	 * Use the devices reg property to determine it's
2174 	 * PCI bus number and device number.
2175 	 */
2176 	if (ddi_getlongprop(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS,
2177 	    "reg", (caddr_t)&pci_rp, &reglen) != DDI_SUCCESS)
2178 		return (DDI_FAILURE);
2179 
2180 	intr = hdlp->ih_vector;
2181 
2182 	/* Spin the interrupt */
2183 	d = PCI_REG_DEV_G(pci_rp[0].pci_phys_hi);
2184 
2185 	if ((intr >= PCI_INTA) && (intr <= PCI_INTD))
2186 		hdlp->ih_vector = ((intr - 1 + (d % 4)) % 4 + 1);
2187 	else
2188 		cmn_err(CE_WARN, "%s#%d: %s: PCI intr=%x out of range",
2189 		    ddi_driver_name(rdip), ddi_get_instance(rdip),
2190 		    ddi_driver_name(dip), intr);
2191 
2192 	DB_DEBUG3(DB_INTR_OPS, dip, "intr=%d, d=%d, is_intr=%d\n",
2193 	    intr, d, hdlp->ih_vector);
2194 
2195 	kmem_free(pci_rp, reglen);
2196 
2197 done:
2198 	/* Pass up the request to our parent. */
2199 	return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result));
2200 }
2201 
2202 static int
2203 db_name_child(dev_info_t *child, char *name, int namelen)
2204 {
2205 	uint_t n, slot, func;
2206 	pci_regspec_t *pci_rp;
2207 
2208 	if (ndi_dev_is_persistent_node(child) == 0) {
2209 		char **unit_addr;
2210 
2211 		/* name .conf nodes by "unit-address" property" */
2212 		if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child,
2213 		    DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) !=
2214 		    DDI_PROP_SUCCESS) {
2215 			cmn_err(CE_WARN, "cannot name node from %s.conf",
2216 			    ddi_driver_name(child));
2217 			return (DDI_FAILURE);
2218 		}
2219 		if (n != 1 || *unit_addr == NULL || **unit_addr == 0) {
2220 			cmn_err(CE_WARN, "unit-address property in %s.conf"
2221 			    " not well-formed", ddi_driver_name(child));
2222 			ddi_prop_free(unit_addr);
2223 			return (DDI_FAILURE);
2224 		}
2225 
2226 		(void) snprintf(name, namelen, "%s", *unit_addr);
2227 		ddi_prop_free(unit_addr);
2228 		return (DDI_SUCCESS);
2229 	}
2230 
2231 	/* name hardware nodes by "reg" property */
2232 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, 0, "reg",
2233 	    (int **)&pci_rp, &n) != DDI_SUCCESS)
2234 		return (DDI_FAILURE);
2235 
2236 	/* get the device identifications */
2237 	slot = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
2238 	func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
2239 
2240 	if (func != 0)
2241 		(void) snprintf(name, namelen, "%x,%x", slot, func);
2242 	else
2243 		(void) snprintf(name, namelen, "%x", slot);
2244 
2245 	ddi_prop_free(pci_rp);
2246 	return (DDI_SUCCESS);
2247 }
2248 
2249 static int
2250 db_initchild(dev_info_t *child)
2251 {
2252 	char name[MAXNAMELEN];
2253 	ddi_acc_handle_t config_handle;
2254 	ushort_t command_preserve, command;
2255 	uint_t n;
2256 	ushort_t bcr;
2257 	uchar_t header_type, min_gnt, latency_timer;
2258 	db_ctrl_t *dbp;
2259 
2260 	if (db_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
2261 		return (DDI_FAILURE);
2262 
2263 	ddi_set_name_addr(child, name);
2264 	ddi_set_parent_data(child, NULL);
2265 
2266 	/*
2267 	 * Pseudo nodes indicate a prototype node with per-instance
2268 	 * properties to be merged into the real h/w device node.
2269 	 * The interpretation of the unit-address is DD[,F]
2270 	 * where DD is the device id and F is the function.
2271 	 */
2272 	if (ndi_dev_is_persistent_node(child) == 0) {
2273 		extern int pci_allow_pseudo_children;
2274 
2275 		/*
2276 		 * Try to merge the properties from this prototype
2277 		 * node into real h/w nodes.
2278 		 */
2279 		if (ndi_merge_node(child, db_name_child) == DDI_SUCCESS) {
2280 			/*
2281 			 * Merged ok - return failure to remove the node.
2282 			 */
2283 			return (DDI_FAILURE);
2284 		}
2285 
2286 		/* workaround for ddivs to run under PCI */
2287 		if (pci_allow_pseudo_children) {
2288 			return (DDI_SUCCESS);
2289 		}
2290 
2291 		/*
2292 		 * The child was not merged into a h/w node,
2293 		 * but there's not much we can do with it other
2294 		 * than return failure to cause the node to be removed.
2295 		 */
2296 		cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
2297 		    ddi_driver_name(child), ddi_get_name_addr(child),
2298 		    ddi_driver_name(child));
2299 		return (DDI_NOT_WELL_FORMED);
2300 	}
2301 
2302 
2303 	if ((db_create_pci_prop(child) != DDI_SUCCESS) ||
2304 	    (pci_config_setup(child, &config_handle) != DDI_SUCCESS)) {
2305 		db_uninitchild(child);
2306 		return (DDI_FAILURE);
2307 	}
2308 
2309 	/*
2310 	 * Determine the configuration header type.
2311 	 */
2312 	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
2313 
2314 	/*
2315 	 * Support for the "command-preserve" property.
2316 	 */
2317 	command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
2318 	    DDI_PROP_DONTPASS, "command-preserve", 0);
2319 	command = pci_config_get16(config_handle, PCI_CONF_COMM);
2320 	command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
2321 	command |= (db_command_default & ~command_preserve);
2322 	pci_config_put16(config_handle, PCI_CONF_COMM, command);
2323 
2324 	DB_DEBUG2(DB_INITCHILD, ddi_get_parent(child),
2325 	    "initializing device vend=%x, devid=%x\n",
2326 	    pci_config_get16(config_handle, PCI_CONF_VENID),
2327 	    pci_config_get16(config_handle, PCI_CONF_DEVID));
2328 	/*
2329 	 * If the device has a bus control register then program it
2330 	 * based on the settings in the command register.
2331 	 */
2332 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
2333 		bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
2334 		if (db_command_default & PCI_COMM_PARITY_DETECT)
2335 			bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
2336 		if (db_command_default & PCI_COMM_SERR_ENABLE)
2337 			bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
2338 		bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
2339 		pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
2340 	}
2341 
2342 	dbp = (db_ctrl_t *)ddi_get_soft_state(db_state,
2343 	    ddi_get_instance(ddi_get_parent(child)));
2344 
2345 	/*
2346 	 * Initialize cache-line-size configuration register if needed.
2347 	 */
2348 	if (db_set_cache_line_size_register &&
2349 	    ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
2350 	    "cache-line-size", 0) == 0) {
2351 		pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
2352 		    dbp->cache_line_size);
2353 		n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
2354 		if (n != 0) {
2355 			(void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
2356 			    "cache-line-size", n);
2357 		}
2358 		DB_DEBUG1(DB_INITCHILD, ddi_get_parent(child),
2359 		    "\nChild Device Cache Size %x\n", dbp->cache_line_size);
2360 	}
2361 
2362 	/*
2363 	 * Initialize latency timer configuration registers if needed.
2364 	 */
2365 	if (db_set_latency_timer_register &&
2366 	    ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
2367 	    "latency-timer", 0) == 0) {
2368 
2369 		if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
2370 			latency_timer = dbp->p_latency_timer;
2371 			pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
2372 			    dbp->latency_timer);
2373 		} else {
2374 			min_gnt = pci_config_get8(config_handle,
2375 			    PCI_CONF_MIN_G);
2376 			latency_timer = min_gnt * 8;
2377 		}
2378 		pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
2379 		    latency_timer);
2380 		n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
2381 		if (n != 0) {
2382 			(void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
2383 			    "latency-timer", n);
2384 		}
2385 		DB_DEBUG1(DB_INITCHILD, ddi_get_parent(child),
2386 		    "\nChild Device latency %x\n", latency_timer);
2387 	}
2388 
2389 	pci_config_teardown(&config_handle);
2390 	return (DDI_SUCCESS);
2391 }
2392 
2393 static void
2394 db_uninitchild(dev_info_t *dip)
2395 {
2396 	ddi_set_name_addr(dip, NULL);
2397 
2398 	/*
2399 	 * Strip the node to properly convert it back to prototype form
2400 	 */
2401 	impl_rem_dev_props(dip);
2402 }
2403 
2404 static int
2405 db_create_pci_prop(dev_info_t *child)
2406 {
2407 	pci_regspec_t *pci_rp;
2408 	int	length;
2409 	int	value;
2410 
2411 	/* get child "reg" property */
2412 	value = ddi_getlongprop(DDI_DEV_T_ANY, child, DDI_PROP_CANSLEEP,
2413 	    "reg", (caddr_t)&pci_rp, &length);
2414 	if (value != DDI_SUCCESS)
2415 		return (value);
2416 
2417 	(void) ndi_prop_update_byte_array(DDI_DEV_T_NONE, child, "reg",
2418 	    (uchar_t *)pci_rp, length);
2419 
2420 	/*
2421 	 * free the memory allocated by ddi_getlongprop ().
2422 	 */
2423 	kmem_free(pci_rp, length);
2424 
2425 	/*
2426 	 * No need to create any 1275 properties here, because either
2427 	 * the OBP creates them or the hotplug framework creates it
2428 	 * during a hotplug operation. So lets return here.
2429 	 */
2430 	return (DDI_SUCCESS);
2431 }
2432 
2433 /*
2434  * db_save_config_regs
2435  *
2436  * This routine saves the state of the configuration registers of all
2437  * immediate child nodes.
2438  *
2439  * used by: db_detach() on suspends
2440  *
2441  * return value: DDI_SUCCESS: ALl children state saved.
2442  *		 DDI_FAILURE: Child device state could not be saved.
2443  */
2444 static int
2445 db_save_config_regs(db_ctrl_t *dbp)
2446 {
2447 	int i;
2448 	dev_info_t *dip;
2449 	ddi_acc_handle_t config_handle;
2450 	db_cfg_state_t *statep;
2451 
2452 	for (i = 0, dip = ddi_get_child(dbp->dip); dip != NULL;
2453 	    dip = ddi_get_next_sibling(dip)) {
2454 		if (i_ddi_devi_attached(dip))
2455 			i++;
2456 	}
2457 	dbp->config_state_index = i;
2458 
2459 	if (!i) {
2460 		/* no children */
2461 		dbp->db_config_state_p = NULL;
2462 		return (DDI_SUCCESS);
2463 	}
2464 
2465 	/* i now equals the total number of child devices */
2466 	dbp->db_config_state_p =
2467 	    kmem_zalloc(i * sizeof (db_cfg_state_t), KM_NOSLEEP);
2468 	if (!dbp->db_config_state_p) {
2469 		cmn_err(CE_WARN,
2470 		    "%s#%d: No memory to save state for child %s#%d\n",
2471 		    ddi_driver_name(dbp->dip),
2472 		    ddi_get_instance(dbp->dip),
2473 		    ddi_get_name(dip), ddi_get_instance(dip));
2474 		return (DDI_FAILURE);
2475 	}
2476 
2477 	for (statep = dbp->db_config_state_p,
2478 	    dip = ddi_get_child(dbp->dip);
2479 	    dip != NULL;
2480 	    dip = ddi_get_next_sibling(dip)) {
2481 
2482 		if (!i_ddi_devi_attached(dip))
2483 			continue;
2484 
2485 		if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
2486 			cmn_err(CE_WARN,
2487 			    "%s#%d: can't config space for %s#%d",
2488 			    ddi_driver_name(dbp->dip),
2489 			    ddi_get_instance(dbp->dip),
2490 			    ddi_driver_name(dip),
2491 			    ddi_get_instance(dip));
2492 			continue;
2493 		}
2494 
2495 		statep->dip = dip;
2496 		statep->command =
2497 		    pci_config_get16(config_handle, PCI_CONF_COMM);
2498 		statep->header_type =
2499 		    pci_config_get8(config_handle, PCI_CONF_HEADER);
2500 		if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2501 			statep->bridge_control =
2502 			    pci_config_get16(config_handle, PCI_BCNF_BCNTRL);
2503 		statep->cache_line_size =
2504 		    pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
2505 		statep->latency_timer =
2506 		    pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
2507 		if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2508 			statep->sec_latency_timer =
2509 			    pci_config_get8(config_handle,
2510 			    PCI_BCNF_LATENCY_TIMER);
2511 		pci_config_teardown(&config_handle);
2512 		statep++;
2513 	}
2514 	return (DDI_SUCCESS);
2515 }
2516 
2517 
2518 /*
2519  * db_restore_config_regs
2520  *
2521  * This routine restores the state of the configuration registers of
2522  * all immediate child nodes.
2523  *
2524  * used by: db_attach() on resume
2525  *
2526  * return value: none
2527  */
2528 static int
2529 db_restore_config_regs(db_ctrl_t *dbp)
2530 {
2531 	int i;
2532 	dev_info_t *dip;
2533 	ddi_acc_handle_t config_handle;
2534 	db_cfg_state_t *statep = dbp->db_config_state_p;
2535 
2536 	for (i = 0; i < dbp->config_state_index; i++, statep++) {
2537 		dip = statep->dip;
2538 		if (!dip) {
2539 			cmn_err(CE_WARN,
2540 			    "%s#%d: skipping bad dev info (index %d)",
2541 			    ddi_driver_name(dbp->dip),
2542 			    ddi_get_instance(dbp->dip), i);
2543 			continue;
2544 		}
2545 		if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
2546 			cmn_err(CE_WARN,
2547 			    "%s#%d: can't config space for %s#%d",
2548 			    ddi_driver_name(dbp->dip),
2549 			    ddi_get_instance(dbp->dip),
2550 			    ddi_driver_name(dip),
2551 			    ddi_get_instance(dip));
2552 			continue;
2553 		}
2554 		pci_config_put16(config_handle, PCI_CONF_COMM, statep->command);
2555 		if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2556 			pci_config_put16(config_handle, PCI_BCNF_BCNTRL,
2557 			    statep->bridge_control);
2558 		pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
2559 		    statep->cache_line_size);
2560 		pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
2561 		    statep->latency_timer);
2562 		if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2563 			pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
2564 			    statep->sec_latency_timer);
2565 		pci_config_teardown(&config_handle);
2566 	}
2567 
2568 	kmem_free(dbp->db_config_state_p,
2569 	    dbp->config_state_index * sizeof (db_cfg_state_t));
2570 	dbp->db_config_state_p = NULL;
2571 	dbp->config_state_index = 0;
2572 
2573 	return (DDI_SUCCESS);
2574 }
2575 
2576 /* put a type 0/1 address on the bus */
2577 static void
2578 db_put_reg_conf_addr(db_acc_pvt_t *db_pvt, uint32_t conf_addr)
2579 {
2580 	if (db_pvt->access_mode & DB_PCI_CONF_CYCLE_TYPE0)\
2581 		ddi_put32(db_pvt->handle, db_pvt->addr, (uint32_t)\
2582 		    DB_PCI_CONF_CYCLE_TYPE0_ADDR((conf_addr)));\
2583 	else	/* type 1 cycle */\
2584 		ddi_put32(db_pvt->handle, db_pvt->addr, (uint32_t)\
2585 		    DB_PCI_CONF_CYCLE_TYPE1_ADDR((conf_addr)));
2586 }
2587 
2588 /* Get 8bits data off the 32bit data */
2589 static uint8_t
2590 db_get_data8(uint32_t addr, uint32_t data)
2591 {
2592 	return (((data) >> (((addr) & 3) * 8)) & 0xff);
2593 }
2594 
2595 /* Get 16bits data off the 32bit data */
2596 static uint16_t
2597 db_get_data16(uint32_t addr, uint32_t data)
2598 {
2599 	return (((data) >> (((addr) & 3) * 8)) & 0xffff);
2600 }
2601 
2602 /* merge 8bit data into the 32bit data */
2603 static uint32_t
2604 db_put_data8(uint32_t addr, uint32_t rdata, uint8_t wdata)
2605 {
2606 	return ((rdata & (~((0xff << ((((addr) & 3) * 8))) & 0xffffffff))) |
2607 	    (((wdata) & 0xff)<<((((addr) & 3))*8)));
2608 }
2609 
2610 /* merge 16bit data into the 32bit data */
2611 static uint32_t
2612 db_put_data16(uint32_t addr, uint32_t rdata, uint16_t wdata)
2613 {
2614 	return ((rdata & (~((0xffff << ((((addr) & 3) * 8))) & 0xffffffff))) |
2615 	    (((wdata) & 0xffff) << ((((addr) & 3))*8)));
2616 }
2617 
2618 
2619 /*
2620  * For the next set of PCI configuration IO calls, we need
2621  * to make sure we own the bus before generating the config cycles,
2622  * using the drawbridge's semaphore method.
2623  */
2624 
2625 /*
2626  * Function to read 8 bit data off the PCI configuration space behind
2627  * the 21554's host interface.
2628  */
2629 static uint8_t
2630 db_ddi_get8(ddi_acc_impl_t *handle, uint8_t *addr)
2631 {
2632 	uint32_t data;
2633 
2634 	data = db_ddi_get32(handle, (uint32_t *)addr);
2635 	return (db_get_data8((uint32_t)(uintptr_t)addr, data));
2636 }
2637 
2638 /*
2639  * Function to read 16 bit data off the PCI configuration space behind
2640  * the 21554's host interface.
2641  */
2642 static uint16_t
2643 db_ddi_get16(ddi_acc_impl_t *handle, uint16_t *addr)
2644 {
2645 	uint32_t data;
2646 
2647 	data = db_ddi_get32(handle, (uint32_t *)addr);
2648 	return (db_get_data16((uint32_t)(uintptr_t)addr, data));
2649 }
2650 
2651 /*
2652  * Function to read 32 bit data off the PCI configuration space behind
2653  * the 21554's host interface.
2654  */
2655 static uint32_t
2656 db_ddi_get32(ddi_acc_impl_t *handle, uint32_t *addr)
2657 {
2658 	db_acc_pvt_t	*db_pvt = (db_acc_pvt_t *)
2659 	    handle->ahi_common.ah_bus_private;
2660 	uint32_t	wait_count = 0;
2661 	uint32_t	data;
2662 	db_ctrl_t	*dbp;
2663 
2664 	dbp = db_pvt->dbp;
2665 
2666 	mutex_enter(&dbp->db_busown);
2667 
2668 	if (db_use_config_own_bit) {
2669 		/*
2670 		 * check if (upstream/downstream)configuration address own
2671 		 * bit set. With this set, we cannot proceed.
2672 		 */
2673 		while (((ddi_get8(db_pvt->handle, db_pvt->bus_own)) &
2674 		    db_pvt->mask) == db_pvt->mask) {
2675 #ifdef DEBUG
2676 			if (dbp->db_pci_max_wait_count < wait_count)
2677 				dbp->db_pci_max_wait_count = wait_count;
2678 #endif
2679 			drv_usecwait(db_pci_own_wait);
2680 			if (++wait_count == db_pci_max_wait) {
2681 				/*
2682 				 * the man page for pci_config_* routines do
2683 				 * Not specify any error condition values.
2684 				 */
2685 				cmn_err(CE_WARN,
2686 				    "%s#%d: pci config bus own error",
2687 				    ddi_driver_name(dbp->dip),
2688 				    ddi_get_instance(dbp->dip));
2689 				dbp->db_pci_err_count++;
2690 				mutex_exit(&dbp->db_busown);
2691 				return ((uint32_t)DB_CONF_FAILURE);
2692 			}
2693 		}
2694 		wait_count = 0;
2695 	}
2696 
2697 	db_put_reg_conf_addr(db_pvt, (uint32_t)(uintptr_t)addr);
2698 	data = ddi_get32(db_pvt->handle, (uint32_t *)db_pvt->data);
2699 
2700 	if (db_use_config_own_bit) {
2701 		while (((ddi_get8(db_pvt->handle, db_pvt->bus_release)) &
2702 		    db_pvt->mask) == db_pvt->mask) {
2703 #ifdef DEBUG
2704 			if (dbp->db_pci_max_wait_count < wait_count)
2705 				dbp->db_pci_max_wait_count = wait_count;
2706 #endif
2707 			drv_usecwait(db_pci_release_wait);
2708 			if (++wait_count == db_pci_max_wait) {
2709 				/*
2710 				 * the man page for pci_config_* routines do
2711 				 * not specify any error condition values.
2712 				 */
2713 				cmn_err(CE_WARN,
2714 				    "%s#%d: pci config bus release error",
2715 				    ddi_driver_name(dbp->dip),
2716 				    ddi_get_instance(dbp->dip));
2717 				dbp->db_pci_err_count++;
2718 				mutex_exit(&dbp->db_busown);
2719 				return ((uint32_t)DB_CONF_FAILURE);
2720 			}
2721 			data = ddi_get32(db_pvt->handle,
2722 			    (uint32_t *)db_pvt->data);
2723 		}
2724 	}
2725 
2726 	mutex_exit(&dbp->db_busown);
2727 
2728 	return (data);
2729 }
2730 
2731 /*
2732  * Function to read 64 bit data off the PCI configuration space behind
2733  * the 21554's host interface.
2734  */
2735 static uint64_t
2736 db_ddi_get64(ddi_acc_impl_t *handle, uint64_t *addr)
2737 {
2738 	uint64_t udata, ldata;
2739 
2740 	ldata = (uint32_t)db_ddi_get32(handle, (uint32_t *)addr);
2741 	udata = (uint32_t)db_ddi_get32(handle, (uint32_t *)addr + 1);
2742 	return (ldata | (udata << 32));
2743 }
2744 
2745 /*
2746  * Function to write 8 bit data into the PCI configuration space behind
2747  * the 21554's host interface.
2748  */
2749 static void
2750 db_ddi_put8(ddi_acc_impl_t *handle, uint8_t *addr, uint8_t data)
2751 {
2752 	uint32_t rdata;
2753 
2754 	rdata = db_ddi_get32(handle, (uint32_t *)addr);
2755 	db_ddi_put32(handle, (uint32_t *)addr,
2756 	    db_put_data8((uint32_t)(uintptr_t)addr, rdata, data));
2757 }
2758 
2759 /*
2760  * Function to write 16 bit data into the PCI configuration space behind
2761  * the 21554's host interface.
2762  */
2763 static void
2764 db_ddi_put16(ddi_acc_impl_t *handle, uint16_t *addr, uint16_t data)
2765 {
2766 	uint32_t rdata;
2767 
2768 	rdata = db_ddi_get32(handle, (uint32_t *)addr);
2769 	db_ddi_put32(handle, (uint32_t *)addr,
2770 	    db_put_data16((uint32_t)(uintptr_t)addr, rdata, data));
2771 }
2772 
2773 /*
2774  * Function to write 32 bit data into the PCI configuration space behind
2775  * the 21554's host interface.
2776  */
2777 static void
2778 db_ddi_put32(ddi_acc_impl_t *handle, uint32_t *addr, uint32_t data)
2779 {
2780 	db_acc_pvt_t	*db_pvt = (db_acc_pvt_t *)
2781 	    handle->ahi_common.ah_bus_private;
2782 	db_ctrl_t	*dbp;
2783 	uint32_t	wait_count = 0;
2784 
2785 	dbp = db_pvt->dbp;
2786 
2787 	mutex_enter(&dbp->db_busown);
2788 
2789 	if (db_use_config_own_bit) {
2790 		/*
2791 		 * check if (upstream/downstream)configuration address own
2792 		 * bit set. with this set, we cannot proceed.
2793 		 */
2794 		while (((ddi_get8(db_pvt->handle, db_pvt->bus_own)) &
2795 		    db_pvt->mask) == db_pvt->mask) {
2796 #ifdef DEBUG
2797 			if (dbp->db_pci_max_wait_count < wait_count)
2798 				dbp->db_pci_max_wait_count = wait_count;
2799 #endif
2800 			drv_usecwait(db_pci_own_wait);
2801 			if (++wait_count == db_pci_max_wait) {
2802 				/*
2803 				 * Since the return value is void here,
2804 				 * we may need to print a message, as this
2805 				 * could be a serious situation.
2806 				 */
2807 				cmn_err(CE_WARN,
2808 				    "%s#%d: pci config bus own error",
2809 				    ddi_driver_name(dbp->dip),
2810 				    ddi_get_instance(dbp->dip));
2811 				dbp->db_pci_err_count++;
2812 				mutex_exit(&dbp->db_busown);
2813 				return;
2814 			}
2815 		}
2816 		wait_count = 0;
2817 	}
2818 
2819 	db_put_reg_conf_addr(db_pvt, (uint32_t)(uintptr_t)addr);
2820 	ddi_put32(db_pvt->handle, (uint32_t *)db_pvt->data, data);
2821 
2822 	if (db_use_config_own_bit) {
2823 		while (((ddi_get8(db_pvt->handle, db_pvt->bus_release)) &
2824 		    db_pvt->mask) == db_pvt->mask) {
2825 #ifdef DEBUG
2826 			if (dbp->db_pci_max_wait_count < wait_count)
2827 				dbp->db_pci_max_wait_count = wait_count;
2828 #endif
2829 			drv_usecwait(db_pci_release_wait);
2830 			if (++wait_count == db_pci_max_wait) {
2831 				/*
2832 				 * the man page for pci_config_* routines do
2833 				 * Not specify any error condition values.
2834 				 */
2835 				cmn_err(CE_WARN,
2836 				    "%s#%d: pci config bus release error",
2837 				    ddi_driver_name(dbp->dip),
2838 				    ddi_get_instance(dbp->dip));
2839 				dbp->db_pci_err_count++;
2840 				mutex_exit(&dbp->db_busown);
2841 				return;
2842 			}
2843 			ddi_put32(db_pvt->handle, (uint32_t *)db_pvt->data,
2844 			    data);
2845 		}
2846 	}
2847 
2848 	mutex_exit(&dbp->db_busown);
2849 }
2850 
2851 /*
2852  * Function to write 64 bit data into the PCI configuration space behind
2853  * the 21554's host interface.
2854  */
2855 static void
2856 db_ddi_put64(ddi_acc_impl_t *handle, uint64_t *addr, uint64_t data)
2857 {
2858 	db_ddi_put32(handle, (uint32_t *)addr, (uint32_t)(data & 0xffffffff));
2859 	db_ddi_put32(handle, (uint32_t *)addr + 1, (uint32_t)(data >> 32));
2860 }
2861 
2862 /*
2863  * Function to rep read 8 bit data off the PCI configuration space behind
2864  * the 21554's host interface.
2865  */
2866 static void
2867 db_ddi_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr,
2868 			uint8_t *dev_addr, size_t repcount, uint_t flags)
2869 {
2870 	if (flags == DDI_DEV_AUTOINCR)
2871 		for (; repcount; repcount--)
2872 			*host_addr++ = db_ddi_get8(handle, dev_addr++);
2873 	else
2874 		for (; repcount; repcount--)
2875 			*host_addr++ = db_ddi_get8(handle, dev_addr);
2876 }
2877 
2878 /*
2879  * Function to rep read 16 bit data off the PCI configuration space behind
2880  * the 21554's host interface.
2881  */
2882 static void
2883 db_ddi_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr,
2884 			uint16_t *dev_addr, size_t repcount, uint_t flags)
2885 {
2886 	if (flags == DDI_DEV_AUTOINCR)
2887 		for (; repcount; repcount--)
2888 			*host_addr++ = db_ddi_get16(handle, dev_addr++);
2889 	else
2890 		for (; repcount; repcount--)
2891 			*host_addr++ = db_ddi_get16(handle, dev_addr);
2892 }
2893 
2894 /*
2895  * Function to rep read 32 bit data off the PCI configuration space behind
2896  * the 21554's host interface.
2897  */
2898 static void
2899 db_ddi_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr,
2900 			uint32_t *dev_addr, size_t repcount, uint_t flags)
2901 {
2902 	if (flags == DDI_DEV_AUTOINCR)
2903 		for (; repcount; repcount--)
2904 			*host_addr++ = db_ddi_get32(handle, dev_addr++);
2905 	else
2906 		for (; repcount; repcount--)
2907 			*host_addr++ = db_ddi_get32(handle, dev_addr);
2908 }
2909 
2910 /*
2911  * Function to rep read 64 bit data off the PCI configuration space behind
2912  * the 21554's host interface.
2913  */
2914 static void
2915 db_ddi_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr,
2916 			uint64_t *dev_addr, size_t repcount, uint_t flags)
2917 {
2918 	if (flags == DDI_DEV_AUTOINCR)
2919 		for (; repcount; repcount--)
2920 			*host_addr++ = db_ddi_get64(handle, dev_addr++);
2921 	else
2922 		for (; repcount; repcount--)
2923 			*host_addr++ = db_ddi_get64(handle, dev_addr);
2924 }
2925 
2926 /*
2927  * Function to rep write 8 bit data into the PCI configuration space behind
2928  * the 21554's host interface.
2929  */
2930 static void
2931 db_ddi_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr,
2932 			uint8_t *dev_addr, size_t repcount, uint_t flags)
2933 {
2934 	if (flags == DDI_DEV_AUTOINCR)
2935 		for (; repcount; repcount--)
2936 			db_ddi_put8(handle, dev_addr++, *host_addr++);
2937 	else
2938 		for (; repcount; repcount--)
2939 			db_ddi_put8(handle, dev_addr, *host_addr++);
2940 }
2941 
2942 /*
2943  * Function to rep write 16 bit data into the PCI configuration space behind
2944  * the 21554's host interface.
2945  */
2946 static void
2947 db_ddi_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr,
2948 			uint16_t *dev_addr, size_t repcount, uint_t flags)
2949 {
2950 	if (flags == DDI_DEV_AUTOINCR)
2951 		for (; repcount; repcount--)
2952 			db_ddi_put16(handle, dev_addr++, *host_addr++);
2953 	else
2954 		for (; repcount; repcount--)
2955 			db_ddi_put16(handle, dev_addr, *host_addr++);
2956 }
2957 
2958 /*
2959  * Function to rep write 32 bit data into the PCI configuration space behind
2960  * the 21554's host interface.
2961  */
2962 static void
2963 db_ddi_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr,
2964 			uint32_t *dev_addr, size_t repcount, uint_t flags)
2965 {
2966 	if (flags == DDI_DEV_AUTOINCR)
2967 		for (; repcount; repcount--)
2968 			db_ddi_put32(handle, dev_addr++, *host_addr++);
2969 	else
2970 		for (; repcount; repcount--)
2971 			db_ddi_put32(handle, dev_addr, *host_addr++);
2972 }
2973 
2974 /*
2975  * Function to rep write 64 bit data into the PCI configuration space behind
2976  * the 21554's host interface.
2977  */
2978 static void
2979 db_ddi_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr,
2980 			uint64_t *dev_addr, size_t repcount, uint_t flags)
2981 {
2982 	if (flags == DDI_DEV_AUTOINCR)
2983 		for (; repcount; repcount--)
2984 			db_ddi_put64(handle, dev_addr++, *host_addr++);
2985 	else
2986 		for (; repcount; repcount--)
2987 			db_ddi_put64(handle, dev_addr, *host_addr++);
2988 }
2989 
2990 #ifdef DEBUG
2991 
2992 static void
2993 db_debug(uint64_t func_id, dev_info_t *dip, char *fmt,
2994 	uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5)
2995 {
2996 	char *s = NULL;
2997 	uint_t dip_no_disp = 0;
2998 
2999 	if (func_id & DB_DONT_DISPLAY_DIP) {
3000 		dip_no_disp = 1;
3001 	}
3002 	if (db_debug_funcs & func_id) {
3003 		switch (func_id) {
3004 		case DB_INIT:		s = "_init";			break;
3005 		case DB_FINI:		s = "_fini";			break;
3006 		case DB_INFO:		s = "_info";			break;
3007 		case DB_GETINFO:	s = "getinfo";			break;
3008 		case DB_ATTACH:		s = "attach";			break;
3009 		case DB_DETACH:		s = "detach";			break;
3010 		case DB_CTLOPS:		s = "ctlops";			break;
3011 		case DB_INITCHILD:	s = "initchild";		break;
3012 		case DB_REMOVECHILD:	s = "removechild";		break;
3013 		case DB_INTR_OPS:	s = "intr_ops";			break;
3014 		case DB_PCI_MAP:	s = "map";			break;
3015 		case DB_SAVE_CONF_REGS:	s = "save_conf_regs";		break;
3016 		case DB_REST_CONF_REGS:	s = "restore_conf_regs";	break;
3017 		case DB_INTR:		s = "intr";			break;
3018 		case DB_OPEN:		s = "open";			break;
3019 		case DB_CLOSE:		s = "close";			break;
3020 		case DB_IOCTL:		s = "ioctl";			break;
3021 		case DB_DVMA:		s = "set_dvma_range";		break;
3022 
3023 		default:		s = "PCI debug unknown";	break;
3024 		}
3025 
3026 		if (s && !dip_no_disp) {
3027 			prom_printf("%s(%d): %s: ", ddi_driver_name(dip),
3028 			    ddi_get_instance(dip), s);
3029 		}
3030 		prom_printf(fmt, a1, a2, a3, a4, a5);
3031 	}
3032 }
3033 #endif
3034 
3035 static int db_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
3036     int flags, char *name, caddr_t valuep, int *lengthp)
3037 {
3038 	minor_t minor = getminor(dev);
3039 	int	instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
3040 
3041 	db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
3042 
3043 
3044 	if (dbp == NULL)
3045 		return (ENXIO);
3046 
3047 	if (dbp->dev_state & DB_SECONDARY_NEXUS)
3048 		return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip,
3049 		    prop_op, flags, name, valuep, lengthp));
3050 
3051 	return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
3052 }
3053 
3054 /*
3055  * Initialize our FMA resources
3056  */
3057 static void
3058 db_fm_init(db_ctrl_t *db_p)
3059 {
3060 	db_p->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
3061 	    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
3062 
3063 	/*
3064 	 * Request our capability level and get our parents capability
3065 	 * and ibc.
3066 	 */
3067 	ddi_fm_init(db_p->dip, &db_p->fm_cap, &db_p->fm_ibc);
3068 	ASSERT((db_p->fm_cap & DDI_FM_EREPORT_CAPABLE) &&
3069 	    (db_p->fm_cap & DDI_FM_ERRCB_CAPABLE));
3070 
3071 	pci_ereport_setup(db_p->dip);
3072 
3073 	/*
3074 	 * Register error callback with our parent.
3075 	 */
3076 	ddi_fm_handler_register(db_p->dip, db_err_callback, NULL);
3077 }
3078 
3079 /*
3080  * Breakdown our FMA resources
3081  */
3082 static void
3083 db_fm_fini(db_ctrl_t *db_p)
3084 {
3085 	/*
3086 	 * Clean up allocated fm structures
3087 	 */
3088 	ddi_fm_handler_unregister(db_p->dip);
3089 	pci_ereport_teardown(db_p->dip);
3090 	ddi_fm_fini(db_p->dip);
3091 }
3092 
3093 /*
3094  * Initialize FMA resources for children devices. Called when
3095  * child calls ddi_fm_init().
3096  */
3097 /*ARGSUSED*/
3098 static int
3099 db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap,
3100 		ddi_iblock_cookie_t *ibc)
3101 {
3102 	db_ctrl_t *db_p = (db_ctrl_t *)ddi_get_soft_state(db_state,
3103 	    ddi_get_instance(dip));
3104 	*ibc = db_p->fm_ibc;
3105 	return (db_p->fm_cap);
3106 }
3107 
3108 /*
3109  * FMA registered error callback
3110  */
3111 static int
3112 db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data)
3113 {
3114 	ASSERT(impl_data == NULL);
3115 	pci_ereport_post(dip, derr, NULL);
3116 	return (derr->fme_status);
3117 }
3118 
3119 static void
3120 db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle)
3121 {
3122 	i_ndi_busop_access_enter(dip, handle);
3123 }
3124 
3125 /* ARGSUSED */
3126 static void
3127 db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle)
3128 {
3129 	i_ndi_busop_access_exit(dip, handle);
3130 }
3131