Home | History | Annotate | Download | only in io
      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