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. conf_printf
  27. conf_printf2

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

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