diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-11-15 10:14:12 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:25 -0500 |
commit | d4079ac49a08e36d6839a9ceb26aec8c24c9ed82 (patch) | |
tree | 91ebc493375fd4e7fa84c3a6ab67a885121b1c81 | |
parent | d05ab185b770de96399766be6bcb5769ab99bc09 (diff) |
[ALSA] powermac - Check value range in ctl callbacks
Check the value ranges in ctl put callbacks properly in snd-powermac
driver.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | sound/ppc/awacs.c | 20 | ||||
-rw-r--r-- | sound/ppc/beep.c | 7 | ||||
-rw-r--r-- | sound/ppc/burgundy.c | 11 | ||||
-rw-r--r-- | sound/ppc/daca.c | 17 | ||||
-rw-r--r-- | sound/ppc/pmac.c | 2 | ||||
-rw-r--r-- | sound/ppc/tumbler.c | 55 |
6 files changed, 79 insertions, 33 deletions
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index 05dabe454658..b15bfb6f7011 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c | |||
@@ -175,10 +175,12 @@ static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol, | |||
175 | int inverted = (kcontrol->private_value >> 16) & 1; | 175 | int inverted = (kcontrol->private_value >> 16) & 1; |
176 | int val, oldval; | 176 | int val, oldval; |
177 | unsigned long flags; | 177 | unsigned long flags; |
178 | int vol[2]; | 178 | unsigned int vol[2]; |
179 | 179 | ||
180 | vol[0] = ucontrol->value.integer.value[0]; | 180 | vol[0] = ucontrol->value.integer.value[0]; |
181 | vol[1] = ucontrol->value.integer.value[1]; | 181 | vol[1] = ucontrol->value.integer.value[1]; |
182 | if (vol[0] > 0x0f || vol[1] > 0x0f) | ||
183 | return -EINVAL; | ||
182 | if (inverted) { | 184 | if (inverted) { |
183 | vol[0] = 0x0f - vol[0]; | 185 | vol[0] = 0x0f - vol[0]; |
184 | vol[1] = 0x0f - vol[1]; | 186 | vol[1] = 0x0f - vol[1]; |
@@ -421,10 +423,14 @@ static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol, | |||
421 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 423 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
422 | int index = kcontrol->private_value; | 424 | int index = kcontrol->private_value; |
423 | struct awacs_amp *amp = chip->mixer_data; | 425 | struct awacs_amp *amp = chip->mixer_data; |
426 | unsigned int val; | ||
424 | snd_assert(amp, return -EINVAL); | 427 | snd_assert(amp, return -EINVAL); |
425 | snd_assert(index >= 0 && index <= 1, return -EINVAL); | 428 | snd_assert(index >= 0 && index <= 1, return -EINVAL); |
426 | if (ucontrol->value.integer.value[0] != amp->amp_tone[index]) { | 429 | val = ucontrol->value.integer.value[0]; |
427 | amp->amp_tone[index] = ucontrol->value.integer.value[0]; | 430 | if (val > 14) |
431 | return -EINVAL; | ||
432 | if (val != amp->amp_tone[index]) { | ||
433 | amp->amp_tone[index] = val; | ||
428 | awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]); | 434 | awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]); |
429 | return 1; | 435 | return 1; |
430 | } | 436 | } |
@@ -456,9 +462,13 @@ static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol, | |||
456 | { | 462 | { |
457 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 463 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
458 | struct awacs_amp *amp = chip->mixer_data; | 464 | struct awacs_amp *amp = chip->mixer_data; |
465 | unsigned int val; | ||
459 | snd_assert(amp, return -EINVAL); | 466 | snd_assert(amp, return -EINVAL); |
460 | if (ucontrol->value.integer.value[0] != amp->amp_master) { | 467 | val = ucontrol->value.integer.value[0]; |
461 | amp->amp_master = ucontrol->value.integer.value[0]; | 468 | if (val > 99) |
469 | return -EINVAL; | ||
470 | if (val != amp->amp_master) { | ||
471 | amp->amp_master = val; | ||
462 | awacs_amp_set_master(amp, amp->amp_master); | 472 | awacs_amp_set_master(amp, amp->amp_master); |
463 | return 1; | 473 | return 1; |
464 | } | 474 | } |
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c index 566b5ab9d4e8..465dd0466b9f 100644 --- a/sound/ppc/beep.c +++ b/sound/ppc/beep.c | |||
@@ -195,10 +195,13 @@ static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol, | |||
195 | struct snd_ctl_elem_value *ucontrol) | 195 | struct snd_ctl_elem_value *ucontrol) |
196 | { | 196 | { |
197 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 197 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
198 | int oval; | 198 | unsigned int oval, nval; |
199 | snd_assert(chip->beep, return -ENXIO); | 199 | snd_assert(chip->beep, return -ENXIO); |
200 | oval = chip->beep->volume; | 200 | oval = chip->beep->volume; |
201 | chip->beep->volume = ucontrol->value.integer.value[0]; | 201 | nval = ucontrol->value.integer.value[0]; |
202 | if (nval > 100) | ||
203 | return -EINVAL; | ||
204 | chip->beep->volume = nval; | ||
202 | return oval != chip->beep->volume; | 205 | return oval != chip->beep->volume; |
203 | } | 206 | } |
204 | 207 | ||
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c index e02263fe44dc..fec74e829743 100644 --- a/sound/ppc/burgundy.c +++ b/sound/ppc/burgundy.c | |||
@@ -136,6 +136,9 @@ snd_pmac_burgundy_write_volume(struct snd_pmac *chip, unsigned int address, | |||
136 | { | 136 | { |
137 | int hardvolume, lvolume, rvolume; | 137 | int hardvolume, lvolume, rvolume; |
138 | 138 | ||
139 | if (volume[0] < 0 || volume[0] > 100 || | ||
140 | volume[1] < 0 || volume[1] > 100) | ||
141 | return; /* -EINVAL */ | ||
139 | lvolume = volume[0] ? volume[0] + BURGUNDY_VOLUME_OFFSET : 0; | 142 | lvolume = volume[0] ? volume[0] + BURGUNDY_VOLUME_OFFSET : 0; |
140 | rvolume = volume[1] ? volume[1] + BURGUNDY_VOLUME_OFFSET : 0; | 143 | rvolume = volume[1] ? volume[1] + BURGUNDY_VOLUME_OFFSET : 0; |
141 | 144 | ||
@@ -301,14 +304,14 @@ static int snd_pmac_burgundy_put_volume_out(struct snd_kcontrol *kcontrol, | |||
301 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 304 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
302 | unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff); | 305 | unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff); |
303 | int stereo = (kcontrol->private_value >> 24) & 1; | 306 | int stereo = (kcontrol->private_value >> 24) & 1; |
304 | int oval, val; | 307 | unsigned int oval, val; |
305 | 308 | ||
306 | oval = ~snd_pmac_burgundy_rcb(chip, addr) & 0xff; | 309 | oval = ~snd_pmac_burgundy_rcb(chip, addr) & 0xff; |
307 | val = ucontrol->value.integer.value[0]; | 310 | val = ucontrol->value.integer.value[0] & 15; |
308 | if (stereo) | 311 | if (stereo) |
309 | val |= ucontrol->value.integer.value[1] << 4; | 312 | val |= (ucontrol->value.integer.value[1] & 15) << 4; |
310 | else | 313 | else |
311 | val |= ucontrol->value.integer.value[0] << 4; | 314 | val |= val << 4; |
312 | val = ~val & 0xff; | 315 | val = ~val & 0xff; |
313 | snd_pmac_burgundy_wcb(chip, addr, val); | 316 | snd_pmac_burgundy_wcb(chip, addr, val); |
314 | return val != oval; | 317 | return val != oval; |
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c index c5a1f0be6a4d..0c8145792d54 100644 --- a/sound/ppc/daca.c +++ b/sound/ppc/daca.c | |||
@@ -115,7 +115,7 @@ static int daca_put_deemphasis(struct snd_kcontrol *kcontrol, | |||
115 | return -ENODEV; | 115 | return -ENODEV; |
116 | change = mix->deemphasis != ucontrol->value.integer.value[0]; | 116 | change = mix->deemphasis != ucontrol->value.integer.value[0]; |
117 | if (change) { | 117 | if (change) { |
118 | mix->deemphasis = ucontrol->value.integer.value[0]; | 118 | mix->deemphasis = !!ucontrol->value.integer.value[0]; |
119 | daca_set_volume(mix); | 119 | daca_set_volume(mix); |
120 | } | 120 | } |
121 | return change; | 121 | return change; |
@@ -149,15 +149,20 @@ static int daca_put_volume(struct snd_kcontrol *kcontrol, | |||
149 | { | 149 | { |
150 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 150 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
151 | struct pmac_daca *mix; | 151 | struct pmac_daca *mix; |
152 | unsigned int vol[2]; | ||
152 | int change; | 153 | int change; |
153 | 154 | ||
154 | if (! (mix = chip->mixer_data)) | 155 | if (! (mix = chip->mixer_data)) |
155 | return -ENODEV; | 156 | return -ENODEV; |
156 | change = mix->left_vol != ucontrol->value.integer.value[0] || | 157 | vol[0] = ucontrol->value.integer.value[0]; |
157 | mix->right_vol != ucontrol->value.integer.value[1]; | 158 | vol[1] = ucontrol->value.integer.value[1]; |
159 | if (vol[0] > DACA_VOL_MAX || vol[1] > DACA_VOL_MAX) | ||
160 | return -EINVAL; | ||
161 | change = mix->left_vol != vol[0] || | ||
162 | mix->right_vol != vol[1]; | ||
158 | if (change) { | 163 | if (change) { |
159 | mix->left_vol = ucontrol->value.integer.value[0]; | 164 | mix->left_vol = vol[0]; |
160 | mix->right_vol = ucontrol->value.integer.value[1]; | 165 | mix->right_vol = vol[1]; |
161 | daca_set_volume(mix); | 166 | daca_set_volume(mix); |
162 | } | 167 | } |
163 | return change; | 168 | return change; |
@@ -188,7 +193,7 @@ static int daca_put_amp(struct snd_kcontrol *kcontrol, | |||
188 | return -ENODEV; | 193 | return -ENODEV; |
189 | change = mix->amp_on != ucontrol->value.integer.value[0]; | 194 | change = mix->amp_on != ucontrol->value.integer.value[0]; |
190 | if (change) { | 195 | if (change) { |
191 | mix->amp_on = ucontrol->value.integer.value[0]; | 196 | mix->amp_on = !!ucontrol->value.integer.value[0]; |
192 | i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG, | 197 | i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG, |
193 | mix->amp_on ? 0x05 : 0x04); | 198 | mix->amp_on ? 0x05 : 0x04); |
194 | } | 199 | } |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 4f9b19c90a43..8c47bebc77c8 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -1028,7 +1028,7 @@ static int pmac_auto_mute_put(struct snd_kcontrol *kcontrol, | |||
1028 | { | 1028 | { |
1029 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 1029 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
1030 | if (ucontrol->value.integer.value[0] != chip->auto_mute) { | 1030 | if (ucontrol->value.integer.value[0] != chip->auto_mute) { |
1031 | chip->auto_mute = ucontrol->value.integer.value[0]; | 1031 | chip->auto_mute = !!ucontrol->value.integer.value[0]; |
1032 | if (chip->update_automute) | 1032 | if (chip->update_automute) |
1033 | chip->update_automute(chip, 1); | 1033 | chip->update_automute(chip, 1); |
1034 | return 1; | 1034 | return 1; |
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 5821cdd0bec9..bacff3d1c189 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -275,14 +275,20 @@ static int tumbler_put_master_volume(struct snd_kcontrol *kcontrol, | |||
275 | { | 275 | { |
276 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 276 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
277 | struct pmac_tumbler *mix = chip->mixer_data; | 277 | struct pmac_tumbler *mix = chip->mixer_data; |
278 | unsigned int vol[2]; | ||
278 | int change; | 279 | int change; |
279 | 280 | ||
280 | snd_assert(mix, return -ENODEV); | 281 | snd_assert(mix, return -ENODEV); |
281 | change = mix->master_vol[0] != ucontrol->value.integer.value[0] || | 282 | vol[0] = ucontrol->value.integer.value[0]; |
282 | mix->master_vol[1] != ucontrol->value.integer.value[1]; | 283 | vol[1] = ucontrol->value.integer.value[1]; |
284 | if (vol[0] >= ARRAY_SIZE(master_volume_table) || | ||
285 | vol[1] >= ARRAY_SIZE(master_volume_table)) | ||
286 | return -EINVAL; | ||
287 | change = mix->master_vol[0] != vol[0] || | ||
288 | mix->master_vol[1] != vol[1]; | ||
283 | if (change) { | 289 | if (change) { |
284 | mix->master_vol[0] = ucontrol->value.integer.value[0]; | 290 | mix->master_vol[0] = vol[0]; |
285 | mix->master_vol[1] = ucontrol->value.integer.value[1]; | 291 | mix->master_vol[1] = vol[1]; |
286 | tumbler_set_master_volume(mix); | 292 | tumbler_set_master_volume(mix); |
287 | } | 293 | } |
288 | return change; | 294 | return change; |
@@ -417,13 +423,22 @@ static int tumbler_put_drc_value(struct snd_kcontrol *kcontrol, | |||
417 | { | 423 | { |
418 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 424 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
419 | struct pmac_tumbler *mix; | 425 | struct pmac_tumbler *mix; |
426 | unsigned int val; | ||
420 | int change; | 427 | int change; |
421 | 428 | ||
422 | if (! (mix = chip->mixer_data)) | 429 | if (! (mix = chip->mixer_data)) |
423 | return -ENODEV; | 430 | return -ENODEV; |
424 | change = mix->drc_range != ucontrol->value.integer.value[0]; | 431 | val = ucontrol->value.integer.value[0]; |
432 | if (chip->model == PMAC_TUMBLER) { | ||
433 | if (val > TAS3001_DRC_MAX) | ||
434 | return -EINVAL; | ||
435 | } else { | ||
436 | if (val > TAS3004_DRC_MAX) | ||
437 | return -EINVAL; | ||
438 | } | ||
439 | change = mix->drc_range != val; | ||
425 | if (change) { | 440 | if (change) { |
426 | mix->drc_range = ucontrol->value.integer.value[0]; | 441 | mix->drc_range = val; |
427 | if (chip->model == PMAC_TUMBLER) | 442 | if (chip->model == PMAC_TUMBLER) |
428 | tumbler_set_drc(mix); | 443 | tumbler_set_drc(mix); |
429 | else | 444 | else |
@@ -530,13 +545,17 @@ static int tumbler_put_mono(struct snd_kcontrol *kcontrol, | |||
530 | struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value; | 545 | struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value; |
531 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 546 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
532 | struct pmac_tumbler *mix; | 547 | struct pmac_tumbler *mix; |
548 | unsigned int vol; | ||
533 | int change; | 549 | int change; |
534 | 550 | ||
535 | if (! (mix = chip->mixer_data)) | 551 | if (! (mix = chip->mixer_data)) |
536 | return -ENODEV; | 552 | return -ENODEV; |
537 | change = mix->mono_vol[info->index] != ucontrol->value.integer.value[0]; | 553 | vol = ucontrol->value.integer.value[0]; |
554 | if (vol >= info->max) | ||
555 | return -EINVAL; | ||
556 | change = mix->mono_vol[info->index] != vol; | ||
538 | if (change) { | 557 | if (change) { |
539 | mix->mono_vol[info->index] = ucontrol->value.integer.value[0]; | 558 | mix->mono_vol[info->index] = vol; |
540 | tumbler_set_mono_volume(mix, info); | 559 | tumbler_set_mono_volume(mix, info); |
541 | } | 560 | } |
542 | return change; | 561 | return change; |
@@ -672,15 +691,21 @@ static int snapper_put_mix(struct snd_kcontrol *kcontrol, | |||
672 | int idx = (int)kcontrol->private_value; | 691 | int idx = (int)kcontrol->private_value; |
673 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); | 692 | struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
674 | struct pmac_tumbler *mix; | 693 | struct pmac_tumbler *mix; |
694 | unsigned int vol[2]; | ||
675 | int change; | 695 | int change; |
676 | 696 | ||
677 | if (! (mix = chip->mixer_data)) | 697 | if (! (mix = chip->mixer_data)) |
678 | return -ENODEV; | 698 | return -ENODEV; |
679 | change = mix->mix_vol[idx][0] != ucontrol->value.integer.value[0] || | 699 | vol[0] = ucontrol->value.integer.value[0]; |
680 | mix->mix_vol[idx][1] != ucontrol->value.integer.value[1]; | 700 | vol[1] = ucontrol->value.integer.value[1]; |
701 | if (vol[0] >= ARRAY_SIZE(mixer_volume_table) || | ||
702 | vol[1] >= ARRAY_SIZE(mixer_volume_table)) | ||
703 | return -EINVAL; | ||
704 | change = mix->mix_vol[idx][0] != vol[0] || | ||
705 | mix->mix_vol[idx][1] != vol[1]; | ||
681 | if (change) { | 706 | if (change) { |
682 | mix->mix_vol[idx][0] = ucontrol->value.integer.value[0]; | 707 | mix->mix_vol[idx][0] = vol[0]; |
683 | mix->mix_vol[idx][1] = ucontrol->value.integer.value[1]; | 708 | mix->mix_vol[idx][1] = vol[1]; |
684 | snapper_set_mix_vol(mix, idx); | 709 | snapper_set_mix_vol(mix, idx); |
685 | } | 710 | } |
686 | return change; | 711 | return change; |
@@ -784,7 +809,7 @@ static int snapper_get_capture_source(struct snd_kcontrol *kcontrol, | |||
784 | struct pmac_tumbler *mix = chip->mixer_data; | 809 | struct pmac_tumbler *mix = chip->mixer_data; |
785 | 810 | ||
786 | snd_assert(mix, return -ENODEV); | 811 | snd_assert(mix, return -ENODEV); |
787 | ucontrol->value.integer.value[0] = mix->capture_source; | 812 | ucontrol->value.enumerated.value[0] = mix->capture_source; |
788 | return 0; | 813 | return 0; |
789 | } | 814 | } |
790 | 815 | ||
@@ -796,9 +821,9 @@ static int snapper_put_capture_source(struct snd_kcontrol *kcontrol, | |||
796 | int change; | 821 | int change; |
797 | 822 | ||
798 | snd_assert(mix, return -ENODEV); | 823 | snd_assert(mix, return -ENODEV); |
799 | change = ucontrol->value.integer.value[0] != mix->capture_source; | 824 | change = ucontrol->value.enuemerated.item[0] != mix->capture_source; |
800 | if (change) { | 825 | if (change) { |
801 | mix->capture_source = !!ucontrol->value.integer.value[0]; | 826 | mix->capture_source = !!ucontrol->value.enumerated.item[0]; |
802 | snapper_set_capture_source(mix); | 827 | snapper_set_capture_source(mix); |
803 | } | 828 | } |
804 | return change; | 829 | return change; |