diff options
Diffstat (limited to 'sys/i386/isa/sound/soundcard.c')
-rw-r--r-- | sys/i386/isa/sound/soundcard.c | 773 |
1 files changed, 488 insertions, 285 deletions
diff --git a/sys/i386/isa/sound/soundcard.c b/sys/i386/isa/sound/soundcard.c index b9e6ee5f1b70..a83df9377eba 100644 --- a/sys/i386/isa/sound/soundcard.c +++ b/sys/i386/isa/sound/soundcard.c @@ -4,398 +4,601 @@ * Soundcard driver for 386BSD. * * Copyright by Hannu Savolainen 1993 - * + * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * */ -#include "sound_config.h" +#include <i386/isa/sound/sound_config.h> -#ifdef CONFIGURE_SOUNDCARD +#if NSND > 0 /* from "snd.h" */ +#include <vm/vm.h> +#include <vm/vm_kern.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> +#include <vm/vm_extern.h> +#include <sys/mman.h> -#include "dev_table.h" +#include <i386/isa/sound/dev_table.h> +#include <i386/isa/isa_device.h> +#include <i386/isa/isa.h> -u_int snd1mask; -u_int snd2mask; -u_int snd3mask; -u_int snd4mask; -u_int snd5mask; -u_int snd6mask; -u_int snd7mask; -u_int snd8mask; -u_int snd9mask; -#define FIX_RETURN(ret) {if ((ret)<0) return -(ret); else return 0;} +/* +** Register definitions for DMA controller 1 (channels 0..3): +*/ +#define DMA1_CHN(c) (IO_DMA1 + 1*(2*(c))) /* addr reg for channel c */ +#define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */ +#define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */ +#define DMA1_FFC (IO_DMA1 + 1*12) /* clear first/last FF */ -static int timer_running = 0; +/* +** Register definitions for DMA controller 2 (channels 4..7): +*/ +#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */ +#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */ +#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ +#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ + + +#define FIX_RETURN(ret) {if ((ret)<0) return -(ret); else return 0;} -static int soundcards_installed = 0; /* Number of installed - * soundcards */ +static int soundcards_installed = 0; /* Number of installed soundcards */ static int soundcard_configured = 0; static struct fileinfo files[SND_NDEVS]; +struct selinfo selinfo[SND_NDEVS >> 4]; + +int +MIDIbuf_poll (int dev, struct fileinfo *file, int events, select_table * wait); + +int +audio_poll(int dev, struct fileinfo * file, int events, select_table * wait); + +int +sequencer_poll (int dev, struct fileinfo *file, int events, select_table * wait); + +void sndintr __P((int unit)); +int sndprobe __P((struct isa_device *)); +int sndattach __P((struct isa_device *)); +int sndmmap __P((dev_t dev, int offset, int nprot )); + +static d_open_t sndopen; +static d_close_t sndclose; +static d_ioctl_t sndioctl; +static d_read_t sndread; +static d_write_t sndwrite; +static d_poll_t sndpoll; + +static char driver_name[] = "snd"; + +#define CDEV_MAJOR 30 +static struct cdevsw snd_cdevsw = { + sndopen, sndclose, sndread, sndwrite, + sndioctl, nxstop, nxreset, nxdevtotty, + sndpoll, sndmmap, nxstrategy, driver_name, + NULL, -1, +}; + + + + +static void sound_mem_init(void); + +/* + * for each "device XXX" entry in the config file, we have + * a struct isa_driver which is linked into isa_devtab_null[] + * + * XXX It is a bit stupid to call the generic routine so many times and + * switch then to the specific one, but the alternative way would be + * to replicate some code in the probe/attach routines. + */ -int sndprobe (struct isa_device *dev); -int sndattach (struct isa_device *dev); -int sndopen (dev_t dev, int flags); -int sndclose (dev_t dev, int flags); -int sndioctl (dev_t dev, int cmd, caddr_t arg, int mode); -int sndread (int dev, struct uio *uio); -int sndwrite (int dev, struct uio *uio); -int sndselect (int dev, int rw); -static void sound_mem_init(void); - -unsigned long +struct isa_driver opldriver = {sndprobe, sndattach, "opl"}; +struct isa_driver trixdriver = {sndprobe, sndattach, "trix"}; +struct isa_driver trixsbdriver = {sndprobe, sndattach, "trixsb"}; +struct isa_driver sbdriver = {sndprobe, sndattach, "sb"}; +struct isa_driver sbxvidriver = {sndprobe, sndattach, "sbxvi"}; +struct isa_driver sbmididriver = {sndprobe, sndattach, "sbmidi"}; +struct isa_driver awedriver = {sndprobe, sndattach, "awe"}; +struct isa_driver pasdriver = {sndprobe, sndattach, "pas"}; +struct isa_driver mpudriver = {sndprobe, sndattach, "mpu"}; +struct isa_driver gusdriver = {sndprobe, sndattach, "gus"}; +struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"}; +struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"}; +struct isa_driver uartdriver = {sndprobe, sndattach, "uart"}; +struct isa_driver mssdriver = {sndprobe, sndattach, "mss"}; +struct isa_driver sscapedriver = {sndprobe, sndattach, "sscape"}; +struct isa_driver sscape_mssdriver = {sndprobe, sndattach, "sscape_mss"}; + +short ipri_to_irq(u_short ipri); + +u_long get_time(void) { - extern struct timeval time; - struct timeval timecopy; - int x; - - x = splclock(); - timecopy = time; - splx(x); - return timecopy.tv_usec/(1000000/HZ) + - (unsigned long)timecopy.tv_sec*HZ; + struct timeval timecopy; + int x; + + x = splclock(); + timecopy = time; + splx(x); + return timecopy.tv_usec / (1000000 / hz) + + (u_long) timecopy.tv_sec * hz; } int -sndread (int dev, struct uio *buf) +sndmmap( dev_t dev, int offset, int nprot ) { - int count = buf->uio_resid; + int unit; + struct dma_buffparms * dmap; + + dev = minor(dev) >> 4; + if (dev > 0 ) return (-1); - dev = minor (dev); + dmap = audio_devs[dev]->dmap_out; - FIX_RETURN (sound_read_sw (dev, &files[dev], buf, count)); + if (nprot & PROT_EXEC) + return( -1 ); + dmap->mapping_flags |= DMA_MAP_MAPPED ; + return( i386_btop(vtophys(dmap->raw_buf) + offset) ); } -int -sndwrite (int dev, struct uio *buf) -{ - int count = buf->uio_resid; - dev = minor (dev); +static int +sndread(dev_t dev, struct uio * buf, int flag) +{ + int count = buf->uio_resid; - FIX_RETURN (sound_write_sw (dev, &files[dev], buf, count)); + dev = minor(dev); + FIX_RETURN(sound_read_sw(dev, &files[dev], buf, count)); } -int -sndopen (dev_t dev, int flags) + +static int +sndwrite(dev_t dev, struct uio * buf, int flag) { - int retval; + int count = buf->uio_resid; - dev = minor (dev); + dev = minor(dev); + FIX_RETURN(sound_write_sw(dev, &files[dev], buf, count)); +} - if (!soundcard_configured && dev) - { - printk ("SoundCard Error: The soundcard system has not been configured\n"); - FIX_RETURN (-ENODEV); +static int +sndopen(dev_t dev, int flags, int mode, struct proc * p) +{ + int retval; + struct fileinfo tmp_file; + + dev = minor(dev); + if (!soundcard_configured && dev) { + printf("SoundCard Error: soundcard system has not been configured\n"); + return ENODEV ; } + tmp_file.mode = 0; + + if (flags & FREAD && flags & FWRITE) + tmp_file.mode = OPEN_READWRITE; + else if (flags & FREAD) + tmp_file.mode = OPEN_READ; + else if (flags & FWRITE) + tmp_file.mode = OPEN_WRITE; - files[dev].mode = 0; + selinfo[dev >> 4].si_pid = 0; + selinfo[dev >> 4].si_flags = 0; + if ((retval = sound_open_sw(dev, &tmp_file)) < 0) + FIX_RETURN(retval); - if (flags & FREAD && flags & FWRITE) - files[dev].mode = OPEN_READWRITE; - else if (flags & FREAD) - files[dev].mode = OPEN_READ; - else if (flags & FWRITE) - files[dev].mode = OPEN_WRITE; + bcopy((char *) &tmp_file, (char *) &files[dev], sizeof(tmp_file)); - FIX_RETURN(sound_open_sw (dev, &files[dev])); + FIX_RETURN(retval); } -int -sndclose (dev_t dev, int flags) + +static int +sndclose(dev_t dev, int flags, int mode, struct proc * p) { + dev = minor(dev); + sound_release_sw(dev, &files[dev]); - dev = minor (dev); + return 0 ; +} - sound_release_sw(dev, &files[dev]); - FIX_RETURN (0); +static int +sndioctl(dev_t dev, int cmd, caddr_t arg, int mode, struct proc * p) +{ + dev = minor(dev); + FIX_RETURN(sound_ioctl_sw(dev, &files[dev], cmd, arg)); } int -sndioctl (dev_t dev, int cmd, caddr_t arg, int mode) +sndpoll(dev_t dev, int events, struct proc * p) { - dev = minor (dev); + dev = minor(dev); + dev = minor(dev); + + /* printf ("snd_select(dev=%d, rw=%d, pid=%d)\n", dev, rw, p->p_pid); */ +#ifdef ALLOW_POLL + switch (dev & 0x0f) { +#ifdef CONFIG_SEQUENCER + case SND_DEV_SEQ: + case SND_DEV_SEQ2: + return sequencer_poll(dev, &files[dev], events, p); + break; +#endif + +#ifdef CONFIG_MIDI + case SND_DEV_MIDIN: + return MIDIbuf_poll(dev, &files[dev], events, p); + break; +#endif + +#ifdef CONFIG_AUDIO + case SND_DEV_DSP: + case SND_DEV_DSP16: + case SND_DEV_AUDIO: + + return audio_poll(dev, &files[dev], events, p); + break; +#endif - FIX_RETURN (sound_ioctl_sw (dev, &files[dev], cmd, (unsigned int) arg)); + default: + return 0; + } + +#endif /* ALLOW_POLL */ + DEB(printf("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg)); + + return 0 ; } -int -sndselect (int dev, int rw) +/* XXX this should become ffs(ipri), perhaps -1 lr 970705 */ +short +ipri_to_irq(u_short ipri) { - dev = minor (dev); + /* + * Converts the ipri (bitmask) to the corresponding irq number + */ + int irq; - DEB (printk ("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg)); + for (irq = 0; irq < 16; irq++) + if (ipri == (1 << irq)) + return irq; - FIX_RETURN (0); + return -1; /* Invalid argument */ } -static short -ipri_to_irq (unsigned short ipri) +static int +driver_to_voxunit(struct isa_driver * driver) { - /* - * Converts the ipri (bitmask) to the corresponding irq number - */ - int irq; + /* + * converts a sound driver pointer into the equivalent VoxWare device + * unit number + */ + if (driver == &opldriver) + return (SNDCARD_ADLIB); + else if (driver == &sbdriver) + return (SNDCARD_SB); + else if (driver == &pasdriver) + return (SNDCARD_PAS); + else if (driver == &gusdriver) + return (SNDCARD_GUS); + else if (driver == &mpudriver) + return (SNDCARD_MPU401); + else if (driver == &sbxvidriver) + return (SNDCARD_SB16); + else if (driver == &sbmididriver) + return (SNDCARD_SB16MIDI); + else if(driver == &awedriver) + return(SNDCARD_AWE32); + else if (driver == &uartdriver) + return (SNDCARD_UART6850); + else if (driver == &gusdriver) + return (SNDCARD_GUS16); + else if (driver == &mssdriver) + return (SNDCARD_MSS); + else if (driver == &sscapedriver) + return(SNDCARD_SSCAPE); + else if (driver == &sscape_mssdriver) + return(SNDCARD_SSCAPE_MSS); + else if (driver == &trixdriver) + return (SNDCARD_TRXPRO); + else if (driver == &trixsbdriver) + return (SNDCARD_TRXPRO_SB); + else + return (0); +} - for (irq = 0; irq < 16; irq++) - if (ipri == (1 << irq)) - return irq; +/* + * very dirty: tmp_osp is allocated in sndprobe, and used at the next + * call in sndattach + */ - return -1; /* Invalid argument */ -} +static sound_os_info *temp_osp; + +/* + * sndprobe is called for each isa_device. From here, a voxware unit + * number is determined, and the appropriate probe routine is selected. + * The parameters from the config line are passed to the hw_config struct. + */ int -sndprobe (struct isa_device *dev) +sndprobe(struct isa_device * dev) { - struct address_info hw_config; - - hw_config.io_base = dev->id_iobase; - hw_config.irq = ipri_to_irq (dev->id_irq); - hw_config.dma = dev->id_drq; - - return sndtable_probe (dev->id_unit, &hw_config); + struct address_info hw_config; + int unit; + + temp_osp = (sound_os_info *)malloc(sizeof(sound_os_info), + M_DEVBUF, M_NOWAIT); + if (!temp_osp) + panic("SOUND: Cannot allocate memory\n"); + + /* + * get config info from the kernel config. These may be overridden + * by the local autoconfiguration routines though (e.g. pnp stuff). + */ + + hw_config.io_base = dev->id_iobase; + hw_config.irq = ipri_to_irq(dev->id_irq); + hw_config.dma = dev->id_drq; + + /* + * misuse the flags field for read dma. Note that, to use 0 as + * read dma channel, one of the high bits should be set. lr970705 XXX + */ + + if (dev->id_flags != 0) + hw_config.dma2 = dev->id_flags & 0x7; + else + hw_config.dma2 = -1; + + hw_config.always_detect = 0; + hw_config.name = NULL; + hw_config.card_subtype = 0; + + temp_osp->unit = dev->id_unit; + hw_config.osp = temp_osp; + unit = driver_to_voxunit(dev->id_driver); + + if (sndtable_probe(unit, &hw_config)) { + dev->id_iobase = hw_config.io_base; + dev->id_irq = hw_config.irq == -1 ? 0 : (1 << hw_config.irq); + dev->id_drq = hw_config.dma; + + if (hw_config.dma != hw_config.dma2 && ( hw_config.dma2 != -1)) + dev->id_flags = hw_config.dma2 | 0x100; /* XXX lr */ + else + dev->id_flags = 0; + return TRUE; + } + return 0; } int -sndattach (struct isa_device *dev) +sndattach(struct isa_device * dev) { - int i; - static int midi_initialized = 0; - static int seq_initialized = 0; - static int generic_midi_initialized = 0; - unsigned long mem_start = 0xefffffff; - struct address_info hw_config; - - hw_config.io_base = dev->id_iobase; - hw_config.irq = ipri_to_irq (dev->id_irq); - hw_config.dma = dev->id_drq; - - if (dev->id_unit) /* Card init */ - if (!sndtable_init_card (dev->id_unit, &hw_config)) - { - printf (" <Driver not configured>"); + int unit; + static int midi_initialized = 0; + static int seq_initialized = 0; + struct address_info hw_config; + + unit = driver_to_voxunit(dev->id_driver); + hw_config.io_base = dev->id_iobase; + hw_config.irq = ipri_to_irq(dev->id_irq); + hw_config.dma = dev->id_drq; + + /* misuse the flags field for read dma */ + if (dev->id_flags != 0) + hw_config.dma2 = dev->id_flags & 0x7; + else + hw_config.dma2 = -1; + + hw_config.card_subtype = 0; + hw_config.osp = temp_osp; + + if (!unit) return FALSE; - } - /* - * Init the high level sound driver - */ - - if (!(soundcards_installed = sndtable_get_cardcount ())) - { - printf (" <No such hardware>"); - return FALSE; /* No cards detected */ + if (!(sndtable_init_card(unit, &hw_config))) { /* init card */ + printf(" <Driver not configured>"); + return FALSE; } + /* + * Init the high level sound driver + */ - printf("\n"); - -#ifndef EXCLUDE_AUDIO - if (num_audiodevs) /* Audio devices present */ - { - mem_start = DMAbuf_init (mem_start); - mem_start = audio_init (mem_start); - sound_mem_init (); + if (!(soundcards_installed = sndtable_get_cardcount())) { + DDB(printf("No drivers actually installed\n")); + return FALSE; /* No cards detected */ } + printf("\n"); - soundcard_configured = 1; +#ifdef CONFIG_AUDIO + if (num_audiodevs) { /* Audio devices present */ + DMAbuf_init(); + sound_mem_init(); + } + soundcard_configured = 1; #endif - if (num_midis && !midi_initialized) - { - midi_initialized = 1; - mem_start = MIDIbuf_init (mem_start); + if (num_midis && !midi_initialized) + midi_initialized = 1; + + if ((num_midis + num_synths) && !seq_initialized) { + seq_initialized = 1; + sequencer_init(); } - if ((num_midis + num_synths) && !seq_initialized) { - seq_initialized = 1; - mem_start = sequencer_init (mem_start); + dev_t dev; + + dev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&dev, &snd_cdevsw, NULL); } - return TRUE; + + return TRUE; } -void -tenmicrosec (void) + +#ifdef CONFIG_AUDIO + +static void +alloc_dmap(int dev, int chan, struct dma_buffparms * dmap) { - int i; + char *tmpbuf; + int i; + + tmpbuf = contigmalloc(audio_devs[dev]->buffsize, M_DEVBUF, M_NOWAIT, + 0ul, 0xfffffful, 1ul, chan & 4 ? 0x20000ul : 0x10000ul); + if (tmpbuf == NULL) + printf("soundcard buffer alloc failed \n"); + + if (tmpbuf == NULL) { + printf("snd: Unable to allocate %d bytes of buffer\n", + 2 * (int) audio_devs[dev]->buffsize); + return; + } + dmap->raw_buf = tmpbuf; + /* + * Use virtual address as the physical address, since isa_dmastart + * performs the phys address computation. + */ + + dmap->raw_buf_phys = (u_long) tmpbuf; + for (i = 0; i < audio_devs[dev]->buffsize; i++) *tmpbuf++ = 0x80; - for (i = 0; i < 16; i++) - inb (0x80); } -void -request_sound_timer (int count) +static void +sound_mem_init(void) { - static int current = 0; - int tmp = count; - - if (count < 0) - timeout (sequencer_timer, 0, -count); - else - { + int dev; + static u_long dsp_init_mask = 0; + + for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */ + if (!(dsp_init_mask & (1 << dev))) /* Not already done */ + if (audio_devs[dev]->dmachan1 >= 0) { + dsp_init_mask |= (1 << dev); + audio_devs[dev]->buffsize = DSP_BUFFSIZE; + /* Now allocate the buffers */ + alloc_dmap(dev, audio_devs[dev]->dmachan1, + audio_devs[dev]->dmap_out); + if (audio_devs[dev]->flags & DMA_DUPLEX) + alloc_dmap(dev, audio_devs[dev]->dmachan2, + audio_devs[dev]->dmap_in); + } /* for dev */ +} - if (count < current) - current = 0; /* Timer restarted */ +#endif - count = count - current; - current = tmp; +int +snd_ioctl_return(int *addr, int value) +{ + if (value < 0) + return value; /* Error */ + suword(addr, value); + return 0; +} - if (!count) - count = 1; +#define MAX_UNIT 50 +typedef void (*irq_proc_t) (int irq); +static irq_proc_t irq_proc[MAX_UNIT] = {NULL}; +static int irq_irq[MAX_UNIT] = {0}; - timeout (sequencer_timer, 0, count); +int +snd_set_irq_handler(int int_lvl, void (*hndlr) (int), sound_os_info * osp) +{ + if (osp->unit >= MAX_UNIT) { + printf("Sound error: Unit number too high (%d)\n", osp->unit); + return 0; } - timer_running = 1; + irq_proc[osp->unit] = hndlr; + irq_irq[osp->unit] = int_lvl; + return 1; } void -sound_stop_timer (void) +sndintr(int unit) { - if (timer_running) - untimeout (sequencer_timer, 0); - timer_running = 0; + if ( (unit >= MAX_UNIT) || (irq_proc[unit] == NULL) ) + return; + + irq_proc[unit] (irq_irq[unit]); /* Call the installed handler */ } -#ifndef EXCLUDE_AUDIO -static void -sound_mem_init (void) +void +conf_printf(char *name, struct address_info * hw_config) { - int i, dev; - unsigned long dma_pagesize; - static unsigned long dsp_init_mask = 0; - - for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */ - if (!(dsp_init_mask & (1 << dev))) /* Not already done */ - if (sound_buffcounts[dev] > 0 && sound_dsp_dmachan[dev] > 0) - { - dsp_init_mask |= (1 << dev); - - if (sound_dma_automode[dev]) - { - sound_dma_automode[dev] = 0; /* Not possible with 386BSD */ - } - -#if 0 - if (sound_buffcounts[dev] == 1) - { - sound_buffcounts[dev] = 2; - sound_buffsizes[dev] /= 2; - } - - if (sound_buffsizes[dev] > 65536) /* Larger is not possible (yet) */ - sound_buffsizes[dev] = 65536; - - if (sound_dsp_dmachan[dev] > 3 && sound_buffsizes[dev] > 65536) - dma_pagesize = 131072; /* 128k */ - else - dma_pagesize = 65536; - - /* More sanity checks */ - - if (sound_buffsizes[dev] > dma_pagesize) - sound_buffsizes[dev] = dma_pagesize; - sound_buffsizes[dev] &= 0xfffff000; /* Truncate to n*4k */ - if (sound_buffsizes[dev] < 4096) - sound_buffsizes[dev] = 4096; -#else - dma_pagesize = 4096; - sound_buffsizes[dev] = 4096; - sound_buffcounts[dev] = 16; /* 16*4k -> 64k */ -#endif + if (!trace_init) + return; - /* Now allocate the buffers */ - - for (snd_raw_count[dev] = 0; snd_raw_count[dev] < sound_buffcounts[dev]; snd_raw_count[dev]++) - { - /* - * The DMA buffer allocation algorithm hogs memory. We allocate - * a memory area which is two times the requires size. This - * guarantees that it contains at least one valid DMA buffer. - * - * This really needs some kind of finetuning. - */ - char *tmpbuf = malloc (2*sound_buffsizes[dev], M_DEVBUF, M_NOWAIT); - unsigned long addr, rounded, start, end; - - if (tmpbuf == NULL) - { - printk ("snd: Unable to allocate %d bytes of buffer\n", - 2 * sound_buffsizes[dev]); - return; - } - - addr = kvtop (tmpbuf); - /* - * Align the start address if required - */ - start = (addr & ~(dma_pagesize - 1)); - end = ((addr+sound_buffsizes[dev]-1) & ~(dma_pagesize - 1)); - - if (start != end) - rounded = end; - else - rounded = addr; /* Fits to the same DMA page */ - - snd_raw_buf[dev][snd_raw_count[dev]] = - &tmpbuf[rounded - addr]; /* Compute offset */ - /* - * Use virtual address as the physical address, since - * isa_dmastart performs the phys address computation. - */ - snd_raw_buf_phys[dev][snd_raw_count[dev]] = - (unsigned long) snd_raw_buf[dev][snd_raw_count[dev]]; - } - } /* for dev */ + printf("<%s> ", name); + if (hw_config->io_base != -1 ) + printf("at 0x%03x", hw_config->io_base); -} + if (hw_config->irq != -1 ) + printf(" irq %d", hw_config->irq); -#endif + if (hw_config->dma != -1 || hw_config->dma2 != -1) { + printf(" dma %d", hw_config->dma); + if (hw_config->dma2 != -1) + printf(",%d", hw_config->dma2); + } -struct isa_driver snddriver = -{sndprobe, sndattach, "snd"}; -int -snd_ioctl_return (int *addr, int value) -{ - if (value < 0) - return value; /* Error */ - suword (addr, value); - return 0; } -int -snd_set_irq_handler (int interrupt_level, void(*hndlr)(int)) +void +conf_printf2(char *name, int base, int irq, int dma, int dma2) { - return 1; + if (!trace_init) + return; + + printf("<%s> at 0x%03x", name, base); + + if (irq) + printf(" irq %d", irq); + + if (dma != -1 || dma2 != -1) { + printf(" dma %d", dma); + if (dma2 != -1) + printf(",%d", dma2); + } + + } -void -snd_release_irq(int vect) + +void tenmicrosec (int j) { + int i, k; + for (k = 0; k < j/10 ; k++) { + for (i = 0; i < 16; i++) + inb (0x80); + } } -#endif +#endif /* NSND > 0 */ + + + + |