xref: /titanic_50/usr/src/uts/sun4u/opl/io/pcicmu/pcicmu.c (revision 3fbbb872ea33adea240e8fd8c692f6d3131cc69b)
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 2007 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  * OPL CMU-CH PCI nexus driver.
30  *
31  */
32 
33 #include <sys/types.h>
34 #include <sys/sysmacros.h>
35 #include <sys/systm.h>
36 #include <sys/intreg.h>
37 #include <sys/intr.h>
38 #include <sys/machsystm.h>
39 #include <sys/conf.h>
40 #include <sys/stat.h>
41 #include <sys/kmem.h>
42 #include <sys/async.h>
43 #include <sys/ivintr.h>
44 #include <sys/sunddi.h>
45 #include <sys/sunndi.h>
46 #include <sys/ndifm.h>
47 #include <sys/ontrap.h>
48 #include <sys/ddi_impldefs.h>
49 #include <sys/ddi_subrdefs.h>
50 #include <sys/epm.h>
51 #include <sys/spl.h>
52 #include <sys/fm/util.h>
53 #include <sys/fm/util.h>
54 #include <sys/fm/protocol.h>
55 #include <sys/fm/io/pci.h>
56 #include <sys/fm/io/sun4upci.h>
57 #include <sys/pcicmu/pcicmu.h>
58 
59 #include <sys/cmn_err.h>
60 #include <sys/time.h>
61 #include <sys/pci.h>
62 #include <sys/modctl.h>
63 #include <sys/open.h>
64 #include <sys/errno.h>
65 #include <sys/file.h>
66 
67 
68 uint32_t pcmu_spurintr_duration = 60000000; /* One minute */
69 
70 /*
71  * The variable controls the default setting of the command register
72  * for pci devices.  See pcmu_init_child() for details.
73  *
74  * This flags also controls the setting of bits in the bridge control
75  * register pci to pci bridges.  See pcmu_init_child() for details.
76  */
77 ushort_t pcmu_command_default = PCI_COMM_SERR_ENABLE |
78 				PCI_COMM_WAIT_CYC_ENAB |
79 				PCI_COMM_PARITY_DETECT |
80 				PCI_COMM_ME |
81 				PCI_COMM_MAE |
82 				PCI_COMM_IO;
83 /*
84  * The following driver parameters are defined as variables to allow
85  * patching for debugging and tuning.  Flags that can be set on a per
86  * PBM basis are bit fields where the PBM device instance number maps
87  * to the bit position.
88  */
89 #ifdef DEBUG
90 uint64_t pcmu_debug_flags = 0;
91 #endif
92 uint_t ecc_error_intr_enable = 1;
93 
94 uint_t pcmu_ecc_afsr_retries = 100;	/* XXX - what's a good value? */
95 
96 uint_t pcmu_intr_retry_intv = 5;	/* for interrupt retry reg */
97 uint_t pcmu_panic_on_fatal_errors = 1;	/* should be 1 at beta */
98 
99 hrtime_t pcmu_intrpend_timeout = 5ll * NANOSEC;	/* 5 seconds in nanoseconds */
100 
101 uint64_t pcmu_errtrig_pa = 0x0;
102 
103 
104 /*
105  * The following value is the number of consecutive unclaimed interrupts that
106  * will be tolerated for a particular ino_p before the interrupt is deemed to
107  * be jabbering and is blocked.
108  */
109 uint_t pcmu_unclaimed_intr_max = 20;
110 
111 /*
112  * function prototypes for dev ops routines:
113  */
114 static int pcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
115 static int pcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
116 static int pcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
117     void *arg, void **result);
118 static int pcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp);
119 static int pcmu_close(dev_t dev, int flags, int otyp, cred_t *credp);
120 static int pcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
121 						cred_t *credp, int *rvalp);
122 static int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
123     int flags, char *name, caddr_t valuep, int *lengthp);
124 static int pcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args);
125 static int pcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args,
126     void *result);
127 
128 static int map_pcmu_registers(pcmu_t *, dev_info_t *);
129 static void unmap_pcmu_registers(pcmu_t *);
130 static void pcmu_pbm_clear_error(pcmu_pbm_t *);
131 
132 static int pcmu_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
133     void *, void *);
134 static int pcmu_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
135     off_t, off_t, caddr_t *);
136 static int pcmu_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
137     ddi_intr_handle_impl_t *, void *);
138 
139 static uint32_t pcmu_identity_init(pcmu_t *pcmu_p);
140 static int pcmu_intr_setup(pcmu_t *pcmu_p);
141 static void pcmu_pbm_errstate_get(pcmu_t *pcmu_p,
142     pcmu_pbm_errstate_t *pbm_err_p);
143 static int pcmu_obj_setup(pcmu_t *pcmu_p);
144 static void pcmu_obj_destroy(pcmu_t *pcmu_p);
145 static void pcmu_obj_resume(pcmu_t *pcmu_p);
146 static void pcmu_obj_suspend(pcmu_t *pcmu_p);
147 
148 static void u2u_ittrans_init(pcmu_t *, u2u_ittrans_data_t **);
149 static void u2u_ittrans_resume(u2u_ittrans_data_t **);
150 static void u2u_ittrans_uninit(u2u_ittrans_data_t *);
151 
152 static pcmu_ksinfo_t	*pcmu_name_kstat;
153 
154 /*
155  * bus ops and dev ops structures:
156  */
157 static struct bus_ops pcmu_bus_ops = {
158 	BUSO_REV,
159 	pcmu_map,
160 	0,
161 	0,
162 	0,
163 	i_ddi_map_fault,
164 	0,
165 	0,
166 	0,
167 	0,
168 	0,
169 	0,
170 	0,
171 	0,
172 	pcmu_ctlops,
173 	ddi_bus_prop_op,
174 	ndi_busop_get_eventcookie,	/* (*bus_get_eventcookie)(); */
175 	ndi_busop_add_eventcall,	/* (*bus_add_eventcall)(); */
176 	ndi_busop_remove_eventcall,	/* (*bus_remove_eventcall)(); */
177 	ndi_post_event,			/* (*bus_post_event)(); */
178 	NULL,				/* (*bus_intr_ctl)(); */
179 	NULL,				/* (*bus_config)(); */
180 	NULL,				/* (*bus_unconfig)(); */
181 	NULL,				/* (*bus_fm_init)(); */
182 	NULL,				/* (*bus_fm_fini)(); */
183 	NULL,				/* (*bus_fm_access_enter)(); */
184 	NULL,				/* (*bus_fm_access_fini)(); */
185 	NULL,				/* (*bus_power)(); */
186 	pcmu_intr_ops			/* (*bus_intr_op)(); */
187 };
188 
189 struct cb_ops pcmu_cb_ops = {
190 	pcmu_open,			/* open */
191 	pcmu_close,			/* close */
192 	nodev,				/* strategy */
193 	nodev,				/* print */
194 	nodev,				/* dump */
195 	nodev,				/* read */
196 	nodev,				/* write */
197 	pcmu_ioctl,			/* ioctl */
198 	nodev,				/* devmap */
199 	nodev,				/* mmap */
200 	nodev,				/* segmap */
201 	nochpoll,			/* poll */
202 	pcmu_prop_op,			/* cb_prop_op */
203 	NULL,				/* streamtab */
204 	D_NEW | D_MP | D_HOTPLUG,	/* Driver compatibility flag */
205 	CB_REV,				/* rev */
206 	nodev,				/* int (*cb_aread)() */
207 	nodev				/* int (*cb_awrite)() */
208 };
209 
210 static struct dev_ops pcmu_ops = {
211 	DEVO_REV,
212 	0,
213 	pcmu_info,
214 	nulldev,
215 	0,
216 	pcmu_attach,
217 	pcmu_detach,
218 	nodev,
219 	&pcmu_cb_ops,
220 	&pcmu_bus_ops,
221 	0
222 };
223 
224 /*
225  * module definitions:
226  */
227 extern struct mod_ops mod_driverops;
228 
229 static struct modldrv modldrv = {
230 	&mod_driverops,				/* Type of module - driver */
231 	"OPL CMU-CH PCI Nexus driver %I%",	/* Name of module. */
232 	&pcmu_ops,				/* driver ops */
233 };
234 
235 static struct modlinkage modlinkage = {
236 	MODREV_1, (void *)&modldrv, NULL
237 };
238 
239 /*
240  * driver global data:
241  */
242 void *per_pcmu_state;			/* per-pbm soft state pointer */
243 kmutex_t pcmu_global_mutex;		/* attach/detach common struct lock */
244 errorq_t *pcmu_ecc_queue = NULL;	/* per-system ecc handling queue */
245 
246 extern void pcmu_child_cfg_save(dev_info_t *dip);
247 extern void pcmu_child_cfg_restore(dev_info_t *dip);
248 
249 int
250 _init(void)
251 {
252 	int e;
253 
254 	/*
255 	 * Initialize per-pci bus soft state pointer.
256 	 */
257 	e = ddi_soft_state_init(&per_pcmu_state, sizeof (pcmu_t), 1);
258 	if (e != 0)
259 		return (e);
260 
261 	/*
262 	 * Initialize global mutexes.
263 	 */
264 	mutex_init(&pcmu_global_mutex, NULL, MUTEX_DRIVER, NULL);
265 
266 	/*
267 	 * Create the performance kstats.
268 	 */
269 	pcmu_kstat_init();
270 
271 	/*
272 	 * Install the module.
273 	 */
274 	e = mod_install(&modlinkage);
275 	if (e != 0) {
276 		ddi_soft_state_fini(&per_pcmu_state);
277 		mutex_destroy(&pcmu_global_mutex);
278 	}
279 	return (e);
280 }
281 
282 int
283 _fini(void)
284 {
285 	int e;
286 
287 	/*
288 	 * Remove the module.
289 	 */
290 	e = mod_remove(&modlinkage);
291 	if (e != 0) {
292 		return (e);
293 	}
294 
295 	/*
296 	 * Destroy pcmu_ecc_queue, and set it to NULL.
297 	 */
298 	if (pcmu_ecc_queue) {
299 		errorq_destroy(pcmu_ecc_queue);
300 		pcmu_ecc_queue = NULL;
301 	}
302 
303 	/*
304 	 * Destroy the performance kstats.
305 	 */
306 	pcmu_kstat_fini();
307 
308 	/*
309 	 * Free the per-pci and per-CMU-CH soft state info and destroy
310 	 * mutex for per-CMU-CH soft state.
311 	 */
312 	ddi_soft_state_fini(&per_pcmu_state);
313 	mutex_destroy(&pcmu_global_mutex);
314 	return (e);
315 }
316 
317 int
318 _info(struct modinfo *modinfop)
319 {
320 	return (mod_info(&modlinkage, modinfop));
321 }
322 
323 /*ARGSUSED*/
324 static int
325 pcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
326 {
327 	int	instance = getminor((dev_t)arg) >> 8;
328 	pcmu_t	*pcmu_p = get_pcmu_soft_state(instance);
329 
330 	switch (infocmd) {
331 	case DDI_INFO_DEVT2INSTANCE:
332 		*result = (void *)(uintptr_t)instance;
333 		return (DDI_SUCCESS);
334 
335 	case DDI_INFO_DEVT2DEVINFO:
336 		if (pcmu_p == NULL)
337 			return (DDI_FAILURE);
338 		*result = (void *)pcmu_p->pcmu_dip;
339 		return (DDI_SUCCESS);
340 
341 	default:
342 		return (DDI_FAILURE);
343 	}
344 }
345 
346 
347 /* device driver entry points */
348 /*
349  * attach entry point:
350  */
351 static int
352 pcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
353 {
354 	pcmu_t *pcmu_p;
355 	int instance = ddi_get_instance(dip);
356 
357 	switch (cmd) {
358 	case DDI_ATTACH:
359 		PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_ATTACH\n");
360 
361 		/*
362 		 * Allocate and get the per-pci soft state structure.
363 		 */
364 		if (alloc_pcmu_soft_state(instance) != DDI_SUCCESS) {
365 			cmn_err(CE_WARN, "%s%d: can't allocate pci state",
366 			    ddi_driver_name(dip), instance);
367 			goto err_bad_pcmu_softstate;
368 		}
369 		pcmu_p = get_pcmu_soft_state(instance);
370 		pcmu_p->pcmu_dip = dip;
371 		mutex_init(&pcmu_p->pcmu_mutex, NULL, MUTEX_DRIVER, NULL);
372 		pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED;
373 		pcmu_p->pcmu_open_count = 0;
374 
375 		/*
376 		 * Get key properties of the pci bridge node.
377 		 */
378 		if (get_pcmu_properties(pcmu_p, dip) == DDI_FAILURE) {
379 			goto err_bad_pcmu_prop;
380 		}
381 
382 		/*
383 		 * Map in the registers.
384 		 */
385 		if (map_pcmu_registers(pcmu_p, dip) == DDI_FAILURE) {
386 			goto err_bad_reg_prop;
387 		}
388 		if (pcmu_obj_setup(pcmu_p) != DDI_SUCCESS) {
389 			goto err_bad_objs;
390 		}
391 
392 		if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
393 		    (uint_t)instance<<8 | 0xff,
394 		    DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
395 			goto err_bad_devctl_node;
396 		}
397 
398 		/*
399 		 * Due to unresolved hardware issues, disable PCIPM until
400 		 * the problem is fully understood.
401 		 *
402 		 * pcmu_pwr_setup(pcmu_p, dip);
403 		 */
404 
405 		ddi_report_dev(dip);
406 
407 		pcmu_p->pcmu_state = PCMU_ATTACHED;
408 		PCMU_DBG0(PCMU_DBG_ATTACH, dip, "attach success\n");
409 		break;
410 
411 err_bad_objs:
412 		ddi_remove_minor_node(dip, "devctl");
413 err_bad_devctl_node:
414 		unmap_pcmu_registers(pcmu_p);
415 err_bad_reg_prop:
416 		free_pcmu_properties(pcmu_p);
417 err_bad_pcmu_prop:
418 		mutex_destroy(&pcmu_p->pcmu_mutex);
419 		free_pcmu_soft_state(instance);
420 err_bad_pcmu_softstate:
421 		return (DDI_FAILURE);
422 
423 	case DDI_RESUME:
424 		PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_RESUME\n");
425 
426 		/*
427 		 * Make sure the CMU-CH control registers
428 		 * are configured properly.
429 		 */
430 		pcmu_p = get_pcmu_soft_state(instance);
431 		mutex_enter(&pcmu_p->pcmu_mutex);
432 
433 		/*
434 		 * Make sure this instance has been suspended.
435 		 */
436 		if (pcmu_p->pcmu_state != PCMU_SUSPENDED) {
437 			PCMU_DBG0(PCMU_DBG_ATTACH, dip,
438 			    "instance NOT suspended\n");
439 			mutex_exit(&pcmu_p->pcmu_mutex);
440 			return (DDI_FAILURE);
441 		}
442 		pcmu_obj_resume(pcmu_p);
443 		pcmu_p->pcmu_state = PCMU_ATTACHED;
444 
445 		pcmu_child_cfg_restore(dip);
446 
447 		mutex_exit(&pcmu_p->pcmu_mutex);
448 		break;
449 
450 	default:
451 		PCMU_DBG0(PCMU_DBG_ATTACH, dip, "unsupported attach op\n");
452 		return (DDI_FAILURE);
453 	}
454 
455 	return (DDI_SUCCESS);
456 }
457 
458 /*
459  * detach entry point:
460  */
461 static int
462 pcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
463 {
464 	int instance = ddi_get_instance(dip);
465 	pcmu_t *pcmu_p = get_pcmu_soft_state(instance);
466 	int len;
467 
468 	/*
469 	 * Make sure we are currently attached
470 	 */
471 	if (pcmu_p->pcmu_state != PCMU_ATTACHED) {
472 		PCMU_DBG0(PCMU_DBG_ATTACH, dip,
473 		    "failed - instance not attached\n");
474 		return (DDI_FAILURE);
475 	}
476 
477 	mutex_enter(&pcmu_p->pcmu_mutex);
478 
479 	switch (cmd) {
480 	case DDI_DETACH:
481 		PCMU_DBG0(PCMU_DBG_DETACH, dip, "DDI_DETACH\n");
482 		pcmu_obj_destroy(pcmu_p);
483 
484 		/*
485 		 * Free the pci soft state structure and the rest of the
486 		 * resources it's using.
487 		 */
488 		free_pcmu_properties(pcmu_p);
489 		unmap_pcmu_registers(pcmu_p);
490 		mutex_exit(&pcmu_p->pcmu_mutex);
491 		mutex_destroy(&pcmu_p->pcmu_mutex);
492 		free_pcmu_soft_state(instance);
493 
494 		/* Free the interrupt-priorities prop if we created it. */
495 		if (ddi_getproplen(DDI_DEV_T_ANY, dip,
496 		    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
497 		    "interrupt-priorities", &len) == DDI_PROP_SUCCESS) {
498 			(void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
499 			    "interrupt-priorities");
500 		}
501 		return (DDI_SUCCESS);
502 
503 	case DDI_SUSPEND:
504 		pcmu_child_cfg_save(dip);
505 		pcmu_obj_suspend(pcmu_p);
506 		pcmu_p->pcmu_state = PCMU_SUSPENDED;
507 
508 		mutex_exit(&pcmu_p->pcmu_mutex);
509 		return (DDI_SUCCESS);
510 
511 	default:
512 		PCMU_DBG0(PCMU_DBG_DETACH, dip, "unsupported detach op\n");
513 		mutex_exit(&pcmu_p->pcmu_mutex);
514 		return (DDI_FAILURE);
515 	}
516 }
517 
518 /* ARGSUSED3 */
519 static int
520 pcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp)
521 {
522 	pcmu_t *pcmu_p;
523 
524 	if (otyp != OTYP_CHR) {
525 		return (EINVAL);
526 	}
527 
528 	/*
529 	 * Get the soft state structure for the device.
530 	 */
531 	pcmu_p = DEV_TO_SOFTSTATE(*devp);
532 	if (pcmu_p == NULL) {
533 		return (ENXIO);
534 	}
535 
536 	/*
537 	 * Handle the open by tracking the device state.
538 	 */
539 	PCMU_DBG2(PCMU_DBG_OPEN, pcmu_p->pcmu_dip,
540 	    "devp=%x: flags=%x\n", devp, flags);
541 	mutex_enter(&pcmu_p->pcmu_mutex);
542 	if (flags & FEXCL) {
543 		if (pcmu_p->pcmu_soft_state != PCMU_SOFT_STATE_CLOSED) {
544 			mutex_exit(&pcmu_p->pcmu_mutex);
545 			PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n");
546 			return (EBUSY);
547 		}
548 		pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN_EXCL;
549 	} else {
550 		if (pcmu_p->pcmu_soft_state == PCMU_SOFT_STATE_OPEN_EXCL) {
551 			mutex_exit(&pcmu_p->pcmu_mutex);
552 			PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n");
553 			return (EBUSY);
554 		}
555 		pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN;
556 	}
557 	pcmu_p->pcmu_open_count++;
558 	mutex_exit(&pcmu_p->pcmu_mutex);
559 	return (0);
560 }
561 
562 
563 /* ARGSUSED */
564 static int
565 pcmu_close(dev_t dev, int flags, int otyp, cred_t *credp)
566 {
567 	pcmu_t *pcmu_p;
568 
569 	if (otyp != OTYP_CHR) {
570 		return (EINVAL);
571 	}
572 
573 	pcmu_p = DEV_TO_SOFTSTATE(dev);
574 	if (pcmu_p == NULL) {
575 		return (ENXIO);
576 	}
577 
578 	PCMU_DBG2(PCMU_DBG_CLOSE, pcmu_p->pcmu_dip,
579 	    "dev=%x: flags=%x\n", dev, flags);
580 	mutex_enter(&pcmu_p->pcmu_mutex);
581 	pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED;
582 	pcmu_p->pcmu_open_count = 0;
583 	mutex_exit(&pcmu_p->pcmu_mutex);
584 	return (0);
585 }
586 
587 /* ARGSUSED */
588 static int
589 pcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
590     cred_t *credp, int *rvalp)
591 {
592 	pcmu_t *pcmu_p;
593 	dev_info_t *dip;
594 	struct devctl_iocdata *dcp;
595 	uint_t bus_state;
596 	int rv = 0;
597 
598 	pcmu_p = DEV_TO_SOFTSTATE(dev);
599 	if (pcmu_p == NULL) {
600 		return (ENXIO);
601 	}
602 
603 	dip = pcmu_p->pcmu_dip;
604 	PCMU_DBG2(PCMU_DBG_IOCTL, dip, "dev=%x: cmd=%x\n", dev, cmd);
605 
606 	/*
607 	 * We can use the generic implementation for these ioctls
608 	 */
609 	switch (cmd) {
610 	case DEVCTL_DEVICE_GETSTATE:
611 	case DEVCTL_DEVICE_ONLINE:
612 	case DEVCTL_DEVICE_OFFLINE:
613 	case DEVCTL_BUS_GETSTATE:
614 		return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
615 	}
616 
617 	/*
618 	 * read devctl ioctl data
619 	 */
620 	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
621 		return (EFAULT);
622 
623 	switch (cmd) {
624 
625 	case DEVCTL_DEVICE_RESET:
626 		PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_DEVICE_RESET\n");
627 		rv = ENOTSUP;
628 		break;
629 
630 
631 	case DEVCTL_BUS_QUIESCE:
632 		PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_QUIESCE\n");
633 		if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) {
634 			if (bus_state == BUS_QUIESCED) {
635 				break;
636 			}
637 		}
638 		(void) ndi_set_bus_state(dip, BUS_QUIESCED);
639 		break;
640 
641 	case DEVCTL_BUS_UNQUIESCE:
642 		PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_UNQUIESCE\n");
643 		if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) {
644 			if (bus_state == BUS_ACTIVE) {
645 				break;
646 			}
647 		}
648 		(void) ndi_set_bus_state(dip, BUS_ACTIVE);
649 		break;
650 
651 	case DEVCTL_BUS_RESET:
652 		PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESET\n");
653 		rv = ENOTSUP;
654 		break;
655 
656 	case DEVCTL_BUS_RESETALL:
657 		PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESETALL\n");
658 		rv = ENOTSUP;
659 		break;
660 
661 	default:
662 		rv = ENOTTY;
663 	}
664 
665 	ndi_dc_freehdl(dcp);
666 	return (rv);
667 }
668 
669 static int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
670     int flags, char *name, caddr_t valuep, int *lengthp)
671 {
672 	return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
673 }
674 /* bus driver entry points */
675 
676 /*
677  * bus map entry point:
678  *
679  *	if map request is for an rnumber
680  *		get the corresponding regspec from device node
681  *	build a new regspec in our parent's format
682  *	build a new map_req with the new regspec
683  *	call up the tree to complete the mapping
684  */
685 static int
686 pcmu_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
687 	off_t off, off_t len, caddr_t *addrp)
688 {
689 	pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
690 	struct regspec p_regspec;
691 	ddi_map_req_t p_mapreq;
692 	int reglen, rval, r_no;
693 	pci_regspec_t reloc_reg, *rp = &reloc_reg;
694 
695 	PCMU_DBG2(PCMU_DBG_MAP, dip, "rdip=%s%d:",
696 	    ddi_driver_name(rdip), ddi_get_instance(rdip));
697 
698 	if (mp->map_flags & DDI_MF_USER_MAPPING) {
699 		return (DDI_ME_UNIMPLEMENTED);
700 	}
701 
702 	switch (mp->map_type) {
703 	case DDI_MT_REGSPEC:
704 		reloc_reg = *(pci_regspec_t *)mp->map_obj.rp;	/* dup whole */
705 		break;
706 
707 	case DDI_MT_RNUMBER:
708 		r_no = mp->map_obj.rnumber;
709 		PCMU_DBG1(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, " r#=%x", r_no);
710 
711 		if (ddi_getlongprop(DDI_DEV_T_NONE, rdip, DDI_PROP_DONTPASS,
712 		    "reg", (caddr_t)&rp, &reglen) != DDI_SUCCESS) {
713 			return (DDI_ME_RNUMBER_RANGE);
714 		}
715 
716 		if (r_no < 0 || r_no >= reglen / sizeof (pci_regspec_t)) {
717 			kmem_free(rp, reglen);
718 			return (DDI_ME_RNUMBER_RANGE);
719 		}
720 		rp += r_no;
721 		break;
722 
723 	default:
724 		return (DDI_ME_INVAL);
725 	}
726 	PCMU_DBG0(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, "\n");
727 
728 	/* use "assigned-addresses" to relocate regspec within pci space */
729 	if (rval = pcmu_reloc_reg(dip, rdip, pcmu_p, rp)) {
730 		goto done;
731 	}
732 
733 	/* adjust regspec according to mapping request */
734 	if (len) {
735 		rp->pci_size_low = (uint_t)len;
736 	}
737 	rp->pci_phys_low += off;
738 
739 	/* use "ranges" to translate relocated pci regspec into parent space */
740 	if (rval = pcmu_xlate_reg(pcmu_p, rp, &p_regspec)) {
741 		goto done;
742 	}
743 
744 	p_mapreq = *mp;		/* dup the whole structure */
745 	p_mapreq.map_type = DDI_MT_REGSPEC;
746 	p_mapreq.map_obj.rp = &p_regspec;
747 	rval = ddi_map(dip, &p_mapreq, 0, 0, addrp);
748 
749 done:
750 	if (mp->map_type == DDI_MT_RNUMBER) {
751 		kmem_free(rp - r_no, reglen);
752 	}
753 	return (rval);
754 }
755 
756 #ifdef  DEBUG
757 int	pcmu_peekfault_cnt = 0;
758 int	pcmu_pokefault_cnt = 0;
759 #endif  /* DEBUG */
760 
761 static int
762 pcmu_do_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
763 {
764 	pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
765 	int err = DDI_SUCCESS;
766 	on_trap_data_t otd;
767 
768 	mutex_enter(&pcbm_p->pcbm_pokeflt_mutex);
769 	pcbm_p->pcbm_ontrap_data = &otd;
770 
771 	/* Set up protected environment. */
772 	if (!on_trap(&otd, OT_DATA_ACCESS)) {
773 		uintptr_t tramp = otd.ot_trampoline;
774 
775 		otd.ot_trampoline = (uintptr_t)&poke_fault;
776 		err = do_poke(in_args->size, (void *)in_args->dev_addr,
777 		    (void *)in_args->host_addr);
778 		otd.ot_trampoline = tramp;
779 	} else {
780 		err = DDI_FAILURE;
781 	}
782 
783 	/*
784 	 * Read the async fault register for the PBM to see it sees
785 	 * a master-abort.
786 	 */
787 	pcmu_pbm_clear_error(pcbm_p);
788 
789 	if (otd.ot_trap & OT_DATA_ACCESS) {
790 		err = DDI_FAILURE;
791 	}
792 
793 	/* Take down protected environment. */
794 	no_trap();
795 
796 	pcbm_p->pcbm_ontrap_data = NULL;
797 	mutex_exit(&pcbm_p->pcbm_pokeflt_mutex);
798 
799 #ifdef  DEBUG
800 	if (err == DDI_FAILURE)
801 		pcmu_pokefault_cnt++;
802 #endif
803 	return (err);
804 }
805 
806 
807 static int
808 pcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
809 {
810 	return (pcmu_do_poke(pcmu_p, in_args));
811 }
812 
813 /* ARGSUSED */
814 static int
815 pcmu_do_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args)
816 {
817 	int err = DDI_SUCCESS;
818 	on_trap_data_t otd;
819 
820 	if (!on_trap(&otd, OT_DATA_ACCESS)) {
821 		uintptr_t tramp = otd.ot_trampoline;
822 
823 		otd.ot_trampoline = (uintptr_t)&peek_fault;
824 		err = do_peek(in_args->size, (void *)in_args->dev_addr,
825 		    (void *)in_args->host_addr);
826 		otd.ot_trampoline = tramp;
827 	} else
828 		err = DDI_FAILURE;
829 
830 	no_trap();
831 
832 #ifdef  DEBUG
833 	if (err == DDI_FAILURE)
834 		pcmu_peekfault_cnt++;
835 #endif
836 	return (err);
837 }
838 
839 
840 static int
841 pcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args, void *result)
842 {
843 	result = (void *)in_args->host_addr;
844 	return (pcmu_do_peek(pcmu_p, in_args));
845 }
846 
847 /*
848  * control ops entry point:
849  *
850  * Requests handled completely:
851  *	DDI_CTLOPS_INITCHILD	see pcmu_init_child() for details
852  *	DDI_CTLOPS_UNINITCHILD
853  *	DDI_CTLOPS_REPORTDEV	see report_dev() for details
854  *	DDI_CTLOPS_XLATE_INTRS	nothing to do
855  *	DDI_CTLOPS_IOMIN	cache line size if streaming otherwise 1
856  *	DDI_CTLOPS_REGSIZE
857  *	DDI_CTLOPS_NREGS
858  *	DDI_CTLOPS_NINTRS
859  *	DDI_CTLOPS_DVMAPAGESIZE
860  *	DDI_CTLOPS_POKE
861  *	DDI_CTLOPS_PEEK
862  *	DDI_CTLOPS_QUIESCE
863  *	DDI_CTLOPS_UNQUIESCE
864  *
865  * All others passed to parent.
866  */
867 static int
868 pcmu_ctlops(dev_info_t *dip, dev_info_t *rdip,
869 	ddi_ctl_enum_t op, void *arg, void *result)
870 {
871 	pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
872 
873 	switch (op) {
874 	case DDI_CTLOPS_INITCHILD:
875 		return (pcmu_init_child(pcmu_p, (dev_info_t *)arg));
876 
877 	case DDI_CTLOPS_UNINITCHILD:
878 		return (pcmu_uninit_child(pcmu_p, (dev_info_t *)arg));
879 
880 	case DDI_CTLOPS_REPORTDEV:
881 		return (pcmu_report_dev(rdip));
882 
883 	case DDI_CTLOPS_IOMIN:
884 		/*
885 		 * If we are using the streaming cache, align at
886 		 * least on a cache line boundary. Otherwise use
887 		 * whatever alignment is passed in.
888 		 */
889 		return (DDI_SUCCESS);
890 
891 	case DDI_CTLOPS_REGSIZE:
892 		*((off_t *)result) = pcmu_get_reg_set_size(rdip, *((int *)arg));
893 		return (DDI_SUCCESS);
894 
895 	case DDI_CTLOPS_NREGS:
896 		*((uint_t *)result) = pcmu_get_nreg_set(rdip);
897 		return (DDI_SUCCESS);
898 
899 	case DDI_CTLOPS_DVMAPAGESIZE:
900 		*((ulong_t *)result) = 0;
901 		return (DDI_SUCCESS);
902 
903 	case DDI_CTLOPS_POKE:
904 		return (pcmu_ctlops_poke(pcmu_p, (peekpoke_ctlops_t *)arg));
905 
906 	case DDI_CTLOPS_PEEK:
907 		return (pcmu_ctlops_peek(pcmu_p, (peekpoke_ctlops_t *)arg,
908 		    result));
909 
910 	case DDI_CTLOPS_AFFINITY:
911 		break;
912 
913 	case DDI_CTLOPS_QUIESCE:
914 		return (DDI_FAILURE);
915 
916 	case DDI_CTLOPS_UNQUIESCE:
917 		return (DDI_FAILURE);
918 
919 	default:
920 		break;
921 	}
922 
923 	/*
924 	 * Now pass the request up to our parent.
925 	 */
926 	PCMU_DBG2(PCMU_DBG_CTLOPS, dip,
927 	    "passing request to parent: rdip=%s%d\n",
928 	    ddi_driver_name(rdip), ddi_get_instance(rdip));
929 	return (ddi_ctlops(dip, rdip, op, arg, result));
930 }
931 
932 
933 /* ARGSUSED */
934 static int
935 pcmu_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
936     ddi_intr_handle_impl_t *hdlp, void *result)
937 {
938 	pcmu_t		*pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip));
939 	int		ret = DDI_SUCCESS;
940 
941 	switch (intr_op) {
942 	case DDI_INTROP_GETCAP:
943 		/* GetCap will always fail for all non PCI devices */
944 		(void) pci_intx_get_cap(rdip, (int *)result);
945 		break;
946 	case DDI_INTROP_SETCAP:
947 		ret = DDI_ENOTSUP;
948 		break;
949 	case DDI_INTROP_ALLOC:
950 		*(int *)result = hdlp->ih_scratch1;
951 		break;
952 	case DDI_INTROP_FREE:
953 		break;
954 	case DDI_INTROP_GETPRI:
955 		*(int *)result = hdlp->ih_pri ? hdlp->ih_pri : 0;
956 		break;
957 	case DDI_INTROP_SETPRI:
958 		break;
959 	case DDI_INTROP_ADDISR:
960 		ret = pcmu_add_intr(dip, rdip, hdlp);
961 		break;
962 	case DDI_INTROP_REMISR:
963 		ret = pcmu_remove_intr(dip, rdip, hdlp);
964 		break;
965 	case DDI_INTROP_ENABLE:
966 		ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp,
967 		    PCMU_INTR_STATE_ENABLE);
968 		break;
969 	case DDI_INTROP_DISABLE:
970 		ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp,
971 		    PCMU_INTR_STATE_DISABLE);
972 		break;
973 	case DDI_INTROP_SETMASK:
974 		ret = pci_intx_set_mask(rdip);
975 		break;
976 	case DDI_INTROP_CLRMASK:
977 		ret = pci_intx_clr_mask(rdip);
978 		break;
979 	case DDI_INTROP_GETPENDING:
980 		ret = pci_intx_get_pending(rdip, (int *)result);
981 		break;
982 	case DDI_INTROP_NINTRS:
983 	case DDI_INTROP_NAVAIL:
984 		*(int *)result = i_ddi_get_intx_nintrs(rdip);
985 		break;
986 	case DDI_INTROP_SUPPORTED_TYPES:
987 		/* PCI nexus driver supports only fixed interrupts */
988 		*(int *)result = i_ddi_get_intx_nintrs(rdip) ?
989 		    DDI_INTR_TYPE_FIXED : 0;
990 		break;
991 	default:
992 		ret = DDI_ENOTSUP;
993 		break;
994 	}
995 
996 	return (ret);
997 }
998 
999 /*
1000  * CMU-CH specifics implementation:
1001  *	interrupt mapping register
1002  *	PBM configuration
1003  *	ECC and PBM error handling
1004  */
1005 
1006 /* called by pcmu_attach() DDI_ATTACH to initialize pci objects */
1007 static int
1008 pcmu_obj_setup(pcmu_t *pcmu_p)
1009 {
1010 	int ret;
1011 
1012 	mutex_enter(&pcmu_global_mutex);
1013 	pcmu_p->pcmu_rev = ddi_prop_get_int(DDI_DEV_T_ANY, pcmu_p->pcmu_dip,
1014 	    DDI_PROP_DONTPASS, "module-revision#", 0);
1015 
1016 	pcmu_ib_create(pcmu_p);
1017 	pcmu_cb_create(pcmu_p);
1018 	pcmu_ecc_create(pcmu_p);
1019 	pcmu_pbm_create(pcmu_p);
1020 	pcmu_err_create(pcmu_p);
1021 	if ((ret = pcmu_intr_setup(pcmu_p)) != DDI_SUCCESS)
1022 		goto done;
1023 
1024 	/*
1025 	 * Due to a hardware bug, do not create kstat for DC systems
1026 	 * with PCI hw revision less than 5.
1027 	 */
1028 	if ((strncmp(ddi_binding_name(pcmu_p->pcmu_dip),
1029 	    PCICMU_OPL_DC_BINDING_NAME, strlen(PCICMU_OPL_DC_BINDING_NAME))
1030 	    != 0) || (pcmu_p->pcmu_rev > 4)) {
1031 		pcmu_kstat_create(pcmu_p);
1032 	}
1033 done:
1034 	mutex_exit(&pcmu_global_mutex);
1035 	if (ret != DDI_SUCCESS) {
1036 		cmn_err(CE_NOTE, "Interrupt register failure, returning 0x%x\n",
1037 		    ret);
1038 	}
1039 	return (ret);
1040 }
1041 
1042 /* called by pcmu_detach() DDI_DETACH to destroy pci objects */
1043 static void
1044 pcmu_obj_destroy(pcmu_t *pcmu_p)
1045 {
1046 	mutex_enter(&pcmu_global_mutex);
1047 
1048 	pcmu_kstat_destroy(pcmu_p);
1049 	pcmu_pbm_destroy(pcmu_p);
1050 	pcmu_err_destroy(pcmu_p);
1051 	pcmu_ecc_destroy(pcmu_p);
1052 	pcmu_cb_destroy(pcmu_p);
1053 	pcmu_ib_destroy(pcmu_p);
1054 	pcmu_intr_teardown(pcmu_p);
1055 
1056 	mutex_exit(&pcmu_global_mutex);
1057 }
1058 
1059 /* called by pcmu_attach() DDI_RESUME to (re)initialize pci objects */
1060 static void
1061 pcmu_obj_resume(pcmu_t *pcmu_p)
1062 {
1063 	mutex_enter(&pcmu_global_mutex);
1064 
1065 	pcmu_ib_configure(pcmu_p->pcmu_ib_p);
1066 	pcmu_ecc_configure(pcmu_p);
1067 	pcmu_ib_resume(pcmu_p->pcmu_ib_p);
1068 	u2u_ittrans_resume((u2u_ittrans_data_t **)
1069 	    &(pcmu_p->pcmu_cb_p->pcb_ittrans_cookie));
1070 
1071 	pcmu_pbm_configure(pcmu_p->pcmu_pcbm_p);
1072 
1073 	pcmu_cb_resume(pcmu_p->pcmu_cb_p);
1074 
1075 	pcmu_pbm_resume(pcmu_p->pcmu_pcbm_p);
1076 
1077 	mutex_exit(&pcmu_global_mutex);
1078 }
1079 
1080 /* called by pcmu_detach() DDI_SUSPEND to suspend pci objects */
1081 static void
1082 pcmu_obj_suspend(pcmu_t *pcmu_p)
1083 {
1084 	mutex_enter(&pcmu_global_mutex);
1085 
1086 	pcmu_pbm_suspend(pcmu_p->pcmu_pcbm_p);
1087 	pcmu_ib_suspend(pcmu_p->pcmu_ib_p);
1088 	pcmu_cb_suspend(pcmu_p->pcmu_cb_p);
1089 
1090 	mutex_exit(&pcmu_global_mutex);
1091 }
1092 
1093 static int
1094 pcmu_intr_setup(pcmu_t *pcmu_p)
1095 {
1096 	dev_info_t *dip = pcmu_p->pcmu_dip;
1097 	pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
1098 	pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p;
1099 	int i, no_of_intrs;
1100 
1101 	/*
1102 	 * Get the interrupts property.
1103 	 */
1104 	if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
1105 	    "interrupts", (caddr_t)&pcmu_p->pcmu_inos,
1106 	    &pcmu_p->pcmu_inos_len) != DDI_SUCCESS) {
1107 		cmn_err(CE_PANIC, "%s%d: no interrupts property\n",
1108 		    ddi_driver_name(dip), ddi_get_instance(dip));
1109 	}
1110 
1111 	/*
1112 	 * figure out number of interrupts in the "interrupts" property
1113 	 * and convert them all into ino.
1114 	 */
1115 	i = ddi_getprop(DDI_DEV_T_ANY, dip, 0, "#interrupt-cells", 1);
1116 	i = CELLS_1275_TO_BYTES(i);
1117 	no_of_intrs = pcmu_p->pcmu_inos_len / i;
1118 	for (i = 0; i < no_of_intrs; i++) {
1119 		pcmu_p->pcmu_inos[i] =
1120 		    PCMU_IB_MONDO_TO_INO(pcmu_p->pcmu_inos[i]);
1121 	}
1122 
1123 	pcb_p->pcb_no_of_inos = no_of_intrs;
1124 	if (i = pcmu_ecc_register_intr(pcmu_p)) {
1125 		goto teardown;
1126 	}
1127 
1128 	intr_dist_add(pcmu_cb_intr_dist, pcb_p);
1129 	pcmu_ecc_enable_intr(pcmu_p);
1130 
1131 	if (i = pcmu_pbm_register_intr(pcbm_p)) {
1132 		intr_dist_rem(pcmu_cb_intr_dist, pcb_p);
1133 		goto teardown;
1134 	}
1135 	intr_dist_add(pcmu_pbm_intr_dist, pcbm_p);
1136 	pcmu_ib_intr_enable(pcmu_p, pcmu_p->pcmu_inos[CBNINTR_PBM]);
1137 
1138 	intr_dist_add_weighted(pcmu_ib_intr_dist_all, pcmu_p->pcmu_ib_p);
1139 	return (DDI_SUCCESS);
1140 teardown:
1141 	pcmu_intr_teardown(pcmu_p);
1142 	return (i);
1143 }
1144 
1145 /*
1146  * pcmu_fix_ranges - fixes the config space entry of the "ranges"
1147  *	property on CMU-CH platforms
1148  */
1149 void
1150 pcmu_fix_ranges(pcmu_ranges_t *rng_p, int rng_entries)
1151 {
1152 	int i;
1153 	for (i = 0; i < rng_entries; i++, rng_p++) {
1154 		if ((rng_p->child_high & PCI_REG_ADDR_M) == PCI_ADDR_CONFIG)
1155 			rng_p->parent_low |= rng_p->child_high;
1156 	}
1157 }
1158 
1159 /*
1160  * map_pcmu_registers
1161  *
1162  * This function is called from the attach routine to map the registers
1163  * accessed by this driver.
1164  *
1165  * used by: pcmu_attach()
1166  *
1167  * return value: DDI_FAILURE on failure
1168  */
1169 static int
1170 map_pcmu_registers(pcmu_t *pcmu_p, dev_info_t *dip)
1171 {
1172 	ddi_device_acc_attr_t attr;
1173 
1174 	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1175 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1176 
1177 	attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
1178 	if (ddi_regs_map_setup(dip, 0, &pcmu_p->pcmu_address[0], 0, 0,
1179 	    &attr, &pcmu_p->pcmu_ac[0]) != DDI_SUCCESS) {
1180 		cmn_err(CE_WARN, "%s%d: unable to map reg entry 0\n",
1181 		    ddi_driver_name(dip), ddi_get_instance(dip));
1182 		return (DDI_FAILURE);
1183 	}
1184 
1185 	/*
1186 	 * We still use pcmu_address[2]
1187 	 */
1188 	if (ddi_regs_map_setup(dip, 2, &pcmu_p->pcmu_address[2], 0, 0,
1189 	    &attr, &pcmu_p->pcmu_ac[2]) != DDI_SUCCESS) {
1190 		cmn_err(CE_WARN, "%s%d: unable to map reg entry 2\n",
1191 		    ddi_driver_name(dip), ddi_get_instance(dip));
1192 		ddi_regs_map_free(&pcmu_p->pcmu_ac[0]);
1193 		return (DDI_FAILURE);
1194 	}
1195 
1196 	/*
1197 	 * The second register set contains the bridge's configuration
1198 	 * header.  This header is at the very beginning of the bridge's
1199 	 * configuration space.  This space has litte-endian byte order.
1200 	 */
1201 	attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
1202 	if (ddi_regs_map_setup(dip, 1, &pcmu_p->pcmu_address[1], 0,
1203 	    PCI_CONF_HDR_SIZE, &attr, &pcmu_p->pcmu_ac[1]) != DDI_SUCCESS) {
1204 
1205 		cmn_err(CE_WARN, "%s%d: unable to map reg entry 1\n",
1206 		    ddi_driver_name(dip), ddi_get_instance(dip));
1207 		ddi_regs_map_free(&pcmu_p->pcmu_ac[0]);
1208 		return (DDI_FAILURE);
1209 	}
1210 	PCMU_DBG2(PCMU_DBG_ATTACH, dip, "address (%p,%p)\n",
1211 	    pcmu_p->pcmu_address[0], pcmu_p->pcmu_address[1]);
1212 	return (DDI_SUCCESS);
1213 }
1214 
1215 /*
1216  * unmap_pcmu_registers:
1217  *
1218  * This routine unmap the registers mapped by map_pcmu_registers.
1219  *
1220  * used by: pcmu_detach()
1221  *
1222  * return value: none
1223  */
1224 static void
1225 unmap_pcmu_registers(pcmu_t *pcmu_p)
1226 {
1227 	ddi_regs_map_free(&pcmu_p->pcmu_ac[0]);
1228 	ddi_regs_map_free(&pcmu_p->pcmu_ac[1]);
1229 	ddi_regs_map_free(&pcmu_p->pcmu_ac[2]);
1230 }
1231 
1232 /*
1233  * These convenience wrappers relies on map_pcmu_registers() to setup
1234  * pcmu_address[0-2] correctly at first.
1235  */
1236 static uintptr_t
1237 get_reg_base(pcmu_t *pcmu_p)
1238 {
1239 	return ((uintptr_t)pcmu_p->pcmu_address[2]);
1240 }
1241 
1242 /* The CMU-CH config reg base is always the 2nd reg entry */
1243 static uintptr_t
1244 get_config_reg_base(pcmu_t *pcmu_p)
1245 {
1246 	return ((uintptr_t)(pcmu_p->pcmu_address[1]));
1247 }
1248 
1249 uint64_t
1250 ib_get_map_reg(pcmu_ib_mondo_t mondo, uint32_t cpu_id)
1251 {
1252 	return ((mondo) | (cpu_id << PCMU_INTR_MAP_REG_TID_SHIFT) |
1253 	    PCMU_INTR_MAP_REG_VALID);
1254 
1255 }
1256 
1257 uint32_t
1258 ib_map_reg_get_cpu(volatile uint64_t reg)
1259 {
1260 	return ((reg & PCMU_INTR_MAP_REG_TID) >>
1261 	    PCMU_INTR_MAP_REG_TID_SHIFT);
1262 }
1263 
1264 uint64_t *
1265 ib_intr_map_reg_addr(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino)
1266 {
1267 	uint64_t *addr;
1268 
1269 	ASSERT(ino & 0x20);
1270 	addr = (uint64_t *)(pib_p->pib_obio_intr_map_regs +
1271 	    (((uint_t)ino & 0x1f) << 3));
1272 	return (addr);
1273 }
1274 
1275 uint64_t *
1276 ib_clear_intr_reg_addr(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino)
1277 {
1278 	uint64_t *addr;
1279 
1280 	ASSERT(ino & 0x20);
1281 	addr = (uint64_t *)(pib_p->pib_obio_clear_intr_regs +
1282 	    (((uint_t)ino & 0x1f) << 3));
1283 	return (addr);
1284 }
1285 
1286 uintptr_t
1287 pcmu_ib_setup(pcmu_ib_t *pib_p)
1288 {
1289 	pcmu_t *pcmu_p = pib_p->pib_pcmu_p;
1290 	uintptr_t a = get_reg_base(pcmu_p);
1291 
1292 	pib_p->pib_ign = PCMU_ID_TO_IGN(pcmu_p->pcmu_id);
1293 	pib_p->pib_max_ino = PCMU_MAX_INO;
1294 	pib_p->pib_obio_intr_map_regs = a + PCMU_IB_OBIO_INTR_MAP_REG_OFFSET;
1295 	pib_p->pib_obio_clear_intr_regs =
1296 	    a + PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET;
1297 	return (a);
1298 }
1299 
1300 /*
1301  * Return the cpuid to to be used for an ino.
1302  *
1303  * On multi-function pci devices, functions have separate devinfo nodes and
1304  * interrupts.
1305  *
1306  * This function determines if there is already an established slot-oriented
1307  * interrupt-to-cpu binding established, if there is then it returns that
1308  * cpu.  Otherwise a new cpu is selected by intr_dist_cpuid().
1309  *
1310  * The devinfo node we are trying to associate a cpu with is
1311  * ino_p->pino_ih_head->ih_dip.
1312  */
1313 uint32_t
1314 pcmu_intr_dist_cpuid(pcmu_ib_t *pib_p, pcmu_ib_ino_info_t *ino_p)
1315 {
1316 	dev_info_t	*rdip = ino_p->pino_ih_head->ih_dip;
1317 	dev_info_t	*prdip = ddi_get_parent(rdip);
1318 	pcmu_ib_ino_info_t	*sino_p;
1319 	dev_info_t	*sdip;
1320 	dev_info_t	*psdip;
1321 	char		*buf1 = NULL, *buf2 = NULL;
1322 	char		*s1, *s2, *s3;
1323 	int		l2;
1324 	int		cpu_id;
1325 
1326 	/* must be CMU-CH driver parent (not ebus) */
1327 	if (strcmp(ddi_driver_name(prdip), "pcicmu") != 0)
1328 		goto newcpu;
1329 
1330 	/*
1331 	 * From PCI 1275 binding: 2.2.1.3 Unit Address representation:
1332 	 *   Since the "unit-number" is the address that appears in on Open
1333 	 *   Firmware 'device path', it follows that only the DD and DD,FF
1334 	 *   forms of the text representation can appear in a 'device path'.
1335 	 *
1336 	 * The rdip unit address is of the form "DD[,FF]".  Define two
1337 	 * unit address strings that represent same-slot use: "DD" and "DD,".
1338 	 * The first compare uses strcmp, the second uses strncmp.
1339 	 */
1340 	s1 = ddi_get_name_addr(rdip);
1341 	if (s1 == NULL) {
1342 		goto newcpu;
1343 	}
1344 
1345 	buf1 = kmem_alloc(MAXNAMELEN, KM_SLEEP);	/* strcmp */
1346 	buf2 = kmem_alloc(MAXNAMELEN, KM_SLEEP);	/* strncmp */
1347 	s1 = strcpy(buf1, s1);
1348 	s2 = strcpy(buf2, s1);
1349 
1350 	s1 = strrchr(s1, ',');
1351 	if (s1) {
1352 		*s1 = '\0';			/* have "DD,FF" */
1353 		s1 = buf1;			/* search via strcmp "DD" */
1354 
1355 		s2 = strrchr(s2, ',');
1356 		*(s2 + 1) = '\0';
1357 		s2 = buf2;
1358 		l2 = strlen(s2);		/* search via strncmp "DD," */
1359 	} else {
1360 		(void) strcat(s2, ",");		/* have "DD" */
1361 		l2 = strlen(s2);		/* search via strncmp "DD," */
1362 	}
1363 
1364 	/*
1365 	 * Search the established ino list for devinfo nodes bound
1366 	 * to an ino that matches one of the slot use strings.
1367 	 */
1368 	ASSERT(MUTEX_HELD(&pib_p->pib_ino_lst_mutex));
1369 	for (sino_p = pib_p->pib_ino_lst; sino_p; sino_p = sino_p->pino_next) {
1370 		/* skip self and non-established */
1371 		if ((sino_p == ino_p) || (sino_p->pino_established == 0))
1372 			continue;
1373 
1374 		/* skip non-siblings */
1375 		sdip = sino_p->pino_ih_head->ih_dip;
1376 		psdip = ddi_get_parent(sdip);
1377 		if (psdip != prdip)
1378 			continue;
1379 
1380 		/* must be CMU-CH driver parent (not ebus) */
1381 		if (strcmp(ddi_driver_name(psdip), "pcicmu") != 0)
1382 			continue;
1383 
1384 		s3 = ddi_get_name_addr(sdip);
1385 		if ((s1 && (strcmp(s1, s3) == 0)) ||
1386 		    (strncmp(s2, s3, l2) == 0)) {
1387 			extern int intr_dist_debug;
1388 
1389 			if (intr_dist_debug) {
1390 				cmn_err(CE_CONT, "intr_dist: "
1391 				    "pcicmu`pcmu_intr_dist_cpuid "
1392 				    "%s#%d %s: cpu %d established "
1393 				    "by %s#%d %s\n", ddi_driver_name(rdip),
1394 				    ddi_get_instance(rdip),
1395 				    ddi_deviname(rdip, buf1),
1396 				    sino_p->pino_cpuid,
1397 				    ddi_driver_name(sdip),
1398 				    ddi_get_instance(sdip),
1399 				    ddi_deviname(sdip, buf2));
1400 			}
1401 			break;
1402 		}
1403 	}
1404 
1405 	/* If a slot use match is found then use established cpu */
1406 	if (sino_p) {
1407 		cpu_id = sino_p->pino_cpuid;	/* target established cpu */
1408 		goto out;
1409 	}
1410 
1411 newcpu:	cpu_id = intr_dist_cpuid();		/* target new cpu */
1412 
1413 out:	if (buf1)
1414 		kmem_free(buf1, MAXNAMELEN);
1415 	if (buf2)
1416 		kmem_free(buf2, MAXNAMELEN);
1417 	return (cpu_id);
1418 }
1419 
1420 void
1421 pcmu_cb_teardown(pcmu_t *pcmu_p)
1422 {
1423 	pcmu_cb_t	*pcb_p = pcmu_p->pcmu_cb_p;
1424 
1425 	u2u_ittrans_uninit((u2u_ittrans_data_t *)pcb_p->pcb_ittrans_cookie);
1426 }
1427 
1428 int
1429 pcmu_ecc_add_intr(pcmu_t *pcmu_p, int inum, pcmu_ecc_intr_info_t *eii_p)
1430 {
1431 	uint32_t mondo;
1432 
1433 	mondo = ((pcmu_p->pcmu_cb_p->pcb_ign << PCMU_INO_BITS) |
1434 	    pcmu_p->pcmu_inos[inum]);
1435 
1436 	VERIFY(add_ivintr(mondo, pcmu_pil[inum], (intrfunc)pcmu_ecc_intr,
1437 	    (caddr_t)eii_p, NULL, NULL) == 0);
1438 
1439 	return (PCMU_ATTACH_RETCODE(PCMU_ECC_OBJ,
1440 	    PCMU_OBJ_INTR_ADD, DDI_SUCCESS));
1441 }
1442 
1443 /* ARGSUSED */
1444 void
1445 pcmu_ecc_rem_intr(pcmu_t *pcmu_p, int inum, pcmu_ecc_intr_info_t *eii_p)
1446 {
1447 	uint32_t mondo;
1448 
1449 	mondo = ((pcmu_p->pcmu_cb_p->pcb_ign << PCMU_INO_BITS) |
1450 	    pcmu_p->pcmu_inos[inum]);
1451 
1452 	VERIFY(rem_ivintr(mondo, pcmu_pil[inum]) == 0);
1453 }
1454 
1455 void
1456 pcmu_pbm_configure(pcmu_pbm_t *pcbm_p)
1457 {
1458 	pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p;
1459 	dev_info_t *dip = pcmu_p->pcmu_dip;
1460 
1461 #define	pbm_err	((PCMU_PCI_AFSR_E_MASK << PCMU_PCI_AFSR_PE_SHIFT) |	\
1462 		(PCMU_PCI_AFSR_E_MASK << PCMU_PCI_AFSR_SE_SHIFT))
1463 #define	csr_err	(PCI_STAT_PERROR | PCI_STAT_S_PERROR |		\
1464 		PCI_STAT_R_MAST_AB | PCI_STAT_R_TARG_AB |	\
1465 		PCI_STAT_S_TARG_AB | PCI_STAT_S_PERROR)
1466 
1467 	/*
1468 	 * Clear any PBM errors.
1469 	 */
1470 	*pcbm_p->pcbm_async_flt_status_reg = pbm_err;
1471 
1472 	/*
1473 	 * Clear error bits in configuration status register.
1474 	 */
1475 	PCMU_DBG1(PCMU_DBG_ATTACH, dip,
1476 	    "pcmu_pbm_configure: conf status reg=%x\n", csr_err);
1477 
1478 	pcbm_p->pcbm_config_header->ch_status_reg = csr_err;
1479 
1480 	PCMU_DBG1(PCMU_DBG_ATTACH, dip,
1481 	    "pcmu_pbm_configure: conf status reg==%x\n",
1482 	    pcbm_p->pcbm_config_header->ch_status_reg);
1483 
1484 	(void) ndi_prop_update_int(DDI_DEV_T_ANY, dip, "latency-timer",
1485 	    (int)pcbm_p->pcbm_config_header->ch_latency_timer_reg);
1486 #undef	pbm_err
1487 #undef	csr_err
1488 }
1489 
1490 uint_t
1491 pcmu_pbm_disable_errors(pcmu_pbm_t *pcbm_p)
1492 {
1493 	pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p;
1494 	pcmu_ib_t *pib_p = pcmu_p->pcmu_ib_p;
1495 
1496 	/*
1497 	 * Disable error and streaming byte hole interrupts via the
1498 	 * PBM control register.
1499 	 */
1500 	*pcbm_p->pcbm_ctrl_reg &= ~PCMU_PCI_CTRL_ERR_INT_EN;
1501 
1502 	/*
1503 	 * Disable error interrupts via the interrupt mapping register.
1504 	 */
1505 	pcmu_ib_intr_disable(pib_p,
1506 	    pcmu_p->pcmu_inos[CBNINTR_PBM], PCMU_IB_INTR_NOWAIT);
1507 	return (BF_NONE);
1508 }
1509 
1510 void
1511 pcmu_cb_setup(pcmu_t *pcmu_p)
1512 {
1513 	uint64_t csr, csr_pa, pa;
1514 	pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p;
1515 
1516 	pcb_p->pcb_ign = PCMU_ID_TO_IGN(pcmu_p->pcmu_id);
1517 	pa = (uint64_t)hat_getpfnum(kas.a_hat, pcmu_p->pcmu_address[0]);
1518 	pcb_p->pcb_base_pa  = pa = pa >> (32 - MMU_PAGESHIFT) << 32;
1519 	pcb_p->pcb_map_pa = pa + PCMU_IB_OBIO_INTR_MAP_REG_OFFSET;
1520 	pcb_p->pcb_clr_pa = pa + PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET;
1521 	pcb_p->pcb_obsta_pa = pa + PCMU_IB_OBIO_INTR_STATE_DIAG_REG;
1522 
1523 	csr_pa = pa + PCMU_CB_CONTROL_STATUS_REG_OFFSET;
1524 	csr = lddphysio(csr_pa);
1525 
1526 	/*
1527 	 * Clear any pending address parity errors.
1528 	 */
1529 	if (csr & PCMU_CB_CONTROL_STATUS_APERR) {
1530 		csr |= PCMU_CB_CONTROL_STATUS_APERR;
1531 		cmn_err(CE_WARN, "clearing UPA address parity error\n");
1532 	}
1533 	csr |= PCMU_CB_CONTROL_STATUS_APCKEN;
1534 	csr &= ~PCMU_CB_CONTROL_STATUS_IAP;
1535 	stdphysio(csr_pa, csr);
1536 
1537 	u2u_ittrans_init(pcmu_p,
1538 	    (u2u_ittrans_data_t **)&pcb_p->pcb_ittrans_cookie);
1539 }
1540 
1541 void
1542 pcmu_ecc_setup(pcmu_ecc_t *pecc_p)
1543 {
1544 	pecc_p->pecc_ue.pecc_errpndg_mask = 0;
1545 	pecc_p->pecc_ue.pecc_offset_mask = PCMU_ECC_UE_AFSR_DW_OFFSET;
1546 	pecc_p->pecc_ue.pecc_offset_shift = PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT;
1547 	pecc_p->pecc_ue.pecc_size_log2 = 3;
1548 }
1549 
1550 static uintptr_t
1551 get_pbm_reg_base(pcmu_t *pcmu_p)
1552 {
1553 	return ((uintptr_t)(pcmu_p->pcmu_address[0]));
1554 }
1555 
1556 void
1557 pcmu_pbm_setup(pcmu_pbm_t *pcbm_p)
1558 {
1559 	pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p;
1560 
1561 	/*
1562 	 * Get the base virtual address for the PBM control block.
1563 	 */
1564 	uintptr_t a = get_pbm_reg_base(pcmu_p);
1565 
1566 	/*
1567 	 * Get the virtual address of the PCI configuration header.
1568 	 * This should be mapped little-endian.
1569 	 */
1570 	pcbm_p->pcbm_config_header =
1571 	    (config_header_t *)get_config_reg_base(pcmu_p);
1572 
1573 	/*
1574 	 * Get the virtual addresses for control, error and diag
1575 	 * registers.
1576 	 */
1577 	pcbm_p->pcbm_ctrl_reg = (uint64_t *)(a + PCMU_PCI_CTRL_REG_OFFSET);
1578 	pcbm_p->pcbm_diag_reg = (uint64_t *)(a + PCMU_PCI_DIAG_REG_OFFSET);
1579 	pcbm_p->pcbm_async_flt_status_reg =
1580 	    (uint64_t *)(a + PCMU_PCI_ASYNC_FLT_STATUS_REG_OFFSET);
1581 	pcbm_p->pcbm_async_flt_addr_reg =
1582 	    (uint64_t *)(a + PCMU_PCI_ASYNC_FLT_ADDR_REG_OFFSET);
1583 }
1584 
1585 /*ARGSUSED*/
1586 void
1587 pcmu_pbm_teardown(pcmu_pbm_t *pcbm_p)
1588 {
1589 }
1590 
1591 int
1592 pcmu_get_numproxy(dev_info_t *dip)
1593 {
1594 	return (ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1595 	    "#upa-interrupt-proxies", 1));
1596 }
1597 
1598 int
1599 pcmu_get_portid(dev_info_t *dip)
1600 {
1601 	return (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1602 	    "portid", -1));
1603 }
1604 
1605 /*
1606  * CMU-CH Performance Events.
1607  */
1608 static pcmu_kev_mask_t
1609 pcicmu_pcmu_events[] = {
1610 	{"pio_cycles_b", 0xf},		{"interrupts", 0x11},
1611 	{"upa_inter_nack", 0x12},	{"pio_reads", 0x13},
1612 	{"pio_writes", 0x14},
1613 	{"clear_pic", 0x1f}
1614 };
1615 
1616 /*
1617  * Create the picN kstat's.
1618  */
1619 void
1620 pcmu_kstat_init()
1621 {
1622 	pcmu_name_kstat = (pcmu_ksinfo_t *)kmem_alloc(sizeof (pcmu_ksinfo_t),
1623 	    KM_NOSLEEP);
1624 
1625 	if (pcmu_name_kstat == NULL) {
1626 		cmn_err(CE_WARN, "pcicmu : no space for kstat\n");
1627 	} else {
1628 		pcmu_name_kstat->pic_no_evs =
1629 		    sizeof (pcicmu_pcmu_events) / sizeof (pcmu_kev_mask_t);
1630 		pcmu_name_kstat->pic_shift[0] = PCMU_SHIFT_PIC0;
1631 		pcmu_name_kstat->pic_shift[1] = PCMU_SHIFT_PIC1;
1632 		pcmu_create_name_kstat("pcmup",
1633 		    pcmu_name_kstat, pcicmu_pcmu_events);
1634 	}
1635 }
1636 
1637 /*
1638  * Called from _fini()
1639  */
1640 void
1641 pcmu_kstat_fini()
1642 {
1643 	if (pcmu_name_kstat != NULL) {
1644 		pcmu_delete_name_kstat(pcmu_name_kstat);
1645 		kmem_free(pcmu_name_kstat, sizeof (pcmu_ksinfo_t));
1646 		pcmu_name_kstat = NULL;
1647 	}
1648 }
1649 
1650 /*
1651  * Create the performance 'counters' kstat.
1652  */
1653 void
1654 pcmu_add_upstream_kstat(pcmu_t *pcmu_p)
1655 {
1656 	pcmu_cntr_pa_t	*cntr_pa_p = &pcmu_p->pcmu_uks_pa;
1657 	uint64_t regbase = va_to_pa((void *)get_reg_base(pcmu_p));
1658 
1659 	cntr_pa_p->pcr_pa = regbase + PCMU_PERF_PCR_OFFSET;
1660 	cntr_pa_p->pic_pa = regbase + PCMU_PERF_PIC_OFFSET;
1661 	pcmu_p->pcmu_uksp = pcmu_create_cntr_kstat(pcmu_p, "pcmup",
1662 	    NUM_OF_PICS, pcmu_cntr_kstat_pa_update, cntr_pa_p);
1663 }
1664 
1665 /*
1666  * u2u_ittrans_init() is caled from in pci.c's pcmu_cb_setup() per CMU.
1667  * Second argument "ittrans_cookie" is address of pcb_ittrans_cookie in
1668  * pcb_p member. allocated interrupt block is returned in it.
1669  */
1670 static void
1671 u2u_ittrans_init(pcmu_t *pcmu_p, u2u_ittrans_data_t **ittrans_cookie)
1672 {
1673 
1674 	u2u_ittrans_data_t *u2u_trans_p;
1675 	ddi_device_acc_attr_t attr;
1676 	int ret;
1677 	int board;
1678 
1679 	/*
1680 	 * Allocate the data structure to support U2U's
1681 	 * interrupt target translations.
1682 	 */
1683 	u2u_trans_p = (u2u_ittrans_data_t *)
1684 	    kmem_zalloc(sizeof (u2u_ittrans_data_t), KM_SLEEP);
1685 
1686 	/*
1687 	 * Get other properties, "board#"
1688 	 */
1689 	board = ddi_getprop(DDI_DEV_T_ANY, pcmu_p->pcmu_dip,
1690 	    DDI_PROP_DONTPASS, "board#", -1);
1691 
1692 	u2u_trans_p->u2u_board = board;
1693 
1694 	if (board == -1) {
1695 		/* this cannot happen on production systems */
1696 		cmn_err(CE_PANIC, "u2u:Invalid property;board = %d", board);
1697 	}
1698 
1699 	/*
1700 	 * Initialize interrupt target translations mutex.
1701 	 */
1702 	mutex_init(&(u2u_trans_p->u2u_ittrans_lock), "u2u_ittrans_lock",
1703 	    MUTEX_DEFAULT, NULL);
1704 
1705 	/*
1706 	 * Get U2U's registers space by ddi_regs_map_setup(9F)
1707 	 */
1708 	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1709 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1710 	attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
1711 
1712 	ret = ddi_regs_map_setup(pcmu_p->pcmu_dip,
1713 	    REGS_INDEX_OF_U2U, (caddr_t *)(&(u2u_trans_p->u2u_regs_base)),
1714 	    0, 0, &attr, &(u2u_trans_p->u2u_acc));
1715 
1716 	/*
1717 	 * check result of ddi_regs_map_setup().
1718 	 */
1719 	if (ret != DDI_SUCCESS) {
1720 		cmn_err(CE_PANIC, "u2u%d: registers map setup failed", board);
1721 	}
1722 
1723 	/*
1724 	 * Read Port-id(1 byte) in u2u
1725 	 */
1726 	u2u_trans_p->u2u_port_id = *(volatile int32_t *)
1727 	    (u2u_trans_p->u2u_regs_base + U2U_PID_REGISTER_OFFSET);
1728 
1729 	if (pcmu_p->pcmu_id != u2u_trans_p->u2u_port_id) {
1730 		cmn_err(CE_PANIC, "u2u%d: Invalid Port-ID", board);
1731 	}
1732 
1733 	*ittrans_cookie = u2u_trans_p;
1734 }
1735 
1736 /*
1737  * u2u_ittras_resume() is called from pcmu_obj_resume() at DDI_RESUME entry.
1738  */
1739 static void
1740 u2u_ittrans_resume(u2u_ittrans_data_t **ittrans_cookie)
1741 {
1742 
1743 	u2u_ittrans_data_t *u2u_trans_p;
1744 	u2u_ittrans_id_t *ittrans_id_p;
1745 	uintptr_t  data_reg_addr;
1746 	int ix;
1747 
1748 	u2u_trans_p = *ittrans_cookie;
1749 
1750 	/*
1751 	 * Set U2U Data Register
1752 	 */
1753 	for (ix = 0; ix < U2U_DATA_NUM; ix++) {
1754 		ittrans_id_p = &(u2u_trans_p->u2u_ittrans_id[ix]);
1755 		data_reg_addr = u2u_trans_p->u2u_regs_base +
1756 		    U2U_DATA_REGISTER_OFFSET + (ix * sizeof (uint64_t));
1757 		if (ittrans_id_p->u2u_ino_map_reg == NULL) {
1758 			/* This index was not set */
1759 			continue;
1760 		}
1761 		*(volatile uint32_t *) (data_reg_addr) =
1762 		    (uint32_t)ittrans_id_p->u2u_tgt_cpu_id;
1763 
1764 	}
1765 }
1766 
1767 /*
1768  * u2u_ittras_uninit() is called from ib_destroy() at detach,
1769  * or occuring error in attach.
1770  */
1771 static void
1772 u2u_ittrans_uninit(u2u_ittrans_data_t *ittrans_cookie)
1773 {
1774 
1775 	if (ittrans_cookie == NULL) {
1776 		return;	/* not support */
1777 	}
1778 
1779 	if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) {
1780 		return;	 /* illeagal case */
1781 	}
1782 
1783 	ddi_regs_map_free(&(ittrans_cookie->u2u_acc));
1784 	mutex_destroy(&(ittrans_cookie->u2u_ittrans_lock));
1785 	kmem_free((void *)ittrans_cookie, sizeof (u2u_ittrans_data_t));
1786 }
1787 
1788 /*
1789  * This routine,u2u_translate_tgtid(, , cpu_id, pino_map_reg),
1790  * searches index having same value of pino_map_reg, or empty.
1791  * Then, stores cpu_id in a U2U Data Register as this index,
1792  * and return this index.
1793  */
1794 int
1795 u2u_translate_tgtid(pcmu_t *pcmu_p, uint_t cpu_id,
1796     volatile uint64_t *pino_map_reg)
1797 {
1798 
1799 	int index = -1;
1800 	int ix;
1801 	int err_level;	/* severity level for cmn_err */
1802 	u2u_ittrans_id_t *ittrans_id_p;
1803 	uintptr_t  data_reg_addr;
1804 	u2u_ittrans_data_t *ittrans_cookie;
1805 
1806 	ittrans_cookie =
1807 	    (u2u_ittrans_data_t *)(pcmu_p->pcmu_cb_p->pcb_ittrans_cookie);
1808 
1809 	if (ittrans_cookie == NULL) {
1810 		return (cpu_id);
1811 	}
1812 
1813 	if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) {
1814 		return (-1);	 /* illeagal case */
1815 	}
1816 
1817 	mutex_enter(&(ittrans_cookie->u2u_ittrans_lock));
1818 
1819 	/*
1820 	 * Decide index No. of U2U Data registers in either
1821 	 * already used by same pino_map_reg, or empty.
1822 	 */
1823 	for (ix = 0; ix < U2U_DATA_NUM; ix++) {
1824 		ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[ix]);
1825 		if (ittrans_id_p->u2u_ino_map_reg == pino_map_reg) {
1826 			/* already used this pino_map_reg */
1827 			index = ix;
1828 			break;
1829 		}
1830 		if (index == -1 &&
1831 		    ittrans_id_p->u2u_ino_map_reg == NULL) {
1832 			index = ix;
1833 		}
1834 	}
1835 
1836 	if (index == -1) {
1837 		if (panicstr) {
1838 			err_level = CE_WARN;
1839 		} else {
1840 			err_level = CE_PANIC;
1841 		}
1842 		cmn_err(err_level, "u2u%d:No more U2U-Data regs!!",
1843 		    ittrans_cookie->u2u_board);
1844 		return (cpu_id);
1845 	}
1846 
1847 	/*
1848 	 * For U2U
1849 	 * set cpu_id into u2u_data_reg by index.
1850 	 * ((uint64_t)(u2u_regs_base
1851 	 *	+ U2U_DATA_REGISTER_OFFSET))[index] = cpu_id;
1852 	 */
1853 
1854 	data_reg_addr = ittrans_cookie->u2u_regs_base
1855 	    + U2U_DATA_REGISTER_OFFSET
1856 	    + (index * sizeof (uint64_t));
1857 
1858 	/*
1859 	 * Set cpu_id into U2U Data register[index]
1860 	 */
1861 	*(volatile uint32_t *) (data_reg_addr) = (uint32_t)cpu_id;
1862 
1863 	/*
1864 	 * Setup for software, excepting at panicing.
1865 	 * and rebooting, etc...?
1866 	 */
1867 	if (!panicstr) {
1868 		ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[index]);
1869 		ittrans_id_p->u2u_tgt_cpu_id = cpu_id;
1870 		ittrans_id_p->u2u_ino_map_reg = pino_map_reg;
1871 	}
1872 
1873 	mutex_exit(&(ittrans_cookie->u2u_ittrans_lock));
1874 
1875 	return (index);
1876 }
1877 
1878 /*
1879  * u2u_ittrans_cleanup() is called from common_pcmu_ib_intr_disable()
1880  * after called intr_rem_cpu(mondo).
1881  */
1882 void
1883 u2u_ittrans_cleanup(u2u_ittrans_data_t *ittrans_cookie,
1884 			volatile uint64_t *pino_map_reg)
1885 {
1886 
1887 	int ix;
1888 	u2u_ittrans_id_t *ittrans_id_p;
1889 
1890 	if (ittrans_cookie == NULL) {
1891 		return;
1892 	}
1893 
1894 	if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) {
1895 		return;	 /* illeagal case */
1896 	}
1897 
1898 	mutex_enter(&(ittrans_cookie->u2u_ittrans_lock));
1899 
1900 	for (ix = 0; ix < U2U_DATA_NUM; ix++) {
1901 		ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[ix]);
1902 		if (ittrans_id_p->u2u_ino_map_reg == pino_map_reg) {
1903 			ittrans_id_p->u2u_ino_map_reg = NULL;
1904 			break;
1905 		}
1906 	}
1907 
1908 	mutex_exit(&(ittrans_cookie->u2u_ittrans_lock));
1909 }
1910 
1911 /*
1912  * pcmu_ecc_classify, called by ecc_handler to classify ecc errors
1913  * and determine if we should panic or not.
1914  */
1915 void
1916 pcmu_ecc_classify(uint64_t err, pcmu_ecc_errstate_t *ecc_err_p)
1917 {
1918 	struct async_flt *ecc = &ecc_err_p->ecc_aflt;
1919 	/* LINTED */
1920 	pcmu_t *pcmu_p = ecc_err_p->ecc_ii_p.pecc_p->pecc_pcmu_p;
1921 
1922 	ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
1923 
1924 	ecc_err_p->ecc_bridge_type = PCI_OPLCMU;	/* RAGS */
1925 	/*
1926 	 * Get the parent bus id that caused the error.
1927 	 */
1928 	ecc_err_p->ecc_dev_id = (ecc_err_p->ecc_afsr & PCMU_ECC_UE_AFSR_ID)
1929 	    >> PCMU_ECC_UE_AFSR_ID_SHIFT;
1930 	/*
1931 	 * Determine the doubleword offset of the error.
1932 	 */
1933 	ecc_err_p->ecc_dw_offset = (ecc_err_p->ecc_afsr &
1934 	    PCMU_ECC_UE_AFSR_DW_OFFSET) >> PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT;
1935 	/*
1936 	 * Determine the primary error type.
1937 	 */
1938 	switch (err) {
1939 	case PCMU_ECC_UE_AFSR_E_PIO:
1940 		if (ecc_err_p->pecc_pri) {
1941 			ecc->flt_erpt_class = PCI_ECC_PIO_UE;
1942 		} else {
1943 			ecc->flt_erpt_class = PCI_ECC_SEC_PIO_UE;
1944 		}
1945 		/* For CMU-CH, a UE is always fatal. */
1946 		ecc->flt_panic = 1;
1947 		break;
1948 
1949 	default:
1950 		return;
1951 	}
1952 }
1953 
1954 /*
1955  * pcmu_pbm_classify, called by pcmu_pbm_afsr_report to classify piow afsr.
1956  */
1957 int
1958 pcmu_pbm_classify(pcmu_pbm_errstate_t *pbm_err_p)
1959 {
1960 	uint32_t e;
1961 	int nerr = 0;
1962 	char **tmp_class;
1963 
1964 	if (pbm_err_p->pcbm_pri) {
1965 		tmp_class = &pbm_err_p->pcbm_pci.pcmu_err_class;
1966 		e = PBM_AFSR_TO_PRIERR(pbm_err_p->pbm_afsr);
1967 		pbm_err_p->pbm_log = FM_LOG_PCI;
1968 	} else {
1969 		tmp_class = &pbm_err_p->pbm_err_class;
1970 		e = PBM_AFSR_TO_SECERR(pbm_err_p->pbm_afsr);
1971 		pbm_err_p->pbm_log = FM_LOG_PBM;
1972 	}
1973 
1974 	if (e & PCMU_PCI_AFSR_E_MA) {
1975 		*tmp_class = pbm_err_p->pcbm_pri ? PCI_MA : PCI_SEC_MA;
1976 		nerr++;
1977 	}
1978 	return (nerr);
1979 }
1980 
1981 /*
1982  * Function used to clear PBM/PCI/IOMMU error state after error handling
1983  * is complete. Only clearing error bits which have been logged. Called by
1984  * pcmu_pbm_err_handler and pcmu_bus_exit.
1985  */
1986 static void
1987 pcmu_clear_error(pcmu_t *pcmu_p, pcmu_pbm_errstate_t *pbm_err_p)
1988 {
1989 	pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
1990 
1991 	ASSERT(MUTEX_HELD(&pcbm_p->pcbm_pcmu_p->pcmu_err_mutex));
1992 
1993 	*pcbm_p->pcbm_ctrl_reg = pbm_err_p->pbm_ctl_stat;
1994 	*pcbm_p->pcbm_async_flt_status_reg = pbm_err_p->pbm_afsr;
1995 	pcbm_p->pcbm_config_header->ch_status_reg =
1996 	    pbm_err_p->pcbm_pci.pcmu_cfg_stat;
1997 }
1998 
1999 /*ARGSUSED*/
2000 int
2001 pcmu_pbm_err_handler(dev_info_t *dip, ddi_fm_error_t *derr,
2002 		const void *impl_data, int caller)
2003 {
2004 	int fatal = 0;
2005 	int nonfatal = 0;
2006 	int unknown = 0;
2007 	uint32_t prierr, secerr;
2008 	pcmu_pbm_errstate_t pbm_err;
2009 	pcmu_t *pcmu_p = (pcmu_t *)impl_data;
2010 	int ret = 0;
2011 
2012 	ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
2013 	pcmu_pbm_errstate_get(pcmu_p, &pbm_err);
2014 
2015 	derr->fme_ena = derr->fme_ena ? derr->fme_ena :
2016 	    fm_ena_generate(0, FM_ENA_FMT1);
2017 
2018 	prierr = PBM_AFSR_TO_PRIERR(pbm_err.pbm_afsr);
2019 	secerr = PBM_AFSR_TO_SECERR(pbm_err.pbm_afsr);
2020 
2021 	if (derr->fme_flag == DDI_FM_ERR_PEEK) {
2022 		/*
2023 		 * For ddi_peek treat all events as nonfatal. We only
2024 		 * really call this function so that pcmu_clear_error()
2025 		 * and ndi_fm_handler_dispatch() will get called.
2026 		 */
2027 		nonfatal++;
2028 		goto done;
2029 	} else if (derr->fme_flag == DDI_FM_ERR_POKE) {
2030 		/*
2031 		 * For ddi_poke we can treat as nonfatal if the
2032 		 * following conditions are met :
2033 		 * 1. Make sure only primary error is MA/TA
2034 		 * 2. Make sure no secondary error
2035 		 * 3. check pci config header stat reg to see MA/TA is
2036 		 *    logged. We cannot verify only MA/TA is recorded
2037 		 *    since it gets much more complicated when a
2038 		 *    PCI-to-PCI bridge is present.
2039 		 */
2040 		if ((prierr == PCMU_PCI_AFSR_E_MA) && !secerr &&
2041 		    (pbm_err.pcbm_pci.pcmu_cfg_stat & PCI_STAT_R_MAST_AB)) {
2042 			nonfatal++;
2043 			goto done;
2044 		}
2045 	}
2046 
2047 	if (prierr || secerr) {
2048 		ret = pcmu_pbm_afsr_report(dip, derr->fme_ena, &pbm_err);
2049 		if (ret == DDI_FM_FATAL) {
2050 			fatal++;
2051 		} else {
2052 			nonfatal++;
2053 		}
2054 	}
2055 
2056 	ret = pcmu_cfg_report(dip, derr, &pbm_err.pcbm_pci, caller, prierr);
2057 	if (ret == DDI_FM_FATAL) {
2058 		fatal++;
2059 	} else if (ret == DDI_FM_NONFATAL) {
2060 		nonfatal++;
2061 	}
2062 
2063 done:
2064 	if (ret == DDI_FM_FATAL) {
2065 		fatal++;
2066 	} else if (ret == DDI_FM_NONFATAL) {
2067 		nonfatal++;
2068 	} else if (ret == DDI_FM_UNKNOWN) {
2069 		unknown++;
2070 	}
2071 
2072 	/* Cleanup and reset error bits */
2073 	pcmu_clear_error(pcmu_p, &pbm_err);
2074 
2075 	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
2076 	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
2077 }
2078 
2079 int
2080 pcmu_check_error(pcmu_t *pcmu_p)
2081 {
2082 	pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
2083 	uint16_t pcmu_cfg_stat;
2084 	uint64_t pbm_afsr;
2085 
2086 	ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
2087 
2088 	pcmu_cfg_stat = pcbm_p->pcbm_config_header->ch_status_reg;
2089 	pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2090 
2091 	if ((pcmu_cfg_stat & (PCI_STAT_S_PERROR | PCI_STAT_S_TARG_AB |
2092 	    PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB |
2093 	    PCI_STAT_S_SYSERR | PCI_STAT_PERROR)) ||
2094 	    (PBM_AFSR_TO_PRIERR(pbm_afsr))) {
2095 		return (1);
2096 	}
2097 	return (0);
2098 
2099 }
2100 
2101 /*
2102  * Function used to gather PBM/PCI error state for the
2103  * pcmu_pbm_err_handler. This function must be called while pcmu_err_mutex
2104  * is held.
2105  */
2106 static void
2107 pcmu_pbm_errstate_get(pcmu_t *pcmu_p, pcmu_pbm_errstate_t *pbm_err_p)
2108 {
2109 	pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
2110 
2111 	ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex));
2112 	bzero(pbm_err_p, sizeof (pcmu_pbm_errstate_t));
2113 
2114 	/*
2115 	 * Capture all pbm error state for later logging
2116 	 */
2117 	pbm_err_p->pbm_bridge_type = PCI_OPLCMU;	/* RAGS */
2118 	pbm_err_p->pcbm_pci.pcmu_cfg_stat =
2119 	    pcbm_p->pcbm_config_header->ch_status_reg;
2120 	pbm_err_p->pbm_ctl_stat = *pcbm_p->pcbm_ctrl_reg;
2121 	pbm_err_p->pcbm_pci.pcmu_cfg_comm =
2122 	    pcbm_p->pcbm_config_header->ch_command_reg;
2123 	pbm_err_p->pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2124 	pbm_err_p->pbm_afar = *pcbm_p->pcbm_async_flt_addr_reg;
2125 	pbm_err_p->pcbm_pci.pcmu_pa = *pcbm_p->pcbm_async_flt_addr_reg;
2126 }
2127 
2128 static void
2129 pcmu_pbm_clear_error(pcmu_pbm_t *pcbm_p)
2130 {
2131 	uint64_t pbm_afsr;
2132 
2133 	/*
2134 	 * for poke() support - called from POKE_FLUSH. Spin waiting
2135 	 * for MA, TA or SERR to be cleared by a pcmu_pbm_error_intr().
2136 	 * We have to wait for SERR too in case the device is beyond
2137 	 * a pci-pci bridge.
2138 	 */
2139 	pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2140 	while (((pbm_afsr >> PCMU_PCI_AFSR_PE_SHIFT) &
2141 	    (PCMU_PCI_AFSR_E_MA | PCMU_PCI_AFSR_E_TA))) {
2142 		pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg;
2143 	}
2144 }
2145 
2146 void
2147 pcmu_err_create(pcmu_t *pcmu_p)
2148 {
2149 	/*
2150 	 * PCI detected ECC errorq, to schedule async handling
2151 	 * of ECC errors and logging.
2152 	 * The errorq is created here but destroyed when _fini is called
2153 	 * for the pci module.
2154 	 */
2155 	if (pcmu_ecc_queue == NULL) {
2156 		pcmu_ecc_queue = errorq_create("pcmu_ecc_queue",
2157 		    (errorq_func_t)pcmu_ecc_err_drain,
2158 		    (void *)NULL,
2159 		    ECC_MAX_ERRS, sizeof (pcmu_ecc_errstate_t),
2160 		    PIL_2, ERRORQ_VITAL);
2161 		if (pcmu_ecc_queue == NULL)
2162 			panic("failed to create required system error queue");
2163 	}
2164 
2165 	/*
2166 	 * Initialize error handling mutex.
2167 	 */
2168 	mutex_init(&pcmu_p->pcmu_err_mutex, NULL, MUTEX_DRIVER,
2169 	    (void *)pcmu_p->pcmu_fm_ibc);
2170 }
2171 
2172 void
2173 pcmu_err_destroy(pcmu_t *pcmu_p)
2174 {
2175 	mutex_destroy(&pcmu_p->pcmu_err_mutex);
2176 }
2177 
2178 /*
2179  * Function used to post PCI block module specific ereports.
2180  */
2181 void
2182 pcmu_pbm_ereport_post(dev_info_t *dip, uint64_t ena,
2183     pcmu_pbm_errstate_t *pbm_err)
2184 {
2185 	char *aux_msg;
2186 	uint32_t prierr, secerr;
2187 	pcmu_t *pcmu_p;
2188 	int instance = ddi_get_instance(dip);
2189 
2190 	ena = ena ? ena : fm_ena_generate(0, FM_ENA_FMT1);
2191 
2192 	pcmu_p = get_pcmu_soft_state(instance);
2193 	prierr = PBM_AFSR_TO_PRIERR(pbm_err->pbm_afsr);
2194 	secerr = PBM_AFSR_TO_SECERR(pbm_err->pbm_afsr);
2195 	if (prierr)
2196 		aux_msg = "PCI primary error: Master Abort";
2197 	else if (secerr)
2198 		aux_msg = "PCI secondary error: Master Abort";
2199 	else
2200 		aux_msg = "";
2201 	cmn_err(CE_WARN, "%s %s: %s %s=0x%lx, %s=0x%lx, %s=0x%lx %s=0x%x",
2202 	    (pcmu_p->pcmu_pcbm_p)->pcbm_nameinst_str,
2203 	    (pcmu_p->pcmu_pcbm_p)->pcbm_nameaddr_str,
2204 	    aux_msg,
2205 	    PCI_PBM_AFAR, pbm_err->pbm_afar,
2206 	    PCI_PBM_AFSR, pbm_err->pbm_afsr,
2207 	    PCI_PBM_CSR, pbm_err->pbm_ctl_stat,
2208 	    "portid", pcmu_p->pcmu_id);
2209 }
2210