root/drivers/sound/soundcard.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_ioctl_return
  2. sound_read
  3. sound_write
  4. sound_lseek
  5. sound_open
  6. sound_release
  7. sound_ioctl
  8. sound_select
  9. sound_mmap
  10. soundcard_init
  11. free_all_irqs
  12. init_module
  13. cleanup_module
  14. tenmicrosec
  15. snd_set_irq_handler
  16. snd_release_irq
  17. sound_alloc_dma
  18. sound_open_dma
  19. sound_free_dma
  20. sound_close_dma
  21. request_sound_timer
  22. sound_stop_timer
  23. sound_alloc_dmap
  24. sound_free_dmap
  25. soud_map_buffer
  26. soundcard_init

   1 /*
   2  * linux/kernel/chr_drv/sound/soundcard.c
   3  *
   4  * Soundcard driver for Linux
   5  *
   6  * Copyright by Hannu Savolainen 1993
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions are
  10  * met: 1. Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer. 2.
  12  * Redistributions in binary form must reproduce the above copyright notice,
  13  * this list of conditions and the following disclaimer in the documentation
  14  * and/or other materials provided with the distribution.
  15  *
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  *
  28  */
  29 /*
  30  * Created modular version by Peter Trattler (peter@sbox.tu-graz.ac.at)
  31  */
  32 
  33 #include "sound_config.h"
  34 
  35 #ifdef CONFIGURE_SOUNDCARD
  36 
  37 #include <linux/major.h>
  38 
  39 #ifndef EXCLUDE_PNP
  40 #include <linux/pnp.h>
  41 #endif
  42 
  43 static int      soundcards_installed = 0;       /* Number of installed cards */
  44 
  45 /*
  46  * Table for permanently allocated memory (used when unloading the module)
  47  */
  48 caddr_t         sound_mem_blocks[1024];
  49 int             sound_num_blocks = 0;
  50 
  51 static int      soundcard_configured = 0;
  52 
  53 static struct fileinfo files[SND_NDEVS];
  54 
  55 static char     dma_alloc_map[8] =
  56 {0};
  57 
  58 #define DMA_MAP_UNAVAIL         0
  59 #define DMA_MAP_FREE            1
  60 #define DMA_MAP_BUSY            2
  61 
  62 int
  63 snd_ioctl_return (int *addr, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65   if (value < 0)
  66     return value;
  67 
  68   put_fs_long (value, (long *) &((addr)[0]));
  69   return 0;
  70 }
  71 
  72 static int
  73 sound_read (struct inode *inode, struct file *file, char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75   int             dev;
  76 
  77   dev = inode->i_rdev;
  78   dev = MINOR (dev);
  79 
  80   return sound_read_sw (dev, &files[dev], buf, count);
  81 }
  82 
  83 static int
  84 sound_write (struct inode *inode, struct file *file, const char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  85 {
  86   int             dev;
  87 
  88   dev = inode->i_rdev;
  89   dev = MINOR (dev);
  90 
  91   return sound_write_sw (dev, &files[dev], buf, count);
  92 }
  93 
  94 static int
  95 sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97   return -EPERM;
  98 }
  99 
 100 static int
 101 sound_open (struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 102 {
 103   int             dev, retval;
 104   struct fileinfo tmp_file;
 105 
 106   dev = inode->i_rdev;
 107   dev = MINOR (dev);
 108 
 109   if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
 110     {
 111       printk ("SoundCard Error: The soundcard system has not been configured\n");
 112       return -ENXIO;
 113     }
 114 
 115   tmp_file.mode = 0;
 116   tmp_file.filp = file;
 117 
 118   if ((file->f_flags & O_ACCMODE) == O_RDWR)
 119     tmp_file.mode = OPEN_READWRITE;
 120   if ((file->f_flags & O_ACCMODE) == O_RDONLY)
 121     tmp_file.mode = OPEN_READ;
 122   if ((file->f_flags & O_ACCMODE) == O_WRONLY)
 123     tmp_file.mode = OPEN_WRITE;
 124 
 125   if ((retval = sound_open_sw (dev, &tmp_file)) < 0)
 126     return retval;
 127 
 128 #ifdef MODULE
 129   MOD_INC_USE_COUNT;
 130 #endif
 131 
 132   memcpy ((char *) &files[dev], (char *) &tmp_file, sizeof (tmp_file));
 133   return retval;
 134 }
 135 
 136 static void
 137 sound_release (struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139   int             dev;
 140 
 141   dev = inode->i_rdev;
 142   dev = MINOR (dev);
 143 
 144   sound_release_sw (dev, &files[dev]);
 145 #ifdef MODULE
 146   MOD_DEC_USE_COUNT;
 147 #endif
 148 }
 149 
 150 static int
 151 sound_ioctl (struct inode *inode, struct file *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 152              unsigned int cmd, unsigned long arg)
 153 {
 154   int             dev, err;
 155 
 156   dev = inode->i_rdev;
 157   dev = MINOR (dev);
 158 
 159   if (cmd == 1)
 160     {
 161       int             i;
 162 
 163       unsigned char  *p;
 164 
 165 
 166       if (!audio_devs[dev >> 4]->dmap_out)
 167         return 0;
 168       if (!audio_devs[dev >> 4]->dmap_out->raw_buf)
 169         return 0;
 170 
 171       p = audio_devs[dev >> 4]->dmap_out->raw_buf;
 172 
 173       for (i = 0; i < 256; i++)
 174         printk ("%02x ", p[i]);
 175       printk ("\n");
 176       return 0;
 177     }
 178 
 179   if (cmd & IOC_INOUT)
 180     {
 181       /*
 182          * Have to validate the address given by the process.
 183        */
 184       int             len;
 185 
 186       len = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
 187 
 188       if (cmd & IOC_IN)
 189         {
 190           if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0)
 191             return err;
 192         }
 193 
 194       if (cmd & IOC_OUT)
 195         {
 196           if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0)
 197             return err;
 198         }
 199 
 200     }
 201 
 202   err = sound_ioctl_sw (dev, &files[dev], cmd, (caddr_t) arg);
 203 
 204   return err;
 205 }
 206 
 207 static int
 208 sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210   int             dev;
 211 
 212   dev = inode->i_rdev;
 213   dev = MINOR (dev);
 214 
 215   DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
 216 
 217   switch (dev & 0x0f)
 218     {
 219 #ifndef EXCLUDE_SEQUENCER
 220     case SND_DEV_SEQ:
 221     case SND_DEV_SEQ2:
 222       return sequencer_select (dev, &files[dev], sel_type, wait);
 223       break;
 224 #endif
 225 
 226 #ifndef EXCLUDE_MIDI
 227     case SND_DEV_MIDIN:
 228       return MIDIbuf_select (dev, &files[dev], sel_type, wait);
 229       break;
 230 #endif
 231 
 232 #ifndef EXCLUDE_AUDIO
 233     case SND_DEV_DSP:
 234     case SND_DEV_DSP16:
 235     case SND_DEV_AUDIO:
 236       return audio_select (dev, &files[dev], sel_type, wait);
 237       break;
 238 #endif
 239 
 240     default:
 241       return 0;
 242     }
 243 
 244   return 0;
 245 }
 246 
 247 static int
 248 sound_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma)
     /* [previous][next][first][last][top][bottom][index][help] */
 249 {
 250   int             dev, dev_class;
 251   unsigned long   size;
 252   struct dma_buffparms *dmap = NULL;
 253 
 254   dev = inode->i_rdev;
 255   dev = MINOR (dev);
 256 
 257   dev_class = dev & 0x0f;
 258   dev >>= 4;
 259 
 260   if (dev_class != SND_DEV_DSP && dev_class != SND_DEV_DSP16 && dev_class != SND_DEV_AUDIO)
 261     {
 262       printk ("Sound: mmap() not supported for other than audio devices\n");
 263       return -EINVAL;
 264     }
 265 
 266   if ((vma->vm_flags & (VM_READ | VM_WRITE)) == (VM_READ | VM_WRITE))
 267     {
 268       printk ("Sound: Cannot do read/write mmap()\n");
 269       return -EINVAL;
 270     }
 271 
 272   if (vma->vm_flags & VM_READ)
 273     {
 274       dmap = audio_devs[dev]->dmap_in;
 275     }
 276   else if (vma->vm_flags & VM_WRITE)
 277     {
 278       dmap = audio_devs[dev]->dmap_out;
 279     }
 280   else
 281     {
 282       printk ("Sound: Undefined mmap() access\n");
 283       return -EINVAL;
 284     }
 285 
 286   if (dmap == NULL)
 287     {
 288       printk ("Sound: mmap() error. dmap == NULL\n");
 289       return -EIO;
 290     }
 291 
 292   if (dmap->raw_buf == NULL)
 293     {
 294       printk ("Sound: mmap() called when raw_buf == NULL\n");
 295       return -EIO;
 296     }
 297 
 298   if (dmap->mapping_flags)
 299     {
 300       printk ("Sound: mmap() called twice for the same DMA buffer\n");
 301       return -EIO;
 302     }
 303 
 304   if (vma->vm_offset != 0)
 305     {
 306       printk ("Sound: mmap() offset must be 0.\n");
 307       return -EINVAL;
 308     }
 309 
 310   size = vma->vm_end - vma->vm_start;
 311 
 312   if (size != dmap->bytes_in_use)
 313     {
 314       printk ("Sound: mmap() size = %ld. Should be %d\n",
 315               size, dmap->bytes_in_use);
 316     }
 317 
 318   if (remap_page_range (vma->vm_start, dmap->raw_buf_phys, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 319     return -EAGAIN;
 320 
 321 
 322   vma->vm_inode = inode;
 323   inode->i_count++;
 324 
 325   dmap->mapping_flags |= DMA_MAP_MAPPED;
 326 
 327   memset (dmap->raw_buf,
 328           dmap->neutral_byte,
 329           dmap->bytes_in_use);
 330   return 0;
 331 }
 332 
 333 static struct file_operations sound_fops =
 334 {
 335   sound_lseek,
 336   sound_read,
 337   sound_write,
 338   NULL,                         /* sound_readdir */
 339   sound_select,
 340   sound_ioctl,
 341   sound_mmap,
 342   sound_open,
 343   sound_release
 344 };
 345 
 346 void
 347 soundcard_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 348 {
 349 #ifndef MODULE
 350   register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
 351 #endif
 352 
 353   soundcard_configured = 1;
 354 
 355   sndtable_init (0);            /* Initialize call tables and
 356                                    * detect cards */
 357 #ifndef EXCLUDE_PNP
 358   sound_pnp_init ();
 359 #endif
 360 
 361   if (!(soundcards_installed = sndtable_get_cardcount ()))
 362     return;                     /* No cards detected */
 363 
 364 #ifndef EXCLUDE_AUDIO
 365   if (num_audiodevs)            /* Audio devices present */
 366     {
 367       DMAbuf_init (0);
 368       audio_init (0);
 369     }
 370 #endif
 371 
 372 #ifndef EXCLUDE_MIDI
 373   if (num_midis)
 374     MIDIbuf_init (0);
 375 #endif
 376 
 377 #ifndef EXCLUDE_SEQUENCER
 378   if (num_midis + num_synths)
 379     sequencer_init (0);
 380 #endif
 381 
 382 }
 383 
 384 static unsigned long irqs = 0;
 385 
 386 #ifdef MODULE
 387 static void
 388 free_all_irqs (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 389 {
 390   int             i;
 391 
 392   for (i = 0; i < 31; i++)
 393     if (irqs & (1ul << i))
 394       {
 395         printk ("Sound warning: IRQ%d was left allocated. Fixed.\n", i);
 396         snd_release_irq (i);
 397       }
 398   irqs = 0;
 399 }
 400 
 401 char            kernel_version[] = UTS_RELEASE;
 402 
 403 #endif
 404 
 405 static int      debugmem = 0;   /* switched off by default */
 406 
 407 static int      sound[20] =
 408 {0};
 409 
 410 int
 411 init_module (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 412 {
 413   int             err;
 414   int             ints[21];
 415   int             i;
 416 
 417   /*
 418      * "sound=" command line handling by Harald Milz.
 419    */
 420   i = 0;
 421   while (i < 20 && sound[i])
 422     ints[i + 1] = sound[i++];
 423   ints[0] = i;
 424 
 425   if (i)
 426     sound_setup ("sound=", ints);
 427 
 428   err = register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
 429   if (err)
 430     {
 431       printk ("sound: driver already loaded/included in kernel\n");
 432       return err;
 433     }
 434 
 435   soundcard_init ();
 436 
 437   if (sound_num_blocks >= 1024)
 438     printk ("Sound warning: Deallocation table was too small.\n");
 439 
 440   return 0;
 441 }
 442 
 443 #ifdef MODULE
 444 void
 445 cleanup_module (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 446 {
 447   if (MOD_IN_USE)
 448     printk ("sound: module busy -- remove delayed\n");
 449   else
 450     {
 451       int             i;
 452 
 453       unregister_chrdev (SOUND_MAJOR, "sound");
 454 
 455       sound_stop_timer ();
 456       sound_unload_drivers ();
 457 
 458       for (i = 0; i < sound_num_blocks; i++)
 459         kfree (sound_mem_blocks[i]);
 460 
 461       free_all_irqs ();         /* If something was left allocated by accident */
 462 
 463       for (i = 0; i < 8; i++)
 464         if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)
 465           {
 466             printk ("Sound: Hmm, DMA%d was left allocated\n", i);
 467             sound_free_dma (i);
 468           }
 469 
 470 #ifndef EXCLUDE_PNP
 471       sound_pnp_disconnect ();
 472 #endif
 473 
 474     }
 475 }
 476 #endif
 477 
 478 void
 479 tenmicrosec (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 480 {
 481   int             i;
 482 
 483   for (i = 0; i < 16; i++)
 484     inb (0x80);
 485 }
 486 
 487 int
 488 snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *), char *name, sound_os_info * osp)
     /* [previous][next][first][last][top][bottom][index][help] */
 489 {
 490   int             retcode;
 491 
 492   retcode = request_irq (interrupt_level, hndlr, 0 /* SA_INTERRUPT */ , name);
 493   if (retcode < 0)
 494     {
 495       printk ("Sound: IRQ%d already in use\n", interrupt_level);
 496     }
 497   else
 498     irqs |= (1ul << interrupt_level);
 499 
 500   return retcode;
 501 }
 502 
 503 void
 504 snd_release_irq (int vect)
     /* [previous][next][first][last][top][bottom][index][help] */
 505 {
 506   irqs &= ~(1ul << vect);
 507   free_irq (vect);
 508 }
 509 
 510 int
 511 sound_alloc_dma (int chn, char *deviceID)
     /* [previous][next][first][last][top][bottom][index][help] */
 512 {
 513   int             err;
 514 
 515   if ((err = request_dma (chn, deviceID)) != 0)
 516     return err;
 517 
 518   dma_alloc_map[chn] = DMA_MAP_FREE;
 519 
 520   return 0;
 521 }
 522 
 523 int
 524 sound_open_dma (int chn, char *deviceID)
     /* [previous][next][first][last][top][bottom][index][help] */
 525 {
 526   unsigned long   flags;
 527 
 528   save_flags (flags);
 529   cli ();
 530 
 531   if (dma_alloc_map[chn] != DMA_MAP_FREE)
 532     {
 533       printk ("sound_open_dma: DMA channel %d busy or not allocated\n", chn);
 534       restore_flags (flags);
 535       return 1;
 536     }
 537 
 538   dma_alloc_map[chn] = DMA_MAP_BUSY;
 539   restore_flags (flags);
 540   return 0;
 541 }
 542 
 543 void
 544 sound_free_dma (int chn)
     /* [previous][next][first][last][top][bottom][index][help] */
 545 {
 546   if (dma_alloc_map[chn] != DMA_MAP_FREE)
 547     {
 548       printk ("sound_free_dma: Bad access to DMA channel %d\n", chn);
 549       return;
 550     }
 551   free_dma (chn);
 552   dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
 553 }
 554 
 555 void
 556 sound_close_dma (int chn)
     /* [previous][next][first][last][top][bottom][index][help] */
 557 {
 558   unsigned long   flags;
 559 
 560   save_flags (flags);
 561   cli ();
 562 
 563   if (dma_alloc_map[chn] != DMA_MAP_BUSY)
 564     {
 565       printk ("sound_close_dma: Bad access to DMA channel %d\n", chn);
 566       restore_flags (flags);
 567       return;
 568     }
 569   dma_alloc_map[chn] = DMA_MAP_FREE;
 570   restore_flags (flags);
 571 }
 572 
 573 #ifndef EXCLUDE_SEQUENCER
 574 void
 575 request_sound_timer (int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 576 {
 577   extern unsigned long seq_time;
 578 
 579   if (count < 0)
 580     count = jiffies + (-count);
 581   else
 582     count += seq_time;
 583   timer_table[SOUND_TIMER].fn = sequencer_timer;
 584   timer_table[SOUND_TIMER].expires = count;
 585   timer_active |= 1 << SOUND_TIMER;
 586 }
 587 
 588 #endif
 589 
 590 void
 591 sound_stop_timer (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 592 {
 593   timer_table[SOUND_TIMER].expires = 0;
 594   timer_active &= ~(1 << SOUND_TIMER);
 595 }
 596 
 597 #ifndef EXCLUDE_AUDIO
 598 
 599 #ifdef KMALLOC_DMA_BROKEN
 600 fatal_error__This_version_is_not_compatible_with_this_kernel;
 601 #endif
 602 
 603 static int      dma_buffsize = DSP_BUFFSIZE;
 604 
 605 int
 606 sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 607 {
 608   char           *start_addr, *end_addr;
 609   int             i, dma_pagesize;
 610 
 611   if (dmap->raw_buf != NULL)
 612     return 0;                   /* Already done */
 613 
 614   if (dma_buffsize < 4096)
 615     dma_buffsize = 4096;
 616 
 617   if (chan < 4)
 618     dma_pagesize = 64 * 1024;
 619   else
 620     dma_pagesize = 128 * 1024;
 621 
 622   dmap->raw_buf = NULL;
 623 
 624   if (debugmem)
 625     printk ("sound: buffsize%d %lu\n", dev, audio_devs[dev]->buffsize);
 626 
 627   audio_devs[dev]->buffsize = dma_buffsize;
 628 
 629   if (audio_devs[dev]->buffsize > dma_pagesize)
 630     audio_devs[dev]->buffsize = dma_pagesize;
 631 
 632   start_addr = NULL;
 633 
 634 /*
 635  * Now loop until we get a free buffer. Try to get smaller buffer if
 636  * it fails.
 637  */
 638 
 639   while (start_addr == NULL && audio_devs[dev]->buffsize > PAGE_SIZE)
 640     {
 641       int             sz, size;
 642 
 643       for (sz = 0, size = PAGE_SIZE;
 644            size < audio_devs[dev]->buffsize;
 645            sz++, size <<= 1);
 646 
 647       audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
 648 
 649       if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
 650         audio_devs[dev]->buffsize /= 2;
 651     }
 652 
 653   if (start_addr == NULL)
 654     {
 655       printk ("Sound error: Couldn't allocate DMA buffer\n");
 656       return -ENOMEM;
 657     }
 658   else
 659     {
 660       /* make some checks */
 661       end_addr = start_addr + audio_devs[dev]->buffsize - 1;
 662 
 663       if (debugmem)
 664         printk ("sound: start 0x%lx, end 0x%lx\n",
 665                 (long) start_addr, (long) end_addr);
 666 
 667       /* now check if it fits into the same dma-pagesize */
 668 
 669       if (((long) start_addr & ~(dma_pagesize - 1))
 670           != ((long) end_addr & ~(dma_pagesize - 1))
 671           || end_addr >= (char *) (16 * 1024 * 1024))
 672         {
 673           printk (
 674                    "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
 675                    (long) start_addr,
 676                    audio_devs[dev]->buffsize);
 677           return -EFAULT;
 678         }
 679     }
 680   dmap->raw_buf = start_addr;
 681   dmap->raw_buf_phys = (unsigned long) start_addr;
 682 
 683   for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
 684     {
 685 #ifdef MAP_PAGE_RESERVED
 686       mem_map[i] |= MAP_PAGE_RESERVED;
 687 #else
 688       mem_map[i].reserved = 1;
 689 #endif
 690     }
 691 
 692   return 0;
 693 }
 694 
 695 void
 696 sound_free_dmap (int dev, struct dma_buffparms *dmap)
     /* [previous][next][first][last][top][bottom][index][help] */
 697 {
 698   if (dmap->raw_buf == NULL)
 699     return;
 700   {
 701     int             sz, size, i;
 702     unsigned long   start_addr, end_addr;
 703 
 704     for (sz = 0, size = PAGE_SIZE;
 705          size < audio_devs[dev]->buffsize;
 706          sz++, size <<= 1);
 707 
 708     start_addr = (unsigned long) dmap->raw_buf;
 709     end_addr = start_addr + audio_devs[dev]->buffsize;
 710 
 711     for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
 712       {
 713 #ifdef MAP_PAGE_RESERVED
 714         mem_map[i] &= ~MAP_PAGE_RESERVED;
 715 #else
 716         mem_map[i].reserved = 0;
 717 #endif
 718       }
 719     free_pages ((unsigned long) dmap->raw_buf, sz);
 720   }
 721   dmap->raw_buf = NULL;
 722 }
 723 
 724 int
 725 soud_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info)
     /* [previous][next][first][last][top][bottom][index][help] */
 726 {
 727   printk ("Entered sound_map_buffer()\n");
 728   printk ("Exited sound_map_buffer()\n");
 729   return -EINVAL;
 730 }
 731 
 732 #else
 733 
 734 void
 735 soundcard_init (void)           /* Dummy version */
     /* [previous][next][first][last][top][bottom][index][help] */
 736 {
 737 }
 738 
 739 #endif
 740 
 741 #endif

/* [previous][next][first][last][top][bottom][index][help] */