Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/core/seq/seq_clientmgr.c
29267 views
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 <[email protected]>
5
* Jaroslav Kysela <[email protected]>
6
* Takashi Iwai <[email protected]>
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
55
static DEFINE_SPINLOCK(clients_lock);
56
static DEFINE_MUTEX(register_mutex);
57
58
/*
59
* client table
60
*/
61
static char clienttablock[SNDRV_SEQ_MAX_CLIENTS];
62
static struct snd_seq_client *clienttab[SNDRV_SEQ_MAX_CLIENTS];
63
static struct snd_seq_usage client_usage;
64
65
/*
66
* prototypes
67
*/
68
static int bounce_error_event(struct snd_seq_client *client,
69
struct snd_seq_event *event,
70
int err, int atomic, int hop);
71
static 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)
76
static void free_ump_info(struct snd_seq_client *client);
77
#endif
78
79
/*
80
*/
81
static 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
93
static inline int snd_seq_write_pool_allocated(struct snd_seq_client *client)
94
{
95
return snd_seq_total_cells(client->pool) > 0;
96
}
97
98
/* return pointer to client structure for specified id */
99
static 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
109
static 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(clientid, 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(card, 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 */
164
struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
165
{
166
return client_use_ptr(clientid, false);
167
}
168
169
/* get snd_seq_client object for the given id;
170
* if not found, retry after loading the modules
171
*/
172
static struct snd_seq_client *client_load_and_use_ptr(int clientid)
173
{
174
return client_use_ptr(clientid, IS_ENABLED(CONFIG_MODULES));
175
}
176
177
static 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
184
static void usage_free(struct snd_seq_usage *res, int num)
185
{
186
res->cur -= num;
187
}
188
189
/* initialise data structures */
190
int __init client_init_data(void)
191
{
192
/* zap out the client table */
193
memset(&clienttablock, 0, sizeof(clienttablock));
194
memset(&clienttab, 0, sizeof(clienttab));
195
return 0;
196
}
197
198
199
static 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(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(&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(&client->pool);
241
kfree(client);
242
return NULL; /* no free slot found or busy, return failure code */
243
}
244
245
246
static 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->number);
256
snd_use_lock_sync(&client->use_lock);
257
if (client->pool)
258
snd_seq_pool_delete(&client->pool);
259
scoped_guard(spinlock_irq, &clients_lock) {
260
clienttablock[client->number] = 0;
261
}
262
return 0;
263
}
264
265
266
static 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(&client_usage, 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 */
294
static 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, file);
302
if (err < 0)
303
return err;
304
305
scoped_guard(mutex, &register_mutex) {
306
client = seq_create_client1(-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(user->fifo_pool_size);
323
if (user->fifo == NULL) {
324
seq_free_client1(client);
325
kfree(client);
326
return -ENOMEM;
327
}
328
}
329
330
usage_alloc(&client_usage, 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(client->name, "Client-%d", c);
340
client->data.user.owner = get_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 */
349
static 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(&client->data.user.fifo);
357
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
358
free_ump_info(client);
359
#endif
360
put_pid(client->data.user.owner);
361
kfree(client);
362
}
363
364
return 0;
365
}
366
367
static 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
*/
384
static 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(&fifo->overflow) > 0) {
411
/* buffer overflow is detected */
412
snd_seq_fifo_clear(fifo);
413
/* return error code */
414
return -ENOSPC;
415
}
416
417
cell = NULL;
418
err = 0;
419
guard(snd_seq_fifo)(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(fifo, &cell, nonblock);
432
if (err < 0)
433
break;
434
if (!event_is_compatible(client, &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(&tmpev, &cell->event, aligned_size);
443
tmpev.data.ext.len &= ~SNDRV_SEQ_EXT_MASK;
444
if (copy_to_user(buf, &tmpev, aligned_size)) {
445
err = -EFAULT;
446
break;
447
}
448
count -= aligned_size;
449
buf += aligned_size;
450
err = snd_seq_expand_var_event(&cell->event, count,
451
(char __force *)buf, 0,
452
aligned_size);
453
if (err < 0)
454
break;
455
result += err;
456
count -= err;
457
buf += err;
458
} else {
459
if (copy_to_user(buf, &cell->event, 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(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
*/
485
static 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
*/
495
static 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(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
*/
526
static 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(&bounce_ev, 0, 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, &bounce_ev, atomic, 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
*/
565
static 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(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(q->timer, true);
577
event->flags |= SNDRV_SEQ_TIME_STAMP_REAL;
578
} else {
579
event->time.tick = snd_seq_timer_get_cur_tick(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 */
586
int __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(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() */
608
static 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(dest, event->dest.port);
619
if (dest_port == NULL)
620
return -ENOENT;
621
622
/* check permission */
623
if (!check_port_perm(dest_port, SNDRV_SEQ_PORT_CAP_WRITE))
624
return -EPERM;
625
626
if (dest_port->timestamping)
627
update_timestamp_of_queue(event, dest_port->time_queue,
628
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
*/
656
static 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, result, atomic, hop);
664
return result;
665
}
666
667
668
/*
669
* send the event to all subscribers:
670
*/
671
static 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, port);
685
if (!src_port)
686
return 0;
687
688
/* save original event record */
689
saved_size = snd_seq_event_packet_size(event);
690
memcpy(&event_saved, event, 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(&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, subs->info.queue,
706
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(event, &event_saved, saved_size);
717
}
718
if (atomic)
719
read_unlock(&grp->list_lock);
720
else
721
up_read(&grp->list_mutex);
722
memcpy(event, &event_saved, saved_size);
723
return (result < 0) ? result : num_ev;
724
}
725
726
static 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
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
*/
766
static 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
*/
802
int 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(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, &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, &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
*/
874
static 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, 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(event->queue, 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(client->pool, event, &cell, !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
*/
930
static 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
*/
962
static 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(&client->ioctl_mutex);
985
if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
986
err = snd_seq_pool_init(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(ev, buf, 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((char *)ev + len, buf + len,
1005
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(ev->data.raw32.d[1]);
1050
#endif
1051
}
1052
1053
/* ok, enqueue it */
1054
err = snd_seq_client_enqueue_event(client, ev, file,
1055
!(file->f_flags & O_NONBLOCK),
1056
0, 0, &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(&client->ioctl_mutex);
1070
goto repeat;
1071
}
1072
}
1073
1074
out:
1075
mutex_unlock(&client->ioctl_mutex);
1076
return written ? written : err;
1077
}
1078
1079
1080
/*
1081
* handle polling
1082
*/
1083
static __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(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(client->pool, file, wait))
1104
mask |= EPOLLOUT | EPOLLWRNORM;
1105
}
1106
1107
return mask;
1108
}
1109
1110
1111
/*-----------------------------------------------------*/
1112
1113
static 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
1121
static 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
1127
static 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() */
1136
static 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(info, 0, 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() */
1154
static 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(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() */
1178
static 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(info->event_filter, cptr->event_filter, 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(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(info->reserved, 0, sizeof(info->reserved));
1204
}
1205
1206
static 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(client_info->client);
1214
if (cptr == NULL)
1215
return -ENOENT; /* don't change !!! */
1216
1217
get_client_info(cptr, client_info);
1218
return 0;
1219
}
1220
1221
1222
/* CLIENT_INFO ioctl() */
1223
static 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(client->event_filter, client_info->event_filter, 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
*/
1267
static 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_idx, &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
*/
1322
static 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, 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
*/
1344
static 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(info->addr.client);
1351
if (cptr == NULL)
1352
return -ENXIO;
1353
1354
port = snd_seq_port_use_ptr(cptr, 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
*/
1367
static 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, 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
1391
static 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(sport, SNDRV_SEQ_PORT_CAP_NO_EXPORT))
1400
return -EPERM;
1401
if (check_port_perm(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(sport, PERM_RD))
1411
return -EPERM;
1412
}
1413
/* check write permission */
1414
if (client->number != subs->dest.client) {
1415
if (! check_port_perm(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
*/
1425
int 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(&event, 0, 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, &event, false); /* non-atomic */
1437
}
1438
1439
1440
/*
1441
* add to port's subscription list IOCTL interface
1442
*/
1443
static 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(subs->dest.client);
1454
if (!receiver)
1455
return -EINVAL;
1456
sender = client_load_and_use_ptr(subs->sender.client);
1457
if (!sender)
1458
return -EINVAL;
1459
sport = snd_seq_port_use_ptr(sender, subs->sender.port);
1460
if (!sport)
1461
return -EINVAL;
1462
dport = snd_seq_port_use_ptr(receiver, 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(client, sender, sport, receiver, dport, subs);
1472
if (! result) /* broadcast announce */
1473
snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
1474
subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED);
1475
return result;
1476
}
1477
1478
1479
/*
1480
* remove from port's subscription list
1481
*/
1482
static 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(subs->dest.client);
1493
if (!receiver)
1494
return -ENXIO;
1495
sender = snd_seq_client_use_ptr(subs->sender.client);
1496
if (!sender)
1497
return -ENXIO;
1498
sport = snd_seq_port_use_ptr(sender, subs->sender.port);
1499
if (!sport)
1500
return -ENXIO;
1501
dport = snd_seq_port_use_ptr(receiver, 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(client, sender, sport, receiver, dport, subs);
1510
if (! result) /* broadcast announce */
1511
snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
1512
subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED);
1513
return result;
1514
}
1515
1516
1517
/* CREATE_QUEUE ioctl() */
1518
static 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->number, info->locked, info->flags);
1524
if (IS_ERR(q))
1525
return PTR_ERR(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(info->name, sizeof(info->name), "Queue-%d", q->queue);
1534
strscpy(q->name, info->name, sizeof(q->name));
1535
1536
return 0;
1537
}
1538
1539
/* DELETE_QUEUE ioctl() */
1540
static 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->number, info->queue);
1545
}
1546
1547
/* GET_QUEUE_INFO ioctl() */
1548
static 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(info->queue);
1555
if (q == NULL)
1556
return -EINVAL;
1557
1558
memset(info, 0, 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() */
1568
static 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(info->queue, client->number)) {
1579
if (snd_seq_queue_set_owner(info->queue, client->number, info->locked) < 0)
1580
return -EPERM;
1581
if (info->locked)
1582
snd_seq_queue_use(info->queue, client->number, 1);
1583
} else {
1584
return -EPERM;
1585
}
1586
1587
q = queueptr(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() */
1598
static 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(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() */
1615
static 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(status->queue);
1623
if (queue == NULL)
1624
return -EINVAL;
1625
memset(status, 0, 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, 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() */
1643
static 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(tempo->queue);
1651
if (queue == NULL)
1652
return -EINVAL;
1653
memset(tempo, 0, 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() */
1670
int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
1671
{
1672
if (!snd_seq_queue_check_access(tempo->queue, client))
1673
return -EPERM;
1674
return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);
1675
}
1676
EXPORT_SYMBOL(snd_seq_set_queue_tempo);
1677
1678
static 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() */
1692
static 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(timer->queue);
1700
if (queue == NULL)
1701
return -EINVAL;
1702
1703
guard(mutex)(&queue->timer_mutex);
1704
tmr = queue->timer;
1705
memset(timer, 0, 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() */
1719
static 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(timer->queue, client->number)) {
1729
struct snd_seq_queue *q __free(snd_seq_queue) = NULL;
1730
struct snd_seq_timer *tmr;
1731
1732
q = queueptr(timer->queue);
1733
if (q == NULL)
1734
return -ENXIO;
1735
guard(mutex)(&q->timer_mutex);
1736
tmr = q->timer;
1737
snd_seq_queue_timer_close(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(timer->queue);
1744
} else {
1745
return -EPERM;
1746
}
1747
1748
return result;
1749
}
1750
1751
1752
/* GET_QUEUE_CLIENT ioctl() */
1753
static 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(info->queue, 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() */
1770
static 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(info->queue, client->number, 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() */
1787
static 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(info->client);
1794
if (cptr == NULL)
1795
return -ENOENT;
1796
memset(info, 0, 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(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(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() */
1815
static 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(&client->pool->counter))
1830
return -EBUSY;
1831
/* remove all existing cells */
1832
snd_seq_pool_mark_closing(client->pool);
1833
snd_seq_pool_done(client->pool);
1834
}
1835
client->pool->size = info->output_pool;
1836
rc = snd_seq_pool_init(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(client->data.user.fifo, 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() */
1860
static 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(client->data.user.fifo);
1875
}
1876
1877
if (info->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT)
1878
snd_seq_queue_remove_cells(client->number, info);
1879
1880
return 0;
1881
}
1882
1883
1884
/*
1885
* get subscription info
1886
*/
1887
static 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(subs->sender.client);
1895
if (!sender)
1896
return -EINVAL;
1897
sport = snd_seq_port_use_ptr(sender, subs->sender.port);
1898
if (!sport)
1899
return -EINVAL;
1900
return snd_seq_port_get_subscription(&sport->c_src, &subs->dest, subs);
1901
}
1902
1903
1904
/*
1905
* get subscription info - check only its presence
1906
*/
1907
static 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(subs->root.client);
1917
if (!cptr)
1918
return -ENXIO;
1919
port = snd_seq_port_use_ptr(cptr, 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)(&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
*/
1962
static 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(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
*/
1986
static 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(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(cptr, 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
2013
static 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
2025
static 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
2037
static 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 */
2064
static 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
2149
static 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
2188
static 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(&buf, 0, 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(&buf, (const void __user *)arg, 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((void __user *)arg, &buf, 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 */
2270
int 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, 0);
2295
if (client == NULL)
2296
return -EBUSY; /* failure code */
2297
usage_alloc(&client_usage, 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(client->name, sizeof(client->name), 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
}
2317
EXPORT_SYMBOL(snd_seq_create_kernel_client);
2318
2319
/* exported to kernel modules */
2320
int 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(client);
2328
if (ptr == NULL)
2329
return -EINVAL;
2330
2331
seq_free_client(ptr);
2332
kfree(ptr);
2333
return 0;
2334
}
2335
EXPORT_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
*/
2342
int 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(client);
2364
if (cptr == NULL)
2365
return -EINVAL;
2366
2367
if (!cptr->accept_output) {
2368
return -EPERM;
2369
} else { /* send it */
2370
guard(mutex)(&cptr->ioctl_mutex);
2371
return snd_seq_client_enqueue_event(cptr, ev, file, blocking,
2372
false, 0,
2373
&cptr->ioctl_mutex);
2374
}
2375
}
2376
EXPORT_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
*/
2385
int 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(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(cptr, ev, atomic, hop);
2408
}
2409
EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
2410
2411
static 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
*/
2438
int 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
}
2448
EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
2449
2450
/* a similar like above but taking locks; used only from OSS sequencer layer */
2451
int 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)(&client->ioctl_mutex);
2459
return call_seq_client_ctl(client, cmd, arg);
2460
}
2461
EXPORT_SYMBOL_GPL(snd_seq_kernel_client_ioctl);
2462
2463
/* exported (for OSS emulator) */
2464
int 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(client->pool, file, wait))
2473
return 1;
2474
return 0;
2475
}
2476
EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
2477
2478
/* get a sequencer client object; for internal use from a kernel client */
2479
struct snd_seq_client *snd_seq_kernel_client_get(int id)
2480
{
2481
return snd_seq_client_use_ptr(id);
2482
}
2483
EXPORT_SYMBOL_GPL(snd_seq_kernel_client_get);
2484
2485
/* put a sequencer client object; for internal use from a kernel client */
2486
void snd_seq_kernel_client_put(struct snd_seq_client *cptr)
2487
{
2488
if (cptr)
2489
snd_seq_client_unref(cptr);
2490
}
2491
EXPORT_SYMBOL_GPL(snd_seq_kernel_client_put);
2492
2493
/*---------------------------------------------------------------------------*/
2494
2495
#ifdef CONFIG_SND_PROC_FS
2496
/*
2497
* /proc interface
2498
*/
2499
static 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)(&group->list_mutex);
2508
if (list_empty(&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
2535
static 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
2546
static 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)(&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, &p->c_src, 1, " Connecting To: ");
2568
snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: ");
2569
}
2570
}
2571
2572
static 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 */
2587
void 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(c);
2603
if (client == NULL)
2604
continue;
2605
if (client->type == NO_CLIENT)
2606
continue;
2607
2608
guard(mutex)(&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, client->pool, " ");
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, client->data.user.fifo->pool, " ");
2625
}
2626
}
2627
}
2628
#endif /* CONFIG_SND_PROC_FS */
2629
2630
/*---------------------------------------------------------------------------*/
2631
2632
2633
/*
2634
* REGISTRATION PART
2635
*/
2636
2637
static 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
2649
static struct device *seq_dev;
2650
2651
/*
2652
* register sequencer device
2653
*/
2654
int __init snd_sequencer_device_init(void)
2655
{
2656
int err;
2657
2658
err = snd_device_alloc(&seq_dev, NULL);
2659
if (err < 0)
2660
return err;
2661
dev_set_name(seq_dev, "seq");
2662
2663
scoped_guard(mutex, &register_mutex) {
2664
err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
2665
&snd_seq_f_ops, NULL, seq_dev);
2666
}
2667
if (err < 0) {
2668
put_device(seq_dev);
2669
return err;
2670
}
2671
2672
return 0;
2673
}
2674
2675
2676
2677
/*
2678
* unregister sequencer device
2679
*/
2680
void snd_sequencer_device_done(void)
2681
{
2682
snd_unregister_device(seq_dev);
2683
put_device(seq_dev);
2684
}
2685
2686