linux/sound/core/rawmidi.c
<<
>>
Prefs
   1/*
   2 *  Abstract layer for MIDI v1.0 stream
   3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   4 *
   5 *
   6 *   This program is free software; you can redistribute it and/or modify
   7 *   it under the terms of the GNU General Public License as published by
   8 *   the Free Software Foundation; either version 2 of the License, or
   9 *   (at your option) any later version.
  10 *
  11 *   This program is distributed in the hope that it will be useful,
  12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *   GNU General Public License for more details.
  15 *
  16 *   You should have received a copy of the GNU General Public License
  17 *   along with this program; if not, write to the Free Software
  18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19 *
  20 */
  21
  22#include <sound/core.h>
  23#include <linux/major.h>
  24#include <linux/init.h>
  25#include <linux/sched.h>
  26#include <linux/slab.h>
  27#include <linux/time.h>
  28#include <linux/wait.h>
  29#include <linux/mutex.h>
  30#include <linux/moduleparam.h>
  31#include <linux/delay.h>
  32#include <sound/rawmidi.h>
  33#include <sound/info.h>
  34#include <sound/control.h>
  35#include <sound/minors.h>
  36#include <sound/initval.h>
  37
  38MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
  39MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA.");
  40MODULE_LICENSE("GPL");
  41
  42#ifdef CONFIG_SND_OSSEMUL
  43static int midi_map[SNDRV_CARDS];
  44static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
  45module_param_array(midi_map, int, NULL, 0444);
  46MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device.");
  47module_param_array(amidi_map, int, NULL, 0444);
  48MODULE_PARM_DESC(amidi_map, "Raw MIDI device number assigned to 2nd OSS device.");
  49#endif /* CONFIG_SND_OSSEMUL */
  50
  51static int snd_rawmidi_free(struct snd_rawmidi *rawmidi);
  52static int snd_rawmidi_dev_free(struct snd_device *device);
  53static int snd_rawmidi_dev_register(struct snd_device *device);
  54static int snd_rawmidi_dev_disconnect(struct snd_device *device);
  55
  56static LIST_HEAD(snd_rawmidi_devices);
  57static DEFINE_MUTEX(register_mutex);
  58
  59static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
  60{
  61        struct snd_rawmidi *rawmidi;
  62
  63        list_for_each_entry(rawmidi, &snd_rawmidi_devices, list)
  64                if (rawmidi->card == card && rawmidi->device == device)
  65                        return rawmidi;
  66        return NULL;
  67}
  68
  69static inline unsigned short snd_rawmidi_file_flags(struct file *file)
  70{
  71        switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
  72        case FMODE_WRITE:
  73                return SNDRV_RAWMIDI_LFLG_OUTPUT;
  74        case FMODE_READ:
  75                return SNDRV_RAWMIDI_LFLG_INPUT;
  76        default:
  77                return SNDRV_RAWMIDI_LFLG_OPEN;
  78        }
  79}
  80
  81static inline int snd_rawmidi_ready(struct snd_rawmidi_substream *substream)
  82{
  83        struct snd_rawmidi_runtime *runtime = substream->runtime;
  84        return runtime->avail >= runtime->avail_min;
  85}
  86
  87static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substream,
  88                                           size_t count)
  89{
  90        struct snd_rawmidi_runtime *runtime = substream->runtime;
  91        return runtime->avail >= runtime->avail_min &&
  92               (!substream->append || runtime->avail >= count);
  93}
  94
  95static void snd_rawmidi_input_event_tasklet(unsigned long data)
  96{
  97        struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
  98        substream->runtime->event(substream);
  99}
 100
 101static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
 102{
 103        struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
 104        substream->ops->trigger(substream, 1);
 105}
 106
 107static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
 108{
 109        struct snd_rawmidi_runtime *runtime;
 110
 111        if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
 112                return -ENOMEM;
 113        spin_lock_init(&runtime->lock);
 114        init_waitqueue_head(&runtime->sleep);
 115        if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
 116                tasklet_init(&runtime->tasklet,
 117                             snd_rawmidi_input_event_tasklet,
 118                             (unsigned long)substream);
 119        else
 120                tasklet_init(&runtime->tasklet,
 121                             snd_rawmidi_output_trigger_tasklet,
 122                             (unsigned long)substream);
 123        runtime->event = NULL;
 124        runtime->buffer_size = PAGE_SIZE;
 125        runtime->avail_min = 1;
 126        if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
 127                runtime->avail = 0;
 128        else
 129                runtime->avail = runtime->buffer_size;
 130        if ((runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL)) == NULL) {
 131                kfree(runtime);
 132                return -ENOMEM;
 133        }
 134        runtime->appl_ptr = runtime->hw_ptr = 0;
 135        substream->runtime = runtime;
 136        return 0;
 137}
 138
 139static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
 140{
 141        struct snd_rawmidi_runtime *runtime = substream->runtime;
 142
 143        kfree(runtime->buffer);
 144        kfree(runtime);
 145        substream->runtime = NULL;
 146        return 0;
 147}
 148
 149static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up)
 150{
 151        if (!substream->opened)
 152                return;
 153        if (up) {
 154                tasklet_schedule(&substream->runtime->tasklet);
 155        } else {
 156                tasklet_kill(&substream->runtime->tasklet);
 157                substream->ops->trigger(substream, 0);
 158        }
 159}
 160
 161static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 162{
 163        if (!substream->opened)
 164                return;
 165        substream->ops->trigger(substream, up);
 166        if (!up && substream->runtime->event)
 167                tasklet_kill(&substream->runtime->tasklet);
 168}
 169
 170int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
 171{
 172        unsigned long flags;
 173        struct snd_rawmidi_runtime *runtime = substream->runtime;
 174
 175        snd_rawmidi_output_trigger(substream, 0);
 176        runtime->drain = 0;
 177        spin_lock_irqsave(&runtime->lock, flags);
 178        runtime->appl_ptr = runtime->hw_ptr = 0;
 179        runtime->avail = runtime->buffer_size;
 180        spin_unlock_irqrestore(&runtime->lock, flags);
 181        return 0;
 182}
 183
 184int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream)
 185{
 186        int err;
 187        long timeout;
 188        struct snd_rawmidi_runtime *runtime = substream->runtime;
 189
 190        err = 0;
 191        runtime->drain = 1;
 192        timeout = wait_event_interruptible_timeout(runtime->sleep,
 193                                (runtime->avail >= runtime->buffer_size),
 194                                10*HZ);
 195        if (signal_pending(current))
 196                err = -ERESTARTSYS;
 197        if (runtime->avail < runtime->buffer_size && !timeout) {
 198                snd_printk(KERN_WARNING "rawmidi drain error (avail = %li, buffer_size = %li)\n", (long)runtime->avail, (long)runtime->buffer_size);
 199                err = -EIO;
 200        }
 201        runtime->drain = 0;
 202        if (err != -ERESTARTSYS) {
 203                /* we need wait a while to make sure that Tx FIFOs are empty */
 204                if (substream->ops->drain)
 205                        substream->ops->drain(substream);
 206                else
 207                        msleep(50);
 208                snd_rawmidi_drop_output(substream);
 209        }
 210        return err;
 211}
 212
 213int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream)
 214{
 215        unsigned long flags;
 216        struct snd_rawmidi_runtime *runtime = substream->runtime;
 217
 218        snd_rawmidi_input_trigger(substream, 0);
 219        runtime->drain = 0;
 220        spin_lock_irqsave(&runtime->lock, flags);
 221        runtime->appl_ptr = runtime->hw_ptr = 0;
 222        runtime->avail = 0;
 223        spin_unlock_irqrestore(&runtime->lock, flags);
 224        return 0;
 225}
 226
 227/* look for an available substream for the given stream direction;
 228 * if a specific subdevice is given, try to assign it
 229 */
 230static int assign_substream(struct snd_rawmidi *rmidi, int subdevice,
 231                            int stream, int mode,
 232                            struct snd_rawmidi_substream **sub_ret)
 233{
 234        struct snd_rawmidi_substream *substream;
 235        struct snd_rawmidi_str *s = &rmidi->streams[stream];
 236        static unsigned int info_flags[2] = {
 237                [SNDRV_RAWMIDI_STREAM_OUTPUT] = SNDRV_RAWMIDI_INFO_OUTPUT,
 238                [SNDRV_RAWMIDI_STREAM_INPUT] = SNDRV_RAWMIDI_INFO_INPUT,
 239        };
 240
 241        if (!(rmidi->info_flags & info_flags[stream]))
 242                return -ENXIO;
 243        if (subdevice >= 0 && subdevice >= s->substream_count)
 244                return -ENODEV;
 245
 246        list_for_each_entry(substream, &s->substreams, list) {
 247                if (substream->opened) {
 248                        if (stream == SNDRV_RAWMIDI_STREAM_INPUT ||
 249                            !(mode & SNDRV_RAWMIDI_LFLG_APPEND) ||
 250                            !substream->append)
 251                                continue;
 252                }
 253                if (subdevice < 0 || subdevice == substream->number) {
 254                        *sub_ret = substream;
 255                        return 0;
 256                }
 257        }
 258        return -EAGAIN;
 259}
 260
 261/* open and do ref-counting for the given substream */
 262static int open_substream(struct snd_rawmidi *rmidi,
 263                          struct snd_rawmidi_substream *substream,
 264                          int mode)
 265{
 266        int err;
 267
 268        if (substream->use_count == 0) {
 269                err = snd_rawmidi_runtime_create(substream);
 270                if (err < 0)
 271                        return err;
 272                err = substream->ops->open(substream);
 273                if (err < 0) {
 274                        snd_rawmidi_runtime_free(substream);
 275                        return err;
 276                }
 277                substream->opened = 1;
 278                substream->active_sensing = 0;
 279                if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
 280                        substream->append = 1;
 281                substream->pid = get_pid(task_pid(current));
 282                rmidi->streams[substream->stream].substream_opened++;
 283        }
 284        substream->use_count++;
 285        return 0;
 286}
 287
 288static void close_substream(struct snd_rawmidi *rmidi,
 289                            struct snd_rawmidi_substream *substream,
 290                            int cleanup);
 291
 292static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
 293                             struct snd_rawmidi_file *rfile)
 294{
 295        struct snd_rawmidi_substream *sinput = NULL, *soutput = NULL;
 296        int err;
 297
 298        rfile->input = rfile->output = NULL;
 299        if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
 300                err = assign_substream(rmidi, subdevice,
 301                                       SNDRV_RAWMIDI_STREAM_INPUT,
 302                                       mode, &sinput);
 303                if (err < 0)
 304                        return err;
 305        }
 306        if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
 307                err = assign_substream(rmidi, subdevice,
 308                                       SNDRV_RAWMIDI_STREAM_OUTPUT,
 309                                       mode, &soutput);
 310                if (err < 0)
 311                        return err;
 312        }
 313
 314        if (sinput) {
 315                err = open_substream(rmidi, sinput, mode);
 316                if (err < 0)
 317                        return err;
 318        }
 319        if (soutput) {
 320                err = open_substream(rmidi, soutput, mode);
 321                if (err < 0) {
 322                        if (sinput)
 323                                close_substream(rmidi, sinput, 0);
 324                        return err;
 325                }
 326        }
 327
 328        rfile->rmidi = rmidi;
 329        rfile->input = sinput;
 330        rfile->output = soutput;
 331        return 0;
 332}
 333
 334/* called from sound/core/seq/seq_midi.c */
 335int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
 336                            int mode, struct snd_rawmidi_file * rfile)
 337{
 338        struct snd_rawmidi *rmidi;
 339        int err;
 340
 341        if (snd_BUG_ON(!rfile))
 342                return -EINVAL;
 343
 344        mutex_lock(&register_mutex);
 345        rmidi = snd_rawmidi_search(card, device);
 346        if (rmidi == NULL) {
 347                mutex_unlock(&register_mutex);
 348                return -ENODEV;
 349        }
 350        if (!try_module_get(rmidi->card->module)) {
 351                mutex_unlock(&register_mutex);
 352                return -ENXIO;
 353        }
 354        mutex_unlock(&register_mutex);
 355
 356        mutex_lock(&rmidi->open_mutex);
 357        err = rawmidi_open_priv(rmidi, subdevice, mode, rfile);
 358        mutex_unlock(&rmidi->open_mutex);
 359        if (err < 0)
 360                module_put(rmidi->card->module);
 361        return err;
 362}
 363
 364static int snd_rawmidi_open(struct inode *inode, struct file *file)
 365{
 366        int maj = imajor(inode);
 367        struct snd_card *card;
 368        int subdevice;
 369        unsigned short fflags;
 370        int err;
 371        struct snd_rawmidi *rmidi;
 372        struct snd_rawmidi_file *rawmidi_file = NULL;
 373        wait_queue_t wait;
 374        struct snd_ctl_file *kctl;
 375
 376        if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 
 377                return -EINVAL;         /* invalid combination */
 378
 379        err = nonseekable_open(inode, file);
 380        if (err < 0)
 381                return err;
 382
 383        if (maj == snd_major) {
 384                rmidi = snd_lookup_minor_data(iminor(inode),
 385                                              SNDRV_DEVICE_TYPE_RAWMIDI);
 386#ifdef CONFIG_SND_OSSEMUL
 387        } else if (maj == SOUND_MAJOR) {
 388                rmidi = snd_lookup_oss_minor_data(iminor(inode),
 389                                                  SNDRV_OSS_DEVICE_TYPE_MIDI);
 390#endif
 391        } else
 392                return -ENXIO;
 393
 394        if (rmidi == NULL)
 395                return -ENODEV;
 396
 397        if (!try_module_get(rmidi->card->module))
 398                return -ENXIO;
 399
 400        mutex_lock(&rmidi->open_mutex);
 401        card = rmidi->card;
 402        err = snd_card_file_add(card, file);
 403        if (err < 0)
 404                goto __error_card;
 405        fflags = snd_rawmidi_file_flags(file);
 406        if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */
 407                fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
 408        rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);
 409        if (rawmidi_file == NULL) {
 410                err = -ENOMEM;
 411                goto __error;
 412        }
 413        init_waitqueue_entry(&wait, current);
 414        add_wait_queue(&rmidi->open_wait, &wait);
 415        while (1) {
 416                subdevice = -1;
 417                read_lock(&card->ctl_files_rwlock);
 418                list_for_each_entry(kctl, &card->ctl_files, list) {
 419                        if (kctl->pid == task_pid(current)) {
 420                                subdevice = kctl->prefer_rawmidi_subdevice;
 421                                if (subdevice != -1)
 422                                        break;
 423                        }
 424                }
 425                read_unlock(&card->ctl_files_rwlock);
 426                err = rawmidi_open_priv(rmidi, subdevice, fflags, rawmidi_file);
 427                if (err >= 0)
 428                        break;
 429                if (err == -EAGAIN) {
 430                        if (file->f_flags & O_NONBLOCK) {
 431                                err = -EBUSY;
 432                                break;
 433                        }
 434                } else
 435                        break;
 436                set_current_state(TASK_INTERRUPTIBLE);
 437                mutex_unlock(&rmidi->open_mutex);
 438                schedule();
 439                mutex_lock(&rmidi->open_mutex);
 440                if (signal_pending(current)) {
 441                        err = -ERESTARTSYS;
 442                        break;
 443                }
 444        }
 445        remove_wait_queue(&rmidi->open_wait, &wait);
 446        if (err < 0) {
 447                kfree(rawmidi_file);
 448                goto __error;
 449        }
 450#ifdef CONFIG_SND_OSSEMUL
 451        if (rawmidi_file->input && rawmidi_file->input->runtime)
 452                rawmidi_file->input->runtime->oss = (maj == SOUND_MAJOR);
 453        if (rawmidi_file->output && rawmidi_file->output->runtime)
 454                rawmidi_file->output->runtime->oss = (maj == SOUND_MAJOR);
 455#endif
 456        file->private_data = rawmidi_file;
 457        mutex_unlock(&rmidi->open_mutex);
 458        return 0;
 459
 460 __error:
 461        snd_card_file_remove(card, file);
 462 __error_card:
 463        mutex_unlock(&rmidi->open_mutex);
 464        module_put(rmidi->card->module);
 465        return err;
 466}
 467
 468static void close_substream(struct snd_rawmidi *rmidi,
 469                            struct snd_rawmidi_substream *substream,
 470                            int cleanup)
 471{
 472        if (--substream->use_count)
 473                return;
 474
 475        if (cleanup) {
 476                if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
 477                        snd_rawmidi_input_trigger(substream, 0);
 478                else {
 479                        if (substream->active_sensing) {
 480                                unsigned char buf = 0xfe;
 481                                /* sending single active sensing message
 482                                 * to shut the device up
 483                                 */
 484                                snd_rawmidi_kernel_write(substream, &buf, 1);
 485                        }
 486                        if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS)
 487                                snd_rawmidi_output_trigger(substream, 0);
 488                }
 489        }
 490        substream->ops->close(substream);
 491        if (substream->runtime->private_free)
 492                substream->runtime->private_free(substream);
 493        snd_rawmidi_runtime_free(substream);
 494        substream->opened = 0;
 495        substream->append = 0;
 496        put_pid(substream->pid);
 497        substream->pid = NULL;
 498        rmidi->streams[substream->stream].substream_opened--;
 499}
 500
 501static void rawmidi_release_priv(struct snd_rawmidi_file *rfile)
 502{
 503        struct snd_rawmidi *rmidi;
 504
 505        rmidi = rfile->rmidi;
 506        mutex_lock(&rmidi->open_mutex);
 507        if (rfile->input) {
 508                close_substream(rmidi, rfile->input, 1);
 509                rfile->input = NULL;
 510        }
 511        if (rfile->output) {
 512                close_substream(rmidi, rfile->output, 1);
 513                rfile->output = NULL;
 514        }
 515        rfile->rmidi = NULL;
 516        mutex_unlock(&rmidi->open_mutex);
 517        wake_up(&rmidi->open_wait);
 518}
 519
 520/* called from sound/core/seq/seq_midi.c */
 521int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile)
 522{
 523        struct snd_rawmidi *rmidi;
 524
 525        if (snd_BUG_ON(!rfile))
 526                return -ENXIO;
 527        
 528        rmidi = rfile->rmidi;
 529        rawmidi_release_priv(rfile);
 530        module_put(rmidi->card->module);
 531        return 0;
 532}
 533
 534static int snd_rawmidi_release(struct inode *inode, struct file *file)
 535{
 536        struct snd_rawmidi_file *rfile;
 537        struct snd_rawmidi *rmidi;
 538        struct module *module;
 539
 540        rfile = file->private_data;
 541        rmidi = rfile->rmidi;
 542        rawmidi_release_priv(rfile);
 543        kfree(rfile);
 544        module = rmidi->card->module;
 545        snd_card_file_remove(rmidi->card, file);
 546        module_put(module);
 547        return 0;
 548}
 549
 550static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
 551                            struct snd_rawmidi_info *info)
 552{
 553        struct snd_rawmidi *rmidi;
 554        
 555        if (substream == NULL)
 556                return -ENODEV;
 557        rmidi = substream->rmidi;
 558        memset(info, 0, sizeof(*info));
 559        info->card = rmidi->card->number;
 560        info->device = rmidi->device;
 561        info->subdevice = substream->number;
 562        info->stream = substream->stream;
 563        info->flags = rmidi->info_flags;
 564        strcpy(info->id, rmidi->id);
 565        strcpy(info->name, rmidi->name);
 566        strcpy(info->subname, substream->name);
 567        info->subdevices_count = substream->pstr->substream_count;
 568        info->subdevices_avail = (substream->pstr->substream_count -
 569                                  substream->pstr->substream_opened);
 570        return 0;
 571}
 572
 573static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream,
 574                                 struct snd_rawmidi_info __user * _info)
 575{
 576        struct snd_rawmidi_info info;
 577        int err;
 578        if ((err = snd_rawmidi_info(substream, &info)) < 0)
 579                return err;
 580        if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
 581                return -EFAULT;
 582        return 0;
 583}
 584
 585int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
 586{
 587        struct snd_rawmidi *rmidi;
 588        struct snd_rawmidi_str *pstr;
 589        struct snd_rawmidi_substream *substream;
 590
 591        mutex_lock(&register_mutex);
 592        rmidi = snd_rawmidi_search(card, info->device);
 593        mutex_unlock(&register_mutex);
 594        if (!rmidi)
 595                return -ENXIO;
 596        if (info->stream < 0 || info->stream > 1)
 597                return -EINVAL;
 598        pstr = &rmidi->streams[info->stream];
 599        if (pstr->substream_count == 0)
 600                return -ENOENT;
 601        if (info->subdevice >= pstr->substream_count)
 602                return -ENXIO;
 603        list_for_each_entry(substream, &pstr->substreams, list) {
 604                if ((unsigned int)substream->number == info->subdevice)
 605                        return snd_rawmidi_info(substream, info);
 606        }
 607        return -ENXIO;
 608}
 609
 610static int snd_rawmidi_info_select_user(struct snd_card *card,
 611                                        struct snd_rawmidi_info __user *_info)
 612{
 613        int err;
 614        struct snd_rawmidi_info info;
 615        if (get_user(info.device, &_info->device))
 616                return -EFAULT;
 617        if (get_user(info.stream, &_info->stream))
 618                return -EFAULT;
 619        if (get_user(info.subdevice, &_info->subdevice))
 620                return -EFAULT;
 621        if ((err = snd_rawmidi_info_select(card, &info)) < 0)
 622                return err;
 623        if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
 624                return -EFAULT;
 625        return 0;
 626}
 627
 628int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
 629                              struct snd_rawmidi_params * params)
 630{
 631        char *newbuf;
 632        struct snd_rawmidi_runtime *runtime = substream->runtime;
 633        
 634        if (substream->append && substream->use_count > 1)
 635                return -EBUSY;
 636        snd_rawmidi_drain_output(substream);
 637        if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
 638                return -EINVAL;
 639        }
 640        if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
 641                return -EINVAL;
 642        }
 643        if (params->buffer_size != runtime->buffer_size) {
 644                newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
 645                if (!newbuf)
 646                        return -ENOMEM;
 647                kfree(runtime->buffer);
 648                runtime->buffer = newbuf;
 649                runtime->buffer_size = params->buffer_size;
 650                runtime->avail = runtime->buffer_size;
 651        }
 652        runtime->avail_min = params->avail_min;
 653        substream->active_sensing = !params->no_active_sensing;
 654        return 0;
 655}
 656
 657int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
 658                             struct snd_rawmidi_params * params)
 659{
 660        char *newbuf;
 661        struct snd_rawmidi_runtime *runtime = substream->runtime;
 662
 663        snd_rawmidi_drain_input(substream);
 664        if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
 665                return -EINVAL;
 666        }
 667        if (params->avail_min < 1 || params->avail_min > params->buffer_size) {
 668                return -EINVAL;
 669        }
 670        if (params->buffer_size != runtime->buffer_size) {
 671                newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
 672                if (!newbuf)
 673                        return -ENOMEM;
 674                kfree(runtime->buffer);
 675                runtime->buffer = newbuf;
 676                runtime->buffer_size = params->buffer_size;
 677        }
 678        runtime->avail_min = params->avail_min;
 679        return 0;
 680}
 681
 682static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream,
 683                                     struct snd_rawmidi_status * status)
 684{
 685        struct snd_rawmidi_runtime *runtime = substream->runtime;
 686
 687        memset(status, 0, sizeof(*status));
 688        status->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
 689        spin_lock_irq(&runtime->lock);
 690        status->avail = runtime->avail;
 691        spin_unlock_irq(&runtime->lock);
 692        return 0;
 693}
 694
 695static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream,
 696                                    struct snd_rawmidi_status * status)
 697{
 698        struct snd_rawmidi_runtime *runtime = substream->runtime;
 699
 700        memset(status, 0, sizeof(*status));
 701        status->stream = SNDRV_RAWMIDI_STREAM_INPUT;
 702        spin_lock_irq(&runtime->lock);
 703        status->avail = runtime->avail;
 704        status->xruns = runtime->xruns;
 705        runtime->xruns = 0;
 706        spin_unlock_irq(&runtime->lock);
 707        return 0;
 708}
 709
 710static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 711{
 712        struct snd_rawmidi_file *rfile;
 713        void __user *argp = (void __user *)arg;
 714
 715        rfile = file->private_data;
 716        if (((cmd >> 8) & 0xff) != 'W')
 717                return -ENOTTY;
 718        switch (cmd) {
 719        case SNDRV_RAWMIDI_IOCTL_PVERSION:
 720                return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0;
 721        case SNDRV_RAWMIDI_IOCTL_INFO:
 722        {
 723                int stream;
 724                struct snd_rawmidi_info __user *info = argp;
 725                if (get_user(stream, &info->stream))
 726                        return -EFAULT;
 727                switch (stream) {
 728                case SNDRV_RAWMIDI_STREAM_INPUT:
 729                        return snd_rawmidi_info_user(rfile->input, info);
 730                case SNDRV_RAWMIDI_STREAM_OUTPUT:
 731                        return snd_rawmidi_info_user(rfile->output, info);
 732                default:
 733                        return -EINVAL;
 734                }
 735        }
 736        case SNDRV_RAWMIDI_IOCTL_PARAMS:
 737        {
 738                struct snd_rawmidi_params params;
 739                if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
 740                        return -EFAULT;
 741                switch (params.stream) {
 742                case SNDRV_RAWMIDI_STREAM_OUTPUT:
 743                        if (rfile->output == NULL)
 744                                return -EINVAL;
 745                        return snd_rawmidi_output_params(rfile->output, &params);
 746                case SNDRV_RAWMIDI_STREAM_INPUT:
 747                        if (rfile->input == NULL)
 748                                return -EINVAL;
 749                        return snd_rawmidi_input_params(rfile->input, &params);
 750                default:
 751                        return -EINVAL;
 752                }
 753        }
 754        case SNDRV_RAWMIDI_IOCTL_STATUS:
 755        {
 756                int err = 0;
 757                struct snd_rawmidi_status status;
 758                if (copy_from_user(&status, argp, sizeof(struct snd_rawmidi_status)))
 759                        return -EFAULT;
 760                switch (status.stream) {
 761                case SNDRV_RAWMIDI_STREAM_OUTPUT:
 762                        if (rfile->output == NULL)
 763                                return -EINVAL;
 764                        err = snd_rawmidi_output_status(rfile->output, &status);
 765                        break;
 766                case SNDRV_RAWMIDI_STREAM_INPUT:
 767                        if (rfile->input == NULL)
 768                                return -EINVAL;
 769                        err = snd_rawmidi_input_status(rfile->input, &status);
 770                        break;
 771                default:
 772                        return -EINVAL;
 773                }
 774                if (err < 0)
 775                        return err;
 776                if (copy_to_user(argp, &status, sizeof(struct snd_rawmidi_status)))
 777                        return -EFAULT;
 778                return 0;
 779        }
 780        case SNDRV_RAWMIDI_IOCTL_DROP:
 781        {
 782                int val;
 783                if (get_user(val, (int __user *) argp))
 784                        return -EFAULT;
 785                switch (val) {
 786                case SNDRV_RAWMIDI_STREAM_OUTPUT:
 787                        if (rfile->output == NULL)
 788                                return -EINVAL;
 789                        return snd_rawmidi_drop_output(rfile->output);
 790                default:
 791                        return -EINVAL;
 792                }
 793        }
 794        case SNDRV_RAWMIDI_IOCTL_DRAIN:
 795        {
 796                int val;
 797                if (get_user(val, (int __user *) argp))
 798                        return -EFAULT;
 799                switch (val) {
 800                case SNDRV_RAWMIDI_STREAM_OUTPUT:
 801                        if (rfile->output == NULL)
 802                                return -EINVAL;
 803                        return snd_rawmidi_drain_output(rfile->output);
 804                case SNDRV_RAWMIDI_STREAM_INPUT:
 805                        if (rfile->input == NULL)
 806                                return -EINVAL;
 807                        return snd_rawmidi_drain_input(rfile->input);
 808                default:
 809                        return -EINVAL;
 810                }
 811        }
 812#ifdef CONFIG_SND_DEBUG
 813        default:
 814                snd_printk(KERN_WARNING "rawmidi: unknown command = 0x%x\n", cmd);
 815#endif
 816        }
 817        return -ENOTTY;
 818}
 819
 820static int snd_rawmidi_control_ioctl(struct snd_card *card,
 821                                     struct snd_ctl_file *control,
 822                                     unsigned int cmd,
 823                                     unsigned long arg)
 824{
 825        void __user *argp = (void __user *)arg;
 826
 827        switch (cmd) {
 828        case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
 829        {
 830                int device;
 831                
 832                if (get_user(device, (int __user *)argp))
 833                        return -EFAULT;
 834                if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */
 835                        device = SNDRV_RAWMIDI_DEVICES - 1;
 836                mutex_lock(&register_mutex);
 837                device = device < 0 ? 0 : device + 1;
 838                while (device < SNDRV_RAWMIDI_DEVICES) {
 839                        if (snd_rawmidi_search(card, device))
 840                                break;
 841                        device++;
 842                }
 843                if (device == SNDRV_RAWMIDI_DEVICES)
 844                        device = -1;
 845                mutex_unlock(&register_mutex);
 846                if (put_user(device, (int __user *)argp))
 847                        return -EFAULT;
 848                return 0;
 849        }
 850        case SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE:
 851        {
 852                int val;
 853                
 854                if (get_user(val, (int __user *)argp))
 855                        return -EFAULT;
 856                control->prefer_rawmidi_subdevice = val;
 857                return 0;
 858        }
 859        case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
 860                return snd_rawmidi_info_select_user(card, argp);
 861        }
 862        return -ENOIOCTLCMD;
 863}
 864
 865/**
 866 * snd_rawmidi_receive - receive the input data from the device
 867 * @substream: the rawmidi substream
 868 * @buffer: the buffer pointer
 869 * @count: the data size to read
 870 *
 871 * Reads the data from the internal buffer.
 872 *
 873 * Returns the size of read data, or a negative error code on failure.
 874 */
 875int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
 876                        const unsigned char *buffer, int count)
 877{
 878        unsigned long flags;
 879        int result = 0, count1;
 880        struct snd_rawmidi_runtime *runtime = substream->runtime;
 881
 882        if (!substream->opened)
 883                return -EBADFD;
 884        if (runtime->buffer == NULL) {
 885                snd_printd("snd_rawmidi_receive: input is not active!!!\n");
 886                return -EINVAL;
 887        }
 888        spin_lock_irqsave(&runtime->lock, flags);
 889        if (count == 1) {       /* special case, faster code */
 890                substream->bytes++;
 891                if (runtime->avail < runtime->buffer_size) {
 892                        runtime->buffer[runtime->hw_ptr++] = buffer[0];
 893                        runtime->hw_ptr %= runtime->buffer_size;
 894                        runtime->avail++;
 895                        result++;
 896                } else {
 897                        runtime->xruns++;
 898                }
 899        } else {
 900                substream->bytes += count;
 901                count1 = runtime->buffer_size - runtime->hw_ptr;
 902                if (count1 > count)
 903                        count1 = count;
 904                if (count1 > (int)(runtime->buffer_size - runtime->avail))
 905                        count1 = runtime->buffer_size - runtime->avail;
 906                memcpy(runtime->buffer + runtime->hw_ptr, buffer, count1);
 907                runtime->hw_ptr += count1;
 908                runtime->hw_ptr %= runtime->buffer_size;
 909                runtime->avail += count1;
 910                count -= count1;
 911                result += count1;
 912                if (count > 0) {
 913                        buffer += count1;
 914                        count1 = count;
 915                        if (count1 > (int)(runtime->buffer_size - runtime->avail)) {
 916                                count1 = runtime->buffer_size - runtime->avail;
 917                                runtime->xruns += count - count1;
 918                        }
 919                        if (count1 > 0) {
 920                                memcpy(runtime->buffer, buffer, count1);
 921                                runtime->hw_ptr = count1;
 922                                runtime->avail += count1;
 923                                result += count1;
 924                        }
 925                }
 926        }
 927        if (result > 0) {
 928                if (runtime->event)
 929                        tasklet_schedule(&runtime->tasklet);
 930                else if (snd_rawmidi_ready(substream))
 931                        wake_up(&runtime->sleep);
 932        }
 933        spin_unlock_irqrestore(&runtime->lock, flags);
 934        return result;
 935}
 936
 937static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
 938                                     unsigned char __user *userbuf,
 939                                     unsigned char *kernelbuf, long count)
 940{
 941        unsigned long flags;
 942        long result = 0, count1;
 943        struct snd_rawmidi_runtime *runtime = substream->runtime;
 944
 945        while (count > 0 && runtime->avail) {
 946                count1 = runtime->buffer_size - runtime->appl_ptr;
 947                if (count1 > count)
 948                        count1 = count;
 949                spin_lock_irqsave(&runtime->lock, flags);
 950                if (count1 > (int)runtime->avail)
 951                        count1 = runtime->avail;
 952                if (kernelbuf)
 953                        memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
 954                if (userbuf) {
 955                        spin_unlock_irqrestore(&runtime->lock, flags);
 956                        if (copy_to_user(userbuf + result,
 957                                         runtime->buffer + runtime->appl_ptr, count1)) {
 958                                return result > 0 ? result : -EFAULT;
 959                        }
 960                        spin_lock_irqsave(&runtime->lock, flags);
 961                }
 962                runtime->appl_ptr += count1;
 963                runtime->appl_ptr %= runtime->buffer_size;
 964                runtime->avail -= count1;
 965                spin_unlock_irqrestore(&runtime->lock, flags);
 966                result += count1;
 967                count -= count1;
 968        }
 969        return result;
 970}
 971
 972long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
 973                             unsigned char *buf, long count)
 974{
 975        snd_rawmidi_input_trigger(substream, 1);
 976        return snd_rawmidi_kernel_read1(substream, NULL/*userbuf*/, buf, count);
 977}
 978
 979static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count,
 980                                loff_t *offset)
 981{
 982        long result;
 983        int count1;
 984        struct snd_rawmidi_file *rfile;
 985        struct snd_rawmidi_substream *substream;
 986        struct snd_rawmidi_runtime *runtime;
 987
 988        rfile = file->private_data;
 989        substream = rfile->input;
 990        if (substream == NULL)
 991                return -EIO;
 992        runtime = substream->runtime;
 993        snd_rawmidi_input_trigger(substream, 1);
 994        result = 0;
 995        while (count > 0) {
 996                spin_lock_irq(&runtime->lock);
 997                while (!snd_rawmidi_ready(substream)) {
 998                        wait_queue_t wait;
 999                        if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
1000                                spin_unlock_irq(&runtime->lock);
1001                                return result > 0 ? result : -EAGAIN;
1002                        }
1003                        init_waitqueue_entry(&wait, current);
1004                        add_wait_queue(&runtime->sleep, &wait);
1005                        set_current_state(TASK_INTERRUPTIBLE);
1006                        spin_unlock_irq(&runtime->lock);
1007                        schedule();
1008                        remove_wait_queue(&runtime->sleep, &wait);
1009                        if (signal_pending(current))
1010                                return result > 0 ? result : -ERESTARTSYS;
1011                        if (!runtime->avail)
1012                                return result > 0 ? result : -EIO;
1013                        spin_lock_irq(&runtime->lock);
1014                }
1015                spin_unlock_irq(&runtime->lock);
1016                count1 = snd_rawmidi_kernel_read1(substream,
1017                                                  (unsigned char __user *)buf,
1018                                                  NULL/*kernelbuf*/,
1019                                                  count);
1020                if (count1 < 0)
1021                        return result > 0 ? result : count1;
1022                result += count1;
1023                buf += count1;
1024                count -= count1;
1025        }
1026        return result;
1027}
1028
1029/**
1030 * snd_rawmidi_transmit_empty - check whether the output buffer is empty
1031 * @substream: the rawmidi substream
1032 * 
1033 * Returns 1 if the internal output buffer is empty, 0 if not.
1034 */
1035int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
1036{
1037        struct snd_rawmidi_runtime *runtime = substream->runtime;
1038        int result;
1039        unsigned long flags;
1040
1041        if (runtime->buffer == NULL) {
1042                snd_printd("snd_rawmidi_transmit_empty: output is not active!!!\n");
1043                return 1;
1044        }
1045        spin_lock_irqsave(&runtime->lock, flags);
1046        result = runtime->avail >= runtime->buffer_size;
1047        spin_unlock_irqrestore(&runtime->lock, flags);
1048        return result;          
1049}
1050
1051/**
1052 * snd_rawmidi_transmit_peek - copy data from the internal buffer
1053 * @substream: the rawmidi substream
1054 * @buffer: the buffer pointer
1055 * @count: data size to transfer
1056 *
1057 * Copies data from the internal output buffer to the given buffer.
1058 *
1059 * Call this in the interrupt handler when the midi output is ready,
1060 * and call snd_rawmidi_transmit_ack() after the transmission is
1061 * finished.
1062 *
1063 * Returns the size of copied data, or a negative error code on failure.
1064 */
1065int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
1066                              unsigned char *buffer, int count)
1067{
1068        unsigned long flags;
1069        int result, count1;
1070        struct snd_rawmidi_runtime *runtime = substream->runtime;
1071
1072        if (runtime->buffer == NULL) {
1073                snd_printd("snd_rawmidi_transmit_peek: output is not active!!!\n");
1074                return -EINVAL;
1075        }
1076        result = 0;
1077        spin_lock_irqsave(&runtime->lock, flags);
1078        if (runtime->avail >= runtime->buffer_size) {
1079                /* warning: lowlevel layer MUST trigger down the hardware */
1080                goto __skip;
1081        }
1082        if (count == 1) {       /* special case, faster code */
1083                *buffer = runtime->buffer[runtime->hw_ptr];
1084                result++;
1085        } else {
1086                count1 = runtime->buffer_size - runtime->hw_ptr;
1087                if (count1 > count)
1088                        count1 = count;
1089                if (count1 > (int)(runtime->buffer_size - runtime->avail))
1090                        count1 = runtime->buffer_size - runtime->avail;
1091                memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1);
1092                count -= count1;
1093                result += count1;
1094                if (count > 0) {
1095                        if (count > (int)(runtime->buffer_size - runtime->avail - count1))
1096                                count = runtime->buffer_size - runtime->avail - count1;
1097                        memcpy(buffer + count1, runtime->buffer, count);
1098                        result += count;
1099                }
1100        }
1101      __skip:
1102        spin_unlock_irqrestore(&runtime->lock, flags);
1103        return result;
1104}
1105
1106/**
1107 * snd_rawmidi_transmit_ack - acknowledge the transmission
1108 * @substream: the rawmidi substream
1109 * @count: the tranferred count
1110 *
1111 * Advances the hardware pointer for the internal output buffer with
1112 * the given size and updates the condition.
1113 * Call after the transmission is finished.
1114 *
1115 * Returns the advanced size if successful, or a negative error code on failure.
1116 */
1117int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1118{
1119        unsigned long flags;
1120        struct snd_rawmidi_runtime *runtime = substream->runtime;
1121
1122        if (runtime->buffer == NULL) {
1123                snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n");
1124                return -EINVAL;
1125        }
1126        spin_lock_irqsave(&runtime->lock, flags);
1127        snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
1128        runtime->hw_ptr += count;
1129        runtime->hw_ptr %= runtime->buffer_size;
1130        runtime->avail += count;
1131        substream->bytes += count;
1132        if (count > 0) {
1133                if (runtime->drain || snd_rawmidi_ready(substream))
1134                        wake_up(&runtime->sleep);
1135        }
1136        spin_unlock_irqrestore(&runtime->lock, flags);
1137        return count;
1138}
1139
1140/**
1141 * snd_rawmidi_transmit - copy from the buffer to the device
1142 * @substream: the rawmidi substream
1143 * @buffer: the buffer pointer
1144 * @count: the data size to transfer
1145 * 
1146 * Copies data from the buffer to the device and advances the pointer.
1147 *
1148 * Returns the copied size if successful, or a negative error code on failure.
1149 */
1150int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
1151                         unsigned char *buffer, int count)
1152{
1153        if (!substream->opened)
1154                return -EBADFD;
1155        count = snd_rawmidi_transmit_peek(substream, buffer, count);
1156        if (count < 0)
1157                return count;
1158        return snd_rawmidi_transmit_ack(substream, count);
1159}
1160
1161static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1162                                      const unsigned char __user *userbuf,
1163                                      const unsigned char *kernelbuf,
1164                                      long count)
1165{
1166        unsigned long flags;
1167        long count1, result;
1168        struct snd_rawmidi_runtime *runtime = substream->runtime;
1169
1170        if (snd_BUG_ON(!kernelbuf && !userbuf))
1171                return -EINVAL;
1172        if (snd_BUG_ON(!runtime->buffer))
1173                return -EINVAL;
1174
1175        result = 0;
1176        spin_lock_irqsave(&runtime->lock, flags);
1177        if (substream->append) {
1178                if ((long)runtime->avail < count) {
1179                        spin_unlock_irqrestore(&runtime->lock, flags);
1180                        return -EAGAIN;
1181                }
1182        }
1183        while (count > 0 && runtime->avail > 0) {
1184                count1 = runtime->buffer_size - runtime->appl_ptr;
1185                if (count1 > count)
1186                        count1 = count;
1187                if (count1 > (long)runtime->avail)
1188                        count1 = runtime->avail;
1189                if (kernelbuf)
1190                        memcpy(runtime->buffer + runtime->appl_ptr,
1191                               kernelbuf + result, count1);
1192                else if (userbuf) {
1193                        spin_unlock_irqrestore(&runtime->lock, flags);
1194                        if (copy_from_user(runtime->buffer + runtime->appl_ptr,
1195                                           userbuf + result, count1)) {
1196                                spin_lock_irqsave(&runtime->lock, flags);
1197                                result = result > 0 ? result : -EFAULT;
1198                                goto __end;
1199                        }
1200                        spin_lock_irqsave(&runtime->lock, flags);
1201                }
1202                runtime->appl_ptr += count1;
1203                runtime->appl_ptr %= runtime->buffer_size;
1204                runtime->avail -= count1;
1205                result += count1;
1206                count -= count1;
1207        }
1208      __end:
1209        count1 = runtime->avail < runtime->buffer_size;
1210        spin_unlock_irqrestore(&runtime->lock, flags);
1211        if (count1)
1212                snd_rawmidi_output_trigger(substream, 1);
1213        return result;
1214}
1215
1216long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
1217                              const unsigned char *buf, long count)
1218{
1219        return snd_rawmidi_kernel_write1(substream, NULL, buf, count);
1220}
1221
1222static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
1223                                 size_t count, loff_t *offset)
1224{
1225        long result, timeout;
1226        int count1;
1227        struct snd_rawmidi_file *rfile;
1228        struct snd_rawmidi_runtime *runtime;
1229        struct snd_rawmidi_substream *substream;
1230
1231        rfile = file->private_data;
1232        substream = rfile->output;
1233        runtime = substream->runtime;
1234        /* we cannot put an atomic message to our buffer */
1235        if (substream->append && count > runtime->buffer_size)
1236                return -EIO;
1237        result = 0;
1238        while (count > 0) {
1239                spin_lock_irq(&runtime->lock);
1240                while (!snd_rawmidi_ready_append(substream, count)) {
1241                        wait_queue_t wait;
1242                        if (file->f_flags & O_NONBLOCK) {
1243                                spin_unlock_irq(&runtime->lock);
1244                                return result > 0 ? result : -EAGAIN;
1245                        }
1246                        init_waitqueue_entry(&wait, current);
1247                        add_wait_queue(&runtime->sleep, &wait);
1248                        set_current_state(TASK_INTERRUPTIBLE);
1249                        spin_unlock_irq(&runtime->lock);
1250                        timeout = schedule_timeout(30 * HZ);
1251                        remove_wait_queue(&runtime->sleep, &wait);
1252                        if (signal_pending(current))
1253                                return result > 0 ? result : -ERESTARTSYS;
1254                        if (!runtime->avail && !timeout)
1255                                return result > 0 ? result : -EIO;
1256                        spin_lock_irq(&runtime->lock);
1257                }
1258                spin_unlock_irq(&runtime->lock);
1259                count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count);
1260                if (count1 < 0)
1261                        return result > 0 ? result : count1;
1262                result += count1;
1263                buf += count1;
1264                if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK))
1265                        break;
1266                count -= count1;
1267        }
1268        if (file->f_flags & O_DSYNC) {
1269                spin_lock_irq(&runtime->lock);
1270                while (runtime->avail != runtime->buffer_size) {
1271                        wait_queue_t wait;
1272                        unsigned int last_avail = runtime->avail;
1273                        init_waitqueue_entry(&wait, current);
1274                        add_wait_queue(&runtime->sleep, &wait);
1275                        set_current_state(TASK_INTERRUPTIBLE);
1276                        spin_unlock_irq(&runtime->lock);
1277                        timeout = schedule_timeout(30 * HZ);
1278                        remove_wait_queue(&runtime->sleep, &wait);
1279                        if (signal_pending(current))
1280                                return result > 0 ? result : -ERESTARTSYS;
1281                        if (runtime->avail == last_avail && !timeout)
1282                                return result > 0 ? result : -EIO;
1283                        spin_lock_irq(&runtime->lock);
1284                }
1285                spin_unlock_irq(&runtime->lock);
1286        }
1287        return result;
1288}
1289
1290static unsigned int snd_rawmidi_poll(struct file *file, poll_table * wait)
1291{
1292        struct snd_rawmidi_file *rfile;
1293        struct snd_rawmidi_runtime *runtime;
1294        unsigned int mask;
1295
1296        rfile = file->private_data;
1297        if (rfile->input != NULL) {
1298                runtime = rfile->input->runtime;
1299                snd_rawmidi_input_trigger(rfile->input, 1);
1300                poll_wait(file, &runtime->sleep, wait);
1301        }
1302        if (rfile->output != NULL) {
1303                runtime = rfile->output->runtime;
1304                poll_wait(file, &runtime->sleep, wait);
1305        }
1306        mask = 0;
1307        if (rfile->input != NULL) {
1308                if (snd_rawmidi_ready(rfile->input))
1309                        mask |= POLLIN | POLLRDNORM;
1310        }
1311        if (rfile->output != NULL) {
1312                if (snd_rawmidi_ready(rfile->output))
1313                        mask |= POLLOUT | POLLWRNORM;
1314        }
1315        return mask;
1316}
1317
1318/*
1319 */
1320#ifdef CONFIG_COMPAT
1321#include "rawmidi_compat.c"
1322#else
1323#define snd_rawmidi_ioctl_compat        NULL
1324#endif
1325
1326/*
1327
1328 */
1329
1330static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1331                                       struct snd_info_buffer *buffer)
1332{
1333        struct snd_rawmidi *rmidi;
1334        struct snd_rawmidi_substream *substream;
1335        struct snd_rawmidi_runtime *runtime;
1336
1337        rmidi = entry->private_data;
1338        snd_iprintf(buffer, "%s\n\n", rmidi->name);
1339        mutex_lock(&rmidi->open_mutex);
1340        if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
1341                list_for_each_entry(substream,
1342                                    &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
1343                                    list) {
1344                        snd_iprintf(buffer,
1345                                    "Output %d\n"
1346                                    "  Tx bytes     : %lu\n",
1347                                    substream->number,
1348                                    (unsigned long) substream->bytes);
1349                        if (substream->opened) {
1350                                snd_iprintf(buffer,
1351                                    "  Owner PID    : %d\n",
1352                                    pid_vnr(substream->pid));
1353                                runtime = substream->runtime;
1354                                snd_iprintf(buffer,
1355                                    "  Mode         : %s\n"
1356                                    "  Buffer size  : %lu\n"
1357                                    "  Avail        : %lu\n",
1358                                    runtime->oss ? "OSS compatible" : "native",
1359                                    (unsigned long) runtime->buffer_size,
1360                                    (unsigned long) runtime->avail);
1361                        }
1362                }
1363        }
1364        if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) {
1365                list_for_each_entry(substream,
1366                                    &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams,
1367                                    list) {
1368                        snd_iprintf(buffer,
1369                                    "Input %d\n"
1370                                    "  Rx bytes     : %lu\n",
1371                                    substream->number,
1372                                    (unsigned long) substream->bytes);
1373                        if (substream->opened) {
1374                                snd_iprintf(buffer,
1375                                            "  Owner PID    : %d\n",
1376                                            pid_vnr(substream->pid));
1377                                runtime = substream->runtime;
1378                                snd_iprintf(buffer,
1379                                            "  Buffer size  : %lu\n"
1380                                            "  Avail        : %lu\n"
1381                                            "  Overruns     : %lu\n",
1382                                            (unsigned long) runtime->buffer_size,
1383                                            (unsigned long) runtime->avail,
1384                                            (unsigned long) runtime->xruns);
1385                        }
1386                }
1387        }
1388        mutex_unlock(&rmidi->open_mutex);
1389}
1390
1391/*
1392 *  Register functions
1393 */
1394
1395static const struct file_operations snd_rawmidi_f_ops =
1396{
1397        .owner =        THIS_MODULE,
1398        .read =         snd_rawmidi_read,
1399        .write =        snd_rawmidi_write,
1400        .open =         snd_rawmidi_open,
1401        .release =      snd_rawmidi_release,
1402        .llseek =       no_llseek,
1403        .poll =         snd_rawmidi_poll,
1404        .unlocked_ioctl =       snd_rawmidi_ioctl,
1405        .compat_ioctl = snd_rawmidi_ioctl_compat,
1406};
1407
1408static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,
1409                                        struct snd_rawmidi_str *stream,
1410                                        int direction,
1411                                        int count)
1412{
1413        struct snd_rawmidi_substream *substream;
1414        int idx;
1415
1416        for (idx = 0; idx < count; idx++) {
1417                substream = kzalloc(sizeof(*substream), GFP_KERNEL);
1418                if (substream == NULL) {
1419                        snd_printk(KERN_ERR "rawmidi: cannot allocate substream\n");
1420                        return -ENOMEM;
1421                }
1422                substream->stream = direction;
1423                substream->number = idx;
1424                substream->rmidi = rmidi;
1425                substream->pstr = stream;
1426                list_add_tail(&substream->list, &stream->substreams);
1427                stream->substream_count++;
1428        }
1429        return 0;
1430}
1431
1432/**
1433 * snd_rawmidi_new - create a rawmidi instance
1434 * @card: the card instance
1435 * @id: the id string
1436 * @device: the device index
1437 * @output_count: the number of output streams
1438 * @input_count: the number of input streams
1439 * @rrawmidi: the pointer to store the new rawmidi instance
1440 *
1441 * Creates a new rawmidi instance.
1442 * Use snd_rawmidi_set_ops() to set the operators to the new instance.
1443 *
1444 * Returns zero if successful, or a negative error code on failure.
1445 */
1446int snd_rawmidi_new(struct snd_card *card, char *id, int device,
1447                    int output_count, int input_count,
1448                    struct snd_rawmidi ** rrawmidi)
1449{
1450        struct snd_rawmidi *rmidi;
1451        int err;
1452        static struct snd_device_ops ops = {
1453                .dev_free = snd_rawmidi_dev_free,
1454                .dev_register = snd_rawmidi_dev_register,
1455                .dev_disconnect = snd_rawmidi_dev_disconnect,
1456        };
1457
1458        if (snd_BUG_ON(!card))
1459                return -ENXIO;
1460        if (rrawmidi)
1461                *rrawmidi = NULL;
1462        rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
1463        if (rmidi == NULL) {
1464                snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
1465                return -ENOMEM;
1466        }
1467        rmidi->card = card;
1468        rmidi->device = device;
1469        mutex_init(&rmidi->open_mutex);
1470        init_waitqueue_head(&rmidi->open_wait);
1471        INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams);
1472        INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
1473
1474        if (id != NULL)
1475                strlcpy(rmidi->id, id, sizeof(rmidi->id));
1476        if ((err = snd_rawmidi_alloc_substreams(rmidi,
1477                                                &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
1478                                                SNDRV_RAWMIDI_STREAM_INPUT,
1479                                                input_count)) < 0) {
1480                snd_rawmidi_free(rmidi);
1481                return err;
1482        }
1483        if ((err = snd_rawmidi_alloc_substreams(rmidi,
1484                                                &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
1485                                                SNDRV_RAWMIDI_STREAM_OUTPUT,
1486                                                output_count)) < 0) {
1487                snd_rawmidi_free(rmidi);
1488                return err;
1489        }
1490        if ((err = snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)) < 0) {
1491                snd_rawmidi_free(rmidi);
1492                return err;
1493        }
1494        if (rrawmidi)
1495                *rrawmidi = rmidi;
1496        return 0;
1497}
1498
1499static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream)
1500{
1501        struct snd_rawmidi_substream *substream;
1502
1503        while (!list_empty(&stream->substreams)) {
1504                substream = list_entry(stream->substreams.next, struct snd_rawmidi_substream, list);
1505                list_del(&substream->list);
1506                kfree(substream);
1507        }
1508}
1509
1510static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
1511{
1512        if (!rmidi)
1513                return 0;
1514
1515        snd_info_free_entry(rmidi->proc_entry);
1516        rmidi->proc_entry = NULL;
1517        mutex_lock(&register_mutex);
1518        if (rmidi->ops && rmidi->ops->dev_unregister)
1519                rmidi->ops->dev_unregister(rmidi);
1520        mutex_unlock(&register_mutex);
1521
1522        snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
1523        snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
1524        if (rmidi->private_free)
1525                rmidi->private_free(rmidi);
1526        kfree(rmidi);
1527        return 0;
1528}
1529
1530static int snd_rawmidi_dev_free(struct snd_device *device)
1531{
1532        struct snd_rawmidi *rmidi = device->device_data;
1533        return snd_rawmidi_free(rmidi);
1534}
1535
1536#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
1537static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device)
1538{
1539        struct snd_rawmidi *rmidi = device->private_data;
1540        rmidi->seq_dev = NULL;
1541}
1542#endif
1543
1544static int snd_rawmidi_dev_register(struct snd_device *device)
1545{
1546        int err;
1547        struct snd_info_entry *entry;
1548        char name[16];
1549        struct snd_rawmidi *rmidi = device->device_data;
1550
1551        if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
1552                return -ENOMEM;
1553        mutex_lock(&register_mutex);
1554        if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
1555                mutex_unlock(&register_mutex);
1556                return -EBUSY;
1557        }
1558        list_add_tail(&rmidi->list, &snd_rawmidi_devices);
1559        sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device);
1560        if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
1561                                       rmidi->card, rmidi->device,
1562                                       &snd_rawmidi_f_ops, rmidi, name)) < 0) {
1563                snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
1564                list_del(&rmidi->list);
1565                mutex_unlock(&register_mutex);
1566                return err;
1567        }
1568        if (rmidi->ops && rmidi->ops->dev_register &&
1569            (err = rmidi->ops->dev_register(rmidi)) < 0) {
1570                snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1571                list_del(&rmidi->list);
1572                mutex_unlock(&register_mutex);
1573                return err;
1574        }
1575#ifdef CONFIG_SND_OSSEMUL
1576        rmidi->ossreg = 0;
1577        if ((int)rmidi->device == midi_map[rmidi->card->number]) {
1578                if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1579                                            rmidi->card, 0, &snd_rawmidi_f_ops,
1580                                            rmidi, name) < 0) {
1581                        snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
1582                } else {
1583                        rmidi->ossreg++;
1584#ifdef SNDRV_OSS_INFO_DEV_MIDI
1585                        snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number, rmidi->name);
1586#endif
1587                }
1588        }
1589        if ((int)rmidi->device == amidi_map[rmidi->card->number]) {
1590                if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1591                                            rmidi->card, 1, &snd_rawmidi_f_ops,
1592                                            rmidi, name) < 0) {
1593                        snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
1594                } else {
1595                        rmidi->ossreg++;
1596                }
1597        }
1598#endif /* CONFIG_SND_OSSEMUL */
1599        mutex_unlock(&register_mutex);
1600        sprintf(name, "midi%d", rmidi->device);
1601        entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
1602        if (entry) {
1603                entry->private_data = rmidi;
1604                entry->c.text.read = snd_rawmidi_proc_info_read;
1605                if (snd_info_register(entry) < 0) {
1606                        snd_info_free_entry(entry);
1607                        entry = NULL;
1608                }
1609        }
1610        rmidi->proc_entry = entry;
1611#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
1612        if (!rmidi->ops || !rmidi->ops->dev_register) { /* own registration mechanism */
1613                if (snd_seq_device_new(rmidi->card, rmidi->device, SNDRV_SEQ_DEV_ID_MIDISYNTH, 0, &rmidi->seq_dev) >= 0) {
1614                        rmidi->seq_dev->private_data = rmidi;
1615                        rmidi->seq_dev->private_free = snd_rawmidi_dev_seq_free;
1616                        sprintf(rmidi->seq_dev->name, "MIDI %d-%d", rmidi->card->number, rmidi->device);
1617                        snd_device_register(rmidi->card, rmidi->seq_dev);
1618                }
1619        }
1620#endif
1621        return 0;
1622}
1623
1624static int snd_rawmidi_dev_disconnect(struct snd_device *device)
1625{
1626        struct snd_rawmidi *rmidi = device->device_data;
1627
1628        mutex_lock(&register_mutex);
1629        list_del_init(&rmidi->list);
1630#ifdef CONFIG_SND_OSSEMUL
1631        if (rmidi->ossreg) {
1632                if ((int)rmidi->device == midi_map[rmidi->card->number]) {
1633                        snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0);
1634#ifdef SNDRV_OSS_INFO_DEV_MIDI
1635                        snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number);
1636#endif
1637                }
1638                if ((int)rmidi->device == amidi_map[rmidi->card->number])
1639                        snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1);
1640                rmidi->ossreg = 0;
1641        }
1642#endif /* CONFIG_SND_OSSEMUL */
1643        snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1644        mutex_unlock(&register_mutex);
1645        return 0;
1646}
1647
1648/**
1649 * snd_rawmidi_set_ops - set the rawmidi operators
1650 * @rmidi: the rawmidi instance
1651 * @stream: the stream direction, SNDRV_RAWMIDI_STREAM_XXX
1652 * @ops: the operator table
1653 *
1654 * Sets the rawmidi operators for the given stream direction.
1655 */
1656void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
1657                         struct snd_rawmidi_ops *ops)
1658{
1659        struct snd_rawmidi_substream *substream;
1660        
1661        list_for_each_entry(substream, &rmidi->streams[stream].substreams, list)
1662                substream->ops = ops;
1663}
1664
1665/*
1666 *  ENTRY functions
1667 */
1668
1669static int __init alsa_rawmidi_init(void)
1670{
1671
1672        snd_ctl_register_ioctl(snd_rawmidi_control_ioctl);
1673        snd_ctl_register_ioctl_compat(snd_rawmidi_control_ioctl);
1674#ifdef CONFIG_SND_OSSEMUL
1675        { int i;
1676        /* check device map table */
1677        for (i = 0; i < SNDRV_CARDS; i++) {
1678                if (midi_map[i] < 0 || midi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
1679                        snd_printk(KERN_ERR "invalid midi_map[%d] = %d\n", i, midi_map[i]);
1680                        midi_map[i] = 0;
1681                }
1682                if (amidi_map[i] < 0 || amidi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
1683                        snd_printk(KERN_ERR "invalid amidi_map[%d] = %d\n", i, amidi_map[i]);
1684                        amidi_map[i] = 1;
1685                }
1686        }
1687        }
1688#endif /* CONFIG_SND_OSSEMUL */
1689        return 0;
1690}
1691
1692static void __exit alsa_rawmidi_exit(void)
1693{
1694        snd_ctl_unregister_ioctl(snd_rawmidi_control_ioctl);
1695        snd_ctl_unregister_ioctl_compat(snd_rawmidi_control_ioctl);
1696}
1697
1698module_init(alsa_rawmidi_init)
1699module_exit(alsa_rawmidi_exit)
1700
1701EXPORT_SYMBOL(snd_rawmidi_output_params);
1702EXPORT_SYMBOL(snd_rawmidi_input_params);
1703EXPORT_SYMBOL(snd_rawmidi_drop_output);
1704EXPORT_SYMBOL(snd_rawmidi_drain_output);
1705EXPORT_SYMBOL(snd_rawmidi_drain_input);
1706EXPORT_SYMBOL(snd_rawmidi_receive);
1707EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
1708EXPORT_SYMBOL(snd_rawmidi_transmit_peek);
1709EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
1710EXPORT_SYMBOL(snd_rawmidi_transmit);
1711EXPORT_SYMBOL(snd_rawmidi_new);
1712EXPORT_SYMBOL(snd_rawmidi_set_ops);
1713EXPORT_SYMBOL(snd_rawmidi_info_select);
1714EXPORT_SYMBOL(snd_rawmidi_kernel_open);
1715EXPORT_SYMBOL(snd_rawmidi_kernel_release);
1716EXPORT_SYMBOL(snd_rawmidi_kernel_read);
1717EXPORT_SYMBOL(snd_rawmidi_kernel_write);
1718