#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
 
 
 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;    
 
              __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 {
                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);
        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);
        }
 }
 
 MODULE_LICENSE("GPL");
 
 
-#ifndef SNDRV_CARDS
-#define SNDRV_CARDS    8
-#endif
-
 /*
  */
 
 
  * 
  */
 
+/* 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)
 }
 
 
-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;
        /* 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;
 
        if (down_interruptible(®ister_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(®ister_mutex);
                return -ENOMEM; /* failure code */
                return -EINVAL;
        if (card == NULL && client_index > 63)
                return -EINVAL;
-       if (card)
-               client_index += 64 + (card->number << 2);
 
        if (down_interruptible(®ister_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(®ister_mutex);
                return -EBUSY;  /* failure code */
 
                        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);
 
        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);
        int track2 = -1;
        struct snd_minor *mptr;
 
+       if (card && card->number >= 8)
+               return 0;
        if (minor < 0)
                return minor;
        down(&sound_oss_mutex);