diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-05-15 13:49:05 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-06-22 15:33:37 -0400 |
commit | 746df94898554b3d8e91d855e934852e626c701c (patch) | |
tree | dc312e426d52804d98080af18f12f5b14010d2e5 | |
parent | 0defb2672d7cde8d048eec35c183da7b88adbd9e (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.h | 3 | ||||
-rw-r--r-- | sound/core/init.c | 51 | ||||
-rw-r--r-- | sound/core/sound.c | 7 |
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 | ||
236 | extern unsigned int snd_cards_lock; | ||
237 | extern struct snd_card *snd_cards[SNDRV_CARDS]; | 236 | extern struct snd_card *snd_cards[SNDRV_CARDS]; |
238 | extern rwlock_t snd_card_rwlock; | 237 | int 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 | ||
41 | unsigned int snd_cards_lock = 0; /* locked for registering/using */ | 41 | static unsigned int snd_cards_lock = 0; /* locked for registering/using */ |
42 | struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; | 42 | struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; |
43 | EXPORT_SYMBOL(snd_cards); | 43 | EXPORT_SYMBOL(snd_cards); |
44 | 44 | ||
45 | DEFINE_RWLOCK(snd_card_rwlock); | 45 | static 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) |
48 | int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); | 48 | int (*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 | ||
174 | EXPORT_SYMBOL(snd_card_new); | 174 | EXPORT_SYMBOL(snd_card_new); |
175 | 175 | ||
176 | /* return non-zero if a card is already locked */ | ||
177 | int 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 | |||
176 | static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) | 187 | static 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 | */ |
82 | void snd_request_card(int card) | 82 | void 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; |