Skip to content

Commit ff7b190

Browse files
committed
ALSA: seq: Fix delivery of UMP events to group ports
When an event with UMP message is sent to a UMP client, the EP port receives always no matter where the event is sent to, as it's a catch-all port. OTOH, if an event is sent to EP port, and if the event has a certain UMP Group, it should have been delivered to the associated UMP Group port, too, but this was ignored, so far. This patch addresses the behavior. Now a UMP event sent to the Endpoint port will be delivered to the subscribers of the UMP group port the event is associated with. The patch also does a bit of refactoring to simplify the code about __deliver_to_subscribers(). Fixes: 177ccf8 ("ALSA: seq: Support MIDI 2.0 UMP Endpoint port") Link: https://patch.msgid.link/20250511134528.6314-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 6e5bea1 commit ff7b190

File tree

3 files changed

+52
-19
lines changed

3 files changed

+52
-19
lines changed

sound/core/seq/seq_clientmgr.c

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -732,15 +732,21 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client,
732732
*/
733733
static int __deliver_to_subscribers(struct snd_seq_client *client,
734734
struct snd_seq_event *event,
735-
struct snd_seq_client_port *src_port,
736-
int atomic, int hop)
735+
int port, int atomic, int hop)
737736
{
737+
struct snd_seq_client_port *src_port;
738738
struct snd_seq_subscribers *subs;
739739
int err, result = 0, num_ev = 0;
740740
union __snd_seq_event event_saved;
741741
size_t saved_size;
742742
struct snd_seq_port_subs_info *grp;
743743

744+
if (port < 0)
745+
return 0;
746+
src_port = snd_seq_port_use_ptr(client, port);
747+
if (!src_port)
748+
return 0;
749+
744750
/* save original event record */
745751
saved_size = snd_seq_event_packet_size(event);
746752
memcpy(&event_saved, event, saved_size);
@@ -775,6 +781,7 @@ static int __deliver_to_subscribers(struct snd_seq_client *client,
775781
read_unlock(&grp->list_lock);
776782
else
777783
up_read(&grp->list_mutex);
784+
snd_seq_port_unlock(src_port);
778785
memcpy(event, &event_saved, saved_size);
779786
return (result < 0) ? result : num_ev;
780787
}
@@ -783,25 +790,32 @@ static int deliver_to_subscribers(struct snd_seq_client *client,
783790
struct snd_seq_event *event,
784791
int atomic, int hop)
785792
{
786-
struct snd_seq_client_port *src_port;
787-
int ret = 0, ret2;
788-
789-
src_port = snd_seq_port_use_ptr(client, event->source.port);
790-
if (src_port) {
791-
ret = __deliver_to_subscribers(client, event, src_port, atomic, hop);
792-
snd_seq_port_unlock(src_port);
793-
}
794-
795-
if (client->ump_endpoint_port < 0 ||
796-
event->source.port == client->ump_endpoint_port)
797-
return ret;
793+
int ret;
794+
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
795+
int ret2;
796+
#endif
798797

799-
src_port = snd_seq_port_use_ptr(client, client->ump_endpoint_port);
800-
if (!src_port)
798+
ret = __deliver_to_subscribers(client, event,
799+
event->source.port, atomic, hop);
800+
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
801+
if (!snd_seq_client_is_ump(client) || client->ump_endpoint_port < 0)
801802
return ret;
802-
ret2 = __deliver_to_subscribers(client, event, src_port, atomic, hop);
803-
snd_seq_port_unlock(src_port);
804-
return ret2 < 0 ? ret2 : ret;
803+
/* If it's an event from EP port (and with a UMP group),
804+
* deliver to subscribers of the corresponding UMP group port, too.
805+
* Or, if it's from non-EP port, deliver to subscribers of EP port, too.
806+
*/
807+
if (event->source.port == client->ump_endpoint_port)
808+
ret2 = __deliver_to_subscribers(client, event,
809+
snd_seq_ump_group_port(event),
810+
atomic, hop);
811+
else
812+
ret2 = __deliver_to_subscribers(client, event,
813+
client->ump_endpoint_port,
814+
atomic, hop);
815+
if (ret2 < 0)
816+
return ret2;
817+
#endif
818+
return ret;
805819
}
806820

807821
/* deliver an event to the destination port(s).

sound/core/seq/seq_ump_convert.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,3 +1285,21 @@ int snd_seq_deliver_to_ump(struct snd_seq_client *source,
12851285
else
12861286
return cvt_to_ump_midi1(dest, dest_port, event, atomic, hop);
12871287
}
1288+
1289+
/* return the UMP group-port number of the event;
1290+
* return -1 if groupless or non-UMP event
1291+
*/
1292+
int snd_seq_ump_group_port(const struct snd_seq_event *event)
1293+
{
1294+
const struct snd_seq_ump_event *ump_ev =
1295+
(const struct snd_seq_ump_event *)event;
1296+
unsigned char type;
1297+
1298+
if (!snd_seq_ev_is_ump(event))
1299+
return -1;
1300+
type = ump_message_type(ump_ev->ump[0]);
1301+
if (ump_is_groupless_msg(type))
1302+
return -1;
1303+
/* group-port number starts from 1 */
1304+
return ump_message_group(ump_ev->ump[0]) + 1;
1305+
}

sound/core/seq/seq_ump_convert.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ int snd_seq_deliver_to_ump(struct snd_seq_client *source,
1818
struct snd_seq_client_port *dest_port,
1919
struct snd_seq_event *event,
2020
int atomic, int hop);
21+
int snd_seq_ump_group_port(const struct snd_seq_event *event);
2122

2223
#endif /* __SEQ_UMP_CONVERT_H */

0 commit comments

Comments
 (0)