diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/usbmixer.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index ec9cdf986928..df8969188d15 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
@@ -461,7 +461,7 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
461 | unsigned int size, unsigned int __user *_tlv) | 461 | unsigned int size, unsigned int __user *_tlv) |
462 | { | 462 | { |
463 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 463 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
464 | DECLARE_TLV_DB_SCALE(scale, 0, 0, 0); | 464 | DECLARE_TLV_DB_MINMAX(scale, 0, 0); |
465 | 465 | ||
466 | if (size < sizeof(scale)) | 466 | if (size < sizeof(scale)) |
467 | return -ENOMEM; | 467 | return -ENOMEM; |
@@ -469,7 +469,16 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
469 | * while ALSA TLV contains in 1/100 dB unit | 469 | * while ALSA TLV contains in 1/100 dB unit |
470 | */ | 470 | */ |
471 | scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256; | 471 | scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256; |
472 | scale[3] = (convert_signed_value(cval, cval->res) * 100) / 256; | 472 | scale[3] = (convert_signed_value(cval, cval->max) * 100) / 256; |
473 | if (scale[3] <= scale[2]) { | ||
474 | /* something is wrong; assume it's either from/to 0dB */ | ||
475 | if (scale[2] < 0) | ||
476 | scale[3] = 0; | ||
477 | else if (scale[2] > 0) | ||
478 | scale[2] = 0; | ||
479 | else /* totally crap, return an error */ | ||
480 | return -EINVAL; | ||
481 | } | ||
473 | if (copy_to_user(_tlv, scale, sizeof(scale))) | 482 | if (copy_to_user(_tlv, scale, sizeof(scale))) |
474 | return -EFAULT; | 483 | return -EFAULT; |
475 | return 0; | 484 | return 0; |