mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 01:10:04 +00:00
ALSA: Add kconfig to specify the max card numbers
Currently ALSA supports up to 32 card instances when the dynamic minor is used. While 32 cards are usually big enough for normal use cases, there are sometimes weird requirements with more card support. Actually, this limitation, 32, comes from the index option, where you can pass the bit mask to assign the card. Other than that, we can actually give more cards up to the minor number limits (currently 256, which can be extended more, too). This patch adds a new Kconfig to specify the max card numbers, and changes a few places to accept more than 32 cards. The only incompatibility with high card numbers would be the handling of index option. The index option can be still used to pass the bitmask for card assignments, but this works only up to 32 slots. More than 32, no bitmask style option is available but only a single slot can be specified via index option. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
8edbb198a6
commit
7bb2491b35
3 changed files with 26 additions and 10 deletions
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
/* number of supported soundcards */
|
/* number of supported soundcards */
|
||||||
#ifdef CONFIG_SND_DYNAMIC_MINORS
|
#ifdef CONFIG_SND_DYNAMIC_MINORS
|
||||||
#define SNDRV_CARDS 32
|
#define SNDRV_CARDS CONFIG_SND_MAX_CARDS
|
||||||
#else
|
#else
|
||||||
#define SNDRV_CARDS 8 /* don't change - minor numbers */
|
#define SNDRV_CARDS 8 /* don't change - minor numbers */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -157,6 +157,15 @@ config SND_DYNAMIC_MINORS
|
||||||
|
|
||||||
If you are unsure about this, say N here.
|
If you are unsure about this, say N here.
|
||||||
|
|
||||||
|
config SND_MAX_CARDS
|
||||||
|
int "Max number of sound cards"
|
||||||
|
range 4 256
|
||||||
|
default 32
|
||||||
|
depends on SND_DYNAMIC_MINORS
|
||||||
|
help
|
||||||
|
Specify the max number of sound cards that can be assigned
|
||||||
|
on a single machine.
|
||||||
|
|
||||||
config SND_SUPPORT_OLD_API
|
config SND_SUPPORT_OLD_API
|
||||||
bool "Support old ALSA API"
|
bool "Support old ALSA API"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -46,7 +46,8 @@ static LIST_HEAD(shutdown_files);
|
||||||
|
|
||||||
static const struct file_operations snd_shutdown_f_ops;
|
static const struct file_operations snd_shutdown_f_ops;
|
||||||
|
|
||||||
static unsigned int snd_cards_lock; /* locked for registering/using */
|
/* locked for registering/using */
|
||||||
|
static DECLARE_BITMAP(snd_cards_lock, SNDRV_CARDS);
|
||||||
struct snd_card *snd_cards[SNDRV_CARDS];
|
struct snd_card *snd_cards[SNDRV_CARDS];
|
||||||
EXPORT_SYMBOL(snd_cards);
|
EXPORT_SYMBOL(snd_cards);
|
||||||
|
|
||||||
|
@ -167,29 +168,35 @@ int snd_card_create(int idx, const char *xid,
|
||||||
err = 0;
|
err = 0;
|
||||||
mutex_lock(&snd_card_mutex);
|
mutex_lock(&snd_card_mutex);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
|
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
|
||||||
/* idx == -1 == 0xffff means: take any free slot */
|
/* idx == -1 == 0xffff means: take any free slot */
|
||||||
if (~snd_cards_lock & idx & 1<<idx2) {
|
if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
|
||||||
|
continue;
|
||||||
|
if (!test_bit(idx2, snd_cards_lock)) {
|
||||||
if (module_slot_match(module, idx2)) {
|
if (module_slot_match(module, idx2)) {
|
||||||
idx = idx2;
|
idx = idx2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
|
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
|
||||||
/* idx == -1 == 0xffff means: take any free slot */
|
/* idx == -1 == 0xffff means: take any free slot */
|
||||||
if (~snd_cards_lock & idx & 1<<idx2) {
|
if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
|
||||||
|
continue;
|
||||||
|
if (!test_bit(idx2, snd_cards_lock)) {
|
||||||
if (!slots[idx2] || !*slots[idx2]) {
|
if (!slots[idx2] || !*slots[idx2]) {
|
||||||
idx = idx2;
|
idx = idx2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
else if (idx < snd_ecards_limit) {
|
else if (idx < snd_ecards_limit) {
|
||||||
if (snd_cards_lock & (1 << idx))
|
if (test_bit(idx, snd_cards_lock))
|
||||||
err = -EBUSY; /* invalid */
|
err = -EBUSY; /* invalid */
|
||||||
} else if (idx >= SNDRV_CARDS)
|
} else if (idx >= SNDRV_CARDS)
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
|
@ -199,7 +206,7 @@ int snd_card_create(int idx, const char *xid,
|
||||||
idx, snd_ecards_limit - 1, err);
|
idx, snd_ecards_limit - 1, err);
|
||||||
goto __error;
|
goto __error;
|
||||||
}
|
}
|
||||||
snd_cards_lock |= 1 << idx; /* lock it */
|
set_bit(idx, snd_cards_lock); /* lock it */
|
||||||
if (idx >= snd_ecards_limit)
|
if (idx >= snd_ecards_limit)
|
||||||
snd_ecards_limit = idx + 1; /* increase the limit */
|
snd_ecards_limit = idx + 1; /* increase the limit */
|
||||||
mutex_unlock(&snd_card_mutex);
|
mutex_unlock(&snd_card_mutex);
|
||||||
|
@ -249,7 +256,7 @@ int snd_card_locked(int card)
|
||||||
int locked;
|
int locked;
|
||||||
|
|
||||||
mutex_lock(&snd_card_mutex);
|
mutex_lock(&snd_card_mutex);
|
||||||
locked = snd_cards_lock & (1 << card);
|
locked = test_bit(card, snd_cards_lock);
|
||||||
mutex_unlock(&snd_card_mutex);
|
mutex_unlock(&snd_card_mutex);
|
||||||
return locked;
|
return locked;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +368,7 @@ int snd_card_disconnect(struct snd_card *card)
|
||||||
/* phase 1: disable fops (user space) operations for ALSA API */
|
/* phase 1: disable fops (user space) operations for ALSA API */
|
||||||
mutex_lock(&snd_card_mutex);
|
mutex_lock(&snd_card_mutex);
|
||||||
snd_cards[card->number] = NULL;
|
snd_cards[card->number] = NULL;
|
||||||
snd_cards_lock &= ~(1 << card->number);
|
clear_bit(card->number, snd_cards_lock);
|
||||||
mutex_unlock(&snd_card_mutex);
|
mutex_unlock(&snd_card_mutex);
|
||||||
|
|
||||||
/* phase 2: replace file->f_op with special dummy operations */
|
/* phase 2: replace file->f_op with special dummy operations */
|
||||||
|
|
Loading…
Reference in a new issue