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

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