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

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