1/* 2 * sound/oss/audio.c 3 * 4 * Device file manager for /dev/audio 5 */ 6 7/* 8 * Copyright (C) by Hannu Savolainen 1993-1997 9 * 10 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) 11 * Version 2 (June 1991). See the "COPYING" file distributed with this software 12 * for more info. 13 */ 14/* 15 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) 16 * Thomas Sailer : moved several static variables into struct audio_operations 17 * (which is grossly misnamed btw.) because they have the same 18 * lifetime as the rest in there and dynamic allocation saves 19 * 12k or so 20 * Thomas Sailer : use more logical O_NONBLOCK semantics 21 * Daniel Rodriksson: reworked the use of the device specific copy_user 22 * still generic 23 * Horst von Brand: Add missing #include <linux/string.h> 24 * Chris Rankin : Update the module-usage counter for the coprocessor, 25 * and decrement the counters again if we cannot open 26 * the audio device. 27 */ 28 29#include <linux/stddef.h> 30#include <linux/string.h> 31#include <linux/kmod.h> 32 33#include "sound_config.h" 34#include "ulaw.h" 35#include "coproc.h" 36 37#define NEUTRAL8 0x80 38#define NEUTRAL16 0x00 39 40 41static int dma_ioctl(int dev, unsigned int cmd, void __user *arg); 42 43static int set_format(int dev, int fmt) 44{ 45 if (fmt != AFMT_QUERY) 46 { 47 audio_devs[dev]->local_conversion = 0; 48 49 if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */ 50 { 51 if (fmt == AFMT_MU_LAW) 52 { 53 fmt = AFMT_U8; 54 audio_devs[dev]->local_conversion = CNV_MU_LAW; 55 } 56 else 57 fmt = AFMT_U8; /* This is always supported */ 58 } 59 audio_devs[dev]->audio_format = audio_devs[dev]->d->set_bits(dev, fmt); 60 audio_devs[dev]->local_format = fmt; 61 } 62 else 63 return audio_devs[dev]->local_format; 64 65 if (audio_devs[dev]->local_conversion) 66 return audio_devs[dev]->local_conversion; 67 else 68 return audio_devs[dev]->local_format; 69} 70 71int audio_open(int dev, struct file *file) 72{ 73 int ret; 74 int bits; 75 int dev_type = dev & 0x0f; 76 int mode = translate_mode(file); 77 const struct audio_driver *driver; 78 const struct coproc_operations *coprocessor; 79 80 dev = dev >> 4; 81 82 if (dev_type == SND_DEV_DSP16) 83 bits = 16; 84 else 85 bits = 8; 86 87 if (dev < 0 || dev >= num_audiodevs) 88 return -ENXIO; 89 90 driver = audio_devs[dev]->d; 91 92 if (!try_module_get(driver->owner)) 93 return -ENODEV; 94 95 if ((ret = DMAbuf_open(dev, mode)) < 0) 96 goto error_1; 97 98 if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) { 99 if (!try_module_get(coprocessor->owner)) 100 goto error_2; 101 102 if ((ret = coprocessor->open(coprocessor->devc, COPR_PCM)) < 0) { 103 printk(KERN_WARNING "Sound: Can't access coprocessor device\n"); 104 goto error_3; 105 } 106 } 107 108 audio_devs[dev]->local_conversion = 0; 109 110 if (dev_type == SND_DEV_AUDIO) 111 set_format(dev, AFMT_MU_LAW); 112 else 113 set_format(dev, bits); 114 115 audio_devs[dev]->audio_mode = AM_NONE; 116 117 return 0; 118 119 /* 120 * Clean-up stack: this is what needs (un)doing if 121 * we can't open the audio device ... 122 */ 123 error_3: 124 module_put(coprocessor->owner); 125 126 error_2: 127 DMAbuf_release(dev, mode); 128 129 error_1: 130 module_put(driver->owner); 131 132 return ret; 133} 134 135static void sync_output(int dev) 136{ 137 int p, i; 138 int l; 139 struct dma_buffparms *dmap = audio_devs[dev]->dmap_out; 140 141 if (dmap->fragment_size <= 0) 142 return; 143 dmap->flags |= DMA_POST; 144 145 /* Align the write pointer with fragment boundaries */ 146 147 if ((l = dmap->user_counter % dmap->fragment_size) > 0) 148 { 149 int len; 150 unsigned long offs = dmap->user_counter % dmap->bytes_in_use; 151 152 len = dmap->fragment_size - l; 153 memset(dmap->raw_buf + offs, dmap->neutral_byte, len); 154 DMAbuf_move_wrpointer(dev, len); 155 } 156 157 /* 158 * Clean all unused buffer fragments. 159 */ 160 161 p = dmap->qtail; 162 dmap->flags |= DMA_POST; 163 164 for (i = dmap->qlen + 1; i < dmap->nbufs; i++) 165 { 166 p = (p + 1) % dmap->nbufs; 167 if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) > 168 (dmap->raw_buf + dmap->buffsize)) 169 printk(KERN_ERR "audio: Buffer error 2\n"); 170 171 memset(dmap->raw_buf + p * dmap->fragment_size, 172 dmap->neutral_byte, 173 dmap->fragment_size); 174 } 175 176 dmap->flags |= DMA_DIRTY; 177} 178 179void audio_release(int dev, struct file *file) 180{ 181 const struct coproc_operations *coprocessor; 182 int mode = translate_mode(file); 183 184 dev = dev >> 4; 185 186 /* 187 * We do this in DMAbuf_release(). Why are we doing it 188 * here? Why don't we test the file mode before setting 189 * both flags? DMAbuf_release() does. 190 * ...pester...pester...pester... 191 */ 192 audio_devs[dev]->dmap_out->closing = 1; 193 audio_devs[dev]->dmap_in->closing = 1; 194 195 /* 196 * We need to make sure we allocated the dmap_out buffer 197 * before we go mucking around with it in sync_output(). 198 */ 199 if (mode & OPEN_WRITE) 200 sync_output(dev); 201 202 if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) { 203 coprocessor->close(coprocessor->devc, COPR_PCM); 204 module_put(coprocessor->owner); 205 } 206 DMAbuf_release(dev, mode); 207 208 module_put(audio_devs[dev]->d->owner); 209} 210 211static void translate_bytes(const unsigned char *table, unsigned char *buff, int n) 212{ 213 unsigned long i; 214 215 if (n <= 0) 216 return; 217 218 for (i = 0; i < n; ++i) 219 buff[i] = table[buff[i]]; 220} 221 222int audio_write(int dev, struct file *file, const char __user *buf, int count) 223{ 224 int c, p, l, buf_size, used, returned; 225 int err; 226 char *dma_buf; 227 228 dev = dev >> 4; 229 230 p = 0; 231 c = count; 232 233 if(count < 0) 234 return -EINVAL; 235 236 if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) 237 return -EPERM; 238 239 if (audio_devs[dev]->flags & DMA_DUPLEX) 240 audio_devs[dev]->audio_mode |= AM_WRITE; 241 else 242 audio_devs[dev]->audio_mode = AM_WRITE; 243 244 if (!count) /* Flush output */ 245 { 246 sync_output(dev); 247 return 0; 248 } 249 250 while (c) 251 { 252 if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, !!(file->f_flags & O_NONBLOCK))) < 0) 253 { 254 /* Handle nonblocking mode */ 255 if ((file->f_flags & O_NONBLOCK) && err == -EAGAIN) 256 return p? p : -EAGAIN; /* No more space. Return # of accepted bytes */ 257 return err; 258 } 259 l = c; 260 261 if (l > buf_size) 262 l = buf_size; 263 264 returned = l; 265 used = l; 266 if (!audio_devs[dev]->d->copy_user) 267 { 268 if ((dma_buf + l) > 269 (audio_devs[dev]->dmap_out->raw_buf + audio_devs[dev]->dmap_out->buffsize)) 270 { 271 printk(KERN_ERR "audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf, l, (long) audio_devs[dev]->dmap_out->raw_buf, (int) audio_devs[dev]->dmap_out->buffsize); 272 return -EDOM; 273 } 274 if (dma_buf < audio_devs[dev]->dmap_out->raw_buf) 275 { 276 printk(KERN_ERR "audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf); 277 return -EDOM; 278 } 279 if(copy_from_user(dma_buf, &(buf)[p], l)) 280 return -EFAULT; 281 } 282 else audio_devs[dev]->d->copy_user (dev, 283 dma_buf, 0, 284 buf, p, 285 c, buf_size, 286 &used, &returned, 287 l); 288 l = returned; 289 290 if (audio_devs[dev]->local_conversion & CNV_MU_LAW) 291 { 292 translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l); 293 } 294 c -= used; 295 p += used; 296 DMAbuf_move_wrpointer(dev, l); 297 298 } 299 300 return count; 301} 302 303int audio_read(int dev, struct file *file, char __user *buf, int count) 304{ 305 int c, p, l; 306 char *dmabuf; 307 int buf_no; 308 309 dev = dev >> 4; 310 p = 0; 311 c = count; 312 313 if (!(audio_devs[dev]->open_mode & OPEN_READ)) 314 return -EPERM; 315 316 if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX)) 317 sync_output(dev); 318 319 if (audio_devs[dev]->flags & DMA_DUPLEX) 320 audio_devs[dev]->audio_mode |= AM_READ; 321 else 322 audio_devs[dev]->audio_mode = AM_READ; 323 324 while(c) 325 { 326 if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l, !!(file->f_flags & O_NONBLOCK))) < 0) 327 { 328 /* 329 * Nonblocking mode handling. Return current # of bytes 330 */ 331 332 if (p > 0) /* Avoid throwing away data */ 333 return p; /* Return it instead */ 334 335 if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN) 336 return -EAGAIN; 337 338 return buf_no; 339 } 340 if (l > c) 341 l = c; 342 343 /* 344 * Insert any local processing here. 345 */ 346 347 if (audio_devs[dev]->local_conversion & CNV_MU_LAW) 348 { 349 translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l); 350 } 351 352 { 353 char *fixit = dmabuf; 354 355 if(copy_to_user(&(buf)[p], fixit, l)) 356 return -EFAULT; 357 } 358 359 DMAbuf_rmchars(dev, buf_no, l); 360 361 p += l; 362 c -= l; 363 } 364 365 return count - c; 366} 367 368int audio_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg) 369{ 370 int val, count; 371 unsigned long flags; 372 struct dma_buffparms *dmap; 373 int __user *p = arg; 374 375 dev = dev >> 4; 376 377 if (_IOC_TYPE(cmd) == 'C') { 378 if (audio_devs[dev]->coproc) /* Coprocessor ioctl */ 379 return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0); 380 /* else 381 printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */ 382 return -ENXIO; 383 } 384 else switch (cmd) 385 { 386 case SNDCTL_DSP_SYNC: 387 if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) 388 return 0; 389 if (audio_devs[dev]->dmap_out->fragment_size == 0) 390 return 0; 391 sync_output(dev); 392 DMAbuf_sync(dev); 393 DMAbuf_reset(dev); 394 return 0; 395 396 case SNDCTL_DSP_POST: 397 if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) 398 return 0; 399 if (audio_devs[dev]->dmap_out->fragment_size == 0) 400 return 0; 401 audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY; 402 sync_output(dev); 403 dma_ioctl(dev, SNDCTL_DSP_POST, NULL); 404 return 0; 405 406 case SNDCTL_DSP_RESET: 407 audio_devs[dev]->audio_mode = AM_NONE; 408 DMAbuf_reset(dev); 409 return 0; 410 411 case SNDCTL_DSP_GETFMTS: 412 val = audio_devs[dev]->format_mask | AFMT_MU_LAW; 413 break; 414 415 case SNDCTL_DSP_SETFMT: 416 if (get_user(val, p)) 417 return -EFAULT; 418 val = set_format(dev, val); 419 break; 420 421 case SNDCTL_DSP_GETISPACE: 422 if (!(audio_devs[dev]->open_mode & OPEN_READ)) 423 return 0; 424 if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX)) 425 return -EBUSY; 426 return dma_ioctl(dev, cmd, arg); 427 428 case SNDCTL_DSP_GETOSPACE: 429 if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) 430 return -EPERM; 431 if ((audio_devs[dev]->audio_mode & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX)) 432 return -EBUSY; 433 return dma_ioctl(dev, cmd, arg); 434 435 case SNDCTL_DSP_NONBLOCK: 436 spin_lock(&file->f_lock); 437 file->f_flags |= O_NONBLOCK; 438 spin_unlock(&file->f_lock); 439 return 0; 440 441 case SNDCTL_DSP_GETCAPS: 442 val = 1 | DSP_CAP_MMAP; /* Revision level of this ioctl() */ 443 if (audio_devs[dev]->flags & DMA_DUPLEX && 444 audio_devs[dev]->open_mode == OPEN_READWRITE) 445 val |= DSP_CAP_DUPLEX; 446 if (audio_devs[dev]->coproc) 447 val |= DSP_CAP_COPROC; 448 if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */ 449 val |= DSP_CAP_BATCH; 450 if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */ 451 val |= DSP_CAP_TRIGGER; 452 break; 453 454 case SOUND_PCM_WRITE_RATE: 455 if (get_user(val, p)) 456 return -EFAULT; 457 val = audio_devs[dev]->d->set_speed(dev, val); 458 break; 459 460 case SOUND_PCM_READ_RATE: 461 val = audio_devs[dev]->d->set_speed(dev, 0); 462 break; 463 464 case SNDCTL_DSP_STEREO: 465 if (get_user(val, p)) 466 return -EFAULT; 467 if (val > 1 || val < 0) 468 return -EINVAL; 469 val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1; 470 break; 471 472 case SOUND_PCM_WRITE_CHANNELS: 473 if (get_user(val, p)) 474 return -EFAULT; 475 val = audio_devs[dev]->d->set_channels(dev, val); 476 break; 477 478 case SOUND_PCM_READ_CHANNELS: 479 val = audio_devs[dev]->d->set_channels(dev, 0); 480 break; 481 482 case SOUND_PCM_READ_BITS: 483 val = audio_devs[dev]->d->set_bits(dev, 0); 484 break; 485 486 case SNDCTL_DSP_SETDUPLEX: 487 if (audio_devs[dev]->open_mode != OPEN_READWRITE) 488 return -EPERM; 489 return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO; 490 491 case SNDCTL_DSP_PROFILE: 492 if (get_user(val, p)) 493 return -EFAULT; 494 if (audio_devs[dev]->open_mode & OPEN_WRITE) 495 audio_devs[dev]->dmap_out->applic_profile = val; 496 if (audio_devs[dev]->open_mode & OPEN_READ) 497 audio_devs[dev]->dmap_in->applic_profile = val; 498 return 0; 499 500 case SNDCTL_DSP_GETODELAY: 501 dmap = audio_devs[dev]->dmap_out; 502 if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) 503 return -EINVAL; 504 if (!(dmap->flags & DMA_ALLOC_DONE)) 505 { 506 val=0; 507 break; 508 } 509 510 spin_lock_irqsave(&dmap->lock,flags); 511 /* Compute number of bytes that have been played */ 512 count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT); 513 if (count < dmap->fragment_size && dmap->qhead != 0) 514 count += dmap->bytes_in_use; /* Pointer wrap not handled yet */ 515 count += dmap->byte_counter; 516 517 /* Subtract current count from the number of bytes written by app */ 518 count = dmap->user_counter - count; 519 if (count < 0) 520 count = 0; 521 spin_unlock_irqrestore(&dmap->lock,flags); 522 val = count; 523 break; 524 525 default: 526 return dma_ioctl(dev, cmd, arg); 527 } 528 return put_user(val, p); 529} 530 531void audio_init_devices(void) 532{ 533 /* 534 * NOTE! This routine could be called several times during boot. 535 */ 536} 537 538void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording) 539{ 540 /* 541 * This routine breaks the physical device buffers to logical ones. 542 */ 543 544 struct audio_operations *dsp_dev = audio_devs[dev]; 545 546 unsigned i, n; 547 unsigned sr, nc, sz, bsz; 548 549 sr = dsp_dev->d->set_speed(dev, 0); 550 nc = dsp_dev->d->set_channels(dev, 0); 551 sz = dsp_dev->d->set_bits(dev, 0); 552 553 if (sz == 8) 554 dmap->neutral_byte = NEUTRAL8; 555 else 556 dmap->neutral_byte = NEUTRAL16; 557 558 if (sr < 1 || nc < 1 || sz < 1) 559 { 560/* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/ 561 sr = DSP_DEFAULT_SPEED; 562 nc = 1; 563 sz = 8; 564 } 565 566 sz = sr * nc * sz; 567 568 sz /= 8; /* #bits -> #bytes */ 569 dmap->data_rate = sz; 570 571 if (!dmap->needs_reorg) 572 return; 573 dmap->needs_reorg = 0; 574 575 if (dmap->fragment_size == 0) 576 { 577 /* Compute the fragment size using the default algorithm */ 578 579 /* 580 * Compute a buffer size for time not exceeding 1 second. 581 * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds 582 * of sound (using the current speed, sample size and #channels). 583 */ 584 585 bsz = dmap->buffsize; 586 while (bsz > sz) 587 bsz /= 2; 588 589 if (bsz == dmap->buffsize) 590 bsz /= 2; /* Needs at least 2 buffers */ 591 592 /* 593 * Split the computed fragment to smaller parts. After 3.5a9 594 * the default subdivision is 4 which should give better 595 * results when recording. 596 */ 597 598 if (dmap->subdivision == 0) /* Not already set */ 599 { 600 dmap->subdivision = 4; /* Init to the default value */ 601 602 if ((bsz / dmap->subdivision) > 4096) 603 dmap->subdivision *= 2; 604 if ((bsz / dmap->subdivision) < 4096) 605 dmap->subdivision = 1; 606 } 607 bsz /= dmap->subdivision; 608 609 if (bsz < 16) 610 bsz = 16; /* Just a sanity check */ 611 612 dmap->fragment_size = bsz; 613 } 614 else 615 { 616 /* 617 * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or 618 * the buffer size computation has already been done. 619 */ 620 if (dmap->fragment_size > (dmap->buffsize / 2)) 621 dmap->fragment_size = (dmap->buffsize / 2); 622 bsz = dmap->fragment_size; 623 } 624 625 if (audio_devs[dev]->min_fragment) 626 if (bsz < (1 << audio_devs[dev]->min_fragment)) 627 bsz = 1 << audio_devs[dev]->min_fragment; 628 if (audio_devs[dev]->max_fragment) 629 if (bsz > (1 << audio_devs[dev]->max_fragment)) 630 bsz = 1 << audio_devs[dev]->max_fragment; 631 bsz &= ~0x07; /* Force size which is multiple of 8 bytes */ 632#ifdef OS_DMA_ALIGN_CHECK 633 OS_DMA_ALIGN_CHECK(bsz); 634#endif 635 636 n = dmap->buffsize / bsz; 637 if (n > MAX_SUB_BUFFERS) 638 n = MAX_SUB_BUFFERS; 639 if (n > dmap->max_fragments) 640 n = dmap->max_fragments; 641 642 if (n < 2) 643 { 644 n = 2; 645 bsz /= 2; 646 } 647 dmap->nbufs = n; 648 dmap->bytes_in_use = n * bsz; 649 dmap->fragment_size = bsz; 650 dmap->max_byte_counter = (dmap->data_rate * 60 * 60) + 651 dmap->bytes_in_use; /* Approximately one hour */ 652 653 if (dmap->raw_buf) 654 { 655 memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use); 656 } 657 658 for (i = 0; i < dmap->nbufs; i++) 659 { 660 dmap->counts[i] = 0; 661 } 662 663 dmap->flags |= DMA_ALLOC_DONE | DMA_EMPTY; 664} 665 666static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact) 667{ 668 if (fact == 0) 669 { 670 fact = dmap->subdivision; 671 if (fact == 0) 672 fact = 1; 673 return fact; 674 } 675 if (dmap->subdivision != 0 || dmap->fragment_size) /* Too late to change */ 676 return -EINVAL; 677 678 if (fact > MAX_REALTIME_FACTOR) 679 return -EINVAL; 680 681 if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16) 682 return -EINVAL; 683 684 dmap->subdivision = fact; 685 return fact; 686} 687 688static int dma_set_fragment(int dev, struct dma_buffparms *dmap, int fact) 689{ 690 int bytes, count; 691 692 if (fact == 0) 693 return -EIO; 694 695 if (dmap->subdivision != 0 || 696 dmap->fragment_size) /* Too late to change */ 697 return -EINVAL; 698 699 bytes = fact & 0xffff; 700 count = (fact >> 16) & 0x7fff; 701 702 if (count == 0) 703 count = MAX_SUB_BUFFERS; 704 else if (count < MAX_SUB_BUFFERS) 705 count++; 706 707 if (bytes < 4 || bytes > 17) /* <16 || > 512k */ 708 return -EINVAL; 709 710 if (count < 2) 711 return -EINVAL; 712 713 if (audio_devs[dev]->min_fragment > 0) 714 if (bytes < audio_devs[dev]->min_fragment) 715 bytes = audio_devs[dev]->min_fragment; 716 717 if (audio_devs[dev]->max_fragment > 0) 718 if (bytes > audio_devs[dev]->max_fragment) 719 bytes = audio_devs[dev]->max_fragment; 720 721#ifdef OS_DMA_MINBITS 722 if (bytes < OS_DMA_MINBITS) 723 bytes = OS_DMA_MINBITS; 724#endif 725 726 dmap->fragment_size = (1 << bytes); 727 dmap->max_fragments = count; 728 729 if (dmap->fragment_size > dmap->buffsize) 730 dmap->fragment_size = dmap->buffsize; 731 732 if (dmap->fragment_size == dmap->buffsize && 733 audio_devs[dev]->flags & DMA_AUTOMODE) 734 dmap->fragment_size /= 2; /* Needs at least 2 buffers */ 735 736 dmap->subdivision = 1; /* Disable SNDCTL_DSP_SUBDIVIDE */ 737 return bytes | ((count - 1) << 16); 738} 739 740static int dma_ioctl(int dev, unsigned int cmd, void __user *arg) 741{ 742 struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out; 743 struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in; 744 struct dma_buffparms *dmap; 745 audio_buf_info info; 746 count_info cinfo; 747 int fact, ret, changed, bits, count, err; 748 unsigned long flags; 749 750 switch (cmd) 751 { 752 case SNDCTL_DSP_SUBDIVIDE: 753 ret = 0; 754 if (get_user(fact, (int __user *)arg)) 755 return -EFAULT; 756 if (audio_devs[dev]->open_mode & OPEN_WRITE) 757 ret = dma_subdivide(dev, dmap_out, fact); 758 if (ret < 0) 759 return ret; 760 if (audio_devs[dev]->open_mode != OPEN_WRITE || 761 (audio_devs[dev]->flags & DMA_DUPLEX && 762 audio_devs[dev]->open_mode & OPEN_READ)) 763 ret = dma_subdivide(dev, dmap_in, fact); 764 if (ret < 0) 765 return ret; 766 break; 767 768 case SNDCTL_DSP_GETISPACE: 769 case SNDCTL_DSP_GETOSPACE: 770 dmap = dmap_out; 771 if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ)) 772 return -EINVAL; 773 if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE)) 774 return -EINVAL; 775 if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX) 776 dmap = dmap_in; 777 if (dmap->mapping_flags & DMA_MAP_MAPPED) 778 return -EINVAL; 779 if (!(dmap->flags & DMA_ALLOC_DONE)) 780 reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE)); 781 info.fragstotal = dmap->nbufs; 782 if (cmd == SNDCTL_DSP_GETISPACE) 783 info.fragments = dmap->qlen; 784 else 785 { 786 if (!DMAbuf_space_in_queue(dev)) 787 info.fragments = 0; 788 else 789 { 790 info.fragments = DMAbuf_space_in_queue(dev); 791 if (audio_devs[dev]->d->local_qlen) 792 { 793 int tmp = audio_devs[dev]->d->local_qlen(dev); 794 if (tmp && info.fragments) 795 tmp--; /* 796 * This buffer has been counted twice 797 */ 798 info.fragments -= tmp; 799 } 800 } 801 } 802 if (info.fragments < 0) 803 info.fragments = 0; 804 else if (info.fragments > dmap->nbufs) 805 info.fragments = dmap->nbufs; 806 807 info.fragsize = dmap->fragment_size; 808 info.bytes = info.fragments * dmap->fragment_size; 809 810 if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen) 811 info.bytes -= dmap->counts[dmap->qhead]; 812 else 813 { 814 info.fragments = info.bytes / dmap->fragment_size; 815 info.bytes -= dmap->user_counter % dmap->fragment_size; 816 } 817 if (copy_to_user(arg, &info, sizeof(info))) 818 return -EFAULT; 819 return 0; 820 821 case SNDCTL_DSP_SETTRIGGER: 822 if (get_user(bits, (int __user *)arg)) 823 return -EFAULT; 824 bits &= audio_devs[dev]->open_mode; 825 if (audio_devs[dev]->d->trigger == NULL) 826 return -EINVAL; 827 if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) && 828 (bits & PCM_ENABLE_OUTPUT)) 829 return -EINVAL; 830 831 if (bits & PCM_ENABLE_INPUT) 832 { 833 spin_lock_irqsave(&dmap_in->lock,flags); 834 changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_INPUT; 835 if (changed && audio_devs[dev]->go) 836 { 837 reorganize_buffers(dev, dmap_in, 1); 838 if ((err = audio_devs[dev]->d->prepare_for_input(dev, 839 dmap_in->fragment_size, dmap_in->nbufs)) < 0) { 840 spin_unlock_irqrestore(&dmap_in->lock,flags); 841 return err; 842 } 843 dmap_in->dma_mode = DMODE_INPUT; 844 audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT; 845 DMAbuf_activate_recording(dev, dmap_in); 846 } else 847 audio_devs[dev]->enable_bits &= ~PCM_ENABLE_INPUT; 848 spin_unlock_irqrestore(&dmap_in->lock,flags); 849 } 850 if (bits & PCM_ENABLE_OUTPUT) 851 { 852 spin_lock_irqsave(&dmap_out->lock,flags); 853 changed = (audio_devs[dev]->enable_bits ^ bits) & PCM_ENABLE_OUTPUT; 854 if (changed && 855 (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) && 856 audio_devs[dev]->go) 857 { 858 if (!(dmap_out->flags & DMA_ALLOC_DONE)) 859 reorganize_buffers(dev, dmap_out, 0); 860 dmap_out->dma_mode = DMODE_OUTPUT; 861 audio_devs[dev]->enable_bits |= PCM_ENABLE_OUTPUT; 862 dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size; 863 DMAbuf_launch_output(dev, dmap_out); 864 } else 865 audio_devs[dev]->enable_bits &= ~PCM_ENABLE_OUTPUT; 866 spin_unlock_irqrestore(&dmap_out->lock,flags); 867 } 868#if 0 869 if (changed && audio_devs[dev]->d->trigger) 870 audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go); 871#endif 872 /* Falls through... */ 873 874 case SNDCTL_DSP_GETTRIGGER: 875 ret = audio_devs[dev]->enable_bits; 876 break; 877 878 case SNDCTL_DSP_SETSYNCRO: 879 if (!audio_devs[dev]->d->trigger) 880 return -EINVAL; 881 audio_devs[dev]->d->trigger(dev, 0); 882 audio_devs[dev]->go = 0; 883 return 0; 884 885 case SNDCTL_DSP_GETIPTR: 886 if (!(audio_devs[dev]->open_mode & OPEN_READ)) 887 return -EINVAL; 888 spin_lock_irqsave(&dmap_in->lock,flags); 889 cinfo.bytes = dmap_in->byte_counter; 890 cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3; 891 if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0) 892 cinfo.bytes += dmap_in->bytes_in_use; /* Pointer wrap not handled yet */ 893 cinfo.blocks = dmap_in->qlen; 894 cinfo.bytes += cinfo.ptr; 895 if (dmap_in->mapping_flags & DMA_MAP_MAPPED) 896 dmap_in->qlen = 0; /* Reset interrupt counter */ 897 spin_unlock_irqrestore(&dmap_in->lock,flags); 898 if (copy_to_user(arg, &cinfo, sizeof(cinfo))) 899 return -EFAULT; 900 return 0; 901 902 case SNDCTL_DSP_GETOPTR: 903 if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) 904 return -EINVAL; 905 906 spin_lock_irqsave(&dmap_out->lock,flags); 907 cinfo.bytes = dmap_out->byte_counter; 908 cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3; 909 if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0) 910 cinfo.bytes += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */ 911 cinfo.blocks = dmap_out->qlen; 912 cinfo.bytes += cinfo.ptr; 913 if (dmap_out->mapping_flags & DMA_MAP_MAPPED) 914 dmap_out->qlen = 0; /* Reset interrupt counter */ 915 spin_unlock_irqrestore(&dmap_out->lock,flags); 916 if (copy_to_user(arg, &cinfo, sizeof(cinfo))) 917 return -EFAULT; 918 return 0; 919 920 case SNDCTL_DSP_GETODELAY: 921 if (!(audio_devs[dev]->open_mode & OPEN_WRITE)) 922 return -EINVAL; 923 if (!(dmap_out->flags & DMA_ALLOC_DONE)) 924 { 925 ret=0; 926 break; 927 } 928 spin_lock_irqsave(&dmap_out->lock,flags); 929 /* Compute number of bytes that have been played */ 930 count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT); 931 if (count < dmap_out->fragment_size && dmap_out->qhead != 0) 932 count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */ 933 count += dmap_out->byte_counter; 934 /* Subtract current count from the number of bytes written by app */ 935 count = dmap_out->user_counter - count; 936 if (count < 0) 937 count = 0; 938 spin_unlock_irqrestore(&dmap_out->lock,flags); 939 ret = count; 940 break; 941 942 case SNDCTL_DSP_POST: 943 if (audio_devs[dev]->dmap_out->qlen > 0) 944 if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE)) 945 DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out); 946 return 0; 947 948 case SNDCTL_DSP_GETBLKSIZE: 949 dmap = dmap_out; 950 if (audio_devs[dev]->open_mode & OPEN_WRITE) 951 reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ)); 952 if (audio_devs[dev]->open_mode == OPEN_READ || 953 (audio_devs[dev]->flags & DMA_DUPLEX && 954 audio_devs[dev]->open_mode & OPEN_READ)) 955 reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ)); 956 if (audio_devs[dev]->open_mode == OPEN_READ) 957 dmap = dmap_in; 958 ret = dmap->fragment_size; 959 break; 960 961 case SNDCTL_DSP_SETFRAGMENT: 962 ret = 0; 963 if (get_user(fact, (int __user *)arg)) 964 return -EFAULT; 965 if (audio_devs[dev]->open_mode & OPEN_WRITE) 966 ret = dma_set_fragment(dev, dmap_out, fact); 967 if (ret < 0) 968 return ret; 969 if (audio_devs[dev]->open_mode == OPEN_READ || 970 (audio_devs[dev]->flags & DMA_DUPLEX && 971 audio_devs[dev]->open_mode & OPEN_READ)) 972 ret = dma_set_fragment(dev, dmap_in, fact); 973 if (ret < 0) 974 return ret; 975 if (!arg) /* don't know what this is good for, but preserve old semantics */ 976 return 0; 977 break; 978 979 default: 980 if (!audio_devs[dev]->d->ioctl) 981 return -EINVAL; 982 return audio_devs[dev]->d->ioctl(dev, cmd, arg); 983 } 984 return put_user(ret, (int __user *)arg); 985} 986