1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * ALSA sequencer Client Manager
4 * Copyright (c) 1998-2001 by Frank van de Pol <fvdpol@coil.demon.nl>
5 * Jaroslav Kysela <perex@perex.cz>
6 * Takashi Iwai <tiwai@suse.de>
7 */
8
9#include <linux/init.h>
10#include <linux/export.h>
11#include <linux/slab.h>
12#include <sound/core.h>
13#include <sound/minors.h>
14#include <linux/kmod.h>
15
16#include <sound/seq_kernel.h>
17#include <sound/ump.h>
18#include "seq_clientmgr.h"
19#include "seq_memory.h"
20#include "seq_queue.h"
21#include "seq_timer.h"
22#include "seq_info.h"
23#include "seq_system.h"
24#include "seq_ump_convert.h"
25#include <sound/seq_device.h>
26#ifdef CONFIG_COMPAT
27#include <linux/compat.h>
28#endif
29
30/* Client Manager
31
32 * this module handles the connections of userland and kernel clients
33 *
34 */
35
36/*
37 * There are four ranges of client numbers (last two shared):
38 * 0..15: global clients
39 * 16..127: statically allocated client numbers for cards 0..27
40 * 128..191: dynamically allocated client numbers for cards 28..31
41 * 128..191: dynamically allocated client numbers for applications
42 */
43
44/* number of kernel non-card clients */
45#define SNDRV_SEQ_GLOBAL_CLIENTS 16
46/* clients per cards, for static clients */
47#define SNDRV_SEQ_CLIENTS_PER_CARD 4
48/* dynamically allocated client numbers (both kernel drivers and user space) */
49#define SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN 128
50
51#define SNDRV_SEQ_LFLG_INPUT 0x0001
52#define SNDRV_SEQ_LFLG_OUTPUT 0x0002
53#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
54
55static DEFINE_SPINLOCK(clients_lock);
56static DEFINE_MUTEX(register_mutex);
57
58/*
59 * client table
60 */
61static char clienttablock[SNDRV_SEQ_MAX_CLIENTS];
62static struct snd_seq_client *clienttab[SNDRV_SEQ_MAX_CLIENTS];
63static struct snd_seq_usage client_usage;
64
65/*
66 * prototypes
67 */
68static int bounce_error_event(struct snd_seq_client *client,
69 struct snd_seq_event *event,
70 int err, int atomic, int hop);
71static int snd_seq_deliver_single_event(struct snd_seq_client *client,
72 struct snd_seq_event *event,
73 int atomic, int hop);
74
75#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
76static void free_ump_info(struct snd_seq_client *client);
77#endif
78
79/*
80 */
81static inline unsigned short snd_seq_file_flags(struct file *file)
82{
83 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
84 case FMODE_WRITE:
85 return SNDRV_SEQ_LFLG_OUTPUT;
86 case FMODE_READ:
87 return SNDRV_SEQ_LFLG_INPUT;
88 default:
89 return SNDRV_SEQ_LFLG_OPEN;
90 }
91}
92
93static inline int snd_seq_write_pool_allocated(struct snd_seq_client *client)
94{
95 return snd_seq_total_cells(pool: client->pool) > 0;
96}
97
98/* return pointer to client structure for specified id */
99static struct snd_seq_client *clientptr(int clientid)
100{
101 if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
102 pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n",
103 clientid);
104 return NULL;
105 }
106 return clienttab[clientid];
107}
108
109static struct snd_seq_client *client_use_ptr(int clientid, bool load_module)
110{
111 struct snd_seq_client *client;
112
113 if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
114 pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n",
115 clientid);
116 return NULL;
117 }
118 scoped_guard(spinlock_irqsave, &clients_lock) {
119 client = clientptr(clientid);
120 if (client)
121 return snd_seq_client_ref(client);
122 if (clienttablock[clientid])
123 return NULL;
124 }
125#ifdef CONFIG_MODULES
126 if (load_module) {
127 static DECLARE_BITMAP(client_requested, SNDRV_SEQ_GLOBAL_CLIENTS);
128 static DECLARE_BITMAP(card_requested, SNDRV_CARDS);
129
130 if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) {
131 int idx;
132
133 if (!test_and_set_bit(nr: clientid, addr: client_requested)) {
134 for (idx = 0; idx < 15; idx++) {
135 if (seq_client_load[idx] < 0)
136 break;
137 if (seq_client_load[idx] == clientid) {
138 request_module("snd-seq-client-%i",
139 clientid);
140 break;
141 }
142 }
143 }
144 } else if (clientid < SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN) {
145 int card = (clientid - SNDRV_SEQ_GLOBAL_CLIENTS) /
146 SNDRV_SEQ_CLIENTS_PER_CARD;
147 if (card < snd_ecards_limit) {
148 if (!test_and_set_bit(nr: card, addr: card_requested))
149 snd_request_card(card);
150 snd_seq_device_load_drivers();
151 }
152 }
153 scoped_guard(spinlock_irqsave, &clients_lock) {
154 client = clientptr(clientid);
155 if (client)
156 return snd_seq_client_ref(client);
157 }
158 }
159#endif
160 return NULL;
161}
162
163/* get snd_seq_client object for the given id quickly */
164struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
165{
166 return client_use_ptr(clientid, load_module: false);
167}
168
169/* get snd_seq_client object for the given id;
170 * if not found, retry after loading the modules
171 */
172static struct snd_seq_client *client_load_and_use_ptr(int clientid)
173{
174 return client_use_ptr(clientid, IS_ENABLED(CONFIG_MODULES));
175}
176
177static void usage_alloc(struct snd_seq_usage *res, int num)
178{
179 res->cur += num;
180 if (res->cur > res->peak)
181 res->peak = res->cur;
182}
183
184static void usage_free(struct snd_seq_usage *res, int num)
185{
186 res->cur -= num;
187}
188
189/* initialise data structures */
190int __init client_init_data(void)
191{
192 /* zap out the client table */
193 memset(s: &clienttablock, c: 0, n: sizeof(clienttablock));
194 memset(s: &clienttab, c: 0, n: sizeof(clienttab));
195 return 0;
196}
197
198
199static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
200{
201 int c;
202 struct snd_seq_client *client;
203
204 /* init client data */
205 client = kzalloc(sizeof(*client), GFP_KERNEL);
206 if (client == NULL)
207 return NULL;
208 client->pool = snd_seq_pool_new(poolsize);
209 if (client->pool == NULL) {
210 kfree(objp: client);
211 return NULL;
212 }
213 client->type = NO_CLIENT;
214 snd_use_lock_init(&client->use_lock);
215 rwlock_init(&client->ports_lock);
216 mutex_init(&client->ports_mutex);
217 INIT_LIST_HEAD(list: &client->ports_list_head);
218 mutex_init(&client->ioctl_mutex);
219 client->ump_endpoint_port = -1;
220
221 /* find free slot in the client table */
222 scoped_guard(spinlock_irq, &clients_lock) {
223 if (client_index < 0) {
224 for (c = SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN;
225 c < SNDRV_SEQ_MAX_CLIENTS;
226 c++) {
227 if (clienttab[c] || clienttablock[c])
228 continue;
229 clienttab[client->number = c] = client;
230 return client;
231 }
232 } else {
233 if (clienttab[client_index] == NULL && !clienttablock[client_index]) {
234 clienttab[client->number = client_index] = client;
235 return client;
236 }
237 }
238 }
239
240 snd_seq_pool_delete(pool: &client->pool);
241 kfree(objp: client);
242 return NULL; /* no free slot found or busy, return failure code */
243}
244
245
246static int seq_free_client1(struct snd_seq_client *client)
247{
248 if (!client)
249 return 0;
250 scoped_guard(spinlock_irq, &clients_lock) {
251 clienttablock[client->number] = 1;
252 clienttab[client->number] = NULL;
253 }
254 snd_seq_delete_all_ports(client);
255 snd_seq_queue_client_leave(client: client->number);
256 snd_use_lock_sync(&client->use_lock);
257 if (client->pool)
258 snd_seq_pool_delete(pool: &client->pool);
259 scoped_guard(spinlock_irq, &clients_lock) {
260 clienttablock[client->number] = 0;
261 }
262 return 0;
263}
264
265
266static void seq_free_client(struct snd_seq_client * client)
267{
268 scoped_guard(mutex, &register_mutex) {
269 switch (client->type) {
270 case NO_CLIENT:
271 pr_warn("ALSA: seq: Trying to free unused client %d\n",
272 client->number);
273 break;
274 case USER_CLIENT:
275 case KERNEL_CLIENT:
276 seq_free_client1(client);
277 usage_free(res: &client_usage, num: 1);
278 break;
279
280 default:
281 pr_err("ALSA: seq: Trying to free client %d with undefined type = %d\n",
282 client->number, client->type);
283 }
284 }
285
286 snd_seq_system_client_ev_client_exit(client->number);
287}
288
289
290
291/* -------------------------------------------------------- */
292
293/* create a user client */
294static int snd_seq_open(struct inode *inode, struct file *file)
295{
296 int c, mode; /* client id */
297 struct snd_seq_client *client;
298 struct snd_seq_user_client *user;
299 int err;
300
301 err = stream_open(inode, filp: file);
302 if (err < 0)
303 return err;
304
305 scoped_guard(mutex, &register_mutex) {
306 client = seq_create_client1(client_index: -1, SNDRV_SEQ_DEFAULT_EVENTS);
307 if (!client)
308 return -ENOMEM; /* failure code */
309
310 mode = snd_seq_file_flags(file);
311 if (mode & SNDRV_SEQ_LFLG_INPUT)
312 client->accept_input = 1;
313 if (mode & SNDRV_SEQ_LFLG_OUTPUT)
314 client->accept_output = 1;
315
316 user = &client->data.user;
317 user->fifo = NULL;
318 user->fifo_pool_size = 0;
319
320 if (mode & SNDRV_SEQ_LFLG_INPUT) {
321 user->fifo_pool_size = SNDRV_SEQ_DEFAULT_CLIENT_EVENTS;
322 user->fifo = snd_seq_fifo_new(poolsize: user->fifo_pool_size);
323 if (user->fifo == NULL) {
324 seq_free_client1(client);
325 kfree(objp: client);
326 return -ENOMEM;
327 }
328 }
329
330 usage_alloc(res: &client_usage, num: 1);
331 client->type = USER_CLIENT;
332 }
333
334 c = client->number;
335 file->private_data = client;
336
337 /* fill client data */
338 user->file = file;
339 sprintf(buf: client->name, fmt: "Client-%d", c);
340 client->data.user.owner = get_pid(pid: task_pid(current));
341
342 /* make others aware this new client */
343 snd_seq_system_client_ev_client_start(c);
344
345 return 0;
346}
347
348/* delete a user client */
349static int snd_seq_release(struct inode *inode, struct file *file)
350{
351 struct snd_seq_client *client = file->private_data;
352
353 if (client) {
354 seq_free_client(client);
355 if (client->data.user.fifo)
356 snd_seq_fifo_delete(f: &client->data.user.fifo);
357#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
358 free_ump_info(client);
359#endif
360 put_pid(pid: client->data.user.owner);
361 kfree(objp: client);
362 }
363
364 return 0;
365}
366
367static bool event_is_compatible(const struct snd_seq_client *client,
368 const struct snd_seq_event *ev)
369{
370 if (snd_seq_ev_is_ump(ev) && !client->midi_version)
371 return false;
372 if (snd_seq_ev_is_ump(ev) && snd_seq_ev_is_variable(ev))
373 return false;
374 return true;
375}
376
377/* handle client read() */
378/* possible error values:
379 * -ENXIO invalid client or file open mode
380 * -ENOSPC FIFO overflow (the flag is cleared after this error report)
381 * -EINVAL no enough user-space buffer to write the whole event
382 * -EFAULT seg. fault during copy to user space
383 */
384static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
385 loff_t *offset)
386{
387 struct snd_seq_client *client = file->private_data;
388 struct snd_seq_fifo *fifo;
389 size_t aligned_size;
390 int err;
391 long result = 0;
392 struct snd_seq_event_cell *cell;
393
394 if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT))
395 return -ENXIO;
396
397 if (!access_ok(buf, count))
398 return -EFAULT;
399
400 /* check client structures are in place */
401 if (snd_BUG_ON(!client))
402 return -ENXIO;
403
404 if (!client->accept_input)
405 return -ENXIO;
406 fifo = client->data.user.fifo;
407 if (!fifo)
408 return -ENXIO;
409
410 if (atomic_read(v: &fifo->overflow) > 0) {
411 /* buffer overflow is detected */
412 snd_seq_fifo_clear(f: fifo);
413 /* return error code */
414 return -ENOSPC;
415 }
416
417 cell = NULL;
418 err = 0;
419 guard(snd_seq_fifo)(T: fifo);
420
421 if (IS_ENABLED(CONFIG_SND_SEQ_UMP) && client->midi_version > 0)
422 aligned_size = sizeof(struct snd_seq_ump_event);
423 else
424 aligned_size = sizeof(struct snd_seq_event);
425
426 /* while data available in queue */
427 while (count >= aligned_size) {
428 int nonblock;
429
430 nonblock = (file->f_flags & O_NONBLOCK) || result > 0;
431 err = snd_seq_fifo_cell_out(f: fifo, cellp: &cell, nonblock);
432 if (err < 0)
433 break;
434 if (!event_is_compatible(client, ev: &cell->event)) {
435 snd_seq_cell_free(cell);
436 cell = NULL;
437 continue;
438 }
439 if (snd_seq_ev_is_variable(&cell->event)) {
440 struct snd_seq_ump_event tmpev;
441
442 memcpy(to: &tmpev, from: &cell->event, len: aligned_size);
443 tmpev.data.ext.len &= ~SNDRV_SEQ_EXT_MASK;
444 if (copy_to_user(to: buf, from: &tmpev, n: aligned_size)) {
445 err = -EFAULT;
446 break;
447 }
448 count -= aligned_size;
449 buf += aligned_size;
450 err = snd_seq_expand_var_event(event: &cell->event, count,
451 buf: (char __force *)buf, in_kernel: 0,
452 size_aligned: aligned_size);
453 if (err < 0)
454 break;
455 result += err;
456 count -= err;
457 buf += err;
458 } else {
459 if (copy_to_user(to: buf, from: &cell->event, n: aligned_size)) {
460 err = -EFAULT;
461 break;
462 }
463 count -= aligned_size;
464 buf += aligned_size;
465 }
466 snd_seq_cell_free(cell);
467 cell = NULL; /* to be sure */
468 result += aligned_size;
469 }
470
471 if (err < 0) {
472 if (cell)
473 snd_seq_fifo_cell_putback(f: fifo, cell);
474 if (err == -EAGAIN && result > 0)
475 err = 0;
476 }
477
478 return (err < 0) ? err : result;
479}
480
481
482/*
483 * check access permission to the port
484 */
485static int check_port_perm(struct snd_seq_client_port *port, unsigned int flags)
486{
487 if ((port->capability & flags) != flags)
488 return 0;
489 return flags;
490}
491
492/*
493 * check if the destination client is available, and return the pointer
494 */
495static struct snd_seq_client *get_event_dest_client(struct snd_seq_event *event)
496{
497 struct snd_seq_client *dest __free(snd_seq_client) = NULL;
498
499 dest = snd_seq_client_use_ptr(clientid: event->dest.client);
500 if (dest == NULL)
501 return NULL;
502 if (! dest->accept_input)
503 return NULL;
504 if (snd_seq_ev_is_ump(event))
505 return no_free_ptr(dest); /* ok - no filter checks */
506
507 if ((dest->filter & SNDRV_SEQ_FILTER_USE_EVENT) &&
508 ! test_bit(event->type, dest->event_filter))
509 return NULL;
510
511 return no_free_ptr(dest); /* ok - accessible */
512}
513
514
515/*
516 * Return the error event.
517 *
518 * If the receiver client is a user client, the original event is
519 * encapsulated in SNDRV_SEQ_EVENT_BOUNCE as variable length event. If
520 * the original event is also variable length, the external data is
521 * copied after the event record.
522 * If the receiver client is a kernel client, the original event is
523 * quoted in SNDRV_SEQ_EVENT_KERNEL_ERROR, since this requires no extra
524 * kmalloc.
525 */
526static int bounce_error_event(struct snd_seq_client *client,
527 struct snd_seq_event *event,
528 int err, int atomic, int hop)
529{
530 struct snd_seq_event bounce_ev;
531 int result;
532
533 if (client == NULL ||
534 ! (client->filter & SNDRV_SEQ_FILTER_BOUNCE) ||
535 ! client->accept_input)
536 return 0; /* ignored */
537
538 /* set up quoted error */
539 memset(s: &bounce_ev, c: 0, n: sizeof(bounce_ev));
540 bounce_ev.type = SNDRV_SEQ_EVENT_KERNEL_ERROR;
541 bounce_ev.flags = SNDRV_SEQ_EVENT_LENGTH_FIXED;
542 bounce_ev.queue = SNDRV_SEQ_QUEUE_DIRECT;
543 bounce_ev.source.client = SNDRV_SEQ_CLIENT_SYSTEM;
544 bounce_ev.source.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
545 bounce_ev.dest.client = client->number;
546 bounce_ev.dest.port = event->source.port;
547 bounce_ev.data.quote.origin = event->dest;
548 bounce_ev.data.quote.event = event;
549 bounce_ev.data.quote.value = -err; /* use positive value */
550 result = snd_seq_deliver_single_event(NULL, event: &bounce_ev, atomic, hop: hop + 1);
551 if (result < 0) {
552 client->event_lost++;
553 return result;
554 }
555
556 return result;
557}
558
559
560/*
561 * rewrite the time-stamp of the event record with the curren time
562 * of the given queue.
563 * return non-zero if updated.
564 */
565static int update_timestamp_of_queue(struct snd_seq_event *event,
566 int queue, int real_time)
567{
568 struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
569
570 q = queueptr(queueid: queue);
571 if (! q)
572 return 0;
573 event->queue = queue;
574 event->flags &= ~SNDRV_SEQ_TIME_STAMP_MASK;
575 if (real_time) {
576 event->time.time = snd_seq_timer_get_cur_time(tmr: q->timer, adjust_ktime: true);
577 event->flags |= SNDRV_SEQ_TIME_STAMP_REAL;
578 } else {
579 event->time.tick = snd_seq_timer_get_cur_tick(tmr: q->timer);
580 event->flags |= SNDRV_SEQ_TIME_STAMP_TICK;
581 }
582 return 1;
583}
584
585/* deliver a single event; called from below and UMP converter */
586int __snd_seq_deliver_single_event(struct snd_seq_client *dest,
587 struct snd_seq_client_port *dest_port,
588 struct snd_seq_event *event,
589 int atomic, int hop)
590{
591 switch (dest->type) {
592 case USER_CLIENT:
593 if (!dest->data.user.fifo)
594 return 0;
595 return snd_seq_fifo_event_in(f: dest->data.user.fifo, event);
596 case KERNEL_CLIENT:
597 if (!dest_port->event_input)
598 return 0;
599 return dest_port->event_input(event,
600 snd_seq_ev_is_direct(event),
601 dest_port->private_data,
602 atomic, hop);
603 }
604 return 0;
605}
606
607/* deliver a single event; called from snd_seq_deliver_single_event() */
608static int _snd_seq_deliver_single_event(struct snd_seq_client *client,
609 struct snd_seq_event *event,
610 int atomic, int hop)
611{
612 struct snd_seq_client *dest __free(snd_seq_client) = NULL;
613 struct snd_seq_client_port *dest_port __free(snd_seq_port) = NULL;
614
615 dest = get_event_dest_client(event);
616 if (dest == NULL)
617 return -ENOENT;
618 dest_port = snd_seq_port_use_ptr(client: dest, num: event->dest.port);
619 if (dest_port == NULL)
620 return -ENOENT;
621
622 /* check permission */
623 if (!check_port_perm(port: dest_port, SNDRV_SEQ_PORT_CAP_WRITE))
624 return -EPERM;
625
626 if (dest_port->timestamping)
627 update_timestamp_of_queue(event, queue: dest_port->time_queue,
628 real_time: dest_port->time_real);
629
630#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
631 if (snd_seq_ev_is_ump(event)) {
632 if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT))
633 return snd_seq_deliver_from_ump(client, dest, dest_port,
634 event, atomic, hop);
635 else if (dest->type == USER_CLIENT &&
636 !snd_seq_client_is_ump(dest))
637 return 0; // drop the event
638 } else if (snd_seq_client_is_ump(dest)) {
639 if (!(dest->filter & SNDRV_SEQ_FILTER_NO_CONVERT))
640 return snd_seq_deliver_to_ump(client, dest, dest_port,
641 event, atomic, hop);
642 }
643#endif /* CONFIG_SND_SEQ_UMP */
644
645 return __snd_seq_deliver_single_event(dest, dest_port, event,
646 atomic, hop);
647}
648
649/*
650 * deliver an event to the specified destination.
651 * if filter is non-zero, client filter bitmap is tested.
652 *
653 * RETURN VALUE: 0 : if succeeded
654 * <0 : error
655 */
656static int snd_seq_deliver_single_event(struct snd_seq_client *client,
657 struct snd_seq_event *event,
658 int atomic, int hop)
659{
660 int result = _snd_seq_deliver_single_event(client, event, atomic, hop);
661
662 if (result < 0 && !snd_seq_ev_is_direct(event))
663 return bounce_error_event(client, event, err: result, atomic, hop);
664 return result;
665}
666
667
668/*
669 * send the event to all subscribers:
670 */
671static int __deliver_to_subscribers(struct snd_seq_client *client,
672 struct snd_seq_event *event,
673 int port, int atomic, int hop)
674{
675 struct snd_seq_client_port *src_port __free(snd_seq_port) = NULL;
676 struct snd_seq_subscribers *subs;
677 int err, result = 0, num_ev = 0;
678 union __snd_seq_event event_saved;
679 size_t saved_size;
680 struct snd_seq_port_subs_info *grp;
681
682 if (port < 0)
683 return 0;
684 src_port = snd_seq_port_use_ptr(client, num: port);
685 if (!src_port)
686 return 0;
687
688 /* save original event record */
689 saved_size = snd_seq_event_packet_size(ev: event);
690 memcpy(to: &event_saved, from: event, len: saved_size);
691 grp = &src_port->c_src;
692
693 /* lock list */
694 if (atomic)
695 read_lock(&grp->list_lock);
696 else
697 down_read_nested(&grp->list_mutex, hop);
698 list_for_each_entry(subs, &grp->list_head, src_list) {
699 /* both ports ready? */
700 if (atomic_read(v: &subs->ref_count) != 2)
701 continue;
702 event->dest = subs->info.dest;
703 if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP)
704 /* convert time according to flag with subscription */
705 update_timestamp_of_queue(event, queue: subs->info.queue,
706 real_time: subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL);
707 err = snd_seq_deliver_single_event(client, event, atomic, hop);
708 if (err < 0) {
709 /* save first error that occurs and continue */
710 if (!result)
711 result = err;
712 continue;
713 }
714 num_ev++;
715 /* restore original event record */
716 memcpy(to: event, from: &event_saved, len: saved_size);
717 }
718 if (atomic)
719 read_unlock(&grp->list_lock);
720 else
721 up_read(sem: &grp->list_mutex);
722 memcpy(to: event, from: &event_saved, len: saved_size);
723 return (result < 0) ? result : num_ev;
724}
725
726static int deliver_to_subscribers(struct snd_seq_client *client,
727 struct snd_seq_event *event,
728 int atomic, int hop)
729{
730 int ret;
731#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
732 int ret2;
733#endif
734
735 ret = __deliver_to_subscribers(client, event,
736 port: event->source.port, atomic, hop);
737#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
738 if (!snd_seq_client_is_ump(client) || client->ump_endpoint_port < 0)
739 return ret;
740 /* If it's an event from EP port (and with a UMP group),
741 * deliver to subscribers of the corresponding UMP group port, too.
742 * Or, if it's from non-EP port, deliver to subscribers of EP port, too.
743 */
744 if (event->source.port == client->ump_endpoint_port)
745 ret2 = __deliver_to_subscribers(client, event,
746 snd_seq_ump_group_port(event),
747 atomic, hop);
748 else
749 ret2 = __deliver_to_subscribers(client, event,
750 client->ump_endpoint_port,
751 atomic, hop);
752 if (ret2 < 0)
753 return ret2;
754#endif
755 return ret;
756}
757
758/* deliver an event to the destination port(s).
759 * if the event is to subscribers or broadcast, the event is dispatched
760 * to multiple targets.
761 *
762 * RETURN VALUE: n > 0 : the number of delivered events.
763 * n == 0 : the event was not passed to any client.
764 * n < 0 : error - event was not processed.
765 */
766static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_event *event,
767 int atomic, int hop)
768{
769 int result;
770
771 hop++;
772 if (hop >= SNDRV_SEQ_MAX_HOPS) {
773 pr_debug("ALSA: seq: too long delivery path (%d:%d->%d:%d)\n",
774 event->source.client, event->source.port,
775 event->dest.client, event->dest.port);
776 return -EMLINK;
777 }
778
779 if (snd_seq_ev_is_variable(event) &&
780 snd_BUG_ON(atomic && (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR)))
781 return -EINVAL;
782
783 if (event->queue == SNDRV_SEQ_ADDRESS_SUBSCRIBERS ||
784 event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS)
785 result = deliver_to_subscribers(client, event, atomic, hop);
786 else
787 result = snd_seq_deliver_single_event(client, event, atomic, hop);
788
789 return result;
790}
791
792/*
793 * dispatch an event cell:
794 * This function is called only from queue check routines in timer
795 * interrupts or after enqueued.
796 * The event cell shall be released or re-queued in this function.
797 *
798 * RETURN VALUE: n > 0 : the number of delivered events.
799 * n == 0 : the event was not passed to any client.
800 * n < 0 : error - event was not processed.
801 */
802int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
803{
804 struct snd_seq_client *client __free(snd_seq_client) = NULL;
805 int result;
806
807 if (snd_BUG_ON(!cell))
808 return -EINVAL;
809
810 client = snd_seq_client_use_ptr(clientid: cell->event.source.client);
811 if (client == NULL) {
812 snd_seq_cell_free(cell); /* release this cell */
813 return -EINVAL;
814 }
815
816 if (!snd_seq_ev_is_ump(&cell->event) &&
817 cell->event.type == SNDRV_SEQ_EVENT_NOTE) {
818 /* NOTE event:
819 * the event cell is re-used as a NOTE-OFF event and
820 * enqueued again.
821 */
822 struct snd_seq_event tmpev, *ev;
823
824 /* reserve this event to enqueue note-off later */
825 tmpev = cell->event;
826 tmpev.type = SNDRV_SEQ_EVENT_NOTEON;
827 result = snd_seq_deliver_event(client, event: &tmpev, atomic, hop);
828
829 /*
830 * This was originally a note event. We now re-use the
831 * cell for the note-off event.
832 */
833
834 ev = &cell->event;
835 ev->type = SNDRV_SEQ_EVENT_NOTEOFF;
836 ev->flags |= SNDRV_SEQ_PRIORITY_HIGH;
837
838 /* add the duration time */
839 switch (ev->flags & SNDRV_SEQ_TIME_STAMP_MASK) {
840 case SNDRV_SEQ_TIME_STAMP_TICK:
841 cell->event.time.tick += ev->data.note.duration;
842 break;
843 case SNDRV_SEQ_TIME_STAMP_REAL:
844 /* unit for duration is ms */
845 ev->time.time.tv_nsec += 1000000 * (ev->data.note.duration % 1000);
846 ev->time.time.tv_sec += ev->data.note.duration / 1000 +
847 ev->time.time.tv_nsec / 1000000000;
848 ev->time.time.tv_nsec %= 1000000000;
849 break;
850 }
851 ev->data.note.velocity = ev->data.note.off_velocity;
852
853 /* Now queue this cell as the note off event */
854 if (snd_seq_enqueue_event(cell, atomic, hop) < 0)
855 snd_seq_cell_free(cell); /* release this cell */
856
857 } else {
858 /* Normal events:
859 * event cell is freed after processing the event
860 */
861
862 result = snd_seq_deliver_event(client, event: &cell->event, atomic, hop);
863 snd_seq_cell_free(cell);
864 }
865
866 return result;
867}
868
869
870/* Allocate a cell from client pool and enqueue it to queue:
871 * if pool is empty and blocking is TRUE, sleep until a new cell is
872 * available.
873 */
874static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
875 struct snd_seq_event *event,
876 struct file *file, int blocking,
877 int atomic, int hop,
878 struct mutex *mutexp)
879{
880 struct snd_seq_event_cell *cell;
881 int err;
882
883 /* special queue values - force direct passing */
884 if (event->queue == SNDRV_SEQ_ADDRESS_SUBSCRIBERS) {
885 event->dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
886 event->queue = SNDRV_SEQ_QUEUE_DIRECT;
887 } else if (event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS) {
888 /* check presence of source port */
889 struct snd_seq_client_port *src_port __free(snd_seq_port) =
890 snd_seq_port_use_ptr(client, num: event->source.port);
891 if (!src_port)
892 return -EINVAL;
893 }
894
895 /* direct event processing without enqueued */
896 if (snd_seq_ev_is_direct(event)) {
897 if (!snd_seq_ev_is_ump(event) &&
898 event->type == SNDRV_SEQ_EVENT_NOTE)
899 return -EINVAL; /* this event must be enqueued! */
900 return snd_seq_deliver_event(client, event, atomic, hop);
901 }
902
903 /* Not direct, normal queuing */
904 if (snd_seq_queue_is_used(queueid: event->queue, client: client->number) <= 0)
905 return -EINVAL; /* invalid queue */
906 if (! snd_seq_write_pool_allocated(client))
907 return -ENXIO; /* queue is not allocated */
908
909 /* allocate an event cell */
910 err = snd_seq_event_dup(pool: client->pool, event, cellp: &cell, nonblock: !blocking || atomic,
911 file, mutexp);
912 if (err < 0)
913 return err;
914
915 /* we got a cell. enqueue it. */
916 err = snd_seq_enqueue_event(cell, atomic, hop);
917 if (err < 0) {
918 snd_seq_cell_free(cell);
919 return err;
920 }
921
922 return 0;
923}
924
925
926/*
927 * check validity of event type and data length.
928 * return non-zero if invalid.
929 */
930static int check_event_type_and_length(struct snd_seq_event *ev)
931{
932 switch (snd_seq_ev_length_type(ev)) {
933 case SNDRV_SEQ_EVENT_LENGTH_FIXED:
934 if (snd_seq_ev_is_variable_type(ev))
935 return -EINVAL;
936 break;
937 case SNDRV_SEQ_EVENT_LENGTH_VARIABLE:
938 if (! snd_seq_ev_is_variable_type(ev) ||
939 (ev->data.ext.len & ~SNDRV_SEQ_EXT_MASK) >= SNDRV_SEQ_MAX_EVENT_LEN)
940 return -EINVAL;
941 break;
942 case SNDRV_SEQ_EVENT_LENGTH_VARUSR:
943 if (! snd_seq_ev_is_direct(ev))
944 return -EINVAL;
945 break;
946 }
947 return 0;
948}
949
950
951/* handle write() */
952/* possible error values:
953 * -ENXIO invalid client or file open mode
954 * -ENOMEM malloc failed
955 * -EFAULT seg. fault during copy from user space
956 * -EINVAL invalid event
957 * -EAGAIN no space in output pool
958 * -EINTR interrupts while sleep
959 * -EMLINK too many hops
960 * others depends on return value from driver callback
961 */
962static ssize_t snd_seq_write(struct file *file, const char __user *buf,
963 size_t count, loff_t *offset)
964{
965 struct snd_seq_client *client = file->private_data;
966 int written = 0, len;
967 int err, handled;
968 union __snd_seq_event __event;
969 struct snd_seq_event *ev = &__event.legacy;
970
971 if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT))
972 return -ENXIO;
973
974 /* check client structures are in place */
975 if (snd_BUG_ON(!client))
976 return -ENXIO;
977
978 if (!client->accept_output || client->pool == NULL)
979 return -ENXIO;
980
981 repeat:
982 handled = 0;
983 /* allocate the pool now if the pool is not allocated yet */
984 mutex_lock(lock: &client->ioctl_mutex);
985 if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
986 err = snd_seq_pool_init(pool: client->pool);
987 if (err < 0)
988 goto out;
989 }
990
991 /* only process whole events */
992 err = -EINVAL;
993 while (count >= sizeof(struct snd_seq_event)) {
994 /* Read in the event header from the user */
995 len = sizeof(struct snd_seq_event);
996 if (copy_from_user(to: ev, from: buf, n: len)) {
997 err = -EFAULT;
998 break;
999 }
1000 /* read in the rest bytes for UMP events */
1001 if (snd_seq_ev_is_ump(ev)) {
1002 if (count < sizeof(struct snd_seq_ump_event))
1003 break;
1004 if (copy_from_user(to: (char *)ev + len, from: buf + len,
1005 n: sizeof(struct snd_seq_ump_event) - len)) {
1006 err = -EFAULT;
1007 break;
1008 }
1009 len = sizeof(struct snd_seq_ump_event);
1010 }
1011
1012 ev->source.client = client->number; /* fill in client number */
1013 /* Check for extension data length */
1014 if (check_event_type_and_length(ev)) {
1015 err = -EINVAL;
1016 break;
1017 }
1018
1019 if (!event_is_compatible(client, ev)) {
1020 err = -EINVAL;
1021 break;
1022 }
1023
1024 /* check for special events */
1025 if (!snd_seq_ev_is_ump(ev)) {
1026 if (ev->type == SNDRV_SEQ_EVENT_NONE)
1027 goto __skip_event;
1028 else if (snd_seq_ev_is_reserved(ev)) {
1029 err = -EINVAL;
1030 break;
1031 }
1032 }
1033
1034 if (snd_seq_ev_is_variable(ev)) {
1035 int extlen = ev->data.ext.len & ~SNDRV_SEQ_EXT_MASK;
1036 if ((size_t)(extlen + len) > count) {
1037 /* back out, will get an error this time or next */
1038 err = -EINVAL;
1039 break;
1040 }
1041 /* set user space pointer */
1042 ev->data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR;
1043 ev->data.ext.ptr = (char __force *)buf + len;
1044 len += extlen; /* increment data length */
1045 } else {
1046#ifdef CONFIG_COMPAT
1047 if (client->convert32 && snd_seq_ev_is_varusr(ev))
1048 ev->data.ext.ptr =
1049 (void __force *)compat_ptr(uptr: ev->data.raw32.d[1]);
1050#endif
1051 }
1052
1053 /* ok, enqueue it */
1054 err = snd_seq_client_enqueue_event(client, event: ev, file,
1055 blocking: !(file->f_flags & O_NONBLOCK),
1056 atomic: 0, hop: 0, mutexp: &client->ioctl_mutex);
1057 if (err < 0)
1058 break;
1059 handled++;
1060
1061 __skip_event:
1062 /* Update pointers and counts */
1063 count -= len;
1064 buf += len;
1065 written += len;
1066
1067 /* let's have a coffee break if too many events are queued */
1068 if (++handled >= 200) {
1069 mutex_unlock(lock: &client->ioctl_mutex);
1070 goto repeat;
1071 }
1072 }
1073
1074 out:
1075 mutex_unlock(lock: &client->ioctl_mutex);
1076 return written ? written : err;
1077}
1078
1079
1080/*
1081 * handle polling
1082 */
1083static __poll_t snd_seq_poll(struct file *file, poll_table * wait)
1084{
1085 struct snd_seq_client *client = file->private_data;
1086 __poll_t mask = 0;
1087
1088 /* check client structures are in place */
1089 if (snd_BUG_ON(!client))
1090 return EPOLLERR;
1091
1092 if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) &&
1093 client->data.user.fifo) {
1094
1095 /* check if data is available in the outqueue */
1096 if (snd_seq_fifo_poll_wait(f: client->data.user.fifo, file, wait))
1097 mask |= EPOLLIN | EPOLLRDNORM;
1098 }
1099
1100 if (snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT) {
1101
1102 /* check if data is available in the pool */
1103 if (snd_seq_pool_poll_wait(pool: client->pool, file, wait))
1104 mask |= EPOLLOUT | EPOLLWRNORM;
1105 }
1106
1107 return mask;
1108}
1109
1110
1111/*-----------------------------------------------------*/
1112
1113static int snd_seq_ioctl_pversion(struct snd_seq_client *client, void *arg)
1114{
1115 int *pversion = arg;
1116
1117 *pversion = SNDRV_SEQ_VERSION;
1118 return 0;
1119}
1120
1121static int snd_seq_ioctl_user_pversion(struct snd_seq_client *client, void *arg)
1122{
1123 client->user_pversion = *(unsigned int *)arg;
1124 return 0;
1125}
1126
1127static int snd_seq_ioctl_client_id(struct snd_seq_client *client, void *arg)
1128{
1129 int *client_id = arg;
1130
1131 *client_id = client->number;
1132 return 0;
1133}
1134
1135/* SYSTEM_INFO ioctl() */
1136static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void *arg)
1137{
1138 struct snd_seq_system_info *info = arg;
1139
1140 memset(s: info, c: 0, n: sizeof(*info));
1141 /* fill the info fields */
1142 info->queues = SNDRV_SEQ_MAX_QUEUES;
1143 info->clients = SNDRV_SEQ_MAX_CLIENTS;
1144 info->ports = SNDRV_SEQ_MAX_PORTS;
1145 info->channels = 256; /* fixed limit */
1146 info->cur_clients = client_usage.cur;
1147 info->cur_queues = snd_seq_queue_get_cur_queues();
1148
1149 return 0;
1150}
1151
1152
1153/* RUNNING_MODE ioctl() */
1154static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void *arg)
1155{
1156 struct snd_seq_running_info *info = arg;
1157 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
1158
1159 /* requested client number */
1160 cptr = client_load_and_use_ptr(clientid: info->client);
1161 if (cptr == NULL)
1162 return -ENOENT; /* don't change !!! */
1163
1164#ifdef SNDRV_BIG_ENDIAN
1165 if (!info->big_endian)
1166 return -EINVAL;
1167#else
1168 if (info->big_endian)
1169 return -EINVAL;
1170#endif
1171 if (info->cpu_mode > sizeof(long))
1172 return -EINVAL;
1173 cptr->convert32 = (info->cpu_mode < sizeof(long));
1174 return 0;
1175}
1176
1177/* CLIENT_INFO ioctl() */
1178static void get_client_info(struct snd_seq_client *cptr,
1179 struct snd_seq_client_info *info)
1180{
1181 info->client = cptr->number;
1182
1183 /* fill the info fields */
1184 info->type = cptr->type;
1185 strscpy(info->name, cptr->name);
1186 info->filter = cptr->filter;
1187 info->event_lost = cptr->event_lost;
1188 memcpy(to: info->event_filter, from: cptr->event_filter, len: 32);
1189 info->group_filter = cptr->group_filter;
1190 info->num_ports = cptr->num_ports;
1191
1192 if (cptr->type == USER_CLIENT)
1193 info->pid = pid_vnr(pid: cptr->data.user.owner);
1194 else
1195 info->pid = -1;
1196
1197 if (cptr->type == KERNEL_CLIENT)
1198 info->card = cptr->data.kernel.card ? cptr->data.kernel.card->number : -1;
1199 else
1200 info->card = -1;
1201
1202 info->midi_version = cptr->midi_version;
1203 memset(s: info->reserved, c: 0, n: sizeof(info->reserved));
1204}
1205
1206static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client,
1207 void *arg)
1208{
1209 struct snd_seq_client_info *client_info = arg;
1210 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
1211
1212 /* requested client number */
1213 cptr = client_load_and_use_ptr(clientid: client_info->client);
1214 if (cptr == NULL)
1215 return -ENOENT; /* don't change !!! */
1216
1217 get_client_info(cptr, info: client_info);
1218 return 0;
1219}
1220
1221
1222/* CLIENT_INFO ioctl() */
1223static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
1224 void *arg)
1225{
1226 struct snd_seq_client_info *client_info = arg;
1227
1228 /* it is not allowed to set the info fields for an another client */
1229 if (client->number != client_info->client)
1230 return -EPERM;
1231 /* also client type must be set now */
1232 if (client->type != client_info->type)
1233 return -EINVAL;
1234
1235 if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3)) {
1236 /* check validity of midi_version field */
1237 if (client_info->midi_version > SNDRV_SEQ_CLIENT_UMP_MIDI_2_0)
1238 return -EINVAL;
1239
1240 /* check if UMP is supported in kernel */
1241 if (!IS_ENABLED(CONFIG_SND_SEQ_UMP) &&
1242 client_info->midi_version > 0)
1243 return -EINVAL;
1244 }
1245
1246 /* fill the info fields */
1247 if (client_info->name[0])
1248 strscpy(client->name, client_info->name, sizeof(client->name));
1249
1250 client->filter = client_info->filter;
1251 client->event_lost = client_info->event_lost;
1252 if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3))
1253 client->midi_version = client_info->midi_version;
1254 memcpy(to: client->event_filter, from: client_info->event_filter, len: 32);
1255 client->group_filter = client_info->group_filter;
1256
1257 /* notify the change */
1258 snd_seq_system_client_ev_client_change(client->number);
1259
1260 return 0;
1261}
1262
1263
1264/*
1265 * CREATE PORT ioctl()
1266 */
1267static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg)
1268{
1269 struct snd_seq_port_info *info = arg;
1270 struct snd_seq_client_port *port;
1271 struct snd_seq_port_callback *callback;
1272 int port_idx, err;
1273
1274 /* it is not allowed to create the port for an another client */
1275 if (info->addr.client != client->number)
1276 return -EPERM;
1277 if (client->type == USER_CLIENT && info->kernel)
1278 return -EINVAL;
1279 if ((info->capability & SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT) &&
1280 client->ump_endpoint_port >= 0)
1281 return -EBUSY;
1282
1283 if (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT)
1284 port_idx = info->addr.port;
1285 else
1286 port_idx = -1;
1287 if (port_idx >= SNDRV_SEQ_ADDRESS_UNKNOWN)
1288 return -EINVAL;
1289 err = snd_seq_create_port(client, port_index: port_idx, port_ret: &port);
1290 if (err < 0)
1291 return err;
1292
1293 if (client->type == KERNEL_CLIENT) {
1294 callback = info->kernel;
1295 if (callback) {
1296 if (callback->owner)
1297 port->owner = callback->owner;
1298 port->private_data = callback->private_data;
1299 port->private_free = callback->private_free;
1300 port->event_input = callback->event_input;
1301 port->c_src.open = callback->subscribe;
1302 port->c_src.close = callback->unsubscribe;
1303 port->c_dest.open = callback->use;
1304 port->c_dest.close = callback->unuse;
1305 }
1306 }
1307
1308 info->addr = port->addr;
1309
1310 snd_seq_set_port_info(port, info);
1311 if (info->capability & SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT)
1312 client->ump_endpoint_port = port->addr.port;
1313 snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
1314 snd_seq_port_unlock(port);
1315
1316 return 0;
1317}
1318
1319/*
1320 * DELETE PORT ioctl()
1321 */
1322static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, void *arg)
1323{
1324 struct snd_seq_port_info *info = arg;
1325 int err;
1326
1327 /* it is not allowed to remove the port for an another client */
1328 if (info->addr.client != client->number)
1329 return -EPERM;
1330
1331 err = snd_seq_delete_port(client, port: info->addr.port);
1332 if (err >= 0) {
1333 if (client->ump_endpoint_port == info->addr.port)
1334 client->ump_endpoint_port = -1;
1335 snd_seq_system_client_ev_port_exit(client->number, info->addr.port);
1336 }
1337 return err;
1338}
1339
1340
1341/*
1342 * GET_PORT_INFO ioctl() (on any client)
1343 */
1344static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, void *arg)
1345{
1346 struct snd_seq_port_info *info = arg;
1347 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
1348 struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
1349
1350 cptr = client_load_and_use_ptr(clientid: info->addr.client);
1351 if (cptr == NULL)
1352 return -ENXIO;
1353
1354 port = snd_seq_port_use_ptr(client: cptr, num: info->addr.port);
1355 if (port == NULL)
1356 return -ENOENT; /* don't change */
1357
1358 /* get port info */
1359 snd_seq_get_port_info(port, info);
1360 return 0;
1361}
1362
1363
1364/*
1365 * SET_PORT_INFO ioctl() (only ports on this/own client)
1366 */
1367static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client, void *arg)
1368{
1369 struct snd_seq_port_info *info = arg;
1370 struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
1371
1372 if (info->addr.client != client->number) /* only set our own ports ! */
1373 return -EPERM;
1374 port = snd_seq_port_use_ptr(client, num: info->addr.port);
1375 if (port) {
1376 snd_seq_set_port_info(port, info);
1377 /* notify the change */
1378 snd_seq_system_client_ev_port_change(info->addr.client,
1379 info->addr.port);
1380 }
1381 return 0;
1382}
1383
1384
1385/*
1386 * port subscription (connection)
1387 */
1388#define PERM_RD (SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ)
1389#define PERM_WR (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE)
1390
1391static int check_subscription_permission(struct snd_seq_client *client,
1392 struct snd_seq_client_port *sport,
1393 struct snd_seq_client_port *dport,
1394 struct snd_seq_port_subscribe *subs)
1395{
1396 if (client->number != subs->sender.client &&
1397 client->number != subs->dest.client) {
1398 /* connection by third client - check export permission */
1399 if (check_port_perm(port: sport, SNDRV_SEQ_PORT_CAP_NO_EXPORT))
1400 return -EPERM;
1401 if (check_port_perm(port: dport, SNDRV_SEQ_PORT_CAP_NO_EXPORT))
1402 return -EPERM;
1403 }
1404
1405 /* check read permission */
1406 /* if sender or receiver is the subscribing client itself,
1407 * no permission check is necessary
1408 */
1409 if (client->number != subs->sender.client) {
1410 if (! check_port_perm(port: sport, PERM_RD))
1411 return -EPERM;
1412 }
1413 /* check write permission */
1414 if (client->number != subs->dest.client) {
1415 if (! check_port_perm(port: dport, PERM_WR))
1416 return -EPERM;
1417 }
1418 return 0;
1419}
1420
1421/*
1422 * send an subscription notify event to user client:
1423 * client must be user client.
1424 */
1425int snd_seq_client_notify_subscription(int client, int port,
1426 struct snd_seq_port_subscribe *info,
1427 int evtype)
1428{
1429 struct snd_seq_event event;
1430
1431 memset(s: &event, c: 0, n: sizeof(event));
1432 event.type = evtype;
1433 event.data.connect.dest = info->dest;
1434 event.data.connect.sender = info->sender;
1435
1436 return snd_seq_system_notify(client, port, ev: &event, atomic: false); /* non-atomic */
1437}
1438
1439
1440/*
1441 * add to port's subscription list IOCTL interface
1442 */
1443static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
1444 void *arg)
1445{
1446 struct snd_seq_port_subscribe *subs = arg;
1447 struct snd_seq_client *receiver __free(snd_seq_client) = NULL;
1448 struct snd_seq_client *sender __free(snd_seq_client) = NULL;
1449 struct snd_seq_client_port *sport __free(snd_seq_port) = NULL;
1450 struct snd_seq_client_port *dport __free(snd_seq_port) = NULL;
1451 int result;
1452
1453 receiver = client_load_and_use_ptr(clientid: subs->dest.client);
1454 if (!receiver)
1455 return -EINVAL;
1456 sender = client_load_and_use_ptr(clientid: subs->sender.client);
1457 if (!sender)
1458 return -EINVAL;
1459 sport = snd_seq_port_use_ptr(client: sender, num: subs->sender.port);
1460 if (!sport)
1461 return -EINVAL;
1462 dport = snd_seq_port_use_ptr(client: receiver, num: subs->dest.port);
1463 if (!dport)
1464 return -EINVAL;
1465
1466 result = check_subscription_permission(client, sport, dport, subs);
1467 if (result < 0)
1468 return result;
1469
1470 /* connect them */
1471 result = snd_seq_port_connect(caller: client, s: sender, sp: sport, d: receiver, dp: dport, info: subs);
1472 if (! result) /* broadcast announce */
1473 snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, port: 0,
1474 info: subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED);
1475 return result;
1476}
1477
1478
1479/*
1480 * remove from port's subscription list
1481 */
1482static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
1483 void *arg)
1484{
1485 struct snd_seq_port_subscribe *subs = arg;
1486 struct snd_seq_client *receiver __free(snd_seq_client) = NULL;
1487 struct snd_seq_client *sender __free(snd_seq_client) = NULL;
1488 struct snd_seq_client_port *sport __free(snd_seq_port) = NULL;
1489 struct snd_seq_client_port *dport __free(snd_seq_port) = NULL;
1490 int result;
1491
1492 receiver = snd_seq_client_use_ptr(clientid: subs->dest.client);
1493 if (!receiver)
1494 return -ENXIO;
1495 sender = snd_seq_client_use_ptr(clientid: subs->sender.client);
1496 if (!sender)
1497 return -ENXIO;
1498 sport = snd_seq_port_use_ptr(client: sender, num: subs->sender.port);
1499 if (!sport)
1500 return -ENXIO;
1501 dport = snd_seq_port_use_ptr(client: receiver, num: subs->dest.port);
1502 if (!dport)
1503 return -ENXIO;
1504
1505 result = check_subscription_permission(client, sport, dport, subs);
1506 if (result < 0)
1507 return result;
1508
1509 result = snd_seq_port_disconnect(caller: client, s: sender, sp: sport, d: receiver, dp: dport, info: subs);
1510 if (! result) /* broadcast announce */
1511 snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, port: 0,
1512 info: subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED);
1513 return result;
1514}
1515
1516
1517/* CREATE_QUEUE ioctl() */
1518static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
1519{
1520 struct snd_seq_queue_info *info = arg;
1521 struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
1522
1523 q = snd_seq_queue_alloc(client: client->number, locked: info->locked, flags: info->flags);
1524 if (IS_ERR(ptr: q))
1525 return PTR_ERR(ptr: q);
1526
1527 info->queue = q->queue;
1528 info->locked = q->locked;
1529 info->owner = q->owner;
1530
1531 /* set queue name */
1532 if (!info->name[0])
1533 snprintf(buf: info->name, size: sizeof(info->name), fmt: "Queue-%d", q->queue);
1534 strscpy(q->name, info->name, sizeof(q->name));
1535
1536 return 0;
1537}
1538
1539/* DELETE_QUEUE ioctl() */
1540static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client, void *arg)
1541{
1542 struct snd_seq_queue_info *info = arg;
1543
1544 return snd_seq_queue_delete(client: client->number, queueid: info->queue);
1545}
1546
1547/* GET_QUEUE_INFO ioctl() */
1548static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
1549 void *arg)
1550{
1551 struct snd_seq_queue_info *info = arg;
1552 struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
1553
1554 q = queueptr(queueid: info->queue);
1555 if (q == NULL)
1556 return -EINVAL;
1557
1558 memset(s: info, c: 0, n: sizeof(*info));
1559 info->queue = q->queue;
1560 info->owner = q->owner;
1561 info->locked = q->locked;
1562 strscpy(info->name, q->name, sizeof(info->name));
1563
1564 return 0;
1565}
1566
1567/* SET_QUEUE_INFO ioctl() */
1568static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,
1569 void *arg)
1570{
1571 struct snd_seq_queue_info *info = arg;
1572 struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
1573
1574 if (info->owner != client->number)
1575 return -EINVAL;
1576
1577 /* change owner/locked permission */
1578 if (snd_seq_queue_check_access(queueid: info->queue, client: client->number)) {
1579 if (snd_seq_queue_set_owner(queueid: info->queue, client: client->number, locked: info->locked) < 0)
1580 return -EPERM;
1581 if (info->locked)
1582 snd_seq_queue_use(queueid: info->queue, client: client->number, use: 1);
1583 } else {
1584 return -EPERM;
1585 }
1586
1587 q = queueptr(queueid: info->queue);
1588 if (! q)
1589 return -EINVAL;
1590 if (q->owner != client->number)
1591 return -EPERM;
1592 strscpy(q->name, info->name, sizeof(q->name));
1593
1594 return 0;
1595}
1596
1597/* GET_NAMED_QUEUE ioctl() */
1598static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client,
1599 void *arg)
1600{
1601 struct snd_seq_queue_info *info = arg;
1602 struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
1603
1604 q = snd_seq_queue_find_name(name: info->name);
1605 if (q == NULL)
1606 return -EINVAL;
1607 info->queue = q->queue;
1608 info->owner = q->owner;
1609 info->locked = q->locked;
1610
1611 return 0;
1612}
1613
1614/* GET_QUEUE_STATUS ioctl() */
1615static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
1616 void *arg)
1617{
1618 struct snd_seq_queue_status *status = arg;
1619 struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
1620 struct snd_seq_timer *tmr;
1621
1622 queue = queueptr(queueid: status->queue);
1623 if (queue == NULL)
1624 return -EINVAL;
1625 memset(s: status, c: 0, n: sizeof(*status));
1626 status->queue = queue->queue;
1627
1628 tmr = queue->timer;
1629 status->events = queue->tickq->cells + queue->timeq->cells;
1630
1631 status->time = snd_seq_timer_get_cur_time(tmr, adjust_ktime: true);
1632 status->tick = snd_seq_timer_get_cur_tick(tmr);
1633
1634 status->running = tmr->running;
1635
1636 status->flags = queue->flags;
1637
1638 return 0;
1639}
1640
1641
1642/* GET_QUEUE_TEMPO ioctl() */
1643static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client,
1644 void *arg)
1645{
1646 struct snd_seq_queue_tempo *tempo = arg;
1647 struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
1648 struct snd_seq_timer *tmr;
1649
1650 queue = queueptr(queueid: tempo->queue);
1651 if (queue == NULL)
1652 return -EINVAL;
1653 memset(s: tempo, c: 0, n: sizeof(*tempo));
1654 tempo->queue = queue->queue;
1655
1656 tmr = queue->timer;
1657
1658 tempo->tempo = tmr->tempo;
1659 tempo->ppq = tmr->ppq;
1660 tempo->skew_value = tmr->skew;
1661 tempo->skew_base = tmr->skew_base;
1662 if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 4))
1663 tempo->tempo_base = tmr->tempo_base;
1664
1665 return 0;
1666}
1667
1668
1669/* SET_QUEUE_TEMPO ioctl() */
1670int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
1671{
1672 if (!snd_seq_queue_check_access(queueid: tempo->queue, client))
1673 return -EPERM;
1674 return snd_seq_queue_timer_set_tempo(queueid: tempo->queue, client, info: tempo);
1675}
1676EXPORT_SYMBOL(snd_seq_set_queue_tempo);
1677
1678static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
1679 void *arg)
1680{
1681 struct snd_seq_queue_tempo *tempo = arg;
1682 int result;
1683
1684 if (client->user_pversion < SNDRV_PROTOCOL_VERSION(1, 0, 4))
1685 tempo->tempo_base = 0;
1686 result = snd_seq_set_queue_tempo(client->number, tempo);
1687 return result < 0 ? result : 0;
1688}
1689
1690
1691/* GET_QUEUE_TIMER ioctl() */
1692static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
1693 void *arg)
1694{
1695 struct snd_seq_queue_timer *timer = arg;
1696 struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;
1697 struct snd_seq_timer *tmr;
1698
1699 queue = queueptr(queueid: timer->queue);
1700 if (queue == NULL)
1701 return -EINVAL;
1702
1703 guard(mutex)(T: &queue->timer_mutex);
1704 tmr = queue->timer;
1705 memset(s: timer, c: 0, n: sizeof(*timer));
1706 timer->queue = queue->queue;
1707
1708 timer->type = tmr->type;
1709 if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {
1710 timer->u.alsa.id = tmr->alsa_id;
1711 timer->u.alsa.resolution = tmr->preferred_resolution;
1712 }
1713
1714 return 0;
1715}
1716
1717
1718/* SET_QUEUE_TIMER ioctl() */
1719static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
1720 void *arg)
1721{
1722 struct snd_seq_queue_timer *timer = arg;
1723 int result = 0;
1724
1725 if (timer->type != SNDRV_SEQ_TIMER_ALSA)
1726 return -EINVAL;
1727
1728 if (snd_seq_queue_check_access(queueid: timer->queue, client: client->number)) {
1729 struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
1730 struct snd_seq_timer *tmr;
1731
1732 q = queueptr(queueid: timer->queue);
1733 if (q == NULL)
1734 return -ENXIO;
1735 guard(mutex)(T: &q->timer_mutex);
1736 tmr = q->timer;
1737 snd_seq_queue_timer_close(queueid: timer->queue);
1738 tmr->type = timer->type;
1739 if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {
1740 tmr->alsa_id = timer->u.alsa.id;
1741 tmr->preferred_resolution = timer->u.alsa.resolution;
1742 }
1743 result = snd_seq_queue_timer_open(queueid: timer->queue);
1744 } else {
1745 return -EPERM;
1746 }
1747
1748 return result;
1749}
1750
1751
1752/* GET_QUEUE_CLIENT ioctl() */
1753static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client,
1754 void *arg)
1755{
1756 struct snd_seq_queue_client *info = arg;
1757 int used;
1758
1759 used = snd_seq_queue_is_used(queueid: info->queue, client: client->number);
1760 if (used < 0)
1761 return -EINVAL;
1762 info->used = used;
1763 info->client = client->number;
1764
1765 return 0;
1766}
1767
1768
1769/* SET_QUEUE_CLIENT ioctl() */
1770static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client,
1771 void *arg)
1772{
1773 struct snd_seq_queue_client *info = arg;
1774 int err;
1775
1776 if (info->used >= 0) {
1777 err = snd_seq_queue_use(queueid: info->queue, client: client->number, use: info->used);
1778 if (err < 0)
1779 return err;
1780 }
1781
1782 return snd_seq_ioctl_get_queue_client(client, arg);
1783}
1784
1785
1786/* GET_CLIENT_POOL ioctl() */
1787static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
1788 void *arg)
1789{
1790 struct snd_seq_client_pool *info = arg;
1791 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
1792
1793 cptr = client_load_and_use_ptr(clientid: info->client);
1794 if (cptr == NULL)
1795 return -ENOENT;
1796 memset(s: info, c: 0, n: sizeof(*info));
1797 info->client = cptr->number;
1798 info->output_pool = cptr->pool->size;
1799 info->output_room = cptr->pool->room;
1800 info->output_free = info->output_pool;
1801 info->output_free = snd_seq_unused_cells(pool: cptr->pool);
1802 if (cptr->type == USER_CLIENT) {
1803 info->input_pool = cptr->data.user.fifo_pool_size;
1804 info->input_free = info->input_pool;
1805 info->input_free = snd_seq_fifo_unused_cells(f: cptr->data.user.fifo);
1806 } else {
1807 info->input_pool = 0;
1808 info->input_free = 0;
1809 }
1810
1811 return 0;
1812}
1813
1814/* SET_CLIENT_POOL ioctl() */
1815static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
1816 void *arg)
1817{
1818 struct snd_seq_client_pool *info = arg;
1819 int rc;
1820
1821 if (client->number != info->client)
1822 return -EINVAL; /* can't change other clients */
1823
1824 if (info->output_pool >= 1 && info->output_pool <= SNDRV_SEQ_MAX_EVENTS &&
1825 (! snd_seq_write_pool_allocated(client) ||
1826 info->output_pool != client->pool->size)) {
1827 if (snd_seq_write_pool_allocated(client)) {
1828 /* is the pool in use? */
1829 if (atomic_read(v: &client->pool->counter))
1830 return -EBUSY;
1831 /* remove all existing cells */
1832 snd_seq_pool_mark_closing(pool: client->pool);
1833 snd_seq_pool_done(pool: client->pool);
1834 }
1835 client->pool->size = info->output_pool;
1836 rc = snd_seq_pool_init(pool: client->pool);
1837 if (rc < 0)
1838 return rc;
1839 }
1840 if (client->type == USER_CLIENT && client->data.user.fifo != NULL &&
1841 info->input_pool >= 1 &&
1842 info->input_pool <= SNDRV_SEQ_MAX_CLIENT_EVENTS &&
1843 info->input_pool != client->data.user.fifo_pool_size) {
1844 /* change pool size */
1845 rc = snd_seq_fifo_resize(f: client->data.user.fifo, poolsize: info->input_pool);
1846 if (rc < 0)
1847 return rc;
1848 client->data.user.fifo_pool_size = info->input_pool;
1849 }
1850 if (info->output_room >= 1 &&
1851 info->output_room <= client->pool->size) {
1852 client->pool->room = info->output_room;
1853 }
1854
1855 return snd_seq_ioctl_get_client_pool(client, arg);
1856}
1857
1858
1859/* REMOVE_EVENTS ioctl() */
1860static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
1861 void *arg)
1862{
1863 struct snd_seq_remove_events *info = arg;
1864
1865 /*
1866 * Input mostly not implemented XXX.
1867 */
1868 if (info->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
1869 /*
1870 * No restrictions so for a user client we can clear
1871 * the whole fifo
1872 */
1873 if (client->type == USER_CLIENT && client->data.user.fifo)
1874 snd_seq_fifo_clear(f: client->data.user.fifo);
1875 }
1876
1877 if (info->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT)
1878 snd_seq_queue_remove_cells(client: client->number, info);
1879
1880 return 0;
1881}
1882
1883
1884/*
1885 * get subscription info
1886 */
1887static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
1888 void *arg)
1889{
1890 struct snd_seq_port_subscribe *subs = arg;
1891 struct snd_seq_client *sender __free(snd_seq_client) = NULL;
1892 struct snd_seq_client_port *sport __free(snd_seq_port) = NULL;
1893
1894 sender = client_load_and_use_ptr(clientid: subs->sender.client);
1895 if (!sender)
1896 return -EINVAL;
1897 sport = snd_seq_port_use_ptr(client: sender, num: subs->sender.port);
1898 if (!sport)
1899 return -EINVAL;
1900 return snd_seq_port_get_subscription(src_grp: &sport->c_src, dest_addr: &subs->dest, subs);
1901}
1902
1903
1904/*
1905 * get subscription info - check only its presence
1906 */
1907static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
1908{
1909 struct snd_seq_query_subs *subs = arg;
1910 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
1911 struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
1912 struct snd_seq_port_subs_info *group;
1913 struct list_head *p;
1914 int i;
1915
1916 cptr = client_load_and_use_ptr(clientid: subs->root.client);
1917 if (!cptr)
1918 return -ENXIO;
1919 port = snd_seq_port_use_ptr(client: cptr, num: subs->root.port);
1920 if (!port)
1921 return -ENXIO;
1922
1923 switch (subs->type) {
1924 case SNDRV_SEQ_QUERY_SUBS_READ:
1925 group = &port->c_src;
1926 break;
1927 case SNDRV_SEQ_QUERY_SUBS_WRITE:
1928 group = &port->c_dest;
1929 break;
1930 default:
1931 return -ENXIO;
1932 }
1933
1934 guard(rwsem_read)(T: &group->list_mutex);
1935 /* search for the subscriber */
1936 subs->num_subs = group->count;
1937 i = 0;
1938 list_for_each(p, &group->list_head) {
1939 if (i++ == subs->index) {
1940 /* found! */
1941 struct snd_seq_subscribers *s;
1942 if (subs->type == SNDRV_SEQ_QUERY_SUBS_READ) {
1943 s = list_entry(p, struct snd_seq_subscribers, src_list);
1944 subs->addr = s->info.dest;
1945 } else {
1946 s = list_entry(p, struct snd_seq_subscribers, dest_list);
1947 subs->addr = s->info.sender;
1948 }
1949 subs->flags = s->info.flags;
1950 subs->queue = s->info.queue;
1951 return 0;
1952 }
1953 }
1954
1955 return -ENOENT;
1956}
1957
1958
1959/*
1960 * query next client
1961 */
1962static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
1963 void *arg)
1964{
1965 struct snd_seq_client_info *info = arg;
1966 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
1967
1968 /* search for next client */
1969 if (info->client < INT_MAX)
1970 info->client++;
1971 if (info->client < 0)
1972 info->client = 0;
1973 for (; info->client < SNDRV_SEQ_MAX_CLIENTS; info->client++) {
1974 cptr = client_load_and_use_ptr(clientid: info->client);
1975 if (cptr) {
1976 get_client_info(cptr, info);
1977 return 0; /* found */
1978 }
1979 }
1980 return -ENOENT;
1981}
1982
1983/*
1984 * query next port
1985 */
1986static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client,
1987 void *arg)
1988{
1989 struct snd_seq_port_info *info = arg;
1990 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
1991 struct snd_seq_client_port *port __free(snd_seq_port) = NULL;
1992
1993 cptr = client_load_and_use_ptr(clientid: info->addr.client);
1994 if (cptr == NULL)
1995 return -ENXIO;
1996
1997 /* search for next port */
1998 info->addr.port++;
1999 port = snd_seq_port_query_nearest(client: cptr, pinfo: info);
2000 if (port == NULL)
2001 return -ENOENT;
2002
2003 /* get port info */
2004 info->addr = port->addr;
2005 snd_seq_get_port_info(port, info);
2006
2007 return 0;
2008}
2009
2010#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
2011#define NUM_UMP_INFOS (SNDRV_UMP_MAX_BLOCKS + 1)
2012
2013static void free_ump_info(struct snd_seq_client *client)
2014{
2015 int i;
2016
2017 if (!client->ump_info)
2018 return;
2019 for (i = 0; i < NUM_UMP_INFOS; i++)
2020 kfree(client->ump_info[i]);
2021 kfree(client->ump_info);
2022 client->ump_info = NULL;
2023}
2024
2025static void terminate_ump_info_strings(void *p, int type)
2026{
2027 if (type == SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT) {
2028 struct snd_ump_endpoint_info *ep = p;
2029 ep->name[sizeof(ep->name) - 1] = 0;
2030 } else {
2031 struct snd_ump_block_info *bp = p;
2032 bp->name[sizeof(bp->name) - 1] = 0;
2033 }
2034}
2035
2036#ifdef CONFIG_SND_PROC_FS
2037static void dump_ump_info(struct snd_info_buffer *buffer,
2038 struct snd_seq_client *client)
2039{
2040 struct snd_ump_endpoint_info *ep;
2041 struct snd_ump_block_info *bp;
2042 int i;
2043
2044 if (!client->ump_info)
2045 return;
2046 ep = client->ump_info[SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT];
2047 if (ep && *ep->name)
2048 snd_iprintf(buffer, " UMP Endpoint: \"%s\"\n", ep->name);
2049 for (i = 0; i < SNDRV_UMP_MAX_BLOCKS; i++) {
2050 bp = client->ump_info[i + 1];
2051 if (bp && *bp->name) {
2052 snd_iprintf(buffer, " UMP Block %d: \"%s\" [%s]\n",
2053 i, bp->name,
2054 bp->active ? "Active" : "Inactive");
2055 snd_iprintf(buffer, " Groups: %d-%d\n",
2056 bp->first_group + 1,
2057 bp->first_group + bp->num_groups);
2058 }
2059 }
2060}
2061#endif
2062
2063/* UMP-specific ioctls -- called directly without data copy */
2064static int snd_seq_ioctl_client_ump_info(struct snd_seq_client *caller,
2065 unsigned int cmd,
2066 unsigned long arg)
2067{
2068 struct snd_seq_client_ump_info __user *argp =
2069 (struct snd_seq_client_ump_info __user *)arg;
2070 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
2071 int client, type, err = 0;
2072 size_t size;
2073 void *p;
2074
2075 if (get_user(client, &argp->client) || get_user(type, &argp->type))
2076 return -EFAULT;
2077 if (cmd == SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO &&
2078 caller->number != client)
2079 return -EPERM;
2080 if (type < 0 || type >= NUM_UMP_INFOS)
2081 return -EINVAL;
2082 if (type == SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT)
2083 size = sizeof(struct snd_ump_endpoint_info);
2084 else
2085 size = sizeof(struct snd_ump_block_info);
2086 cptr = client_load_and_use_ptr(client);
2087 if (!cptr)
2088 return -ENOENT;
2089
2090 scoped_guard(mutex, &cptr->ioctl_mutex) {
2091 if (!cptr->midi_version) {
2092 err = -EBADFD;
2093 break;
2094 }
2095
2096 if (cmd == SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO) {
2097 if (!cptr->ump_info)
2098 p = NULL;
2099 else
2100 p = cptr->ump_info[type];
2101 if (!p) {
2102 err = -ENODEV;
2103 break;
2104 }
2105 if (copy_to_user(argp->info, p, size)) {
2106 err = -EFAULT;
2107 break;
2108 }
2109 } else {
2110 if (cptr->type != USER_CLIENT) {
2111 err = -EBADFD;
2112 break;
2113 }
2114 if (!cptr->ump_info) {
2115 cptr->ump_info = kcalloc(NUM_UMP_INFOS,
2116 sizeof(void *), GFP_KERNEL);
2117 if (!cptr->ump_info) {
2118 err = -ENOMEM;
2119 break;
2120 }
2121 }
2122 p = memdup_user(argp->info, size);
2123 if (IS_ERR(p)) {
2124 err = PTR_ERR(p);
2125 break;
2126 }
2127 kfree(cptr->ump_info[type]);
2128 terminate_ump_info_strings(p, type);
2129 cptr->ump_info[type] = p;
2130 }
2131
2132 }
2133 if (!err && cmd == SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO) {
2134 if (type == SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT)
2135 snd_seq_system_ump_notify(client, 0,
2136 SNDRV_SEQ_EVENT_UMP_EP_CHANGE,
2137 false);
2138 else
2139 snd_seq_system_ump_notify(client, type - 1,
2140 SNDRV_SEQ_EVENT_UMP_BLOCK_CHANGE,
2141 false);
2142 }
2143 return err;
2144}
2145#endif
2146
2147/* -------------------------------------------------------- */
2148
2149static const struct ioctl_handler {
2150 unsigned int cmd;
2151 int (*func)(struct snd_seq_client *client, void *arg);
2152} ioctl_handlers[] = {
2153 { SNDRV_SEQ_IOCTL_PVERSION, snd_seq_ioctl_pversion },
2154 { SNDRV_SEQ_IOCTL_USER_PVERSION, snd_seq_ioctl_user_pversion },
2155 { SNDRV_SEQ_IOCTL_CLIENT_ID, snd_seq_ioctl_client_id },
2156 { SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info },
2157 { SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode },
2158 { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info },
2159 { SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, snd_seq_ioctl_set_client_info },
2160 { SNDRV_SEQ_IOCTL_CREATE_PORT, snd_seq_ioctl_create_port },
2161 { SNDRV_SEQ_IOCTL_DELETE_PORT, snd_seq_ioctl_delete_port },
2162 { SNDRV_SEQ_IOCTL_GET_PORT_INFO, snd_seq_ioctl_get_port_info },
2163 { SNDRV_SEQ_IOCTL_SET_PORT_INFO, snd_seq_ioctl_set_port_info },
2164 { SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, snd_seq_ioctl_subscribe_port },
2165 { SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, snd_seq_ioctl_unsubscribe_port },
2166 { SNDRV_SEQ_IOCTL_CREATE_QUEUE, snd_seq_ioctl_create_queue },
2167 { SNDRV_SEQ_IOCTL_DELETE_QUEUE, snd_seq_ioctl_delete_queue },
2168 { SNDRV_SEQ_IOCTL_GET_QUEUE_INFO, snd_seq_ioctl_get_queue_info },
2169 { SNDRV_SEQ_IOCTL_SET_QUEUE_INFO, snd_seq_ioctl_set_queue_info },
2170 { SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE, snd_seq_ioctl_get_named_queue },
2171 { SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, snd_seq_ioctl_get_queue_status },
2172 { SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, snd_seq_ioctl_get_queue_tempo },
2173 { SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, snd_seq_ioctl_set_queue_tempo },
2174 { SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, snd_seq_ioctl_get_queue_timer },
2175 { SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, snd_seq_ioctl_set_queue_timer },
2176 { SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, snd_seq_ioctl_get_queue_client },
2177 { SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT, snd_seq_ioctl_set_queue_client },
2178 { SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, snd_seq_ioctl_get_client_pool },
2179 { SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, snd_seq_ioctl_set_client_pool },
2180 { SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, snd_seq_ioctl_get_subscription },
2181 { SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, snd_seq_ioctl_query_next_client },
2182 { SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, snd_seq_ioctl_query_next_port },
2183 { SNDRV_SEQ_IOCTL_REMOVE_EVENTS, snd_seq_ioctl_remove_events },
2184 { SNDRV_SEQ_IOCTL_QUERY_SUBS, snd_seq_ioctl_query_subs },
2185 { 0, NULL },
2186};
2187
2188static long snd_seq_ioctl(struct file *file, unsigned int cmd,
2189 unsigned long arg)
2190{
2191 struct snd_seq_client *client = file->private_data;
2192 /* To use kernel stack for ioctl data. */
2193 union {
2194 int pversion;
2195 int client_id;
2196 struct snd_seq_system_info system_info;
2197 struct snd_seq_running_info running_info;
2198 struct snd_seq_client_info client_info;
2199 struct snd_seq_port_info port_info;
2200 struct snd_seq_port_subscribe port_subscribe;
2201 struct snd_seq_queue_info queue_info;
2202 struct snd_seq_queue_status queue_status;
2203 struct snd_seq_queue_tempo tempo;
2204 struct snd_seq_queue_timer queue_timer;
2205 struct snd_seq_queue_client queue_client;
2206 struct snd_seq_client_pool client_pool;
2207 struct snd_seq_remove_events remove_events;
2208 struct snd_seq_query_subs query_subs;
2209 } buf;
2210 const struct ioctl_handler *handler;
2211 unsigned long size;
2212 int err;
2213
2214 if (snd_BUG_ON(!client))
2215 return -ENXIO;
2216
2217#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
2218 /* exception - handling large data */
2219 switch (cmd) {
2220 case SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO:
2221 case SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO:
2222 return snd_seq_ioctl_client_ump_info(client, cmd, arg);
2223 }
2224#endif
2225
2226 for (handler = ioctl_handlers; handler->cmd > 0; ++handler) {
2227 if (handler->cmd == cmd)
2228 break;
2229 }
2230 if (handler->cmd == 0)
2231 return -ENOTTY;
2232
2233 memset(s: &buf, c: 0, n: sizeof(buf));
2234
2235 /*
2236 * All of ioctl commands for ALSA sequencer get an argument of size
2237 * within 13 bits. We can safely pick up the size from the command.
2238 */
2239 size = _IOC_SIZE(handler->cmd);
2240 if (handler->cmd & IOC_IN) {
2241 if (copy_from_user(to: &buf, from: (const void __user *)arg, n: size))
2242 return -EFAULT;
2243 }
2244
2245 scoped_guard(mutex, &client->ioctl_mutex) {
2246 err = handler->func(client, &buf);
2247 }
2248 if (err >= 0) {
2249 /* Some commands includes a bug in 'dir' field. */
2250 if (handler->cmd == SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT ||
2251 handler->cmd == SNDRV_SEQ_IOCTL_SET_CLIENT_POOL ||
2252 (handler->cmd & IOC_OUT))
2253 if (copy_to_user(to: (void __user *)arg, from: &buf, n: size))
2254 return -EFAULT;
2255 }
2256
2257 return err;
2258}
2259
2260#ifdef CONFIG_COMPAT
2261#include "seq_compat.c"
2262#else
2263#define snd_seq_ioctl_compat NULL
2264#endif
2265
2266/* -------------------------------------------------------- */
2267
2268
2269/* exported to kernel modules */
2270int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2271 const char *name_fmt, ...)
2272{
2273 struct snd_seq_client *client;
2274 va_list args;
2275
2276 if (snd_BUG_ON(in_interrupt()))
2277 return -EBUSY;
2278
2279 if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD)
2280 return -EINVAL;
2281 if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
2282 return -EINVAL;
2283
2284 scoped_guard(mutex, &register_mutex) {
2285
2286 if (card) {
2287 client_index += SNDRV_SEQ_GLOBAL_CLIENTS
2288 + card->number * SNDRV_SEQ_CLIENTS_PER_CARD;
2289 if (client_index >= SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN)
2290 client_index = -1;
2291 }
2292
2293 /* empty write queue as default */
2294 client = seq_create_client1(client_index, poolsize: 0);
2295 if (client == NULL)
2296 return -EBUSY; /* failure code */
2297 usage_alloc(res: &client_usage, num: 1);
2298
2299 client->accept_input = 1;
2300 client->accept_output = 1;
2301 client->data.kernel.card = card;
2302 client->user_pversion = SNDRV_SEQ_VERSION;
2303
2304 va_start(args, name_fmt);
2305 vsnprintf(buf: client->name, size: sizeof(client->name), fmt: name_fmt, args);
2306 va_end(args);
2307
2308 client->type = KERNEL_CLIENT;
2309 }
2310
2311 /* make others aware this new client */
2312 snd_seq_system_client_ev_client_start(client->number);
2313
2314 /* return client number to caller */
2315 return client->number;
2316}
2317EXPORT_SYMBOL(snd_seq_create_kernel_client);
2318
2319/* exported to kernel modules */
2320int snd_seq_delete_kernel_client(int client)
2321{
2322 struct snd_seq_client *ptr;
2323
2324 if (snd_BUG_ON(in_interrupt()))
2325 return -EBUSY;
2326
2327 ptr = clientptr(clientid: client);
2328 if (ptr == NULL)
2329 return -EINVAL;
2330
2331 seq_free_client(client: ptr);
2332 kfree(objp: ptr);
2333 return 0;
2334}
2335EXPORT_SYMBOL(snd_seq_delete_kernel_client);
2336
2337/*
2338 * exported, called by kernel clients to enqueue events (w/o blocking)
2339 *
2340 * RETURN VALUE: zero if succeed, negative if error
2341 */
2342int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev,
2343 struct file *file, bool blocking)
2344{
2345 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
2346
2347 if (snd_BUG_ON(!ev))
2348 return -EINVAL;
2349
2350 if (!snd_seq_ev_is_ump(ev)) {
2351 if (ev->type == SNDRV_SEQ_EVENT_NONE)
2352 return 0; /* ignore this */
2353 if (ev->type == SNDRV_SEQ_EVENT_KERNEL_ERROR)
2354 return -EINVAL; /* quoted events can't be enqueued */
2355 }
2356
2357 /* fill in client number */
2358 ev->source.client = client;
2359
2360 if (check_event_type_and_length(ev))
2361 return -EINVAL;
2362
2363 cptr = client_load_and_use_ptr(clientid: client);
2364 if (cptr == NULL)
2365 return -EINVAL;
2366
2367 if (!cptr->accept_output) {
2368 return -EPERM;
2369 } else { /* send it */
2370 guard(mutex)(T: &cptr->ioctl_mutex);
2371 return snd_seq_client_enqueue_event(client: cptr, event: ev, file, blocking,
2372 atomic: false, hop: 0,
2373 mutexp: &cptr->ioctl_mutex);
2374 }
2375}
2376EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
2377
2378/*
2379 * exported, called by kernel clients to dispatch events directly to other
2380 * clients, bypassing the queues. Event time-stamp will be updated.
2381 *
2382 * RETURN VALUE: negative = delivery failed,
2383 * zero, or positive: the number of delivered events
2384 */
2385int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
2386 int atomic, int hop)
2387{
2388 struct snd_seq_client *cptr __free(snd_seq_client) = NULL;
2389
2390 if (snd_BUG_ON(!ev))
2391 return -EINVAL;
2392
2393 /* fill in client number */
2394 ev->queue = SNDRV_SEQ_QUEUE_DIRECT;
2395 ev->source.client = client;
2396
2397 if (check_event_type_and_length(ev))
2398 return -EINVAL;
2399
2400 cptr = snd_seq_client_use_ptr(clientid: client);
2401 if (cptr == NULL)
2402 return -EINVAL;
2403
2404 if (!cptr->accept_output)
2405 return -EPERM;
2406 else
2407 return snd_seq_deliver_event(client: cptr, event: ev, atomic, hop);
2408}
2409EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
2410
2411static int call_seq_client_ctl(struct snd_seq_client *client,
2412 unsigned int cmd, void *arg)
2413{
2414 const struct ioctl_handler *handler;
2415
2416 for (handler = ioctl_handlers; handler->cmd > 0; ++handler) {
2417 if (handler->cmd == cmd)
2418 return handler->func(client, arg);
2419 }
2420
2421 pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
2422 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
2423 return -ENOTTY;
2424}
2425
2426/**
2427 * snd_seq_kernel_client_ctl - operate a command for a client with data in
2428 * kernel space.
2429 * @clientid: A numerical ID for a client.
2430 * @cmd: An ioctl(2) command for ALSA sequencer operation.
2431 * @arg: A pointer to data in kernel space.
2432 *
2433 * Against its name, both kernel/application client can be handled by this
2434 * kernel API. A pointer of 'arg' argument should be in kernel space.
2435 *
2436 * Return: 0 at success. Negative error code at failure.
2437 */
2438int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
2439{
2440 struct snd_seq_client *client;
2441
2442 client = clientptr(clientid);
2443 if (client == NULL)
2444 return -ENXIO;
2445
2446 return call_seq_client_ctl(client, cmd, arg);
2447}
2448EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
2449
2450/* a similar like above but taking locks; used only from OSS sequencer layer */
2451int snd_seq_kernel_client_ioctl(int clientid, unsigned int cmd, void *arg)
2452{
2453 struct snd_seq_client *client __free(snd_seq_client) = NULL;
2454
2455 client = client_load_and_use_ptr(clientid);
2456 if (!client)
2457 return -ENXIO;
2458 guard(mutex)(T: &client->ioctl_mutex);
2459 return call_seq_client_ctl(client, cmd, arg);
2460}
2461EXPORT_SYMBOL_GPL(snd_seq_kernel_client_ioctl);
2462
2463/* exported (for OSS emulator) */
2464int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
2465{
2466 struct snd_seq_client *client;
2467
2468 client = clientptr(clientid);
2469 if (client == NULL)
2470 return -ENXIO;
2471
2472 if (snd_seq_pool_poll_wait(pool: client->pool, file, wait))
2473 return 1;
2474 return 0;
2475}
2476EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
2477
2478/* get a sequencer client object; for internal use from a kernel client */
2479struct snd_seq_client *snd_seq_kernel_client_get(int id)
2480{
2481 return snd_seq_client_use_ptr(clientid: id);
2482}
2483EXPORT_SYMBOL_GPL(snd_seq_kernel_client_get);
2484
2485/* put a sequencer client object; for internal use from a kernel client */
2486void snd_seq_kernel_client_put(struct snd_seq_client *cptr)
2487{
2488 if (cptr)
2489 snd_seq_client_unref(client: cptr);
2490}
2491EXPORT_SYMBOL_GPL(snd_seq_kernel_client_put);
2492
2493/*---------------------------------------------------------------------------*/
2494
2495#ifdef CONFIG_SND_PROC_FS
2496/*
2497 * /proc interface
2498 */
2499static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer,
2500 struct snd_seq_port_subs_info *group,
2501 int is_src, char *msg)
2502{
2503 struct list_head *p;
2504 struct snd_seq_subscribers *s;
2505 int count = 0;
2506
2507 guard(rwsem_read)(T: &group->list_mutex);
2508 if (list_empty(head: &group->list_head))
2509 return;
2510 snd_iprintf(buffer, msg);
2511 list_for_each(p, &group->list_head) {
2512 if (is_src)
2513 s = list_entry(p, struct snd_seq_subscribers, src_list);
2514 else
2515 s = list_entry(p, struct snd_seq_subscribers, dest_list);
2516 if (count++)
2517 snd_iprintf(buffer, ", ");
2518 snd_iprintf(buffer, "%d:%d",
2519 is_src ? s->info.dest.client : s->info.sender.client,
2520 is_src ? s->info.dest.port : s->info.sender.port);
2521 if (s->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP)
2522 snd_iprintf(buffer, "[%c:%d]", ((s->info.flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 'r' : 't'), s->info.queue);
2523 if (group->exclusive)
2524 snd_iprintf(buffer, "[ex]");
2525 }
2526 snd_iprintf(buffer, "\n");
2527}
2528
2529#define FLAG_PERM_RD(perm) ((perm) & SNDRV_SEQ_PORT_CAP_READ ? ((perm) & SNDRV_SEQ_PORT_CAP_SUBS_READ ? 'R' : 'r') : '-')
2530#define FLAG_PERM_WR(perm) ((perm) & SNDRV_SEQ_PORT_CAP_WRITE ? ((perm) & SNDRV_SEQ_PORT_CAP_SUBS_WRITE ? 'W' : 'w') : '-')
2531#define FLAG_PERM_EX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_NO_EXPORT ? '-' : 'e')
2532
2533#define FLAG_PERM_DUPLEX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_DUPLEX ? 'X' : '-')
2534
2535static const char *port_direction_name(unsigned char dir)
2536{
2537 static const char *names[4] = {
2538 "-", "In", "Out", "In/Out"
2539 };
2540
2541 if (dir > SNDRV_SEQ_PORT_DIR_BIDIRECTION)
2542 return "Invalid";
2543 return names[dir];
2544}
2545
2546static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
2547 struct snd_seq_client *client)
2548{
2549 struct snd_seq_client_port *p;
2550
2551 guard(mutex)(T: &client->ports_mutex);
2552 list_for_each_entry(p, &client->ports_list_head, list) {
2553 if (p->capability & SNDRV_SEQ_PORT_CAP_INACTIVE)
2554 continue;
2555 snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c) [%s]",
2556 p->addr.port, p->name,
2557 FLAG_PERM_RD(p->capability),
2558 FLAG_PERM_WR(p->capability),
2559 FLAG_PERM_EX(p->capability),
2560 FLAG_PERM_DUPLEX(p->capability),
2561 port_direction_name(p->direction));
2562#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
2563 if (snd_seq_client_is_midi2(client) && p->is_midi1)
2564 snd_iprintf(buffer, " [MIDI1]");
2565#endif
2566 snd_iprintf(buffer, "\n");
2567 snd_seq_info_dump_subscribers(buffer, group: &p->c_src, is_src: 1, msg: " Connecting To: ");
2568 snd_seq_info_dump_subscribers(buffer, group: &p->c_dest, is_src: 0, msg: " Connected From: ");
2569 }
2570}
2571
2572static const char *midi_version_string(unsigned int version)
2573{
2574 switch (version) {
2575 case SNDRV_SEQ_CLIENT_LEGACY_MIDI:
2576 return "Legacy";
2577 case SNDRV_SEQ_CLIENT_UMP_MIDI_1_0:
2578 return "UMP MIDI1";
2579 case SNDRV_SEQ_CLIENT_UMP_MIDI_2_0:
2580 return "UMP MIDI2";
2581 default:
2582 return "Unknown";
2583 }
2584}
2585
2586/* exported to seq_info.c */
2587void snd_seq_info_clients_read(struct snd_info_entry *entry,
2588 struct snd_info_buffer *buffer)
2589{
2590 int c;
2591
2592 snd_iprintf(buffer, "Client info\n");
2593 snd_iprintf(buffer, " cur clients : %d\n", client_usage.cur);
2594 snd_iprintf(buffer, " peak clients : %d\n", client_usage.peak);
2595 snd_iprintf(buffer, " max clients : %d\n", SNDRV_SEQ_MAX_CLIENTS);
2596 snd_iprintf(buffer, "\n");
2597
2598 /* list the client table */
2599 for (c = 0; c < SNDRV_SEQ_MAX_CLIENTS; c++) {
2600 struct snd_seq_client *client __free(snd_seq_client) = NULL;
2601
2602 client = client_load_and_use_ptr(clientid: c);
2603 if (client == NULL)
2604 continue;
2605 if (client->type == NO_CLIENT)
2606 continue;
2607
2608 guard(mutex)(T: &client->ioctl_mutex);
2609 snd_iprintf(buffer, "Client %3d : \"%s\" [%s %s]\n",
2610 c, client->name,
2611 client->type == USER_CLIENT ? "User" : "Kernel",
2612 midi_version_string(client->midi_version));
2613#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
2614 dump_ump_info(buffer, client);
2615#endif
2616 snd_seq_info_dump_ports(buffer, client);
2617 if (snd_seq_write_pool_allocated(client)) {
2618 snd_iprintf(buffer, " Output pool :\n");
2619 snd_seq_info_pool(buffer, pool: client->pool, space: " ");
2620 }
2621 if (client->type == USER_CLIENT && client->data.user.fifo &&
2622 client->data.user.fifo->pool) {
2623 snd_iprintf(buffer, " Input pool :\n");
2624 snd_seq_info_pool(buffer, pool: client->data.user.fifo->pool, space: " ");
2625 }
2626 }
2627}
2628#endif /* CONFIG_SND_PROC_FS */
2629
2630/*---------------------------------------------------------------------------*/
2631
2632
2633/*
2634 * REGISTRATION PART
2635 */
2636
2637static const struct file_operations snd_seq_f_ops =
2638{
2639 .owner = THIS_MODULE,
2640 .read = snd_seq_read,
2641 .write = snd_seq_write,
2642 .open = snd_seq_open,
2643 .release = snd_seq_release,
2644 .poll = snd_seq_poll,
2645 .unlocked_ioctl = snd_seq_ioctl,
2646 .compat_ioctl = snd_seq_ioctl_compat,
2647};
2648
2649static struct device *seq_dev;
2650
2651/*
2652 * register sequencer device
2653 */
2654int __init snd_sequencer_device_init(void)
2655{
2656 int err;
2657
2658 err = snd_device_alloc(dev_p: &seq_dev, NULL);
2659 if (err < 0)
2660 return err;
2661 dev_set_name(dev: seq_dev, name: "seq");
2662
2663 scoped_guard(mutex, &register_mutex) {
2664 err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, dev: 0,
2665 f_ops: &snd_seq_f_ops, NULL, device: seq_dev);
2666 }
2667 if (err < 0) {
2668 put_device(dev: seq_dev);
2669 return err;
2670 }
2671
2672 return 0;
2673}
2674
2675
2676
2677/*
2678 * unregister sequencer device
2679 */
2680void snd_sequencer_device_done(void)
2681{
2682 snd_unregister_device(dev: seq_dev);
2683 put_device(dev: seq_dev);
2684}
2685