forked from mirrors/linux
		
	ALSA: usb-audio: Unify the release of usb_mixer_elem_info objects
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>
This commit is contained in:
		
							parent
							
								
									68e9fde245
								
							
						
					
					
						commit
						52c3e317a8
					
				
					 1 changed files with 28 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue