[ALSA] dynamic minors (6/6): increase maximum number of sound cards
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>
This commit is contained in:
Родитель
204bdb1b50
Коммит
d001544ded
|
@ -28,7 +28,12 @@
|
||||||
|
|
||||||
#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 */
|
#ifndef CONFIG_SND_MAJOR /* standard configuration */
|
||||||
#define CONFIG_SND_MAJOR 116
|
#define CONFIG_SND_MAJOR 116
|
||||||
|
|
|
@ -338,7 +338,7 @@ int snd_card_free_in_thread(struct snd_card *card)
|
||||||
|
|
||||||
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;
|
char *id, *spos;
|
||||||
|
|
||||||
id = spos = card->shortname;
|
id = spos = card->shortname;
|
||||||
|
@ -380,9 +380,12 @@ static void choose_default_id(struct snd_card *card)
|
||||||
|
|
||||||
__change:
|
__change:
|
||||||
len = strlen(id);
|
len = strlen(id);
|
||||||
if (idx_flag)
|
if (idx_flag) {
|
||||||
id[len-1]++;
|
if (id[len-1] != '9')
|
||||||
else if ((size_t)len <= sizeof(card->id) - 3) {
|
id[len-1]++;
|
||||||
|
else
|
||||||
|
id[len-1] = 'A';
|
||||||
|
} else if ((size_t)len <= sizeof(card->id) - 3) {
|
||||||
strcat(id, "_1");
|
strcat(id, "_1");
|
||||||
idx_flag++;
|
idx_flag++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -461,12 +464,12 @@ static void snd_card_info_read(struct snd_info_entry *entry,
|
||||||
read_lock(&snd_card_rwlock);
|
read_lock(&snd_card_rwlock);
|
||||||
if ((card = snd_cards[idx]) != NULL) {
|
if ((card = snd_cards[idx]) != NULL) {
|
||||||
count++;
|
count++;
|
||||||
snd_iprintf(buffer, "%i [%-15s]: %s - %s\n",
|
snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
|
||||||
idx,
|
idx,
|
||||||
card->id,
|
card->id,
|
||||||
card->driver,
|
card->driver,
|
||||||
card->shortname);
|
card->shortname);
|
||||||
snd_iprintf(buffer, " %s\n",
|
snd_iprintf(buffer, " %s\n",
|
||||||
card->longname);
|
card->longname);
|
||||||
}
|
}
|
||||||
read_unlock(&snd_card_rwlock);
|
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++) {
|
for (idx = 0; idx < SNDRV_CARDS; idx++) {
|
||||||
read_lock(&snd_card_rwlock);
|
read_lock(&snd_card_rwlock);
|
||||||
if ((card = snd_cards[idx]) != NULL)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,10 +43,6 @@ MODULE_DESCRIPTION("Memory allocator for ALSA system.");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
|
||||||
#ifndef SNDRV_CARDS
|
|
||||||
#define SNDRV_CARDS 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* 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_INPUT 0x0001
|
||||||
#define SNDRV_SEQ_LFLG_OUTPUT 0x0002
|
#define SNDRV_SEQ_LFLG_OUTPUT 0x0002
|
||||||
#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
|
#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;
|
unsigned long flags;
|
||||||
int c;
|
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 */
|
/* find free slot in the client table */
|
||||||
spin_lock_irqsave(&clients_lock, flags);
|
spin_lock_irqsave(&clients_lock, flags);
|
||||||
if (client_index < 0) {
|
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])
|
if (clienttab[c] || clienttablock[c])
|
||||||
continue;
|
continue;
|
||||||
clienttab[client->number = c] = client;
|
clienttab[client->number = c] = client;
|
||||||
|
@ -306,7 +319,7 @@ static int snd_seq_open(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
if (down_interruptible(®ister_mutex))
|
if (down_interruptible(®ister_mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
|
client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS, 0);
|
||||||
if (client == NULL) {
|
if (client == NULL) {
|
||||||
up(®ister_mutex);
|
up(®ister_mutex);
|
||||||
return -ENOMEM; /* failure code */
|
return -ENOMEM; /* failure code */
|
||||||
|
@ -2212,13 +2225,19 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (card == NULL && client_index > 63)
|
if (card == NULL && client_index > 63)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (card)
|
|
||||||
client_index += 64 + (card->number << 2);
|
|
||||||
|
|
||||||
if (down_interruptible(®ister_mutex))
|
if (down_interruptible(®ister_mutex))
|
||||||
return -ERESTARTSYS;
|
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) {
|
if (client == NULL) {
|
||||||
up(®ister_mutex);
|
up(®ister_mutex);
|
||||||
return -EBUSY; /* failure code */
|
return -EBUSY; /* failure code */
|
||||||
|
|
|
@ -358,15 +358,15 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
|
||||||
continue;
|
continue;
|
||||||
if (mptr->card >= 0) {
|
if (mptr->card >= 0) {
|
||||||
if (mptr->device >= 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,
|
minor, mptr->card, mptr->device,
|
||||||
snd_device_type_name(mptr->type));
|
snd_device_type_name(mptr->type));
|
||||||
else
|
else
|
||||||
snd_iprintf(buffer, "%3i: [%i] : %s\n",
|
snd_iprintf(buffer, "%3i: [%2i] : %s\n",
|
||||||
minor, mptr->card,
|
minor, mptr->card,
|
||||||
snd_device_type_name(mptr->type));
|
snd_device_type_name(mptr->type));
|
||||||
} else
|
} else
|
||||||
snd_iprintf(buffer, "%3i: : %s\n", minor,
|
snd_iprintf(buffer, "%3i: : %s\n", minor,
|
||||||
snd_device_type_name(mptr->type));
|
snd_device_type_name(mptr->type));
|
||||||
}
|
}
|
||||||
up(&sound_mutex);
|
up(&sound_mutex);
|
||||||
|
|
|
@ -105,6 +105,8 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
|
||||||
int register1 = -1, register2 = -1;
|
int register1 = -1, register2 = -1;
|
||||||
struct device *carddev = NULL;
|
struct device *carddev = NULL;
|
||||||
|
|
||||||
|
if (card && card->number >= 8)
|
||||||
|
return 0; /* ignore silently */
|
||||||
if (minor < 0)
|
if (minor < 0)
|
||||||
return minor;
|
return minor;
|
||||||
preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
|
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;
|
int track2 = -1;
|
||||||
struct snd_minor *mptr;
|
struct snd_minor *mptr;
|
||||||
|
|
||||||
|
if (card && card->number >= 8)
|
||||||
|
return 0;
|
||||||
if (minor < 0)
|
if (minor < 0)
|
||||||
return minor;
|
return minor;
|
||||||
down(&sound_oss_mutex);
|
down(&sound_oss_mutex);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче