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

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