aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-05-15 13:49:05 -0400
committerJaroslav Kysela <perex@suse.cz>2006-06-22 15:33:37 -0400
commit746df94898554b3d8e91d855e934852e626c701c (patch)
treedc312e426d52804d98080af18f12f5b14010d2e5
parent0defb2672d7cde8d048eec35c183da7b88adbd9e (diff)
[ALSA] Fix rwlock around snd_iprintf() in sound core
Fixed rwlock around snd_iprintf() in sound core part. Replaced with mutex. Also, make mutex and flags static variables with addition of snd_card_locked() function (just for sound.c). Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/core.h3
-rw-r--r--sound/core/init.c51
-rw-r--r--sound/core/sound.c7
3 files changed, 33 insertions, 28 deletions
diff --git a/include/sound/core.h b/include/sound/core.h
index 5135147f20e8..5d184be0ff72 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -233,9 +233,8 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size
233 233
234/* init.c */ 234/* init.c */
235 235
236extern unsigned int snd_cards_lock;
237extern struct snd_card *snd_cards[SNDRV_CARDS]; 236extern struct snd_card *snd_cards[SNDRV_CARDS];
238extern rwlock_t snd_card_rwlock; 237int snd_card_locked(int card);
239#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 238#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
240#define SND_MIXER_OSS_NOTIFY_REGISTER 0 239#define SND_MIXER_OSS_NOTIFY_REGISTER 0
241#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1 240#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1
diff --git a/sound/core/init.c b/sound/core/init.c
index 2ff0e5e90865..38b2d4a9d672 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -38,11 +38,11 @@ struct snd_shutdown_f_ops {
38 struct snd_shutdown_f_ops *next; 38 struct snd_shutdown_f_ops *next;
39}; 39};
40 40
41unsigned int snd_cards_lock = 0; /* locked for registering/using */ 41static unsigned int snd_cards_lock = 0; /* locked for registering/using */
42struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; 42struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL};
43EXPORT_SYMBOL(snd_cards); 43EXPORT_SYMBOL(snd_cards);
44 44
45DEFINE_RWLOCK(snd_card_rwlock); 45static DEFINE_MUTEX(snd_card_mutex);
46 46
47#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 47#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
48int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); 48int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
@@ -112,7 +112,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
112 strlcpy(card->id, xid, sizeof(card->id)); 112 strlcpy(card->id, xid, sizeof(card->id));
113 } 113 }
114 err = 0; 114 err = 0;
115 write_lock(&snd_card_rwlock); 115 mutex_lock(&snd_card_mutex);
116 if (idx < 0) { 116 if (idx < 0) {
117 int idx2; 117 int idx2;
118 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 118 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
@@ -130,12 +130,12 @@ struct snd_card *snd_card_new(int idx, const char *xid,
130 else 130 else
131 err = -ENODEV; 131 err = -ENODEV;
132 if (idx < 0 || err < 0) { 132 if (idx < 0 || err < 0) {
133 write_unlock(&snd_card_rwlock); 133 mutex_unlock(&snd_card_mutex);
134 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); 134 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1);
135 goto __error; 135 goto __error;
136 } 136 }
137 snd_cards_lock |= 1 << idx; /* lock it */ 137 snd_cards_lock |= 1 << idx; /* lock it */
138 write_unlock(&snd_card_rwlock); 138 mutex_unlock(&snd_card_mutex);
139 card->number = idx; 139 card->number = idx;
140 card->module = module; 140 card->module = module;
141 INIT_LIST_HEAD(&card->devices); 141 INIT_LIST_HEAD(&card->devices);
@@ -173,6 +173,17 @@ struct snd_card *snd_card_new(int idx, const char *xid,
173 173
174EXPORT_SYMBOL(snd_card_new); 174EXPORT_SYMBOL(snd_card_new);
175 175
176/* return non-zero if a card is already locked */
177int snd_card_locked(int card)
178{
179 int locked;
180
181 mutex_lock(&snd_card_mutex);
182 locked = snd_cards_lock & (1 << card);
183 mutex_unlock(&snd_card_mutex);
184 return locked;
185}
186
176static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) 187static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
177{ 188{
178 return -ENODEV; 189 return -ENODEV;
@@ -240,9 +251,9 @@ int snd_card_disconnect(struct snd_card *card)
240 spin_unlock(&card->files_lock); 251 spin_unlock(&card->files_lock);
241 252
242 /* phase 1: disable fops (user space) operations for ALSA API */ 253 /* phase 1: disable fops (user space) operations for ALSA API */
243 write_lock(&snd_card_rwlock); 254 mutex_lock(&snd_card_mutex);
244 snd_cards[card->number] = NULL; 255 snd_cards[card->number] = NULL;
245 write_unlock(&snd_card_rwlock); 256 mutex_unlock(&snd_card_mutex);
246 257
247 /* phase 2: replace file->f_op with special dummy operations */ 258 /* phase 2: replace file->f_op with special dummy operations */
248 259
@@ -321,9 +332,9 @@ int snd_card_free(struct snd_card *card)
321 332
322 if (card == NULL) 333 if (card == NULL)
323 return -EINVAL; 334 return -EINVAL;
324 write_lock(&snd_card_rwlock); 335 mutex_lock(&snd_card_mutex);
325 snd_cards[card->number] = NULL; 336 snd_cards[card->number] = NULL;
326 write_unlock(&snd_card_rwlock); 337 mutex_unlock(&snd_card_mutex);
327 338
328#ifdef CONFIG_PM 339#ifdef CONFIG_PM
329 wake_up(&card->power_sleep); 340 wake_up(&card->power_sleep);
@@ -359,9 +370,9 @@ int snd_card_free(struct snd_card *card)
359 card->s_f_ops = s_f_ops->next; 370 card->s_f_ops = s_f_ops->next;
360 kfree(s_f_ops); 371 kfree(s_f_ops);
361 } 372 }
362 write_lock(&snd_card_rwlock); 373 mutex_lock(&snd_card_mutex);
363 snd_cards_lock &= ~(1 << card->number); 374 snd_cards_lock &= ~(1 << card->number);
364 write_unlock(&snd_card_rwlock); 375 mutex_unlock(&snd_card_mutex);
365 kfree(card); 376 kfree(card);
366 return 0; 377 return 0;
367} 378}
@@ -497,16 +508,16 @@ int snd_card_register(struct snd_card *card)
497 snd_assert(card != NULL, return -EINVAL); 508 snd_assert(card != NULL, return -EINVAL);
498 if ((err = snd_device_register_all(card)) < 0) 509 if ((err = snd_device_register_all(card)) < 0)
499 return err; 510 return err;
500 write_lock(&snd_card_rwlock); 511 mutex_lock(&snd_card_mutex);
501 if (snd_cards[card->number]) { 512 if (snd_cards[card->number]) {
502 /* already registered */ 513 /* already registered */
503 write_unlock(&snd_card_rwlock); 514 mutex_unlock(&snd_card_mutex);
504 return 0; 515 return 0;
505 } 516 }
506 if (card->id[0] == '\0') 517 if (card->id[0] == '\0')
507 choose_default_id(card); 518 choose_default_id(card);
508 snd_cards[card->number] = card; 519 snd_cards[card->number] = card;
509 write_unlock(&snd_card_rwlock); 520 mutex_unlock(&snd_card_mutex);
510 init_info_for_card(card); 521 init_info_for_card(card);
511#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 522#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
512 if (snd_mixer_oss_notify_callback) 523 if (snd_mixer_oss_notify_callback)
@@ -527,7 +538,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
527 struct snd_card *card; 538 struct snd_card *card;
528 539
529 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 540 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
530 read_lock(&snd_card_rwlock); 541 mutex_lock(&snd_card_mutex);
531 if ((card = snd_cards[idx]) != NULL) { 542 if ((card = snd_cards[idx]) != NULL) {
532 count++; 543 count++;
533 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", 544 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
@@ -538,7 +549,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
538 snd_iprintf(buffer, " %s\n", 549 snd_iprintf(buffer, " %s\n",
539 card->longname); 550 card->longname);
540 } 551 }
541 read_unlock(&snd_card_rwlock); 552 mutex_unlock(&snd_card_mutex);
542 } 553 }
543 if (!count) 554 if (!count)
544 snd_iprintf(buffer, "--- no soundcards ---\n"); 555 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -552,12 +563,12 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer)
552 struct snd_card *card; 563 struct snd_card *card;
553 564
554 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 565 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
555 read_lock(&snd_card_rwlock); 566 mutex_lock(&snd_card_mutex);
556 if ((card = snd_cards[idx]) != NULL) { 567 if ((card = snd_cards[idx]) != NULL) {
557 count++; 568 count++;
558 snd_iprintf(buffer, "%s\n", card->longname); 569 snd_iprintf(buffer, "%s\n", card->longname);
559 } 570 }
560 read_unlock(&snd_card_rwlock); 571 mutex_unlock(&snd_card_mutex);
561 } 572 }
562 if (!count) { 573 if (!count) {
563 snd_iprintf(buffer, "--- no soundcards ---\n"); 574 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -575,11 +586,11 @@ static void snd_card_module_info_read(struct snd_info_entry *entry,
575 struct snd_card *card; 586 struct snd_card *card;
576 587
577 for (idx = 0; idx < SNDRV_CARDS; idx++) { 588 for (idx = 0; idx < SNDRV_CARDS; idx++) {
578 read_lock(&snd_card_rwlock); 589 mutex_lock(&snd_card_mutex);
579 if ((card = snd_cards[idx]) != NULL) 590 if ((card = snd_cards[idx]) != NULL)
580 snd_iprintf(buffer, "%2i %s\n", 591 snd_iprintf(buffer, "%2i %s\n",
581 idx, card->module->name); 592 idx, card->module->name);
582 read_unlock(&snd_card_rwlock); 593 mutex_unlock(&snd_card_mutex);
583 } 594 }
584} 595}
585#endif 596#endif
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 8313f97907d8..02c8cc4ebffe 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -81,14 +81,9 @@ extern struct class *sound_class;
81 */ 81 */
82void snd_request_card(int card) 82void snd_request_card(int card)
83{ 83{
84 int locked;
85
86 if (! current->fs->root) 84 if (! current->fs->root)
87 return; 85 return;
88 read_lock(&snd_card_rwlock); 86 if (snd_card_locked(card))
89 locked = snd_cards_lock & (1 << card);
90 read_unlock(&snd_card_rwlock);
91 if (locked)
92 return; 87 return;
93 if (card < 0 || card >= cards_limit) 88 if (card < 0 || card >= cards_limit)
94 return; 89 return;