diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index b8a230a7583b..b0197b1d1fe4 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h @@ -18,6 +18,7 @@ #if IS_ENABLED(CONFIG_SND_SEQUENCER) #include #endif +#include /* * Raw MIDI interface @@ -49,6 +50,8 @@ struct snd_rawmidi_global_ops { struct snd_seq_port_info *info); long (*ioctl)(struct snd_rawmidi *rmidi, unsigned int cmd, void __user *argp); + void (*proc_read)(struct snd_info_entry *entry, + struct snd_info_buffer *buf); }; struct snd_rawmidi_runtime { diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index ffb5b58105f4..2d3cec908154 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1770,6 +1770,8 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, if (IS_ENABLED(CONFIG_SND_UMP)) snd_iprintf(buffer, "Type: %s\n", rawmidi_is_ump(rmidi) ? "UMP" : "Legacy"); + if (rmidi->ops->proc_read) + rmidi->ops->proc_read(entry, buffer); mutex_lock(&rmidi->open_mutex); if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { list_for_each_entry(substream, diff --git a/sound/core/ump.c b/sound/core/ump.c index ee57ba1ee989..651cd3752719 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -21,11 +21,14 @@ static int snd_ump_dev_register(struct snd_rawmidi *rmidi); static int snd_ump_dev_unregister(struct snd_rawmidi *rmidi); static long snd_ump_ioctl(struct snd_rawmidi *rmidi, unsigned int cmd, void __user *argp); +static void snd_ump_proc_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer); static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = { .dev_register = snd_ump_dev_register, .dev_unregister = snd_ump_dev_unregister, .ioctl = snd_ump_ioctl, + .proc_read = snd_ump_proc_read, }; static void snd_ump_endpoint_free(struct snd_rawmidi *rmidi) @@ -226,5 +229,51 @@ static long snd_ump_ioctl(struct snd_rawmidi *rmidi, unsigned int cmd, } } +static const char *ump_direction_string(int dir) +{ + switch (dir) { + case SNDRV_UMP_DIR_INPUT: + return "input"; + case SNDRV_UMP_DIR_OUTPUT: + return "output"; + case SNDRV_UMP_DIR_BIDIRECTION: + return "bidirection"; + default: + return "unknown"; + } +} + +/* Additional proc file output */ +static void snd_ump_proc_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_rawmidi *rmidi = entry->private_data; + struct snd_ump_endpoint *ump = rawmidi_to_ump(rmidi); + struct snd_ump_block *fb; + + snd_iprintf(buffer, "EP Name: %s\n", ump->info.name); + snd_iprintf(buffer, "EP Product ID: %s\n", ump->info.product_id); + snd_iprintf(buffer, "UMP Version: 0x%04x\n", ump->info.version); + snd_iprintf(buffer, "Protocol Caps: 0x%08x\n", ump->info.protocol_caps); + snd_iprintf(buffer, "Protocol: 0x%08x\n", ump->info.protocol); + snd_iprintf(buffer, "Num Blocks: %d\n\n", ump->info.num_blocks); + + list_for_each_entry(fb, &ump->block_list, list) { + snd_iprintf(buffer, "Block %d (%s)\n", fb->info.block_id, + fb->info.name); + snd_iprintf(buffer, " Direction: %s\n", + ump_direction_string(fb->info.direction)); + snd_iprintf(buffer, " Active: %s\n", + fb->info.active ? "Yes" : "No"); + snd_iprintf(buffer, " Groups: %d-%d\n", + fb->info.first_group + 1, + fb->info.first_group + fb->info.num_groups); + snd_iprintf(buffer, " Is MIDI1: %s%s\n", + (fb->info.flags & SNDRV_UMP_BLOCK_IS_MIDI1) ? "Yes" : "No", + (fb->info.flags & SNDRV_UMP_BLOCK_IS_LOWSPEED) ? " (Low Speed)" : ""); + snd_iprintf(buffer, "\n"); + } +} + MODULE_DESCRIPTION("Universal MIDI Packet (UMP) Core Driver"); MODULE_LICENSE("GPL");