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_ioctl
  10. space_in_queue
  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_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  * sound/dmabuf.c
   3  *
   4  * The DMA buffer manager for digitized voice applications
   5  *
   6  * Copyright by Hannu Savolainen 1993, 1994
   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_WAIT_QUEUES (dev_sleeper[MAX_AUDIO_DEV], dev_sleep_flag[MAX_AUDIO_DEV]);
  39 
  40 static struct dma_buffparms dmaps[MAX_AUDIO_DEV] =
  41 {0};                            /*
  42                  * Primitive way to allocate
  43                  * such a large array.
  44                  * Needs dynamic run-time allocation.
  45                  */
  46 
  47 static void
  48 reorganize_buffers (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50   /*
  51    * This routine breaks the physical device buffers to logical ones.
  52    */
  53 
  54   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
  55   struct audio_operations *dsp_dev = audio_devs[dev];
  56 
  57   unsigned        i, p, n;
  58   unsigned        sr, nc, sz, bsz;
  59 
  60   if (dmap->fragment_size == 0)
  61     {                           /* Compute the fragment size using the default algorithm */
  62 
  63       sr = dsp_dev->ioctl (dev, SOUND_PCM_READ_RATE, 0, 1);
  64       nc = dsp_dev->ioctl (dev, SOUND_PCM_READ_CHANNELS, 0, 1);
  65       sz = dsp_dev->ioctl (dev, SOUND_PCM_READ_BITS, 0, 1);
  66 
  67       if (sr < 1 || nc < 1 || sz < 1)
  68         {
  69           printk ("Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n",
  70                   dev, sr, nc, sz);
  71           sr = DSP_DEFAULT_SPEED;
  72           nc = 1;
  73           sz = 8;
  74         }
  75 
  76       sz /= 8;                  /* #bits -> #bytes */
  77 
  78       sz = sr * nc * sz;
  79 
  80       /*
  81    * Compute a buffer size for time not exceeding 1 second.
  82    * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
  83    * of sound (using the current speed, sample size and #channels).
  84    */
  85 
  86       bsz = dsp_dev->buffsize;
  87       while (bsz > sz)
  88         bsz /= 2;
  89 
  90       if (dsp_dev->buffcount == 1 && bsz == dsp_dev->buffsize)
  91         bsz /= 2;               /* Needs at least 2 buffers */
  92 
  93       if (dmap->subdivision == 0)       /* Not already set */
  94         dmap->subdivision = 1;  /* Init to default value */
  95 
  96       bsz /= dmap->subdivision;
  97 
  98       if (bsz < 64)
  99         bsz = 4096;             /* Just a sanity check */
 100 
 101       while ((dsp_dev->buffsize * dsp_dev->buffcount) / bsz > MAX_SUB_BUFFERS)
 102         bsz *= 2;
 103 
 104       dmap->fragment_size = bsz;
 105     }
 106   else
 107     {
 108       /*
 109  * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
 110  * the buffer size computation has already been done.
 111  */
 112       if (dmap->fragment_size > audio_devs[dev]->buffsize)
 113         dmap->fragment_size = audio_devs[dev]->buffsize;
 114       bsz = dmap->fragment_size;
 115     }
 116 
 117   /*
 118    * Now computing addresses for the logical buffers
 119    */
 120 
 121   n = 0;
 122   for (i = 0; i < dmap->raw_count &&
 123        n < dmap->max_fragments &&
 124        n < MAX_SUB_BUFFERS; i++)
 125     {
 126       p = 0;
 127 
 128       while ((p + bsz) <= dsp_dev->buffsize &&
 129              n < dmap->max_fragments &&
 130              n < MAX_SUB_BUFFERS)
 131         {
 132           dmap->buf[n] = dmap->raw_buf[i] + p;
 133           dmap->buf_phys[n] = dmap->raw_buf_phys[i] + p;
 134           p += bsz;
 135           n++;
 136         }
 137     }
 138 
 139   dmap->nbufs = n;
 140   dmap->bytes_in_use = n * bsz;
 141 
 142   for (i = 0; i < dmap->nbufs; i++)
 143     {
 144       dmap->counts[i] = 0;
 145     }
 146 
 147   dmap->flags |= DMA_ALLOC_DONE;
 148 }
 149 
 150 static void
 151 dma_init_buffers (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 152 {
 153   struct dma_buffparms *dmap = audio_devs[dev]->dmap = &dmaps[dev];
 154 
 155   RESET_WAIT_QUEUE (dev_sleeper[dev], dev_sleep_flag[dev]);
 156 
 157   dmap->flags = DMA_BUSY;       /* Other flags off */
 158   dmap->qlen = dmap->qhead = dmap->qtail = 0;
 159 
 160   dmap->qlen = dmap->qtail = dmap->qhead = 0;
 161   dmap->dma_mode = DMODE_NONE;
 162 }
 163 
 164 int
 165 DMAbuf_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167   int             retval;
 168   struct dma_buffparms *dmap = NULL;
 169 
 170   if (dev >= num_audiodevs)
 171     {
 172       printk ("PCM device %d not installed.\n", dev);
 173       return RET_ERROR (ENXIO);
 174     }
 175 
 176   if (!audio_devs[dev])
 177     {
 178       printk ("PCM device %d not initialized\n", dev);
 179       return RET_ERROR (ENXIO);
 180     }
 181 
 182   dmap = audio_devs[dev]->dmap = &dmaps[dev];
 183 
 184   if (dmap->flags & DMA_BUSY)
 185     return RET_ERROR (EBUSY);
 186 
 187 #ifdef USE_RUNTIME_DMAMEM
 188   dmap->raw_buf[0] = NULL;
 189   sound_dma_malloc (dev);
 190 #endif
 191 
 192   if (dmap->raw_buf[0] == NULL)
 193     return RET_ERROR (ENOSPC);  /* Memory allocation failed during boot */
 194 
 195   if ((retval = audio_devs[dev]->open (dev, mode)) < 0)
 196     return retval;
 197 
 198   dmap->open_mode = mode;
 199   dmap->subdivision = dmap->underrun_count = 0;
 200   dmap->fragment_size = 0;
 201   dmap->max_fragments = 65536;  /* Just a large value */
 202 
 203   dma_init_buffers (dev);
 204   audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_BITS, 8, 1);
 205   audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_CHANNELS, 1, 1);
 206   audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_RATE, DSP_DEFAULT_SPEED, 1);
 207 
 208   return 0;
 209 }
 210 
 211 static void
 212 dma_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 213 {
 214   int             retval;
 215   unsigned long   flags;
 216 
 217   DISABLE_INTR (flags);
 218 
 219   audio_devs[dev]->reset (dev);
 220   audio_devs[dev]->close (dev);
 221 
 222   if ((retval = audio_devs[dev]->open (dev, audio_devs[dev]->dmap->open_mode)) < 0)
 223     printk ("Sound: Reset failed - Can't reopen device\n");
 224   RESTORE_INTR (flags);
 225 
 226   dma_init_buffers (dev);
 227   reorganize_buffers (dev);
 228 }
 229 
 230 static int
 231 dma_sync (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233   unsigned long   flags;
 234 
 235   if (audio_devs[dev]->dmap->dma_mode == DMODE_OUTPUT)
 236     {
 237       DISABLE_INTR (flags);
 238 
 239       while (!PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev])
 240              && audio_devs[dev]->dmap->qlen)
 241         {
 242           DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 10 * HZ);
 243           if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
 244             {
 245               RESTORE_INTR (flags);
 246               return audio_devs[dev]->dmap->qlen;
 247             }
 248         }
 249       RESTORE_INTR (flags);
 250 
 251       /*
 252        * Some devices such as GUS have huge amount of on board RAM for the
 253        * audio data. We have to wait util the device has finished playing.
 254        */
 255 
 256       DISABLE_INTR (flags);
 257       if (audio_devs[dev]->local_qlen)  /* Device has hidden buffers */
 258         {
 259           while (!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
 260                  && audio_devs[dev]->local_qlen (dev))
 261             {
 262               DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], HZ);
 263             }
 264         }
 265       RESTORE_INTR (flags);
 266     }
 267   return audio_devs[dev]->dmap->qlen;
 268 }
 269 
 270 int
 271 DMAbuf_release (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 272 {
 273   unsigned long   flags;
 274 
 275   if (!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
 276       && (audio_devs[dev]->dmap->dma_mode == DMODE_OUTPUT))
 277     {
 278       dma_sync (dev);
 279     }
 280 
 281 #ifdef USE_RUNTIME_DMAMEM
 282   sound_dma_free (dev);
 283 #endif
 284 
 285   DISABLE_INTR (flags);
 286   audio_devs[dev]->reset (dev);
 287 
 288   audio_devs[dev]->close (dev);
 289 
 290   audio_devs[dev]->dmap->dma_mode = DMODE_NONE;
 291   audio_devs[dev]->dmap->flags &= ~DMA_BUSY;
 292   RESTORE_INTR (flags);
 293 
 294   return 0;
 295 }
 296 
 297 int
 298 DMAbuf_getrdbuffer (int dev, char **buf, int *len)
     /* [previous][next][first][last][top][bottom][index][help] */
 299 {
 300   unsigned long   flags;
 301   int             err = EIO;
 302   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 303 
 304   DISABLE_INTR (flags);
 305   if (!dmap->qlen)
 306     {
 307       if (dmap->flags & DMA_RESTART)
 308         {
 309           dma_reset (dev);
 310           dmap->flags &= ~DMA_RESTART;
 311         }
 312 
 313       if (dmap->dma_mode == DMODE_OUTPUT)       /* Direction change */
 314         {
 315           dma_sync (dev);
 316           dma_reset (dev);
 317           dmap->dma_mode = DMODE_NONE;
 318         }
 319 
 320       if (!(dmap->flags & DMA_ALLOC_DONE))
 321         reorganize_buffers (dev);
 322 
 323       if (!dmap->dma_mode)
 324         {
 325           int             err;
 326 
 327           if ((err = audio_devs[dev]->prepare_for_input (dev,
 328                                      dmap->fragment_size, dmap->nbufs)) < 0)
 329             {
 330               RESTORE_INTR (flags);
 331               return err;
 332             }
 333           dmap->dma_mode = DMODE_INPUT;
 334         }
 335 
 336       if (!(dmap->flags & DMA_ACTIVE))
 337         {
 338           audio_devs[dev]->start_input (dev, dmap->buf_phys[dmap->qtail],
 339                                         dmap->fragment_size, 0,
 340                                  !(audio_devs[dev]->flags & DMA_AUTOMODE) ||
 341                                         !(dmap->flags & DMA_STARTED));
 342           dmap->flags |= DMA_ACTIVE | DMA_STARTED;
 343         }
 344 
 345       /* Wait for the next block */
 346 
 347       DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);
 348       if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
 349         {
 350           printk ("Sound: DMA timed out - IRQ/DRQ config error?\n");
 351           err = EIO;
 352           SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);
 353         }
 354       else
 355         err = EINTR;
 356     }
 357   RESTORE_INTR (flags);
 358 
 359   if (!dmap->qlen)
 360     return RET_ERROR (err);
 361 
 362   *buf = &dmap->buf[dmap->qhead][dmap->counts[dmap->qhead]];
 363   *len = dmap->fragment_size - dmap->counts[dmap->qhead];
 364 
 365   return dmap->qhead;
 366 }
 367 
 368 int
 369 DMAbuf_rmchars (int dev, int buff_no, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
 370 {
 371   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 372 
 373   int             p = dmap->counts[dmap->qhead] + c;
 374 
 375   if (p >= dmap->fragment_size)
 376     {                           /* This buffer is completely empty */
 377       dmap->counts[dmap->qhead] = 0;
 378       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 379         printk ("\nSound: Audio queue1 corrupted for dev%d (%d/%d)\n",
 380                 dev, dmap->qlen, dmap->nbufs);
 381       dmap->qlen--;
 382       dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
 383     }
 384   else
 385     dmap->counts[dmap->qhead] = p;
 386 
 387   return 0;
 388 }
 389 
 390 int
 391 DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 392 {
 393   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 394 
 395   switch (cmd)
 396     {
 397     case SNDCTL_DSP_RESET:
 398       dma_reset (dev);
 399       return 0;
 400       break;
 401 
 402     case SNDCTL_DSP_SYNC:
 403       dma_sync (dev);
 404       dma_reset (dev);
 405       return 0;
 406       break;
 407 
 408     case SNDCTL_DSP_GETBLKSIZE:
 409       if (!(dmap->flags & DMA_ALLOC_DONE))
 410         reorganize_buffers (dev);
 411 
 412       return IOCTL_OUT (arg, dmap->fragment_size);
 413       break;
 414 
 415     case SNDCTL_DSP_SUBDIVIDE:
 416       {
 417         int             fact = IOCTL_IN (arg);
 418 
 419         if (fact == 0)
 420           {
 421             fact = dmap->subdivision;
 422             if (fact == 0)
 423               fact = 1;
 424             return IOCTL_OUT (arg, fact);
 425           }
 426 
 427         if (dmap->subdivision != 0 ||
 428             dmap->fragment_size)/* Too late to change */
 429           return RET_ERROR (EINVAL);
 430 
 431         if (fact > MAX_REALTIME_FACTOR)
 432           return RET_ERROR (EINVAL);
 433 
 434         if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
 435           return RET_ERROR (EINVAL);
 436 
 437         dmap->subdivision = fact;
 438         return IOCTL_OUT (arg, fact);
 439       }
 440       break;
 441 
 442     case SNDCTL_DSP_SETFRAGMENT:
 443       {
 444         int             fact = IOCTL_IN (arg);
 445         int             bytes, count;
 446 
 447         if (fact == 0)
 448           return RET_ERROR (EIO);
 449 
 450         if (dmap->subdivision != 0 ||
 451             dmap->fragment_size)/* Too late to change */
 452           return RET_ERROR (EINVAL);
 453 
 454         bytes = fact & 0xffff;
 455         count = (fact >> 16) & 0xffff;
 456 
 457         if (count == 0)
 458           count = MAX_SUB_BUFFERS;
 459 
 460         if (bytes < 7 || bytes > 17)    /* <64 || > 128k */
 461           return RET_ERROR (EINVAL);
 462 
 463         if (count < 2)
 464           return RET_ERROR (EINVAL);
 465 
 466         dmap->fragment_size = (1 << bytes);
 467         dmap->max_fragments = count;
 468 
 469         if (dmap->fragment_size > audio_devs[dev]->buffsize)
 470           dmap->fragment_size = audio_devs[dev]->buffsize;
 471 
 472         if (dmap->fragment_size == audio_devs[dev]->buffsize &&
 473             audio_devs[dev]->flags & DMA_AUTOMODE)
 474           dmap->fragment_size /= 2;     /* Needs at least 2 buffers */
 475 
 476         dmap->subdivision = 1;  /* Disable SNDCTL_DSP_SUBDIVIDE */
 477         return IOCTL_OUT (arg, bytes | (count << 16));
 478       }
 479       break;
 480 
 481     default:
 482       return audio_devs[dev]->ioctl (dev, cmd, arg, local);
 483     }
 484 
 485   return RET_ERROR (EIO);
 486 }
 487 
 488 static int
 489 space_in_queue (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 490 {
 491   int             len, max, tmp;
 492   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 493 
 494   if (dmap->qlen == dmap->nbufs)/* No space at all */
 495     return 0;
 496 
 497   /*
 498   * Verify that there are no more pending buffers than the limit
 499   * defined by the process.
 500   */
 501 
 502   max = dmap->max_fragments;
 503   len = dmap->qlen;
 504 
 505   if (audio_devs[dev]->local_qlen)
 506     {
 507       tmp = audio_devs[dev]->local_qlen (dev);
 508       if (tmp & len)
 509         tmp--;                  /*
 510                          * This buffer has been counted twice
 511                          */
 512       len += tmp;
 513     }
 514 
 515   if (len >= max)
 516     return 0;
 517   return 1;
 518 }
 519 
 520 int
 521 DMAbuf_getwrbuffer (int dev, char **buf, int *size)
     /* [previous][next][first][last][top][bottom][index][help] */
 522 {
 523   unsigned long   flags;
 524   int             abort, err = EIO;
 525   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 526 
 527   if (dmap->dma_mode == DMODE_INPUT)    /* Direction change */
 528     {
 529       dma_reset (dev);
 530       dmap->dma_mode = DMODE_NONE;
 531     }
 532   else if (dmap->flags & DMA_RESTART)   /* Restart buffering */
 533     {
 534       dma_sync (dev);
 535       dma_reset (dev);
 536     }
 537 
 538   dmap->flags &= ~DMA_RESTART;
 539 
 540   if (!(dmap->flags & DMA_ALLOC_DONE))
 541     reorganize_buffers (dev);
 542 
 543   if (!dmap->dma_mode)
 544     {
 545       int             err;
 546 
 547       dmap->dma_mode = DMODE_OUTPUT;
 548       if ((err = audio_devs[dev]->prepare_for_output (dev,
 549                                      dmap->fragment_size, dmap->nbufs)) < 0)
 550         return err;
 551     }
 552 
 553 
 554   DISABLE_INTR (flags);
 555 
 556   abort = 0;
 557   while (!space_in_queue (dev) &&
 558          !abort)
 559     {
 560       /*
 561        * Wait for free space
 562        */
 563       DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);
 564       if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
 565         {
 566           printk ("Sound: DMA timed out - IRQ/DRQ config error?\n");
 567           err = EIO;
 568           abort = 1;
 569           SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);
 570         }
 571       else if (PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
 572         {
 573           err = EINTR;
 574           abort = 1;
 575         }
 576     }
 577   RESTORE_INTR (flags);
 578 
 579   if (!space_in_queue (dev))
 580     {
 581       return RET_ERROR (err);   /* Caught a signal ? */
 582     }
 583 
 584   *buf = dmap->buf[dmap->qtail];
 585   *size = dmap->fragment_size;
 586   dmap->counts[dmap->qtail] = 0;
 587 
 588   return dmap->qtail;
 589 }
 590 
 591 int
 592 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
 593 {
 594   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 595 
 596   if (buff_no != dmap->qtail)
 597     printk ("Sound warning: DMA buffers out of sync %d != %d\n", buff_no, dmap->qtail);
 598 
 599   dmap->qlen++;
 600   if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 601     printk ("\nSound: Audio queue2 corrupted for dev%d (%d/%d)\n",
 602             dev, dmap->qlen, dmap->nbufs);
 603 
 604   dmap->counts[dmap->qtail] = l;
 605 
 606   if ((l != dmap->fragment_size) &&
 607       ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
 608        audio_devs[dev]->flags & NEEDS_RESTART))
 609     dmap->flags |= DMA_RESTART;
 610   else
 611     dmap->flags &= ~DMA_RESTART;
 612 
 613   dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
 614 
 615   if (!(dmap->flags & DMA_ACTIVE))
 616     {
 617       dmap->flags |= DMA_ACTIVE;
 618       audio_devs[dev]->output_block (dev, dmap->buf_phys[dmap->qhead],
 619                                      dmap->counts[dmap->qhead], 0,
 620                                  !(audio_devs[dev]->flags & DMA_AUTOMODE) ||
 621                                      !(dmap->flags & DMA_STARTED));
 622       dmap->flags |= DMA_STARTED;
 623     }
 624 
 625   return 0;
 626 }
 627 
 628 int
 629 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 630 {
 631   int             chan = audio_devs[dev]->dmachan;
 632   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 633   unsigned long   flags;
 634 
 635   /*
 636    * This function is not as portable as it should be.
 637    */
 638 
 639   /*
 640    * The count must be one less than the actual size. This is handled by
 641    * set_dma_addr()
 642    */
 643 
 644   if (audio_devs[dev]->flags & DMA_AUTOMODE)
 645     {                           /*
 646                                  * Auto restart mode. Transfer the whole *
 647                                  * buffer
 648                                  */
 649 #ifdef linux
 650       DISABLE_INTR (flags);
 651       disable_dma (chan);
 652       clear_dma_ff (chan);
 653       set_dma_mode (chan, dma_mode | DMA_AUTOINIT);
 654       set_dma_addr (chan, dmap->raw_buf_phys[0]);
 655       set_dma_count (chan, dmap->bytes_in_use);
 656       enable_dma (chan);
 657       RESTORE_INTR (flags);
 658 #else
 659 
 660 #ifdef __386BSD__
 661       printk ("sound: Invalid DMA mode for device %d\n", dev);
 662 
 663       isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
 664                     dmap->raw_buf_phys[0],
 665                     dmap->bytes_in_use,
 666                     chan);
 667 #else
 668 #if defined(GENERIC_SYSV)
 669 #ifndef DMAMODE_AUTO
 670       printk ("sound: Invalid DMA mode for device %d\n", dev);
 671 #endif
 672       dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode)
 673 #ifdef DMAMODE_AUTO
 674                  | DMAMODE_AUTO
 675 #endif
 676                  ,
 677                  dmap->raw_buf_phys[0], dmap->bytes_in_use);
 678       dma_enable (chan);
 679 #else
 680 #error This routine is not valid for this OS.
 681 #endif
 682 #endif
 683 
 684 #endif
 685     }
 686   else
 687     {
 688 #ifdef linux
 689       DISABLE_INTR (flags);
 690       disable_dma (chan);
 691       clear_dma_ff (chan);
 692       set_dma_mode (chan, dma_mode);
 693       set_dma_addr (chan, physaddr);
 694       set_dma_count (chan, count);
 695       enable_dma (chan);
 696       RESTORE_INTR (flags);
 697 #else
 698 #ifdef __386BSD__
 699       isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
 700                     physaddr,
 701                     count,
 702                     chan);
 703 #else
 704 
 705 #if defined(GENERIC_SYSV)
 706       dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode),
 707                  physaddr, count);
 708       dma_enable (chan);
 709 #else
 710 #error This routine is not valid for this OS.
 711 #endif /* GENERIC_SYSV */
 712 #endif
 713 
 714 #endif
 715     }
 716 
 717   return count;
 718 }
 719 
 720 long
 721 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 722 {
 723   int             dev;
 724 
 725   /*
 726  * NOTE! This routine could be called several times.
 727  */
 728 
 729   for (dev = 0; dev < num_audiodevs; dev++)
 730     audio_devs[dev]->dmap = &dmaps[dev];
 731   return mem_start;
 732 }
 733 
 734 void
 735 DMAbuf_outputintr (int dev, int event_type)
     /* [previous][next][first][last][top][bottom][index][help] */
 736 {
 737   /*
 738  * Event types:
 739  *      0 = DMA transfer done. Device still has more data in the local
 740  *          buffer.
 741  *      1 = DMA transfer done. Device doesn't have local buffer or it's
 742  *          empty now.
 743  *      2 = No DMA transfer but the device has now more space in it's local
 744  *          buffer.
 745  */
 746 
 747   unsigned long   flags;
 748   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 749 
 750   if (event_type != 2)
 751     {
 752       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 753         {
 754           printk ("\nSound: Audio queue3 corrupted for dev%d (%d/%d)\n",
 755                   dev, dmap->qlen, dmap->nbufs);
 756           return;
 757         }
 758 
 759       dmap->qlen--;
 760       dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
 761       dmap->flags &= ~DMA_ACTIVE;
 762 
 763       if (dmap->qlen)
 764         {
 765           audio_devs[dev]->output_block (dev, dmap->buf_phys[dmap->qhead],
 766                                          dmap->counts[dmap->qhead], 1,
 767                                   !(audio_devs[dev]->flags & DMA_AUTOMODE));
 768           dmap->flags |= DMA_ACTIVE;
 769         }
 770       else if (event_type == 1)
 771         {
 772           dmap->underrun_count++;
 773           audio_devs[dev]->halt_xfer (dev);
 774           if ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
 775               audio_devs[dev]->flags & NEEDS_RESTART)
 776             dmap->flags |= DMA_RESTART;
 777           else
 778             dmap->flags &= ~DMA_RESTART;
 779         }
 780     }                           /* event_type != 2 */
 781 
 782   DISABLE_INTR (flags);
 783   if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))
 784     {
 785       WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
 786     }
 787   RESTORE_INTR (flags);
 788 }
 789 
 790 void
 791 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 792 {
 793   unsigned long   flags;
 794   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 795 
 796   if (dmap->qlen == (dmap->nbufs - 1))
 797     {
 798       printk ("Sound: Recording overrun\n");
 799       dmap->underrun_count++;
 800       audio_devs[dev]->halt_xfer (dev);
 801       dmap->flags &= ~DMA_ACTIVE;
 802       if (audio_devs[dev]->flags & DMA_AUTOMODE)
 803         dmap->flags |= DMA_RESTART;
 804       else
 805         dmap->flags &= ~DMA_RESTART;
 806     }
 807   else
 808     {
 809       dmap->qlen++;
 810       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 811         printk ("\nSound: Audio queue4 corrupted for dev%d (%d/%d)\n",
 812                 dev, dmap->qlen, dmap->nbufs);
 813       dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
 814 
 815       audio_devs[dev]->start_input (dev, dmap->buf_phys[dmap->qtail],
 816                                     dmap->fragment_size, 1,
 817                                   !(audio_devs[dev]->flags & DMA_AUTOMODE));
 818       dmap->flags |= DMA_ACTIVE;
 819     }
 820 
 821   DISABLE_INTR (flags);
 822   if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))
 823     {
 824       WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
 825     }
 826   RESTORE_INTR (flags);
 827 }
 828 
 829 int
 830 DMAbuf_open_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 831 {
 832   unsigned long   flags;
 833   int             chan = audio_devs[dev]->dmachan;
 834 
 835   if (ALLOC_DMA_CHN (chan,"audio"))
 836     {
 837       printk ("Unable to grab DMA%d for the audio driver\n", chan);
 838       return RET_ERROR (EBUSY);
 839     }
 840 
 841   DISABLE_INTR (flags);
 842 #ifdef linux
 843   disable_dma (chan);
 844   clear_dma_ff (chan);
 845 #endif
 846   RESTORE_INTR (flags);
 847 
 848   return 0;
 849 }
 850 
 851 void
 852 DMAbuf_close_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 853 {
 854   int             chan = audio_devs[dev]->dmachan;
 855 
 856   DMAbuf_reset_dma (chan);
 857   RELEASE_DMA_CHN (chan);
 858 }
 859 
 860 void
 861 DMAbuf_reset_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 862 {
 863 }
 864 
 865 /*
 866  * The sound_mem_init() is called by mem_init() immediately after mem_map is
 867  * initialized and before free_page_list is created.
 868  *
 869  * This routine allocates DMA buffers at the end of available physical memory (
 870  * <16M) and marks pages reserved at mem_map.
 871  */
 872 
 873 #else
 874 /*
 875  * Stub versions if audio services not included
 876  */
 877 
 878 int
 879 DMAbuf_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 880 {
 881   return RET_ERROR (ENXIO);
 882 }
 883 
 884 int
 885 DMAbuf_release (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 886 {
 887   return 0;
 888 }
 889 
 890 int
 891 DMAbuf_getwrbuffer (int dev, char **buf, int *size)
     /* [previous][next][first][last][top][bottom][index][help] */
 892 {
 893   return RET_ERROR (EIO);
 894 }
 895 
 896 int
 897 DMAbuf_getrdbuffer (int dev, char **buf, int *len)
     /* [previous][next][first][last][top][bottom][index][help] */
 898 {
 899   return RET_ERROR (EIO);
 900 }
 901 
 902 int
 903 DMAbuf_rmchars (int dev, int buff_no, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
 904 {
 905   return RET_ERROR (EIO);
 906 }
 907 
 908 int
 909 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
 910 {
 911   return RET_ERROR (EIO);
 912 }
 913 
 914 int
 915 DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 916 {
 917   return RET_ERROR (EIO);
 918 }
 919 
 920 long
 921 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 922 {
 923   return mem_start;
 924 }
 925 
 926 int
 927 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 928 {
 929   return RET_ERROR (EIO);
 930 }
 931 
 932 int
 933 DMAbuf_open_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 934 {
 935   return RET_ERROR (ENXIO);
 936 }
 937 
 938 void
 939 DMAbuf_close_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 940 {
 941   return;
 942 }
 943 
 944 void
 945 DMAbuf_reset_dma (int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 946 {
 947   return;
 948 }
 949 
 950 void
 951 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 952 {
 953   return;
 954 }
 955 
 956 void
 957 DMAbuf_outputintr (int dev, int underrun_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 958 {
 959   return;
 960 }
 961 
 962 #endif
 963 
 964 #endif

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