Skip to content

Commit

Permalink
ALSA: hda - Call snd_array_init() early and only once
Browse files Browse the repository at this point in the history
This is a preliminary patch for introducing a protection to access
races of snd_array instances.  Call snd_array_init() appropriately
at the initialization time and don't call it twice.

Also the allocations of codec-spec structs are cleaned up by helper
functions in patch_sigmatel.c and patch_analog.c.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Nov 28, 2012
1 parent 04324cc commit 361dab3
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 103 deletions.
1 change: 1 addition & 0 deletions sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);

#ifdef CONFIG_PM
Expand Down
1 change: 0 additions & 1 deletion sound/pci/hda/hda_jack.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
if (jack)
return jack;
snd_array_init(&codec->jacktbl, sizeof(*jack), 16);
jack = snd_array_new(&codec->jacktbl);
if (!jack)
return NULL;
Expand Down
72 changes: 38 additions & 34 deletions sound/pci/hda/patch_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,16 +1246,27 @@ static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
}

static int patch_ad1986a(struct hda_codec *codec)
static int alloc_ad_spec(struct hda_codec *codec)
{
struct ad198x_spec *spec;
int err, board_config;

spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
if (!spec)
return -ENOMEM;

codec->spec = spec;
snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
return 0;
}

static int patch_ad1986a(struct hda_codec *codec)
{
struct ad198x_spec *spec;
int err, board_config;

err = alloc_ad_spec(codec);
if (err < 0)
return err;
spec = codec->spec;

err = snd_hda_attach_beep_device(codec, 0x19);
if (err < 0) {
Expand Down Expand Up @@ -1548,11 +1559,10 @@ static int patch_ad1983(struct hda_codec *codec)
struct ad198x_spec *spec;
int err;

spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;

codec->spec = spec;
err = alloc_ad_spec(codec);
if (err < 0)
return err;
spec = codec->spec;

err = snd_hda_attach_beep_device(codec, 0x10);
if (err < 0) {
Expand Down Expand Up @@ -1954,11 +1964,10 @@ static int patch_ad1981(struct hda_codec *codec)
struct ad198x_spec *spec;
int err, board_config;

spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
err = alloc_ad_spec(codec);
if (err < 0)
return -ENOMEM;

codec->spec = spec;
spec = codec->spec;

err = snd_hda_attach_beep_device(codec, 0x10);
if (err < 0) {
Expand Down Expand Up @@ -2836,7 +2845,6 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
{
struct snd_kcontrol_new *knew;

snd_array_init(&spec->kctls, sizeof(*knew), 32);
knew = snd_array_new(&spec->kctls);
if (!knew)
return -ENOMEM;
Expand Down Expand Up @@ -3254,11 +3262,10 @@ static int patch_ad1988(struct hda_codec *codec)
struct ad198x_spec *spec;
int err, board_config;

spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;

codec->spec = spec;
err = alloc_ad_spec(codec);
if (err < 0)
return err;
spec = codec->spec;

if (is_rev2(codec))
snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
Expand Down Expand Up @@ -3574,11 +3581,10 @@ static int patch_ad1884(struct hda_codec *codec)
struct ad198x_spec *spec;
int err;

spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;

codec->spec = spec;
err = alloc_ad_spec(codec);
if (err < 0)
return err;
spec = codec->spec;

err = snd_hda_attach_beep_device(codec, 0x10);
if (err < 0) {
Expand Down Expand Up @@ -4574,11 +4580,10 @@ static int patch_ad1884a(struct hda_codec *codec)
struct ad198x_spec *spec;
int err, board_config;

spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;

codec->spec = spec;
err = alloc_ad_spec(codec);
if (err < 0)
return err;
spec = codec->spec;

err = snd_hda_attach_beep_device(codec, 0x10);
if (err < 0) {
Expand Down Expand Up @@ -4987,11 +4992,10 @@ static int patch_ad1882(struct hda_codec *codec)
struct ad198x_spec *spec;
int err, board_config;

spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;

codec->spec = spec;
err = alloc_ad_spec(codec);
if (err < 0)
return err;
spec = codec->spec;

err = snd_hda_attach_beep_device(codec, 0x10);
if (err < 0) {
Expand Down
4 changes: 2 additions & 2 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,6 @@ static const struct snd_kcontrol_new alc_automute_mode_enum = {

static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
{
snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
return snd_array_new(&spec->kctls);
}

Expand Down Expand Up @@ -3605,7 +3604,6 @@ static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec,
{
struct alc_spec *spec = codec->spec;
struct hda_bind_ctls **ctlp, *ctl;
snd_array_init(&spec->bind_ctls, sizeof(ctl), 8);
ctlp = snd_array_new(&spec->bind_ctls);
if (!ctlp)
return NULL;
Expand Down Expand Up @@ -4376,6 +4374,8 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
codec->spec = spec;
spec->mixer_nid = mixer_nid;
snd_hda_gen_init(&spec->gen);
snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
snd_array_init(&spec->bind_ctls, sizeof(struct hda_bind_ctls *), 8);

err = alc_codec_rename_from_preset(codec);
if (err < 0) {
Expand Down
Loading

0 comments on commit 361dab3

Please sign in to comment.