diff options
Diffstat (limited to 'sound/pci/emu10k1/emufx.c')
| -rw-r--r-- | sound/pci/emu10k1/emufx.c | 121 |
1 files changed, 46 insertions, 75 deletions
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 9904bcfee106..37af7bf76347 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -1,23 +1,18 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) by Jaroslav Kysela <perex@perex.cz> + * James Courtier-Dutton <James@superbug.co.uk> + * Oswald Buddenhagen <oswald.buddenhagen@gmx.de> * Creative Labs, Inc. - * Routines for effect processor FX8010 - * - * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> - * Added EMU 1010 support. - * - * BUGS: - * -- * - * TODO: - * -- + * Routines for effect processor FX8010 */ #include <linux/pci.h> #include <linux/capability.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/string.h> #include <linux/vmalloc.h> #include <linux/init.h> #include <linux/mutex.h> @@ -445,13 +440,11 @@ int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu, void *private_data, struct snd_emu10k1_fx8010_irq *irq) { - unsigned long flags; - irq->handler = handler; irq->gpr_running = gpr_running; irq->private_data = private_data; irq->next = NULL; - spin_lock_irqsave(&emu->fx8010.irq_lock, flags); + guard(spinlock_irqsave)(&emu->fx8010.irq_lock); if (emu->fx8010.irq_handlers == NULL) { emu->fx8010.irq_handlers = irq; emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt; @@ -460,7 +453,6 @@ int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu, irq->next = emu->fx8010.irq_handlers; emu->fx8010.irq_handlers = irq; } - spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags); return 0; } @@ -468,9 +460,8 @@ int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_irq *irq) { struct snd_emu10k1_fx8010_irq *tmp; - unsigned long flags; - spin_lock_irqsave(&emu->fx8010.irq_lock, flags); + guard(spinlock_irqsave)(&emu->fx8010.irq_lock); tmp = emu->fx8010.irq_handlers; if (tmp == irq) { emu->fx8010.irq_handlers = tmp->next; @@ -484,7 +475,6 @@ int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu, if (tmp) tmp->next = tmp->next->next; } - spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags); return 0; } @@ -799,13 +789,10 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, if (snd_emu10k1_look_for_ctl(emu, &gctl->id)) continue; gctl_id = (struct snd_ctl_elem_id *)&gctl->id; - down_read(&emu->card->controls_rwsem); if (snd_ctl_find_id(emu->card, gctl_id)) { - up_read(&emu->card->controls_rwsem); err = -EEXIST; goto __error; } - up_read(&emu->card->controls_rwsem); if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER && gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) { err = -EINVAL; @@ -977,11 +964,9 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, in_kernel); if (err < 0) return err; - down_write(&card->controls_rwsem); ctl = snd_emu10k1_look_for_ctl(emu, &id); if (ctl) snd_ctl_remove(card, ctl->kcontrol); - up_write(&card->controls_rwsem); } return 0; } @@ -1036,12 +1021,12 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_code *icode, bool in_kernel) { - int err = 0; + int err; - mutex_lock(&emu->fx8010.lock); + guard(mutex)(&emu->fx8010.lock); err = snd_emu10k1_verify_controls(emu, icode, in_kernel); if (err < 0) - goto __error; + return err; strscpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); /* stop FX processor - this may be dangerous, but it's better to miss some samples than generate wrong ones - [jk] */ @@ -1052,27 +1037,25 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, /* ok, do the main job */ err = snd_emu10k1_del_controls(emu, icode, in_kernel); if (err < 0) - goto __error; + return err; err = snd_emu10k1_gpr_poke(emu, icode, in_kernel); if (err < 0) - goto __error; + return err; err = snd_emu10k1_tram_poke(emu, icode, in_kernel); if (err < 0) - goto __error; + return err; err = snd_emu10k1_code_poke(emu, icode, in_kernel); if (err < 0) - goto __error; + return err; err = snd_emu10k1_add_controls(emu, icode, in_kernel); if (err < 0) - goto __error; + return err; /* start FX processor when the DSP code is updated */ if (emu->audigy) snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg); else snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg); - __error: - mutex_unlock(&emu->fx8010.lock); - return err; + return 0; } static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, @@ -1080,7 +1063,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, { int err; - mutex_lock(&emu->fx8010.lock); + guard(mutex)(&emu->fx8010.lock); strscpy(icode->name, emu->fx8010.name, sizeof(icode->name)); /* ok, do the main job */ err = snd_emu10k1_gpr_peek(emu, icode); @@ -1090,7 +1073,6 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, err = snd_emu10k1_code_peek(emu, icode); if (err >= 0) err = snd_emu10k1_list_controls(emu, icode); - mutex_unlock(&emu->fx8010.lock); return err; } @@ -1098,7 +1080,6 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_pcm_rec *ipcm) { unsigned int i; - int err = 0; struct snd_emu10k1_fx8010_pcm *pcm; if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) @@ -1108,20 +1089,16 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, if (ipcm->channels > 32) return -EINVAL; pcm = &emu->fx8010.pcm[ipcm->substream]; - mutex_lock(&emu->fx8010.lock); - spin_lock_irq(&emu->reg_lock); - if (pcm->opened) { - err = -EBUSY; - goto __error; - } + guard(mutex)(&emu->fx8010.lock); + guard(spinlock_irq)(&emu->reg_lock); + if (pcm->opened) + return -EBUSY; if (ipcm->channels == 0) { /* remove */ pcm->valid = 0; } else { /* FIXME: we need to add universal code to the PCM transfer routine */ - if (ipcm->channels != 2) { - err = -EINVAL; - goto __error; - } + if (ipcm->channels != 2) + return -EINVAL; pcm->valid = 1; pcm->opened = 0; pcm->channels = ipcm->channels; @@ -1136,17 +1113,13 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, for (i = 0; i < pcm->channels; i++) pcm->etram[i] = ipcm->etram[i]; } - __error: - spin_unlock_irq(&emu->reg_lock); - mutex_unlock(&emu->fx8010.lock); - return err; + return 0; } static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_pcm_rec *ipcm) { unsigned int i; - int err = 0; struct snd_emu10k1_fx8010_pcm *pcm; if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) @@ -1154,8 +1127,8 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, ipcm->substream = array_index_nospec(ipcm->substream, EMU10K1_FX8010_PCM_COUNT); pcm = &emu->fx8010.pcm[ipcm->substream]; - mutex_lock(&emu->fx8010.lock); - spin_lock_irq(&emu->reg_lock); + guard(mutex)(&emu->fx8010.lock); + guard(spinlock_irq)(&emu->reg_lock); ipcm->channels = pcm->channels; ipcm->tram_start = pcm->tram_start; ipcm->buffer_size = pcm->buffer_size; @@ -1169,9 +1142,7 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, ipcm->etram[i] = pcm->etram[i]; ipcm->res1 = ipcm->res2 = 0; ipcm->pad = 0; - spin_unlock_irq(&emu->reg_lock); - mutex_unlock(&emu->fx8010.lock); - return err; + return 0; } #define SND_EMU10K1_GPR_CONTROLS 44 @@ -1186,7 +1157,7 @@ snd_emu10k1_init_mono_control2(struct snd_emu10k1_fx8010_control_gpr *ctl, const char *name, int gpr, int defval, int defval_hr) { ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, name); + strscpy(ctl->id.name, name); ctl->vcount = ctl->count = 1; if (high_res_gpr_volume) { ctl->min = -1; @@ -1210,7 +1181,7 @@ snd_emu10k1_init_stereo_control2(struct snd_emu10k1_fx8010_control_gpr *ctl, const char *name, int gpr, int defval, int defval_hr) { ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, name); + strscpy(ctl->id.name, name); ctl->vcount = ctl->count = 2; if (high_res_gpr_volume) { ctl->min = -1; @@ -1235,7 +1206,7 @@ snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl, const char *name, int gpr, int defval) { ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, name); + strscpy(ctl->id.name, name); ctl->vcount = ctl->count = 1; ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; ctl->min = 0; @@ -1248,7 +1219,7 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl const char *name, int gpr, int defval) { ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, name); + strscpy(ctl->id.name, name); ctl->vcount = ctl->count = 2; ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; @@ -1336,7 +1307,7 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) /* clear TRAM data & address lines */ memset(icode->tram_valid, 0xff, 256 / 8); - strcpy(icode->name, "Audigy DSP code for ALSA"); + strscpy(icode->name, "Audigy DSP code for ALSA"); ptr = 0; nctl = 0; gpr_map[bit_shifter16] = 0x00008000; @@ -1574,7 +1545,7 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) */ ctl = &controls[nctl + 0]; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, "Tone Control - Bass"); + strscpy(ctl->id.name, "Tone Control - Bass"); ctl->vcount = 2; ctl->count = 10; ctl->min = 0; @@ -1583,7 +1554,7 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; ctl = &controls[nctl + 1]; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, "Tone Control - Treble"); + strscpy(ctl->id.name, "Tone Control - Treble"); ctl->vcount = 2; ctl->count = 10; ctl->min = 0; @@ -1860,7 +1831,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) /* clear TRAM data & address lines */ memset(icode->tram_valid, 0xff, 160 / 8); - strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela"); + strscpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela"); ptr = 0; i = 0; /* we have 12 inputs */ playback = SND_EMU10K1_INPUTS; @@ -2171,7 +2142,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) */ ctl = &controls[i + 0]; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, "Tone Control - Bass"); + strscpy(ctl->id.name, "Tone Control - Bass"); ctl->vcount = 2; ctl->count = 10; ctl->min = 0; @@ -2181,7 +2152,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; ctl = &controls[i + 1]; ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(ctl->id.name, "Tone Control - Treble"); + strscpy(ctl->id.name, "Tone Control - Treble"); ctl->vcount = 2; ctl->count = 10; ctl->min = 0; @@ -2425,9 +2396,9 @@ int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size) } if ((emu->fx8010.etram_pages.bytes / 2) == size) return 0; - spin_lock_irq(&emu->emu_lock); - outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG); - spin_unlock_irq(&emu->emu_lock); + scoped_guard(spinlock_irq, &emu->emu_lock) { + outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG); + } snd_emu10k1_ptr_write(emu, TCB, 0, 0); snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K); if (emu->fx8010.etram_pages.area != NULL) { @@ -2443,9 +2414,9 @@ int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size) memset(emu->fx8010.etram_pages.area, 0, size * 2); snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr); snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg); - spin_lock_irq(&emu->emu_lock); - outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG); - spin_unlock_irq(&emu->emu_lock); + scoped_guard(spinlock_irq, &emu->emu_lock) { + outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG); + } } return 0; @@ -2557,9 +2528,9 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un return -EPERM; if (get_user(addr, (unsigned int __user *)argp)) return -EFAULT; - mutex_lock(&emu->fx8010.lock); - res = snd_emu10k1_fx8010_tram_setup(emu, addr); - mutex_unlock(&emu->fx8010.lock); + scoped_guard(mutex, &emu->fx8010.lock) { + res = snd_emu10k1_fx8010_tram_setup(emu, addr); + } return res; case SNDRV_EMU10K1_IOCTL_STOP: if (!capable(CAP_SYS_ADMIN)) @@ -2634,7 +2605,7 @@ int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device) err = snd_hwdep_new(emu->card, "FX8010", device, &hw); if (err < 0) return err; - strcpy(hw->name, "EMU10K1 (FX8010)"); + strscpy(hw->name, "EMU10K1 (FX8010)"); hw->iface = SNDRV_HWDEP_IFACE_EMU10K1; hw->ops.open = snd_emu10k1_fx8010_open; hw->ops.ioctl = snd_emu10k1_fx8010_ioctl; |
