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