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 (C) 4Front Technologies 1996-2008. 23 * 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include <sys/types.h> 29 #include <sys/list.h> 30 #include <sys/sysmacros.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 #include <sys/callb.h> 34 #include <sys/kstat.h> 35 #include <sys/note.h> 36 37 #include "audio_impl.h" 38 39 /* 40 * Audio Engine functions. 41 */ 42 43 audio_dev_t * 44 audio_dev_alloc(dev_info_t *dip, int instance) 45 { 46 audio_dev_t *d; 47 48 /* 49 * For a card with multiple independent audio ports on it, we 50 * allow the driver to provide a different instance numbering 51 * scheme than the standard DDI instance number. (This is 52 * sort of like the PPA numbering scheme used by NIC drivers 53 * -- by default PPA == instance, but sometimes we need more 54 * flexibility.) 55 */ 56 if (instance == 0) { 57 instance = ddi_get_instance(dip); 58 } 59 /* generally this shouldn't occur */ 60 if (instance > AUDIO_MN_INST_MASK) { 61 audio_dev_warn(NULL, "bad instance number for %s (%d)", 62 ddi_driver_name(dip), instance); 63 return (NULL); 64 } 65 66 if ((d = kmem_zalloc(sizeof (*d), KM_NOSLEEP)) == NULL) { 67 audio_dev_warn(NULL, "unable to allocate audio device struct"); 68 return (NULL); 69 } 70 d->d_dip = dip; 71 d->d_number = -1; 72 d->d_major = ddi_driver_major(dip); 73 d->d_instance = instance; 74 d->d_pcmvol = 100; 75 mutex_init(&d->d_lock, NULL, MUTEX_DRIVER, NULL); 76 cv_init(&d->d_cv, NULL, CV_DRIVER, NULL); 77 rw_init(&d->d_ctrl_lock, NULL, RW_DRIVER, NULL); 78 list_create(&d->d_clients, sizeof (struct audio_client), 79 offsetof(struct audio_client, c_dev_linkage)); 80 list_create(&d->d_engines, sizeof (struct audio_engine), 81 offsetof(struct audio_engine, e_dev_linkage)); 82 list_create(&d->d_controls, sizeof (struct audio_ctrl), 83 offsetof(struct audio_ctrl, ctrl_linkage)); 84 list_create(&d->d_hwinfo, sizeof (struct audio_infostr), 85 offsetof(struct audio_infostr, i_linkage)); 86 (void) snprintf(d->d_name, sizeof (d->d_name), "%s#%d", 87 ddi_driver_name(dip), instance); 88 89 return (d); 90 } 91 92 void 93 audio_dev_free(audio_dev_t *d) 94 { 95 struct audio_infostr *isp; 96 while ((isp = list_remove_head(&d->d_hwinfo)) != NULL) { 97 kmem_free(isp, sizeof (*isp)); 98 } 99 if (d->d_pcmvol_ctrl != NULL) { 100 audio_dev_del_control(d->d_pcmvol_ctrl); 101 } 102 list_destroy(&d->d_hwinfo); 103 list_destroy(&d->d_engines); 104 list_destroy(&d->d_controls); 105 list_destroy(&d->d_clients); 106 rw_destroy(&d->d_ctrl_lock); 107 mutex_destroy(&d->d_lock); 108 cv_destroy(&d->d_cv); 109 kmem_free(d, sizeof (*d)); 110 } 111 112 void 113 audio_dev_set_description(audio_dev_t *d, const char *desc) 114 { 115 (void) strlcpy(d->d_desc, desc, sizeof (d->d_desc)); 116 } 117 118 void 119 audio_dev_set_version(audio_dev_t *d, const char *vers) 120 { 121 (void) strlcpy(d->d_vers, vers, sizeof (d->d_vers)); 122 } 123 124 void 125 audio_dev_add_info(audio_dev_t *d, const char *info) 126 { 127 struct audio_infostr *isp; 128 129 /* failure to add information structure is not critical */ 130 isp = kmem_zalloc(sizeof (*isp), KM_NOSLEEP); 131 if (isp == NULL) { 132 audio_dev_warn(d, "unable to allocate information structure"); 133 } else { 134 (void) snprintf(isp->i_line, sizeof (isp->i_line), info); 135 list_insert_tail(&d->d_hwinfo, isp); 136 } 137 } 138 139 void 140 audio_engine_consume(audio_engine_t *e) 141 { 142 mutex_enter(&e->e_lock); 143 e->e_tail = ENG_COUNT(e); 144 if (e->e_tail > e->e_head) { 145 /* want more data than we have, not much we can do */ 146 e->e_errors++; 147 e->e_underruns++; 148 } 149 auimpl_output_callback(e); 150 mutex_exit(&e->e_lock); 151 } 152 153 void 154 audio_engine_produce(audio_engine_t *e) 155 { 156 mutex_enter(&e->e_lock); 157 e->e_head = ENG_COUNT(e); 158 if ((e->e_head - e->e_tail) > e->e_nframes) { 159 /* no room for engine data, not much we can do */ 160 e->e_errors++; 161 e->e_overruns++; 162 } 163 auimpl_input_callback(e); 164 mutex_exit(&e->e_lock); 165 } 166 167 void 168 audio_engine_reset(audio_engine_t *e) 169 { 170 char *buf; 171 char *ptr; 172 int nfr; 173 int tail; 174 175 176 if ((e->e_flags & (ENGINE_INPUT | ENGINE_OUTPUT)) == 0) { 177 /* engine not open, nothing to do */ 178 return; 179 } 180 181 buf = kmem_alloc(e->e_nbytes, KM_SLEEP); 182 ptr = buf; 183 184 mutex_enter(&e->e_lock); 185 186 tail = e->e_tidx; 187 nfr = min(e->e_head - e->e_tail, e->e_nframes); 188 while (nfr) { 189 int cnt; 190 int nbytes; 191 192 cnt = min((e->e_nframes - tail), nfr); 193 nbytes = cnt * e->e_framesz; 194 195 bcopy(e->e_data + (tail * e->e_framesz), ptr, nbytes); 196 ptr += nbytes; 197 tail += cnt; 198 if (tail >= e->e_framesz) { 199 tail -= e->e_framesz; 200 } 201 nfr -= cnt; 202 } 203 204 nfr = min(e->e_head - e->e_tail, e->e_nframes); 205 if (e->e_flags & ENGINE_INPUT) { 206 /* record */ 207 e->e_hidx = 0; 208 e->e_tidx = (e->e_nframes - nfr) % e->e_nframes; 209 } else { 210 /* play */ 211 e->e_hidx = nfr % e->e_nframes; 212 e->e_tidx = 0; 213 } 214 215 /* relocate from scratch area to destination */ 216 bcopy(buf, e->e_data + (e->e_tidx * e->e_framesz), nfr * e->e_framesz); 217 mutex_exit(&e->e_lock); 218 219 kmem_free(buf, e->e_nbytes); 220 } 221 222 audio_engine_t * 223 audio_engine_alloc(audio_engine_ops_t *ops, unsigned flags) 224 { 225 int i; 226 audio_engine_t *e; 227 228 if (ops->audio_engine_version != AUDIO_ENGINE_VERSION) { 229 audio_dev_warn(NULL, "audio engine version mismatch: %d != %d", 230 ops->audio_engine_version, AUDIO_ENGINE_VERSION); 231 return (NULL); 232 } 233 234 /* NB: The ops vector must be held in persistent storage! */ 235 e = kmem_zalloc(sizeof (audio_engine_t), KM_NOSLEEP); 236 if (e == NULL) { 237 audio_dev_warn(NULL, "unable to allocate engine struct"); 238 return (NULL); 239 } 240 e->e_ops = *ops; 241 mutex_init(&e->e_lock, NULL, MUTEX_DRIVER, NULL); 242 list_create(&e->e_streams, sizeof (struct audio_stream), 243 offsetof(struct audio_stream, s_eng_linkage)); 244 245 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) { 246 e->e_chbufs[i] = kmem_zalloc(sizeof (int32_t) * AUDIO_CHBUFS, 247 KM_NOSLEEP); 248 if (e->e_chbufs[i] == NULL) { 249 audio_dev_warn(NULL, "unable to allocate channel buf"); 250 audio_engine_free(e); 251 return (NULL); 252 } 253 } 254 255 e->e_flags = flags & ENGINE_DRIVER_FLAGS; 256 return (e); 257 } 258 259 void 260 audio_engine_free(audio_engine_t *e) 261 { 262 int i; 263 264 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) { 265 if (e->e_chbufs[i] != NULL) { 266 kmem_free(e->e_chbufs[i], 267 sizeof (int32_t) * AUDIO_CHBUFS); 268 } 269 } 270 list_destroy(&e->e_streams); 271 mutex_destroy(&e->e_lock); 272 kmem_free(e, sizeof (*e)); 273 } 274 275 static list_t auimpl_devs_by_index; 276 static list_t auimpl_devs_by_number; 277 static krwlock_t auimpl_dev_lock; 278 279 /* 280 * Not for public consumption: Private interfaces. 281 */ 282 void 283 auimpl_dev_hold(audio_dev_t *d) 284 { 285 /* bump the reference count */ 286 mutex_enter(&d->d_lock); 287 d->d_refcnt++; 288 mutex_exit(&d->d_lock); 289 } 290 291 audio_dev_t * 292 auimpl_dev_hold_by_devt(dev_t dev) 293 { 294 audio_dev_t *d; 295 major_t major; 296 int instance; 297 list_t *l = &auimpl_devs_by_index; 298 299 major = getmajor(dev); 300 instance = (getminor(dev) >> AUDIO_MN_INST_SHIFT) & AUDIO_MN_INST_MASK; 301 302 rw_enter(&auimpl_dev_lock, RW_READER); 303 304 for (d = list_head(l); d; d = list_next(l, d)) { 305 if ((d->d_major == major) && (d->d_instance == instance)) { 306 auimpl_dev_hold(d); 307 break; 308 } 309 } 310 311 rw_exit(&auimpl_dev_lock); 312 return (d); 313 } 314 315 audio_dev_t * 316 auimpl_dev_hold_by_index(int index) 317 { 318 audio_dev_t *d; 319 list_t *l = &auimpl_devs_by_index; 320 321 rw_enter(&auimpl_dev_lock, RW_READER); 322 323 for (d = list_head(l); d; d = list_next(l, d)) { 324 if (d->d_index == index) { 325 auimpl_dev_hold(d); 326 break; 327 } 328 } 329 330 rw_exit(&auimpl_dev_lock); 331 return (d); 332 } 333 334 void 335 auimpl_dev_release(audio_dev_t *d) 336 { 337 mutex_enter(&d->d_lock); 338 d->d_refcnt--; 339 mutex_exit(&d->d_lock); 340 } 341 342 int 343 auimpl_choose_format(int fmts) 344 { 345 /* 346 * Choose the very best format we can. We choose 24 bit in 347 * preference to 32 bit because we mix in 24 bit. We do that 348 * to allow overflows to fit within 32-bits. (Very few humans 349 * can tell a difference between 24 and 32 bit audio anyway.) 350 */ 351 if (fmts & AUDIO_FORMAT_S24_NE) 352 return (AUDIO_FORMAT_S24_NE); 353 354 if (fmts & AUDIO_FORMAT_S32_NE) 355 return (AUDIO_FORMAT_S32_NE); 356 357 if (fmts & AUDIO_FORMAT_S24_OE) 358 return (AUDIO_FORMAT_S24_OE); 359 360 if (fmts & AUDIO_FORMAT_S32_OE) 361 return (AUDIO_FORMAT_S32_OE); 362 363 if (fmts & AUDIO_FORMAT_S16_NE) 364 return (AUDIO_FORMAT_S16_NE); 365 366 if (fmts & AUDIO_FORMAT_S16_OE) 367 return (AUDIO_FORMAT_S16_OE); 368 369 if (fmts & AUDIO_FORMAT_AC3) 370 return (AUDIO_FORMAT_AC3); 371 372 return (AUDIO_FORMAT_NONE); 373 } 374 375 int 376 auimpl_engine_open(audio_dev_t *d, int fmts, int flags, audio_stream_t *sp) 377 { 378 audio_engine_t *e = NULL; 379 list_t *list; 380 unsigned caps; 381 int priority = 0; 382 int rv = ENODEV; 383 int sampsz; 384 int i; 385 386 /* 387 * Engine selection: 388 * 389 * We try hard to avoid consuming an engine that can be used 390 * for another purpose. 391 * 392 */ 393 394 /* 395 * Which direction are we opening. (We must open exactly 396 * one direction, otherwise the open is meaningless.) 397 */ 398 if (flags & ENGINE_OUTPUT) 399 caps = ENGINE_OUTPUT_CAP; 400 else if (flags & ENGINE_INPUT) 401 caps = ENGINE_INPUT_CAP; 402 else 403 return (EINVAL); 404 405 list = &d->d_engines; 406 407 mutex_enter(&d->d_lock); 408 409 /* 410 * First we want to know if we already have "default" input 411 * and output engines. 412 */ 413 414 again: 415 416 for (audio_engine_t *t = list_head(list); t; t = list_next(list, t)) { 417 int mypri; 418 419 /* make sure the engine can do what we want it to */ 420 mutex_enter(&t->e_lock); 421 if ((((t->e_flags & caps) & caps) == 0) || 422 ((ENG_FORMAT(t) & fmts) == 0)) { 423 mutex_exit(&t->e_lock); 424 continue; 425 } 426 427 /* if engine is in exclusive use, can't do it */ 428 if (t->e_flags & ENGINE_EXCLUSIVE) { 429 mutex_exit(&t->e_lock); 430 rv = EBUSY; 431 continue; 432 } 433 434 /* if engine is in incompatible use, can't do it */ 435 if (((flags & ENGINE_INPUT) && (t->e_flags & ENGINE_OUTPUT)) || 436 ((flags & ENGINE_OUTPUT) && (t->e_flags & ENGINE_INPUT))) { 437 mutex_exit(&t->e_lock); 438 rv = EBUSY; 439 continue; 440 } 441 442 /* 443 * In order to support as many different possible 444 * output streams (e.g. AC3 passthru or AC3 decode), 445 * or multiple exclusive outputs, we treat audio 446 * engines as *precious*. 447 * 448 * This means that we will try hard to reuse an 449 * existing allocated engine. This may not be the 450 * optimal performance configuration (especially if we 451 * wanted to avoid rate conversion, for example), but 452 * it should have fewer cases where the configuration 453 * results in denying service to any client. 454 */ 455 456 rv = 0; 457 mypri = 2000; 458 459 /* try not to pick on idle engines */ 460 if (list_is_empty(&t->e_streams)) { 461 mypri -= 1000; 462 } 463 464 /* try not to pick on duplex engines first */ 465 if ((t->e_flags & ENGINE_CAPS) != caps) { 466 mypri -= 100; 467 } 468 469 /* try not to pick on engines that can do other formats */ 470 if (t->e_format & ~fmts) { 471 mypri -= 10; 472 } 473 474 if (mypri > priority) { 475 if (e != NULL) { 476 mutex_exit(&e->e_lock); 477 } 478 e = t; 479 priority = mypri; 480 } else { 481 mutex_exit(&t->e_lock); 482 } 483 } 484 485 if ((rv == EBUSY) && ((flags & ENGINE_NDELAY) == 0)) { 486 ASSERT(e == NULL); 487 if (cv_wait_sig(&d->d_cv, &d->d_lock) == 0) { 488 mutex_exit(&d->d_lock); 489 return (EINTR); 490 } 491 goto again; 492 } 493 494 if (rv != 0) { 495 ASSERT(e == NULL); 496 mutex_exit(&d->d_lock); 497 return (rv); 498 } 499 500 ASSERT(e != NULL); 501 ASSERT(mutex_owned(&e->e_lock)); 502 503 /* 504 * If the engine is already open, there is no need for further 505 * work. The first open will be relatively expensive, but 506 * subsequent opens should be as cheap as possible. 507 */ 508 if (!list_is_empty(&e->e_streams)) { 509 rv = 0; 510 goto ok; 511 } 512 513 e->e_format = ENG_FORMAT(e); 514 e->e_nchan = ENG_CHANNELS(e); 515 e->e_rate = ENG_RATE(e); 516 517 /* Find out the "best" sample format supported by the device */ 518 switch (e->e_format) { 519 case AUDIO_FORMAT_S24_NE: 520 e->e_export = auimpl_export_24ne; 521 e->e_import = auimpl_import_24ne; 522 sampsz = 4; 523 break; 524 case AUDIO_FORMAT_S32_NE: 525 e->e_export = auimpl_export_32ne; 526 e->e_import = auimpl_import_32ne; 527 sampsz = 4; 528 break; 529 case AUDIO_FORMAT_S24_OE: 530 e->e_export = auimpl_export_24oe; 531 e->e_import = auimpl_import_24oe; 532 sampsz = 4; 533 break; 534 case AUDIO_FORMAT_S32_OE: 535 e->e_export = auimpl_export_32oe; 536 e->e_import = auimpl_import_32oe; 537 sampsz = 4; 538 break; 539 case AUDIO_FORMAT_S16_NE: 540 e->e_export = auimpl_export_16ne; 541 e->e_import = auimpl_import_16ne; 542 sampsz = 2; 543 break; 544 case AUDIO_FORMAT_S16_OE: 545 e->e_export = auimpl_export_16oe; 546 e->e_import = auimpl_import_16oe; 547 sampsz = 2; 548 break; 549 case AUDIO_FORMAT_AC3: 550 e->e_export = auimpl_export_24ne; 551 e->e_import = auimpl_import_24ne; 552 flags |= ENGINE_EXCLUSIVE; 553 sampsz = 2; 554 break; 555 default: 556 audio_dev_warn(d, "bad format"); 557 rv = ENOTSUP; 558 goto done; 559 } 560 561 /* sanity test a few values */ 562 if ((e->e_nchan < 0) || (e->e_nchan > AUDIO_MAX_CHANNELS) || 563 (e->e_rate < 5000) || (e->e_rate > 192000)) { 564 audio_dev_warn(d, "bad engine channels or rate"); 565 rv = EINVAL; 566 goto done; 567 } 568 569 rv = ENG_OPEN(e, &e->e_fragfr, &e->e_nfrags, &e->e_data); 570 if (rv != 0) { 571 audio_dev_warn(d, "unable to open engine"); 572 goto done; 573 } 574 if ((e->e_fragfr < 1) || (e->e_data == NULL)) { 575 audio_dev_warn(d, "improper engine configuration"); 576 rv = EINVAL; 577 goto done; 578 } 579 580 if ((e->e_fragfr > AUDIO_CHBUFS) || (e->e_nfrags < 2)) { 581 rv = EINVAL; 582 audio_dev_warn(d, "invalid fragment configuration"); 583 goto done; 584 } 585 586 e->e_framesz = e->e_nchan * sampsz; 587 e->e_fragbytes = e->e_fragfr * e->e_framesz; 588 e->e_nframes = e->e_nfrags * e->e_fragfr; 589 e->e_intrs = e->e_rate / e->e_fragfr; 590 e->e_nbytes = e->e_nframes * e->e_framesz; 591 e->e_head = 0; 592 e->e_tail = 0; 593 e->e_hidx = 0; 594 e->e_tidx = 0; 595 e->e_limiter_state = 0x10000; 596 bzero(e->e_data, e->e_nbytes); 597 598 if (e->e_ops.audio_engine_playahead == NULL) { 599 e->e_playahead = (e->e_fragfr * 3) / 2; 600 } else { 601 e->e_playahead = ENG_PLAYAHEAD(e); 602 /* 603 * Need to have at least a fragment plus some extra to 604 * avoid underruns. 605 */ 606 if (e->e_playahead < ((e->e_fragfr * 3) / 2)) { 607 e->e_playahead = (e->e_fragfr * 3) / 2; 608 } 609 610 /* 611 * Impossible to queue more frames than FIFO can hold. 612 */ 613 if (e->e_playahead > e->e_nframes) { 614 e->e_playahead = (e->e_fragfr * 3) / 2; 615 } 616 } 617 618 for (i = 0; i < e->e_nchan; i++) { 619 if (e->e_ops.audio_engine_chinfo == NULL) { 620 e->e_choffs[i] = i; 621 e->e_chincr[i] = e->e_nchan; 622 } else { 623 ENG_CHINFO(e, i, &e->e_choffs[i], &e->e_chincr[i]); 624 } 625 } 626 627 e->e_flags |= (ENGINE_OPEN | (flags & (ENGINE_OUTPUT | ENGINE_INPUT))); 628 629 /* 630 * Start the output callback to populate the engine on 631 * startup. This avoids a false underrun when we're first 632 * starting up. 633 */ 634 if (flags & ENGINE_OUTPUT) { 635 auimpl_output_callback(e); 636 } 637 638 /* 639 * Start the engine up now. 640 * 641 * AC3: Note that this will need to be modified for AC3, since 642 * for AC3 we can't start the device until we actually have 643 * some data for it from the application. Probably the best 644 * way to do this would be to add a flag, ENGINE_DEFERRED or 645 * somesuch. 646 */ 647 if (e->e_ops.audio_engine_start != NULL) { 648 rv = ENG_START(e); 649 if (rv != 0) { 650 ENG_CLOSE(e); 651 goto done; 652 } 653 } 654 655 ok: 656 sp->s_phys_parms->p_rate = e->e_rate; 657 sp->s_phys_parms->p_nchan = e->e_nchan; 658 659 list_insert_tail(&e->e_streams, sp); 660 sp->s_engine = e; 661 662 done: 663 mutex_exit(&e->e_lock); 664 mutex_exit(&d->d_lock); 665 return (rv); 666 } 667 668 void 669 auimpl_engine_close(audio_stream_t *sp) 670 { 671 audio_engine_t *e = sp->s_engine; 672 audio_dev_t *d; 673 674 if (e == NULL) 675 return; 676 677 d = e->e_dev; 678 679 mutex_enter(&d->d_lock); 680 mutex_enter(&e->e_lock); 681 sp->s_engine = NULL; 682 list_remove(&e->e_streams, sp); 683 if (list_is_empty(&e->e_streams)) { 684 /* if last client holding engine open, close it all down */ 685 if (e->e_ops.audio_engine_stop != NULL) 686 ENG_STOP(e); 687 e->e_flags &= ENGINE_DRIVER_FLAGS; 688 ENG_CLOSE(e); 689 } 690 mutex_exit(&e->e_lock); 691 692 cv_broadcast(&d->d_cv); 693 mutex_exit(&d->d_lock); 694 } 695 696 int 697 audio_dev_register(audio_dev_t *d) 698 { 699 list_t *l; 700 audio_dev_t *srch; 701 int start; 702 703 /* 704 * Make sure we don't automatically unload. This prevents 705 * loss of hardware settings when no audio clients are 706 * running. 707 */ 708 (void) ddi_prop_update_int(DDI_DEV_T_NONE, d->d_dip, 709 DDI_NO_AUTODETACH, 1); 710 711 /* 712 * This does an in-order insertion, finding the first available 713 * free index. "Special" devices (ones without any actual engines) 714 * are all numbered 0. There should only be one of them anyway. 715 * All others start at one. 716 */ 717 if (d->d_flags & DEV_SNDSTAT_CAP) { 718 start = 0; 719 } else { 720 start = 1; 721 } 722 d->d_index = start; 723 rw_enter(&auimpl_dev_lock, RW_WRITER); 724 l = &auimpl_devs_by_index; 725 for (srch = list_head(l); srch; srch = list_next(l, srch)) { 726 /* skip over special nodes */ 727 if (srch->d_index < start) 728 continue; 729 if (srch->d_index > d->d_index) { 730 /* found a free spot! */ 731 break; 732 } 733 d->d_index++; 734 } 735 /* 736 * NB: If srch is NULL, then list_insert_before puts 737 * it on the tail of the list. So if we didn't find a 738 * hole, then that's where we want it. 739 */ 740 list_insert_before(l, srch, d); 741 742 /* insert in order by number */ 743 l = &auimpl_devs_by_number; 744 for (srch = list_head(l); srch; srch = list_next(l, srch)) { 745 if (srch->d_number >= d->d_number) { 746 break; 747 } 748 } 749 list_insert_before(l, srch, d); 750 751 rw_exit(&auimpl_dev_lock); 752 753 if (auimpl_create_minors(d) != 0) { 754 rw_enter(&auimpl_dev_lock, RW_WRITER); 755 auimpl_remove_minors(d); 756 list_remove(&auimpl_devs_by_index, d); 757 list_remove(&auimpl_devs_by_number, d); 758 rw_exit(&auimpl_dev_lock); 759 return (DDI_FAILURE); 760 } 761 762 return (DDI_SUCCESS); 763 } 764 765 int 766 audio_dev_unregister(audio_dev_t *d) 767 { 768 rw_enter(&auimpl_dev_lock, RW_WRITER); 769 770 mutex_enter(&d->d_lock); 771 /* if we are still in use, we can't unregister */ 772 if (d->d_refcnt) { 773 mutex_exit(&d->d_lock); 774 rw_exit(&auimpl_dev_lock); 775 return (DDI_FAILURE); 776 } 777 auimpl_remove_minors(d); 778 list_remove(&auimpl_devs_by_index, d); 779 list_remove(&auimpl_devs_by_number, d); 780 mutex_exit(&d->d_lock); 781 782 rw_exit(&auimpl_dev_lock); 783 784 return (DDI_SUCCESS); 785 } 786 787 static int 788 auimpl_engine_ksupdate(kstat_t *ksp, int rw) 789 { 790 audio_engine_t *e = ksp->ks_private; 791 struct audio_stats *st = &e->e_stats; 792 793 if (rw == KSTAT_WRITE) { 794 return (EACCES); 795 } 796 797 mutex_enter(&e->e_lock); 798 st->st_head.value.ui64 = e->e_head; 799 st->st_tail.value.ui64 = e->e_tail; 800 st->st_flags.value.ui32 = e->e_flags; 801 st->st_fragfr.value.ui32 = e->e_fragfr; 802 st->st_nfrags.value.ui32 = e->e_nfrags; 803 st->st_framesz.value.ui32 = e->e_framesz; 804 st->st_nbytes.value.ui32 = e->e_nbytes; 805 st->st_hidx.value.ui32 = e->e_hidx; 806 st->st_tidx.value.ui32 = e->e_tidx; 807 st->st_format.value.ui32 = e->e_format; 808 st->st_nchan.value.ui32 = e->e_nchan; 809 st->st_rate.value.ui32 = e->e_rate; 810 st->st_intrs.value.ui32 = e->e_intrs; 811 st->st_errors.value.ui32 = e->e_errors; 812 st->st_engine_underruns.value.ui32 = e->e_underruns; 813 st->st_engine_overruns.value.ui32 = e->e_overruns; 814 st->st_stream_underruns.value.ui32 = e->e_stream_underruns; 815 st->st_stream_overruns.value.ui32 = e->e_stream_overruns; 816 st->st_suspended.value.ui32 = e->e_suspended; 817 mutex_exit(&e->e_lock); 818 819 return (0); 820 } 821 822 static void 823 auimpl_engine_ksinit(audio_dev_t *d, audio_engine_t *e) 824 { 825 char name[32]; 826 struct audio_stats *st; 827 828 (void) snprintf(name, sizeof (name), "engine_%d", e->e_num); 829 830 e->e_ksp = kstat_create(ddi_driver_name(d->d_dip), d->d_instance, 831 name, "misc", KSTAT_TYPE_NAMED, 832 sizeof (struct audio_stats) / sizeof (kstat_named_t), 0); 833 834 if (e->e_ksp == NULL) { 835 audio_dev_warn(d, "unable to initialize kstats"); 836 return; 837 } 838 839 st = &e->e_stats; 840 e->e_ksp->ks_data = st; 841 e->e_ksp->ks_private = e; 842 e->e_ksp->ks_lock = NULL; 843 e->e_ksp->ks_update = auimpl_engine_ksupdate; 844 kstat_named_init(&st->st_head, "head", KSTAT_DATA_UINT64); 845 kstat_named_init(&st->st_tail, "tail", KSTAT_DATA_UINT64); 846 kstat_named_init(&st->st_flags, "flags", KSTAT_DATA_UINT32); 847 kstat_named_init(&st->st_fragfr, "fragfr", KSTAT_DATA_UINT32); 848 kstat_named_init(&st->st_nfrags, "nfrags", KSTAT_DATA_UINT32); 849 kstat_named_init(&st->st_framesz, "framesz", KSTAT_DATA_UINT32); 850 kstat_named_init(&st->st_nbytes, "nbytes", KSTAT_DATA_UINT32); 851 kstat_named_init(&st->st_hidx, "hidx", KSTAT_DATA_UINT32); 852 kstat_named_init(&st->st_tidx, "tidx", KSTAT_DATA_UINT32); 853 kstat_named_init(&st->st_format, "format", KSTAT_DATA_UINT32); 854 kstat_named_init(&st->st_nchan, "channels", KSTAT_DATA_UINT32); 855 kstat_named_init(&st->st_rate, "rate", KSTAT_DATA_UINT32); 856 kstat_named_init(&st->st_intrs, "intrhz", KSTAT_DATA_UINT32); 857 kstat_named_init(&st->st_errors, "errors", KSTAT_DATA_UINT32); 858 kstat_named_init(&st->st_engine_overruns, "engine_overruns", 859 KSTAT_DATA_UINT32); 860 kstat_named_init(&st->st_engine_underruns, "engine_underruns", 861 KSTAT_DATA_UINT32); 862 kstat_named_init(&st->st_stream_overruns, "stream_overruns", 863 KSTAT_DATA_UINT32); 864 kstat_named_init(&st->st_stream_underruns, "stream_underruns", 865 KSTAT_DATA_UINT32); 866 kstat_named_init(&st->st_suspended, "suspended", KSTAT_DATA_UINT32); 867 kstat_install(e->e_ksp); 868 } 869 870 void 871 audio_dev_add_engine(audio_dev_t *d, audio_engine_t *e) 872 { 873 e->e_num = d->d_engno++; 874 875 mutex_enter(&d->d_lock); 876 877 auimpl_engine_ksinit(d, e); 878 879 /* check for duplex */ 880 if ((e->e_flags & ENGINE_OUTPUT_CAP) && (d->d_flags & DEV_INPUT_CAP)) { 881 d->d_flags |= DEV_DUPLEX_CAP; 882 } 883 if ((e->e_flags & ENGINE_INPUT_CAP) && (d->d_flags & DEV_OUTPUT_CAP)) { 884 d->d_flags |= DEV_DUPLEX_CAP; 885 } 886 /* add in the direction caps -- must be done after duplex above */ 887 if (e->e_flags & ENGINE_OUTPUT_CAP) { 888 d->d_flags |= DEV_OUTPUT_CAP; 889 } 890 if (e->e_flags & ENGINE_INPUT_CAP) { 891 d->d_flags |= DEV_INPUT_CAP; 892 } 893 894 list_insert_tail(&d->d_engines, e); 895 e->e_dev = d; 896 mutex_exit(&d->d_lock); 897 } 898 899 void 900 audio_dev_remove_engine(audio_dev_t *d, audio_engine_t *e) 901 { 902 mutex_enter(&d->d_lock); 903 list_remove(&d->d_engines, e); 904 e->e_dev = NULL; 905 if (e->e_ksp) 906 kstat_delete(e->e_ksp); 907 e->e_ksp = NULL; 908 mutex_exit(&d->d_lock); 909 } 910 911 /* 912 * Change the number. 913 */ 914 void 915 auclnt_set_dev_number(audio_dev_t *d, int num) 916 { 917 list_t *l = &auimpl_devs_by_number; 918 audio_dev_t *srch; 919 920 /* reorder our list */ 921 rw_enter(&auimpl_dev_lock, RW_WRITER); 922 d->d_number = num; 923 list_remove(l, d); 924 for (srch = list_head(l); srch; srch = list_next(l, srch)) { 925 if (srch->d_number >= d->d_number) { 926 break; 927 } 928 } 929 list_insert_before(l, srch, d); 930 931 rw_exit(&auimpl_dev_lock); 932 } 933 934 void 935 auclnt_walk_devs(int (*walker)(audio_dev_t *, void *), void *arg) 936 { 937 audio_dev_t *d; 938 boolean_t cont; 939 list_t *l; 940 941 l = &auimpl_devs_by_index; 942 rw_enter(&auimpl_dev_lock, RW_READER); 943 for (d = list_head(l); d; d = list_next(l, d)) { 944 mutex_enter(&d->d_lock); 945 cont = walker(d, arg); 946 mutex_exit(&d->d_lock); 947 if (cont == AUDIO_WALK_STOP) 948 break; 949 } 950 rw_exit(&auimpl_dev_lock); 951 } 952 953 void 954 auclnt_walk_devs_by_number(int (*walker)(audio_dev_t *, void *), void *arg) 955 { 956 audio_dev_t *d; 957 boolean_t cont; 958 list_t *l; 959 960 l = &auimpl_devs_by_number; 961 rw_enter(&auimpl_dev_lock, RW_READER); 962 for (d = list_head(l); d; d = list_next(l, d)) { 963 mutex_enter(&d->d_lock); 964 cont = walker(d, arg); 965 mutex_exit(&d->d_lock); 966 if (cont == AUDIO_WALK_STOP) 967 break; 968 } 969 rw_exit(&auimpl_dev_lock); 970 } 971 972 void 973 auclnt_dev_walk_engines(audio_dev_t *d, 974 int (*walker)(audio_engine_t *, void *), 975 void *arg) 976 { 977 audio_engine_t *e; 978 list_t *l = &d->d_engines; 979 980 mutex_enter(&d->d_lock); 981 for (e = list_head(l); e != NULL; e = list_next(l, e)) { 982 if (walker(e, arg) == AUDIO_WALK_STOP) { 983 break; 984 } 985 } 986 mutex_exit(&d->d_lock); 987 } 988 989 int 990 auclnt_engine_get_format(audio_engine_t *e) 991 { 992 return (ENG_FORMAT(e)); 993 } 994 995 int 996 auclnt_engine_get_channels(audio_engine_t *e) 997 { 998 return (ENG_CHANNELS(e)); 999 } 1000 1001 int 1002 auclnt_engine_get_rate(audio_engine_t *e) 1003 { 1004 return (ENG_RATE(e)); 1005 } 1006 1007 unsigned 1008 auclnt_engine_get_capab(audio_engine_t *e) 1009 { 1010 unsigned capab = 0; 1011 1012 if (e->e_flags & ENGINE_INPUT_CAP) { 1013 capab |= AUDIO_CLIENT_CAP_RECORD; 1014 } 1015 if (e->e_flags & ENGINE_OUTPUT_CAP) { 1016 capab |= AUDIO_CLIENT_CAP_PLAY; 1017 } 1018 return (capab); 1019 } 1020 1021 static void 1022 auimpl_walk_engines(int (*walker)(audio_engine_t *, void *), void *arg) 1023 { 1024 audio_dev_t *d; 1025 audio_engine_t *e; 1026 list_t *l1; 1027 list_t *l2; 1028 boolean_t done = B_FALSE; 1029 1030 rw_enter(&auimpl_dev_lock, RW_READER); 1031 l1 = &auimpl_devs_by_index; 1032 for (d = list_head(l1); d; d = list_next(l1, d)) { 1033 mutex_enter(&d->d_lock); 1034 l2 = &d->d_engines; 1035 for (e = list_head(l2); e; e = list_next(l2, e)) { 1036 if (walker(e, arg) == AUDIO_WALK_STOP) { 1037 done = B_TRUE; 1038 break; 1039 } 1040 } 1041 mutex_exit(&d->d_lock); 1042 if (done) 1043 break; 1044 } 1045 rw_exit(&auimpl_dev_lock); 1046 } 1047 1048 /* 1049 * This function suspends an engine. The intent is to pause the 1050 * engine temporarily so that it does not underrun while user threads 1051 * are suspended. The driver is still responsible for actually doing 1052 * the driver suspend work -- all this does is put the engine in a 1053 * paused state. It does not prevent, for example, threads from 1054 * accessing the hardware. 1055 * 1056 * A properly implemented driver won't even be aware of the existence 1057 * of this routine -- the driver will just handle the suspend & 1058 * resume. At the point of suspend & resume, the driver will see that 1059 * the engines are not running (as if all threads had "paused" it). 1060 * 1061 * Failure to execute either of the routines below is not critical, 1062 * but will probably lead to underruns and overflows as the kernel 1063 * driver gets resumed well in advance of the time when user threads 1064 * are ready to start operation. 1065 */ 1066 static int 1067 auimpl_engine_suspend(audio_engine_t *e, void *dontcare) 1068 { 1069 _NOTE(ARGUNUSED(dontcare)); 1070 1071 mutex_enter(&e->e_lock); 1072 e->e_suspended = B_TRUE; 1073 mutex_exit(&e->e_lock); 1074 1075 return (AUDIO_WALK_CONTINUE); 1076 } 1077 1078 static int 1079 auimpl_engine_resume(audio_engine_t *e, void *dontcare) 1080 { 1081 _NOTE(ARGUNUSED(dontcare)); 1082 mutex_enter(&e->e_lock); 1083 e->e_suspended = B_FALSE; 1084 mutex_exit(&e->e_lock); 1085 return (AUDIO_WALK_CONTINUE); 1086 } 1087 1088 boolean_t 1089 auimpl_cpr(void *arg, int code) 1090 { 1091 _NOTE(ARGUNUSED(arg)); 1092 1093 switch (code) { 1094 case CB_CODE_CPR_CHKPT: 1095 auimpl_walk_engines(auimpl_engine_suspend, NULL); 1096 return (B_TRUE); 1097 1098 case CB_CODE_CPR_RESUME: 1099 auimpl_walk_engines(auimpl_engine_resume, NULL); 1100 return (B_TRUE); 1101 1102 default: 1103 return (B_FALSE); 1104 } 1105 } 1106 1107 static callb_id_t auimpl_cpr_id = 0; 1108 1109 void 1110 auimpl_dev_init(void) 1111 { 1112 rw_init(&auimpl_dev_lock, NULL, RW_DRIVER, NULL); 1113 list_create(&auimpl_devs_by_index, sizeof (struct audio_dev), 1114 offsetof(struct audio_dev, d_by_index)); 1115 list_create(&auimpl_devs_by_number, sizeof (struct audio_dev), 1116 offsetof(struct audio_dev, d_by_number)); 1117 1118 /* 1119 * We "borrow" the CB_CL_CPR_PM class, which gets executed at 1120 * about the right time for us. It would be nice to have a 1121 * new CB_CL_CPR_AUDIO class, but it isn't critical at this 1122 * point. 1123 * 1124 * Note that we don't care about our thread id. 1125 */ 1126 auimpl_cpr_id = callb_add(auimpl_cpr, NULL, CB_CL_CPR_PM, "audio_cpr"); 1127 } 1128 1129 void 1130 auimpl_dev_fini(void) 1131 { 1132 (void) callb_delete(auimpl_cpr_id); 1133 list_destroy(&auimpl_devs_by_index); 1134 list_destroy(&auimpl_devs_by_number); 1135 rw_destroy(&auimpl_dev_lock); 1136 } 1137 1138 void 1139 audio_engine_set_private(audio_engine_t *eng, void *prv) 1140 { 1141 eng->e_private = prv; 1142 } 1143 1144 void * 1145 audio_engine_get_private(audio_engine_t *eng) 1146 { 1147 return (eng->e_private); 1148 } 1149 1150 void 1151 audio_dump_bytes(const uint8_t *w, int dcount) 1152 { 1153 char line[64]; 1154 char *s; 1155 int i; 1156 const int wrap = 16; 1157 1158 s = line; 1159 line[0] = 0; 1160 1161 cmn_err(CE_NOTE, "starting @ %p", (void *)w); 1162 for (i = 0; i < dcount; i++) { 1163 1164 (void) sprintf(s, " %02x", *w); 1165 s += strlen(s); 1166 w++; 1167 1168 if ((i % wrap) == (wrap - 1)) { 1169 cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line); 1170 line[0] = 0; 1171 s = line; 1172 } 1173 } 1174 1175 if ((i % wrap) != 0) { 1176 cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line); 1177 } 1178 } 1179 1180 void 1181 audio_dump_words(const uint16_t *w, int dcount) 1182 { 1183 char line[64]; 1184 char *s; 1185 int i; 1186 const int wrap = 8; 1187 1188 s = line; 1189 line[0] = 0; 1190 1191 cmn_err(CE_NOTE, "starting @ %p", (void *)w); 1192 for (i = 0; i < dcount; i++) { 1193 1194 (void) sprintf(s, " %04x", *w); 1195 s += strlen(s); 1196 w++; 1197 1198 if ((i % wrap) == (wrap - 1)) { 1199 cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line); 1200 line[0] = 0; 1201 s = line; 1202 } 1203 } 1204 1205 if ((i % wrap) != 0) { 1206 cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line); 1207 } 1208 } 1209 1210 void 1211 audio_dump_dwords(const uint32_t *w, int dcount) 1212 { 1213 char line[128]; 1214 char *s; 1215 int i; 1216 const int wrap = 4; 1217 1218 s = line; 1219 line[0] = 0; 1220 1221 cmn_err(CE_NOTE, "starting @ %p", (void *)w); 1222 for (i = 0; i < dcount; i++) { 1223 1224 (void) sprintf(s, " %08x", *w); 1225 s += strlen(s); 1226 w++; 1227 1228 if ((i % wrap) == (wrap - 1)) { 1229 cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line); 1230 line[0] = 0; 1231 s = line; 1232 } 1233 } 1234 1235 if ((i % wrap) != 0) { 1236 cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line); 1237 } 1238 } 1239