aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-02-16 10:38:07 -0500
committerTakashi Iwai <tiwai@suse.de>2012-02-16 10:39:14 -0500
commitc14c95f62ecb8710af14ae0d48e01991b70bb6f4 (patch)
tree4c76b1d76cbb9dac76662a92b172a22e3a6b04f3 /sound
parent8866f405efd4171f9d9c91901d2dd02f01bacb60 (diff)
ALSA: hda/realtek - Fix overflow of vol/sw check bitmap
The bitmap introduced in the commit [527e4d73: ALSA: hda/realtek - Fix missing volume controls with ALC260] is too narrow for some codecs, which may have more NIDs than 0x20, thus it may overflow the bitmap array on them. Just double the number to cover all and also add a sanity-check code to be safer. Cc: <stable@kernel.org> [v3.2+] Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_realtek.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1358987c49d8..389a28a21fa9 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -80,6 +80,8 @@ enum {
80 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ 80 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
81}; 81};
82 82
83#define MAX_VOL_NIDS 0x40
84
83struct alc_spec { 85struct alc_spec {
84 /* codec parameterization */ 86 /* codec parameterization */
85 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 87 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -118,8 +120,8 @@ struct alc_spec {
118 const hda_nid_t *capsrc_nids; 120 const hda_nid_t *capsrc_nids;
119 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 121 hda_nid_t dig_in_nid; /* digital-in NID; optional */
120 hda_nid_t mixer_nid; /* analog-mixer NID */ 122 hda_nid_t mixer_nid; /* analog-mixer NID */
121 DECLARE_BITMAP(vol_ctls, 0x20 << 1); 123 DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
122 DECLARE_BITMAP(sw_ctls, 0x20 << 1); 124 DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
123 125
124 /* capture setup for dynamic dual-adc switch */ 126 /* capture setup for dynamic dual-adc switch */
125 hda_nid_t cur_adc; 127 hda_nid_t cur_adc;
@@ -3149,7 +3151,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3149static inline unsigned int get_ctl_pos(unsigned int data) 3151static inline unsigned int get_ctl_pos(unsigned int data)
3150{ 3152{
3151 hda_nid_t nid = get_amp_nid_(data); 3153 hda_nid_t nid = get_amp_nid_(data);
3152 unsigned int dir = get_amp_direction_(data); 3154 unsigned int dir;
3155 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3156 return 0;
3157 dir = get_amp_direction_(data);
3153 return (nid << 1) | dir; 3158 return (nid << 1) | dir;
3154} 3159}
3155 3160