ALSA: usb-audio: Unify the release of usb_mixer_elem_info objects
authorTakashi Iwai <tiwai@suse.de>
Thu, 22 Aug 2019 06:23:10 +0000 (08:23 +0200)
committerTakashi Iwai <tiwai@suse.de>
Thu, 22 Aug 2019 08:36:00 +0000 (10:36 +0200)
Instead of the direct kfree() calls, introduce a new local helper to
release the usb_mixer_elem_info object.  This will be extended to do
more than a single kfree() in the later patches.

Also, use the standard goto instead of multiple calls in
parse_audio_selector_unit() error paths.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/mixer.c

index 34def5911af2af04e6e2d0d3df7dbdb2058763c9..277660fd6e0ac44ee81f3c1e8cf940a63691bd23 100644 (file)
@@ -1026,10 +1026,15 @@ static struct usb_feature_control_info audio_feature_info[] = {
        { UAC2_FU_PHASE_INVERTER,        "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 },
 };
 
+static void usb_mixer_elem_info_free(struct usb_mixer_elem_info *cval)
+{
+       kfree(cval);
+}
+
 /* private_free callback */
 void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl)
 {
-       kfree(kctl->private_data);
+       usb_mixer_elem_info_free(kctl->private_data);
        kctl->private_data = NULL;
 }
 
@@ -1552,7 +1557,7 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer,
 
        ctl_info = get_feature_control_info(control);
        if (!ctl_info) {
-               kfree(cval);
+               usb_mixer_elem_info_free(cval);
                return;
        }
        if (mixer->protocol == UAC_VERSION_1)
@@ -1585,7 +1590,7 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer,
 
        if (!kctl) {
                usb_audio_err(mixer->chip, "cannot malloc kcontrol\n");
-               kfree(cval);
+               usb_mixer_elem_info_free(cval);
                return;
        }
        kctl->private_free = snd_usb_mixer_elem_free;
@@ -1755,7 +1760,7 @@ static void build_connector_control(struct usb_mixer_interface *mixer,
        kctl = snd_ctl_new1(&usb_connector_ctl_ro, cval);
        if (!kctl) {
                usb_audio_err(mixer->chip, "cannot malloc kcontrol\n");
-               kfree(cval);
+               usb_mixer_elem_info_free(cval);
                return;
        }
        get_connector_control_name(mixer, term, is_input, kctl->id.name,
@@ -1808,7 +1813,7 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid,
        kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval);
 
        if (!kctl) {
-               kfree(cval);
+               usb_mixer_elem_info_free(cval);
                return -ENOMEM;
        }
 
@@ -2070,7 +2075,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
        kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
        if (!kctl) {
                usb_audio_err(state->chip, "cannot malloc kcontrol\n");
-               kfree(cval);
+               usb_mixer_elem_info_free(cval);
                return;
        }
        kctl->private_free = snd_usb_mixer_elem_free;
@@ -2468,7 +2473,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
 
                kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
                if (!kctl) {
-                       kfree(cval);
+                       usb_mixer_elem_info_free(cval);
                        return -ENOMEM;
                }
                kctl->private_free = snd_usb_mixer_elem_free;
@@ -2606,7 +2611,7 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
        if (kctl->private_data) {
                struct usb_mixer_elem_info *cval = kctl->private_data;
                num_ins = cval->max;
-               kfree(cval);
+               usb_mixer_elem_info_free(cval);
                kctl->private_data = NULL;
        }
        if (kctl->private_value) {
@@ -2678,10 +2683,10 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
                break;
        }
 
-       namelist = kmalloc_array(desc->bNrInPins, sizeof(char *), GFP_KERNEL);
+       namelist = kcalloc(desc->bNrInPins, sizeof(char *), GFP_KERNEL);
        if (!namelist) {
-               kfree(cval);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto error_cval;
        }
 #define MAX_ITEM_NAME_LEN      64
        for (i = 0; i < desc->bNrInPins; i++) {
@@ -2689,11 +2694,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
                len = 0;
                namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
                if (!namelist[i]) {
-                       while (i--)
-                               kfree(namelist[i]);
-                       kfree(namelist);
-                       kfree(cval);
-                       return -ENOMEM;
+                       err = -ENOMEM;
+                       goto error_name;
                }
                len = check_mapped_selector_name(state, unitid, i, namelist[i],
                                                 MAX_ITEM_NAME_LEN);
@@ -2707,10 +2709,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
        kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
        if (! kctl) {
                usb_audio_err(state->chip, "cannot malloc kcontrol\n");
-               for (i = 0; i < desc->bNrInPins; i++)
-                       kfree(namelist[i]);
-               kfree(namelist);
-               kfree(cval);
+               err = -ENOMEM;
+               goto error_name;
                return -ENOMEM;
        }
        kctl->private_value = (unsigned long)namelist;
@@ -2757,6 +2757,14 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
        usb_audio_dbg(state->chip, "[%d] SU [%s] items = %d\n",
                    cval->head.id, kctl->id.name, desc->bNrInPins);
        return snd_usb_mixer_add_control(&cval->head, kctl);
+
+ error_name:
+       for (i = 0; i < desc->bNrInPins; i++)
+               kfree(namelist[i]);
+       kfree(namelist);
+ error_cval:
+       usb_mixer_elem_info_free(cval);
+       return err;
 }
 
 /*