23 #include <linux/sched.h>
24 #include <linux/module.h>
25 #include <linux/device.h>
27 #include <linux/slab.h>
28 #include <linux/time.h>
29 #include <linux/ctype.h>
49 static unsigned int snd_cards_lock;
68 if (!module || !module->
name || !
slots[idx])
96 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
97 int (*snd_mixer_oss_notify_callback)(
struct snd_card *
card,
int free_flag);
101 #ifdef CONFIG_PROC_FS
105 snd_iprintf(buffer,
"%s\n", entry->
card->id);
113 if ((err = snd_info_card_register(card)) < 0) {
117 if ((entry = snd_info_create_card_entry(card,
"id", card->
proc_root)) ==
NULL) {
121 entry->
c.
text.read = snd_card_id_read;
122 if (snd_info_register(entry) < 0) {
123 snd_info_free_entry(entry);
130 #define init_info_for_card(card)
162 card = kzalloc(
sizeof(*card) + extra_size,
GFP_KERNEL);
172 if (~snd_cards_lock & idx & 1<<idx2) {
173 if (module_slot_match(module, idx2)) {
182 if (~snd_cards_lock & idx & 1<<idx2) {
192 if (snd_cards_lock & (1 << idx))
202 snd_cards_lock |= 1 <<
idx;
208 INIT_LIST_HEAD(&card->
devices);
228 err = snd_info_card_create(card);
252 locked = snd_cards_lock & (1 <<
card);
257 static loff_t snd_disconnect_llseek(
struct file *
file, loff_t
offset,
int orig)
278 spin_lock(&shutdown_lock);
280 if (_df->file == file) {
286 spin_unlock(&shutdown_lock);
294 panic(
"%s(%p, %p) failed!", __func__, inode, file);
297 static unsigned int snd_disconnect_poll(
struct file * file,
poll_table *
wait)
302 static long snd_disconnect_ioctl(
struct file *file,
303 unsigned int cmd,
unsigned long arg)
308 static int snd_disconnect_mmap(
struct file *file,
struct vm_area_struct *vma)
313 static int snd_disconnect_fasync(
int fd,
struct file *file,
int on)
321 .llseek = snd_disconnect_llseek,
322 .read = snd_disconnect_read,
323 .write = snd_disconnect_write,
324 .release = snd_disconnect_release,
325 .poll = snd_disconnect_poll,
326 .unlocked_ioctl = snd_disconnect_ioctl,
328 .compat_ioctl = snd_disconnect_ioctl,
330 .mmap = snd_disconnect_mmap,
331 .fasync = snd_disconnect_fasync
364 snd_cards_lock &= ~(1 << card->
number);
375 spin_lock(&shutdown_lock);
377 spin_unlock(&shutdown_lock);
379 mfile->
file->f_op = &snd_shutdown_f_ops;
387 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
388 if (snd_mixer_oss_notify_callback)
389 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
397 snd_info_card_disconnect(card);
421 static int snd_card_do_free(
struct snd_card *card)
423 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
424 if (snd_mixer_oss_notify_callback)
425 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
441 snd_info_free_entry(card->
proc_id);
442 if (snd_info_card_free(card) < 0) {
462 snd_card_do_free(card);
480 snd_card_do_free(card);
494 snd_card_do_free(card);
501 static const char *retrieve_id_from_card_name(
const char *
name)
503 const char *spos =
name;
514 static bool card_id_ok(
struct snd_card *card,
const char *
id)
517 if (!snd_info_check_reserved_words(
id))
520 if (snd_cards[i] && snd_cards[i] != card &&
521 !
strcmp(snd_cards[i]->
id,
id))
528 static void copy_valid_id_string(
struct snd_card *card,
const char *
src,
536 *
id++ =
isalpha(*src) ? *src :
'D';
537 while (*nid && (
size_t)(
id - card->
id) <
sizeof(card->
id) - 1) {
548 static void snd_card_set_id_no_lock(
struct snd_card *card,
const char *src,
553 bool is_default =
false;
556 copy_valid_id_string(card, src, nid);
563 if (!*
id || !
strncmp(
id,
"card", 4)) {
570 if (card_id_ok(card,
id))
576 char *spos =
id + len;
577 if (len >
sizeof(card->
id) - 3)
578 spos =
id +
sizeof(card->
id) - 3;
583 if (
id[len - 1] !=
'9')
611 if (card->
id[0] !=
'\0')
614 snd_card_set_id_no_lock(card, nid, nid);
632 char buf1[
sizeof(card->
id)];
633 size_t copy = count >
sizeof(card->
id) - 1 ?
638 for (idx = 0; idx < copy; idx++) {
640 if (!
isalnum(c) && c !=
'_' && c !=
'-')
646 if (!card_id_ok(
NULL, buf1)) {
651 snd_info_card_id_change(card);
661 card_number_show_attr(
struct device *dev,
700 if (snd_cards[card->
number]) {
707 char tmpid[
sizeof(card->
id)];
709 snd_card_set_id_no_lock(card, tmpid, tmpid);
714 snd_card_set_id_no_lock(card, src,
715 retrieve_id_from_card_name(src));
720 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
721 if (snd_mixer_oss_notify_callback)
722 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
738 #ifdef CONFIG_PROC_FS
749 if ((card = snd_cards[idx]) !=
NULL) {
751 snd_iprintf(buffer,
"%2i [%-15s]: %s - %s\n",
756 snd_iprintf(buffer,
" %s\n",
762 snd_iprintf(buffer,
"--- no soundcards ---\n");
765 #ifdef CONFIG_SND_OSSEMUL
774 if ((card = snd_cards[idx]) !=
NULL) {
776 snd_iprintf(buffer,
"%s\n", card->
longname);
781 snd_iprintf(buffer,
"--- no soundcards ---\n");
789 static void snd_card_module_info_read(
struct snd_info_entry *entry,
797 if ((card = snd_cards[idx]) !=
NULL)
798 snd_iprintf(buffer,
"%2i %s\n",
812 entry->
c.
text.read = snd_card_info_read;
813 if (snd_info_register(entry) < 0) {
814 snd_info_free_entry(entry);
817 snd_card_info_entry =
entry;
822 entry->
c.
text.read = snd_card_module_info_read;
823 if (snd_info_register(entry) < 0)
824 snd_info_free_entry(entry);
826 snd_card_module_info_entry =
entry;
835 snd_info_free_entry(snd_card_info_entry);
837 snd_info_free_entry(snd_card_module_info_entry);
858 int len =
strlen(component);
862 if (ptr[len] ==
'\0' || ptr[len] ==
' ')
931 if (mfile->
file == file) {
933 spin_lock(&shutdown_lock);
935 spin_unlock(&shutdown_lock);
972 init_waitqueue_entry(&wait,
current);