From 9fb6198e8c574c6547fbfac0ae1eaf7894ddfdcc Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 11 Nov 2008 16:51:02 +0100 Subject: [PATCH 1/5] ALSA: add /sys/class/sound/card#/id (r/w) and card#/number (r/o) files For udev, we need a way to rename soundcard names. The soundcard numbers (indexes) are hardwired but we have a text identification which can be changed at run-time. The ALSA user space tools already allow using of this text identification. Signed-off-by: Jaroslav Kysela Signed-off-by: Takashi Iwai --- sound/core/init.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/sound/core/init.c b/sound/core/init.c index b47ff8b44be8..5ff297d1d89a 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -533,6 +533,64 @@ static void choose_default_id(struct snd_card *card) } } +#ifndef CONFIG_SYSFS_DEPRECATED +static ssize_t +card_id_show_attr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct snd_card *card = dev_get_drvdata(dev); + return snprintf(buf, PAGE_SIZE, "%s\n", card ? card->id : "(null)"); +} + +static ssize_t +card_id_store_attr(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct snd_card *card = dev_get_drvdata(dev); + char buf1[sizeof(card->id)]; + size_t copy = count > sizeof(card->id) - 1 ? + sizeof(card->id) - 1 : count; + size_t idx; + int c; + + for (idx = 0; idx < copy; idx++) { + c = buf[idx]; + if (!isalnum(c) && c != '_' && c != '-') + return -EINVAL; + } + memcpy(buf1, buf, copy); + buf1[copy] = '\0'; + mutex_lock(&snd_card_mutex); + if (!snd_info_check_reserved_words(buf1)) { + __exist: + mutex_unlock(&snd_card_mutex); + return -EEXIST; + } + for (idx = 0; idx < snd_ecards_limit; idx++) { + if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) + goto __exist; + } + strcpy(card->id, buf1); + mutex_unlock(&snd_card_mutex); + + return count; +} + +static struct device_attribute card_id_attrs = + __ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr); + +static ssize_t +card_number_show_attr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct snd_card *card = dev_get_drvdata(dev); + return snprintf(buf, PAGE_SIZE, "%i\n", card ? card->number : -1); +} + +static struct device_attribute card_number_attrs = + __ATTR(number, S_IRUGO, card_number_show_attr, NULL); +#endif /* CONFIG_SYSFS_DEPRECATED */ + /** * snd_card_register - register the soundcard * @card: soundcard structure @@ -553,7 +611,7 @@ int snd_card_register(struct snd_card *card) #ifndef CONFIG_SYSFS_DEPRECATED if (!card->card_dev) { card->card_dev = device_create(sound_class, card->dev, - MKDEV(0, 0), NULL, + MKDEV(0, 0), card, "card%i", card->number); if (IS_ERR(card->card_dev)) card->card_dev = NULL; @@ -575,6 +633,12 @@ int snd_card_register(struct snd_card *card) #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) if (snd_mixer_oss_notify_callback) snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); +#endif +#ifndef CONFIG_SYSFS_DEPRECATED + if (card->card_dev) { + device_create_file(card->card_dev, &card_id_attrs); + device_create_file(card->card_dev, &card_number_attrs); + } #endif return 0; } From c2eb9c4ea383aee154e7139395872c4da629e715 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 12 Nov 2008 16:31:37 +0100 Subject: [PATCH 2/5] ALSA: when card identification is changed, change also /proc/asound symlink Signed-off-by: Jaroslav Kysela Signed-off-by: Takashi Iwai --- include/sound/info.h | 2 ++ sound/core/info.c | 17 +++++++++++++++++ sound/core/init.c | 1 + 3 files changed, 20 insertions(+) diff --git a/include/sound/info.h b/include/sound/info.h index 8ae72e74f898..46f702a76e4f 100644 --- a/include/sound/info.h +++ b/include/sound/info.h @@ -126,6 +126,7 @@ int snd_info_card_create(struct snd_card * card); int snd_info_card_register(struct snd_card * card); int snd_info_card_free(struct snd_card * card); void snd_info_card_disconnect(struct snd_card * card); +void snd_info_card_id_change(struct snd_card * card); int snd_info_register(struct snd_info_entry * entry); /* for card drivers */ @@ -160,6 +161,7 @@ static inline int snd_info_card_create(struct snd_card * card) { return 0; } static inline int snd_info_card_register(struct snd_card * card) { return 0; } static inline int snd_info_card_free(struct snd_card * card) { return 0; } static inline void snd_info_card_disconnect(struct snd_card * card) { } +static inline void snd_info_card_id_change(struct snd_card * card) { } static inline int snd_info_register(struct snd_info_entry * entry) { return 0; } static inline int snd_card_proc_new(struct snd_card *card, const char *name, diff --git a/sound/core/info.c b/sound/core/info.c index 527b207462b0..70fa87189f36 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -652,6 +652,23 @@ int snd_info_card_register(struct snd_card *card) return 0; } +/* + * called on card->id change + */ +void snd_info_card_id_change(struct snd_card *card) +{ + mutex_lock(&info_mutex); + if (card->proc_root_link) { + snd_remove_proc_entry(snd_proc_root, card->proc_root_link); + card->proc_root_link = NULL; + } + if (strcmp(card->id, card->proc_root->name)) + card->proc_root_link = proc_symlink(card->id, + snd_proc_root, + card->proc_root->name); + mutex_unlock(&info_mutex); +} + /* * de-register the card proc file * called from init.c diff --git a/sound/core/init.c b/sound/core/init.c index 5ff297d1d89a..af1e407ca27f 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -571,6 +571,7 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr, goto __exist; } strcpy(card->id, buf1); + snd_info_card_id_change(card); mutex_unlock(&snd_card_mutex); return count; From 972d4c50fbbb1b9c10293ff90e4e1d45e7fb21ac Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 12 Nov 2008 16:37:48 +0100 Subject: [PATCH 3/5] ALSA: hdsp/hdspm: remove card->id from rawmidi device name The card->id (card text identification) can be changed at runtime. It might be confusing to have old text identification in device name. Signed-off-by: Jaroslav Kysela Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdsp.c | 2 +- sound/pci/rme9652/hdspm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 736246f98acc..fdd3be5b439d 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -1452,7 +1452,7 @@ static int snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int i if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) return -1; - sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); + sprintf(hdsp->midi[id].rmidi->name, "HDSP MIDI %d", id+1); hdsp->midi[id].rmidi->private_data = &hdsp->midi[id]; snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output); diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 98762f909d64..dc5c4baa1e64 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -1293,7 +1293,7 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card, if (err < 0) return err; - sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); + sprintf(hdspm->midi[id].rmidi->name, "HDSPM MIDI %d", id+1); hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, From fd64138c0eff8351b93ef99f7da929bb8a49b9ed Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 12 Nov 2008 16:53:47 +0100 Subject: [PATCH 4/5] ALSA: include/sound/info.h - coding style changed Change coding style to be more acceptable by checkpatch.pl. Signed-off-by: Jaroslav Kysela Signed-off-by: Takashi Iwai --- include/sound/info.h | 104 +++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/include/sound/info.h b/include/sound/info.h index 46f702a76e4f..7c2ee1a21b00 100644 --- a/include/sound/info.h +++ b/include/sound/info.h @@ -40,30 +40,34 @@ struct snd_info_buffer { struct snd_info_entry; struct snd_info_entry_text { - void (*read) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); - void (*write) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); + void (*read)(struct snd_info_entry *entry, + struct snd_info_buffer *buffer); + void (*write)(struct snd_info_entry *entry, + struct snd_info_buffer *buffer); }; struct snd_info_entry_ops { - int (*open) (struct snd_info_entry *entry, - unsigned short mode, void **file_private_data); - int (*release) (struct snd_info_entry * entry, - unsigned short mode, void *file_private_data); - long (*read) (struct snd_info_entry *entry, void *file_private_data, - struct file * file, char __user *buf, + int (*open)(struct snd_info_entry *entry, + unsigned short mode, void **file_private_data); + int (*release)(struct snd_info_entry *entry, + unsigned short mode, void *file_private_data); + long (*read)(struct snd_info_entry *entry, void *file_private_data, + struct file *file, char __user *buf, + unsigned long count, unsigned long pos); + long (*write)(struct snd_info_entry *entry, void *file_private_data, + struct file *file, const char __user *buf, unsigned long count, unsigned long pos); - long (*write) (struct snd_info_entry *entry, void *file_private_data, - struct file * file, const char __user *buf, - unsigned long count, unsigned long pos); - long long (*llseek) (struct snd_info_entry *entry, void *file_private_data, - struct file * file, long long offset, int orig); - unsigned int (*poll) (struct snd_info_entry *entry, void *file_private_data, - struct file * file, poll_table * wait); - int (*ioctl) (struct snd_info_entry *entry, void *file_private_data, - struct file * file, unsigned int cmd, unsigned long arg); - int (*mmap) (struct snd_info_entry *entry, void *file_private_data, - struct inode * inode, struct file * file, - struct vm_area_struct * vma); + long long (*llseek)(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + long long offset, int orig); + unsigned int(*poll)(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + poll_table *wait); + int (*ioctl)(struct snd_info_entry *entry, void *file_private_data, + struct file *file, unsigned int cmd, unsigned long arg); + int (*mmap)(struct snd_info_entry *entry, void *file_private_data, + struct inode *inode, struct file *file, + struct vm_area_struct *vma); }; struct snd_info_entry { @@ -106,35 +110,37 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer); static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {} #endif -int snd_iprintf(struct snd_info_buffer * buffer, char *fmt,...) __attribute__ ((format (printf, 2, 3))); +int snd_iprintf(struct snd_info_buffer *buffer, char *fmt, ...) \ + __attribute__ ((format (printf, 2, 3))); int snd_info_init(void); int snd_info_done(void); -int snd_info_get_line(struct snd_info_buffer * buffer, char *line, int len); +int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len); char *snd_info_get_str(char *dest, char *src, int len); -struct snd_info_entry *snd_info_create_module_entry(struct module * module, +struct snd_info_entry *snd_info_create_module_entry(struct module *module, const char *name, - struct snd_info_entry * parent); -struct snd_info_entry *snd_info_create_card_entry(struct snd_card * card, + struct snd_info_entry *parent); +struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, const char *name, - struct snd_info_entry * parent); -void snd_info_free_entry(struct snd_info_entry * entry); -int snd_info_store_text(struct snd_info_entry * entry); -int snd_info_restore_text(struct snd_info_entry * entry); + struct snd_info_entry *parent); +void snd_info_free_entry(struct snd_info_entry *entry); +int snd_info_store_text(struct snd_info_entry *entry); +int snd_info_restore_text(struct snd_info_entry *entry); -int snd_info_card_create(struct snd_card * card); -int snd_info_card_register(struct snd_card * card); -int snd_info_card_free(struct snd_card * card); -void snd_info_card_disconnect(struct snd_card * card); -void snd_info_card_id_change(struct snd_card * card); -int snd_info_register(struct snd_info_entry * entry); +int snd_info_card_create(struct snd_card *card); +int snd_info_card_register(struct snd_card *card); +int snd_info_card_free(struct snd_card *card); +void snd_info_card_disconnect(struct snd_card *card); +void snd_info_card_id_change(struct snd_card *card); +int snd_info_register(struct snd_info_entry *entry); /* for card drivers */ -int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_entry **entryp); +int snd_card_proc_new(struct snd_card *card, const char *name, + struct snd_info_entry **entryp); static inline void snd_info_set_text_ops(struct snd_info_entry *entry, - void *private_data, - void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) + void *private_data, + void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) { entry->private_data = private_data; entry->c.text.read = read; @@ -147,22 +153,22 @@ int snd_info_check_reserved_words(const char *str); #define snd_seq_root NULL #define snd_oss_root NULL -static inline int snd_iprintf(struct snd_info_buffer * buffer, char *fmt,...) { return 0; } +static inline int snd_iprintf(struct snd_info_buffer *buffer, char *fmt, ...) { return 0; } static inline int snd_info_init(void) { return 0; } static inline int snd_info_done(void) { return 0; } -static inline int snd_info_get_line(struct snd_info_buffer * buffer, char *line, int len) { return 0; } +static inline int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) { return 0; } static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; } -static inline struct snd_info_entry *snd_info_create_module_entry(struct module * module, const char *name, struct snd_info_entry * parent) { return NULL; } -static inline struct snd_info_entry *snd_info_create_card_entry(struct snd_card * card, const char *name, struct snd_info_entry * parent) { return NULL; } -static inline void snd_info_free_entry(struct snd_info_entry * entry) { ; } +static inline struct snd_info_entry *snd_info_create_module_entry(struct module *module, const char *name, struct snd_info_entry *parent) { return NULL; } +static inline struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, const char *name, struct snd_info_entry *parent) { return NULL; } +static inline void snd_info_free_entry(struct snd_info_entry *entry) { ; } -static inline int snd_info_card_create(struct snd_card * card) { return 0; } -static inline int snd_info_card_register(struct snd_card * card) { return 0; } -static inline int snd_info_card_free(struct snd_card * card) { return 0; } -static inline void snd_info_card_disconnect(struct snd_card * card) { } -static inline void snd_info_card_id_change(struct snd_card * card) { } -static inline int snd_info_register(struct snd_info_entry * entry) { return 0; } +static inline int snd_info_card_create(struct snd_card *card) { return 0; } +static inline int snd_info_card_register(struct snd_card *card) { return 0; } +static inline int snd_info_card_free(struct snd_card *card) { return 0; } +static inline void snd_info_card_disconnect(struct snd_card *card) { } +static inline void snd_info_card_id_change(struct snd_card *card) { } +static inline int snd_info_register(struct snd_info_entry *entry) { return 0; } static inline int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_entry **entryp) { return -EINVAL; } From 2af752936b311a846622668f8b0f1893d8eccade Mon Sep 17 00:00:00 2001 From: Hannes Eder Date: Tue, 18 Nov 2008 12:25:06 -0500 Subject: [PATCH 5/5] sound: Fix warnings relating to ignored return value in snd_card_register Do not ignore the return of 'device_create_file' in 'snd_card_register' and thereby fixing the following warnings: sound/core/init.c: In function 'snd_card_register': sound/core/init.c:640: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result sound/core/init.c:641: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result Signed-off-by: Hannes Eder Signed-off-by: Takashi Iwai --- sound/core/init.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/core/init.c b/sound/core/init.c index af1e407ca27f..0d5520c415d3 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -637,8 +637,12 @@ int snd_card_register(struct snd_card *card) #endif #ifndef CONFIG_SYSFS_DEPRECATED if (card->card_dev) { - device_create_file(card->card_dev, &card_id_attrs); - device_create_file(card->card_dev, &card_number_attrs); + err = device_create_file(card->card_dev, &card_id_attrs); + if (err < 0) + return err; + err = device_create_file(card->card_dev, &card_number_attrs); + if (err < 0) + return err; } #endif return 0;