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