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