[ALSA] dynamic minors (6/6): increase maximum number of sound cards
authorClemens Ladisch <clemens@ladisch.de>
Sun, 20 Nov 2005 13:09:05 +0000 (14:09 +0100)
committerJaroslav Kysela <perex@suse.cz>
Tue, 3 Jan 2006 11:29:21 +0000 (12:29 +0100)
Modules: ALSA Core,Memalloc module,ALSA sequencer

With dynamic minor numbers, we can increase the number of sound cards.

This requires that the sequencer client numbers of some kernel drivers
are allocated dynamically, too.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
include/sound/driver.h
sound/core/init.c
sound/core/memalloc.c
sound/core/seq/seq_clientmgr.c
sound/core/sound.c
sound/core/sound_oss.c

index 3f0416ac24d95fe9d711165451028e7e85a38747..89c6a73f39206b06691aee19dab5a29c26327d74 100644 (file)
 
 #include <linux/config.h>
 
-#define SNDRV_CARDS            8       /* number of supported soundcards - don't change - minor numbers */
+/* number of supported soundcards */
+#ifdef CONFIG_SND_DYNAMIC_MINORS
+#define SNDRV_CARDS 32
+#else
+#define SNDRV_CARDS 8          /* don't change - minor numbers */
+#endif
 
 #ifndef CONFIG_SND_MAJOR       /* standard configuration */
 #define CONFIG_SND_MAJOR       116
