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