From: Takashi Iwai Date: Wed, 27 Aug 2025 08:05:07 +0000 (+0200) Subject: ALSA: seq: Simplify internal command operation from OSS layer X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=df2e8107f037a87459ffc0eadb0b19e2611913f9;p=users%2Fhch%2Fmisc.git ALSA: seq: Simplify internal command operation from OSS layer snd_seq_client_ioctl_lock() and *_unlock() are used only from a single function of the OSS layer, and it's just to wrap the call of snd_seq_kernel_client_ctl(). Provide another variant of snd_seq_kernel_client_ctl() that takes the locks internally and drop the ugly snd_seq_client_ioctl_lock() and *_unlock() implementations, instead. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250827080520.7544-2-tiwai@suse.de --- diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h index 6163a00bc8de..935cf3df0b30 100644 --- a/sound/core/seq/oss/seq_oss_device.h +++ b/sound/core/seq/oss/seq_oss_device.h @@ -137,12 +137,7 @@ snd_seq_oss_dispatch(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int a static inline int snd_seq_oss_control(struct seq_oss_devinfo *dp, unsigned int type, void *arg) { - int err; - - snd_seq_client_ioctl_lock(dp->cseq); - err = snd_seq_kernel_client_ctl(dp->cseq, type, arg); - snd_seq_client_ioctl_unlock(dp->cseq); - return err; + return snd_seq_kernel_client_ioctl(dp->cseq, type, arg); } /* fill the addresses in header */ diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index aa9c956d2581..7787f4661626 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -182,41 +182,6 @@ static struct snd_seq_client *client_load_and_use_ptr(int clientid) return client_use_ptr(clientid, IS_ENABLED(CONFIG_MODULES)); } -/* Take refcount and perform ioctl_mutex lock on the given client; - * used only for OSS sequencer - * Unlock via snd_seq_client_ioctl_unlock() below - */ -bool snd_seq_client_ioctl_lock(int clientid) -{ - struct snd_seq_client *client; - - client = client_load_and_use_ptr(clientid); - if (!client) - return false; - mutex_lock(&client->ioctl_mutex); - /* The client isn't unrefed here; see snd_seq_client_ioctl_unlock() */ - return true; -} -EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_lock); - -/* Unlock and unref the given client; for OSS sequencer use only */ -void snd_seq_client_ioctl_unlock(int clientid) -{ - struct snd_seq_client *client; - - client = snd_seq_client_use_ptr(clientid); - if (WARN_ON(!client)) - return; - mutex_unlock(&client->ioctl_mutex); - /* The doubly unrefs below are intentional; the first one releases the - * leftover from snd_seq_client_ioctl_lock() above, and the second one - * is for releasing snd_seq_client_use_ptr() in this function - */ - snd_seq_client_unlock(client); - snd_seq_client_unlock(client); -} -EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_unlock); - static void usage_alloc(struct snd_seq_usage *res, int num) { res->cur += num; @@ -2558,6 +2523,21 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev, } EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); +static int call_seq_client_ctl(struct snd_seq_client *client, + unsigned int cmd, void *arg) +{ + const struct ioctl_handler *handler; + + for (handler = ioctl_handlers; handler->cmd > 0; ++handler) { + if (handler->cmd == cmd) + return handler->func(client, arg); + } + + pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); + return -ENOTTY; +} + /** * snd_seq_kernel_client_ctl - operate a command for a client with data in * kernel space. @@ -2572,24 +2552,33 @@ EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); */ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) { - const struct ioctl_handler *handler; struct snd_seq_client *client; client = clientptr(clientid); if (client == NULL) return -ENXIO; - for (handler = ioctl_handlers; handler->cmd > 0; ++handler) { - if (handler->cmd == cmd) - return handler->func(client, arg); - } - - pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", - cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); - return -ENOTTY; + return call_seq_client_ctl(client, cmd, arg); } EXPORT_SYMBOL(snd_seq_kernel_client_ctl); +/* a similar like above but taking locks; used only from OSS sequencer layer */ +int snd_seq_kernel_client_ioctl(int clientid, unsigned int cmd, void *arg) +{ + struct snd_seq_client *client; + int ret; + + client = client_load_and_use_ptr(clientid); + if (!client) + return -ENXIO; + mutex_lock(&client->ioctl_mutex); + ret = call_seq_client_ctl(client, cmd, arg); + mutex_unlock(&client->ioctl_mutex); + snd_seq_client_unlock(client); + return ret; +} +EXPORT_SYMBOL_GPL(snd_seq_kernel_client_ioctl); + /* exported (for OSS emulator) */ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait) { diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h index 915b1017286e..7d0758e72aa9 100644 --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h @@ -94,8 +94,7 @@ int __snd_seq_deliver_single_event(struct snd_seq_client *dest, int atomic, int hop); /* only for OSS sequencer */ -bool snd_seq_client_ioctl_lock(int clientid); -void snd_seq_client_ioctl_unlock(int clientid); +int snd_seq_kernel_client_ioctl(int clientid, unsigned int cmd, void *arg); extern int seq_client_load[15];