index 728bb2ce0bc773c2e168e9f0fe2ff6087e687250..58e17d385f8d9cc65a58cdfa84a13a64f6d63b0d 100644 (file)
@@ -338,7 +338,7 @@ int snd_card_free_in_thread(struct snd_card *card)
 
 static void choose_default_id(struct snd_card *card)
 {
-       int i, len, idx_flag = 0, loops = 8;
+       int i, len, idx_flag = 0, loops = SNDRV_CARDS;
        char *id, *spos;
        
        id = spos = card->shortname;    
@@ -380,9 +380,12 @@ static void choose_default_id(struct snd_card *card)
 
              __change:
                len = strlen(id);
-               if (idx_flag)
-                       id[len-1]++;
-               else if ((size_t)len <= sizeof(card->id) - 3) {
+               if (idx_flag) {
+                       if (id[len-1] != '9')
+                               id[len-1]++;
+                       else
+                               id[len-1] = 'A';
+               } else if ((size_t)len <= sizeof(card->id) - 3) {
                        strcat(id, "_1");
                        idx_flag++;
                } else {
@@ -461,12 +464,12 @@ static void snd_card_info_read(struct snd_info_entry *entry,
                read_lock(&snd_card_rwlock);
                if ((card = snd_cards[idx]) != NULL) {
                        count++;
-                       snd_iprintf(buffer, "%i [%-15s]: %s - %s\n",
+                       snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
                                        idx,
                                        card->id,
                                        card->driver,
                                        card->shortname);
-                       snd_iprintf(buffer, "                     %s\n",
+                       snd_iprintf(buffer, "                      %s\n",
                                        card->longname);
                }
                read_unlock(&snd_card_rwlock);
@@ -508,7 +511,8 @@ static void snd_card_module_info_read(struct snd_info_entry *entry,
        for (idx = 0; idx < SNDRV_CARDS; idx++) {
                read_lock(&snd_card_rwlock);
                if ((card = snd_cards[idx]) != NULL)
-                       snd_iprintf(buffer, "%i %s\n", idx, card->module->name);
+                       snd_iprintf(buffer, "%2i %s\n",
+                                   idx, card->module->name);
                read_unlock(&snd_card_rwlock);
        }
 }
index e4b8959dd4bba4ff75f2617bdc76b843ff51b41c..19b3dcbb09c23bdaad0192e53877116501275490 100644 (file)
@@ -43,10 +43,6 @@ MODULE_DESCRIPTION("Memory allocator for ALSA system.");
 MODULE_LICENSE("GPL");
 
 
-#ifndef SNDRV_CARDS
-#define SNDRV_CARDS    8
-#endif
-
 /*
  */
 
index 95bd5ae92b9267e912b3b3b6719e7acc9ab517fc..2a9c6b316b140c1ee38a29b43eaa6280d240bcf7 100644 (file)
  * 
  */
 
+/* range for dynamically allocated client numbers of kernel drivers */
+#define SNDRV_SEQ_DYNAMIC_CLIENT_BEGIN 16
+#define SNDRV_SEQ_DYNAMIC_CLIENT_END   48
+
 #define SNDRV_SEQ_LFLG_INPUT   0x0001
 #define SNDRV_SEQ_LFLG_OUTPUT  0x0002
 #define SNDRV_SEQ_LFLG_OPEN    (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
@@ -203,7 +207,8 @@ int __init client_init_data(void)
 }
 
 
-static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
+static struct snd_seq_client *seq_create_client1(int client_index, int poolsize,
+                                                int kernel_client)
 {
        unsigned long flags;
        int c;
@@ -227,7 +232,15 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
        /* find free slot in the client table */
        spin_lock_irqsave(&clients_lock, flags);
        if (client_index < 0) {
-               for (c = 128; c < SNDRV_SEQ_MAX_CLIENTS; c++) {
+               int cmin, cmax;
+               if (kernel_client) {
+                       cmin = SNDRV_SEQ_DYNAMIC_CLIENT_BEGIN;
+                       cmax = SNDRV_SEQ_DYNAMIC_CLIENT_END;
+               } else {
+                       cmin = 128;
+                       cmax = SNDRV_SEQ_MAX_CLIENTS;
+               }
+               for (c = cmin; c < cmax; c++) {
                        if (clienttab[c] || clienttablock[c])
                                continue;
                        clienttab[client->number = c] = client;
@@ -306,7 +319,7 @@ static int snd_seq_open(struct inode *inode, struct file *file)
 
        if (down_interruptible(&register_mutex))
                return -ERESTARTSYS;
-       client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
+       client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS, 0);
        if (client == NULL) {
                up(&register_mutex);
                return -ENOMEM; /* failure code */
@@ -2212,13 +2225,19 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
                return -EINVAL;
        if (card == NULL && client_index > 63)
                return -EINVAL;
-       if (card)
-               client_index += 64 + (card->number << 2);
 
        if (down_interruptible(&register_mutex))
                return -ERESTARTSYS;
+
+       if (card) {
+               if (card->number < 16)
+                       client_index += 64 + (card->number << 2);
+               else
+                       client_index = -1;
+       }
+
        /* empty write queue as default */
-       client = seq_create_client1(client_index, 0);
+       client = seq_create_client1(client_index, 0, 1);
        if (client == NULL) {
                up(&register_mutex);
                return -EBUSY;  /* failure code */
index 5e22283078fc38fb64a59df64df6b9d822772fff..5febd0545d7d8cc9d0c3cfa6b6f67accee0648c7 100644 (file)
@@ -358,15 +358,15 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
                        continue;
                if (mptr->card >= 0) {
                        if (mptr->device >= 0)
-                               snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n",
+                               snd_iprintf(buffer, "%3i: [%2i-%2i]: %s\n",
                                            minor, mptr->card, mptr->device,
                                            snd_device_type_name(mptr->type));
                        else
-                               snd_iprintf(buffer, "%3i: [%i]   : %s\n",
+                               snd_iprintf(buffer, "%3i: [%2i]   : %s\n",
                                            minor, mptr->card,
                                            snd_device_type_name(mptr->type));
                } else
-                       snd_iprintf(buffer, "%3i:       : %s\n", minor,
+                       snd_iprintf(buffer, "%3i:        : %s\n", minor,
                                    snd_device_type_name(mptr->type));
        }
        up(&sound_mutex);
index b9e89cac4c5dba103a91175a2dbcaa319931589b..3ae1c0d7ffd086256d2ceece62395125a75e0e9e 100644 (file)
@@ -105,6 +105,8 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
        int register1 = -1, register2 = -1;
        struct device *carddev = NULL;
 
+       if (card && card->number >= 8)
+               return 0; /* ignore silently */
        if (minor < 0)
                return minor;
        preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
@@ -162,6 +164,8 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
        int track2 = -1;
        struct snd_minor *mptr;
 
+       if (card && card->number >= 8)
+               return 0;
        if (minor < 0)
                return minor;
        down(&sound_oss_mutex);