diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
commit | 86464aed71025541805e7b1515541aee89879e33 (patch) | |
tree | e01a457a4912a8553bc65524aa3125d51f29f810 /drivers/sound/dmasound.c | |
parent | 88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff) |
Merge with Linux 2.2.1.
Diffstat (limited to 'drivers/sound/dmasound.c')
-rw-r--r-- | drivers/sound/dmasound.c | 132 |
1 files changed, 75 insertions, 57 deletions
diff --git a/drivers/sound/dmasound.c b/drivers/sound/dmasound.c index aaf21e2ba..43b419817 100644 --- a/drivers/sound/dmasound.c +++ b/drivers/sound/dmasound.c @@ -90,7 +90,7 @@ History: #include <linux/sound.h> #include <linux/init.h> -#ifdef __mc68000__ +#if defined(__mc68000__) || defined(CONFIG_APUS) #include <asm/setup.h> #endif #include <asm/system.h> @@ -686,9 +686,9 @@ static struct sound_settings sound; #ifdef CONFIG_ATARI -static void *AtaAlloc(unsigned int size, int flags) __init; -static void AtaFree(void *, unsigned int size) __init; -static int AtaIrqInit(void) __init; +static void *AtaAlloc(unsigned int size, int flags); +static void AtaFree(void *, unsigned int size); +static int AtaIrqInit(void); #ifdef MODULE static void AtaIrqCleanUp(void); #endif /* MODULE */ @@ -709,9 +709,9 @@ static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp); #endif /* CONFIG_ATARI */ #ifdef CONFIG_AMIGA -static void *AmiAlloc(unsigned int size, int flags) __init; -static void AmiFree(void *, unsigned int) __init; -static int AmiIrqInit(void) __init; +static void *AmiAlloc(unsigned int size, int flags); +static void AmiFree(void *, unsigned int); +static int AmiIrqInit(void); #ifdef MODULE static void AmiIrqCleanUp(void); #endif /* MODULE */ @@ -726,9 +726,9 @@ static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp); #endif /* CONFIG_AMIGA */ #ifdef CONFIG_PPC -static void *PMacAlloc(unsigned int size, int flags) __init; -static void PMacFree(void *ptr, unsigned int size) __init; -static int PMacIrqInit(void) __init; +static void *PMacAlloc(unsigned int size, int flags); +static void PMacFree(void *ptr, unsigned int size); +static int PMacIrqInit(void); #ifdef MODULE static void PMacIrqCleanup(void); #endif /* MODULE */ @@ -2084,8 +2084,7 @@ static ssize_t pmac_ctx_s16(const u_char *userPtr, size_t userCount, int utotal, ftotal; frameLeft >>= 2; - if (stereo) - userCount >>= 1; + userCount >>= (stereo? 2: 1); ftotal = frameLeft; utotal = userCount; while (frameLeft) { @@ -2130,8 +2129,7 @@ static ssize_t pmac_ctx_u16(const u_char *userPtr, size_t userCount, int utotal, ftotal; frameLeft >>= 2; - if (stereo) - userCount >>= 1; + userCount >>= (stereo? 2: 1); ftotal = frameLeft; utotal = userCount; while (frameLeft) { @@ -2223,7 +2221,7 @@ static void AtaFree(void *obj, unsigned int size) atari_stram_free( obj ); } -static int AtaIrqInit(void) +static int __init AtaIrqInit(void) { /* Set up timer A. Timer A will receive a signal upon end of playing from the sound @@ -2720,7 +2718,7 @@ static void AmiFree(void *obj, unsigned int size) amiga_chip_free (obj); } -static int AmiIrqInit(void) +static int __init AmiIrqInit(void) { /* turn off DMA for audio channels */ custom.dmacon = AMI_AUDIO_OFF; @@ -2988,7 +2986,7 @@ static void PMacFree(void *ptr, unsigned int size) kfree(ptr); } -static int PMacIrqInit(void) +static int __init PMacIrqInit(void) { if (request_irq(awacs_irq, pmac_awacs_intr, 0, "AWACS", 0) || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "AWACS out", 0)) @@ -3850,12 +3848,12 @@ static struct file_operations mixer_fops = }; -__initfunc(static void mixer_init(void)) +static void __init mixer_init(void) { #ifndef MODULE int mixer_unit; #endif - mixer_unit = register_sound_mixer(&mixer_fops); + mixer_unit = register_sound_mixer(&mixer_fops, -1); if (mixer_unit < 0) return; @@ -3898,6 +3896,42 @@ __initfunc(static void mixer_init(void)) */ +static int sq_allocate_buffers(void) +{ + int i; + + if (sound_buffers) + return 0; + sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL); + if (!sound_buffers) + return -ENOMEM; + for (i = 0; i < numBufs; i++) { + sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL); + if (!sound_buffers[i]) { + while (i--) + sound.mach.dma_free (sound_buffers[i], bufSize << 10); + kfree (sound_buffers); + sound_buffers = 0; + return -ENOMEM; + } + } + return 0; +} + + +static void sq_release_buffers(void) +{ + int i; + + if (sound_buffers) { + for (i = 0; i < numBufs; i++) + sound.mach.dma_free (sound_buffers[i], bufSize << 10); + kfree (sound_buffers); + sound_buffers = 0; + } +} + + static void sq_setup(int numBufs, int bufSize, char **buffers) { #ifdef CONFIG_PPC @@ -3913,7 +3947,6 @@ static void sq_setup(int numBufs, int bufSize, char **buffers) sq.front = sq.count = 0; sq.rear = -1; sq.write_queue = sq.open_queue = sq.sync_queue = 0; - sq.busy = 0; sq.syncing = 0; sq.playing = 0; @@ -4033,9 +4066,12 @@ static int sq_open(struct inode *inode, struct file *file) } rc = 0; } + sq.busy = 1; + rc = sq_allocate_buffers(); + if (rc) + goto err_out_nobusy; sq_setup(numBufs, bufSize << 10, sound_buffers); sq.open_mode = file->f_flags; - sq.busy = 1; #ifdef CONFIG_ATARI sq.ignore_int = 1; #endif /* CONFIG_ATARI */ @@ -4049,6 +4085,9 @@ static int sq_open(struct inode *inode, struct file *file) sound_set_format(AFMT_MU_LAW); } return 0; +err_out_nobusy: + sq.busy = 0; + WAKE_UP(sq.open_queue); err_out: MOD_DEC_USE_COUNT; return rc; @@ -4101,8 +4140,10 @@ static int sq_release(struct inode *inode, struct file *file) sound.soft = sound.dsp; sound.hard = sound.dsp; sound_silence(); - if (rc == 0) + if (rc == 0) { + sq_release_buffers(); MOD_DEC_USE_COUNT; + } return rc; } @@ -4212,12 +4253,12 @@ static struct file_operations sq_fops = }; -__initfunc(static void sq_init(void)) +static void __init sq_init(void) { #ifndef MODULE int sq_unit; #endif - sq_unit = register_sound_dsp(&sq_fops); + sq_unit = register_sound_dsp(&sq_fops, -1); if (sq_unit < 0) return; @@ -4407,7 +4448,7 @@ static struct file_operations state_fops = }; -__initfunc(static void state_init(void)) +static void __init state_init(void) { #ifndef MODULE int state_unit; @@ -4430,15 +4471,14 @@ static long long sound_lseek(struct file *file, long long offset, int orig) /*** Config & Setup **********************************************************/ -__initfunc(void dmasound_init(void)) +void __init dmasound_init(void) { int has_sound = 0; - int i; #ifdef CONFIG_PPC struct device_node *np; #endif -#ifdef __mc68000__ +#if defined(__mc68000__) || defined(CONFIG_APUS) switch (m68k_machtype) { #ifdef CONFIG_ATARI case MACH_ATARI: @@ -4466,7 +4506,7 @@ __initfunc(void dmasound_init(void)) break; #endif /* CONFIG_AMIGA */ } -#endif /* __mc68000__ */ +#endif /* __mc68000__||CONFIG_APUS */ #ifdef CONFIG_PPC awacs_subframe = 0; @@ -4501,8 +4541,10 @@ __initfunc(void dmasound_init(void)) awacs_rx_irq = np->intrs[2].line; awacs_tx_cmd_space = kmalloc((numBufs + 4) * sizeof(struct dbdma_cmd), GFP_KERNEL); - if (awacs_tx_cmd_space == NULL) - goto out_of_memory; + if (awacs_tx_cmd_space == NULL) { + printk("DMA sound driver: Not enough buffer memory, driver disabled!\n"); + return; + } awacs_tx_cmds = (volatile struct dbdma_cmd *) DBDMA_ALIGN(awacs_tx_cmd_space); awacs_reg[0] = MASK_MUX_CD; @@ -4543,24 +4585,6 @@ __initfunc(void dmasound_init(void)) return; /* Set up sound queue, /dev/audio and /dev/dsp. */ - sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL); - if (!sound_buffers) { - out_of_memory: - printk("DMA sound driver: Not enough buffer memory, driver disabled!\n"); - return; - } - for (i = 0; i < numBufs; i++) { - sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL); - if (!sound_buffers[i]) { - while (i--) - sound.mach.dma_free (sound_buffers[i], bufSize << 10); - kfree (sound_buffers); - sound_buffers = 0; - goto out_of_memory; - } - } - - sq_setup(numBufs, bufSize << 10, sound_buffers); /* Set default settings. */ sq_init(); @@ -4588,7 +4612,7 @@ __initfunc(void dmasound_init(void)) #define MAXARGS 8 /* Should be sufficient for now */ -__initfunc(void dmasound_setup(char *str, int *ints)) +void __init dmasound_setup(char *str, int *ints) { /* check the bootstrap parameter for "dmasound=" */ @@ -4628,18 +4652,12 @@ int init_module(void) void cleanup_module(void) { - int i; - if (irq_installed) { sound_silence(); sound.mach.irqcleanup(); } - if (sound_buffers) { - for (i = 0; i < numBufs; i++) - sound.mach.dma_free(sound_buffers[i], bufSize << 10); - kfree(sound_buffers); - } + sq_release_buffers(); if (mixer_unit >= 0) unregister_sound_mixer(mixer_unit); |