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. soundcard_init
  10. free_all_irqs
  11. init_module
  12. cleanup_module
  13. tenmicrosec
  14. snd_set_irq_handler
  15. snd_release_irq
  16. request_sound_timer
  17. sound_stop_timer
  18. valid_dma_page
  19. add_to_dma_list
  20. module_sound_mem_init
  21. module_sound_mem_release
  22. sound_mem_init
  23. soundcard_init
  24. sound_mem_init
  25. module_sound_mem_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 static int      soundcards_installed = 0;       /* Number of installed
  40 
  41                                                  * soundcards */
  42 static int      soundcard_configured = 0;
  43 
  44 static struct fileinfo files[SND_NDEVS];
  45 
  46 int
  47 snd_ioctl_return (int *addr, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49   if (value < 0)
  50     return value;
  51 
  52   PUT_WORD_TO_USER (addr, 0, value);
  53   return 0;
  54 }
  55 
  56 static int
  57 sound_read (struct inode *inode, struct file *file, char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59   int             dev;
  60 
  61   dev = MINOR(inode->i_rdev);
  62 
  63   return sound_read_sw (dev, &files[dev], buf, count);
  64 }
  65 
  66 static int
  67 sound_write (struct inode *inode, struct file *file, const char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69   int             dev;
  70 
  71 #ifdef MODULE
  72   int             err;
  73 
  74 #endif
  75 
  76   dev = MINOR(inode->i_rdev);
  77 
  78   return sound_write_sw (dev, &files[dev], buf, count);
  79 }
  80 
  81 static int
  82 sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84   return RET_ERROR (EPERM);
  85 }
  86 
  87 static int
  88 sound_open (struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90   int             dev, retval;
  91   struct fileinfo tmp_file;
  92 
  93   dev = MINOR(inode->i_rdev);
  94 
  95   if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
  96     {
  97       printk ("SoundCard Error: The soundcard system has not been configured\n");
  98       return RET_ERROR (ENXIO);
  99     }
 100 
 101   tmp_file.mode = 0;
 102   tmp_file.filp = file;
 103 
 104   if ((file->f_flags & O_ACCMODE) == O_RDWR)
 105     tmp_file.mode = OPEN_READWRITE;
 106   if ((file->f_flags & O_ACCMODE) == O_RDONLY)
 107     tmp_file.mode = OPEN_READ;
 108   if ((file->f_flags & O_ACCMODE) == O_WRONLY)
 109     tmp_file.mode = OPEN_WRITE;
 110 
 111   if ((retval = sound_open_sw (dev, &tmp_file)) < 0)
 112     return retval;
 113 
 114 #ifdef MODULE
 115   MOD_INC_USE_COUNT;
 116 #endif
 117 
 118   memcpy ((char *) &files[dev], (char *) &tmp_file, sizeof (tmp_file));
 119   return retval;
 120 }
 121 
 122 static void
 123 sound_release (struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125   int             dev;
 126 
 127   dev = MINOR(inode->i_rdev);
 128 
 129   sound_release_sw (dev, &files[dev]);
 130 #ifdef MODULE
 131   MOD_DEC_USE_COUNT;
 132 #endif
 133 }
 134 
 135 static int
 136 sound_ioctl (struct inode *inode, struct file *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 137              unsigned int cmd, unsigned long arg)
 138 {
 139   int             dev;
 140 
 141   dev = MINOR(inode->i_rdev);
 142 
 143   if (cmd & IOC_INOUT)
 144     {
 145       /*
 146          * Have to validate the address given by the process.
 147        */
 148       int             len, err;
 149 
 150       len = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
 151 
 152       if (cmd & IOC_IN)
 153         {
 154           if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0)
 155             return err;
 156         }
 157 
 158       if (cmd & IOC_OUT)
 159         {
 160           if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0)
 161             return err;
 162         }
 163 
 164     }
 165 
 166   return sound_ioctl_sw (dev, &files[dev], cmd, arg);
 167 }
 168 
 169 static int
 170 sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172   int             dev;
 173 
 174   dev = MINOR(inode->i_rdev);
 175 
 176   DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
 177 
 178   switch (dev & 0x0f)
 179     {
 180 #ifndef EXCLUDE_SEQUENCER
 181     case SND_DEV_SEQ:
 182     case SND_DEV_SEQ2:
 183       return sequencer_select (dev, &files[dev], sel_type, wait);
 184       break;
 185 #endif
 186 
 187 #ifndef EXCLUDE_MIDI
 188     case SND_DEV_MIDIN:
 189       return MIDIbuf_select (dev, &files[dev], sel_type, wait);
 190       break;
 191 #endif
 192 
 193 #ifndef EXCLUDE_AUDIO
 194     case SND_DEV_DSP:
 195     case SND_DEV_DSP16:
 196     case SND_DEV_AUDIO:
 197       return audio_select (dev, &files[dev], sel_type, wait);
 198       break;
 199 #endif
 200 
 201     default:
 202       return 0;
 203     }
 204 
 205   return 0;
 206 }
 207 
 208 static struct file_operations sound_fops =
 209 {
 210   sound_lseek,
 211   sound_read,
 212   sound_write,
 213   NULL,                         /* sound_readdir */
 214   sound_select,
 215   sound_ioctl,
 216   NULL,
 217   sound_open,
 218   sound_release
 219 };
 220 
 221 long
 222 soundcard_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 223 {
 224 #ifndef MODULE
 225   register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
 226 #endif
 227 
 228   soundcard_configured = 1;
 229 
 230   mem_start = sndtable_init (mem_start);        /* Initialize call tables and
 231                                                  * detect cards */
 232 
 233   if (!(soundcards_installed = sndtable_get_cardcount ()))
 234     return mem_start;           /* No cards detected */
 235 
 236 #ifndef EXCLUDE_AUDIO
 237   if (num_audiodevs)            /* Audio devices present */
 238     {
 239       mem_start = DMAbuf_init (mem_start);
 240       mem_start = audio_init (mem_start);
 241     }
 242 #endif
 243 
 244 #ifndef EXCLUDE_MIDI
 245   if (num_midis)
 246     mem_start = MIDIbuf_init (mem_start);
 247 #endif
 248 
 249 #ifndef EXCLUDE_SEQUENCER
 250   if (num_midis + num_synths)
 251     mem_start = sequencer_init (mem_start);
 252 #endif
 253 
 254   return mem_start;
 255 }
 256 
 257 #ifdef MODULE
 258 static unsigned long irqs = 0;
 259 void            snd_release_irq (int);
 260 static int      module_sound_mem_init (void);
 261 static void     module_sound_mem_release (void);
 262 
 263 static void
 264 free_all_irqs (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 265 {
 266   int             i;
 267 
 268   for (i = 0; i < 31; i++)
 269     if (irqs & (1ul << i))
 270       snd_release_irq (i);
 271   irqs = 0;
 272 }
 273 
 274 char            kernel_version[] = UTS_RELEASE;
 275 
 276 static long     memory_pool = 0;
 277 static int      memsize = 70 * 1024;
 278 static int      debugmem = 0;   /* switched off by default */
 279 
 280 int
 281 init_module (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 282 {
 283   long            lastbyte;
 284   int             err;
 285 
 286   printk ("sound: made modular by Peter Trattler (peter@sbox.tu-graz.ac.at)\n");
 287   err = register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
 288   if (err)
 289     {
 290       printk ("sound: driver already loaded/included in kernel\n");
 291       return err;
 292     }
 293   memory_pool = (long) kmalloc (memsize, GFP_KERNEL);
 294   if (memory_pool == 0l)
 295     {
 296       unregister_chrdev (SOUND_MAJOR, "sound");
 297       return -ENOMEM;
 298     }
 299   lastbyte = soundcard_init (memory_pool);
 300   if (lastbyte > memory_pool + memsize)
 301     {
 302       printk ("sound: Not enough memory; use : 'insmod sound.o memsize=%ld'\n",
 303               lastbyte - memory_pool);
 304       kfree ((void *) memory_pool);
 305       unregister_chrdev (SOUND_MAJOR, "sound");
 306       free_all_irqs ();
 307       return -ENOMEM;
 308     }
 309   err = module_sound_mem_init ();
 310   if (err)
 311     {
 312       module_sound_mem_release ();
 313       kfree ((void *) memory_pool);
 314       unregister_chrdev (SOUND_MAJOR, "sound");
 315       free_all_irqs ();
 316       return err;
 317     }
 318   if (lastbyte < memory_pool + memsize)
 319     printk ("sound: (Suggestion) too much memory; use : 'insmod sound.o memsize=%ld'\n",
 320             lastbyte - memory_pool);
 321   return 0;
 322 }
 323 
 324 void
 325 cleanup_module (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 326 {
 327   if (MOD_IN_USE)
 328     printk ("sound: module busy -- remove delayed\n");
 329   else
 330     {
 331       kfree ((void *) memory_pool);
 332       unregister_chrdev (SOUND_MAJOR, "sound");
 333       free_all_irqs ();
 334       module_sound_mem_release ();
 335     }
 336 }
 337 
 338 #endif
 339 
 340 void
 341 tenmicrosec (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 342 {
 343   int             i;
 344 
 345   for (i = 0; i < 16; i++)
 346     inb (0x80);
 347 }
 348 
 349 int
 350 snd_set_irq_handler (int interrupt_level, INT_HANDLER_PROTO (), char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 351 {
 352   int             retcode;
 353 
 354   retcode = request_irq (interrupt_level, hndlr, SA_INTERRUPT, name);
 355   if (retcode < 0)
 356     {
 357       printk ("Sound: IRQ%d already in use\n", interrupt_level);
 358     }
 359 #ifdef MODULE
 360   else
 361     irqs |= (1ul << interrupt_level);
 362 #endif
 363 
 364   return retcode;
 365 }
 366 
 367 void
 368 snd_release_irq (int vect)
     /* [previous][next][first][last][top][bottom][index][help] */
 369 {
 370 #ifdef MODULE
 371   irqs &= ~(1ul << vect);
 372 #endif
 373   free_irq (vect);
 374 }
 375 
 376 #ifndef EXCLUDE_SEQUENCER
 377 void
 378 request_sound_timer (int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 379 {
 380   extern unsigned long seq_time;
 381 
 382 #if 1
 383   if (count < 0)
 384     count = jiffies + (-count);
 385   else
 386     count += seq_time;
 387   timer_table[SOUND_TIMER].fn = sequencer_timer;
 388   timer_table[SOUND_TIMER].expires = count;
 389   timer_active |= 1 << SOUND_TIMER;
 390 #endif
 391 }
 392 
 393 #endif
 394 
 395 void
 396 sound_stop_timer (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 397 {
 398 #if 1
 399   timer_table[SOUND_TIMER].expires = 0;
 400   timer_active &= ~(1 << SOUND_TIMER);
 401 #endif
 402 }
 403 
 404 #ifndef EXCLUDE_AUDIO
 405 static int
 406 valid_dma_page (unsigned long addr, unsigned long dev_buffsize, unsigned long dma_pagesize)
     /* [previous][next][first][last][top][bottom][index][help] */
 407 {
 408   if (((addr & (dma_pagesize - 1)) + dev_buffsize) <= dma_pagesize)
 409     return 1;
 410   else
 411     return 0;
 412 }
 413 
 414 #ifdef MODULE
 415 
 416 #ifdef KMALLOC_DMA_BROKEN
 417 #define KMALLOC_MEM_REGIONS 20
 418 
 419 static char    *dma_list[KMALLOC_MEM_REGIONS];
 420 static int      dma_last = 0;
 421 inline void
 422 add_to_dma_list (char *adr)
     /* [previous][next][first][last][top][bottom][index][help] */
 423 {
 424   dma_list[dma_last++] = adr;
 425 }
 426 
 427 #endif
 428 
 429 static int
 430 module_sound_mem_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 431 {
 432   int             dev, ret = 0;
 433   unsigned long   dma_pagesize;
 434   char           *start_addr, *end_addr;
 435   int             order, size;
 436   struct dma_buffparms *dmap;
 437 
 438   for (dev = 0; dev < num_audiodevs; dev++)
 439     if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
 440       {
 441         dmap = audio_devs[dev]->dmap;
 442         if (audio_devs[dev]->flags & DMA_AUTOMODE)
 443           audio_devs[dev]->buffcount = 1;
 444 
 445         if (audio_devs[dev]->dmachan > 3)
 446           dma_pagesize = 131072;        /* 16bit dma: 128k */
 447         else
 448           dma_pagesize = 65536; /* 8bit dma: 64k */
 449         if (debugmem)
 450           printk ("sound: dma-page-size %lu\n", dma_pagesize);
 451         /* More sanity checks */
 452 
 453         if (audio_devs[dev]->buffsize > dma_pagesize)
 454           audio_devs[dev]->buffsize = dma_pagesize;
 455         audio_devs[dev]->buffsize &= 0xfffff000;        /* Truncate to n*4k */
 456         if (audio_devs[dev]->buffsize < 4096)
 457           audio_devs[dev]->buffsize = 4096;
 458         if (debugmem)
 459           printk ("sound: buffsize %lu\n", audio_devs[dev]->buffsize);
 460         /* Now allocate the buffers */
 461         for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount;
 462              dmap->raw_count++)
 463           {
 464 #ifdef KMALLOC_DMA_BROKEN
 465             start_addr = kmalloc (audio_devs[dev]->buffsize, GFP_KERNEL);
 466             if (start_addr)
 467               {
 468                 if (debugmem)
 469                   printk ("sound: trying 0x%lx for DMA\n", (long) start_addr);
 470                 if (valid_dma_page ((unsigned long) start_addr,
 471                                     audio_devs[dev]->buffsize,
 472                                     dma_pagesize))
 473                   add_to_dma_list (start_addr);
 474                 else
 475                   {
 476                     kfree (start_addr);
 477                     start_addr = kmalloc (audio_devs[dev]->buffsize * 2,
 478                                           GFP_KERNEL);  /* what a waste :-( */
 479                     if (start_addr)
 480                       {
 481                         if (debugmem)
 482                           printk ("sound: failed; trying 0x%lx aligned to",
 483                                   (long) start_addr);
 484                         add_to_dma_list (start_addr);
 485                         /* now align it to the next dma-page boundary */
 486                         start_addr = (char *) (((long) start_addr
 487                                                 + dma_pagesize - 1)
 488                                                & ~(dma_pagesize - 1));
 489                         if (debugmem)
 490                           printk (" 0x%lx\n", (long) start_addr);
 491                       }
 492                   }
 493               }
 494 #else
 495             for (order = 0, size = PAGE_SIZE;
 496                  size < audio_devs[dev]->buffsize;
 497                  order++, size <<= 1);
 498             start_addr = (char *) __get_free_pages(GFP_KERNEL, order, MAX_DMA_ADDRESS);
 499 #endif
 500             if (start_addr == NULL)
 501               ret = -ENOMEM;    /* Can't stop the loop in this case, because
 502                                    * ...->raw_buf [...] must be initilized
 503                                    * to valid values (at least to NULL)
 504                                  */
 505             else
 506               {
 507                 /* make some checks */
 508                 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
 509                 if (debugmem)
 510                   printk ("sound: start 0x%lx, end 0x%lx\n",
 511                           (long) start_addr, (long) end_addr);
 512                 /* now check if it fits into the same dma-pagesize */
 513                 if (((long) start_addr & ~(dma_pagesize - 1))
 514                     != ((long) end_addr & ~(dma_pagesize - 1))
 515                     || end_addr >= (char *) (16 * 1024 * 1024))
 516                   {
 517                     printk (
 518                              "sound: kmalloc returned invalid address 0x%lx for %ld Bytes DMA-buffer\n",
 519                              (long) start_addr,
 520                              audio_devs[dev]->buffsize);
 521                     ret = -EFAULT;
 522                   }
 523               }
 524             dmap->raw_buf[dmap->raw_count] = start_addr;
 525             dmap->raw_buf_phys[dmap->raw_count] = (unsigned long) start_addr;
 526           }
 527       }
 528   return ret;
 529 }
 530 
 531 static void
 532 module_sound_mem_release (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 533 {
 534 #ifdef KMALLOC_DMA_BROKEN
 535   int             i;
 536 
 537   for (i = 0; i < dma_last; i++)
 538     {
 539       if (debugmem)
 540         printk ("sound: freeing 0x%lx\n", (long) dma_list[i]);
 541       kfree (dma_list[i]);
 542     }
 543 #else
 544   int             dev, i;
 545   int             order, size;
 546 
 547   for (dev = 0; dev < num_audiodevs; dev++) {
 548     for (order = 0, size = PAGE_SIZE;
 549          size < audio_devs[dev]->buffsize;
 550          order++, size <<= 1);
 551     if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
 552       {
 553         for (i = 0; i < audio_devs[dev]->buffcount; i++)
 554           if (audio_devs[dev]->dmap->raw_buf[i])
 555             {
 556               if (debugmem)
 557                 printk ("sound: freeing 0x%lx\n",
 558                         (long) (audio_devs[dev]->dmap->raw_buf[i]));
 559               free_pages((unsigned long) audio_devs[dev]->dmap->raw_buf[i], 
 560                          order);
 561             }
 562       }
 563   }
 564 #endif
 565 }
 566 
 567 #else /* !MODULE */
 568 
 569 void
 570 sound_mem_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 571 {
 572   int             i, dev;
 573   unsigned long   start_addr, end_addr, mem_ptr, dma_pagesize;
 574   struct dma_buffparms *dmap;
 575 
 576   mem_ptr = high_memory;
 577 
 578   /* Some sanity checks */
 579 
 580   if (mem_ptr > (16 * 1024 * 1024))
 581     mem_ptr = 16 * 1024 * 1024; /* Limit to 16M */
 582 
 583   for (dev = 0; dev < num_audiodevs; dev++)     /* Enumerate devices */
 584     if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
 585       {
 586         dmap = audio_devs[dev]->dmap;
 587 
 588         if (audio_devs[dev]->flags & DMA_AUTOMODE)
 589           audio_devs[dev]->buffcount = 1;
 590 
 591         if (audio_devs[dev]->dmachan > 3 && audio_devs[dev]->buffsize > 65536)
 592           dma_pagesize = 131072;        /* 128k */
 593         else
 594           dma_pagesize = 65536;
 595 
 596         /* More sanity checks */
 597 
 598         if (audio_devs[dev]->buffsize > dma_pagesize)
 599           audio_devs[dev]->buffsize = dma_pagesize;
 600         audio_devs[dev]->buffsize &= 0xfffff000;        /* Truncate to n*4k */
 601         if (audio_devs[dev]->buffsize < 4096)
 602           audio_devs[dev]->buffsize = 4096;
 603 
 604         /* Now allocate the buffers */
 605 
 606         for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount; dmap->raw_count++)
 607           {
 608             start_addr = mem_ptr - audio_devs[dev]->buffsize;
 609             if (!valid_dma_page (start_addr, audio_devs[dev]->buffsize, dma_pagesize))
 610               start_addr &= ~(dma_pagesize - 1);        /* Align address to
 611                                                          * dma_pagesize */
 612 
 613             end_addr = start_addr + audio_devs[dev]->buffsize - 1;
 614 
 615             dmap->raw_buf[dmap->raw_count] = (char *) start_addr;
 616             dmap->raw_buf_phys[dmap->raw_count] = start_addr;
 617             mem_ptr = start_addr;
 618 
 619             for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
 620               {
 621                 if (mem_map[i].reserved || mem_map[i].count)
 622                   panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
 623 
 624                 mem_map[i].reserved = 1;
 625               }
 626           }
 627       }                         /* for dev */
 628 }
 629 
 630 #endif /* !MODULE */
 631 
 632 #endif
 633 
 634 #else
 635 
 636 long
 637 soundcard_init (long mem_start) /* Dummy version */
     /* [previous][next][first][last][top][bottom][index][help] */
 638 {
 639   return mem_start;
 640 }
 641 
 642 #endif
 643 
 644 #if !defined(CONFIGURE_SOUNDCARD) || defined(EXCLUDE_AUDIO)
 645 void
 646 sound_mem_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 647 {
 648   /* Dummy version */
 649 }
 650 
 651 #ifdef MODULE
 652 static int
 653 module_sound_mem_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 654 {
 655   return 0;                     /* no error */
 656 }
 657 
 658 #endif
 659 
 660 #endif

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