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