Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: ump: Additional proc output

UMP devices may have more interesting information than the traditional
rawmidi. Extend the rawmidi_global_ops to allow the optional proc
info output and show some more bits in the proc file for UMP.

Note that the "Groups" field shows the first and the last UMP Groups,
and both numbers are 1-based (i.e. the first group is 1).

Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-7-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+54
+3
include/sound/rawmidi.h
··· 18 18 #if IS_ENABLED(CONFIG_SND_SEQUENCER) 19 19 #include <sound/seq_device.h> 20 20 #endif 21 + #include <sound/info.h> 21 22 22 23 /* 23 24 * Raw MIDI interface ··· 50 49 struct snd_seq_port_info *info); 51 50 long (*ioctl)(struct snd_rawmidi *rmidi, unsigned int cmd, 52 51 void __user *argp); 52 + void (*proc_read)(struct snd_info_entry *entry, 53 + struct snd_info_buffer *buf); 53 54 }; 54 55 55 56 struct snd_rawmidi_runtime {
+2
sound/core/rawmidi.c
··· 1770 1770 if (IS_ENABLED(CONFIG_SND_UMP)) 1771 1771 snd_iprintf(buffer, "Type: %s\n", 1772 1772 rawmidi_is_ump(rmidi) ? "UMP" : "Legacy"); 1773 + if (rmidi->ops->proc_read) 1774 + rmidi->ops->proc_read(entry, buffer); 1773 1775 mutex_lock(&rmidi->open_mutex); 1774 1776 if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { 1775 1777 list_for_each_entry(substream,
+49
sound/core/ump.c
··· 21 21 static int snd_ump_dev_unregister(struct snd_rawmidi *rmidi); 22 22 static long snd_ump_ioctl(struct snd_rawmidi *rmidi, unsigned int cmd, 23 23 void __user *argp); 24 + static void snd_ump_proc_read(struct snd_info_entry *entry, 25 + struct snd_info_buffer *buffer); 24 26 25 27 static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = { 26 28 .dev_register = snd_ump_dev_register, 27 29 .dev_unregister = snd_ump_dev_unregister, 28 30 .ioctl = snd_ump_ioctl, 31 + .proc_read = snd_ump_proc_read, 29 32 }; 30 33 31 34 static void snd_ump_endpoint_free(struct snd_rawmidi *rmidi) ··· 226 223 default: 227 224 ump_dbg(ump, "rawmidi: unknown command = 0x%x\n", cmd); 228 225 return -ENOTTY; 226 + } 227 + } 228 + 229 + static const char *ump_direction_string(int dir) 230 + { 231 + switch (dir) { 232 + case SNDRV_UMP_DIR_INPUT: 233 + return "input"; 234 + case SNDRV_UMP_DIR_OUTPUT: 235 + return "output"; 236 + case SNDRV_UMP_DIR_BIDIRECTION: 237 + return "bidirection"; 238 + default: 239 + return "unknown"; 240 + } 241 + } 242 + 243 + /* Additional proc file output */ 244 + static void snd_ump_proc_read(struct snd_info_entry *entry, 245 + struct snd_info_buffer *buffer) 246 + { 247 + struct snd_rawmidi *rmidi = entry->private_data; 248 + struct snd_ump_endpoint *ump = rawmidi_to_ump(rmidi); 249 + struct snd_ump_block *fb; 250 + 251 + snd_iprintf(buffer, "EP Name: %s\n", ump->info.name); 252 + snd_iprintf(buffer, "EP Product ID: %s\n", ump->info.product_id); 253 + snd_iprintf(buffer, "UMP Version: 0x%04x\n", ump->info.version); 254 + snd_iprintf(buffer, "Protocol Caps: 0x%08x\n", ump->info.protocol_caps); 255 + snd_iprintf(buffer, "Protocol: 0x%08x\n", ump->info.protocol); 256 + snd_iprintf(buffer, "Num Blocks: %d\n\n", ump->info.num_blocks); 257 + 258 + list_for_each_entry(fb, &ump->block_list, list) { 259 + snd_iprintf(buffer, "Block %d (%s)\n", fb->info.block_id, 260 + fb->info.name); 261 + snd_iprintf(buffer, " Direction: %s\n", 262 + ump_direction_string(fb->info.direction)); 263 + snd_iprintf(buffer, " Active: %s\n", 264 + fb->info.active ? "Yes" : "No"); 265 + snd_iprintf(buffer, " Groups: %d-%d\n", 266 + fb->info.first_group + 1, 267 + fb->info.first_group + fb->info.num_groups); 268 + snd_iprintf(buffer, " Is MIDI1: %s%s\n", 269 + (fb->info.flags & SNDRV_UMP_BLOCK_IS_MIDI1) ? "Yes" : "No", 270 + (fb->info.flags & SNDRV_UMP_BLOCK_IS_LOWSPEED) ? " (Low Speed)" : ""); 271 + snd_iprintf(buffer, "\n"); 229 272 } 230 273 } 231 274