aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-11-15 10:14:12 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:25 -0500
commitd4079ac49a08e36d6839a9ceb26aec8c24c9ed82 (patch)
tree91ebc493375fd4e7fa84c3a6ab67a885121b1c81 /sound
parentd05ab185b770de96399766be6bcb5769ab99bc09 (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>
Diffstat (limited to 'sound')
-rw-r--r--sound/ppc/awacs.c20
-rw-r--r--sound/ppc/beep.c7
-rw-r--r--sound/ppc/burgundy.c11
-rw-r--r--sound/ppc/daca.c17
-rw-r--r--sound/ppc/pmac.c2
-rw-r--r--sound/ppc/tumbler.c55
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;