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 if (lxa_zs != NULL) {
1359 strfree(lxa_zs->lxa_zs_zonename);
1360 kmem_free(lxa_zs, sizeof (*lxa_zs));
1361 }
1362 if (pval != NULL)
1363 ddi_prop_free(pval);
1364 if (idev_name != NULL)
1365 strfree(idev_name);
1366 if (odev_name != NULL)
1367 strfree(odev_name);
1368 return (EIO);
1369 }
1370
1371 static int
1372 lxa_zone_unreg(intptr_t arg, int mode)
1373 {
1374 lxa_zone_reg_t lxa_zr;
1375 lxa_zstate_t *lxa_zs = NULL;
1376 char *idev_name = NULL, *odev_name = NULL, *pval = NULL;
1377 int rv, i;
1378
1379 if (ddi_copyin((void *)arg, &lxa_zr, sizeof (lxa_zr), mode) != 0)
1380 return (EFAULT);
1381
1382 /* make sure that zone_name is a valid string */
1383 for (i = 0; i < sizeof (lxa_zr.lxa_zr_zone_name); i++)
1384 if (lxa_zr.lxa_zr_zone_name[i] == '\0')
1385 break;
1386 if (i == sizeof (lxa_zr.lxa_zr_zone_name))
1387 return (EINVAL);
1388
1389 /* get the property names */
1390 idev_name = lxa_devprop_name(lxa_zr.lxa_zr_zone_name,
1391 LXA_PROP_INPUTDEV);
1392 odev_name = lxa_devprop_name(lxa_zr.lxa_zr_zone_name,
1393 LXA_PROP_OUTPUTDEV);
1394
1395 mutex_enter(&lxa_lock);
1396
1397 if (lxa_registered_zones <= 0) {
1398 rv = ENOENT;
1399 goto err_unlock;
1400 }
1401
1402 /* make sure this zone is actually registered */
1403 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lxa_dip,
1404 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1405 idev_name, &pval) != DDI_PROP_SUCCESS) {
1406 rv = ENOENT;
1407 goto err_unlock;
1408 }
1409 ddi_prop_free(pval);
1410 pval = NULL;
1411 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lxa_dip,
1412 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1413 odev_name, &pval) != DDI_PROP_SUCCESS) {
1414 rv = ENOENT;
1415 goto err_unlock;
1416 }
1417 ddi_prop_free(pval);
1418 pval = NULL;
1419 if (mod_hash_find(lxa_zstate_hash,
1420 (mod_hash_key_t)lxa_zr.lxa_zr_zone_name,
1421 (mod_hash_val_t *)&lxa_zs) != 0) {
1422 rv = ENOENT;
1423 goto err_unlock;
1424 }
1425 ASSERT(strcmp(lxa_zr.lxa_zr_zone_name, lxa_zs->lxa_zs_zonename) == 0);
1426
1427 /*
1428 * if the audio device is currently in use then refuse to
1429 * unregister the zone
1430 */
1431 if ((lxa_zs->lxa_zs_ostate != NULL) ||
1432 (lxa_zs->lxa_zs_ostate != NULL)) {
1433 rv = EBUSY;
1434 goto err_unlock;
1435 }
1436
1437 /* success! cleanup zone config state */
1438 (void) ddi_prop_remove(DDI_DEV_T_NONE, lxa_dip, idev_name);
1439 (void) ddi_prop_remove(DDI_DEV_T_NONE, lxa_dip, odev_name);
1440
1441 /*
1442 * note, the action of removing the zone state structure from the
1443 * hash will automatically free lxa_zs->lxa_zs_zonename.
1444 *
1445 * the reason for this is that we used lxa_zs->lxa_zs_zonename
1446 * as the hash key and by default mod_hash_create_strhash() uses
1447 * mod_hash_strkey_dtor() as a the hash key destructor. (which
1448 * free's the key for us.
1449 */
1450 (void) mod_hash_remove(lxa_zstate_hash,
1451 (mod_hash_key_t)lxa_zr.lxa_zr_zone_name,
1452 (mod_hash_val_t *)&lxa_zs);
1453 lxa_registered_zones--;
1454 mutex_exit(&lxa_lock);
1455
1456 /* cleanup */
1457 kmem_free(lxa_zs, sizeof (*lxa_zs));
1458 strfree(idev_name);
1459 strfree(odev_name);
1460 return (0);
1461
1462 err_unlock:
1463 mutex_exit(&lxa_lock);
1464
1465 if (pval != NULL)
1466 ddi_prop_free(pval);
1467 if (idev_name != NULL)
1468 strfree(idev_name);
1469 if (odev_name != NULL)
1470 strfree(odev_name);
1471 return (rv);
1472 }
1473
1474 static int
1475 lxa_ioctl_devctl(int cmd, intptr_t arg, int mode)
1476 {
1477 /* devctl ioctls are only allowed from the global zone */
1478 ASSERT(getzoneid() == 0);
1479 if (getzoneid() != 0)
1480 return (EINVAL);
1481
1482 switch (cmd) {
1483 case LXA_IOC_ZONE_REG:
1484 return (lxa_zone_reg(arg, mode));
1485 case LXA_IOC_ZONE_UNREG:
1486 return (lxa_zone_unreg(arg, mode));
1487 }
1488
1489 return (EINVAL);
1490 }
1491
1492 static int
1493 /*ARGSUSED*/
1494 lxa_open(dev_t *devp, int flags, int otyp, cred_t *credp)
1495 {
1496 lxa_dev_type_t open_type = LXA_TYPE_INVALID;
1497 lxa_zstate_t *lxa_zs;
1498 lxa_state_t *lxa_state;
1499 minor_t minor;
1500 int rv;
1501
1502 if (getminor(*devp) == LXA_MINORNUM_DEVCTL) {
1503 /*
1504 * this is a devctl node, it exists to administer this
1505 * pseudo driver so it doesn't actually need access to
1506 * any underlying audio devices. hence there is nothing
1507 * really to do here. course, this driver should
1508 * only be administered from the global zone.
1509 */
1510 ASSERT(getzoneid() == 0);
1511 if (getzoneid() != 0)
1512 return (EINVAL);
1513 return (0);
1514 }
1515
1516 /* lookup the zone state structure */
1517 if (mod_hash_find(lxa_zstate_hash, (mod_hash_key_t)getzonename(),
1518 (mod_hash_val_t *)&lxa_zs) != 0) {
1519 return (EIO);
1520 }
1521
1522 /* determine what type of device was opened */
1523 switch (getminor(*devp)) {
1524 case LXA_MINORNUM_DSP:
1525 open_type = LXA_TYPE_AUDIO;
1526 break;
1527 case LXA_MINORNUM_MIXER:
1528 open_type = LXA_TYPE_AUDIOCTL;
1529 break;
1530 default:
1531 return (EINVAL);
1532 }
1533 ASSERT(open_type != LXA_TYPE_INVALID);
1534
1535 /* all other opens are clone opens so get a new minor node */
1536 minor = id_alloc(lxa_minor_id);
1537
1538 /* allocate and initialize the new lxa_state structure */
1539 lxa_state = kmem_zalloc(sizeof (*lxa_state), KM_SLEEP);
1540 lxa_state->lxas_zs = lxa_zs;
1541 lxa_state->lxas_dev_old = *devp;
1542 lxa_state->lxas_dev_new = makedevice(getmajor(*devp), minor);
1543 lxa_state->lxas_flags = flags;
1544 lxa_state->lxas_type = open_type;
1545
1546 /* initialize the input and output device */
1547 if (((rv = lxa_dev_open(lxa_state)) != 0) ||
1548 ((rv = lxa_dev_getfeatures(lxa_state)) != 0)) {
1549 lxa_state_close(lxa_state);
1550 return (rv);
1551 }
1552
1553 /*
1554 * save this audio statue structure into a hash indexed
1555 * by it's minor device number. (this will provide a convient
1556 * way to lookup the state structure on future operations.)
1557 */
1558 if (mod_hash_insert(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
1559 (mod_hash_val_t)lxa_state) != 0) {
1560 lxa_state_close(lxa_state);
1561 return (EIO);
1562 }
1563
1564 mutex_enter(&lxa_lock);
1565
1566 /* apply the currently cached zone PCM mixer levels */
1567 if ((lxa_state->lxas_type == LXA_TYPE_AUDIO) &&
1568 (lxa_state->lxas_odev_lh != NULL)) {
1569 audio_info_t ai;
1570
1571 AUDIO_INITINFO(&ai);
1572 ai.play.gain = lxa_zs->lxa_zs_pcm_levels.lxa_ml_gain;
1573 ai.play.balance = lxa_zs->lxa_zs_pcm_levels.lxa_ml_balance;
1574
1575 if ((rv = lxa_audio_setinfo(lxa_state,
1576 AUDIO_SETINFO, (intptr_t)&ai, FKIOCTL)) != 0) {
1577 mutex_exit(&lxa_lock);
1578 lxa_state_close(lxa_state);
1579 return (rv);
1580 }
1581 }
1582
1583 /*
1584 * we only allow one active open of the input or output device.
1585 * check here for duplicate opens
1586 */
1587 if (lxa_state->lxas_type == LXA_TYPE_AUDIO) {
1588 if ((lxa_state->lxas_idev_lh != NULL) &&
1589 (lxa_zs->lxa_zs_istate != NULL)) {
1590 mutex_exit(&lxa_lock);
1591 lxa_state_close(lxa_state);
1592 return (EBUSY);
1593 }
1594 if ((lxa_state->lxas_odev_lh != NULL) &&
1595 (lxa_zs->lxa_zs_ostate != NULL)) {
1596 mutex_exit(&lxa_lock);
1597 lxa_state_close(lxa_state);
1598 return (EBUSY);
1599 }
1600
1601 /* not a duplicate open, update the global zone state */
1602 if (lxa_state->lxas_idev_lh != NULL)
1603 lxa_zs->lxa_zs_istate = lxa_state;
1604 if (lxa_state->lxas_odev_lh != NULL)
1605 lxa_zs->lxa_zs_ostate = lxa_state;
1606 }
1607 mutex_exit(&lxa_lock);
1608
1609 /* make sure to return our newly allocated dev_t */
1610 *devp = lxa_state->lxas_dev_new;
1611 return (0);
1612 }
1613
1614 static int
1615 /*ARGSUSED*/
1616 lxa_close(dev_t dev, int flags, int otyp, cred_t *credp)
1617 {
1618 lxa_state_t *lxa_state;
1619 minor_t minor = getminor(dev);
1620
1621 /* handle devctl minor nodes (these nodes don't have a handle */
1622 if (getminor(dev) == LXA_MINORNUM_DEVCTL)
1623 return (0);
1624
1625 /* get the handle for this device */
1626 if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
1627 (mod_hash_val_t *)&lxa_state) != 0)
1628 return (EINVAL);
1629
1630 lxa_state_close(lxa_state);
1631 return (0);
1632 }
1633
1634 static int
1635 /*ARGSUSED*/
1636 lxa_read(dev_t dev, struct uio *uiop, cred_t *credp)
1637 {
1638 lxa_state_t *lxa_state;
1639 minor_t minor = getminor(dev);
1640 int rv;
1641
1642 /* get the handle for this device */
1643 if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
1644 (mod_hash_val_t *)&lxa_state) != 0)
1645 return (EINVAL);
1646
1647 /*
1648 * if a process has mmaped this device then we don't allow
1649 * any more reads or writes to the device
1650 */
1651 if (lxa_state->lxas_umem_cookie != NULL)
1652 return (EIO);
1653
1654 /* we can't do a read if there is no input device */
1655 if (lxa_state->lxas_idev_lh == NULL)
1656 return (EBADF);
1657
1658 /* pass the request on */
1659 while (uiop->uio_resid != 0) {
1660 rv = ldi_read(lxa_state->lxas_idev_lh, uiop, kcred);
1661 if ((rv != 0) || (uiop->uio_fmode & (FNONBLOCK|FNDELAY))) {
1662 break;
1663 }
1664 }
1665 return (rv);
1666 }
1667
1668 static int
1669 /*ARGSUSED*/
1670 lxa_write(dev_t dev, struct uio *uiop, cred_t *credp)
1671 {
1672 lxa_state_t *lxa_state;
1673 minor_t minor = getminor(dev);
1674 int rv;
1675
1676 /* get the handle for this device */
1677 if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
1678 (mod_hash_val_t *)&lxa_state) != 0)
1679 return (EINVAL);
1680
1681 /*
1682 * if a process has mmaped this device then we don't allow
1683 * any more reads or writes to the device
1684 */
1685 if (lxa_state->lxas_umem_cookie != NULL)
1686 return (EIO);
1687
1688 /* we can't do a write if there is no output device */
1689 if (lxa_state->lxas_odev_lh == NULL)
1690 return (EBADF);
1691
1692 /* pass the request on */
1693 while (uiop->uio_resid != 0) {
1694 rv = ldi_write(lxa_state->lxas_odev_lh, uiop, kcred);
1695 if ((rv != 0) || (uiop->uio_fmode & (FNONBLOCK|FNDELAY))) {
1696 break;
1697 }
1698 }
1699 return (rv);
1700 }
1701
1702 static int
1703 /*ARGSUSED*/
1704 lxa_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1705 int *rvalp)
1706 {
1707 lxa_state_t *lxa_state;
1708 minor_t minor = getminor(dev);
1709
1710 /* handle devctl minor nodes (these nodes don't have a handle */
1711 if (getminor(dev) == LXA_MINORNUM_DEVCTL)
1712 return (lxa_ioctl_devctl(cmd, arg, mode));
1713
1714 /* get the handle for this device */
1715 if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
1716 (mod_hash_val_t *)&lxa_state) != 0)
1717 return (EINVAL);
1718
1719 ASSERT((lxa_state->lxas_type == LXA_TYPE_AUDIO) ||
1720 (lxa_state->lxas_type == LXA_TYPE_AUDIOCTL));
1721
1722 switch (cmd) {
1723 case LXA_IOC_GETMINORNUM:
1724 {
1725 int minornum = getminor(lxa_state->lxas_dev_old);
1726 if (ddi_copyout(&minornum, (void *)arg,
1727 sizeof (minornum), mode) != 0)
1728 return (EFAULT);
1729 }
1730 return (0);
1731 }
1732
1733 if (lxa_state->lxas_type == LXA_TYPE_AUDIO) {
1734 /* deal with native ioctl */
1735 switch (cmd) {
1736 case LXA_IOC_MMAP_OUTPUT:
1737 return (lxa_ioc_mmap_output(lxa_state, arg, mode));
1738 case LXA_IOC_MMAP_PTR:
1739 return (lxa_ioc_mmap_ptr(lxa_state, arg, mode));
1740 case LXA_IOC_GET_FRAG_INFO:
1741 return (lxa_ioc_get_frag_info(lxa_state, arg, mode));
1742 case LXA_IOC_SET_FRAG_INFO:
1743 return (lxa_ioc_set_frag_info(lxa_state, arg, mode));
1744 }
1745
1746 /* deal with layered ioctls */
1747 switch (cmd) {
1748 case AUDIO_DRAIN:
1749 return (lxa_audio_drain(lxa_state));
1750 case AUDIO_SETINFO:
1751 return (lxa_audio_setinfo(lxa_state,
1752 AUDIO_SETINFO, arg, mode));
1753 case AUDIO_GETINFO:
1754 return (lxa_audio_getinfo(lxa_state, arg, mode));
1755 }
1756 }
1757
1758 if (lxa_state->lxas_type == LXA_TYPE_AUDIOCTL) {
1759 /* deal with native ioctl */
1760 switch (cmd) {
1761 case LXA_IOC_MIXER_GET_VOL:
1762 return (lxa_mixer_get_common(lxa_state,
1763 cmd, arg, mode));
1764 case LXA_IOC_MIXER_SET_VOL:
1765 return (lxa_mixer_set_common(lxa_state,
1766 cmd, arg, mode));
1767 case LXA_IOC_MIXER_GET_MIC:
1768 return (lxa_mixer_get_common(lxa_state,
1769 cmd, arg, mode));
1770 case LXA_IOC_MIXER_SET_MIC:
1771 return (lxa_mixer_set_common(lxa_state,
1772 cmd, arg, mode));
1773 case LXA_IOC_MIXER_GET_PCM:
1774 return (lxa_mixer_get_pcm(lxa_state, arg, mode));
1775 case LXA_IOC_MIXER_SET_PCM:
1776 return (lxa_mixer_set_pcm(lxa_state, arg, mode));
1777 }
1778
1779 }
1780
1781 return (EINVAL);
1782 }
1783
1784 static int
1785 /*ARGSUSED*/
1786 lxa_devmap(dev_t dev, devmap_cookie_t dhp,
1787 offset_t off, size_t len, size_t *maplen, uint_t model)
1788 {
1789 lxa_state_t *lxa_state;
1790 minor_t minor = getminor(dev);
1791 ddi_umem_cookie_t umem_cookie;
1792 void *umem_ptr;
1793 int rv;
1794
1795 /* get the handle for this device */
1796 if (mod_hash_find(lxa_state_hash, (mod_hash_key_t)(uintptr_t)minor,
1797 (mod_hash_val_t *)&lxa_state) != 0)
1798 return (EINVAL);
1799
1800 /* we only support mmaping of audio devices */
1801 if (lxa_state->lxas_type != LXA_TYPE_AUDIO)
1802 return (EINVAL);
1803
1804 /* we only support output via mmap */
1805 if ((lxa_state->lxas_flags & FWRITE) == 0)
1806 return (EINVAL);
1807
1808 /* sanity check the amount of memory the user is allocating */
1809 if ((len == 0) ||
1810 (len > LXA_OSS_FRAG_MEM) ||
1811 ((len % lxa_state->lxas_frag_size) != 0))
1812 return (EINVAL);
1813
1814 /* allocate and clear memory to mmap */
1815 umem_ptr = ddi_umem_alloc(len, DDI_UMEM_NOSLEEP, &umem_cookie);
1816 if (umem_ptr == NULL)
1817 return (ENOMEM);
1818 bzero(umem_ptr, len);
1819
1820 /* setup the memory mappings */
1821 rv = devmap_umem_setup(dhp, lxa_dip, NULL, umem_cookie, 0, len,
1822 PROT_USER | PROT_READ | PROT_WRITE, 0, NULL);
1823 if (rv != 0) {
1824 ddi_umem_free(umem_cookie);
1825 return (EIO);
1826 }
1827
1828 mutex_enter(&lxa_lock);
1829
1830 /* we only support one mmap per open */
1831 if (lxa_state->lxas_umem_cookie != NULL) {
1832 ASSERT(lxa_state->lxas_umem_ptr != NULL);
1833 mutex_exit(&lxa_lock);
1834 ddi_umem_free(umem_cookie);
1835 return (EBUSY);
1836 }
1837 ASSERT(lxa_state->lxas_umem_ptr == NULL);
1838
1839 *maplen = len;
1840 lxa_state->lxas_umem_len = len;
1841 lxa_state->lxas_umem_ptr = umem_ptr;
1842 lxa_state->lxas_umem_cookie = umem_cookie;
1843 mutex_exit(&lxa_lock);
1844 return (0);
1845 }
1846
1847 static int
1848 /*ARGSUSED*/
1849 lxa_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1850 {
1851 int instance = ddi_get_instance(dip);
1852
1853 if (cmd != DDI_ATTACH)
1854 return (DDI_FAILURE);
1855
1856 ASSERT(instance == 0);
1857 if (instance != 0)
1858 return (DDI_FAILURE);
1859
1860 lxa_dip = dip;
1861 mutex_init(&lxa_lock, NULL, MUTEX_DEFAULT, NULL);
1862
1863 /* create our minor nodes */
1864 if (ddi_create_minor_node(dip, LXA_MINORNAME_DEVCTL, S_IFCHR,
1865 LXA_MINORNUM_DEVCTL, DDI_PSEUDO, 0) != DDI_SUCCESS)
1866 return (DDI_FAILURE);
1867
1868 if (ddi_create_minor_node(dip, LXA_MINORNAME_DSP, S_IFCHR,
1869 LXA_MINORNUM_DSP, DDI_PSEUDO, 0) != DDI_SUCCESS)
1870 return (DDI_FAILURE);
1871
1872 if (ddi_create_minor_node(dip, LXA_MINORNAME_MIXER, S_IFCHR,
1873 LXA_MINORNUM_MIXER, DDI_PSEUDO, 0) != DDI_SUCCESS)
1874 return (DDI_FAILURE);
1875
1876 /* allocate our data structures */
1877 lxa_minor_id = id_space_create("lxa_minor_id",
1878 LXA_MINORNUM_COUNT, LX_AUDIO_MAX_OPENS);
1879 lxa_state_hash = mod_hash_create_idhash("lxa_state_hash",
1880 lxa_state_hash_size, mod_hash_null_valdtor);
1881 lxa_zstate_hash = mod_hash_create_strhash("lxa_zstate_hash",
1882 lxa_zstate_hash_size, mod_hash_null_valdtor);
1883
1884 return (DDI_SUCCESS);
1885 }
1886
1887 static int
1888 /*ARGSUSED*/
1889 lxa_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1890 {
1891 if (cmd != DDI_DETACH)
1892 return (DDI_FAILURE);
1893
1894 ASSERT(!MUTEX_HELD(&lxa_lock));
1895 if (lxa_registered_zones > 0)
1896 return (DDI_FAILURE);
1897
1898 mod_hash_destroy_idhash(lxa_state_hash);
1899 mod_hash_destroy_idhash(lxa_zstate_hash);
1900 id_space_destroy(lxa_minor_id);
1901 lxa_state_hash = NULL;
1902 lxa_dip = NULL;
1903
1904 return (DDI_SUCCESS);
1905 }
1906
1907 static int
1908 /*ARGSUSED*/
1909 lxa_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **resultp)
1910 {
1911 switch (infocmd) {
1912 case DDI_INFO_DEVT2DEVINFO:
1913 *resultp = lxa_dip;
1914 return (DDI_SUCCESS);
1915
1916 case DDI_INFO_DEVT2INSTANCE:
1917 *resultp = (void *)0;
1918 return (DDI_SUCCESS);
1919 }
1920 return (DDI_FAILURE);
1921 }
1922
1923 /*
1924 * Driver flags
1925 */
1926 static struct cb_ops lxa_cb_ops = {
1927 lxa_open, /* open */
1928 lxa_close, /* close */
1929 nodev, /* strategy */
1930 nodev, /* print */
1931 nodev, /* dump */
1932 lxa_read, /* read */
1933 lxa_write, /* write */
1934 lxa_ioctl, /* ioctl */
1935 lxa_devmap, /* devmap */
1936 nodev, /* mmap */
1937 ddi_devmap_segmap, /* segmap */
1938 nochpoll, /* chpoll */
1939 ddi_prop_op, /* prop_op */
1940 NULL, /* cb_str */
1941 D_NEW | D_MP | D_DEVMAP,
1942 CB_REV,
1943 NULL,
1944 NULL
1945 };
1946
1947 static struct dev_ops lxa_ops = {
1948 DEVO_REV,
1949 0,
1950 lxa_getinfo,
1951 nulldev,
1952 nulldev,
1953 lxa_attach,
1954 lxa_detach,
1955 nodev,
1956 &lxa_cb_ops,
1957 NULL,
1958 NULL,
1959 ddi_quiesce_not_needed, /* quiesce */
1960 };
1961
1962 /*
1963 * Module linkage information for the kernel.
1964 */
1965 static struct modldrv modldrv = {
1966 &mod_driverops, /* type of module */
1967 "linux audio driver", /* description of module */
1968 &lxa_ops /* driver ops */
1969 };
1970
1971 static struct modlinkage modlinkage = {
1972 MODREV_1,
1973 &modldrv,
1974 NULL
1975 };
1976
1977 /*
1978 * standard module entry points
1979 */
1980 int
1981 _init(void)
1982 {
1983 return (mod_install(&modlinkage));
1984 }
1985
1986 int
1987 _fini(void)
1988 {
1989 return (mod_remove(&modlinkage));
1990 }
1991
1992 int
1993 _info(struct modinfo *modinfop)
1994 {
1995 return (mod_info(&modlinkage, modinfop));
1996 }