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

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