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 daclient daclient_t; 101 typedef struct dadev dadev_t; 102 typedef struct daproc daproc_t; 103 104 /* common structure shared between both audioctl and audio nodes */ 105 struct daclient { 106 daproc_t *dc_proc; 107 dadev_t *dc_dev; 108 audio_client_t *dc_client; 109 queue_t *dc_wq; 110 unsigned dc_eof; 111 list_t dc_eofcnt; 112 kmutex_t dc_lock; 113 mblk_t *dc_draining; 114 }; 115 116 struct eofcnt { 117 list_node_t linkage; 118 uint64_t tail; 119 }; 120 121 struct dadev { 122 audio_dev_t *d_dev; 123 124 list_t d_procs; 125 kmutex_t d_mx; 126 kcondvar_t d_cv; 127 }; 128 129 struct daproc { 130 pid_t p_id; 131 struct audio_info p_info; 132 int p_refcnt; 133 int p_oflag; 134 list_node_t p_linkage; 135 dadev_t *p_dev; 136 audio_client_t *p_writer; 137 audio_client_t *p_reader; 138 }; 139 140 int devaudio_proc_hold(audio_client_t *, int); 141 void devaudio_proc_release(audio_client_t *); 142 static void devaudio_proc_update(daproc_t *); 143 144 145 static int 146 devaudio_compose_format(audio_prinfo_t *prinfo) 147 { 148 switch (prinfo->precision) { 149 case 8: 150 switch (prinfo->encoding) { 151 case AUDIO_ENCODING_ULAW: 152 return (AUDIO_FORMAT_ULAW); 153 case AUDIO_ENCODING_ALAW: 154 return (AUDIO_FORMAT_ALAW); 155 case AUDIO_ENCODING_LINEAR8: 156 return (AUDIO_FORMAT_U8); 157 case AUDIO_ENCODING_LINEAR: 158 return (AUDIO_FORMAT_S8); 159 } 160 break; 161 case 16: 162 if (prinfo->encoding == AUDIO_ENCODING_LINEAR) 163 return (AUDIO_FORMAT_S16_NE); 164 break; 165 case 32: 166 if (prinfo->encoding == AUDIO_ENCODING_LINEAR) 167 return (AUDIO_FORMAT_S32_NE); 168 break; 169 } 170 return (AUDIO_FORMAT_NONE); 171 172 } 173 174 static void 175 devaudio_decompose_format(audio_prinfo_t *prinfo, int afmt) 176 { 177 int e, p; 178 179 /* 180 * N.B.: Even though some of the formats below can't be set by 181 * this personality, reporting them (using the closest match) 182 * allows this personality to roughly approximate settings for 183 * other streams. It would be incredibly poor form for any 184 * personality to modify the format settings for a different 185 * personality, so we don't worry about that case. 186 */ 187 188 switch (afmt) { 189 case AUDIO_FORMAT_ULAW: 190 e = AUDIO_ENCODING_ULAW; 191 p = 8; 192 break; 193 194 case AUDIO_FORMAT_ALAW: 195 e = AUDIO_ENCODING_ALAW; 196 p = 8; 197 break; 198 199 case AUDIO_FORMAT_U8: 200 e = AUDIO_ENCODING_LINEAR8; 201 p = 8; 202 break; 203 204 case AUDIO_FORMAT_S8: 205 e = AUDIO_ENCODING_LINEAR; 206 p = 8; 207 break; 208 209 case AUDIO_FORMAT_S16_NE: 210 case AUDIO_FORMAT_S16_OE: 211 case AUDIO_FORMAT_U16_NE: 212 case AUDIO_FORMAT_U16_OE: 213 e = AUDIO_ENCODING_LINEAR; 214 p = 16; 215 break; 216 217 case AUDIO_FORMAT_S24_NE: 218 case AUDIO_FORMAT_S24_OE: 219 case AUDIO_FORMAT_S24_PACKED: 220 e = AUDIO_ENCODING_LINEAR; 221 p = 24; 222 break; 223 224 case AUDIO_FORMAT_S32_NE: 225 case AUDIO_FORMAT_S32_OE: 226 e = AUDIO_ENCODING_LINEAR; 227 p = 32; 228 break; 229 230 default: 231 /* all other formats (e.g. AC3) are uninterpreted */ 232 e = AUDIO_ENCODING_NONE; 233 p = 32; 234 break; 235 } 236 237 prinfo->encoding = e; 238 prinfo->precision = p; 239 } 240 241 static daproc_t * 242 devaudio_proc_alloc(audio_client_t *c) 243 { 244 audio_info_t *info; 245 audio_prinfo_t *prinfo; 246 uint32_t caps; 247 daproc_t *proc; 248 249 if ((proc = kmem_zalloc(sizeof (*proc), KM_NOSLEEP)) == NULL) { 250 return (NULL); 251 } 252 info = &proc->p_info; 253 254 /* 255 * audio(7I) says: Upon the initial open() of the audio 256 * device, the driver resets the data format of the device to 257 * the default state of 8-bit, 8Khz, mono u-Law data. 258 */ 259 prinfo = &info->play; 260 prinfo->channels = 1; 261 prinfo->sample_rate = 8000; 262 prinfo->encoding = AUDIO_ENCODING_ULAW; 263 prinfo->precision = 8; 264 prinfo->gain = AUDIO_MAX_GAIN; 265 prinfo->balance = AUDIO_MID_BALANCE; 266 prinfo->buffer_size = 8192; 267 prinfo->pause = B_FALSE; 268 prinfo->waiting = B_FALSE; 269 prinfo->open = B_FALSE; 270 prinfo->active = B_FALSE; 271 prinfo->samples = 0; 272 prinfo->eof = 0; 273 prinfo->error = 0; 274 prinfo->minordev = 0; 275 prinfo->port = AUDIO_SPEAKER; 276 prinfo->avail_ports = AUDIO_SPEAKER; 277 prinfo->mod_ports = AUDIO_NONE; 278 prinfo->_xxx = 0; 279 280 prinfo = &info->record; 281 prinfo->channels = 1; 282 prinfo->sample_rate = 8000; 283 prinfo->encoding = AUDIO_ENCODING_ULAW; 284 prinfo->precision = 8; 285 prinfo->gain = AUDIO_MAX_GAIN; 286 prinfo->balance = AUDIO_MID_BALANCE; 287 prinfo->buffer_size = 8192; 288 prinfo->waiting = B_FALSE; 289 prinfo->open = B_FALSE; 290 prinfo->active = B_FALSE; 291 prinfo->samples = 0; 292 prinfo->eof = 0; 293 prinfo->error = 0; 294 prinfo->minordev = 0; 295 prinfo->port = AUDIO_MICROPHONE; 296 prinfo->avail_ports = AUDIO_MICROPHONE; 297 prinfo->mod_ports = AUDIO_MICROPHONE; 298 299 info->output_muted = B_FALSE; 300 /* pretend we don't have a software mixer - we don't support the API */ 301 info->hw_features = 0; 302 info->sw_features = 0; 303 info->sw_features_enabled = 0; 304 305 caps = auclnt_get_dev_capab(auclnt_get_dev(c)); 306 if (caps & AUDIO_CLIENT_CAP_PLAY) 307 info->hw_features |= AUDIO_HWFEATURE_PLAY; 308 if (caps & AUDIO_CLIENT_CAP_RECORD) 309 info->hw_features |= AUDIO_HWFEATURE_RECORD; 310 if (caps & AUDIO_CLIENT_CAP_DUPLEX) 311 info->hw_features |= AUDIO_HWFEATURE_DUPLEX; 312 313 return (proc); 314 } 315 316 static void 317 devaudio_proc_free(daproc_t *proc) 318 { 319 kmem_free(proc, sizeof (*proc)); 320 } 321 322 int 323 devaudio_proc_hold(audio_client_t *c, int oflag) 324 { 325 pid_t pid; 326 daproc_t *proc; 327 dadev_t *dev; 328 daclient_t *dc; 329 list_t *l; 330 audio_dev_t *adev; 331 int rv; 332 333 adev = auclnt_get_dev(c); 334 335 /* first allocate and initialize the daclient private data */ 336 if ((dc = kmem_zalloc(sizeof (*dc), KM_NOSLEEP)) == NULL) { 337 return (ENOMEM); 338 } 339 340 mutex_init(&dc->dc_lock, NULL, MUTEX_DRIVER, NULL); 341 list_create(&dc->dc_eofcnt, sizeof (struct eofcnt), 342 offsetof(struct eofcnt, linkage)); 343 auclnt_set_private(c, dc); 344 345 dev = auclnt_get_dev_minor_data(adev, AUDIO_MINOR_DEVAUDIO); 346 l = &dev->d_procs; 347 pid = auclnt_get_pid(c); 348 349 /* set a couple of common fields */ 350 dc->dc_client = c; 351 dc->dc_dev = dev; 352 353 mutex_enter(&dev->d_mx); 354 for (proc = list_head(l); proc != NULL; proc = list_next(l, proc)) { 355 if (proc->p_id == pid) { 356 proc->p_refcnt++; 357 break; 358 } 359 } 360 if (proc == NULL) { 361 if ((proc = devaudio_proc_alloc(c)) == NULL) { 362 rv = ENOMEM; 363 goto failed; 364 } 365 proc->p_refcnt = 1; 366 proc->p_id = pid; 367 proc->p_dev = dev; 368 list_insert_tail(l, proc); 369 } 370 371 while (proc->p_oflag & oflag) { 372 373 if (oflag & (FNDELAY|FNONBLOCK)) { 374 rv = EBUSY; 375 goto failed; 376 } 377 if (oflag & FWRITE) 378 proc->p_info.play.waiting++; 379 if (oflag & FREAD) 380 proc->p_info.record.waiting++; 381 if (cv_wait_sig(&dev->d_cv, &dev->d_mx) == 0) { 382 /* interrupted! */ 383 if (oflag & FWRITE) 384 proc->p_info.play.waiting--; 385 if (oflag & FREAD) 386 proc->p_info.record.waiting--; 387 rv = EINTR; 388 goto failed; 389 } 390 if (oflag & FWRITE) 391 proc->p_info.play.waiting--; 392 if (oflag & FREAD) 393 proc->p_info.record.waiting--; 394 } 395 396 if (oflag & FWRITE) { 397 audio_prinfo_t *play = &proc->p_info.play; 398 audio_stream_t *sp = auclnt_output_stream(c); 399 400 if (((rv = auclnt_set_rate(sp, 8000)) != 0) || 401 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) || 402 ((rv = auclnt_set_channels(sp, 1)) != 0)) { 403 goto failed; 404 } 405 406 auclnt_set_samples(sp, 0); 407 auclnt_set_errors(sp, 0); 408 play->eof = 0; 409 play->buffer_size = 8192; 410 411 auclnt_set_gain(sp, ((play->gain * 100) / AUDIO_MAX_GAIN)); 412 auclnt_set_muted(sp, proc->p_info.output_muted); 413 play->open = B_TRUE; 414 proc->p_writer = c; 415 proc->p_oflag |= FWRITE; 416 } 417 418 if (oflag & FREAD) { 419 audio_prinfo_t *rec = &proc->p_info.record; 420 audio_stream_t *sp = auclnt_input_stream(c); 421 422 if (((rv = auclnt_set_rate(sp, 8000)) != 0) || 423 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) || 424 ((rv = auclnt_set_channels(sp, 1)) != 0)) { 425 goto failed; 426 } 427 428 auclnt_set_samples(sp, 0); 429 auclnt_set_errors(sp, 0); 430 rec->eof = 0; 431 rec->buffer_size = 8192; 432 433 auclnt_set_gain(sp, ((rec->gain * 100) / AUDIO_MAX_GAIN)); 434 rec->open = B_TRUE; 435 proc->p_reader = c; 436 proc->p_oflag |= FREAD; 437 } 438 439 440 dc->dc_wq = auclnt_get_wq(c); 441 442 /* we update the s_proc last to avoid a race */ 443 dc->dc_proc = proc; 444 445 devaudio_proc_update(proc); 446 447 mutex_exit(&dev->d_mx); 448 449 return (0); 450 451 failed: 452 mutex_exit(&dev->d_mx); 453 devaudio_proc_release(c); 454 return (rv); 455 456 } 457 458 static void 459 devaudio_clear_eof(audio_client_t *c) 460 { 461 struct eofcnt *eof; 462 daclient_t *dc; 463 464 dc = auclnt_get_private(c); 465 mutex_enter(&dc->dc_lock); 466 while ((eof = list_remove_head(&dc->dc_eofcnt)) != NULL) { 467 kmem_free(eof, sizeof (*eof)); 468 } 469 mutex_exit(&dc->dc_lock); 470 } 471 472 void 473 devaudio_proc_release(audio_client_t *c) 474 { 475 daproc_t *proc; 476 dadev_t *dev; 477 mblk_t *mp; 478 daclient_t *dc; 479 480 dc = auclnt_get_private(c); 481 proc = dc->dc_proc; 482 dev = dc->dc_dev; 483 dc->dc_proc = NULL; 484 485 mutex_enter(&dev->d_mx); 486 487 if (proc != NULL) { 488 proc->p_refcnt--; 489 ASSERT(proc->p_refcnt >= 0); 490 491 if (c == proc->p_writer) { 492 proc->p_oflag &= ~FWRITE; 493 proc->p_writer = NULL; 494 } 495 if (c == proc->p_reader) { 496 proc->p_oflag &= ~FREAD; 497 proc->p_reader = NULL; 498 } 499 cv_broadcast(&dev->d_cv); 500 501 if (proc->p_refcnt == 0) { 502 list_remove(&dev->d_procs, proc); 503 devaudio_proc_free(proc); 504 } 505 dc->dc_proc = NULL; 506 } 507 508 mutex_exit(&dev->d_mx); 509 510 devaudio_clear_eof(c); 511 512 while ((mp = dc->dc_draining) != NULL) { 513 dc->dc_draining = mp->b_next; 514 mp->b_next = NULL; 515 freemsg(mp); 516 } 517 518 mutex_destroy(&dc->dc_lock); 519 list_destroy(&dc->dc_eofcnt); 520 kmem_free(dc, sizeof (*dc)); 521 } 522 523 static void 524 devaudio_input(audio_client_t *c) 525 { 526 audio_stream_t *sp = auclnt_input_stream(c); 527 daclient_t *dc = auclnt_get_private(c); 528 unsigned framesz = auclnt_get_framesz(sp); 529 queue_t *rq = auclnt_get_rq(c); 530 mblk_t *mp; 531 unsigned nbytes = dc->dc_proc->p_info.record.buffer_size; 532 unsigned count = nbytes / framesz; 533 534 /* 535 * Potentially send a message upstream with the record data. 536 * We collect this up in chunks of the buffer size requested 537 * by the client. 538 */ 539 540 while (auclnt_get_count(sp) >= count) { 541 542 if ((!canputnext(rq)) || 543 ((mp = allocb(nbytes, BPRI_MED)) == NULL)) { 544 /* 545 * This will apply back pressure to the 546 * buffer. We haven't yet lost any data, we 547 * just can't send it up. The point at which 548 * we have an unrecoverable overrun is in the 549 * buffer, not in the streams queue. So, no 550 * need to do anything right now. 551 * 552 * Note that since recording is enabled, we 553 * expect that the callback routine will be 554 * called repeatedly & regularly, so we don't 555 * have to worry about leaving data orphaned 556 * in the queue. 557 */ 558 break; 559 } 560 561 (void) auclnt_consume_data(sp, (caddr_t)mp->b_wptr, count); 562 mp->b_wptr += nbytes; 563 putnext(rq, mp); 564 } 565 } 566 567 static void 568 devaudio_proc_update(daproc_t *proc) 569 { 570 audio_info_t *info; 571 audio_stream_t *sp; 572 audio_client_t *c; 573 574 info = &proc->p_info; 575 576 ASSERT(mutex_owned(&proc->p_dev->d_mx)); 577 578 if ((c = proc->p_writer) != NULL) { 579 sp = auclnt_output_stream(c); 580 581 info->play.sample_rate = auclnt_get_rate(sp); 582 info->play.channels = auclnt_get_channels(sp); 583 devaudio_decompose_format(&info->play, auclnt_get_format(sp)); 584 585 info->play.gain = 586 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100; 587 info->play.pause = auclnt_is_paused(sp); 588 info->play.active = auclnt_is_running(sp); 589 info->play.samples = auclnt_get_samples(sp); 590 info->play.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE; 591 info->output_muted = auclnt_get_muted(sp); 592 } else { 593 info->play.encoding = AUDIO_ENCODING_NONE; 594 info->play.precision = 0; 595 info->play.sample_rate = 0; 596 info->play.pause = B_FALSE; 597 info->play.active = B_FALSE; 598 info->play.error = B_FALSE; 599 info->play.samples = 0; 600 } 601 602 if ((c = proc->p_reader) != NULL) { 603 sp = auclnt_input_stream(c); 604 605 info->record.sample_rate = auclnt_get_rate(sp); 606 info->record.channels = auclnt_get_channels(sp); 607 devaudio_decompose_format(&info->record, auclnt_get_format(sp)); 608 609 info->record.gain = 610 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100; 611 info->record.pause = auclnt_is_paused(sp); 612 info->record.active = auclnt_is_running(sp); 613 info->record.samples = auclnt_get_samples(sp); 614 info->record.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE; 615 } else { 616 info->record.encoding = AUDIO_ENCODING_NONE; 617 info->record.precision = 0; 618 info->record.sample_rate = 0; 619 info->record.pause = B_FALSE; 620 info->record.active = B_FALSE; 621 info->record.error = B_FALSE; 622 info->record.samples = 0; 623 } 624 } 625 626 static void 627 devaudio_ioc_getinfo(queue_t *wq, audio_client_t *c, mblk_t *mp) 628 { 629 daclient_t *dc = auclnt_get_private(c); 630 daproc_t *proc = dc->dc_proc; 631 mblk_t *bcont; 632 633 if ((bcont = allocb(sizeof (audio_info_t), BPRI_MED)) == NULL) { 634 miocnak(wq, mp, 0, ENOMEM); 635 return; 636 } 637 638 mutex_enter(&dc->dc_dev->d_mx); 639 devaudio_proc_update(proc); 640 bcopy(&proc->p_info, bcont->b_wptr, sizeof (audio_info_t)); 641 mutex_exit(&dc->dc_dev->d_mx); 642 643 bcont->b_wptr += sizeof (audio_info_t); 644 645 mcopyout(mp, NULL, sizeof (audio_info_t), NULL, bcont); 646 qreply(wq, mp); 647 } 648 649 #define CHANGED(new, old, field) \ 650 ((new->field != ((uint32_t)~0)) && (new->field != old->field)) 651 #define CHANGED8(new, old, field) \ 652 ((new->field != ((uint8_t)~0)) && (new->field != old->field)) 653 654 static void 655 devaudio_ioc_setinfo(queue_t *wq, audio_client_t *c, mblk_t *mp) 656 { 657 daclient_t *dc; 658 daproc_t *proc; 659 audio_info_t *oinfo; 660 audio_info_t *ninfo; 661 audio_prinfo_t *npr; 662 audio_prinfo_t *opr; 663 664 int pfmt = AUDIO_FORMAT_NONE; 665 int rfmt = AUDIO_FORMAT_NONE; 666 667 boolean_t reader; 668 boolean_t writer; 669 boolean_t isctl; 670 audio_stream_t *sp; 671 int rv; 672 caddr_t uaddr; 673 mblk_t *bcont; 674 675 struct copyresp *csp; 676 677 if (DB_TYPE(mp) == M_IOCTL) { 678 /* the special value "1" indicates that this is a copyin */ 679 uaddr = *(caddr_t *)(void *)mp->b_cont->b_rptr; 680 681 mcopyin(mp, uaddr, sizeof (audio_info_t), NULL); 682 qreply(wq, mp); 683 return; 684 } 685 686 ASSERT(DB_TYPE(mp) == M_IOCDATA); 687 if (((bcont = mp->b_cont) == NULL) || 688 (MBLKL(mp->b_cont) != sizeof (audio_info_t))) { 689 miocnak(wq, mp, 0, EINVAL); 690 return; 691 } 692 693 mp->b_cont = NULL; 694 csp = (void *)mp->b_rptr; 695 uaddr = (void *)csp->cp_private; 696 dc = auclnt_get_private(c); 697 ninfo = (void *)bcont->b_rptr; 698 699 mutex_enter(&dc->dc_dev->d_mx); 700 701 proc = dc->dc_proc; 702 oinfo = &proc->p_info; 703 704 if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) { 705 /* control node can do both read and write fields */ 706 isctl = B_TRUE; 707 reader = B_TRUE; 708 writer = B_TRUE; 709 } else { 710 isctl = B_FALSE; 711 writer = (c == proc->p_writer); 712 reader = (c == proc->p_reader); 713 } 714 715 /* 716 * Start by validating settings. 717 */ 718 npr = &ninfo->play; 719 opr = &oinfo->play; 720 721 if (writer && CHANGED(npr, opr, sample_rate)) { 722 if ((isctl) || 723 (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) { 724 rv = EINVAL; 725 goto err; 726 } 727 } 728 if (writer && CHANGED(npr, opr, channels)) { 729 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) { 730 rv = EINVAL; 731 goto err; 732 } 733 } 734 if (writer && 735 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) { 736 if (npr->encoding == (uint32_t)~0) 737 npr->encoding = opr->encoding; 738 if (npr->precision == (uint32_t)~0) 739 npr->precision = opr->precision; 740 pfmt = devaudio_compose_format(npr); 741 if ((isctl) || (pfmt == AUDIO_FORMAT_NONE)) { 742 rv = EINVAL; 743 goto err; 744 } 745 } 746 747 /* play fields that anyone can modify */ 748 if (CHANGED(npr, opr, gain)) { 749 if (npr->gain > AUDIO_MAX_GAIN) { 750 rv = EINVAL; 751 goto err; 752 } 753 } 754 755 756 npr = &ninfo->record; 757 opr = &oinfo->record; 758 759 if (reader && CHANGED(npr, opr, sample_rate)) { 760 if ((isctl) || 761 (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) { 762 rv = EINVAL; 763 goto err; 764 } 765 } 766 if (reader && CHANGED(npr, opr, channels)) { 767 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) { 768 rv = EINVAL; 769 goto err; 770 } 771 } 772 if (reader && 773 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) { 774 if (npr->encoding == (uint32_t)~0) 775 npr->encoding = opr->encoding; 776 if (npr->precision == (uint32_t)~0) 777 npr->precision = opr->precision; 778 rfmt = devaudio_compose_format(npr); 779 if ((isctl) || (rfmt == AUDIO_FORMAT_NONE)) { 780 rv = EINVAL; 781 goto err; 782 } 783 } 784 if (reader && CHANGED(npr, opr, buffer_size)) { 785 if (isctl) { 786 rv = EINVAL; 787 goto err; 788 } 789 /* make sure we can support 16-bit stereo samples */ 790 if ((npr->buffer_size % 4) != 0) { 791 npr->buffer_size = (npr->buffer_size + 3) & ~3; 792 } 793 /* limit the maximum buffer size somewhat */ 794 if (npr->buffer_size > 16384) { 795 npr->buffer_size = 16384; 796 } 797 } 798 799 /* record fields that anyone can modify */ 800 if (CHANGED(npr, opr, gain)) { 801 if (npr->gain > AUDIO_MAX_GAIN) { 802 rv = EINVAL; 803 goto err; 804 } 805 } 806 807 /* 808 * Now apply the changes. 809 */ 810 if (proc->p_writer != NULL) { 811 sp = auclnt_output_stream(proc->p_writer); 812 npr = &ninfo->play; 813 opr = &oinfo->play; 814 815 if (CHANGED(npr, opr, sample_rate)) { 816 if ((rv = auclnt_set_rate(sp, npr->sample_rate)) != 0) 817 goto err; 818 } 819 if (CHANGED(npr, opr, channels)) { 820 if ((rv = auclnt_set_channels(sp, npr->channels)) != 0) 821 goto err; 822 } 823 if (pfmt != AUDIO_FORMAT_NONE) { 824 if ((rv = auclnt_set_format(sp, pfmt)) != 0) 825 goto err; 826 } 827 if (CHANGED(npr, opr, samples)) { 828 auclnt_set_samples(sp, npr->samples); 829 } 830 if (CHANGED(npr, opr, eof)) { 831 /* 832 * This ugly special case code is required to 833 * prevent problems with realaudio. 834 */ 835 if (npr->eof == 0) { 836 devaudio_clear_eof(proc->p_writer); 837 } 838 opr->eof = npr->eof; 839 } 840 if (CHANGED8(npr, opr, pause)) { 841 if (npr->pause) { 842 auclnt_set_paused(sp); 843 } else { 844 auclnt_clear_paused(sp); 845 846 /* qenable to start up the playback */ 847 qenable(auclnt_get_wq(proc->p_writer)); 848 } 849 } 850 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) { 851 opr->waiting = npr->waiting; 852 } 853 if (CHANGED8(npr, opr, error)) { 854 auclnt_set_errors(sp, npr->error); 855 } 856 if (CHANGED(npr, opr, gain)) { 857 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN); 858 } 859 if (CHANGED8(ninfo, oinfo, output_muted)) { 860 auclnt_set_muted(sp, ninfo->output_muted); 861 } 862 if (CHANGED(npr, opr, buffer_size)) { 863 /* 864 * No checks on the buffer size are performed 865 * for play side. The value of the buffer size 866 * is meaningless for play side anyway. 867 */ 868 opr->buffer_size = npr->buffer_size; 869 } 870 } else { 871 /* these values are preserved even if /dev/audio not open */ 872 if (CHANGED(npr, opr, gain)) { 873 opr->gain = npr->gain; 874 } 875 if (CHANGED8(ninfo, oinfo, output_muted)) { 876 oinfo->output_muted = ninfo->output_muted; 877 } 878 } 879 880 if (proc->p_reader != NULL) { 881 sp = auclnt_input_stream(proc->p_reader); 882 npr = &ninfo->record; 883 opr = &oinfo->record; 884 885 if (CHANGED(npr, opr, sample_rate)) { 886 if ((rv = auclnt_set_rate(sp, npr->sample_rate)) != 0) 887 goto err; 888 } 889 if (CHANGED(npr, opr, channels)) { 890 if ((rv = auclnt_set_channels(sp, npr->channels)) != 0) 891 goto err; 892 } 893 if (rfmt != AUDIO_FORMAT_NONE) { 894 if ((rv = auclnt_set_format(sp, rfmt)) != 0) 895 goto err; 896 } 897 if (CHANGED(npr, opr, samples)) { 898 auclnt_set_samples(sp, npr->samples); 899 } 900 if (CHANGED(npr, opr, eof)) { 901 opr->eof = npr->eof; 902 } 903 if (CHANGED8(npr, opr, pause)) { 904 if (npr->pause) { 905 auclnt_set_paused(sp); 906 } else { 907 auclnt_clear_paused(sp); 908 auclnt_start(sp); 909 } 910 } 911 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) { 912 opr->waiting = npr->waiting; 913 } 914 if (CHANGED8(npr, opr, error)) { 915 auclnt_set_errors(sp, npr->error); 916 } 917 if (CHANGED(npr, opr, buffer_size)) { 918 opr->buffer_size = npr->buffer_size; 919 } 920 if (CHANGED(npr, opr, gain)) { 921 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN); 922 } 923 } else { 924 /* these values are preserved even if /dev/audio not open */ 925 if (CHANGED(npr, opr, gain)) { 926 opr->gain = npr->gain; 927 } 928 } 929 930 devaudio_proc_update(dc->dc_proc); 931 bcopy(&dc->dc_proc->p_info, ninfo, sizeof (*ninfo)); 932 933 mutex_exit(&dc->dc_dev->d_mx); 934 mcopyout(mp, NULL, sizeof (audio_info_t), uaddr, bcont); 935 qreply(wq, mp); 936 return; 937 938 err: 939 mutex_exit(&dc->dc_dev->d_mx); 940 miocnak(wq, mp, 0, rv); 941 } 942 943 static void 944 devaudio_ioc_getdev(queue_t *wq, audio_client_t *c, mblk_t *mp) 945 { 946 audio_dev_t *d = auclnt_get_dev(c); 947 mblk_t *bcont; 948 audio_device_t *a; 949 950 if ((bcont = allocb(sizeof (*a), BPRI_MED)) == NULL) { 951 miocnak(wq, mp, 0, ENOMEM); 952 return; 953 } 954 955 a = (void *)bcont->b_wptr; 956 (void) snprintf(a->name, sizeof (a->name), 957 "SUNW,%s", auclnt_get_dev_name(d)); 958 (void) strlcpy(a->config, 959 auclnt_get_dev_description(d), sizeof (a->config)); 960 (void) strlcpy(a->version, 961 auclnt_get_dev_version(d), sizeof (a->version)); 962 bcont->b_wptr += sizeof (*a); 963 964 mcopyout(mp, NULL, sizeof (*a), NULL, bcont); 965 qreply(wq, mp); 966 } 967 968 static int 969 devaudio_sigpoll(audio_client_t *c, void *arg) 970 { 971 daproc_t *proc = arg; 972 daclient_t *dc; 973 974 if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) { 975 dc = auclnt_get_private(c); 976 /* we only need to notify peers in our own process */ 977 if ((dc != NULL) && (dc->dc_proc == proc)) { 978 (void) putnextctl1(auclnt_get_rq(c), M_PCSIG, SIGPOLL); 979 } 980 } 981 return (AUDIO_WALK_CONTINUE); 982 } 983 984 static void 985 devaudio_drain(audio_client_t *c) 986 { 987 daclient_t *dc = auclnt_get_private(c); 988 mblk_t *mplist, *mp; 989 990 mutex_enter(&dc->dc_lock); 991 mplist = dc->dc_draining; 992 dc->dc_draining = NULL; 993 mutex_exit(&dc->dc_lock); 994 995 while ((mp = mplist) != NULL) { 996 mplist = mp->b_next; 997 mp->b_next = NULL; 998 miocack(auclnt_get_wq(c), mp, 0, 0); 999 } 1000 } 1001 1002 static void 1003 devaudio_output(audio_client_t *c) 1004 { 1005 daclient_t *dc = auclnt_get_private(c); 1006 daproc_t *proc = dc->dc_proc; 1007 uint64_t tail; 1008 struct eofcnt *eof; 1009 int eofs = 0; 1010 1011 tail = auclnt_get_tail(auclnt_output_stream(c)); 1012 1013 /* get more data! (do this early) */ 1014 qenable(auclnt_get_wq(c)); 1015 1016 mutex_enter(&dc->dc_lock); 1017 while (((eof = list_head(&dc->dc_eofcnt)) != NULL) && 1018 (eof->tail < tail)) { 1019 list_remove(&dc->dc_eofcnt, eof); 1020 kmem_free(eof, sizeof (*eof)); 1021 eofs++; 1022 } 1023 proc->p_info.play.eof += eofs; 1024 mutex_exit(&dc->dc_lock); 1025 1026 if (eofs) { 1027 auclnt_dev_walk_clients(auclnt_get_dev(c), 1028 devaudio_sigpoll, proc); 1029 } 1030 } 1031 1032 static void * 1033 devaudio_init(audio_dev_t *adev) 1034 { 1035 dadev_t *dev; 1036 unsigned cap; 1037 1038 cap = auclnt_get_dev_capab(adev); 1039 /* if not a play or record device, don't bother initializing it */ 1040 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) { 1041 return (NULL); 1042 } 1043 1044 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP); 1045 dev->d_dev = adev; 1046 mutex_init(&dev->d_mx, NULL, MUTEX_DRIVER, NULL); 1047 cv_init(&dev->d_cv, NULL, CV_DRIVER, NULL); 1048 list_create(&dev->d_procs, sizeof (struct daproc), 1049 offsetof(struct daproc, p_linkage)); 1050 1051 return (dev); 1052 } 1053 1054 static void 1055 devaudio_fini(void *arg) 1056 { 1057 dadev_t *dev = arg; 1058 1059 if (dev != NULL) { 1060 1061 mutex_destroy(&dev->d_mx); 1062 cv_destroy(&dev->d_cv); 1063 list_destroy(&dev->d_procs); 1064 kmem_free(dev, sizeof (*dev)); 1065 } 1066 } 1067 1068 static int 1069 devaudio_open(audio_client_t *c, int oflag) 1070 { 1071 int rv; 1072 1073 if ((rv = auclnt_open(c, AUDIO_FORMAT_PCM, oflag)) != 0) { 1074 return (rv); 1075 } 1076 1077 if ((rv = devaudio_proc_hold(c, oflag)) != 0) { 1078 auclnt_close(c); 1079 return (rv); 1080 } 1081 1082 /* start up the input */ 1083 if (oflag & FREAD) { 1084 auclnt_start(auclnt_input_stream(c)); 1085 } 1086 1087 return (0); 1088 } 1089 1090 static int 1091 devaudioctl_open(audio_client_t *c, int oflag) 1092 { 1093 int rv; 1094 1095 _NOTE(ARGUNUSED(oflag)); 1096 1097 oflag &= ~(FWRITE | FREAD); 1098 1099 if ((rv = auclnt_open(c, AUDIO_FORMAT_NONE, 0)) != 0) { 1100 return (rv); 1101 } 1102 1103 if ((rv = devaudio_proc_hold(c, oflag)) != 0) { 1104 auclnt_close(c); 1105 return (rv); 1106 } 1107 1108 return (0); 1109 } 1110 1111 static void 1112 devaudio_close(audio_client_t *c) 1113 { 1114 auclnt_stop(auclnt_output_stream(c)); 1115 auclnt_stop(auclnt_input_stream(c)); 1116 1117 auclnt_close(c); 1118 devaudio_proc_release(c); 1119 } 1120 1121 static void 1122 devaudioctl_close(audio_client_t *c) 1123 { 1124 auclnt_close(c); 1125 devaudio_proc_release(c); 1126 } 1127 1128 static void 1129 devaudio_miocdata(audio_client_t *c, mblk_t *mp) 1130 { 1131 struct copyresp *csp; 1132 queue_t *wq; 1133 1134 csp = (void *)mp->b_rptr; 1135 wq = auclnt_get_wq(c); 1136 1137 /* 1138 * If a transfer error occurred, the framework already 1139 * MIOCNAK'd it. 1140 */ 1141 if (csp->cp_rval != 0) { 1142 freemsg(mp); 1143 return; 1144 } 1145 1146 /* 1147 * If no state, then this is a response to M_COPYOUT, and we 1148 * are done. (Audio ioctls just copyout a single structure at 1149 * completion of work.) 1150 */ 1151 if (csp->cp_private == NULL) { 1152 miocack(wq, mp, 0, 0); 1153 return; 1154 } 1155 1156 /* now, call the handler ioctl */ 1157 switch (csp->cp_cmd) { 1158 case AUDIO_SETINFO: 1159 devaudio_ioc_setinfo(wq, c, mp); 1160 break; 1161 default: 1162 miocnak(wq, mp, 0, EINVAL); 1163 break; 1164 } 1165 } 1166 1167 static void 1168 devaudio_mioctl(audio_client_t *c, mblk_t *mp) 1169 { 1170 struct iocblk *iocp = (void *)mp->b_rptr; 1171 queue_t *wq = auclnt_get_wq(c); 1172 1173 /* BSD legacy here: we only support transparent ioctls */ 1174 if (iocp->ioc_count != TRANSPARENT) { 1175 miocnak(wq, mp, 0, EINVAL); 1176 return; 1177 } 1178 1179 switch (iocp->ioc_cmd) { 1180 case AUDIO_GETINFO: 1181 devaudio_ioc_getinfo(wq, c, mp); 1182 break; 1183 1184 case AUDIO_SETINFO: 1185 devaudio_ioc_setinfo(wq, c, mp); 1186 break; 1187 1188 case AUDIO_GETDEV: 1189 devaudio_ioc_getdev(wq, c, mp); 1190 break; 1191 1192 case AUDIO_DIAG_LOOPBACK: 1193 /* we don't support this one */ 1194 miocnak(wq, mp, 0, ENOTTY); 1195 break; 1196 1197 case AUDIO_MIXERCTL_GET_MODE: 1198 case AUDIO_MIXERCTL_SET_MODE: 1199 case AUDIO_MIXERCTL_GET_CHINFO: 1200 case AUDIO_MIXERCTL_SET_CHINFO: 1201 case AUDIO_MIXERCTL_GETINFO: 1202 case AUDIO_MIXERCTL_SETINFO: 1203 case AUDIO_GET_NUM_CHS: 1204 case AUDIO_GET_CH_NUMBER: 1205 case AUDIO_GET_CH_TYPE: 1206 case AUDIO_MIXER_SINGLE_OPEN: 1207 case AUDIO_MIXER_MULTIPLE_OPEN: 1208 case AUDIO_MIXER_GET_SAMPLE_RATES: 1209 default: 1210 miocnak(wq, mp, 0, EINVAL); 1211 break; 1212 } 1213 } 1214 1215 static void 1216 devaudioctl_wput(audio_client_t *c, mblk_t *mp) 1217 { 1218 queue_t *wq = auclnt_get_wq(c); 1219 1220 switch (DB_TYPE(mp)) { 1221 case M_IOCTL: 1222 /* Drain ioctl needs to be handled on the service queue */ 1223 devaudio_mioctl(c, mp); 1224 break; 1225 1226 case M_IOCDATA: 1227 devaudio_miocdata(c, mp); 1228 break; 1229 1230 case M_FLUSH: 1231 /* 1232 * We don't flush the engine. The reason is that 1233 * other streams might be using the engine. This is 1234 * fundamentally no different from the case where the 1235 * engine hardware has data buffered in an 1236 * inaccessible FIFO. 1237 * 1238 * Clients that want to ensure no more data is coming 1239 * should stop the stream before flushing. 1240 */ 1241 if (*mp->b_rptr & FLUSHW) { 1242 *mp->b_rptr &= ~FLUSHW; 1243 } 1244 if (*mp->b_rptr & FLUSHR) { 1245 qreply(wq, mp); 1246 } else { 1247 freemsg(mp); 1248 } 1249 break; 1250 1251 case M_DATA: 1252 /* 1253 * No audio data on control nodes! 1254 */ 1255 freemsg(mp); 1256 1257 default: 1258 freemsg(mp); 1259 break; 1260 } 1261 } 1262 1263 static void 1264 devaudio_wput(audio_client_t *c, mblk_t *mp) 1265 { 1266 queue_t *wq = auclnt_get_wq(c); 1267 1268 switch (DB_TYPE(mp)) { 1269 case M_IOCTL: 1270 /* Drain ioctl needs to be handled on the service queue */ 1271 if (*(int *)(void *)mp->b_rptr == AUDIO_DRAIN) { 1272 (void) putq(wq, mp); 1273 } else { 1274 devaudio_mioctl(c, mp); 1275 } 1276 break; 1277 1278 case M_IOCDATA: 1279 devaudio_miocdata(c, mp); 1280 break; 1281 1282 case M_FLUSH: 1283 /* 1284 * We don't flush the engine. The reason is that 1285 * other streams might be using the engine. This is 1286 * fundamentally no different from the case where the 1287 * engine hardware has data buffered in an 1288 * inaccessible FIFO. 1289 * 1290 * Clients that want to ensure no more data is coming 1291 * should stop the stream before flushing. 1292 */ 1293 if (*mp->b_rptr & FLUSHW) { 1294 flushq(wq, FLUSHALL); 1295 auclnt_flush(auclnt_output_stream(c)); 1296 *mp->b_rptr &= ~FLUSHW; 1297 } 1298 if (*mp->b_rptr & FLUSHR) { 1299 flushq(RD(wq), FLUSHALL); 1300 auclnt_flush(auclnt_input_stream(c)); 1301 qreply(wq, mp); 1302 } else { 1303 freemsg(mp); 1304 } 1305 break; 1306 1307 case M_DATA: 1308 /* 1309 * Defer processing to the queue. This keeps the data 1310 * ordered, and allows the wsrv routine to gather 1311 * multiple mblks at once. 1312 */ 1313 if (mp->b_cont != NULL) { 1314 1315 /* 1316 * If we need to pullup, do it here to 1317 * simplify the rest of the processing later. 1318 * This should rarely (if ever) be necessary. 1319 */ 1320 mblk_t *nmp; 1321 1322 if ((nmp = msgpullup(mp, -1)) == NULL) { 1323 freemsg(mp); 1324 } else { 1325 freemsg(mp); 1326 (void) putq(wq, nmp); 1327 } 1328 } else { 1329 (void) putq(wq, mp); 1330 } 1331 break; 1332 1333 default: 1334 freemsg(mp); 1335 break; 1336 } 1337 } 1338 1339 static void 1340 devaudio_wsrv(audio_client_t *c) 1341 { 1342 queue_t *wq = auclnt_get_wq(c); 1343 daclient_t *dc = auclnt_get_private(c); 1344 audio_stream_t *sp; 1345 mblk_t *mp; 1346 unsigned framesz; 1347 1348 sp = auclnt_output_stream(c); 1349 1350 framesz = auclnt_get_framesz(sp); 1351 1352 while ((mp = getq(wq)) != NULL) { 1353 1354 unsigned count; 1355 1356 /* got a message */ 1357 1358 /* if its a drain ioctl, we need to process it here */ 1359 if (DB_TYPE(mp) == M_IOCTL) { 1360 ASSERT((*(int *)(void *)mp->b_rptr) == AUDIO_DRAIN); 1361 mutex_enter(&dc->dc_lock); 1362 mp->b_next = dc->dc_draining; 1363 dc->dc_draining = mp; 1364 mutex_exit(&dc->dc_lock); 1365 1366 if (auclnt_start_drain(c) != 0) { 1367 devaudio_drain(c); 1368 } 1369 continue; 1370 } 1371 1372 ASSERT(DB_TYPE(mp) == M_DATA); 1373 1374 /* 1375 * Empty mblk require special handling, since they 1376 * indicate EOF. We treat them separate from the main 1377 * processing loop. 1378 */ 1379 if (MBLKL(mp) == 0) { 1380 struct eofcnt *eof; 1381 1382 eof = kmem_zalloc(sizeof (*eof), KM_NOSLEEP); 1383 if (eof != NULL) { 1384 eof->tail = auclnt_get_head(sp); 1385 mutex_enter(&dc->dc_lock); 1386 list_insert_tail(&dc->dc_eofcnt, eof); 1387 mutex_exit(&dc->dc_lock); 1388 } 1389 freemsg(mp); 1390 continue; 1391 } 1392 1393 count = auclnt_produce_data(sp, (caddr_t)mp->b_rptr, 1394 MBLKL(mp) / framesz); 1395 1396 mp->b_rptr += count * framesz; 1397 1398 if (MBLKL(mp) >= framesz) { 1399 (void) putbq(wq, mp); 1400 break; 1401 } else { 1402 freemsg(mp); 1403 } 1404 } 1405 1406 /* if the stream isn't running yet, start it up */ 1407 if (!auclnt_is_paused(sp)) 1408 auclnt_start(sp); 1409 } 1410 1411 static struct audio_client_ops devaudio_ops = { 1412 "sound,audio", 1413 devaudio_init, 1414 devaudio_fini, 1415 devaudio_open, 1416 devaudio_close, 1417 NULL, /* read */ 1418 NULL, /* write */ 1419 NULL, /* ioctl */ 1420 NULL, /* chpoll */ 1421 NULL, /* mmap */ 1422 devaudio_input, 1423 devaudio_output, 1424 NULL, /* notify */ 1425 devaudio_drain, 1426 devaudio_wput, 1427 devaudio_wsrv 1428 }; 1429 1430 static struct audio_client_ops devaudioctl_ops = { 1431 "sound,audioctl", 1432 NULL, /* dev_init */ 1433 NULL, /* dev_fini */ 1434 devaudioctl_open, 1435 devaudioctl_close, 1436 NULL, /* read */ 1437 NULL, /* write */ 1438 NULL, /* ioctl */ 1439 NULL, /* chpoll */ 1440 NULL, /* mmap */ 1441 NULL, /* output */ 1442 NULL, /* input */ 1443 NULL, /* notify */ 1444 NULL, /* drain */ 1445 devaudioctl_wput, 1446 NULL, 1447 }; 1448 1449 void 1450 auimpl_sun_init(void) 1451 { 1452 auclnt_register_ops(AUDIO_MINOR_DEVAUDIO, &devaudio_ops); 1453 auclnt_register_ops(AUDIO_MINOR_DEVAUDIOCTL, &devaudioctl_ops); 1454 } 1455