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