1 /* 2 * ALSA sequencer Ports 3 * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl> 4 * Jaroslav Kysela <perex@suse.cz> 5 * 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 */ 22 23 #include <sound/driver.h> 24 #include <sound/core.h> 25 #include <linux/slab.h> 26 #include "seq_system.h" 27 #include "seq_ports.h" 28 #include "seq_clientmgr.h" 29 30 /* 31 32 registration of client ports 33 34 */ 35 36 37 /* 38 39 NOTE: the current implementation of the port structure as a linked list is 40 not optimal for clients that have many ports. For sending messages to all 41 subscribers of a port we first need to find the address of the port 42 structure, which means we have to traverse the list. A direct access table 43 (array) would be better, but big preallocated arrays waste memory. 44 45 Possible actions: 46 47 1) leave it this way, a client does normaly does not have more than a few 48 ports 49 50 2) replace the linked list of ports by a array of pointers which is 51 dynamicly kmalloced. When a port is added or deleted we can simply allocate 52 a new array, copy the corresponding pointers, and delete the old one. We 53 then only need a pointer to this array, and an integer that tells us how 54 much elements are in array. 55 56 */ 57 58 /* return pointer to port structure - port is locked if found */ 59 client_port_t *snd_seq_port_use_ptr(client_t *client, int num) 60 { 61 struct list_head *p; 62 client_port_t *port; 63 64 if (client == NULL) 65 return NULL; 66 read_lock(&client->ports_lock); 67 list_for_each(p, &client->ports_list_head) { 68 port = list_entry(p, client_port_t, list); 69 if (port->addr.port == num) { 70 if (port->closing) 71 break; /* deleting now */ 72 snd_use_lock_use(&port->use_lock); 73 read_unlock(&client->ports_lock); 74 return port; 75 } 76 } 77 read_unlock(&client->ports_lock); 78 return NULL; /* not found */ 79 } 80 81 82 /* search for the next port - port is locked if found */ 83 client_port_t *snd_seq_port_query_nearest(client_t *client, snd_seq_port_info_t *pinfo) 84 { 85 int num; 86 struct list_head *p; 87 client_port_t *port, *found; 88 89 num = pinfo->addr.port; 90 found = NULL; 91 read_lock(&client->ports_lock); 92 list_for_each(p, &client->ports_list_head) { 93 port = list_entry(p, client_port_t, list); 94 if (port->addr.port < num) 95 continue; 96 if (port->addr.port == num) { 97 found = port; 98 break; 99 } 100 if (found == NULL || port->addr.port < found->addr.port) 101 found = port; 102 } 103 if (found) { 104 if (found->closing) 105 found = NULL; 106 else 107 snd_use_lock_use(&found->use_lock); 108 } 109 read_unlock(&client->ports_lock); 110 return found; 111 } 112 113 114 /* initialize port_subs_info_t */ 115 static void port_subs_info_init(port_subs_info_t *grp) 116 { 117 INIT_LIST_HEAD(&grp->list_head); 118 grp->count = 0; 119 grp->exclusive = 0; 120 rwlock_init(&grp->list_lock); 121 init_rwsem(&grp->list_mutex); 122 grp->open = NULL; 123 grp->close = NULL; 124 } 125 126 127 /* create a port, port number is returned (-1 on failure) */ 128 client_port_t *snd_seq_create_port(client_t *client, int port) 129 { 130 unsigned long flags; 131 client_port_t *new_port; 132 struct list_head *l; 133 int num = -1; 134 135 /* sanity check */ 136 snd_assert(client, return NULL); 137 138 if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) { 139 snd_printk(KERN_WARNING "too many ports for client %d\n", client->number); 140 return NULL; 141 } 142 143 /* create a new port */ 144 new_port = kzalloc(sizeof(*new_port), GFP_KERNEL); 145 if (! new_port) { 146 snd_printd("malloc failed for registering client port\n"); 147 return NULL; /* failure, out of memory */ 148 } 149 /* init port data */ 150 new_port->addr.client = client->number; 151 new_port->addr.port = -1; 152 new_port->owner = THIS_MODULE; 153 sprintf(new_port->name, "port-%d", num); 154 snd_use_lock_init(&new_port->use_lock); 155 port_subs_info_init(&new_port->c_src); 156 port_subs_info_init(&new_port->c_dest); 157 158 num = port >= 0 ? port : 0; 159 down(&client->ports_mutex); 160 write_lock_irqsave(&client->ports_lock, flags); 161 list_for_each(l, &client->ports_list_head) { 162 client_port_t *p = list_entry(l, client_port_t, list); 163 if (p->addr.port > num) 164 break; 165 if (port < 0) /* auto-probe mode */ 166 num = p->addr.port + 1; 167 } 168 /* insert the new port */ 169 list_add_tail(&new_port->list, l); 170 client->num_ports++; 171 new_port->addr.port = num; /* store the port number in the port */ 172 write_unlock_irqrestore(&client->ports_lock, flags); 173 up(&client->ports_mutex); 174 sprintf(new_port->name, "port-%d", num); 175 176 return new_port; 177 } 178 179 /* */ 180 enum group_type_t { 181 SRC_LIST, DEST_LIST 182 }; 183 184 static int subscribe_port(client_t *client, client_port_t *port, port_subs_info_t *grp, snd_seq_port_subscribe_t *info, int send_ack); 185 static int unsubscribe_port(client_t *client, client_port_t *port, port_subs_info_t *grp, snd_seq_port_subscribe_t *info, int send_ack); 186 187 188 static client_port_t *get_client_port(snd_seq_addr_t *addr, client_t **cp) 189 { 190 client_port_t *p; 191 *cp = snd_seq_client_use_ptr(addr->client); 192 if (*cp) { 193 p = snd_seq_port_use_ptr(*cp, addr->port); 194 if (! p) { 195 snd_seq_client_unlock(*cp); 196 *cp = NULL; 197 } 198 return p; 199 } 200 return NULL; 201 } 202 203 /* 204 * remove all subscribers on the list 205 * this is called from port_delete, for each src and dest list. 206 */ 207 static void clear_subscriber_list(client_t *client, client_port_t *port, 208 port_subs_info_t *grp, int grptype) 209 { 210 struct list_head *p, *n; 211 212 down_write(&grp->list_mutex); 213 list_for_each_safe(p, n, &grp->list_head) { 214 subscribers_t *subs; 215 client_t *c; 216 client_port_t *aport; 217 218 if (grptype == SRC_LIST) { 219 subs = list_entry(p, subscribers_t, src_list); 220 aport = get_client_port(&subs->info.dest, &c); 221 } else { 222 subs = list_entry(p, subscribers_t, dest_list); 223 aport = get_client_port(&subs->info.sender, &c); 224 } 225 list_del(p); 226 unsubscribe_port(client, port, grp, &subs->info, 0); 227 if (!aport) { 228 /* looks like the connected port is being deleted. 229 * we decrease the counter, and when both ports are deleted 230 * remove the subscriber info 231 */ 232 if (atomic_dec_and_test(&subs->ref_count)) 233 kfree(subs); 234 } else { 235 /* ok we got the connected port */ 236 port_subs_info_t *agrp; 237 agrp = (grptype == SRC_LIST) ? &aport->c_dest : &aport->c_src; 238 down_write(&agrp->list_mutex); 239 if (grptype == SRC_LIST) 240 list_del(&subs->dest_list); 241 else 242 list_del(&subs->src_list); 243 unsubscribe_port(c, aport, agrp, &subs->info, 1); 244 kfree(subs); 245 up_write(&agrp->list_mutex); 246 snd_seq_port_unlock(aport); 247 snd_seq_client_unlock(c); 248 } 249 } 250 up_write(&grp->list_mutex); 251 } 252 253 /* delete port data */ 254 static int port_delete(client_t *client, client_port_t *port) 255 { 256 /* set closing flag and wait for all port access are gone */ 257 port->closing = 1; 258 snd_use_lock_sync(&port->use_lock); 259 260 /* clear subscribers info */ 261 clear_subscriber_list(client, port, &port->c_src, SRC_LIST); 262 clear_subscriber_list(client, port, &port->c_dest, DEST_LIST); 263 264 if (port->private_free) 265 port->private_free(port->private_data); 266 267 snd_assert(port->c_src.count == 0,); 268 snd_assert(port->c_dest.count == 0,); 269 270 kfree(port); 271 return 0; 272 } 273 274 275 /* delete a port with the given port id */ 276 int snd_seq_delete_port(client_t *client, int port) 277 { 278 unsigned long flags; 279 struct list_head *l; 280 client_port_t *found = NULL; 281 282 down(&client->ports_mutex); 283 write_lock_irqsave(&client->ports_lock, flags); 284 list_for_each(l, &client->ports_list_head) { 285 client_port_t *p = list_entry(l, client_port_t, list); 286 if (p->addr.port == port) { 287 /* ok found. delete from the list at first */ 288 list_del(l); 289 client->num_ports--; 290 found = p; 291 break; 292 } 293 } 294 write_unlock_irqrestore(&client->ports_lock, flags); 295 up(&client->ports_mutex); 296 if (found) 297 return port_delete(client, found); 298 else 299 return -ENOENT; 300 } 301 302 /* delete the all ports belonging to the given client */ 303 int snd_seq_delete_all_ports(client_t *client) 304 { 305 unsigned long flags; 306 struct list_head deleted_list, *p, *n; 307 308 /* move the port list to deleted_list, and 309 * clear the port list in the client data. 310 */ 311 down(&client->ports_mutex); 312 write_lock_irqsave(&client->ports_lock, flags); 313 if (! list_empty(&client->ports_list_head)) { 314 __list_add(&deleted_list, 315 client->ports_list_head.prev, 316 client->ports_list_head.next); 317 INIT_LIST_HEAD(&client->ports_list_head); 318 } else { 319 INIT_LIST_HEAD(&deleted_list); 320 } 321 client->num_ports = 0; 322 write_unlock_irqrestore(&client->ports_lock, flags); 323 324 /* remove each port in deleted_list */ 325 list_for_each_safe(p, n, &deleted_list) { 326 client_port_t *port = list_entry(p, client_port_t, list); 327 list_del(p); 328 snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); 329 port_delete(client, port); 330 } 331 up(&client->ports_mutex); 332 return 0; 333 } 334 335 /* set port info fields */ 336 int snd_seq_set_port_info(client_port_t * port, snd_seq_port_info_t * info) 337 { 338 snd_assert(port && info, return -EINVAL); 339 340 /* set port name */ 341 if (info->name[0]) 342 strlcpy(port->name, info->name, sizeof(port->name)); 343 344 /* set capabilities */ 345 port->capability = info->capability; 346 347 /* get port type */ 348 port->type = info->type; 349 350 /* information about supported channels/voices */ 351 port->midi_channels = info->midi_channels; 352 port->midi_voices = info->midi_voices; 353 port->synth_voices = info->synth_voices; 354 355 /* timestamping */ 356 port->timestamping = (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0; 357 port->time_real = (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0; 358 port->time_queue = info->time_queue; 359 360 return 0; 361 } 362 363 /* get port info fields */ 364 int snd_seq_get_port_info(client_port_t * port, snd_seq_port_info_t * info) 365 { 366 snd_assert(port && info, return -EINVAL); 367 368 /* get port name */ 369 strlcpy(info->name, port->name, sizeof(info->name)); 370 371 /* get capabilities */ 372 info->capability = port->capability; 373 374 /* get port type */ 375 info->type = port->type; 376 377 /* information about supported channels/voices */ 378 info->midi_channels = port->midi_channels; 379 info->midi_voices = port->midi_voices; 380 info->synth_voices = port->synth_voices; 381 382 /* get subscriber counts */ 383 info->read_use = port->c_src.count; 384 info->write_use = port->c_dest.count; 385 386 /* timestamping */ 387 info->flags = 0; 388 if (port->timestamping) { 389 info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP; 390 if (port->time_real) 391 info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL; 392 info->time_queue = port->time_queue; 393 } 394 395 return 0; 396 } 397 398 399 400 /* 401 * call callback functions (if any): 402 * the callbacks are invoked only when the first (for connection) or 403 * the last subscription (for disconnection) is done. Second or later 404 * subscription results in increment of counter, but no callback is 405 * invoked. 406 * This feature is useful if these callbacks are associated with 407 * initialization or termination of devices (see seq_midi.c). 408 * 409 * If callback_all option is set, the callback function is invoked 410 * at each connnection/disconnection. 411 */ 412 413 static int subscribe_port(client_t *client, client_port_t *port, port_subs_info_t *grp, 414 snd_seq_port_subscribe_t *info, int send_ack) 415 { 416 int err = 0; 417 418 if (!try_module_get(port->owner)) 419 return -EFAULT; 420 grp->count++; 421 if (grp->open && (port->callback_all || grp->count == 1)) { 422 err = grp->open(port->private_data, info); 423 if (err < 0) { 424 module_put(port->owner); 425 grp->count--; 426 } 427 } 428 if (err >= 0 && send_ack && client->type == USER_CLIENT) 429 snd_seq_client_notify_subscription(port->addr.client, port->addr.port, 430 info, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED); 431 432 return err; 433 } 434 435 static int unsubscribe_port(client_t *client, client_port_t *port, 436 port_subs_info_t *grp, 437 snd_seq_port_subscribe_t *info, int send_ack) 438 { 439 int err = 0; 440 441 if (! grp->count) 442 return -EINVAL; 443 grp->count--; 444 if (grp->close && (port->callback_all || grp->count == 0)) 445 err = grp->close(port->private_data, info); 446 if (send_ack && client->type == USER_CLIENT) 447 snd_seq_client_notify_subscription(port->addr.client, port->addr.port, 448 info, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED); 449 module_put(port->owner); 450 return err; 451 } 452 453 454 455 /* check if both addresses are identical */ 456 static inline int addr_match(snd_seq_addr_t *r, snd_seq_addr_t *s) 457 { 458 return (r->client == s->client) && (r->port == s->port); 459 } 460 461 /* check the two subscribe info match */ 462 /* if flags is zero, checks only sender and destination addresses */ 463 static int match_subs_info(snd_seq_port_subscribe_t *r, 464 snd_seq_port_subscribe_t *s) 465 { 466 if (addr_match(&r->sender, &s->sender) && 467 addr_match(&r->dest, &s->dest)) { 468 if (r->flags && r->flags == s->flags) 469 return r->queue == s->queue; 470 else if (! r->flags) 471 return 1; 472 } 473 return 0; 474 } 475 476 477 /* connect two ports */ 478 int snd_seq_port_connect(client_t *connector, 479 client_t *src_client, client_port_t *src_port, 480 client_t *dest_client, client_port_t *dest_port, 481 snd_seq_port_subscribe_t *info) 482 { 483 port_subs_info_t *src = &src_port->c_src; 484 port_subs_info_t *dest = &dest_port->c_dest; 485 subscribers_t *subs; 486 struct list_head *p; 487 int err, src_called = 0; 488 unsigned long flags; 489 int exclusive; 490 491 subs = kzalloc(sizeof(*subs), GFP_KERNEL); 492 if (! subs) 493 return -ENOMEM; 494 495 subs->info = *info; 496 atomic_set(&subs->ref_count, 2); 497 498 down_write(&src->list_mutex); 499 down_write(&dest->list_mutex); 500 501 exclusive = info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE ? 1 : 0; 502 err = -EBUSY; 503 if (exclusive) { 504 if (! list_empty(&src->list_head) || ! list_empty(&dest->list_head)) 505 goto __error; 506 } else { 507 if (src->exclusive || dest->exclusive) 508 goto __error; 509 /* check whether already exists */ 510 list_for_each(p, &src->list_head) { 511 subscribers_t *s = list_entry(p, subscribers_t, src_list); 512 if (match_subs_info(info, &s->info)) 513 goto __error; 514 } 515 list_for_each(p, &dest->list_head) { 516 subscribers_t *s = list_entry(p, subscribers_t, dest_list); 517 if (match_subs_info(info, &s->info)) 518 goto __error; 519 } 520 } 521 522 if ((err = subscribe_port(src_client, src_port, src, info, 523 connector->number != src_client->number)) < 0) 524 goto __error; 525 src_called = 1; 526 527 if ((err = subscribe_port(dest_client, dest_port, dest, info, 528 connector->number != dest_client->number)) < 0) 529 goto __error; 530 531 /* add to list */ 532 write_lock_irqsave(&src->list_lock, flags); 533 // write_lock(&dest->list_lock); // no other lock yet 534 list_add_tail(&subs->src_list, &src->list_head); 535 list_add_tail(&subs->dest_list, &dest->list_head); 536 // write_unlock(&dest->list_lock); // no other lock yet 537 write_unlock_irqrestore(&src->list_lock, flags); 538 539 src->exclusive = dest->exclusive = exclusive; 540 541 up_write(&dest->list_mutex); 542 up_write(&src->list_mutex); 543 return 0; 544 545 __error: 546 if (src_called) 547 unsubscribe_port(src_client, src_port, src, info, 548 connector->number != src_client->number); 549 kfree(subs); 550 up_write(&dest->list_mutex); 551 up_write(&src->list_mutex); 552 return err; 553 } 554 555 556 /* remove the connection */ 557 int snd_seq_port_disconnect(client_t *connector, 558 client_t *src_client, client_port_t *src_port, 559 client_t *dest_client, client_port_t *dest_port, 560 snd_seq_port_subscribe_t *info) 561 { 562 port_subs_info_t *src = &src_port->c_src; 563 port_subs_info_t *dest = &dest_port->c_dest; 564 subscribers_t *subs; 565 struct list_head *p; 566 int err = -ENOENT; 567 unsigned long flags; 568 569 down_write(&src->list_mutex); 570 down_write(&dest->list_mutex); 571 572 /* look for the connection */ 573 list_for_each(p, &src->list_head) { 574 subs = list_entry(p, subscribers_t, src_list); 575 if (match_subs_info(info, &subs->info)) { 576 write_lock_irqsave(&src->list_lock, flags); 577 // write_lock(&dest->list_lock); // no lock yet 578 list_del(&subs->src_list); 579 list_del(&subs->dest_list); 580 // write_unlock(&dest->list_lock); 581 write_unlock_irqrestore(&src->list_lock, flags); 582 src->exclusive = dest->exclusive = 0; 583 unsubscribe_port(src_client, src_port, src, info, 584 connector->number != src_client->number); 585 unsubscribe_port(dest_client, dest_port, dest, info, 586 connector->number != dest_client->number); 587 kfree(subs); 588 err = 0; 589 break; 590 } 591 } 592 593 up_write(&dest->list_mutex); 594 up_write(&src->list_mutex); 595 return err; 596 } 597 598 599 /* get matched subscriber */ 600 subscribers_t *snd_seq_port_get_subscription(port_subs_info_t *src_grp, 601 snd_seq_addr_t *dest_addr) 602 { 603 struct list_head *p; 604 subscribers_t *s, *found = NULL; 605 606 down_read(&src_grp->list_mutex); 607 list_for_each(p, &src_grp->list_head) { 608 s = list_entry(p, subscribers_t, src_list); 609 if (addr_match(dest_addr, &s->info.dest)) { 610 found = s; 611 break; 612 } 613 } 614 up_read(&src_grp->list_mutex); 615 return found; 616 } 617 618 /* 619 * Attach a device driver that wants to receive events from the 620 * sequencer. Returns the new port number on success. 621 * A driver that wants to receive the events converted to midi, will 622 * use snd_seq_midisynth_register_port(). 623 */ 624 /* exported */ 625 int snd_seq_event_port_attach(int client, 626 snd_seq_port_callback_t *pcbp, 627 int cap, int type, int midi_channels, 628 int midi_voices, char *portname) 629 { 630 snd_seq_port_info_t portinfo; 631 int ret; 632 633 /* Set up the port */ 634 memset(&portinfo, 0, sizeof(portinfo)); 635 portinfo.addr.client = client; 636 strlcpy(portinfo.name, portname ? portname : "Unamed port", 637 sizeof(portinfo.name)); 638 639 portinfo.capability = cap; 640 portinfo.type = type; 641 portinfo.kernel = pcbp; 642 portinfo.midi_channels = midi_channels; 643 portinfo.midi_voices = midi_voices; 644 645 /* Create it */ 646 ret = snd_seq_kernel_client_ctl(client, 647 SNDRV_SEQ_IOCTL_CREATE_PORT, 648 &portinfo); 649 650 if (ret >= 0) 651 ret = portinfo.addr.port; 652 653 return ret; 654 } 655 656 657 /* 658 * Detach the driver from a port. 659 */ 660 /* exported */ 661 int snd_seq_event_port_detach(int client, int port) 662 { 663 snd_seq_port_info_t portinfo; 664 int err; 665 666 memset(&portinfo, 0, sizeof(portinfo)); 667 portinfo.addr.client = client; 668 portinfo.addr.port = port; 669 err = snd_seq_kernel_client_ctl(client, 670 SNDRV_SEQ_IOCTL_DELETE_PORT, 671 &portinfo); 672 673 return err; 674 } 675