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