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. open_dmap
  4. close_dmap
  5. DMAbuf_open
  6. dma_reset
  7. dma_reset_output
  8. dma_reset_input
  9. dma_sync
  10. DMAbuf_release
  11. activate_recording
  12. DMAbuf_getrdbuffer
  13. DMAbuf_rmchars
  14. dma_subdivide
  15. dma_set_fragment
  16. get_buffer_pointer
  17. DMAbuf_ioctl
  18. DMAbuf_start_devices
  19. space_in_queue
  20. DMAbuf_getwrbuffer
  21. DMAbuf_start_output
  22. DMAbuf_start_dma
  23. DMAbuf_init
  24. DMAbuf_outputintr
  25. DMAbuf_inputintr
  26. DMAbuf_open_dma
  27. DMAbuf_close_dma
  28. DMAbuf_reset_dma
  29. DMAbuf_select
  30. DMAbuf_open
  31. DMAbuf_release
  32. DMAbuf_getwrbuffer
  33. DMAbuf_getrdbuffer
  34. DMAbuf_rmchars
  35. DMAbuf_start_output
  36. DMAbuf_ioctl
  37. DMAbuf_init
  38. DMAbuf_start_dma
  39. DMAbuf_open_dma
  40. DMAbuf_close_dma
  41. DMAbuf_reset_dma
  42. DMAbuf_inputintr
  43. 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 #if !defined(EXCLUDE_AUDIO) || !defined(EXCLUDE_GUS)
  35 
  36 static struct wait_queue *in_sleeper[MAX_AUDIO_DEV] =
  37 {NULL};
  38 static volatile struct snd_wait in_sleep_flag[MAX_AUDIO_DEV] =
  39 {
  40   {0}};
  41 static struct wait_queue *out_sleeper[MAX_AUDIO_DEV] =
  42 {NULL};
  43 static volatile struct snd_wait out_sleep_flag[MAX_AUDIO_DEV] =
  44 {
  45   {0}};
  46 
  47 static int      ndmaps = 0;
  48 
  49 #define MAX_DMAP (MAX_AUDIO_DEV*2)
  50 
  51 static struct dma_buffparms dmaps[MAX_DMAP] =
  52 {
  53   {0}};                         /*
  54 
  55                                    * Primitive way to allocate
  56                                    * such a large array.
  57                                    * Needs dynamic run-time alloction.
  58                                  */
  59 static int      space_in_queue (int dev);
  60 
  61 static void     dma_reset_output (int dev);
  62 static void     dma_reset_input (int dev);
  63 
  64 static void
  65 reorganize_buffers (int dev, struct dma_buffparms *dmap)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67   /*
  68    * This routine breaks the physical device buffers to logical ones.
  69    */
  70 
  71   struct audio_operations *dsp_dev = audio_devs[dev];
  72 
  73   unsigned        i, n;
  74   unsigned        sr, nc, sz, bsz;
  75 
  76   if (dmap->fragment_size == 0)
  77     {                           /* Compute the fragment size using the default algorithm */
  78 
  79       sr = dsp_dev->ioctl (dev, SOUND_PCM_READ_RATE, 0, 1);
  80       nc = dsp_dev->ioctl (dev, SOUND_PCM_READ_CHANNELS, 0, 1);
  81       sz = dsp_dev->ioctl (dev, SOUND_PCM_READ_BITS, 0, 1);
  82 
  83       if (sz == 8)
  84         dmap->neutral_byte = 0x80;
  85       else
  86         dmap->neutral_byte = 0x00;
  87 
  88       if (sr < 1 || nc < 1 || sz < 1)
  89         {
  90           printk ("Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n",
  91                   dev, sr, nc, sz);
  92           sr = DSP_DEFAULT_SPEED;
  93           nc = 1;
  94           sz = 8;
  95         }
  96 
  97       sz = sr * nc * sz;
  98 
  99       sz /= 8;                  /* #bits -> #bytes */
 100 
 101       /*
 102          * Compute a buffer size for time not exeeding 1 second.
 103          * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
 104          * of sound (using the current speed, sample size and #channels).
 105        */
 106 
 107       bsz = dsp_dev->buffsize;
 108       while (bsz > sz)
 109         bsz /= 2;
 110 
 111       if (bsz == dsp_dev->buffsize)
 112         bsz /= 2;               /* Needs at least 2 buffers */
 113 
 114       if (dmap->subdivision == 0)       /* Not already set */
 115         dmap->subdivision = 1;  /* Init to default value */
 116       else
 117         bsz /= dmap->subdivision;
 118 
 119       if (bsz < 16)
 120         bsz = 16;               /* Just a sanity check */
 121 
 122       dmap->fragment_size = bsz;
 123     }
 124   else
 125     {
 126       /*
 127          * The process has specified the buffer sice with SNDCTL_DSP_SETFRAGMENT or
 128          * the buffer sice computation has already been done.
 129        */
 130       if (dmap->fragment_size > (audio_devs[dev]->buffsize / 2))
 131         dmap->fragment_size = (audio_devs[dev]->buffsize / 2);
 132       bsz = dmap->fragment_size;
 133     }
 134 
 135   bsz &= ~0x03;                 /* Force size which is multiple of 4 bytes */
 136 
 137   n = dsp_dev->buffsize / bsz;
 138   if (n > MAX_SUB_BUFFERS)
 139     n = MAX_SUB_BUFFERS;
 140   if (n > dmap->max_fragments)
 141     n = dmap->max_fragments;
 142   dmap->nbufs = n;
 143   dmap->bytes_in_use = n * bsz;
 144 
 145   for (i = 0; i < dmap->nbufs; i++)
 146     {
 147       dmap->counts[i] = 0;
 148     }
 149 
 150   dmap->flags |= DMA_ALLOC_DONE;
 151 }
 152 
 153 static void
 154 dma_init_buffers (int dev, struct dma_buffparms *dmap)
     /* [previous][next][first][last][top][bottom][index][help] */
 155 {
 156   if (dmap == audio_devs[dev]->dmap_out)
 157     {
 158       out_sleep_flag[dev].mode = WK_NONE;
 159     }
 160   else
 161     in_sleep_flag[dev].mode = WK_NONE;
 162 
 163   dmap->flags = DMA_BUSY;       /* Other flags off */
 164   dmap->qlen = dmap->qhead = dmap->qtail = 0;
 165   dmap->nbufs = 1;
 166   dmap->bytes_in_use = audio_devs[dev]->buffsize;
 167 
 168   dmap->dma_mode = DMODE_NONE;
 169   dmap->mapping_flags = 0;
 170   dmap->neutral_byte = 0x00;
 171 }
 172 
 173 static int
 174 open_dmap (int dev, int mode, struct dma_buffparms *dmap, int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176   if (dmap->flags & DMA_BUSY)
 177     return -EBUSY;
 178 
 179   {
 180     int             err;
 181 
 182     if ((err = sound_alloc_dmap (dev, dmap, chan)) < 0)
 183       return err;
 184   }
 185 
 186   if (dmap->raw_buf == NULL)
 187     return -ENOSPC;             /* Memory allocation failed during boot */
 188 
 189   if (sound_open_dma (chan, audio_devs[dev]->name))
 190     {
 191       printk ("Unable to grab(2) DMA%d for the audio driver\n", chan);
 192       return -EBUSY;
 193     }
 194 
 195   dmap->open_mode = mode;
 196   dmap->subdivision = dmap->underrun_count = 0;
 197   dmap->fragment_size = 0;
 198   dmap->max_fragments = 65536;  /* Just a large value */
 199   dmap->byte_counter = 0;
 200 
 201   dma_init_buffers (dev, dmap);
 202 
 203   return 0;
 204 }
 205 
 206 static void
 207 close_dmap (int dev, struct dma_buffparms *dmap, int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209   sound_close_dma (chan);
 210 
 211   if (dmap->flags & DMA_BUSY)
 212     dmap->dma_mode = DMODE_NONE;
 213   dmap->flags &= ~DMA_BUSY;
 214 
 215   sound_free_dmap (dev, dmap);
 216 }
 217 
 218 int
 219 DMAbuf_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221   int             retval;
 222   struct dma_buffparms *dmap_in = NULL;
 223   struct dma_buffparms *dmap_out = NULL;
 224 
 225   if (dev >= num_audiodevs)
 226     {
 227       printk ("PCM device %d not installed.\n", dev);
 228       return -ENXIO;
 229     }
 230 
 231   if (!audio_devs[dev])
 232     {
 233       printk ("PCM device %d not initialized\n", dev);
 234       return -ENXIO;
 235     }
 236 
 237   if (!(audio_devs[dev]->flags & DMA_DUPLEX))
 238     {
 239       audio_devs[dev]->dmap_in = audio_devs[dev]->dmap_out;
 240       audio_devs[dev]->dmachan2 = audio_devs[dev]->dmachan1;
 241     }
 242 
 243   if ((retval = audio_devs[dev]->open (dev, mode)) < 0)
 244     return retval;
 245 
 246   dmap_out = audio_devs[dev]->dmap_out;
 247   dmap_in = audio_devs[dev]->dmap_in;
 248 
 249   if ((retval = open_dmap (dev, mode, dmap_out, audio_devs[dev]->dmachan1)) < 0)
 250     {
 251       audio_devs[dev]->close (dev);
 252       return retval;
 253     }
 254 
 255   audio_devs[dev]->enable_bits = mode;
 256   if (audio_devs[dev]->flags & DMA_DUPLEX && dmap_out != dmap_in)
 257     if ((retval = open_dmap (dev, mode, dmap_in, audio_devs[dev]->dmachan2)) < 0)
 258       {
 259         audio_devs[dev]->close (dev);
 260         close_dmap (dev, dmap_out, audio_devs[dev]->dmachan1);
 261         return retval;
 262       }
 263   audio_devs[dev]->open_mode = mode;
 264   audio_devs[dev]->go = 1;
 265 
 266   audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_BITS, (ioctl_arg) 8, 1);
 267   audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_CHANNELS, (ioctl_arg) 1, 1);
 268   audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_RATE, (ioctl_arg) DSP_DEFAULT_SPEED, 1);
 269 
 270   return 0;
 271 }
 272 
 273 static void
 274 dma_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276   unsigned long   flags;
 277 
 278   save_flags (flags);
 279   cli ();
 280   audio_devs[dev]->reset (dev);
 281   restore_flags (flags);
 282 
 283   dma_reset_output (dev);
 284 
 285   if (audio_devs[dev]->flags & DMA_DUPLEX)
 286     dma_reset_input (dev);
 287 }
 288 
 289 static void
 290 dma_reset_output (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 291 {
 292   unsigned long   flags;
 293 
 294   save_flags (flags);
 295   cli ();
 296   if (!(audio_devs[dev]->flags & DMA_DUPLEX) ||
 297       !audio_devs[dev]->halt_output)
 298     audio_devs[dev]->reset (dev);
 299   else
 300     audio_devs[dev]->halt_output (dev);
 301   restore_flags (flags);
 302 
 303   dma_init_buffers (dev, audio_devs[dev]->dmap_out);
 304   reorganize_buffers (dev, audio_devs[dev]->dmap_out);
 305 }
 306 
 307 static void
 308 dma_reset_input (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 309 {
 310   unsigned long   flags;
 311 
 312   save_flags (flags);
 313   cli ();
 314   if (!(audio_devs[dev]->flags & DMA_DUPLEX) ||
 315       !audio_devs[dev]->halt_input)
 316     audio_devs[dev]->reset (dev);
 317   else
 318     audio_devs[dev]->halt_input (dev);
 319   restore_flags (flags);
 320 
 321   dma_init_buffers (dev, audio_devs[dev]->dmap_in);
 322   reorganize_buffers (dev, audio_devs[dev]->dmap_in);
 323 }
 324 
 325 static int
 326 dma_sync (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 327 {
 328   unsigned long   flags;
 329 
 330   if (!audio_devs[dev]->go && (!audio_devs[dev]->enable_bits & PCM_ENABLE_OUTPUT))
 331     return 0;
 332 
 333   if (audio_devs[dev]->dmap_out->dma_mode == DMODE_OUTPUT)
 334     {
 335       save_flags (flags);
 336       cli ();
 337 
 338       while (!(current->signal & ~current->blocked)
 339              && audio_devs[dev]->dmap_out->qlen)
 340         {
 341 
 342           {
 343             unsigned long   tl;
 344 
 345             if (10 * HZ)
 346               current->timeout = tl = jiffies + (10 * HZ);
 347             else
 348               tl = 0xffffffff;
 349             out_sleep_flag[dev].mode = WK_SLEEP;
 350             interruptible_sleep_on (&out_sleeper[dev]);
 351             if (!(out_sleep_flag[dev].mode & WK_WAKEUP))
 352               {
 353                 if (jiffies >= tl)
 354                   out_sleep_flag[dev].mode |= WK_TIMEOUT;
 355               }
 356             out_sleep_flag[dev].mode &= ~WK_SLEEP;
 357           };
 358           if ((out_sleep_flag[dev].mode & WK_TIMEOUT))
 359             {
 360               restore_flags (flags);
 361               return audio_devs[dev]->dmap_out->qlen;
 362             }
 363         }
 364       restore_flags (flags);
 365 
 366       /*
 367        * Some devices such as GUS have huge amount of on board RAM for the
 368        * audio data. We have to wait until the device has finished playing.
 369        */
 370 
 371       save_flags (flags);
 372       cli ();
 373       if (audio_devs[dev]->local_qlen)  /* Device has hidden buffers */
 374         {
 375           while (!((current->signal & ~current->blocked))
 376                  && audio_devs[dev]->local_qlen (dev))
 377             {
 378 
 379               {
 380                 unsigned long   tl;
 381 
 382                 if (HZ)
 383                   current->timeout = tl = jiffies + (HZ);
 384                 else
 385                   tl = 0xffffffff;
 386                 out_sleep_flag[dev].mode = WK_SLEEP;
 387                 interruptible_sleep_on (&out_sleeper[dev]);
 388                 if (!(out_sleep_flag[dev].mode & WK_WAKEUP))
 389                   {
 390                     if (jiffies >= tl)
 391                       out_sleep_flag[dev].mode |= WK_TIMEOUT;
 392                   }
 393                 out_sleep_flag[dev].mode &= ~WK_SLEEP;
 394               };
 395             }
 396         }
 397       restore_flags (flags);
 398     }
 399   return audio_devs[dev]->dmap_out->qlen;
 400 }
 401 
 402 int
 403 DMAbuf_release (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 404 {
 405   unsigned long   flags;
 406 
 407   if (!((current->signal & ~current->blocked))
 408       && (audio_devs[dev]->dmap_out->dma_mode == DMODE_OUTPUT))
 409     {
 410       dma_sync (dev);
 411     }
 412 
 413   save_flags (flags);
 414   cli ();
 415   audio_devs[dev]->reset (dev);
 416 
 417   audio_devs[dev]->close (dev);
 418 
 419   close_dmap (dev, audio_devs[dev]->dmap_out, audio_devs[dev]->dmachan1);
 420 
 421   if (audio_devs[dev]->flags & DMA_DUPLEX)
 422     close_dmap (dev, audio_devs[dev]->dmap_in, audio_devs[dev]->dmachan2);
 423   audio_devs[dev]->open_mode = 0;
 424 
 425   restore_flags (flags);
 426 
 427   return 0;
 428 }
 429 
 430 static int
 431 activate_recording (int dev, struct dma_buffparms *dmap)
     /* [previous][next][first][last][top][bottom][index][help] */
 432 {
 433   if (!(audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT))
 434     return 0;
 435 
 436   if (dmap->flags & DMA_RESTART)
 437     {
 438       dma_reset_input (dev);
 439       dmap->flags &= ~DMA_RESTART;
 440     }
 441 
 442   if (dmap->dma_mode == DMODE_OUTPUT)   /* Direction change */
 443     {
 444       dma_sync (dev);
 445       dma_reset (dev);
 446       dmap->dma_mode = DMODE_NONE;
 447     }
 448 
 449   if (!(dmap->flags & DMA_ALLOC_DONE))
 450     reorganize_buffers (dev, dmap);
 451 
 452   if (!dmap->dma_mode)
 453     {
 454       int             err;
 455 
 456       if ((err = audio_devs[dev]->prepare_for_input (dev,
 457                                      dmap->fragment_size, dmap->nbufs)) < 0)
 458         {
 459           return err;
 460         }
 461       dmap->dma_mode = DMODE_INPUT;
 462     }
 463 
 464   if (!(dmap->flags & DMA_ACTIVE))
 465     {
 466       audio_devs[dev]->start_input (dev, dmap->raw_buf_phys +
 467                                     dmap->qtail * dmap->fragment_size,
 468                                     dmap->fragment_size, 0,
 469                                  !(audio_devs[dev]->flags & DMA_AUTOMODE) ||
 470                                     !(dmap->flags & DMA_STARTED));
 471       dmap->flags |= DMA_ACTIVE | DMA_STARTED;
 472       if (audio_devs[dev]->trigger)
 473         audio_devs[dev]->trigger (dev,
 474                         audio_devs[dev]->enable_bits * audio_devs[dev]->go);
 475     }
 476   return 0;
 477 }
 478 
 479 int
 480 DMAbuf_getrdbuffer (int dev, char **buf, int *len, int dontblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 481 {
 482   unsigned long   flags;
 483   int             err = EIO;
 484   struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
 485 
 486   save_flags (flags);
 487   cli ();
 488   if (!dmap->qlen)
 489     {
 490       int             timeout;
 491 
 492       if ((err = activate_recording (dev, dmap)) < 0)
 493         {
 494           restore_flags (flags);
 495           return err;
 496         }
 497 
 498       /* Wait for the next block */
 499 
 500       if (dontblock)
 501         {
 502           restore_flags (flags);
 503           return -EAGAIN;
 504         }
 505 
 506       if (!(audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT) &
 507           audio_devs[dev]->go)
 508         {
 509           restore_flags (flags);
 510           return -EAGAIN;
 511         }
 512 
 513       if (!audio_devs[dev]->go)
 514         timeout = 0;
 515       else
 516         timeout = 2 * HZ;
 517 
 518 
 519       {
 520         unsigned long   tl;
 521 
 522         if (timeout)
 523           current->timeout = tl = jiffies + (timeout);
 524         else
 525           tl = 0xffffffff;
 526         in_sleep_flag[dev].mode = WK_SLEEP;
 527         interruptible_sleep_on (&in_sleeper[dev]);
 528         if (!(in_sleep_flag[dev].mode & WK_WAKEUP))
 529           {
 530             if (jiffies >= tl)
 531               in_sleep_flag[dev].mode |= WK_TIMEOUT;
 532           }
 533         in_sleep_flag[dev].mode &= ~WK_SLEEP;
 534       };
 535       if ((in_sleep_flag[dev].mode & WK_TIMEOUT))
 536         {
 537           printk ("Sound: DMA (input) timed out - IRQ/DRQ config error?\n");
 538           err = EIO;
 539           ;
 540         }
 541       else
 542         err = EINTR;
 543     }
 544   restore_flags (flags);
 545 
 546   if (!dmap->qlen)
 547     return -err;
 548 
 549   *buf = &dmap->raw_buf[dmap->qhead * dmap->fragment_size + dmap->counts[dmap->qhead]];
 550   *len = dmap->fragment_size - dmap->counts[dmap->qhead];
 551 
 552   return dmap->qhead;
 553 }
 554 
 555 int
 556 DMAbuf_rmchars (int dev, int buff_no, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
 557 {
 558   struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
 559 
 560   int             p = dmap->counts[dmap->qhead] + c;
 561 
 562   if (p >= dmap->fragment_size)
 563     {                           /* This buffer is completely empty */
 564       dmap->counts[dmap->qhead] = 0;
 565       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
 566         printk ("\nSound: Audio queue1 corrupted for dev%d (%d/%d)\n",
 567                 dev, dmap->qlen, dmap->nbufs);
 568       dmap->qlen--;
 569       dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
 570     }
 571   else
 572     dmap->counts[dmap->qhead] = p;
 573 
 574   return 0;
 575 }
 576 
 577 static int
 578 dma_subdivide (int dev, struct dma_buffparms *dmap, ioctl_arg arg, int fact)
     /* [previous][next][first][last][top][bottom][index][help] */
 579 {
 580   if (fact == 0)
 581     {
 582       fact = dmap->subdivision;
 583       if (fact == 0)
 584         fact = 1;
 585       return snd_ioctl_return ((int *) arg, fact);
 586     }
 587 
 588   if (dmap->subdivision != 0 ||
 589       dmap->fragment_size)      /* Loo late to change */
 590     return -EINVAL;
 591 
 592   if (fact > MAX_REALTIME_FACTOR)
 593     return -EINVAL;
 594 
 595   if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
 596     return -EINVAL;
 597 
 598   dmap->subdivision = fact;
 599   return snd_ioctl_return ((int *) arg, fact);
 600 }
 601 
 602 static int
 603 dma_set_fragment (int dev, struct dma_buffparms *dmap, ioctl_arg arg, int fact)
     /* [previous][next][first][last][top][bottom][index][help] */
 604 {
 605   int             bytes, count;
 606 
 607   if (fact == 0)
 608     return -EIO;
 609 
 610   if (dmap->subdivision != 0 ||
 611       dmap->fragment_size)      /* Loo late to change */
 612     return -EINVAL;
 613 
 614   bytes = fact & 0xffff;
 615   count = (fact >> 16) & 0xffff;
 616 
 617   if (count == 0)
 618     count = MAX_SUB_BUFFERS;
 619 
 620   if (bytes < 4 || bytes > 17)  /* <16 || > 128k */
 621     return -EINVAL;
 622 
 623   if (count < 2)
 624     return -EINVAL;
 625 
 626   dmap->fragment_size = (1 << bytes);
 627   dmap->max_fragments = count;
 628 
 629   if (dmap->fragment_size > audio_devs[dev]->buffsize)
 630     dmap->fragment_size = audio_devs[dev]->buffsize;
 631 
 632   if (dmap->fragment_size == audio_devs[dev]->buffsize &&
 633       audio_devs[dev]->flags & DMA_AUTOMODE)
 634     dmap->fragment_size /= 2;   /* Needs at least 2 buffers */
 635 
 636   dmap->subdivision = 1;        /* Disable SNDCTL_DSP_SUBDIVIDE */
 637   return snd_ioctl_return ((int *) arg, bytes | (count << 16));
 638 }
 639 
 640 static int
 641 get_buffer_pointer (int dev, int chan, struct dma_buffparms *dmap)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643   int             pos;
 644   unsigned long   flags;
 645 
 646   save_flags (flags);
 647   cli ();
 648   if (!(dmap->flags & DMA_ACTIVE))
 649     pos = 0;
 650   else
 651     {
 652       clear_dma_ff (chan);
 653       disable_dma (chan);
 654       pos = get_dma_residue (chan);
 655       enable_dma (chan);
 656     }
 657   restore_flags (flags);
 658   /* printk ("%04x ", pos); */
 659 
 660   if (audio_devs[dev]->flags & DMA_AUTOMODE)
 661     return dmap->bytes_in_use - pos;
 662   else
 663     {
 664       pos = dmap->fragment_size - pos;
 665       if (pos < 0)
 666         return 0;
 667       return pos;
 668     }
 669 }
 670 
 671 int
 672 DMAbuf_ioctl (int dev, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 673 {
 674   struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
 675   struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
 676 
 677   switch (cmd)
 678     {
 679     case SNDCTL_DSP_RESET:
 680       dma_reset (dev);
 681       return 0;
 682       break;
 683 
 684     case SNDCTL_DSP_SYNC:
 685       dma_sync (dev);
 686       dma_reset (dev);
 687       return 0;
 688       break;
 689 
 690     case SNDCTL_DSP_GETBLKSIZE:
 691       if (!(dmap_out->flags & DMA_ALLOC_DONE))
 692         reorganize_buffers (dev, dmap_out);
 693 
 694       return snd_ioctl_return ((int *) arg, dmap_out->fragment_size);
 695       break;
 696 
 697     case SNDCTL_DSP_SUBDIVIDE:
 698       {
 699         int             fact = get_fs_long ((long *) arg);
 700         int             ret;
 701 
 702         ret = dma_subdivide (dev, dmap_out, arg, fact);
 703         if (ret < 0)
 704           return ret;
 705 
 706         if (audio_devs[dev]->flags & DMA_DUPLEX)
 707           ret = dma_subdivide (dev, dmap_in, arg, fact);
 708 
 709         return ret;
 710       }
 711       break;
 712 
 713     case SNDCTL_DSP_SETFRAGMENT:
 714       {
 715         int             fact = get_fs_long ((long *) arg);
 716         int             ret;
 717 
 718         ret = dma_set_fragment (dev, dmap_out, arg, fact);
 719         if (ret < 0)
 720           return ret;
 721 
 722         if (audio_devs[dev]->flags & DMA_DUPLEX)
 723           ret = dma_set_fragment (dev, dmap_in, arg, fact);
 724 
 725         return ret;
 726       }
 727       break;
 728 
 729     case SNDCTL_DSP_GETISPACE:
 730     case SNDCTL_DSP_GETOSPACE:
 731       if (!local)
 732         return -EINVAL;
 733       else
 734         {
 735           struct dma_buffparms *dmap = dmap_out;
 736 
 737           audio_buf_info *info = (audio_buf_info *) arg;
 738 
 739           if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
 740             dmap = dmap_in;
 741 
 742 
 743           if (!(dmap->flags & DMA_ALLOC_DONE))
 744             reorganize_buffers (dev, dmap);
 745 
 746           info->fragstotal = dmap->nbufs;
 747 
 748           if (cmd == SNDCTL_DSP_GETISPACE)
 749             info->fragments = dmap->qlen;
 750           else
 751             {
 752               if (!space_in_queue (dev))
 753                 info->fragments = 0;
 754               else
 755                 {
 756                   info->fragments = dmap->nbufs - dmap->qlen;
 757                   if (audio_devs[dev]->local_qlen)
 758                     {
 759                       int             tmp = audio_devs[dev]->local_qlen (dev);
 760 
 761                       if (tmp & info->fragments)
 762                         tmp--;  /*
 763                                    * This buffer has been counted twice
 764                                  */
 765                       info->fragments -= tmp;
 766                     }
 767                 }
 768             }
 769 
 770           if (info->fragments < 0)
 771             info->fragments = 0;
 772           else if (info->fragments > dmap->nbufs)
 773             info->fragments = dmap->nbufs;
 774 
 775           info->fragsize = dmap->fragment_size;
 776           info->bytes = info->fragments * dmap->fragment_size;
 777 
 778           if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
 779             info->bytes -= dmap->counts[dmap->qhead];
 780         }
 781       return 0;
 782 
 783     case SNDCTL_DSP_SETTRIGGER:
 784       {
 785         unsigned long   flags;
 786 
 787         int             bits = get_fs_long ((long *) arg) & audio_devs[dev]->open_mode;
 788         int             changed;
 789 
 790         if (audio_devs[dev]->trigger == NULL)
 791           return -EINVAL;
 792 
 793         if (!(audio_devs[dev]->flags & DMA_DUPLEX))
 794           if ((bits & PCM_ENABLE_INPUT) && (bits & PCM_ENABLE_OUTPUT))
 795             {
 796               printk ("Sound: Device doesn't have full duplex capability\n");
 797               return -EINVAL;
 798             }
 799 
 800         save_flags (flags);
 801         cli ();
 802         changed = audio_devs[dev]->enable_bits ^ bits;
 803 
 804         if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go)
 805           {
 806             if (!(dmap_in->flags & DMA_ALLOC_DONE))
 807               reorganize_buffers (dev, dmap_in);
 808 
 809             activate_recording (dev, dmap_in);
 810           }
 811 
 812 
 813         audio_devs[dev]->enable_bits = bits;
 814         if (changed && audio_devs[dev]->trigger)
 815           audio_devs[dev]->trigger (dev, bits * audio_devs[dev]->go);
 816         restore_flags (flags);
 817       }
 818     case SNDCTL_DSP_GETTRIGGER:
 819       return snd_ioctl_return ((int *) arg, audio_devs[dev]->enable_bits);
 820       break;
 821 
 822     case SNDCTL_DSP_GETIPTR:
 823       {
 824         count_info      info;
 825         unsigned long   flags;
 826 
 827         save_flags (flags);
 828         cli ();
 829         info.bytes = audio_devs[dev]->dmap_in->byte_counter;
 830         info.ptr = get_buffer_pointer (dev, audio_devs[dev]->dmachan2, audio_devs[dev]->dmap_in);
 831         info.blocks = audio_devs[dev]->dmap_in->qlen;
 832         info.bytes += info.ptr;
 833         memcpy_tofs ((&((char *) arg)[0]), (char *) &info, sizeof (info));
 834 
 835         restore_flags (flags);
 836         return 0;
 837       }
 838       break;
 839 
 840     case SNDCTL_DSP_GETOPTR:
 841       {
 842         count_info      info;
 843         unsigned long   flags;
 844 
 845         save_flags (flags);
 846         cli ();
 847         info.bytes = audio_devs[dev]->dmap_out->byte_counter;
 848         info.ptr = get_buffer_pointer (dev, audio_devs[dev]->dmachan1, audio_devs[dev]->dmap_out);
 849         info.blocks = audio_devs[dev]->dmap_out->qlen;
 850         info.bytes += info.ptr;
 851         memcpy_tofs ((&((char *) arg)[0]), (char *) &info, sizeof (info));
 852 
 853         restore_flags (flags);
 854         return 0;
 855       }
 856       break;
 857 
 858 
 859     default:
 860       return audio_devs[dev]->ioctl (dev, cmd, arg, local);
 861     }
 862 
 863 }
 864 
 865 /*
 866  * DMAbuf_start_devices() is called by the /dev/music driver to start
 867  * one or more audio devices at desired moment.
 868  */
 869 
 870 void
 871 DMAbuf_start_devices (unsigned int devmask)
     /* [previous][next][first][last][top][bottom][index][help] */
 872 {
 873   int             dev;
 874 
 875   for (dev = 0; dev < num_audiodevs; dev++)
 876     if (devmask & (1 << dev))
 877       if (audio_devs[dev]->open_mode != 0)
 878         if (!audio_devs[dev]->go)
 879           {
 880             /* OK to start the device */
 881             audio_devs[dev]->go = 1;
 882           }
 883 }
 884 
 885 static int
 886 space_in_queue (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 887 {
 888   int             len, max, tmp;
 889   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 890 
 891   if (dmap->qlen >= dmap->nbufs)        /* No space at all */
 892     return 0;
 893 
 894   /*
 895      * Verify that there are no more pending buffers than the limit
 896      * defined by the process.
 897    */
 898 
 899   max = dmap->max_fragments;
 900   len = dmap->qlen;
 901 
 902   if (audio_devs[dev]->local_qlen)
 903     {
 904       tmp = audio_devs[dev]->local_qlen (dev);
 905       if (tmp & len)
 906         tmp--;                  /*
 907                                    * This buffer has been counted twice
 908                                  */
 909       len += tmp;
 910     }
 911 
 912   if (len >= max)
 913     return 0;
 914   return 1;
 915 }
 916 
 917 int
 918 DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 919 {
 920   unsigned long   flags;
 921   int             abort, err = EIO;
 922   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 923 
 924 
 925   if (dmap->dma_mode == DMODE_INPUT)    /* Direction change */
 926     {
 927       dma_reset (dev);
 928       dmap->dma_mode = DMODE_NONE;
 929     }
 930   else if (dmap->flags & DMA_RESTART)   /* Restart buffering */
 931     {
 932       dma_sync (dev);
 933       dma_reset_output (dev);
 934     }
 935 
 936   dmap->flags &= ~DMA_RESTART;
 937 
 938   if (!(dmap->flags & DMA_ALLOC_DONE))
 939     reorganize_buffers (dev, dmap);
 940 
 941   if (!dmap->dma_mode)
 942     {
 943       int             err;
 944 
 945       dmap->dma_mode = DMODE_OUTPUT;
 946       if ((err = audio_devs[dev]->prepare_for_output (dev,
 947                                      dmap->fragment_size, dmap->nbufs)) < 0)
 948         return err;
 949     }
 950 
 951   save_flags (flags);
 952   cli ();
 953 
 954   abort = 0;
 955   while (!space_in_queue (dev) &&
 956          !abort)
 957     {
 958       int             timeout;
 959 
 960       if (dontblock)
 961         {
 962           restore_flags (flags);
 963           return -EAGAIN;
 964         }
 965 
 966       if (!(audio_devs[dev]->enable_bits & PCM_ENABLE_OUTPUT) &&
 967           audio_devs[dev]->go)
 968         {
 969           restore_flags (flags);
 970           return -EAGAIN;
 971         }
 972 
 973       /*
 974        * Wait for free space
 975        */
 976       if (!audio_devs[dev]->go)
 977         timeout = 0;
 978       else
 979         timeout = 2 * HZ;
 980 
 981 
 982       {
 983         unsigned long   tl;
 984 
 985         if (timeout)
 986           current->timeout = tl = jiffies + (timeout);
 987         else
 988           tl = 0xffffffff;
 989         out_sleep_flag[dev].mode = WK_SLEEP;
 990         interruptible_sleep_on (&out_sleeper[dev]);
 991         if (!(out_sleep_flag[dev].mode & WK_WAKEUP))
 992           {
 993             if (jiffies >= tl)
 994               out_sleep_flag[dev].mode |= WK_TIMEOUT;
 995           }
 996         out_sleep_flag[dev].mode &= ~WK_SLEEP;
 997       };
 998       if ((out_sleep_flag[dev].mode & WK_TIMEOUT))
 999         {
1000           printk ("Sound: DMA (output) timed out - IRQ/DRQ config error?\n");
1001           err = EIO;
1002           abort = 1;
1003           ;
1004         }
1005       else if ((current->signal & ~current->blocked))
1006         {
1007           err = EINTR;
1008           abort = 1;
1009         }
1010     }
1011   restore_flags (flags);
1012 
1013   if (!space_in_queue (dev))
1014     {
1015       return -err;              /* Caught a signal ? */
1016     }
1017 
1018   *buf = dmap->raw_buf + dmap->qtail * dmap->fragment_size;
1019   *size = dmap->fragment_size;
1020   dmap->counts[dmap->qtail] = 0;
1021 
1022   return dmap->qtail;
1023 }
1024 
1025 int
1026 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
1027 {
1028   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
1029 
1030 /*
1031  * Bypass buffering if using mmaped access
1032  */
1033 
1034   if (dmap != NULL)
1035     {
1036 
1037       if (buff_no != dmap->qtail)
1038         printk ("Sound warning: DMA buffers out of sync %d != %d\n", buff_no, dmap->qtail);
1039 
1040       dmap->qlen++;
1041       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
1042         printk ("\nSound: Audio queue2 corrupted for dev%d (%d/%d)\n",
1043                 dev, dmap->qlen, dmap->nbufs);
1044 
1045       dmap->counts[dmap->qtail] = l;
1046 
1047       if ((l != dmap->fragment_size) &&
1048           ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
1049            audio_devs[dev]->flags & NEEDS_RESTART))
1050         dmap->flags |= DMA_RESTART;
1051       else
1052         dmap->flags &= ~DMA_RESTART;
1053 
1054       dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
1055     }
1056 
1057   if (!(dmap->flags & DMA_ACTIVE))
1058     {
1059       dmap->flags |= DMA_ACTIVE;
1060       audio_devs[dev]->output_block (dev, dmap->raw_buf_phys +
1061                                      dmap->qhead * dmap->fragment_size,
1062                                      dmap->counts[dmap->qhead], 0,
1063                                  !(audio_devs[dev]->flags & DMA_AUTOMODE) ||
1064                                      !(dmap->flags & DMA_STARTED));
1065       dmap->flags |= DMA_STARTED;
1066       if (audio_devs[dev]->trigger)
1067         audio_devs[dev]->trigger (dev,
1068                         audio_devs[dev]->enable_bits * audio_devs[dev]->go);
1069     }
1070 
1071   return 0;
1072 }
1073 
1074 int
1075 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1076 {
1077   int             chan;
1078   struct dma_buffparms *dmap;
1079   unsigned long   flags;
1080 
1081   if (dma_mode == DMA_MODE_WRITE)
1082     {
1083       chan = audio_devs[dev]->dmachan1;
1084       dmap = audio_devs[dev]->dmap_out;
1085     }
1086   else
1087     {
1088       chan = audio_devs[dev]->dmachan2;
1089       dmap = audio_devs[dev]->dmap_in;
1090     }
1091 
1092   /*
1093    * The count must be one less than the actual size. This is handled by
1094    * set_dma_addr()
1095    */
1096 
1097   if (audio_devs[dev]->flags & DMA_AUTOMODE)
1098     {                           /*
1099                                  * Auto restart mode. Transfer the whole *
1100                                  * buffer
1101                                  */
1102       save_flags (flags);
1103       cli ();
1104       disable_dma (chan);
1105       clear_dma_ff (chan);
1106       set_dma_mode (chan, dma_mode | DMA_AUTOINIT);
1107       set_dma_addr (chan, dmap->raw_buf_phys);
1108       set_dma_count (chan, dmap->bytes_in_use);
1109       enable_dma (chan);
1110       restore_flags (flags);
1111     }
1112   else
1113     {
1114       save_flags (flags);
1115       cli ();
1116       disable_dma (chan);
1117       clear_dma_ff (chan);
1118       set_dma_mode (chan, dma_mode);
1119       set_dma_addr (chan, physaddr);
1120       set_dma_count (chan, count);
1121       enable_dma (chan);
1122       restore_flags (flags);
1123     }
1124 
1125   return count;
1126 }
1127 
1128 long
1129 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1130 {
1131   int             dev;
1132 
1133 
1134   /*
1135      * NOTE! This routine could be called several times.
1136    */
1137 
1138   for (dev = 0; dev < num_audiodevs; dev++)
1139     if (audio_devs[dev]->dmap_out == NULL)
1140       {
1141         audio_devs[dev]->dmap_out =
1142           audio_devs[dev]->dmap_in =
1143           &dmaps[ndmaps++];
1144 
1145         if (audio_devs[dev]->flags & DMA_DUPLEX)
1146           audio_devs[dev]->dmap_in =
1147             &dmaps[ndmaps++];
1148       }
1149   return mem_start;
1150 }
1151 
1152 void
1153 DMAbuf_outputintr (int dev, int event_type)
     /* [previous][next][first][last][top][bottom][index][help] */
1154 {
1155   /*
1156      * Event types:
1157      *  0 = DMA transfer done. Device still has more data in the local
1158      *      buffer.
1159      *  1 = DMA transfer done. Device doesn't have local buffer or it's
1160      *      empty now.
1161      *  2 = No DMA transfer but the device has now more space in it's local
1162      *      buffer.
1163    */
1164 
1165   unsigned long   flags;
1166   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
1167 
1168   dmap->byte_counter += dmap->counts[dmap->qhead];
1169 
1170 #ifdef OS_DMA_INTR
1171   sound_dma_intr (dev, audio_devs[dev]->dmap_out, audio_devs[dev]->dmachan1);
1172 #endif
1173 
1174   if (event_type != 2)
1175     {
1176       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
1177         {
1178           printk ("\nSound: Audio queue3 corrupted for dev%d (%d/%d)\n",
1179                   dev, dmap->qlen, dmap->nbufs);
1180           return;
1181         }
1182 
1183       dmap->qlen--;
1184       dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
1185       dmap->flags &= ~DMA_ACTIVE;
1186 
1187       if (dmap->qlen)
1188         {
1189           if (!(audio_devs[dev]->flags & DMA_AUTOMODE))
1190             {
1191               audio_devs[dev]->output_block (dev, dmap->raw_buf_phys +
1192                                           dmap->qhead * dmap->fragment_size,
1193                                              dmap->counts[dmap->qhead], 1,
1194                                   !(audio_devs[dev]->flags & DMA_AUTOMODE));
1195               if (audio_devs[dev]->trigger)
1196                 audio_devs[dev]->trigger (dev,
1197                         audio_devs[dev]->enable_bits * audio_devs[dev]->go);
1198             }
1199           dmap->flags |= DMA_ACTIVE;
1200         }
1201       else if (event_type == 1)
1202         {
1203           dmap->underrun_count++;
1204           if ((audio_devs[dev]->flags & DMA_DUPLEX) &&
1205               audio_devs[dev]->halt_output)
1206             audio_devs[dev]->halt_output (dev);
1207           else
1208             audio_devs[dev]->halt_xfer (dev);
1209 
1210           if ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
1211               audio_devs[dev]->flags & NEEDS_RESTART)
1212             dmap->flags |= DMA_RESTART;
1213           else
1214             dmap->flags &= ~DMA_RESTART;
1215         }
1216     }                           /* event_type != 2 */
1217 
1218   save_flags (flags);
1219   cli ();
1220   if ((out_sleep_flag[dev].mode & WK_SLEEP))
1221     {
1222       {
1223         out_sleep_flag[dev].mode = WK_WAKEUP;
1224         wake_up (&out_sleeper[dev]);
1225       };
1226     }
1227   restore_flags (flags);
1228 }
1229 
1230 void
1231 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1232 {
1233   unsigned long   flags;
1234   struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
1235 
1236   dmap->byte_counter += dmap->fragment_size;
1237 
1238 #ifdef OS_DMA_INTR
1239   sound_dma_intr (dev, audio_devs[dev]->dmap_in, audio_devs[dev]->dmachan2);
1240 #endif
1241 
1242   if (dmap->qlen == (dmap->nbufs - 1))
1243     {
1244       printk ("Sound: Recording overrun\n");
1245       dmap->underrun_count++;
1246       if ((audio_devs[dev]->flags & DMA_DUPLEX) &&
1247           audio_devs[dev]->halt_input)
1248         audio_devs[dev]->halt_input (dev);
1249       else
1250         audio_devs[dev]->halt_xfer (dev);
1251 
1252       dmap->flags &= ~DMA_ACTIVE;
1253       if (audio_devs[dev]->flags & DMA_AUTOMODE)
1254         dmap->flags |= DMA_RESTART;
1255       else
1256         dmap->flags &= ~DMA_RESTART;
1257     }
1258   else
1259     {
1260       dmap->qlen++;
1261       if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
1262         printk ("\nSound: Audio queue4 corrupted for dev%d (%d/%d)\n",
1263                 dev, dmap->qlen, dmap->nbufs);
1264       dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
1265 
1266       if (!(audio_devs[dev]->flags & DMA_AUTOMODE))
1267         {
1268           audio_devs[dev]->start_input (dev, dmap->raw_buf_phys +
1269                                         dmap->qtail * dmap->fragment_size,
1270                                         dmap->fragment_size, 1,
1271                                   !(audio_devs[dev]->flags & DMA_AUTOMODE));
1272           if (audio_devs[dev]->trigger)
1273             audio_devs[dev]->trigger (dev,
1274                         audio_devs[dev]->enable_bits * audio_devs[dev]->go);
1275         }
1276 
1277       dmap->flags |= DMA_ACTIVE;
1278     }
1279 
1280   save_flags (flags);
1281   cli ();
1282   if ((in_sleep_flag[dev].mode & WK_SLEEP))
1283     {
1284       {
1285         in_sleep_flag[dev].mode = WK_WAKEUP;
1286         wake_up (&in_sleeper[dev]);
1287       };
1288     }
1289   restore_flags (flags);
1290 }
1291 
1292 int
1293 DMAbuf_open_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1294 {
1295   int             chan = audio_devs[dev]->dmachan1;
1296   int             err;
1297   unsigned long   flags;
1298 
1299   if ((err = open_dmap (dev, OPEN_READWRITE, audio_devs[dev]->dmap_out, audio_devs[dev]->dmachan1)) < 0)
1300     {
1301       return -EBUSY;
1302     }
1303   dma_init_buffers (dev, audio_devs[dev]->dmap_out);
1304   audio_devs[dev]->dmap_out->flags |= DMA_ALLOC_DONE;
1305   audio_devs[dev]->dmap_out->fragment_size = audio_devs[dev]->buffsize;
1306   /* reorganize_buffers (dev, audio_devs[dev]->dmap_out); */
1307 
1308   if (audio_devs[dev]->flags & DMA_DUPLEX)
1309     {
1310       if ((err = open_dmap (dev, OPEN_READWRITE, audio_devs[dev]->dmap_in, audio_devs[dev]->dmachan2)) < 0)
1311         {
1312           printk ("Unable to grab DMA%d for the audio driver\n",
1313                   audio_devs[dev]->dmachan2);
1314           close_dmap (dev, audio_devs[dev]->dmap_out, audio_devs[dev]->dmachan1);
1315           return -EBUSY;
1316         }
1317       dma_init_buffers (dev, audio_devs[dev]->dmap_in);
1318       audio_devs[dev]->dmap_in->flags |= DMA_ALLOC_DONE;
1319       audio_devs[dev]->dmap_in->fragment_size = audio_devs[dev]->buffsize;
1320       /* reorganize_buffers (dev, audio_devs[dev]->dmap_in); */
1321     }
1322   else
1323     {
1324       audio_devs[dev]->dmap_in = audio_devs[dev]->dmap_out;
1325       audio_devs[dev]->dmachan2 = audio_devs[dev]->dmachan1;
1326     }
1327 
1328 
1329   save_flags (flags);
1330   cli ();
1331   disable_dma (chan);
1332   clear_dma_ff (chan);
1333   restore_flags (flags);
1334 
1335   return 0;
1336 }
1337 
1338 void
1339 DMAbuf_close_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1340 {
1341   DMAbuf_reset_dma (dev);
1342   close_dmap (dev, audio_devs[dev]->dmap_out, audio_devs[dev]->dmachan1);
1343 
1344   if (audio_devs[dev]->flags & DMA_DUPLEX)
1345     close_dmap (dev, audio_devs[dev]->dmap_in, audio_devs[dev]->dmachan2);
1346 
1347 }
1348 
1349 void
1350 DMAbuf_reset_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1351 {
1352 }
1353 
1354 int
1355 DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1356 {
1357   struct dma_buffparms *dmap;
1358   unsigned long   flags;
1359 
1360   switch (sel_type)
1361     {
1362     case SEL_IN:
1363       dmap = audio_devs[dev]->dmap_in;
1364 
1365 
1366       if (dmap->dma_mode != DMODE_INPUT)
1367         {
1368           if ((audio_devs[dev]->flags & DMA_DUPLEX) && !dmap->qlen &&
1369               audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
1370               audio_devs[dev]->go)
1371             {
1372               unsigned long   flags;
1373 
1374               save_flags (flags);
1375               cli ();
1376               activate_recording (dev, dmap);
1377               restore_flags (flags);
1378             }
1379           return 0;
1380         }
1381 
1382       if (!dmap->qlen)
1383         {
1384           save_flags (flags);
1385           cli ();
1386           in_sleep_flag[dev].mode = WK_SLEEP;
1387           select_wait (&in_sleeper[dev], wait);
1388           restore_flags (flags);
1389           return 0;
1390         }
1391       return 1;
1392       break;
1393 
1394     case SEL_OUT:
1395       dmap = audio_devs[dev]->dmap_out;
1396 
1397 
1398       if (dmap->dma_mode == DMODE_INPUT)
1399         {
1400           return 0;
1401         }
1402 
1403       if (dmap->dma_mode == DMODE_NONE)
1404         {
1405           return 1;
1406         }
1407 
1408       if (!space_in_queue (dev))
1409         {
1410           save_flags (flags);
1411           cli ();
1412           out_sleep_flag[dev].mode = WK_SLEEP;
1413           select_wait (&out_sleeper[dev], wait);
1414           restore_flags (flags);
1415           return 0;
1416         }
1417       return 1;
1418       break;
1419 
1420     case SEL_EX:
1421       return 0;
1422     }
1423 
1424   return 0;
1425 }
1426 
1427 
1428 #else /* EXCLUDE_AUDIO */
1429 /*
1430  * Stub versions if audio services not included
1431  */
1432 
1433 int
1434 DMAbuf_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1435 {
1436   return -ENXIO;
1437 }
1438 
1439 int
1440 DMAbuf_release (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1441 {
1442   return 0;
1443 }
1444 
1445 int
1446 DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1447 {
1448   return -EIO;
1449 }
1450 
1451 int
1452 DMAbuf_getrdbuffer (int dev, char **buf, int *len, int dontblock)
     /* [previous][next][first][last][top][bottom][index][help] */
1453 {
1454   return -EIO;
1455 }
1456 
1457 int
1458 DMAbuf_rmchars (int dev, int buff_no, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
1459 {
1460   return -EIO;
1461 }
1462 
1463 int
1464 DMAbuf_start_output (int dev, int buff_no, int l)
     /* [previous][next][first][last][top][bottom][index][help] */
1465 {
1466   return -EIO;
1467 }
1468 
1469 int
1470 DMAbuf_ioctl (int dev, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
1471 {
1472   return -EIO;
1473 }
1474 
1475 long
1476 DMAbuf_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1477 {
1478   return mem_start;
1479 }
1480 
1481 int
1482 DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1483 {
1484   return -EIO;
1485 }
1486 
1487 int
1488 DMAbuf_open_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1489 {
1490   return -ENXIO;
1491 }
1492 
1493 void
1494 DMAbuf_close_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1495 {
1496   return;
1497 }
1498 
1499 void
1500 DMAbuf_reset_dma (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1501 {
1502   return;
1503 }
1504 
1505 void
1506 DMAbuf_inputintr (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1507 {
1508   return;
1509 }
1510 
1511 void
1512 DMAbuf_outputintr (int dev, int underrun_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
1513 {
1514   return;
1515 }
1516 #endif
1517 
1518 #endif

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