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 <linux/config.h>
#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
#ifndef CONFIG_SND_MAJOR /* standard configuration */
#define CONFIG_SND_MAJOR 116
static void choose_default_id(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;
char *id, *spos;
id = spos = card->shortname;
__change:
len = strlen(id);
__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 {
strcat(id, "_1");
idx_flag++;
} else {
read_lock(&snd_card_rwlock);
if ((card = snd_cards[idx]) != NULL) {
count++;
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);
idx,
card->id,
card->driver,
card->shortname);
- snd_iprintf(buffer, " %s\n",
+ snd_iprintf(buffer, " %s\n",
card->longname);
}
read_unlock(&snd_card_rwlock);
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)
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);
}
}
read_unlock(&snd_card_rwlock);
}
}
-#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)
#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;
{
unsigned long flags;
int c;
/* find free slot in the client table */
spin_lock_irqsave(&clients_lock, flags);
if (client_index < 0) {
/* 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 (clienttab[c] || clienttablock[c])
continue;
clienttab[client->number = c] = client;
if (down_interruptible(®ister_mutex))
return -ERESTARTSYS;
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 */
if (client == NULL) {
up(®ister_mutex);
return -ENOMEM; /* failure code */
return -EINVAL;
if (card == NULL && client_index > 63)
return -EINVAL;
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 (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 */
/* 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 */
if (client == NULL) {
up(®ister_mutex);
return -EBUSY; /* failure code */
continue;
if (mptr->card >= 0) {
if (mptr->device >= 0)
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
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
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);
snd_device_type_name(mptr->type));
}
up(&sound_mutex);
int register1 = -1, register2 = -1;
struct device *carddev = NULL;
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);
if (minor < 0)
return minor;
preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
int track2 = -1;
struct snd_minor *mptr;
int track2 = -1;
struct snd_minor *mptr;
+ if (card && card->number >= 8)
+ return 0;
if (minor < 0)
return minor;
down(&sound_oss_mutex);
if (minor < 0)
return minor;
down(&sound_oss_mutex);