root/drivers/sound/dmabuf.c

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

DEFINITIONS

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

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