OpenGrok

Cross Reference: sunddi.c
xref: /onnv/onnv-gate/usr/src/uts/common/os/sunddi.c
Home | History | Annotate | Line # | Download | only in os
      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 /*
     23  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
     24  */
     25 
     26 #include <sys/note.h>
     27 #include <sys/types.h>
     28 #include <sys/param.h>
     29 #include <sys/systm.h>
     30 #include <sys/buf.h>
     31 #include <sys/uio.h>
     32 #include <sys/cred.h>
     33 #include <sys/poll.h>
     34 #include <sys/mman.h>
     35 #include <sys/kmem.h>
     36 #include <sys/model.h>
     37 #include <sys/file.h>
     38 #include <sys/proc.h>
     39 #include <sys/open.h>
     40 #include <sys/user.h>
     41 #include <sys/t_lock.h>
     42 #include <sys/vm.h>
     43 #include <sys/stat.h>
     44 #include <vm/hat.h>
     45 #include <vm/seg.h>
     46 #include <vm/seg_vn.h>
     47 #include <vm/seg_dev.h>
     48 #include <vm/as.h>
     49 #include <sys/cmn_err.h>
     50 #include <sys/cpuvar.h>
     51 #include <sys/debug.h>
     52 #include <sys/autoconf.h>
     53 #include <sys/sunddi.h>
     54 #include <sys/esunddi.h>
     55 #include <sys/sunndi.h>
     56 #include <sys/kstat.h>
     57 #include <sys/conf.h>
     58 #include <sys/ddi_impldefs.h>	/* include implementation structure defs */
     59 #include <sys/ndi_impldefs.h>	/* include prototypes */
     60 #include <sys/ddi_timer.h>
     61 #include <sys/hwconf.h>
     62 #include <sys/pathname.h>
     63 #include <sys/modctl.h>
     64 #include <sys/epm.h>
     65 #include <sys/devctl.h>
     66 #include <sys/callb.h>
     67 #include <sys/cladm.h>
     68 #include <sys/sysevent.h>
     69 #include <sys/dacf_impl.h>
     70 #include <sys/ddidevmap.h>
     71 #include <sys/bootconf.h>
     72 #include <sys/disp.h>
     73 #include <sys/atomic.h>
     74 #include <sys/promif.h>
     75 #include <sys/instance.h>
     76 #include <sys/sysevent/eventdefs.h>
     77 #include <sys/task.h>
     78 #include <sys/project.h>
     79 #include <sys/taskq.h>
     80 #include <sys/devpolicy.h>
     81 #include <sys/ctype.h>
     82 #include <net/if.h>
     83 #include <sys/rctl.h>
     84 #include <sys/zone.h>
     85 #include <sys/clock_impl.h>
     86 #include <sys/ddi.h>
     87 #include <sys/modhash.h>
     88 #include <sys/sunldi_impl.h>
     89 #include <sys/fs/dv_node.h>
     90 #include <sys/fs/snode.h>
     91 
     92 extern	pri_t	minclsyspri;
     93 
     94 extern	rctl_hndl_t rc_project_locked_mem;
     95 extern	rctl_hndl_t rc_zone_locked_mem;
     96 
     97 #ifdef DEBUG
     98 static int sunddi_debug = 0;
     99 #endif /* DEBUG */
    100 
    101 /* ddi_umem_unlock miscellaneous */
    102 
    103 static	void	i_ddi_umem_unlock_thread_start(void);
    104 
    105 static	kmutex_t	ddi_umem_unlock_mutex; /* unlock list mutex */
    106 static	kcondvar_t	ddi_umem_unlock_cv; /* unlock list block/unblock */
    107 static	kthread_t	*ddi_umem_unlock_thread;
    108 /*
    109  * The ddi_umem_unlock FIFO list.  NULL head pointer indicates empty list.
    110  */
    111 static	struct	ddi_umem_cookie *ddi_umem_unlock_head = NULL;
    112 static	struct	ddi_umem_cookie *ddi_umem_unlock_tail = NULL;
    113 
    114 /*
    115  * DDI(Sun) Function and flag definitions:
    116  */
    117 
    118 #if defined(__x86)
    119 /*
    120  * Used to indicate which entries were chosen from a range.
    121  */
    122 char	*chosen_reg = "chosen-reg";
    123 #endif
    124 
    125 /*
    126  * Function used to ring system console bell
    127  */
    128 void (*ddi_console_bell_func)(clock_t duration);
    129 
    130 /*
    131  * Creating register mappings and handling interrupts:
    132  */
    133 
    134 /*
    135  * Generic ddi_map: Call parent to fulfill request...
    136  */
    137 
    138 int
    139 ddi_map(dev_info_t *dp, ddi_map_req_t *mp, off_t offset,
    140     off_t len, caddr_t *addrp)
    141 {
    142 	dev_info_t *pdip;
    143 
    144 	ASSERT(dp);
    145 	pdip = (dev_info_t *)DEVI(dp)->devi_parent;
    146 	return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)(pdip,
    147 	    dp, mp, offset, len, addrp));
    148 }
    149 
    150 /*
    151  * ddi_apply_range: (Called by nexi only.)
    152  * Apply ranges in parent node dp, to child regspec rp...
    153  */
    154 
    155 int
    156 ddi_apply_range(dev_info_t *dp, dev_info_t *rdip, struct regspec *rp)
    157 {
    158 	return (i_ddi_apply_range(dp, rdip, rp));
    159 }
    160 
    161 int
    162 ddi_map_regs(dev_info_t *dip, uint_t rnumber, caddr_t *kaddrp, off_t offset,
    163     off_t len)
    164 {
    165 	ddi_map_req_t mr;
    166 #if defined(__x86)
    167 	struct {
    168 		int	bus;
    169 		int	addr;
    170 		int	size;
    171 	} reg, *reglist;
    172 	uint_t	length;
    173 	int	rc;
    174 
    175 	/*
    176 	 * get the 'registers' or the 'reg' property.
    177 	 * We look up the reg property as an array of
    178 	 * int's.
    179 	 */
    180 	rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
    181 	    DDI_PROP_DONTPASS, "registers", (int **)&reglist, &length);
    182 	if (rc != DDI_PROP_SUCCESS)
    183 		rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
    184 		    DDI_PROP_DONTPASS, "reg", (int **)&reglist, &length);
    185 	if (rc == DDI_PROP_SUCCESS) {
    186 		/*
    187 		 * point to the required entry.
    188 		 */
    189 		reg = reglist[rnumber];
    190 		reg.addr += offset;
    191 		if (len != 0)
    192 			reg.size = len;
    193 		/*
    194 		 * make a new property containing ONLY the required tuple.
    195 		 */
    196 		if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
    197 		    chosen_reg, (int *)&reg, (sizeof (reg)/sizeof (int)))
    198 		    != DDI_PROP_SUCCESS) {
    199 			cmn_err(CE_WARN, "%s%d: cannot create '%s' "
    200 			    "property", DEVI(dip)->devi_name,
    201 			    DEVI(dip)->devi_instance, chosen_reg);
    202 		}
    203 		/*
    204 		 * free the memory allocated by
    205 		 * ddi_prop_lookup_int_array ().
    206 		 */
    207 		ddi_prop_free((void *)reglist);
    208 	}
    209 #endif
    210 	mr.map_op = DDI_MO_MAP_LOCKED;
    211 	mr.map_type = DDI_MT_RNUMBER;
    212 	mr.map_obj.rnumber = rnumber;
    213 	mr.map_prot = PROT_READ | PROT_WRITE;
    214 	mr.map_flags = DDI_MF_KERNEL_MAPPING;
    215 	mr.map_handlep = NULL;
    216 	mr.map_vers = DDI_MAP_VERSION;
    217 
    218 	/*
    219 	 * Call my parent to map in my regs.
    220 	 */
    221 
    222 	return (ddi_map(dip, &mr, offset, len, kaddrp));
    223 }
    224 
    225 void
    226 ddi_unmap_regs(dev_info_t *dip, uint_t rnumber, caddr_t *kaddrp, off_t offset,
    227     off_t len)
    228 {
    229 	ddi_map_req_t mr;
    230 
    231 	mr.map_op = DDI_MO_UNMAP;
    232 	mr.map_type = DDI_MT_RNUMBER;
    233 	mr.map_flags = DDI_MF_KERNEL_MAPPING;
    234 	mr.map_prot = PROT_READ | PROT_WRITE;	/* who cares? */
    235 	mr.map_obj.rnumber = rnumber;
    236 	mr.map_handlep = NULL;
    237 	mr.map_vers = DDI_MAP_VERSION;
    238 
    239 	/*
    240 	 * Call my parent to unmap my regs.
    241 	 */
    242 
    243 	(void) ddi_map(dip, &mr, offset, len, kaddrp);
    244 	*kaddrp = (caddr_t)0;
    245 #if defined(__x86)
    246 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, chosen_reg);
    247 #endif
    248 }
    249 
    250 int
    251 ddi_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
    252 	off_t offset, off_t len, caddr_t *vaddrp)
    253 {
    254 	return (i_ddi_bus_map(dip, rdip, mp, offset, len, vaddrp));
    255 }
    256 
    257 /*
    258  * nullbusmap:	The/DDI default bus_map entry point for nexi
    259  *		not conforming to the reg/range paradigm (i.e. scsi, etc.)
    260  *		with no HAT/MMU layer to be programmed at this level.
    261  *
    262  *		If the call is to map by rnumber, return an error,
    263  *		otherwise pass anything else up the tree to my parent.
    264  */
    265 int
    266 nullbusmap(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
    267 	off_t offset, off_t len, caddr_t *vaddrp)
    268 {
    269 	_NOTE(ARGUNUSED(rdip))
    270 	if (mp->map_type == DDI_MT_RNUMBER)
    271 		return (DDI_ME_UNSUPPORTED);
    272 
    273 	return (ddi_map(dip, mp, offset, len, vaddrp));
    274 }
    275 
    276 /*
    277  * ddi_rnumber_to_regspec: Not for use by leaf drivers.
    278  *			   Only for use by nexi using the reg/range paradigm.
    279  */
    280 struct regspec *
    281 ddi_rnumber_to_regspec(dev_info_t *dip, int rnumber)
    282 {
    283 	return (i_ddi_rnumber_to_regspec(dip, rnumber));
    284 }
    285 
    286 
    287 /*
    288  * Note that we allow the dip to be nil because we may be called
    289  * prior even to the instantiation of the devinfo tree itself - all
    290  * regular leaf and nexus drivers should always use a non-nil dip!
    291  *
    292  * We treat peek in a somewhat cavalier fashion .. assuming that we'll
    293  * simply get a synchronous fault as soon as we touch a missing address.
    294  *
    295  * Poke is rather more carefully handled because we might poke to a write
    296  * buffer, "succeed", then only find some time later that we got an
    297  * asynchronous fault that indicated that the address we were writing to
    298  * was not really backed by hardware.
    299  */
    300 
    301 static int
    302 i_ddi_peekpoke(dev_info_t *devi, ddi_ctl_enum_t cmd, size_t size,
    303     void *addr, void *value_p)
    304 {
    305 	union {
    306 		uint64_t	u64;
    307 		uint32_t	u32;
    308 		uint16_t	u16;
    309 		uint8_t		u8;
    310 	} peekpoke_value;
    311 
    312 	peekpoke_ctlops_t peekpoke_args;
    313 	uint64_t dummy_result;
    314 	int rval;
    315 
    316 	/* Note: size is assumed to be correct;  it is not checked. */
    317 	peekpoke_args.size = size;
    318 	peekpoke_args.dev_addr = (uintptr_t)addr;
    319 	peekpoke_args.handle = NULL;
    320 	peekpoke_args.repcount = 1;
    321 	peekpoke_args.flags = 0;
    322 
    323 	if (cmd == DDI_CTLOPS_POKE) {
    324 		switch (size) {
    325 		case sizeof (uint8_t):
    326 			peekpoke_value.u8 = *(uint8_t *)value_p;
    327 			break;
    328 		case sizeof (uint16_t):
    329 			peekpoke_value.u16 = *(uint16_t *)value_p;
    330 			break;
    331 		case sizeof (uint32_t):
    332 			peekpoke_value.u32 = *(uint32_t *)value_p;
    333 			break;
    334 		case sizeof (uint64_t):
    335 			peekpoke_value.u64 = *(uint64_t *)value_p;
    336 			break;
    337 		}
    338 	}
    339 
    340 	peekpoke_args.host_addr = (uintptr_t)&peekpoke_value.u64;
    341 
    342 	if (devi != NULL)
    343 		rval = ddi_ctlops(devi, devi, cmd, &peekpoke_args,
    344 		    &dummy_result);
    345 	else
    346 		rval = peekpoke_mem(cmd, &peekpoke_args);
    347 
    348 	/*
    349 	 * A NULL value_p is permitted by ddi_peek(9F); discard the result.
    350 	 */
    351 	if ((cmd == DDI_CTLOPS_PEEK) & (value_p != NULL)) {
    352 		switch (size) {
    353 		case sizeof (uint8_t):
    354 			*(uint8_t *)value_p = peekpoke_value.u8;
    355 			break;
    356 		case sizeof (uint16_t):
    357 			*(uint16_t *)value_p = peekpoke_value.u16;
    358 			break;
    359 		case sizeof (uint32_t):
    360 			*(uint32_t *)value_p = peekpoke_value.u32;
    361 			break;
    362 		case sizeof (uint64_t):
    363 			*(uint64_t *)value_p = peekpoke_value.u64;
    364 			break;
    365 		}
    366 	}
    367 
    368 	return (rval);
    369 }
    370 
    371 /*
    372  * Keep ddi_peek() and ddi_poke() in case 3rd parties are calling this.
    373  * they shouldn't be, but the 9f manpage kind of pseudo exposes it.
    374  */
    375 int
    376 ddi_peek(dev_info_t *devi, size_t size, void *addr, void *value_p)
    377 {
    378 	switch (size) {
    379 	case sizeof (uint8_t):
    380 	case sizeof (uint16_t):
    381 	case sizeof (uint32_t):
    382 	case sizeof (uint64_t):
    383 		break;
    384 	default:
    385 		return (DDI_FAILURE);
    386 	}
    387 
    388 	return (i_ddi_peekpoke(devi, DDI_CTLOPS_PEEK, size, addr, value_p));
    389 }
    390 
    391 int
    392 ddi_poke(dev_info_t *devi, size_t size, void *addr, void *value_p)
    393 {
    394 	switch (size) {
    395 	case sizeof (uint8_t):
    396 	case sizeof (uint16_t):
    397 	case sizeof (uint32_t):
    398 	case sizeof (uint64_t):
    399 		break;
    400 	default:
    401 		return (DDI_FAILURE);
    402 	}
    403 
    404 	return (i_ddi_peekpoke(devi, DDI_CTLOPS_POKE, size, addr, value_p));
    405 }
    406 
    407 int
    408 ddi_peek8(dev_info_t *dip, int8_t *addr, int8_t *val_p)
    409 {
    410 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    411 	    val_p));
    412 }
    413 
    414 int
    415 ddi_peek16(dev_info_t *dip, int16_t *addr, int16_t *val_p)
    416 {
    417 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    418 	    val_p));
    419 }
    420 
    421 int
    422 ddi_peek32(dev_info_t *dip, int32_t *addr, int32_t *val_p)
    423 {
    424 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    425 	    val_p));
    426 }
    427 
    428 int
    429 ddi_peek64(dev_info_t *dip, int64_t *addr, int64_t *val_p)
    430 {
    431 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    432 	    val_p));
    433 }
    434 
    435 
    436 /*
    437  * We need to separate the old interfaces from the new ones and leave them
    438  * in here for a while. Previous versions of the OS defined the new interfaces
    439  * to the old interfaces. This way we can fix things up so that we can
    440  * eventually remove these interfaces.
    441  * e.g. A 3rd party module/driver using ddi_peek8 and built against S10
    442  * or earlier will actually have a reference to ddi_peekc in the binary.
    443  */
    444 #ifdef _ILP32
    445 int
    446 ddi_peekc(dev_info_t *dip, int8_t *addr, int8_t *val_p)
    447 {
    448 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    449 	    val_p));
    450 }
    451 
    452 int
    453 ddi_peeks(dev_info_t *dip, int16_t *addr, int16_t *val_p)
    454 {
    455 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    456 	    val_p));
    457 }
    458 
    459 int
    460 ddi_peekl(dev_info_t *dip, int32_t *addr, int32_t *val_p)
    461 {
    462 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    463 	    val_p));
    464 }
    465 
    466 int
    467 ddi_peekd(dev_info_t *dip, int64_t *addr, int64_t *val_p)
    468 {
    469 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_PEEK, sizeof (*val_p), addr,
    470 	    val_p));
    471 }
    472 #endif /* _ILP32 */
    473 
    474 int
    475 ddi_poke8(dev_info_t *dip, int8_t *addr, int8_t val)
    476 {
    477 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    478 }
    479 
    480 int
    481 ddi_poke16(dev_info_t *dip, int16_t *addr, int16_t val)
    482 {
    483 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    484 }
    485 
    486 int
    487 ddi_poke32(dev_info_t *dip, int32_t *addr, int32_t val)
    488 {
    489 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    490 }
    491 
    492 int
    493 ddi_poke64(dev_info_t *dip, int64_t *addr, int64_t val)
    494 {
    495 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    496 }
    497 
    498 /*
    499  * We need to separate the old interfaces from the new ones and leave them
    500  * in here for a while. Previous versions of the OS defined the new interfaces
    501  * to the old interfaces. This way we can fix things up so that we can
    502  * eventually remove these interfaces.
    503  * e.g. A 3rd party module/driver using ddi_poke8 and built against S10
    504  * or earlier will actually have a reference to ddi_pokec in the binary.
    505  */
    506 #ifdef _ILP32
    507 int
    508 ddi_pokec(dev_info_t *dip, int8_t *addr, int8_t val)
    509 {
    510 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    511 }
    512 
    513 int
    514 ddi_pokes(dev_info_t *dip, int16_t *addr, int16_t val)
    515 {
    516 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    517 }
    518 
    519 int
    520 ddi_pokel(dev_info_t *dip, int32_t *addr, int32_t val)
    521 {
    522 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    523 }
    524 
    525 int
    526 ddi_poked(dev_info_t *dip, int64_t *addr, int64_t val)
    527 {
    528 	return (i_ddi_peekpoke(dip, DDI_CTLOPS_POKE, sizeof (val), addr, &val));
    529 }
    530 #endif /* _ILP32 */
    531 
    532 /*
    533  * ddi_peekpokeio() is used primarily by the mem drivers for moving
    534  * data to and from uio structures via peek and poke.  Note that we
    535  * use "internal" routines ddi_peek and ddi_poke to make this go
    536  * slightly faster, avoiding the call overhead ..
    537  */
    538 int
    539 ddi_peekpokeio(dev_info_t *devi, struct uio *uio, enum uio_rw rw,
    540     caddr_t addr, size_t len, uint_t xfersize)
    541 {
    542 	int64_t	ibuffer;
    543 	int8_t w8;
    544 	size_t sz;
    545 	int o;
    546 
    547 	if (xfersize > sizeof (long))
    548 		xfersize = sizeof (long);
    549 
    550 	while (len != 0) {
    551 		if ((len | (uintptr_t)addr) & 1) {
    552 			sz = sizeof (int8_t);
    553 			if (rw == UIO_WRITE) {
    554 				if ((o = uwritec(uio)) == -1)
    555 					return (DDI_FAILURE);
    556 				if (ddi_poke8(devi, (int8_t *)addr,
    557 				    (int8_t)o) != DDI_SUCCESS)
    558 					return (DDI_FAILURE);
    559 			} else {
    560 				if (i_ddi_peekpoke(devi, DDI_CTLOPS_PEEK, sz,
    561 				    (int8_t *)addr, &w8) != DDI_SUCCESS)
    562 					return (DDI_FAILURE);
    563 				if (ureadc(w8, uio))
    564 					return (DDI_FAILURE);
    565 			}
    566 		} else {
    567 			switch (xfersize) {
    568 			case sizeof (int64_t):
    569 				if (((len | (uintptr_t)addr) &
    570 				    (sizeof (int64_t) - 1)) == 0) {
    571 					sz = xfersize;
    572 					break;
    573 				}
    574 				/*FALLTHROUGH*/
    575 			case sizeof (int32_t):
    576 				if (((len | (uintptr_t)addr) &
    577 				    (sizeof (int32_t) - 1)) == 0) {
    578 					sz = xfersize;
    579 					break;
    580 				}
    581 				/*FALLTHROUGH*/
    582 			default:
    583 				/*
    584 				 * This still assumes that we might have an
    585 				 * I/O bus out there that permits 16-bit
    586 				 * transfers (and that it would be upset by
    587 				 * 32-bit transfers from such locations).
    588 				 */
    589 				sz = sizeof (int16_t);
    590 				break;
    591 			}
    592 
    593 			if (rw == UIO_READ) {
    594 				if (i_ddi_peekpoke(devi, DDI_CTLOPS_PEEK, sz,
    595 				    addr, &ibuffer) != DDI_SUCCESS)
    596 					return (DDI_FAILURE);
    597 			}
    598 
    599 			if (uiomove(&ibuffer, sz, rw, uio))
    600 				return (DDI_FAILURE);
    601 
    602 			if (rw == UIO_WRITE) {
    603 				if (i_ddi_peekpoke(devi, DDI_CTLOPS_POKE, sz,
    604 				    addr, &ibuffer) != DDI_SUCCESS)
    605 					return (DDI_FAILURE);
    606 			}
    607 		}
    608 		addr += sz;
    609 		len -= sz;
    610 	}
    611 	return (DDI_SUCCESS);
    612 }
    613 
    614 /*
    615  * These routines are used by drivers that do layered ioctls
    616  * On sparc, they're implemented in assembler to avoid spilling
    617  * register windows in the common (copyin) case ..
    618  */
    619 #if !defined(__sparc)
    620 int
    621 ddi_copyin(const void *buf, void *kernbuf, size_t size, int flags)
    622 {
    623 	if (flags & FKIOCTL)
    624 		return (kcopy(buf, kernbuf, size) ? -1 : 0);
    625 	return (copyin(buf, kernbuf, size));
    626 }
    627 
    628 int
    629 ddi_copyout(const void *buf, void *kernbuf, size_t size, int flags)
    630 {
    631 	if (flags & FKIOCTL)
    632 		return (kcopy(buf, kernbuf, size) ? -1 : 0);
    633 	return (copyout(buf, kernbuf, size));
    634 }
    635 #endif	/* !__sparc */
    636 
    637 /*
    638  * Conversions in nexus pagesize units.  We don't duplicate the
    639  * 'nil dip' semantics of peek/poke because btopr/btop/ptob are DDI/DKI
    640  * routines anyway.
    641  */
    642 unsigned long
    643 ddi_btop(dev_info_t *dip, unsigned long bytes)
    644 {
    645 	unsigned long pages;
    646 
    647 	(void) ddi_ctlops(dip, dip, DDI_CTLOPS_BTOP, &bytes, &pages);
    648 	return (pages);
    649 }
    650 
    651 unsigned long
    652 ddi_btopr(dev_info_t *dip, unsigned long bytes)
    653 {
    654 	unsigned long pages;
    655 
    656 	(void) ddi_ctlops(dip, dip, DDI_CTLOPS_BTOPR, &bytes, &pages);
    657 	return (pages);
    658 }
    659 
    660 unsigned long
    661 ddi_ptob(dev_info_t *dip, unsigned long pages)
    662 {
    663 	unsigned long bytes;
    664 
    665 	(void) ddi_ctlops(dip, dip, DDI_CTLOPS_PTOB, &pages, &bytes);
    666 	return (bytes);
    667 }
    668 
    669 unsigned int
    670 ddi_enter_critical(void)
    671 {
    672 	return ((uint_t)spl7());
    673 }
    674 
    675 void
    676 ddi_exit_critical(unsigned int spl)
    677 {
    678 	splx((int)spl);
    679 }
    680 
    681 /*
    682  * Nexus ctlops punter
    683  */
    684 
    685 #if !defined(__sparc)
    686 /*
    687  * Request bus_ctl parent to handle a bus_ctl request
    688  *
    689  * (The sparc version is in sparc_ddi.s)
    690  */
    691 int
    692 ddi_ctlops(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t op, void *a, void *v)
    693 {
    694 	int (*fp)();
    695 
    696 	if (!d || !r)
    697 		return (DDI_FAILURE);
    698 
    699 	if ((d = (dev_info_t *)DEVI(d)->devi_bus_ctl) == NULL)
    700 		return (DDI_FAILURE);
    701 
    702 	fp = DEVI(d)->devi_ops->devo_bus_ops->bus_ctl;
    703 	return ((*fp)(d, r, op, a, v));
    704 }
    705 
    706 #endif
    707 
    708 /*
    709  * DMA/DVMA setup
    710  */
    711 
    712 #if defined(__sparc)
    713 static ddi_dma_lim_t standard_limits = {
    714 	(uint_t)0,	/* addr_t dlim_addr_lo */
    715 	(uint_t)-1,	/* addr_t dlim_addr_hi */
    716 	(uint_t)-1,	/* uint_t dlim_cntr_max */
    717 	(uint_t)1,	/* uint_t dlim_burstsizes */
    718 	(uint_t)1,	/* uint_t dlim_minxfer */
    719 	0		/* uint_t dlim_dmaspeed */
    720 };
    721 #elif defined(__x86)
    722 static ddi_dma_lim_t standard_limits = {
    723 	(uint_t)0,		/* addr_t dlim_addr_lo */
    724 	(uint_t)0xffffff,	/* addr_t dlim_addr_hi */
    725 	(uint_t)0,		/* uint_t dlim_cntr_max */
    726 	(uint_t)0x00000001,	/* uint_t dlim_burstsizes */
    727 	(uint_t)DMA_UNIT_8,	/* uint_t dlim_minxfer */
    728 	(uint_t)0,		/* uint_t dlim_dmaspeed */
    729 	(uint_t)0x86<<24+0,	/* uint_t dlim_version */
    730 	(uint_t)0xffff,		/* uint_t dlim_adreg_max */
    731 	(uint_t)0xffff,		/* uint_t dlim_ctreg_max */
    732 	(uint_t)512,		/* uint_t dlim_granular */
    733 	(int)1,			/* int dlim_sgllen */
    734 	(uint_t)0xffffffff	/* uint_t dlim_reqsizes */
    735 };
    736 
    737 #endif
    738 
    739 int
    740 ddi_dma_setup(dev_info_t *dip, struct ddi_dma_req *dmareqp,
    741     ddi_dma_handle_t *handlep)
    742 {
    743 	int (*funcp)() = ddi_dma_map;
    744 	struct bus_ops *bop;
    745 #if defined(__sparc)
    746 	auto ddi_dma_lim_t dma_lim;
    747 
    748 	if (dmareqp->dmar_limits == (ddi_dma_lim_t *)0) {
    749 		dma_lim = standard_limits;
    750 	} else {
    751 		dma_lim = *dmareqp->dmar_limits;
    752 	}
    753 	dmareqp->dmar_limits = &dma_lim;
    754 #endif
    755 #if defined(__x86)
    756 	if (dmareqp->dmar_limits == (ddi_dma_lim_t *)0)
    757 		return (DDI_FAILURE);
    758 #endif
    759 
    760 	/*
    761 	 * Handle the case that the requester is both a leaf
    762 	 * and a nexus driver simultaneously by calling the
    763 	 * requester's bus_dma_map function directly instead
    764 	 * of ddi_dma_map.
    765 	 */
    766 	bop = DEVI(dip)->devi_ops->devo_bus_ops;
    767 	if (bop && bop->bus_dma_map)
    768 		funcp = bop->bus_dma_map;
    769 	return ((*funcp)(dip, dip, dmareqp, handlep));
    770 }
    771 
    772 int
    773 ddi_dma_addr_setup(dev_info_t *dip, struct as *as, caddr_t addr, size_t len,
    774     uint_t flags, int (*waitfp)(), caddr_t arg,
    775     ddi_dma_lim_t *limits, ddi_dma_handle_t *handlep)
    776 {
    777 	int (*funcp)() = ddi_dma_map;
    778 	ddi_dma_lim_t dma_lim;
    779 	struct ddi_dma_req dmareq;
    780 	struct bus_ops *bop;
    781 
    782 	if (len == 0) {
    783 		return (DDI_DMA_NOMAPPING);
    784 	}
    785 	if (limits == (ddi_dma_lim_t *)0) {
    786 		dma_lim = standard_limits;
    787 	} else {
    788 		dma_lim = *limits;
    789 	}
    790 	dmareq.dmar_limits = &dma_lim;
    791 	dmareq.dmar_flags = flags;
    792 	dmareq.dmar_fp = waitfp;
    793 	dmareq.dmar_arg = arg;
    794 	dmareq.dmar_object.dmao_size = len;
    795 	dmareq.dmar_object.dmao_type = DMA_OTYP_VADDR;
    796 	dmareq.dmar_object.dmao_obj.virt_obj.v_as = as;
    797 	dmareq.dmar_object.dmao_obj.virt_obj.v_addr = addr;
    798 	dmareq.dmar_object.dmao_obj.virt_obj.v_priv = NULL;
    799 
    800 	/*
    801 	 * Handle the case that the requester is both a leaf
    802 	 * and a nexus driver simultaneously by calling the
    803 	 * requester's bus_dma_map function directly instead
    804 	 * of ddi_dma_map.
    805 	 */
    806 	bop = DEVI(dip)->devi_ops->devo_bus_ops;
    807 	if (bop && bop->bus_dma_map)
    808 		funcp = bop->bus_dma_map;
    809 
    810 	return ((*funcp)(dip, dip, &dmareq, handlep));
    811 }
    812 
    813 int
    814 ddi_dma_buf_setup(dev_info_t *dip, struct buf *bp, uint_t flags,
    815     int (*waitfp)(), caddr_t arg, ddi_dma_lim_t *limits,
    816     ddi_dma_handle_t *handlep)
    817 {
    818 	int (*funcp)() = ddi_dma_map;
    819 	ddi_dma_lim_t dma_lim;
    820 	struct ddi_dma_req dmareq;
    821 	struct bus_ops *bop;
    822 
    823 	if (limits == (ddi_dma_lim_t *)0) {
    824 		dma_lim = standard_limits;
    825 	} else {
    826 		dma_lim = *limits;
    827 	}
    828 	dmareq.dmar_limits = &dma_lim;
    829 	dmareq.dmar_flags = flags;
    830 	dmareq.dmar_fp = waitfp;
    831 	dmareq.dmar_arg = arg;
    832 	dmareq.dmar_object.dmao_size = (uint_t)bp->b_bcount;
    833 
    834 	if (bp->b_flags & B_PAGEIO) {
    835 		dmareq.dmar_object.dmao_type = DMA_OTYP_PAGES;
    836 		dmareq.dmar_object.dmao_obj.pp_obj.pp_pp = bp->b_pages;
    837 		dmareq.dmar_object.dmao_obj.pp_obj.pp_offset =
    838 		    (uint_t)(((uintptr_t)bp->b_un.b_addr) & MMU_PAGEOFFSET);
    839 	} else {
    840 		dmareq.dmar_object.dmao_type = DMA_OTYP_BUFVADDR;
    841 		dmareq.dmar_object.dmao_obj.virt_obj.v_addr = bp->b_un.b_addr;
    842 		if (bp->b_flags & B_SHADOW) {
    843 			dmareq.dmar_object.dmao_obj.virt_obj.v_priv =
    844 			    bp->b_shadow;
    845 		} else {
    846 			dmareq.dmar_object.dmao_obj.virt_obj.v_priv = NULL;
    847 		}
    848 
    849 		/*
    850 		 * If the buffer has no proc pointer, or the proc
    851 		 * struct has the kernel address space, or the buffer has
    852 		 * been marked B_REMAPPED (meaning that it is now
    853 		 * mapped into the kernel's address space), then
    854 		 * the address space is kas (kernel address space).
    855 		 */
    856 		if ((bp->b_proc == NULL) || (bp->b_proc->p_as == &kas) ||
    857 		    (bp->b_flags & B_REMAPPED)) {
    858 			dmareq.dmar_object.dmao_obj.virt_obj.v_as = 0;
    859 		} else {
    860 			dmareq.dmar_object.dmao_obj.virt_obj.v_as =
    861 			    bp->b_proc->p_as;
    862 		}
    863 	}
    864 
    865 	/*
    866 	 * Handle the case that the requester is both a leaf
    867 	 * and a nexus driver simultaneously by calling the
    868 	 * requester's bus_dma_map function directly instead
    869 	 * of ddi_dma_map.
    870 	 */
    871 	bop = DEVI(dip)->devi_ops->devo_bus_ops;
    872 	if (bop && bop->bus_dma_map)
    873 		funcp = bop->bus_dma_map;
    874 
    875 	return ((*funcp)(dip, dip, &dmareq, handlep));
    876 }
    877 
    878 #if !defined(__sparc)
    879 /*
    880  * Request bus_dma_ctl parent to fiddle with a dma request.
    881  *
    882  * (The sparc version is in sparc_subr.s)
    883  */
    884 int
    885 ddi_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
    886     ddi_dma_handle_t handle, enum ddi_dma_ctlops request,
    887     off_t *offp, size_t *lenp, caddr_t *objp, uint_t flags)
    888 {
    889 	int (*fp)();
    890 
    891 	if (dip != ddi_root_node())
    892 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_ctl;
    893 	fp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_ctl;
    894 	return ((*fp) (dip, rdip, handle, request, offp, lenp, objp, flags));
    895 }
    896 #endif
    897 
    898 /*
    899  * For all DMA control functions, call the DMA control
    900  * routine and return status.
    901  *
    902  * Just plain assume that the parent is to be called.
    903  * If a nexus driver or a thread outside the framework
    904  * of a nexus driver or a leaf driver calls these functions,
    905  * it is up to them to deal with the fact that the parent's
    906  * bus_dma_ctl function will be the first one called.
    907  */
    908 
    909 #define	HD	((ddi_dma_impl_t *)h)->dmai_rdip
    910 
    911 int
    912 ddi_dma_kvaddrp(ddi_dma_handle_t h, off_t off, size_t len, caddr_t *kp)
    913 {
    914 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_KVADDR, &off, &len, kp, 0));
    915 }
    916 
    917 int
    918 ddi_dma_htoc(ddi_dma_handle_t h, off_t o, ddi_dma_cookie_t *c)
    919 {
    920 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_HTOC, &o, 0, (caddr_t *)c, 0));
    921 }
    922 
    923 int
    924 ddi_dma_coff(ddi_dma_handle_t h, ddi_dma_cookie_t *c, off_t *o)
    925 {
    926 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_COFF,
    927 	    (off_t *)c, 0, (caddr_t *)o, 0));
    928 }
    929 
    930 int
    931 ddi_dma_movwin(ddi_dma_handle_t h, off_t *o, size_t *l, ddi_dma_cookie_t *c)
    932 {
    933 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_MOVWIN, o,
    934 	    l, (caddr_t *)c, 0));
    935 }
    936 
    937 int
    938 ddi_dma_curwin(ddi_dma_handle_t h, off_t *o, size_t *l)
    939 {
    940 	if ((((ddi_dma_impl_t *)h)->dmai_rflags & DDI_DMA_PARTIAL) == 0)
    941 		return (DDI_FAILURE);
    942 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_REPWIN, o, l, 0, 0));
    943 }
    944 
    945 int
    946 ddi_dma_nextwin(ddi_dma_handle_t h, ddi_dma_win_t win,
    947     ddi_dma_win_t *nwin)
    948 {
    949 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_NEXTWIN, (off_t *)&win, 0,
    950 	    (caddr_t *)nwin, 0));
    951 }
    952 
    953 int
    954 ddi_dma_nextseg(ddi_dma_win_t win, ddi_dma_seg_t seg, ddi_dma_seg_t *nseg)
    955 {
    956 	ddi_dma_handle_t h = (ddi_dma_handle_t)win;
    957 
    958 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_NEXTSEG, (off_t *)&win,
    959 	    (size_t *)&seg, (caddr_t *)nseg, 0));
    960 }
    961 
    962 #if (defined(__i386) && !defined(__amd64)) || defined(__sparc)
    963 /*
    964  * This routine is Obsolete and should be removed from ALL architectures
    965  * in a future release of Solaris.
    966  *
    967  * It is deliberately NOT ported to amd64; please fix the code that
    968  * depends on this routine to use ddi_dma_nextcookie(9F).
    969  *
    970  * NOTE: even though we fixed the pointer through a 32-bit param issue (the fix
    971  * is a side effect to some other cleanup), we're still not going to support
    972  * this interface on x64.
    973  */
    974 int
    975 ddi_dma_segtocookie(ddi_dma_seg_t seg, off_t *o, off_t *l,
    976     ddi_dma_cookie_t *cookiep)
    977 {
    978 	ddi_dma_handle_t h = (ddi_dma_handle_t)seg;
    979 
    980 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_SEGTOC, o, (size_t *)l,
    981 	    (caddr_t *)cookiep, 0));
    982 }
    983 #endif	/* (__i386 && !__amd64) || __sparc */
    984 
    985 #if !defined(__sparc)
    986 
    987 /*
    988  * The SPARC versions of these routines are done in assembler to
    989  * save register windows, so they're in sparc_subr.s.
    990  */
    991 
    992 int
    993 ddi_dma_map(dev_info_t *dip, dev_info_t *rdip,
    994 	struct ddi_dma_req *dmareqp, ddi_dma_handle_t *handlep)
    995 {
    996 	int (*funcp)(dev_info_t *, dev_info_t *, struct ddi_dma_req *,
    997 	    ddi_dma_handle_t *);
    998 
    999 	if (dip != ddi_root_node())
   1000 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_map;
   1001 
   1002 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_map;
   1003 	return ((*funcp)(dip, rdip, dmareqp, handlep));
   1004 }
   1005 
   1006 int
   1007 ddi_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
   1008     int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
   1009 {
   1010 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_attr_t *,
   1011 	    int (*)(caddr_t), caddr_t, ddi_dma_handle_t *);
   1012 
   1013 	if (dip != ddi_root_node())
   1014 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_allochdl;
   1015 
   1016 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_allochdl;
   1017 	return ((*funcp)(dip, rdip, attr, waitfp, arg, handlep));
   1018 }
   1019 
   1020 int
   1021 ddi_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handlep)
   1022 {
   1023 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_handle_t);
   1024 
   1025 	if (dip != ddi_root_node())
   1026 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_allochdl;
   1027 
   1028 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_freehdl;
   1029 	return ((*funcp)(dip, rdip, handlep));
   1030 }
   1031 
   1032 int
   1033 ddi_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
   1034     ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
   1035     ddi_dma_cookie_t *cp, uint_t *ccountp)
   1036 {
   1037 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_handle_t,
   1038 	    struct ddi_dma_req *, ddi_dma_cookie_t *, uint_t *);
   1039 
   1040 	if (dip != ddi_root_node())
   1041 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_bindhdl;
   1042 
   1043 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_bindhdl;
   1044 	return ((*funcp)(dip, rdip, handle, dmareq, cp, ccountp));
   1045 }
   1046 
   1047 int
   1048 ddi_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
   1049     ddi_dma_handle_t handle)
   1050 {
   1051 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_handle_t);
   1052 
   1053 	if (dip != ddi_root_node())
   1054 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_unbindhdl;
   1055 
   1056 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_unbindhdl;
   1057 	return ((*funcp)(dip, rdip, handle));
   1058 }
   1059 
   1060 
   1061 int
   1062 ddi_dma_flush(dev_info_t *dip, dev_info_t *rdip,
   1063     ddi_dma_handle_t handle, off_t off, size_t len,
   1064     uint_t cache_flags)
   1065 {
   1066 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_handle_t,
   1067 	    off_t, size_t, uint_t);
   1068 
   1069 	if (dip != ddi_root_node())
   1070 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_flush;
   1071 
   1072 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_flush;
   1073 	return ((*funcp)(dip, rdip, handle, off, len, cache_flags));
   1074 }
   1075 
   1076 int
   1077 ddi_dma_win(dev_info_t *dip, dev_info_t *rdip,
   1078     ddi_dma_handle_t handle, uint_t win, off_t *offp,
   1079     size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
   1080 {
   1081 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_handle_t,
   1082 	    uint_t, off_t *, size_t *, ddi_dma_cookie_t *, uint_t *);
   1083 
   1084 	if (dip != ddi_root_node())
   1085 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_win;
   1086 
   1087 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_win;
   1088 	return ((*funcp)(dip, rdip, handle, win, offp, lenp,
   1089 	    cookiep, ccountp));
   1090 }
   1091 
   1092 int
   1093 ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, uint_t whom)
   1094 {
   1095 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)h;
   1096 	dev_info_t *dip, *rdip;
   1097 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_handle_t, off_t,
   1098 	    size_t, uint_t);
   1099 
   1100 	/*
   1101 	 * the DMA nexus driver will set DMP_NOSYNC if the
   1102 	 * platform does not require any sync operation. For
   1103 	 * example if the memory is uncached or consistent
   1104 	 * and without any I/O write buffers involved.
   1105 	 */
   1106 	if ((hp->dmai_rflags & DMP_NOSYNC) == DMP_NOSYNC)
   1107 		return (DDI_SUCCESS);
   1108 
   1109 	dip = rdip = hp->dmai_rdip;
   1110 	if (dip != ddi_root_node())
   1111 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_flush;
   1112 	funcp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_flush;
   1113 	return ((*funcp)(dip, rdip, h, o, l, whom));
   1114 }
   1115 
   1116 int
   1117 ddi_dma_unbind_handle(ddi_dma_handle_t h)
   1118 {
   1119 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)h;
   1120 	dev_info_t *dip, *rdip;
   1121 	int (*funcp)(dev_info_t *, dev_info_t *, ddi_dma_handle_t);
   1122 
   1123 	dip = rdip = hp->dmai_rdip;
   1124 	if (dip != ddi_root_node())
   1125 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_unbindhdl;
   1126 	funcp = DEVI(rdip)->devi_bus_dma_unbindfunc;
   1127 	return ((*funcp)(dip, rdip, h));
   1128 }
   1129 
   1130 #endif	/* !__sparc */
   1131 
   1132 int
   1133 ddi_dma_free(ddi_dma_handle_t h)
   1134 {
   1135 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_FREE, 0, 0, 0, 0));
   1136 }
   1137 
   1138 int
   1139 ddi_iopb_alloc(dev_info_t *dip, ddi_dma_lim_t *limp, uint_t len, caddr_t *iopbp)
   1140 {
   1141 	ddi_dma_lim_t defalt;
   1142 	size_t size = len;
   1143 
   1144 	if (!limp) {
   1145 		defalt = standard_limits;
   1146 		limp = &defalt;
   1147 	}
   1148 	return (i_ddi_mem_alloc_lim(dip, limp, size, 0, 0, 0,
   1149 	    iopbp, NULL, NULL));
   1150 }
   1151 
   1152 void
   1153 ddi_iopb_free(caddr_t iopb)
   1154 {
   1155 	i_ddi_mem_free(iopb, NULL);
   1156 }
   1157 
   1158 int
   1159 ddi_mem_alloc(dev_info_t *dip, ddi_dma_lim_t *limits, uint_t length,
   1160 	uint_t flags, caddr_t *kaddrp, uint_t *real_length)
   1161 {
   1162 	ddi_dma_lim_t defalt;
   1163 	size_t size = length;
   1164 
   1165 	if (!limits) {
   1166 		defalt = standard_limits;
   1167 		limits = &defalt;
   1168 	}
   1169 	return (i_ddi_mem_alloc_lim(dip, limits, size, flags & 0x1,
   1170 	    1, 0, kaddrp, real_length, NULL));
   1171 }
   1172 
   1173 void
   1174 ddi_mem_free(caddr_t kaddr)
   1175 {
   1176 	i_ddi_mem_free(kaddr, NULL);
   1177 }
   1178 
   1179 /*
   1180  * DMA attributes, alignment, burst sizes, and transfer minimums
   1181  */
   1182 int
   1183 ddi_dma_get_attr(ddi_dma_handle_t handle, ddi_dma_attr_t *attrp)
   1184 {
   1185 	ddi_dma_impl_t *dimp = (ddi_dma_impl_t *)handle;
   1186 
   1187 	if (attrp == NULL)
   1188 		return (DDI_FAILURE);
   1189 	*attrp = dimp->dmai_attr;
   1190 	return (DDI_SUCCESS);
   1191 }
   1192 
   1193 int
   1194 ddi_dma_burstsizes(ddi_dma_handle_t handle)
   1195 {
   1196 	ddi_dma_impl_t *dimp = (ddi_dma_impl_t *)handle;
   1197 
   1198 	if (!dimp)
   1199 		return (0);
   1200 	else
   1201 		return (dimp->dmai_burstsizes);
   1202 }
   1203 
   1204 int
   1205 ddi_dma_devalign(ddi_dma_handle_t handle, uint_t *alignment, uint_t *mineffect)
   1206 {
   1207 	ddi_dma_impl_t *dimp = (ddi_dma_impl_t *)handle;
   1208 
   1209 	if (!dimp || !alignment || !mineffect)
   1210 		return (DDI_FAILURE);
   1211 	if (!(dimp->dmai_rflags & DDI_DMA_SBUS_64BIT)) {
   1212 		*alignment = 1 << ddi_ffs(dimp->dmai_burstsizes);
   1213 	} else {
   1214 		if (dimp->dmai_burstsizes & 0xff0000) {
   1215 			*alignment = 1 << ddi_ffs(dimp->dmai_burstsizes >> 16);
   1216 		} else {
   1217 			*alignment = 1 << ddi_ffs(dimp->dmai_burstsizes);
   1218 		}
   1219 	}
   1220 	*mineffect = dimp->dmai_minxfer;
   1221 	return (DDI_SUCCESS);
   1222 }
   1223 
   1224 int
   1225 ddi_iomin(dev_info_t *a, int i, int stream)
   1226 {
   1227 	int r;
   1228 
   1229 	/*
   1230 	 * Make sure that the initial value is sane
   1231 	 */
   1232 	if (i & (i - 1))
   1233 		return (0);
   1234 	if (i == 0)
   1235 		i = (stream) ? 4 : 1;
   1236 
   1237 	r = ddi_ctlops(a, a,
   1238 	    DDI_CTLOPS_IOMIN, (void *)(uintptr_t)stream, (void *)&i);
   1239 	if (r != DDI_SUCCESS || (i & (i - 1)))
   1240 		return (0);
   1241 	return (i);
   1242 }
   1243 
   1244 /*
   1245  * Given two DMA attribute structures, apply the attributes
   1246  * of one to the other, following the rules of attributes
   1247  * and the wishes of the caller.
   1248  *
   1249  * The rules of DMA attribute structures are that you cannot
   1250  * make things *less* restrictive as you apply one set
   1251  * of attributes to another.
   1252  *
   1253  */
   1254 void
   1255 ddi_dma_attr_merge(ddi_dma_attr_t *attr, ddi_dma_attr_t *mod)
   1256 {
   1257 	attr->dma_attr_addr_lo =
   1258 	    MAX(attr->dma_attr_addr_lo, mod->dma_attr_addr_lo);
   1259 	attr->dma_attr_addr_hi =
   1260 	    MIN(attr->dma_attr_addr_hi, mod->dma_attr_addr_hi);
   1261 	attr->dma_attr_count_max =
   1262 	    MIN(attr->dma_attr_count_max, mod->dma_attr_count_max);
   1263 	attr->dma_attr_align =
   1264 	    MAX(attr->dma_attr_align,  mod->dma_attr_align);
   1265 	attr->dma_attr_burstsizes =
   1266 	    (uint_t)(attr->dma_attr_burstsizes & mod->dma_attr_burstsizes);
   1267 	attr->dma_attr_minxfer =
   1268 	    maxbit(attr->dma_attr_minxfer, mod->dma_attr_minxfer);
   1269 	attr->dma_attr_maxxfer =
   1270 	    MIN(attr->dma_attr_maxxfer, mod->dma_attr_maxxfer);
   1271 	attr->dma_attr_seg = MIN(attr->dma_attr_seg, mod->dma_attr_seg);
   1272 	attr->dma_attr_sgllen = MIN((uint_t)attr->dma_attr_sgllen,
   1273 	    (uint_t)mod->dma_attr_sgllen);
   1274 	attr->dma_attr_granular =
   1275 	    MAX(attr->dma_attr_granular, mod->dma_attr_granular);
   1276 }
   1277 
   1278 /*
   1279  * mmap/segmap interface:
   1280  */
   1281 
   1282 /*
   1283  * ddi_segmap:		setup the default segment driver. Calls the drivers
   1284  *			XXmmap routine to validate the range to be mapped.
   1285  *			Return ENXIO of the range is not valid.  Create
   1286  *			a seg_dev segment that contains all of the
   1287  *			necessary information and will reference the
   1288  *			default segment driver routines. It returns zero
   1289  *			on success or non-zero on failure.
   1290  */
   1291 int
   1292 ddi_segmap(dev_t dev, off_t offset, struct as *asp, caddr_t *addrp, off_t len,
   1293     uint_t prot, uint_t maxprot, uint_t flags, cred_t *credp)
   1294 {
   1295 	extern int spec_segmap(dev_t, off_t, struct as *, caddr_t *,
   1296 	    off_t, uint_t, uint_t, uint_t, struct cred *);
   1297 
   1298 	return (spec_segmap(dev, offset, asp, addrp, len,
   1299 	    prot, maxprot, flags, credp));
   1300 }
   1301 
   1302 /*
   1303  * ddi_map_fault:	Resolve mappings at fault time.  Used by segment
   1304  *			drivers. Allows each successive parent to resolve
   1305  *			address translations and add its mappings to the
   1306  *			mapping list supplied in the page structure. It
   1307  *			returns zero on success	or non-zero on failure.
   1308  */
   1309 
   1310 int
   1311 ddi_map_fault(dev_info_t *dip, struct hat *hat, struct seg *seg,
   1312     caddr_t addr, struct devpage *dp, pfn_t pfn, uint_t prot, uint_t lock)
   1313 {
   1314 	return (i_ddi_map_fault(dip, dip, hat, seg, addr, dp, pfn, prot, lock));
   1315 }
   1316 
   1317 /*
   1318  * ddi_device_mapping_check:	Called from ddi_segmap_setup.
   1319  *	Invokes platform specific DDI to determine whether attributes specified
   1320  *	in attr(9s) are	valid for the region of memory that will be made
   1321  *	available for direct access to user process via the mmap(2) system call.
   1322  */
   1323 int
   1324 ddi_device_mapping_check(dev_t dev, ddi_device_acc_attr_t *accattrp,
   1325     uint_t rnumber, uint_t *hat_flags)
   1326 {
   1327 	ddi_acc_handle_t handle;
   1328 	ddi_map_req_t mr;
   1329 	ddi_acc_hdl_t *hp;
   1330 	int result;
   1331 	dev_info_t *dip;
   1332 
   1333 	/*
   1334 	 * we use e_ddi_hold_devi_by_dev to search for the devi.  We
   1335 	 * release it immediately since it should already be held by
   1336 	 * a devfs vnode.
   1337 	 */
   1338 	if ((dip =
   1339 	    e_ddi_hold_devi_by_dev(dev, E_DDI_HOLD_DEVI_NOATTACH)) == NULL)
   1340 		return (-1);
   1341 	ddi_release_devi(dip);		/* for e_ddi_hold_devi_by_dev() */
   1342 
   1343 	/*
   1344 	 * Allocate and initialize the common elements of data
   1345 	 * access handle.
   1346 	 */
   1347 	handle = impl_acc_hdl_alloc(KM_SLEEP, NULL);
   1348 	if (handle == NULL)
   1349 		return (-1);
   1350 
   1351 	hp = impl_acc_hdl_get(handle);
   1352 	hp->ah_vers = VERS_ACCHDL;
   1353 	hp->ah_dip = dip;
   1354 	hp->ah_rnumber = rnumber;
   1355 	hp->ah_offset = 0;
   1356 	hp->ah_len = 0;
   1357 	hp->ah_acc = *accattrp;
   1358 
   1359 	/*
   1360 	 * Set up the mapping request and call to parent.
   1361 	 */
   1362 	mr.map_op = DDI_MO_MAP_HANDLE;
   1363 	mr.map_type = DDI_MT_RNUMBER;
   1364 	mr.map_obj.rnumber = rnumber;
   1365 	mr.map_prot = PROT_READ | PROT_WRITE;
   1366 	mr.map_flags = DDI_MF_KERNEL_MAPPING;
   1367 	mr.map_handlep = hp;
   1368 	mr.map_vers = DDI_MAP_VERSION;
   1369 	result = ddi_map(dip, &mr, 0, 0, NULL);
   1370 
   1371 	/*
   1372 	 * Region must be mappable, pick up flags from the framework.
   1373 	 */
   1374 	*hat_flags = hp->ah_hat_flags;
   1375 
   1376 	impl_acc_hdl_free(handle);
   1377 
   1378 	/*
   1379 	 * check for end result.
   1380 	 */
   1381 	if (result != DDI_SUCCESS)
   1382 		return (-1);
   1383 	return (0);
   1384 }
   1385 
   1386 
   1387 /*
   1388  * Property functions:	 See also, ddipropdefs.h.
   1389  *
   1390  * These functions are the framework for the property functions,
   1391  * i.e. they support software defined properties.  All implementation
   1392  * specific property handling (i.e.: self-identifying devices and
   1393  * PROM defined properties are handled in the implementation specific
   1394  * functions (defined in ddi_implfuncs.h).
   1395  */
   1396 
   1397 /*
   1398  * nopropop:	Shouldn't be called, right?
   1399  */
   1400 int
   1401 nopropop(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
   1402     char *name, caddr_t valuep, int *lengthp)
   1403 {
   1404 	_NOTE(ARGUNUSED(dev, dip, prop_op, mod_flags, name, valuep, lengthp))
   1405 	return (DDI_PROP_NOT_FOUND);
   1406 }
   1407 
   1408 #ifdef	DDI_PROP_DEBUG
   1409 int ddi_prop_debug_flag = 0;
   1410 
   1411 int
   1412 ddi_prop_debug(int enable)
   1413 {
   1414 	int prev = ddi_prop_debug_flag;
   1415 
   1416 	if ((enable != 0) || (prev != 0))
   1417 		printf("ddi_prop_debug: debugging %s\n",
   1418 		    enable ? "enabled" : "disabled");
   1419 	ddi_prop_debug_flag = enable;
   1420 	return (prev);
   1421 }
   1422 
   1423 #endif	/* DDI_PROP_DEBUG */
   1424 
   1425 /*
   1426  * Search a property list for a match, if found return pointer
   1427  * to matching prop struct, else return NULL.
   1428  */
   1429 
   1430 ddi_prop_t *
   1431 i_ddi_prop_search(dev_t dev, char *name, uint_t flags, ddi_prop_t **list_head)
   1432 {
   1433 	ddi_prop_t	*propp;
   1434 
   1435 	/*
   1436 	 * find the property in child's devinfo:
   1437 	 * Search order defined by this search function is first matching
   1438 	 * property with input dev == DDI_DEV_T_ANY matching any dev or
   1439 	 * dev == propp->prop_dev, name == propp->name, and the correct
   1440 	 * data type as specified in the flags.  If a DDI_DEV_T_NONE dev
   1441 	 * value made it this far then it implies a DDI_DEV_T_ANY search.
   1442 	 */
   1443 	if (dev == DDI_DEV_T_NONE)
   1444 		dev = DDI_DEV_T_ANY;
   1445 
   1446 	for (propp = *list_head; propp != NULL; propp = propp->prop_next)  {
   1447 
   1448 		if (!DDI_STRSAME(propp->prop_name, name))
   1449 			continue;
   1450 
   1451 		if ((dev != DDI_DEV_T_ANY) && (propp->prop_dev != dev))
   1452 			continue;
   1453 
   1454 		if (((propp->prop_flags & flags) & DDI_PROP_TYPE_MASK) == 0)
   1455 			continue;
   1456 
   1457 		return (propp);
   1458 	}
   1459 
   1460 	return ((ddi_prop_t *)0);
   1461 }
   1462 
   1463 /*
   1464  * Search for property within devnames structures
   1465  */
   1466 ddi_prop_t *
   1467 i_ddi_search_global_prop(dev_t dev, char *name, uint_t flags)
   1468 {
   1469 	major_t		major;
   1470 	struct devnames	*dnp;
   1471 	ddi_prop_t	*propp;
   1472 
   1473 	/*
   1474 	 * Valid dev_t value is needed to index into the
   1475 	 * correct devnames entry, therefore a dev_t
   1476 	 * value of DDI_DEV_T_ANY is not appropriate.
   1477 	 */
   1478 	ASSERT(dev != DDI_DEV_T_ANY);
   1479 	if (dev == DDI_DEV_T_ANY) {
   1480 		return ((ddi_prop_t *)0);
   1481 	}
   1482 
   1483 	major = getmajor(dev);
   1484 	dnp = &(devnamesp[major]);
   1485 
   1486 	if (dnp->dn_global_prop_ptr == NULL)
   1487 		return ((ddi_prop_t *)0);
   1488 
   1489 	LOCK_DEV_OPS(&dnp->dn_lock);
   1490 
   1491 	for (propp = dnp->dn_global_prop_ptr->prop_list;
   1492 	    propp != NULL;
   1493 	    propp = (ddi_prop_t *)propp->prop_next) {
   1494 
   1495 		if (!DDI_STRSAME(propp->prop_name, name))
   1496 			continue;
   1497 
   1498 		if ((!(flags & DDI_PROP_ROOTNEX_GLOBAL)) &&
   1499 		    (!(flags & LDI_DEV_T_ANY)) && (propp->prop_dev != dev))
   1500 			continue;
   1501 
   1502 		if (((propp->prop_flags & flags) & DDI_PROP_TYPE_MASK) == 0)
   1503 			continue;
   1504 
   1505 		/* Property found, return it */
   1506 		UNLOCK_DEV_OPS(&dnp->dn_lock);
   1507 		return (propp);
   1508 	}
   1509 
   1510 	UNLOCK_DEV_OPS(&dnp->dn_lock);
   1511 	return ((ddi_prop_t *)0);
   1512 }
   1513 
   1514 static char prop_no_mem_msg[] = "can't allocate memory for ddi property <%s>";
   1515 
   1516 /*
   1517  * ddi_prop_search_global:
   1518  *	Search the global property list within devnames
   1519  *	for the named property.  Return the encoded value.
   1520  */
   1521 static int
   1522 i_ddi_prop_search_global(dev_t dev, uint_t flags, char *name,
   1523     void *valuep, uint_t *lengthp)
   1524 {
   1525 	ddi_prop_t	*propp;
   1526 	caddr_t		buffer;
   1527 
   1528 	propp =  i_ddi_search_global_prop(dev, name, flags);
   1529 
   1530 	/* Property NOT found, bail */
   1531 	if (propp == (ddi_prop_t *)0)
   1532 		return (DDI_PROP_NOT_FOUND);
   1533 
   1534 	if (propp->prop_flags & DDI_PROP_UNDEF_IT)
   1535 		return (DDI_PROP_UNDEFINED);
   1536 
   1537 	if ((buffer = kmem_alloc(propp->prop_len,
   1538 	    (flags & DDI_PROP_CANSLEEP) ? KM_SLEEP : KM_NOSLEEP)) == NULL) {
   1539 		cmn_err(CE_CONT, prop_no_mem_msg, name);
   1540 		return (DDI_PROP_NO_MEMORY);
   1541 	}
   1542 
   1543 	/*
   1544 	 * Return the encoded data
   1545 	 */
   1546 	*(caddr_t *)valuep = buffer;
   1547 	*lengthp = propp->prop_len;
   1548 	bcopy(propp->prop_val, buffer, propp->prop_len);
   1549 
   1550 	return (DDI_PROP_SUCCESS);
   1551 }
   1552 
   1553 /*
   1554  * ddi_prop_search_common:	Lookup and return the encoded value
   1555  */
   1556 int
   1557 ddi_prop_search_common(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
   1558     uint_t flags, char *name, void *valuep, uint_t *lengthp)
   1559 {
   1560 	ddi_prop_t	*propp;
   1561 	int		i;
   1562 	caddr_t		buffer;
   1563 	caddr_t		prealloc = NULL;
   1564 	int		plength = 0;
   1565 	dev_info_t	*pdip;
   1566 	int		(*bop)();
   1567 
   1568 	/*CONSTANTCONDITION*/
   1569 	while (1)  {
   1570 
   1571 		mutex_enter(&(DEVI(dip)->devi_lock));
   1572 
   1573 
   1574 		/*
   1575 		 * find the property in child's devinfo:
   1576 		 * Search order is:
   1577 		 *	1. driver defined properties
   1578 		 *	2. system defined properties
   1579 		 *	3. driver global properties
   1580 		 *	4. boot defined properties
   1581 		 */
   1582 
   1583 		propp = i_ddi_prop_search(dev, name, flags,
   1584 		    &(DEVI(dip)->devi_drv_prop_ptr));
   1585 		if (propp == NULL)  {
   1586 			propp = i_ddi_prop_search(dev, name, flags,
   1587 			    &(DEVI(dip)->devi_sys_prop_ptr));
   1588 		}
   1589 		if ((propp == NULL) && DEVI(dip)->devi_global_prop_list) {
   1590 			propp = i_ddi_prop_search(dev, name, flags,
   1591 			    &DEVI(dip)->devi_global_prop_list->prop_list);
   1592 		}
   1593 
   1594 		if (propp == NULL)  {
   1595 			propp = i_ddi_prop_search(dev, name, flags,
   1596 			    &(DEVI(dip)->devi_hw_prop_ptr));
   1597 		}
   1598 
   1599 		/*
   1600 		 * Software property found?
   1601 		 */
   1602 		if (propp != (ddi_prop_t *)0)	{
   1603 
   1604 			/*
   1605 			 * If explicit undefine, return now.
   1606 			 */
   1607 			if (propp->prop_flags & DDI_PROP_UNDEF_IT) {
   1608 				mutex_exit(&(DEVI(dip)->devi_lock));
   1609 				if (prealloc)
   1610 					kmem_free(prealloc, plength);
   1611 				return (DDI_PROP_UNDEFINED);
   1612 			}
   1613 
   1614 			/*
   1615 			 * If we only want to know if it exists, return now
   1616 			 */
   1617 			if (prop_op == PROP_EXISTS) {
   1618 				mutex_exit(&(DEVI(dip)->devi_lock));
   1619 				ASSERT(prealloc == NULL);
   1620 				return (DDI_PROP_SUCCESS);
   1621 			}
   1622 
   1623 			/*
   1624 			 * If length only request or prop length == 0,
   1625 			 * service request and return now.
   1626 			 */
   1627 			if ((prop_op == PROP_LEN) ||(propp->prop_len == 0)) {
   1628 				*lengthp = propp->prop_len;
   1629 
   1630 				/*
   1631 				 * if prop_op is PROP_LEN_AND_VAL_ALLOC
   1632 				 * that means prop_len is 0, so set valuep
   1633 				 * also to NULL
   1634 				 */
   1635 				if (prop_op == PROP_LEN_AND_VAL_ALLOC)
   1636 					*(caddr_t *)valuep = NULL;
   1637 
   1638 				mutex_exit(&(DEVI(dip)->devi_lock));
   1639 				if (prealloc)
   1640 					kmem_free(prealloc, plength);
   1641 				return (DDI_PROP_SUCCESS);
   1642 			}
   1643 
   1644 			/*
   1645 			 * If LEN_AND_VAL_ALLOC and the request can sleep,
   1646 			 * drop the mutex, allocate the buffer, and go
   1647 			 * through the loop again.  If we already allocated
   1648 			 * the buffer, and the size of the property changed,
   1649 			 * keep trying...
   1650 			 */
   1651 			if ((prop_op == PROP_LEN_AND_VAL_ALLOC) &&
   1652 			    (flags & DDI_PROP_CANSLEEP))  {
   1653 				if (prealloc && (propp->prop_len != plength)) {
   1654 					kmem_free(prealloc, plength);
   1655 					prealloc = NULL;
   1656 				}
   1657 				if (prealloc == NULL)  {
   1658 					plength = propp->prop_len;
   1659 					mutex_exit(&(DEVI(dip)->devi_lock));
   1660 					prealloc = kmem_alloc(plength,
   1661 					    KM_SLEEP);
   1662 					continue;
   1663 				}
   1664 			}
   1665 
   1666 			/*
   1667 			 * Allocate buffer, if required.  Either way,
   1668 			 * set `buffer' variable.
   1669 			 */
   1670 			i = *lengthp;			/* Get callers length */
   1671 			*lengthp = propp->prop_len;	/* Set callers length */
   1672 
   1673 			switch (prop_op) {
   1674 
   1675 			case PROP_LEN_AND_VAL_ALLOC:
   1676 
   1677 				if (prealloc == NULL) {
   1678 					buffer = kmem_alloc(propp->prop_len,
   1679 					    KM_NOSLEEP);
   1680 				} else {
   1681 					buffer = prealloc;
   1682 				}
   1683 
   1684 				if (buffer == NULL)  {
   1685 					mutex_exit(&(DEVI(dip)->devi_lock));
   1686 					cmn_err(CE_CONT, prop_no_mem_msg, name);
   1687 					return (DDI_PROP_NO_MEMORY);
   1688 				}
   1689 				/* Set callers buf ptr */
   1690 				*(caddr_t *)valuep = buffer;
   1691 				break;
   1692 
   1693 			case PROP_LEN_AND_VAL_BUF:
   1694 
   1695 				if (propp->prop_len > (i)) {
   1696 					mutex_exit(&(DEVI(dip)->devi_lock));
   1697 					return (DDI_PROP_BUF_TOO_SMALL);
   1698 				}
   1699 
   1700 				buffer = valuep;  /* Get callers buf ptr */
   1701 				break;
   1702 
   1703 			default:
   1704 				break;
   1705 			}
   1706 
   1707 			/*
   1708 			 * Do the copy.
   1709 			 */
   1710 			bcopy(propp->prop_val, buffer, propp->prop_len);
   1711 			mutex_exit(&(DEVI(dip)->devi_lock));
   1712 			return (DDI_PROP_SUCCESS);
   1713 		}
   1714 
   1715 		mutex_exit(&(DEVI(dip)->devi_lock));
   1716 		if (prealloc)
   1717 			kmem_free(prealloc, plength);
   1718 		prealloc = NULL;
   1719 
   1720 		/*
   1721 		 * Prop not found, call parent bus_ops to deal with possible
   1722 		 * h/w layer (possible PROM defined props, etc.) and to
   1723 		 * possibly ascend the hierarchy, if allowed by flags.
   1724 		 */
   1725 		pdip = (dev_info_t *)DEVI(dip)->devi_parent;
   1726 
   1727 		/*
   1728 		 * One last call for the root driver PROM props?
   1729 		 */
   1730 		if (dip == ddi_root_node())  {
   1731 			return (ddi_bus_prop_op(dev, dip, dip, prop_op,
   1732 			    flags, name, valuep, (int *)lengthp));
   1733 		}
   1734 
   1735 		/*
   1736 		 * We may have been called to check for properties
   1737 		 * within a single devinfo node that has no parent -
   1738 		 * see make_prop()
   1739 		 */
   1740 		if (pdip == NULL) {
   1741 			ASSERT((flags &
   1742 			    (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM)) ==
   1743 			    (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM));
   1744 			return (DDI_PROP_NOT_FOUND);
   1745 		}
   1746 
   1747 		/*
   1748 		 * Instead of recursing, we do iterative calls up the tree.
   1749 		 * As a bit of optimization, skip the bus_op level if the
   1750 		 * node is a s/w node and if the parent's bus_prop_op function
   1751 		 * is `ddi_bus_prop_op', because we know that in this case,
   1752 		 * this function does nothing.
   1753 		 *
   1754 		 * 4225415: If the parent isn't attached, or the child
   1755 		 * hasn't been named by the parent yet, use the default
   1756 		 * ddi_bus_prop_op as a proxy for the parent.  This
   1757 		 * allows property lookups in any child/parent state to
   1758 		 * include 'prom' and inherited properties, even when
   1759 		 * there are no drivers attached to the child or parent.
   1760 		 */
   1761 
   1762 		bop = ddi_bus_prop_op;
   1763 		if (i_ddi_devi_attached(pdip) &&
   1764 		    (i_ddi_node_state(dip) >= DS_INITIALIZED))
   1765 			bop = DEVI(pdip)->devi_ops->devo_bus_ops->bus_prop_op;
   1766 
   1767 		i = DDI_PROP_NOT_FOUND;
   1768 
   1769 		if ((bop != ddi_bus_prop_op) || ndi_dev_is_prom_node(dip)) {
   1770 			i = (*bop)(dev, pdip, dip, prop_op,
   1771 			    flags | DDI_PROP_DONTPASS,
   1772 			    name, valuep, lengthp);
   1773 		}
   1774 
   1775 		if ((flags & DDI_PROP_DONTPASS) ||
   1776 		    (i != DDI_PROP_NOT_FOUND))
   1777 			return (i);
   1778 
   1779 		dip = pdip;
   1780 	}
   1781 	/*NOTREACHED*/
   1782 }
   1783 
   1784 
   1785 /*
   1786  * ddi_prop_op: The basic property operator for drivers.
   1787  *
   1788  * In ddi_prop_op, the type of valuep is interpreted based on prop_op:
   1789  *
   1790  *	prop_op			valuep
   1791  *	------			------
   1792  *
   1793  *	PROP_LEN		<unused>
   1794  *
   1795  *	PROP_LEN_AND_VAL_BUF	Pointer to callers buffer
   1796  *
   1797  *	PROP_LEN_AND_VAL_ALLOC	Address of callers pointer (will be set to
   1798  *				address of allocated buffer, if successful)
   1799  */
   1800 int
   1801 ddi_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
   1802     char *name, caddr_t valuep, int *lengthp)
   1803 {
   1804 	int	i;
   1805 
   1806 	ASSERT((mod_flags & DDI_PROP_TYPE_MASK) == 0);
   1807 
   1808 	/*
   1809 	 * If this was originally an LDI prop lookup then we bail here.
   1810 	 * The reason is that the LDI property lookup interfaces first call
   1811 	 * a drivers prop_op() entry point to allow it to override
   1812 	 * properties.  But if we've made it here, then the driver hasn't
   1813 	 * overriden any properties.  We don't want to continue with the
   1814 	 * property search here because we don't have any type inforamtion.
   1815 	 * When we return failure, the LDI interfaces will then proceed to
   1816 	 * call the typed property interfaces to look up the property.
   1817 	 */
   1818 	if (mod_flags & DDI_PROP_DYNAMIC)
   1819 		return (DDI_PROP_NOT_FOUND);
   1820 
   1821 	/*
   1822 	 * check for pre-typed property consumer asking for typed property:
   1823 	 * see e_ddi_getprop_int64.
   1824 	 */
   1825 	if (mod_flags & DDI_PROP_CONSUMER_TYPED)
   1826 		mod_flags |= DDI_PROP_TYPE_INT64;
   1827 	mod_flags |= DDI_PROP_TYPE_ANY;
   1828 
   1829 	i = ddi_prop_search_common(dev, dip, prop_op,
   1830 	    mod_flags, name, valuep, (uint_t *)lengthp);
   1831 	if (i == DDI_PROP_FOUND_1275)
   1832 		return (DDI_PROP_SUCCESS);
   1833 	return (i);
   1834 }
   1835 
   1836 /*
   1837  * ddi_prop_op_nblocks_blksize: The basic property operator for drivers that
   1838  * maintain size in number of blksize blocks.  Provides a dynamic property
   1839  * implementation for size oriented properties based on nblocks64 and blksize
   1840  * values passed in by the driver.  Fallback to ddi_prop_op if the nblocks64
   1841  * is too large.  This interface should not be used with a nblocks64 that
   1842  * represents the driver's idea of how to represent unknown, if nblocks is
   1843  * unknown use ddi_prop_op.
   1844  */
   1845 int
   1846 ddi_prop_op_nblocks_blksize(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
   1847     int mod_flags, char *name, caddr_t valuep, int *lengthp,
   1848     uint64_t nblocks64, uint_t blksize)
   1849 {
   1850 	uint64_t size64;
   1851 	int	blkshift;
   1852 
   1853 	/* convert block size to shift value */
   1854 	ASSERT(BIT_ONLYONESET(blksize));
   1855 	blkshift = highbit(blksize) - 1;
   1856 
   1857 	/*
   1858 	 * There is no point in supporting nblocks64 values that don't have
   1859 	 * an accurate uint64_t byte count representation.
   1860 	 */
   1861 	if (nblocks64 >= (UINT64_MAX >> blkshift))
   1862 		return (ddi_prop_op(dev, dip, prop_op, mod_flags,
   1863 		    name, valuep, lengthp));
   1864 
   1865 	size64 = nblocks64 << blkshift;
   1866 	return (ddi_prop_op_size_blksize(dev, dip, prop_op, mod_flags,
   1867 	    name, valuep, lengthp, size64, blksize));
   1868 }
   1869 
   1870 /*
   1871  * ddi_prop_op_nblocks: ddi_prop_op_nblocks_blksize with DEV_BSIZE blksize.
   1872  */
   1873 int
   1874 ddi_prop_op_nblocks(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
   1875     int mod_flags, char *name, caddr_t valuep, int *lengthp, uint64_t nblocks64)
   1876 {
   1877 	return (ddi_prop_op_nblocks_blksize(dev, dip, prop_op,
   1878 	    mod_flags, name, valuep, lengthp, nblocks64, DEV_BSIZE));
   1879 }
   1880 
   1881 /*
   1882  * ddi_prop_op_size_blksize: The basic property operator for block drivers that
   1883  * maintain size in bytes. Provides a of dynamic property implementation for
   1884  * size oriented properties based on size64 value and blksize passed in by the
   1885  * driver.  Fallback to ddi_prop_op if the size64 is too large. This interface
   1886  * should not be used with a size64 that represents the driver's idea of how
   1887  * to represent unknown, if size is unknown use ddi_prop_op.
   1888  *
   1889  * NOTE: the legacy "nblocks"/"size" properties are treated as 32-bit unsigned
   1890  * integers. While the most likely interface to request them ([bc]devi_size)
   1891  * is declared int (signed) there is no enforcement of this, which means we
   1892  * can't enforce limitations here without risking regression.
   1893  */
   1894 int
   1895 ddi_prop_op_size_blksize(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
   1896     int mod_flags, char *name, caddr_t valuep, int *lengthp, uint64_t size64,
   1897     uint_t blksize)
   1898 {
   1899 	uint64_t nblocks64;
   1900 	int	callers_length;
   1901 	caddr_t	buffer;
   1902 	int	blkshift;
   1903 
   1904 	/*
   1905 	 * This is a kludge to support capture of size(9P) pure dynamic
   1906 	 * properties in snapshots for non-cmlb code (without exposing
   1907 	 * i_ddi_prop_dyn changes). When everyone uses cmlb, this code
   1908 	 * should be removed.
   1909 	 */
   1910 	if (i_ddi_prop_dyn_driver_get(dip) == NULL) {
   1911 		static i_ddi_prop_dyn_t prop_dyn_size[] = {
   1912 		    {"Size",		DDI_PROP_TYPE_INT64,	S_IFCHR},
   1913 		    {"Nblocks",		DDI_PROP_TYPE_INT64,	S_IFBLK},
   1914 		    {NULL}
   1915 		};
   1916 		i_ddi_prop_dyn_driver_set(dip, prop_dyn_size);
   1917 	}
   1918 
   1919 	/* convert block size to shift value */
   1920 	ASSERT(BIT_ONLYONESET(blksize));
   1921 	blkshift = highbit(blksize) - 1;
   1922 
   1923 	/* compute DEV_BSIZE nblocks value */
   1924 	nblocks64 = size64 >> blkshift;
   1925 
   1926 	/* get callers length, establish length of our dynamic properties */
   1927 	callers_length = *lengthp;
   1928 
   1929 	if (strcmp(name, "Nblocks") == 0)
   1930 		*lengthp = sizeof (uint64_t);
   1931 	else if (strcmp(name, "Size") == 0)
   1932 		*lengthp = sizeof (uint64_t);
   1933 	else if ((strcmp(name, "nblocks") == 0) && (nblocks64 < UINT_MAX))
   1934 		*lengthp = sizeof (uint32_t);
   1935 	else if ((strcmp(name, "size") == 0) && (size64 < UINT_MAX))
   1936 		*lengthp = sizeof (uint32_t);
   1937 	else if ((strcmp(name, "blksize") == 0) && (blksize < UINT_MAX))
   1938 		*lengthp = sizeof (uint32_t);
   1939 	else {
   1940 		/* fallback to ddi_prop_op */
   1941 		return (ddi_prop_op(dev, dip, prop_op, mod_flags,
   1942 		    name, valuep, lengthp));
   1943 	}
   1944 
   1945 	/* service request for the length of the property */
   1946 	if (prop_op == PROP_LEN)
   1947 		return (DDI_PROP_SUCCESS);
   1948 
   1949 	switch (prop_op) {
   1950 	case PROP_LEN_AND_VAL_ALLOC:
   1951 		if ((buffer = kmem_alloc(*lengthp,
   1952 		    (mod_flags & DDI_PROP_CANSLEEP) ?
   1953 		    KM_SLEEP : KM_NOSLEEP)) == NULL)
   1954 			return (DDI_PROP_NO_MEMORY);
   1955 
   1956 		*(caddr_t *)valuep = buffer;	/* set callers buf ptr */
   1957 		break;
   1958 
   1959 	case PROP_LEN_AND_VAL_BUF:
   1960 		/* the length of the property and the request must match */
   1961 		if (callers_length != *lengthp)
   1962 			return (DDI_PROP_INVAL_ARG);
   1963 
   1964 		buffer = valuep;		/* get callers buf ptr */
   1965 		break;
   1966 
   1967 	default:
   1968 		return (DDI_PROP_INVAL_ARG);
   1969 	}
   1970 
   1971 	/* transfer the value into the buffer */
   1972 	if (strcmp(name, "Nblocks") == 0)
   1973 		*((uint64_t *)buffer) = nblocks64;
   1974 	else if (strcmp(name, "Size") == 0)
   1975 		*((uint64_t *)buffer) = size64;
   1976 	else if (strcmp(name, "nblocks") == 0)
   1977 		*((uint32_t *)buffer) = (uint32_t)nblocks64;
   1978 	else if (strcmp(name, "size") == 0)
   1979 		*((uint32_t *)buffer) = (uint32_t)size64;
   1980 	else if (strcmp(name, "blksize") == 0)
   1981 		*((uint32_t *)buffer) = (uint32_t)blksize;
   1982 	return (DDI_PROP_SUCCESS);
   1983 }
   1984 
   1985 /*
   1986  * ddi_prop_op_size: ddi_prop_op_size_blksize with DEV_BSIZE block size.
   1987  */
   1988 int
   1989 ddi_prop_op_size(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
   1990     int mod_flags, char *name, caddr_t valuep, int *lengthp, uint64_t size64)
   1991 {
   1992 	return (ddi_prop_op_size_blksize(dev, dip, prop_op,
   1993 	    mod_flags, name, valuep, lengthp, size64, DEV_BSIZE));
   1994 }
   1995 
   1996 /*
   1997  * Variable length props...
   1998  */
   1999 
   2000 /*
   2001  * ddi_getlongprop:	Get variable length property len+val into a buffer
   2002  *		allocated by property provider via kmem_alloc. Requester
   2003  *		is responsible for freeing returned property via kmem_free.
   2004  *
   2005  *	Arguments:
   2006  *
   2007  *	dev_t:	Input:	dev_t of property.
   2008  *	dip:	Input:	dev_info_t pointer of child.
   2009  *	flags:	Input:	Possible flag modifiers are:
   2010  *		DDI_PROP_DONTPASS:	Don't pass to parent if prop not found.
   2011  *		DDI_PROP_CANSLEEP:	Memory allocation may sleep.
   2012  *	name:	Input:	name of property.
   2013  *	valuep:	Output:	Addr of callers buffer pointer.
   2014  *	lengthp:Output:	*lengthp will contain prop length on exit.
   2015  *
   2016  *	Possible Returns:
   2017  *
   2018  *		DDI_PROP_SUCCESS:	Prop found and returned.
   2019  *		DDI_PROP_NOT_FOUND:	Prop not found
   2020  *		DDI_PROP_UNDEFINED:	Prop explicitly undefined.
   2021  *		DDI_PROP_NO_MEMORY:	Prop found, but unable to alloc mem.
   2022  */
   2023 
   2024 int
   2025 ddi_getlongprop(dev_t dev, dev_info_t *dip, int flags,
   2026     char *name, caddr_t valuep, int *lengthp)
   2027 {
   2028 	return (ddi_prop_op(dev, dip, PROP_LEN_AND_VAL_ALLOC,
   2029 	    flags, name, valuep, lengthp));
   2030 }
   2031 
   2032 /*
   2033  *
   2034  * ddi_getlongprop_buf:		Get long prop into pre-allocated callers
   2035  *				buffer. (no memory allocation by provider).
   2036  *
   2037  *	dev_t:	Input:	dev_t of property.
   2038  *	dip:	Input:	dev_info_t pointer of child.
   2039  *	flags:	Input:	DDI_PROP_DONTPASS or NULL
   2040  *	name:	Input:	name of property
   2041  *	valuep:	Input:	ptr to callers buffer.
   2042  *	lengthp:I/O:	ptr to length of callers buffer on entry,
   2043  *			actual length of property on exit.
   2044  *
   2045  *	Possible returns:
   2046  *
   2047  *		DDI_PROP_SUCCESS	Prop found and returned
   2048  *		DDI_PROP_NOT_FOUND	Prop not found
   2049  *		DDI_PROP_UNDEFINED	Prop explicitly undefined.
   2050  *		DDI_PROP_BUF_TOO_SMALL	Prop found, callers buf too small,
   2051  *					no value returned, but actual prop
   2052  *					length returned in *lengthp
   2053  *
   2054  */
   2055 
   2056 int
   2057 ddi_getlongprop_buf(dev_t dev, dev_info_t *dip, int flags,
   2058     char *name, caddr_t valuep, int *lengthp)
   2059 {
   2060 	return (ddi_prop_op(dev, dip, PROP_LEN_AND_VAL_BUF,
   2061 	    flags, name, valuep, lengthp));
   2062 }
   2063 
   2064 /*
   2065  * Integer/boolean sized props.
   2066  *
   2067  * Call is value only... returns found boolean or int sized prop value or
   2068  * defvalue if prop not found or is wrong length or is explicitly undefined.
   2069  * Only flag is DDI_PROP_DONTPASS...
   2070  *
   2071  * By convention, this interface returns boolean (0) sized properties
   2072  * as value (int)1.
   2073  *
   2074  * This never returns an error, if property not found or specifically
   2075  * undefined, the input `defvalue' is returned.
   2076  */
   2077 
   2078 int
   2079 ddi_getprop(dev_t dev, dev_info_t *dip, int flags, char *name, int defvalue)
   2080 {
   2081 	int	propvalue = defvalue;
   2082 	int	proplength = sizeof (int);
   2083 	int	error;
   2084 
   2085 	error = ddi_prop_op(dev, dip, PROP_LEN_AND_VAL_BUF,
   2086 	    flags, name, (caddr_t)&propvalue, &proplength);
   2087 
   2088 	if ((error == DDI_PROP_SUCCESS) && (proplength == 0))
   2089 		propvalue = 1;
   2090 
   2091 	return (propvalue);
   2092 }
   2093 
   2094 /*
   2095  * Get prop length interface: flags are 0 or DDI_PROP_DONTPASS
   2096  * if returns DDI_PROP_SUCCESS, length returned in *lengthp.
   2097  */
   2098 
   2099 int
   2100 ddi_getproplen(dev_t dev, dev_info_t *dip, int flags, char *name, int *lengthp)
   2101 {
   2102 	return (ddi_prop_op(dev, dip, PROP_LEN, flags, name, NULL, lengthp));
   2103 }
   2104 
   2105 /*
   2106  * Allocate a struct prop_driver_data, along with 'size' bytes
   2107  * for decoded property data.  This structure is freed by
   2108  * calling ddi_prop_free(9F).
   2109  */
   2110 static void *
   2111 ddi_prop_decode_alloc(size_t size, void (*prop_free)(struct prop_driver_data *))
   2112 {
   2113 	struct prop_driver_data *pdd;
   2114 
   2115 	/*
   2116 	 * Allocate a structure with enough memory to store the decoded data.
   2117 	 */
   2118 	pdd = kmem_zalloc(sizeof (struct prop_driver_data) + size, KM_SLEEP);
   2119 	pdd->pdd_size = (sizeof (struct prop_driver_data) + size);
   2120 	pdd->pdd_prop_free = prop_free;
   2121 
   2122 	/*
   2123 	 * Return a pointer to the location to put the decoded data.
   2124 	 */
   2125 	return ((void *)((caddr_t)pdd + sizeof (struct prop_driver_data)));
   2126 }
   2127 
   2128 /*
   2129  * Allocated the memory needed to store the encoded data in the property
   2130  * handle.
   2131  */
   2132 static int
   2133 ddi_prop_encode_alloc(prop_handle_t *ph, size_t size)
   2134 {
   2135 	/*
   2136 	 * If size is zero, then set data to NULL and size to 0.  This
   2137 	 * is a boolean property.
   2138 	 */
   2139 	if (size == 0) {
   2140 		ph->ph_size = 0;
   2141 		ph->ph_data = NULL;
   2142 		ph->ph_cur_pos = NULL;
   2143 		ph->ph_save_pos = NULL;
   2144 	} else {
   2145 		if (ph->ph_flags == DDI_PROP_DONTSLEEP) {
   2146 			ph->ph_data = kmem_zalloc(size, KM_NOSLEEP);
   2147 			if (ph->ph_data == NULL)
   2148 				return (DDI_PROP_NO_MEMORY);
   2149 		} else
   2150 			ph->ph_data = kmem_zalloc(size, KM_SLEEP);
   2151 		ph->ph_size = size;
   2152 		ph->ph_cur_pos = ph->ph_data;
   2153 		ph->ph_save_pos = ph->ph_data;
   2154 	}
   2155 	return (DDI_PROP_SUCCESS);
   2156 }
   2157 
   2158 /*
   2159  * Free the space allocated by the lookup routines.  Each lookup routine
   2160  * returns a pointer to the decoded data to the driver.  The driver then
   2161  * passes this pointer back to us.  This data actually lives in a struct
   2162  * prop_driver_data.  We use negative indexing to find the beginning of
   2163  * the structure and then free the entire structure using the size and
   2164  * the free routine stored in the structure.
   2165  */
   2166 void
   2167 ddi_prop_free(void *datap)
   2168 {
   2169 	struct prop_driver_data *pdd;
   2170 
   2171 	/*
   2172 	 * Get the structure
   2173 	 */
   2174 	pdd = (struct prop_driver_data *)
   2175 	    ((caddr_t)datap - sizeof (struct prop_driver_data));
   2176 	/*
   2177 	 * Call the free routine to free it
   2178 	 */
   2179 	(*pdd->pdd_prop_free)(pdd);
   2180 }
   2181 
   2182 /*
   2183  * Free the data associated with an array of ints,
   2184  * allocated with ddi_prop_decode_alloc().
   2185  */
   2186 static void
   2187 ddi_prop_free_ints(struct prop_driver_data *pdd)
   2188 {
   2189 	kmem_free(pdd, pdd->pdd_size);
   2190 }
   2191 
   2192 /*
   2193  * Free a single string property or a single string contained within
   2194  * the argv style return value of an array of strings.
   2195  */
   2196 static void
   2197 ddi_prop_free_string(struct prop_driver_data *pdd)
   2198 {
   2199 	kmem_free(pdd, pdd->pdd_size);
   2200 
   2201 }
   2202 
   2203 /*
   2204  * Free an array of strings.
   2205  */
   2206 static void
   2207 ddi_prop_free_strings(struct prop_driver_data *pdd)
   2208 {
   2209 	kmem_free(pdd, pdd->pdd_size);
   2210 }
   2211 
   2212 /*
   2213  * Free the data associated with an array of bytes.
   2214  */
   2215 static void
   2216 ddi_prop_free_bytes(struct prop_driver_data *pdd)
   2217 {
   2218 	kmem_free(pdd, pdd->pdd_size);
   2219 }
   2220 
   2221 /*
   2222  * Reset the current location pointer in the property handle to the
   2223  * beginning of the data.
   2224  */
   2225 void
   2226 ddi_prop_reset_pos(prop_handle_t *ph)
   2227 {
   2228 	ph->ph_cur_pos = ph->ph_data;
   2229 	ph->ph_save_pos = ph->ph_data;
   2230 }
   2231 
   2232 /*
   2233  * Restore the current location pointer in the property handle to the
   2234  * saved position.
   2235  */
   2236 void
   2237 ddi_prop_save_pos(prop_handle_t *ph)
   2238 {
   2239 	ph->ph_save_pos = ph->ph_cur_pos;
   2240 }
   2241 
   2242 /*
   2243  * Save the location that the current location pointer is pointing to..
   2244  */
   2245 void
   2246 ddi_prop_restore_pos(prop_handle_t *ph)
   2247 {
   2248 	ph->ph_cur_pos = ph->ph_save_pos;
   2249 }
   2250 
   2251 /*
   2252  * Property encode/decode functions
   2253  */
   2254 
   2255 /*
   2256  * Decode a single integer property
   2257  */
   2258 static int
   2259 ddi_prop_fm_decode_int(prop_handle_t *ph, void *data, uint_t *nelements)
   2260 {
   2261 	int	i;
   2262 	int	tmp;
   2263 
   2264 	/*
   2265 	 * If there is nothing to decode return an error
   2266 	 */
   2267 	if (ph->ph_size == 0)
   2268 		return (DDI_PROP_END_OF_DATA);
   2269 
   2270 	/*
   2271 	 * Decode the property as a single integer and return it
   2272 	 * in data if we were able to decode it.
   2273 	 */
   2274 	i = DDI_PROP_INT(ph, DDI_PROP_CMD_DECODE, &tmp);
   2275 	if (i < DDI_PROP_RESULT_OK) {
   2276 		switch (i) {
   2277 		case DDI_PROP_RESULT_EOF:
   2278 			return (DDI_PROP_END_OF_DATA);
   2279 
   2280 		case DDI_PROP_RESULT_ERROR:
   2281 			return (DDI_PROP_CANNOT_DECODE);
   2282 		}
   2283 	}
   2284 
   2285 	*(int *)data = tmp;
   2286 	*nelements = 1;
   2287 	return (DDI_PROP_SUCCESS);
   2288 }
   2289 
   2290 /*
   2291  * Decode a single 64 bit integer property
   2292  */
   2293 static int
   2294 ddi_prop_fm_decode_int64(prop_handle_t *ph, void *data, uint_t *nelements)
   2295 {
   2296 	int	i;
   2297 	int64_t	tmp;
   2298 
   2299 	/*
   2300 	 * If there is nothing to decode return an error
   2301 	 */
   2302 	if (ph->ph_size == 0)
   2303 		return (DDI_PROP_END_OF_DATA);
   2304 
   2305 	/*
   2306 	 * Decode the property as a single integer and return it
   2307 	 * in data if we were able to decode it.
   2308 	 */
   2309 	i = DDI_PROP_INT64(ph, DDI_PROP_CMD_DECODE, &tmp);
   2310 	if (i < DDI_PROP_RESULT_OK) {
   2311 		switch (i) {
   2312 		case DDI_PROP_RESULT_EOF:
   2313 			return (DDI_PROP_END_OF_DATA);
   2314 
   2315 		case DDI_PROP_RESULT_ERROR:
   2316 			return (DDI_PROP_CANNOT_DECODE);
   2317 		}
   2318 	}
   2319 
   2320 	*(int64_t *)data = tmp;
   2321 	*nelements = 1;
   2322 	return (DDI_PROP_SUCCESS);
   2323 }
   2324 
   2325 /*
   2326  * Decode an array of integers property
   2327  */
   2328 static int
   2329 ddi_prop_fm_decode_ints(prop_handle_t *ph, void *data, uint_t *nelements)
   2330 {
   2331 	int	i;
   2332 	int	cnt = 0;
   2333 	int	*tmp;
   2334 	int	*intp;
   2335 	int	n;
   2336 
   2337 	/*
   2338 	 * Figure out how many array elements there are by going through the
   2339 	 * data without decoding it first and counting.
   2340 	 */
   2341 	for (;;) {
   2342 		i = DDI_PROP_INT(ph, DDI_PROP_CMD_SKIP, NULL);
   2343 		if (i < 0)
   2344 			break;
   2345 		cnt++;
   2346 	}
   2347 
   2348 	/*
   2349 	 * If there are no elements return an error
   2350 	 */
   2351 	if (cnt == 0)
   2352 		return (DDI_PROP_END_OF_DATA);
   2353 
   2354 	/*
   2355 	 * If we cannot skip through the data, we cannot decode it
   2356 	 */
   2357 	if (i == DDI_PROP_RESULT_ERROR)
   2358 		return (DDI_PROP_CANNOT_DECODE);
   2359 
   2360 	/*
   2361 	 * Reset the data pointer to the beginning of the encoded data
   2362 	 */
   2363 	ddi_prop_reset_pos(ph);
   2364 
   2365 	/*
   2366 	 * Allocated memory to store the decoded value in.
   2367 	 */
   2368 	intp = ddi_prop_decode_alloc((cnt * sizeof (int)),
   2369 	    ddi_prop_free_ints);
   2370 
   2371 	/*
   2372 	 * Decode each element and place it in the space we just allocated
   2373 	 */
   2374 	tmp = intp;
   2375 	for (n = 0; n < cnt; n++, tmp++) {
   2376 		i = DDI_PROP_INT(ph, DDI_PROP_CMD_DECODE, tmp);
   2377 		if (i < DDI_PROP_RESULT_OK) {
   2378 			/*
   2379 			 * Free the space we just allocated
   2380 			 * and return an error.
   2381 			 */
   2382 			ddi_prop_free(intp);
   2383 			switch (i) {
   2384 			case DDI_PROP_RESULT_EOF:
   2385 				return (DDI_PROP_END_OF_DATA);
   2386 
   2387 			case DDI_PROP_RESULT_ERROR:
   2388 				return (DDI_PROP_CANNOT_DECODE);
   2389 			}
   2390 		}
   2391 	}
   2392 
   2393 	*nelements = cnt;
   2394 	*(int **)data = intp;
   2395 
   2396 	return (DDI_PROP_SUCCESS);
   2397 }
   2398 
   2399 /*
   2400  * Decode a 64 bit integer array property
   2401  */
   2402 static int
   2403 ddi_prop_fm_decode_int64_array(prop_handle_t *ph, void *data, uint_t *nelements)
   2404 {
   2405 	int	i;
   2406 	int	n;
   2407 	int	cnt = 0;
   2408 	int64_t	*tmp;
   2409 	int64_t	*intp;
   2410 
   2411 	/*
   2412 	 * Count the number of array elements by going
   2413 	 * through the data without decoding it.
   2414 	 */
   2415 	for (;;) {
   2416 		i = DDI_PROP_INT64(ph, DDI_PROP_CMD_SKIP, NULL);
   2417 		if (i < 0)
   2418 			break;
   2419 		cnt++;
   2420 	}
   2421 
   2422 	/*
   2423 	 * If there are no elements return an error
   2424 	 */
   2425 	if (cnt == 0)
   2426 		return (DDI_PROP_END_OF_DATA);
   2427 
   2428 	/*
   2429 	 * If we cannot skip through the data, we cannot decode it
   2430 	 */
   2431 	if (i == DDI_PROP_RESULT_ERROR)
   2432 		return (DDI_PROP_CANNOT_DECODE);
   2433 
   2434 	/*
   2435 	 * Reset the data pointer to the beginning of the encoded data
   2436 	 */
   2437 	ddi_prop_reset_pos(ph);
   2438 
   2439 	/*
   2440 	 * Allocate memory to store the decoded value.
   2441 	 */
   2442 	intp = ddi_prop_decode_alloc((cnt * sizeof (int64_t)),
   2443 	    ddi_prop_free_ints);
   2444 
   2445 	/*
   2446 	 * Decode each element and place it in the space allocated
   2447 	 */
   2448 	tmp = intp;
   2449 	for (n = 0; n < cnt; n++, tmp++) {
   2450 		i = DDI_PROP_INT64(ph, DDI_PROP_CMD_DECODE, tmp);
   2451 		if (i < DDI_PROP_RESULT_OK) {
   2452 			/*
   2453 			 * Free the space we just allocated
   2454 			 * and return an error.
   2455 			 */
   2456 			ddi_prop_free(intp);
   2457 			switch (i) {
   2458 			case DDI_PROP_RESULT_EOF:
   2459 				return (DDI_PROP_END_OF_DATA);
   2460 
   2461 			case DDI_PROP_RESULT_ERROR:
   2462 				return (DDI_PROP_CANNOT_DECODE);
   2463 			}
   2464 		}
   2465 	}
   2466 
   2467 	*nelements = cnt;
   2468 	*(int64_t **)data = intp;
   2469 
   2470 	return (DDI_PROP_SUCCESS);
   2471 }
   2472 
   2473 /*
   2474  * Encode an array of integers property (Can be one element)
   2475  */
   2476 int
   2477 ddi_prop_fm_encode_ints(prop_handle_t *ph, void *data, uint_t nelements)
   2478 {
   2479 	int	i;
   2480 	int	*tmp;
   2481 	int	cnt;
   2482 	int	size;
   2483 
   2484 	/*
   2485 	 * If there is no data, we cannot do anything
   2486 	 */
   2487 	if (nelements == 0)
   2488 		return (DDI_PROP_CANNOT_ENCODE);
   2489 
   2490 	/*
   2491 	 * Get the size of an encoded int.
   2492 	 */
   2493 	size = DDI_PROP_INT(ph, DDI_PROP_CMD_GET_ESIZE, NULL);
   2494 
   2495 	if (size < DDI_PROP_RESULT_OK) {
   2496 		switch (size) {
   2497 		case DDI_PROP_RESULT_EOF:
   2498 			return (DDI_PROP_END_OF_DATA);
   2499 
   2500 		case DDI_PROP_RESULT_ERROR:
   2501 			return (DDI_PROP_CANNOT_ENCODE);
   2502 		}
   2503 	}
   2504 
   2505 	/*
   2506 	 * Allocate space in the handle to store the encoded int.
   2507 	 */
   2508 	if (ddi_prop_encode_alloc(ph, size * nelements) !=
   2509 	    DDI_PROP_SUCCESS)
   2510 		return (DDI_PROP_NO_MEMORY);
   2511 
   2512 	/*
   2513 	 * Encode the array of ints.
   2514 	 */
   2515 	tmp = (int *)data;
   2516 	for (cnt = 0; cnt < nelements; cnt++, tmp++) {
   2517 		i = DDI_PROP_INT(ph, DDI_PROP_CMD_ENCODE, tmp);
   2518 		if (i < DDI_PROP_RESULT_OK) {
   2519 			switch (i) {
   2520 			case DDI_PROP_RESULT_EOF:
   2521 				return (DDI_PROP_END_OF_DATA);
   2522 
   2523 			case DDI_PROP_RESULT_ERROR:
   2524 				return (DDI_PROP_CANNOT_ENCODE);
   2525 			}
   2526 		}
   2527 	}
   2528 
   2529 	return (DDI_PROP_SUCCESS);
   2530 }
   2531 
   2532 
   2533 /*
   2534  * Encode a 64 bit integer array property
   2535  */
   2536 int
   2537 ddi_prop_fm_encode_int64(prop_handle_t *ph, void *data, uint_t nelements)
   2538 {
   2539 	int i;
   2540 	int cnt;
   2541 	int size;
   2542 	int64_t *tmp;
   2543 
   2544 	/*
   2545 	 * If there is no data, we cannot do anything
   2546 	 */
   2547 	if (nelements == 0)
   2548 		return (DDI_PROP_CANNOT_ENCODE);
   2549 
   2550 	/*
   2551 	 * Get the size of an encoded 64 bit int.
   2552 	 */
   2553 	size = DDI_PROP_INT64(ph, DDI_PROP_CMD_GET_ESIZE, NULL);
   2554 
   2555 	if (size < DDI_PROP_RESULT_OK) {
   2556 		switch (size) {
   2557 		case DDI_PROP_RESULT_EOF:
   2558 			return (DDI_PROP_END_OF_DATA);
   2559 
   2560 		case DDI_PROP_RESULT_ERROR:
   2561 			return (DDI_PROP_CANNOT_ENCODE);
   2562 		}
   2563 	}
   2564 
   2565 	/*
   2566 	 * Allocate space in the handle to store the encoded int.
   2567 	 */
   2568 	if (ddi_prop_encode_alloc(ph, size * nelements) !=
   2569 	    DDI_PROP_SUCCESS)
   2570 		return (DDI_PROP_NO_MEMORY);
   2571 
   2572 	/*
   2573 	 * Encode the array of ints.
   2574 	 */
   2575 	tmp = (int64_t *)data;
   2576 	for (cnt = 0; cnt < nelements; cnt++, tmp++) {
   2577 		i = DDI_PROP_INT64(ph, DDI_PROP_CMD_ENCODE, tmp);
   2578 		if (i < DDI_PROP_RESULT_OK) {
   2579 			switch (i) {
   2580 			case DDI_PROP_RESULT_EOF:
   2581 				return (DDI_PROP_END_OF_DATA);
   2582 
   2583 			case DDI_PROP_RESULT_ERROR:
   2584 				return (DDI_PROP_CANNOT_ENCODE);
   2585 			}
   2586 		}
   2587 	}
   2588 
   2589 	return (DDI_PROP_SUCCESS);
   2590 }
   2591 
   2592 /*
   2593  * Decode a single string property
   2594  */
   2595 static int
   2596 ddi_prop_fm_decode_string(prop_handle_t *ph, void *data, uint_t *nelements)
   2597 {
   2598 	char		*tmp;
   2599 	char		*str;
   2600 	int		i;
   2601 	int		size;
   2602 
   2603 	/*
   2604 	 * If there is nothing to decode return an error
   2605 	 */
   2606 	if (ph->ph_size == 0)
   2607 		return (DDI_PROP_END_OF_DATA);
   2608 
   2609 	/*
   2610 	 * Get the decoded size of the encoded string.
   2611 	 */
   2612 	size = DDI_PROP_STR(ph, DDI_PROP_CMD_GET_DSIZE, NULL);
   2613 	if (size < DDI_PROP_RESULT_OK) {
   2614 		switch (size) {
   2615 		case DDI_PROP_RESULT_EOF:
   2616 			return (DDI_PROP_END_OF_DATA);
   2617 
   2618 		case DDI_PROP_RESULT_ERROR:
   2619 			return (DDI_PROP_CANNOT_DECODE);
   2620 		}
   2621 	}
   2622 
   2623 	/*
   2624 	 * Allocated memory to store the decoded value in.
   2625 	 */
   2626 	str = ddi_prop_decode_alloc((size_t)size, ddi_prop_free_string);
   2627 
   2628 	ddi_prop_reset_pos(ph);
   2629 
   2630 	/*
   2631 	 * Decode the str and place it in the space we just allocated
   2632 	 */
   2633 	tmp = str;
   2634 	i = DDI_PROP_STR(ph, DDI_PROP_CMD_DECODE, tmp);
   2635 	if (i < DDI_PROP_RESULT_OK) {
   2636 		/*
   2637 		 * Free the space we just allocated
   2638 		 * and return an error.
   2639 		 */
   2640 		ddi_prop_free(str);
   2641 		switch (i) {
   2642 		case DDI_PROP_RESULT_EOF:
   2643 			return (DDI_PROP_END_OF_DATA);
   2644 
   2645 		case DDI_PROP_RESULT_ERROR:
   2646 			return (DDI_PROP_CANNOT_DECODE);
   2647 		}
   2648 	}
   2649 
   2650 	*(char **)data = str;
   2651 	*nelements = 1;
   2652 
   2653 	return (DDI_PROP_SUCCESS);
   2654 }
   2655 
   2656 /*
   2657  * Decode an array of strings.
   2658  */
   2659 int
   2660 ddi_prop_fm_decode_strings(prop_handle_t *ph, void *data, uint_t *nelements)
   2661 {
   2662 	int		cnt = 0;
   2663 	char		**strs;
   2664 	char		**tmp;
   2665 	char		*ptr;
   2666 	int		i;
   2667 	int		n;
   2668 	int		size;
   2669 	size_t		nbytes;
   2670 
   2671 	/*
   2672 	 * Figure out how many array elements there are by going through the
   2673 	 * data without decoding it first and counting.
   2674 	 */
   2675 	for (;;) {
   2676 		i = DDI_PROP_STR(ph, DDI_PROP_CMD_SKIP, NULL);
   2677 		if (i < 0)
   2678 			break;
   2679 		cnt++;
   2680 	}
   2681 
   2682 	/*
   2683 	 * If there are no elements return an error
   2684 	 */
   2685 	if (cnt == 0)
   2686 		return (DDI_PROP_END_OF_DATA);
   2687 
   2688 	/*
   2689 	 * If we cannot skip through the data, we cannot decode it
   2690 	 */
   2691 	if (i == DDI_PROP_RESULT_ERROR)
   2692 		return (DDI_PROP_CANNOT_DECODE);
   2693 
   2694 	/*
   2695 	 * Reset the data pointer to the beginning of the encoded data
   2696 	 */
   2697 	ddi_prop_reset_pos(ph);
   2698 
   2699 	/*
   2700 	 * Figure out how much memory we need for the sum total
   2701 	 */
   2702 	nbytes = (cnt + 1) * sizeof (char *);
   2703 
   2704 	for (n = 0; n < cnt; n++) {
   2705 		/*
   2706 		 * Get the decoded size of the current encoded string.
   2707 		 */
   2708 		size = DDI_PROP_STR(ph, DDI_PROP_CMD_GET_DSIZE, NULL);
   2709 		if (size < DDI_PROP_RESULT_OK) {
   2710 			switch (size) {
   2711 			case DDI_PROP_RESULT_EOF:
   2712 				return (DDI_PROP_END_OF_DATA);
   2713 
   2714 			case DDI_PROP_RESULT_ERROR:
   2715 				return (DDI_PROP_CANNOT_DECODE);
   2716 			}
   2717 		}
   2718 
   2719 		nbytes += size;
   2720 	}
   2721 
   2722 	/*
   2723 	 * Allocate memory in which to store the decoded strings.
   2724 	 */
   2725 	strs = ddi_prop_decode_alloc(nbytes, ddi_prop_free_strings);
   2726 
   2727 	/*
   2728 	 * Set up pointers for each string by figuring out yet
   2729 	 * again how long each string is.
   2730 	 */
   2731 	ddi_prop_reset_pos(ph);
   2732 	ptr = (caddr_t)strs + ((cnt + 1) * sizeof (char *));
   2733 	for (tmp = strs, n = 0; n < cnt; n++, tmp++) {
   2734 		/*
   2735 		 * Get the decoded size of the current encoded string.
   2736 		 */
   2737 		size = DDI_PROP_STR(ph, DDI_PROP_CMD_GET_DSIZE, NULL);
   2738 		if (size < DDI_PROP_RESULT_OK) {
   2739 			ddi_prop_free(strs);
   2740 			switch (size) {
   2741 			case DDI_PROP_RESULT_EOF:
   2742 				return (DDI_PROP_END_OF_DATA);
   2743 
   2744 			case DDI_PROP_RESULT_ERROR:
   2745 				return (DDI_PROP_CANNOT_DECODE);
   2746 			}
   2747 		}
   2748 
   2749 		*tmp = ptr;
   2750 		ptr += size;
   2751 	}
   2752 
   2753 	/*
   2754 	 * String array is terminated by a NULL
   2755 	 */
   2756 	*tmp = NULL;
   2757 
   2758 	/*
   2759 	 * Finally, we can decode each string
   2760 	 */
   2761 	ddi_prop_reset_pos(ph);
   2762 	for (tmp = strs, n = 0; n < cnt; n++, tmp++) {
   2763 		i = DDI_PROP_STR(ph, DDI_PROP_CMD_DECODE, *tmp);
   2764 		if (i < DDI_PROP_RESULT_OK) {
   2765 			/*
   2766 			 * Free the space we just allocated
   2767 			 * and return an error
   2768 			 */
   2769 			ddi_prop_free(strs);
   2770 			switch (i) {
   2771 			case DDI_PROP_RESULT_EOF:
   2772 				return (DDI_PROP_END_OF_DATA);
   2773 
   2774 			case DDI_PROP_RESULT_ERROR:
   2775 				return (DDI_PROP_CANNOT_DECODE);
   2776 			}
   2777 		}
   2778 	}
   2779 
   2780 	*(char ***)data = strs;
   2781 	*nelements = cnt;
   2782 
   2783 	return (DDI_PROP_SUCCESS);
   2784 }
   2785 
   2786 /*
   2787  * Encode a string.
   2788  */
   2789 int
   2790 ddi_prop_fm_encode_string(prop_handle_t *ph, void *data, uint_t nelements)
   2791 {
   2792 	char		**tmp;
   2793 	int		size;
   2794 	int		i;
   2795 
   2796 	/*
   2797 	 * If there is no data, we cannot do anything
   2798 	 */
   2799 	if (nelements == 0)
   2800 		return (DDI_PROP_CANNOT_ENCODE);
   2801 
   2802 	/*
   2803 	 * Get the size of the encoded string.
   2804 	 */
   2805 	tmp = (char **)data;
   2806 	size = DDI_PROP_STR(ph, DDI_PROP_CMD_GET_ESIZE, *tmp);
   2807 	if (size < DDI_PROP_RESULT_OK) {
   2808 		switch (size) {
   2809 		case DDI_PROP_RESULT_EOF:
   2810 			return (DDI_PROP_END_OF_DATA);
   2811 
   2812 		case DDI_PROP_RESULT_ERROR:
   2813 			return (DDI_PROP_CANNOT_ENCODE);
   2814 		}
   2815 	}
   2816 
   2817 	/*
   2818 	 * Allocate space in the handle to store the encoded string.
   2819 	 */
   2820 	if (ddi_prop_encode_alloc(ph, size) != DDI_PROP_SUCCESS)
   2821 		return (DDI_PROP_NO_MEMORY);
   2822 
   2823 	ddi_prop_reset_pos(ph);
   2824 
   2825 	/*
   2826 	 * Encode the string.
   2827 	 */
   2828 	tmp = (char **)data;
   2829 	i = DDI_PROP_STR(ph, DDI_PROP_CMD_ENCODE, *tmp);
   2830 	if (i < DDI_PROP_RESULT_OK) {
   2831 		switch (i) {
   2832 		case DDI_PROP_RESULT_EOF:
   2833 			return (DDI_PROP_END_OF_DATA);
   2834 
   2835 		case DDI_PROP_RESULT_ERROR:
   2836 			return (DDI_PROP_CANNOT_ENCODE);
   2837 		}
   2838 	}
   2839 
   2840 	return (DDI_PROP_SUCCESS);
   2841 }
   2842 
   2843 
   2844 /*
   2845  * Encode an array of strings.
   2846  */
   2847 int
   2848 ddi_prop_fm_encode_strings(prop_handle_t *ph, void *data, uint_t nelements)
   2849 {
   2850 	int		cnt = 0;
   2851 	char		**tmp;
   2852 	int		size;
   2853 	uint_t		total_size;
   2854 	int		i;
   2855 
   2856 	/*
   2857 	 * If there is no data, we cannot do anything
   2858 	 */
   2859 	if (nelements == 0)
   2860 		return (DDI_PROP_CANNOT_ENCODE);
   2861 
   2862 	/*
   2863 	 * Get the total size required to encode all the strings.
   2864 	 */
   2865 	total_size = 0;
   2866 	tmp = (char **)data;
   2867 	for (cnt = 0; cnt < nelements; cnt++, tmp++) {
   2868 		size = DDI_PROP_STR(ph, DDI_PROP_CMD_GET_ESIZE, *tmp);
   2869 		if (size < DDI_PROP_RESULT_OK) {
   2870 			switch (size) {
   2871 			case DDI_PROP_RESULT_EOF:
   2872 				return (DDI_PROP_END_OF_DATA);
   2873 
   2874 			case DDI_PROP_RESULT_ERROR:
   2875 				return (DDI_PROP_CANNOT_ENCODE);
   2876 			}
   2877 		}
   2878 		total_size += (uint_t)size;
   2879 	}
   2880 
   2881 	/*
   2882 	 * Allocate space in the handle to store the encoded strings.
   2883 	 */
   2884 	if (ddi_prop_encode_alloc(ph, total_size) != DDI_PROP_SUCCESS)
   2885 		return (DDI_PROP_NO_MEMORY);
   2886 
   2887 	ddi_prop_reset_pos(ph);
   2888 
   2889 	/*
   2890 	 * Encode the array of strings.
   2891 	 */
   2892 	tmp = (char **)data;
   2893 	for (cnt = 0; cnt < nelements; cnt++, tmp++) {
   2894 		i = DDI_PROP_STR(ph, DDI_PROP_CMD_ENCODE, *tmp);
   2895 		if (i < DDI_PROP_RESULT_OK) {
   2896 			switch (i) {
   2897 			case DDI_PROP_RESULT_EOF:
   2898 				return (DDI_PROP_END_OF_DATA);
   2899 
   2900 			case DDI_PROP_RESULT_ERROR:
   2901 				return (DDI_PROP_CANNOT_ENCODE);
   2902 			}
   2903 		}
   2904 	}
   2905 
   2906 	return (DDI_PROP_SUCCESS);
   2907 }
   2908 
   2909 
   2910 /*
   2911  * Decode an array of bytes.
   2912  */
   2913 static int
   2914 ddi_prop_fm_decode_bytes(prop_handle_t *ph, void *data, uint_t *nelements)
   2915 {
   2916 	uchar_t		*tmp;
   2917 	int		nbytes;
   2918 	int		i;
   2919 
   2920 	/*
   2921 	 * If there are no elements return an error
   2922 	 */
   2923 	if (ph->ph_size == 0)
   2924 		return (DDI_PROP_END_OF_DATA);
   2925 
   2926 	/*
   2927 	 * Get the size of the encoded array of bytes.
   2928 	 */
   2929 	nbytes = DDI_PROP_BYTES(ph, DDI_PROP_CMD_GET_DSIZE,
   2930 	    data, ph->ph_size);
   2931 	if (nbytes < DDI_PROP_RESULT_OK) {
   2932 		switch (nbytes) {
   2933 		case DDI_PROP_RESULT_EOF:
   2934 			return (DDI_PROP_END_OF_DATA);
   2935 
   2936 		case DDI_PROP_RESULT_ERROR:
   2937 			return (DDI_PROP_CANNOT_DECODE);
   2938 		}
   2939 	}
   2940 
   2941 	/*
   2942 	 * Allocated memory to store the decoded value in.
   2943 	 */
   2944 	tmp = ddi_prop_decode_alloc(nbytes, ddi_prop_free_bytes);
   2945 
   2946 	/*
   2947 	 * Decode each element and place it in the space we just allocated
   2948 	 */
   2949 	i = DDI_PROP_BYTES(ph, DDI_PROP_CMD_DECODE, tmp, nbytes);
   2950 	if (i < DDI_PROP_RESULT_OK) {
   2951 		/*
   2952 		 * Free the space we just allocated
   2953 		 * and return an error
   2954 		 */
   2955 		ddi_prop_free(tmp);
   2956 		switch (i) {
   2957 		case DDI_PROP_RESULT_EOF:
   2958 			return (DDI_PROP_END_OF_DATA);
   2959 
   2960 		case DDI_PROP_RESULT_ERROR:
   2961 			return (DDI_PROP_CANNOT_DECODE);
   2962 		}
   2963 	}
   2964 
   2965 	*(uchar_t **)data = tmp;
   2966 	*nelements = nbytes;
   2967 
   2968 	return (DDI_PROP_SUCCESS);
   2969 }
   2970 
   2971 /*
   2972  * Encode an array of bytes.
   2973  */
   2974 int
   2975 ddi_prop_fm_encode_bytes(prop_handle_t *ph, void *data, uint_t nelements)
   2976 {
   2977 	int		size;
   2978 	int		i;
   2979 
   2980 	/*
   2981 	 * If there are no elements, then this is a boolean property,
   2982 	 * so just create a property handle with no data and return.
   2983 	 */
   2984 	if (nelements == 0) {
   2985 		(void) ddi_prop_encode_alloc(ph, 0);
   2986 		return (DDI_PROP_SUCCESS);
   2987 	}
   2988 
   2989 	/*
   2990 	 * Get the size of the encoded array of bytes.
   2991 	 */
   2992 	size = DDI_PROP_BYTES(ph, DDI_PROP_CMD_GET_ESIZE, (uchar_t *)data,
   2993 	    nelements);
   2994 	if (size < DDI_PROP_RESULT_OK) {
   2995 		switch (size) {
   2996 		case DDI_PROP_RESULT_EOF:
   2997 			return (DDI_PROP_END_OF_DATA);
   2998 
   2999 		case DDI_PROP_RESULT_ERROR:
   3000 			return (DDI_PROP_CANNOT_DECODE);
   3001 		}
   3002 	}
   3003 
   3004 	/*
   3005 	 * Allocate space in the handle to store the encoded bytes.
   3006 	 */
   3007 	if (ddi_prop_encode_alloc(ph, (uint_t)size) != DDI_PROP_SUCCESS)
   3008 		return (DDI_PROP_NO_MEMORY);
   3009 
   3010 	/*
   3011 	 * Encode the array of bytes.
   3012 	 */
   3013 	i = DDI_PROP_BYTES(ph, DDI_PROP_CMD_ENCODE, (uchar_t *)data,
   3014 	    nelements);
   3015 	if (i < DDI_PROP_RESULT_OK) {
   3016 		switch (i) {
   3017 		case DDI_PROP_RESULT_EOF:
   3018 			return (DDI_PROP_END_OF_DATA);
   3019 
   3020 		case DDI_PROP_RESULT_ERROR:
   3021 			return (DDI_PROP_CANNOT_ENCODE);
   3022 		}
   3023 	}
   3024 
   3025 	return (DDI_PROP_SUCCESS);
   3026 }
   3027 
   3028 /*
   3029  * OBP 1275 integer, string and byte operators.
   3030  *
   3031  * DDI_PROP_CMD_DECODE:
   3032  *
   3033  *	DDI_PROP_RESULT_ERROR:		cannot decode the data
   3034  *	DDI_PROP_RESULT_EOF:		end of data
   3035  *	DDI_PROP_OK:			data was decoded
   3036  *
   3037  * DDI_PROP_CMD_ENCODE:
   3038  *
   3039  *	DDI_PROP_RESULT_ERROR:		cannot encode the data
   3040  *	DDI_PROP_RESULT_EOF:		end of data
   3041  *	DDI_PROP_OK:			data was encoded
   3042  *
   3043  * DDI_PROP_CMD_SKIP:
   3044  *
   3045  *	DDI_PROP_RESULT_ERROR:		cannot skip the data
   3046  *	DDI_PROP_RESULT_EOF:		end of data
   3047  *	DDI_PROP_OK:			data was skipped
   3048  *
   3049  * DDI_PROP_CMD_GET_ESIZE:
   3050  *
   3051  *	DDI_PROP_RESULT_ERROR:		cannot get encoded size
   3052  *	DDI_PROP_RESULT_EOF:		end of data
   3053  *	> 0:				the encoded size
   3054  *
   3055  * DDI_PROP_CMD_GET_DSIZE:
   3056  *
   3057  *	DDI_PROP_RESULT_ERROR:		cannot get decoded size
   3058  *	DDI_PROP_RESULT_EOF:		end of data
   3059  *	> 0:				the decoded size
   3060  */
   3061 
   3062 /*
   3063  * OBP 1275 integer operator
   3064  *
   3065  * OBP properties are a byte stream of data, so integers may not be
   3066  * properly aligned.  Therefore we need to copy them one byte at a time.
   3067  */
   3068 int
   3069 ddi_prop_1275_int(prop_handle_t *ph, uint_t cmd, int *data)
   3070 {
   3071 	int	i;
   3072 
   3073 	switch (cmd) {
   3074 	case DDI_PROP_CMD_DECODE:
   3075 		/*
   3076 		 * Check that there is encoded data
   3077 		 */
   3078 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0)
   3079 			return (DDI_PROP_RESULT_ERROR);
   3080 		if (ph->ph_flags & PH_FROM_PROM) {
   3081 			i = MIN(ph->ph_size, PROP_1275_INT_SIZE);
   3082 			if ((int *)ph->ph_cur_pos > ((int *)ph->ph_data +
   3083 			    ph->ph_size - i))
   3084 				return (DDI_PROP_RESULT_ERROR);
   3085 		} else {
   3086 			if (ph->ph_size < sizeof (int) ||
   3087 			    ((int *)ph->ph_cur_pos > ((int *)ph->ph_data +
   3088 			    ph->ph_size - sizeof (int))))
   3089 				return (DDI_PROP_RESULT_ERROR);
   3090 		}
   3091 
   3092 		/*
   3093 		 * Copy the integer, using the implementation-specific
   3094 		 * copy function if the property is coming from the PROM.
   3095 		 */
   3096 		if (ph->ph_flags & PH_FROM_PROM) {
   3097 			*data = impl_ddi_prop_int_from_prom(
   3098 			    (uchar_t *)ph->ph_cur_pos,
   3099 			    (ph->ph_size < PROP_1275_INT_SIZE) ?
   3100 			    ph->ph_size : PROP_1275_INT_SIZE);
   3101 		} else {
   3102 			bcopy(ph->ph_cur_pos, data, sizeof (int));
   3103 		}
   3104 
   3105 		/*
   3106 		 * Move the current location to the start of the next
   3107 		 * bit of undecoded data.
   3108 		 */
   3109 		ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos +
   3110 		    PROP_1275_INT_SIZE;
   3111 		return (DDI_PROP_RESULT_OK);
   3112 
   3113 	case DDI_PROP_CMD_ENCODE:
   3114 		/*
   3115 		 * Check that there is room to encoded the data
   3116 		 */
   3117 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0 ||
   3118 		    ph->ph_size < PROP_1275_INT_SIZE ||
   3119 		    ((int *)ph->ph_cur_pos > ((int *)ph->ph_data +
   3120 		    ph->ph_size - sizeof (int))))
   3121 			return (DDI_PROP_RESULT_ERROR);
   3122 
   3123 		/*
   3124 		 * Encode the integer into the byte stream one byte at a
   3125 		 * time.
   3126 		 */
   3127 		bcopy(data, ph->ph_cur_pos, sizeof (int));
   3128 
   3129 		/*
   3130 		 * Move the current location to the start of the next bit of
   3131 		 * space where we can store encoded data.
   3132 		 */
   3133 		ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + PROP_1275_INT_SIZE;
   3134 		return (DDI_PROP_RESULT_OK);
   3135 
   3136 	case DDI_PROP_CMD_SKIP:
   3137 		/*
   3138 		 * Check that there is encoded data
   3139 		 */
   3140 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0 ||
   3141 		    ph->ph_size < PROP_1275_INT_SIZE)
   3142 			return (DDI_PROP_RESULT_ERROR);
   3143 
   3144 
   3145 		if ((caddr_t)ph->ph_cur_pos ==
   3146 		    (caddr_t)ph->ph_data + ph->ph_size) {
   3147 			return (DDI_PROP_RESULT_EOF);
   3148 		} else if ((caddr_t)ph->ph_cur_pos >
   3149 		    (caddr_t)ph->ph_data + ph->ph_size) {
   3150 			return (DDI_PROP_RESULT_EOF);
   3151 		}
   3152 
   3153 		/*
   3154 		 * Move the current location to the start of the next bit of
   3155 		 * undecoded data.
   3156 		 */
   3157 		ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos + PROP_1275_INT_SIZE;
   3158 		return (DDI_PROP_RESULT_OK);
   3159 
   3160 	case DDI_PROP_CMD_GET_ESIZE:
   3161 		/*
   3162 		 * Return the size of an encoded integer on OBP
   3163 		 */
   3164 		return (PROP_1275_INT_SIZE);
   3165 
   3166 	case DDI_PROP_CMD_GET_DSIZE:
   3167 		/*
   3168 		 * Return the size of a decoded integer on the system.
   3169 		 */
   3170 		return (sizeof (int));
   3171 
   3172 	default:
   3173 #ifdef DEBUG
   3174 		panic("ddi_prop_1275_int: %x impossible", cmd);
   3175 		/*NOTREACHED*/
   3176 #else
   3177 		return (DDI_PROP_RESULT_ERROR);
   3178 #endif	/* DEBUG */
   3179 	}
   3180 }
   3181 
   3182 /*
   3183  * 64 bit integer operator.
   3184  *
   3185  * This is an extension, defined by Sun, to the 1275 integer
   3186  * operator.  This routine handles the encoding/decoding of
   3187  * 64 bit integer properties.
   3188  */
   3189 int
   3190 ddi_prop_int64_op(prop_handle_t *ph, uint_t cmd, int64_t *data)
   3191 {
   3192 
   3193 	switch (cmd) {
   3194 	case DDI_PROP_CMD_DECODE:
   3195 		/*
   3196 		 * Check that there is encoded data
   3197 		 */
   3198 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0)
   3199 			return (DDI_PROP_RESULT_ERROR);
   3200 		if (ph->ph_flags & PH_FROM_PROM) {
   3201 			return (DDI_PROP_RESULT_ERROR);
   3202 		} else {
   3203 			if (ph->ph_size < sizeof (int64_t) ||
   3204 			    ((int64_t *)ph->ph_cur_pos >
   3205 			    ((int64_t *)ph->ph_data +
   3206 			    ph->ph_size - sizeof (int64_t))))
   3207 				return (DDI_PROP_RESULT_ERROR);
   3208 		}
   3209 		/*
   3210 		 * Copy the integer, using the implementation-specific
   3211 		 * copy function if the property is coming from the PROM.
   3212 		 */
   3213 		if (ph->ph_flags & PH_FROM_PROM) {
   3214 			return (DDI_PROP_RESULT_ERROR);
   3215 		} else {
   3216 			bcopy(ph->ph_cur_pos, data, sizeof (int64_t));
   3217 		}
   3218 
   3219 		/*
   3220 		 * Move the current location to the start of the next
   3221 		 * bit of undecoded data.
   3222 		 */
   3223 		ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos +
   3224 		    sizeof (int64_t);
   3225 			return (DDI_PROP_RESULT_OK);
   3226 
   3227 	case DDI_PROP_CMD_ENCODE:
   3228 		/*
   3229 		 * Check that there is room to encoded the data
   3230 		 */
   3231 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0 ||
   3232 		    ph->ph_size < sizeof (int64_t) ||
   3233 		    ((int64_t *)ph->ph_cur_pos > ((int64_t *)ph->ph_data +
   3234 		    ph->ph_size - sizeof (int64_t))))
   3235 			return (DDI_PROP_RESULT_ERROR);
   3236 
   3237 		/*
   3238 		 * Encode the integer into the byte stream one byte at a
   3239 		 * time.
   3240 		 */
   3241 		bcopy(data, ph->ph_cur_pos, sizeof (int64_t));
   3242 
   3243 		/*
   3244 		 * Move the current location to the start of the next bit of
   3245 		 * space where we can store encoded data.
   3246 		 */
   3247 		ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos +
   3248 		    sizeof (int64_t);
   3249 		return (DDI_PROP_RESULT_OK);
   3250 
   3251 	case DDI_PROP_CMD_SKIP:
   3252 		/*
   3253 		 * Check that there is encoded data
   3254 		 */
   3255 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0 ||
   3256 		    ph->ph_size < sizeof (int64_t))
   3257 			return (DDI_PROP_RESULT_ERROR);
   3258 
   3259 		if ((caddr_t)ph->ph_cur_pos ==
   3260 		    (caddr_t)ph->ph_data + ph->ph_size) {
   3261 			return (DDI_PROP_RESULT_EOF);
   3262 		} else if ((caddr_t)ph->ph_cur_pos >
   3263 		    (caddr_t)ph->ph_data + ph->ph_size) {
   3264 			return (DDI_PROP_RESULT_EOF);
   3265 		}
   3266 
   3267 		/*
   3268 		 * Move the current location to the start of
   3269 		 * the next bit of undecoded data.
   3270 		 */
   3271 		ph->ph_cur_pos = (uchar_t *)ph->ph_cur_pos +
   3272 		    sizeof (int64_t);
   3273 			return (DDI_PROP_RESULT_OK);
   3274 
   3275 	case DDI_PROP_CMD_GET_ESIZE:
   3276 		/*
   3277 		 * Return the size of an encoded integer on OBP
   3278 		 */
   3279 		return (sizeof (int64_t));
   3280 
   3281 	case DDI_PROP_CMD_GET_DSIZE:
   3282 		/*
   3283 		 * Return the size of a decoded integer on the system.
   3284 		 */
   3285 		return (sizeof (int64_t));
   3286 
   3287 	default:
   3288 #ifdef DEBUG
   3289 		panic("ddi_prop_int64_op: %x impossible", cmd);
   3290 		/*NOTREACHED*/
   3291 #else
   3292 		return (DDI_PROP_RESULT_ERROR);
   3293 #endif  /* DEBUG */
   3294 	}
   3295 }
   3296 
   3297 /*
   3298  * OBP 1275 string operator.
   3299  *
   3300  * OBP strings are NULL terminated.
   3301  */
   3302 int
   3303 ddi_prop_1275_string(prop_handle_t *ph, uint_t cmd, char *data)
   3304 {
   3305 	int	n;
   3306 	char	*p;
   3307 	char	*end;
   3308 
   3309 	switch (cmd) {
   3310 	case DDI_PROP_CMD_DECODE:
   3311 		/*
   3312 		 * Check that there is encoded data
   3313 		 */
   3314 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0) {
   3315 			return (DDI_PROP_RESULT_ERROR);
   3316 		}
   3317 
   3318 		/*
   3319 		 * Match DDI_PROP_CMD_GET_DSIZE logic for when to stop and
   3320 		 * how to NULL terminate result.
   3321 		 */
   3322 		p = (char *)ph->ph_cur_pos;
   3323 		end = (char *)ph->ph_data + ph->ph_size;
   3324 		if (p >= end)
   3325 			return (DDI_PROP_RESULT_EOF);
   3326 
   3327 		while (p < end) {
   3328 			*data++ = *p;
   3329 			if (*p++ == 0) {	/* NULL from OBP */
   3330 				ph->ph_cur_pos = p;
   3331 				return (DDI_PROP_RESULT_OK);
   3332 			}
   3333 		}
   3334 
   3335 		/*
   3336 		 * If OBP did not NULL terminate string, which happens
   3337 		 * (at least) for 'true'/'false' boolean values, account for
   3338 		 * the space and store null termination on decode.
   3339 		 */
   3340 		ph->ph_cur_pos = p;
   3341 		*data = 0;
   3342 		return (DDI_PROP_RESULT_OK);
   3343 
   3344 	case DDI_PROP_CMD_ENCODE:
   3345 		/*
   3346 		 * Check that there is room to encoded the data
   3347 		 */
   3348 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0) {
   3349 			return (DDI_PROP_RESULT_ERROR);
   3350 		}
   3351 
   3352 		n = strlen(data) + 1;
   3353 		if ((char *)ph->ph_cur_pos > ((char *)ph->ph_data +
   3354 		    ph->ph_size - n)) {
   3355 			return (DDI_PROP_RESULT_ERROR);
   3356 		}
   3357 
   3358 		/*
   3359 		 * Copy the NULL terminated string
   3360 		 */
   3361 		bcopy(data, ph->ph_cur_pos, n);
   3362 
   3363 		/*
   3364 		 * Move the current location to the start of the next bit of
   3365 		 * space where we can store encoded data.
   3366 		 */
   3367 		ph->ph_cur_pos = (char *)ph->ph_cur_pos + n;
   3368 		return (DDI_PROP_RESULT_OK);
   3369 
   3370 	case DDI_PROP_CMD_SKIP:
   3371 		/*
   3372 		 * Check that there is encoded data
   3373 		 */
   3374 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0) {
   3375 			return (DDI_PROP_RESULT_ERROR);
   3376 		}
   3377 
   3378 		/*
   3379 		 * Return the string length plus one for the NULL
   3380 		 * We know the size of the property, we need to
   3381 		 * ensure that the string is properly formatted,
   3382 		 * since we may be looking up random OBP data.
   3383 		 */
   3384 		p = (char *)ph->ph_cur_pos;
   3385 		end = (char *)ph->ph_data + ph->ph_size;
   3386 		if (p >= end)
   3387 			return (DDI_PROP_RESULT_EOF);
   3388 
   3389 		while (p < end) {
   3390 			if (*p++ == 0) {	/* NULL from OBP */
   3391 				ph->ph_cur_pos = p;
   3392 				return (DDI_PROP_RESULT_OK);
   3393 			}
   3394 		}
   3395 
   3396 		/*
   3397 		 * Accommodate the fact that OBP does not always NULL
   3398 		 * terminate strings.
   3399 		 */
   3400 		ph->ph_cur_pos = p;
   3401 		return (DDI_PROP_RESULT_OK);
   3402 
   3403 	case DDI_PROP_CMD_GET_ESIZE:
   3404 		/*
   3405 		 * Return the size of the encoded string on OBP.
   3406 		 */
   3407 		return (strlen(data) + 1);
   3408 
   3409 	case DDI_PROP_CMD_GET_DSIZE:
   3410 		/*
   3411 		 * Return the string length plus one for the NULL.
   3412 		 * We know the size of the property, we need to
   3413 		 * ensure that the string is properly formatted,
   3414 		 * since we may be looking up random OBP data.
   3415 		 */
   3416 		p = (char *)ph->ph_cur_pos;
   3417 		end = (char *)ph->ph_data + ph->ph_size;
   3418 		if (p >= end)
   3419 			return (DDI_PROP_RESULT_EOF);
   3420 
   3421 		for (n = 0; p < end; n++) {
   3422 			if (*p++ == 0) {	/* NULL from OBP */
   3423 				ph->ph_cur_pos = p;
   3424 				return (n + 1);
   3425 			}
   3426 		}
   3427 
   3428 		/*
   3429 		 * If OBP did not NULL terminate string, which happens for
   3430 		 * 'true'/'false' boolean values, account for the space
   3431 		 * to store null termination here.
   3432 		 */
   3433 		ph->ph_cur_pos = p;
   3434 		return (n + 1);
   3435 
   3436 	default:
   3437 #ifdef DEBUG
   3438 		panic("ddi_prop_1275_string: %x impossible", cmd);
   3439 		/*NOTREACHED*/
   3440 #else
   3441 		return (DDI_PROP_RESULT_ERROR);
   3442 #endif	/* DEBUG */
   3443 	}
   3444 }
   3445 
   3446 /*
   3447  * OBP 1275 byte operator
   3448  *
   3449  * Caller must specify the number of bytes to get.  OBP encodes bytes
   3450  * as a byte so there is a 1-to-1 translation.
   3451  */
   3452 int
   3453 ddi_prop_1275_bytes(prop_handle_t *ph, uint_t cmd, uchar_t *data,
   3454 	uint_t nelements)
   3455 {
   3456 	switch (cmd) {
   3457 	case DDI_PROP_CMD_DECODE:
   3458 		/*
   3459 		 * Check that there is encoded data
   3460 		 */
   3461 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0 ||
   3462 		    ph->ph_size < nelements ||
   3463 		    ((char *)ph->ph_cur_pos > ((char *)ph->ph_data +
   3464 		    ph->ph_size - nelements)))
   3465 			return (DDI_PROP_RESULT_ERROR);
   3466 
   3467 		/*
   3468 		 * Copy out the bytes
   3469 		 */
   3470 		bcopy(ph->ph_cur_pos, data, nelements);
   3471 
   3472 		/*
   3473 		 * Move the current location
   3474 		 */
   3475 		ph->ph_cur_pos = (char *)ph->ph_cur_pos + nelements;
   3476 		return (DDI_PROP_RESULT_OK);
   3477 
   3478 	case DDI_PROP_CMD_ENCODE:
   3479 		/*
   3480 		 * Check that there is room to encode the data
   3481 		 */
   3482 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0 ||
   3483 		    ph->ph_size < nelements ||
   3484 		    ((char *)ph->ph_cur_pos > ((char *)ph->ph_data +
   3485 		    ph->ph_size - nelements)))
   3486 			return (DDI_PROP_RESULT_ERROR);
   3487 
   3488 		/*
   3489 		 * Copy in the bytes
   3490 		 */
   3491 		bcopy(data, ph->ph_cur_pos, nelements);
   3492 
   3493 		/*
   3494 		 * Move the current location to the start of the next bit of
   3495 		 * space where we can store encoded data.
   3496 		 */
   3497 		ph->ph_cur_pos = (char *)ph->ph_cur_pos + nelements;
   3498 		return (DDI_PROP_RESULT_OK);
   3499 
   3500 	case DDI_PROP_CMD_SKIP:
   3501 		/*
   3502 		 * Check that there is encoded data
   3503 		 */
   3504 		if (ph->ph_cur_pos == NULL || ph->ph_size == 0 ||
   3505 		    ph->ph_size < nelements)
   3506 			return (DDI_PROP_RESULT_ERROR);
   3507 
   3508 		if ((char *)ph->ph_cur_pos > ((char *)ph->ph_data +
   3509 		    ph->ph_size - nelements))
   3510 			return (DDI_PROP_RESULT_EOF);
   3511 
   3512 		/*
   3513 		 * Move the current location
   3514 		 */
   3515 		ph->ph_cur_pos = (char *)ph->ph_cur_pos + nelements;
   3516 		return (DDI_PROP_RESULT_OK);
   3517 
   3518 	case DDI_PROP_CMD_GET_ESIZE:
   3519 		/*
   3520 		 * The size in bytes of the encoded size is the
   3521 		 * same as the decoded size provided by the caller.
   3522 		 */
   3523 		return (nelements);
   3524 
   3525 	case DDI_PROP_CMD_GET_DSIZE:
   3526 		/*
   3527 		 * Just return the number of bytes specified by the caller.
   3528 		 */
   3529 		return (nelements);
   3530 
   3531 	default:
   3532 #ifdef DEBUG
   3533 		panic("ddi_prop_1275_bytes: %x impossible", cmd);
   3534 		/*NOTREACHED*/
   3535 #else
   3536 		return (DDI_PROP_RESULT_ERROR);
   3537 #endif	/* DEBUG */
   3538 	}
   3539 }
   3540 
   3541 /*
   3542  * Used for properties that come from the OBP, hardware configuration files,
   3543  * or that are created by calls to ddi_prop_update(9F).
   3544  */
   3545 static struct prop_handle_ops prop_1275_ops = {
   3546 	ddi_prop_1275_int,
   3547 	ddi_prop_1275_string,
   3548 	ddi_prop_1275_bytes,
   3549 	ddi_prop_int64_op
   3550 };
   3551 
   3552 
   3553 /*
   3554  * Interface to create/modify a managed property on child's behalf...
   3555  * Flags interpreted are:
   3556  *	DDI_PROP_CANSLEEP:	Allow memory allocation to sleep.
   3557  *	DDI_PROP_SYSTEM_DEF:	Manipulate system list rather than driver list.
   3558  *
   3559  * Use same dev_t when modifying or undefining a property.
   3560  * Search for properties with DDI_DEV_T_ANY to match first named
   3561  * property on the list.
   3562  *
   3563  * Properties are stored LIFO and subsequently will match the first
   3564  * `matching' instance.
   3565  */
   3566 
   3567 /*
   3568  * ddi_prop_add:	Add a software defined property
   3569  */
   3570 
   3571 /*
   3572  * define to get a new ddi_prop_t.
   3573  * km_flags are KM_SLEEP or KM_NOSLEEP.
   3574  */
   3575 
   3576 #define	DDI_NEW_PROP_T(km_flags)	\
   3577 	(kmem_zalloc(sizeof (ddi_prop_t), km_flags))
   3578 
   3579 static int
   3580 ddi_prop_add(dev_t dev, dev_info_t *dip, int flags,
   3581     char *name, caddr_t value, int length)
   3582 {
   3583 	ddi_prop_t	*new_propp, *propp;
   3584 	ddi_prop_t	**list_head = &(DEVI(dip)->devi_drv_prop_ptr);
   3585 	int		km_flags = KM_NOSLEEP;
   3586 	int		name_buf_len;
   3587 
   3588 	/*
   3589 	 * If dev_t is DDI_DEV_T_ANY or name's length is zero return error.
   3590 	 */
   3591 
   3592 	if (dev == DDI_DEV_T_ANY || name == (char *)0 || strlen(name) == 0)
   3593 		return (DDI_PROP_INVAL_ARG);
   3594 
   3595 	if (flags & DDI_PROP_CANSLEEP)
   3596 		km_flags = KM_SLEEP;
   3597 
   3598 	if (flags & DDI_PROP_SYSTEM_DEF)
   3599 		list_head = &(DEVI(dip)->devi_sys_prop_ptr);
   3600 	else if (flags & DDI_PROP_HW_DEF)
   3601 		list_head = &(DEVI(dip)->devi_hw_prop_ptr);
   3602 
   3603 	if ((new_propp = DDI_NEW_PROP_T(km_flags)) == NULL)  {
   3604 		cmn_err(CE_CONT, prop_no_mem_msg, name);
   3605 		return (DDI_PROP_NO_MEMORY);
   3606 	}
   3607 
   3608 	/*
   3609 	 * If dev is major number 0, then we need to do a ddi_name_to_major
   3610 	 * to get the real major number for the device.  This needs to be
   3611 	 * done because some drivers need to call ddi_prop_create in their
   3612 	 * attach routines but they don't have a dev.  By creating the dev
   3613 	 * ourself if the major number is 0, drivers will not have to know what
   3614 	 * their major number.	They can just create a dev with major number
   3615 	 * 0 and pass it in.  For device 0, we will be doing a little extra
   3616 	 * work by recreating the same dev that we already have, but its the
   3617 	 * price you pay :-).
   3618 	 *
   3619 	 * This fixes bug #1098060.
   3620 	 */
   3621 	if (getmajor(dev) == DDI_MAJOR_T_UNKNOWN) {
   3622 		new_propp->prop_dev =
   3623 		    makedevice(ddi_name_to_major(DEVI(dip)->devi_binding_name),
   3624 		    getminor(dev));
   3625 	} else
   3626 		new_propp->prop_dev = dev;
   3627 
   3628 	/*
   3629 	 * Allocate space for property name and copy it in...
   3630 	 */
   3631 
   3632 	name_buf_len = strlen(name) + 1;
   3633 	new_propp->prop_name = kmem_alloc(name_buf_len, km_flags);
   3634 	if (new_propp->prop_name == 0)	{
   3635 		kmem_free(new_propp, sizeof (ddi_prop_t));
   3636 		cmn_err(CE_CONT, prop_no_mem_msg, name);
   3637 		return (DDI_PROP_NO_MEMORY);
   3638 	}
   3639 	bcopy(name, new_propp->prop_name, name_buf_len);
   3640 
   3641 	/*
   3642 	 * Set the property type
   3643 	 */
   3644 	new_propp->prop_flags = flags & DDI_PROP_TYPE_MASK;
   3645 
   3646 	/*
   3647 	 * Set length and value ONLY if not an explicit property undefine:
   3648 	 * NOTE: value and length are zero for explicit undefines.
   3649 	 */
   3650 
   3651 	if (flags & DDI_PROP_UNDEF_IT) {
   3652 		new_propp->prop_flags |= DDI_PROP_UNDEF_IT;
   3653 	} else {
   3654 		if ((new_propp->prop_len = length) != 0) {
   3655 			new_propp->prop_val = kmem_alloc(length, km_flags);
   3656 			if (new_propp->prop_val == 0)  {
   3657 				kmem_free(new_propp->prop_name, name_buf_len);
   3658 				kmem_free(new_propp, sizeof (ddi_prop_t));
   3659 				cmn_err(CE_CONT, prop_no_mem_msg, name);
   3660 				return (DDI_PROP_NO_MEMORY);
   3661 			}
   3662 			bcopy(value, new_propp->prop_val, length);
   3663 		}
   3664 	}
   3665 
   3666 	/*
   3667 	 * Link property into beginning of list. (Properties are LIFO order.)
   3668 	 */
   3669 
   3670 	mutex_enter(&(DEVI(dip)->devi_lock));
   3671 	propp = *list_head;
   3672 	new_propp->prop_next = propp;
   3673 	*list_head = new_propp;
   3674 	mutex_exit(&(DEVI(dip)->devi_lock));
   3675 	return (DDI_PROP_SUCCESS);
   3676 }
   3677 
   3678 
   3679 /*
   3680  * ddi_prop_change:	Modify a software managed property value
   3681  *
   3682  *			Set new length and value if found.
   3683  *			returns DDI_PROP_INVAL_ARG if dev is DDI_DEV_T_ANY or
   3684  *			input name is the NULL string.
   3685  *			returns DDI_PROP_NO_MEMORY if unable to allocate memory
   3686  *
   3687  *			Note: an undef can be modified to be a define,
   3688  *			(you can't go the other way.)
   3689  */
   3690 
   3691 static int
   3692 ddi_prop_change(dev_t dev, dev_info_t *dip, int flags,
   3693     char *name, caddr_t value, int length)
   3694 {
   3695 	ddi_prop_t	*propp;
   3696 	ddi_prop_t	**ppropp;
   3697 	caddr_t		p = NULL;
   3698 
   3699 	if ((dev == DDI_DEV_T_ANY) || (name == NULL) || (strlen(name) == 0))
   3700 		return (DDI_PROP_INVAL_ARG);
   3701 
   3702 	/*
   3703 	 * Preallocate buffer, even if we don't need it...
   3704 	 */
   3705 	if (length != 0)  {
   3706 		p = kmem_alloc(length, (flags & DDI_PROP_CANSLEEP) ?
   3707 		    KM_SLEEP : KM_NOSLEEP);
   3708 		if (p == NULL)	{
   3709 			cmn_err(CE_CONT, prop_no_mem_msg, name);
   3710 			return (DDI_PROP_NO_MEMORY);
   3711 		}
   3712 	}
   3713 
   3714 	/*
   3715 	 * If the dev_t value contains DDI_MAJOR_T_UNKNOWN for the major
   3716 	 * number, a real dev_t value should be created based upon the dip's
   3717 	 * binding driver.  See ddi_prop_add...
   3718 	 */
   3719 	if (getmajor(dev) == DDI_MAJOR_T_UNKNOWN)
   3720 		dev = makedevice(
   3721 		    ddi_name_to_major(DEVI(dip)->devi_binding_name),
   3722 		    getminor(dev));
   3723 
   3724 	/*
   3725 	 * Check to see if the property exists.  If so we modify it.
   3726 	 * Else we create it by calling ddi_prop_add().
   3727 	 */
   3728 	mutex_enter(&(DEVI(dip)->devi_lock));
   3729 	ppropp = &DEVI(dip)->devi_drv_prop_ptr;
   3730 	if (flags & DDI_PROP_SYSTEM_DEF)
   3731 		ppropp = &DEVI(dip)->devi_sys_prop_ptr;
   3732 	else if (flags & DDI_PROP_HW_DEF)
   3733 		ppropp = &DEVI(dip)->devi_hw_prop_ptr;
   3734 
   3735 	if ((propp = i_ddi_prop_search(dev, name, flags, ppropp)) != NULL) {
   3736 		/*
   3737 		 * Need to reallocate buffer?  If so, do it
   3738 		 * carefully (reuse same space if new prop
   3739 		 * is same size and non-NULL sized).
   3740 		 */
   3741 		if (length != 0)
   3742 			bcopy(value, p, length);
   3743 
   3744 		if (propp->prop_len != 0)
   3745 			kmem_free(propp->prop_val, propp->prop_len);
   3746 
   3747 		propp->prop_len = length;
   3748 		propp->prop_val = p;
   3749 		propp->prop_flags &= ~DDI_PROP_UNDEF_IT;
   3750 		mutex_exit(&(DEVI(dip)->devi_lock));
   3751 		return (DDI_PROP_SUCCESS);
   3752 	}
   3753 
   3754 	mutex_exit(&(DEVI(dip)->devi_lock));
   3755 	if (length != 0)
   3756 		kmem_free(p, length);
   3757 
   3758 	return (ddi_prop_add(dev, dip, flags, name, value, length));
   3759 }
   3760 
   3761 /*
   3762  * Common update routine used to update and encode a property.	Creates
   3763  * a property handle, calls the property encode routine, figures out if
   3764  * the property already exists and updates if it does.	Otherwise it
   3765  * creates if it does not exist.
   3766  */
   3767 int
   3768 ddi_prop_update_common(dev_t match_dev, dev_info_t *dip, int flags,
   3769     char *name, void *data, uint_t nelements,
   3770     int (*prop_create)(prop_handle_t *, void *data, uint_t nelements))
   3771 {
   3772 	prop_handle_t	ph;
   3773 	int		rval;
   3774 	uint_t		ourflags;
   3775 
   3776 	/*
   3777 	 * If dev_t is DDI_DEV_T_ANY or name's length is zero,
   3778 	 * return error.
   3779 	 */
   3780 	if (match_dev == DDI_DEV_T_ANY || name == NULL || strlen(name) == 0)
   3781 		return (DDI_PROP_INVAL_ARG);
   3782 
   3783 	/*
   3784 	 * Create the handle
   3785 	 */
   3786 	ph.ph_data = NULL;
   3787 	ph.ph_cur_pos = NULL;
   3788 	ph.ph_save_pos = NULL;
   3789 	ph.ph_size = 0;
   3790 	ph.ph_ops = &prop_1275_ops;
   3791 
   3792 	/*
   3793 	 * ourflags:
   3794 	 * For compatibility with the old interfaces.  The old interfaces
   3795 	 * didn't sleep by default and slept when the flag was set.  These
   3796 	 * interfaces to the opposite.	So the old interfaces now set the
   3797 	 * DDI_PROP_DONTSLEEP flag by default which tells us not to sleep.
   3798 	 *
   3799 	 * ph.ph_flags:
   3800 	 * Blocked data or unblocked data allocation
   3801 	 * for ph.ph_data in ddi_prop_encode_alloc()
   3802 	 */
   3803 	if (flags & DDI_PROP_DONTSLEEP) {
   3804 		ourflags = flags;
   3805 		ph.ph_flags = DDI_PROP_DONTSLEEP;
   3806 	} else {
   3807 		ourflags = flags | DDI_PROP_CANSLEEP;
   3808 		ph.ph_flags = DDI_PROP_CANSLEEP;
   3809 	}
   3810 
   3811 	/*
   3812 	 * Encode the data and store it in the property handle by
   3813 	 * calling the prop_encode routine.
   3814 	 */
   3815 	if ((rval = (*prop_create)(&ph, data, nelements)) !=
   3816 	    DDI_PROP_SUCCESS) {
   3817 		if (rval == DDI_PROP_NO_MEMORY)
   3818 			cmn_err(CE_CONT, prop_no_mem_msg, name);
   3819 		if (ph.ph_size != 0)
   3820 			kmem_free(ph.ph_data, ph.ph_size);
   3821 		return (rval);
   3822 	}
   3823 
   3824 	/*
   3825 	 * The old interfaces use a stacking approach to creating
   3826 	 * properties.	If we are being called from the old interfaces,
   3827 	 * the DDI_PROP_STACK_CREATE flag will be set, so we just do a
   3828 	 * create without checking.
   3829 	 */
   3830 	if (flags & DDI_PROP_STACK_CREATE) {
   3831 		rval = ddi_prop_add(match_dev, dip,
   3832 		    ourflags, name, ph.ph_data, ph.ph_size);
   3833 	} else {
   3834 		rval = ddi_prop_change(match_dev, dip,
   3835 		    ourflags, name, ph.ph_data, ph.ph_size);
   3836 	}
   3837 
   3838 	/*
   3839 	 * Free the encoded data allocated in the prop_encode routine.
   3840 	 */
   3841 	if (ph.ph_size != 0)
   3842 		kmem_free(ph.ph_data, ph.ph_size);
   3843 
   3844 	return (rval);
   3845 }
   3846 
   3847 
   3848 /*
   3849  * ddi_prop_create:	Define a managed property:
   3850  *			See above for details.
   3851  */
   3852 
   3853 int
   3854 ddi_prop_create(dev_t dev, dev_info_t *dip, int flag,
   3855     char *name, caddr_t value, int length)
   3856 {
   3857 	if (!(flag & DDI_PROP_CANSLEEP)) {
   3858 		flag |= DDI_PROP_DONTSLEEP;
   3859 #ifdef DDI_PROP_DEBUG
   3860 		if (length != 0)
   3861 			cmn_err(CE_NOTE, "!ddi_prop_create: interface obsolete,"
   3862 			    "use ddi_prop_update (prop = %s, node = %s%d)",
   3863 			    name, ddi_driver_name(dip), ddi_get_instance(dip));
   3864 #endif /* DDI_PROP_DEBUG */
   3865 	}
   3866 	flag &= ~DDI_PROP_SYSTEM_DEF;
   3867 	flag |= DDI_PROP_STACK_CREATE | DDI_PROP_TYPE_ANY;
   3868 	return (ddi_prop_update_common(dev, dip, flag, name,
   3869 	    value, length, ddi_prop_fm_encode_bytes));
   3870 }
   3871 
   3872 int
   3873 e_ddi_prop_create(dev_t dev, dev_info_t *dip, int flag,
   3874     char *name, caddr_t value, int length)
   3875 {
   3876 	if (!(flag & DDI_PROP_CANSLEEP))
   3877 		flag |= DDI_PROP_DONTSLEEP;
   3878 	flag |= DDI_PROP_SYSTEM_DEF | DDI_PROP_STACK_CREATE | DDI_PROP_TYPE_ANY;
   3879 	return (ddi_prop_update_common(dev, dip, flag,
   3880 	    name, value, length, ddi_prop_fm_encode_bytes));
   3881 }
   3882 
   3883 int
   3884 ddi_prop_modify(dev_t dev, dev_info_t *dip, int flag,
   3885     char *name, caddr_t value, int length)
   3886 {
   3887 	ASSERT((flag & DDI_PROP_TYPE_MASK) == 0);
   3888 
   3889 	/*
   3890 	 * If dev_t is DDI_DEV_T_ANY or name's length is zero,
   3891 	 * return error.
   3892 	 */
   3893 	if (dev == DDI_DEV_T_ANY || name == NULL || strlen(name) == 0)
   3894 		return (DDI_PROP_INVAL_ARG);
   3895 
   3896 	if (!(flag & DDI_PROP_CANSLEEP))
   3897 		flag |= DDI_PROP_DONTSLEEP;
   3898 	flag &= ~DDI_PROP_SYSTEM_DEF;
   3899 	if (ddi_prop_exists(dev, dip, (flag | DDI_PROP_NOTPROM), name) == 0)
   3900 		return (DDI_PROP_NOT_FOUND);
   3901 
   3902 	return (ddi_prop_update_common(dev, dip,
   3903 	    (flag | DDI_PROP_TYPE_BYTE), name,
   3904 	    value, length, ddi_prop_fm_encode_bytes));
   3905 }
   3906 
   3907 int
   3908 e_ddi_prop_modify(dev_t dev, dev_info_t *dip, int flag,
   3909     char *name, caddr_t value, int length)
   3910 {
   3911 	ASSERT((flag & DDI_PROP_TYPE_MASK) == 0);
   3912 
   3913 	/*
   3914 	 * If dev_t is DDI_DEV_T_ANY or name's length is zero,
   3915 	 * return error.
   3916 	 */
   3917 	if (dev == DDI_DEV_T_ANY || name == NULL || strlen(name) == 0)
   3918 		return (DDI_PROP_INVAL_ARG);
   3919 
   3920 	if (ddi_prop_exists(dev, dip, (flag | DDI_PROP_SYSTEM_DEF), name) == 0)
   3921 		return (DDI_PROP_NOT_FOUND);
   3922 
   3923 	if (!(flag & DDI_PROP_CANSLEEP))
   3924 		flag |= DDI_PROP_DONTSLEEP;
   3925 	return (ddi_prop_update_common(dev, dip,
   3926 	    (flag | DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_BYTE),
   3927 	    name, value, length, ddi_prop_fm_encode_bytes));
   3928 }
   3929 
   3930 
   3931 /*
   3932  * Common lookup routine used to lookup and decode a property.
   3933  * Creates a property handle, searches for the raw encoded data,
   3934  * fills in the handle, and calls the property decode functions
   3935  * passed in.
   3936  *
   3937  * This routine is not static because ddi_bus_prop_op() which lives in
   3938  * ddi_impl.c calls it.  No driver should be calling this routine.
   3939  */
   3940 int
   3941 ddi_prop_lookup_common(dev_t match_dev, dev_info_t *dip,
   3942     uint_t flags, char *name, void *data, uint_t *nelements,
   3943     int (*prop_decoder)(prop_handle_t *, void *data, uint_t *nelements))
   3944 {
   3945 	int		rval;
   3946 	uint_t		ourflags;
   3947 	prop_handle_t	ph;
   3948 
   3949 	if ((match_dev == DDI_DEV_T_NONE) ||
   3950 	    (name == NULL) || (strlen(name) == 0))
   3951 		return (DDI_PROP_INVAL_ARG);
   3952 
   3953 	ourflags = (flags & DDI_PROP_DONTSLEEP) ? flags :
   3954 	    flags | DDI_PROP_CANSLEEP;
   3955 
   3956 	/*
   3957 	 * Get the encoded data
   3958 	 */
   3959 	bzero(&ph, sizeof (prop_handle_t));
   3960 
   3961 	if ((flags & DDI_UNBND_DLPI2) || (flags & DDI_PROP_ROOTNEX_GLOBAL)) {
   3962 		/*
   3963 		 * For rootnex and unbound dlpi style-2 devices, index into
   3964 		 * the devnames' array and search the global
   3965 		 * property list.
   3966 		 */
   3967 		ourflags &= ~DDI_UNBND_DLPI2;
   3968 		rval = i_ddi_prop_search_global(match_dev,
   3969 		    ourflags, name, &ph.ph_data, &ph.ph_size);
   3970 	} else {
   3971 		rval = ddi_prop_search_common(match_dev, dip,
   3972 		    PROP_LEN_AND_VAL_ALLOC, ourflags, name,
   3973 		    &ph.ph_data, &ph.ph_size);
   3974 
   3975 	}
   3976 
   3977 	if (rval != DDI_PROP_SUCCESS && rval != DDI_PROP_FOUND_1275) {
   3978 		ASSERT(ph.ph_data == NULL);
   3979 		ASSERT(ph.ph_size == 0);
   3980 		return (rval);
   3981 	}
   3982 
   3983 	/*
   3984 	 * If the encoded data came from a OBP or software
   3985 	 * use the 1275 OBP decode/encode routines.
   3986 	 */
   3987 	ph.ph_cur_pos = ph.ph_data;
   3988 	ph.ph_save_pos = ph.ph_data;
   3989 	ph.ph_ops = &prop_1275_ops;
   3990 	ph.ph_flags = (rval == DDI_PROP_FOUND_1275) ? PH_FROM_PROM : 0;
   3991 
   3992 	rval = (*prop_decoder)(&ph, data, nelements);
   3993 
   3994 	/*
   3995 	 * Free the encoded data
   3996 	 */
   3997 	if (ph.ph_size != 0)
   3998 		kmem_free(ph.ph_data, ph.ph_size);
   3999 
   4000 	return (rval);
   4001 }
   4002 
   4003 /*
   4004  * Lookup and return an array of composite properties.  The driver must
   4005  * provide the decode routine.
   4006  */
   4007 int
   4008 ddi_prop_lookup(dev_t match_dev, dev_info_t *dip,
   4009     uint_t flags, char *name, void *data, uint_t *nelements,
   4010     int (*prop_decoder)(prop_handle_t *, void *data, uint_t *nelements))
   4011 {
   4012 	return (ddi_prop_lookup_common(match_dev, dip,
   4013 	    (flags | DDI_PROP_TYPE_COMPOSITE), name,
   4014 	    data, nelements, prop_decoder));
   4015 }
   4016 
   4017 /*
   4018  * Return 1 if a property exists (no type checking done).
   4019  * Return 0 if it does not exist.
   4020  */
   4021 int
   4022 ddi_prop_exists(dev_t match_dev, dev_info_t *dip, uint_t flags, char *name)
   4023 {
   4024 	int	i;
   4025 	uint_t	x = 0;
   4026 
   4027 	i = ddi_prop_search_common(match_dev, dip, PROP_EXISTS,
   4028 	    flags | DDI_PROP_TYPE_MASK, name, NULL, &x);
   4029 	return (i == DDI_PROP_SUCCESS || i == DDI_PROP_FOUND_1275);
   4030 }
   4031 
   4032 
   4033 /*
   4034  * Update an array of composite properties.  The driver must
   4035  * provide the encode routine.
   4036  */
   4037 int
   4038 ddi_prop_update(dev_t match_dev, dev_info_t *dip,
   4039     char *name, void *data, uint_t nelements,
   4040     int (*prop_create)(prop_handle_t *, void *data, uint_t nelements))
   4041 {
   4042 	return (ddi_prop_update_common(match_dev, dip, DDI_PROP_TYPE_COMPOSITE,
   4043 	    name, data, nelements, prop_create));
   4044 }
   4045 
   4046 /*
   4047  * Get a single integer or boolean property and return it.
   4048  * If the property does not exists, or cannot be decoded,
   4049  * then return the defvalue passed in.
   4050  *
   4051  * This routine always succeeds.
   4052  */
   4053 int
   4054 ddi_prop_get_int(dev_t match_dev, dev_info_t *dip, uint_t flags,
   4055     char *name, int defvalue)
   4056 {
   4057 	int	data;
   4058 	uint_t	nelements;
   4059 	int	rval;
   4060 
   4061 	if (flags & ~(DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4062 	    LDI_DEV_T_ANY | DDI_UNBND_DLPI2 | DDI_PROP_ROOTNEX_GLOBAL)) {
   4063 #ifdef DEBUG
   4064 		if (dip != NULL) {
   4065 			cmn_err(CE_WARN, "ddi_prop_get_int: invalid flag"
   4066 			    " 0x%x (prop = %s, node = %s%d)", flags,
   4067 			    name, ddi_driver_name(dip), ddi_get_instance(dip));
   4068 		}
   4069 #endif /* DEBUG */
   4070 		flags &= DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4071 		    LDI_DEV_T_ANY | DDI_UNBND_DLPI2;
   4072 	}
   4073 
   4074 	if ((rval = ddi_prop_lookup_common(match_dev, dip,
   4075 	    (flags | DDI_PROP_TYPE_INT), name, &data, &nelements,
   4076 	    ddi_prop_fm_decode_int)) != DDI_PROP_SUCCESS) {
   4077 		if (rval == DDI_PROP_END_OF_DATA)
   4078 			data = 1;
   4079 		else
   4080 			data = defvalue;
   4081 	}
   4082 	return (data);
   4083 }
   4084 
   4085 /*
   4086  * Get a single 64 bit integer or boolean property and return it.
   4087  * If the property does not exists, or cannot be decoded,
   4088  * then return the defvalue passed in.
   4089  *
   4090  * This routine always succeeds.
   4091  */
   4092 int64_t
   4093 ddi_prop_get_int64(dev_t match_dev, dev_info_t *dip, uint_t flags,
   4094     char *name, int64_t defvalue)
   4095 {
   4096 	int64_t	data;
   4097 	uint_t	nelements;
   4098 	int	rval;
   4099 
   4100 	if (flags & ~(DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4101 	    LDI_DEV_T_ANY | DDI_UNBND_DLPI2 | DDI_PROP_ROOTNEX_GLOBAL)) {
   4102 #ifdef DEBUG
   4103 		if (dip != NULL) {
   4104 			cmn_err(CE_WARN, "ddi_prop_get_int64: invalid flag"
   4105 			    " 0x%x (prop = %s, node = %s%d)", flags,
   4106 			    name, ddi_driver_name(dip), ddi_get_instance(dip));
   4107 		}
   4108 #endif /* DEBUG */
   4109 		return (DDI_PROP_INVAL_ARG);
   4110 	}
   4111 
   4112 	if ((rval = ddi_prop_lookup_common(match_dev, dip,
   4113 	    (flags | DDI_PROP_TYPE_INT64 | DDI_PROP_NOTPROM),
   4114 	    name, &data, &nelements, ddi_prop_fm_decode_int64))
   4115 	    != DDI_PROP_SUCCESS) {
   4116 		if (rval == DDI_PROP_END_OF_DATA)
   4117 			data = 1;
   4118 		else
   4119 			data = defvalue;
   4120 	}
   4121 	return (data);
   4122 }
   4123 
   4124 /*
   4125  * Get an array of integer property
   4126  */
   4127 int
   4128 ddi_prop_lookup_int_array(dev_t match_dev, dev_info_t *dip, uint_t flags,
   4129     char *name, int **data, uint_t *nelements)
   4130 {
   4131 	if (flags & ~(DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4132 	    LDI_DEV_T_ANY | DDI_UNBND_DLPI2 | DDI_PROP_ROOTNEX_GLOBAL)) {
   4133 #ifdef DEBUG
   4134 		if (dip != NULL) {
   4135 			cmn_err(CE_WARN, "ddi_prop_lookup_int_array: "
   4136 			    "invalid flag 0x%x (prop = %s, node = %s%d)",
   4137 			    flags, name, ddi_driver_name(dip),
   4138 			    ddi_get_instance(dip));
   4139 		}
   4140 #endif /* DEBUG */
   4141 		flags &= DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4142 		    LDI_DEV_T_ANY | DDI_UNBND_DLPI2;
   4143 	}
   4144 
   4145 	return (ddi_prop_lookup_common(match_dev, dip,
   4146 	    (flags | DDI_PROP_TYPE_INT), name, data,
   4147 	    nelements, ddi_prop_fm_decode_ints));
   4148 }
   4149 
   4150 /*
   4151  * Get an array of 64 bit integer properties
   4152  */
   4153 int
   4154 ddi_prop_lookup_int64_array(dev_t match_dev, dev_info_t *dip, uint_t flags,
   4155     char *name, int64_t **data, uint_t *nelements)
   4156 {
   4157 	if (flags & ~(DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4158 	    LDI_DEV_T_ANY | DDI_UNBND_DLPI2 | DDI_PROP_ROOTNEX_GLOBAL)) {
   4159 #ifdef DEBUG
   4160 		if (dip != NULL) {
   4161 			cmn_err(CE_WARN, "ddi_prop_lookup_int64_array: "
   4162 			    "invalid flag 0x%x (prop = %s, node = %s%d)",
   4163 			    flags, name, ddi_driver_name(dip),
   4164 			    ddi_get_instance(dip));
   4165 		}
   4166 #endif /* DEBUG */
   4167 		return (DDI_PROP_INVAL_ARG);
   4168 	}
   4169 
   4170 	return (ddi_prop_lookup_common(match_dev, dip,
   4171 	    (flags | DDI_PROP_TYPE_INT64 | DDI_PROP_NOTPROM),
   4172 	    name, data, nelements, ddi_prop_fm_decode_int64_array));
   4173 }
   4174 
   4175 /*
   4176  * Update a single integer property.  If the property exists on the drivers
   4177  * property list it updates, else it creates it.
   4178  */
   4179 int
   4180 ddi_prop_update_int(dev_t match_dev, dev_info_t *dip,
   4181     char *name, int data)
   4182 {
   4183 	return (ddi_prop_update_common(match_dev, dip, DDI_PROP_TYPE_INT,
   4184 	    name, &data, 1, ddi_prop_fm_encode_ints));
   4185 }
   4186 
   4187 /*
   4188  * Update a single 64 bit integer property.
   4189  * Update the driver property list if it exists, else create it.
   4190  */
   4191 int
   4192 ddi_prop_update_int64(dev_t match_dev, dev_info_t *dip,
   4193     char *name, int64_t data)
   4194 {
   4195 	return (ddi_prop_update_common(match_dev, dip, DDI_PROP_TYPE_INT64,
   4196 	    name, &data, 1, ddi_prop_fm_encode_int64));
   4197 }
   4198 
   4199 int
   4200 e_ddi_prop_update_int(dev_t match_dev, dev_info_t *dip,
   4201     char *name, int data)
   4202 {
   4203 	return (ddi_prop_update_common(match_dev, dip,
   4204 	    DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_INT,
   4205 	    name, &data, 1, ddi_prop_fm_encode_ints));
   4206 }
   4207 
   4208 int
   4209 e_ddi_prop_update_int64(dev_t match_dev, dev_info_t *dip,
   4210     char *name, int64_t data)
   4211 {
   4212 	return (ddi_prop_update_common(match_dev, dip,
   4213 	    DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_INT64,
   4214 	    name, &data, 1, ddi_prop_fm_encode_int64));
   4215 }
   4216 
   4217 /*
   4218  * Update an array of integer property.  If the property exists on the drivers
   4219  * property list it updates, else it creates it.
   4220  */
   4221 int
   4222 ddi_prop_update_int_array(dev_t match_dev, dev_info_t *dip,
   4223     char *name, int *data, uint_t nelements)
   4224 {
   4225 	return (ddi_prop_update_common(match_dev, dip, DDI_PROP_TYPE_INT,
   4226 	    name, data, nelements, ddi_prop_fm_encode_ints));
   4227 }
   4228 
   4229 /*
   4230  * Update an array of 64 bit integer properties.
   4231  * Update the driver property list if it exists, else create it.
   4232  */
   4233 int
   4234 ddi_prop_update_int64_array(dev_t match_dev, dev_info_t *dip,
   4235     char *name, int64_t *data, uint_t nelements)
   4236 {
   4237 	return (ddi_prop_update_common(match_dev, dip, DDI_PROP_TYPE_INT64,
   4238 	    name, data, nelements, ddi_prop_fm_encode_int64));
   4239 }
   4240 
   4241 int
   4242 e_ddi_prop_update_int64_array(dev_t match_dev, dev_info_t *dip,
   4243     char *name, int64_t *data, uint_t nelements)
   4244 {
   4245 	return (ddi_prop_update_common(match_dev, dip,
   4246 	    DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_INT64,
   4247 	    name, data, nelements, ddi_prop_fm_encode_int64));
   4248 }
   4249 
   4250 int
   4251 e_ddi_prop_update_int_array(dev_t match_dev, dev_info_t *dip,
   4252     char *name, int *data, uint_t nelements)
   4253 {
   4254 	return (ddi_prop_update_common(match_dev, dip,
   4255 	    DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_INT,
   4256 	    name, data, nelements, ddi_prop_fm_encode_ints));
   4257 }
   4258 
   4259 /*
   4260  * Get a single string property.
   4261  */
   4262 int
   4263 ddi_prop_lookup_string(dev_t match_dev, dev_info_t *dip, uint_t flags,
   4264     char *name, char **data)
   4265 {
   4266 	uint_t x;
   4267 
   4268 	if (flags & ~(DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4269 	    LDI_DEV_T_ANY | DDI_UNBND_DLPI2 | DDI_PROP_ROOTNEX_GLOBAL)) {
   4270 #ifdef DEBUG
   4271 		if (dip != NULL) {
   4272 			cmn_err(CE_WARN, "%s: invalid flag 0x%x "
   4273 			    "(prop = %s, node = %s%d); invalid bits ignored",
   4274 			    "ddi_prop_lookup_string", flags, name,
   4275 			    ddi_driver_name(dip), ddi_get_instance(dip));
   4276 		}
   4277 #endif /* DEBUG */
   4278 		flags &= DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4279 		    LDI_DEV_T_ANY | DDI_UNBND_DLPI2;
   4280 	}
   4281 
   4282 	return (ddi_prop_lookup_common(match_dev, dip,
   4283 	    (flags | DDI_PROP_TYPE_STRING), name, data,
   4284 	    &x, ddi_prop_fm_decode_string));
   4285 }
   4286 
   4287 /*
   4288  * Get an array of strings property.
   4289  */
   4290 int
   4291 ddi_prop_lookup_string_array(dev_t match_dev, dev_info_t *dip, uint_t flags,
   4292     char *name, char ***data, uint_t *nelements)
   4293 {
   4294 	if (flags & ~(DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4295 	    LDI_DEV_T_ANY | DDI_UNBND_DLPI2 | DDI_PROP_ROOTNEX_GLOBAL)) {
   4296 #ifdef DEBUG
   4297 		if (dip != NULL) {
   4298 			cmn_err(CE_WARN, "ddi_prop_lookup_string_array: "
   4299 			    "invalid flag 0x%x (prop = %s, node = %s%d)",
   4300 			    flags, name, ddi_driver_name(dip),
   4301 			    ddi_get_instance(dip));
   4302 		}
   4303 #endif /* DEBUG */
   4304 		flags &= DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4305 		    LDI_DEV_T_ANY | DDI_UNBND_DLPI2;
   4306 	}
   4307 
   4308 	return (ddi_prop_lookup_common(match_dev, dip,
   4309 	    (flags | DDI_PROP_TYPE_STRING), name, data,
   4310 	    nelements, ddi_prop_fm_decode_strings));
   4311 }
   4312 
   4313 /*
   4314  * Update a single string property.
   4315  */
   4316 int
   4317 ddi_prop_update_string(dev_t match_dev, dev_info_t *dip,
   4318     char *name, char *data)
   4319 {
   4320 	return (ddi_prop_update_common(match_dev, dip,
   4321 	    DDI_PROP_TYPE_STRING, name, &data, 1,
   4322 	    ddi_prop_fm_encode_string));
   4323 }
   4324 
   4325 int
   4326 e_ddi_prop_update_string(dev_t match_dev, dev_info_t *dip,
   4327     char *name, char *data)
   4328 {
   4329 	return (ddi_prop_update_common(match_dev, dip,
   4330 	    DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_STRING,
   4331 	    name, &data, 1, ddi_prop_fm_encode_string));
   4332 }
   4333 
   4334 
   4335 /*
   4336  * Update an array of strings property.
   4337  */
   4338 int
   4339 ddi_prop_update_string_array(dev_t match_dev, dev_info_t *dip,
   4340     char *name, char **data, uint_t nelements)
   4341 {
   4342 	return (ddi_prop_update_common(match_dev, dip,
   4343 	    DDI_PROP_TYPE_STRING, name, data, nelements,
   4344 	    ddi_prop_fm_encode_strings));
   4345 }
   4346 
   4347 int
   4348 e_ddi_prop_update_string_array(dev_t match_dev, dev_info_t *dip,
   4349     char *name, char **data, uint_t nelements)
   4350 {
   4351 	return (ddi_prop_update_common(match_dev, dip,
   4352 	    DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_STRING,
   4353 	    name, data, nelements,
   4354 	    ddi_prop_fm_encode_strings));
   4355 }
   4356 
   4357 
   4358 /*
   4359  * Get an array of bytes property.
   4360  */
   4361 int
   4362 ddi_prop_lookup_byte_array(dev_t match_dev, dev_info_t *dip, uint_t flags,
   4363     char *name, uchar_t **data, uint_t *nelements)
   4364 {
   4365 	if (flags & ~(DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4366 	    LDI_DEV_T_ANY | DDI_UNBND_DLPI2 | DDI_PROP_ROOTNEX_GLOBAL)) {
   4367 #ifdef DEBUG
   4368 		if (dip != NULL) {
   4369 			cmn_err(CE_WARN, "ddi_prop_lookup_byte_array: "
   4370 			    " invalid flag 0x%x (prop = %s, node = %s%d)",
   4371 			    flags, name, ddi_driver_name(dip),
   4372 			    ddi_get_instance(dip));
   4373 		}
   4374 #endif /* DEBUG */
   4375 		flags &= DDI_PROP_DONTPASS | DDI_PROP_NOTPROM |
   4376 		    LDI_DEV_T_ANY | DDI_UNBND_DLPI2;
   4377 	}
   4378 
   4379 	return (ddi_prop_lookup_common(match_dev, dip,
   4380 	    (flags | DDI_PROP_TYPE_BYTE), name, data,
   4381 	    nelements, ddi_prop_fm_decode_bytes));
   4382 }
   4383 
   4384 /*
   4385  * Update an array of bytes property.
   4386  */
   4387 int
   4388 ddi_prop_update_byte_array(dev_t match_dev, dev_info_t *dip,
   4389     char *name, uchar_t *data, uint_t nelements)
   4390 {
   4391 	if (nelements == 0)
   4392 		return (DDI_PROP_INVAL_ARG);
   4393 
   4394 	return (ddi_prop_update_common(match_dev, dip, DDI_PROP_TYPE_BYTE,
   4395 	    name, data, nelements, ddi_prop_fm_encode_bytes));
   4396 }
   4397 
   4398 
   4399 int
   4400 e_ddi_prop_update_byte_array(dev_t match_dev, dev_info_t *dip,
   4401     char *name, uchar_t *data, uint_t nelements)
   4402 {
   4403 	if (nelements == 0)
   4404 		return (DDI_PROP_INVAL_ARG);
   4405 
   4406 	return (ddi_prop_update_common(match_dev, dip,
   4407 	    DDI_PROP_SYSTEM_DEF | DDI_PROP_TYPE_BYTE,
   4408 	    name, data, nelements, ddi_prop_fm_encode_bytes));
   4409 }
   4410 
   4411 
   4412 /*
   4413  * ddi_prop_remove_common:	Undefine a managed property:
   4414  *			Input dev_t must match dev_t when defined.
   4415  *			Returns DDI_PROP_NOT_FOUND, possibly.
   4416  *			DDI_PROP_INVAL_ARG is also possible if dev is
   4417  *			DDI_DEV_T_ANY or incoming name is the NULL string.
   4418  */
   4419 int
   4420 ddi_prop_remove_common(dev_t dev, dev_info_t *dip, char *name, int flag)
   4421 {
   4422 	ddi_prop_t	**list_head = &(DEVI(dip)->devi_drv_prop_ptr);
   4423 	ddi_prop_t	*propp;
   4424 	ddi_prop_t	*lastpropp = NULL;
   4425 
   4426 	if ((dev == DDI_DEV_T_ANY) || (name == (char *)0) ||
   4427 	    (strlen(name) == 0)) {
   4428 		return (DDI_PROP_INVAL_ARG);
   4429 	}
   4430 
   4431 	if (flag & DDI_PROP_SYSTEM_DEF)
   4432 		list_head = &(DEVI(dip)->devi_sys_prop_ptr);
   4433 	else if (flag & DDI_PROP_HW_DEF)
   4434 		list_head = &(DEVI(dip)->devi_hw_prop_ptr);
   4435 
   4436 	mutex_enter(&(DEVI(dip)->devi_lock));
   4437 
   4438 	for (propp = *list_head; propp != NULL; propp = propp->prop_next)  {
   4439 		if (DDI_STRSAME(propp->prop_name, name) &&
   4440 		    (dev == propp->prop_dev)) {
   4441 			/*
   4442 			 * Unlink this propp allowing for it to
   4443 			 * be first in the list:
   4444 			 */
   4445 
   4446 			if (lastpropp == NULL)
   4447 				*list_head = propp->prop_next;
   4448 			else
   4449 				lastpropp->prop_next = propp->prop_next;
   4450 
   4451 			mutex_exit(&(DEVI(dip)->devi_lock));
   4452 
   4453 			/*
   4454 			 * Free memory and return...
   4455 			 */
   4456 			kmem_free(propp->prop_name,
   4457 			    strlen(propp->prop_name) + 1);
   4458 			if (propp->prop_len != 0)
   4459 				kmem_free(propp->prop_val, propp->prop_len);
   4460 			kmem_free(propp, sizeof (ddi_prop_t));
   4461 			return (DDI_PROP_SUCCESS);
   4462 		}
   4463 		lastpropp = propp;
   4464 	}
   4465 	mutex_exit(&(DEVI(dip)->devi_lock));
   4466 	return (DDI_PROP_NOT_FOUND);
   4467 }
   4468 
   4469 int
   4470 ddi_prop_remove(dev_t dev, dev_info_t *dip, char *name)
   4471 {
   4472 	return (ddi_prop_remove_common(dev, dip, name, 0));
   4473 }
   4474 
   4475 int
   4476 e_ddi_prop_remove(dev_t dev, dev_info_t *dip, char *name)
   4477 {
   4478 	return (ddi_prop_remove_common(dev, dip, name, DDI_PROP_SYSTEM_DEF));
   4479 }
   4480 
   4481 /*
   4482  * e_ddi_prop_list_delete: remove a list of properties
   4483  *	Note that the caller needs to provide the required protection
   4484  *	(eg. devi_lock if these properties are still attached to a devi)
   4485  */
   4486 void
   4487 e_ddi_prop_list_delete(ddi_prop_t *props)
   4488 {
   4489 	i_ddi_prop_list_delete(props);
   4490 }
   4491 
   4492 /*
   4493  * ddi_prop_remove_all_common:
   4494  *	Used before unloading a driver to remove
   4495  *	all properties. (undefines all dev_t's props.)
   4496  *	Also removes `explicitly undefined' props.
   4497  *	No errors possible.
   4498  */
   4499 void
   4500 ddi_prop_remove_all_common(dev_info_t *dip, int flag)
   4501 {
   4502 	ddi_prop_t	**list_head;
   4503 
   4504 	mutex_enter(&(DEVI(dip)->devi_lock));
   4505 	if (flag & DDI_PROP_SYSTEM_DEF) {
   4506 		list_head = &(DEVI(dip)->devi_sys_prop_ptr);
   4507 	} else if (flag & DDI_PROP_HW_DEF) {
   4508 		list_head = &(DEVI(dip)->devi_hw_prop_ptr);
   4509 	} else {
   4510 		list_head = &(DEVI(dip)->devi_drv_prop_ptr);
   4511 	}
   4512 	i_ddi_prop_list_delete(*list_head);
   4513 	*list_head = NULL;
   4514 	mutex_exit(&(DEVI(dip)->devi_lock));
   4515 }
   4516 
   4517 
   4518 /*
   4519  * ddi_prop_remove_all:		Remove all driver prop definitions.
   4520  */
   4521 
   4522 void
   4523 ddi_prop_remove_all(dev_info_t *dip)
   4524 {
   4525 	i_ddi_prop_dyn_driver_set(dip, NULL);
   4526 	ddi_prop_remove_all_common(dip, 0);
   4527 }
   4528 
   4529 /*
   4530  * e_ddi_prop_remove_all:	Remove all system prop definitions.
   4531  */
   4532 
   4533 void
   4534 e_ddi_prop_remove_all(dev_info_t *dip)
   4535 {
   4536 	ddi_prop_remove_all_common(dip, (int)DDI_PROP_SYSTEM_DEF);
   4537 }
   4538 
   4539 
   4540 /*
   4541  * ddi_prop_undefine:	Explicitly undefine a property.  Property
   4542  *			searches which match this property return
   4543  *			the error code DDI_PROP_UNDEFINED.
   4544  *
   4545  *			Use ddi_prop_remove to negate effect of
   4546  *			ddi_prop_undefine
   4547  *
   4548  *			See above for error returns.
   4549  */
   4550 
   4551 int
   4552 ddi_prop_undefine(dev_t dev, dev_info_t *dip, int flag, char *name)
   4553 {
   4554 	if (!(flag & DDI_PROP_CANSLEEP))
   4555 		flag |= DDI_PROP_DONTSLEEP;
   4556 	flag |= DDI_PROP_STACK_CREATE | DDI_PROP_UNDEF_IT | DDI_PROP_TYPE_ANY;
   4557 	return (ddi_prop_update_common(dev, dip, flag,
   4558 	    name, NULL, 0, ddi_prop_fm_encode_bytes));
   4559 }
   4560 
   4561 int
   4562 e_ddi_prop_undefine(dev_t dev, dev_info_t *dip, int flag, char *name)
   4563 {
   4564 	if (!(flag & DDI_PROP_CANSLEEP))
   4565 		flag |= DDI_PROP_DONTSLEEP;
   4566 	flag |= DDI_PROP_SYSTEM_DEF | DDI_PROP_STACK_CREATE |
   4567 	    DDI_PROP_UNDEF_IT | DDI_PROP_TYPE_ANY;
   4568 	return (ddi_prop_update_common(dev, dip, flag,
   4569 	    name, NULL, 0, ddi_prop_fm_encode_bytes));
   4570 }
   4571 
   4572 /*
   4573  * Support for gathering dynamic properties in devinfo snapshot.
   4574  */
   4575 void
   4576 i_ddi_prop_dyn_driver_set(dev_info_t *dip, i_ddi_prop_dyn_t *dp)
   4577 {
   4578 	DEVI(dip)->devi_prop_dyn_driver = dp;
   4579 }
   4580 
   4581 i_ddi_prop_dyn_t *
   4582 i_ddi_prop_dyn_driver_get(dev_info_t *dip)
   4583 {
   4584 	return (DEVI(dip)->devi_prop_dyn_driver);
   4585 }
   4586 
   4587 void
   4588 i_ddi_prop_dyn_parent_set(dev_info_t *dip, i_ddi_prop_dyn_t *dp)
   4589 {
   4590 	DEVI(dip)->devi_prop_dyn_parent = dp;
   4591 }
   4592 
   4593 i_ddi_prop_dyn_t *
   4594 i_ddi_prop_dyn_parent_get(dev_info_t *dip)
   4595 {
   4596 	return (DEVI(dip)->devi_prop_dyn_parent);
   4597 }
   4598 
   4599 void
   4600 i_ddi_prop_dyn_cache_invalidate(dev_info_t *dip, i_ddi_prop_dyn_t *dp)
   4601 {
   4602 	/* for now we invalidate the entire cached snapshot */
   4603 	if (dip && dp)
   4604 		i_ddi_di_cache_invalidate();
   4605 }
   4606 
   4607 /* ARGSUSED */
   4608 void
   4609 ddi_prop_cache_invalidate(dev_t dev, dev_info_t *dip, char *name, int flags)
   4610 {
   4611 	/* for now we invalidate the entire cached snapshot */
   4612 	i_ddi_di_cache_invalidate();
   4613 }
   4614 
   4615 
   4616 /*
   4617  * Code to search hardware layer (PROM), if it exists, on behalf of child.
   4618  *
   4619  * if input dip != child_dip, then call is on behalf of child
   4620  * to search PROM, do it via ddi_prop_search_common() and ascend only
   4621  * if allowed.
   4622  *
   4623  * if input dip == ch_dip (child_dip), call is on behalf of root driver,
   4624  * to search for PROM defined props only.
   4625  *
   4626  * Note that the PROM search is done only if the requested dev
   4627  * is either DDI_DEV_T_ANY or DDI_DEV_T_NONE. PROM properties
   4628  * have no associated dev, thus are automatically associated with
   4629  * DDI_DEV_T_NONE.
   4630  *
   4631  * Modifying flag DDI_PROP_NOTPROM inhibits the search in the h/w layer.
   4632  *
   4633  * Returns DDI_PROP_FOUND_1275 if found to indicate to framework
   4634  * that the property resides in the prom.
   4635  */
   4636 int
   4637 impl_ddi_bus_prop_op(dev_t dev, dev_info_t *dip, dev_info_t *ch_dip,
   4638     ddi_prop_op_t prop_op, int mod_flags,
   4639     char *name, caddr_t valuep, int *lengthp)
   4640 {
   4641 	int	len;
   4642 	caddr_t buffer;
   4643 
   4644 	/*
   4645 	 * If requested dev is DDI_DEV_T_NONE or DDI_DEV_T_ANY, then
   4646 	 * look in caller's PROM if it's a self identifying device...
   4647 	 *
   4648 	 * Note that this is very similar to ddi_prop_op, but we
   4649 	 * search the PROM instead of the s/w defined properties,
   4650 	 * and we are called on by the parent driver to do this for
   4651 	 * the child.
   4652 	 */
   4653 
   4654 	if (((dev == DDI_DEV_T_NONE) || (dev == DDI_DEV_T_ANY)) &&
   4655 	    ndi_dev_is_prom_node(ch_dip) &&
   4656 	    ((mod_flags & DDI_PROP_NOTPROM) == 0)) {
   4657 		len = prom_getproplen((pnode_t)DEVI(ch_dip)->devi_nodeid, name);
   4658 		if (len == -1) {
   4659 			return (DDI_PROP_NOT_FOUND);
   4660 		}
   4661 
   4662 		/*
   4663 		 * If exists only request, we're done
   4664 		 */
   4665 		if (prop_op == PROP_EXISTS) {
   4666 			return (DDI_PROP_FOUND_1275);
   4667 		}
   4668 
   4669 		/*
   4670 		 * If length only request or prop length == 0, get out
   4671 		 */
   4672 		if ((prop_op == PROP_LEN) || (len == 0)) {
   4673 			*lengthp = len;
   4674 			return (DDI_PROP_FOUND_1275);
   4675 		}
   4676 
   4677 		/*
   4678 		 * Allocate buffer if required... (either way `buffer'
   4679 		 * is receiving address).
   4680 		 */
   4681 
   4682 		switch (prop_op) {
   4683 
   4684 		case PROP_LEN_AND_VAL_ALLOC:
   4685 
   4686 			buffer = kmem_alloc((size_t)len,
   4687 			    mod_flags & DDI_PROP_CANSLEEP ?
   4688 			    KM_SLEEP : KM_NOSLEEP);
   4689 			if (buffer == NULL) {
   4690 				return (DDI_PROP_NO_MEMORY);
   4691 			}
   4692 			*(caddr_t *)valuep = buffer;
   4693 			break;
   4694 
   4695 		case PROP_LEN_AND_VAL_BUF:
   4696 
   4697 			if (len > (*lengthp)) {
   4698 				*lengthp = len;
   4699 				return (DDI_PROP_BUF_TOO_SMALL);
   4700 			}
   4701 
   4702 			buffer = valuep;
   4703 			break;
   4704 
   4705 		default:
   4706 			break;
   4707 		}
   4708 
   4709 		/*
   4710 		 * Call the PROM function to do the copy.
   4711 		 */
   4712 		(void) prom_getprop((pnode_t)DEVI(ch_dip)->devi_nodeid,
   4713 		    name, buffer);
   4714 
   4715 		*lengthp = len; /* return the actual length to the caller */
   4716 		(void) impl_fix_props(dip, ch_dip, name, len, buffer);
   4717 		return (DDI_PROP_FOUND_1275);
   4718 	}
   4719 
   4720 	return (DDI_PROP_NOT_FOUND);
   4721 }
   4722 
   4723 /*
   4724  * The ddi_bus_prop_op default bus nexus prop op function.
   4725  *
   4726  * Code to search hardware layer (PROM), if it exists,
   4727  * on behalf of child, then, if appropriate, ascend and check
   4728  * my own software defined properties...
   4729  */
   4730 int
   4731 ddi_bus_prop_op(dev_t dev, dev_info_t *dip, dev_info_t *ch_dip,
   4732     ddi_prop_op_t prop_op, int mod_flags,
   4733     char *name, caddr_t valuep, int *lengthp)
   4734 {
   4735 	int	error;
   4736 
   4737 	error = impl_ddi_bus_prop_op(dev, dip, ch_dip, prop_op, mod_flags,
   4738 	    name, valuep, lengthp);
   4739 
   4740 	if (error == DDI_PROP_SUCCESS || error == DDI_PROP_FOUND_1275 ||
   4741 	    error == DDI_PROP_BUF_TOO_SMALL)
   4742 		return (error);
   4743 
   4744 	if (error == DDI_PROP_NO_MEMORY) {
   4745 		cmn_err(CE_CONT, prop_no_mem_msg, name);
   4746 		return (DDI_PROP_NO_MEMORY);
   4747 	}
   4748 
   4749 	/*
   4750 	 * Check the 'options' node as a last resort
   4751 	 */
   4752 	if ((mod_flags & DDI_PROP_DONTPASS) != 0)
   4753 		return (DDI_PROP_NOT_FOUND);
   4754 
   4755 	if (ch_dip == ddi_root_node())	{
   4756 		/*
   4757 		 * As a last resort, when we've reached
   4758 		 * the top and still haven't found the
   4759 		 * property, see if the desired property
   4760 		 * is attached to the options node.
   4761 		 *
   4762 		 * The options dip is attached right after boot.
   4763 		 */
   4764 		ASSERT(options_dip != NULL);
   4765 		/*
   4766 		 * Force the "don't pass" flag to *just* see
   4767 		 * what the options node has to offer.
   4768 		 */
   4769 		return (ddi_prop_search_common(dev, options_dip, prop_op,
   4770 		    mod_flags|DDI_PROP_DONTPASS, name, valuep,
   4771 		    (uint_t *)lengthp));
   4772 	}
   4773 
   4774 	/*
   4775 	 * Otherwise, continue search with parent's s/w defined properties...
   4776 	 * NOTE: Using `dip' in following call increments the level.
   4777 	 */
   4778 
   4779 	return (ddi_prop_search_common(dev, dip, prop_op, mod_flags,
   4780 	    name, valuep, (uint_t *)lengthp));
   4781 }
   4782 
   4783 /*
   4784  * External property functions used by other parts of the kernel...
   4785  */
   4786 
   4787 /*
   4788  * e_ddi_getlongprop: See comments for ddi_get_longprop.
   4789  */
   4790 
   4791 int
   4792 e_ddi_getlongprop(dev_t dev, vtype_t type, char *name, int flags,
   4793     caddr_t valuep, int *lengthp)
   4794 {
   4795 	_NOTE(ARGUNUSED(type))
   4796 	dev_info_t *devi;
   4797 	ddi_prop_op_t prop_op = PROP_LEN_AND_VAL_ALLOC;
   4798 	int error;
   4799 
   4800 	if ((devi = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
   4801 		return (DDI_PROP_NOT_FOUND);
   4802 
   4803 	error = cdev_prop_op(dev, devi, prop_op, flags, name, valuep, lengthp);
   4804 	ddi_release_devi(devi);
   4805 	return (error);
   4806 }
   4807 
   4808 /*
   4809  * e_ddi_getlongprop_buf:	See comments for ddi_getlongprop_buf.
   4810  */
   4811 
   4812 int
   4813 e_ddi_getlongprop_buf(dev_t dev, vtype_t type, char *name, int flags,
   4814     caddr_t valuep, int *lengthp)
   4815 {
   4816 	_NOTE(ARGUNUSED(type))
   4817 	dev_info_t *devi;
   4818 	ddi_prop_op_t prop_op = PROP_LEN_AND_VAL_BUF;
   4819 	int error;
   4820 
   4821 	if ((devi = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
   4822 		return (DDI_PROP_NOT_FOUND);
   4823 
   4824 	error = cdev_prop_op(dev, devi, prop_op, flags, name, valuep, lengthp);
   4825 	ddi_release_devi(devi);
   4826 	return (error);
   4827 }
   4828 
   4829 /*
   4830  * e_ddi_getprop:	See comments for ddi_getprop.
   4831  */
   4832 int
   4833 e_ddi_getprop(dev_t dev, vtype_t type, char *name, int flags, int defvalue)
   4834 {
   4835 	_NOTE(ARGUNUSED(type))
   4836 	dev_info_t *devi;
   4837 	ddi_prop_op_t prop_op = PROP_LEN_AND_VAL_BUF;
   4838 	int	propvalue = defvalue;
   4839 	int	proplength = sizeof (int);
   4840 	int	error;
   4841 
   4842 	if ((devi = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
   4843 		return (defvalue);
   4844 
   4845 	error = cdev_prop_op(dev, devi, prop_op,
   4846 	    flags, name, (caddr_t)&propvalue, &proplength);
   4847 	ddi_release_devi(devi);
   4848 
   4849 	if ((error == DDI_PROP_SUCCESS) && (proplength == 0))
   4850 		propvalue = 1;
   4851 
   4852 	return (propvalue);
   4853 }
   4854 
   4855 /*
   4856  * e_ddi_getprop_int64:
   4857  *
   4858  * This is a typed interfaces, but predates typed properties. With the
   4859  * introduction of typed properties the framework tries to ensure
   4860  * consistent use of typed interfaces. This is why TYPE_INT64 is not
   4861  * part of TYPE_ANY.  E_ddi_getprop_int64 is a special case where a
   4862  * typed interface invokes legacy (non-typed) interfaces:
   4863  * cdev_prop_op(), prop_op(9E), ddi_prop_op(9F)).  In this case the
   4864  * fact that TYPE_INT64 is not part of TYPE_ANY matters.  To support
   4865  * this type of lookup as a single operation we invoke the legacy
   4866  * non-typed interfaces with the special CONSUMER_TYPED bit set. The
   4867  * framework ddi_prop_op(9F) implementation is expected to check for
   4868  * CONSUMER_TYPED and, if set, expand type bits beyond TYPE_ANY
   4869  * (currently TYPE_INT64).
   4870  */
   4871 int64_t
   4872 e_ddi_getprop_int64(dev_t dev, vtype_t type, char *name,
   4873     int flags, int64_t defvalue)
   4874 {
   4875 	_NOTE(ARGUNUSED(type))
   4876 	dev_info_t	*devi;
   4877 	ddi_prop_op_t	prop_op = PROP_LEN_AND_VAL_BUF;
   4878 	int64_t		propvalue = defvalue;
   4879 	int		proplength = sizeof (propvalue);
   4880 	int		error;
   4881 
   4882 	if ((devi = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
   4883 		return (defvalue);
   4884 
   4885 	error = cdev_prop_op(dev, devi, prop_op, flags |
   4886 	    DDI_PROP_CONSUMER_TYPED, name, (caddr_t)&propvalue, &proplength);
   4887 	ddi_release_devi(devi);
   4888 
   4889 	if ((error == DDI_PROP_SUCCESS) && (proplength == 0))
   4890 		propvalue = 1;
   4891 
   4892 	return (propvalue);
   4893 }
   4894 
   4895 /*
   4896  * e_ddi_getproplen:	See comments for ddi_getproplen.
   4897  */
   4898 int
   4899 e_ddi_getproplen(dev_t dev, vtype_t type, char *name, int flags, int *lengthp)
   4900 {
   4901 	_NOTE(ARGUNUSED(type))
   4902 	dev_info_t *devi;
   4903 	ddi_prop_op_t prop_op = PROP_LEN;
   4904 	int error;
   4905 
   4906 	if ((devi = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
   4907 		return (DDI_PROP_NOT_FOUND);
   4908 
   4909 	error = cdev_prop_op(dev, devi, prop_op, flags, name, NULL, lengthp);
   4910 	ddi_release_devi(devi);
   4911 	return (error);
   4912 }
   4913 
   4914 /*
   4915  * Routines to get at elements of the dev_info structure
   4916  */
   4917 
   4918 /*
   4919  * ddi_binding_name: Return the driver binding name of the devinfo node
   4920  *		This is the name the OS used to bind the node to a driver.
   4921  */
   4922 char *
   4923 ddi_binding_name(dev_info_t *dip)
   4924 {
   4925 	return (DEVI(dip)->devi_binding_name);
   4926 }
   4927 
   4928 /*
   4929  * ddi_driver_major: Return the major number of the driver that
   4930  *	the supplied devinfo is bound to.  If not yet bound,
   4931  *	DDI_MAJOR_T_NONE.
   4932  *
   4933  * When used by the driver bound to 'devi', this
   4934  * function will reliably return the driver major number.
   4935  * Other ways of determining the driver major number, such as
   4936  *	major = ddi_name_to_major(ddi_get_name(devi));
   4937  *	major = ddi_name_to_major(ddi_binding_name(devi));
   4938  * can return a different result as the driver/alias binding
   4939  * can change dynamically, and thus should be avoided.
   4940  */
   4941 major_t
   4942 ddi_driver_major(dev_info_t *devi)
   4943 {
   4944 	return (DEVI(devi)->devi_major);
   4945 }
   4946 
   4947 /*
   4948  * ddi_driver_name: Return the normalized driver name. this is the
   4949  *		actual driver name
   4950  */
   4951 const char *
   4952 ddi_driver_name(dev_info_t *devi)
   4953 {
   4954 	major_t major;
   4955 
   4956 	if ((major = ddi_driver_major(devi)) != DDI_MAJOR_T_NONE)
   4957 		return (ddi_major_to_name(major));
   4958 
   4959 	return (ddi_node_name(devi));
   4960 }
   4961 
   4962 /*
   4963  * i_ddi_set_binding_name:	Set binding name.
   4964  *
   4965  *	Set the binding name to the given name.
   4966  *	This routine is for use by the ddi implementation, not by drivers.
   4967  */
   4968 void
   4969 i_ddi_set_binding_name(dev_info_t *dip, char *name)
   4970 {
   4971 	DEVI(dip)->devi_binding_name = name;
   4972 
   4973 }
   4974 
   4975 /*
   4976  * ddi_get_name: A synonym of ddi_binding_name() ... returns a name
   4977  * the implementation has used to bind the node to a driver.
   4978  */
   4979 char *
   4980 ddi_get_name(dev_info_t *dip)
   4981 {
   4982 	return (DEVI(dip)->devi_binding_name);
   4983 }
   4984 
   4985 /*
   4986  * ddi_node_name: Return the name property of the devinfo node
   4987  *		This may differ from ddi_binding_name if the node name
   4988  *		does not define a binding to a driver (i.e. generic names).
   4989  */
   4990 char *
   4991 ddi_node_name(dev_info_t *dip)
   4992 {
   4993 	return (DEVI(dip)->devi_node_name);
   4994 }
   4995 
   4996 
   4997 /*
   4998  * ddi_get_nodeid:	Get nodeid stored in dev_info structure.
   4999  */
   5000 int
   5001 ddi_get_nodeid(dev_info_t *dip)
   5002 {
   5003 	return (DEVI(dip)->devi_nodeid);
   5004 }
   5005 
   5006 int
   5007 ddi_get_instance(dev_info_t *dip)
   5008 {
   5009 	return (DEVI(dip)->devi_instance);
   5010 }
   5011 
   5012 struct dev_ops *
   5013 ddi_get_driver(dev_info_t *dip)
   5014 {
   5015 	return (DEVI(dip)->devi_ops);
   5016 }
   5017 
   5018 void
   5019 ddi_set_driver(dev_info_t *dip, struct dev_ops *devo)
   5020 {
   5021 	DEVI(dip)->devi_ops = devo;
   5022 }
   5023 
   5024 /*
   5025  * ddi_set_driver_private/ddi_get_driver_private:
   5026  * Get/set device driver private data in devinfo.
   5027  */
   5028 void
   5029 ddi_set_driver_private(dev_info_t *dip, void *data)
   5030 {
   5031 	DEVI(dip)->devi_driver_data = data;
   5032 }
   5033 
   5034 void *
   5035 ddi_get_driver_private(dev_info_t *dip)
   5036 {
   5037 	return (DEVI(dip)->devi_driver_data);
   5038 }
   5039 
   5040 /*
   5041  * ddi_get_parent, ddi_get_child, ddi_get_next_sibling
   5042  */
   5043 
   5044 dev_info_t *
   5045 ddi_get_parent(dev_info_t *dip)
   5046 {
   5047 	return ((dev_info_t *)DEVI(dip)->devi_parent);
   5048 }
   5049 
   5050 dev_info_t *
   5051 ddi_get_child(dev_info_t *dip)
   5052 {
   5053 	return ((dev_info_t *)DEVI(dip)->devi_child);
   5054 }
   5055 
   5056 dev_info_t *
   5057 ddi_get_next_sibling(dev_info_t *dip)
   5058 {
   5059 	return ((dev_info_t *)DEVI(dip)->devi_sibling);
   5060 }
   5061 
   5062 dev_info_t *
   5063 ddi_get_next(dev_info_t *dip)
   5064 {
   5065 	return ((dev_info_t *)DEVI(dip)->devi_next);
   5066 }
   5067 
   5068 void
   5069 ddi_set_next(dev_info_t *dip, dev_info_t *nextdip)
   5070 {
   5071 	DEVI(dip)->devi_next = DEVI(nextdip);
   5072 }
   5073 
   5074 /*
   5075  * ddi_root_node:		Return root node of devinfo tree
   5076  */
   5077 
   5078 dev_info_t *
   5079 ddi_root_node(void)
   5080 {
   5081 	extern dev_info_t *top_devinfo;
   5082 
   5083 	return (top_devinfo);
   5084 }
   5085 
   5086 /*
   5087  * Miscellaneous functions:
   5088  */
   5089 
   5090 /*
   5091  * Implementation specific hooks
   5092  */
   5093 
   5094 void
   5095 ddi_report_dev(dev_info_t *d)
   5096 {
   5097 	char *b;
   5098 
   5099 	(void) ddi_ctlops(d, d, DDI_CTLOPS_REPORTDEV, (void *)0, (void *)0);
   5100 
   5101 	/*
   5102 	 * If this devinfo node has cb_ops, it's implicitly accessible from
   5103 	 * userland, so we print its full name together with the instance
   5104 	 * number 'abbreviation' that the driver may use internally.
   5105 	 */
   5106 	if (DEVI(d)->devi_ops->devo_cb_ops != (struct cb_ops *)0 &&
   5107 	    (b = kmem_zalloc(MAXPATHLEN, KM_NOSLEEP))) {
   5108 		cmn_err(CE_CONT, "?%s%d is %s\n",
   5109 		    ddi_driver_name(d), ddi_get_instance(d),
   5110 		    ddi_pathname(d, b));
   5111 		kmem_free(b, MAXPATHLEN);
   5112 	}
   5113 }
   5114 
   5115 /*
   5116  * ddi_ctlops() is described in the assembler not to buy a new register
   5117  * window when it's called and can reduce cost in climbing the device tree
   5118  * without using the tail call optimization.
   5119  */
   5120 int
   5121 ddi_dev_regsize(dev_info_t *dev, uint_t rnumber, off_t *result)
   5122 {
   5123 	int ret;
   5124 
   5125 	ret = ddi_ctlops(dev, dev, DDI_CTLOPS_REGSIZE,
   5126 	    (void *)&rnumber, (void *)result);
   5127 
   5128 	return (ret == DDI_SUCCESS ? DDI_SUCCESS : DDI_FAILURE);
   5129 }
   5130 
   5131 int
   5132 ddi_dev_nregs(dev_info_t *dev, int *result)
   5133 {
   5134 	return (ddi_ctlops(dev, dev, DDI_CTLOPS_NREGS, 0, (void *)result));
   5135 }
   5136 
   5137 int
   5138 ddi_dev_is_sid(dev_info_t *d)
   5139 {
   5140 	return (ddi_ctlops(d, d, DDI_CTLOPS_SIDDEV, (void *)0, (void *)0));
   5141 }
   5142 
   5143 int
   5144 ddi_slaveonly(dev_info_t *d)
   5145 {
   5146 	return (ddi_ctlops(d, d, DDI_CTLOPS_SLAVEONLY, (void *)0, (void *)0));
   5147 }
   5148 
   5149 int
   5150 ddi_dev_affinity(dev_info_t *a, dev_info_t *b)
   5151 {
   5152 	return (ddi_ctlops(a, a, DDI_CTLOPS_AFFINITY, (void *)b, (void *)0));
   5153 }
   5154 
   5155 int
   5156 ddi_streams_driver(dev_info_t *dip)
   5157 {
   5158 	if (i_ddi_devi_attached(dip) &&
   5159 	    (DEVI(dip)->devi_ops->devo_cb_ops != NULL) &&
   5160 	    (DEVI(dip)->devi_ops->devo_cb_ops->cb_str != NULL))
   5161 		return (DDI_SUCCESS);
   5162 	return (DDI_FAILURE);
   5163 }
   5164 
   5165 /*
   5166  * callback free list
   5167  */
   5168 
   5169 static int ncallbacks;
   5170 static int nc_low = 170;
   5171 static int nc_med = 512;
   5172 static int nc_high = 2048;
   5173 static struct ddi_callback *callbackq;
   5174 static struct ddi_callback *callbackqfree;
   5175 
   5176 /*
   5177  * set/run callback lists
   5178  */
   5179 struct	cbstats	{
   5180 	kstat_named_t	cb_asked;
   5181 	kstat_named_t	cb_new;
   5182 	kstat_named_t	cb_run;
   5183 	kstat_named_t	cb_delete;
   5184 	kstat_named_t	cb_maxreq;
   5185 	kstat_named_t	cb_maxlist;
   5186 	kstat_named_t	cb_alloc;
   5187 	kstat_named_t	cb_runouts;
   5188 	kstat_named_t	cb_L2;
   5189 	kstat_named_t	cb_grow;
   5190 } cbstats = {
   5191 	{"asked",	KSTAT_DATA_UINT32},
   5192 	{"new",		KSTAT_DATA_UINT32},
   5193 	{"run",		KSTAT_DATA_UINT32},
   5194 	{"delete",	KSTAT_DATA_UINT32},
   5195 	{"maxreq",	KSTAT_DATA_UINT32},
   5196 	{"maxlist",	KSTAT_DATA_UINT32},
   5197 	{"alloc",	KSTAT_DATA_UINT32},
   5198 	{"runouts",	KSTAT_DATA_UINT32},
   5199 	{"L2",		KSTAT_DATA_UINT32},
   5200 	{"grow",	KSTAT_DATA_UINT32},
   5201 };
   5202 
   5203 #define	nc_asked	cb_asked.value.ui32
   5204 #define	nc_new		cb_new.value.ui32
   5205 #define	nc_run		cb_run.value.ui32
   5206 #define	nc_delete	cb_delete.value.ui32
   5207 #define	nc_maxreq	cb_maxreq.value.ui32
   5208 #define	nc_maxlist	cb_maxlist.value.ui32
   5209 #define	nc_alloc	cb_alloc.value.ui32
   5210 #define	nc_runouts	cb_runouts.value.ui32
   5211 #define	nc_L2		cb_L2.value.ui32
   5212 #define	nc_grow		cb_grow.value.ui32
   5213 
   5214 static kmutex_t ddi_callback_mutex;
   5215 
   5216 /*
   5217  * callbacks are handled using a L1/L2 cache. The L1 cache
   5218  * comes out of kmem_cache_alloc and can expand/shrink dynamically. If
   5219  * we can't get callbacks from the L1 cache [because pageout is doing
   5220  * I/O at the time freemem is 0], we allocate callbacks out of the
   5221  * L2 cache. The L2 cache is static and depends on the memory size.
   5222  * [We might also count the number of devices at probe time and
   5223  * allocate one structure per device and adjust for deferred attach]
   5224  */
   5225 void
   5226 impl_ddi_callback_init(void)
   5227 {
   5228 	int	i;
   5229 	uint_t	physmegs;
   5230 	kstat_t	*ksp;
   5231 
   5232 	physmegs = physmem >> (20 - PAGESHIFT);
   5233 	if (physmegs < 48) {
   5234 		ncallbacks = nc_low;
   5235 	} else if (physmegs < 128) {
   5236 		ncallbacks = nc_med;
   5237 	} else {
   5238 		ncallbacks = nc_high;
   5239 	}
   5240 
   5241 	/*
   5242 	 * init free list
   5243 	 */
   5244 	callbackq = kmem_zalloc(
   5245 	    ncallbacks * sizeof (struct ddi_callback), KM_SLEEP);
   5246 	for (i = 0; i < ncallbacks-1; i++)
   5247 		callbackq[i].c_nfree = &callbackq[i+1];
   5248 	callbackqfree = callbackq;
   5249 
   5250 	/* init kstats */
   5251 	if (ksp = kstat_create("unix", 0, "cbstats", "misc", KSTAT_TYPE_NAMED,
   5252 	    sizeof (cbstats) / sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL)) {
   5253 		ksp->ks_data = (void *) &cbstats;
   5254 		kstat_install(ksp);
   5255 	}
   5256 
   5257 }
   5258 
   5259 static void
   5260 callback_insert(int (*funcp)(caddr_t), caddr_t arg, uintptr_t *listid,
   5261 	int count)
   5262 {
   5263 	struct ddi_callback *list, *marker, *new;
   5264 	size_t size = sizeof (struct ddi_callback);
   5265 
   5266 	list = marker = (struct ddi_callback *)*listid;
   5267 	while (list != NULL) {
   5268 		if (list->c_call == funcp && list->c_arg == arg) {
   5269 			list->c_count += count;
   5270 			return;
   5271 		}
   5272 		marker = list;
   5273 		list = list->c_nlist;
   5274 	}
   5275 	new = kmem_alloc(size, KM_NOSLEEP);
   5276 	if (new == NULL) {
   5277 		new = callbackqfree;
   5278 		if (new == NULL) {
   5279 			new = kmem_alloc_tryhard(sizeof (struct ddi_callback),
   5280 			    &size, KM_NOSLEEP | KM_PANIC);
   5281 			cbstats.nc_grow++;
   5282 		} else {
   5283 			callbackqfree = new->c_nfree;
   5284 			cbstats.nc_L2++;
   5285 		}
   5286 	}
   5287 	if (marker != NULL) {
   5288 		marker->c_nlist = new;
   5289 	} else {
   5290 		*listid = (uintptr_t)new;
   5291 	}
   5292 	new->c_size = size;
   5293 	new->c_nlist = NULL;
   5294 	new->c_call = funcp;
   5295 	new->c_arg = arg;
   5296 	new->c_count = count;
   5297 	cbstats.nc_new++;
   5298 	cbstats.nc_alloc++;
   5299 	if (cbstats.nc_alloc > cbstats.nc_maxlist)
   5300 		cbstats.nc_maxlist = cbstats.nc_alloc;
   5301 }
   5302 
   5303 void
   5304 ddi_set_callback(int (*funcp)(caddr_t), caddr_t arg, uintptr_t *listid)
   5305 {
   5306 	mutex_enter(&ddi_callback_mutex);
   5307 	cbstats.nc_asked++;
   5308 	if ((cbstats.nc_asked - cbstats.nc_run) > cbstats.nc_maxreq)
   5309 		cbstats.nc_maxreq = (cbstats.nc_asked - cbstats.nc_run);
   5310 	(void) callback_insert(funcp, arg, listid, 1);
   5311 	mutex_exit(&ddi_callback_mutex);
   5312 }
   5313 
   5314 static void
   5315 real_callback_run(void *Queue)
   5316 {
   5317 	int (*funcp)(caddr_t);
   5318 	caddr_t arg;
   5319 	int count, rval;
   5320 	uintptr_t *listid;
   5321 	struct ddi_callback *list, *marker;
   5322 	int check_pending = 1;
   5323 	int pending = 0;
   5324 
   5325 	do {
   5326 		mutex_enter(&ddi_callback_mutex);
   5327 		listid = Queue;
   5328 		list = (struct ddi_callback *)*listid;
   5329 		if (list == NULL) {
   5330 			mutex_exit(&ddi_callback_mutex);
   5331 			return;
   5332 		}
   5333 		if (check_pending) {
   5334 			marker = list;
   5335 			while (marker != NULL) {
   5336 				pending += marker->c_count;
   5337 				marker = marker->c_nlist;
   5338 			}
   5339 			check_pending = 0;
   5340 		}
   5341 		ASSERT(pending > 0);
   5342 		ASSERT(list->c_count > 0);
   5343 		funcp = list->c_call;
   5344 		arg = list->c_arg;
   5345 		count = list->c_count;
   5346 		*(uintptr_t *)Queue = (uintptr_t)list->c_nlist;
   5347 		if (list >= &callbackq[0] &&
   5348 		    list <= &callbackq[ncallbacks-1]) {
   5349 			list->c_nfree = callbackqfree;
   5350 			callbackqfree = list;
   5351 		} else
   5352 			kmem_free(list, list->c_size);
   5353 
   5354 		cbstats.nc_delete++;
   5355 		cbstats.nc_alloc--;
   5356 		mutex_exit(&ddi_callback_mutex);
   5357 
   5358 		do {
   5359 			if ((rval = (*funcp)(arg)) == 0) {
   5360 				pending -= count;
   5361 				mutex_enter(&ddi_callback_mutex);
   5362 				(void) callback_insert(funcp, arg, listid,
   5363 				    count);
   5364 				cbstats.nc_runouts++;
   5365 			} else {
   5366 				pending--;
   5367 				mutex_enter(&ddi_callback_mutex);
   5368 				cbstats.nc_run++;
   5369 			}
   5370 			mutex_exit(&ddi_callback_mutex);
   5371 		} while (rval != 0 && (--count > 0));
   5372 	} while (pending > 0);
   5373 }
   5374 
   5375 void
   5376 ddi_run_callback(uintptr_t *listid)
   5377 {
   5378 	softcall(real_callback_run, listid);
   5379 }
   5380 
   5381 /*
   5382  * ddi_periodic_t
   5383  * ddi_periodic_add(void (*func)(void *), void *arg, hrtime_t interval,
   5384  *     int level)
   5385  *
   5386  * INTERFACE LEVEL
   5387  *      Solaris DDI specific (Solaris DDI)
   5388  *
   5389  * PARAMETERS
   5390  *      func: the callback function
   5391  *
   5392  *            The callback function will be invoked. The function is invoked
   5393  *            in kernel context if the argument level passed is the zero.
   5394  *            Otherwise it's invoked in interrupt context at the specified
   5395  *            level.
   5396  *
   5397  *       arg: the argument passed to the callback function
   5398  *
   5399  *  interval: interval time
   5400  *
   5401  *    level : callback interrupt level
   5402  *
   5403  *            If the value is the zero, the callback function is invoked
   5404  *            in kernel context. If the value is more than the zero, but
   5405  *            less than or equal to ten, the callback function is invoked in
   5406  *            interrupt context at the specified interrupt level, which may
   5407  *            be used for real time applications.
   5408  *
   5409  *            This value must be in range of 0-10, which can be a numeric
   5410  *            number or a pre-defined macro (DDI_IPL_0, ... , DDI_IPL_10).
   5411  *
   5412  * DESCRIPTION
   5413  *      ddi_periodic_add(9F) schedules the specified function to be
   5414  *      periodically invoked in the interval time.
   5415  *
   5416  *      As well as timeout(9F), the exact time interval over which the function
   5417  *      takes effect cannot be guaranteed, but the value given is a close
   5418  *      approximation.
   5419  *
   5420  *      Drivers waiting on behalf of processes with real-time constraints must
   5421  *      pass non-zero value with the level argument to ddi_periodic_add(9F).
   5422  *
   5423  * RETURN VALUES
   5424  *      ddi_periodic_add(9F) returns a non-zero opaque value (ddi_periodic_t),
   5425  *      which must be used for ddi_periodic_delete(9F) to specify the request.
   5426  *
   5427  * CONTEXT
   5428  *      ddi_periodic_add(9F) can be called in user or kernel context, but
   5429  *      it cannot be called in interrupt context, which is different from
   5430  *      timeout(9F).
   5431  */
   5432 ddi_periodic_t
   5433 ddi_periodic_add(void (*func)(void *), void *arg, hrtime_t interval, int level)
   5434 {
   5435 	/*
   5436 	 * Sanity check of the argument level.
   5437 	 */
   5438 	if (level < DDI_IPL_0 || level > DDI_IPL_10)
   5439 		cmn_err(CE_PANIC,
   5440 		    "ddi_periodic_add: invalid interrupt level (%d).", level);
   5441 
   5442 	/*
   5443 	 * Sanity check of the context. ddi_periodic_add() cannot be
   5444 	 * called in either interrupt context or high interrupt context.
   5445 	 */
   5446 	if (servicing_interrupt())
   5447 		cmn_err(CE_PANIC,
   5448 		    "ddi_periodic_add: called in (high) interrupt context.");
   5449 
   5450 	return ((ddi_periodic_t)i_timeout(func, arg, interval, level));
   5451 }
   5452 
   5453 /*
   5454  * void
   5455  * ddi_periodic_delete(ddi_periodic_t req)
   5456  *
   5457  * INTERFACE LEVEL
   5458  *     Solaris DDI specific (Solaris DDI)
   5459  *
   5460  * PARAMETERS
   5461  *     req: ddi_periodic_t opaque value ddi_periodic_add(9F) returned
   5462  *     previously.
   5463  *
   5464  * DESCRIPTION
   5465  *     ddi_periodic_delete(9F) cancels the ddi_periodic_add(9F) request
   5466  *     previously requested.
   5467  *
   5468  *     ddi_periodic_delete(9F) will not return until the pending request
   5469  *     is canceled or executed.
   5470  *
   5471  *     As well as untimeout(9F), calling ddi_periodic_delete(9F) for a
   5472  *     timeout which is either running on another CPU, or has already
   5473  *     completed causes no problems. However, unlike untimeout(9F), there is
   5474  *     no restrictions on the lock which might be held across the call to
   5475  *     ddi_periodic_delete(9F).
   5476  *
   5477  *     Drivers should be structured with the understanding that the arrival of
   5478  *     both an interrupt and a timeout for that interrupt can occasionally
   5479  *     occur, in either order.
   5480  *
   5481  * CONTEXT
   5482  *     ddi_periodic_delete(9F) can be called in user or kernel context, but
   5483  *     it cannot be called in interrupt context, which is different from
   5484  *     untimeout(9F).
   5485  */
   5486 void
   5487 ddi_periodic_delete(ddi_periodic_t req)
   5488 {
   5489 	/*
   5490 	 * Sanity check of the context. ddi_periodic_delete() cannot be
   5491 	 * called in either interrupt context or high interrupt context.
   5492 	 */
   5493 	if (servicing_interrupt())
   5494 		cmn_err(CE_PANIC,
   5495 		    "ddi_periodic_delete: called in (high) interrupt context.");
   5496 
   5497 	i_untimeout((timeout_t)req);
   5498 }
   5499 
   5500 dev_info_t *
   5501 nodevinfo(dev_t dev, int otyp)
   5502 {
   5503 	_NOTE(ARGUNUSED(dev, otyp))
   5504 	return ((dev_info_t *)0);
   5505 }
   5506 
   5507 /*
   5508  * A driver should support its own getinfo(9E) entry point. This function
   5509  * is provided as a convenience for ON drivers that don't expect their
   5510  * getinfo(9E) entry point to be called. A driver that uses this must not
   5511  * call ddi_create_minor_node.
   5512  */
   5513 int
   5514 ddi_no_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
   5515 {
   5516 	_NOTE(ARGUNUSED(dip, infocmd, arg, result))
   5517 	return (DDI_FAILURE);
   5518 }
   5519 
   5520 /*
   5521  * A driver should support its own getinfo(9E) entry point. This function
   5522  * is provided as a convenience for ON drivers that where the minor number
   5523  * is the instance. Drivers that do not have 1:1 mapping must implement
   5524  * their own getinfo(9E) function.
   5525  */
   5526 int
   5527 ddi_getinfo_1to1(dev_info_t *dip, ddi_info_cmd_t infocmd,
   5528     void *arg, void **result)
   5529 {
   5530 	_NOTE(ARGUNUSED(dip))
   5531 	int	instance;
   5532 
   5533 	if (infocmd != DDI_INFO_DEVT2INSTANCE)
   5534 		return (DDI_FAILURE);
   5535 
   5536 	instance = getminor((dev_t)(uintptr_t)arg);
   5537 	*result = (void *)(uintptr_t)instance;
   5538 	return (DDI_SUCCESS);
   5539 }
   5540 
   5541 int
   5542 ddifail(dev_info_t *devi, ddi_attach_cmd_t cmd)
   5543 {
   5544 	_NOTE(ARGUNUSED(devi, cmd))
   5545 	return (DDI_FAILURE);
   5546 }
   5547 
   5548 int
   5549 ddi_no_dma_map(dev_info_t *dip, dev_info_t *rdip,
   5550     struct ddi_dma_req *dmareqp, ddi_dma_handle_t *handlep)
   5551 {
   5552 	_NOTE(ARGUNUSED(dip, rdip, dmareqp, handlep))
   5553 	return (DDI_DMA_NOMAPPING);
   5554 }
   5555 
   5556 int
   5557 ddi_no_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
   5558     int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
   5559 {
   5560 	_NOTE(ARGUNUSED(dip, rdip, attr, waitfp, arg, handlep))
   5561 	return (DDI_DMA_BADATTR);
   5562 }
   5563 
   5564 int
   5565 ddi_no_dma_freehdl(dev_info_t *dip, dev_info_t *rdip,
   5566     ddi_dma_handle_t handle)
   5567 {
   5568 	_NOTE(ARGUNUSED(dip, rdip, handle))
   5569 	return (DDI_FAILURE);
   5570 }
   5571 
   5572 int
   5573 ddi_no_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
   5574     ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
   5575     ddi_dma_cookie_t *cp, uint_t *ccountp)
   5576 {
   5577 	_NOTE(ARGUNUSED(dip, rdip, handle, dmareq, cp, ccountp))
   5578 	return (DDI_DMA_NOMAPPING);
   5579 }
   5580 
   5581 int
   5582 ddi_no_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
   5583     ddi_dma_handle_t handle)
   5584 {
   5585 	_NOTE(ARGUNUSED(dip, rdip, handle))
   5586 	return (DDI_FAILURE);
   5587 }
   5588 
   5589 int
   5590 ddi_no_dma_flush(dev_info_t *dip, dev_info_t *rdip,
   5591     ddi_dma_handle_t handle, off_t off, size_t len,
   5592     uint_t cache_flags)
   5593 {
   5594 	_NOTE(ARGUNUSED(dip, rdip, handle, off, len, cache_flags))
   5595 	return (DDI_FAILURE);
   5596 }
   5597 
   5598 int
   5599 ddi_no_dma_win(dev_info_t *dip, dev_info_t *rdip,
   5600     ddi_dma_handle_t handle, uint_t win, off_t *offp,
   5601     size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
   5602 {
   5603 	_NOTE(ARGUNUSED(dip, rdip, handle, win, offp, lenp, cookiep, ccountp))
   5604 	return (DDI_FAILURE);
   5605 }
   5606 
   5607 int
   5608 ddi_no_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
   5609     ddi_dma_handle_t handle, enum ddi_dma_ctlops request,
   5610     off_t *offp, size_t *lenp, caddr_t *objp, uint_t flags)
   5611 {
   5612 	_NOTE(ARGUNUSED(dip, rdip, handle, request, offp, lenp, objp, flags))
   5613 	return (DDI_FAILURE);
   5614 }
   5615 
   5616 void
   5617 ddivoid(void)
   5618 {}
   5619 
   5620 int
   5621 nochpoll(dev_t dev, short events, int anyyet, short *reventsp,
   5622     struct pollhead **pollhdrp)
   5623 {
   5624 	_NOTE(ARGUNUSED(dev, events, anyyet, reventsp, pollhdrp))
   5625 	return (ENXIO);
   5626 }
   5627 
   5628 cred_t *
   5629 ddi_get_cred(void)
   5630 {
   5631 	return (CRED());
   5632 }
   5633 
   5634 clock_t
   5635 ddi_get_lbolt(void)
   5636 {
   5637 	return ((clock_t)lbolt_hybrid());
   5638 }
   5639 
   5640 int64_t
   5641 ddi_get_lbolt64(void)
   5642 {
   5643 	return (lbolt_hybrid());
   5644 }
   5645 
   5646 time_t
   5647 ddi_get_time(void)
   5648 {
   5649 	time_t	now;
   5650 
   5651 	if ((now = gethrestime_sec()) == 0) {
   5652 		timestruc_t ts;
   5653 		mutex_enter(&tod_lock);
   5654 		ts = tod_get();
   5655 		mutex_exit(&tod_lock);
   5656 		return (ts.tv_sec);
   5657 	} else {
   5658 		return (now);
   5659 	}
   5660 }
   5661 
   5662 pid_t
   5663 ddi_get_pid(void)
   5664 {
   5665 	return (ttoproc(curthread)->p_pid);
   5666 }
   5667 
   5668 kt_did_t
   5669 ddi_get_kt_did(void)
   5670 {
   5671 	return (curthread->t_did);
   5672 }
   5673 
   5674 /*
   5675  * This function returns B_TRUE if the caller can reasonably expect that a call
   5676  * to cv_wait_sig(9F), cv_timedwait_sig(9F), or qwait_sig(9F) could be awakened
   5677  * by user-level signal.  If it returns B_FALSE, then the caller should use
   5678  * other means to make certain that the wait will not hang "forever."
   5679  *
   5680  * It does not check the signal mask, nor for reception of any particular
   5681  * signal.
   5682  *
   5683  * Currently, a thread can receive a signal if it's not a kernel thread and it
   5684  * is not in the middle of exit(2) tear-down.  Threads that are in that
   5685  * tear-down effectively convert cv_wait_sig to cv_wait, cv_timedwait_sig to
   5686  * cv_timedwait, and qwait_sig to qwait.
   5687  */
   5688 boolean_t
   5689 ddi_can_receive_sig(void)
   5690 {
   5691 	proc_t *pp;
   5692 
   5693 	if (curthread->t_proc_flag & TP_LWPEXIT)
   5694 		return (B_FALSE);
   5695 	if ((pp = ttoproc(curthread)) == NULL)
   5696 		return (B_FALSE);
   5697 	return (pp->p_as != &kas);
   5698 }
   5699 
   5700 /*
   5701  * Swap bytes in 16-bit [half-]words
   5702  */
   5703 void
   5704 swab(void *src, void *dst, size_t nbytes)
   5705 {
   5706 	uchar_t *pf = (uchar_t *)src;
   5707 	uchar_t *pt = (uchar_t *)dst;
   5708 	uchar_t tmp;
   5709 	int nshorts;
   5710 
   5711 	nshorts = nbytes >> 1;
   5712 
   5713 	while (--nshorts >= 0) {
   5714 		tmp = *pf++;
   5715 		*pt++ = *pf++;
   5716 		*pt++ = tmp;
   5717 	}
   5718 }
   5719 
   5720 static void
   5721 ddi_append_minor_node(dev_info_t *ddip, struct ddi_minor_data *dmdp)
   5722 {
   5723 	int			circ;
   5724 	struct ddi_minor_data	*dp;
   5725 
   5726 	ndi_devi_enter(ddip, &circ);
   5727 	if ((dp = DEVI(ddip)->devi_minor) == (struct ddi_minor_data *)NULL) {
   5728 		DEVI(ddip)->devi_minor = dmdp;
   5729 	} else {
   5730 		while (dp->next != (struct ddi_minor_data *)NULL)
   5731 			dp = dp->next;
   5732 		dp->next = dmdp;
   5733 	}
   5734 	ndi_devi_exit(ddip, circ);
   5735 }
   5736 
   5737 /*
   5738  * Part of the obsolete SunCluster DDI Hooks.
   5739  * Keep for binary compatibility
   5740  */
   5741 minor_t
   5742 ddi_getiminor(dev_t dev)
   5743 {
   5744 	return (getminor(dev));
   5745 }
   5746 
   5747 static int
   5748 i_log_devfs_minor_create(dev_info_t *dip, char *minor_name)
   5749 {
   5750 	int se_flag;
   5751 	int kmem_flag;
   5752 	int se_err;
   5753 	char *pathname, *class_name;
   5754 	sysevent_t *ev = NULL;
   5755 	sysevent_id_t eid;
   5756 	sysevent_value_t se_val;
   5757 	sysevent_attr_list_t *ev_attr_list = NULL;
   5758 
   5759 	/* determine interrupt context */
   5760 	se_flag = (servicing_interrupt()) ? SE_NOSLEEP : SE_SLEEP;
   5761 	kmem_flag = (se_flag == SE_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
   5762 
   5763 	i_ddi_di_cache_invalidate();
   5764 
   5765 #ifdef DEBUG
   5766 	if ((se_flag == SE_NOSLEEP) && sunddi_debug) {
   5767 		cmn_err(CE_CONT, "ddi_create_minor_node: called from "
   5768 		    "interrupt level by driver %s",
   5769 		    ddi_driver_name(dip));
   5770 	}
   5771 #endif /* DEBUG */
   5772 
   5773 	ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_MINOR_CREATE, EP_DDI, se_flag);
   5774 	if (ev == NULL) {
   5775 		goto fail;
   5776 	}
   5777 
   5778 	pathname = kmem_alloc(MAXPATHLEN, kmem_flag);
   5779 	if (pathname == NULL) {
   5780 		sysevent_free(ev);
   5781 		goto fail;
   5782 	}
   5783 
   5784 	(void) ddi_pathname(dip, pathname);
   5785 	ASSERT(strlen(pathname));
   5786 	se_val.value_type = SE_DATA_TYPE_STRING;
   5787 	se_val.value.sv_string = pathname;
   5788 	if (sysevent_add_attr(&ev_attr_list, DEVFS_PATHNAME,
   5789 	    &se_val, se_flag) != 0) {
   5790 		kmem_free(pathname, MAXPATHLEN);
   5791 		sysevent_free(ev);
   5792 		goto fail;
   5793 	}
   5794 	kmem_free(pathname, MAXPATHLEN);
   5795 
   5796 	/* add the device class attribute */
   5797 	if ((class_name = i_ddi_devi_class(dip)) != NULL) {
   5798 		se_val.value_type = SE_DATA_TYPE_STRING;
   5799 		se_val.value.sv_string = class_name;
   5800 		if (sysevent_add_attr(&ev_attr_list,
   5801 		    DEVFS_DEVI_CLASS, &se_val, SE_SLEEP) != 0) {
   5802 			sysevent_free_attr(ev_attr_list);
   5803 			goto fail;
   5804 		}
   5805 	}
   5806 
   5807 	/*
   5808 	 * allow for NULL minor names
   5809 	 */
   5810 	if (minor_name != NULL) {
   5811 		se_val.value.sv_string = minor_name;
   5812 		if (sysevent_add_attr(&ev_attr_list, DEVFS_MINOR_NAME,
   5813 		    &se_val, se_flag) != 0) {
   5814 			sysevent_free_attr(ev_attr_list);
   5815 			sysevent_free(ev);
   5816 			goto fail;
   5817 		}
   5818 	}
   5819 
   5820 	if (sysevent_attach_attributes(ev, ev_attr_list) != 0) {
   5821 		sysevent_free_attr(ev_attr_list);
   5822 		sysevent_free(ev);
   5823 		goto fail;
   5824 	}
   5825 
   5826 	if ((se_err = log_sysevent(ev, se_flag, &eid)) != 0) {
   5827 		if (se_err == SE_NO_TRANSPORT) {
   5828 			cmn_err(CE_WARN, "/devices or /dev may not be current "
   5829 			    "for driver %s (%s). Run devfsadm -i %s",
   5830 			    ddi_driver_name(dip), "syseventd not responding",
   5831 			    ddi_driver_name(dip));
   5832 		} else {
   5833 			sysevent_free(ev);
   5834 			goto fail;
   5835 		}
   5836 	}
   5837 
   5838 	sysevent_free(ev);
   5839 	return (DDI_SUCCESS);
   5840 fail:
   5841 	cmn_err(CE_WARN, "/devices or /dev may not be current "
   5842 	    "for driver %s. Run devfsadm -i %s",
   5843 	    ddi_driver_name(dip), ddi_driver_name(dip));
   5844 	return (DDI_SUCCESS);
   5845 }
   5846 
   5847 /*
   5848  * failing to remove a minor node is not of interest
   5849  * therefore we do not generate an error message
   5850  */
   5851 static int
   5852 i_log_devfs_minor_remove(dev_info_t *dip, char *minor_name)
   5853 {
   5854 	char *pathname, *class_name;
   5855 	sysevent_t *ev;
   5856 	sysevent_id_t eid;
   5857 	sysevent_value_t se_val;
   5858 	sysevent_attr_list_t *ev_attr_list = NULL;
   5859 
   5860 	/*
   5861 	 * only log ddi_remove_minor_node() calls outside the scope
   5862 	 * of attach/detach reconfigurations and when the dip is
   5863 	 * still initialized.
   5864 	 */
   5865 	if (DEVI_IS_ATTACHING(dip) || DEVI_IS_DETACHING(dip) ||
   5866 	    (i_ddi_node_state(dip) < DS_INITIALIZED)) {
   5867 		return (DDI_SUCCESS);
   5868 	}
   5869 
   5870 	i_ddi_di_cache_invalidate();
   5871 
   5872 	ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_MINOR_REMOVE, EP_DDI, SE_SLEEP);
   5873 	if (ev == NULL) {
   5874 		return (DDI_SUCCESS);
   5875 	}
   5876 
   5877 	pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
   5878 	if (pathname == NULL) {
   5879 		sysevent_free(ev);
   5880 		return (DDI_SUCCESS);
   5881 	}
   5882 
   5883 	(void) ddi_pathname(dip, pathname);
   5884 	ASSERT(strlen(pathname));
   5885 	se_val.value_type = SE_DATA_TYPE_STRING;
   5886 	se_val.value.sv_string = pathname;
   5887 	if (sysevent_add_attr(&ev_attr_list, DEVFS_PATHNAME,
   5888 	    &se_val, SE_SLEEP) != 0) {
   5889 		kmem_free(pathname, MAXPATHLEN);
   5890 		sysevent_free(ev);
   5891 		return (DDI_SUCCESS);
   5892 	}
   5893 
   5894 	kmem_free(pathname, MAXPATHLEN);
   5895 
   5896 	/*
   5897 	 * allow for NULL minor names
   5898 	 */
   5899 	if (minor_name != NULL) {
   5900 		se_val.value.sv_string = minor_name;
   5901 		if (sysevent_add_attr(&ev_attr_list, DEVFS_MINOR_NAME,
   5902 		    &se_val, SE_SLEEP) != 0) {
   5903 			sysevent_free_attr(ev_attr_list);
   5904 			goto fail;
   5905 		}
   5906 	}
   5907 
   5908 	if ((class_name = i_ddi_devi_class(dip)) != NULL) {
   5909 		/* add the device class, driver name and instance attributes */
   5910 
   5911 		se_val.value_type = SE_DATA_TYPE_STRING;
   5912 		se_val.value.sv_string = class_name;
   5913 		if (sysevent_add_attr(&ev_attr_list,
   5914 		    DEVFS_DEVI_CLASS, &se_val, SE_SLEEP) != 0) {
   5915 			sysevent_free_attr(ev_attr_list);
   5916 			goto fail;
   5917 		}
   5918 
   5919 		se_val.value_type = SE_DATA_TYPE_STRING;
   5920 		se_val.value.sv_string = (char *)ddi_driver_name(dip);
   5921 		if (sysevent_add_attr(&ev_attr_list,
   5922 		    DEVFS_DRIVER_NAME, &se_val, SE_SLEEP) != 0) {
   5923 			sysevent_free_attr(ev_attr_list);
   5924 			goto fail;
   5925 		}
   5926 
   5927 		se_val.value_type = SE_DATA_TYPE_INT32;
   5928 		se_val.value.sv_int32 = ddi_get_instance(dip);
   5929 		if (sysevent_add_attr(&ev_attr_list,
   5930 		    DEVFS_INSTANCE, &se_val, SE_SLEEP) != 0) {
   5931 			sysevent_free_attr(ev_attr_list);
   5932 			goto fail;
   5933 		}
   5934 
   5935 	}
   5936 
   5937 	if (sysevent_attach_attributes(ev, ev_attr_list) != 0) {
   5938 		sysevent_free_attr(ev_attr_list);
   5939 	} else {
   5940 		(void) log_sysevent(ev, SE_SLEEP, &eid);
   5941 	}
   5942 fail:
   5943 	sysevent_free(ev);
   5944 	return (DDI_SUCCESS);
   5945 }
   5946 
   5947 /*
   5948  * Derive the device class of the node.
   5949  * Device class names aren't defined yet. Until this is done we use
   5950  * devfs event subclass names as device class names.
   5951  */
   5952 static int
   5953 derive_devi_class(dev_info_t *dip, char *node_type, int flag)
   5954 {
   5955 	int rv = DDI_SUCCESS;
   5956 
   5957 	if (i_ddi_devi_class(dip) == NULL) {
   5958 		if (strncmp(node_type, DDI_NT_BLOCK,
   5959 		    sizeof (DDI_NT_BLOCK) - 1) == 0 &&
   5960 		    (node_type[sizeof (DDI_NT_BLOCK) - 1] == '\0' ||
   5961 		    node_type[sizeof (DDI_NT_BLOCK) - 1] == ':') &&
   5962 		    strcmp(node_type, DDI_NT_FD) != 0) {
   5963 
   5964 			rv = i_ddi_set_devi_class(dip, ESC_DISK, flag);
   5965 
   5966 		} else if (strncmp(node_type, DDI_NT_NET,
   5967 		    sizeof (DDI_NT_NET) - 1) == 0 &&
   5968 		    (node_type[sizeof (DDI_NT_NET) - 1] == '\0' ||
   5969 		    node_type[sizeof (DDI_NT_NET) - 1] == ':')) {
   5970 
   5971 			rv = i_ddi_set_devi_class(dip, ESC_NETWORK, flag);
   5972 
   5973 		} else if (strncmp(node_type, DDI_NT_PRINTER,
   5974 		    sizeof (DDI_NT_PRINTER) - 1) == 0 &&
   5975 		    (node_type[sizeof (DDI_NT_PRINTER) - 1] == '\0' ||
   5976 		    node_type[sizeof (DDI_NT_PRINTER) - 1] == ':')) {
   5977 
   5978 			rv = i_ddi_set_devi_class(dip, ESC_PRINTER, flag);
   5979 
   5980 		} else if (strncmp(node_type, DDI_PSEUDO,
   5981 		    sizeof (DDI_PSEUDO) -1) == 0 &&
   5982 		    (strncmp(ESC_LOFI, ddi_node_name(dip),
   5983 		    sizeof (ESC_LOFI) -1) == 0)) {
   5984 			rv = i_ddi_set_devi_class(dip, ESC_LOFI, flag);
   5985 		}
   5986 	}
   5987 
   5988 	return (rv);
   5989 }
   5990 
   5991 /*
   5992  * Check compliance with PSARC 2003/375:
   5993  *
   5994  * The name must contain only characters a-z, A-Z, 0-9 or _ and it must not
   5995  * exceed IFNAMSIZ (16) characters in length.
   5996  */
   5997 static boolean_t
   5998 verify_name(char *name)
   5999 {
   6000 	size_t	len = strlen(name);
   6001 	char	*cp;
   6002 
   6003 	if (len == 0 || len > IFNAMSIZ)
   6004 		return (B_FALSE);
   6005 
   6006 	for (cp = name; *cp != '\0'; cp++) {
   6007 		if (!isalnum(*cp) && *cp != '_')
   6008 			return (B_FALSE);
   6009 	}
   6010 
   6011 	return (B_TRUE);
   6012 }
   6013 
   6014 /*
   6015  * ddi_create_minor_common:	Create a  ddi_minor_data structure and
   6016  *				attach it to the given devinfo node.
   6017  */
   6018 
   6019 int
   6020 ddi_create_minor_common(dev_info_t *dip, char *name, int spec_type,
   6021     minor_t minor_num, char *node_type, int flag, ddi_minor_type mtype,
   6022     const char *read_priv, const char *write_priv, mode_t priv_mode)
   6023 {
   6024 	struct ddi_minor_data *dmdp;
   6025 	major_t major;
   6026 
   6027 	if (spec_type != S_IFCHR && spec_type != S_IFBLK)
   6028 		return (DDI_FAILURE);
   6029 
   6030 	if (name == NULL)
   6031 		return (DDI_FAILURE);
   6032 
   6033 	/*
   6034 	 * Log a message if the minor number the driver is creating
   6035 	 * is not expressible on the on-disk filesystem (currently
   6036 	 * this is limited to 18 bits both by UFS). The device can
   6037 	 * be opened via devfs, but not by device special files created
   6038 	 * via mknod().
   6039 	 */
   6040 	if (minor_num > L_MAXMIN32) {
   6041 		cmn_err(CE_WARN,
   6042 		    "%s%d:%s minor 0x%x too big for 32-bit applications",
   6043 		    ddi_driver_name(dip), ddi_get_instance(dip),
   6044 		    name, minor_num);
   6045 		return (DDI_FAILURE);
   6046 	}
   6047 
   6048 	/* dip must be bound and attached */
   6049 	major = ddi_driver_major(dip);
   6050 	ASSERT(major != DDI_MAJOR_T_NONE);
   6051 
   6052 	/*
   6053 	 * Default node_type to DDI_PSEUDO and issue notice in debug mode
   6054 	 */
   6055 	if (node_type == NULL) {
   6056 		node_type = DDI_PSEUDO;
   6057 		NDI_CONFIG_DEBUG((CE_NOTE, "!illegal node_type NULL for %s%d "
   6058 		    " minor node %s; default to DDI_PSEUDO",
   6059 		    ddi_driver_name(dip), ddi_get_instance(dip), name));
   6060 	}
   6061 
   6062 	/*
   6063 	 * If the driver is a network driver, ensure that the name falls within
   6064 	 * the interface naming constraints specified by PSARC/2003/375.
   6065 	 */
   6066 	if (strcmp(node_type, DDI_NT_NET) == 0) {
   6067 		if (!verify_name(name))
   6068 			return (DDI_FAILURE);
   6069 
   6070 		if (mtype == DDM_MINOR) {
   6071 			struct devnames *dnp = &devnamesp[major];
   6072 
   6073 			/* Mark driver as a network driver */
   6074 			LOCK_DEV_OPS(&dnp->dn_lock);
   6075 			dnp->dn_flags |= DN_NETWORK_DRIVER;
   6076 
   6077 			/*
   6078 			 * If this minor node is created during the device
   6079 			 * attachment, this is a physical network device.
   6080 			 * Mark the driver as a physical network driver.
   6081 			 */
   6082 			if (DEVI_IS_ATTACHING(dip))
   6083 				dnp->dn_flags |= DN_NETWORK_PHYSDRIVER;
   6084 			UNLOCK_DEV_OPS(&dnp->dn_lock);
   6085 		}
   6086 	}
   6087 
   6088 	if (mtype == DDM_MINOR) {
   6089 		if (derive_devi_class(dip,  node_type, KM_NOSLEEP) !=
   6090 		    DDI_SUCCESS)
   6091 			return (DDI_FAILURE);
   6092 	}
   6093 
   6094 	/*
   6095 	 * Take care of minor number information for the node.
   6096 	 */
   6097 
   6098 	if ((dmdp = kmem_zalloc(sizeof (struct ddi_minor_data),
   6099 	    KM_NOSLEEP)) == NULL) {
   6100 		return (DDI_FAILURE);
   6101 	}
   6102 	if ((dmdp->ddm_name = i_ddi_strdup(name, KM_NOSLEEP)) == NULL) {
   6103 		kmem_free(dmdp, sizeof (struct ddi_minor_data));
   6104 		return (DDI_FAILURE);
   6105 	}
   6106 	dmdp->dip = dip;
   6107 	dmdp->ddm_dev = makedevice(major, minor_num);
   6108 	dmdp->ddm_spec_type = spec_type;
   6109 	dmdp->ddm_node_type = node_type;
   6110 	dmdp->type = mtype;
   6111 	if (flag & CLONE_DEV) {
   6112 		dmdp->type = DDM_ALIAS;
   6113 		dmdp->ddm_dev = makedevice(ddi_driver_major(clone_dip), major);
   6114 	}
   6115 	if (flag & PRIVONLY_DEV) {
   6116 		dmdp->ddm_flags |= DM_NO_FSPERM;
   6117 	}
   6118 	if (read_priv || write_priv) {
   6119 		dmdp->ddm_node_priv =
   6120 		    devpolicy_priv_by_name(read_priv, write_priv);
   6121 	}
   6122 	dmdp->ddm_priv_mode = priv_mode;
   6123 
   6124 	ddi_append_minor_node(dip, dmdp);
   6125 
   6126 	/*
   6127 	 * only log ddi_create_minor_node() calls which occur
   6128 	 * outside the scope of attach(9e)/detach(9e) reconfigurations
   6129 	 */
   6130 	if (!(DEVI_IS_ATTACHING(dip) || DEVI_IS_DETACHING(dip)) &&
   6131 	    mtype != DDM_INTERNAL_PATH) {
   6132 		(void) i_log_devfs_minor_create(dip, name);
   6133 	}
   6134 
   6135 	/*
   6136 	 * Check if any dacf rules match the creation of this minor node
   6137 	 */
   6138 	dacfc_match_create_minor(name, node_type, dip, dmdp, flag);
   6139 	return (DDI_SUCCESS);
   6140 }
   6141 
   6142 int
   6143 ddi_create_minor_node(dev_info_t *dip, char *name, int spec_type,
   6144     minor_t minor_num, char *node_type, int flag)
   6145 {
   6146 	return (ddi_create_minor_common(dip, name, spec_type, minor_num,
   6147 	    node_type, flag, DDM_MINOR, NULL, NULL, 0));
   6148 }
   6149 
   6150 int
   6151 ddi_create_priv_minor_node(dev_info_t *dip, char *name, int spec_type,
   6152     minor_t minor_num, char *node_type, int flag,
   6153     const char *rdpriv, const char *wrpriv, mode_t priv_mode)
   6154 {
   6155 	return (ddi_create_minor_common(dip, name, spec_type, minor_num,
   6156 	    node_type, flag, DDM_MINOR, rdpriv, wrpriv, priv_mode));
   6157 }
   6158 
   6159 int
   6160 ddi_create_default_minor_node(dev_info_t *dip, char *name, int spec_type,
   6161     minor_t minor_num, char *node_type, int flag)
   6162 {
   6163 	return (ddi_create_minor_common(dip, name, spec_type, minor_num,
   6164 	    node_type, flag, DDM_DEFAULT, NULL, NULL, 0));
   6165 }
   6166 
   6167 /*
   6168  * Internal (non-ddi) routine for drivers to export names known
   6169  * to the kernel (especially ddi_pathname_to_dev_t and friends)
   6170  * but not exported externally to /dev
   6171  */
   6172 int
   6173 ddi_create_internal_pathname(dev_info_t *dip, char *name, int spec_type,
   6174     minor_t minor_num)
   6175 {
   6176 	return (ddi_create_minor_common(dip, name, spec_type, minor_num,
   6177 	    "internal", 0, DDM_INTERNAL_PATH, NULL, NULL, 0));
   6178 }
   6179 
   6180 void
   6181 ddi_remove_minor_node(dev_info_t *dip, char *name)
   6182 {
   6183 	int			circ;
   6184 	struct ddi_minor_data	*dmdp, *dmdp1;
   6185 	struct ddi_minor_data	**dmdp_prev;
   6186 
   6187 	ndi_devi_enter(dip, &circ);
   6188 	dmdp_prev = &DEVI(dip)->devi_minor;
   6189 	dmdp = DEVI(dip)->devi_minor;
   6190 	while (dmdp != NULL) {
   6191 		dmdp1 = dmdp->next;
   6192 		if ((name == NULL || (dmdp->ddm_name != NULL &&
   6193 		    strcmp(name, dmdp->ddm_name) == 0))) {
   6194 			if (dmdp->ddm_name != NULL) {
   6195 				if (dmdp->type != DDM_INTERNAL_PATH)
   6196 					(void) i_log_devfs_minor_remove(dip,
   6197 					    dmdp->ddm_name);
   6198 				kmem_free(dmdp->ddm_name,
   6199 				    strlen(dmdp->ddm_name) + 1);
   6200 			}
   6201 			/*
   6202 			 * Release device privilege, if any.
   6203 			 * Release dacf client data associated with this minor
   6204 			 * node by storing NULL.
   6205 			 */
   6206 			if (dmdp->ddm_node_priv)
   6207 				dpfree(dmdp->ddm_node_priv);
   6208 			dacf_store_info((dacf_infohdl_t)dmdp, NULL);
   6209 			kmem_free(dmdp, sizeof (struct ddi_minor_data));
   6210 			*dmdp_prev = dmdp1;
   6211 			/*
   6212 			 * OK, we found it, so get out now -- if we drive on,
   6213 			 * we will strcmp against garbage.  See 1139209.
   6214 			 */
   6215 			if (name != NULL)
   6216 				break;
   6217 		} else {
   6218 			dmdp_prev = &dmdp->next;
   6219 		}
   6220 		dmdp = dmdp1;
   6221 	}
   6222 	ndi_devi_exit(dip, circ);
   6223 }
   6224 
   6225 
   6226 int
   6227 ddi_in_panic()
   6228 {
   6229 	return (panicstr != NULL);
   6230 }
   6231 
   6232 
   6233 /*
   6234  * Find first bit set in a mask (returned counting from 1 up)
   6235  */
   6236 
   6237 int
   6238 ddi_ffs(long mask)
   6239 {
   6240 	return (ffs(mask));
   6241 }
   6242 
   6243 /*
   6244  * Find last bit set. Take mask and clear
   6245  * all but the most significant bit, and
   6246  * then let ffs do the rest of the work.
   6247  *
   6248  * Algorithm courtesy of Steve Chessin.
   6249  */
   6250 
   6251 int
   6252 ddi_fls(long mask)
   6253 {
   6254 	while (mask) {
   6255 		long nx;
   6256 
   6257 		if ((nx = (mask & (mask - 1))) == 0)
   6258 			break;
   6259 		mask = nx;
   6260 	}
   6261 	return (ffs(mask));
   6262 }
   6263 
   6264 /*
   6265  * The ddi_soft_state_* routines comprise generic storage management utilities
   6266  * for driver soft state structures (in "the old days," this was done with
   6267  * statically sized array - big systems and dynamic loading and unloading
   6268  * make heap allocation more attractive).
   6269  */
   6270 
   6271 /*
   6272  * Allocate a set of pointers to 'n_items' objects of size 'size'
   6273  * bytes.  Each pointer is initialized to nil.
   6274  *
   6275  * The 'size' and 'n_items' values are stashed in the opaque
   6276  * handle returned to the caller.
   6277  *
   6278  * This implementation interprets 'set of pointers' to mean 'array
   6279  * of pointers' but note that nothing in the interface definition
   6280  * precludes an implementation that uses, for example, a linked list.
   6281  * However there should be a small efficiency gain from using an array
   6282  * at lookup time.
   6283  *
   6284  * NOTE	As an optimization, we make our growable array allocations in
   6285  *	powers of two (bytes), since that's how much kmem_alloc (currently)
   6286  *	gives us anyway.  It should save us some free/realloc's ..
   6287  *
   6288  *	As a further optimization, we make the growable array start out
   6289  *	with MIN_N_ITEMS in it.
   6290  */
   6291 
   6292 #define	MIN_N_ITEMS	8	/* 8 void *'s == 32 bytes */
   6293 
   6294 int
   6295 ddi_soft_state_init(void **state_p, size_t size, size_t n_items)
   6296 {
   6297 	i_ddi_soft_state	*ss;
   6298 
   6299 	if (state_p == NULL || size == 0)
   6300 		return (EINVAL);
   6301 
   6302 	ss = kmem_zalloc(sizeof (*ss), KM_SLEEP);
   6303 	mutex_init(&ss->lock, NULL, MUTEX_DRIVER, NULL);
   6304 	ss->size = size;
   6305 
   6306 	if (n_items < MIN_N_ITEMS)
   6307 		ss->n_items = MIN_N_ITEMS;
   6308 	else {
   6309 		int bitlog;
   6310 
   6311 		if ((bitlog = ddi_fls(n_items)) == ddi_ffs(n_items))
   6312 			bitlog--;
   6313 		ss->n_items = 1 << bitlog;
   6314 	}
   6315 
   6316 	ASSERT(ss->n_items >= n_items);
   6317 
   6318 	ss->array = kmem_zalloc(ss->n_items * sizeof (void *), KM_SLEEP);
   6319 
   6320 	*state_p = ss;
   6321 	return (0);
   6322 }
   6323 
   6324 /*
   6325  * Allocate a state structure of size 'size' to be associated
   6326  * with item 'item'.
   6327  *
   6328  * In this implementation, the array is extended to
   6329  * allow the requested offset, if needed.
   6330  */
   6331 int
   6332 ddi_soft_state_zalloc(void *state, int item)
   6333 {
   6334 	i_ddi_soft_state	*ss = (i_ddi_soft_state *)state;
   6335 	void			**array;
   6336 	void			*new_element;
   6337 
   6338 	if ((state == NULL) || (item < 0))
   6339 		return (DDI_FAILURE);
   6340 
   6341 	mutex_enter(&ss->lock);
   6342 	if (ss->size == 0) {
   6343 		mutex_exit(&ss->lock);
   6344 		cmn_err(CE_WARN, "ddi_soft_state_zalloc: bad handle: %s",
   6345 		    mod_containing_pc(caller()));
   6346 		return (DDI_FAILURE);
   6347 	}
   6348 
   6349 	array = ss->array;	/* NULL if ss->n_items == 0 */
   6350 	ASSERT(ss->n_items != 0 && array != NULL);
   6351 
   6352 	/*
   6353 	 * refuse to tread on an existing element
   6354 	 */
   6355 	if (item < ss->n_items && array[item] != NULL) {
   6356 		mutex_exit(&ss->lock);
   6357 		return (DDI_FAILURE);
   6358 	}
   6359 
   6360 	/*
   6361 	 * Allocate a new element to plug in
   6362 	 */
   6363 	new_element = kmem_zalloc(ss->size, KM_SLEEP);
   6364 
   6365 	/*
   6366 	 * Check if the array is big enough, if not, grow it.
   6367 	 */
   6368 	if (item >= ss->n_items) {
   6369 		void			**new_array;
   6370 		size_t			new_n_items;
   6371 		struct i_ddi_soft_state	*dirty;
   6372 
   6373 		/*
   6374 		 * Allocate a new array of the right length, copy
   6375 		 * all the old pointers to the new array, then
   6376 		 * if it exists at all, put the old array on the
   6377 		 * dirty list.
   6378 		 *
   6379 		 * Note that we can't kmem_free() the old array.
   6380 		 *
   6381 		 * Why -- well the 'get' operation is 'mutex-free', so we
   6382 		 * can't easily catch a suspended thread that is just about
   6383 		 * to dereference the array we just grew out of.  So we
   6384 		 * cons up a header and put it on a list of 'dirty'
   6385 		 * pointer arrays.  (Dirty in the sense that there may
   6386 		 * be suspended threads somewhere that are in the middle
   6387 		 * of referencing them).  Fortunately, we -can- garbage
   6388 		 * collect it all at ddi_soft_state_fini time.
   6389 		 */
   6390 		new_n_items = ss->n_items;
   6391 		while (new_n_items < (1 + item))
   6392 			new_n_items <<= 1;	/* double array size .. */
   6393 
   6394 		ASSERT(new_n_items >= (1 + item));	/* sanity check! */
   6395 
   6396 		new_array = kmem_zalloc(new_n_items * sizeof (void *),
   6397 		    KM_SLEEP);
   6398 		/*
   6399 		 * Copy the pointers into the new array
   6400 		 */
   6401 		bcopy(array, new_array, ss->n_items * sizeof (void *));
   6402 
   6403 		/*
   6404 		 * Save the old array on the dirty list
   6405 		 */
   6406 		dirty = kmem_zalloc(sizeof (*dirty), KM_SLEEP);
   6407 		dirty->array = ss->array;
   6408 		dirty->n_items = ss->n_items;
   6409 		dirty->next = ss->next;
   6410 		ss->next = dirty;
   6411 
   6412 		ss->array = (array = new_array);
   6413 		ss->n_items = new_n_items;
   6414 	}
   6415 
   6416 	ASSERT(array != NULL && item < ss->n_items && array[item] == NULL);
   6417 
   6418 	array[item] = new_element;
   6419 
   6420 	mutex_exit(&ss->lock);
   6421 	return (DDI_SUCCESS);
   6422 }
   6423 
   6424 /*
   6425  * Fetch a pointer to the allocated soft state structure.
   6426  *
   6427  * This is designed to be cheap.
   6428  *
   6429  * There's an argument that there should be more checking for
   6430  * nil pointers and out of bounds on the array.. but we do a lot
   6431  * of that in the alloc/free routines.
   6432  *
   6433  * An array has the convenience that we don't need to lock read-access
   6434  * to it c.f. a linked list.  However our "expanding array" strategy
   6435  * means that we should hold a readers lock on the i_ddi_soft_state
   6436  * structure.
   6437  *
   6438  * However, from a performance viewpoint, we need to do it without
   6439  * any locks at all -- this also makes it a leaf routine.  The algorithm
   6440  * is 'lock-free' because we only discard the pointer arrays at
   6441  * ddi_soft_state_fini() time.
   6442  */
   6443 void *
   6444 ddi_get_soft_state(void *state, int item)
   6445 {
   6446 	i_ddi_soft_state	*ss = (i_ddi_soft_state *)state;
   6447 
   6448 	ASSERT((ss != NULL) && (item >= 0));
   6449 
   6450 	if (item < ss->n_items && ss->array != NULL)
   6451 		return (ss->array[item]);
   6452 	return (NULL);
   6453 }
   6454 
   6455 /*
   6456  * Free the state structure corresponding to 'item.'   Freeing an
   6457  * element that has either gone or was never allocated is not
   6458  * considered an error.  Note that we free the state structure, but
   6459  * we don't shrink our pointer array, or discard 'dirty' arrays,
   6460  * since even a few pointers don't really waste too much memory.
   6461  *
   6462  * Passing an item number that is out of bounds, or a null pointer will
   6463  * provoke an error message.
   6464  */
   6465 void
   6466 ddi_soft_state_free(void *state, int item)
   6467 {
   6468 	i_ddi_soft_state	*ss = (i_ddi_soft_state *)state;
   6469 	void			**array;
   6470 	void			*element;
   6471 	static char		msg[] = "ddi_soft_state_free:";
   6472 
   6473 	if (ss == NULL) {
   6474 		cmn_err(CE_WARN, "%s null handle: %s",
   6475 		    msg, mod_containing_pc(caller()));
   6476 		return;
   6477 	}
   6478 
   6479 	element = NULL;
   6480 
   6481 	mutex_enter(&ss->lock);
   6482 
   6483 	if ((array = ss->array) == NULL || ss->size == 0) {
   6484 		cmn_err(CE_WARN, "%s bad handle: %s",
   6485 		    msg, mod_containing_pc(caller()));
   6486 	} else if (item < 0 || item >= ss->n_items) {
   6487 		cmn_err(CE_WARN, "%s item %d not in range [0..%lu]: %s",
   6488 		    msg, item, ss->n_items - 1, mod_containing_pc(caller()));
   6489 	} else if (array[item] != NULL) {
   6490 		element = array[item];
   6491 		array[item] = NULL;
   6492 	}
   6493 
   6494 	mutex_exit(&ss->lock);
   6495 
   6496 	if (element)
   6497 		kmem_free(element, ss->size);
   6498 }
   6499 
   6500 /*
   6501  * Free the entire set of pointers, and any
   6502  * soft state structures contained therein.
   6503  *
   6504  * Note that we don't grab the ss->lock mutex, even though
   6505  * we're inspecting the various fields of the data structure.
   6506  *
   6507  * There is an implicit assumption that this routine will
   6508  * never run concurrently with any of the above on this
   6509  * particular state structure i.e. by the time the driver
   6510  * calls this routine, there should be no other threads
   6511  * running in the driver.
   6512  */
   6513 void
   6514 ddi_soft_state_fini(void **state_p)
   6515 {
   6516 	i_ddi_soft_state	*ss, *dirty;
   6517 	int			item;
   6518 	static char		msg[] = "ddi_soft_state_fini:";
   6519 
   6520 	if (state_p == NULL ||
   6521 	    (ss = (i_ddi_soft_state *)(*state_p)) == NULL) {
   6522 		cmn_err(CE_WARN, "%s null handle: %s",
   6523 		    msg, mod_containing_pc(caller()));
   6524 		return;
   6525 	}
   6526 
   6527 	if (ss->size == 0) {
   6528 		cmn_err(CE_WARN, "%s bad handle: %s",
   6529 		    msg, mod_containing_pc(caller()));
   6530 		return;
   6531 	}
   6532 
   6533 	if (ss->n_items > 0) {
   6534 		for (item = 0; item < ss->n_items; item++)
   6535 			ddi_soft_state_free(ss, item);
   6536 		kmem_free(ss->array, ss->n_items * sizeof (void *));
   6537 	}
   6538 
   6539 	/*
   6540 	 * Now delete any dirty arrays from previous 'grow' operations
   6541 	 */
   6542 	for (dirty = ss->next; dirty; dirty = ss->next) {
   6543 		ss->next = dirty->next;
   6544 		kmem_free(dirty->array, dirty->n_items * sizeof (void *));
   6545 		kmem_free(dirty, sizeof (*dirty));
   6546 	}
   6547 
   6548 	mutex_destroy(&ss->lock);
   6549 	kmem_free(ss, sizeof (*ss));
   6550 
   6551 	*state_p = NULL;
   6552 }
   6553 
   6554 #define	SS_N_ITEMS_PER_HASH	16
   6555 #define	SS_MIN_HASH_SZ		16
   6556 #define	SS_MAX_HASH_SZ		4096
   6557 
   6558 int
   6559 ddi_soft_state_bystr_init(ddi_soft_state_bystr **state_p, size_t size,
   6560     int n_items)
   6561 {
   6562 	i_ddi_soft_state_bystr	*sss;
   6563 	int			hash_sz;
   6564 
   6565 	ASSERT(state_p && size && n_items);
   6566 	if ((state_p == NULL) || (size == 0) || (n_items == 0))
   6567 		return (EINVAL);
   6568 
   6569 	/* current implementation is based on hash, convert n_items to hash */
   6570 	hash_sz = n_items / SS_N_ITEMS_PER_HASH;
   6571 	if (hash_sz < SS_MIN_HASH_SZ)
   6572 		hash_sz = SS_MIN_HASH_SZ;
   6573 	else if (hash_sz > SS_MAX_HASH_SZ)
   6574 		hash_sz = SS_MAX_HASH_SZ;
   6575 
   6576 	/* allocate soft_state pool */
   6577 	sss = kmem_zalloc(sizeof (*sss), KM_SLEEP);
   6578 	sss->ss_size = size;
   6579 	sss->ss_mod_hash = mod_hash_create_strhash("soft_state_bystr",
   6580 	    hash_sz, mod_hash_null_valdtor);
   6581 	*state_p = (ddi_soft_state_bystr *)sss;
   6582 	return (0);
   6583 }
   6584 
   6585 int
   6586 ddi_soft_state_bystr_zalloc(ddi_soft_state_bystr *state, const char *str)
   6587 {
   6588 	i_ddi_soft_state_bystr	*sss = (i_ddi_soft_state_bystr *)state;
   6589 	void			*sso;
   6590 	char			*dup_str;
   6591 
   6592 	ASSERT(sss && str && sss->ss_mod_hash);
   6593 	if ((sss == NULL) || (str == NULL) || (sss->ss_mod_hash == NULL))
   6594 		return (DDI_FAILURE);
   6595 	sso = kmem_zalloc(sss->ss_size, KM_SLEEP);
   6596 	dup_str = i_ddi_strdup((char *)str, KM_SLEEP);
   6597 	if (mod_hash_insert(sss->ss_mod_hash,
   6598 	    (mod_hash_key_t)dup_str, (mod_hash_val_t)sso) == 0)
   6599 		return (DDI_SUCCESS);
   6600 
   6601 	/*
   6602 	 * The only error from an strhash insert is caused by a duplicate key.
   6603 	 * We refuse to tread on an existing elements, so free and fail.
   6604 	 */
   6605 	kmem_free(dup_str, strlen(dup_str) + 1);
   6606 	kmem_free(sso, sss->ss_size);
   6607 	return (DDI_FAILURE);
   6608 }
   6609 
   6610 void *
   6611 ddi_soft_state_bystr_get(ddi_soft_state_bystr *state, const char *str)
   6612 {
   6613 	i_ddi_soft_state_bystr	*sss = (i_ddi_soft_state_bystr *)state;
   6614 	void			*sso;
   6615 
   6616 	ASSERT(sss && str && sss->ss_mod_hash);
   6617 	if ((sss == NULL) || (str == NULL) || (sss->ss_mod_hash == NULL))
   6618 		return (NULL);
   6619 
   6620 	if (mod_hash_find(sss->ss_mod_hash,
   6621 	    (mod_hash_key_t)str, (mod_hash_val_t *)&sso) == 0)
   6622 		return (sso);
   6623 	return (NULL);
   6624 }
   6625 
   6626 void
   6627 ddi_soft_state_bystr_free(ddi_soft_state_bystr *state, const char *str)
   6628 {
   6629 	i_ddi_soft_state_bystr	*sss = (i_ddi_soft_state_bystr *)state;
   6630 	void			*sso;
   6631 
   6632 	ASSERT(sss && str && sss->ss_mod_hash);
   6633 	if ((sss == NULL) || (str == NULL) || (sss->ss_mod_hash == NULL))
   6634 		return;
   6635 
   6636 	(void) mod_hash_remove(sss->ss_mod_hash,
   6637 	    (mod_hash_key_t)str, (mod_hash_val_t *)&sso);
   6638 	kmem_free(sso, sss->ss_size);
   6639 }
   6640 
   6641 void
   6642 ddi_soft_state_bystr_fini(ddi_soft_state_bystr **state_p)
   6643 {
   6644 	i_ddi_soft_state_bystr	*sss;
   6645 
   6646 	ASSERT(state_p);
   6647 	if (state_p == NULL)
   6648 		return;
   6649 
   6650 	sss = (i_ddi_soft_state_bystr *)(*state_p);
   6651 	if (sss == NULL)
   6652 		return;
   6653 
   6654 	ASSERT(sss->ss_mod_hash);
   6655 	if (sss->ss_mod_hash) {
   6656 		mod_hash_destroy_strhash(sss->ss_mod_hash);
   6657 		sss->ss_mod_hash = NULL;
   6658 	}
   6659 
   6660 	kmem_free(sss, sizeof (*sss));
   6661 	*state_p = NULL;
   6662 }
   6663 
   6664 /*
   6665  * The ddi_strid_* routines provide string-to-index management utilities.
   6666  */
   6667 /* allocate and initialize an strid set */
   6668 int
   6669 ddi_strid_init(ddi_strid **strid_p, int n_items)
   6670 {
   6671 	i_ddi_strid	*ss;
   6672 	int		hash_sz;
   6673 
   6674 	if (strid_p == NULL)
   6675 		return (DDI_FAILURE);
   6676 
   6677 	/* current implementation is based on hash, convert n_items to hash */
   6678 	hash_sz = n_items / SS_N_ITEMS_PER_HASH;
   6679 	if (hash_sz < SS_MIN_HASH_SZ)
   6680 		hash_sz = SS_MIN_HASH_SZ;
   6681 	else if (hash_sz > SS_MAX_HASH_SZ)
   6682 		hash_sz = SS_MAX_HASH_SZ;
   6683 
   6684 	ss = kmem_alloc(sizeof (*ss), KM_SLEEP);
   6685 	ss->strid_chunksz = n_items;
   6686 	ss->strid_spacesz = n_items;
   6687 	ss->strid_space = id_space_create("strid", 1, n_items);
   6688 	ss->strid_bystr = mod_hash_create_strhash("strid_bystr", hash_sz,
   6689 	    mod_hash_null_valdtor);
   6690 	ss->strid_byid = mod_hash_create_idhash("strid_byid", hash_sz,
   6691 	    mod_hash_null_valdtor);
   6692 	*strid_p = (ddi_strid *)ss;
   6693 	return (DDI_SUCCESS);
   6694 }
   6695 
   6696 /* allocate an id mapping within the specified set for str, return id */
   6697 static id_t
   6698 i_ddi_strid_alloc(ddi_strid *strid, char *str)
   6699 {
   6700 	i_ddi_strid	*ss = (i_ddi_strid *)strid;
   6701 	id_t		id;
   6702 	char		*s;
   6703 
   6704 	ASSERT(ss && str);
   6705 	if ((ss == NULL) || (str == NULL))
   6706 		return (0);
   6707 
   6708 	/*
   6709 	 * Allocate an id using VM_FIRSTFIT in order to keep allocated id
   6710 	 * range as compressed as possible.  This is important to minimize
   6711 	 * the amount of space used when the id is used as a ddi_soft_state
   6712 	 * index by the caller.
   6713 	 *
   6714 	 * If the id list is exhausted, increase the size of the list
   6715 	 * by the chuck size specified in ddi_strid_init and reattempt
   6716 	 * the allocation
   6717 	 */
   6718 	if ((id = id_allocff_nosleep(ss->strid_space)) == (id_t)-1) {
   6719 		id_space_extend(ss->strid_space, ss->strid_spacesz,
   6720 		    ss->strid_spacesz + ss->strid_chunksz);
   6721 		ss->strid_spacesz += ss->strid_chunksz;
   6722 		if ((id = id_allocff_nosleep(ss->strid_space)) == (id_t)-1)
   6723 			return (0);
   6724 	}
   6725 
   6726 	/*
   6727 	 * NOTE: since we create and destroy in unison we can save space by
   6728 	 * using bystr key as the byid value.  This means destroy must occur
   6729 	 * in (byid, bystr) order.
   6730 	 */
   6731 	s = i_ddi_strdup(str, KM_SLEEP);
   6732 	if (mod_hash_insert(ss->strid_bystr, (mod_hash_key_t)s,
   6733 	    (mod_hash_val_t)(intptr_t)id) != 0) {
   6734 		ddi_strid_free(strid, id);
   6735 		return (0);
   6736 	}
   6737 	if (mod_hash_insert(ss->strid_byid, (mod_hash_key_t)(intptr_t)id,
   6738 	    (mod_hash_val_t)s) != 0) {
   6739 		ddi_strid_free(strid, id);
   6740 		return (0);
   6741 	}
   6742 
   6743 	/* NOTE: s if freed on mod_hash_destroy by mod_hash_strval_dtor */
   6744 	return (id);
   6745 }
   6746 
   6747 /* allocate an id mapping within the specified set for str, return id */
   6748 id_t
   6749 ddi_strid_alloc(ddi_strid *strid, char *str)
   6750 {
   6751 	return (i_ddi_strid_alloc(strid, str));
   6752 }
   6753 
   6754 /* return the id within the specified strid given the str */
   6755 id_t
   6756 ddi_strid_str2id(ddi_strid *strid, char *str)
   6757 {
   6758 	i_ddi_strid	*ss = (i_ddi_strid *)strid;
   6759 	id_t		id = 0;
   6760 	mod_hash_val_t	hv;
   6761 
   6762 	ASSERT(ss && str);
   6763 	if (ss && str && (mod_hash_find(ss->strid_bystr,
   6764 	    (mod_hash_key_t)str, &hv) == 0))
   6765 		id = (int)(intptr_t)hv;
   6766 	return (id);
   6767 }
   6768 
   6769 /* return str within the specified strid given the id */
   6770 char *
   6771 ddi_strid_id2str(ddi_strid *strid, id_t id)
   6772 {
   6773 	i_ddi_strid	*ss = (i_ddi_strid *)strid;
   6774 	char		*str = NULL;
   6775 	mod_hash_val_t	hv;
   6776 
   6777 	ASSERT(ss && id > 0);
   6778 	if (ss && (id > 0) && (mod_hash_find(ss->strid_byid,
   6779 	    (mod_hash_key_t)(uintptr_t)id, &hv) == 0))
   6780 		str = (char *)hv;
   6781 	return (str);
   6782 }
   6783 
   6784 /* free the id mapping within the specified strid */
   6785 void
   6786 ddi_strid_free(ddi_strid *strid, id_t id)
   6787 {
   6788 	i_ddi_strid	*ss = (i_ddi_strid *)strid;
   6789 	char		*str;
   6790 
   6791 	ASSERT(ss && id > 0);
   6792 	if ((ss == NULL) || (id <= 0))
   6793 		return;
   6794 
   6795 	/* bystr key is byid value: destroy order must be (byid, bystr) */
   6796 	str = ddi_strid_id2str(strid, id);
   6797 	(void) mod_hash_destroy(ss->strid_byid, (mod_hash_key_t)(uintptr_t)id);
   6798 	id_free(ss->strid_space, id);
   6799 
   6800 	if (str)
   6801 		(void) mod_hash_destroy(ss->strid_bystr, (mod_hash_key_t)str);
   6802 }
   6803 
   6804 /* destroy the strid set */
   6805 void
   6806 ddi_strid_fini(ddi_strid **strid_p)
   6807 {
   6808 	i_ddi_strid	*ss;
   6809 
   6810 	ASSERT(strid_p);
   6811 	if (strid_p == NULL)
   6812 		return;
   6813 
   6814 	ss = (i_ddi_strid *)(*strid_p);
   6815 	if (ss == NULL)
   6816 		return;
   6817 
   6818 	/* bystr key is byid value: destroy order must be (byid, bystr) */
   6819 	if (ss->strid_byid)
   6820 		mod_hash_destroy_hash(ss->strid_byid);
   6821 	if (ss->strid_byid)
   6822 		mod_hash_destroy_hash(ss->strid_bystr);
   6823 	if (ss->strid_space)
   6824 		id_space_destroy(ss->strid_space);
   6825 	kmem_free(ss, sizeof (*ss));
   6826 	*strid_p = NULL;
   6827 }
   6828 
   6829 /*
   6830  * This sets the devi_addr entry in the dev_info structure 'dip' to 'name'.
   6831  * Storage is double buffered to prevent updates during devi_addr use -
   6832  * double buffering is adaquate for reliable ddi_deviname() consumption.
   6833  * The double buffer is not freed until dev_info structure destruction
   6834  * (by i_ddi_free_node).
   6835  */
   6836 void
   6837 ddi_set_name_addr(dev_info_t *dip, char *name)
   6838 {
   6839 	char	*buf = DEVI(dip)->devi_addr_buf;
   6840 	char	*newaddr;
   6841 
   6842 	if (buf == NULL) {
   6843 		buf = kmem_zalloc(2 * MAXNAMELEN, KM_SLEEP);
   6844 		DEVI(dip)->devi_addr_buf = buf;
   6845 	}
   6846 
   6847 	if (name) {
   6848 		ASSERT(strlen(name) < MAXNAMELEN);
   6849 		newaddr = (DEVI(dip)->devi_addr == buf) ?
   6850 		    (buf + MAXNAMELEN) : buf;
   6851 		(void) strlcpy(newaddr, name, MAXNAMELEN);
   6852 	} else
   6853 		newaddr = NULL;
   6854 
   6855 	DEVI(dip)->devi_addr = newaddr;
   6856 }
   6857 
   6858 char *
   6859 ddi_get_name_addr(dev_info_t *dip)
   6860 {
   6861 	return (DEVI(dip)->devi_addr);
   6862 }
   6863 
   6864 void
   6865 ddi_set_parent_data(dev_info_t *dip, void *pd)
   6866 {
   6867 	DEVI(dip)->devi_parent_data = pd;
   6868 }
   6869 
   6870 void *
   6871 ddi_get_parent_data(dev_info_t *dip)
   6872 {
   6873 	return (DEVI(dip)->devi_parent_data);
   6874 }
   6875 
   6876 /*
   6877  * ddi_name_to_major: returns the major number of a named module,
   6878  * derived from the current driver alias binding.
   6879  *
   6880  * Caveat: drivers should avoid the use of this function, in particular
   6881  * together with ddi_get_name/ddi_binding name, as per
   6882  *	major = ddi_name_to_major(ddi_get_name(devi));
   6883  * ddi_name_to_major() relies on the state of the device/alias binding,
   6884  * which can and does change dynamically as aliases are administered
   6885  * over time.  An attached device instance cannot rely on the major
   6886  * number returned by ddi_name_to_major() to match its own major number.
   6887  *
   6888  * For driver use, ddi_driver_major() reliably returns the major number
   6889  * for the module to which the device was bound at attach time over
   6890  * the life of the instance.
   6891  *	major = ddi_driver_major(dev_info_t *)
   6892  */
   6893 major_t
   6894 ddi_name_to_major(char *name)
   6895 {
   6896 	return (mod_name_to_major(name));
   6897 }
   6898 
   6899 /*
   6900  * ddi_major_to_name: Returns the module name bound to a major number.
   6901  */
   6902 char *
   6903 ddi_major_to_name(major_t major)
   6904 {
   6905 	return (mod_major_to_name(major));
   6906 }
   6907 
   6908 /*
   6909  * Return the name of the devinfo node pointed at by 'dip' in the buffer
   6910  * pointed at by 'name.'  A devinfo node is named as a result of calling
   6911  * ddi_initchild().
   6912  *
   6913  * Note: the driver must be held before calling this function!
   6914  */
   6915 char *
   6916 ddi_deviname(dev_info_t *dip, char *name)
   6917 {
   6918 	char *addrname;
   6919 	char none = '\0';
   6920 
   6921 	if (dip == ddi_root_node()) {
   6922 		*name = '\0';
   6923 		return (name);
   6924 	}
   6925 
   6926 	if (i_ddi_node_state(dip) < DS_BOUND) {
   6927 		addrname = &none;
   6928 	} else {
   6929 		/*
   6930 		 * Use ddi_get_name_addr() without checking state so we get
   6931 		 * a unit-address if we are called after ddi_set_name_addr()
   6932 		 * by nexus DDI_CTL_INITCHILD code, but before completing
   6933 		 * node promotion to DS_INITIALIZED.  We currently have
   6934 		 * two situations where we are called in this state:
   6935 		 *   o  For framework processing of a path-oriented alias.
   6936 		 *   o  If a SCSA nexus driver calls ddi_devid_register()
   6937 		 *	from it's tran_tgt_init(9E) implementation.
   6938 		 */
   6939 		addrname = ddi_get_name_addr(dip);
   6940 		if (addrname == NULL)
   6941 			addrname = &none;
   6942 	}
   6943 
   6944 	if (*addrname == '\0') {
   6945 		(void) sprintf(name, "/%s", ddi_node_name(dip));
   6946 	} else {
   6947 		(void) sprintf(name, "/%s@%s", ddi_node_name(dip), addrname);
   6948 	}
   6949 
   6950 	return (name);
   6951 }
   6952 
   6953 /*
   6954  * Spits out the name of device node, typically name@addr, for a given node,
   6955  * using the driver name, not the nodename.
   6956  *
   6957  * Used by match_parent. Not to be used elsewhere.
   6958  */
   6959 char *
   6960 i_ddi_parname(dev_info_t *dip, char *name)
   6961 {
   6962 	char *addrname;
   6963 
   6964 	if (dip == ddi_root_node()) {
   6965 		*name = '\0';
   6966 		return (name);
   6967 	}
   6968 
   6969 	ASSERT(i_ddi_node_state(dip) >= DS_INITIALIZED);
   6970 
   6971 	if (*(addrname = ddi_get_name_addr(dip)) == '\0')
   6972 		(void) sprintf(name, "%s", ddi_binding_name(dip));
   6973 	else
   6974 		(void) sprintf(name, "%s@%s", ddi_binding_name(dip), addrname);
   6975 	return (name);
   6976 }
   6977 
   6978 static char *
   6979 pathname_work(dev_info_t *dip, char *path)
   6980 {
   6981 	char *bp;
   6982 
   6983 	if (dip == ddi_root_node()) {
   6984 		*path = '\0';
   6985 		return (path);
   6986 	}
   6987 	(void) pathname_work(ddi_get_parent(dip), path);
   6988 	bp = path + strlen(path);
   6989 	(void) ddi_deviname(dip, bp);
   6990 	return (path);
   6991 }
   6992 
   6993 char *
   6994 ddi_pathname(dev_info_t *dip, char *path)
   6995 {
   6996 	return (pathname_work(dip, path));
   6997 }
   6998 
   6999 char *
   7000 ddi_pathname_minor(struct ddi_minor_data *dmdp, char *path)
   7001 {
   7002 	if (dmdp->dip == NULL)
   7003 		*path = '\0';
   7004 	else {
   7005 		(void) ddi_pathname(dmdp->dip, path);
   7006 		if (dmdp->ddm_name) {
   7007 			(void) strcat(path, ":");
   7008 			(void) strcat(path, dmdp->ddm_name);
   7009 		}
   7010 	}
   7011 	return (path);
   7012 }
   7013 
   7014 static char *
   7015 pathname_work_obp(dev_info_t *dip, char *path)
   7016 {
   7017 	char *bp;
   7018 	char *obp_path;
   7019 
   7020 	/*
   7021 	 * look up the "obp-path" property, return the path if it exists
   7022 	 */
   7023 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
   7024 	    "obp-path", &obp_path) == DDI_PROP_SUCCESS) {
   7025 		(void) strcpy(path, obp_path);
   7026 		ddi_prop_free(obp_path);
   7027 		return (path);
   7028 	}
   7029 
   7030 	/*
   7031 	 * stop at root, no obp path
   7032 	 */
   7033 	if (dip == ddi_root_node()) {
   7034 		return (NULL);
   7035 	}
   7036 
   7037 	obp_path = pathname_work_obp(ddi_get_parent(dip), path);
   7038 	if (obp_path == NULL)
   7039 		return (NULL);
   7040 
   7041 	/*
   7042 	 * append our component to parent's obp path
   7043 	 */
   7044 	bp = path + strlen(path);
   7045 	if (*(bp - 1) != '/')
   7046 		(void) strcat(bp++, "/");
   7047 	(void) ddi_deviname(dip, bp);
   7048 	return (path);
   7049 }
   7050 
   7051 /*
   7052  * return the 'obp-path' based path for the given node, or NULL if the node
   7053  * does not have a different obp path. NOTE: Unlike ddi_pathname, this
   7054  * function can't be called from interrupt context (since we need to
   7055  * lookup a string property).
   7056  */
   7057 char *
   7058 ddi_pathname_obp(dev_info_t *dip, char *path)
   7059 {
   7060 	ASSERT(!servicing_interrupt());
   7061 	if (dip == NULL || path == NULL)
   7062 		return (NULL);
   7063 
   7064 	/* split work into a separate function to aid debugging */
   7065 	return (pathname_work_obp(dip, path));
   7066 }
   7067 
   7068 int
   7069 ddi_pathname_obp_set(dev_info_t *dip, char *component)
   7070 {
   7071 	dev_info_t *pdip;
   7072 	char *obp_path = NULL;
   7073 	int rc = DDI_FAILURE;
   7074 
   7075 	if (dip == NULL)
   7076 		return (DDI_FAILURE);
   7077 
   7078 	obp_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
   7079 
   7080 	pdip = ddi_get_parent(dip);
   7081 
   7082 	if (ddi_pathname_obp(pdip, obp_path) == NULL) {
   7083 		(void) ddi_pathname(pdip, obp_path);
   7084 	}
   7085 
   7086 	if (component) {
   7087 		(void) strncat(obp_path, "/", MAXPATHLEN);
   7088 		(void) strncat(obp_path, component, MAXPATHLEN);
   7089 	}
   7090 	rc = ndi_prop_update_string(DDI_DEV_T_NONE, dip, "obp-path",
   7091 	    obp_path);
   7092 
   7093 	if (obp_path)
   7094 		kmem_free(obp_path, MAXPATHLEN);
   7095 
   7096 	return (rc);
   7097 }
   7098 
   7099 /*
   7100  * Given a dev_t, return the pathname of the corresponding device in the
   7101  * buffer pointed at by "path."  The buffer is assumed to be large enough
   7102  * to hold the pathname of the device (MAXPATHLEN).
   7103  *
   7104  * The pathname of a device is the pathname of the devinfo node to which
   7105  * the device "belongs," concatenated with the character ':' and the name
   7106  * of the minor node corresponding to the dev_t.  If spec_type is 0 then
   7107  * just the pathname of the devinfo node is returned without driving attach
   7108  * of that node.  For a non-zero spec_type, an attach is performed and a
   7109  * search of the minor list occurs.
   7110  *
   7111  * It is possible that the path associated with the dev_t is not
   7112  * currently available in the devinfo tree.  In order to have a
   7113  * dev_t, a device must have been discovered before, which means
   7114  * that the path is always in the instance tree.  The one exception
   7115  * to this is if the dev_t is associated with a pseudo driver, in
   7116  * which case the device must exist on the pseudo branch of the
   7117  * devinfo tree as a result of parsing .conf files.
   7118  */
   7119 int
   7120 ddi_dev_pathname(dev_t devt, int spec_type, char *path)
   7121 {
   7122 	int		circ;
   7123 	major_t		major = getmajor(devt);
   7124 	int		instance;
   7125 	dev_info_t	*dip;
   7126 	char		*minorname;
   7127 	char		*drvname;
   7128 
   7129 	if (major >= devcnt)
   7130 		goto fail;
   7131 	if (major == clone_major) {
   7132 		/* clone has no minor nodes, manufacture the path here */
   7133 		if ((drvname = ddi_major_to_name(getminor(devt))) == NULL)
   7134 			goto fail;
   7135 
   7136 		(void) snprintf(path, MAXPATHLEN, "%s:%s", CLONE_PATH, drvname);
   7137 		return (DDI_SUCCESS);
   7138 	}
   7139 
   7140 	/* extract instance from devt (getinfo(9E) DDI_INFO_DEVT2INSTANCE). */
   7141 	if ((instance = dev_to_instance(devt)) == -1)
   7142 		goto fail;
   7143 
   7144 	/* reconstruct the path given the major/instance */
   7145 	if (e_ddi_majorinstance_to_path(major, instance, path) != DDI_SUCCESS)
   7146 		goto fail;
   7147 
   7148 	/* if spec_type given we must drive attach and search minor nodes */
   7149 	if ((spec_type == S_IFCHR) || (spec_type == S_IFBLK)) {
   7150 		/* attach the path so we can search minors */
   7151 		if ((dip = e_ddi_hold_devi_by_path(path, 0)) == NULL)
   7152 			goto fail;
   7153 
   7154 		/* Add minorname to path. */
   7155 		ndi_devi_enter(dip, &circ);
   7156 		minorname = i_ddi_devtspectype_to_minorname(dip,
   7157 		    devt, spec_type);
   7158 		if (minorname) {
   7159 			(void) strcat(path, ":");
   7160 			(void) strcat(path, minorname);
   7161 		}
   7162 		ndi_devi_exit(dip, circ);
   7163 		ddi_release_devi(dip);
   7164 		if (minorname == NULL)
   7165 			goto fail;
   7166 	}
   7167 	ASSERT(strlen(path) < MAXPATHLEN);
   7168 	return (DDI_SUCCESS);
   7169 
   7170 fail:	*path = 0;
   7171 	return (DDI_FAILURE);
   7172 }
   7173 
   7174 /*
   7175  * Given a major number and an instance, return the path.
   7176  * This interface does NOT drive attach.
   7177  */
   7178 int
   7179 e_ddi_majorinstance_to_path(major_t major, int instance, char *path)
   7180 {
   7181 	struct devnames *dnp;
   7182 	dev_info_t	*dip;
   7183 
   7184 	if ((major >= devcnt) || (instance == -1)) {
   7185 		*path = 0;
   7186 		return (DDI_FAILURE);
   7187 	}
   7188 
   7189 	/* look for the major/instance in the instance tree */
   7190 	if (e_ddi_instance_majorinstance_to_path(major, instance,
   7191 	    path) == DDI_SUCCESS) {
   7192 		ASSERT(strlen(path) < MAXPATHLEN);
   7193 		return (DDI_SUCCESS);
   7194 	}
   7195 
   7196 	/*
   7197 	 * Not in instance tree, find the instance on the per driver list and
   7198 	 * construct path to instance via ddi_pathname(). This is how paths
   7199 	 * down the 'pseudo' branch are constructed.
   7200 	 */
   7201 	dnp = &(devnamesp[major]);
   7202 	LOCK_DEV_OPS(&(dnp->dn_lock));
   7203 	for (dip = dnp->dn_head; dip;
   7204 	    dip = (dev_info_t *)DEVI(dip)->devi_next) {
   7205 		/* Skip if instance does not match. */
   7206 		if (DEVI(dip)->devi_instance != instance)
   7207 			continue;
   7208 
   7209 		/*
   7210 		 * An ndi_hold_devi() does not prevent DS_INITIALIZED->DS_BOUND
   7211 		 * node demotion, so it is not an effective way of ensuring
   7212 		 * that the ddi_pathname result has a unit-address.  Instead,
   7213 		 * we reverify the node state after calling ddi_pathname().
   7214 		 */
   7215 		if (i_ddi_node_state(dip) >= DS_INITIALIZED) {
   7216 			(void) ddi_pathname(dip, path);
   7217 			if (i_ddi_node_state(dip) < DS_INITIALIZED)
   7218 				continue;
   7219 			UNLOCK_DEV_OPS(&(dnp->dn_lock));
   7220 			ASSERT(strlen(path) < MAXPATHLEN);
   7221 			return (DDI_SUCCESS);
   7222 		}
   7223 	}
   7224 	UNLOCK_DEV_OPS(&(dnp->dn_lock));
   7225 
   7226 	/* can't reconstruct the path */
   7227 	*path = 0;
   7228 	return (DDI_FAILURE);
   7229 }
   7230 
   7231 #define	GLD_DRIVER_PPA "SUNW,gld_v0_ppa"
   7232 
   7233 /*
   7234  * Given the dip for a network interface return the ppa for that interface.
   7235  *
   7236  * In all cases except GLD v0 drivers, the ppa == instance.
   7237  * In the case of GLD v0 drivers, the ppa is equal to the attach order.
   7238  * So for these drivers when the attach routine calls gld_register(),
   7239  * the GLD framework creates an integer property called "gld_driver_ppa"
   7240  * that can be queried here.
   7241  *
   7242  * The only time this function is used is when a system is booting over nfs.
   7243  * In this case the system has to resolve the pathname of the boot device
   7244  * to it's ppa.
   7245  */
   7246 int
   7247 i_ddi_devi_get_ppa(dev_info_t *dip)
   7248 {
   7249 	return (ddi_prop_get_int(DDI_DEV_T_ANY, dip,
   7250 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
   7251 	    GLD_DRIVER_PPA, ddi_get_instance(dip)));
   7252 }
   7253 
   7254 /*
   7255  * i_ddi_devi_set_ppa() should only be called from gld_register()
   7256  * and only for GLD v0 drivers
   7257  */
   7258 void
   7259 i_ddi_devi_set_ppa(dev_info_t *dip, int ppa)
   7260 {
   7261 	(void) e_ddi_prop_update_int(DDI_DEV_T_NONE, dip, GLD_DRIVER_PPA, ppa);
   7262 }
   7263 
   7264 
   7265 /*
   7266  * Private DDI Console bell functions.
   7267  */
   7268 void
   7269 ddi_ring_console_bell(clock_t duration)
   7270 {
   7271 	if (ddi_console_bell_func != NULL)
   7272 		(*ddi_console_bell_func)(duration);
   7273 }
   7274 
   7275 void
   7276 ddi_set_console_bell(void (*bellfunc)(clock_t duration))
   7277 {
   7278 	ddi_console_bell_func = bellfunc;
   7279 }
   7280 
   7281 int
   7282 ddi_dma_alloc_handle(dev_info_t *dip, ddi_dma_attr_t *attr,
   7283 	int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
   7284 {
   7285 	int (*funcp)() = ddi_dma_allochdl;
   7286 	ddi_dma_attr_t dma_attr;
   7287 	struct bus_ops *bop;
   7288 
   7289 	if (attr == (ddi_dma_attr_t *)0)
   7290 		return (DDI_DMA_BADATTR);
   7291 
   7292 	dma_attr = *attr;
   7293 
   7294 	bop = DEVI(dip)->devi_ops->devo_bus_ops;
   7295 	if (bop && bop->bus_dma_allochdl)
   7296 		funcp = bop->bus_dma_allochdl;
   7297 
   7298 	return ((*funcp)(dip, dip, &dma_attr, waitfp, arg, handlep));
   7299 }
   7300 
   7301 void
   7302 ddi_dma_free_handle(ddi_dma_handle_t *handlep)
   7303 {
   7304 	ddi_dma_handle_t h = *handlep;
   7305 	(void) ddi_dma_freehdl(HD, HD, h);
   7306 }
   7307 
   7308 static uintptr_t dma_mem_list_id = 0;
   7309 
   7310 
   7311 int
   7312 ddi_dma_mem_alloc(ddi_dma_handle_t handle, size_t length,
   7313 	ddi_device_acc_attr_t *accattrp, uint_t flags,
   7314 	int (*waitfp)(caddr_t), caddr_t arg, caddr_t *kaddrp,
   7315 	size_t *real_length, ddi_acc_handle_t *handlep)
   7316 {
   7317 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7318 	dev_info_t *dip = hp->dmai_rdip;
   7319 	ddi_acc_hdl_t *ap;
   7320 	ddi_dma_attr_t *attrp = &hp->dmai_attr;
   7321 	uint_t sleepflag, xfermodes;
   7322 	int (*fp)(caddr_t);
   7323 	int rval;
   7324 
   7325 	if (waitfp == DDI_DMA_SLEEP)
   7326 		fp = (int (*)())KM_SLEEP;
   7327 	else if (waitfp == DDI_DMA_DONTWAIT)
   7328 		fp = (int (*)())KM_NOSLEEP;
   7329 	else
   7330 		fp = waitfp;
   7331 	*handlep = impl_acc_hdl_alloc(fp, arg);
   7332 	if (*handlep == NULL)
   7333 		return (DDI_FAILURE);
   7334 
   7335 	/* check if the cache attributes are supported */
   7336 	if (i_ddi_check_cache_attr(flags) == B_FALSE)
   7337 		return (DDI_FAILURE);
   7338 
   7339 	/*
   7340 	 * Transfer the meaningful bits to xfermodes.
   7341 	 * Double-check if the 3rd party driver correctly sets the bits.
   7342 	 * If not, set DDI_DMA_STREAMING to keep compatibility.
   7343 	 */
   7344 	xfermodes = flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING);
   7345 	if (xfermodes == 0) {
   7346 		xfermodes = DDI_DMA_STREAMING;
   7347 	}
   7348 
   7349 	/*
   7350 	 * initialize the common elements of data access handle
   7351 	 */
   7352 	ap = impl_acc_hdl_get(*handlep);
   7353 	ap->ah_vers = VERS_ACCHDL;
   7354 	ap->ah_dip = dip;
   7355 	ap->ah_offset = 0;
   7356 	ap->ah_len = 0;
   7357 	ap->ah_xfermodes = flags;
   7358 	ap->ah_acc = *accattrp;
   7359 
   7360 	sleepflag = ((waitfp == DDI_DMA_SLEEP) ? 1 : 0);
   7361 	if (xfermodes == DDI_DMA_CONSISTENT) {
   7362 		rval = i_ddi_mem_alloc(dip, attrp, length, sleepflag,
   7363 		    flags, accattrp, kaddrp, NULL, ap);
   7364 		*real_length = length;
   7365 	} else {
   7366 		rval = i_ddi_mem_alloc(dip, attrp, length, sleepflag,
   7367 		    flags, accattrp, kaddrp, real_length, ap);
   7368 	}
   7369 	if (rval == DDI_SUCCESS) {
   7370 		ap->ah_len = (off_t)(*real_length);
   7371 		ap->ah_addr = *kaddrp;
   7372 	} else {
   7373 		impl_acc_hdl_free(*handlep);
   7374 		*handlep = (ddi_acc_handle_t)NULL;
   7375 		if (waitfp != DDI_DMA_SLEEP && waitfp != DDI_DMA_DONTWAIT) {
   7376 			ddi_set_callback(waitfp, arg, &dma_mem_list_id);
   7377 		}
   7378 		rval = DDI_FAILURE;
   7379 	}
   7380 	return (rval);
   7381 }
   7382 
   7383 void
   7384 ddi_dma_mem_free(ddi_acc_handle_t *handlep)
   7385 {
   7386 	ddi_acc_hdl_t *ap;
   7387 
   7388 	ap = impl_acc_hdl_get(*handlep);
   7389 	ASSERT(ap);
   7390 
   7391 	i_ddi_mem_free((caddr_t)ap->ah_addr, ap);
   7392 
   7393 	/*
   7394 	 * free the handle
   7395 	 */
   7396 	impl_acc_hdl_free(*handlep);
   7397 	*handlep = (ddi_acc_handle_t)NULL;
   7398 
   7399 	if (dma_mem_list_id != 0) {
   7400 		ddi_run_callback(&dma_mem_list_id);
   7401 	}
   7402 }
   7403 
   7404 int
   7405 ddi_dma_buf_bind_handle(ddi_dma_handle_t handle, struct buf *bp,
   7406 	uint_t flags, int (*waitfp)(caddr_t), caddr_t arg,
   7407 	ddi_dma_cookie_t *cookiep, uint_t *ccountp)
   7408 {
   7409 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7410 	dev_info_t *dip, *rdip;
   7411 	struct ddi_dma_req dmareq;
   7412 	int (*funcp)();
   7413 
   7414 	dmareq.dmar_flags = flags;
   7415 	dmareq.dmar_fp = waitfp;
   7416 	dmareq.dmar_arg = arg;
   7417 	dmareq.dmar_object.dmao_size = (uint_t)bp->b_bcount;
   7418 
   7419 	if (bp->b_flags & B_PAGEIO) {
   7420 		dmareq.dmar_object.dmao_type = DMA_OTYP_PAGES;
   7421 		dmareq.dmar_object.dmao_obj.pp_obj.pp_pp = bp->b_pages;
   7422 		dmareq.dmar_object.dmao_obj.pp_obj.pp_offset =
   7423 		    (uint_t)(((uintptr_t)bp->b_un.b_addr) & MMU_PAGEOFFSET);
   7424 	} else {
   7425 		dmareq.dmar_object.dmao_obj.virt_obj.v_addr = bp->b_un.b_addr;
   7426 		if (bp->b_flags & B_SHADOW) {
   7427 			dmareq.dmar_object.dmao_obj.virt_obj.v_priv =
   7428 			    bp->b_shadow;
   7429 			dmareq.dmar_object.dmao_type = DMA_OTYP_BUFVADDR;
   7430 		} else {
   7431 			dmareq.dmar_object.dmao_type =
   7432 			    (bp->b_flags & (B_PHYS | B_REMAPPED)) ?
   7433 			    DMA_OTYP_BUFVADDR : DMA_OTYP_VADDR;
   7434 			dmareq.dmar_object.dmao_obj.virt_obj.v_priv = NULL;
   7435 		}
   7436 
   7437 		/*
   7438 		 * If the buffer has no proc pointer, or the proc
   7439 		 * struct has the kernel address space, or the buffer has
   7440 		 * been marked B_REMAPPED (meaning that it is now
   7441 		 * mapped into the kernel's address space), then
   7442 		 * the address space is kas (kernel address space).
   7443 		 */
   7444 		if ((bp->b_proc == NULL) || (bp->b_proc->p_as == &kas) ||
   7445 		    (bp->b_flags & B_REMAPPED)) {
   7446 			dmareq.dmar_object.dmao_obj.virt_obj.v_as = 0;
   7447 		} else {
   7448 			dmareq.dmar_object.dmao_obj.virt_obj.v_as =
   7449 			    bp->b_proc->p_as;
   7450 		}
   7451 	}
   7452 
   7453 	dip = rdip = hp->dmai_rdip;
   7454 	if (dip != ddi_root_node())
   7455 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_bindhdl;
   7456 	funcp = DEVI(rdip)->devi_bus_dma_bindfunc;
   7457 	return ((*funcp)(dip, rdip, handle, &dmareq, cookiep, ccountp));
   7458 }
   7459 
   7460 int
   7461 ddi_dma_addr_bind_handle(ddi_dma_handle_t handle, struct as *as,
   7462 	caddr_t addr, size_t len, uint_t flags, int (*waitfp)(caddr_t),
   7463 	caddr_t arg, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
   7464 {
   7465 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7466 	dev_info_t *dip, *rdip;
   7467 	struct ddi_dma_req dmareq;
   7468 	int (*funcp)();
   7469 
   7470 	if (len == (uint_t)0) {
   7471 		return (DDI_DMA_NOMAPPING);
   7472 	}
   7473 	dmareq.dmar_flags = flags;
   7474 	dmareq.dmar_fp = waitfp;
   7475 	dmareq.dmar_arg = arg;
   7476 	dmareq.dmar_object.dmao_size = len;
   7477 	dmareq.dmar_object.dmao_type = DMA_OTYP_VADDR;
   7478 	dmareq.dmar_object.dmao_obj.virt_obj.v_as = as;
   7479 	dmareq.dmar_object.dmao_obj.virt_obj.v_addr = addr;
   7480 	dmareq.dmar_object.dmao_obj.virt_obj.v_priv = NULL;
   7481 
   7482 	dip = rdip = hp->dmai_rdip;
   7483 	if (dip != ddi_root_node())
   7484 		dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_bindhdl;
   7485 	funcp = DEVI(rdip)->devi_bus_dma_bindfunc;
   7486 	return ((*funcp)(dip, rdip, handle, &dmareq, cookiep, ccountp));
   7487 }
   7488 
   7489 void
   7490 ddi_dma_nextcookie(ddi_dma_handle_t handle, ddi_dma_cookie_t *cookiep)
   7491 {
   7492 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7493 	ddi_dma_cookie_t *cp;
   7494 
   7495 	cp = hp->dmai_cookie;
   7496 	ASSERT(cp);
   7497 
   7498 	cookiep->dmac_notused = cp->dmac_notused;
   7499 	cookiep->dmac_type = cp->dmac_type;
   7500 	cookiep->dmac_address = cp->dmac_address;
   7501 	cookiep->dmac_size = cp->dmac_size;
   7502 	hp->dmai_cookie++;
   7503 }
   7504 
   7505 int
   7506 ddi_dma_numwin(ddi_dma_handle_t handle, uint_t *nwinp)
   7507 {
   7508 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7509 	if ((hp->dmai_rflags & DDI_DMA_PARTIAL) == 0) {
   7510 		return (DDI_FAILURE);
   7511 	} else {
   7512 		*nwinp = hp->dmai_nwin;
   7513 		return (DDI_SUCCESS);
   7514 	}
   7515 }
   7516 
   7517 int
   7518 ddi_dma_getwin(ddi_dma_handle_t h, uint_t win, off_t *offp,
   7519 	size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
   7520 {
   7521 	int (*funcp)() = ddi_dma_win;
   7522 	struct bus_ops *bop;
   7523 
   7524 	bop = DEVI(HD)->devi_ops->devo_bus_ops;
   7525 	if (bop && bop->bus_dma_win)
   7526 		funcp = bop->bus_dma_win;
   7527 
   7528 	return ((*funcp)(HD, HD, h, win, offp, lenp, cookiep, ccountp));
   7529 }
   7530 
   7531 int
   7532 ddi_dma_set_sbus64(ddi_dma_handle_t h, ulong_t burstsizes)
   7533 {
   7534 	return (ddi_dma_mctl(HD, HD, h, DDI_DMA_SET_SBUS64, 0,
   7535 	    &burstsizes, 0, 0));
   7536 }
   7537 
   7538 int
   7539 i_ddi_dma_fault_check(ddi_dma_impl_t *hp)
   7540 {
   7541 	return (hp->dmai_fault);
   7542 }
   7543 
   7544 int
   7545 ddi_check_dma_handle(ddi_dma_handle_t handle)
   7546 {
   7547 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7548 	int (*check)(ddi_dma_impl_t *);
   7549 
   7550 	if ((check = hp->dmai_fault_check) == NULL)
   7551 		check = i_ddi_dma_fault_check;
   7552 
   7553 	return (((*check)(hp) == DDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
   7554 }
   7555 
   7556 void
   7557 i_ddi_dma_set_fault(ddi_dma_handle_t handle)
   7558 {
   7559 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7560 	void (*notify)(ddi_dma_impl_t *);
   7561 
   7562 	if (!hp->dmai_fault) {
   7563 		hp->dmai_fault = 1;
   7564 		if ((notify = hp->dmai_fault_notify) != NULL)
   7565 			(*notify)(hp);
   7566 	}
   7567 }
   7568 
   7569 void
   7570 i_ddi_dma_clr_fault(ddi_dma_handle_t handle)
   7571 {
   7572 	ddi_dma_impl_t *hp = (ddi_dma_impl_t *)handle;
   7573 	void (*notify)(ddi_dma_impl_t *);
   7574 
   7575 	if (hp->dmai_fault) {
   7576 		hp->dmai_fault = 0;
   7577 		if ((notify = hp->dmai_fault_notify) != NULL)
   7578 			(*notify)(hp);
   7579 	}
   7580 }
   7581 
   7582 /*
   7583  * register mapping routines.
   7584  */
   7585 int
   7586 ddi_regs_map_setup(dev_info_t *dip, uint_t rnumber, caddr_t *addrp,
   7587 	offset_t offset, offset_t len, ddi_device_acc_attr_t *accattrp,
   7588 	ddi_acc_handle_t *handle)
   7589 {
   7590 	ddi_map_req_t mr;
   7591 	ddi_acc_hdl_t *hp;
   7592 	int result;
   7593 
   7594 	/*
   7595 	 * Allocate and initialize the common elements of data access handle.
   7596 	 */
   7597 	*handle = impl_acc_hdl_alloc(KM_SLEEP, NULL);
   7598 	hp = impl_acc_hdl_get(*handle);
   7599 	hp->ah_vers = VERS_ACCHDL;
   7600 	hp->ah_dip = dip;
   7601 	hp->ah_rnumber = rnumber;
   7602 	hp->ah_offset = offset;
   7603 	hp->ah_len = len;
   7604 	hp->ah_acc = *accattrp;
   7605 
   7606 	/*
   7607 	 * Set up the mapping request and call to parent.
   7608 	 */
   7609 	mr.map_op = DDI_MO_MAP_LOCKED;
   7610 	mr.map_type = DDI_MT_RNUMBER;
   7611 	mr.map_obj.rnumber = rnumber;
   7612 	mr.map_prot = PROT_READ | PROT_WRITE;
   7613 	mr.map_flags = DDI_MF_KERNEL_MAPPING;
   7614 	mr.map_handlep = hp;
   7615 	mr.map_vers = DDI_MAP_VERSION;
   7616 	result = ddi_map(dip, &mr, offset, len, addrp);
   7617 
   7618 	/*
   7619 	 * check for end result
   7620 	 */
   7621 	if (result != DDI_SUCCESS) {
   7622 		impl_acc_hdl_free(*handle);
   7623 		*handle = (ddi_acc_handle_t)NULL;
   7624 	} else {
   7625 		hp->ah_addr = *addrp;
   7626 	}
   7627 
   7628 	return (result);
   7629 }
   7630 
   7631 void
   7632 ddi_regs_map_free(ddi_acc_handle_t *handlep)
   7633 {
   7634 	ddi_map_req_t mr;
   7635 	ddi_acc_hdl_t *hp;
   7636 
   7637 	hp = impl_acc_hdl_get(*handlep);
   7638 	ASSERT(hp);
   7639 
   7640 	mr.map_op = DDI_MO_UNMAP;
   7641 	mr.map_type = DDI_MT_RNUMBER;
   7642 	mr.map_obj.rnumber = hp->ah_rnumber;
   7643 	mr.map_prot = PROT_READ | PROT_WRITE;
   7644 	mr.map_flags = DDI_MF_KERNEL_MAPPING;
   7645 	mr.map_handlep = hp;
   7646 	mr.map_vers = DDI_MAP_VERSION;
   7647 
   7648 	/*
   7649 	 * Call my parent to unmap my regs.
   7650 	 */
   7651 	(void) ddi_map(hp->ah_dip, &mr, hp->ah_offset,
   7652 	    hp->ah_len, &hp->ah_addr);
   7653 	/*
   7654 	 * free the handle
   7655 	 */
   7656 	impl_acc_hdl_free(*handlep);
   7657 	*handlep = (ddi_acc_handle_t)NULL;
   7658 }
   7659 
   7660 int
   7661 ddi_device_zero(ddi_acc_handle_t handle, caddr_t dev_addr, size_t bytecount,
   7662 	ssize_t dev_advcnt, uint_t dev_datasz)
   7663 {
   7664 	uint8_t *b;
   7665 	uint16_t *w;
   7666 	uint32_t *l;
   7667 	uint64_t *ll;
   7668 
   7669 	/* check for total byte count is multiple of data transfer size */
   7670 	if (bytecount != ((bytecount / dev_datasz) * dev_datasz))
   7671 		return (DDI_FAILURE);
   7672 
   7673 	switch (dev_datasz) {
   7674 	case DDI_DATA_SZ01_ACC:
   7675 		for (b = (uint8_t *)dev_addr;
   7676 		    bytecount != 0; bytecount -= 1, b += dev_advcnt)
   7677 			ddi_put8(handle, b, 0);
   7678 		break;
   7679 	case DDI_DATA_SZ02_ACC:
   7680 		for (w = (uint16_t *)dev_addr;
   7681 		    bytecount != 0; bytecount -= 2, w += dev_advcnt)
   7682 			ddi_put16(handle, w, 0);
   7683 		break;
   7684 	case DDI_DATA_SZ04_ACC:
   7685 		for (l = (uint32_t *)dev_addr;
   7686 		    bytecount != 0; bytecount -= 4, l += dev_advcnt)
   7687 			ddi_put32(handle, l, 0);
   7688 		break;
   7689 	case DDI_DATA_SZ08_ACC:
   7690 		for (ll = (uint64_t *)dev_addr;
   7691 		    bytecount != 0; bytecount -= 8, ll += dev_advcnt)
   7692 			ddi_put64(handle, ll, 0x0ll);
   7693 		break;
   7694 	default:
   7695 		return (DDI_FAILURE);
   7696 	}
   7697 	return (DDI_SUCCESS);
   7698 }
   7699 
   7700 int
   7701 ddi_device_copy(
   7702 	ddi_acc_handle_t src_handle, caddr_t src_addr, ssize_t src_advcnt,
   7703 	ddi_acc_handle_t dest_handle, caddr_t dest_addr, ssize_t dest_advcnt,
   7704 	size_t bytecount, uint_t dev_datasz)
   7705 {
   7706 	uint8_t *b_src, *b_dst;
   7707 	uint16_t *w_src, *w_dst;
   7708 	uint32_t *l_src, *l_dst;
   7709 	uint64_t *ll_src, *ll_dst;
   7710 
   7711 	/* check for total byte count is multiple of data transfer size */
   7712 	if (bytecount != ((bytecount / dev_datasz) * dev_datasz))
   7713 		return (DDI_FAILURE);
   7714 
   7715 	switch (dev_datasz) {
   7716 	case DDI_DATA_SZ01_ACC:
   7717 		b_src = (uint8_t *)src_addr;
   7718 		b_dst = (uint8_t *)dest_addr;
   7719 
   7720 		for (; bytecount != 0; bytecount -= 1) {
   7721 			ddi_put8(dest_handle, b_dst,
   7722 			    ddi_get8(src_handle, b_src));
   7723 			b_dst += dest_advcnt;
   7724 			b_src += src_advcnt;
   7725 		}
   7726 		break;
   7727 	case DDI_DATA_SZ02_ACC:
   7728 		w_src = (uint16_t *)src_addr;
   7729 		w_dst = (uint16_t *)dest_addr;
   7730 
   7731 		for (; bytecount != 0; bytecount -= 2) {
   7732 			ddi_put16(dest_handle, w_dst,
   7733 			    ddi_get16(src_handle, w_src));
   7734 			w_dst += dest_advcnt;
   7735 			w_src += src_advcnt;
   7736 		}
   7737 		break;
   7738 	case DDI_DATA_SZ04_ACC:
   7739 		l_src = (uint32_t *)src_addr;
   7740 		l_dst = (uint32_t *)dest_addr;
   7741 
   7742 		for (; bytecount != 0; bytecount -= 4) {
   7743 			ddi_put32(dest_handle, l_dst,
   7744 			    ddi_get32(src_handle, l_src));
   7745 			l_dst += dest_advcnt;
   7746 			l_src += src_advcnt;
   7747 		}
   7748 		break;
   7749 	case DDI_DATA_SZ08_ACC:
   7750 		ll_src = (uint64_t *)src_addr;
   7751 		ll_dst = (uint64_t *)dest_addr;
   7752 
   7753 		for (; bytecount != 0; bytecount -= 8) {
   7754 			ddi_put64(dest_handle, ll_dst,
   7755 			    ddi_get64(src_handle, ll_src));
   7756 			ll_dst += dest_advcnt;
   7757 			ll_src += src_advcnt;
   7758 		}
   7759 		break;
   7760 	default:
   7761 		return (DDI_FAILURE);
   7762 	}
   7763 	return (DDI_SUCCESS);
   7764 }
   7765 
   7766 #define	swap16(value)  \
   7767 	((((value) & 0xff) << 8) | ((value) >> 8))
   7768 
   7769 #define	swap32(value)	\
   7770 	(((uint32_t)swap16((uint16_t)((value) & 0xffff)) << 16) | \
   7771 	(uint32_t)swap16((uint16_t)((value) >> 16)))
   7772 
   7773 #define	swap64(value)	\
   7774 	(((uint64_t)swap32((uint32_t)((value) & 0xffffffff)) \
   7775 	    << 32) | \
   7776 	(uint64_t)swap32((uint32_t)((value) >> 32)))
   7777 
   7778 uint16_t
   7779 ddi_swap16(uint16_t value)
   7780 {
   7781 	return (swap16(value));
   7782 }
   7783 
   7784 uint32_t
   7785 ddi_swap32(uint32_t value)
   7786 {
   7787 	return (swap32(value));
   7788 }
   7789 
   7790 uint64_t
   7791 ddi_swap64(uint64_t value)
   7792 {
   7793 	return (swap64(value));
   7794 }
   7795 
   7796 /*
   7797  * Convert a binding name to a driver name.
   7798  * A binding name is the name used to determine the driver for a
   7799  * device - it may be either an alias for the driver or the name
   7800  * of the driver itself.
   7801  */
   7802 char *
   7803 i_binding_to_drv_name(char *bname)
   7804 {
   7805 	major_t major_no;
   7806 
   7807 	ASSERT(bname != NULL);
   7808 
   7809 	if ((major_no = ddi_name_to_major(bname)) == -1)
   7810 		return (NULL);
   7811 	return (ddi_major_to_name(major_no));
   7812 }
   7813 
   7814 /*
   7815  * Search for minor name that has specified dev_t and spec_type.
   7816  * If spec_type is zero then any dev_t match works.  Since we
   7817  * are returning a pointer to the minor name string, we require the
   7818  * caller to do the locking.
   7819  */
   7820 char *
   7821 i_ddi_devtspectype_to_minorname(dev_info_t *dip, dev_t dev, int spec_type)
   7822 {
   7823 	struct ddi_minor_data	*dmdp;
   7824 
   7825 	/*
   7826 	 * The did layered driver currently intentionally returns a
   7827 	 * devinfo ptr for an underlying sd instance based on a did
   7828 	 * dev_t. In this case it is not an error.
   7829 	 *
   7830 	 * The did layered driver is associated with Sun Cluster.
   7831 	 */
   7832 	ASSERT((ddi_driver_major(dip) == getmajor(dev)) ||
   7833 	    (strcmp(ddi_major_to_name(getmajor(dev)), "did") == 0));
   7834 
   7835 	ASSERT(DEVI_BUSY_OWNED(dip));
   7836 	for (dmdp = DEVI(dip)->devi_minor; dmdp; dmdp = dmdp->next) {
   7837 		if (((dmdp->type == DDM_MINOR) ||
   7838 		    (dmdp->type == DDM_INTERNAL_PATH) ||
   7839 		    (dmdp->type == DDM_DEFAULT)) &&
   7840 		    (dmdp->ddm_dev == dev) &&
   7841 		    ((((spec_type & (S_IFCHR|S_IFBLK))) == 0) ||
   7842 		    (dmdp->ddm_spec_type == spec_type)))
   7843 			return (dmdp->ddm_name);
   7844 	}
   7845 
   7846 	return (NULL);
   7847 }
   7848 
   7849 /*
   7850  * Find the devt and spectype of the specified minor_name.
   7851  * Return DDI_FAILURE if minor_name not found. Since we are
   7852  * returning everything via arguments we can do the locking.
   7853  */
   7854 int
   7855 i_ddi_minorname_to_devtspectype(dev_info_t *dip, char *minor_name,
   7856 	dev_t *devtp, int *spectypep)
   7857 {
   7858 	int			circ;
   7859 	struct ddi_minor_data	*dmdp;
   7860 
   7861 	/* deal with clone minor nodes */
   7862 	if (dip == clone_dip) {
   7863 		major_t	major;
   7864 		/*
   7865 		 * Make sure minor_name is a STREAMS driver.
   7866 		 * We load the driver but don't attach to any instances.
   7867 		 */
   7868 
   7869 		major = ddi_name_to_major(minor_name);
   7870 		if (major == DDI_MAJOR_T_NONE)
   7871 			return (DDI_FAILURE);
   7872 
   7873 		if (ddi_hold_driver(major) == NULL)
   7874 			return (DDI_FAILURE);
   7875 
   7876 		if (STREAMSTAB(major) == NULL) {
   7877 			ddi_rele_driver(major);
   7878 			return (DDI_FAILURE);
   7879 		}
   7880 		ddi_rele_driver(major);
   7881 
   7882 		if (devtp)
   7883 			*devtp = makedevice(clone_major, (minor_t)major);
   7884 
   7885 		if (spectypep)
   7886 			*spectypep = S_IFCHR;
   7887 
   7888 		return (DDI_SUCCESS);
   7889 	}
   7890 
   7891 	ndi_devi_enter(dip, &circ);
   7892 	for (dmdp = DEVI(dip)->devi_minor; dmdp; dmdp = dmdp->next) {
   7893 		if (((dmdp->type != DDM_MINOR) &&
   7894 		    (dmdp->type != DDM_INTERNAL_PATH) &&
   7895 		    (dmdp->type != DDM_DEFAULT)) ||
   7896 		    strcmp(minor_name, dmdp->ddm_name))
   7897 			continue;
   7898 
   7899 		if (devtp)
   7900 			*devtp = dmdp->ddm_dev;
   7901 
   7902 		if (spectypep)
   7903 			*spectypep = dmdp->ddm_spec_type;
   7904 
   7905 		ndi_devi_exit(dip, circ);
   7906 		return (DDI_SUCCESS);
   7907 	}
   7908 	ndi_devi_exit(dip, circ);
   7909 
   7910 	return (DDI_FAILURE);
   7911 }
   7912 
   7913 static kmutex_t devid_gen_mutex;
   7914 static short	devid_gen_number;
   7915 
   7916 #ifdef DEBUG
   7917 
   7918 static int	devid_register_corrupt = 0;
   7919 static int	devid_register_corrupt_major = 0;
   7920 static int	devid_register_corrupt_hint = 0;
   7921 static int	devid_register_corrupt_hint_major = 0;
   7922 
   7923 static int devid_lyr_debug = 0;
   7924 
   7925 #define	DDI_DEBUG_DEVID_DEVTS(msg, ndevs, devs)		\
   7926 	if (devid_lyr_debug)					\
   7927 		ddi_debug_devid_devts(msg, ndevs, devs)
   7928 
   7929 #else
   7930 
   7931 #define	DDI_DEBUG_DEVID_DEVTS(msg, ndevs, devs)
   7932 
   7933 #endif /* DEBUG */
   7934 
   7935 
   7936 #ifdef	DEBUG
   7937 
   7938 static void
   7939 ddi_debug_devid_devts(char *msg, int ndevs, dev_t *devs)
   7940 {
   7941 	int i;
   7942 
   7943 	cmn_err(CE_CONT, "%s:\n", msg);
   7944 	for (i = 0; i < ndevs; i++) {
   7945 		cmn_err(CE_CONT, "    0x%lx\n", devs[i]);
   7946 	}
   7947 }
   7948 
   7949 static void
   7950 ddi_debug_devid_paths(char *msg, int npaths, char **paths)
   7951 {
   7952 	int i;
   7953 
   7954 	cmn_err(CE_CONT, "%s:\n", msg);
   7955 	for (i = 0; i < npaths; i++) {
   7956 		cmn_err(CE_CONT, "    %s\n", paths[i]);
   7957 	}
   7958 }
   7959 
   7960 static void
   7961 ddi_debug_devid_devts_per_path(char *path, int ndevs, dev_t *devs)
   7962 {
   7963 	int i;
   7964 
   7965 	cmn_err(CE_CONT, "dev_ts per path %s\n", path);
   7966 	for (i = 0; i < ndevs; i++) {
   7967 		cmn_err(CE_CONT, "    0x%lx\n", devs[i]);
   7968 	}
   7969 }
   7970 
   7971 #endif	/* DEBUG */
   7972 
   7973 /*
   7974  * Register device id into DDI framework.
   7975  * Must be called when the driver is bound.
   7976  */
   7977 static int
   7978 i_ddi_devid_register(dev_info_t *dip, ddi_devid_t devid)
   7979 {
   7980 	impl_devid_t	*i_devid = (impl_devid_t *)devid;
   7981 	size_t		driver_len;
   7982 	const char	*driver_name;
   7983 	char		*devid_str;
   7984 	major_t		major;
   7985 
   7986 	if ((dip == NULL) ||
   7987 	    ((major = ddi_driver_major(dip)) == DDI_MAJOR_T_NONE))
   7988 		return (DDI_FAILURE);
   7989 
   7990 	/* verify that the devid is valid */
   7991 	if (ddi_devid_valid(devid) != DDI_SUCCESS)
   7992 		return (DDI_FAILURE);
   7993 
   7994 	/* Updating driver name hint in devid */
   7995 	driver_name = ddi_driver_name(dip);
   7996 	driver_len = strlen(driver_name);
   7997 	if (driver_len > DEVID_HINT_SIZE) {
   7998 		/* Pick up last four characters of driver name */
   7999 		driver_name += driver_len - DEVID_HINT_SIZE;
   8000 		driver_len = DEVID_HINT_SIZE;
   8001 	}
   8002 	bzero(i_devid->did_driver, DEVID_HINT_SIZE);
   8003 	bcopy(driver_name, i_devid->did_driver, driver_len);
   8004 
   8005 #ifdef DEBUG
   8006 	/* Corrupt the devid for testing. */
   8007 	if (devid_register_corrupt)
   8008 		i_devid->did_id[0] += devid_register_corrupt;
   8009 	if (devid_register_corrupt_major &&
   8010 	    (major == devid_register_corrupt_major))
   8011 		i_devid->did_id[0] += 1;
   8012 	if (devid_register_corrupt_hint)
   8013 		i_devid->did_driver[0] += devid_register_corrupt_hint;
   8014 	if (devid_register_corrupt_hint_major &&
   8015 	    (major == devid_register_corrupt_hint_major))
   8016 		i_devid->did_driver[0] += 1;
   8017 #endif /* DEBUG */
   8018 
   8019 	/* encode the devid as a string */
   8020 	if ((devid_str = ddi_devid_str_encode(devid, NULL)) == NULL)
   8021 		return (DDI_FAILURE);
   8022 
   8023 	/* add string as a string property */
   8024 	if (ndi_prop_update_string(DDI_DEV_T_NONE, dip,
   8025 	    DEVID_PROP_NAME, devid_str) != DDI_SUCCESS) {
   8026 		cmn_err(CE_WARN, "%s%d: devid property update failed",
   8027 		    ddi_driver_name(dip), ddi_get_instance(dip));
   8028 		ddi_devid_str_free(devid_str);
   8029 		return (DDI_FAILURE);
   8030 	}
   8031 
   8032 	/* keep pointer to devid string for interrupt context fma code */
   8033 	if (DEVI(dip)->devi_devid_str)
   8034 		ddi_devid_str_free(DEVI(dip)->devi_devid_str);
   8035 	DEVI(dip)->devi_devid_str = devid_str;
   8036 	return (DDI_SUCCESS);
   8037 }
   8038 
   8039 int
   8040 ddi_devid_register(dev_info_t *dip, ddi_devid_t devid)
   8041 {
   8042 	int rval;
   8043 
   8044 	rval = i_ddi_devid_register(dip, devid);
   8045 	if (rval == DDI_SUCCESS) {
   8046 		/*
   8047 		 * Register devid in devid-to-path cache
   8048 		 */
   8049 		if (e_devid_cache_register(dip, devid) == DDI_SUCCESS) {
   8050 			mutex_enter(&DEVI(dip)->devi_lock);
   8051 			DEVI(dip)->devi_flags |= DEVI_CACHED_DEVID;
   8052 			mutex_exit(&DEVI(dip)->devi_lock);
   8053 		} else if (ddi_get_name_addr(dip)) {
   8054 			/*
   8055 			 * We only expect cache_register DDI_FAILURE when we
   8056 			 * can't form the full path because of NULL devi_addr.
   8057 			 */
   8058 			cmn_err(CE_WARN, "%s%d: failed to cache devid",
   8059 			    ddi_driver_name(dip), ddi_get_instance(dip));
   8060 		}
   8061 	} else {
   8062 		cmn_err(CE_WARN, "%s%d: failed to register devid",
   8063 		    ddi_driver_name(dip), ddi_get_instance(dip));
   8064 	}
   8065 	return (rval);
   8066 }
   8067 
   8068 /*
   8069  * Remove (unregister) device id from DDI framework.
   8070  * Must be called when device is detached.
   8071  */
   8072 static void
   8073 i_ddi_devid_unregister(dev_info_t *dip)
   8074 {
   8075 	if (DEVI(dip)->devi_devid_str) {
   8076 		ddi_devid_str_free(DEVI(dip)->devi_devid_str);
   8077 		DEVI(dip)->devi_devid_str = NULL;
   8078 	}
   8079 
   8080 	/* remove the devid property */
   8081 	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, DEVID_PROP_NAME);
   8082 }
   8083 
   8084 void
   8085 ddi_devid_unregister(dev_info_t *dip)
   8086 {
   8087 	mutex_enter(&DEVI(dip)->devi_lock);
   8088 	DEVI(dip)->devi_flags &= ~DEVI_CACHED_DEVID;
   8089 	mutex_exit(&DEVI(dip)->devi_lock);
   8090 	e_devid_cache_unregister(dip);
   8091 	i_ddi_devid_unregister(dip);
   8092 }
   8093 
   8094 /*
   8095  * Allocate and initialize a device id.
   8096  */
   8097 int
   8098 ddi_devid_init(
   8099 	dev_info_t	*dip,
   8100 	ushort_t	devid_type,
   8101 	ushort_t	nbytes,
   8102 	void		*id,
   8103 	ddi_devid_t	*ret_devid)
   8104 {
   8105 	impl_devid_t	*i_devid;
   8106 	int		sz = sizeof (*i_devid) + nbytes - sizeof (char);
   8107 	int		driver_len;
   8108 	const char	*driver_name;
   8109 
   8110 	switch (devid_type) {
   8111 	case DEVID_SCSI3_WWN:
   8112 		/*FALLTHRU*/
   8113 	case DEVID_SCSI_SERIAL:
   8114 		/*FALLTHRU*/
   8115 	case DEVID_ATA_SERIAL:
   8116 		/*FALLTHRU*/
   8117 	case DEVID_ENCAP:
   8118 		if (nbytes == 0)
   8119 			return (DDI_FAILURE);
   8120 		if (id == NULL)
   8121 			return (DDI_FAILURE);
   8122 		break;
   8123 	case DEVID_FAB:
   8124 		if (nbytes != 0)
   8125 			return (DDI_FAILURE);
   8126 		if (id != NULL)
   8127 			return (DDI_FAILURE);
   8128 		nbytes = sizeof (int) +
   8129 		    sizeof (struct timeval32) + sizeof (short);
   8130 		sz += nbytes;
   8131 		break;
   8132 	default:
   8133 		return (DDI_FAILURE);
   8134 	}
   8135 
   8136 	if ((i_devid = kmem_zalloc(sz, KM_SLEEP)) == NULL)
   8137 		return (DDI_FAILURE);
   8138 
   8139 	i_devid->did_magic_hi = DEVID_MAGIC_MSB;
   8140 	i_devid->did_magic_lo = DEVID_MAGIC_LSB;
   8141 	i_devid->did_rev_hi = DEVID_REV_MSB;
   8142 	i_devid->did_rev_lo = DEVID_REV_LSB;
   8143 	DEVID_FORMTYPE(i_devid, devid_type);
   8144 	DEVID_FORMLEN(i_devid, nbytes);
   8145 
   8146 	/* Fill in driver name hint */
   8147 	driver_name = ddi_driver_name(dip);
   8148 	driver_len = strlen(driver_name);
   8149 	if (driver_len > DEVID_HINT_SIZE) {
   8150 		/* Pick up last four characters of driver name */
   8151 		driver_name += driver_len - DEVID_HINT_SIZE;
   8152 		driver_len = DEVID_HINT_SIZE;
   8153 	}
   8154 
   8155 	bcopy(driver_name, i_devid->did_driver, driver_len);
   8156 
   8157 	/* Fill in id field */
   8158 	if (devid_type == DEVID_FAB) {
   8159 		char		*cp;
   8160 		uint32_t	hostid;
   8161 		struct timeval32 timestamp32;
   8162 		int		i;
   8163 		int		*ip;
   8164 		short		gen;
   8165 
   8166 		/* increase the generation number */
   8167 		mutex_enter(&devid_gen_mutex);
   8168 		gen = devid_gen_number++;
   8169 		mutex_exit(&devid_gen_mutex);
   8170 
   8171 		cp = i_devid->did_id;
   8172 
   8173 		/* Fill in host id (big-endian byte ordering) */
   8174 		hostid = zone_get_hostid(NULL);
   8175 		*cp++ = hibyte(hiword(hostid));
   8176 		*cp++ = lobyte(hiword(hostid));
   8177 		*cp++ = hibyte(loword(hostid));
   8178 		*cp++ = lobyte(loword(hostid));
   8179 
   8180 		/*
   8181 		 * Fill in timestamp (big-endian byte ordering)
   8182 		 *
   8183 		 * (Note that the format may have to be changed
   8184 		 * before 2038 comes around, though it's arguably
   8185 		 * unique enough as it is..)
   8186 		 */
   8187 		uniqtime32(&timestamp32);
   8188 		ip = (int *)&timestamp32;
   8189 		for (i = 0;
   8190 		    i < sizeof (timestamp32) / sizeof (int); i++, ip++) {
   8191 			int	val;
   8192 			val = *ip;
   8193 			*cp++ = hibyte(hiword(val));
   8194 			*cp++ = lobyte(hiword(val));
   8195 			*cp++ = hibyte(loword(val));
   8196 			*cp++ = lobyte(loword(val));
   8197 		}
   8198 
   8199 		/* fill in the generation number */
   8200 		*cp++ = hibyte(gen);
   8201 		*cp++ = lobyte(gen);
   8202 	} else
   8203 		bcopy(id, i_devid->did_id, nbytes);
   8204 
   8205 	/* return device id */
   8206 	*ret_devid = (ddi_devid_t)i_devid;
   8207 	return (DDI_SUCCESS);
   8208 }
   8209 
   8210 int
   8211 ddi_devid_get(dev_info_t *dip, ddi_devid_t *ret_devid)
   8212 {
   8213 	return (i_ddi_devi_get_devid(DDI_DEV_T_ANY, dip, ret_devid));
   8214 }
   8215 
   8216 int
   8217 i_ddi_devi_get_devid(dev_t dev, dev_info_t *dip, ddi_devid_t *ret_devid)
   8218 {
   8219 	char		*devidstr;
   8220 
   8221 	ASSERT(dev != DDI_DEV_T_NONE);
   8222 
   8223 	/* look up the property, devt specific first */
   8224 	if (ddi_prop_lookup_string(dev, dip, DDI_PROP_DONTPASS,
   8225 	    DEVID_PROP_NAME, &devidstr) != DDI_PROP_SUCCESS) {
   8226 		if ((dev == DDI_DEV_T_ANY) ||
   8227 		    (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
   8228 		    DDI_PROP_DONTPASS, DEVID_PROP_NAME, &devidstr) !=
   8229 		    DDI_PROP_SUCCESS)) {
   8230 			return (DDI_FAILURE);
   8231 		}
   8232 	}
   8233 
   8234 	/* convert to binary form */
   8235 	if (ddi_devid_str_decode(devidstr, ret_devid, NULL) == -1) {
   8236 		ddi_prop_free(devidstr);
   8237 		return (DDI_FAILURE);
   8238 	}
   8239 	ddi_prop_free(devidstr);
   8240 	return (DDI_SUCCESS);
   8241 }
   8242 
   8243 /*
   8244  * Return a copy of the device id for dev_t
   8245  */
   8246 int
   8247 ddi_lyr_get_devid(dev_t dev, ddi_devid_t *ret_devid)
   8248 {
   8249 	dev_info_t	*dip;
   8250 	int		rval;
   8251 
   8252 	/* get the dip */
   8253 	if ((dip = e_ddi_hold_devi_by_dev(dev, 0)) == NULL)
   8254 		return (DDI_FAILURE);
   8255 
   8256 	rval = i_ddi_devi_get_devid(dev, dip, ret_devid);
   8257 
   8258 	ddi_release_devi(dip);		/* e_ddi_hold_devi_by_dev() */
   8259 	return (rval);
   8260 }
   8261 
   8262 /*
   8263  * Return a copy of the minor name for dev_t and spec_type
   8264  */
   8265 int
   8266 ddi_lyr_get_minor_name(dev_t dev, int spec_type, char **minor_name)
   8267 {
   8268 	char		*buf;
   8269 	int		circ;
   8270 	dev_info_t	*dip;
   8271 	char		*nm;
   8272 	int		rval;
   8273 
   8274 	if ((dip = e_ddi_hold_devi_by_dev(dev, 0)) == NULL) {
   8275 		*minor_name = NULL;
   8276 		return (DDI_FAILURE);
   8277 	}
   8278 
   8279 	/* Find the minor name and copy into max size buf */
   8280 	buf = kmem_alloc(MAXNAMELEN, KM_SLEEP);
   8281 	ndi_devi_enter(dip, &circ);
   8282 	nm = i_ddi_devtspectype_to_minorname(dip, dev, spec_type);
   8283 	if (nm)
   8284 		(void) strcpy(buf, nm);
   8285 	ndi_devi_exit(dip, circ);
   8286 	ddi_release_devi(dip);	/* e_ddi_hold_devi_by_dev() */
   8287 
   8288 	if (nm) {
   8289 		/* duplicate into min size buf for return result */
   8290 		*minor_name = i_ddi_strdup(buf, KM_SLEEP);
   8291 		rval = DDI_SUCCESS;
   8292 	} else {
   8293 		*minor_name = NULL;
   8294 		rval = DDI_FAILURE;
   8295 	}
   8296 
   8297 	/* free max size buf and return */
   8298 	kmem_free(buf, MAXNAMELEN);
   8299 	return (rval);
   8300 }
   8301 
   8302 int
   8303 ddi_lyr_devid_to_devlist(
   8304 	ddi_devid_t	devid,
   8305 	char		*minor_name,
   8306 	int		*retndevs,
   8307 	dev_t		**retdevs)
   8308 {
   8309 	ASSERT(ddi_devid_valid(devid) == DDI_SUCCESS);
   8310 
   8311 	if (e_devid_cache_to_devt_list(devid, minor_name,
   8312 	    retndevs, retdevs) == DDI_SUCCESS) {
   8313 		ASSERT(*retndevs > 0);
   8314 		DDI_DEBUG_DEVID_DEVTS("ddi_lyr_devid_to_devlist",
   8315 		    *retndevs, *retdevs);
   8316 		return (DDI_SUCCESS);
   8317 	}
   8318 
   8319 	if (e_ddi_devid_discovery(devid) == DDI_FAILURE) {
   8320 		return (DDI_FAILURE);
   8321 	}
   8322 
   8323 	if (e_devid_cache_to_devt_list(devid, minor_name,
   8324 	    retndevs, retdevs) == DDI_SUCCESS) {
   8325 		ASSERT(*retndevs > 0);
   8326 		DDI_DEBUG_DEVID_DEVTS("ddi_lyr_devid_to_devlist",
   8327 		    *retndevs, *retdevs);
   8328 		return (DDI_SUCCESS);
   8329 	}
   8330 
   8331 	return (DDI_FAILURE);
   8332 }
   8333 
   8334 void
   8335 ddi_lyr_free_devlist(dev_t *devlist, int ndevs)
   8336 {
   8337 	kmem_free(devlist, sizeof (dev_t) * ndevs);
   8338 }
   8339 
   8340 /*
   8341  * Note: This will need to be fixed if we ever allow processes to
   8342  * have more than one data model per exec.
   8343  */
   8344 model_t
   8345 ddi_mmap_get_model(void)
   8346 {
   8347 	return (get_udatamodel());
   8348 }
   8349 
   8350 model_t
   8351 ddi_model_convert_from(model_t model)
   8352 {
   8353 	return ((model & DDI_MODEL_MASK) & ~DDI_MODEL_NATIVE);
   8354 }
   8355 
   8356 /*
   8357  * ddi interfaces managing storage and retrieval of eventcookies.
   8358  */
   8359 
   8360 /*
   8361  * Invoke bus nexus driver's implementation of the
   8362  * (*bus_remove_eventcall)() interface to remove a registered
   8363  * callback handler for "event".
   8364  */
   8365 int
   8366 ddi_remove_event_handler(ddi_callback_id_t id)
   8367 {
   8368 	ndi_event_callbacks_t *cb = (ndi_event_callbacks_t *)id;
   8369 	dev_info_t *ddip;
   8370 
   8371 	ASSERT(cb);
   8372 	if (!cb) {
   8373 		return (DDI_FAILURE);
   8374 	}
   8375 
   8376 	ddip = NDI_EVENT_DDIP(cb->ndi_evtcb_cookie);
   8377 	return (ndi_busop_remove_eventcall(ddip, id));
   8378 }
   8379 
   8380 /*
   8381  * Invoke bus nexus driver's implementation of the
   8382  * (*bus_add_eventcall)() interface to register a callback handler
   8383  * for "event".
   8384  */
   8385 int
   8386 ddi_add_event_handler(dev_info_t *dip, ddi_eventcookie_t event,
   8387     void (*handler)(dev_info_t *, ddi_eventcookie_t, void *, void *),
   8388     void *arg, ddi_callback_id_t *id)
   8389 {
   8390 	return (ndi_busop_add_eventcall(dip, dip, event, handler, arg, id));
   8391 }
   8392 
   8393 
   8394 /*
   8395  * Return a handle for event "name" by calling up the device tree
   8396  * hierarchy via  (*bus_get_eventcookie)() interface until claimed
   8397  * by a bus nexus or top of dev_info tree is reached.
   8398  */
   8399 int
   8400 ddi_get_eventcookie(dev_info_t *dip, char *name,
   8401     ddi_eventcookie_t *event_cookiep)
   8402 {
   8403 	return (ndi_busop_get_eventcookie(dip, dip,
   8404 	    name, event_cookiep));
   8405 }
   8406 
   8407 /*
   8408  * This procedure is provided as the general callback function when
   8409  * umem_lockmemory calls as_add_callback for long term memory locking.
   8410  * When as_unmap, as_setprot, or as_free encounter segments which have
   8411  * locked memory, this callback will be invoked.
   8412  */
   8413 void
   8414 umem_lock_undo(struct as *as, void *arg, uint_t event)
   8415 {
   8416 	_NOTE(ARGUNUSED(as, event))
   8417 	struct ddi_umem_cookie *cp = (struct ddi_umem_cookie *)arg;
   8418 
   8419 	/*
   8420 	 * Call the cleanup function.  Decrement the cookie reference
   8421 	 * count, if it goes to zero, return the memory for the cookie.
   8422 	 * The i_ddi_umem_unlock for this cookie may or may not have been
   8423 	 * called already.  It is the responsibility of the caller of
   8424 	 * umem_lockmemory to handle the case of the cleanup routine
   8425 	 * being called after a ddi_umem_unlock for the cookie
   8426 	 * was called.
   8427 	 */
   8428 
   8429 	(*cp->callbacks.cbo_umem_lock_cleanup)((ddi_umem_cookie_t)cp);
   8430 
   8431 	/* remove the cookie if reference goes to zero */
   8432 	if (atomic_add_long_nv((ulong_t *)(&(cp->cook_refcnt)), -1) == 0) {
   8433 		kmem_free(cp, sizeof (struct ddi_umem_cookie));
   8434 	}
   8435 }
   8436 
   8437 /*
   8438  * The following two Consolidation Private routines provide generic
   8439  * interfaces to increase/decrease the amount of device-locked memory.
   8440  *
   8441  * To keep project_rele and project_hold consistent, i_ddi_decr_locked_memory()
   8442  * must be called every time i_ddi_incr_locked_memory() is called.
   8443  */
   8444 int
   8445 /* ARGSUSED */
   8446 i_ddi_incr_locked_memory(proc_t *procp, rctl_qty_t inc)
   8447 {
   8448 	ASSERT(procp != NULL);
   8449 	mutex_enter(&procp->p_lock);
   8450 	if (rctl_incr_locked_mem(procp, NULL, inc, 1)) {
   8451 		mutex_exit(&procp->p_lock);
   8452 		return (ENOMEM);
   8453 	}
   8454 	mutex_exit(&procp->p_lock);
   8455 	return (0);
   8456 }
   8457 
   8458 /*
   8459  * To keep project_rele and project_hold consistent, i_ddi_incr_locked_memory()
   8460  * must be called every time i_ddi_decr_locked_memory() is called.
   8461  */
   8462 /* ARGSUSED */
   8463 void
   8464 i_ddi_decr_locked_memory(proc_t *procp, rctl_qty_t dec)
   8465 {
   8466 	ASSERT(procp != NULL);
   8467 	mutex_enter(&procp->p_lock);
   8468 	rctl_decr_locked_mem(procp, NULL, dec, 1);
   8469 	mutex_exit(&procp->p_lock);
   8470 }
   8471 
   8472 /*
   8473  * The cookie->upd_max_lock_rctl flag is used to determine if we should
   8474  * charge device locked memory to the max-locked-memory rctl.  Tracking
   8475  * device locked memory causes the rctl locks to get hot under high-speed
   8476  * I/O such as RDSv3 over IB.  If there is no max-locked-memory rctl limit,
   8477  * we bypass charging the locked memory to the rctl altogether.  The cookie's
   8478  * flag tells us if the rctl value should be updated when unlocking the memory,
   8479  * in case the rctl gets changed after the memory was locked.  Any device
   8480  * locked memory in that rare case will not be counted toward the rctl limit.
   8481  *
   8482  * When tracking the locked memory, the kproject_t parameter is always NULL
   8483  * in the code paths:
   8484  *	i_ddi_incr_locked_memory -> rctl_incr_locked_mem
   8485  *	i_ddi_decr_locked_memory -> rctl_decr_locked_mem
   8486  * Thus, we always use the tk_proj member to check the projp setting.
   8487  */
   8488 static void
   8489 init_lockedmem_rctl_flag(struct ddi_umem_cookie *cookie)
   8490 {
   8491 	proc_t		*p;
   8492 	kproject_t	*projp;
   8493 	zone_t		*zonep;
   8494 
   8495 	ASSERT(cookie);
   8496 	p = cookie->procp;
   8497 	ASSERT(p);
   8498 
   8499 	zonep = p->p_zone;
   8500 	projp = p->p_task->tk_proj;
   8501 
   8502 	ASSERT(zonep);
   8503 	ASSERT(projp);
   8504 
   8505 	if (zonep->zone_locked_mem_ctl == UINT64_MAX &&
   8506 	    projp->kpj_data.kpd_locked_mem_ctl == UINT64_MAX)
   8507 		cookie->upd_max_lock_rctl = 0;
   8508 	else
   8509 		cookie->upd_max_lock_rctl = 1;
   8510 }
   8511 
   8512 /*
   8513  * This routine checks if the max-locked-memory resource ctl is
   8514  * exceeded, if not increments it, grabs a hold on the project.
   8515  * Returns 0 if successful otherwise returns error code
   8516  */
   8517 static int
   8518 umem_incr_devlockmem(struct ddi_umem_cookie *cookie)
   8519 {
   8520 	proc_t		*procp;
   8521 	int		ret;
   8522 
   8523 	ASSERT(cookie);
   8524 	if (cookie->upd_max_lock_rctl == 0)
   8525 		return (0);
   8526 
   8527 	procp = cookie->procp;
   8528 	ASSERT(procp);
   8529 
   8530 	if ((ret = i_ddi_incr_locked_memory(procp,
   8531 	    cookie->size)) != 0) {
   8532 		return (ret);
   8533 	}
   8534 	return (0);
   8535 }
   8536 
   8537 /*
   8538  * Decrements the max-locked-memory resource ctl and releases
   8539  * the hold on the project that was acquired during umem_incr_devlockmem
   8540  */
   8541 static void
   8542 umem_decr_devlockmem(struct ddi_umem_cookie *cookie)
   8543 {
   8544 	proc_t		*proc;
   8545 
   8546 	if (cookie->upd_max_lock_rctl == 0)
   8547 		return;
   8548 
   8549 	proc = (proc_t *)cookie->procp;
   8550 	if (!proc)
   8551 		return;
   8552 
   8553 	i_ddi_decr_locked_memory(proc, cookie->size);
   8554 }
   8555 
   8556 /*
   8557  * A consolidation private function which is essentially equivalent to
   8558  * ddi_umem_lock but with the addition of arguments ops_vector and procp.
   8559  * A call to as_add_callback is done if DDI_UMEMLOCK_LONGTERM is set, and
   8560  * the ops_vector is valid.
   8561  *
   8562  * Lock the virtual address range in the current process and create a
   8563  * ddi_umem_cookie (of type UMEM_LOCKED). This can be used to pass to
   8564  * ddi_umem_iosetup to create a buf or do devmap_umem_setup/remap to export
   8565  * to user space.
   8566  *
   8567  * Note: The resource control accounting currently uses a full charge model
   8568  * in other words attempts to lock the same/overlapping areas of memory
   8569  * will deduct the full size of the buffer from the projects running
   8570  * counter for the device locked memory.
   8571  *
   8572  * addr, size should be PAGESIZE aligned
   8573  *
   8574  * flags - DDI_UMEMLOCK_READ, DDI_UMEMLOCK_WRITE or both
   8575  *	identifies whether the locked memory will be read or written or both
   8576  *      DDI_UMEMLOCK_LONGTERM  must be set when the locking will
   8577  * be maintained for an indefinitely long period (essentially permanent),
   8578  * rather than for what would be required for a typical I/O completion.
   8579  * When DDI_UMEMLOCK_LONGTERM is set, umem_lockmemory will return EFAULT
   8580  * if the memory pertains to a regular file which is mapped MAP_SHARED.
   8581  * This is to prevent a deadlock if a file truncation is attempted after
   8582  * after the locking is done.
   8583  *
   8584  * Returns 0 on success
   8585  *	EINVAL - for invalid parameters
   8586  *	EPERM, ENOMEM and other error codes returned by as_pagelock
   8587  *	ENOMEM - is returned if the current request to lock memory exceeds
   8588  *		*.max-locked-memory resource control value.
   8589  *      EFAULT - memory pertains to a regular file mapped shared and
   8590  *		and DDI_UMEMLOCK_LONGTERM flag is set
   8591  *	EAGAIN - could not start the ddi_umem_unlock list processing thread
   8592  */
   8593 int
   8594 umem_lockmemory(caddr_t addr, size_t len, int flags, ddi_umem_cookie_t *cookie,
   8595 		struct umem_callback_ops *ops_vector,
   8596 		proc_t *procp)
   8597 {
   8598 	int	error;
   8599 	struct ddi_umem_cookie *p;
   8600 	void	(*driver_callback)() = NULL;
   8601 	struct as *as;
   8602 	struct seg		*seg;
   8603 	vnode_t			*vp;
   8604 
   8605 	/* Allow device drivers to not have to reference "curproc" */
   8606 	if (procp == NULL)
   8607 		procp = curproc;
   8608 	as = procp->p_as;
   8609 	*cookie = NULL;		/* in case of any error return */
   8610 
   8611 	/* These are the only three valid flags */
   8612 	if ((flags & ~(DDI_UMEMLOCK_READ | DDI_UMEMLOCK_WRITE |
   8613 	    DDI_UMEMLOCK_LONGTERM)) != 0)
   8614 		return (EINVAL);
   8615 
   8616 	/* At least one (can be both) of the two access flags must be set */
   8617 	if ((flags & (DDI_UMEMLOCK_READ | DDI_UMEMLOCK_WRITE)) == 0)
   8618 		return (EINVAL);
   8619 
   8620 	/* addr and len must be page-aligned */
   8621 	if (((uintptr_t)addr & PAGEOFFSET) != 0)
   8622 		return (EINVAL);
   8623 
   8624 	if ((len & PAGEOFFSET) != 0)
   8625 		return (EINVAL);
   8626 
   8627 	/*
   8628 	 * For longterm locking a driver callback must be specified; if
   8629 	 * not longterm then a callback is optional.
   8630 	 */
   8631 	if (ops_vector != NULL) {
   8632 		if (ops_vector->cbo_umem_callback_version !=
   8633 		    UMEM_CALLBACK_VERSION)
   8634 			return (EINVAL);
   8635 		else
   8636 			driver_callback = ops_vector->cbo_umem_lock_cleanup;
   8637 	}
   8638 	if ((driver_callback == NULL) && (flags & DDI_UMEMLOCK_LONGTERM))
   8639 		return (EINVAL);
   8640 
   8641 	/*
   8642 	 * Call i_ddi_umem_unlock_thread_start if necessary.  It will
   8643 	 * be called on first ddi_umem_lock or umem_lockmemory call.
   8644 	 */
   8645 	if (ddi_umem_unlock_thread == NULL)
   8646 		i_ddi_umem_unlock_thread_start();
   8647 
   8648 	/* Allocate memory for the cookie */
   8649 	p = kmem_zalloc(sizeof (struct ddi_umem_cookie), KM_SLEEP);
   8650 
   8651 	/* Convert the flags to seg_rw type */
   8652 	if (flags & DDI_UMEMLOCK_WRITE) {
   8653 		p->s_flags = S_WRITE;
   8654 	} else {
   8655 		p->s_flags = S_READ;
   8656 	}
   8657 
   8658 	/* Store procp in cookie for later iosetup/unlock */
   8659 	p->procp = (void *)procp;
   8660 
   8661 	/*
   8662 	 * Store the struct as pointer in cookie for later use by
   8663 	 * ddi_umem_unlock.  The proc->p_as will be stale if ddi_umem_unlock
   8664 	 * is called after relvm is called.
   8665 	 */
   8666 	p->asp = as;
   8667 
   8668 	/*
   8669 	 * The size field is needed for lockmem accounting.
   8670 	 */
   8671 	p->size = len;
   8672 	init_lockedmem_rctl_flag(p);
   8673 
   8674 	if (umem_incr_devlockmem(p) != 0) {
   8675 		/*
   8676 		 * The requested memory cannot be locked
   8677 		 */
   8678 		kmem_free(p, sizeof (struct ddi_umem_cookie));
   8679 		*cookie = (ddi_umem_cookie_t)NULL;
   8680 		return (ENOMEM);
   8681 	}
   8682 
   8683 	/* Lock the pages corresponding to addr, len in memory */
   8684 	error = as_pagelock(as, &(p->pparray), addr, len, p->s_flags);
   8685 	if (error != 0) {
   8686 		umem_decr_devlockmem(p);
   8687 		kmem_free(p, sizeof (struct ddi_umem_cookie));
   8688 		*cookie = (ddi_umem_cookie_t)NULL;
   8689 		return (error);
   8690 	}
   8691 
   8692 	/*
   8693 	 * For longterm locking the addr must pertain to a seg_vn segment or
   8694 	 * or a seg_spt segment.
   8695 	 * If the segment pertains to a regular file, it cannot be
   8696 	 * mapped MAP_SHARED.
   8697 	 * This is to prevent a deadlock if a file truncation is attempted
   8698 	 * after the locking is done.
   8699 	 * Doing this after as_pagelock guarantees persistence of the as; if
   8700 	 * an unacceptable segment is found, the cleanup includes calling
   8701 	 * as_pageunlock before returning EFAULT.
   8702 	 *
   8703 	 * segdev is allowed here as it is already locked.  This allows
   8704 	 * for memory exported by drivers through mmap() (which is already
   8705 	 * locked) to be allowed for LONGTERM.
   8706 	 */
   8707 	if (flags & DDI_UMEMLOCK_LONGTERM) {
   8708 		extern  struct seg_ops segspt_shmops;
   8709 		extern	struct seg_ops segdev_ops;
   8710 		AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
   8711 		for (seg = as_segat(as, addr); ; seg = AS_SEGNEXT(as, seg)) {
   8712 			if (seg == NULL || seg->s_base > addr + len)
   8713 				break;
   8714 			if (seg->s_ops == &segdev_ops)
   8715 				continue;
   8716 			if (((seg->s_ops != &segvn_ops) &&
   8717 			    (seg->s_ops != &segspt_shmops)) ||
   8718 			    ((SEGOP_GETVP(seg, addr, &vp) == 0 &&
   8719 			    vp != NULL && vp->v_type == VREG) &&
   8720 			    (SEGOP_GETTYPE(seg, addr) & MAP_SHARED))) {
   8721 				as_pageunlock(as, p->pparray,
   8722 				    addr, len, p->s_flags);
   8723 				AS_LOCK_EXIT(as, &as->a_lock);
   8724 				umem_decr_devlockmem(p);
   8725 				kmem_free(p, sizeof (struct ddi_umem_cookie));
   8726 				*cookie = (ddi_umem_cookie_t)NULL;
   8727 				return (EFAULT);
   8728 			}
   8729 		}
   8730 		AS_LOCK_EXIT(as, &as->a_lock);
   8731 	}
   8732 
   8733 
   8734 	/* Initialize the fields in the ddi_umem_cookie */
   8735 	p->cvaddr = addr;
   8736 	p->type = UMEM_LOCKED;
   8737 	if (driver_callback != NULL) {
   8738 		/* i_ddi_umem_unlock and umem_lock_undo may need the cookie */
   8739 		p->cook_refcnt = 2;
   8740 		p->callbacks = *ops_vector;
   8741 	} else {
   8742 		/* only i_ddi_umme_unlock needs the cookie */
   8743 		p->cook_refcnt = 1;
   8744 	}
   8745 
   8746 	*cookie = (ddi_umem_cookie_t)p;
   8747 
   8748 	/*
   8749 	 * If a driver callback was specified, add an entry to the
   8750 	 * as struct callback list. The as_pagelock above guarantees
   8751 	 * the persistence of as.
   8752 	 */
   8753 	if (driver_callback) {
   8754 		error = as_add_callback(as, umem_lock_undo, p, AS_ALL_EVENT,
   8755 		    addr, len, KM_SLEEP);
   8756 		if (error != 0) {
   8757 			as_pageunlock(as, p->pparray,
   8758 			    addr, len, p->s_flags);
   8759 			umem_decr_devlockmem(p);
   8760 			kmem_free(p, sizeof (struct ddi_umem_cookie));
   8761 			*cookie = (ddi_umem_cookie_t)NULL;
   8762 		}
   8763 	}
   8764 	return (error);
   8765 }
   8766 
   8767 /*
   8768  * Unlock the pages locked by ddi_umem_lock or umem_lockmemory and free
   8769  * the cookie.  Called from i_ddi_umem_unlock_thread.
   8770  */
   8771 
   8772 static void
   8773 i_ddi_umem_unlock(struct ddi_umem_cookie *p)
   8774 {
   8775 	uint_t	rc;
   8776 
   8777 	/*
   8778 	 * There is no way to determine whether a callback to
   8779 	 * umem_lock_undo was registered via as_add_callback.
   8780 	 * (i.e. umem_lockmemory was called with DDI_MEMLOCK_LONGTERM and
   8781 	 * a valid callback function structure.)  as_delete_callback
   8782 	 * is called to delete a possible registered callback.  If the
   8783 	 * return from as_delete_callbacks is AS_CALLBACK_DELETED, it
   8784 	 * indicates that there was a callback registered, and that is was
   8785 	 * successfully deleted.  Thus, the cookie reference count
   8786 	 * will never be decremented by umem_lock_undo.  Just return the
   8787 	 * memory for the cookie, since both users of the cookie are done.
   8788 	 * A return of AS_CALLBACK_NOTFOUND indicates a callback was
   8789 	 * never registered.  A return of AS_CALLBACK_DELETE_DEFERRED
   8790 	 * indicates that callback processing is taking place and, and
   8791 	 * umem_lock_undo is, or will be, executing, and thus decrementing
   8792 	 * the cookie reference count when it is complete.
   8793 	 *
   8794 	 * This needs to be done before as_pageunlock so that the
   8795 	 * persistence of as is guaranteed because of the locked pages.
   8796 	 *
   8797 	 */
   8798 	rc = as_delete_callback(p->asp, p);
   8799 
   8800 
   8801 	/*
   8802 	 * The proc->p_as will be stale if i_ddi_umem_unlock is called
   8803 	 * after relvm is called so use p->asp.
   8804 	 */
   8805 	as_pageunlock(p->asp, p->pparray, p->cvaddr, p->size, p->s_flags);
   8806 
   8807 	/*
   8808 	 * Now that we have unlocked the memory decrement the
   8809 	 * *.max-locked-memory rctl
   8810 	 */
   8811 	umem_decr_devlockmem(p);
   8812 
   8813 	if (rc == AS_CALLBACK_DELETED) {
   8814 		/* umem_lock_undo will not happen, return the cookie memory */
   8815 		ASSERT(p->cook_refcnt == 2);
   8816 		kmem_free(p, sizeof (struct ddi_umem_cookie));
   8817 	} else {
   8818 		/*
   8819 		 * umem_undo_lock may happen if as_delete_callback returned
   8820 		 * AS_CALLBACK_DELETE_DEFERRED.  In that case, decrement the
   8821 		 * reference count, atomically, and return the cookie
   8822 		 * memory if the reference count goes to zero.  The only
   8823 		 * other value for rc is AS_CALLBACK_NOTFOUND.  In that
   8824 		 * case, just return the cookie memory.
   8825 		 */
   8826 		if ((rc != AS_CALLBACK_DELETE_DEFERRED) ||
   8827 		    (atomic_add_long_nv((ulong_t *)(&(p->cook_refcnt)), -1)
   8828 		    == 0)) {
   8829 			kmem_free(p, sizeof (struct ddi_umem_cookie));
   8830 		}
   8831 	}
   8832 }
   8833 
   8834 /*
   8835  * i_ddi_umem_unlock_thread - deferred ddi_umem_unlock list handler.
   8836  *
   8837  * Call i_ddi_umem_unlock for entries in the ddi_umem_unlock list
   8838  * until it is empty.  Then, wait for more to be added.  This thread is awoken
   8839  * via calls to ddi_umem_unlock.
   8840  */
   8841 
   8842 static void
   8843 i_ddi_umem_unlock_thread(void)
   8844 {
   8845 	struct ddi_umem_cookie	*ret_cookie;
   8846 	callb_cpr_t	cprinfo;
   8847 
   8848 	/* process the ddi_umem_unlock list */
   8849 	CALLB_CPR_INIT(&cprinfo, &ddi_umem_unlock_mutex,
   8850 	    callb_generic_cpr, "unlock_thread");
   8851 	for (;;) {
   8852 		mutex_enter(&ddi_umem_unlock_mutex);
   8853 		if (ddi_umem_unlock_head != NULL) {	/* list not empty */
   8854 			ret_cookie = ddi_umem_unlock_head;
   8855 			/* take if off the list */
   8856 			if ((ddi_umem_unlock_head =
   8857 			    ddi_umem_unlock_head->unl_forw) == NULL) {
   8858 				ddi_umem_unlock_tail = NULL;
   8859 			}
   8860 			mutex_exit(&ddi_umem_unlock_mutex);
   8861 			/* unlock the pages in this cookie */
   8862 			(void) i_ddi_umem_unlock(ret_cookie);
   8863 		} else {   /* list is empty, wait for next ddi_umem_unlock */
   8864 			CALLB_CPR_SAFE_BEGIN(&cprinfo);
   8865 			cv_wait(&ddi_umem_unlock_cv, &ddi_umem_unlock_mutex);
   8866 			CALLB_CPR_SAFE_END(&cprinfo, &ddi_umem_unlock_mutex);
   8867 			mutex_exit(&ddi_umem_unlock_mutex);
   8868 		}
   8869 	}
   8870 	/* ddi_umem_unlock_thread does not exit */
   8871 	/* NOTREACHED */
   8872 }
   8873 
   8874 /*
   8875  * Start the thread that will process the ddi_umem_unlock list if it is
   8876  * not already started (i_ddi_umem_unlock_thread).
   8877  */
   8878 static void
   8879 i_ddi_umem_unlock_thread_start(void)
   8880 {
   8881 	mutex_enter(&ddi_umem_unlock_mutex);
   8882 	if (ddi_umem_unlock_thread == NULL) {
   8883 		ddi_umem_unlock_thread = thread_create(NULL, 0,
   8884 		    i_ddi_umem_unlock_thread, NULL, 0, &p0,
   8885 		    TS_RUN, minclsyspri);
   8886 	}
   8887 	mutex_exit(&ddi_umem_unlock_mutex);
   8888 }
   8889 
   8890 /*
   8891  * Lock the virtual address range in the current process and create a
   8892  * ddi_umem_cookie (of type UMEM_LOCKED). This can be used to pass to
   8893  * ddi_umem_iosetup to create a buf or do devmap_umem_setup/remap to export
   8894  * to user space.
   8895  *
   8896  * Note: The resource control accounting currently uses a full charge model
   8897  * in other words attempts to lock the same/overlapping areas of memory
   8898  * will deduct the full size of the buffer from the projects running
   8899  * counter for the device locked memory. This applies to umem_lockmemory too.
   8900  *
   8901  * addr, size should be PAGESIZE aligned
   8902  * flags - DDI_UMEMLOCK_READ, DDI_UMEMLOCK_WRITE or both
   8903  *	identifies whether the locked memory will be read or written or both
   8904  *
   8905  * Returns 0 on success
   8906  *	EINVAL - for invalid parameters
   8907  *	EPERM, ENOMEM and other error codes returned by as_pagelock
   8908  *	ENOMEM - is returned if the current request to lock memory exceeds
   8909  *		*.max-locked-memory resource control value.
   8910  *	EAGAIN - could not start the ddi_umem_unlock list processing thread
   8911  */
   8912 int
   8913 ddi_umem_lock(caddr_t addr, size_t len, int flags, ddi_umem_cookie_t *cookie)
   8914 {
   8915 	int	error;
   8916 	struct ddi_umem_cookie *p;
   8917 
   8918 	*cookie = NULL;		/* in case of any error return */
   8919 
   8920 	/* These are the only two valid flags */
   8921 	if ((flags & ~(DDI_UMEMLOCK_READ | DDI_UMEMLOCK_WRITE)) != 0) {
   8922 		return (EINVAL);
   8923 	}
   8924 
   8925 	/* At least one of the two flags (or both) must be set */
   8926 	if ((flags & (DDI_UMEMLOCK_READ | DDI_UMEMLOCK_WRITE)) == 0) {
   8927 		return (EINVAL);
   8928 	}
   8929 
   8930 	/* addr and len must be page-aligned */
   8931 	if (((uintptr_t)addr & PAGEOFFSET) != 0) {
   8932 		return (EINVAL);
   8933 	}
   8934 
   8935 	if ((len & PAGEOFFSET) != 0) {
   8936 		return (EINVAL);
   8937 	}
   8938 
   8939 	/*
   8940 	 * Call i_ddi_umem_unlock_thread_start if necessary.  It will
   8941 	 * be called on first ddi_umem_lock or umem_lockmemory call.
   8942 	 */
   8943 	if (ddi_umem_unlock_thread == NULL)
   8944 		i_ddi_umem_unlock_thread_start();
   8945 
   8946 	/* Allocate memory for the cookie */
   8947 	p = kmem_zalloc(sizeof (struct ddi_umem_cookie), KM_SLEEP);
   8948 
   8949 	/* Convert the flags to seg_rw type */
   8950 	if (flags & DDI_UMEMLOCK_WRITE) {
   8951 		p->s_flags = S_WRITE;
   8952 	} else {
   8953 		p->s_flags = S_READ;
   8954 	}
   8955 
   8956 	/* Store curproc in cookie for later iosetup/unlock */
   8957 	p->procp = (void *)curproc;
   8958 
   8959 	/*
   8960 	 * Store the struct as pointer in cookie for later use by
   8961 	 * ddi_umem_unlock.  The proc->p_as will be stale if ddi_umem_unlock
   8962 	 * is called after relvm is called.
   8963 	 */
   8964 	p->asp = curproc->p_as;
   8965 	/*
   8966 	 * The size field is needed for lockmem accounting.
   8967 	 */
   8968 	p->size = len;
   8969 	init_lockedmem_rctl_flag(p);
   8970 
   8971 	if (umem_incr_devlockmem(p) != 0) {
   8972 		/*
   8973 		 * The requested memory cannot be locked
   8974 		 */
   8975 		kmem_free(p, sizeof (struct ddi_umem_cookie));
   8976 		*cookie = (ddi_umem_cookie_t)NULL;
   8977 		return (ENOMEM);
   8978 	}
   8979 
   8980 	/* Lock the pages corresponding to addr, len in memory */
   8981 	error = as_pagelock(((proc_t *)p->procp)->p_as, &(p->pparray),
   8982 	    addr, len, p->s_flags);
   8983 	if (error != 0) {
   8984 		umem_decr_devlockmem(p);
   8985 		kmem_free(p, sizeof (struct ddi_umem_cookie));
   8986 		*cookie = (ddi_umem_cookie_t)NULL;
   8987 		return (error);
   8988 	}
   8989 
   8990 	/* Initialize the fields in the ddi_umem_cookie */
   8991 	p->cvaddr = addr;
   8992 	p->type = UMEM_LOCKED;
   8993 	p->cook_refcnt = 1;
   8994 
   8995 	*cookie = (ddi_umem_cookie_t)p;
   8996 	return (error);
   8997 }
   8998 
   8999 /*
   9000  * Add the cookie to the ddi_umem_unlock list.  Pages will be
   9001  * unlocked by i_ddi_umem_unlock_thread.
   9002  */
   9003 
   9004 void
   9005 ddi_umem_unlock(ddi_umem_cookie_t cookie)
   9006 {
   9007 	struct ddi_umem_cookie	*p = (struct ddi_umem_cookie *)cookie;
   9008 
   9009 	ASSERT(p->type == UMEM_LOCKED);
   9010 	ASSERT(CPU_ON_INTR(CPU) == 0); /* cannot be high level */
   9011 	ASSERT(ddi_umem_unlock_thread != NULL);
   9012 
   9013 	p->unl_forw = (struct ddi_umem_cookie *)NULL;	/* end of list */
   9014 	/*
   9015 	 * Queue the unlock request and notify i_ddi_umem_unlock thread
   9016 	 * if it's called in the interrupt context. Otherwise, unlock pages
   9017 	 * immediately.
   9018 	 */
   9019 	if (servicing_interrupt()) {
   9020 		/* queue the unlock request and notify the thread */
   9021 		mutex_enter(&ddi_umem_unlock_mutex);
   9022 		if (ddi_umem_unlock_head == NULL) {
   9023 			ddi_umem_unlock_head = ddi_umem_unlock_tail = p;
   9024 			cv_broadcast(&ddi_umem_unlock_cv);
   9025 		} else {
   9026 			ddi_umem_unlock_tail->unl_forw = p;
   9027 			ddi_umem_unlock_tail = p;
   9028 		}
   9029 		mutex_exit(&ddi_umem_unlock_mutex);
   9030 	} else {
   9031 		/* unlock the pages right away */
   9032 		(void) i_ddi_umem_unlock(p);
   9033 	}
   9034 }
   9035 
   9036 /*
   9037  * Create a buf structure from a ddi_umem_cookie
   9038  * cookie - is a ddi_umem_cookie for from ddi_umem_lock and ddi_umem_alloc
   9039  *		(only UMEM_LOCKED & KMEM_NON_PAGEABLE types supported)
   9040  * off, len - identifies the portion of the memory represented by the cookie
   9041  *		that the buf points to.
   9042  *	NOTE: off, len need to follow the alignment/size restrictions of the
   9043  *		device (dev) that this buf will be passed to. Some devices
   9044  *		will accept unrestricted alignment/size, whereas others (such as
   9045  *		st) require some block-size alignment/size. It is the caller's
   9046  *		responsibility to ensure that the alignment/size restrictions
   9047  *		are met (we cannot assert as we do not know the restrictions)
   9048  *
   9049  * direction - is one of B_READ or B_WRITE and needs to be compatible with
   9050  *		the flags used in ddi_umem_lock
   9051  *
   9052  * The following three arguments are used to initialize fields in the
   9053  * buf structure and are uninterpreted by this routine.
   9054  *
   9055  * dev
   9056  * blkno
   9057  * iodone
   9058  *
   9059  * sleepflag - is one of DDI_UMEM_SLEEP or DDI_UMEM_NOSLEEP
   9060  *
   9061  * Returns a buf structure pointer on success (to be freed by freerbuf)
   9062  *	NULL on any parameter error or memory alloc failure
   9063  *
   9064  */
   9065 struct buf *
   9066 ddi_umem_iosetup(ddi_umem_cookie_t cookie, off_t off, size_t len,
   9067 	int direction, dev_t dev, daddr_t blkno,
   9068 	int (*iodone)(struct buf *), int sleepflag)
   9069 {
   9070 	struct ddi_umem_cookie *p = (struct ddi_umem_cookie *)cookie;
   9071 	struct buf *bp;
   9072 
   9073 	/*
   9074 	 * check for valid cookie offset, len
   9075 	 */
   9076 	if ((off + len) > p->size) {
   9077 		return (NULL);
   9078 	}
   9079 
   9080 	if (len > p->size) {
   9081 		return (NULL);
   9082 	}
   9083 
   9084 	/* direction has to be one of B_READ or B_WRITE */
   9085 	if ((direction != B_READ) && (direction != B_WRITE)) {
   9086 		return (NULL);
   9087 	}
   9088 
   9089 	/* These are the only two valid sleepflags */
   9090 	if ((sleepflag != DDI_UMEM_SLEEP) && (sleepflag != DDI_UMEM_NOSLEEP)) {
   9091 		return (NULL);
   9092 	}
   9093 
   9094 	/*
   9095 	 * Only cookies of type UMEM_LOCKED and KMEM_NON_PAGEABLE are supported
   9096 	 */
   9097 	if ((p->type != UMEM_LOCKED) && (p->type != KMEM_NON_PAGEABLE)) {
   9098 		return (NULL);
   9099 	}
   9100 
   9101 	/* If type is KMEM_NON_PAGEABLE procp is NULL */
   9102 	ASSERT((p->type == KMEM_NON_PAGEABLE) ?
   9103 	    (p->procp == NULL) : (p->procp != NULL));
   9104 
   9105 	bp = kmem_alloc(sizeof (struct buf), sleepflag);
   9106 	if (bp == NULL) {
   9107 		return (NULL);
   9108 	}
   9109 	bioinit(bp);
   9110 
   9111 	bp->b_flags = B_BUSY | B_PHYS | direction;
   9112 	bp->b_edev = dev;
   9113 	bp->b_lblkno = blkno;
   9114 	bp->b_iodone = iodone;
   9115 	bp->b_bcount = len;
   9116 	bp->b_proc = (proc_t *)p->procp;
   9117 	ASSERT(((uintptr_t)(p->cvaddr) & PAGEOFFSET) == 0);
   9118 	bp->b_un.b_addr = (caddr_t)((uintptr_t)(p->cvaddr) + off);
   9119 	if (p->pparray != NULL) {
   9120 		bp->b_flags |= B_SHADOW;
   9121 		ASSERT(((uintptr_t)(p->cvaddr) & PAGEOFFSET) == 0);
   9122 		bp->b_shadow = p->pparray + btop(off);
   9123 	}
   9124 	return (bp);
   9125 }
   9126 
   9127 /*
   9128  * Fault-handling and related routines
   9129  */
   9130 
   9131 ddi_devstate_t
   9132 ddi_get_devstate(dev_info_t *dip)
   9133 {
   9134 	if (DEVI_IS_DEVICE_OFFLINE(dip))
   9135 		return (DDI_DEVSTATE_OFFLINE);
   9136 	else if (DEVI_IS_DEVICE_DOWN(dip) || DEVI_IS_BUS_DOWN(dip))
   9137 		return (DDI_DEVSTATE_DOWN);
   9138 	else if (DEVI_IS_BUS_QUIESCED(dip))
   9139 		return (DDI_DEVSTATE_QUIESCED);
   9140 	else if (DEVI_IS_DEVICE_DEGRADED(dip))
   9141 		return (DDI_DEVSTATE_DEGRADED);
   9142 	else
   9143 		return (DDI_DEVSTATE_UP);
   9144 }
   9145 
   9146 void
   9147 ddi_dev_report_fault(dev_info_t *dip, ddi_fault_impact_t impact,
   9148 	ddi_fault_location_t location, const char *message)
   9149 {
   9150 	struct ddi_fault_event_data fd;
   9151 	ddi_eventcookie_t ec;
   9152 
   9153 	/*
   9154 	 * Assemble all the information into a fault-event-data structure
   9155 	 */
   9156 	fd.f_dip = dip;
   9157 	fd.f_impact = impact;
   9158 	fd.f_location = location;
   9159 	fd.f_message = message;
   9160 	fd.f_oldstate = ddi_get_devstate(dip);
   9161 
   9162 	/*
   9163 	 * Get eventcookie from defining parent.
   9164 	 */
   9165 	if (ddi_get_eventcookie(dip, DDI_DEVI_FAULT_EVENT, &ec) !=
   9166 	    DDI_SUCCESS)
   9167 		return;
   9168 
   9169 	(void) ndi_post_event(dip, dip, ec, &fd);
   9170 }
   9171 
   9172 char *
   9173 i_ddi_devi_class(dev_info_t *dip)
   9174 {
   9175 	return (DEVI(dip)->devi_device_class);
   9176 }
   9177 
   9178 int
   9179 i_ddi_set_devi_class(dev_info_t *dip, char *devi_class, int flag)
   9180 {
   9181 	struct dev_info *devi = DEVI(dip);
   9182 
   9183 	mutex_enter(&devi->devi_lock);
   9184 
   9185 	if (devi->devi_device_class)
   9186 		kmem_free(devi->devi_device_class,
   9187 		    strlen(devi->devi_device_class) + 1);
   9188 
   9189 	if ((devi->devi_device_class = i_ddi_strdup(devi_class, flag))
   9190 	    != NULL) {
   9191 		mutex_exit(&devi->devi_lock);
   9192 		return (DDI_SUCCESS);
   9193 	}
   9194 
   9195 	mutex_exit(&devi->devi_lock);
   9196 
   9197 	return (DDI_FAILURE);
   9198 }
   9199 
   9200 
   9201 /*
   9202  * Task Queues DDI interfaces.
   9203  */
   9204 
   9205 /* ARGSUSED */
   9206 ddi_taskq_t *
   9207 ddi_taskq_create(dev_info_t *dip, const char *name, int nthreads,
   9208     pri_t pri, uint_t cflags)
   9209 {
   9210 	char full_name[TASKQ_NAMELEN];
   9211 	const char *tq_name;
   9212 	int nodeid = 0;
   9213 
   9214 	if (dip == NULL)
   9215 		tq_name = name;
   9216 	else {
   9217 		nodeid = ddi_get_instance(dip);
   9218 
   9219 		if (name == NULL)
   9220 			name = "tq";
   9221 
   9222 		(void) snprintf(full_name, sizeof (full_name), "%s_%s",
   9223 		    ddi_driver_name(dip), name);
   9224 
   9225 		tq_name = full_name;
   9226 	}
   9227 
   9228 	return ((ddi_taskq_t *)taskq_create_instance(tq_name, nodeid, nthreads,
   9229 	    pri == TASKQ_DEFAULTPRI ? minclsyspri : pri,
   9230 	    nthreads, INT_MAX, TASKQ_PREPOPULATE));
   9231 }
   9232 
   9233 void
   9234 ddi_taskq_destroy(ddi_taskq_t *tq)
   9235 {
   9236 	taskq_destroy((taskq_t *)tq);
   9237 }
   9238 
   9239 int
   9240 ddi_taskq_dispatch(ddi_taskq_t *tq, void (* func)(void *),
   9241     void *arg, uint_t dflags)
   9242 {
   9243 	taskqid_t id = taskq_dispatch((taskq_t *)tq, func, arg,
   9244 	    dflags == DDI_SLEEP ? TQ_SLEEP : TQ_NOSLEEP);
   9245 
   9246 	return (id != 0 ? DDI_SUCCESS : DDI_FAILURE);
   9247 }
   9248 
   9249 void
   9250 ddi_taskq_wait(ddi_taskq_t *tq)
   9251 {
   9252 	taskq_wait((taskq_t *)tq);
   9253 }
   9254 
   9255 void
   9256 ddi_taskq_suspend(ddi_taskq_t *tq)
   9257 {
   9258 	taskq_suspend((taskq_t *)tq);
   9259 }
   9260 
   9261 boolean_t
   9262 ddi_taskq_suspended(ddi_taskq_t *tq)
   9263 {
   9264 	return (taskq_suspended((taskq_t *)tq));
   9265 }
   9266 
   9267 void
   9268 ddi_taskq_resume(ddi_taskq_t *tq)
   9269 {
   9270 	taskq_resume((taskq_t *)tq);
   9271 }
   9272 
   9273 int
   9274 ddi_parse(
   9275 	const char	*ifname,
   9276 	char		*alnum,
   9277 	uint_t		*nump)
   9278 {
   9279 	const char	*p;
   9280 	int		l;
   9281 	ulong_t		num;
   9282 	boolean_t	nonum = B_TRUE;
   9283 	char		c;
   9284 
   9285 	l = strlen(ifname);
   9286 	for (p = ifname + l; p != ifname; l--) {
   9287 		c = *--p;
   9288 		if (!isdigit(c)) {
   9289 			(void) strlcpy(alnum, ifname, l + 1);
   9290 			if (ddi_strtoul(p + 1, NULL, 10, &num) != 0)
   9291 				return (DDI_FAILURE);
   9292 			break;
   9293 		}
   9294 		nonum = B_FALSE;
   9295 	}
   9296 	if (l == 0 || nonum)
   9297 		return (DDI_FAILURE);
   9298 
   9299 	*nump = num;
   9300 	return (DDI_SUCCESS);
   9301 }
   9302 
   9303 /*
   9304  * Default initialization function for drivers that don't need to quiesce.
   9305  */
   9306 /* ARGSUSED */
   9307 int
   9308 ddi_quiesce_not_needed(dev_info_t *dip)
   9309 {
   9310 	return (DDI_SUCCESS);
   9311 }
   9312 
   9313 /*
   9314  * Initialization function for drivers that should implement quiesce()
   9315  * but haven't yet.
   9316  */
   9317 /* ARGSUSED */
   9318 int
   9319 ddi_quiesce_not_supported(dev_info_t *dip)
   9320 {
   9321 	return (DDI_FAILURE);
   9322 }
   9323 
   9324 char *
   9325 ddi_strdup(const char *str, int flag)
   9326 {
   9327 	int	n;
   9328 	char	*ptr;
   9329 
   9330 	ASSERT(str != NULL);
   9331 	ASSERT((flag == KM_SLEEP) || (flag == KM_NOSLEEP));
   9332 
   9333 	n = strlen(str);
   9334 	if ((ptr = kmem_alloc(n + 1, flag)) == NULL)
   9335 		return (NULL);
   9336 	bcopy(str, ptr, n + 1);
   9337 	return (ptr);
   9338 }
   9339 
   9340 char *
   9341 strdup(const char *str)
   9342 {
   9343 	return (ddi_strdup(str, KM_SLEEP));
   9344 }
   9345 
   9346 void
   9347 strfree(char *str)
   9348 {
   9349 	ASSERT(str != NULL);
   9350 	kmem_free(str, strlen(str) + 1);
   9351 }
   9352 
   9353 /*
   9354  * Generic DDI callback interfaces.
   9355  */
   9356 
   9357 int
   9358 ddi_cb_register(dev_info_t *dip, ddi_cb_flags_t flags, ddi_cb_func_t cbfunc,
   9359     void *arg1, void *arg2, ddi_cb_handle_t *ret_hdlp)
   9360 {
   9361 	ddi_cb_t	*cbp;
   9362 
   9363 	ASSERT(dip != NULL);
   9364 	ASSERT(DDI_CB_FLAG_VALID(flags));
   9365 	ASSERT(cbfunc != NULL);
   9366 	ASSERT(ret_hdlp != NULL);
   9367 
   9368 	/* Sanity check the context */
   9369 	ASSERT(!servicing_interrupt());
   9370 	if (servicing_interrupt())
   9371 		return (DDI_FAILURE);
   9372 
   9373 	/* Validate parameters */
   9374 	if ((dip == NULL) || !DDI_CB_FLAG_VALID(flags) ||
   9375 	    (cbfunc == NULL) || (ret_hdlp == NULL))
   9376 		return (DDI_EINVAL);
   9377 
   9378 	/* Check for previous registration */
   9379 	if (DEVI(dip)->devi_cb_p != NULL)
   9380 		return (DDI_EALREADY);
   9381 
   9382 	/* Allocate and initialize callback */
   9383 	cbp = kmem_zalloc(sizeof (ddi_cb_t), KM_SLEEP);
   9384 	cbp->cb_dip = dip;
   9385 	cbp->cb_func = cbfunc;
   9386 	cbp->cb_arg1 = arg1;
   9387 	cbp->cb_arg2 = arg2;
   9388 	cbp->cb_flags = flags;
   9389 	DEVI(dip)->devi_cb_p = cbp;
   9390 
   9391 	/* If adding an IRM callback, notify IRM */
   9392 	if (flags & DDI_CB_FLAG_INTR)
   9393 		i_ddi_irm_set_cb(dip, B_TRUE);
   9394 
   9395 	*ret_hdlp = (ddi_cb_handle_t)&(DEVI(dip)->devi_cb_p);
   9396 	return (DDI_SUCCESS);
   9397 }
   9398 
   9399 int
   9400 ddi_cb_unregister(ddi_cb_handle_t hdl)
   9401 {
   9402 	ddi_cb_t	*cbp;
   9403 	dev_info_t	*dip;
   9404 
   9405 	ASSERT(hdl != NULL);
   9406 
   9407 	/* Sanity check the context */
   9408 	ASSERT(!servicing_interrupt());
   9409 	if (servicing_interrupt())
   9410 		return (DDI_FAILURE);
   9411 
   9412 	/* Validate parameters */
   9413 	if ((hdl == NULL) || ((cbp = *(ddi_cb_t **)hdl) == NULL) ||
   9414 	    ((dip = cbp->cb_dip) == NULL))
   9415 		return (DDI_EINVAL);
   9416 
   9417 	/* If removing an IRM callback, notify IRM */
   9418 	if (cbp->cb_flags & DDI_CB_FLAG_INTR)
   9419 		i_ddi_irm_set_cb(dip, B_FALSE);
   9420 
   9421 	/* Destroy the callback */
   9422 	kmem_free(cbp, sizeof (ddi_cb_t));
   9423 	DEVI(dip)->devi_cb_p = NULL;
   9424 
   9425 	return (DDI_SUCCESS);
   9426 }
   9427 
   9428 /*
   9429  * Platform independent DR routines
   9430  */
   9431 
   9432 static int
   9433 ndi2errno(int n)
   9434 {
   9435 	int err = 0;
   9436 
   9437 	switch (n) {
   9438 		case NDI_NOMEM:
   9439 			err = ENOMEM;
   9440 			break;
   9441 		case NDI_BUSY:
   9442 			err = EBUSY;
   9443 			break;
   9444 		case NDI_FAULT:
   9445 			err = EFAULT;
   9446 			break;
   9447 		case NDI_FAILURE:
   9448 			err = EIO;
   9449 			break;
   9450 		case NDI_SUCCESS:
   9451 			break;
   9452 		case NDI_BADHANDLE:
   9453 		default:
   9454 			err = EINVAL;
   9455 			break;
   9456 	}
   9457 	return (err);
   9458 }
   9459 
   9460 /*
   9461  * Prom tree node list
   9462  */
   9463 struct ptnode {
   9464 	pnode_t		nodeid;
   9465 	struct ptnode	*next;
   9466 };
   9467 
   9468 /*
   9469  * Prom tree walk arg
   9470  */
   9471 struct pta {
   9472 	dev_info_t	*pdip;
   9473 	devi_branch_t	*bp;
   9474 	uint_t		flags;
   9475 	dev_info_t	*fdip;
   9476 	struct ptnode	*head;
   9477 };
   9478 
   9479 static void
   9480 visit_node(pnode_t nodeid, struct pta *ap)
   9481 {
   9482 	struct ptnode	**nextp;
   9483 	int		(*select)(pnode_t, void *, uint_t);
   9484 
   9485 	ASSERT(nodeid != OBP_NONODE && nodeid != OBP_BADNODE);
   9486 
   9487 	select = ap->bp->create.prom_branch_select;
   9488 
   9489 	ASSERT(select);
   9490 
   9491 	if (select(nodeid, ap->bp->arg, 0) == DDI_SUCCESS) {
   9492 
   9493 		for (nextp = &ap->head; *nextp; nextp = &(*nextp)->next)
   9494 			;
   9495 
   9496 		*nextp = kmem_zalloc(sizeof (struct ptnode), KM_SLEEP);
   9497 
   9498 		(*nextp)->nodeid = nodeid;
   9499 	}
   9500 
   9501 	if ((ap->flags & DEVI_BRANCH_CHILD) == DEVI_BRANCH_CHILD)
   9502 		return;
   9503 
   9504 	nodeid = prom_childnode(nodeid);
   9505 	while (nodeid != OBP_NONODE && nodeid != OBP_BADNODE) {
   9506 		visit_node(nodeid, ap);
   9507 		nodeid = prom_nextnode(nodeid);
   9508 	}
   9509 }
   9510 
   9511 /*
   9512  * NOTE: The caller of this function must check for device contracts
   9513  * or LDI callbacks against this dip before setting the dip offline.
   9514  */
   9515 static int
   9516 set_infant_dip_offline(dev_info_t *dip, void *arg)
   9517 {
   9518 	char	*path = (char *)arg;
   9519 
   9520 	ASSERT(dip);
   9521 	ASSERT(arg);
   9522 
   9523 	if (i_ddi_node_state(dip) >= DS_ATTACHED) {
   9524 		(void) ddi_pathname(dip, path);
   9525 		cmn_err(CE_WARN, "Attempt to set offline flag on attached "
   9526 		    "node: %s", path);
   9527 		return (DDI_FAILURE);
   9528 	}
   9529 
   9530 	mutex_enter(&(DEVI(dip)->devi_lock));
   9531 	if (!DEVI_IS_DEVICE_OFFLINE(dip))
   9532 		DEVI_SET_DEVICE_OFFLINE(dip);
   9533 	mutex_exit(&(DEVI(dip)->devi_lock));
   9534 
   9535 	return (DDI_SUCCESS);
   9536 }
   9537 
   9538 typedef struct result {
   9539 	char	*path;
   9540 	int	result;
   9541 } result_t;
   9542 
   9543 static int
   9544 dip_set_offline(dev_info_t *dip, void *arg)
   9545 {
   9546 	int end;
   9547 	result_t *resp = (result_t *)arg;
   9548 
   9549 	ASSERT(dip);
   9550 	ASSERT(resp);
   9551 
   9552 	/*
   9553 	 * We stop the walk if e_ddi_offline_notify() returns
   9554 	 * failure, because this implies that one or more consumers
   9555 	 * (either LDI or contract based) has blocked the offline.
   9556 	 * So there is no point in conitnuing the walk
   9557 	 */
   9558 	if (e_ddi_offline_notify(dip) == DDI_FAILURE) {
   9559 		resp->result = DDI_FAILURE;
   9560 		return (DDI_WALK_TERMINATE);
   9561 	}
   9562 
   9563 	/*
   9564 	 * If set_infant_dip_offline() returns failure, it implies
   9565 	 * that we failed to set a particular dip offline. This
   9566 	 * does not imply that the offline as a whole should fail.
   9567 	 * We want to do the best we can, so we continue the walk.
   9568 	 */
   9569 	if (set_infant_dip_offline(dip, resp->path) == DDI_SUCCESS)
   9570 		end = DDI_SUCCESS;
   9571 	else
   9572 		end = DDI_FAILURE;
   9573 
   9574 	e_ddi_offline_finalize(dip, end);
   9575 
   9576 	return (DDI_WALK_CONTINUE);
   9577 }
   9578 
   9579 /*
   9580  * The call to e_ddi_offline_notify() exists for the
   9581  * unlikely error case that a branch we are trying to
   9582  * create already exists and has device contracts or LDI
   9583  * event callbacks against it.
   9584  *
   9585  * We allow create to succeed for such branches only if
   9586  * no constraints block the offline.
   9587  */
   9588 static int
   9589 branch_set_offline(dev_info_t *dip, char *path)
   9590 {
   9591 	int		circ;
   9592 	int		end;
   9593 	result_t	res;
   9594 
   9595 
   9596 	if (e_ddi_offline_notify(dip) == DDI_FAILURE) {
   9597 		return (DDI_FAILURE);
   9598 	}
   9599 
   9600 	if (set_infant_dip_offline(dip, path) == DDI_SUCCESS)
   9601 		end = DDI_SUCCESS;
   9602 	else
   9603 		end = DDI_FAILURE;
   9604 
   9605 	e_ddi_offline_finalize(dip, end);
   9606 
   9607 	if (end == DDI_FAILURE)
   9608 		return (DDI_FAILURE);
   9609 
   9610 	res.result = DDI_SUCCESS;
   9611 	res.path = path;
   9612 
   9613 	ndi_devi_enter(dip, &circ);
   9614 	ddi_walk_devs(ddi_get_child(dip), dip_set_offline, &res);
   9615 	ndi_devi_exit(dip, circ);
   9616 
   9617 	return (res.result);
   9618 }
   9619 
   9620 /*ARGSUSED*/
   9621 static int
   9622 create_prom_branch(void *arg, int has_changed)
   9623 {
   9624 	int		circ;
   9625 	int		exists, rv;
   9626 	pnode_t		nodeid;
   9627 	struct ptnode	*tnp;
   9628 	dev_info_t	*dip;
   9629 	struct pta	*ap = arg;
   9630 	devi_branch_t	*bp;
   9631 	char		*path;
   9632 
   9633 	ASSERT(ap);
   9634 	ASSERT(ap->fdip == NULL);
   9635 	ASSERT(ap->pdip && ndi_dev_is_prom_node(ap->pdip));
   9636 
   9637 	bp = ap->bp;
   9638 
   9639 	nodeid = ddi_get_nodeid(ap->pdip);
   9640 	if (nodeid == OBP_NONODE || nodeid == OBP_BADNODE) {
   9641 		cmn_err(CE_WARN, "create_prom_branch: invalid "
   9642 		    "nodeid: 0x%x", nodeid);
   9643 		return (EINVAL);
   9644 	}
   9645 
   9646 	ap->head = NULL;
   9647 
   9648 	nodeid = prom_childnode(nodeid);
   9649 	while (nodeid != OBP_NONODE && nodeid != OBP_BADNODE) {
   9650 		visit_node(nodeid, ap);
   9651 		nodeid = prom_nextnode(nodeid);
   9652 	}
   9653 
   9654 	if (ap->head == NULL)
   9655 		return (ENODEV);
   9656 
   9657 	path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
   9658 	rv = 0;
   9659 	while ((tnp = ap->head) != NULL) {
   9660 		ap->head = tnp->next;
   9661 
   9662 		ndi_devi_enter(ap->pdip, &circ);
   9663 
   9664 		/*
   9665 		 * Check if the branch already exists.
   9666 		 */
   9667 		exists = 0;
   9668 		dip = e_ddi_nodeid_to_dip(tnp->nodeid);
   9669 		if (dip != NULL) {
   9670 			exists = 1;
   9671 
   9672 			/* Parent is held busy, so release hold */
   9673 			ndi_rele_devi(dip);
   9674 #ifdef	DEBUG
   9675 			cmn_err(CE_WARN, "create_prom_branch: dip(%p) exists"
   9676 			    " for nodeid 0x%x", (void *)dip, tnp->nodeid);
   9677 #endif
   9678 		} else {
   9679 			dip = i_ddi_create_branch(ap->pdip, tnp->nodeid);
   9680 		}
   9681 
   9682 		kmem_free(tnp, sizeof (struct ptnode));
   9683 
   9684 		/*
   9685 		 * Hold the branch if it is not already held
   9686 		 */
   9687 		if (dip && !exists) {
   9688 			e_ddi_branch_hold(dip);
   9689 		}
   9690 
   9691 		ASSERT(dip == NULL || e_ddi_branch_held(dip));
   9692 
   9693 		/*
   9694 		 * Set all dips in the newly created branch offline so that
   9695 		 * only a "configure" operation can attach
   9696 		 * the branch
   9697 		 */
   9698 		if (dip == NULL || branch_set_offline(dip, path)
   9699 		    == DDI_FAILURE) {
   9700 			ndi_devi_exit(ap->pdip, circ);
   9701 			rv = EIO;
   9702 			continue;
   9703 		}
   9704 
   9705 		ASSERT(ddi_get_parent(dip) == ap->pdip);
   9706 
   9707 		ndi_devi_exit(ap->pdip, circ);
   9708 
   9709 		if (ap->flags & DEVI_BRANCH_CONFIGURE) {
   9710 			int error = e_ddi_branch_configure(dip, &ap->fdip, 0);
   9711 			if (error && rv == 0)
   9712 				rv = error;
   9713 		}
   9714 
   9715 		/*
   9716 		 * Invoke devi_branch_callback() (if it exists) only for
   9717 		 * newly created branches
   9718 		 */
   9719 		if (bp->devi_branch_callback && !exists)
   9720 			bp->devi_branch_callback(dip, bp->arg, 0);
   9721 	}
   9722 
   9723 	kmem_free(path, MAXPATHLEN);
   9724 
   9725 	return (rv);
   9726 }
   9727 
   9728 static int
   9729 sid_node_create(dev_info_t *pdip, devi_branch_t *bp, dev_info_t **rdipp)
   9730 {
   9731 	int			rv, circ, len;
   9732 	int			i, flags, ret;
   9733 	dev_info_t		*dip;
   9734 	char			*nbuf;
   9735 	char			*path;
   9736 	static const char	*noname = "<none>";
   9737 
   9738 	ASSERT(pdip);
   9739 	ASSERT(DEVI_BUSY_OWNED(pdip));
   9740 
   9741 	flags = 0;
   9742 
   9743 	/*
   9744 	 * Creating the root of a branch ?
   9745 	 */
   9746 	if (rdipp) {
   9747 		*rdipp = NULL;
   9748 		flags = DEVI_BRANCH_ROOT;
   9749 	}
   9750 
   9751 	ndi_devi_alloc_sleep(pdip, (char *)noname, DEVI_SID_NODEID, &dip);
   9752 	rv = bp->create.sid_branch_create(dip, bp->arg, flags);
   9753 
   9754 	nbuf = kmem_alloc(OBP_MAXDRVNAME, KM_SLEEP);
   9755 
   9756 	if (rv == DDI_WALK_ERROR) {
   9757 		cmn_err(CE_WARN, "e_ddi_branch_create: Error setting"
   9758 		    " properties on devinfo node %p",  (void *)dip);
   9759 		goto fail;
   9760 	}
   9761 
   9762 	len = OBP_MAXDRVNAME;
   9763 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
   9764 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "name", nbuf, &len)
   9765 	    != DDI_PROP_SUCCESS) {
   9766 		cmn_err(CE_WARN, "e_ddi_branch_create: devinfo node %p has"
   9767 		    "no name property", (void *)dip);
   9768 		goto fail;
   9769 	}
   9770 
   9771 	ASSERT(i_ddi_node_state(dip) == DS_PROTO);
   9772 	if (ndi_devi_set_nodename(dip, nbuf, 0) != NDI_SUCCESS) {
   9773 		cmn_err(CE_WARN, "e_ddi_branch_create: cannot set name (%s)"
   9774 		    " for devinfo node %p", nbuf, (void *)dip);
   9775 		goto fail;
   9776 	}
   9777 
   9778 	kmem_free(nbuf, OBP_MAXDRVNAME);
   9779 
   9780 	/*
   9781 	 * Ignore bind failures just like boot does
   9782 	 */
   9783 	(void) ndi_devi_bind_driver(dip, 0);
   9784 
   9785 	switch (rv) {
   9786 	case DDI_WALK_CONTINUE:
   9787 	case DDI_WALK_PRUNESIB:
   9788 		ndi_devi_enter(dip, &circ);
   9789 
   9790 		i = DDI_WALK_CONTINUE;
   9791 		for (; i == DDI_WALK_CONTINUE; ) {
   9792 			i = sid_node_create(dip, bp, NULL);
   9793 		}
   9794 
   9795 		ASSERT(i == DDI_WALK_ERROR || i == DDI_WALK_PRUNESIB);
   9796 		if (i == DDI_WALK_ERROR)
   9797 			rv = i;
   9798 		/*
   9799 		 * If PRUNESIB stop creating siblings
   9800 		 * of dip's child. Subsequent walk behavior
   9801 		 * is determined by rv returned by dip.
   9802 		 */
   9803 
   9804 		ndi_devi_exit(dip, circ);
   9805 		break;
   9806 	case DDI_WALK_TERMINATE:
   9807 		/*
   9808 		 * Don't create children and ask our parent
   9809 		 * to not create siblings either.
   9810 		 */
   9811 		rv = DDI_WALK_PRUNESIB;
   9812 		break;
   9813 	case DDI_WALK_PRUNECHILD:
   9814 		/*
   9815 		 * Don't create children, but ask parent to continue
   9816 		 * with siblings.
   9817 		 */
   9818 		rv = DDI_WALK_CONTINUE;
   9819 		break;
   9820 	default:
   9821 		ASSERT(0);
   9822 		break;
   9823 	}
   9824 
   9825 	if (rdipp)
   9826 		*rdipp = dip;
   9827 
   9828 	/*
   9829 	 * Set device offline - only the "configure" op should cause an attach.
   9830 	 * Note that it is safe to set the dip offline without checking
   9831 	 * for either device contract or layered driver (LDI) based constraints
   9832 	 * since there cannot be any contracts or LDI opens of this device.
   9833 	 * This is because this node is a newly created dip with the parent busy
   9834 	 * held, so no other thread can come in and attach this dip. A dip that
   9835 	 * has never been attached cannot have contracts since by definition
   9836 	 * a device contract (an agreement between a process and a device minor
   9837 	 * node) can only be created against a device that has minor nodes
   9838 	 * i.e is attached. Similarly an LDI open will only succeed if the
   9839 	 * dip is attached. We assert below that the dip is not attached.
   9840 	 */
   9841 	ASSERT(i_ddi_node_state(dip) < DS_ATTACHED);
   9842 	path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
   9843 	ret = set_infant_dip_offline(dip, path);
   9844 	ASSERT(ret == DDI_SUCCESS);
   9845 	kmem_free(path, MAXPATHLEN);
   9846 
   9847 	return (rv);
   9848 fail:
   9849 	(void) ndi_devi_free(dip);
   9850 	kmem_free(nbuf, OBP_MAXDRVNAME);
   9851 	return (DDI_WALK_ERROR);
   9852 }
   9853 
   9854 static int
   9855 create_sid_branch(
   9856 	dev_info_t	*pdip,
   9857 	devi_branch_t	*bp,
   9858 	dev_info_t	**dipp,
   9859 	uint_t		flags)
   9860 {
   9861 	int		rv = 0, state = DDI_WALK_CONTINUE;
   9862 	dev_info_t	*rdip;
   9863 
   9864 	while (state == DDI_WALK_CONTINUE) {
   9865 		int	circ;
   9866 
   9867 		ndi_devi_enter(pdip, &circ);
   9868 
   9869 		state = sid_node_create(pdip, bp, &rdip);
   9870 		if (rdip == NULL) {
   9871 			ndi_devi_exit(pdip, circ);
   9872 			ASSERT(state == DDI_WALK_ERROR);
   9873 			break;
   9874 		}
   9875 
   9876 		e_ddi_branch_hold(rdip);
   9877 
   9878 		ndi_devi_exit(pdip, circ);
   9879 
   9880 		if (flags & DEVI_BRANCH_CONFIGURE) {
   9881 			int error = e_ddi_branch_configure(rdip, dipp, 0);
   9882 			if (error && rv == 0)
   9883 				rv = error;
   9884 		}
   9885 
   9886 		/*
   9887 		 * devi_branch_callback() is optional
   9888 		 */
   9889 		if (bp->devi_branch_callback)
   9890 			bp->devi_branch_callback(rdip, bp->arg, 0);
   9891 	}
   9892 
   9893 	ASSERT(state == DDI_WALK_ERROR || state == DDI_WALK_PRUNESIB);
   9894 
   9895 	return (state == DDI_WALK_ERROR ? EIO : rv);
   9896 }
   9897 
   9898 int
   9899 e_ddi_branch_create(
   9900 	dev_info_t	*pdip,
   9901 	devi_branch_t	*bp,
   9902 	dev_info_t	**dipp,
   9903 	uint_t		flags)
   9904 {
   9905 	int prom_devi, sid_devi, error;
   9906 
   9907 	if (pdip == NULL || bp == NULL || bp->type == 0)
   9908 		return (EINVAL);
   9909 
   9910 	prom_devi = (bp->type == DEVI_BRANCH_PROM) ? 1 : 0;
   9911 	sid_devi = (bp->type == DEVI_BRANCH_SID) ? 1 : 0;
   9912 
   9913 	if (prom_devi && bp->create.prom_branch_select == NULL)
   9914 		return (EINVAL);
   9915 	else if (sid_devi && bp->create.sid_branch_create == NULL)
   9916 		return (EINVAL);
   9917 	else if (!prom_devi && !sid_devi)
   9918 		return (EINVAL);
   9919 
   9920 	if (flags & DEVI_BRANCH_EVENT)
   9921 		return (EINVAL);
   9922 
   9923 	if (prom_devi) {
   9924 		struct pta pta = {0};
   9925 
   9926 		pta.pdip = pdip;
   9927 		pta.bp = bp;
   9928 		pta.flags = flags;
   9929 
   9930 		error = prom_tree_access(create_prom_branch, &pta, NULL);
   9931 
   9932 		if (dipp)
   9933 			*dipp = pta.fdip;
   9934 		else if (pta.fdip)
   9935 			ndi_rele_devi(pta.fdip);
   9936 	} else {
   9937 		error = create_sid_branch(pdip, bp, dipp, flags);
   9938 	}
   9939 
   9940 	return (error);
   9941 }
   9942 
   9943 int
   9944 e_ddi_branch_configure(dev_info_t *rdip, dev_info_t **dipp, uint_t flags)
   9945 {
   9946 	int		rv;
   9947 	char		*devnm;
   9948 	dev_info_t	*pdip;
   9949 
   9950 	if (dipp)
   9951 		*dipp = NULL;
   9952 
   9953 	if (rdip == NULL || flags != 0 || (flags & DEVI_BRANCH_EVENT))
   9954 		return (EINVAL);
   9955 
   9956 	pdip = ddi_get_parent(rdip);
   9957 
   9958 	ndi_hold_devi(pdip);
   9959 
   9960 	if (!e_ddi_branch_held(rdip)) {
   9961 		ndi_rele_devi(pdip);
   9962 		cmn_err(CE_WARN, "e_ddi_branch_configure: "
   9963 		    "dip(%p) not held", (void *)rdip);
   9964 		return (EINVAL);
   9965 	}
   9966 
   9967 	if (i_ddi_node_state(rdip) < DS_INITIALIZED) {
   9968 		/*
   9969 		 * First attempt to bind a driver. If we fail, return
   9970 		 * success (On some platforms, dips for some device
   9971 		 * types (CPUs) may not have a driver)
   9972 		 */
   9973 		if (ndi_devi_bind_driver(rdip, 0) != NDI_SUCCESS) {
   9974 			ndi_rele_devi(pdip);
   9975 			return (0);
   9976 		}
   9977 
   9978 		if (ddi_initchild(pdip, rdip) != DDI_SUCCESS) {
   9979 			rv = NDI_FAILURE;
   9980 			goto out;
   9981 		}
   9982 	}
   9983 
   9984 	ASSERT(i_ddi_node_state(rdip) >= DS_INITIALIZED);
   9985 
   9986 	devnm = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
   9987 
   9988 	(void) ddi_deviname(rdip, devnm);
   9989 
   9990 	if ((rv = ndi_devi_config_one(pdip, devnm+1, &rdip,
   9991 	    NDI_DEVI_ONLINE | NDI_CONFIG)) == NDI_SUCCESS) {
   9992 		/* release hold from ndi_devi_config_one() */
   9993 		ndi_rele_devi(rdip);
   9994 	}
   9995 
   9996 	kmem_free(devnm, MAXNAMELEN + 1);
   9997 out:
   9998 	if (rv != NDI_SUCCESS && dipp && rdip) {
   9999 		ndi_hold_devi(rdip);
   10000 		*dipp = rdip;
   10001 	}
   10002 	ndi_rele_devi(pdip);
   10003 	return (ndi2errno(rv));
   10004 }
   10005 
   10006 void
   10007 e_ddi_branch_hold(dev_info_t *rdip)
   10008 {
   10009 	if (e_ddi_branch_held(rdip)) {
   10010 		cmn_err(CE_WARN, "e_ddi_branch_hold: branch already held");
   10011 		return;
   10012 	}
   10013 
   10014 	mutex_enter(&DEVI(rdip)->devi_lock);
   10015 	if ((DEVI(rdip)->devi_flags & DEVI_BRANCH_HELD) == 0) {
   10016 		DEVI(rdip)->devi_flags |= DEVI_BRANCH_HELD;
   10017 		DEVI(rdip)->devi_ref++;
   10018 	}
   10019 	ASSERT(DEVI(rdip)->devi_ref > 0);
   10020 	mutex_exit(&DEVI(rdip)->devi_lock);
   10021 }
   10022 
   10023 int
   10024 e_ddi_branch_held(dev_info_t *rdip)
   10025 {
   10026 	int rv = 0;
   10027 
   10028 	mutex_enter(&DEVI(rdip)->devi_lock);
   10029 	if ((DEVI(rdip)->devi_flags & DEVI_BRANCH_HELD) &&
   10030 	    DEVI(rdip)->devi_ref > 0) {
   10031 		rv = 1;
   10032 	}
   10033 	mutex_exit(&DEVI(rdip)->devi_lock);
   10034 
   10035 	return (rv);
   10036 }
   10037 
   10038 void
   10039 e_ddi_branch_rele(dev_info_t *rdip)
   10040 {
   10041 	mutex_enter(&DEVI(rdip)->devi_lock);
   10042 	DEVI(rdip)->devi_flags &= ~DEVI_BRANCH_HELD;
   10043 	DEVI(rdip)->devi_ref--;
   10044 	mutex_exit(&DEVI(rdip)->devi_lock);
   10045 }
   10046 
   10047 int
   10048 e_ddi_branch_unconfigure(
   10049 	dev_info_t *rdip,
   10050 	dev_info_t **dipp,
   10051 	uint_t flags)
   10052 {
   10053 	int	circ, rv;
   10054 	int	destroy;
   10055 	char	*devnm;
   10056 	uint_t	nflags;
   10057 	dev_info_t *pdip;
   10058 
   10059 	if (dipp)
   10060 		*dipp = NULL;
   10061 
   10062 	if (rdip == NULL)
   10063 		return (EINVAL);
   10064 
   10065 	pdip = ddi_get_parent(rdip);
   10066 
   10067 	ASSERT(pdip);
   10068 
   10069 	/*
   10070 	 * Check if caller holds pdip busy - can cause deadlocks during
   10071 	 * devfs_clean()
   10072 	 */
   10073 	if (DEVI_BUSY_OWNED(pdip)) {
   10074 		cmn_err(CE_WARN, "e_ddi_branch_unconfigure: failed: parent"
   10075 		    " devinfo node(%p) is busy held", (void *)pdip);
   10076 		return (EINVAL);
   10077 	}
   10078 
   10079 	destroy = (flags & DEVI_BRANCH_DESTROY) ? 1 : 0;
   10080 
   10081 	devnm = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
   10082 
   10083 	ndi_devi_enter(pdip, &circ);
   10084 	(void) ddi_deviname(rdip, devnm);
   10085 	ndi_devi_exit(pdip, circ);
   10086 
   10087 	/*
   10088 	 * ddi_deviname() returns a component name with / prepended.
   10089 	 */
   10090 	(void) devfs_clean(pdip, devnm + 1, DV_CLEAN_FORCE);
   10091 
   10092 	ndi_devi_enter(pdip, &circ);
   10093 
   10094 	/*
   10095 	 * Recreate device name as it may have changed state (init/uninit)
   10096 	 * when parent busy lock was dropped for devfs_clean()
   10097 	 */
   10098 	(void) ddi_deviname(rdip, devnm);
   10099 
   10100 	if (!e_ddi_branch_held(rdip)) {
   10101 		kmem_free(devnm, MAXNAMELEN + 1);
   10102 		ndi_devi_exit(pdip, circ);
   10103 		cmn_err(CE_WARN, "e_ddi_%s_branch: dip(%p) not held",
   10104 		    destroy ? "destroy" : "unconfigure", (void *)rdip);
   10105 		return (EINVAL);
   10106 	}
   10107 
   10108 	/*
   10109 	 * Release hold on the branch. This is ok since we are holding the
   10110 	 * parent busy. If rdip is not removed, we must do a hold on the
   10111 	 * branch before returning.
   10112 	 */
   10113 	e_ddi_branch_rele(rdip);
   10114 
   10115 	nflags = NDI_DEVI_OFFLINE;
   10116 	if (destroy || (flags & DEVI_BRANCH_DESTROY)) {
   10117 		nflags |= NDI_DEVI_REMOVE;
   10118 		destroy = 1;
   10119 	} else {
   10120 		nflags |= NDI_UNCONFIG;		/* uninit but don't remove */
   10121 	}
   10122 
   10123 	if (flags & DEVI_BRANCH_EVENT)
   10124 		nflags |= NDI_POST_EVENT;
   10125 
   10126 	if (i_ddi_devi_attached(pdip) &&
   10127 	    (i_ddi_node_state(rdip) >= DS_INITIALIZED)) {
   10128 		rv = ndi_devi_unconfig_one(pdip, devnm+1, dipp, nflags);
   10129 	} else {
   10130 		rv = e_ddi_devi_unconfig(rdip, dipp, nflags);
   10131 		if (rv == NDI_SUCCESS) {
   10132 			ASSERT(!destroy || ddi_get_child(rdip) == NULL);
   10133 			rv = ndi_devi_offline(rdip, nflags);
   10134 		}
   10135 	}
   10136 
   10137 	if (!destroy || rv != NDI_SUCCESS) {
   10138 		/* The dip still exists, so do a hold */
   10139 		e_ddi_branch_hold(rdip);
   10140 	}
   10141 out:
   10142 	kmem_free(devnm, MAXNAMELEN + 1);
   10143 	ndi_devi_exit(pdip, circ);
   10144 	return (ndi2errno(rv));
   10145 }
   10146 
   10147 int
   10148 e_ddi_branch_destroy(dev_info_t *rdip, dev_info_t **dipp, uint_t flag)
   10149 {
   10150 	return (e_ddi_branch_unconfigure(rdip, dipp,
   10151 	    flag|DEVI_BRANCH_DESTROY));
   10152 }
   10153 
   10154 /*
   10155  * Number of chains for hash table
   10156  */
   10157 #define	NUMCHAINS	17
   10158 
   10159 /*
   10160  * Devinfo busy arg
   10161  */
   10162 struct devi_busy {
   10163 	int dv_total;
   10164 	int s_total;
   10165 	mod_hash_t *dv_hash;
   10166 	mod_hash_t *s_hash;
   10167 	int (*callback)(dev_info_t *, void *, uint_t);
   10168 	void *arg;
   10169 };
   10170 
   10171 static int
   10172 visit_dip(dev_info_t *dip, void *arg)
   10173 {
   10174 	uintptr_t sbusy, dvbusy, ref;
   10175 	struct devi_busy *bsp = arg;
   10176 
   10177 	ASSERT(bsp->callback);
   10178 
   10179 	/*
   10180 	 * A dip cannot be busy if its reference count is 0
   10181 	 */
   10182 	if ((ref = e_ddi_devi_holdcnt(dip)) == 0) {
   10183 		return (bsp->callback(dip, bsp->arg, 0));
   10184 	}
   10185 
   10186 	if (mod_hash_find(bsp->dv_hash, dip, (mod_hash_val_t *)&dvbusy))
   10187 		dvbusy = 0;
   10188 
   10189 	/*
   10190 	 * To catch device opens currently maintained on specfs common snodes.
   10191 	 */
   10192 	if (mod_hash_find(bsp->s_hash, dip, (mod_hash_val_t *)&sbusy))
   10193 		sbusy = 0;
   10194 
   10195 #ifdef	DEBUG
   10196 	if (ref < sbusy || ref < dvbusy) {
   10197 		cmn_err(CE_WARN, "dip(%p): sopen = %lu, dvopen = %lu "
   10198 		    "dip ref = %lu\n", (void *)dip, sbusy, dvbusy, ref);
   10199 	}
   10200 #endif
   10201 
   10202 	dvbusy = (sbusy > dvbusy) ? sbusy : dvbusy;
   10203 
   10204 	return (bsp->callback(dip, bsp->arg, dvbusy));
   10205 }
   10206 
   10207 static int
   10208 visit_snode(struct snode *sp, void *arg)
   10209 {
   10210 	uintptr_t sbusy;
   10211 	dev_info_t *dip;
   10212 	int count;
   10213 	struct devi_busy *bsp = arg;
   10214 
   10215 	ASSERT(sp);
   10216 
   10217 	/*
   10218 	 * The stable lock is held. This prevents
   10219 	 * the snode and its associated dip from
   10220 	 * going away.
   10221 	 */
   10222 	dip = NULL;
   10223 	count = spec_devi_open_count(sp, &dip);
   10224 
   10225 	if (count <= 0)
   10226 		return (DDI_WALK_CONTINUE);
   10227 
   10228 	ASSERT(dip);
   10229 
   10230 	if (mod_hash_remove(bsp->s_hash, dip, (mod_hash_val_t *)&sbusy))
   10231 		sbusy = count;
   10232 	else
   10233 		sbusy += count;
   10234 
   10235 	if (mod_hash_insert(bsp->s_hash, dip, (mod_hash_val_t)sbusy)) {
   10236 		cmn_err(CE_WARN, "%s: s_hash insert failed: dip=0x%p, "
   10237 		    "sbusy = %lu", "e_ddi_branch_referenced",
   10238 		    (void *)dip, sbusy);
   10239 	}
   10240 
   10241 	bsp->s_total += count;
   10242 
   10243 	return (DDI_WALK_CONTINUE);
   10244 }
   10245 
   10246 static void
   10247 visit_dvnode(struct dv_node *dv, void *arg)
   10248 {
   10249 	uintptr_t dvbusy;
   10250 	uint_t count;
   10251 	struct vnode *vp;
   10252 	struct devi_busy *bsp = arg;
   10253 
   10254 	ASSERT(dv && dv->dv_devi);
   10255 
   10256 	vp = DVTOV(dv);
   10257 
   10258 	mutex_enter(&vp->v_lock);
   10259 	count = vp->v_count;
   10260 	mutex_exit(&vp->v_lock);
   10261 
   10262 	if (!count)
   10263 		return;
   10264 
   10265 	if (mod_hash_remove(bsp->dv_hash, dv->dv_devi,
   10266 	    (mod_hash_val_t *)&dvbusy))
   10267 		dvbusy = count;
   10268 	else
   10269 		dvbusy += count;
   10270 
   10271 	if (mod_hash_insert(bsp->dv_hash, dv->dv_devi,
   10272 	    (mod_hash_val_t)dvbusy)) {
   10273 		cmn_err(CE_WARN, "%s: dv_hash insert failed: dip=0x%p, "
   10274 		    "dvbusy=%lu", "e_ddi_branch_referenced",
   10275 		    (void *)dv->dv_devi, dvbusy);
   10276 	}
   10277 
   10278 	bsp->dv_total += count;
   10279 }
   10280 
   10281 /*
   10282  * Returns reference count on success or -1 on failure.
   10283  */
   10284 int
   10285 e_ddi_branch_referenced(
   10286 	dev_info_t *rdip,
   10287 	int (*callback)(dev_info_t *dip, void *arg, uint_t ref),
   10288 	void *arg)
   10289 {
   10290 	int circ;
   10291 	char *path;
   10292 	dev_info_t *pdip;
   10293 	struct devi_busy bsa = {0};
   10294 
   10295 	ASSERT(rdip);
   10296 
   10297 	path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
   10298 
   10299 	ndi_hold_devi(rdip);
   10300 
   10301 	pdip = ddi_get_parent(rdip);
   10302 
   10303 	ASSERT(pdip);
   10304 
   10305 	/*
   10306 	 * Check if caller holds pdip busy - can cause deadlocks during
   10307 	 * devfs_walk()
   10308 	 */
   10309 	if (!e_ddi_branch_held(rdip) || DEVI_BUSY_OWNED(pdip)) {
   10310 		cmn_err(CE_WARN, "e_ddi_branch_referenced: failed: "
   10311 		    "devinfo branch(%p) not held or parent busy held",
   10312 		    (void *)rdip);
   10313 		ndi_rele_devi(rdip);
   10314 		kmem_free(path, MAXPATHLEN);
   10315 		return (-1);
   10316 	}
   10317 
   10318 	ndi_devi_enter(pdip, &circ);
   10319 	(void) ddi_pathname(rdip, path);
   10320 	ndi_devi_exit(pdip, circ);
   10321 
   10322 	bsa.dv_hash = mod_hash_create_ptrhash("dv_node busy hash", NUMCHAINS,
   10323 	    mod_hash_null_valdtor, sizeof (struct dev_info));
   10324 
   10325 	bsa.s_hash = mod_hash_create_ptrhash("snode busy hash", NUMCHAINS,
   10326 	    mod_hash_null_valdtor, sizeof (struct snode));
   10327 
   10328 	if (devfs_walk(path, visit_dvnode, &bsa)) {
   10329 		cmn_err(CE_WARN, "e_ddi_branch_referenced: "
   10330 		    "devfs walk failed for: %s", path);
   10331 		kmem_free(path, MAXPATHLEN);
   10332 		bsa.s_total = bsa.dv_total = -1;
   10333 		goto out;
   10334 	}
   10335 
   10336 	kmem_free(path, MAXPATHLEN);
   10337 
   10338 	/*
   10339 	 * Walk the snode table to detect device opens, which are currently
   10340 	 * maintained on specfs common snodes.
   10341 	 */
   10342 	spec_snode_walk(visit_snode, &bsa);
   10343 
   10344 	if (callback == NULL)
   10345 		goto out;
   10346 
   10347 	bsa.callback = callback;
   10348 	bsa.arg = arg;
   10349 
   10350 	if (visit_dip(rdip, &bsa) == DDI_WALK_CONTINUE) {
   10351 		ndi_devi_enter(rdip, &circ);
   10352 		ddi_walk_devs(ddi_get_child(rdip), visit_dip, &bsa);
   10353 		ndi_devi_exit(rdip, circ);
   10354 	}
   10355 
   10356 out:
   10357 	ndi_rele_devi(rdip);
   10358 	mod_hash_destroy_ptrhash(bsa.s_hash);
   10359 	mod_hash_destroy_ptrhash(bsa.dv_hash);
   10360 	return (bsa.s_total > bsa.dv_total ? bsa.s_total : bsa.dv_total);
   10361 }
   10362