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