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 guard(mutex)(&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 return -ENOMEM; 41 } 42 snd_sndstat_strings[num][dev] = x; 43 return 0; 44 } 45 EXPORT_SYMBOL(snd_oss_info_register); 46 47 static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) 48 { 49 int idx, ok = -1; 50 char *str; 51 52 snd_iprintf(buf, "\n%s:", id); 53 guard(mutex)(&strings); 54 for (idx = 0; idx < SNDRV_CARDS; idx++) { 55 str = snd_sndstat_strings[idx][dev]; 56 if (str) { 57 if (ok < 0) { 58 snd_iprintf(buf, "\n"); 59 ok++; 60 } 61 snd_iprintf(buf, "%i: %s\n", idx, str); 62 } 63 } 64 if (ok < 0) 65 snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); 66 return ok; 67 } 68 69 static void snd_sndstat_proc_read(struct snd_info_entry *entry, 70 struct snd_info_buffer *buffer) 71 { 72 snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA emulation code)\n"); 73 snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n", 74 init_utsname()->sysname, 75 init_utsname()->nodename, 76 init_utsname()->release, 77 init_utsname()->version, 78 init_utsname()->machine); 79 snd_iprintf(buffer, "Config options: 0\n"); 80 snd_iprintf(buffer, "\nInstalled drivers: \n"); 81 snd_iprintf(buffer, "Type 10: ALSA emulation\n"); 82 snd_iprintf(buffer, "\nCard config: \n"); 83 snd_card_info_read_oss(buffer); 84 snd_sndstat_show_strings(buffer, "Audio devices", SNDRV_OSS_INFO_DEV_AUDIO); 85 snd_sndstat_show_strings(buffer, "Synth devices", SNDRV_OSS_INFO_DEV_SYNTH); 86 snd_sndstat_show_strings(buffer, "Midi devices", SNDRV_OSS_INFO_DEV_MIDI); 87 snd_sndstat_show_strings(buffer, "Timers", SNDRV_OSS_INFO_DEV_TIMERS); 88 snd_sndstat_show_strings(buffer, "Mixers", SNDRV_OSS_INFO_DEV_MIXERS); 89 } 90 91 int __init snd_info_minor_register(void) 92 { 93 struct snd_info_entry *entry; 94 95 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); 96 entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", 97 snd_oss_root); 98 if (!entry) 99 return -ENOMEM; 100 entry->c.text.read = snd_sndstat_proc_read; 101 return snd_info_register(entry); /* freed in error path */ 102 } 103