[ALSA] dynamic minors (2/6): simplify storage of snd_minor structures

Modules: ALSA Core

Store the snd_minor structure pointers in one array instead of using a
separate list for each card.  This simplifies the mapping from device
files to minor struct by removing the need to know about the encoding
of the card number in the minor number.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 4d189ff..afbfd8d 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -35,25 +35,12 @@
 #include <sound/info.h>
 #include <linux/sound.h>
 
-#define SNDRV_OS_MINORS		256
+#define SNDRV_OSS_MINORS 128
 
-static struct list_head snd_oss_minors_hash[SNDRV_CARDS];
+static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
 
 static DECLARE_MUTEX(sound_oss_mutex);
 
-static struct snd_minor *snd_oss_minor_search(int minor)
-{
-	struct list_head *list;
-	struct snd_minor *mptr;
-
-	list_for_each(list, &snd_oss_minors_hash[SNDRV_MINOR_OSS_CARD(minor)]) {
-		mptr = list_entry(list, struct snd_minor, list);
-		if (mptr->number == minor)
-			return mptr;
-	}
-	return NULL;
-}
-
 static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
 {
 	int minor;
@@ -86,7 +73,7 @@
 	default:
 		return -EINVAL;
 	}
-	snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL);
+	snd_assert(minor >= 0 && minor < SNDRV_OSS_MINORS, return -EINVAL);
 	return minor;
 }
 
@@ -103,15 +90,15 @@
 
 	if (minor < 0)
 		return minor;
-	preg = kzalloc(sizeof(struct snd_minor), GFP_KERNEL);
+	preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
 	if (preg == NULL)
 		return -ENOMEM;
-	preg->number = minor;
 	preg->type = type;
+	preg->card = card ? card->number : -1;
 	preg->device = dev;
 	preg->f_ops = f_ops;
 	down(&sound_oss_mutex);
-	list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]);
+	snd_oss_minors[minor] = preg;
 	minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
 	switch (minor_unit) {
 	case SNDRV_MINOR_OSS_PCM:
@@ -143,7 +130,7 @@
       		unregister_sound_special(register2);
       	if (register1 >= 0)
       		unregister_sound_special(register1);
-      	list_del(&preg->list);
+	snd_oss_minors[minor] = NULL;
 	up(&sound_oss_mutex);
 	kfree(preg);
       	return -EBUSY;
@@ -159,7 +146,7 @@
 	if (minor < 0)
 		return minor;
 	down(&sound_oss_mutex);
-	mptr = snd_oss_minor_search(minor);
+	mptr = snd_oss_minors[minor];
 	if (mptr == NULL) {
 		up(&sound_oss_mutex);
 		return -ENOENT;
@@ -178,7 +165,7 @@
 	}
 	if (track2 >= 0)
 		unregister_sound_special(track2);
-	list_del(&mptr->list);
+	snd_oss_minors[minor] = NULL;
 	up(&sound_oss_mutex);
 	kfree(mptr);
 	return 0;
@@ -214,22 +201,20 @@
 static void snd_minor_info_oss_read(struct snd_info_entry *entry,
 				    struct snd_info_buffer *buffer)
 {
-	int card, dev;
-	struct list_head *list;
+	int minor;
 	struct snd_minor *mptr;
 
 	down(&sound_oss_mutex);
-	for (card = 0; card < SNDRV_CARDS; card++) {
-		list_for_each(list, &snd_oss_minors_hash[card]) {
-			mptr = list_entry(list, struct snd_minor, list);
-			dev = SNDRV_MINOR_OSS_DEVICE(mptr->number);
-		        if (dev != SNDRV_MINOR_OSS_SNDSTAT &&
-			    dev != SNDRV_MINOR_OSS_SEQUENCER &&
-			    dev != SNDRV_MINOR_OSS_MUSIC)
-				snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, dev, snd_oss_device_type_name(mptr->type));
-			else
-				snd_iprintf(buffer, "%3i:       : %s\n", mptr->number, snd_oss_device_type_name(mptr->type));
-		}
+	for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
+		if (!(mptr = snd_oss_minors[minor]))
+			continue;
+		if (mptr->card >= 0)
+			snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor,
+				    mptr->card, mptr->device,
+				    snd_oss_device_type_name(mptr->type));
+		else
+			snd_iprintf(buffer, "%3i:       : %s\n", minor,
+				    snd_oss_device_type_name(mptr->type));
 	}
 	up(&sound_oss_mutex);
 }
@@ -264,13 +249,4 @@
 	return 0;
 }
 
-int __init snd_oss_init_module(void)
-{
-	int card;
-	
-	for (card = 0; card < SNDRV_CARDS; card++)
-		INIT_LIST_HEAD(&snd_oss_minors_hash[card]);
-	return 0;
-}
-
 #endif /* CONFIG_SND_OSSEMUL */