aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2009-03-17 09:30:31 -0400
committerTakashi Iwai <tiwai@suse.de>2009-03-18 02:50:44 -0400
commitee5047102cf632351c418060bfbe3b6eb5c42e7b (patch)
tree18819b5810d5d36aacd79a0d9a12dfceeb97fb0e /sound/pci/hda/hda_codec.c
parentb9591448e5160ccd353d8547ade018cfdf2b3e09 (diff)
ALSA: snd-hda-intel - add checks for invalid values to *query_supported_pcm()
If ratesp or formatsp values are zero, wrong values are passed to ALSA's the PCM midlevel code. The bug is showed more later than expected. Also, clean a bit the code. Signed-off-by: Jaroslav Kysela <perex@perex.cz> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index cf6339436de..b90a2400f53 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2539,12 +2539,11 @@ EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
2539static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 2539static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2540 u32 *ratesp, u64 *formatsp, unsigned int *bpsp) 2540 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
2541{ 2541{
2542 int i; 2542 unsigned int i, val, wcaps;
2543 unsigned int val, streams;
2544 2543
2545 val = 0; 2544 val = 0;
2546 if (nid != codec->afg && 2545 wcaps = get_wcaps(codec, nid);
2547 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { 2546 if (nid != codec->afg && (wcaps & AC_WCAP_FORMAT_OVRD)) {
2548 val = snd_hda_param_read(codec, nid, AC_PAR_PCM); 2547 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
2549 if (val == -1) 2548 if (val == -1)
2550 return -EIO; 2549 return -EIO;
@@ -2558,15 +2557,20 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2558 if (val & (1 << i)) 2557 if (val & (1 << i))
2559 rates |= rate_bits[i].alsa_bits; 2558 rates |= rate_bits[i].alsa_bits;
2560 } 2559 }
2560 if (rates == 0) {
2561 snd_printk(KERN_ERR "hda_codec: rates == 0 "
2562 "(nid=0x%x, val=0x%x, ovrd=%i)\n",
2563 nid, val,
2564 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0);
2565 return -EIO;
2566 }
2561 *ratesp = rates; 2567 *ratesp = rates;
2562 } 2568 }
2563 2569
2564 if (formatsp || bpsp) { 2570 if (formatsp || bpsp) {
2565 u64 formats = 0; 2571 u64 formats = 0;
2566 unsigned int bps; 2572 unsigned int streams, bps;
2567 unsigned int wcaps;
2568 2573
2569 wcaps = get_wcaps(codec, nid);
2570 streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); 2574 streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
2571 if (streams == -1) 2575 if (streams == -1)
2572 return -EIO; 2576 return -EIO;
@@ -2619,6 +2623,15 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2619 formats |= SNDRV_PCM_FMTBIT_U8; 2623 formats |= SNDRV_PCM_FMTBIT_U8;
2620 bps = 8; 2624 bps = 8;
2621 } 2625 }
2626 if (formats == 0) {
2627 snd_printk(KERN_ERR "hda_codec: formats == 0 "
2628 "(nid=0x%x, val=0x%x, ovrd=%i, "
2629 "streams=0x%x)\n",
2630 nid, val,
2631 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0,
2632 streams);
2633 return -EIO;
2634 }
2622 if (formatsp) 2635 if (formatsp)
2623 *formatsp = formats; 2636 *formatsp = formats;
2624 if (bpsp) 2637 if (bpsp)
@@ -2734,12 +2747,16 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
2734static int set_pcm_default_values(struct hda_codec *codec, 2747static int set_pcm_default_values(struct hda_codec *codec,
2735 struct hda_pcm_stream *info) 2748 struct hda_pcm_stream *info)
2736{ 2749{
2750 int err;
2751
2737 /* query support PCM information from the given NID */ 2752 /* query support PCM information from the given NID */
2738 if (info->nid && (!info->rates || !info->formats)) { 2753 if (info->nid && (!info->rates || !info->formats)) {
2739 snd_hda_query_supported_pcm(codec, info->nid, 2754 err = snd_hda_query_supported_pcm(codec, info->nid,
2740 info->rates ? NULL : &info->rates, 2755 info->rates ? NULL : &info->rates,
2741 info->formats ? NULL : &info->formats, 2756 info->formats ? NULL : &info->formats,
2742 info->maxbps ? NULL : &info->maxbps); 2757 info->maxbps ? NULL : &info->maxbps);
2758 if (err < 0)
2759 return err;
2743 } 2760 }
2744 if (info->ops.open == NULL) 2761 if (info->ops.open == NULL)
2745 info->ops.open = hda_pcm_default_open_close; 2762 info->ops.open = hda_pcm_default_open_close;