1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Information interface for ALSA driver 4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 5 */ 6 7 #include <linux/slab.h> 8 #include <linux/time.h> 9 #include <linux/string.h> 10 #include <linux/export.h> 11 #include <sound/core.h> 12 #include <sound/minors.h> 13 #include <sound/info.h> 14 #include <linux/utsname.h> 15 #include <linux/mutex.h> 16 17 /* 18 * OSS compatible part 19 */ 20 21 static DEFINE_MUTEX(strings); 22 static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT]; 23 24 int snd_oss_info_register(int dev, int num, char *string) 25 { 26 char *x; 27 28 if (snd_BUG_ON(dev < 0 || dev >= SNDRV_OSS_INFO_DEV_COUNT)) 29 return -ENXIO; 30 if (snd_BUG_ON(num < 0 || num >= SNDRV_CARDS)) 31 return -ENXIO; 32 mutex_lock(&strings); 33 if (string == NULL) { 34 x = snd_sndstat_strings[num][dev]; 35 kfree(x); 36 x = NULL; 37 } else { 38 x = kstrdup(string, GFP_KERNEL); 39 if (x == NULL) { 40 mutex_unlock(&strings); 41 return -ENOMEM; 42 } 43 } 44 snd_sndstat_strings[num][dev] = x; 45 mutex_unlock(&strings); 46 return 0; 47 } 48 EXPORT_SYMBOL(snd_oss_info_register); 49 50 static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) 51 { 52 int idx, ok = -1; 53 char *str; 54 55 snd_iprintf(buf, "\n%s:", id); 56 mutex_lock(&strings); 57 for (idx = 0; idx < SNDRV_CARDS; idx++) { 58 str = snd_sndstat_strings[idx][dev]; 59 if (str) { 60 if (ok < 0) { 61 snd_iprintf(buf, "\n"); 62 ok++; 63 } 64 snd_iprintf(buf, "%i: %s\n", idx, str); 65 } 66 } 67 mutex_unlock(&strings); 68 if (ok < 0) 69 snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); 70 return ok; 71 } 72 73 static void snd_sndstat_proc_read(struct snd_info_entry *entry, 74 struct snd_info_buffer *buffer) 75 { 76 snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA emulation code)\n"); 77 snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n", 78 init_utsname()->sysname, 79 init_utsname()->nodename, 80 init_utsname()->release, 81 init_utsname()->version, 82 init_utsname()->machine); 83 snd_iprintf(buffer, "Config options: 0\n"); 84 snd_iprintf(buffer, "\nInstalled drivers: \n"); 85 snd_iprintf(buffer, "Type 10: ALSA emulation\n"); 86 snd_iprintf(buffer, "\nCard config: \n"); 87 snd_card_info_read_oss(buffer); 88 snd_sndstat_show_strings(buffer, "Audio devices", SNDRV_OSS_INFO_DEV_AUDIO); 89 snd_sndstat_show_strings(buffer, "Synth devices", SNDRV_OSS_INFO_DEV_SYNTH); 90 snd_sndstat_show_strings(buffer, "Midi devices", SNDRV_OSS_INFO_DEV_MIDI); 91 snd_sndstat_show_strings(buffer, "Timers", SNDRV_OSS_INFO_DEV_TIMERS); 92 snd_sndstat_show_strings(buffer, "Mixers", SNDRV_OSS_INFO_DEV_MIXERS); 93 } 94 95 int __init snd_info_minor_register(void) 96 { 97 struct snd_info_entry *entry; 98 99 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); 100 entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", 101 snd_oss_root); 102 if (!entry) 103 return -ENOMEM; 104 entry->c.text.read = snd_sndstat_proc_read; 105 return snd_info_register(entry); /* freed in error path */ 106 } 107