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

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 <tiwai@suse.de>
Link: https://patch.msgid.link/20250827080520.7544-2-tiwai@suse.de

+35 -52
+1 -6
sound/core/seq/oss/seq_oss_device.h
··· 137 137 static inline int 138 138 snd_seq_oss_control(struct seq_oss_devinfo *dp, unsigned int type, void *arg) 139 139 { 140 - int err; 141 - 142 - snd_seq_client_ioctl_lock(dp->cseq); 143 - err = snd_seq_kernel_client_ctl(dp->cseq, type, arg); 144 - snd_seq_client_ioctl_unlock(dp->cseq); 145 - return err; 140 + return snd_seq_kernel_client_ioctl(dp->cseq, type, arg); 146 141 } 147 142 148 143 /* fill the addresses in header */
+33 -44
sound/core/seq/seq_clientmgr.c
··· 182 182 return client_use_ptr(clientid, IS_ENABLED(CONFIG_MODULES)); 183 183 } 184 184 185 - /* Take refcount and perform ioctl_mutex lock on the given client; 186 - * used only for OSS sequencer 187 - * Unlock via snd_seq_client_ioctl_unlock() below 188 - */ 189 - bool snd_seq_client_ioctl_lock(int clientid) 190 - { 191 - struct snd_seq_client *client; 192 - 193 - client = client_load_and_use_ptr(clientid); 194 - if (!client) 195 - return false; 196 - mutex_lock(&client->ioctl_mutex); 197 - /* The client isn't unrefed here; see snd_seq_client_ioctl_unlock() */ 198 - return true; 199 - } 200 - EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_lock); 201 - 202 - /* Unlock and unref the given client; for OSS sequencer use only */ 203 - void snd_seq_client_ioctl_unlock(int clientid) 204 - { 205 - struct snd_seq_client *client; 206 - 207 - client = snd_seq_client_use_ptr(clientid); 208 - if (WARN_ON(!client)) 209 - return; 210 - mutex_unlock(&client->ioctl_mutex); 211 - /* The doubly unrefs below are intentional; the first one releases the 212 - * leftover from snd_seq_client_ioctl_lock() above, and the second one 213 - * is for releasing snd_seq_client_use_ptr() in this function 214 - */ 215 - snd_seq_client_unlock(client); 216 - snd_seq_client_unlock(client); 217 - } 218 - EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_unlock); 219 - 220 185 static void usage_alloc(struct snd_seq_usage *res, int num) 221 186 { 222 187 res->cur += num; ··· 2523 2558 } 2524 2559 EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); 2525 2560 2561 + static int call_seq_client_ctl(struct snd_seq_client *client, 2562 + unsigned int cmd, void *arg) 2563 + { 2564 + const struct ioctl_handler *handler; 2565 + 2566 + for (handler = ioctl_handlers; handler->cmd > 0; ++handler) { 2567 + if (handler->cmd == cmd) 2568 + return handler->func(client, arg); 2569 + } 2570 + 2571 + pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", 2572 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); 2573 + return -ENOTTY; 2574 + } 2575 + 2526 2576 /** 2527 2577 * snd_seq_kernel_client_ctl - operate a command for a client with data in 2528 2578 * kernel space. ··· 2552 2572 */ 2553 2573 int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) 2554 2574 { 2555 - const struct ioctl_handler *handler; 2556 2575 struct snd_seq_client *client; 2557 2576 2558 2577 client = clientptr(clientid); 2559 2578 if (client == NULL) 2560 2579 return -ENXIO; 2561 2580 2562 - for (handler = ioctl_handlers; handler->cmd > 0; ++handler) { 2563 - if (handler->cmd == cmd) 2564 - return handler->func(client, arg); 2565 - } 2566 - 2567 - pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", 2568 - cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); 2569 - return -ENOTTY; 2581 + return call_seq_client_ctl(client, cmd, arg); 2570 2582 } 2571 2583 EXPORT_SYMBOL(snd_seq_kernel_client_ctl); 2584 + 2585 + /* a similar like above but taking locks; used only from OSS sequencer layer */ 2586 + int snd_seq_kernel_client_ioctl(int clientid, unsigned int cmd, void *arg) 2587 + { 2588 + struct snd_seq_client *client; 2589 + int ret; 2590 + 2591 + client = client_load_and_use_ptr(clientid); 2592 + if (!client) 2593 + return -ENXIO; 2594 + mutex_lock(&client->ioctl_mutex); 2595 + ret = call_seq_client_ctl(client, cmd, arg); 2596 + mutex_unlock(&client->ioctl_mutex); 2597 + snd_seq_client_unlock(client); 2598 + return ret; 2599 + } 2600 + EXPORT_SYMBOL_GPL(snd_seq_kernel_client_ioctl); 2572 2601 2573 2602 /* exported (for OSS emulator) */ 2574 2603 int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
+1 -2
sound/core/seq/seq_clientmgr.h
··· 94 94 int atomic, int hop); 95 95 96 96 /* only for OSS sequencer */ 97 - bool snd_seq_client_ioctl_lock(int clientid); 98 - void snd_seq_client_ioctl_unlock(int clientid); 97 + int snd_seq_kernel_client_ioctl(int clientid, unsigned int cmd, void *arg); 99 98 100 99 extern int seq_client_load[15]; 101 100