Home | History | Annotate | Download | only in io
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 
     27 #include <sys/audio.h>
     28 #include <sys/conf.h>
     29 #include <sys/debug.h>
     30 #include <sys/disp.h>
     31 #include <sys/ddi.h>
     32 #include <sys/file.h>
     33 #include <sys/id_space.h>
     34 #include <sys/kmem.h>
     35 #include <sys/lx_audio.h>
     36 #include <sys/mixer.h>
     37 #include <sys/modhash.h>
     38 #include <sys/stat.h>
     39 #include <sys/sunddi.h>
     40 #include <sys/sunldi.h>
     41 #include <sys/sysmacros.h>
     42 #include <sys/stropts.h>
     43 #include <sys/types.h>
     44 #include <sys/zone.h>
     45 
     46 /* Properties used by the lx_audio driver */
     47 #define	LXA_PROP_INPUTDEV		"inputdev"
     48 #define	LXA_PROP_OUTPUTDEV		"outputdev"
     49 
     50 /* default device paths used by this driver */
     51 #define	LXA_DEV_DEFAULT			"/dev/audio"
     52 #define	LXA_DEV_CUSTOM_DIR		"/dev/sound/"
     53 
     54 /* maximum possible number of concurrent opens of this driver */
     55 #define	LX_AUDIO_MAX_OPENS		1024
     56 
     57 /*
     58  * these are default fragment size and fragment count values.
     59  * these values were chosen to make quake work well on my
     60  * laptop: 2Ghz Pentium M + NVIDIA GeForce Go 6400.
     61  *
     62  * for reference:
     63  * - 1 sec of stereo output at 44Khz is about 171 Kb of data
     64  * - 1 sec of mono output at 8Khz is about 8Kb of data
     65  */
     66 #define	LXA_OSS_FRAG_SIZE		(1024)	/* 1/8 sec at 8Khz mono */
     67 #define	LXA_OSS_FRAG_CNT		(1024 * 2)
     68 
     69 /* maximum ammount of fragment memory we'll allow a process to mmap */
     70 #define	LXA_OSS_FRAG_MEM		(1024 * 1024 * 2) /* 2Mb */
     71 
     72 /* forward declarations */
     73 typedef struct lxa_state lxa_state_t;
     74 typedef struct lxa_zstate lxa_zstate_t;
     75 
     76 /*
     77  * Structure and enum declarations
     78  */
     79 typedef enum {
     80 	LXA_TYPE_INVALID	= 0,
     81 	LXA_TYPE_AUDIO		= 1,	/* audio device */
     82 	LXA_TYPE_AUDIOCTL	= 2	/* audio control/mixer device */
     83 } lxa_dev_type_t;
     84 
     85 struct lxa_zstate {
     86 	char			*lxa_zs_zonename;
     87 
     88 	/*
     89 	 * we could store the input/output audio device setting here,
     90 	 * but instead we're keeing them as device node properties
     91 	 * so that a user can easily see the audio configuration for
     92 	 * a zone via prtconf.
     93 	 */
     94 
     95 	/*
     96 	 * OSS doesn't support multiple opens of the audio device.
     97 	 * (multiple opens of the mixer device are supported.)
     98 	 * so here we'll keep a pointer to any open input/output
     99 	 * streams.  (OSS does support two opens if one is for input
    100 	 * and the other is for output.)
    101 	 */
    102 	lxa_state_t		*lxa_zs_istate;
    103 	lxa_state_t		*lxa_zs_ostate;
    104 
    105 	/*
    106 	 * we need to cache channel gain and balance.  channel gain and
    107 	 * balance map to PCM volume in OSS, which are supposedly a property
    108 	 * of the underlying hardware.  but in solaris, channels are
    109 	 * implemented in software and only exist when an audio device
    110 	 * is actually open.  (each open returns a unique channel.)  OSS
    111 	 * apps will expect consistent PCM volume set/get operations to
    112 	 * work even if no audio device is open.  hence, if no underlying
    113 	 * device is open we need to cache the gain and balance setting.
    114 	 */
    115 	lxa_mixer_levels_t	lxa_zs_pcm_levels;
    116 };
    117 
    118 struct lxa_state {
    119 	lxa_zstate_t	*lxas_zs;	/* zone state pointer */
    120 
    121 	dev_t		lxas_dev_old;	/* dev_t used to open the device */
    122 	dev_t		lxas_dev_new;	/* new dev_t assigned to an open */
    123 	int		lxas_flags;	/* original flags passed to open */
    124 	lxa_dev_type_t	lxas_type;	/* type of device that was opened */
    125 
    126 	int		lxas_devs_same;	/* input and output device the same? */
    127 
    128 	/* input device variables */
    129 	ldi_handle_t	lxas_idev_lh;		/* ldi handle for access */
    130 	int		lxas_idev_flags;	/* flags used for open */
    131 
    132 	/* output device variables */
    133 	ldi_handle_t	lxas_odev_lh;		/* ldi handle for access */
    134 	int		lxas_odev_flags;	/* flags used for open */
    135 
    136 	/*
    137 	 * since we support multiplexing of devices we need to remember
    138 	 * certain parameters about the devices
    139 	 */
    140 	uint_t		lxas_hw_features;
    141 	uint_t		lxas_sw_features;
    142 
    143 	uint_t		lxas_frag_size;
    144 	uint_t		lxas_frag_cnt;
    145 
    146 	/*
    147 	 * members needed to support mmap device access.  note that to
    148 	 * simplifly things we only support one mmap access per open.
    149 	 */
    150 	ddi_umem_cookie_t	lxas_umem_cookie;
    151 	char			*lxas_umem_ptr;
    152 	size_t			lxas_umem_len;
    153 	kthread_t		*lxas_mmap_thread;
    154 	int			lxas_mmap_thread_running;
    155 	int			lxas_mmap_thread_exit;
    156 	int			lxas_mmap_thread_frag;
    157 };
    158 
    159 /*
    160  * Global variables
    161  */
    162 dev_info_t	*lxa_dip = NULL;
    163 kmutex_t	lxa_lock;
    164 id_space_t	*lxa_minor_id = NULL;
    165 mod_hash_t	*lxa_state_hash = NULL;
    166 mod_hash_t	*lxa_zstate_hash = NULL;
    167 size_t		lxa_state_hash_size = 15;
    168 size_t		lxa_zstate_hash_size = 15;
    169 size_t		lxa_registered_zones = 0;
    170 
    171 /*
    172  * function declarations
    173  */
    174 static void lxa_mmap_output_disable(lxa_state_t *);
    175 
    176 /*
    177  * functions
    178  */
    179 static void
    180 lxa_state_close(lxa_state_t *lxa_state)
    181 {
    182 	lxa_zstate_t		*lxa_zs = lxa_state->lxas_zs;
    183 	minor_t			minor = getminor(lxa_state->lxas_dev_new);
    184 
    185 	/* disable any mmap output that might still be going on */
    186 	lxa_mmap_output_disable(lxa_state);
    187 
    188 	/*
    189 	 * if this was the active input/output device, unlink it from
    190 	 * the global zone state so that other opens of the audio device
    191 	 * can now succeed.
    192 	 */
    193 	mutex_enter(&lxa_lock);
    194 	if (lxa_zs->lxa_zs_istate == lxa_state)
    195 		lxa_zs->lxa_zs_istate = NULL;
    196 	if (lxa_zs->lxa_zs_ostate == lxa_state) {
    197 		lxa_zs->lxa_zs_ostate = NULL;
    198 	}
    199 	mutex_exit(&lxa_lock);
    200 
    201 	/* remove this state structure from the hash (if it's there) */
    202 	(void) mod_hash_remove(lxa_state_hash,
    203 	    (mod_hash_key_t)(uintptr_t)minor, (mod_hash_val_t *)&lxa_state);
    204 
    205 	/* close any audio device that we have open */
    206 	if (lxa_state->lxas_idev_lh != NULL)
    207 		(void) ldi_close(lxa_state->lxas_idev_lh,
    208 		    lxa_state->lxas_idev_flags, kcred);
    209 	if (lxa_state->lxas_odev_lh != NULL)
    210 		(void) ldi_close(lxa_state->lxas_odev_lh,
    211 		    lxa_state->lxas_odev_flags, kcred);
    212 
    213 	/* free up any memory allocated by mmaps */
    214 	if (lxa_state->lxas_umem_cookie != NULL)
    215 		ddi_umem_free(lxa_state->lxas_umem_cookie);
    216 
    217 	/* release the id associated with this state structure */
    218 	id_free(lxa_minor_id, minor);
    219 
    220 	kmem_free(lxa_state, sizeof (*lxa_state));
    221 }
    222 
    223 static char *
    224 getzonename(void)
    225 {
    226 	return (curproc->p_zone->zone_name);
    227 }
    228 
    229 static char *
    230 lxa_devprop_name(char *zname, char *pname)
    231 {
    232 	char	*zpname;
    233 	int	n;
    234 
    235 	ASSERT((pname != NULL) && (zname != NULL));
    236 
    237 	/* prepend the zone name to the property name */
    238 	n = snprintf(NULL, 0, "%s_%s", zname, pname) + 1;
    239 	zpname = kmem_alloc(n, KM_SLEEP);
    240 	(void) snprintf(zpname, n, "%s_%s", zname, pname);
    241 
    242 	return (zpname);
    243 }
    244 
    245 static int
    246 lxa_devprop_verify(char *pval)
    247 {
    248 	int	n;
    249 
    250 	ASSERT(pval != NULL);
    251 
    252 	if (strcmp(pval, "default") == 0)
    253 		return (0);
    254 
    255 	/* make sure the value is an integer */
    256 	for (n = 0; pval[n] != '\0'; n++) {
    257 		if ((pval[n] < '0') && (pval[n] > '9')) {
    258 			return (-1);
    259 		}
    260 	}
    261 
    262 	return (0);
    263 }
    264 
    265 static char *
    266 lxa_devprop_lookup(char *zname, char *pname, lxa_dev_type_t lxa_type)
    267 {
    268 	char		*zprop_name, *pval;
    269 	char		*dev_path;
    270 	int		n, rv;
    271 
    272 	ASSERT((pname != NULL) && (zname != NULL));
    273 	ASSERT((lxa_type == LXA_TYPE_AUDIO) || (lxa_type == LXA_TYPE_AUDIOCTL));
    274 
    275 	zprop_name = lxa_devprop_name(zname, pname);
    276 
    277 	/* attempt to lookup the property */
    278 	rv = ddi_prop_lookup_string(DDI_DEV_T_ANY, lxa_dip,
    279 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, zprop_name, &pval);
    280 	strfree(zprop_name);
    281 
    282 	if (rv != DDI_PROP_SUCCESS)
    283 		return (NULL);
    284 
    285 	if (lxa_devprop_verify(pval) != 0) {
    286 		ddi_prop_free(pval);
    287 		return (NULL);
    288 	}
    289 
    290 	if (strcmp(pval, "none") == 0) {
    291 		/* there is no audio device specified */
    292 		return (NULL);
    293 	} else if (strcmp(pval, "default") == 0) {
    294 		/* use the default audio device on the system */
    295 		dev_path = strdup(LXA_DEV_DEFAULT);
    296 	} else {
    297 		/* a custom audio device was specified, generate a path */
    298 		n = snprintf(NULL, 0, "%s%s", LXA_DEV_CUSTOM_DIR, pval) + 1;
    299 		dev_path = kmem_alloc(n, KM_SLEEP);
    300 		(void) snprintf(dev_path, n, "%s%s", LXA_DEV_CUSTOM_DIR, pval);
    301 	}
    302 	ddi_prop_free(pval);
    303 
    304 	/*
    305 	 * if this is an audio control device so we need to append
    306 	 * "ctl" to the path
    307 	 */
    308 	if (lxa_type == LXA_TYPE_AUDIOCTL) {
    309 		char	*tmp;
    310 		n = snprintf(NULL, 0, "%s%s", dev_path, "ctl") + 1;
    311 		tmp = kmem_alloc(n, KM_SLEEP);
    312 		(void) snprintf(tmp, n, "%s%s", dev_path, "ctl");
    313 		strfree(dev_path);
    314 		dev_path = tmp;
    315 	}
    316 
    317 	return (dev_path);
    318 }
    319 
    320 static int
    321 lxa_dev_getfeatures(lxa_state_t *lxa_state)
    322 {
    323 	audio_info_t	ai_idev, ai_odev;
    324 	int		n, rv;
    325 
    326 	/* set a default fragment size */
    327 	lxa_state->lxas_frag_size = LXA_OSS_FRAG_SIZE;
    328 	lxa_state->lxas_frag_cnt = LXA_OSS_FRAG_CNT;
    329 
    330 	/* get info for the currently open audio devices */
    331 	if ((lxa_state->lxas_idev_lh != NULL) &&
    332 	    ((rv = ldi_ioctl(lxa_state->lxas_idev_lh,
    333 	    AUDIO_GETINFO, (intptr_t)&ai_idev, FKIOCTL, kcred, &n)) != 0))
    334 		return (rv);
    335 	if ((lxa_state->lxas_odev_lh != NULL) &&
    336 	    ((rv = ldi_ioctl(lxa_state->lxas_odev_lh,
    337 	    AUDIO_GETINFO, (intptr_t)&ai_odev, FKIOCTL, kcred, &n)) != 0))
    338 		return (rv);
    339 
    340 	/* if we're only open for reading or writing then it's easy */
    341 	if (lxa_state->lxas_idev_lh == NULL) {
    342 		lxa_state->lxas_sw_features = ai_odev.sw_features;
    343 		lxa_state->lxas_hw_features = ai_odev.hw_features;
    344 		return (0);
    345 	} else if (lxa_state->lxas_odev_lh == NULL) {
    346 		lxa_state->lxas_sw_features = ai_idev.sw_features;
    347 		lxa_state->lxas_hw_features = ai_idev.hw_features;
    348 		return (0);
    349 	}
    350 
    351 	/*
    352 	 * well if we're open for reading and writing but the underlying
    353 	 * device is the same then it's also pretty easy
    354 	 */
    355 	if (lxa_state->lxas_devs_same) {
    356 		if ((ai_odev.sw_features != ai_idev.sw_features) ||
    357 		    (ai_odev.hw_features != ai_idev.hw_features)) {
    358 			zcmn_err(getzoneid(), CE_WARN, "lx_audio error: "
    359 			    "audio device reported inconsistent features");
    360 			return (EIO);
    361 		}
    362 		lxa_state->lxas_sw_features = ai_odev.sw_features;
    363 		lxa_state->lxas_hw_features = ai_odev.hw_features;
    364 		return (0);
    365 	}
    366 
    367 	/*
    368 	 * figure out which software features we're going to support.
    369 	 * we will report a feature as supported if both the input
    370 	 * and output device support it.
    371 	 */
    372 	lxa_state->lxas_sw_features = 0;
    373 	n = ai_idev.sw_features & ai_odev.sw_features;
    374 	if (n & AUDIO_SWFEATURE_MIXER)
    375 		lxa_state->lxas_sw_features |= AUDIO_SWFEATURE_MIXER;
    376 
    377 	/*
    378 	 * figure out which hardware features we're going to support.
    379 	 * for a first pass we will report a feature as supported if
    380 	 * both the input and output device support it.
    381 	 */
    382 	lxa_state->lxas_hw_features = 0;
    383 	n = ai_idev.hw_features & ai_odev.hw_features;
    384 	if (n & AUDIO_HWFEATURE_MSCODEC)
    385 		lxa_state->lxas_hw_features |= AUDIO_HWFEATURE_MSCODEC;
    386 
    387 	/*
    388 	 * if we made it here then we have different audio input and output
    389 	 * devices.  this will allow us to report support for additional
    390 	 * hardware features that may not supported by just the input or
    391 	 * output device alone.
    392 	 */
    393 
    394 	/* always report tha we support both playback and recording */
    395 	lxa_state->lxas_hw_features =
    396 	    AUDIO_HWFEATURE_PLAY | AUDIO_HWFEATURE_RECORD;
    397 
    398 	/* always report full duplex support */
    399 	lxa_state->lxas_hw_features = AUDIO_HWFEATURE_DUPLEX;
    400 
    401 	/* never report that we have input to output loopback support */
    402 	ASSERT((lxa_state->lxas_hw_features & AUDIO_HWFEATURE_IN2OUT) == 0);
    403 	return (0);
    404 }
    405 
    406 static int
    407 lxa_dev_open(lxa_state_t *lxa_state)
    408 {
    409 	char		*idev, *odev;
    410 	int		flags, rv;
    411 	ldi_handle_t	lh;
    412 	ldi_ident_t	li = NULL;
    413 
    414 	ASSERT((lxa_state->lxas_type == LXA_TYPE_AUDIO) ||
    415 	    (lxa_state->lxas_type == LXA_TYPE_AUDIOCTL));
    416 
    417 	/*
    418 	 * check if we have configuration properties for this zone.
    419 	 * if we don't then audio isn't supported in this zone.
    420 	 */
    421 	idev = lxa_devprop_lookup(getzonename(), LXA_PROP_INPUTDEV,
    422 	    lxa_state->lxas_type);
    423 	odev = lxa_devprop_lookup(getzonename(), LXA_PROP_OUTPUTDEV,
    424 	    lxa_state->lxas_type);
    425 
    426 	/* make sure there is at least one device to read from or write to */
    427 	if ((idev == NULL) && (odev == NULL))
    428 		return (ENODEV);
    429 
    430 	/* see if the input and output devices are actually the same device */
    431 	if (((idev != NULL) && (odev != NULL)) &&
    432 	    (strcmp(idev, odev) == 0))
    433 		lxa_state->lxas_devs_same = 1;
    434 
    435 	/* we don't respect FEXCL */
    436 	flags = lxa_state->lxas_flags & ~FEXCL;
    437 	if (lxa_state->lxas_type == LXA_TYPE_AUDIO) {
    438 		/*
    439 		 * if we're opening audio devices then we need to muck
    440 		 * with the FREAD/FWRITE flags.
    441 		 *
    442 		 * certain audio device may only support input or output
    443 		 * (but not both.)  so if we're multiplexing input/output
    444 		 * to different devices we need to make sure we don't try
    445 		 * and open the output device for reading and the input
    446 		 * device for writing.
    447 		 *
    448 		 * if we're using the same device for input/output we still
    449 		 * need to do this because some audio devices won't let
    450 		 * themselves be opened multiple times for read access.
    451 		 */
    452 		lxa_state->lxas_idev_flags = flags & ~FWRITE;
    453 		lxa_state->lxas_odev_flags = flags & ~FREAD;
    454 
    455 		/* make sure we have devices to read from and write to */
    456 		if (((flags & FREAD) && (idev == NULL)) ||
    457 		    ((flags & FWRITE) && (odev == NULL))) {
    458 			rv = ENODEV;
    459 			goto out;
    460 		}
    461 	} else {
    462 		lxa_state->lxas_idev_flags = lxa_state->lxas_odev_flags = flags;
    463 	}
    464 
    465 	/* get an ident to open the devices */
    466 	if (ldi_ident_from_dev(lxa_state->lxas_dev_new, &li) != 0) {
    467 		rv = ENODEV;
    468 		goto out;
    469 	}
    470 
    471 	/* open the input device */
    472 	lxa_state->lxas_idev_lh = NULL;
    473 	if (((lxa_state->lxas_type == LXA_TYPE_AUDIOCTL) ||
    474 	    (lxa_state->lxas_idev_flags & FREAD)) &&
    475 	    (idev != NULL)) {
    476 		rv = ldi_open_by_name(idev, lxa_state->lxas_idev_flags,
    477 		    kcred, &lh, li);
    478 		if (rv != 0) {
    479 			zcmn_err(getzoneid(), CE_WARN, "lxa_open_dev: "
    480 			    "unable to open audio device: %s", idev);
    481 			zcmn_err(getzoneid(), CE_WARN, "lxa_open_dev: "
    482 			    "possible zone audio configuration error");
    483 			goto out;
    484 		}
    485 		lxa_state->lxas_idev_lh = lh;
    486 	}
    487 
    488 	/* open the output device */
    489 	lxa_state->lxas_odev_lh = NULL;
    490 	if (((lxa_state->lxas_type == LXA_TYPE_AUDIOCTL) ||
    491 	    (lxa_state->lxas_odev_flags & FWRITE)) &&
    492 	    (odev != NULL)) {
    493 		rv = ldi_open_by_name(odev, lxa_state->lxas_odev_flags,
    494 		    kcred, &lh, li);
    495 		if (rv != 0) {
    496 			/*
    497 			 * If this open failed and we previously opened an
    498 			 * input device, it is the responsibility of the
    499 			 * caller to close that device after we return
    500 			 * failure here.
    501 			 */
    502 			zcmn_err(getzoneid(), CE_WARN, "lxa_open_dev: "
    503 			    "unable to open audio device: %s", odev);
    504 			zcmn_err(getzoneid(), CE_WARN, "lxa_open_dev: "
    505 			    "possible zone audio configuration error");
    506 			goto out;
    507 		}
    508 		lxa_state->lxas_odev_lh = lh;
    509 	}
    510 
    511 	/* free up stuff */
    512 out:
    513 	if (li != NULL)
    514 		ldi_ident_release(li);
    515 	if (idev != NULL)
    516 		strfree(idev);
    517 	if (odev != NULL)
    518 		strfree(odev);
    519 
    520 	return (rv);
    521 }
    522 
    523 void
    524 lxa_mmap_thread_exit(lxa_state_t *lxa_state)
    525 {
    526 	mutex_enter(&lxa_lock);
    527 	lxa_state->lxas_mmap_thread = NULL;
    528 	lxa_state->lxas_mmap_thread_frag = 0;
    529 	lxa_state->lxas_mmap_thread_running = 0;
    530 	lxa_state->lxas_mmap_thread_exit = 0;
    531 	mutex_exit(&lxa_lock);
    532 	thread_exit();
    533 	/*NOTREACHED*/
    534 }
    535 
    536 void
    537 lxa_mmap_thread(lxa_state_t *lxa_state)
    538 {
    539 	struct uio	uio, uio_null;
    540 	iovec_t		iovec, iovec_null;
    541 	uint_t		bytes_per_sec, usec_per_frag, ticks_per_frag;
    542 	int		rv, junk, eof, retry;
    543 	audio_info_t	ai;
    544 
    545 	/* we better be setup for writing to the output device */
    546 	ASSERT((lxa_state->lxas_flags & FWRITE) != 0);
    547 	ASSERT(lxa_state->lxas_odev_lh != NULL);
    548 
    549 	/* setup a uio to output one fragment */
    550 	uio.uio_iov = &iovec;
    551 	uio.uio_iovcnt = 1;
    552 	uio.uio_offset = 0;
    553 	uio.uio_segflg = UIO_SYSSPACE;
    554 	uio.uio_fmode = 0;
    555 	uio.uio_extflg = 0;
    556 	uio.uio_llimit = MAXOFFSET_T;
    557 
    558 	/* setup a uio to output a eof (a fragment with a length of 0) */
    559 	uio_null.uio_iov = &iovec_null;
    560 	uio_null.uio_iov->iov_len = 0;
    561 	uio_null.uio_iov->iov_base = NULL;
    562 	uio_null.uio_iovcnt = 1;
    563 	uio_null.uio_offset = 0;
    564 	uio_null.uio_segflg = UIO_SYSSPACE;
    565 	uio_null.uio_fmode = 0;
    566 	uio_null.uio_extflg = 0;
    567 	uio_null.uio_llimit = MAXOFFSET_T;
    568 	uio_null.uio_resid = 0;
    569 
    570 lxa_mmap_thread_top:
    571 	ASSERT(!MUTEX_HELD(&lxa_lock));
    572 
    573 	/* first drain any pending audio output */
    574 	if ((rv = ldi_ioctl(lxa_state->lxas_odev_lh,
    575 	    AUDIO_DRAIN, NULL, FKIOCTL, kcred, &junk)) != 0) {
    576 		cmn_err(CE_WARN, "lxa_mmap_thread: "
    577 		    "AUDIO_DRAIN failed, aborting audio output");
    578 		lxa_mmap_thread_exit(lxa_state);
    579 		/*NOTREACHED*/
    580 	}
    581 
    582 	/*
    583 	 * we depend on the ai.play.eof value to keep track of
    584 	 * audio output progress so reset it here.
    585 	 */
    586 	AUDIO_INITINFO(&ai);
    587 	ai.play.eof = 0;
    588 	if ((rv = ldi_ioctl(lxa_state->lxas_odev_lh,
    589 	    AUDIO_SETINFO, (intptr_t)&ai, FKIOCTL, kcred, &junk)) != 0) {
    590 		cmn_err(CE_WARN, "lxa_mmap_thread: "
    591 		    "AUDIO_SETINFO failed, aborting audio output");
    592 		lxa_mmap_thread_exit(lxa_state);
    593 		/*NOTREACHED*/
    594 	}
    595 
    596 	/*
    597 	 * we're going to need to know the sampling rate and number
    598 	 * of output channels to estimate how long we can sleep between
    599 	 * requests.
    600 	 */
    601 	if ((rv = ldi_ioctl(lxa_state->lxas_odev_lh, AUDIO_GETINFO,
    602 	    (intptr_t)&ai, FKIOCTL, kcred, &junk)) != 0) {
    603 		cmn_err(CE_WARN, "lxa_mmap_thread: "
    604 		    "AUDIO_GETINFO failed, aborting audio output");
    605 		lxa_mmap_thread_exit(lxa_state);
    606 		/*NOTREACHED*/
    607 	}
    608 
    609 	/* estimate how many ticks it takes to output a fragment of data */
    610 	bytes_per_sec = (ai.play.sample_rate * ai.play.channels *
    611 	    ai.play.precision) / 8;
    612 	usec_per_frag = MICROSEC * lxa_state->lxas_frag_size / bytes_per_sec;
    613 	ticks_per_frag = drv_usectohz(usec_per_frag);
    614 
    615 	/* queue up three fragments of of data into the output stream */
    616 	eof = 3;
    617 
    618 	/* sanity check the eof value */
    619 	ASSERT(ai.play.eof == 0);
    620 	ai.play.eof = 0;
    621 
    622 	/* we always start audio output at fragment 0 */
    623 	mutex_enter(&lxa_lock);
    624 	lxa_state->lxas_mmap_thread_frag = 0;
    625 
    626 	/*
    627 	 * we shouldn't have allowed the mapping if it isn't a multiple
    628 	 * of the fragment size
    629 	 */
    630 	ASSERT((lxa_state->lxas_umem_len % lxa_state->lxas_frag_size) == 0);
    631 
    632 	while (!lxa_state->lxas_mmap_thread_exit) {
    633 		size_t start, end;
    634 
    635 		/*
    636 		 * calculate the start and ending offsets of the next
    637 		 * fragment to output
    638 		 */
    639 		start = lxa_state->lxas_mmap_thread_frag *
    640 		    lxa_state->lxas_frag_size;
    641 		end = start + lxa_state->lxas_frag_size;
    642 
    643 		ASSERT(start < lxa_state->lxas_umem_len);
    644 		ASSERT(end <= lxa_state->lxas_umem_len);
    645 
    646 		/* setup the uio to output one fragment of audio */
    647 		uio.uio_resid = end - start;
    648 		uio.uio_iov->iov_len = end - start;
    649 		uio.uio_iov->iov_base = &lxa_state->lxas_umem_ptr[start];
    650 
    651 		/* increment the current fragment index */
    652 		lxa_state->lxas_mmap_thread_frag =
    653 		    (lxa_state->lxas_mmap_thread_frag + 1) %
    654 		    (lxa_state->lxas_umem_len / lxa_state->lxas_frag_size);
    655 
    656 		/* drop the audio lock before actually outputting data */
    657 		mutex_exit(&lxa_lock);
    658 
    659 		/*
    660 		 * write the fragment of audio data to the device stream
    661 		 * then write a eof to the stream to tell the device to
    662 		 * increment ai.play.eof when it's done processing the
    663 		 * fragment we just wrote
    664 		 */
    665 		if ((rv = ldi_write(lxa_state->lxas_odev_lh,
    666 		    &uio, kcred)) != 0) {
    667 			cmn_err(CE_WARN, "lxa_mmap_thread: "
    668 			    "ldi_write() failed (%d), "
    669 			    "resetting audio output", rv);
    670 			goto lxa_mmap_thread_top;
    671 		}
    672 		if ((rv = ldi_write(lxa_state->lxas_odev_lh,
    673 		    &uio_null, kcred)) != 0) {
    674 			cmn_err(CE_WARN, "lxa_mmap_thread: "
    675 			    "ldi_write(eof) failed (%d), "
    676 			    "resetting audio output", rv);
    677 			goto lxa_mmap_thread_top;
    678 		}
    679 
    680 		/*
    681 		 * we want to avoid buffer underrun so ensure that
    682 		 * there is always at least one fragment of data in the
    683 		 * output stream.
    684 		 */
    685 		mutex_enter(&lxa_lock);
    686 		if (--eof > 0) {
    687 			continue;
    688 		}
    689 
    690 		/*
    691 		 * now we wait until the audio device has finished outputting
    692 		 * at least one fragment of data.
    693 		 */
    694 		retry = 0;
    695 		while (!lxa_state->lxas_mmap_thread_exit && (eof == 0)) {
    696 			uint_t ai_eof_old = ai.play.eof;
    697 
    698 			mutex_exit(&lxa_lock);
    699 
    700 			/*
    701 			 * delay for the number of ticks it takes
    702 			 * to output one fragment of data
    703 			 */
    704 			if (ticks_per_frag > 0)
    705 				delay(ticks_per_frag);
    706 
    707 			/* check if we've managed to output any fragments */
    708 			if ((rv = ldi_ioctl(lxa_state->lxas_odev_lh,
    709 			    AUDIO_GETINFO, (intptr_t)&ai,
    710 			    FKIOCTL, kcred, &junk)) != 0) {
    711 				cmn_err(CE_WARN, "lxa_mmap_thread: "
    712 				    "AUDIO_GETINFO failed (%d), "
    713 				    "resetting audio output", rv);
    714 				/* re-start mmap audio output */
    715 				goto lxa_mmap_thread_top;
    716 			}
    717 
    718 			if (ai_eof_old == ai.play.eof) {
    719 				/* institute a random retry limit */
    720 				if (retry++ < 100) {
    721 					mutex_enter(&lxa_lock);
    722 					continue;
    723 				}
    724 				cmn_err(CE_WARN, "lxa_mmap_thread: "
    725 				    "output stalled, "
    726 				    "resetting audio output");
    727 				/* re-start mmap audio output */
    728 				goto lxa_mmap_thread_top;
    729 			}
    730 
    731 			if (ai.play.eof > ai_eof_old) {
    732 				eof = ai.play.eof - ai_eof_old;
    733 			} else {
    734 				/* eof counter wrapped around */
    735 				ASSERT(ai_eof_old < ai.play.eof);
    736 				eof = ai.play.eof + (ai_eof_old - UINTMAX_MAX);
    737 			}
    738 			/* we're done with this loop so re-aquire the lock */
    739 			ASSERT(eof != 0);
    740 			mutex_enter(&lxa_lock);
    741 		}
    742 	}
    743 	mutex_exit(&lxa_lock);
    744 	lxa_mmap_thread_exit(lxa_state);
    745 	/*NOTREACHED*/
    746 }
    747 
    748 static void
    749 lxa_mmap_output_disable(lxa_state_t *lxa_state)
    750 {
    751 	kt_did_t tid;
    752 
    753 	mutex_enter(&lxa_lock);
    754 
    755 	/* if the output thread isn't running there's nothing to do */
    756 	if (lxa_state->lxas_mmap_thread_running == 0) {
    757 		mutex_exit(&lxa_lock);
    758 		return;
    759 	}
    760 
    761 	/* tell the pcm mmap output thread to exit */
    762 	lxa_state->lxas_mmap_thread_exit = 1;
    763 
    764 	/* wait for the mmap output thread to exit */
    765 	tid = lxa_state->lxas_mmap_thread->t_did;
    766 	mutex_exit(&lxa_lock);
    767 	thread_join(tid);
    768 }
    769 
    770 static void
    771 lxa_mmap_output_enable(lxa_state_t *lxa_state)
    772 {
    773 	mutex_enter(&lxa_lock);
    774 
    775 	/* if the output thread is already running there's nothing to do */
    776 	if (lxa_state->lxas_mmap_thread_running != 0) {
    777 		mutex_exit(&lxa_lock);
    778 		return;
    779 	}
    780 
    781 	/* setup output state */
    782 	lxa_state->lxas_mmap_thread_running = 1;
    783 	lxa_state->lxas_mmap_thread_exit = 0;
    784 	lxa_state->lxas_mmap_thread_frag = 0;
    785 
    786 	/* kick off a thread to do the mmap pcm output */
    787 	lxa_state->lxas_mmap_thread = thread_create(NULL, 0,
    788 	    (void (*)())lxa_mmap_thread, lxa_state,
    789 	    0, &p0, TS_RUN, minclsyspri);
    790 	ASSERT(lxa_state->lxas_mmap_thread != NULL);
    791 
    792 	mutex_exit(&lxa_lock);
    793 }
    794 
    795 static int
    796 lxa_ioc_mmap_output(lxa_state_t *lxa_state, intptr_t arg, int mode)
    797 {
    798 	uint_t	trigger;
    799 
    800 	/* we only support output via mmap */
    801 	if ((lxa_state->lxas_flags & FWRITE) == 0)
    802 		return (EINVAL);
    803 
    804 	/* if the user hasn't mmap the device then there's nothing to do */
    805 	if (lxa_state->lxas_umem_cookie == NULL)
    806 		return (EINVAL);
    807 
    808 	/* copy in the request */
    809 	if (ddi_copyin((void *)arg, &trigger, sizeof (trigger), mode) != 0)
    810 		return (EFAULT);
    811 
    812 	/* a zero value disables output */
    813 	if (trigger == 0) {
    814 		lxa_mmap_output_disable(lxa_state);
    815 		return (0);
    816 	}
    817 
    818 	/* a non-zero value enables output */
    819 	lxa_mmap_output_enable(lxa_state);
    820 	return (0);
    821 }
    822 
    823 static int
    824 lxa_ioc_mmap_ptr(lxa_state_t *lxa_state, intptr_t arg, int mode)
    825 {
    826 	int	ptr;
    827 
    828 	/* we only support output via mmap */
    829 	if ((lxa_state->lxas_flags & FWRITE) == 0)
    830 		return (EINVAL);
    831 
    832 	/* if the user hasn't mmap the device then there's nothing to do */
    833 	if (lxa_state->lxas_umem_cookie == NULL)
    834 		return (EINVAL);
    835 
    836 	/* if the output thread isn't running then there's nothing to do */
    837 	if (lxa_state->lxas_mmap_thread_running == 0)
    838 		return (EINVAL);
    839 
    840 	mutex_enter(&lxa_lock);
    841 	ptr = lxa_state->lxas_mmap_thread_frag * lxa_state->lxas_frag_size;
    842 	mutex_exit(&lxa_lock);
    843 
    844 	if (ddi_copyout(&ptr, (void *)arg, sizeof (ptr), mode) != 0)
    845 		return (EFAULT);
    846 
    847 	return (0);
    848 }
    849 
    850 static int
    851 lxa_ioc_get_frag_info(lxa_state_t *lxa_state, intptr_t arg, int mode)
    852 {
    853 	lxa_frag_info_t	fi;
    854 
    855 	fi.lxa_fi_size = lxa_state->lxas_frag_size;
    856 	fi.lxa_fi_cnt = lxa_state->lxas_frag_cnt;
    857 
    858 	if (ddi_copyout(&fi, (void *)arg, sizeof (fi), mode) != 0)
    859 		return (EFAULT);
    860 
    861 	return (0);
    862 }
    863 
    864 static int
    865 lxa_ioc_set_frag_info(lxa_state_t *lxa_state, intptr_t arg, int mode)
    866 {
    867 	lxa_frag_info_t	fi;
    868 
    869 	/* if the device is mmaped we can't change the fragment settings */
    870 	if (lxa_state->lxas_umem_cookie != NULL)
    871 		return (EINVAL);
    872 
    873 	/* copy in the request */
    874 	if (ddi_copyin((void *)arg, &fi, sizeof (fi), mode) != 0)
    875 		return (EFAULT);
    876 
    877 	/* do basic bounds checking */
    878 	if ((fi.lxa_fi_cnt == 0) || (fi.lxa_fi_size < 16))
    879 		return (EINVAL);
    880 
    881 	/* don't accept size values less than 16 */
    882 
    883 	lxa_state->lxas_frag_size = fi.lxa_fi_size;
    884 	lxa_state->lxas_frag_cnt = fi.lxa_fi_cnt;
    885 
    886 	return (0);
    887 }
    888 
    889 static int
    890 lxa_audio_drain(lxa_state_t *lxa_state)
    891 {
    892 	int	junk;
    893 
    894 	/* only applies to output buffers */
    895 	if (lxa_state->lxas_odev_lh == NULL)
    896 		return (EINVAL);
    897 
    898 	/* can't fail so ignore the return value */
    899 	(void) ldi_ioctl(lxa_state->lxas_odev_lh, AUDIO_DRAIN, NULL,
    900 	    FKIOCTL, kcred, &junk);
    901 	return (0);
    902 }
    903 
    904 /*
    905  * lxa_audio_info_merge() usage notes:
    906  *
    907  * - it's important to make sure NOT to get the ai_idev and ai_odev
    908  *   parameters mixed up when calling lxa_audio_info_merge().
    909  *
    910  * - it's important for the caller to make sure that AUDIO_GETINFO
    911  *   was called for the input device BEFORE the output device.  (see
    912  *   the comments for merging the monitor_gain setting to see why.)
    913  */
    914 static void
    915 lxa_audio_info_merge(lxa_state_t *lxa_state,
    916     audio_info_t *ai_idev, audio_info_t *ai_odev, audio_info_t *ai_merged)
    917 {
    918 	/* if we're not setup for output return the intput device info */
    919 	if (lxa_state->lxas_odev_lh == NULL) {
    920 		*ai_merged = *ai_idev;
    921 		return;
    922 	}
    923 
    924 	/* if we're not setup for input return the output device info */
    925 	if (lxa_state->lxas_idev_lh == NULL) {
    926 		*ai_merged = *ai_odev;
    927 		return;
    928 	}
    929 
    930 	/* get record values from the input device */
    931 	ai_merged->record = ai_idev->record;
    932 
    933 	/* get play values from the output device */
    934 	ai_merged->play = ai_odev->play;
    935 
    936 	/* muting status only matters for the output device */
    937 	ai_merged->output_muted = ai_odev->output_muted;
    938 
    939 	/* we don't support device reference counts, always return 1 */
    940 	ai_merged->ref_cnt = 1;
    941 
    942 	/*
    943 	 * for supported hw/sw features report the combined feature
    944 	 * set we calcuated out earlier.
    945 	 */
    946 	ai_merged->hw_features = lxa_state->lxas_hw_features;
    947 	ai_merged->sw_features = lxa_state->lxas_sw_features;
    948 
    949 	if (!lxa_state->lxas_devs_same) {
    950 		/*
    951 		 * if the input and output devices are different
    952 		 * physical devices then we don't support input to
    953 		 * output loopback so we always report the input
    954 		 * to output loopback gain to be zero.
    955 		 */
    956 		ai_merged->monitor_gain = 0;
    957 	} else {
    958 		/*
    959 		 * the intput and output devices are actually the
    960 		 * same physical device.  hence it probably supports
    961 		 * intput to output loopback.  regardless we should
    962 		 * pass back the intput to output gain reported by
    963 		 * the device.  when we pick a value to passback we
    964 		 * use the output device value since that was
    965 		 * the most recently queried.  (we base this
    966 		 * decision on the assumption that io gain is
    967 		 * actually hardware setting in the device and
    968 		 * hence if it is changed on one open instance of
    969 		 * the device the change will be visable to all
    970 		 * other instances of the device.)
    971 		 */
    972 		ai_merged->monitor_gain = ai_odev->monitor_gain;
    973 	}
    974 
    975 	/*
    976 	 * for currently enabled software features always return the
    977 	 * merger of the two.  (of course the enabled software features
    978 	 * for the input and output devices should alway be the same,
    979 	 * so if it isn't complain.)
    980 	 */
    981 	if (ai_idev->sw_features_enabled != ai_odev->sw_features_enabled)
    982 		zcmn_err(getzoneid(), CE_WARN, "lx_audio: "
    983 		    "unexpected sofware feature state");
    984 	ai_merged->sw_features_enabled =
    985 	    ai_idev->sw_features_enabled & ai_odev->sw_features_enabled;
    986 }
    987 
    988 static int
    989 lxa_audio_setinfo(lxa_state_t *lxa_state, int cmd, intptr_t arg,
    990     int mode)
    991 {
    992 	audio_info_t	ai, ai_null, ai_idev, ai_odev;
    993 	int		rv, junk;
    994 
    995 	/* copy in the request */
    996 	if (ddi_copyin((void *)arg, &ai, sizeof (ai), mode) != 0)
    997 		return (EFAULT);
    998 
    999 	/*
   1000 	 * if the caller is attempting to enable a software feature that
   1001 	 * we didn't report as supported the return an error
   1002 	 */
   1003 	if ((ai.sw_features_enabled != -1) &&
   1004 	    (ai.sw_features_enabled & ~lxa_state->lxas_sw_features))
   1005 		return (EINVAL);
   1006 
   1007 	/*
   1008 	 * if a process has mmaped this device then we don't allow
   1009 	 * changes to the play.eof field (since mmap output depends
   1010 	 * on this field.
   1011 	 */
   1012 	if ((lxa_state->lxas_umem_cookie != NULL) &&
   1013 	    (ai.play.eof != -1))
   1014 		return (EIO);
   1015 
   1016 	/* initialize the new requests */
   1017 	AUDIO_INITINFO(&ai_null);
   1018 	ai_idev = ai_odev = ai;
   1019 
   1020 	/* remove audio input settings from the output device request */
   1021 	ai_odev.record = ai_null.record;
   1022 
   1023 	/* remove audio output settings from the input device request */
   1024 	ai_idev.play = ai_null.play;
   1025 	ai_idev.output_muted = ai_null.output_muted;
   1026 
   1027 	/* apply settings to the intput device */
   1028 	if ((lxa_state->lxas_idev_lh != NULL) &&
   1029 	    ((rv = ldi_ioctl(lxa_state->lxas_idev_lh, cmd,
   1030 	    (intptr_t)&ai_idev, FKIOCTL, kcred, &junk)) != 0))
   1031 		return (rv);
   1032 
   1033 	/* apply settings to the output device */
   1034 	if ((lxa_state->lxas_odev_lh != NULL) &&
   1035 	    ((rv = ldi_ioctl(lxa_state->lxas_odev_lh, cmd,
   1036 	    (intptr_t)&ai_odev, FKIOCTL, kcred, &junk)) != 0))
   1037 		return (rv);
   1038 
   1039 	/*
   1040 	 * a AUDIO_SETINFO call performs an implicit AUDIO_GETINFO to
   1041 	 * return values (see the coments in audioio.h.) so we need
   1042 	 * to combine the values returned from the input and output
   1043 	 * device back into the users buffer.
   1044 	 */
   1045 	lxa_audio_info_merge(lxa_state, &ai_idev, &ai_odev, &ai);
   1046 
   1047 	/* copyout the results */
   1048 	if (ddi_copyout(&ai, (void *)arg, sizeof (ai), mode) != 0) {
   1049 		return (EFAULT);
   1050 	}
   1051 
   1052 	return (0);
   1053 }
   1054 
   1055 static int
   1056 lxa_audio_getinfo(lxa_state_t *lxa_state, intptr_t arg, int mode)
   1057 {
   1058 	audio_info_t	ai, ai_idev, ai_odev;
   1059 	int		rv, junk;
   1060 
   1061 	/* get the settings from the input device */
   1062 	if ((lxa_state->lxas_idev_lh != NULL) &&
   1063 	    ((rv = ldi_ioctl(lxa_state->lxas_idev_lh, AUDIO_GETINFO,
   1064 	    (intptr_t)&ai_idev, FKIOCTL, kcred, &junk)) != 0))
   1065 		return (rv);
   1066 
   1067 	/* get the settings from the output device */
   1068 	if ((lxa_state->lxas_odev_lh != NULL) &&
   1069 	    ((rv = ldi_ioctl(lxa_state->lxas_odev_lh, AUDIO_GETINFO,
   1070 	    (intptr_t)&ai_odev, FKIOCTL, kcred, &junk)) != 0))
   1071 		return (rv);
   1072 
   1073 	/*
   1074 	 * we need to combine the values returned from the input
   1075 	 * and output device back into a single user buffer.
   1076 	 */
   1077 	lxa_audio_info_merge(lxa_state, &ai_idev, &ai_odev, &ai);
   1078 
   1079 	/* copyout the results */
   1080 	if (ddi_copyout(&ai, (void *)arg, sizeof (ai), mode) != 0)
   1081 		return (EFAULT);
   1082 
   1083 	return (0);
   1084 }
   1085 
   1086 static int
   1087 lxa_mixer_ai_from_lh(ldi_handle_t lh, audio_info_t *ai)
   1088 {
   1089 	int		rv, junk;
   1090 
   1091 	ASSERT((lh != NULL) && (ai != NULL));
   1092 
   1093 	/* get the device state and channel state */
   1094 	rv = ldi_ioctl(lh, AUDIO_GETINFO, (intptr_t)ai, FKIOCTL, kcred, &junk);
   1095 
   1096 	return (rv);
   1097 }
   1098 
   1099 static int
   1100 lxa_mixer_get_ai(lxa_state_t *lxa_state, audio_info_t *ai)
   1101 {
   1102 	audio_info_t	ai_idev, ai_odev;
   1103 	int		rv;
   1104 
   1105 	/* if there is no input device, query the output device */
   1106 	if (lxa_state->lxas_idev_lh == NULL)
   1107 		return (lxa_mixer_ai_from_lh(lxa_state->lxas_odev_lh, ai));
   1108 
   1109 	/* if there is no ouput device, query the intput device */
   1110 	if (lxa_state->lxas_odev_lh == NULL)
   1111 		return (lxa_mixer_ai_from_lh(lxa_state->lxas_idev_lh, ai));
   1112 
   1113 	/*
   1114 	 * now get the audio_info and channel information for the
   1115 	 * underlying output device.
   1116 	 */
   1117 	if ((rv = lxa_mixer_ai_from_lh(lxa_state->lxas_idev_lh,
   1118 	    &ai_idev)) != 0)
   1119 		return (rv);
   1120 	if ((rv = lxa_mixer_ai_from_lh(lxa_state->lxas_odev_lh,
   1121 	    &ai_odev)) != 0)
   1122 		return (rv);
   1123 
   1124 	/* now merge the audio_info structures */
   1125 	lxa_audio_info_merge(lxa_state, &ai_idev, &ai_odev, ai);
   1126 	return (0);
   1127 }
   1128 
   1129 static int
   1130 lxa_mixer_get_common(lxa_state_t *lxa_state, int cmd, intptr_t arg, int mode)
   1131 {
   1132 	lxa_mixer_levels_t	lxa_ml;
   1133 	audio_info_t		ai;
   1134 	int			rv;
   1135 
   1136 	ASSERT(lxa_state->lxas_type == LXA_TYPE_AUDIOCTL);
   1137 
   1138 	if ((rv = lxa_mixer_get_ai(lxa_state, &ai)) != 0)
   1139 		return (rv);
   1140 
   1141 	switch (cmd) {
   1142 	case LXA_IOC_MIXER_GET_VOL:
   1143 		lxa_ml.lxa_ml_gain = ai.play.gain;
   1144 		lxa_ml.lxa_ml_balance = ai.play.balance;
   1145 		break;
   1146 	case LXA_IOC_MIXER_GET_MIC:
   1147 		lxa_ml.lxa_ml_gain = ai.record.gain;
   1148 		lxa_ml.lxa_ml_balance = ai.record.balance;
   1149 		break;
   1150 	}
   1151 
   1152 	if (ddi_copyout(&lxa_ml, (void *)arg, sizeof (lxa_ml), mode) != 0)
   1153 		return (EFAULT);
   1154 	return (0);
   1155 }
   1156 
   1157 static int
   1158 lxa_mixer_set_common(lxa_state_t *lxa_state, int cmd, intptr_t arg, int mode)
   1159 {
   1160 	lxa_mixer_levels_t	lxa_ml;
   1161 	audio_info_t		ai;
   1162 
   1163 	ASSERT(lxa_state->lxas_type == LXA_TYPE_AUDIOCTL);
   1164 
   1165 	/* get the new mixer settings */
   1166 	if (ddi_copyin((void *)arg, &lxa_ml, sizeof (lxa_ml), mode) != 0)
   1167 		return (EFAULT);
   1168 
   1169 	/* sanity check the mixer settings */
   1170 	if (!LXA_MIXER_LEVELS_OK(&lxa_ml))
   1171 		return (EINVAL);
   1172 
   1173 	/* initialize an audio_info struct with the new settings */
   1174 	AUDIO_INITINFO(&ai);
   1175 	switch (cmd) {
   1176 	case LXA_IOC_MIXER_SET_VOL:
   1177 		ai.play.gain = lxa_ml.lxa_ml_gain;
   1178 		ai.play.balance = lxa_ml.lxa_ml_balance;
   1179 		break;
   1180 	case LXA_IOC_MIXER_SET_MIC:
   1181 		ai.record.gain = lxa_ml.lxa_ml_gain;
   1182 		ai.record.balance = lxa_ml.lxa_ml_balance;
   1183 		break;
   1184 	}
   1185 
   1186 	return (lxa_audio_setinfo(lxa_state, AUDIO_SETINFO, (intptr_t)&ai,
   1187 	    FKIOCTL));
   1188 }
   1189 
   1190 static int
   1191 lxa_mixer_get_pcm(lxa_state_t *lxa_state, intptr_t arg, int mode)
   1192 {
   1193 	ASSERT(lxa_state->lxas_type == LXA_TYPE_AUDIOCTL);
   1194 
   1195 	/* simply return the cached pcm mixer settings */
   1196 	mutex_enter(&lxa_lock);
   1197 	if (ddi_copyout(&lxa_state->lxas_zs->lxa_zs_pcm_levels, (void *)arg,
   1198 	    sizeof (lxa_state->lxas_zs->lxa_zs_pcm_levels), mode) != 0) {
   1199 		mutex_exit(&lxa_lock);
   1200 		return (EFAULT);
   1201 	}
   1202 	mutex_exit(&lxa_lock);
   1203 	return (0);
   1204 }
   1205 
   1206 static int
   1207 lxa_mixer_set_pcm(lxa_state_t *lxa_state, intptr_t arg, int mode)
   1208 {
   1209 	lxa_mixer_levels_t	lxa_ml;
   1210 	int			rv;
   1211 
   1212 	ASSERT(lxa_state->lxas_type == LXA_TYPE_AUDIOCTL);
   1213 
   1214 	/* get the new mixer settings */
   1215 	if (ddi_copyin((void *)arg, &lxa_ml, sizeof (lxa_ml), mode) != 0)
   1216 		return (EFAULT);
   1217 
   1218 	/* sanity check the mixer settings */
   1219 	if (!LXA_MIXER_LEVELS_OK(&lxa_ml))
   1220 		return (EINVAL);
   1221 
   1222 	mutex_enter(&lxa_lock);
   1223 
   1224 	/* if there is an active output channel, update it */
   1225 	if (lxa_state->lxas_zs->lxa_zs_ostate != NULL) {
   1226 		audio_info_t	ai;
   1227 
   1228 		/* initialize an audio_info struct with the new settings */
   1229 		AUDIO_INITINFO(&ai);
   1230 		ai.play.gain = lxa_ml.lxa_ml_gain;
   1231 		ai.play.balance = lxa_ml.lxa_ml_balance;
   1232 
   1233 		if ((rv = lxa_audio_setinfo(lxa_state->lxas_zs->lxa_zs_ostate,
   1234 		    AUDIO_SETINFO, (intptr_t)&ai, FKIOCTL)) != 0) {
   1235 			mutex_exit(&lxa_lock);
   1236 			return (rv);
   1237 		}
   1238 	}
   1239 
   1240 	/* update the cached mixer settings */
   1241 	lxa_state->lxas_zs->lxa_zs_pcm_levels = lxa_ml;
   1242 
   1243 	mutex_exit(&lxa_lock);
   1244 	return (0);
   1245 }
   1246 
   1247 static int
   1248 lxa_zone_reg(intptr_t arg, int mode)
   1249 {
   1250 	lxa_zone_reg_t	lxa_zr;
   1251 	lxa_zstate_t	*lxa_zs = NULL;
   1252 	char		*idev_name = NULL, *odev_name = NULL, *pval = NULL;
   1253 	int		i, junk;
   1254 
   1255 	if (ddi_copyin((void *)arg, &lxa_zr, sizeof (lxa_zr), mode) != 0)
   1256 		return (EFAULT);
   1257 
   1258 	/* make sure that zone_name is a valid string */
   1259 	for (i = 0; i < sizeof (lxa_zr.lxa_zr_zone_name); i++)
   1260 		if (lxa_zr.lxa_zr_zone_name[i] == '\0')
   1261 			break;
   1262 	if (i == sizeof (lxa_zr.lxa_zr_zone_name))
   1263 		return (EINVAL);
   1264 
   1265 	/* make sure that inputdev is a valid string */
   1266 	for (i = 0; i < sizeof (lxa_zr.lxa_zr_inputdev); i++)
   1267 		if (lxa_zr.lxa_zr_inputdev[i] == '\0')
   1268 			break;
   1269 	if (i == sizeof (lxa_zr.lxa_zr_inputdev))
   1270 		return (EINVAL);
   1271 
   1272 	/* make sure it's a valid inputdev property value */
   1273 	if (lxa_devprop_verify(lxa_zr.lxa_zr_inputdev) != 0)
   1274 		return (EINVAL);
   1275 
   1276 	/* make sure that outputdev is a valid string */
   1277 	for (i = 0; i < sizeof (lxa_zr.lxa_zr_outputdev); i++)
   1278 		if (lxa_zr.lxa_zr_outputdev[i] == '\0')
   1279 			break;
   1280 	if (i == sizeof (lxa_zr.lxa_zr_outputdev))
   1281 		return (EINVAL);
   1282 
   1283 	/* make sure it's a valid outputdev property value */
   1284 	if (lxa_devprop_verify(lxa_zr.lxa_zr_outputdev) != 0)
   1285 		return (EINVAL);
   1286 
   1287 	/* get the property names */
   1288 	idev_name = lxa_devprop_name(lxa_zr.lxa_zr_zone_name,
   1289 	    LXA_PROP_INPUTDEV);
   1290 	odev_name = lxa_devprop_name(lxa_zr.lxa_zr_zone_name,
   1291 	    LXA_PROP_OUTPUTDEV);
   1292 
   1293 	/*
   1294 	 * allocate and initialize a zone state structure
   1295 	 * since the audio device can't possibly be opened yet
   1296 	 * (since we're setting it up now and the zone isn't booted
   1297 	 * yet) assign some some resonable default pcm channel settings.
   1298 	 * also, default to one mixer channel.
   1299 	 */
   1300 	lxa_zs = kmem_zalloc(sizeof (*lxa_zs), KM_SLEEP);
   1301 	lxa_zs->lxa_zs_zonename = strdup(lxa_zr.lxa_zr_zone_name);
   1302 	lxa_zs->lxa_zs_pcm_levels.lxa_ml_gain = AUDIO_MID_GAIN;
   1303 	lxa_zs->lxa_zs_pcm_levels.lxa_ml_balance = AUDIO_MID_BALANCE;
   1304 
   1305 	mutex_enter(&lxa_lock);
   1306 
   1307 	/*
   1308 	 * make sure this zone isn't already registered
   1309 	 * a zone is registered with properties for that zone exist
   1310 	 * or there is a zone state structure for that zone
   1311 	 */
   1312 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lxa_dip,
   1313 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
   1314 	    idev_name, &pval) == DDI_PROP_SUCCESS) {
   1315 		goto err_unlock;
   1316 	}
   1317 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lxa_dip,
   1318 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
   1319 	    odev_name, &pval) == DDI_PROP_SUCCESS) {
   1320 		goto err_unlock;
   1321 	}
   1322 	if (mod_hash_find(lxa_zstate_hash,
   1323 	    (mod_hash_key_t)lxa_zs->lxa_zs_zonename,
   1324 	    (mod_hash_val_t *)&junk) == 0)
   1325 		goto err_unlock;
   1326 
   1327 	/*
   1328 	 * create the new properties and insert the zone state structure
   1329 	 * into the global hash
   1330 	 */
   1331 	if (ddi_prop_update_string(DDI_DEV_T_NONE, lxa_dip,
   1332 	    idev_name, lxa_zr.lxa_zr_inputdev) != DDI_PROP_SUCCESS)
   1333 		goto err_prop_remove;
   1334 	if (ddi_prop_update_string(DDI_DEV_T_NONE, lxa_dip,
   1335 	    odev_name, lxa_zr.lxa_zr_outputdev) != DDI_PROP_SUCCESS)
   1336 		goto err_prop_remove;
   1337 	if (mod_hash_insert(lxa_zstate_hash,
   1338 	    (mod_hash_key_t)lxa_zs->lxa_zs_zonename,
   1339 	    (mod_hash_val_t)lxa_zs) != 0)
   1340 		goto err_prop_remove;
   1341 
   1342 	/* success! */
   1343 	lxa_registered_zones++;
   1344 	mutex_exit(&lxa_lock);
   1345 
   1346 	/* cleanup */
   1347 	strfree(idev_name);
   1348 	strfree(odev_name);
   1349 	return (0);
   1350 
   1351 err_prop_remove:
   1352 	(void) ddi_prop_remove(DDI_DEV_T_NONE, lxa_dip, idev_name);
   1353 	(void) ddi_prop_remove(DDI_DEV_T_NONE, lxa_dip, odev_name);
   1354 
   1355 err_unlock:
   1356 	mutex_exit(&lxa_lock);
   1357 
   1358 err:
   1359 	if (lxa_zs != NULL) {
   1360 		strfree(lxa_zs->lxa_zs_zonename);
   1361 		kmem_free(lxa_zs, sizeof (*lxa_zs));
   1362 	}
   1363 	if (pval != NULL)
   1364 		ddi_prop_free(pval);
   1365 	if (idev_name != NULL)
   1366 		strfree(idev_name);
   1367 	if (odev_name != NULL)
   1368 		strfree(odev_name);
   1369 	return (EIO);
   1370 }
   1371 
   1372 static int
   1373 lxa_zone_unreg(intptr_t arg, int mode)
   1374 {
   1375 	lxa_zone_reg_t	lxa_zr;
   1376 	lxa_zstate_t	*lxa_zs = NULL;
   1377 	char		*idev_name = NULL, *odev_name = NULL, *pval = NULL;
   1378 	int		rv, i;
   1379 
   1380 	if (ddi_copyin((void *)arg, &lxa_zr, sizeof (lxa_zr), mode) != 0)
   1381 		return (EFAULT);
   1382 
   1383 	/* make sure that zone_name is a valid string */
   1384 	for (i = 0; i < sizeof (lxa_zr.lxa_zr_zone_name); i++)
   1385 		if (lxa_zr.lxa_zr_zone_name[i] == '\0')
   1386 			break;
   1387 	if (i == sizeof (lxa_zr.lxa_zr_zone_name))
   1388 		return (EINVAL);
   1389 
   1390 	/* get the property names */
   1391 	idev_name = lxa_devprop_name(lxa_zr.lxa_zr_zone_name,
   1392 	    LXA_PROP_INPUTDEV);
   1393 	odev_name = lxa_devprop_name(lxa_zr.lxa_zr_zone_name,
   1394 	    LXA_PROP_OUTPUTDEV);
   1395 
   1396 	mutex_enter(&lxa_lock);
   1397 
   1398 	if (lxa_registered_zones <= 0) {
   1399 		rv = ENOENT;
   1400 		goto err_unlock;
   1401 	}
   1402 
   1403 	/* make sure this zone is actually registered */
   1404 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lxa_dip,
   1405 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
   1406 	    idev_name, &pval) != DDI_PROP_SUCCESS) {
   1407 		rv = ENOENT;
   1408 		goto err_unlock;
   1409 	}
   1410 	ddi_prop_free(pval);
   1411 	pval = NULL;
   1412 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lxa_dip,
   1413 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
   1414 	    odev_name, &pval) != DDI_PROP_SUCCESS) {
   1415 		rv = ENOENT;
   1416 		goto err_unlock;
   1417 	}
   1418 	ddi_prop_free(pval);
   1419 	pval = NULL;
   1420 	if (mod_hash_find(lxa_zstate_hash,
   1421 	    (mod_hash_key_t)lxa_zr.lxa_zr_zone_name,
   1422 	    (mod_hash_val_t *)&lxa_zs) != 0) {
   1423 		rv = ENOENT;
   1424 		goto err_unlock;
   1425 	}
   1426 	ASSERT(strcmp(lxa_zr.lxa_zr_zone_name, lxa_zs->lxa_zs_zonename) == 0);
   1427 
   1428 	/*
   1429 	 * if the audio device is currently in use then refuse to
   1430 	 * unregister the zone
   1431 	 */
   1432 	if ((lxa_zs->lxa_zs_ostate != NULL) ||
   1433 	    (lxa_zs->lxa_zs_ostate != NULL)) {
   1434 		rv = EBUSY;
   1435 		goto err_unlock;
   1436 	}
   1437 
   1438 	/* success! cleanup zone config state */
   1439 	(void) ddi_prop_remove(DDI_DEV_T_NONE, lxa_dip, idev_name);
   1440 	(void) ddi_prop_remove(DDI_DEV_T_NONE, lxa_dip, odev_name);
   1441 
   1442 	/*
   1443 	 * note, the action of removing the zone state structure from the
   1444 	 * hash will automatically free lxa_zs->lxa_zs_zonename.
   1445 	 *
   1446 	 * the reason for this is that we used lxa_zs->lxa_zs_zonename
   1447 	 * as the hash key and by default mod_hash_create_strhash() uses
   1448 	 * mod_hash_strkey_dtor() as a the hash key destructor.  (which
   1449 	 * free's the key for us.
   1450 	 */
   1451 	(void) mod_hash_remove(lxa_zstate_hash,
   1452 	    (mod_hash_key_t)lxa_zr.lxa_zr_zone_name,
   1453 	    (mod_hash_val_t *)&lxa_zs);
   1454 	lxa_registered_zones--;
   1455 	mutex_exit(&lxa_lock);
   1456 
   1457 	/* cleanup */
   1458 	kmem_free(lxa_zs, sizeof (*lxa_zs));
   1459 	strfree(idev_name);
   1460 	strfree(odev_name);
   1461 	return (0);
   1462 
   1463 err_unlock:
   1464 	mutex_exit(&lxa_lock);
   1465 
   1466 err:
   1467 	if (pval != NULL)
   1468 		ddi_prop_free(pval);
   1469 	if (idev_name != NULL)
   1470 		strfree(idev_name);
   1471 	if (odev_name != NULL)
   1472 		strfree(odev_name);
   1473 	return (rv);
   1474 }
   1475 
   1476 static int
   1477 lxa_ioctl_devctl(int cmd, intptr_t arg, int mode)
   1478 {
   1479 	/* devctl ioctls are only allowed from the global zone */
   1480 	ASSERT(getzoneid() == 0);
   1481 	if (getzoneid() != 0)
   1482 		return (EINVAL);
   1483 
   1484 	switch (cmd) {
   1485 	case LXA_IOC_ZONE_REG:
   1486 		return (lxa_zone_reg(arg, mode));
   1487 	case LXA_IOC_ZONE_UNREG:
   1488 		return (lxa_zone_unreg(arg, mode));
   1489 	}
   1490 
   1491 	return (EINVAL);
   1492 }
   1493 
   1494 static int
   1495 /*ARGSUSED*/
   1496 lxa_open(dev_t *devp, int flags, int otyp, cred_t *credp)
   1497 {
   1498 	lxa_dev_type_t	open_type = LXA_TYPE_INVALID;
   1499 	lxa_zstate_t	*lxa_zs;
   1500 	lxa_state_t	*lxa_state;
   1501 	minor_t		minor;
   1502 	int		rv;
   1503 
   1504 	if (getminor(*devp) == LXA_MINORNUM_DEVCTL) {
   1505 		/*
   1506 		 * this is a devctl node, it exists to administer this
   1507 		 * pseudo driver so it doesn't actually need access to
   1508 		 * any underlying audio devices.  hence there is nothing
   1509 		 * really to do here.  course, this driver should
   1510 		 * only be administered from the global zone.
   1511 		 */
   1512 		ASSERT(getzoneid() == 0);
   1513 		if (getzoneid() != 0)
   1514 			return (EINVAL);
   1515 		return (0);
   1516 	}
   1517 
   1518 	/* lookup the zone state structure */
   1519 	if (mod_hash_find(lxa_zstate_hash, (mod_hash_key_t)getzonename(),
   1520 	    (mod_hash_val_t *)&lxa_zs) != 0) {
   1521 		return (EIO);
   1522 	}
   1523 
   1524 	/* determine what type of device was opened */
   1525 	switch (getminor(*devp)) {
   1526 	case LXA_MINORNUM_DSP:
   1527 		open_type = LXA_TYPE_AUDIO;
   1528 		break;
   1529 	case LXA_MINORNUM_MIXER:
   1530 		open_type = LXA_TYPE_AUDIOCTL;
   1531 		break;
   1532 	default:
   1533 		return (EINVAL);
   1534 	}
   1535 	ASSERT(open_type != LXA_TYPE_INVALID);
   1536 
   1537 	/* all other opens are clone opens so get a new minor node */
   1538 	minor = id_alloc(lxa_minor_id);
   1539 
   1540 	/* allocate and initialize the new lxa_state structure */
   1541 	lxa_state = kmem_zalloc(sizeof (*lxa_state), KM_SLEEP);
   1542 	lxa_state->lxas_zs = lxa_zs;
   1543 	lxa_state->lxas_dev_old = *devp;
   1544 	lxa_state->lxas_dev_new = makedevice(getmajor(*devp), minor);
   1545 	lxa_state->lxas_flags = flags;
   1546 	lxa_state->lxas_type = open_type;
   1547 
   1548 	/* initialize the input and output device */
   1549 	if (((rv = lxa_dev_open(lxa_state)) != 0) ||
   1550 	    ((rv = lxa_dev_getfeatures(lxa_state)) != 0)) {
   1551 		lxa_state_close(lxa_state);
   1552 		return (rv);
   1553 	}
   1554 
   1555 	/*
   1556 	 * save this audio statue structure into a hash indexed
   1557 	 * by it's minor device number.  (this will provide a convient
   1558 	 * way to lookup the state structure on future operations.)
   1559 	 */
   1560 	if (mod_hash_insert(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
   1561 	    (mod_hash_val_t)lxa_state) != 0) {
   1562 		lxa_state_close(lxa_state);
   1563 		return (EIO);
   1564 	}
   1565 
   1566 	mutex_enter(&lxa_lock);
   1567 
   1568 	/* apply the currently cached zone PCM mixer levels */
   1569 	if ((lxa_state->lxas_type == LXA_TYPE_AUDIO) &&
   1570 	    (lxa_state->lxas_odev_lh != NULL)) {
   1571 		audio_info_t ai;
   1572 
   1573 		AUDIO_INITINFO(&ai);
   1574 		ai.play.gain = lxa_zs->lxa_zs_pcm_levels.lxa_ml_gain;
   1575 		ai.play.balance = lxa_zs->lxa_zs_pcm_levels.lxa_ml_balance;
   1576 
   1577 		if ((rv = lxa_audio_setinfo(lxa_state,
   1578 		    AUDIO_SETINFO, (intptr_t)&ai, FKIOCTL)) != 0) {
   1579 			mutex_exit(&lxa_lock);
   1580 			lxa_state_close(lxa_state);
   1581 			return (rv);
   1582 		}
   1583 	}
   1584 
   1585 	/*
   1586 	 * we only allow one active open of the input or output device.
   1587 	 * check here for duplicate opens
   1588 	 */
   1589 	if (lxa_state->lxas_type == LXA_TYPE_AUDIO) {
   1590 		if ((lxa_state->lxas_idev_lh != NULL) &&
   1591 		    (lxa_zs->lxa_zs_istate != NULL)) {
   1592 			mutex_exit(&lxa_lock);
   1593 			lxa_state_close(lxa_state);
   1594 			return (EBUSY);
   1595 		}
   1596 		if ((lxa_state->lxas_odev_lh != NULL) &&
   1597 		    (lxa_zs->lxa_zs_ostate != NULL)) {
   1598 			mutex_exit(&lxa_lock);
   1599 			lxa_state_close(lxa_state);
   1600 			return (EBUSY);
   1601 		}
   1602 
   1603 		/* not a duplicate open, update the global zone state */
   1604 		if (lxa_state->lxas_idev_lh != NULL)
   1605 			lxa_zs->lxa_zs_istate = lxa_state;
   1606 		if (lxa_state->lxas_odev_lh != NULL)
   1607 			lxa_zs->lxa_zs_ostate = lxa_state;
   1608 	}
   1609 	mutex_exit(&lxa_lock);
   1610 
   1611 	/* make sure to return our newly allocated dev_t */
   1612 	*devp = lxa_state->lxas_dev_new;
   1613 	return (0);
   1614 }
   1615 
   1616 static int
   1617 /*ARGSUSED*/
   1618 lxa_close(dev_t dev, int flags, int otyp, cred_t *credp)
   1619 {
   1620 	lxa_state_t	*lxa_state;
   1621 	minor_t		minor = getminor(dev);
   1622 
   1623 	/* handle devctl minor nodes (these nodes don't have a handle */
   1624 	if (getminor(dev) == LXA_MINORNUM_DEVCTL)
   1625 		return (0);
   1626 
   1627 	/* get the handle for this device */
   1628 	if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
   1629 	    (mod_hash_val_t *)&lxa_state) != 0)
   1630 		return (EINVAL);
   1631 
   1632 	lxa_state_close(lxa_state);
   1633 	return (0);
   1634 }
   1635 
   1636 static int
   1637 /*ARGSUSED*/
   1638 lxa_read(dev_t dev, struct uio *uiop, cred_t *credp)
   1639 {
   1640 	lxa_state_t	*lxa_state;
   1641 	minor_t		minor = getminor(dev);
   1642 	int		rv;
   1643 
   1644 	/* get the handle for this device */
   1645 	if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
   1646 	    (mod_hash_val_t *)&lxa_state) != 0)
   1647 		return (EINVAL);
   1648 
   1649 	/*
   1650 	 * if a process has mmaped this device then we don't allow
   1651 	 * any more reads or writes to the device
   1652 	 */
   1653 	if (lxa_state->lxas_umem_cookie != NULL)
   1654 		return (EIO);
   1655 
   1656 	/* we can't do a read if there is no input device */
   1657 	if (lxa_state->lxas_idev_lh == NULL)
   1658 		return (EBADF);
   1659 
   1660 	/* pass the request on */
   1661 	while (uiop->uio_resid != 0) {
   1662 		rv = ldi_read(lxa_state->lxas_idev_lh, uiop, kcred);
   1663 		if ((rv != 0) || (uiop->uio_fmode & (FNONBLOCK|FNDELAY))) {
   1664 			break;
   1665 		}
   1666 	}
   1667 	return (rv);
   1668 }
   1669 
   1670 static int
   1671 /*ARGSUSED*/
   1672 lxa_write(dev_t dev, struct uio *uiop, cred_t *credp)
   1673 {
   1674 	lxa_state_t	*lxa_state;
   1675 	minor_t		minor = getminor(dev);
   1676 	int		rv;
   1677 
   1678 	/* get the handle for this device */
   1679 	if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
   1680 	    (mod_hash_val_t *)&lxa_state) != 0)
   1681 		return (EINVAL);
   1682 
   1683 	/*
   1684 	 * if a process has mmaped this device then we don't allow
   1685 	 * any more reads or writes to the device
   1686 	 */
   1687 	if (lxa_state->lxas_umem_cookie != NULL)
   1688 		return (EIO);
   1689 
   1690 	/* we can't do a write if there is no output device */
   1691 	if (lxa_state->lxas_odev_lh == NULL)
   1692 		return (EBADF);
   1693 
   1694 	/* pass the request on */
   1695 	while (uiop->uio_resid != 0) {
   1696 		rv = ldi_write(lxa_state->lxas_odev_lh, uiop, kcred);
   1697 		if ((rv != 0) || (uiop->uio_fmode & (FNONBLOCK|FNDELAY))) {
   1698 			break;
   1699 		}
   1700 	}
   1701 	return (rv);
   1702 }
   1703 
   1704 static int
   1705 /*ARGSUSED*/
   1706 lxa_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
   1707     int *rvalp)
   1708 {
   1709 	lxa_state_t	*lxa_state;
   1710 	minor_t		minor = getminor(dev);
   1711 
   1712 	/* handle devctl minor nodes (these nodes don't have a handle */
   1713 	if (getminor(dev) == LXA_MINORNUM_DEVCTL)
   1714 		return (lxa_ioctl_devctl(cmd, arg, mode));
   1715 
   1716 	/* get the handle for this device */
   1717 	if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
   1718 	    (mod_hash_val_t *)&lxa_state) != 0)
   1719 		return (EINVAL);
   1720 
   1721 	ASSERT((lxa_state->lxas_type == LXA_TYPE_AUDIO) ||
   1722 	    (lxa_state->lxas_type == LXA_TYPE_AUDIOCTL));
   1723 
   1724 	switch (cmd) {
   1725 	case LXA_IOC_GETMINORNUM:
   1726 		{
   1727 			int minornum = getminor(lxa_state->lxas_dev_old);
   1728 			if (ddi_copyout(&minornum, (void *)arg,
   1729 			    sizeof (minornum), mode) != 0)
   1730 				return (EFAULT);
   1731 		}
   1732 		return (0);
   1733 	}
   1734 
   1735 	if (lxa_state->lxas_type == LXA_TYPE_AUDIO) {
   1736 		/* deal with native ioctl */
   1737 		switch (cmd) {
   1738 		case LXA_IOC_MMAP_OUTPUT:
   1739 			return (lxa_ioc_mmap_output(lxa_state, arg, mode));
   1740 		case LXA_IOC_MMAP_PTR:
   1741 			return (lxa_ioc_mmap_ptr(lxa_state, arg, mode));
   1742 		case LXA_IOC_GET_FRAG_INFO:
   1743 			return (lxa_ioc_get_frag_info(lxa_state, arg, mode));
   1744 		case LXA_IOC_SET_FRAG_INFO:
   1745 			return (lxa_ioc_set_frag_info(lxa_state, arg, mode));
   1746 		}
   1747 
   1748 		/* deal with layered ioctls */
   1749 		switch (cmd) {
   1750 		case AUDIO_DRAIN:
   1751 			return (lxa_audio_drain(lxa_state));
   1752 		case AUDIO_SETINFO:
   1753 			return (lxa_audio_setinfo(lxa_state,
   1754 			    AUDIO_SETINFO, arg, mode));
   1755 		case AUDIO_GETINFO:
   1756 			return (lxa_audio_getinfo(lxa_state, arg, mode));
   1757 		}
   1758 	}
   1759 
   1760 	if (lxa_state->lxas_type == LXA_TYPE_AUDIOCTL) {
   1761 		/* deal with native ioctl */
   1762 		switch (cmd) {
   1763 		case LXA_IOC_MIXER_GET_VOL:
   1764 			return (lxa_mixer_get_common(lxa_state,
   1765 			    cmd, arg, mode));
   1766 		case LXA_IOC_MIXER_SET_VOL:
   1767 			return (lxa_mixer_set_common(lxa_state,
   1768 			    cmd, arg, mode));
   1769 		case LXA_IOC_MIXER_GET_MIC:
   1770 			return (lxa_mixer_get_common(lxa_state,
   1771 			    cmd, arg, mode));
   1772 		case LXA_IOC_MIXER_SET_MIC:
   1773 			return (lxa_mixer_set_common(lxa_state,
   1774 			    cmd, arg, mode));
   1775 		case LXA_IOC_MIXER_GET_PCM:
   1776 			return (lxa_mixer_get_pcm(lxa_state, arg, mode));
   1777 		case LXA_IOC_MIXER_SET_PCM:
   1778 			return (lxa_mixer_set_pcm(lxa_state, arg, mode));
   1779 		}
   1780 
   1781 	}
   1782 
   1783 	return (EINVAL);
   1784 }
   1785 
   1786 static int
   1787 /*ARGSUSED*/
   1788 lxa_devmap(dev_t dev, devmap_cookie_t dhp,
   1789     offset_t off, size_t len, size_t *maplen, uint_t model)
   1790 {
   1791 	lxa_state_t		*lxa_state;
   1792 	minor_t			minor = getminor(dev);
   1793 	ddi_umem_cookie_t	umem_cookie;
   1794 	void			*umem_ptr;
   1795 	int			rv;
   1796 
   1797 	/* get the handle for this device */
   1798 	if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
   1799 	    (mod_hash_val_t *)&lxa_state) != 0)
   1800 		return (EINVAL);
   1801 
   1802 	/* we only support mmaping of audio devices */
   1803 	if (lxa_state->lxas_type != LXA_TYPE_AUDIO)
   1804 		return (EINVAL);
   1805 
   1806 	/* we only support output via mmap */
   1807 	if ((lxa_state->lxas_flags & FWRITE) == 0)
   1808 		return (EINVAL);
   1809 
   1810 	/* sanity check the amount of memory the user is allocating */
   1811 	if ((len == 0) ||
   1812 	    (len > LXA_OSS_FRAG_MEM) ||
   1813 	    ((len % lxa_state->lxas_frag_size) != 0))
   1814 		return (EINVAL);
   1815 
   1816 	/* allocate and clear memory to mmap */
   1817 	umem_ptr = ddi_umem_alloc(len, DDI_UMEM_NOSLEEP, &umem_cookie);
   1818 	if (umem_ptr == NULL)
   1819 		return (ENOMEM);
   1820 	bzero(umem_ptr, len);
   1821 
   1822 	/* setup the memory mappings */
   1823 	rv = devmap_umem_setup(dhp, lxa_dip, NULL, umem_cookie, 0, len,
   1824 	    PROT_USER | PROT_READ | PROT_WRITE, 0, NULL);
   1825 	if (rv != 0) {
   1826 		ddi_umem_free(umem_cookie);
   1827 		return (EIO);
   1828 	}
   1829 
   1830 	mutex_enter(&lxa_lock);
   1831 
   1832 	/* we only support one mmap per open */
   1833 	if (lxa_state->lxas_umem_cookie != NULL) {
   1834 		ASSERT(lxa_state->lxas_umem_ptr != NULL);
   1835 		mutex_exit(&lxa_lock);
   1836 		ddi_umem_free(umem_cookie);
   1837 		return (EBUSY);
   1838 	}
   1839 	ASSERT(lxa_state->lxas_umem_ptr == NULL);
   1840 
   1841 	*maplen = len;
   1842 	lxa_state->lxas_umem_len = len;
   1843 	lxa_state->lxas_umem_ptr = umem_ptr;
   1844 	lxa_state->lxas_umem_cookie = umem_cookie;
   1845 	mutex_exit(&lxa_lock);
   1846 	return (0);
   1847 }
   1848 
   1849 static int
   1850 /*ARGSUSED*/
   1851 lxa_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
   1852 {
   1853 	int	instance = ddi_get_instance(dip);
   1854 
   1855 	if (cmd != DDI_ATTACH)
   1856 		return (DDI_FAILURE);
   1857 
   1858 	ASSERT(instance == 0);
   1859 	if (instance != 0)
   1860 		return (DDI_FAILURE);
   1861 
   1862 	lxa_dip = dip;
   1863 	mutex_init(&lxa_lock, NULL, MUTEX_DEFAULT, NULL);
   1864 
   1865 	/* create our minor nodes */
   1866 	if (ddi_create_minor_node(dip, LXA_MINORNAME_DEVCTL, S_IFCHR,
   1867 	    LXA_MINORNUM_DEVCTL, DDI_PSEUDO, 0) != DDI_SUCCESS)
   1868 		return (DDI_FAILURE);
   1869 
   1870 	if (ddi_create_minor_node(dip, LXA_MINORNAME_DSP, S_IFCHR,
   1871 	    LXA_MINORNUM_DSP, DDI_PSEUDO, 0) != DDI_SUCCESS)
   1872 		return (DDI_FAILURE);
   1873 
   1874 	if (ddi_create_minor_node(dip, LXA_MINORNAME_MIXER, S_IFCHR,
   1875 	    LXA_MINORNUM_MIXER, DDI_PSEUDO, 0) != DDI_SUCCESS)
   1876 		return (DDI_FAILURE);
   1877 
   1878 	/* allocate our data structures */
   1879 	lxa_minor_id = id_space_create("lxa_minor_id",
   1880 	    LXA_MINORNUM_COUNT, LX_AUDIO_MAX_OPENS);
   1881 	lxa_state_hash = mod_hash_create_idhash("lxa_state_hash",
   1882 	    lxa_state_hash_size, mod_hash_null_valdtor);
   1883 	lxa_zstate_hash = mod_hash_create_strhash("lxa_zstate_hash",
   1884 	    lxa_zstate_hash_size, mod_hash_null_valdtor);
   1885 
   1886 	return (DDI_SUCCESS);
   1887 }
   1888 
   1889 static int
   1890 /*ARGSUSED*/
   1891 lxa_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
   1892 {
   1893 	if (cmd != DDI_DETACH)
   1894 		return (DDI_FAILURE);
   1895 
   1896 	ASSERT(!MUTEX_HELD(&lxa_lock));
   1897 	if (lxa_registered_zones > 0)
   1898 		return (DDI_FAILURE);
   1899 
   1900 	mod_hash_destroy_idhash(lxa_state_hash);
   1901 	mod_hash_destroy_idhash(lxa_zstate_hash);
   1902 	id_space_destroy(lxa_minor_id);
   1903 	lxa_state_hash = NULL;
   1904 	lxa_dip = NULL;
   1905 
   1906 	return (DDI_SUCCESS);
   1907 }
   1908 
   1909 static int
   1910 /*ARGSUSED*/
   1911 lxa_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **resultp)
   1912 {
   1913 	switch (infocmd) {
   1914 	case DDI_INFO_DEVT2DEVINFO:
   1915 		*resultp = lxa_dip;
   1916 		return (DDI_SUCCESS);
   1917 
   1918 	case DDI_INFO_DEVT2INSTANCE:
   1919 		*resultp = (void *)0;
   1920 		return (DDI_SUCCESS);
   1921 	}
   1922 	return (DDI_FAILURE);
   1923 }
   1924 
   1925 /*
   1926  * Driver flags
   1927  */
   1928 static struct cb_ops lxa_cb_ops = {
   1929 	lxa_open,		/* open */
   1930 	lxa_close,		/* close */
   1931 	nodev,			/* strategy */
   1932 	nodev,			/* print */
   1933 	nodev,			/* dump */
   1934 	lxa_read,		/* read */
   1935 	lxa_write,		/* write */
   1936 	lxa_ioctl,		/* ioctl */
   1937 	lxa_devmap,		/* devmap */
   1938 	nodev,			/* mmap */
   1939 	ddi_devmap_segmap,	/* segmap */
   1940 	nochpoll,		/* chpoll */
   1941 	ddi_prop_op,		/* prop_op */
   1942 	NULL,			/* cb_str */
   1943 	D_NEW | D_MP | D_DEVMAP,
   1944 	CB_REV,
   1945 	NULL,
   1946 	NULL
   1947 };
   1948 
   1949 static struct dev_ops lxa_ops = {
   1950 	DEVO_REV,
   1951 	0,
   1952 	lxa_getinfo,
   1953 	nulldev,
   1954 	nulldev,
   1955 	lxa_attach,
   1956 	lxa_detach,
   1957 	nodev,
   1958 	&lxa_cb_ops,
   1959 	NULL,
   1960 	NULL,
   1961 	ddi_quiesce_not_needed,		/* quiesce */
   1962 };
   1963 
   1964 /*
   1965  * Module linkage information for the kernel.
   1966  */
   1967 static struct modldrv modldrv = {
   1968 	&mod_driverops,		/* type of module */
   1969 	"linux audio driver",	/* description of module */
   1970 	&lxa_ops		/* driver ops */
   1971 };
   1972 
   1973 static struct modlinkage modlinkage = {
   1974 	MODREV_1,
   1975 	&modldrv,
   1976 	NULL
   1977 };
   1978 
   1979 /*
   1980  * standard module entry points
   1981  */
   1982 int
   1983 _init(void)
   1984 {
   1985 	return (mod_install(&modlinkage));
   1986 }
   1987 
   1988 int
   1989 _fini(void)
   1990 {
   1991 	return (mod_remove(&modlinkage));
   1992 }
   1993 
   1994 int
   1995 _info(struct modinfo *modinfop)
   1996 {
   1997 	return (mod_info(&modlinkage, modinfop));
   1998 }
   1999