xref: /illumos-gate/usr/src/uts/sun4/io/ebus.c (revision bf56214c0556fa6864189c826d39dbe156bb22a0)
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 #include <sys/types.h>
29 #include <sys/conf.h>
30 #include <sys/ddi.h>
31 #include <sys/sunddi.h>
32 #include <sys/ddi_impldefs.h>
33 #include <sys/ddi_subrdefs.h>
34 #include <sys/pci.h>
35 #include <sys/autoconf.h>
36 #include <sys/cmn_err.h>
37 #include <sys/errno.h>
38 #include <sys/kmem.h>
39 #include <sys/debug.h>
40 #include <sys/sysmacros.h>
41 #include <sys/ebus.h>
42 #include <sys/open.h>
43 #include <sys/stat.h>
44 #include <sys/file.h>
45 #include <sys/sunndi.h>
46 
47 #ifdef DEBUG
48 uint64_t ebus_debug_flags = 0;
49 #endif
50 
51 /*
52  * The values of the following variables are used to initialize
53  * the cache line size and latency timer registers in the ebus
54  * configuration header.  Variables are used instead of constants
55  * to allow tuning from the /etc/system file.
56  */
57 static uint8_t ebus_cache_line_size = 0x10;	/* 64 bytes */
58 static uint8_t ebus_latency_timer = 0x40;	/* 64 PCI cycles */
59 
60 /*
61  * function prototypes for bus ops routines:
62  */
63 static int
64 ebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
65 	off_t offset, off_t len, caddr_t *addrp);
66 static int
67 ebus_ctlops(dev_info_t *dip, dev_info_t *rdip,
68 	ddi_ctl_enum_t op, void *arg, void *result);
69 static int
70 ebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
71     ddi_intr_handle_impl_t *hdlp, void *result);
72 
73 /*
74  * function prototypes for dev ops routines:
75  */
76 static int ebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
77 static int ebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
78 static int ebus_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
79 	void *arg, void **result);
80 
81 /*
82  * general function prototypes:
83  */
84 static int ebus_config(ebus_devstate_t *ebus_p);
85 static int ebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip,
86     ebus_regspec_t *ebus_rp, vregspec_t *rp);
87 int ebus_get_ranges_prop(ebus_devstate_t *ebus_p);
88 static void ebus_get_cells_prop(ebus_devstate_t *ebus_p);
89 static void ebus_vreg_dump(ebus_devstate_t *ebus_p, vregspec_t *rp);
90 
91 #define	getprop(dip, name, addr, intp)		\
92 		ddi_getlongprop(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
93 				(name), (caddr_t)(addr), (intp))
94 
95 static int ebus_open(dev_t *devp, int flags, int otyp, cred_t *credp);
96 static int ebus_close(dev_t dev, int flags, int otyp, cred_t *credp);
97 static int ebus_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
98 						cred_t *credp, int *rvalp);
99 struct cb_ops ebus_cb_ops = {
100 	ebus_open,			/* open */
101 	ebus_close,			/* close */
102 	nodev,				/* strategy */
103 	nodev,				/* print */
104 	nodev,				/* dump */
105 	nodev,				/* read */
106 	nodev,				/* write */
107 	ebus_ioctl,			/* ioctl */
108 	nodev,				/* devmap */
109 	nodev,				/* mmap */
110 	nodev,				/* segmap */
111 	nochpoll,			/* poll */
112 	ddi_prop_op,			/* cb_prop_op */
113 	NULL,				/* streamtab */
114 	D_NEW | D_MP | D_HOTPLUG,	/* Driver compatibility flag */
115 	CB_REV,				/* rev */
116 	nodev,				/* int (*cb_aread)() */
117 	nodev				/* int (*cb_awrite)() */
118 };
119 
120 /*
121  * bus ops and dev ops structures:
122  */
123 static struct bus_ops ebus_bus_ops = {
124 	BUSO_REV,
125 	ebus_map,
126 	NULL,
127 	NULL,
128 	NULL,
129 	i_ddi_map_fault,
130 	ddi_dma_map,
131 	ddi_dma_allochdl,
132 	ddi_dma_freehdl,
133 	ddi_dma_bindhdl,
134 	ddi_dma_unbindhdl,
135 	ddi_dma_flush,
136 	ddi_dma_win,
137 	ddi_dma_mctl,
138 	ebus_ctlops,
139 	ddi_bus_prop_op,
140 	ndi_busop_get_eventcookie,
141 	ndi_busop_add_eventcall,
142 	ndi_busop_remove_eventcall,
143 	ndi_post_event,
144 	0,
145 	0,
146 	0,
147 	0,
148 	0,
149 	0,
150 	0,
151 	0,
152 	ebus_intr_ops
153 };
154 
155 static struct dev_ops ebus_ops = {
156 	DEVO_REV,
157 	0,
158 	ebus_info,
159 	nulldev,
160 	nulldev,
161 	ebus_attach,
162 	ebus_detach,
163 	nodev,
164 	&ebus_cb_ops,
165 	&ebus_bus_ops
166 };
167 
168 /*
169  * module definitions:
170  */
171 #include <sys/modctl.h>
172 extern struct mod_ops mod_driverops;
173 
174 static struct modldrv modldrv = {
175 	&mod_driverops, 	/* Type of module.  This one is a driver */
176 	"ebus nexus driver %I%", /* Name of module. */
177 	&ebus_ops,		/* driver ops */
178 };
179 
180 static struct modlinkage modlinkage = {
181 	MODREV_1, (void *)&modldrv, NULL
182 };
183 
184 /*
185  * driver global data:
186  */
187 static void *per_ebus_state;		/* per-ebus soft state pointer */
188 
189 
190 int
191 _init(void)
192 {
193 	int e;
194 
195 	/*
196 	 * Initialize per-ebus soft state pointer.
197 	 */
198 	e = ddi_soft_state_init(&per_ebus_state, sizeof (ebus_devstate_t), 1);
199 	if (e != 0)
200 		return (e);
201 
202 	/*
203 	 * Install the module.
204 	 */
205 	e = mod_install(&modlinkage);
206 	if (e != 0)
207 		ddi_soft_state_fini(&per_ebus_state);
208 	return (e);
209 }
210 
211 int
212 _fini(void)
213 {
214 	int e;
215 
216 	/*
217 	 * Remove the module.
218 	 */
219 	e = mod_remove(&modlinkage);
220 	if (e != 0)
221 		return (e);
222 
223 	/*
224 	 * Free the soft state info.
225 	 */
226 	ddi_soft_state_fini(&per_ebus_state);
227 	return (e);
228 }
229 
230 int
231 _info(struct modinfo *modinfop)
232 {
233 	return (mod_info(&modlinkage, modinfop));
234 }
235 
236 /* device driver entry points */
237 
238 /*ARGSUSED*/
239 static int
240 ebus_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
241 {
242 	ebus_devstate_t *ebus_p;	/* per ebus state pointer */
243 	int instance;
244 
245 	instance = getminor((dev_t)arg);
246 	ebus_p = get_ebus_soft_state(instance);
247 
248 	switch (infocmd) {
249 	case DDI_INFO_DEVT2INSTANCE:
250 		*result = (void *)(uintptr_t)instance;
251 		break;
252 	case DDI_INFO_DEVT2DEVINFO:
253 		if (ebus_p == NULL)
254 			return (DDI_FAILURE);
255 		*result = (void *)ebus_p->dip;
256 		break;
257 	default:
258 		return (DDI_FAILURE);
259 	}
260 
261 	return (DDI_SUCCESS);
262 }
263 
264 /*
265  * attach entry point:
266  *
267  * normal attach:
268  *
269  *	create soft state structure (dip, reg, nreg and state fields)
270  *	map in configuration header
271  *	make sure device is properly configured
272  *	report device
273  */
274 static int
275 ebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
276 {
277 	ebus_devstate_t *ebus_p;	/* per ebus state pointer */
278 	int instance;
279 
280 	DBG1(D_ATTACH, NULL, "dip=%p\n", dip);
281 
282 	switch (cmd) {
283 	case DDI_ATTACH:
284 
285 		/*
286 		 * Allocate soft state for this instance.
287 		 */
288 		instance = ddi_get_instance(dip);
289 		if (ddi_soft_state_zalloc(per_ebus_state, instance)
290 		    != DDI_SUCCESS) {
291 			DBG(D_ATTACH, NULL, "failed to alloc soft state\n");
292 			return (DDI_FAILURE);
293 		}
294 		ebus_p = get_ebus_soft_state(instance);
295 		ebus_p->dip = dip;
296 		mutex_init(&ebus_p->ebus_mutex, NULL, MUTEX_DRIVER, NULL);
297 		ebus_p->ebus_soft_state = EBUS_SOFT_STATE_CLOSED;
298 
299 		ebus_get_cells_prop(ebus_p);
300 
301 		(void) ddi_prop_create(DDI_DEV_T_NONE, dip,
302 		    DDI_PROP_CANSLEEP, "no-dma-interrupt-sync", NULL, 0);
303 		/* Get our ranges property for mapping child registers. */
304 		if (ebus_get_ranges_prop(ebus_p) != DDI_SUCCESS) {
305 			goto attach_fail;
306 		}
307 
308 		/*
309 		 * create minor node for devctl interfaces
310 		 */
311 		if (ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
312 			DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
313 			goto attach_fail;
314 		}
315 
316 		if (ebus_config(ebus_p) != DDI_SUCCESS) {
317 			ddi_remove_minor_node(dip, "devctl");
318 			goto attach_fail;
319 		}
320 
321 		/*
322 		 * Make the pci_report_pmcap() call only for RIO
323 		 * implementations.
324 		 */
325 		if (IS_RIO(dip)) {
326 			(void) pci_report_pmcap(dip, PCI_PM_IDLESPEED,
327 			    (void *)EBUS_4MHZ);
328 		}
329 
330 		/*
331 		 * Make the state as attached and report the device.
332 		 */
333 		ebus_p->state = ATTACHED;
334 		ddi_report_dev(dip);
335 		DBG(D_ATTACH, ebus_p, "returning\n");
336 		break;
337 
338 	case DDI_RESUME:
339 
340 		instance = ddi_get_instance(dip);
341 		ebus_p = get_ebus_soft_state(instance);
342 
343 		(void) ebus_config(ebus_p);
344 
345 		ebus_p->state = RESUMED;
346 		break;
347 	}
348 
349 	return (DDI_SUCCESS);
350 
351 attach_fail:
352 	mutex_destroy(&ebus_p->ebus_mutex);
353 	free_ebus_soft_state(instance);
354 	return (DDI_FAILURE);
355 }
356 
357 /*
358  * detach entry point:
359  */
360 static int
361 ebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
362 {
363 	int instance = ddi_get_instance(dip);
364 	ebus_devstate_t *ebus_p = get_ebus_soft_state(instance);
365 
366 	switch (cmd) {
367 	case DDI_DETACH:
368 		DBG1(D_DETACH, ebus_p, "DDI_DETACH dip=%p\n", dip);
369 
370 		kmem_free(ebus_p->vrangep, ebus_p->vrange_len);
371 
372 		ddi_remove_minor_node(dip, "devctl");
373 		mutex_destroy(&ebus_p->ebus_mutex);
374 		free_ebus_soft_state(instance);
375 		break;
376 	case DDI_SUSPEND:
377 		DBG1(D_DETACH, ebus_p, "DDI_SUSPEND dip=%p\n", dip);
378 		ebus_p->state = SUSPENDED;
379 		break;
380 	default:
381 		DBG(D_ATTACH, NULL,
382 		    "failed to recognize ebus detach command\n");
383 		return (DDI_FAILURE);
384 	}
385 	return (DDI_SUCCESS);
386 }
387 
388 
389 int
390 ebus_get_ranges_prop(ebus_devstate_t *ebus_p)
391 {
392 	if (ddi_getlongprop(DDI_DEV_T_ANY, ebus_p->dip, DDI_PROP_DONTPASS,
393 		"ranges", (caddr_t)&ebus_p->vrangep, &ebus_p->vrange_len)
394 	    != DDI_SUCCESS) {
395 		cmn_err(CE_WARN, "Can't get %s ranges property",
396 		    ddi_get_name(ebus_p->dip));
397 		return (DDI_ME_REGSPEC_RANGE);
398 	}
399 
400 	ebus_p->vrange_cnt = ebus_p->vrange_len /
401 	    (ebus_p->ebus_paddr_cells + ebus_p->ebus_addr_cells +
402 		ebus_p->ebus_psz_cells);
403 
404 	if (ebus_p->vrange_cnt == 0) {
405 		kmem_free(ebus_p->vrangep, ebus_p->vrange_len);
406 		DBG(D_ATTACH, NULL, "range is equal to zero\n");
407 		return (DDI_FAILURE);
408 	}
409 
410 	return (DDI_SUCCESS);
411 }
412 
413 static void
414 ebus_get_cells_prop(ebus_devstate_t *ebus_p)
415 {
416 	dev_info_t *dip = ebus_p->dip;
417 	dev_info_t *pdip;
418 
419 	ebus_p->ebus_addr_cells = ddi_getprop(DDI_DEV_T_ANY,
420 	    dip, DDI_PROP_DONTPASS, "#address-cells", 2);
421 
422 	pdip = ddi_get_parent(dip);
423 	ebus_p->ebus_paddr_cells = ddi_getprop(DDI_DEV_T_ANY,
424 	    pdip, DDI_PROP_DONTPASS, "#address-cells", 2);
425 
426 	ASSERT((ebus_p->ebus_paddr_cells == 3) ||
427 	    (ebus_p->ebus_paddr_cells == 2));
428 
429 	ebus_p->ebus_sz_cells = ddi_getprop(DDI_DEV_T_ANY,
430 	    dip, DDI_PROP_DONTPASS, "#size-cells", 2);
431 	ebus_p->ebus_psz_cells = ddi_getprop(DDI_DEV_T_ANY,
432 	    pdip, DDI_PROP_DONTPASS, "#size-cells", 1);
433 
434 	/* XXX rootnex assumes 1 cell and does not respect #size-cells */
435 	if (ddi_root_node() == pdip)
436 		ebus_p->ebus_psz_cells = 1;
437 
438 	ASSERT((ebus_p->ebus_psz_cells == 2) ||
439 	    (ebus_p->ebus_psz_cells == 1));
440 
441 }
442 
443 /* bus driver entry points */
444 
445 /*
446  * bus map entry point:
447  *
448  * 	if map request is for an rnumber
449  *		get the corresponding regspec from device node
450  * 	build a new regspec in our parent's format
451  *	build a new map_req with the new regspec
452  *	call up the tree to complete the mapping
453  */
454 static int
455 ebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
456 	off_t off, off_t len, caddr_t *addrp)
457 {
458 	ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip));
459 	ebus_regspec_t *ebus_rp, *ebus_regs;
460 	vregspec_t vreg;
461 	ddi_map_req_t p_map_request;
462 	int rnumber, i, n;
463 	int rval = DDI_SUCCESS;
464 
465 	/*
466 	 * Handle the mapping according to its type.
467 	 */
468 	DBG4(D_MAP, ebus_p, "rdip=%s%d: off=%x len=%x\n",
469 	    ddi_get_name(rdip), ddi_get_instance(rdip), off, len);
470 	switch (mp->map_type) {
471 	case DDI_MT_REGSPEC:
472 
473 		/*
474 		 * We assume the register specification is in ebus format.
475 		 * We must convert it into a PCI format regspec and pass
476 		 * the request to our parent.
477 		 */
478 		DBG3(D_MAP, ebus_p, "rdip=%s%d: REGSPEC - handlep=%p\n",
479 			ddi_get_name(rdip), ddi_get_instance(rdip),
480 			mp->map_handlep);
481 		ebus_rp = (ebus_regspec_t *)mp->map_obj.rp;
482 		break;
483 
484 	case DDI_MT_RNUMBER:
485 
486 		/*
487 		 * Get the "reg" property from the device node and convert
488 		 * it to our parent's format.
489 		 */
490 		rnumber = mp->map_obj.rnumber;
491 		DBG4(D_MAP, ebus_p, "rdip=%s%d: rnumber=%x handlep=%p\n",
492 			ddi_get_name(rdip), ddi_get_instance(rdip),
493 			rnumber, mp->map_handlep);
494 
495 		if (getprop(rdip, "reg", &ebus_regs, &i) != DDI_SUCCESS) {
496 			DBG(D_MAP, ebus_p, "can't get reg property\n");
497 			return (DDI_ME_RNUMBER_RANGE);
498 		}
499 
500 		n = i / sizeof (ebus_regspec_t);
501 
502 		if (rnumber < 0 || rnumber >= n) {
503 			DBG(D_MAP, ebus_p, "rnumber out of range\n");
504 			return (DDI_ME_RNUMBER_RANGE);
505 		}
506 		ebus_rp = &ebus_regs[rnumber];
507 		break;
508 
509 	default:
510 		return (DDI_ME_INVAL);
511 
512 	}
513 
514 	/* Adjust our reg property with offset and length */
515 	ebus_rp->addr_low += off;
516 	if (len)
517 		ebus_rp->size = len;
518 
519 	rval = ebus_apply_range(ebus_p, rdip, ebus_rp, &vreg);
520 
521 	if (mp->map_type == DDI_MT_RNUMBER)
522 		kmem_free(ebus_regs, i);
523 
524 	if (rval != DDI_SUCCESS)
525 		return (rval);
526 
527 	p_map_request = *mp;
528 	p_map_request.map_type = DDI_MT_REGSPEC;
529 
530 	p_map_request.map_obj.rp = (struct regspec *)&vreg;
531 
532 	rval = ddi_map(dip, &p_map_request, 0, 0, addrp);
533 	DBG1(D_MAP, ebus_p, "parent returned %x\n", rval);
534 	return (rval);
535 }
536 
537 /*
538  * ebus_apply_range generically relocates child's regspec to
539  * parent's format according to ebus' range spec
540  *
541  * Assumptions:
542  * - rng_caddr_hi is the space type
543  * - rng_caddr_low is the base address
544  * - ebus address is 32 bit and ebus entirely lives between 0-4G of
545  *   parent space, so maths on preg/rng_cell_p[ebus_p->ebus_paddr_cells - 1],
546  *   preg_cell_p[i], rng_caddr_low and ebus_rp->size are sufficient.
547  */
548 static int
549 ebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip,
550     ebus_regspec_t *ebus_rp, vregspec_t *rp) {
551 	int b, i;
552 	int nrange = ebus_p->vrange_cnt;
553 	uint32_t addr_offset, rng_caddr_hi, rng_caddr_low, rng_sz;
554 	uint32_t req_addr = ebus_rp->addr_low;
555 
556 	uint32_t *rng_cell_p = (uint32_t *)ebus_p->vrangep;
557 	int rng_rec_sz = ebus_p->ebus_paddr_cells + ebus_p->ebus_addr_cells +
558 	    ebus_p->ebus_sz_cells;
559 	uint32_t *preg_cell_p = (uint32_t *)rp;
560 	int preg_rec_sz = ebus_p->ebus_paddr_cells + ebus_p->ebus_psz_cells;
561 
562 	static char out_of_range[] =
563 	    "Out of range register specification from device node <%s>";
564 
565 	DBG3(D_MAP, ebus_p, "Range Matching Addr 0x%x.%x size 0x%x\n",
566 	    ebus_rp->addr_hi, req_addr, ebus_rp->size);
567 
568 	for (b = 0; b < nrange; b++, rng_cell_p += rng_rec_sz) {
569 
570 		rng_caddr_hi = rng_cell_p[0];
571 		rng_caddr_low = rng_cell_p[1];
572 		rng_sz = rng_cell_p[rng_rec_sz-1];
573 
574 		/* Check for correct space */
575 		if (ebus_rp->addr_hi != rng_caddr_hi)
576 			continue;
577 
578 		/* Detect whether request entirely fits within a range */
579 		if (req_addr < rng_caddr_low)
580 			continue;
581 
582 		if ((req_addr + ebus_rp->size - 1)
583 		    > (rng_caddr_low + rng_sz - 1))
584 			continue;
585 
586 		addr_offset = req_addr - rng_caddr_low;
587 
588 		/* parent addr = child addr + offset from ranges */
589 		for (i = 0; i < preg_rec_sz; i++)
590 			preg_cell_p[i] = 0;
591 
592 		/* Copy the physical address */
593 		for (i = 0; i < ebus_p->ebus_paddr_cells; i++)
594 			preg_cell_p[i] = rng_cell_p[ebus_p->ebus_addr_cells+i];
595 
596 		preg_cell_p[ebus_p->ebus_paddr_cells-1] += addr_offset;
597 
598 		/* Copy the size */
599 		preg_cell_p[preg_rec_sz-1] = min(ebus_rp->size,
600 		    rng_sz - addr_offset);
601 
602 #ifdef DEBUG
603 		ebus_vreg_dump(ebus_p, (vregspec_t *)preg_cell_p);
604 #endif /* DEBUG */
605 
606 		break;
607 	}
608 
609 	if (b == nrange)  {
610 		cmn_err(CE_WARN, out_of_range, ddi_get_name(rdip));
611 		return (DDI_ME_REGSPEC_RANGE);
612 	}
613 
614 	return (DDI_SUCCESS);
615 }
616 
617 static int
618 ebus_name_child(dev_info_t *child, char *name, int namelen)
619 {
620 	ebus_regspec_t *ebus_rp;
621 	int reglen;
622 
623 	/*
624 	 * Get the address portion of the node name based on the
625 	 * address/offset.
626 	 */
627 	if (ddi_getlongprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
628 	    "reg", (caddr_t)&ebus_rp, &reglen) != DDI_SUCCESS) {
629 		return (DDI_FAILURE);
630 	}
631 
632 	(void) snprintf(name, namelen, "%x,%x", ebus_rp->addr_hi,
633 	    ebus_rp->addr_low);
634 	kmem_free(ebus_rp, reglen);
635 
636 	return (DDI_SUCCESS);
637 }
638 
639 /*
640  * control ops entry point:
641  *
642  * Requests handled completely:
643  *	DDI_CTLOPS_INITCHILD
644  *	DDI_CTLOPS_UNINITCHILD
645  *	DDI_CTLOPS_REPORTDEV
646  *	DDI_CTLOPS_REGSIZE
647  *	DDI_CTLOPS_NREGS
648  *
649  * All others passed to parent.
650  */
651 static int
652 ebus_ctlops(dev_info_t *dip, dev_info_t *rdip,
653 	ddi_ctl_enum_t op, void *arg, void *result)
654 {
655 #ifdef DEBUG
656 	ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip));
657 #endif
658 	ebus_regspec_t *ebus_rp;
659 	int i, n;
660 	char name[10];
661 
662 	switch (op) {
663 	case DDI_CTLOPS_INITCHILD: {
664 		dev_info_t *child = (dev_info_t *)arg;
665 		/*
666 		 * Set the address portion of the node name based on the
667 		 * address/offset.
668 		 */
669 		DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_INITCHILD: rdip=%s%d\n",
670 		    ddi_get_name(child), ddi_get_instance(child));
671 
672 		if (ebus_name_child(child, name, 10) != DDI_SUCCESS) {
673 			DBG(D_CTLOPS, ebus_p, "can't name child\n");
674 			return (DDI_FAILURE);
675 		}
676 
677 		ddi_set_name_addr(child, name);
678 		ddi_set_parent_data(child, NULL);
679 		return (DDI_SUCCESS);
680 	}
681 
682 	case DDI_CTLOPS_UNINITCHILD:
683 		DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_UNINITCHILD: rdip=%s%d\n",
684 			ddi_get_name((dev_info_t *)arg),
685 			ddi_get_instance((dev_info_t *)arg));
686 		ddi_set_name_addr((dev_info_t *)arg, NULL);
687 		ddi_remove_minor_node((dev_info_t *)arg, NULL);
688 		impl_rem_dev_props((dev_info_t *)arg);
689 		return (DDI_SUCCESS);
690 
691 	case DDI_CTLOPS_REPORTDEV:
692 
693 		DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REPORTDEV: rdip=%s%d\n",
694 			ddi_get_name(rdip), ddi_get_instance(rdip));
695 		cmn_err(CE_CONT, "?%s%d at %s%d: offset %s\n",
696 			ddi_driver_name(rdip), ddi_get_instance(rdip),
697 			ddi_driver_name(dip), ddi_get_instance(dip),
698 			ddi_get_name_addr(rdip));
699 		return (DDI_SUCCESS);
700 
701 	case DDI_CTLOPS_REGSIZE:
702 
703 		DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REGSIZE: rdip=%s%d\n",
704 			ddi_get_name(rdip), ddi_get_instance(rdip));
705 		if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) {
706 			DBG(D_CTLOPS, ebus_p, "can't get reg property\n");
707 			return (DDI_FAILURE);
708 		}
709 		n = i / sizeof (ebus_regspec_t);
710 		if (*(int *)arg < 0 || *(int *)arg >= n) {
711 			DBG(D_MAP, ebus_p, "rnumber out of range\n");
712 			kmem_free(ebus_rp, i);
713 			return (DDI_FAILURE);
714 		}
715 		*((off_t *)result) = ebus_rp[*(int *)arg].size;
716 		kmem_free(ebus_rp, i);
717 		return (DDI_SUCCESS);
718 
719 	case DDI_CTLOPS_NREGS:
720 
721 		DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_NREGS: rdip=%s%d\n",
722 			ddi_get_name(rdip), ddi_get_instance(rdip));
723 		if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) {
724 			DBG(D_CTLOPS, ebus_p, "can't get reg property\n");
725 			return (DDI_FAILURE);
726 		}
727 		*((uint_t *)result) = i / sizeof (ebus_regspec_t);
728 		kmem_free(ebus_rp, i);
729 		return (DDI_SUCCESS);
730 	}
731 
732 	/*
733 	 * Now pass the request up to our parent.
734 	 */
735 	DBG2(D_CTLOPS, ebus_p, "passing request to parent: rdip=%s%d\n",
736 		ddi_get_name(rdip), ddi_get_instance(rdip));
737 	return (ddi_ctlops(dip, rdip, op, arg, result));
738 }
739 
740 struct ebus_string_to_pil {
741 	int8_t *string;
742 	uint32_t pil;
743 };
744 
745 static struct ebus_string_to_pil ebus_name_to_pil[] = {{"SUNW,CS4231", 9},
746 							{"audio", 9},
747 							{"fdthree", 8},
748 							{"floppy", 8},
749 							{"ecpp", 3},
750 							{"parallel", 3},
751 							{"su", 12},
752 							{"se", 12},
753 							{"serial", 12},
754 							{"power", 14}};
755 
756 static struct ebus_string_to_pil ebus_device_type_to_pil[] = {{"serial", 12},
757 								{"block", 8}};
758 
759 static int
760 ebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
761     ddi_intr_handle_impl_t *hdlp, void *result)
762 {
763 #ifdef DEBUG
764 	ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip));
765 #endif
766 	int32_t		i, max_children, max_device_types, len;
767 	char		*name_p, *device_type_p;
768 
769 	DBG1(D_INTR, ebus_p, "ebus_p 0x%p\n", ebus_p);
770 
771 	/*
772 	 * NOTE: These ops below will never be supported in this nexus
773 	 * driver, hence they always return immediately.
774 	 */
775 	switch (intr_op) {
776 	case DDI_INTROP_GETCAP:
777 		*(int *)result = DDI_INTR_FLAG_LEVEL;
778 		return (DDI_SUCCESS);
779 	case DDI_INTROP_SUPPORTED_TYPES:
780 		*(int *)result = i_ddi_get_intx_nintrs(rdip) ?
781 		    DDI_INTR_TYPE_FIXED : 0;
782 		return (DDI_SUCCESS);
783 	case DDI_INTROP_SETCAP:
784 	case DDI_INTROP_SETMASK:
785 	case DDI_INTROP_CLRMASK:
786 	case DDI_INTROP_GETPENDING:
787 		return (DDI_ENOTSUP);
788 	default:
789 		break;
790 	}
791 
792 	if (hdlp->ih_pri)
793 		goto done;
794 
795 	/*
796 	 * This is a hack to set the PIL for the devices under ebus.
797 	 * We first look up a device by it's specific name, if we can't
798 	 * match the name, we try and match it's device_type property.
799 	 * Lastly we default a PIL level of 1.
800 	 */
801 	name_p = ddi_node_name(rdip);
802 	max_children = sizeof (ebus_name_to_pil) /
803 	    sizeof (struct ebus_string_to_pil);
804 
805 	for (i = 0; i < max_children; i++) {
806 		if (strcmp(ebus_name_to_pil[i].string, name_p) == 0) {
807 			DBG2(D_INTR, ebus_p, "child name %s; match PIL %d\n",
808 			    ebus_name_to_pil[i].string,
809 			    ebus_name_to_pil[i].pil);
810 
811 			hdlp->ih_pri = ebus_name_to_pil[i].pil;
812 			goto done;
813 		}
814 	}
815 
816 	if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS,
817 	    "device_type", (caddr_t)&device_type_p, &len) == DDI_SUCCESS) {
818 
819 		max_device_types = sizeof (ebus_device_type_to_pil) /
820 		    sizeof (struct ebus_string_to_pil);
821 
822 		for (i = 0; i < max_device_types; i++) {
823 			if (strcmp(ebus_device_type_to_pil[i].string,
824 			    device_type_p) == 0) {
825 				DBG2(D_INTR, ebus_p, "Device type %s; match "
826 				    "PIL %d\n", ebus_device_type_to_pil[i].
827 				    string, ebus_device_type_to_pil[i].pil);
828 
829 				hdlp->ih_pri = ebus_device_type_to_pil[i].pil;
830 				break;
831 			}
832 		}
833 
834 		kmem_free(device_type_p, len);
835 	}
836 
837 	/*
838 	 * If we get here, we need to set a default value
839 	 * for the PIL.
840 	 */
841 	if (hdlp->ih_pri == 0) {
842 		hdlp->ih_pri = 1;
843 
844 		cmn_err(CE_WARN, "%s%d assigning default interrupt level %d "
845 		    "for device %s%d", ddi_driver_name(dip),
846 		    ddi_get_instance(dip), hdlp->ih_pri, ddi_driver_name(rdip),
847 		    ddi_get_instance(rdip));
848 	}
849 
850 done:
851 	/* Pass up the request to our parent. */
852 	return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result));
853 }
854 
855 /*
856  * ebus_config: setup pci config space registers:
857  *     enable bus mastering, memory access and error reporting
858  */
859 static int
860 ebus_config(ebus_devstate_t *ebus_p)
861 {
862 	ddi_acc_handle_t conf_handle;
863 	uint16_t comm;
864 	dev_info_t *dip = ebus_p->dip;
865 	char *devtype_str;
866 	int devtype_len;
867 
868 	if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_get_parent(dip),
869 		DDI_PROP_DONTPASS, "device_type", (caddr_t)&devtype_str,
870 		&devtype_len) != DDI_SUCCESS) {
871 		cmn_err(CE_WARN, "Can't get %s device_type property",
872 		    ddi_get_name(ddi_get_parent(dip)));
873 
874 		return (DDI_FAILURE);
875 	}
876 
877 	comm = strcmp(devtype_str, "pci");
878 	kmem_free(devtype_str, devtype_len);
879 
880 	if (comm)
881 		return (DDI_SUCCESS);
882 
883 	/*
884 	 * Make sure the master enable and memory access enable
885 	 * bits are set in the config command register.
886 	 */
887 	if (pci_config_setup(ebus_p->dip, &conf_handle) != DDI_SUCCESS)
888 		return (DDI_FAILURE);
889 
890 	comm = pci_config_get16(conf_handle, PCI_CONF_COMM),
891 #ifdef DEBUG
892 	    DBG1(D_MAP, ebus_p, "command register was 0x%x\n", comm);
893 #endif
894 	comm |= (PCI_COMM_ME|PCI_COMM_MAE|PCI_COMM_SERR_ENABLE|
895 	    PCI_COMM_PARITY_DETECT);
896 	pci_config_put16(conf_handle, PCI_CONF_COMM, comm),
897 #ifdef DEBUG
898 	    DBG1(D_MAP, ebus_p, "command register is now 0x%x\n", comm);
899 #endif
900 	pci_config_put8(conf_handle, PCI_CONF_CACHE_LINESZ,
901 	    (uchar_t)ebus_cache_line_size);
902 	pci_config_put8(conf_handle, PCI_CONF_LATENCY_TIMER,
903 	    (uchar_t)ebus_latency_timer);
904 	pci_config_teardown(&conf_handle);
905 	return (DDI_SUCCESS);
906 }
907 
908 #ifdef DEBUG
909 extern void prom_printf(const char *, ...);
910 
911 static void
912 ebus_debug(uint_t flag, ebus_devstate_t *ebus_p, char *fmt,
913 	uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5)
914 {
915 	char *s;
916 
917 	if (ebus_debug_flags & flag) {
918 		switch (flag) {
919 		case D_ATTACH:
920 			s = "attach"; break;
921 		case D_DETACH:
922 			s = "detach"; break;
923 		case D_MAP:
924 			s = "map"; break;
925 		case D_CTLOPS:
926 			s = "ctlops"; break;
927 		case D_INTR:
928 			s = "intr"; break;
929 		}
930 		if (ebus_p)
931 			cmn_err(CE_CONT, "%s%d: %s: ",
932 				ddi_get_name(ebus_p->dip),
933 				ddi_get_instance(ebus_p->dip), s);
934 		else
935 			cmn_err(CE_CONT, "ebus: ");
936 		cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5);
937 	}
938 }
939 
940 static void
941 ebus_vreg_dump(ebus_devstate_t *ebus_p, vregspec_t *rp)
942 {
943 	if (ebus_p->ebus_paddr_cells == 3) {
944 		DBG5(D_MAP, ebus_p, "(%x,%x,%x)(%x,%x)\n",
945 		    rp->pci_regspec.pci_phys_hi,
946 		    rp->pci_regspec.pci_phys_mid,
947 		    rp->pci_regspec.pci_phys_low,
948 		    rp->pci_regspec.pci_size_hi,
949 		    rp->pci_regspec.pci_size_low);
950 	} else if (ebus_p->ebus_paddr_cells == 2) {
951 		DBG3(D_MAP, ebus_p, "%x,%x,%x\n",
952 		    rp->jbus_regspec.regspec_bustype,
953 		    rp->jbus_regspec.regspec_addr,
954 		    rp->jbus_regspec.regspec_size);
955 	}
956 }
957 #endif /* DEBUG */
958 
959 /* ARGSUSED3 */
960 static int
961 ebus_open(dev_t *devp, int flags, int otyp, cred_t *credp)
962 {
963 	ebus_devstate_t *ebus_p;
964 
965 	/*
966 	 * Make sure the open is for the right file type.
967 	 */
968 	if (otyp != OTYP_CHR)
969 		return (EINVAL);
970 
971 	/*
972 	 * Get the soft state structure for the device.
973 	 */
974 	ebus_p = get_ebus_soft_state(getminor(*devp));
975 	if (ebus_p == NULL)
976 		return (ENXIO);
977 
978 	/*
979 	 * Handle the open by tracking the device state.
980 	 */
981 	mutex_enter(&ebus_p->ebus_mutex);
982 	if (flags & FEXCL) {
983 		if (ebus_p->ebus_soft_state != EBUS_SOFT_STATE_CLOSED) {
984 			mutex_exit(&ebus_p->ebus_mutex);
985 			return (EBUSY);
986 		}
987 		ebus_p->ebus_soft_state = EBUS_SOFT_STATE_OPEN_EXCL;
988 	} else {
989 		if (ebus_p->ebus_soft_state == EBUS_SOFT_STATE_OPEN_EXCL) {
990 			mutex_exit(&ebus_p->ebus_mutex);
991 			return (EBUSY);
992 		}
993 		ebus_p->ebus_soft_state = EBUS_SOFT_STATE_OPEN;
994 	}
995 	mutex_exit(&ebus_p->ebus_mutex);
996 	return (0);
997 }
998 
999 
1000 /* ARGSUSED */
1001 static int
1002 ebus_close(dev_t dev, int flags, int otyp, cred_t *credp)
1003 {
1004 	ebus_devstate_t *ebus_p;
1005 
1006 	if (otyp != OTYP_CHR)
1007 		return (EINVAL);
1008 
1009 	ebus_p = get_ebus_soft_state(getminor(dev));
1010 	if (ebus_p == NULL)
1011 		return (ENXIO);
1012 
1013 	mutex_enter(&ebus_p->ebus_mutex);
1014 	ebus_p->ebus_soft_state = EBUS_SOFT_STATE_CLOSED;
1015 	mutex_exit(&ebus_p->ebus_mutex);
1016 	return (0);
1017 }
1018 
1019 
1020 /*
1021  * ebus_ioctl: devctl hotplug controls
1022  */
1023 /* ARGSUSED */
1024 static int
1025 ebus_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1026 	int *rvalp)
1027 {
1028 	ebus_devstate_t *ebus_p;
1029 	dev_info_t *self;
1030 	struct devctl_iocdata *dcp;
1031 	uint_t bus_state;
1032 	int rv = 0;
1033 
1034 	ebus_p = get_ebus_soft_state(getminor(dev));
1035 	if (ebus_p == NULL)
1036 		return (ENXIO);
1037 
1038 	self = ebus_p->dip;
1039 
1040 	/*
1041 	 * We can use the generic implementation for these ioctls
1042 	 */
1043 	switch (cmd) {
1044 	case DEVCTL_DEVICE_GETSTATE:
1045 	case DEVCTL_DEVICE_ONLINE:
1046 	case DEVCTL_DEVICE_OFFLINE:
1047 	case DEVCTL_BUS_GETSTATE:
1048 		return (ndi_devctl_ioctl(self, cmd, arg, mode, 0));
1049 	}
1050 
1051 	/*
1052 	 * read devctl ioctl data
1053 	 */
1054 	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1055 		return (EFAULT);
1056 
1057 	switch (cmd) {
1058 
1059 	case DEVCTL_DEVICE_RESET:
1060 		rv = ENOTSUP;
1061 		break;
1062 
1063 	case DEVCTL_BUS_QUIESCE:
1064 		if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1065 			if (bus_state == BUS_QUIESCED)
1066 				break;
1067 		(void) ndi_set_bus_state(self, BUS_QUIESCED);
1068 		break;
1069 
1070 	case DEVCTL_BUS_UNQUIESCE:
1071 		if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1072 			if (bus_state == BUS_ACTIVE)
1073 				break;
1074 		(void) ndi_set_bus_state(self, BUS_ACTIVE);
1075 		break;
1076 
1077 	case DEVCTL_BUS_RESET:
1078 		rv = ENOTSUP;
1079 		break;
1080 
1081 	case DEVCTL_BUS_RESETALL:
1082 		rv = ENOTSUP;
1083 		break;
1084 
1085 	default:
1086 		rv = ENOTTY;
1087 	}
1088 
1089 	ndi_dc_freehdl(dcp);
1090 	return (rv);
1091 }
1092