root/drivers/sound/dmabuf.c

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

DEFINITIONS

This source file includes following definitions.
  1. reorganize_buffers
  2. dma_init_buffers
  3. DMAbuf_open
  4. dma_reset
  5. dma_sync
  6. DMAbuf_release
  7. DMAbuf_getrdbuffer
  8. DMAbuf_rmchars
  9. DMAbuf_read
  10. DMAbuf_ioctl
  11. DMAbuf_getwrbuffer
  12. DMAbuf_start_output
  13. DMAbuf_start_dma
  14. DMAbuf_init
  15. DMAbuf_outputintr
  16. DMAbuf_inputintr
  17. DMAbuf_open_dma
  18. DMAbuf_close_dma
  19. DMAbuf_reset_dma
  20. DMAbuf_open
  21. DMAbuf_release
  22. DMAbuf_read
  23. DMAbuf_getwrbuffer
  24. DMAbuf_getrdbuffer
  25. DMAbuf_rmchars
  26. DMAbuf_start_output
  27. DMAbuf_ioctl
  28. DMAbuf_init
  29. DMAbuf_start_dma
  30. DMAbuf_open_dma
  31. DMAbuf_close_dma
  32. DMAbuf_reset_dma
  33. DMAbuf_inputintr
  34. DMAbuf_outputintr

   1 /*
   2  * linux/kernel/chr_drv/sound/dmabuf.c
   3  * 
   4  * The DMA buffer manager for digitized voice applications
   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 #include "sound_config.h"
  31 
  32 #ifdef CONFIGURE_SOUNDCARD
  33 
  34 #include "sound_calls.h"
  35 
  36 #if !defined(EXCLUDE_AUDIO) || !defined(EXCLUDE_GUS)
  37 
  38 #define MAX_SUB_BUFFERS         (32*MAX_REALTIME_FACTOR)
  39 
  40 /*
  41  * The DSP channel can be used either for input or output. Variable
  42  * 'dma_mode' will be set when the program calls read or write first time
  43  * after open. Current version doesn't support mode changes without closing
  44  * and reopening the device. Support for this feature may be implemented in a
  45  * future version of this driver.
  46  */
  47 
  48 #define DMODE_NONE              0
  49 #define DMODE_OUTPUT            1
  50 #define DMODE_INPUT             2
  51 
  52 DEFINE_WAIT_QUEUES (dev_sleeper[MAX_DSP_DEV], dev_sleep_flag[MAX_DSP_DEV]);
  53 
  54 static int      dma_mode[MAX_DSP_DEV] =
  55 {0};                            /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
  56 
  57 static volatile int dmabuf_interrupted[MAX_DSP_DEV] =
  58 {0};
  59 
  60 /*
  61  * Pointers to raw buffers
  62  */
  63 
  64 char           *snd_raw_buf[MAX_DSP_DEV][DSP_BUFFCOUNT] =
  65 {
  66   {NULL}};
  67 unsigned long   snd_raw_buf_phys[MAX_DSP_DEV][DSP_BUFFCOUNT];
  68 int             snd_raw_count[MAX_DSP_DEV];
  69 
  70 /*
  71  * Device state tables
  72  */
  73 
  74 static int      dev_busy[MAX_DSP_DEV];
  75 static int      dev_needs_restart[MAX_DSP_DEV];
  76 static int      dev_modes[MAX_DSP_DEV];
  77 static int      dev_active[MAX_DSP_DEV];
  78 static int      dev_started[MAX_DSP_DEV];
  79 static int      dev_qlen[MAX_DSP_DEV];
  80 static int      dev_qhead[MAX_DSP_DEV];
  81 static int      dev_qtail[MAX_DSP_DEV];
  82 static int      dev_underrun[MAX_DSP_DEV];
  83 static int      bufferalloc_done[MAX_DSP_DEV] =
  84 {0};
  85 
  86 /*
  87  * Logical buffers for each devices
  88  */
  89 
  90 static int      dev_nbufs[MAX_DSP_DEV]; /* # of logical buffers ( >=
  91                                          * sound_buffcounts[dev] */
  92 static int      dev_counts[MAX_DSP_DEV][MAX_SUB_BUFFERS];
  93 static int      dev_subdivision[MAX_DSP_DEV];
  94 static unsigned long dev_buf_phys[MAX_DSP_DEV][MAX_SUB_BUFFERS];
  95 static char    *dev_buf[MAX_DSP_DEV][MAX_SUB_BUFFERS] =
  96   {{NULL}};
  97 static int      dev_buffsize[MAX_DSP_DEV];
  98 
  99 static void
 100 reorganize_buffers (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102   /*
 103    * This routine breaks the physical device buffers to logical ones.
 104    */
 105 
 106   unsigned long   i, p, n;
 107   unsigned long   sr, nc, sz, bsz;
 108 
 109   sr = dsp_devs[dev]->ioctl (dev, SOUND_PCM_READ_RATE, 0, 1);
 110   nc = dsp_devs[dev]->ioctl (dev, SOUND_PCM_READ_CHANNELS, 0, 1);
 111   sz = dsp_devs[dev]->ioctl (dev, SOUND_PCM_READ_BITS, 0, 1);
 112 
 113   if (sr < 1 || nc < 1 || sz < 1)
 114     {
 115       printk ("SOUND: Invalid PCM parameters[%d] sr=%lu, nc=%lu, sz=%lu\n",
 116         dev, sr, nc, sz);
 117       sr = DSP_DEFAULT_SPEED;
 118       nc = 1;
 119       sz = 8;
 120     }
 121 
 122   sz /= 8;                      /* Convert # of bits -> # of bytes */
 123 
 124   sz = sr * nc * sz;
 125 
 126   /*
 127    * Compute a buffer size not exeeding 1 second.
 128    */
 129 
 130   bsz = sound_buffsizes[dev];
 131 
 132   while (bsz > sz)
 133     bsz >>= 1;                  /* Divide by 2 */
 134 
 135   if (sound_buffcounts[dev] == 1 && bsz == sound_buffsizes[dev])
 136     bsz >>= 1;                  /* Need at least 2 buffers */
 137 
 138   if (dev_subdivision[dev] == 0)
 139      dev_subdivision[dev] = 1;  /* Default value */
 140 
 141   bsz /= dev_subdivision[dev];  /* Use smaller buffers */
 142 
 143   if (bsz == 0) bsz = 4096;     /* Just a sanity check */
 144 
 145   while ((sound_buffsizes[dev]*sound_buffcounts[dev])/bsz > MAX_SUB_BUFFERS)
 146         bsz <<= 1;      /* Too much buffers */
 147 
 148   dev_buffsize[dev] = bsz;
 149   n = 0;
 150 
 151   /*
 152    * Now computing addresses for the logical buffers
 153    */
 154 
 155   for (i = 0; i < snd_raw_count[dev]; i++)
 156     {
 157       p = 0;
 158 
 159       while ((p + bsz) <= sound_buffsizes[dev])
 160         {
 161           dev_buf[dev][n] = snd_raw_buf[dev][i] + p;
 162           dev_buf_phys[dev][n] = snd_raw_buf_phys[dev][i] + p;
 163           p += bsz;
 164           n++;
 165         }
 166     }
 167 
 168   dev_nbufs[dev] = n;
 169 
 170   for (i = 0; i < dev_nbufs[dev]; i++)
 171     {
 172       dev_counts[dev][i] = 0;
 173     }
 174 
 175   bufferalloc_done[dev] = 1;
 176 }
 177 
 178 static void
 179 dma_init_buffers(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181   RESET_WAIT_QUEUE (dev_sleeper[dev], dev_sleep_flag[dev]);
 182   dev_underrun[dev] = 0;
 183 
 184   dev_busy[dev] = 1;
 185 
 186   bufferalloc_done[dev] = 0;
 187 
 188   dev_active[dev] = dev_qlen[dev] = dev_qtail[dev] = dev_qhead[dev] = 0;
 189   dev_needs_restart[dev] = dev_started[dev] = 0;
 190   dma_mode[dev] = DMODE_NONE;
 191 }
 192 
 193 int
 194 DMAbuf_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 195 {
 196   int             retval;
 197 
 198   if (dev >= num_dspdevs)
 199     {
 200       printk ("PCM device %d not installed.\n", dev);
 201       return RET_ERROR (ENXIO);
 202     }
 203 
 204   if (dev_busy[dev])
 205     return RET_ERROR (EBUSY);
 206 
 207   if (!dsp_devs[dev])
 208     {
 209       printk ("DSP device %d not initialized\n", dev);
 210       return RET_ERROR (ENXIO);
 211     }
 212 
 213   if (snd_raw_buf[dev][0] == NULL)
 214     return RET_ERROR (ENOSPC);  /* Memory allocation failed during boot */
 215 
 216   if ((retval = dsp_devs[dev]->open (dev, mode)) < 0)
 217     return retval;
 218 
 219   dev_modes[dev] = mode;
 220   dev_subdivision[dev] = 0;
 221 
 222   dma_init_buffers(dev);
 223   dsp_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_BITS, 8, 1);
 224   dsp_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_CHANNELS, 1, 1);
 225   dsp_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_RATE, DSP_DEFAULT_SPEED, 1);
 226 
 227   return 0;
 228 }
 229 
 230 static void
 231 dma_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233   int retval;
 234   unsigned long flags;
 235 
 236   DISABLE_INTR(flags);
 237   dsp_devs[dev]->reset (dev);
 238   dsp_devs[dev]->close (dev);
 239 
 240   if ((retval = dsp_devs[dev]->open (dev, dev_modes[dev])) < 0)
 241     printk("Sound: Reset failed - Can't reopen device\n");
 242   RESTORE_INTR(flags);
 243 
 244   dma_init_buffers(dev);
 245   reorganize_buffers(dev);
 246 }
 247 
 248 static int
 249 dma_sync (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 250 {
 251   unsigned long   flags;
 252   unsigned long   time;
 253   int             timed_out;
 254 
 255   if (dma_mode[dev] == DMODE_OUTPUT)
 256     {
 257       DISABLE_INTR (flags);
 258 
 259       timed_out = 0;
 260       time = GET_TIME ();
 261 
 262       while ((!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]) ||
 263                 dmabuf_interrupted[dev]) && !timed_out)
 264              && dev_qlen[dev])
 265         {
 266           DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 10 * HZ);
 267           if ((GET_TIME () - time) > (10 * HZ))
 268             timed_out = 1;
 269         }
 270       RESTORE_INTR (flags);
 271 
 272       /*
 273        * Some devices such as GUS have huge amount of on board RAM for the
 274        * audio data. We have to wait util the device has finished playing.
 275        */
 276 
 277       DISABLE_INTR (flags);
 278       if (dsp_devs[dev]->has_output_drained)    /* Device has hidden buffers */
 279         {
 280           while (!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]) ||
 281                    dmabuf_interrupted[dev])
 282                  && !dsp_devs[dev]->has_output_drained (dev))
 283             {
 284               DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], HZ / 4);
 285             }
 286         }
 287       RESTORE_INTR (flags);
 288     }
 289   return dev_qlen[dev];
 290 }
 291 
 292 int
 293 DMAbuf_release (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295 
 296   if (!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]) ||
 297         dmabuf_interrupted[dev])
 298       && (dma_mode[dev] == DMODE_OUTPUT))
 299     {
 300       dma_sync (dev);
 301     }
 302 
 303   dsp_devs[dev]->reset (dev);
 304 
 305   dsp_devs[dev]->close (dev);
 306 
 307   dma_mode[dev] = DMODE_NONE;
 308   dev_busy[dev] = 0;
 309 
 310   return 0;
 311 }
 312 
 313 int
 314 DMAbuf_getrdbuffer (int dev, char **buf, int *len)
     /* [previous][next][first][last][top][bottom][index][help] */
 315 {
 316   unsigned long   flags;
 317   int err = EIO;
 318 
 319   if (dma_mode[dev] == DMODE_OUTPUT) /* Was output -> direction change */
 320   {
 321         dma_sync(dev);
 322         dma_reset(dev);
 323         dma_mode[dev] = DMODE_NONE;
 324   }
 325 
 326   if (!bufferalloc_done[dev])
 327     reorganize_buffers (dev);
 328 
 329   if (!dma_mode[dev])
 330     {
 331       int             err;
 332 
 333       if ((err = dsp_devs[dev]->prepare_for_input (dev,
 334                                     dev_buffsize[dev], dev_nbufs[dev])) < 0)
 335         return err;
 336       dma_mode[dev] = DMODE_INPUT;
 337     }
 338 
 339   DISABLE_INTR (flags);
 340   if (!dev_qlen[dev])
 341     {
 342       if (dev_needs_restart[dev])
 343       {
 344         dma_reset(dev);
 345       }
 346 
 347       if (!dev_active[dev])
 348         {
 349           dsp_devs[dev]->start_input (dev, dev_buf_phys[dev][dev_qtail[dev]], 
 350                                       dev_buffsize[dev], 0,
 351                                       !sound_dma_automode[dev] || 
 352                                       !dev_started[dev]);
 353           dev_active[dev] = 1;
 354           dev_started[dev] = 1;
 355         }
 356 
 357       /* Wait for the next block */
 358       DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);
 359       if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
 360         {
 361           printk ("Sound: DMA timed out\n");
 362           err = EIO;
 363           SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);
 364         }
 365       else
 366         err = EINTR;
 367     }
 368   RESTORE_INTR (flags);
 369 
 370   if (!dev_qlen[dev])
 371     return RET_ERROR (err);
 372 
 373   *buf = &dev_buf[dev][dev_qhead[dev]][dev_counts[dev][dev_qhead[dev]]];
 374   *len = dev_buffsize[dev] - dev_counts[dev][dev_qhead[dev]];
 375 
 376   return dev_qhead[dev];
 377 }
 378 
 379 int
 380 DMAbuf_rmchars (int dev, int buff_no, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
 381 {
 382   int             p = dev_counts[dev][dev_qhead[dev]] + c;
 383 
 384   if (p >= dev_buffsize[dev])
 385     {                           /* This buffer is now empty */
 386       dev_counts[dev][dev_qhead[dev]] = 0;
 387       dev_qlen[dev]--;
 388       dev_qhead[dev] = (dev_qhead[dev] + 1) % dev_nbufs[dev];
 389     }
 390   else
 391     dev_counts[dev][dev_qhead[dev]] = p;
 392 
 393   return 0;
 394 }
 395 
 396 int
 397 DMAbuf_read (int dev, snd_rw_buf * user_buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 398 {
 399   char           *dmabuf;
 400   int             buff_no, c, err;
 401 
 402   /*
 403    * This routine returns at most 'count' bytes from the dsp input buffers.
 404    * Returns negative value if there is an error.
 405    */
 406 
 407   if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &c)) < 0)
 408     return buff_no;
 409 
 410   if (c > count)
 411     c = count;
 412 
 413   COPY_TO_USER (user_buf, 0, dmabuf, c);
 414 
 415   if ((err = DMAbuf_rmchars (dev, buff_no, c)) < 0)
 416     return err;
 417   return c;
 418 
 419 }
 420 
 421 int
 422 DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 423 {
 424   switch (cmd)
 425     {
 426     case SNDCTL_DSP_RESET:
 427       dma_reset (dev);
 428       return 0;
 429       break;
 430 
 431     case SNDCTL_DSP_SYNC:
 432       dma_sync (dev);
 433       dma_reset (dev);
 434       return 0;
 435       break;
 436 
 437     case SNDCTL_DSP_GETBLKSIZE:
 438       if (!bufferalloc_done[dev])
 439         reorganize_buffers (dev);
 440 
 441       return IOCTL_OUT (arg, dev_buffsize[dev]);
 442       break;
 443 
 444     case SNDCTL_DSP_SUBDIVIDE:
 445       {
 446         int fact = IOCTL_IN(arg);
 447 
 448         if (fact == 0)
 449         {
 450           fact = dev_subdivision[dev];
 451           if (fact == 0) fact = 1;
 452           return IOCTL_OUT(arg, fact);
 453         }
 454 
 455         if (dev_subdivision[dev] != 0) /* Too late to change */
 456            return RET_ERROR(EINVAL);
 457 
 458         if (fact > MAX_REALTIME_FACTOR) return RET_ERROR(EINVAL);
 459 
 460         if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact !=16)
 461            return RET_ERROR(EINVAL);
 462 
 463         dev_subdivision[dev] = fact;
 464         return IOCTL_OUT(arg, fact);
 465       }
 466       break;
 467 
 468     default:
 469       return dsp_devs[dev]->ioctl (dev, cmd, arg, local);
 470     }
 471 
 472   return RET_ERROR (EIO);
 473 }
 474 
 475 int
 476 DMAbuf_getwrbuffer (int dev, char **buf, int *size)
     /* [previous][next][first][last][top][bottom][index][help] */
 477 {
 478   unsigned long   flags;
 479   int             err = EIO;
 480 
 481   if (dma_mode[dev] == DMODE_INPUT)     /* Was input -> Direction change */
 482     {
 483         dma_reset(dev);
 484         dma_mode[dev] = DMODE_NONE;
 485     }
 486   else
 487    if (dev_needs_restart[dev])  /* Restart buffering */
 488     {
 489         dma_sync(dev);
 490         dma_reset(dev);
 491     }
 492   
 493   dev_needs_restart[dev] = 0;
 494 
 495   if (!bufferalloc_done[dev])
 496     reorganize_buffers (dev);
 497 
 498   if (!dma_mode[dev])
 499     {
 500       int             err;
 501 
 502       dma_mode[dev] = DMODE_OUTPUT;
 503       if ((err = dsp_devs[dev]->prepare_for_output (dev,
 504                                     dev_buffsize[dev], dev_nbufs[dev])) < 0)
 505         return err;
 506     }
 507 
 508 
 509   DISABLE_INTR (flags);
 510 
 511   RESET_WAIT_QUEUE (dev_sleeper[dev], dev_sleep_flag[dev]);
 512 
 513   if (dev_qlen[dev] == dev_nbufs[dev])
 514     {
 515       if (!dev_active[dev])
 516         {
 517           printk ("Soundcard warning: DMA not activated %d/%d\n",
 518                   dev_qlen[dev], dev_nbufs[dev]);
 519           return RET_ERROR (EIO);
 520         }
 521 
 522       /* Wait for free space */
 523       DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);
 524       if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
 525         {
 526           printk ("Sound: DMA timed out\n");
 527           err = EIO;
 528           SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);
 529         }
 530       else if (PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
 531         err = EINTR;
 532     }
 533   RESTORE_INTR (flags);
 534 
 535   if (dev_qlen[dev] == dev_nbufs[dev])
 536     return RET_ERROR (err);     /* We have got signal (?) */
 537 
 538   *buf = dev_buf[dev][dev_qtail[dev]];
 539   *size = dev_buffsize[dev];
 540   dev_counts[dev][dev_qtail[dev]] = 0;
 541 
 542   return dev_qtail[dev];
 543 }
 544 
 545 int
 546 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
 547 {
 548   if (buff_no != dev_qtail[dev])
 549     printk ("Soundcard warning: DMA buffers out of sync %d != %d\n", buff_no, dev_qtail[dev]);
 550 
 551   dev_qlen[dev]++;
 552 
 553   dev_counts[dev][dev_qtail[dev]] = l;
 554 
 555   dev_needs_restart[dev] = (l != dev_buffsize[dev]);
 556 
 557   dev_qtail[dev] = (dev_qtail[dev] + 1) % dev_nbufs[dev];
 558 
 559   if (!dev_active[dev])
 560     {
 561       dev_active[dev] = 1;
 562       dsp_devs[dev]->output_block (dev, dev_buf_phys[dev][dev_qhead[dev]], 
 563         dev_counts[dev][dev_qhead[dev]], 0, 
 564         !sound_dma_automode[dev] || !dev_started[dev]);  
 565       dev_started[dev] = 1; 
 566     }
 567 
 568   return 0;
 569 }
 570 
 571 int
 572 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 573 {
 574   int             chan = sound_dsp_dmachan[dev];
 575   unsigned long   flags;
 576 
 577   /*
 578    * This function is not as portable as it should be.
 579    */
 580 
 581   /*
 582    * The count must be one less than the actual size. This is handled by
 583    * set_dma_addr()
 584    */
 585 
 586   if (sound_dma_automode[dev])
 587     {                           /* Auto restart mode. Transfer the whole
 588                                  * buffer */
 589 #ifdef linux
 590       DISABLE_INTR (flags);
 591       disable_dma (chan);
 592       clear_dma_ff (chan);
 593       set_dma_mode (chan, dma_mode | DMA_AUTOINIT);
 594       set_dma_addr (chan, snd_raw_buf_phys[dev][0]);
 595       set_dma_count (chan, sound_buffsizes[dev]);
 596       enable_dma (chan);
 597       RESTORE_INTR (flags);
 598 #else
 599 
 600 #ifdef __386BSD__
 601       printk ("sound: Invalid DMA mode for device %d\n", dev);
 602 
 603       isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
 604                     snd_raw_buf_phys[dev][0],
 605                     sound_buffsizes[dev],
 606                     chan);
 607 #else
 608 #if defined(ISC) || defined(SCO)
 609       printk ("sound: Invalid DMA mode for device %d\n", dev);
 610       dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode)
 611 #ifdef ISC
 612                  | DMAMODE_AUTO
 613 #endif
 614                  ,
 615                  snd_raw_buf_phys[dev][0], count);
 616       dma_enable (chan);
 617 #else
 618 #  error This routine is not valid for this OS.
 619 #endif
 620 #endif
 621 
 622 #endif
 623     }
 624   else
 625     {
 626 #ifdef linux
 627       DISABLE_INTR (flags);
 628       disable_dma (chan);
 629       clear_dma_ff (chan);
 630       set_dma_mode (chan, dma_mode);
 631       set_dma_addr (chan, physaddr);
 632       set_dma_count (chan, count);
 633       enable_dma (chan);
 634       RESTORE_INTR (flags);
 635 #else
 636 #ifdef __386BSD__
 637       isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
 638                     physaddr,
 639                     count,
 640                     chan);
 641 #else
 642 
 643 #if defined(ISC) || defined(SCO)
 644       dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode),
 645                  physaddr, count);
 646       dma_enable (chan);
 647 #else
 648 #  error This routine is not valid for this OS.
 649 #endif /* !ISC */
 650 #endif
 651 
 652 #endif
 653     }
 654 
 655   return count;
 656 }
 657 
 658 long
 659 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 660 {
 661   int             i;
 662 
 663   /*
 664    * In this version the DMA buffer allocation is done by sound_mem_init()
 665    * which is called by init/main.c
 666    */
 667 
 668   for (i = 0; i < MAX_DSP_DEV; i++)
 669     {
 670       dev_qlen[i] = 0;
 671       dev_qhead[i] = 0;
 672       dev_qtail[i] = 0;
 673       dev_active[i] = 0;
 674       dev_busy[i] = 0;
 675       bufferalloc_done[i] = 0;
 676     }
 677 
 678   return mem_start;
 679 }
 680 
 681 void
 682 DMAbuf_outputintr (int dev, int underrun_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 683 {
 684   unsigned long   flags;
 685 
 686   dev_qlen[dev]--;
 687   dev_qhead[dev] = (dev_qhead[dev] + 1) % dev_nbufs[dev];
 688   dev_active[dev] = 0;
 689 
 690   if (dev_qlen[dev])
 691     {
 692       dsp_devs[dev]->output_block (dev, dev_buf_phys[dev][dev_qhead[dev]], 
 693           dev_counts[dev][dev_qhead[dev]], 1, 
 694           !sound_dma_automode[dev]);
 695       dev_active[dev] = 1;
 696     }
 697   else
 698     if (underrun_flag)
 699     {
 700       dev_underrun[dev]++;
 701       dsp_devs[dev]->halt_xfer (dev);
 702       dev_needs_restart[dev] = 1;
 703     }
 704 
 705   DISABLE_INTR (flags);
 706   if (SOMEONE_WAITING (dev_sleep_flag[dev]))
 707     {
 708       WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
 709     }
 710   RESTORE_INTR (flags);
 711 }
 712 
 713 void
 714 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 715 {
 716   unsigned long   flags;
 717 
 718   if (!dev_busy[dev])
 719     {
 720       dsp_devs[dev]->close (dev);
 721     }
 722   else if (dev_qlen[dev] == (dev_nbufs[dev] - 1))
 723     {
 724       dev_underrun[dev]++;
 725       dsp_devs[dev]->halt_xfer (dev);
 726       dev_active[dev] = 0;
 727       dev_needs_restart[dev] = 1;
 728     }
 729   else
 730     {
 731       dev_qlen[dev]++;
 732       dev_qtail[dev] = (dev_qtail[dev] + 1) % dev_nbufs[dev];
 733 
 734       dsp_devs[dev]->start_input (dev, dev_buf_phys[dev][dev_qtail[dev]], 
 735                                   dev_buffsize[dev], 1,
 736                                   !sound_dma_automode[dev]);
 737       dev_active[dev] = 1;
 738     }
 739 
 740   DISABLE_INTR (flags);
 741   if (SOMEONE_WAITING (dev_sleep_flag[dev]))
 742     {
 743       WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
 744     }
 745   RESTORE_INTR (flags);
 746 }
 747 
 748 int
 749 DMAbuf_open_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 750 {
 751   unsigned long   flags;
 752   int             chan = sound_dsp_dmachan[dev];
 753 
 754   if (ALLOC_DMA_CHN (chan))
 755     {
 756       printk ("Unable to grab DMA%d for the audio driver\n", chan);
 757       return 0;
 758     }
 759 
 760   DISABLE_INTR (flags);
 761 #ifdef linux
 762   disable_dma (chan);
 763   clear_dma_ff (chan);
 764 #endif
 765   RESTORE_INTR (flags);
 766 
 767   return 1;
 768 }
 769 
 770 void
 771 DMAbuf_close_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 772 {
 773   int             chan = sound_dsp_dmachan[dev];
 774 
 775   DMAbuf_reset_dma (chan);
 776   RELEASE_DMA_CHN (chan);
 777 }
 778 
 779 void
 780 DMAbuf_reset_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 781 {
 782 }
 783 
 784 /*
 785  * The sound_mem_init() is called by mem_init() immediately after mem_map is
 786  * initialized and before free_page_list is created.
 787  * 
 788  * This routine allocates DMA buffers at the end of available physical memory (
 789  * <16M) and marks pages reserved at mem_map.
 790  */
 791 
 792 #else
 793 /* Stub versions if audio services not included  */
 794 
 795 int
 796 DMAbuf_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 797 {
 798   return RET_ERROR (ENXIO);
 799 }
 800 
 801 int
 802 DMAbuf_release (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 803 {
 804   return 0;
 805 }
 806 
 807 int
 808 DMAbuf_read (int dev, snd_rw_buf * user_buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 809 {
 810   return RET_ERROR (EIO);
 811 }
 812 
 813 int
 814 DMAbuf_getwrbuffer (int dev, char **buf, int *size)
     /* [previous][next][first][last][top][bottom][index][help] */
 815 {
 816   return RET_ERROR (EIO);
 817 }
 818 
 819 int
 820 DMAbuf_getrdbuffer (int dev, char **buf, int *len)
     /* [previous][next][first][last][top][bottom][index][help] */
 821 {
 822   return RET_ERROR (EIO);
 823 }
 824 
 825 int
 826 DMAbuf_rmchars (int dev, int buff_no, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
 827 {
 828   return RET_ERROR (EIO);
 829 }
 830 
 831 int
 832 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
 833 {
 834   return RET_ERROR (EIO);
 835 }
 836 
 837 int
 838 DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 839 {
 840   return RET_ERROR (EIO);
 841 }
 842 
 843 long
 844 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 845 {
 846   return mem_start;
 847 }
 848 
 849 int
 850 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 851 {
 852   return RET_ERROR (EIO);
 853 }
 854 
 855 int
 856 DMAbuf_open_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 857 {
 858   return RET_ERROR (ENXIO);
 859 }
 860 
 861 void
 862 DMAbuf_close_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 863 {
 864   return;
 865 }
 866 
 867 void
 868 DMAbuf_reset_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 869 {
 870   return;
 871 }
 872 
 873 void
 874 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 875 {
 876   return;
 877 }
 878 
 879 void
 880 DMAbuf_outputintr (int dev, int underrun_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 881 {
 882   return;
 883 }
 884 
 885 #endif
 886 
 887 #endif

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