diff options
Diffstat (limited to 'sound/usb/mixer.c')
| -rw-r--r-- | sound/usb/mixer.c | 21 | 
1 files changed, 13 insertions, 8 deletions
| diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 638e7f73801..ca4739c3f65 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -715,8 +715,9 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_  		case UAC2_CLOCK_SELECTOR: {  			struct uac_selector_unit_descriptor *d = p1;  			/* call recursively to retrieve the channel info */ -			if (check_input_term(state, d->baSourceID[0], term) < 0) -				return -ENODEV; +			err = check_input_term(state, d->baSourceID[0], term); +			if (err < 0) +				return err;  			term->type = d->bDescriptorSubtype << 16; /* virtual type */  			term->id = id;  			term->name = uac_selector_unit_iSelector(d); @@ -725,7 +726,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_  		case UAC1_PROCESSING_UNIT:  		case UAC1_EXTENSION_UNIT:  		/* UAC2_PROCESSING_UNIT_V2 */ -		/* UAC2_EFFECT_UNIT */ { +		/* UAC2_EFFECT_UNIT */ +		case UAC2_EXTENSION_UNIT_V2: {  			struct uac_processing_unit_descriptor *d = p1;  			if (state->mixer->protocol == UAC_VERSION_2 && @@ -1356,8 +1358,9 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void  		return err;  	/* determine the input source type and name */ -	if (check_input_term(state, hdr->bSourceID, &iterm) < 0) -		return -EINVAL; +	err = check_input_term(state, hdr->bSourceID, &iterm); +	if (err < 0) +		return err;  	master_bits = snd_usb_combine_bytes(bmaControls, csize);  	/* master configuration quirks */ @@ -2052,6 +2055,8 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)  			return parse_audio_extension_unit(state, unitid, p1);  		else /* UAC_VERSION_2 */  			return parse_audio_processing_unit(state, unitid, p1); +	case UAC2_EXTENSION_UNIT_V2: +		return parse_audio_extension_unit(state, unitid, p1);  	default:  		snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);  		return -EINVAL; @@ -2118,7 +2123,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)  			state.oterm.type = le16_to_cpu(desc->wTerminalType);  			state.oterm.name = desc->iTerminal;  			err = parse_audio_unit(&state, desc->bSourceID); -			if (err < 0) +			if (err < 0 && err != -EINVAL)  				return err;  		} else { /* UAC_VERSION_2 */  			struct uac2_output_terminal_descriptor *desc = p; @@ -2130,12 +2135,12 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)  			state.oterm.type = le16_to_cpu(desc->wTerminalType);  			state.oterm.name = desc->iTerminal;  			err = parse_audio_unit(&state, desc->bSourceID); -			if (err < 0) +			if (err < 0 && err != -EINVAL)  				return err;  			/* for UAC2, use the same approach to also add the clock selectors */  			err = parse_audio_unit(&state, desc->bCSourceID); -			if (err < 0) +			if (err < 0 && err != -EINVAL)  				return err;  		}  	} |