[ALSA] hda-codec - Allocate amp hash array dynamically
authorTakashi Iwai <tiwai@suse.de>
Mon, 7 Nov 2005 13:38:44 +0000 (14:38 +0100)
committerJaroslav Kysela <perex@suse.cz>
Tue, 3 Jan 2006 11:15:47 +0000 (12:15 +0100)
Modules: HDA Codec driver

Allocate amp hash array dynamically instead of static array.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h

index 0dbeeaf6113af4c36aa1a55077a3096bf45b44ac..e7fb182f90ed546f96c95f9d67c7e7d1edb87947 100644 (file)
@@ -465,6 +465,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
        codec->bus->caddr_tbl[codec->addr] = NULL;
        if (codec->patch_ops.free)
                codec->patch_ops.free(codec);
+       kfree(codec->amp_info);
        kfree(codec);
 }
 
@@ -586,6 +587,8 @@ static void init_amp_hash(struct hda_codec *codec)
 {
        memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));
        codec->num_amp_entries = 0;
+       codec->amp_info_size = 0;
+       codec->amp_info = NULL;
 }
 
 /* query the hash.  allocate an entry if not found. */
@@ -603,9 +606,22 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
        }
 
        /* add a new hash entry */
-       if (codec->num_amp_entries >= ARRAY_SIZE(codec->amp_info)) {
-               snd_printk(KERN_ERR "hda_codec: Tooooo many amps!\n");
-               return NULL;
+       if (codec->num_amp_entries >= codec->amp_info_size) {
+               /* reallocate the array */
+               int new_size = codec->amp_info_size + 64;
+               struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
+                                                       GFP_KERNEL);
+               if (! new_info) {
+                       snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n");
+                       return NULL;
+               }
+               if (codec->amp_info) {
+                       memcpy(new_info, codec->amp_info,
+                              codec->amp_info_size * sizeof(struct hda_amp_info));
+                       kfree(codec->amp_info);
+               }
+               codec->amp_info_size = new_size;
+               codec->amp_info = new_info;
        }
        cur = codec->num_amp_entries++;
        info = &codec->amp_info[cur];
index 1179d6cfa82a3ae20a36c03c14cecad07494d3a2..b0123adc569c0466a87846bc9d80b5fc490c9436 100644 (file)
@@ -545,7 +545,8 @@ struct hda_codec {
        /* hash for amp access */
        u16 amp_hash[32];
        int num_amp_entries;
-       struct hda_amp_info amp_info[128]; /* big enough? */
+       int amp_info_size;
+       struct hda_amp_info *amp_info;
 
        struct semaphore spdif_mutex;
        unsigned int spdif_status;      /* IEC958 status bits */