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 * Sun audio(7I) and mixer(7I) personality. 28 * 29 * There are some "undocumented" details of how legacy Sun audio 30 * interfaces work. The following "rules" were derived from reading the 31 * legacy Sun mixer code, and to the best of our knowledge are not 32 * documented elsewhere. 33 * 34 * - We create a "fake" audio device, which behaves like a classic 35 * exclusive audio device, for each PID, as determined during open(2). 36 * 37 * - Different processes don't interfere with each other. Even though 38 * they are running concurrently, they each think they have exclusive 39 * control over the audio device. 40 * 41 * - Read and write directions operate independent of each other. That 42 * is, a device open for reading won't intefere with a future open for 43 * writing, and vice versa. This is true even within the same process. 44 * 45 * - Because the virtualization is by PID, strange behavior may occur 46 * if a process tries to open an audio device at the same time it 47 * has already received a file descriptor from another process (such 48 * through inheritence via fork()). 49 * 50 * - The "fake" audio device has no control over physical settings. 51 * It sees only the software attenuation-based volumes for play and 52 * record, and has no support for alternate input or output ports or 53 * access to the monitoring features of the hardware. 54 * 55 * - Explicit notificaton signals (SIGPOLL) are only ever sent up the 56 * audioctl node -- never up a regular audio node. (The stream head 57 * may still issue SIGPOLL based on readability/writability of 58 * course.) 59 * 60 * - Corollary: processes that want asynch. notifications will open 61 * /dev/audioctl as well as /dev/audio. 62 * 63 * - We don't support the MIXER mode at all. 64 * 65 * - By corollary, a process is only allowed to open /dev/audio once 66 * (in each direction.) 67 * 68 * - Attempts to open /dev/audio in duplex mode (O_RDWR) fail (EBUSY) 69 * if the device cannot support duplex operation. 70 * 71 * - Attempts to open a device with FREAD set fail if the device is not 72 * capable of recording. (Likewise for FWRITE and playback.) 73 * 74 * - No data transfer is permitted for audioctl nodes. (No actual 75 * record or play.) 76 * 77 * - Sun audio does not support any formats other than linear and 78 * ULAW/ALAW. I.e. it will never support AC3 or other "opaque" 79 * streams which require special handling. 80 * 81 * - Sun audio only supports stereo or monophonic data streams. 82 */ 83 84 #include <sys/types.h> 85 #include <sys/open.h> 86 #include <sys/errno.h> 87 #include <sys/audio.h> 88 #include <sys/mixer.h> 89 #include <sys/file.h> 90 #include <sys/stropts.h> 91 #include <sys/strsun.h> 92 #include <sys/sysmacros.h> 93 #include <sys/list.h> 94 #include <sys/note.h> 95 #include <sys/stat.h> 96 #include <sys/ddi.h> 97 #include <sys/sunddi.h> 98 #include "audio_client.h" 99 100 typedef struct sclient sclient_t; 101 typedef struct sdev sdev_t; 102 typedef struct sproc sproc_t; 103 typedef struct sioc sioc_t; 104 105 typedef enum { 106 COPYIN, 107 COPYOUT, 108 IOCTL, 109 ACK, 110 NAK, 111 FINI 112 } sioc_state_t; 113 114 struct sioc { 115 sclient_t *i_sc; 116 int i_cmd; 117 size_t i_size; 118 void *i_data; 119 mblk_t *i_bcont; 120 int i_step; 121 uint_t i_model; 122 sioc_state_t i_state; 123 mblk_t *i_mp; 124 caddr_t i_addr; 125 int i_error; 126 }; 127 128 /* common structure shared between both audioctl and audio nodes */ 129 struct sclient { 130 sproc_t *s_proc; 131 sdev_t *s_sdev; 132 audio_client_t *s_client; 133 queue_t *s_rq; 134 queue_t *s_wq; 135 ldi_handle_t s_lh; 136 unsigned s_eof; 137 list_t s_eofcnt; 138 kmutex_t s_lock; 139 mblk_t *s_draining; 140 }; 141 142 struct eofcnt { 143 list_node_t linkage; 144 uint64_t tail; 145 }; 146 147 struct sdev { 148 audio_dev_t *d_dev; 149 150 list_t d_procs; 151 kmutex_t d_mx; 152 kcondvar_t d_cv; 153 }; 154 155 struct sproc { 156 pid_t p_id; 157 struct audio_info p_info; 158 int p_refcnt; 159 int p_oflag; 160 list_node_t p_linkage; 161 sdev_t *p_sdev; 162 sclient_t *p_writer; 163 sclient_t *p_reader; 164 }; 165 166 int sproc_hold(audio_client_t *, ldi_handle_t, queue_t *, int); 167 void sproc_release(sclient_t *); 168 static void sproc_update(sproc_t *); 169 170 171 static kmutex_t sdev_lock; 172 static dev_info_t *sdev_dip; 173 174 /* 175 * Alloc extra room for ioctl buffer, in case none was supplied or copyin was 176 * shorter than we need for the whole struct. On failure, returns an 177 * appropriate errno, zero on success. Any original data is preserved. 178 */ 179 static int 180 sioc_alloc(sioc_t *ip, size_t size) 181 { 182 mblk_t *nmp; 183 184 /* if we already have enough, just use what we've got */ 185 if (ip->i_size >= size) 186 return (0); 187 188 if ((nmp = allocb(size, BPRI_MED)) == NULL) { 189 ip->i_state = NAK; 190 ip->i_error = ENOMEM; 191 return (ENOMEM); 192 } 193 bzero(nmp->b_rptr, size); 194 195 /* if there was already some data present, preserve it */ 196 if (ip->i_size != 0) { 197 bcopy(ip->i_data, nmp->b_rptr, ip->i_size); 198 freemsg(ip->i_bcont); 199 } 200 ip->i_bcont = nmp; 201 ip->i_data = nmp->b_rptr; 202 ip->i_size = size; 203 204 return (0); 205 } 206 207 static void 208 sioc_copyin(sioc_t *ip, size_t size) 209 { 210 ip->i_state = COPYIN; 211 ip->i_size = size; 212 if (ip->i_bcont != NULL) { 213 freemsg(ip->i_bcont); 214 ip->i_bcont = NULL; 215 } 216 217 mcopyin(ip->i_mp, ip, size, ip->i_addr); 218 } 219 220 static void 221 sioc_copyout(sioc_t *ip, size_t size) 222 { 223 mblk_t *bcont; 224 225 ASSERT(ip->i_size >= size); 226 227 bcont = ip->i_bcont; 228 229 ip->i_state = COPYOUT; 230 ip->i_bcont = NULL; 231 232 mcopyout(ip->i_mp, ip, size, ip->i_addr, bcont); 233 } 234 235 static void 236 sioc_error(sioc_t *ip, int error) 237 { 238 ip->i_state = NAK; 239 ip->i_error = error; 240 } 241 242 static void 243 sioc_success(sioc_t *ip) 244 { 245 ip->i_state = ACK; 246 } 247 248 static void 249 sioc_fini(sioc_t *ip) 250 { 251 if (ip->i_bcont != NULL) 252 freemsg(ip->i_bcont); 253 254 kmem_free(ip, sizeof (*ip)); 255 } 256 257 static void 258 sioc_finish(sioc_t *ip) 259 { 260 mblk_t *mp; 261 sclient_t *sc; 262 263 sc = ip->i_sc; 264 mp = ip->i_mp; 265 ip->i_mp = NULL; 266 267 switch (ip->i_state) { 268 case ACK: 269 miocack(sc->s_wq, mp, 0, 0); 270 break; 271 272 case IOCTL: /* caller didn't use sioc_success */ 273 ip->i_error = ECANCELED; 274 miocnak(sc->s_wq, mp, 0, ip->i_error); 275 break; 276 277 case NAK: 278 miocnak(sc->s_wq, mp, 0, ip->i_error); 279 break; 280 281 case COPYOUT: 282 case COPYIN: 283 /* data copy to be done */ 284 qreply(sc->s_wq, mp); 285 return; 286 287 case FINI: 288 if (mp != NULL) { 289 freemsg(mp); 290 } 291 break; 292 } 293 294 sioc_fini(ip); 295 } 296 297 static int 298 sun_compose_format(audio_prinfo_t *prinfo) 299 { 300 switch (prinfo->precision) { 301 case 8: 302 switch (prinfo->encoding) { 303 case AUDIO_ENCODING_ULAW: 304 return (AUDIO_FORMAT_ULAW); 305 case AUDIO_ENCODING_ALAW: 306 return (AUDIO_FORMAT_ALAW); 307 case AUDIO_ENCODING_LINEAR8: 308 return (AUDIO_FORMAT_U8); 309 case AUDIO_ENCODING_LINEAR: 310 return (AUDIO_FORMAT_S8); 311 } 312 break; 313 case 16: 314 if (prinfo->encoding == AUDIO_ENCODING_LINEAR) 315 return (AUDIO_FORMAT_S16_NE); 316 break; 317 case 32: 318 if (prinfo->encoding == AUDIO_ENCODING_LINEAR) 319 return (AUDIO_FORMAT_S32_NE); 320 break; 321 } 322 return (AUDIO_FORMAT_NONE); 323 324 } 325 326 static void 327 sun_decompose_format(audio_prinfo_t *prinfo, int afmt) 328 { 329 int e, p; 330 331 /* 332 * N.B.: Even though some of the formats below can't be set by 333 * this personality, reporting them (using the closest match) 334 * allows this personality to roughly approximate settings for 335 * other streams. It would be incredibly poor form for any 336 * personality to modify the format settings for a different 337 * personality, so we don't worry about that case. 338 */ 339 340 switch (afmt) { 341 case AUDIO_FORMAT_ULAW: 342 e = AUDIO_ENCODING_ULAW; 343 p = 8; 344 break; 345 346 case AUDIO_FORMAT_ALAW: 347 e = AUDIO_ENCODING_ALAW; 348 p = 8; 349 break; 350 351 case AUDIO_FORMAT_U8: 352 e = AUDIO_ENCODING_LINEAR8; 353 p = 8; 354 break; 355 356 case AUDIO_FORMAT_S8: 357 e = AUDIO_ENCODING_LINEAR; 358 p = 8; 359 break; 360 361 case AUDIO_FORMAT_S16_NE: 362 case AUDIO_FORMAT_S16_OE: 363 case AUDIO_FORMAT_U16_NE: 364 case AUDIO_FORMAT_U16_OE: 365 e = AUDIO_ENCODING_LINEAR; 366 p = 16; 367 break; 368 369 case AUDIO_FORMAT_S24_NE: 370 case AUDIO_FORMAT_S24_OE: 371 case AUDIO_FORMAT_S24_PACKED: 372 e = AUDIO_ENCODING_LINEAR; 373 p = 24; 374 break; 375 376 case AUDIO_FORMAT_S32_NE: 377 case AUDIO_FORMAT_S32_OE: 378 e = AUDIO_ENCODING_LINEAR; 379 p = 32; 380 break; 381 382 default: 383 /* all other formats (e.g. AC3) are uninterpreted */ 384 e = AUDIO_ENCODING_NONE; 385 p = 32; 386 break; 387 } 388 389 prinfo->encoding = e; 390 prinfo->precision = p; 391 } 392 393 static sproc_t * 394 sproc_alloc(sclient_t *sc) 395 { 396 audio_client_t *c; 397 audio_info_t *info; 398 audio_prinfo_t *prinfo; 399 uint32_t caps; 400 sproc_t *proc; 401 402 c = sc->s_client; 403 if ((proc = kmem_zalloc(sizeof (*proc), KM_NOSLEEP)) == NULL) { 404 return (NULL); 405 } 406 info = &proc->p_info; 407 408 /* 409 * audio(7I) says: Upon the initial open() of the audio 410 * device, the driver resets the data format of the device to 411 * the default state of 8-bit, 8Khz, mono u-Law data. 412 */ 413 prinfo = &info->play; 414 prinfo->channels = 1; 415 prinfo->sample_rate = 8000; 416 prinfo->encoding = AUDIO_ENCODING_ULAW; 417 prinfo->precision = 8; 418 prinfo->gain = AUDIO_MAX_GAIN; 419 prinfo->balance = AUDIO_MID_BALANCE; 420 prinfo->buffer_size = 8192; 421 prinfo->pause = B_FALSE; 422 prinfo->waiting = B_FALSE; 423 prinfo->open = B_FALSE; 424 prinfo->active = B_FALSE; 425 prinfo->samples = 0; 426 prinfo->eof = 0; 427 prinfo->error = 0; 428 prinfo->minordev = 0; 429 prinfo->port = AUDIO_SPEAKER; 430 prinfo->avail_ports = AUDIO_SPEAKER; 431 prinfo->mod_ports = AUDIO_NONE; 432 prinfo->_xxx = 0; 433 434 prinfo = &info->record; 435 prinfo->channels = 1; 436 prinfo->sample_rate = 8000; 437 prinfo->encoding = AUDIO_ENCODING_ULAW; 438 prinfo->precision = 8; 439 prinfo->gain = AUDIO_MAX_GAIN; 440 prinfo->balance = AUDIO_MID_BALANCE; 441 prinfo->buffer_size = 8192; 442 prinfo->waiting = B_FALSE; 443 prinfo->open = B_FALSE; 444 prinfo->active = B_FALSE; 445 prinfo->samples = 0; 446 prinfo->eof = 0; 447 prinfo->error = 0; 448 prinfo->minordev = 0; 449 prinfo->port = AUDIO_MICROPHONE; 450 prinfo->avail_ports = AUDIO_MICROPHONE; 451 prinfo->mod_ports = AUDIO_MICROPHONE; 452 453 info->output_muted = B_FALSE; 454 /* pretend we don't have a software mixer - we don't support the API */ 455 info->hw_features = 0; 456 info->sw_features = 0; 457 info->sw_features_enabled = 0; 458 459 caps = auclnt_get_dev_capab(auclnt_get_dev(c)); 460 if (caps & AUDIO_CLIENT_CAP_PLAY) 461 info->hw_features |= AUDIO_HWFEATURE_PLAY; 462 if (caps & AUDIO_CLIENT_CAP_RECORD) 463 info->hw_features |= AUDIO_HWFEATURE_RECORD; 464 if (caps & AUDIO_CLIENT_CAP_DUPLEX) 465 info->hw_features |= AUDIO_HWFEATURE_DUPLEX; 466 467 return (proc); 468 } 469 470 static void 471 sproc_free(sproc_t *proc) 472 { 473 kmem_free(proc, sizeof (*proc)); 474 } 475 476 int 477 sproc_hold(audio_client_t *c, ldi_handle_t lh, queue_t *rq, int oflag) 478 { 479 pid_t pid; 480 sproc_t *proc; 481 sdev_t *sdev; 482 sclient_t *sc; 483 list_t *l; 484 audio_dev_t *adev; 485 int rv; 486 487 adev = auclnt_get_dev(c); 488 489 /* first allocate and initialize the sclient private data */ 490 if ((sc = kmem_zalloc(sizeof (*sc), KM_NOSLEEP)) == NULL) { 491 return (ENOMEM); 492 } 493 494 mutex_init(&sc->s_lock, NULL, MUTEX_DRIVER, NULL); 495 list_create(&sc->s_eofcnt, sizeof (struct eofcnt), 496 offsetof(struct eofcnt, linkage)); 497 auclnt_set_private(c, sc); 498 499 sdev = auclnt_get_dev_minor_data(adev, AUDIO_MINOR_DEVAUDIO); 500 l = &sdev->d_procs; 501 pid = auclnt_get_pid(c); 502 503 /* set a couple of common fields */ 504 sc->s_client = c; 505 sc->s_sdev = sdev; 506 507 mutex_enter(&sdev->d_mx); 508 for (proc = list_head(l); proc != NULL; proc = list_next(l, proc)) { 509 if (proc->p_id == pid) { 510 proc->p_refcnt++; 511 break; 512 } 513 } 514 if (proc == NULL) { 515 if ((proc = sproc_alloc(sc)) == NULL) { 516 rv = ENOMEM; 517 goto failed; 518 } 519 proc->p_refcnt = 1; 520 proc->p_id = pid; 521 proc->p_sdev = sdev; 522 list_insert_tail(l, proc); 523 } 524 525 while (proc->p_oflag & oflag) { 526 527 if (oflag & (FNDELAY|FNONBLOCK)) { 528 rv = EBUSY; 529 goto failed; 530 } 531 if (oflag & FWRITE) 532 proc->p_info.play.waiting++; 533 if (oflag & FREAD) 534 proc->p_info.record.waiting++; 535 if (cv_wait_sig(&sdev->d_cv, &sdev->d_mx) == 0) { 536 /* interrupted! */ 537 if (oflag & FWRITE) 538 proc->p_info.play.waiting--; 539 if (oflag & FREAD) 540 proc->p_info.record.waiting--; 541 rv = EINTR; 542 goto failed; 543 } 544 if (oflag & FWRITE) 545 proc->p_info.play.waiting--; 546 if (oflag & FREAD) 547 proc->p_info.record.waiting--; 548 } 549 550 if (oflag & FWRITE) { 551 audio_prinfo_t *play = &proc->p_info.play; 552 audio_stream_t *sp = auclnt_output_stream(c); 553 554 if (((rv = auclnt_set_rate(sp, 8000)) != 0) || 555 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) || 556 ((rv = auclnt_set_channels(sp, 1)) != 0)) { 557 goto failed; 558 } 559 560 auclnt_set_samples(sp, 0); 561 auclnt_set_errors(sp, 0); 562 play->eof = 0; 563 play->buffer_size = 8192; 564 565 auclnt_set_gain(sp, ((play->gain * 100) / AUDIO_MAX_GAIN)); 566 auclnt_set_muted(sp, proc->p_info.output_muted); 567 play->open = B_TRUE; 568 proc->p_writer = sc; 569 proc->p_oflag |= FWRITE; 570 } 571 572 if (oflag & FREAD) { 573 audio_prinfo_t *rec = &proc->p_info.record; 574 audio_stream_t *sp = auclnt_input_stream(c); 575 576 if (((rv = auclnt_set_rate(sp, 8000)) != 0) || 577 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) || 578 ((rv = auclnt_set_channels(sp, 1)) != 0)) { 579 goto failed; 580 } 581 582 auclnt_set_samples(sp, 0); 583 auclnt_set_errors(sp, 0); 584 rec->eof = 0; 585 rec->buffer_size = 8192; 586 587 auclnt_set_gain(sp, ((rec->gain * 100) / AUDIO_MAX_GAIN)); 588 rec->open = B_TRUE; 589 proc->p_reader = sc; 590 proc->p_oflag |= FREAD; 591 } 592 593 sc->s_lh = lh; 594 sc->s_rq = rq; 595 sc->s_wq = WR(rq); 596 WR(rq)->q_ptr = rq->q_ptr = sc; 597 /* we update the s_proc last to avoid a race */ 598 sc->s_proc = proc; 599 600 sproc_update(proc); 601 602 mutex_exit(&sdev->d_mx); 603 604 return (0); 605 606 failed: 607 mutex_exit(&sdev->d_mx); 608 sproc_release(sc); 609 return (rv); 610 611 } 612 613 static void 614 sun_clear_eof(sclient_t *sc) 615 { 616 struct eofcnt *eof; 617 mutex_enter(&sc->s_lock); 618 while ((eof = list_remove_head(&sc->s_eofcnt)) != NULL) { 619 kmem_free(eof, sizeof (*eof)); 620 } 621 mutex_exit(&sc->s_lock); 622 } 623 624 void 625 sproc_release(sclient_t *sc) 626 { 627 sproc_t *proc; 628 sdev_t *sdev; 629 mblk_t *mp; 630 631 proc = sc->s_proc; 632 sdev = sc->s_sdev; 633 sc->s_proc = NULL; 634 635 mutex_enter(&sdev->d_mx); 636 637 if (proc != NULL) { 638 proc->p_refcnt--; 639 ASSERT(proc->p_refcnt >= 0); 640 641 if (sc == proc->p_writer) { 642 proc->p_oflag &= ~FWRITE; 643 proc->p_writer = NULL; 644 } 645 if (sc == proc->p_reader) { 646 proc->p_oflag &= ~FREAD; 647 proc->p_reader = NULL; 648 } 649 cv_broadcast(&sdev->d_cv); 650 651 if (proc->p_refcnt == 0) { 652 list_remove(&sdev->d_procs, proc); 653 sproc_free(proc); 654 } 655 sc->s_proc = NULL; 656 } 657 658 mutex_exit(&sdev->d_mx); 659 660 sun_clear_eof(sc); 661 662 while ((mp = sc->s_draining) != NULL) { 663 sc->s_draining = mp->b_next; 664 mp->b_next = NULL; 665 freemsg(mp); 666 } 667 668 mutex_destroy(&sc->s_lock); 669 list_destroy(&sc->s_eofcnt); 670 kmem_free(sc, sizeof (*sc)); 671 } 672 673 static void 674 sun_sendup(audio_client_t *c) 675 { 676 audio_stream_t *sp = auclnt_input_stream(c); 677 sclient_t *sc = auclnt_get_private(c); 678 unsigned framesz = auclnt_get_framesz(sp); 679 queue_t *rq = sc->s_rq; 680 mblk_t *mp; 681 unsigned nbytes = sc->s_proc->p_info.record.buffer_size; 682 unsigned count = nbytes / framesz; 683 684 /* 685 * Potentially send a message upstream with the record data. 686 * We collect this up in chunks of the buffer size requested 687 * by the client. 688 */ 689 690 while (auclnt_get_count(sp) >= count) { 691 692 if ((!canputnext(rq)) || 693 ((mp = allocb(nbytes, BPRI_MED)) == NULL)) { 694 /* 695 * This will apply back pressure to the 696 * buffer. We haven't yet lost any data, we 697 * just can't send it up. The point at which 698 * we have an unrecoverable overrun is in the 699 * buffer, not in the streams queue. So, no 700 * need to do anything right now. 701 * 702 * Note that since recording is enabled, we 703 * expect that the callback routine will be 704 * called repeatedly & regularly, so we don't 705 * have to worry about leaving data orphaned 706 * in the queue. 707 */ 708 break; 709 } 710 711 (void) auclnt_consume_data(sp, (caddr_t)mp->b_wptr, count); 712 mp->b_wptr += nbytes; 713 putnext(rq, mp); 714 } 715 } 716 717 static int 718 sun_open(audio_client_t *c, int oflag) 719 { 720 _NOTE(ARGUNUSED(c)); 721 _NOTE(ARGUNUSED(oflag)); 722 return (0); 723 } 724 725 static void 726 sun_close(audio_client_t *c) 727 { 728 _NOTE(ARGUNUSED(c)); 729 } 730 731 static void 732 sproc_update(sproc_t *proc) 733 { 734 audio_info_t *info; 735 audio_stream_t *sp; 736 sclient_t *sc; 737 738 info = &proc->p_info; 739 740 ASSERT(mutex_owned(&proc->p_sdev->d_mx)); 741 742 if ((sc = proc->p_writer) != NULL) { 743 sp = auclnt_output_stream(sc->s_client); 744 745 info->play.sample_rate = auclnt_get_rate(sp); 746 info->play.channels = auclnt_get_channels(sp); 747 sun_decompose_format(&info->play, auclnt_get_format(sp)); 748 749 info->play.gain = 750 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100; 751 info->play.pause = auclnt_is_paused(sp); 752 info->play.active = !info->play.pause; 753 info->play.samples = auclnt_get_samples(sp); 754 info->play.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE; 755 info->output_muted = auclnt_get_muted(sp); 756 } 757 758 if ((sc = proc->p_reader) != NULL) { 759 sp = auclnt_input_stream(sc->s_client); 760 761 info->record.sample_rate = auclnt_get_rate(sp); 762 info->record.channels = auclnt_get_channels(sp); 763 sun_decompose_format(&info->record, auclnt_get_format(sp)); 764 765 info->record.gain = 766 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100; 767 info->record.pause = auclnt_is_paused(sp); 768 info->record.active = !info->record.pause; 769 info->record.samples = auclnt_get_samples(sp); 770 info->record.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE; 771 } 772 } 773 774 static void 775 sioc_getinfo(sioc_t *ip) 776 { 777 sclient_t *sc = ip->i_sc; 778 sproc_t *proc = sc->s_proc; 779 int rv; 780 781 switch (ip->i_step) { 782 case 0: 783 if ((rv = sioc_alloc(ip, sizeof (audio_info_t))) != 0) { 784 sioc_error(ip, rv); 785 break; 786 } 787 788 mutex_enter(&sc->s_sdev->d_mx); 789 sproc_update(proc); 790 mutex_exit(&sc->s_sdev->d_mx); 791 792 bcopy(&proc->p_info, ip->i_data, sizeof (audio_info_t)); 793 sioc_copyout(ip, sizeof (audio_info_t)); 794 break; 795 case 1: 796 sioc_success(ip); 797 break; 798 } 799 800 ip->i_step++; 801 sioc_finish(ip); 802 } 803 804 #define CHANGED(new, old, field) \ 805 ((new->field != ((uint32_t)~0)) && (new->field != old->field)) 806 #define CHANGED8(new, old, field) \ 807 ((new->field != ((uint8_t)~0)) && (new->field != old->field)) 808 809 static int 810 sun_setinfo(sclient_t *sc, audio_info_t *ninfo) 811 { 812 sproc_t *proc = sc->s_proc; 813 audio_info_t *oinfo = &proc->p_info; 814 audio_prinfo_t *npr; 815 audio_prinfo_t *opr; 816 817 int pfmt = AUDIO_FORMAT_NONE; 818 int rfmt = AUDIO_FORMAT_NONE; 819 820 boolean_t reader; 821 boolean_t writer; 822 boolean_t isctl; 823 audio_stream_t *sp; 824 int rv; 825 826 if (auclnt_get_minor_type(sc->s_client) == AUDIO_MINOR_DEVAUDIOCTL) { 827 /* control node can do both read and write fields */ 828 isctl = B_TRUE; 829 reader = B_TRUE; 830 writer = B_TRUE; 831 } else { 832 isctl = B_FALSE; 833 writer = sc == proc->p_writer; 834 reader = sc == proc->p_reader; 835 } 836 837 /* 838 * Start by validating settings. 839 */ 840 npr = &ninfo->play; 841 opr = &oinfo->play; 842 843 if (writer && CHANGED(npr, opr, sample_rate)) { 844 if ((isctl) || 845 (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) { 846 return (EINVAL); 847 } 848 } 849 if (writer && CHANGED(npr, opr, channels)) { 850 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) { 851 return (EINVAL); 852 } 853 } 854 if (writer && 855 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) { 856 if (npr->encoding == (uint32_t)~0) 857 npr->encoding = opr->encoding; 858 if (npr->precision == (uint32_t)~0) 859 npr->precision = opr->precision; 860 pfmt = sun_compose_format(npr); 861 if ((isctl) || (pfmt == AUDIO_FORMAT_NONE)) { 862 return (EINVAL); 863 } 864 } 865 866 /* play fields that anyone can modify */ 867 if (CHANGED(npr, opr, gain)) { 868 if (npr->gain > AUDIO_MAX_GAIN) { 869 return (EINVAL); 870 } 871 } 872 873 874 npr = &ninfo->record; 875 opr = &oinfo->record; 876 877 if (reader && CHANGED(npr, opr, sample_rate)) { 878 if ((isctl) || 879 (npr->sample_rate < 5500) || 880 (npr->sample_rate > 48000)) { 881 return (EINVAL); 882 } 883 } 884 if (reader && CHANGED(npr, opr, channels)) { 885 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) { 886 return (EINVAL); 887 } 888 } 889 if (reader && 890 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) { 891 if (npr->encoding == (uint32_t)~0) 892 npr->encoding = opr->encoding; 893 if (npr->precision == (uint32_t)~0) 894 npr->precision = opr->precision; 895 rfmt = sun_compose_format(npr); 896 if ((isctl) || (rfmt == AUDIO_FORMAT_NONE)) { 897 return (EINVAL); 898 } 899 } 900 if (reader && CHANGED(npr, opr, buffer_size)) { 901 if (isctl) { 902 return (EINVAL); 903 } 904 /* make sure we can support 16-bit stereo samples */ 905 if ((npr->buffer_size % 4) != 0) { 906 npr->buffer_size = (npr->buffer_size + 3) & ~3; 907 } 908 /* limit the maximum buffer size somewhat */ 909 if (npr->buffer_size > 16384) { 910 npr->buffer_size = 16384; 911 } 912 } 913 914 /* record fields that anyone can modify */ 915 if (CHANGED(npr, opr, gain)) { 916 if (npr->gain > AUDIO_MAX_GAIN) { 917 return (EINVAL); 918 } 919 } 920 921 /* 922 * Now apply the changes. 923 */ 924 if (proc->p_writer != NULL) { 925 sp = auclnt_output_stream(proc->p_writer->s_client); 926 npr = &ninfo->play; 927 opr = &oinfo->play; 928 929 if (CHANGED(npr, opr, sample_rate)) { 930 rv = auclnt_set_rate(sp, npr->sample_rate); 931 if (rv != 0) 932 return (rv); 933 } 934 if (CHANGED(npr, opr, channels)) { 935 rv = auclnt_set_channels(sp, npr->channels); 936 if (rv != 0) 937 return (rv); 938 } 939 if (pfmt != AUDIO_FORMAT_NONE) { 940 rv = auclnt_set_format(sp, pfmt); 941 if (rv != 0) 942 return (rv); 943 } 944 if (CHANGED(npr, opr, samples)) { 945 auclnt_set_samples(sp, npr->samples); 946 } 947 if (CHANGED(npr, opr, eof)) { 948 /* 949 * This ugly special case code is required to 950 * prevent problems with realaudio. 951 */ 952 if (npr->eof == 0) { 953 sun_clear_eof(proc->p_writer); 954 } 955 opr->eof = npr->eof; 956 } 957 if (CHANGED8(npr, opr, pause)) { 958 if (npr->pause) { 959 auclnt_set_paused(sp); 960 } else { 961 auclnt_clear_paused(sp); 962 /* qenable to start up the playback */ 963 qenable(proc->p_writer->s_wq); 964 } 965 } 966 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) { 967 opr->waiting = npr->waiting; 968 } 969 if (CHANGED8(npr, opr, error)) { 970 auclnt_set_errors(sp, npr->error); 971 } 972 if (CHANGED(npr, opr, gain)) { 973 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN); 974 } 975 if (CHANGED8(ninfo, oinfo, output_muted)) { 976 auclnt_set_muted(sp, ninfo->output_muted); 977 } 978 if (CHANGED(npr, opr, buffer_size)) { 979 /* 980 * No checks on the buffer size are performed 981 * for play side. The value of the buffer size 982 * is meaningless for play side anyway. 983 */ 984 opr->buffer_size = npr->buffer_size; 985 } 986 } else { 987 /* these vaalues are preserved even if /dev/audio not open */ 988 if (CHANGED(npr, opr, gain)) { 989 opr->gain = npr->gain; 990 } 991 if (CHANGED8(ninfo, oinfo, output_muted)) { 992 oinfo->output_muted = ninfo->output_muted; 993 } 994 } 995 996 if (proc->p_reader != NULL) { 997 sp = auclnt_input_stream(proc->p_reader->s_client); 998 npr = &ninfo->record; 999 opr = &oinfo->record; 1000 1001 if (CHANGED(npr, opr, sample_rate)) { 1002 rv = auclnt_set_rate(sp, npr->sample_rate); 1003 if (rv != 0) 1004 return (rv); 1005 } 1006 if (CHANGED(npr, opr, channels)) { 1007 rv = auclnt_set_channels(sp, npr->channels); 1008 if (rv != 0) 1009 return (rv); 1010 } 1011 if (rfmt != AUDIO_FORMAT_NONE) { 1012 rv = auclnt_set_format(sp, rfmt); 1013 if (rv != 0) 1014 return (rv); 1015 } 1016 if (CHANGED(npr, opr, samples)) { 1017 auclnt_set_samples(sp, npr->samples); 1018 } 1019 if (CHANGED(npr, opr, eof)) { 1020 opr->eof = npr->eof; 1021 } 1022 if (CHANGED8(npr, opr, pause)) { 1023 if (npr->pause) { 1024 auclnt_set_paused(sp); 1025 } else { 1026 auclnt_clear_paused(sp); 1027 auclnt_start(sp); 1028 } 1029 } 1030 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) { 1031 opr->waiting = npr->waiting; 1032 } 1033 if (CHANGED8(npr, opr, error)) { 1034 auclnt_set_errors(sp, npr->error); 1035 } 1036 if (CHANGED(npr, opr, buffer_size)) { 1037 opr->buffer_size = npr->buffer_size; 1038 } 1039 if (CHANGED(npr, opr, gain)) { 1040 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN); 1041 } 1042 } else { 1043 /* these values are preserved even if /dev/audio not open */ 1044 if (CHANGED(npr, opr, gain)) { 1045 opr->gain = npr->gain; 1046 } 1047 } 1048 1049 return (0); 1050 } 1051 1052 static void 1053 sioc_setinfo(sioc_t *ip) 1054 { 1055 int rv; 1056 sclient_t *sc = ip->i_sc; 1057 audio_info_t *ninfo; 1058 1059 switch (ip->i_step) { 1060 case 0: 1061 sioc_copyin(ip, sizeof (audio_info_t)); 1062 break; 1063 1064 case 1: 1065 ninfo = (audio_info_t *)ip->i_data; 1066 1067 mutex_enter(&sc->s_sdev->d_mx); 1068 rv = sun_setinfo(ip->i_sc, ninfo); 1069 1070 if (rv != 0) { 1071 sioc_error(ip, rv); 1072 } else { 1073 sproc_update(sc->s_proc); 1074 1075 bcopy(&sc->s_proc->p_info, ninfo, sizeof (*ninfo)); 1076 sioc_copyout(ip, sizeof (audio_info_t)); 1077 } 1078 mutex_exit(&sc->s_sdev->d_mx); 1079 break; 1080 1081 case 2: 1082 sioc_success(ip); 1083 break; 1084 } 1085 1086 ip->i_step++; 1087 sioc_finish(ip); 1088 } 1089 1090 static void 1091 sioc_getdev(sioc_t *ip) 1092 { 1093 int rv; 1094 sclient_t *sc = ip->i_sc; 1095 audio_client_t *c = sc->s_client; 1096 audio_dev_t *d = auclnt_get_dev(c); 1097 1098 switch (ip->i_step) { 1099 case 0: 1100 rv = sioc_alloc(ip, sizeof (audio_device_t)); 1101 if (rv == 0) { 1102 audio_device_t *a = ip->i_data; 1103 1104 (void) snprintf(a->name, sizeof (a->name), 1105 "SUNW,%s", auclnt_get_dev_name(d)); 1106 (void) strlcpy(a->config, 1107 auclnt_get_dev_description(d), sizeof (a->config)); 1108 (void) strlcpy(a->version, 1109 auclnt_get_dev_version(d), sizeof (a->version)); 1110 sioc_copyout(ip, sizeof (*a)); 1111 } else { 1112 sioc_error(ip, rv); 1113 } 1114 break; 1115 1116 case 1: 1117 sioc_success(ip); 1118 break; 1119 } 1120 1121 ip->i_step++; 1122 sioc_finish(ip); 1123 } 1124 1125 static void 1126 sunstr_ioctl(sioc_t *ip) 1127 { 1128 switch (ip->i_cmd) { 1129 case AUDIO_GETINFO: 1130 sioc_getinfo(ip); 1131 break; 1132 1133 case AUDIO_SETINFO: 1134 sioc_setinfo(ip); 1135 break; 1136 1137 case AUDIO_GETDEV: 1138 sioc_getdev(ip); 1139 break; 1140 1141 case AUDIO_DIAG_LOOPBACK: 1142 /* we don't support this one */ 1143 sioc_error(ip, ENOTTY); 1144 sioc_finish(ip); 1145 break; 1146 1147 case AUDIO_MIXERCTL_GET_MODE: 1148 case AUDIO_MIXERCTL_SET_MODE: 1149 case AUDIO_MIXERCTL_GET_CHINFO: 1150 case AUDIO_MIXERCTL_SET_CHINFO: 1151 case AUDIO_MIXERCTL_GETINFO: 1152 case AUDIO_MIXERCTL_SETINFO: 1153 case AUDIO_GET_NUM_CHS: 1154 case AUDIO_GET_CH_NUMBER: 1155 case AUDIO_GET_CH_TYPE: 1156 case AUDIO_MIXER_SINGLE_OPEN: 1157 case AUDIO_MIXER_MULTIPLE_OPEN: 1158 case AUDIO_MIXER_GET_SAMPLE_RATES: 1159 default: 1160 sioc_error(ip, EINVAL); 1161 sioc_finish(ip); 1162 break; 1163 } 1164 } 1165 1166 static int 1167 sun_sigpoll(audio_client_t *c, void *arg) 1168 { 1169 sproc_t *proc = arg; 1170 sclient_t *sc; 1171 1172 if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) { 1173 sc = auclnt_get_private(c); 1174 /* we only need to notify peers in our own process */ 1175 if ((sc != NULL) && (sc->s_proc == proc)) { 1176 (void) putnextctl1(sc->s_rq, M_PCSIG, SIGPOLL); 1177 } 1178 } 1179 return (AUDIO_WALK_CONTINUE); 1180 } 1181 1182 static void 1183 sun_drain(audio_client_t *c) 1184 { 1185 sclient_t *sc = auclnt_get_private(c); 1186 mblk_t *mplist, *mp; 1187 1188 mutex_enter(&sc->s_lock); 1189 mplist = sc->s_draining; 1190 sc->s_draining = NULL; 1191 mutex_exit(&sc->s_lock); 1192 1193 while ((mp = mplist) != NULL) { 1194 mplist = mp->b_next; 1195 mp->b_next = NULL; 1196 miocack(sc->s_wq, mp, 0, 0); 1197 } 1198 } 1199 1200 static void 1201 sun_output(audio_client_t *c) 1202 { 1203 sclient_t *sc = auclnt_get_private(c); 1204 sproc_t *proc = sc->s_proc; 1205 uint64_t tail; 1206 struct eofcnt *eof; 1207 int eofs = 0; 1208 1209 tail = auclnt_get_tail(auclnt_output_stream(c)); 1210 1211 /* get more data! (do this early) */ 1212 qenable(sc->s_wq); 1213 1214 mutex_enter(&sc->s_lock); 1215 while (((eof = list_head(&sc->s_eofcnt)) != NULL) && 1216 (eof->tail < tail)) { 1217 list_remove(&sc->s_eofcnt, eof); 1218 kmem_free(eof, sizeof (*eof)); 1219 eofs++; 1220 } 1221 proc->p_info.play.eof += eofs; 1222 mutex_exit(&sc->s_lock); 1223 1224 if (eofs) { 1225 auclnt_dev_walk_clients(auclnt_get_dev(c), 1226 sun_sigpoll, proc); 1227 } 1228 } 1229 1230 static void 1231 sun_input(audio_client_t *c) 1232 { 1233 sun_sendup(c); 1234 } 1235 1236 static int 1237 sun_create_minors(audio_dev_t *adev, void *notused) 1238 { 1239 char path[MAXPATHLEN]; 1240 minor_t minor; 1241 int inst; 1242 int index; 1243 const char *driver; 1244 unsigned cap; 1245 1246 _NOTE(ARGUNUSED(notused)); 1247 1248 ASSERT(mutex_owned(&sdev_lock)); 1249 1250 /* don't create device nodes for sndstat device */ 1251 cap = auclnt_get_dev_capab(adev); 1252 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) { 1253 return (AUDIO_WALK_CONTINUE); 1254 } 1255 1256 index = auclnt_get_dev_index(adev); 1257 inst = auclnt_get_dev_instance(adev); 1258 driver = auclnt_get_dev_driver(adev); 1259 1260 if (sdev_dip != NULL) { 1261 1262 minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIO); 1263 (void) snprintf(path, sizeof (path), "sound,%s,audio%d", 1264 driver, inst); 1265 (void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor, 1266 DDI_NT_AUDIO, 0); 1267 1268 minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIOCTL); 1269 (void) snprintf(path, sizeof (path), "sound,%s,audioctl%d", 1270 driver, inst); 1271 (void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor, 1272 DDI_NT_AUDIO, 0); 1273 } 1274 1275 return (AUDIO_WALK_CONTINUE); 1276 } 1277 1278 static int 1279 sun_remove_minors(audio_dev_t *adev, void *notused) 1280 { 1281 char path[MAXPATHLEN]; 1282 int inst; 1283 const char *driver; 1284 unsigned cap; 1285 1286 _NOTE(ARGUNUSED(notused)); 1287 1288 ASSERT(mutex_owned(&sdev_lock)); 1289 1290 cap = auclnt_get_dev_capab(adev); 1291 /* if not a play or record device, don't bother creating minors */ 1292 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) { 1293 return (AUDIO_WALK_CONTINUE); 1294 } 1295 1296 inst = auclnt_get_dev_instance(adev); 1297 driver = auclnt_get_dev_driver(adev); 1298 1299 if (sdev_dip != NULL) { 1300 1301 (void) snprintf(path, sizeof (path), "sound,%s,audio%d", 1302 driver, inst); 1303 ddi_remove_minor_node(sdev_dip, path); 1304 1305 (void) snprintf(path, sizeof (path), "sound,%s,audioctl%d", 1306 driver, inst); 1307 ddi_remove_minor_node(sdev_dip, path); 1308 } 1309 1310 return (AUDIO_WALK_CONTINUE); 1311 } 1312 1313 static void * 1314 sun_dev_init(audio_dev_t *adev) 1315 { 1316 sdev_t *sdev; 1317 unsigned cap; 1318 1319 cap = auclnt_get_dev_capab(adev); 1320 /* if not a play or record device, don't bother initializing it */ 1321 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) { 1322 return (NULL); 1323 } 1324 1325 sdev = kmem_zalloc(sizeof (*sdev), KM_SLEEP); 1326 sdev->d_dev = adev; 1327 mutex_init(&sdev->d_mx, NULL, MUTEX_DRIVER, NULL); 1328 cv_init(&sdev->d_cv, NULL, CV_DRIVER, NULL); 1329 list_create(&sdev->d_procs, sizeof (struct sproc), 1330 offsetof(struct sproc, p_linkage)); 1331 1332 mutex_enter(&sdev_lock); 1333 (void) sun_create_minors(adev, NULL); 1334 mutex_exit(&sdev_lock); 1335 1336 return (sdev); 1337 } 1338 1339 static void 1340 sun_dev_fini(void *arg) 1341 { 1342 sdev_t *sdev = arg; 1343 1344 if (sdev != NULL) { 1345 1346 /* remove minor nodes */ 1347 mutex_enter(&sdev_lock); 1348 (void) sun_remove_minors(sdev->d_dev, NULL); 1349 mutex_exit(&sdev_lock); 1350 1351 mutex_destroy(&sdev->d_mx); 1352 cv_destroy(&sdev->d_cv); 1353 list_destroy(&sdev->d_procs); 1354 kmem_free(sdev, sizeof (*sdev)); 1355 } 1356 } 1357 1358 static struct audio_client_ops sun_ops = { 1359 "internal,audio", 1360 sun_dev_init, 1361 sun_dev_fini, 1362 sun_open, 1363 sun_close, 1364 NULL, /* read */ 1365 NULL, /* write */ 1366 NULL, /* ioctl */ 1367 NULL, /* chpoll */ 1368 NULL, /* mmap */ 1369 sun_input, 1370 sun_output, 1371 NULL, /* notify */ 1372 sun_drain, 1373 }; 1374 1375 static struct audio_client_ops sunctl_ops = { 1376 "internal,audioctl", 1377 NULL, /* dev_init */ 1378 NULL, /* dev_fini */ 1379 sun_open, 1380 sun_close, 1381 NULL, /* read */ 1382 NULL, /* write */ 1383 NULL, /* ioctl */ 1384 NULL, /* chpoll */ 1385 NULL, /* mmap */ 1386 NULL, /* output */ 1387 NULL, /* input */ 1388 NULL, /* notify */ 1389 NULL, /* drain */ 1390 }; 1391 1392 void 1393 auimpl_sun_init(void) 1394 { 1395 mutex_init(&sdev_lock, NULL, MUTEX_DRIVER, NULL); 1396 sdev_dip = NULL; 1397 auclnt_register_ops(AUDIO_MINOR_DEVAUDIO, &sun_ops); 1398 auclnt_register_ops(AUDIO_MINOR_DEVAUDIOCTL, &sunctl_ops); 1399 } 1400 1401 /* 1402 * This is the operations entry points that are streams specific... 1403 * We map "instance" numbers. 1404 */ 1405 1406 static int 1407 sunstr_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *cr) 1408 { 1409 int rv; 1410 minor_t minor; 1411 minor_t index; 1412 minor_t type; 1413 dev_t physdev; 1414 ldi_ident_t lid; 1415 ldi_handle_t lh = NULL; 1416 audio_client_t *c = NULL; 1417 audio_dev_t *adev; 1418 unsigned fmt; 1419 int oflag; 1420 boolean_t isopen = B_FALSE; 1421 1422 if (sflag != 0) { 1423 /* no direct clone or module opens */ 1424 return (EINVAL); 1425 } 1426 1427 /* 1428 * NB: We reuse the partitioning that the core framework is 1429 * using for instance numbering. This does mean that we are 1430 * limited to at most AUDIO_MN_INST_MASK devices, but this 1431 * number is sufficiently large (8192) that not to be a concern. 1432 */ 1433 1434 minor = getminor(*devp); 1435 index = (minor >> AUDIO_MN_INST_SHIFT) & AUDIO_MN_INST_MASK; 1436 type = (minor >> AUDIO_MN_TYPE_SHIFT) & AUDIO_MN_TYPE_MASK; 1437 1438 /* can't directly open a cloned node! */ 1439 if (minor & AUDIO_MN_CLONE_MASK) { 1440 return (ENXIO); 1441 } 1442 1443 switch (type) { 1444 case AUDIO_MINOR_DEVAUDIOCTL: 1445 fmt = AUDIO_FORMAT_NONE; 1446 oflag = flag & ~(FWRITE | FREAD); 1447 break; 1448 case AUDIO_MINOR_DEVAUDIO: 1449 fmt = AUDIO_FORMAT_PCM; 1450 oflag = flag; 1451 break; 1452 default: 1453 /* these minor types are not legal */ 1454 return (ENXIO); 1455 } 1456 1457 /* look up and hold the matching audio device */ 1458 adev = auclnt_hold_dev_by_index(index); 1459 if (adev == NULL) { 1460 return (ENXIO); 1461 } 1462 /* find the matching physical devt */ 1463 physdev = makedevice(ddi_driver_major(auclnt_get_dev_devinfo(adev)), 1464 AUDIO_MKMN(auclnt_get_dev_instance(adev), type)); 1465 1466 if ((rv = ldi_ident_from_stream(rq, &lid)) == 0) { 1467 rv = ldi_open_by_dev(&physdev, OTYP_CHR, flag, cr, &lh, lid); 1468 } 1469 1470 /* ldi open is done, lh holds device, and we can release our hold */ 1471 auclnt_release_dev(adev); 1472 1473 if (rv != 0) { 1474 goto fail; 1475 } 1476 /* phys layer clones a device for us */ 1477 ASSERT((getminor(physdev) & AUDIO_MN_CLONE_MASK) != 0); 1478 1479 /* 1480 * Note: We don't need to retain the hold on the client 1481 * structure, because the client is logically "held" by the 1482 * open LDI handle. We're just using this hold_by_devt to 1483 * locate the associated client. 1484 */ 1485 c = auclnt_hold_by_devt(physdev); 1486 ASSERT(c != NULL); 1487 auclnt_release(c); 1488 1489 if ((rv = auclnt_open(c, fmt, oflag)) != 0) { 1490 goto fail; 1491 } 1492 isopen = B_TRUE; 1493 1494 if ((rv = sproc_hold(c, lh, rq, oflag)) != 0) { 1495 goto fail; 1496 } 1497 1498 /* start up the input */ 1499 if (oflag & FREAD) { 1500 auclnt_start(auclnt_input_stream(c)); 1501 } 1502 1503 /* we just reuse same minor number that phys layer used */ 1504 *devp = makedevice(getmajor(*devp), getminor(physdev)); 1505 1506 qprocson(rq); 1507 1508 return (0); 1509 1510 fail: 1511 if (isopen) { 1512 auclnt_close(c); 1513 } 1514 if (lh != NULL) { 1515 (void) ldi_close(lh, flag, cr); 1516 } 1517 1518 return (rv); 1519 } 1520 1521 static int 1522 sunstr_close(queue_t *rq, int flag, cred_t *cr) 1523 { 1524 sclient_t *sc; 1525 audio_client_t *c; 1526 int rv; 1527 1528 sc = rq->q_ptr; 1529 c = sc->s_client; 1530 1531 if ((auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIO) && 1532 (ddi_can_receive_sig() || (ddi_get_pid() == 0))) { 1533 rv = auclnt_drain(c); 1534 } 1535 1536 auclnt_stop(auclnt_output_stream(c)); 1537 auclnt_stop(auclnt_input_stream(c)); 1538 1539 auclnt_close(c); 1540 1541 qprocsoff(rq); 1542 1543 (void) ldi_close(sc->s_lh, flag, cr); 1544 1545 sproc_release(sc); 1546 1547 return (rv); 1548 } 1549 1550 static void 1551 sunstr_miocdata(sclient_t *sc, mblk_t *mp) 1552 { 1553 struct copyresp *csp; 1554 sioc_t *ip; 1555 mblk_t *bcont; 1556 1557 csp = (void *)mp->b_rptr; 1558 1559 /* 1560 * If no state, then something "bad" has happened. 1561 */ 1562 if (((ip = (void *)csp->cp_private) == NULL) || (ip->i_sc != sc)) { 1563 miocnak(sc->s_wq, mp, 0, EFAULT); 1564 return; 1565 } 1566 1567 /* 1568 * If we failed to transfer data to/from userland, then we are 1569 * done. (Stream head will have notified userland.) 1570 */ 1571 if (csp->cp_rval != 0) { 1572 ip->i_state = FINI; 1573 ip->i_mp = mp; 1574 sioc_finish(ip); 1575 return; 1576 } 1577 1578 /* 1579 * Buffer area for ioctl is attached to chain. 1580 * For an ioctl that didn't have any data to copyin, 1581 * we might need to allocate a new buffer area. 1582 */ 1583 bcont = mp->b_cont; 1584 ip->i_bcont = bcont; 1585 mp->b_cont = NULL; 1586 1587 if (bcont != NULL) { 1588 ip->i_data = bcont->b_rptr; 1589 } 1590 1591 /* 1592 * Meaty part of data processing. 1593 */ 1594 ip->i_state = IOCTL; 1595 ip->i_mp = mp; 1596 1597 /* now, call the handler ioctl */ 1598 sunstr_ioctl(ip); 1599 } 1600 1601 static void 1602 sunstr_mioctl(sclient_t *sc, mblk_t *mp) 1603 { 1604 struct iocblk *iocp = (void *)mp->b_rptr; 1605 sioc_t *ip; 1606 1607 /* BSD legacy here: we only support transparent ioctls */ 1608 if (iocp->ioc_count != TRANSPARENT) { 1609 miocnak(sc->s_wq, mp, 0, EINVAL); 1610 return; 1611 } 1612 1613 ip = kmem_zalloc(sizeof (*ip), KM_NOSLEEP); 1614 if (ip == NULL) { 1615 miocnak(sc->s_wq, mp, 0, ENOMEM); 1616 return; 1617 } 1618 1619 /* make sure everything is setup in case we need to do copyin/out */ 1620 ip->i_sc = sc; 1621 ip->i_model = iocp->ioc_flag; 1622 ip->i_cmd = iocp->ioc_cmd; 1623 ip->i_addr = *(caddr_t *)(void *)mp->b_cont->b_rptr; 1624 ip->i_state = IOCTL; 1625 ip->i_mp = mp; 1626 freemsg(mp->b_cont); 1627 mp->b_cont = NULL; 1628 1629 /* now, call the handler ioctl */ 1630 sunstr_ioctl(ip); 1631 } 1632 1633 static int 1634 sunstr_wput(queue_t *wq, mblk_t *mp) 1635 { 1636 sclient_t *sc = wq->q_ptr; 1637 struct iocblk *iocp; 1638 1639 switch (DB_TYPE(mp)) { 1640 case M_IOCTL: 1641 /* Drain ioctl needs to be handled on the service queue */ 1642 iocp = (void *)mp->b_rptr; 1643 if (iocp->ioc_cmd == AUDIO_DRAIN) { 1644 if (auclnt_get_minor_type(sc->s_client) == 1645 AUDIO_MINOR_DEVAUDIO) { 1646 (void) putq(wq, mp); 1647 } else { 1648 miocnak(wq, mp, 0, EINVAL); 1649 } 1650 } else { 1651 sunstr_mioctl(sc, mp); 1652 } 1653 break; 1654 1655 case M_IOCDATA: 1656 sunstr_miocdata(sc, mp); 1657 break; 1658 1659 case M_FLUSH: 1660 /* 1661 * We don't flush the engine. The reason is that 1662 * other streams might be using the engine. This is 1663 * fundamentally no different from the case where the 1664 * engine hardware has data buffered in an 1665 * inaccessible FIFO. 1666 * 1667 * Clients that want to ensure no more data is coming 1668 * should stop the stream before flushing. 1669 */ 1670 if (*mp->b_rptr & FLUSHW) { 1671 flushq(wq, FLUSHALL); 1672 auclnt_flush(auclnt_output_stream(sc->s_client)); 1673 *mp->b_rptr &= ~FLUSHW; 1674 } 1675 if (*mp->b_rptr & FLUSHR) { 1676 flushq(RD(wq), FLUSHALL); 1677 auclnt_flush(auclnt_input_stream(sc->s_client)); 1678 qreply(wq, mp); 1679 } else { 1680 freemsg(mp); 1681 } 1682 break; 1683 1684 case M_DATA: 1685 /* 1686 * If we don't have an engine, then we can't accept 1687 * write() data. audio(7i) says we just ignore it, 1688 * so we toss it. 1689 */ 1690 if (auclnt_get_minor_type(sc->s_client) != 1691 AUDIO_MINOR_DEVAUDIO) { 1692 freemsg(mp); 1693 } else { 1694 /* 1695 * Defer processing to the queue. This keeps 1696 * the data ordered, and allows the wsrv 1697 * routine to gather multiple mblks at once. 1698 */ 1699 if (mp->b_cont != NULL) { 1700 1701 /* 1702 * If we need to pullup, do it here to 1703 * simplify the rest of the processing 1704 * later. This should rarely (if 1705 * ever) be necessary. 1706 */ 1707 mblk_t *nmp; 1708 1709 if ((nmp = msgpullup(mp, -1)) == NULL) { 1710 freemsg(mp); 1711 } else { 1712 freemsg(mp); 1713 (void) putq(wq, nmp); 1714 } 1715 } else { 1716 (void) putq(wq, mp); 1717 } 1718 } 1719 break; 1720 1721 default: 1722 freemsg(mp); 1723 break; 1724 } 1725 return (0); 1726 } 1727 1728 static int 1729 sunstr_wsrv(queue_t *wq) 1730 { 1731 sclient_t *sc = wq->q_ptr; 1732 audio_client_t *c = sc->s_client; 1733 audio_stream_t *sp; 1734 mblk_t *mp; 1735 unsigned framesz; 1736 1737 sp = auclnt_output_stream(c); 1738 1739 framesz = auclnt_get_framesz(sp); 1740 1741 while ((mp = getq(wq)) != NULL) { 1742 1743 unsigned count; 1744 1745 /* got a message */ 1746 1747 /* if its a drain ioctl, we need to process it here */ 1748 if (DB_TYPE(mp) == M_IOCTL) { 1749 ASSERT((*(int *)(void *)mp->b_rptr) == AUDIO_DRAIN); 1750 mutex_enter(&sc->s_lock); 1751 mp->b_next = sc->s_draining; 1752 sc->s_draining = mp; 1753 mutex_exit(&sc->s_lock); 1754 1755 if (auclnt_start_drain(c) != 0) { 1756 sun_drain(c); 1757 } 1758 continue; 1759 } 1760 1761 ASSERT(DB_TYPE(mp) == M_DATA); 1762 1763 /* 1764 * Empty mblk require special handling, since they 1765 * indicate EOF. We treat them separate from the main 1766 * processing loop. 1767 */ 1768 if (MBLKL(mp) == 0) { 1769 struct eofcnt *eof; 1770 1771 eof = kmem_zalloc(sizeof (*eof), KM_NOSLEEP); 1772 if (eof != NULL) { 1773 eof->tail = auclnt_get_head(sp); 1774 mutex_enter(&sc->s_lock); 1775 list_insert_tail(&sc->s_eofcnt, eof); 1776 mutex_exit(&sc->s_lock); 1777 } 1778 freemsg(mp); 1779 continue; 1780 } 1781 1782 count = auclnt_produce_data(sp, (caddr_t)mp->b_rptr, 1783 MBLKL(mp) / framesz); 1784 1785 mp->b_rptr += count * framesz; 1786 1787 if (MBLKL(mp) >= framesz) { 1788 (void) putbq(wq, mp); 1789 break; 1790 } else { 1791 freemsg(mp); 1792 } 1793 } 1794 1795 /* if the stream isn't running yet, start it up */ 1796 if (!auclnt_is_paused(sp)) 1797 auclnt_start(sp); 1798 1799 return (0); 1800 } 1801 1802 static int 1803 sunstr_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1804 { 1805 if ((cmd != DDI_ATTACH) || (dip == NULL)) { 1806 return (DDI_FAILURE); 1807 } 1808 if (ddi_get_instance(dip) != 0) { 1809 return (DDI_FAILURE); 1810 } 1811 1812 mutex_enter(&sdev_lock); 1813 sdev_dip = dip; 1814 auclnt_walk_devs(sun_create_minors, NULL); 1815 mutex_exit(&sdev_lock); 1816 ddi_report_dev(dip); 1817 1818 return (0); 1819 } 1820 1821 static int 1822 sunstr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1823 { 1824 if ((cmd != DDI_DETACH) || (dip == NULL)) { 1825 return (DDI_FAILURE); 1826 } 1827 if (ddi_get_instance(dip) != 0) { 1828 return (DDI_FAILURE); 1829 } 1830 1831 mutex_enter(&sdev_lock); 1832 /* remove all minors */ 1833 auclnt_walk_devs(sun_remove_minors, NULL); 1834 sdev_dip = NULL; 1835 mutex_exit(&sdev_lock); 1836 1837 return (0); 1838 } 1839 1840 static int 1841 sunstr_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 1842 { 1843 int error; 1844 1845 _NOTE(ARGUNUSED(dip)); 1846 _NOTE(ARGUNUSED(arg)); 1847 1848 switch (cmd) { 1849 case DDI_INFO_DEVT2DEVINFO: 1850 *result = sdev_dip; 1851 error = DDI_SUCCESS; 1852 break; 1853 case DDI_INFO_DEVT2INSTANCE: 1854 *result = 0; 1855 error = DDI_SUCCESS; 1856 break; 1857 default: 1858 *result = NULL; 1859 error = DDI_FAILURE; 1860 } 1861 return (error); 1862 } 1863 1864 static struct module_info sunstr_minfo = { 1865 0, /* used for strlog(1M) only, which we don't use */ 1866 "austr", 1867 0, /* min pkt size */ 1868 2048, /* max pkt size */ 1869 65536, /* hi water */ 1870 32768, /* lo water */ 1871 }; 1872 1873 static struct qinit sunstr_rqinit = { 1874 NULL, /* qi_putp */ 1875 NULL, /* qi_srvp */ 1876 sunstr_open, /* qi_qopen */ 1877 sunstr_close, /* qi_qclose */ 1878 NULL, /* qi_qadmin */ 1879 &sunstr_minfo, /* qi_minfo */ 1880 NULL, /* qi_mstat */ 1881 }; 1882 1883 static struct qinit sunstr_wqinit = { 1884 sunstr_wput, /* qi_putp */ 1885 sunstr_wsrv, /* qi_srvp */ 1886 NULL, /* qi_qopen */ 1887 NULL, /* qi_qclose */ 1888 NULL, /* qi_qadmin */ 1889 &sunstr_minfo, /* qi_minfo */ 1890 NULL, /* qi_mstat */ 1891 }; 1892 1893 static struct streamtab sunstr_strtab = { 1894 &sunstr_rqinit, 1895 &sunstr_wqinit, 1896 NULL, 1897 NULL 1898 }; 1899 1900 struct cb_ops sunstr_cb_ops = { 1901 nodev, /* open */ 1902 nodev, /* close */ 1903 nodev, /* strategy */ 1904 nodev, /* print */ 1905 nodev, /* dump */ 1906 nodev, /* read */ 1907 nodev, /* write */ 1908 nodev, /* ioctl */ 1909 nodev, /* devmap */ 1910 nodev, /* mmap */ 1911 nodev, /* segmap */ 1912 nochpoll, /* chpoll */ 1913 ddi_prop_op, /* prop_op */ 1914 &sunstr_strtab, /* str */ 1915 D_MP, /* flag */ 1916 CB_REV, /* rev */ 1917 nodev, /* aread */ 1918 nodev, /* awrite */ 1919 }; 1920 1921 static struct dev_ops sunstr_dev_ops = { 1922 DEVO_REV, /* rev */ 1923 0, /* refcnt */ 1924 sunstr_getinfo, /* getinfo */ 1925 nulldev, /* identify */ 1926 nulldev, /* probe */ 1927 sunstr_attach, /* attach */ 1928 sunstr_detach, /* detach */ 1929 nodev, /* reset */ 1930 &sunstr_cb_ops, /* cb_ops */ 1931 NULL, /* bus_ops */ 1932 NULL, /* power */ 1933 }; 1934 1935 static struct modldrv sunstr_modldrv = { 1936 &mod_driverops, 1937 "Audio Streams Support", 1938 &sunstr_dev_ops, 1939 }; 1940 1941 static struct modlinkage sunstr_modlinkage = { 1942 MODREV_1, /* MODREV_1 indicated by manual */ 1943 &sunstr_modldrv, 1944 NULL 1945 }; 1946 1947 int 1948 sunstr_init(void) 1949 { 1950 /* 1951 * NB: This *must* be called after the "audio" module's 1952 * _init routine has called auimpl_sun_init(). 1953 */ 1954 return (mod_install(&sunstr_modlinkage)); 1955 } 1956 1957 int 1958 sunstr_fini(void) 1959 { 1960 return (mod_remove(&sunstr_modlinkage)); 1961 } 1962 1963 int 1964 sunstr_info(struct modinfo *modinfop) 1965 { 1966 return (mod_info(&sunstr_modlinkage, modinfop)); 1967 } 1968