Commit d4079ac4 authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela
Browse files

[ALSA] powermac - Check value range in ctl callbacks



Check the value ranges in ctl put callbacks properly in snd-powermac
driver.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent d05ab185
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -175,10 +175,12 @@ static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
	int inverted = (kcontrol->private_value >> 16) & 1;
	int val, oldval;
	unsigned long flags;
	int vol[2];
	unsigned int vol[2];

	vol[0] = ucontrol->value.integer.value[0];
	vol[1] = ucontrol->value.integer.value[1];
	if (vol[0] > 0x0f || vol[1] > 0x0f)
		return -EINVAL;
	if (inverted) {
		vol[0] = 0x0f - vol[0];
		vol[1] = 0x0f - vol[1];
@@ -421,10 +423,14 @@ static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol,
	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
	int index = kcontrol->private_value;
	struct awacs_amp *amp = chip->mixer_data;
	unsigned int val;
	snd_assert(amp, return -EINVAL);
	snd_assert(index >= 0 && index <= 1, return -EINVAL);
	if (ucontrol->value.integer.value[0] != amp->amp_tone[index]) {
		amp->amp_tone[index] = ucontrol->value.integer.value[0];
	val = ucontrol->value.integer.value[0];
	if (val > 14)
		return -EINVAL;
	if (val != amp->amp_tone[index]) {
		amp->amp_tone[index] = val;
		awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
		return 1;
	}
@@ -456,9 +462,13 @@ static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
{
	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
	struct awacs_amp *amp = chip->mixer_data;
	unsigned int val;
	snd_assert(amp, return -EINVAL);
	if (ucontrol->value.integer.value[0] != amp->amp_master) {
		amp->amp_master = ucontrol->value.integer.value[0];
	val = ucontrol->value.integer.value[0];
	if (val > 99)
		return -EINVAL;
	if (val != amp->amp_master) {
		amp->amp_master = val;
		awacs_amp_set_master(amp, amp->amp_master);
		return 1;
	}
+5 −2
Original line number Diff line number Diff line
@@ -195,10 +195,13 @@ static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
	int oval;
	unsigned int oval, nval;
	snd_assert(chip->beep, return -ENXIO);
	oval = chip->beep->volume;
	chip->beep->volume = ucontrol->value.integer.value[0];
	nval = ucontrol->value.integer.value[0];
	if (nval > 100)
		return -EINVAL;
	chip->beep->volume = nval;
	return oval != chip->beep->volume;
}

+7 −4
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@ snd_pmac_burgundy_write_volume(struct snd_pmac *chip, unsigned int address,
{
	int hardvolume, lvolume, rvolume;

	if (volume[0] < 0 || volume[0] > 100 ||
	    volume[1] < 0 || volume[1] > 100)
		return; /* -EINVAL */
	lvolume = volume[0] ? volume[0] + BURGUNDY_VOLUME_OFFSET : 0;
	rvolume = volume[1] ? volume[1] + BURGUNDY_VOLUME_OFFSET : 0;

@@ -301,14 +304,14 @@ static int snd_pmac_burgundy_put_volume_out(struct snd_kcontrol *kcontrol,
	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
	unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
	int stereo = (kcontrol->private_value >> 24) & 1;
	int oval, val;
	unsigned int oval, val;

	oval = ~snd_pmac_burgundy_rcb(chip, addr) & 0xff;
	val = ucontrol->value.integer.value[0];
	val = ucontrol->value.integer.value[0] & 15;
	if (stereo)
		val |= ucontrol->value.integer.value[1] << 4;
		val |= (ucontrol->value.integer.value[1] & 15) << 4;
	else
		val |= ucontrol->value.integer.value[0] << 4;
		val |= val << 4;
	val = ~val & 0xff;
	snd_pmac_burgundy_wcb(chip, addr, val);
	return val != oval;
+11 −6
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ static int daca_put_deemphasis(struct snd_kcontrol *kcontrol,
		return -ENODEV;
	change = mix->deemphasis != ucontrol->value.integer.value[0];
	if (change) {
		mix->deemphasis = ucontrol->value.integer.value[0];
		mix->deemphasis = !!ucontrol->value.integer.value[0];
		daca_set_volume(mix);
	}
	return change;
@@ -149,15 +149,20 @@ static int daca_put_volume(struct snd_kcontrol *kcontrol,
{
	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
	struct pmac_daca *mix;
	unsigned int vol[2];
	int change;

	if (! (mix = chip->mixer_data))
		return -ENODEV;
	change = mix->left_vol != ucontrol->value.integer.value[0] ||
		mix->right_vol != ucontrol->value.integer.value[1];
	vol[0] = ucontrol->value.integer.value[0];
	vol[1] = ucontrol->value.integer.value[1];
	if (vol[0] > DACA_VOL_MAX || vol[1] > DACA_VOL_MAX)
		return -EINVAL;
	change = mix->left_vol != vol[0] ||
		mix->right_vol != vol[1];
	if (change) {
		mix->left_vol = ucontrol->value.integer.value[0];
		mix->right_vol = ucontrol->value.integer.value[1];
		mix->left_vol = vol[0];
		mix->right_vol = vol[1];
		daca_set_volume(mix);
	}
	return change;
@@ -188,7 +193,7 @@ static int daca_put_amp(struct snd_kcontrol *kcontrol,
		return -ENODEV;
	change = mix->amp_on != ucontrol->value.integer.value[0];
	if (change) {
		mix->amp_on = ucontrol->value.integer.value[0];
		mix->amp_on = !!ucontrol->value.integer.value[0];
		i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
					  mix->amp_on ? 0x05 : 0x04);
	}
+1 −1
Original line number Diff line number Diff line
@@ -1028,7 +1028,7 @@ static int pmac_auto_mute_put(struct snd_kcontrol *kcontrol,
{
	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
	if (ucontrol->value.integer.value[0] != chip->auto_mute) {
		chip->auto_mute = ucontrol->value.integer.value[0];
		chip->auto_mute = !!ucontrol->value.integer.value[0];
		if (chip->update_automute)
			chip->update_automute(chip, 1);
		return 1;
Loading