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

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