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

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