root/drivers/sound/dmabuf.c

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

DEFINITIONS

This source file includes following definitions.
  1. reorganize_buffers
  2. dma_init_buffers
  3. DMAbuf_open
  4. dma_reset
  5. dma_sync
  6. DMAbuf_release
  7. DMAbuf_getrdbuffer
  8. DMAbuf_rmchars
  9. DMAbuf_read
  10. DMAbuf_ioctl
  11. DMAbuf_getwrbuffer
  12. DMAbuf_start_output
  13. DMAbuf_start_dma
  14. DMAbuf_init
  15. DMAbuf_outputintr
  16. DMAbuf_inputintr
  17. DMAbuf_open_dma
  18. DMAbuf_close_dma
  19. DMAbuf_reset_dma
  20. DMAbuf_open
  21. DMAbuf_release
  22. DMAbuf_read
  23. DMAbuf_getwrbuffer
  24. DMAbuf_getrdbuffer
  25. DMAbuf_rmchars
  26. DMAbuf_start_output
  27. DMAbuf_ioctl
  28. DMAbuf_init
  29. DMAbuf_start_dma
  30. DMAbuf_open_dma
  31. DMAbuf_close_dma
  32. DMAbuf_reset_dma
  33. DMAbuf_inputintr
  34. DMAbuf_outputintr

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

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