aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/init.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-05-15 02:46:39 -0400
committerTakashi Iwai <tiwai@suse.de>2013-05-24 10:41:46 -0400
commit7bb2491b35a254fe6fd592c32a142a2f2f31fe6e (patch)
treebe7933980d3449e54cad4395e3b53185324f29c3 /sound/core/init.c
parent8edbb198a62e2c3d0bea06ce50a4d45a009849b6 (diff)
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>
Diffstat (limited to 'sound/core/init.c')
-rw-r--r--sound/core/init.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/sound/core/init.c b/sound/core/init.c
index ed4a4811b6a1..6b9087115da2 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -46,7 +46,8 @@ static LIST_HEAD(shutdown_files);
46 46
47static const struct file_operations snd_shutdown_f_ops; 47static const struct file_operations snd_shutdown_f_ops;
48 48
49static unsigned int snd_cards_lock; /* locked for registering/using */ 49/* locked for registering/using */
50static DECLARE_BITMAP(snd_cards_lock, SNDRV_CARDS);
50struct snd_card *snd_cards[SNDRV_CARDS]; 51struct snd_card *snd_cards[SNDRV_CARDS];
51EXPORT_SYMBOL(snd_cards); 52EXPORT_SYMBOL(snd_cards);
52 53
@@ -167,29 +168,35 @@ int snd_card_create(int idx, const char *xid,
167 err = 0; 168 err = 0;
168 mutex_lock(&snd_card_mutex); 169 mutex_lock(&snd_card_mutex);
169 if (idx < 0) { 170 if (idx < 0) {
170 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 171 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
171 /* idx == -1 == 0xffff means: take any free slot */ 172 /* idx == -1 == 0xffff means: take any free slot */
172 if (~snd_cards_lock & idx & 1<<idx2) { 173 if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
174 continue;
175 if (!test_bit(idx2, snd_cards_lock)) {
173 if (module_slot_match(module, idx2)) { 176 if (module_slot_match(module, idx2)) {
174 idx = idx2; 177 idx = idx2;
175 break; 178 break;
176 } 179 }
177 } 180 }
181 }
178 } 182 }
179 if (idx < 0) { 183 if (idx < 0) {
180 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 184 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
181 /* idx == -1 == 0xffff means: take any free slot */ 185 /* idx == -1 == 0xffff means: take any free slot */
182 if (~snd_cards_lock & idx & 1<<idx2) { 186 if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
187 continue;
188 if (!test_bit(idx2, snd_cards_lock)) {
183 if (!slots[idx2] || !*slots[idx2]) { 189 if (!slots[idx2] || !*slots[idx2]) {
184 idx = idx2; 190 idx = idx2;
185 break; 191 break;
186 } 192 }
187 } 193 }
194 }
188 } 195 }
189 if (idx < 0) 196 if (idx < 0)
190 err = -ENODEV; 197 err = -ENODEV;
191 else if (idx < snd_ecards_limit) { 198 else if (idx < snd_ecards_limit) {
192 if (snd_cards_lock & (1 << idx)) 199 if (test_bit(idx, snd_cards_lock))
193 err = -EBUSY; /* invalid */ 200 err = -EBUSY; /* invalid */
194 } else if (idx >= SNDRV_CARDS) 201 } else if (idx >= SNDRV_CARDS)
195 err = -ENODEV; 202 err = -ENODEV;
@@ -199,7 +206,7 @@ int snd_card_create(int idx, const char *xid,
199 idx, snd_ecards_limit - 1, err); 206 idx, snd_ecards_limit - 1, err);
200 goto __error; 207 goto __error;
201 } 208 }
202 snd_cards_lock |= 1 << idx; /* lock it */ 209 set_bit(idx, snd_cards_lock); /* lock it */
203 if (idx >= snd_ecards_limit) 210 if (idx >= snd_ecards_limit)
204 snd_ecards_limit = idx + 1; /* increase the limit */ 211 snd_ecards_limit = idx + 1; /* increase the limit */
205 mutex_unlock(&snd_card_mutex); 212 mutex_unlock(&snd_card_mutex);
@@ -249,7 +256,7 @@ int snd_card_locked(int card)
249 int locked; 256 int locked;
250 257
251 mutex_lock(&snd_card_mutex); 258 mutex_lock(&snd_card_mutex);
252 locked = snd_cards_lock & (1 << card); 259 locked = test_bit(card, snd_cards_lock);
253 mutex_unlock(&snd_card_mutex); 260 mutex_unlock(&snd_card_mutex);
254 return locked; 261 return locked;
255} 262}
@@ -361,7 +368,7 @@ int snd_card_disconnect(struct snd_card *card)
361 /* phase 1: disable fops (user space) operations for ALSA API */ 368 /* phase 1: disable fops (user space) operations for ALSA API */
362 mutex_lock(&snd_card_mutex); 369 mutex_lock(&snd_card_mutex);
363 snd_cards[card->number] = NULL; 370 snd_cards[card->number] = NULL;
364 snd_cards_lock &= ~(1 << card->number); 371 clear_bit(card->number, snd_cards_lock);
365 mutex_unlock(&snd_card_mutex); 372 mutex_unlock(&snd_card_mutex);
366 373
367 /* phase 2: replace file->f_op with special dummy operations */ 374 /* phase 2: replace file->f_op with special dummy operations */