25 #include <linux/export.h>
26 #include <linux/slab.h>
58 #define SNDRV_SEQ_GLOBAL_CLIENTS 16
60 #define SNDRV_SEQ_CLIENTS_PER_CARD 4
62 #define SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN 128
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)
83 int err,
int atomic,
int hop);
86 int filter,
int atomic,
int hop);
105 static inline unsigned short snd_seq_file_flags(
struct file *
file)
119 return snd_seq_total_cells(client->
pool) > 0;
126 snd_printd(
"Seq: oops. Trying to get pointer to client %d\n",
130 return clienttab[clientid];
139 snd_printd(
"Seq: oops. Trying to get pointer to client %d\n",
144 client = clientptr(clientid);
147 if (clienttablock[clientid]) {
148 spin_unlock_irqrestore(&clients_lock, flags);
151 spin_unlock_irqrestore(&clients_lock, flags);
152 #ifdef CONFIG_MODULES
159 if (!client_requested[clientid]) {
160 client_requested[clientid] = 1;
161 for (idx = 0; idx < 15; idx++) {
165 request_module(
"snd-seq-client-%i",
175 if (! card_requested[card]) {
176 card_requested[
card] = 1;
183 client = clientptr(clientid);
186 spin_unlock_irqrestore(&clients_lock, flags);
193 spin_unlock_irqrestore(&clients_lock, flags);
213 memset(&clienttablock, 0,
sizeof(clienttablock));
214 memset(&clienttab, 0,
sizeof(clienttab));
226 client = kzalloc(
sizeof(*client),
GFP_KERNEL);
242 if (client_index < 0) {
246 if (clienttab[c] || clienttablock[c])
249 spin_unlock_irqrestore(&clients_lock, flags);
253 if (clienttab[client_index] ==
NULL && !clienttablock[client_index]) {
255 spin_unlock_irqrestore(&clients_lock, flags);
259 spin_unlock_irqrestore(&clients_lock, flags);
275 clienttablock[client->
number] = 1;
277 spin_unlock_irqrestore(&clients_lock, flags);
283 clienttablock[client->
number] = 0;
284 spin_unlock_irqrestore(&clients_lock, flags);
292 switch (client->
type) {
299 seq_free_client1(client);
300 usage_free(&client_usage, 1);
317 static int snd_seq_open(
struct inode *
inode,
struct file *file)
331 if (client ==
NULL) {
336 mode = snd_seq_file_flags(file);
346 if (mode & SNDRV_SEQ_LFLG_INPUT) {
350 seq_free_client1(client);
357 usage_alloc(&client_usage, 1);
375 static int snd_seq_release(
struct inode *inode,
struct file *file)
380 seq_free_client(client);
397 static ssize_t snd_seq_read(
struct file *file,
char __user *
buf,
size_t count,
406 if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT))
438 if (snd_seq_ev_is_variable(&cell->
event)) {
472 if (err == -
EAGAIN && result > 0)
477 return (err < 0) ? err :
result;
508 if (filter && !(dest->
filter & filter))
531 int err,
int atomic,
int hop)
536 if (client ==
NULL ||
542 memset(&bounce_ev, 0,
sizeof(bounce_ev));
548 bounce_ev.dest.client = client->
number;
549 bounce_ev.dest.port =
event->source.port;
550 bounce_ev.data.quote.origin =
event->dest;
551 bounce_ev.data.quote.event =
event;
552 bounce_ev.data.quote.value = -
err;
553 result = snd_seq_deliver_single_event(
NULL, &bounce_ev, 0, atomic, hop + 1);
568 static int update_timestamp_of_queue(
struct snd_seq_event *event,
569 int queue,
int real_time)
576 event->queue =
queue;
597 static int snd_seq_deliver_single_event(
struct snd_seq_client *client,
599 int filter,
int atomic,
int hop)
606 direct = snd_seq_ev_is_direct(event);
608 dest = get_event_dest_client(event, filter);
612 if (dest_port ==
NULL)
622 update_timestamp_of_queue(event, dest_port->
time_queue,
625 switch (dest->
type) {
648 if (result < 0 && !direct) {
649 result = bounce_error_event(client, event, result, atomic, hop);
663 int err = 0, num_ev = 0;
669 if (src_port ==
NULL)
672 event_saved = *
event;
673 grp = &src_port->
c_src;
681 event->dest = subs->
info.dest;
684 update_timestamp_of_queue(event, subs->
info.queue,
686 err = snd_seq_deliver_single_event(client, event,
692 *
event = event_saved;
698 *
event = event_saved;
700 return (err < 0) ? err : num_ev;
704 #ifdef SUPPORT_BROADCAST
712 int num_ev = 0, err = 0;
717 if (dest_client ==
NULL)
722 event->dest.port = port->
addr.port;
724 err = snd_seq_deliver_single_event(
NULL, event,
734 return (err < 0) ? err : num_ev;
744 int err = 0, num_ev = 0;
752 if (dest == client->
number)
754 event->dest.client =
dest;
755 event->dest.port = addr.port;
757 err = port_broadcast_event(client, event, atomic, hop);
760 err = snd_seq_deliver_single_event(
NULL, event,
768 return (err < 0) ? err : num_ev;
776 snd_printd(
"seq: multicast not supported yet.\n");
797 snd_printd(
"too long delivery path (%d:%d->%d:%d)\n",
799 event->
dest.client, event->
dest.port);
805 result = deliver_to_subscribers(client, event, atomic, hop);
806 #ifdef SUPPORT_BROADCAST
809 result = broadcast_event(client, event, atomic, hop);
810 else if (event->
dest.client >= SNDRV_SEQ_MAX_CLIENTS)
811 result = multicast_event(client, event, atomic, hop);
813 result = port_broadcast_event(client, event, atomic, hop);
816 result = snd_seq_deliver_single_event(client, event, 0, atomic, hop);
840 if (client ==
NULL) {
855 result = snd_seq_deliver_event(client, &tmpev, atomic, hop);
876 ev->
time.
time.tv_nsec %= 1000000000;
890 result = snd_seq_deliver_event(client, &cell->
event, atomic, hop);
903 static int snd_seq_client_enqueue_event(
struct snd_seq_client *client,
905 struct file *file,
int blocking,
916 #ifdef SUPPORT_BROADCAST
925 if (src_port ==
NULL)
931 if (snd_seq_ev_is_direct(event)) {
934 return snd_seq_deliver_event(client, event, atomic, hop);
940 if (! snd_seq_write_pool_allocated(client))
962 static int check_event_type_and_length(
struct snd_seq_event *ev)
964 switch (snd_seq_ev_length_type(ev)) {
966 if (snd_seq_ev_is_variable_type(ev))
970 if (! snd_seq_ev_is_variable_type(ev) ||
975 if (! snd_seq_ev_is_direct(ev))
994 static ssize_t snd_seq_write(
struct file *file,
const char __user *buf,
995 size_t count, loff_t *offset)
998 int written = 0,
len;
1002 if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT))
1013 if (client->
pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
1026 event.source.client = client->
number;
1028 if (check_event_type_and_length(&event)) {
1036 else if (snd_seq_ev_is_reserved(&event)) {
1041 if (snd_seq_ev_is_variable(&event)) {
1043 if ((
size_t)(extlen +
len) > count) {
1050 event.data.ext.ptr = (
char __force *)buf
1054 #ifdef CONFIG_COMPAT
1055 if (client->
convert32 && snd_seq_ev_is_varusr(&event)) {
1057 event.data.ext.ptr =
ptr;
1063 err = snd_seq_client_enqueue_event(client, &event, file,
1076 return written ? written :
err;
1083 static unsigned int snd_seq_poll(
struct file *file,
poll_table *
wait)
1086 unsigned int mask = 0;
1092 if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) &&
1100 if (snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT) {
1103 if (!snd_seq_write_pool_allocated(client) ||
1116 static int snd_seq_ioctl_system_info(
struct snd_seq_client *client,
void __user *
arg)
1125 info.channels = 256;
1126 info.cur_clients = client_usage.cur;
1136 static int snd_seq_ioctl_running_mode(
struct snd_seq_client *client,
void __user *arg)
1150 #ifdef SNDRV_BIG_ENDIAN
1151 if (!
info.big_endian) {
1156 if (
info.big_endian) {
1162 if (
info.cpu_mode >
sizeof(
long)) {
1188 static int snd_seq_ioctl_get_client_info(
struct snd_seq_client *client,
1202 get_client_info(cptr, &client_info);
1205 if (
copy_to_user(arg, &client_info,
sizeof(client_info)))
1212 static int snd_seq_ioctl_set_client_info(
struct snd_seq_client *client,
1221 if (client->
number != client_info.client)
1224 if (client->
type != client_info.type)
1228 if (client_info.name[0])
1231 client->
filter = client_info.filter;
1233 memcpy(client->event_filter, client_info.event_filter, 32);
1242 static int snd_seq_ioctl_create_port(
struct snd_seq_client *client,
1265 if ((callback =
info.kernel) !=
NULL) {
1266 if (callback->
owner)
1293 static int snd_seq_ioctl_delete_port(
struct snd_seq_client *client,
1317 static int snd_seq_ioctl_get_port_info(
struct snd_seq_client *client,
1350 static int snd_seq_ioctl_set_port_info(
struct snd_seq_client *client,
1373 #define PERM_RD (SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ)
1374 #define PERM_WR (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE)
1376 static int check_subscription_permission(
struct snd_seq_client *client,
1395 if (! check_port_perm(sport,
PERM_RD))
1400 if (! check_port_perm(dport,
PERM_WR))
1416 memset(&event, 0,
sizeof(event));
1417 event.type = evtype;
1418 event.data.connect.dest = info->
dest;
1419 event.data.connect.sender = info->
sender;
1428 static int snd_seq_ioctl_subscribe_port(
struct snd_seq_client *client,
1448 result = check_subscription_permission(client, sport, dport, &subs);
1473 static int snd_seq_ioctl_unsubscribe_port(
struct snd_seq_client *client,
1476 int result = -
ENXIO;
1493 result = check_subscription_permission(client, sport, dport, &subs);
1515 static int snd_seq_ioctl_create_queue(
struct snd_seq_client *client,
1550 static int snd_seq_ioctl_delete_queue(
struct snd_seq_client *client,
1562 static int snd_seq_ioctl_get_queue_info(
struct snd_seq_client *client,
1589 static int snd_seq_ioctl_set_queue_info(
struct snd_seq_client *client,
1625 static int snd_seq_ioctl_get_named_queue(
struct snd_seq_client *client,
void __user *arg)
1648 static int snd_seq_ioctl_get_queue_status(
struct snd_seq_client *client,
1682 static int snd_seq_ioctl_get_queue_tempo(
struct snd_seq_client *client,
1722 static int snd_seq_ioctl_set_queue_tempo(
struct snd_seq_client *client,
1732 return result < 0 ? result : 0;
1737 static int snd_seq_ioctl_get_queue_timer(
struct snd_seq_client *client,
1774 static int snd_seq_ioctl_set_queue_timer(
struct snd_seq_client *client,
1816 static int snd_seq_ioctl_get_queue_client(
struct snd_seq_client *client,
1838 static int snd_seq_ioctl_set_queue_client(
struct snd_seq_client *client,
1847 if (
info.used >= 0) {
1853 return snd_seq_ioctl_get_queue_client(client, arg);
1858 static int snd_seq_ioctl_get_client_pool(
struct snd_seq_client *client,
1871 info.output_pool = cptr->
pool->size;
1872 info.output_room = cptr->
pool->room;
1873 info.output_free =
info.output_pool;
1874 info.output_free = snd_seq_unused_cells(cptr->
pool);
1879 info.input_free = snd_seq_unused_cells(cptr->
data.
user.fifo->pool);
1881 info.input_pool = 0;
1882 info.input_free = 0;
1892 static int snd_seq_ioctl_set_client_pool(
struct snd_seq_client *client,
1905 (! snd_seq_write_pool_allocated(client) ||
1906 info.output_pool != client->
pool->size)) {
1907 if (snd_seq_write_pool_allocated(client)) {
1912 client->
pool->size =
info.output_pool;
1918 info.input_pool >= 1 &&
1927 if (
info.output_room >= 1 &&
1928 info.output_room <= client->
pool->size) {
1929 client->
pool->room =
info.output_room;
1932 return snd_seq_ioctl_get_client_pool(client, arg);
1937 static int snd_seq_ioctl_remove_events(
struct snd_seq_client *client,
1967 static int snd_seq_ioctl_get_subscription(
struct snd_seq_client *client,
2007 static int snd_seq_ioctl_query_subs(
struct snd_seq_client *client,
2010 int result = -
ENXIO;
2026 switch (subs.type) {
2028 group = &port->
c_src;
2039 subs.num_subs = group->
count;
2043 if (i++ == subs.index) {
2048 subs.addr = s->
info.dest;
2051 subs.addr = s->
info.sender;
2053 subs.flags = s->
info.flags;
2054 subs.queue = s->
info.queue;
2077 static int snd_seq_ioctl_query_next_client(
struct snd_seq_client *client,
2088 if (
info.client < 0)
2098 get_client_info(cptr, &
info);
2109 static int snd_seq_ioctl_query_next_port(
struct snd_seq_client *client,
2143 static struct seq_ioctl_table {
2146 } ioctl_tables[] = {
2182 struct seq_ioctl_table *
p;
2195 for (p = ioctl_tables; p->cmd; p++) {
2197 return p->func(client, arg);
2199 snd_printd(
"seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
2205 static long snd_seq_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
2212 return snd_seq_do_ioctl(client, cmd, (
void __user *) arg);
2215 #ifdef CONFIG_COMPAT
2218 #define snd_seq_ioctl_compat NULL
2250 client = seq_create_client1(client_index, 0);
2251 if (client ==
NULL) {
2255 usage_alloc(&client_usage, 1);
2284 ptr = clientptr(client);
2288 seq_free_client(ptr);
2298 static int kernel_client_enqueue(
int client,
struct snd_seq_event *ev,
2299 struct file *file,
int blocking,
2300 int atomic,
int hop)
2316 if (check_event_type_and_length(ev))
2326 result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop);
2338 int atomic,
int hop)
2340 return kernel_client_enqueue(client, ev,
NULL, 0, atomic, hop);
2352 int atomic,
int hop)
2354 return kernel_client_enqueue(client, ev, file, 1, atomic, hop);
2367 int atomic,
int hop)
2379 if (check_event_type_and_length(ev))
2389 result = snd_seq_deliver_event(cptr, ev, atomic, hop);
2407 client = clientptr(clientid);
2410 fs = snd_enter_user();
2411 result = snd_seq_do_ioctl(client, cmd, (
void __force __user *)arg);
2423 client = clientptr(clientid);
2427 if (! snd_seq_write_pool_allocated(client))
2438 #ifdef CONFIG_PROC_FS
2444 int is_src,
char *
msg)
2455 snd_iprintf(buffer, msg);
2462 snd_iprintf(buffer,
", ");
2463 snd_iprintf(buffer,
"%d:%d",
2464 is_src ? s->
info.dest.client : s->
info.sender.client,
2465 is_src ? s->
info.dest.port : s->
info.sender.port);
2469 snd_iprintf(buffer,
"[ex]");
2472 snd_iprintf(buffer,
"\n");
2475 #define FLAG_PERM_RD(perm) ((perm) & SNDRV_SEQ_PORT_CAP_READ ? ((perm) & SNDRV_SEQ_PORT_CAP_SUBS_READ ? 'R' : 'r') : '-')
2476 #define FLAG_PERM_WR(perm) ((perm) & SNDRV_SEQ_PORT_CAP_WRITE ? ((perm) & SNDRV_SEQ_PORT_CAP_SUBS_WRITE ? 'W' : 'w') : '-')
2477 #define FLAG_PERM_EX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_NO_EXPORT ? '-' : 'e')
2479 #define FLAG_PERM_DUPLEX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_DUPLEX ? 'X' : '-')
2488 snd_iprintf(buffer,
" Port %3d : \"%s\" (%c%c%c%c)\n",
2494 snd_seq_info_dump_subscribers(buffer, &p->
c_src, 1,
" Connecting To: ");
2495 snd_seq_info_dump_subscribers(buffer, &p->
c_dest, 0,
" Connected From: ");
2508 snd_iprintf(buffer,
"Client info\n");
2509 snd_iprintf(buffer,
" cur clients : %d\n", client_usage.cur);
2510 snd_iprintf(buffer,
" peak clients : %d\n", client_usage.peak);
2511 snd_iprintf(buffer,
" max clients : %d\n", SNDRV_SEQ_MAX_CLIENTS);
2512 snd_iprintf(buffer,
"\n");
2524 snd_iprintf(buffer,
"Client %3d : \"%s\" [%s]\n",
2527 snd_seq_info_dump_ports(buffer, client);
2528 if (snd_seq_write_pool_allocated(client)) {
2529 snd_iprintf(buffer,
" Output pool :\n");
2534 snd_iprintf(buffer,
" Input pool :\n");
2552 .read = snd_seq_read,
2553 .write = snd_seq_write,
2554 .open = snd_seq_open,
2555 .release = snd_seq_release,
2557 .poll = snd_seq_poll,
2558 .unlocked_ioctl = snd_seq_ioctl,
2573 &snd_seq_f_ops,
NULL,
"seq")) < 0) {