From: Takashi Iwai Date: Tue, 14 Apr 2026 13:22:11 +0000 (+0200) Subject: ALSA: 6fire: Cover the whole probe and disconnect calls with register_mutex X-Git-Tag: v7.1-rc1~22^2~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3c80e76a0e94c7c9771997de90f6a284b4f10d9;p=thirdparty%2Fkernel%2Flinux.git ALSA: 6fire: Cover the whole probe and disconnect calls with register_mutex In 6fire driver, we protect the concurrent calls against probe and disconnect with the register_mutex, but it's applied only partially. Since we handle two global pointers in devices[] and chips[] pairs, the assignment of the latter can be inconsistent upon concurrent interface probes, and the refcount handling isn't properly protected at disconnect, either. This patch extends the mutex application range to the whole probe and disconnect functions. It makes the code safer against potential concurrent probles and disconnects, while it makes the code easier to read, too. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20260414132218.411013-2-tiwai@suse.de --- diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index 874f6cd503ca5..18a25449bcd39 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c @@ -83,22 +83,21 @@ static int usb6fire_chip_probe(struct usb_interface *intf, struct snd_card *card = NULL; /* look if we already serve this card and return if so */ - scoped_guard(mutex, ®ister_mutex) { - for (i = 0; i < SNDRV_CARDS; i++) { - if (devices[i] == device) { - if (chips[i]) - chips[i]->intf_count++; - usb_set_intfdata(intf, chips[i]); - return 0; - } else if (!devices[i] && regidx < 0) - regidx = i; - } - if (regidx < 0) { - dev_err(&intf->dev, "too many cards registered.\n"); - return -ENODEV; - } - devices[regidx] = device; + guard(mutex)(®ister_mutex); + for (i = 0; i < SNDRV_CARDS; i++) { + if (devices[i] == device) { + if (chips[i]) + chips[i]->intf_count++; + usb_set_intfdata(intf, chips[i]); + return 0; + } else if (!devices[i] && regidx < 0) + regidx = i; + } + if (regidx < 0) { + dev_err(&intf->dev, "too many cards registered.\n"); + return -ENODEV; } + devices[regidx] = device; /* check, if firmware is present on device, upload it if not */ ret = usb6fire_fw_init(intf); @@ -165,14 +164,13 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf) struct sfire_chip *chip; struct snd_card *card; + guard(mutex)(®ister_mutex); chip = usb_get_intfdata(intf); if (chip) { /* if !chip, fw upload has been performed */ chip->intf_count--; if (!chip->intf_count) { - scoped_guard(mutex, ®ister_mutex) { - devices[chip->regidx] = NULL; - chips[chip->regidx] = NULL; - } + devices[chip->regidx] = NULL; + chips[chip->regidx] = NULL; /* * Save card pointer before teardown.