]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: 6fire: Fix leftover global pointers after probe failures
authorTakashi Iwai <tiwai@suse.de>
Tue, 14 Apr 2026 13:22:12 +0000 (15:22 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 15 Apr 2026 12:27:27 +0000 (14:27 +0200)
snd-usb-6fire driver holds devices[] and chips[] pointer arrays to
keep the usb_device and sfire_chip objects assigned to multiple
interfaces.  Those are, however, not properly cleared at the error
path of usb6fire_chip_probe(), which may confuse the later probes.
Also, the use of two pointer arrays makes things complicated; chips[]
may be NULL while devices[] may be left over.

For addressing this inconsistency, unify the pointer arrays, and use
only chips[] for managing the multiple devices, while the device is
checked with chip->dev pointer, instead.  Also, the assignment of
chips[] is moved at a later point where the probe successfully
returns, so that we don't leave the pointer there after the error.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260414132218.411013-3-tiwai@suse.de
sound/usb/6fire/chip.c

index 18a25449bcd39ce165fc5492dbdbe0ff2b54c1f0..dd787de986b1a31cdacebd248a6cdef3cfbbcf47 100644 (file)
@@ -31,7 +31,6 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */
 static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for the 6fire sound device");
@@ -85,19 +84,17 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
        /* look if we already serve this card and return if so */
        guard(mutex)(&register_mutex);
        for (i = 0; i < SNDRV_CARDS; i++) {
-               if (devices[i] == device) {
-                       if (chips[i])
-                               chips[i]->intf_count++;
+               if (chips[i] && chips[i]->dev == device) {
+                       chips[i]->intf_count++;
                        usb_set_intfdata(intf, chips[i]);
                        return 0;
-               } else if (!devices[i] && regidx < 0)
+               } else if (!chips[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);
@@ -123,7 +120,6 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
                        device->bus->busnum, device->devnum);
 
        chip = card->private_data;
-       chips[regidx] = chip;
        chip->dev = device;
        chip->regidx = regidx;
        chip->intf_count = 1;
@@ -151,7 +147,10 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
                dev_err(&intf->dev, "cannot register card.");
                goto destroy_chip;
        }
+
        usb_set_intfdata(intf, chip);
+       chips[regidx] = chip;
+
        return 0;
 
 destroy_chip:
@@ -169,7 +168,6 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)
        if (chip) { /* if !chip, fw upload has been performed */
                chip->intf_count--;
                if (!chip->intf_count) {
-                       devices[chip->regidx] = NULL;
                        chips[chip->regidx] = NULL;
 
                        /*