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 *, 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, 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 sc->s_proc = proc; 526 527 while (proc->p_oflag & oflag) { 528 529 if (oflag & (FNDELAY|FNONBLOCK)) { 530 rv = EBUSY; 531 goto failed; 532 } 533 if (oflag & FWRITE) 534 proc->p_info.play.waiting++; 535 if (oflag & FREAD) 536 proc->p_info.record.waiting++; 537 if (cv_wait_sig(&sdev->d_cv, &sdev->d_mx) == 0) { 538 /* interrupted! */ 539 if (oflag & FWRITE) 540 proc->p_info.play.waiting--; 541 if (oflag & FREAD) 542 proc->p_info.record.waiting--; 543 rv = EINTR; 544 goto failed; 545 } 546 if (oflag & FWRITE) 547 proc->p_info.play.waiting--; 548 if (oflag & FREAD) 549 proc->p_info.record.waiting--; 550 } 551 552 if (oflag & FWRITE) { 553 audio_prinfo_t *play = &proc->p_info.play; 554 audio_stream_t *sp = auclnt_output_stream(c); 555 556 if (((rv = auclnt_set_rate(sp, 8000)) != 0) || 557 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) || 558 ((rv = auclnt_set_channels(sp, 1)) != 0)) { 559 goto failed; 560 } 561 562 auclnt_set_samples(sp, 0); 563 auclnt_set_errors(sp, 0); 564 play->eof = 0; 565 play->buffer_size = 8192; 566 567 auclnt_set_gain(sp, ((play->gain * 100) / AUDIO_MAX_GAIN)); 568 auclnt_set_muted(sp, proc->p_info.output_muted); 569 play->open = B_TRUE; 570 proc->p_writer = sc; 571 proc->p_oflag |= FWRITE; 572 } 573 574 if (oflag & FREAD) { 575 audio_prinfo_t *rec = &proc->p_info.record; 576 audio_stream_t *sp = auclnt_input_stream(c); 577 578 if (((rv = auclnt_set_rate(sp, 8000)) != 0) || 579 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) || 580 ((rv = auclnt_set_channels(sp, 1)) != 0)) { 581 goto failed; 582 } 583 584 auclnt_set_samples(sp, 0); 585 auclnt_set_errors(sp, 0); 586 rec->eof = 0; 587 rec->buffer_size = 8192; 588 589 auclnt_set_gain(sp, ((rec->gain * 100) / AUDIO_MAX_GAIN)); 590 rec->open = B_TRUE; 591 proc->p_reader = sc; 592 proc->p_oflag |= FREAD; 593 } 594 595 sproc_update(proc); 596 597 mutex_exit(&sdev->d_mx); 598 599 return (0); 600 601 failed: 602 mutex_exit(&sdev->d_mx); 603 sproc_release(sc); 604 return (rv); 605 606 } 607 608 static void 609 sun_clear_eof(sclient_t *sc) 610 { 611 struct eofcnt *eof; 612 mutex_enter(&sc->s_lock); 613 while ((eof = list_remove_head(&sc->s_eofcnt)) != NULL) { 614 kmem_free(eof, sizeof (*eof)); 615 } 616 mutex_exit(&sc->s_lock); 617 } 618 619 void 620 sproc_release(sclient_t *sc) 621 { 622 sproc_t *proc; 623 sdev_t *sdev; 624 mblk_t *mp; 625 626 proc = sc->s_proc; 627 sdev = sc->s_sdev; 628 sc->s_proc = NULL; 629 630 mutex_enter(&sdev->d_mx); 631 632 if (proc != NULL) { 633 proc->p_refcnt--; 634 ASSERT(proc->p_refcnt >= 0); 635 636 if (sc == proc->p_writer) { 637 proc->p_oflag &= ~FWRITE; 638 proc->p_writer = NULL; 639 } 640 if (sc == proc->p_reader) { 641 proc->p_oflag &= ~FREAD; 642 proc->p_reader = NULL; 643 } 644 cv_broadcast(&sdev->d_cv); 645 646 if (proc->p_refcnt == 0) { 647 list_remove(&sdev->d_procs, proc); 648 sproc_free(proc); 649 } 650 sc->s_proc = NULL; 651 } 652 653 mutex_exit(&sdev->d_mx); 654 655 sun_clear_eof(sc); 656 657 while ((mp = sc->s_draining) != NULL) { 658 sc->s_draining = mp->b_next; 659 mp->b_next = NULL; 660 freemsg(mp); 661 } 662 663 mutex_destroy(&sc->s_lock); 664 list_destroy(&sc->s_eofcnt); 665 kmem_free(sc, sizeof (*sc)); 666 } 667 668 static void 669 sun_sendup(audio_client_t *c) 670 { 671 audio_stream_t *sp = auclnt_input_stream(c); 672 sclient_t *sc = auclnt_get_private(c); 673 unsigned framesz = auclnt_get_framesz(sp); 674 queue_t *rq = sc->s_rq; 675 mblk_t *mp; 676 unsigned nbytes = sc->s_proc->p_info.record.buffer_size; 677 unsigned count = nbytes / framesz; 678 679 /* 680 * Potentially send a message upstream with the record data. 681 * We collect this up in chunks of the buffer size requested 682 * by the client. 683 */ 684 685 while (auclnt_get_count(sp) >= count) { 686 687 if ((!canputnext(rq)) || 688 ((mp = allocb(nbytes, BPRI_MED)) == NULL)) { 689 /* 690 * This will apply back pressure to the 691 * buffer. We haven't yet lost any data, we 692 * just can't send it up. The point at which 693 * we have an unrecoverable overrun is in the 694 * buffer, not in the streams queue. So, no 695 * need to do anything right now. 696 * 697 * Note that since recording is enabled, we 698 * expect that the callback routine will be 699 * called repeatedly & regularly, so we don't 700 * have to worry about leaving data orphaned 701 * in the queue. 702 */ 703 break; 704 } 705 706 (void) auclnt_consume_data(sp, (caddr_t)mp->b_wptr, count); 707 mp->b_wptr += nbytes; 708 putnext(rq, mp); 709 } 710 } 711 712 static int 713 sun_open(audio_client_t *c, int oflag) 714 { 715 _NOTE(ARGUNUSED(c)); 716 _NOTE(ARGUNUSED(oflag)); 717 return (0); 718 } 719 720 static void 721 sun_close(audio_client_t *c) 722 { 723 _NOTE(ARGUNUSED(c)); 724 } 725 726 static void 727 sproc_update(sproc_t *proc) 728 { 729 audio_info_t *info; 730 audio_stream_t *sp; 731 sclient_t *sc; 732 733 info = &proc->p_info; 734 735 ASSERT(mutex_owned(&proc->p_sdev->d_mx)); 736 737 if ((sc = proc->p_writer) != NULL) { 738 sp = auclnt_output_stream(sc->s_client); 739 740 info->play.sample_rate = auclnt_get_rate(sp); 741 info->play.channels = auclnt_get_channels(sp); 742 sun_decompose_format(&info->play, auclnt_get_format(sp)); 743 744 info->play.gain = 745 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100; 746 info->play.pause = auclnt_is_paused(sp); 747 info->play.active = !info->play.pause; 748 info->play.samples = auclnt_get_samples(sp); 749 info->play.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE; 750 info->output_muted = auclnt_get_muted(sp); 751 } 752 753 if ((sc = proc->p_reader) != NULL) { 754 sp = auclnt_input_stream(sc->s_client); 755 756 info->record.sample_rate = auclnt_get_rate(sp); 757 info->record.channels = auclnt_get_channels(sp); 758 sun_decompose_format(&info->record, auclnt_get_format(sp)); 759 760 info->record.gain = 761 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100; 762 info->record.pause = auclnt_is_paused(sp); 763 info->record.active = !info->record.pause; 764 info->record.samples = auclnt_get_samples(sp); 765 info->record.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE; 766 } 767 } 768 769 static void 770 sioc_getinfo(sioc_t *ip) 771 { 772 sclient_t *sc = ip->i_sc; 773 sproc_t *proc = sc->s_proc; 774 int rv; 775 776 switch (ip->i_step) { 777 case 0: 778 if ((rv = sioc_alloc(ip, sizeof (audio_info_t))) != 0) { 779 sioc_error(ip, rv); 780 break; 781 } 782 783 mutex_enter(&sc->s_sdev->d_mx); 784 sproc_update(proc); 785 mutex_exit(&sc->s_sdev->d_mx); 786 787 bcopy(&proc->p_info, ip->i_data, sizeof (audio_info_t)); 788 sioc_copyout(ip, sizeof (audio_info_t)); 789 break; 790 case 1: 791 sioc_success(ip); 792 break; 793 } 794 795 ip->i_step++; 796 sioc_finish(ip); 797 } 798 799 #define CHANGED(new, old, field) \ 800 ((new->field != ((uint32_t)~0)) && (new->field != old->field)) 801 #define CHANGED8(new, old, field) \ 802 ((new->field != ((uint8_t)~0)) && (new->field != old->field)) 803 804 static int 805 sun_setinfo(sclient_t *sc, audio_info_t *ninfo) 806 { 807 sproc_t *proc = sc->s_proc; 808 audio_info_t *oinfo = &proc->p_info; 809 audio_prinfo_t *npr; 810 audio_prinfo_t *opr; 811 812 int pfmt = AUDIO_FORMAT_NONE; 813 int rfmt = AUDIO_FORMAT_NONE; 814 815 boolean_t reader; 816 boolean_t writer; 817 boolean_t isctl; 818 audio_stream_t *sp; 819 int rv; 820 821 if (auclnt_get_minor_type(sc->s_client) == AUDIO_MINOR_DEVAUDIOCTL) { 822 /* control node can do both read and write fields */ 823 isctl = B_TRUE; 824 reader = B_TRUE; 825 writer = B_TRUE; 826 } else { 827 isctl = B_FALSE; 828 writer = sc == proc->p_writer; 829 reader = sc == proc->p_reader; 830 } 831 832 /* 833 * Start by validating settings. 834 */ 835 npr = &ninfo->play; 836 opr = &oinfo->play; 837 838 if (writer && CHANGED(npr, opr, sample_rate)) { 839 if ((isctl) || 840 (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) { 841 return (EINVAL); 842 } 843 } 844 if (writer && CHANGED(npr, opr, channels)) { 845 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) { 846 return (EINVAL); 847 } 848 } 849 if (writer && 850 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) { 851 if (npr->encoding == (uint32_t)~0) 852 npr->encoding = opr->encoding; 853 if (npr->precision == (uint32_t)~0) 854 npr->precision = opr->precision; 855 pfmt = sun_compose_format(npr); 856 if ((isctl) || (pfmt == AUDIO_FORMAT_NONE)) { 857 return (EINVAL); 858 } 859 } 860 861 /* play fields that anyone can modify */ 862 if (CHANGED(npr, opr, gain)) { 863 if (npr->gain > AUDIO_MAX_GAIN) { 864 return (EINVAL); 865 } 866 } 867 868 869 npr = &ninfo->record; 870 opr = &oinfo->record; 871 872 if (reader && CHANGED(npr, opr, sample_rate)) { 873 if ((isctl) || 874 (npr->sample_rate < 5500) || 875 (npr->sample_rate > 48000)) { 876 return (EINVAL); 877 } 878 } 879 if (reader && CHANGED(npr, opr, channels)) { 880 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) { 881 return (EINVAL); 882 } 883 } 884 if (reader && 885 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) { 886 if (npr->encoding == (uint32_t)~0) 887 npr->encoding = opr->encoding; 888 if (npr->precision == (uint32_t)~0) 889 npr->precision = opr->precision; 890 rfmt = sun_compose_format(npr); 891 if ((isctl) || (rfmt == AUDIO_FORMAT_NONE)) { 892 return (EINVAL); 893 } 894 } 895 if (reader && CHANGED(npr, opr, buffer_size)) { 896 if (isctl) { 897 return (EINVAL); 898 } 899 /* make sure we can support 16-bit stereo samples */ 900 if ((npr->buffer_size % 4) != 0) { 901 npr->buffer_size = (npr->buffer_size + 3) & ~3; 902 } 903 /* limit the maximum buffer size somewhat */ 904 if (npr->buffer_size > 16384) { 905 npr->buffer_size = 16384; 906 } 907 } 908 909 /* record fields that anyone can modify */ 910 if (CHANGED(npr, opr, gain)) { 911 if (npr->gain > AUDIO_MAX_GAIN) { 912 return (EINVAL); 913 } 914 } 915 916 /* 917 * Now apply the changes. 918 */ 919 if (proc->p_writer != NULL) { 920 sp = auclnt_output_stream(proc->p_writer->s_client); 921 npr = &ninfo->play; 922 opr = &oinfo->play; 923 924 if (CHANGED(npr, opr, sample_rate)) { 925 rv = auclnt_set_rate(sp, npr->sample_rate); 926 if (rv != 0) 927 return (rv); 928 } 929 if (CHANGED(npr, opr, channels)) { 930 rv = auclnt_set_channels(sp, npr->channels); 931 if (rv != 0) 932 return (rv); 933 } 934 if (pfmt != AUDIO_FORMAT_NONE) { 935 rv = auclnt_set_format(sp, pfmt); 936 if (rv != 0) 937 return (rv); 938 } 939 if (CHANGED(npr, opr, samples)) { 940 auclnt_set_samples(sp, npr->samples); 941 } 942 if (CHANGED(npr, opr, eof)) { 943 /* 944 * This ugly special case code is required to 945 * prevent problems with realaudio. 946 */ 947 if (npr->eof == 0) { 948 sun_clear_eof(proc->p_writer); 949 } 950 opr->eof = npr->eof; 951 } 952 if (CHANGED8(npr, opr, pause)) { 953 if (npr->pause) { 954 auclnt_set_paused(sp); 955 } else { 956 auclnt_clear_paused(sp); 957 /* qenable to start up the playback */ 958 qenable(proc->p_writer->s_wq); 959 } 960 } 961 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) { 962 opr->waiting = npr->waiting; 963 } 964 if (CHANGED8(npr, opr, error)) { 965 auclnt_set_errors(sp, npr->error); 966 } 967 if (CHANGED(npr, opr, gain)) { 968 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN); 969 } 970 if (CHANGED8(ninfo, oinfo, output_muted)) { 971 auclnt_set_muted(sp, ninfo->output_muted); 972 } 973 if (CHANGED(npr, opr, buffer_size)) { 974 /* 975 * No checks on the buffer size are performed 976 * for play side. The value of the buffer size 977 * is meaningless for play side anyway. 978 */ 979 opr->buffer_size = npr->buffer_size; 980 } 981 } else { 982 /* these vaalues are preserved even if /dev/audio not open */ 983 if (CHANGED(npr, opr, gain)) { 984 opr->gain = npr->gain; 985 } 986 if (CHANGED8(ninfo, oinfo, output_muted)) { 987 oinfo->output_muted = ninfo->output_muted; 988 } 989 } 990 991 if (proc->p_reader != NULL) { 992 sp = auclnt_input_stream(proc->p_reader->s_client); 993 npr = &ninfo->record; 994 opr = &oinfo->record; 995 996 if (CHANGED(npr, opr, sample_rate)) { 997 rv = auclnt_set_rate(sp, npr->sample_rate); 998 if (rv != 0) 999 return (rv); 1000 } 1001 if (CHANGED(npr, opr, channels)) { 1002 rv = auclnt_set_channels(sp, npr->channels); 1003 if (rv != 0) 1004 return (rv); 1005 } 1006 if (rfmt != AUDIO_FORMAT_NONE) { 1007 rv = auclnt_set_format(sp, rfmt); 1008 if (rv != 0) 1009 return (rv); 1010 } 1011 if (CHANGED(npr, opr, samples)) { 1012 auclnt_set_samples(sp, npr->samples); 1013 } 1014 if (CHANGED(npr, opr, eof)) { 1015 opr->eof = npr->eof; 1016 } 1017 if (CHANGED8(npr, opr, pause)) { 1018 if (npr->pause) { 1019 auclnt_set_paused(sp); 1020 } else { 1021 auclnt_clear_paused(sp); 1022 auclnt_start(sp); 1023 } 1024 } 1025 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) { 1026 opr->waiting = npr->waiting; 1027 } 1028 if (CHANGED8(npr, opr, error)) { 1029 auclnt_set_errors(sp, npr->error); 1030 } 1031 if (CHANGED(npr, opr, buffer_size)) { 1032 opr->buffer_size = npr->buffer_size; 1033 } 1034 if (CHANGED(npr, opr, gain)) { 1035 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN); 1036 } 1037 } else { 1038 /* these values are preserved even if /dev/audio not open */ 1039 if (CHANGED(npr, opr, gain)) { 1040 opr->gain = npr->gain; 1041 } 1042 } 1043 1044 return (0); 1045 } 1046 1047 static void 1048 sioc_setinfo(sioc_t *ip) 1049 { 1050 int rv; 1051 sclient_t *sc = ip->i_sc; 1052 audio_info_t *ninfo; 1053 1054 switch (ip->i_step) { 1055 case 0: 1056 sioc_copyin(ip, sizeof (audio_info_t)); 1057 break; 1058 1059 case 1: 1060 ninfo = (audio_info_t *)ip->i_data; 1061 1062 mutex_enter(&sc->s_sdev->d_mx); 1063 rv = sun_setinfo(ip->i_sc, ninfo); 1064 1065 if (rv != 0) { 1066 sioc_error(ip, rv); 1067 } else { 1068 sproc_update(sc->s_proc); 1069 1070 bcopy(&sc->s_proc->p_info, ninfo, sizeof (*ninfo)); 1071 sioc_copyout(ip, sizeof (audio_info_t)); 1072 } 1073 mutex_exit(&sc->s_sdev->d_mx); 1074 break; 1075 1076 case 2: 1077 sioc_success(ip); 1078 break; 1079 } 1080 1081 ip->i_step++; 1082 sioc_finish(ip); 1083 } 1084 1085 static void 1086 sioc_getdev(sioc_t *ip) 1087 { 1088 int rv; 1089 sclient_t *sc = ip->i_sc; 1090 audio_client_t *c = sc->s_client; 1091 audio_dev_t *d = auclnt_get_dev(c); 1092 1093 switch (ip->i_step) { 1094 case 0: 1095 rv = sioc_alloc(ip, sizeof (audio_device_t)); 1096 if (rv == 0) { 1097 audio_device_t *a = ip->i_data; 1098 1099 (void) snprintf(a->name, sizeof (a->name), 1100 "SUNW,%s", auclnt_get_dev_name(d)); 1101 (void) strlcpy(a->config, 1102 auclnt_get_dev_description(d), sizeof (a->config)); 1103 (void) strlcpy(a->version, 1104 auclnt_get_dev_version(d), sizeof (a->version)); 1105 sioc_copyout(ip, sizeof (*a)); 1106 } else { 1107 sioc_error(ip, rv); 1108 } 1109 break; 1110 1111 case 1: 1112 sioc_success(ip); 1113 break; 1114 } 1115 1116 ip->i_step++; 1117 sioc_finish(ip); 1118 } 1119 1120 static void 1121 sunstr_ioctl(sioc_t *ip) 1122 { 1123 switch (ip->i_cmd) { 1124 case AUDIO_GETINFO: 1125 sioc_getinfo(ip); 1126 break; 1127 1128 case AUDIO_SETINFO: 1129 sioc_setinfo(ip); 1130 break; 1131 1132 case AUDIO_GETDEV: 1133 sioc_getdev(ip); 1134 break; 1135 1136 case AUDIO_DIAG_LOOPBACK: 1137 /* we don't support this one */ 1138 sioc_error(ip, ENOTTY); 1139 sioc_finish(ip); 1140 break; 1141 1142 case AUDIO_MIXERCTL_GET_MODE: 1143 case AUDIO_MIXERCTL_SET_MODE: 1144 case AUDIO_MIXERCTL_GET_CHINFO: 1145 case AUDIO_MIXERCTL_SET_CHINFO: 1146 case AUDIO_MIXERCTL_GETINFO: 1147 case AUDIO_MIXERCTL_SETINFO: 1148 case AUDIO_GET_NUM_CHS: 1149 case AUDIO_GET_CH_NUMBER: 1150 case AUDIO_GET_CH_TYPE: 1151 case AUDIO_MIXER_SINGLE_OPEN: 1152 case AUDIO_MIXER_MULTIPLE_OPEN: 1153 case AUDIO_MIXER_GET_SAMPLE_RATES: 1154 default: 1155 sioc_error(ip, EINVAL); 1156 sioc_finish(ip); 1157 break; 1158 } 1159 } 1160 1161 static int 1162 sun_sigpoll(audio_client_t *c, void *arg) 1163 { 1164 sproc_t *proc = arg; 1165 sclient_t *sc; 1166 1167 if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) { 1168 sc = auclnt_get_private(c); 1169 /* we only need to notify peers in our own process */ 1170 if ((sc != NULL) && (sc->s_proc == proc)) { 1171 (void) putnextctl1(sc->s_rq, M_PCSIG, SIGPOLL); 1172 } 1173 } 1174 return (AUDIO_WALK_CONTINUE); 1175 } 1176 1177 static void 1178 sun_drain(audio_client_t *c) 1179 { 1180 sclient_t *sc = auclnt_get_private(c); 1181 mblk_t *mplist, *mp; 1182 1183 mutex_enter(&sc->s_lock); 1184 mplist = sc->s_draining; 1185 sc->s_draining = NULL; 1186 mutex_exit(&sc->s_lock); 1187 1188 while ((mp = mplist) != NULL) { 1189 mplist = mp->b_next; 1190 mp->b_next = NULL; 1191 miocack(sc->s_wq, mp, 0, 0); 1192 } 1193 } 1194 1195 static void 1196 sun_output(audio_client_t *c) 1197 { 1198 sclient_t *sc = auclnt_get_private(c); 1199 sproc_t *proc = sc->s_proc; 1200 uint64_t tail; 1201 struct eofcnt *eof; 1202 int eofs = 0; 1203 1204 tail = auclnt_get_tail(auclnt_output_stream(c)); 1205 1206 /* get more data! (do this early) */ 1207 qenable(sc->s_wq); 1208 1209 mutex_enter(&sc->s_lock); 1210 while (((eof = list_head(&sc->s_eofcnt)) != NULL) && 1211 (eof->tail < tail)) { 1212 list_remove(&sc->s_eofcnt, eof); 1213 kmem_free(eof, sizeof (*eof)); 1214 eofs++; 1215 } 1216 proc->p_info.play.eof += eofs; 1217 mutex_exit(&sc->s_lock); 1218 1219 if (eofs) { 1220 auclnt_dev_walk_clients(auclnt_get_dev(c), 1221 sun_sigpoll, proc); 1222 } 1223 } 1224 1225 static void 1226 sun_input(audio_client_t *c) 1227 { 1228 sun_sendup(c); 1229 } 1230 1231 static int 1232 sun_create_minors(audio_dev_t *adev, void *notused) 1233 { 1234 char path[MAXPATHLEN]; 1235 minor_t minor; 1236 int inst; 1237 int index; 1238 const char *driver; 1239 unsigned cap; 1240 1241 _NOTE(ARGUNUSED(notused)); 1242 1243 ASSERT(mutex_owned(&sdev_lock)); 1244 1245 /* don't create device nodes for sndstat device */ 1246 cap = auclnt_get_dev_capab(adev); 1247 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) { 1248 return (AUDIO_WALK_CONTINUE); 1249 } 1250 1251 index = auclnt_get_dev_index(adev); 1252 inst = auclnt_get_dev_instance(adev); 1253 driver = auclnt_get_dev_driver(adev); 1254 1255 if (sdev_dip != NULL) { 1256 1257 minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIO); 1258 (void) snprintf(path, sizeof (path), "sound,%s,audio%d", 1259 driver, inst); 1260 (void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor, 1261 DDI_NT_AUDIO, 0); 1262 1263 minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIOCTL); 1264 (void) snprintf(path, sizeof (path), "sound,%s,audioctl%d", 1265 driver, inst); 1266 (void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor, 1267 DDI_NT_AUDIO, 0); 1268 } 1269 1270 return (AUDIO_WALK_CONTINUE); 1271 } 1272 1273 static int 1274 sun_remove_minors(audio_dev_t *adev, void *notused) 1275 { 1276 char path[MAXPATHLEN]; 1277 int inst; 1278 const char *driver; 1279 unsigned cap; 1280 1281 _NOTE(ARGUNUSED(notused)); 1282 1283 ASSERT(mutex_owned(&sdev_lock)); 1284 1285 cap = auclnt_get_dev_capab(adev); 1286 /* if not a play or record device, don't bother creating minors */ 1287 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) { 1288 return (AUDIO_WALK_CONTINUE); 1289 } 1290 1291 inst = auclnt_get_dev_instance(adev); 1292 driver = auclnt_get_dev_driver(adev); 1293 1294 if (sdev_dip != NULL) { 1295 1296 (void) snprintf(path, sizeof (path), "sound,%s,audio%d", 1297 driver, inst); 1298 ddi_remove_minor_node(sdev_dip, path); 1299 1300 (void) snprintf(path, sizeof (path), "sound,%s,audioctl%d", 1301 driver, inst); 1302 ddi_remove_minor_node(sdev_dip, path); 1303 } 1304 1305 return (AUDIO_WALK_CONTINUE); 1306 } 1307 1308 static void * 1309 sun_dev_init(audio_dev_t *adev) 1310 { 1311 sdev_t *sdev; 1312 unsigned cap; 1313 1314 cap = auclnt_get_dev_capab(adev); 1315 /* if not a play or record device, don't bother initializing it */ 1316 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) { 1317 return (NULL); 1318 } 1319 1320 sdev = kmem_zalloc(sizeof (*sdev), KM_SLEEP); 1321 sdev->d_dev = adev; 1322 mutex_init(&sdev->d_mx, NULL, MUTEX_DRIVER, NULL); 1323 cv_init(&sdev->d_cv, NULL, CV_DRIVER, NULL); 1324 list_create(&sdev->d_procs, sizeof (struct sproc), 1325 offsetof(struct sproc, p_linkage)); 1326 1327 mutex_enter(&sdev_lock); 1328 (void) sun_create_minors(adev, NULL); 1329 mutex_exit(&sdev_lock); 1330 1331 return (sdev); 1332 } 1333 1334 static void 1335 sun_dev_fini(void *arg) 1336 { 1337 sdev_t *sdev = arg; 1338 1339 if (sdev != NULL) { 1340 1341 /* remove minor nodes */ 1342 mutex_enter(&sdev_lock); 1343 (void) sun_remove_minors(sdev->d_dev, NULL); 1344 mutex_exit(&sdev_lock); 1345 1346 mutex_destroy(&sdev->d_mx); 1347 cv_destroy(&sdev->d_cv); 1348 list_destroy(&sdev->d_procs); 1349 kmem_free(sdev, sizeof (*sdev)); 1350 } 1351 } 1352 1353 static struct audio_client_ops sun_ops = { 1354 "internal,audio", 1355 sun_dev_init, 1356 sun_dev_fini, 1357 sun_open, 1358 sun_close, 1359 NULL, /* read */ 1360 NULL, /* write */ 1361 NULL, /* ioctl */ 1362 NULL, /* chpoll */ 1363 NULL, /* mmap */ 1364 sun_input, 1365 sun_output, 1366 NULL, /* notify */ 1367 sun_drain, 1368 }; 1369 1370 static struct audio_client_ops sunctl_ops = { 1371 "internal,audioctl", 1372 NULL, /* dev_init */ 1373 NULL, /* dev_fini */ 1374 sun_open, 1375 sun_close, 1376 NULL, /* read */ 1377 NULL, /* write */ 1378 NULL, /* ioctl */ 1379 NULL, /* chpoll */ 1380 NULL, /* mmap */ 1381 NULL, /* output */ 1382 NULL, /* input */ 1383 NULL, /* notify */ 1384 NULL, /* drain */ 1385 }; 1386 1387 void 1388 auimpl_sun_init(void) 1389 { 1390 mutex_init(&sdev_lock, NULL, MUTEX_DRIVER, NULL); 1391 sdev_dip = NULL; 1392 auclnt_register_ops(AUDIO_MINOR_DEVAUDIO, &sun_ops); 1393 auclnt_register_ops(AUDIO_MINOR_DEVAUDIOCTL, &sunctl_ops); 1394 } 1395 1396 /* 1397 * This is the operations entry points that are streams specific... 1398 * We map "instance" numbers. 1399 */ 1400 1401 static int 1402 sunstr_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *cr) 1403 { 1404 int rv; 1405 minor_t minor; 1406 minor_t index; 1407 minor_t type; 1408 dev_t physdev; 1409 ldi_ident_t lid; 1410 ldi_handle_t lh = NULL; 1411 audio_client_t *c = NULL; 1412 sclient_t *sc = NULL; 1413 audio_dev_t *adev; 1414 unsigned fmt; 1415 int oflag; 1416 boolean_t isopen = B_FALSE; 1417 1418 if (sflag != 0) { 1419 /* no direct clone or module opens */ 1420 return (EINVAL); 1421 } 1422 1423 /* 1424 * NB: We reuse the partitioning that the core framework is 1425 * using for instance numbering. This does mean that we are 1426 * limited to at most AUDIO_MN_INST_MASK devices, but this 1427 * number is sufficiently large (8192) that not to be a concern. 1428 */ 1429 1430 minor = getminor(*devp); 1431 index = (minor >> AUDIO_MN_INST_SHIFT) & AUDIO_MN_INST_MASK; 1432 type = (minor >> AUDIO_MN_TYPE_SHIFT) & AUDIO_MN_TYPE_MASK; 1433 1434 /* can't directly open a cloned node! */ 1435 if (minor & AUDIO_MN_CLONE_MASK) { 1436 return (ENXIO); 1437 } 1438 1439 switch (type) { 1440 case AUDIO_MINOR_DEVAUDIOCTL: 1441 fmt = AUDIO_FORMAT_NONE; 1442 oflag = flag & ~(FWRITE | FREAD); 1443 break; 1444 case AUDIO_MINOR_DEVAUDIO: 1445 fmt = AUDIO_FORMAT_PCM; 1446 oflag = flag; 1447 break; 1448 default: 1449 /* these minor types are not legal */ 1450 return (ENXIO); 1451 } 1452 1453 /* look up and hold the matching audio device */ 1454 adev = auclnt_hold_dev_by_index(index); 1455 if (adev == NULL) { 1456 return (ENXIO); 1457 } 1458 /* find the matching physical devt */ 1459 physdev = makedevice(ddi_driver_major(auclnt_get_dev_devinfo(adev)), 1460 AUDIO_MKMN(auclnt_get_dev_instance(adev), type)); 1461 1462 if ((rv = ldi_ident_from_stream(rq, &lid)) == 0) { 1463 rv = ldi_open_by_dev(&physdev, OTYP_CHR, flag, cr, &lh, lid); 1464 } 1465 1466 /* ldi open is done, lh holds device, and we can release our hold */ 1467 auclnt_release_dev(adev); 1468 1469 if (rv != 0) { 1470 goto fail; 1471 } 1472 /* phys layer clones a device for us */ 1473 ASSERT((getminor(physdev) & AUDIO_MN_CLONE_MASK) != 0); 1474 1475 /* 1476 * Note: We don't need to retain the hold on the client 1477 * structure, because the client is logically "held" by the 1478 * open LDI handle. We're just using this hold_by_devt to 1479 * locate the associated client. 1480 */ 1481 c = auclnt_hold_by_devt(physdev); 1482 ASSERT(c != NULL); 1483 auclnt_release(c); 1484 1485 if ((rv = auclnt_open(c, fmt, oflag)) != 0) { 1486 goto fail; 1487 } 1488 isopen = B_TRUE; 1489 1490 if ((rv = sproc_hold(c, oflag)) != 0) { 1491 goto fail; 1492 } 1493 1494 sc = auclnt_get_private(c); 1495 WR(rq)->q_ptr = rq->q_ptr = sc; 1496 sc->s_lh = lh; 1497 sc->s_rq = rq; 1498 sc->s_wq = WR(rq); 1499 1500 /* start up the input */ 1501 if (oflag & FREAD) { 1502 auclnt_start(auclnt_input_stream(c)); 1503 } 1504 1505 /* we just reuse same minor number that phys layer used */ 1506 *devp = makedevice(getmajor(*devp), getminor(physdev)); 1507 1508 qprocson(rq); 1509 1510 return (0); 1511 1512 fail: 1513 if (sc != NULL) { 1514 sproc_release(sc); 1515 } 1516 if (isopen) { 1517 auclnt_close(c); 1518 } 1519 if (lh != NULL) { 1520 (void) ldi_close(lh, flag, cr); 1521 } 1522 1523 return (rv); 1524 } 1525 1526 static int 1527 sunstr_close(queue_t *rq, int flag, cred_t *cr) 1528 { 1529 sclient_t *sc; 1530 audio_client_t *c; 1531 int rv; 1532 1533 sc = rq->q_ptr; 1534 c = sc->s_client; 1535 1536 if ((auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIO) && 1537 (ddi_can_receive_sig() || (ddi_get_pid() == 0))) { 1538 rv = auclnt_drain(c); 1539 } 1540 1541 auclnt_stop(auclnt_output_stream(c)); 1542 auclnt_stop(auclnt_input_stream(c)); 1543 1544 auclnt_close(c); 1545 1546 qprocsoff(rq); 1547 1548 (void) ldi_close(sc->s_lh, flag, cr); 1549 1550 sproc_release(sc); 1551 1552 return (rv); 1553 } 1554 1555 static void 1556 sunstr_miocdata(sclient_t *sc, mblk_t *mp) 1557 { 1558 struct copyresp *csp; 1559 sioc_t *ip; 1560 mblk_t *bcont; 1561 1562 csp = (void *)mp->b_rptr; 1563 1564 /* 1565 * If no state, then something "bad" has happened. 1566 */ 1567 if (((ip = (void *)csp->cp_private) == NULL) || (ip->i_sc != sc)) { 1568 miocnak(sc->s_wq, mp, 0, EFAULT); 1569 return; 1570 } 1571 1572 /* 1573 * If we failed to transfer data to/from userland, then we are 1574 * done. (Stream head will have notified userland.) 1575 */ 1576 if (csp->cp_rval != 0) { 1577 ip->i_state = FINI; 1578 ip->i_mp = mp; 1579 sioc_finish(ip); 1580 return; 1581 } 1582 1583 /* 1584 * Buffer area for ioctl is attached to chain. 1585 * For an ioctl that didn't have any data to copyin, 1586 * we might need to allocate a new buffer area. 1587 */ 1588 bcont = mp->b_cont; 1589 ip->i_bcont = bcont; 1590 mp->b_cont = NULL; 1591 1592 if (bcont != NULL) { 1593 ip->i_data = bcont->b_rptr; 1594 } 1595 1596 /* 1597 * Meaty part of data processing. 1598 */ 1599 ip->i_state = IOCTL; 1600 ip->i_mp = mp; 1601 1602 /* now, call the handler ioctl */ 1603 sunstr_ioctl(ip); 1604 } 1605 1606 static void 1607 sunstr_mioctl(sclient_t *sc, mblk_t *mp) 1608 { 1609 struct iocblk *iocp = (void *)mp->b_rptr; 1610 sioc_t *ip; 1611 1612 /* BSD legacy here: we only support transparent ioctls */ 1613 if (iocp->ioc_count != TRANSPARENT) { 1614 miocnak(sc->s_wq, mp, 0, EINVAL); 1615 return; 1616 } 1617 1618 ip = kmem_zalloc(sizeof (*ip), KM_NOSLEEP); 1619 if (ip == NULL) { 1620 miocnak(sc->s_wq, mp, 0, ENOMEM); 1621 return; 1622 } 1623 1624 /* make sure everything is setup in case we need to do copyin/out */ 1625 ip->i_sc = sc; 1626 ip->i_model = iocp->ioc_flag; 1627 ip->i_cmd = iocp->ioc_cmd; 1628 ip->i_addr = *(caddr_t *)(void *)mp->b_cont->b_rptr; 1629 ip->i_state = IOCTL; 1630 ip->i_mp = mp; 1631 freemsg(mp->b_cont); 1632 mp->b_cont = NULL; 1633 1634 /* now, call the handler ioctl */ 1635 sunstr_ioctl(ip); 1636 } 1637 1638 static int 1639 sunstr_wput(queue_t *wq, mblk_t *mp) 1640 { 1641 sclient_t *sc = wq->q_ptr; 1642 struct iocblk *iocp; 1643 1644 switch (DB_TYPE(mp)) { 1645 case M_IOCTL: 1646 /* Drain ioctl needs to be handled on the service queue */ 1647 iocp = (void *)mp->b_rptr; 1648 if (iocp->ioc_cmd == AUDIO_DRAIN) { 1649 if (auclnt_get_minor_type(sc->s_client) == 1650 AUDIO_MINOR_DEVAUDIO) { 1651 (void) putq(wq, mp); 1652 } else { 1653 miocnak(wq, mp, 0, EINVAL); 1654 } 1655 } else { 1656 sunstr_mioctl(sc, mp); 1657 } 1658 break; 1659 1660 case M_IOCDATA: 1661 sunstr_miocdata(sc, mp); 1662 break; 1663 1664 case M_FLUSH: 1665 /* 1666 * We don't flush the engine. The reason is that 1667 * other streams might be using the engine. This is 1668 * fundamentally no different from the case where the 1669 * engine hardware has data buffered in an 1670 * inaccessible FIFO. 1671 * 1672 * Clients that want to ensure no more data is coming 1673 * should stop the stream before flushing. 1674 */ 1675 if (*mp->b_rptr & FLUSHW) { 1676 flushq(wq, FLUSHALL); 1677 auclnt_flush(auclnt_output_stream(sc->s_client)); 1678 *mp->b_rptr &= ~FLUSHW; 1679 } 1680 if (*mp->b_rptr & FLUSHR) { 1681 flushq(RD(wq), FLUSHALL); 1682 auclnt_flush(auclnt_input_stream(sc->s_client)); 1683 qreply(wq, mp); 1684 } else { 1685 freemsg(mp); 1686 } 1687 break; 1688 1689 case M_DATA: 1690 /* 1691 * If we don't have an engine, then we can't accept 1692 * write() data. audio(7i) says we just ignore it, 1693 * so we toss it. 1694 */ 1695 if (auclnt_get_minor_type(sc->s_client) != 1696 AUDIO_MINOR_DEVAUDIO) { 1697 freemsg(mp); 1698 } else { 1699 /* 1700 * Defer processing to the queue. This keeps 1701 * the data ordered, and allows the wsrv 1702 * routine to gather multiple mblks at once. 1703 */ 1704 if (mp->b_cont != NULL) { 1705 1706 /* 1707 * If we need to pullup, do it here to 1708 * simplify the rest of the processing 1709 * later. This should rarely (if 1710 * ever) be necessary. 1711 */ 1712 mblk_t *nmp; 1713 1714 if ((nmp = msgpullup(mp, -1)) == NULL) { 1715 freemsg(mp); 1716 } else { 1717 freemsg(mp); 1718 (void) putq(wq, nmp); 1719 } 1720 } else { 1721 (void) putq(wq, mp); 1722 } 1723 } 1724 break; 1725 1726 default: 1727 freemsg(mp); 1728 break; 1729 } 1730 return (0); 1731 } 1732 1733 static int 1734 sunstr_wsrv(queue_t *wq) 1735 { 1736 sclient_t *sc = wq->q_ptr; 1737 audio_client_t *c = sc->s_client; 1738 audio_stream_t *sp; 1739 mblk_t *mp; 1740 unsigned framesz; 1741 1742 sp = auclnt_output_stream(c); 1743 1744 framesz = auclnt_get_framesz(sp); 1745 1746 while ((mp = getq(wq)) != NULL) { 1747 1748 unsigned count; 1749 1750 /* got a message */ 1751 1752 /* if its a drain ioctl, we need to process it here */ 1753 if (DB_TYPE(mp) == M_IOCTL) { 1754 ASSERT((*(int *)(void *)mp->b_rptr) == AUDIO_DRAIN); 1755 mutex_enter(&sc->s_lock); 1756 mp->b_next = sc->s_draining; 1757 sc->s_draining = mp; 1758 mutex_exit(&sc->s_lock); 1759 1760 if (auclnt_start_drain(c) != 0) { 1761 sun_drain(c); 1762 } 1763 continue; 1764 } 1765 1766 ASSERT(DB_TYPE(mp) == M_DATA); 1767 1768 /* 1769 * Empty mblk require special handling, since they 1770 * indicate EOF. We treat them separate from the main 1771 * processing loop. 1772 */ 1773 if (MBLKL(mp) == 0) { 1774 struct eofcnt *eof; 1775 1776 eof = kmem_zalloc(sizeof (*eof), KM_NOSLEEP); 1777 if (eof != NULL) { 1778 eof->tail = auclnt_get_head(sp); 1779 mutex_enter(&sc->s_lock); 1780 list_insert_tail(&sc->s_eofcnt, eof); 1781 mutex_exit(&sc->s_lock); 1782 } 1783 freemsg(mp); 1784 continue; 1785 } 1786 1787 count = auclnt_produce_data(sp, (caddr_t)mp->b_rptr, 1788 MBLKL(mp) / framesz); 1789 1790 mp->b_rptr += count * framesz; 1791 1792 if (MBLKL(mp) >= framesz) { 1793 (void) putbq(wq, mp); 1794 break; 1795 } else { 1796 freemsg(mp); 1797 } 1798 } 1799 1800 /* if the stream isn't running yet, start it up */ 1801 if (!auclnt_is_paused(sp)) 1802 auclnt_start(sp); 1803 1804 return (0); 1805 } 1806 1807 static int 1808 sunstr_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1809 { 1810 if ((cmd != DDI_ATTACH) || (dip == NULL)) { 1811 return (DDI_FAILURE); 1812 } 1813 if (ddi_get_instance(dip) != 0) { 1814 return (DDI_FAILURE); 1815 } 1816 1817 mutex_enter(&sdev_lock); 1818 sdev_dip = dip; 1819 auclnt_walk_devs(sun_create_minors, NULL); 1820 mutex_exit(&sdev_lock); 1821 ddi_report_dev(dip); 1822 1823 return (0); 1824 } 1825 1826 static int 1827 sunstr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1828 { 1829 if ((cmd != DDI_DETACH) || (dip == NULL)) { 1830 return (DDI_FAILURE); 1831 } 1832 if (ddi_get_instance(dip) != 0) { 1833 return (DDI_FAILURE); 1834 } 1835 1836 mutex_enter(&sdev_lock); 1837 /* remove all minors */ 1838 auclnt_walk_devs(sun_remove_minors, NULL); 1839 sdev_dip = NULL; 1840 mutex_exit(&sdev_lock); 1841 1842 return (0); 1843 } 1844 1845 static int 1846 sunstr_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 1847 { 1848 int error; 1849 1850 _NOTE(ARGUNUSED(dip)); 1851 _NOTE(ARGUNUSED(arg)); 1852 1853 switch (cmd) { 1854 case DDI_INFO_DEVT2DEVINFO: 1855 *result = sdev_dip; 1856 error = DDI_SUCCESS; 1857 break; 1858 case DDI_INFO_DEVT2INSTANCE: 1859 *result = 0; 1860 error = DDI_SUCCESS; 1861 break; 1862 default: 1863 *result = NULL; 1864 error = DDI_FAILURE; 1865 } 1866 return (error); 1867 } 1868 1869 static struct module_info sunstr_minfo = { 1870 0, /* used for strlog(1M) only, which we don't use */ 1871 "austr", 1872 0, /* min pkt size */ 1873 2048, /* max pkt size */ 1874 65536, /* hi water */ 1875 32768, /* lo water */ 1876 }; 1877 1878 static struct qinit sunstr_rqinit = { 1879 NULL, /* qi_putp */ 1880 NULL, /* qi_srvp */ 1881 sunstr_open, /* qi_qopen */ 1882 sunstr_close, /* qi_qclose */ 1883 NULL, /* qi_qadmin */ 1884 &sunstr_minfo, /* qi_minfo */ 1885 NULL, /* qi_mstat */ 1886 }; 1887 1888 static struct qinit sunstr_wqinit = { 1889 sunstr_wput, /* qi_putp */ 1890 sunstr_wsrv, /* qi_srvp */ 1891 NULL, /* qi_qopen */ 1892 NULL, /* qi_qclose */ 1893 NULL, /* qi_qadmin */ 1894 &sunstr_minfo, /* qi_minfo */ 1895 NULL, /* qi_mstat */ 1896 }; 1897 1898 static struct streamtab sunstr_strtab = { 1899 &sunstr_rqinit, 1900 &sunstr_wqinit, 1901 NULL, 1902 NULL 1903 }; 1904 1905 struct cb_ops sunstr_cb_ops = { 1906 nodev, /* open */ 1907 nodev, /* close */ 1908 nodev, /* strategy */ 1909 nodev, /* print */ 1910 nodev, /* dump */ 1911 nodev, /* read */ 1912 nodev, /* write */ 1913 nodev, /* ioctl */ 1914 nodev, /* devmap */ 1915 nodev, /* mmap */ 1916 nodev, /* segmap */ 1917 nochpoll, /* chpoll */ 1918 ddi_prop_op, /* prop_op */ 1919 &sunstr_strtab, /* str */ 1920 D_MP, /* flag */ 1921 CB_REV, /* rev */ 1922 nodev, /* aread */ 1923 nodev, /* awrite */ 1924 }; 1925 1926 static struct dev_ops sunstr_dev_ops = { 1927 DEVO_REV, /* rev */ 1928 0, /* refcnt */ 1929 sunstr_getinfo, /* getinfo */ 1930 nulldev, /* identify */ 1931 nulldev, /* probe */ 1932 sunstr_attach, /* attach */ 1933 sunstr_detach, /* detach */ 1934 nodev, /* reset */ 1935 &sunstr_cb_ops, /* cb_ops */ 1936 NULL, /* bus_ops */ 1937 NULL, /* power */ 1938 }; 1939 1940 static struct modldrv sunstr_modldrv = { 1941 &mod_driverops, 1942 "Audio Streams Support", 1943 &sunstr_dev_ops, 1944 }; 1945 1946 static struct modlinkage sunstr_modlinkage = { 1947 MODREV_1, /* MODREV_1 indicated by manual */ 1948 &sunstr_modldrv, 1949 NULL 1950 }; 1951 1952 int 1953 sunstr_init(void) 1954 { 1955 /* 1956 * NB: This *must* be called after the "audio" module's 1957 * _init routine has called auimpl_sun_init(). 1958 */ 1959 return (mod_install(&sunstr_modlinkage)); 1960 } 1961 1962 int 1963 sunstr_fini(void) 1964 { 1965 return (mod_remove(&sunstr_modlinkage)); 1966 } 1967 1968 int 1969 sunstr_info(struct modinfo *modinfop) 1970 { 1971 return (mod_info(&sunstr_modlinkage, modinfop)); 1972 } 1973