From 361dab3ec2c59044f420cdf232523cd4af4e833e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 9 May 2012 14:35:27 +0200 Subject: ALSA: hda - Call snd_array_init() early and only once 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 --- sound/pci/hda/patch_sigmatel.c | 128 ++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 65 deletions(-) (limited to 'sound/pci/hda/patch_sigmatel.c') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 1f6fd584e1c..df13c0f8489 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2811,7 +2811,6 @@ stac_control_new(struct sigmatel_spec *spec, { struct snd_kcontrol_new *knew; - snd_array_init(&spec->kctls, sizeof(*knew), 32); knew = snd_array_new(&spec->kctls); if (!knew) return NULL; @@ -5159,20 +5158,34 @@ static const struct hda_codec_ops stac92xx_patch_ops = { .reboot_notify = stac92xx_shutup, }; +static int alloc_stac_spec(struct hda_codec *codec, int num_pins, + const hda_nid_t *pin_nids) +{ + struct sigmatel_spec *spec; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + codec->spec = spec; + codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */ + spec->num_pins = num_pins; + spec->pin_nids = pin_nids; + snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); + return 0; +} + static int patch_stac9200(struct hda_codec *codec) { struct sigmatel_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, ARRAY_SIZE(stac9200_pin_nids), + stac9200_pin_nids); + if (err < 0) + return err; - codec->no_trigger_sense = 1; - codec->spec = spec; + spec = codec->spec; spec->linear_tone_beep = 1; - spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); - spec->pin_nids = stac9200_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, stac9200_models, stac9200_cfg_tbl); @@ -5228,15 +5241,13 @@ static int patch_stac925x(struct hda_codec *codec) struct sigmatel_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, ARRAY_SIZE(stac925x_pin_nids), + stac925x_pin_nids); + if (err < 0) + return err; - codec->no_trigger_sense = 1; - codec->spec = spec; + spec = codec->spec; spec->linear_tone_beep = 1; - spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); - spec->pin_nids = stac925x_pin_nids; /* Check first for codec ID */ spec->board_config = snd_hda_check_board_codec_sid_config(codec, @@ -5311,19 +5322,17 @@ static int patch_stac92hd73xx(struct hda_codec *codec) { struct sigmatel_spec *spec; hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; - int err = 0; + int err; int num_dacs; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, ARRAY_SIZE(stac92hd73xx_pin_nids), + stac92hd73xx_pin_nids); + if (err < 0) + return err; - codec->no_trigger_sense = 1; - codec->spec = spec; + spec = codec->spec; spec->linear_tone_beep = 0; codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; - spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); - spec->pin_nids = stac92hd73xx_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_92HD73XX_MODELS, stac92hd73xx_models, @@ -5600,9 +5609,9 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) int default_polarity = -1; /* no default cfg */ int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, 0, NULL); /* pins filled later */ + if (err < 0) + return err; if (hp_bnb2011_with_dock(codec)) { snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f); @@ -5610,11 +5619,9 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) } codec->epss = 0; /* longer delay needed for D3 */ - codec->no_trigger_sense = 1; - codec->spec = spec; - stac92hd8x_fill_auto_spec(codec); + spec = codec->spec; spec->linear_tone_beep = 0; codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->digbeep_nid = 0x21; @@ -5783,21 +5790,19 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) struct sigmatel_spec *spec; const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; unsigned int pin_cfg; - int err = 0; + int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, STAC92HD71BXX_NUM_PINS, + stac92hd71bxx_pin_nids_4port); + if (err < 0) + return err; - codec->no_trigger_sense = 1; - codec->spec = spec; + spec = codec->spec; spec->linear_tone_beep = 0; codec->patch_ops = stac92xx_patch_ops; - spec->num_pins = STAC92HD71BXX_NUM_PINS; switch (codec->vendor_id) { case 0x111d76b6: case 0x111d76b7: - spec->pin_nids = stac92hd71bxx_pin_nids_4port; break; case 0x111d7603: case 0x111d7608: @@ -6028,15 +6033,13 @@ static int patch_stac922x(struct hda_codec *codec) struct sigmatel_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, ARRAY_SIZE(stac922x_pin_nids), + stac922x_pin_nids); + if (err < 0) + return err; - codec->no_trigger_sense = 1; - codec->spec = spec; + spec = codec->spec; spec->linear_tone_beep = 1; - spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); - spec->pin_nids = stac922x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, stac922x_models, stac922x_cfg_tbl); @@ -6133,16 +6136,14 @@ static int patch_stac927x(struct hda_codec *codec) struct sigmatel_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, ARRAY_SIZE(stac927x_pin_nids), + stac927x_pin_nids); + if (err < 0) + return err; - codec->no_trigger_sense = 1; - codec->spec = spec; + spec = codec->spec; spec->linear_tone_beep = 1; codec->slave_dig_outs = stac927x_slave_dig_outs; - spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); - spec->pin_nids = stac927x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, stac927x_models, stac927x_cfg_tbl); @@ -6269,15 +6270,13 @@ static int patch_stac9205(struct hda_codec *codec) struct sigmatel_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + err = alloc_stac_spec(codec, ARRAY_SIZE(stac9205_pin_nids), + stac9205_pin_nids); + if (err < 0) + return err; - codec->no_trigger_sense = 1; - codec->spec = spec; + spec = codec->spec; spec->linear_tone_beep = 1; - spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); - spec->pin_nids = stac9205_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, stac9205_models, stac9205_cfg_tbl); @@ -6425,14 +6424,13 @@ static int patch_stac9872(struct hda_codec *codec) struct sigmatel_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - codec->no_trigger_sense = 1; - codec->spec = spec; + err = alloc_stac_spec(codec, ARRAY_SIZE(stac9872_pin_nids), + stac9872_pin_nids); + if (err < 0) + return err; + + spec = codec->spec; spec->linear_tone_beep = 1; - spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); - spec->pin_nids = stac9872_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, stac9872_models, -- cgit v1.2.3