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 }