Commit 22eefaea authored by Takashi Iwai's avatar Takashi Iwai

ALSA: seq: Avoid delivery of events for disabled UMP groups

ALSA sequencer core still delivers events to the disabled UMP Group,
leaving this handling to the device.  But it's rather risky and it's
easy to imagine that such an unexpected event may screw up the device
firmware.

This patch avoids the superfluous event deliveries by setting the
group_filter of the UMP client as default, and evaluate the
group_filter properly at delivery from non-UMP clients.

The grouop_filter is updated upon the dynamic UMP Function Block
updates, so that it follows the change of the disabled UMP Groups,
too.

Fixes: d2b70607 ("ALSA: seq: Add UMP group filter")
Link: https://lore.kernel.org/r/20230912085144.32534-1-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 60edec9b
......@@ -416,6 +416,25 @@ static void setup_client_midi_version(struct seq_ump_client *client)
snd_seq_kernel_client_put(cptr);
}
/* set up client's group_filter bitmap */
static void setup_client_group_filter(struct seq_ump_client *client)
{
struct snd_seq_client *cptr;
unsigned int filter;
int p;
cptr = snd_seq_kernel_client_get(client->seq_client);
if (!cptr)
return;
filter = ~(1U << 0); /* always allow groupless messages */
for (p = 0; p < SNDRV_UMP_MAX_GROUPS; p++) {
if (client->groups[p].active)
filter &= ~(1U << (p + 1));
}
cptr->group_filter = filter;
snd_seq_kernel_client_put(cptr);
}
/* UMP group change notification */
static void handle_group_notify(struct work_struct *work)
{
......@@ -424,6 +443,7 @@ static void handle_group_notify(struct work_struct *work)
update_group_attrs(client);
update_port_infos(client);
setup_client_group_filter(client);
}
/* UMP FB change notification */
......@@ -492,6 +512,8 @@ static int snd_seq_ump_probe(struct device *_dev)
goto error;
}
setup_client_group_filter(client);
err = create_ump_endpoint_port(client);
if (err < 0)
goto error;
......
......@@ -1197,6 +1197,8 @@ int snd_seq_deliver_to_ump(struct snd_seq_client *source,
struct snd_seq_event *event,
int atomic, int hop)
{
if (dest->group_filter & (1U << dest_port->ump_group))
return 0; /* group filtered - skip the event */
if (event->type == SNDRV_SEQ_EVENT_SYSEX)
return cvt_sysex_to_ump(dest, dest_port, event, atomic, hop);
else if (snd_seq_client_is_midi2(dest))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment