Skip to content

Commit

Permalink
ALSA: hda - Fix undefined symbol due to builtin/module mixup
Browse files Browse the repository at this point in the history
Even after the fix for leftover kconfig handling (commit f8f1bec),
the current code still doesn't handle properly the builtin/module
mixup case between the core snd-hda-codec and other codec drivers.
For example, when CONFIG_SND_HDA_INTEL=y and
CONFIG_SND_HDA_CODEC_HDMI=m, it'll end up with an unresolved symbol
snd_hda_parse_hdmi_codec.  This patch fixes the issue.

Now codec->parser points to the parser object *only* when a module
(either generic or HDMI parser) is loaded and bound.  When a builtin
symbol is used, codec->parser still points to NULL.  This is the
difference from the previous versions.

Fixes: f8f1bec ('ALSA: hda - Fix leftover ifdef checks after modularization')
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Feb 10, 2014
1 parent f88abaa commit ef8e39b
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1339,23 +1339,15 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
/*
* Dynamic symbol binding for the codec parsers
*/
#ifdef MODULE
#define load_parser_sym(sym) ((int (*)(struct hda_codec *))symbol_request(sym))
#define unload_parser_addr(addr) symbol_put_addr(addr)
#else
#define load_parser_sym(sym) (sym)
#define unload_parser_addr(addr) do {} while (0)
#endif

#define load_parser(codec, sym) \
((codec)->parser = load_parser_sym(sym))
((codec)->parser = (int (*)(struct hda_codec *))symbol_request(sym))

static void unload_parser(struct hda_codec *codec)
{
if (codec->parser) {
unload_parser_addr(codec->parser);
codec->parser = NULL;
}
if (codec->parser)
symbol_put_addr(codec->parser);
codec->parser = NULL;
}

/*
Expand Down Expand Up @@ -1620,12 +1612,20 @@ int snd_hda_codec_configure(struct hda_codec *codec)
patch = codec->preset->patch;
if (!patch) {
unload_parser(codec); /* to be sure */
if (is_likely_hdmi_codec(codec))
if (is_likely_hdmi_codec(codec)) {
#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
patch = load_parser(codec, snd_hda_parse_hdmi_codec);
#if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
if (!patch)
#elif IS_BUILTIN(CONFIG_SND_HDA_CODEC_HDMI)
patch = snd_hda_parse_hdmi_codec;
#endif
}
if (!patch) {
#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
patch = load_parser(codec, snd_hda_parse_generic_codec);
#elif IS_BUILTIN(CONFIG_SND_HDA_GENERIC)
patch = snd_hda_parse_generic_codec;
#endif
}
if (!patch) {
printk(KERN_ERR "hda-codec: No codec parser is available\n");
return -ENODEV;
Expand Down

0 comments on commit ef8e39b

Please sign in to comment.