[ALSA] hda-codec - Allocate amp hash array dynamically

Modules: HDA Codec driver

Allocate amp hash array dynamically instead of static array.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0dbeeaf..e7fb182 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -465,6 +465,7 @@
 	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 @@
 {
 	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 @@
 	}
 
 	/* 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];
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 1179d6c..b0123ad 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -545,7 +545,8 @@
 	/* 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 */