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