diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 33034e07b3d6..636f309c9424 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -421,30 +421,26 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int { struct snd_sb *chip = snd_pcm_substream_chip(substream); int result = 0; - - /* FIXME race condition in here!!! - chip->mode non-atomic update gets consistently protected - by reg_lock always, _except_ for this place!! - Probably need to take reg_lock as outer (or inner??) lock, too. - (or serialize both lock operations? probably not, though... - racy?) - */ - guard(spinlock)(&chip->mixer_lock); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - chip->mode |= SB_RATE_LOCK_CAPTURE; - snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL, - capture_cmd(chip)); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - chip->mode &= ~SB_RATE_LOCK_CAPTURE; - snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL, - capture_cmd(chip)); - break; - default: - result = -EINVAL; - break; + + guard(spinlock)(&chip->reg_lock); + scoped_guard(spinlock, &chip->mixer_lock) { + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + chip->mode |= SB_RATE_LOCK_CAPTURE; + snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL, + capture_cmd(chip)); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + chip->mode &= ~SB_RATE_LOCK_CAPTURE; + snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL, + capture_cmd(chip)); + break; + default: + result = -EINVAL; + break; + } } return result; }