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