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       else
 493         {
 494           audio_buf_info *info = (audio_buf_info *) arg;
 495 
 496           if (!(dmap->flags & DMA_ALLOC_DONE))
 497             reorganize_buffers (dev);
 498 
 499           if (cmd == SNDCTL_DSP_GETISPACE)
 500             info->fragments = dmap->qlen;
 501           else
 502             {
 503               if (!space_in_queue (dev))
 504                 info->fragments = 0;
 505               else
 506                 {
 507                   info->fragments = dmap->nbufs - dmap->qlen;
 508                   if (audio_devs[dev]->local_qlen)
 509                     {
 510                       int             tmp = audio_devs[dev]->local_qlen (dev);
 511 
 512                       if (tmp & info->fragments)
 513                         tmp--;  /*
 514                                    * This buffer has been counted twice
 515                                  */
 516                       info->fragments -= tmp;
 517                     }
 518                 }
 519             }
 520 
 521           if (info->fragments < 0)
 522             info->fragments = 0;
 523           else if (info->fragments > dmap->nbufs)
 524             info->fragments = dmap->nbufs;
 525 
 526           info->fragsize = dmap->fragment_size;
 527           info->bytes = info->fragments * dmap->fragment_size;
 528 
 529           if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
 530             info->bytes -= dmap->counts[dmap->qhead];
 531         }
 532       return 0;
 533 
 534     default:
 535       return audio_devs[dev]->ioctl (dev, cmd, arg, local);
 536     }
 537 
 538 }
 539 
 540 static int
 541 space_in_queue (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 542 {
 543   int             len, max, tmp;
 544   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 545 
 546   if (dmap->qlen >= dmap->nbufs)        /* No space at all */
 547     return 0;
 548 
 549   /*
 550      * Verify that there are no more pending buffers than the limit
 551      * defined by the process.
 552    */
 553 
 554   max = dmap->max_fragments;
 555   len = dmap->qlen;
 556 
 557   if (audio_devs[dev]->local_qlen)
 558     {
 559       tmp = audio_devs[dev]->local_qlen (dev);
 560       if (tmp & len)
 561         tmp--;                  /*
 562                                    * This buffer has been counted twice
 563                                  */
 564       len += tmp;
 565     }
 566 
 567   if (len >= max)
 568     return 0;
 569   return 1;
 570 }
 571 
 572 int
 573 DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 574 {
 575   unsigned long   flags;
 576   int             abort, err = EIO;
 577   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 578 
 579   if (dmap->dma_mode == DMODE_INPUT)    /* Direction change */
 580     {
 581       dma_reset (dev);
 582       dmap->dma_mode = DMODE_NONE;
 583     }
 584   else if (dmap->flags & DMA_RESTART)   /* Restart buffering */
 585     {
 586       dma_sync (dev);
 587       dma_reset (dev);
 588     }
 589 
 590   dmap->flags &= ~DMA_RESTART;
 591 
 592   if (!(dmap->flags & DMA_ALLOC_DONE))
 593     reorganize_buffers (dev);
 594 
 595   if (!dmap->dma_mode)
 596     {
 597       int             err;
 598 
 599       dmap->dma_mode = DMODE_OUTPUT;
 600       if ((err = audio_devs[dev]->prepare_for_output (dev,
 601                                      dmap->fragment_size, dmap->nbufs)) < 0)
 602         return err;
 603     }
 604 
 605 
 606   if (dontblock)
 607     return RET_ERROR (EAGAIN);
 608 
 609   DISABLE_INTR (flags);
 610 
 611   abort = 0;
 612   while (!space_in_queue (dev) &&
 613          !abort)
 614     {
 615       /*
 616        * Wait for free space
 617        */
 618       DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);
 619       if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
 620         {
 621           printk ("Sound: DMA timed out - IRQ/DRQ config error?\n");
 622           err = EIO;
 623           abort = 1;
 624           SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);
 625         }
 626       else if (PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
 627         {
 628           err = EINTR;
 629           abort = 1;
 630         }
 631     }
 632   RESTORE_INTR (flags);
 633 
 634   if (!space_in_queue (dev))
 635     {
 636       return RET_ERROR (err);   /* Caught a signal ? */
 637     }
 638 
 639   *buf = dmap->buf[dmap->qtail];
 640   *size = dmap->fragment_size;
 641   dmap->counts[dmap->qtail] = 0;
 642 
 643   return dmap->qtail;
 644 }
 645 
 646 int
 647 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
 648 {
 649   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 650 
 651   if (buff_no != dmap->qtail)
 652     printk ("Sound warning: DMA buffers out of sync %d != %d\n", buff_no, dmap->qtail);
 653 
 654   dmap->qlen++;
 655   if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 656     printk ("\nSound: Audio queue2 corrupted for dev%d (%d/%d)\n",
 657             dev, dmap->qlen, dmap->nbufs);
 658 
 659   dmap->counts[dmap->qtail] = l;
 660 
 661   if ((l != dmap->fragment_size) &&
 662       ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
 663        audio_devs[dev]->flags & NEEDS_RESTART))
 664     dmap->flags |= DMA_RESTART;
 665   else
 666     dmap->flags &= ~DMA_RESTART;
 667 
 668   dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
 669 
 670   if (!(dmap->flags & DMA_ACTIVE))
 671     {
 672       dmap->flags |= DMA_ACTIVE;
 673       audio_devs[dev]->output_block (dev, dmap->buf_phys[dmap->qhead],
 674                                      dmap->counts[dmap->qhead], 0,
 675                                  !(audio_devs[dev]->flags & DMA_AUTOMODE) ||
 676                                      !(dmap->flags & DMA_STARTED));
 677       dmap->flags |= DMA_STARTED;
 678     }
 679 
 680   return 0;
 681 }
 682 
 683 int
 684 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 685 {
 686   int             chan = audio_devs[dev]->dmachan;
 687   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 688   unsigned long   flags;
 689 
 690   /*
 691    * This function is not as portable as it should be.
 692    */
 693 
 694   /*
 695    * The count must be one less than the actual size. This is handled by
 696    * set_dma_addr()
 697    */
 698 
 699   if (audio_devs[dev]->flags & DMA_AUTOMODE)
 700     {                           /*
 701                                  * Auto restart mode. Transfer the whole *
 702                                  * buffer
 703                                  */
 704 #ifdef linux
 705       DISABLE_INTR (flags);
 706       disable_dma (chan);
 707       clear_dma_ff (chan);
 708       set_dma_mode (chan, dma_mode | DMA_AUTOINIT);
 709       set_dma_addr (chan, dmap->raw_buf_phys[0]);
 710       set_dma_count (chan, dmap->bytes_in_use);
 711       enable_dma (chan);
 712       RESTORE_INTR (flags);
 713 #else
 714 
 715 #ifdef __386BSD__
 716       printk ("sound: Invalid DMA mode for device %d\n", dev);
 717 
 718       isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
 719                     dmap->raw_buf_phys[0],
 720                     dmap->bytes_in_use,
 721                     chan);
 722 #else
 723 #if defined(GENERIC_SYSV)
 724 #ifndef DMAMODE_AUTO
 725       printk ("sound: Invalid DMA mode for device %d\n", dev);
 726 #endif
 727 #if defined(SVR42)
 728 
 729       /*
 730          ** send full count to snd_dma_prog, it will take care of subtracting
 731          ** one if it is required.
 732        */
 733       snd_dma_prog (chan, dmap->raw_buf_phys[0], dmap->bytes_in_use,
 734                     dma_mode, TRUE);
 735 
 736 #else /* !SVR42 */
 737       dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode)
 738 #ifdef DMAMODE_AUTO
 739                  | DMAMODE_AUTO
 740 #endif
 741                  ,
 742                  dmap->raw_buf_phys[0], dmap->bytes_in_use - 1);
 743       dma_enable (chan);
 744 #endif /*  ! SVR42 */
 745 #else
 746 #error This routine is not valid for this OS.
 747 #endif
 748 #endif
 749 
 750 #endif
 751     }
 752   else
 753     {
 754 #ifdef linux
 755       DISABLE_INTR (flags);
 756       disable_dma (chan);
 757       clear_dma_ff (chan);
 758       set_dma_mode (chan, dma_mode);
 759       set_dma_addr (chan, physaddr);
 760       set_dma_count (chan, count);
 761       enable_dma (chan);
 762       RESTORE_INTR (flags);
 763 #else
 764 #ifdef __386BSD__
 765       isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
 766                     physaddr,
 767                     count,
 768                     chan);
 769 #else
 770 
 771 #if defined(GENERIC_SYSV)
 772 #if defined(SVR42)
 773 
 774       snd_dma_prog (chan, physaddr, count, dma_mode, FALSE);
 775 
 776 #else /* ! SVR42 */
 777       dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode),
 778                  physaddr, count);
 779       dma_enable (chan);
 780 #endif /* SVR42 */
 781 #else
 782 #error This routine is not valid for this OS.
 783 #endif /* GENERIC_SYSV */
 784 #endif
 785 
 786 #endif
 787     }
 788 
 789   return count;
 790 }
 791 
 792 long
 793 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 794 {
 795   int             dev;
 796 
 797 #if defined(SVR42)
 798   snd_dma_init ();
 799 #endif /* SVR42 */
 800 
 801   /*
 802      * NOTE! This routine could be called several times.
 803    */
 804 
 805   for (dev = 0; dev < num_audiodevs; dev++)
 806     audio_devs[dev]->dmap = &dmaps[dev];
 807   return mem_start;
 808 }
 809 
 810 void
 811 DMAbuf_outputintr (int dev, int event_type)
     /* [previous][next][first][last][top][bottom][index][help] */
 812 {
 813   /*
 814      * Event types:
 815      *  0 = DMA transfer done. Device still has more data in the local
 816      *      buffer.
 817      *  1 = DMA transfer done. Device doesn't have local buffer or it's
 818      *      empty now.
 819      *  2 = No DMA transfer but the device has now more space in it's local
 820      *      buffer.
 821    */
 822 
 823   unsigned long   flags;
 824   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 825 
 826 #if defined(SVR42)
 827   snd_dma_intr (audio_devs[dev]->dmachan);
 828 #endif /* SVR42 */
 829 
 830   if (event_type != 2)
 831     {
 832       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 833         {
 834           printk ("\nSound: Audio queue3 corrupted for dev%d (%d/%d)\n",
 835                   dev, dmap->qlen, dmap->nbufs);
 836           return;
 837         }
 838 
 839       dmap->qlen--;
 840       dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
 841       dmap->flags &= ~DMA_ACTIVE;
 842 
 843       if (dmap->qlen)
 844         {
 845           audio_devs[dev]->output_block (dev, dmap->buf_phys[dmap->qhead],
 846                                          dmap->counts[dmap->qhead], 1,
 847                                   !(audio_devs[dev]->flags & DMA_AUTOMODE));
 848           dmap->flags |= DMA_ACTIVE;
 849         }
 850       else if (event_type == 1)
 851         {
 852           dmap->underrun_count++;
 853           audio_devs[dev]->halt_xfer (dev);
 854           if ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
 855               audio_devs[dev]->flags & NEEDS_RESTART)
 856             dmap->flags |= DMA_RESTART;
 857           else
 858             dmap->flags &= ~DMA_RESTART;
 859         }
 860     }                           /* event_type != 2 */
 861 
 862   DISABLE_INTR (flags);
 863   if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))
 864     {
 865       WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
 866     }
 867   RESTORE_INTR (flags);
 868 }
 869 
 870 void
 871 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 872 {
 873   unsigned long   flags;
 874   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 875 
 876 #if defined(SVR42)
 877   snd_dma_intr (audio_devs[dev]->dmachan);
 878 #endif /* SVR42 */
 879 
 880   if (dmap->qlen == (dmap->nbufs - 1))
 881     {
 882       printk ("Sound: Recording overrun\n");
 883       dmap->underrun_count++;
 884       audio_devs[dev]->halt_xfer (dev);
 885       dmap->flags &= ~DMA_ACTIVE;
 886       if (audio_devs[dev]->flags & DMA_AUTOMODE)
 887         dmap->flags |= DMA_RESTART;
 888       else
 889         dmap->flags &= ~DMA_RESTART;
 890     }
 891   else
 892     {
 893       dmap->qlen++;
 894       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 895         printk ("\nSound: Audio queue4 corrupted for dev%d (%d/%d)\n",
 896                 dev, dmap->qlen, dmap->nbufs);
 897       dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
 898 
 899       audio_devs[dev]->start_input (dev, dmap->buf_phys[dmap->qtail],
 900                                     dmap->fragment_size, 1,
 901                                   !(audio_devs[dev]->flags & DMA_AUTOMODE));
 902       dmap->flags |= DMA_ACTIVE;
 903     }
 904 
 905   DISABLE_INTR (flags);
 906   if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))
 907     {
 908       WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
 909     }
 910   RESTORE_INTR (flags);
 911 }
 912 
 913 int
 914 DMAbuf_open_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 915 {
 916   unsigned long   flags;
 917   int             chan = audio_devs[dev]->dmachan;
 918 
 919   if (ALLOC_DMA_CHN (chan, audio_devs[dev]->name))
 920     {
 921       printk ("Unable to grab DMA%d for the audio driver\n", chan);
 922       return RET_ERROR (EBUSY);
 923     }
 924 
 925   DISABLE_INTR (flags);
 926 #ifdef linux
 927   disable_dma (chan);
 928   clear_dma_ff (chan);
 929 #endif
 930   RESTORE_INTR (flags);
 931 
 932   return 0;
 933 }
 934 
 935 void
 936 DMAbuf_close_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 937 {
 938   int             chan = audio_devs[dev]->dmachan;
 939 
 940   DMAbuf_reset_dma (dev);
 941   RELEASE_DMA_CHN (chan);
 942 }
 943 
 944 void
 945 DMAbuf_reset_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 946 {
 947 #if 0
 948   int             chan = audio_devs[dev]->dmachan;
 949 
 950   disable_dma (chan);
 951 #endif
 952 }
 953 
 954 #ifdef ALLOW_SELECT
 955 int
 956 DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 957 {
 958   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 959   unsigned long   flags;
 960 
 961   switch (sel_type)
 962     {
 963     case SEL_IN:
 964 
 965       if (dmap->dma_mode != DMODE_INPUT)
 966         return 0;
 967 
 968       if (!dmap->qlen)
 969         {
 970           DISABLE_INTR (flags);
 971           dev_sleep_flag[dev].mode = WK_SLEEP;
 972           select_wait (&dev_sleeper[dev], wait);
 973           RESTORE_INTR (flags);
 974           return 0;
 975         }
 976       return 1;
 977       break;
 978 
 979     case SEL_OUT:
 980       if (dmap->dma_mode == DMODE_INPUT)
 981         {
 982           return 0;
 983         }
 984 
 985       if (dmap->dma_mode == DMODE_NONE)
 986         {
 987           return 1;
 988         }
 989 
 990       if (!space_in_queue (dev))
 991         {
 992           DISABLE_INTR (flags);
 993           dev_sleep_flag[dev].mode = WK_SLEEP;
 994           select_wait (&dev_sleeper[dev], wait);
 995           RESTORE_INTR (flags);
 996           return 0;
 997         }
 998       return 1;
 999       break;
1000 
1001     case SEL_EX:
1002       return 0;
1003     }
1004 
1005   return 0;
1006 }
1007 
1008 #endif /* ALLOW_SELECT */
1009 
1010 #else /* EXCLUDE_AUDIO */
1011 /*
1012  * Stub versions if audio services not included
1013  */
1014 
1015 int
1016 DMAbuf_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1017 {
1018   return RET_ERROR (ENXIO);
1019 }
1020 
1021 int
1022 DMAbuf_release (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1023 {
1024   return 0;
1025 }
1026 
1027 int
1028 DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1029 {
1030   return RET_ERROR (EIO);
1031 }
1032 
1033 int
1034 DMAbuf_getrdbuffer (int dev, char **buf, int *len, int dontblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1035 {
1036   return RET_ERROR (EIO);
1037 }
1038 
1039 int
1040 DMAbuf_rmchars (int dev, int buff_no, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
1041 {
1042   return RET_ERROR (EIO);
1043 }
1044 
1045 int
1046 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
1047 {
1048   return RET_ERROR (EIO);
1049 }
1050 
1051 int
1052 DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
1053 {
1054   return RET_ERROR (EIO);
1055 }
1056 
1057 long
1058 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1059 {
1060   return mem_start;
1061 }
1062 
1063 int
1064 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1065 {
1066   return RET_ERROR (EIO);
1067 }
1068 
1069 int
1070 DMAbuf_open_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1071 {
1072   return RET_ERROR (ENXIO);
1073 }
1074 
1075 void
1076 DMAbuf_close_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1077 {
1078   return;
1079 }
1080 
1081 void
1082 DMAbuf_reset_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1083 {
1084   return;
1085 }
1086 
1087 void
1088 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1089 {
1090   return;
1091 }
1092 
1093 void
1094 DMAbuf_outputintr (int dev, int underrun_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
1095 {
1096   return;
1097 }
1098 
1099 #endif
1100 
1101 #endif

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