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 = kzalloc(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, 988 (unsigned char __force *)buf, 989 count, 0); 990 if (count1 < 0) 991 return result > 0 ? result : count1; 992 result += count1; 993 buf += count1; 994 count -= count1; 995 } 996 return result; 997 } 998 999 /** 1000 * snd_rawmidi_transmit_empty - check whether the output buffer is empty 1001 * @substream: the rawmidi substream 1002 * 1003 * Returns 1 if the internal output buffer is empty, 0 if not. 1004 */ 1005 int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream) 1006 { 1007 snd_rawmidi_runtime_t *runtime = substream->runtime; 1008 int result; 1009 unsigned long flags; 1010 1011 if (runtime->buffer == NULL) { 1012 snd_printd("snd_rawmidi_transmit_empty: output is not active!!!\n"); 1013 return 1; 1014 } 1015 spin_lock_irqsave(&runtime->lock, flags); 1016 result = runtime->avail >= runtime->buffer_size; 1017 spin_unlock_irqrestore(&runtime->lock, flags); 1018 return result; 1019 } 1020 1021 /** 1022 * snd_rawmidi_transmit_peek - copy data from the internal buffer 1023 * @substream: the rawmidi substream 1024 * @buffer: the buffer pointer 1025 * @count: data size to transfer 1026 * 1027 * Copies data from the internal output buffer to the given buffer. 1028 * 1029 * Call this in the interrupt handler when the midi output is ready, 1030 * and call snd_rawmidi_transmit_ack() after the transmission is 1031 * finished. 1032 * 1033 * Returns the size of copied data, or a negative error code on failure. 1034 */ 1035 int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count) 1036 { 1037 unsigned long flags; 1038 int result, count1; 1039 snd_rawmidi_runtime_t *runtime = substream->runtime; 1040 1041 if (runtime->buffer == NULL) { 1042 snd_printd("snd_rawmidi_transmit_peek: output is not active!!!\n"); 1043 return -EINVAL; 1044 } 1045 result = 0; 1046 spin_lock_irqsave(&runtime->lock, flags); 1047 if (runtime->avail >= runtime->buffer_size) { 1048 /* warning: lowlevel layer MUST trigger down the hardware */ 1049 goto __skip; 1050 } 1051 if (count == 1) { /* special case, faster code */ 1052 *buffer = runtime->buffer[runtime->hw_ptr]; 1053 result++; 1054 } else { 1055 count1 = runtime->buffer_size - runtime->hw_ptr; 1056 if (count1 > count) 1057 count1 = count; 1058 if (count1 > (int)(runtime->buffer_size - runtime->avail)) 1059 count1 = runtime->buffer_size - runtime->avail; 1060 memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1); 1061 count -= count1; 1062 result += count1; 1063 if (count > 0) { 1064 if (count > (int)(runtime->buffer_size - runtime->avail - count1)) 1065 count = runtime->buffer_size - runtime->avail - count1; 1066 memcpy(buffer + count1, runtime->buffer, count); 1067 result += count; 1068 } 1069 } 1070 __skip: 1071 spin_unlock_irqrestore(&runtime->lock, flags); 1072 return result; 1073 } 1074 1075 /** 1076 * snd_rawmidi_transmit_ack - acknowledge the transmission 1077 * @substream: the rawmidi substream 1078 * @count: the tranferred count 1079 * 1080 * Advances the hardware pointer for the internal output buffer with 1081 * the given size and updates the condition. 1082 * Call after the transmission is finished. 1083 * 1084 * Returns the advanced size if successful, or a negative error code on failure. 1085 */ 1086 int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count) 1087 { 1088 unsigned long flags; 1089 snd_rawmidi_runtime_t *runtime = substream->runtime; 1090 1091 if (runtime->buffer == NULL) { 1092 snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n"); 1093 return -EINVAL; 1094 } 1095 spin_lock_irqsave(&runtime->lock, flags); 1096 snd_assert(runtime->avail + count <= runtime->buffer_size, ); 1097 runtime->hw_ptr += count; 1098 runtime->hw_ptr %= runtime->buffer_size; 1099 runtime->avail += count; 1100 substream->bytes += count; 1101 if (count > 0) { 1102 if (runtime->drain || snd_rawmidi_ready(substream)) 1103 wake_up(&runtime->sleep); 1104 } 1105 spin_unlock_irqrestore(&runtime->lock, flags); 1106 return count; 1107 } 1108 1109 /** 1110 * snd_rawmidi_transmit - copy from the buffer to the device 1111 * @substream: the rawmidi substream 1112 * @buffer: the buffer pointer 1113 * @count: the data size to transfer 1114 * 1115 * Copies data from the buffer to the device and advances the pointer. 1116 * 1117 * Returns the copied size if successful, or a negative error code on failure. 1118 */ 1119 int snd_rawmidi_transmit(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count) 1120 { 1121 count = snd_rawmidi_transmit_peek(substream, buffer, count); 1122 if (count < 0) 1123 return count; 1124 return snd_rawmidi_transmit_ack(substream, count); 1125 } 1126 1127 static long snd_rawmidi_kernel_write1(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count, int kernel) 1128 { 1129 unsigned long flags; 1130 long count1, result; 1131 snd_rawmidi_runtime_t *runtime = substream->runtime; 1132 1133 snd_assert(buf != NULL, return -EINVAL); 1134 snd_assert(runtime->buffer != NULL, return -EINVAL); 1135 1136 result = 0; 1137 spin_lock_irqsave(&runtime->lock, flags); 1138 if (substream->append) { 1139 if ((long)runtime->avail < count) { 1140 spin_unlock_irqrestore(&runtime->lock, flags); 1141 return -EAGAIN; 1142 } 1143 } 1144 while (count > 0 && runtime->avail > 0) { 1145 count1 = runtime->buffer_size - runtime->appl_ptr; 1146 if (count1 > count) 1147 count1 = count; 1148 if (count1 > (long)runtime->avail) 1149 count1 = runtime->avail; 1150 if (kernel) { 1151 memcpy(runtime->buffer + runtime->appl_ptr, buf, count1); 1152 } else { 1153 spin_unlock_irqrestore(&runtime->lock, flags); 1154 if (copy_from_user(runtime->buffer + runtime->appl_ptr, 1155 (char __user *)buf, count1)) { 1156 spin_lock_irqsave(&runtime->lock, flags); 1157 result = result > 0 ? result : -EFAULT; 1158 goto __end; 1159 } 1160 spin_lock_irqsave(&runtime->lock, flags); 1161 } 1162 runtime->appl_ptr += count1; 1163 runtime->appl_ptr %= runtime->buffer_size; 1164 runtime->avail -= count1; 1165 result += count1; 1166 buf += count1; 1167 count -= count1; 1168 } 1169 __end: 1170 count1 = runtime->avail < runtime->buffer_size; 1171 spin_unlock_irqrestore(&runtime->lock, flags); 1172 if (count1) 1173 snd_rawmidi_output_trigger(substream, 1); 1174 return result; 1175 } 1176 1177 long snd_rawmidi_kernel_write(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count) 1178 { 1179 return snd_rawmidi_kernel_write1(substream, buf, count, 1); 1180 } 1181 1182 static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) 1183 { 1184 long result, timeout; 1185 int count1; 1186 snd_rawmidi_file_t *rfile; 1187 snd_rawmidi_runtime_t *runtime; 1188 snd_rawmidi_substream_t *substream; 1189 1190 rfile = file->private_data; 1191 substream = rfile->output; 1192 runtime = substream->runtime; 1193 /* we cannot put an atomic message to our buffer */ 1194 if (substream->append && count > runtime->buffer_size) 1195 return -EIO; 1196 result = 0; 1197 while (count > 0) { 1198 spin_lock_irq(&runtime->lock); 1199 while (!snd_rawmidi_ready_append(substream, count)) { 1200 wait_queue_t wait; 1201 if (file->f_flags & O_NONBLOCK) { 1202 spin_unlock_irq(&runtime->lock); 1203 return result > 0 ? result : -EAGAIN; 1204 } 1205 init_waitqueue_entry(&wait, current); 1206 add_wait_queue(&runtime->sleep, &wait); 1207 set_current_state(TASK_INTERRUPTIBLE); 1208 spin_unlock_irq(&runtime->lock); 1209 timeout = schedule_timeout(30 * HZ); 1210 remove_wait_queue(&runtime->sleep, &wait); 1211 if (signal_pending(current)) 1212 return result > 0 ? result : -ERESTARTSYS; 1213 if (!runtime->avail && !timeout) 1214 return result > 0 ? result : -EIO; 1215 spin_lock_irq(&runtime->lock); 1216 } 1217 spin_unlock_irq(&runtime->lock); 1218 count1 = snd_rawmidi_kernel_write1(substream, 1219 (unsigned char __force *)buf, 1220 count, 0); 1221 if (count1 < 0) 1222 return result > 0 ? result : count1; 1223 result += count1; 1224 buf += count1; 1225 if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK)) 1226 break; 1227 count -= count1; 1228 } 1229 if (file->f_flags & O_SYNC) { 1230 spin_lock_irq(&runtime->lock); 1231 while (runtime->avail != runtime->buffer_size) { 1232 wait_queue_t wait; 1233 unsigned int last_avail = runtime->avail; 1234 init_waitqueue_entry(&wait, current); 1235 add_wait_queue(&runtime->sleep, &wait); 1236 set_current_state(TASK_INTERRUPTIBLE); 1237 spin_unlock_irq(&runtime->lock); 1238 timeout = schedule_timeout(30 * HZ); 1239 remove_wait_queue(&runtime->sleep, &wait); 1240 if (signal_pending(current)) 1241 return result > 0 ? result : -ERESTARTSYS; 1242 if (runtime->avail == last_avail && !timeout) 1243 return result > 0 ? result : -EIO; 1244 spin_lock_irq(&runtime->lock); 1245 } 1246 spin_unlock_irq(&runtime->lock); 1247 } 1248 return result; 1249 } 1250 1251 static unsigned int snd_rawmidi_poll(struct file *file, poll_table * wait) 1252 { 1253 snd_rawmidi_file_t *rfile; 1254 snd_rawmidi_runtime_t *runtime; 1255 unsigned int mask; 1256 1257 rfile = file->private_data; 1258 if (rfile->input != NULL) { 1259 runtime = rfile->input->runtime; 1260 snd_rawmidi_input_trigger(rfile->input, 1); 1261 poll_wait(file, &runtime->sleep, wait); 1262 } 1263 if (rfile->output != NULL) { 1264 runtime = rfile->output->runtime; 1265 poll_wait(file, &runtime->sleep, wait); 1266 } 1267 mask = 0; 1268 if (rfile->input != NULL) { 1269 if (snd_rawmidi_ready(rfile->input)) 1270 mask |= POLLIN | POLLRDNORM; 1271 } 1272 if (rfile->output != NULL) { 1273 if (snd_rawmidi_ready(rfile->output)) 1274 mask |= POLLOUT | POLLWRNORM; 1275 } 1276 return mask; 1277 } 1278 1279 /* 1280 */ 1281 #ifdef CONFIG_COMPAT 1282 #include "rawmidi_compat.c" 1283 #else 1284 #define snd_rawmidi_ioctl_compat NULL 1285 #endif 1286 1287 /* 1288 1289 */ 1290 1291 static void snd_rawmidi_proc_info_read(snd_info_entry_t *entry, 1292 snd_info_buffer_t * buffer) 1293 { 1294 snd_rawmidi_t *rmidi; 1295 snd_rawmidi_substream_t *substream; 1296 snd_rawmidi_runtime_t *runtime; 1297 struct list_head *list; 1298 1299 rmidi = entry->private_data; 1300 snd_iprintf(buffer, "%s\n\n", rmidi->name); 1301 down(&rmidi->open_mutex); 1302 if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { 1303 list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { 1304 substream = list_entry(list, snd_rawmidi_substream_t, list); 1305 snd_iprintf(buffer, 1306 "Output %d\n" 1307 " Tx bytes : %lu\n", 1308 substream->number, 1309 (unsigned long) substream->bytes); 1310 if (substream->opened) { 1311 runtime = substream->runtime; 1312 snd_iprintf(buffer, 1313 " Mode : %s\n" 1314 " Buffer size : %lu\n" 1315 " Avail : %lu\n", 1316 runtime->oss ? "OSS compatible" : "native", 1317 (unsigned long) runtime->buffer_size, 1318 (unsigned long) runtime->avail); 1319 } 1320 } 1321 } 1322 if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) { 1323 list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { 1324 substream = list_entry(list, snd_rawmidi_substream_t, list); 1325 snd_iprintf(buffer, 1326 "Input %d\n" 1327 " Rx bytes : %lu\n", 1328 substream->number, 1329 (unsigned long) substream->bytes); 1330 if (substream->opened) { 1331 runtime = substream->runtime; 1332 snd_iprintf(buffer, 1333 " Buffer size : %lu\n" 1334 " Avail : %lu\n" 1335 " Overruns : %lu\n", 1336 (unsigned long) runtime->buffer_size, 1337 (unsigned long) runtime->avail, 1338 (unsigned long) runtime->xruns); 1339 } 1340 } 1341 } 1342 up(&rmidi->open_mutex); 1343 } 1344 1345 /* 1346 * Register functions 1347 */ 1348 1349 static struct file_operations snd_rawmidi_f_ops = 1350 { 1351 .owner = THIS_MODULE, 1352 .read = snd_rawmidi_read, 1353 .write = snd_rawmidi_write, 1354 .open = snd_rawmidi_open, 1355 .release = snd_rawmidi_release, 1356 .poll = snd_rawmidi_poll, 1357 .unlocked_ioctl = snd_rawmidi_ioctl, 1358 .compat_ioctl = snd_rawmidi_ioctl_compat, 1359 }; 1360 1361 static snd_minor_t snd_rawmidi_reg = 1362 { 1363 .comment = "raw midi", 1364 .f_ops = &snd_rawmidi_f_ops, 1365 }; 1366 1367 static int snd_rawmidi_alloc_substreams(snd_rawmidi_t *rmidi, 1368 snd_rawmidi_str_t *stream, 1369 int direction, 1370 int count) 1371 { 1372 snd_rawmidi_substream_t *substream; 1373 int idx; 1374 1375 INIT_LIST_HEAD(&stream->substreams); 1376 for (idx = 0; idx < count; idx++) { 1377 substream = kzalloc(sizeof(*substream), GFP_KERNEL); 1378 if (substream == NULL) 1379 return -ENOMEM; 1380 substream->stream = direction; 1381 substream->number = idx; 1382 substream->rmidi = rmidi; 1383 substream->pstr = stream; 1384 list_add_tail(&substream->list, &stream->substreams); 1385 stream->substream_count++; 1386 } 1387 return 0; 1388 } 1389 1390 /** 1391 * snd_rawmidi_new - create a rawmidi instance 1392 * @card: the card instance 1393 * @id: the id string 1394 * @device: the device index 1395 * @output_count: the number of output streams 1396 * @input_count: the number of input streams 1397 * @rrawmidi: the pointer to store the new rawmidi instance 1398 * 1399 * Creates a new rawmidi instance. 1400 * Use snd_rawmidi_set_ops() to set the operators to the new instance. 1401 * 1402 * Returns zero if successful, or a negative error code on failure. 1403 */ 1404 int snd_rawmidi_new(snd_card_t * card, char *id, int device, 1405 int output_count, int input_count, 1406 snd_rawmidi_t ** rrawmidi) 1407 { 1408 snd_rawmidi_t *rmidi; 1409 int err; 1410 static snd_device_ops_t ops = { 1411 .dev_free = snd_rawmidi_dev_free, 1412 .dev_register = snd_rawmidi_dev_register, 1413 .dev_disconnect = snd_rawmidi_dev_disconnect, 1414 .dev_unregister = snd_rawmidi_dev_unregister 1415 }; 1416 1417 snd_assert(rrawmidi != NULL, return -EINVAL); 1418 *rrawmidi = NULL; 1419 snd_assert(card != NULL, return -ENXIO); 1420 rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL); 1421 if (rmidi == NULL) 1422 return -ENOMEM; 1423 rmidi->card = card; 1424 rmidi->device = device; 1425 init_MUTEX(&rmidi->open_mutex); 1426 init_waitqueue_head(&rmidi->open_wait); 1427 if (id != NULL) 1428 strlcpy(rmidi->id, id, sizeof(rmidi->id)); 1429 if ((err = snd_rawmidi_alloc_substreams(rmidi, &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT], SNDRV_RAWMIDI_STREAM_INPUT, input_count)) < 0) { 1430 snd_rawmidi_free(rmidi); 1431 return err; 1432 } 1433 if ((err = snd_rawmidi_alloc_substreams(rmidi, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT], SNDRV_RAWMIDI_STREAM_OUTPUT, output_count)) < 0) { 1434 snd_rawmidi_free(rmidi); 1435 return err; 1436 } 1437 if ((err = snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)) < 0) { 1438 snd_rawmidi_free(rmidi); 1439 return err; 1440 } 1441 *rrawmidi = rmidi; 1442 return 0; 1443 } 1444 1445 static void snd_rawmidi_free_substreams(snd_rawmidi_str_t *stream) 1446 { 1447 snd_rawmidi_substream_t *substream; 1448 1449 while (!list_empty(&stream->substreams)) { 1450 substream = list_entry(stream->substreams.next, snd_rawmidi_substream_t, list); 1451 list_del(&substream->list); 1452 kfree(substream); 1453 } 1454 } 1455 1456 static int snd_rawmidi_free(snd_rawmidi_t *rmidi) 1457 { 1458 snd_assert(rmidi != NULL, return -ENXIO); 1459 snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); 1460 snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); 1461 if (rmidi->private_free) 1462 rmidi->private_free(rmidi); 1463 kfree(rmidi); 1464 return 0; 1465 } 1466 1467 static int snd_rawmidi_dev_free(snd_device_t *device) 1468 { 1469 snd_rawmidi_t *rmidi = device->device_data; 1470 return snd_rawmidi_free(rmidi); 1471 } 1472 1473 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) 1474 static void snd_rawmidi_dev_seq_free(snd_seq_device_t *device) 1475 { 1476 snd_rawmidi_t *rmidi = device->private_data; 1477 rmidi->seq_dev = NULL; 1478 } 1479 #endif 1480 1481 static int snd_rawmidi_dev_register(snd_device_t *device) 1482 { 1483 int idx, err; 1484 snd_info_entry_t *entry; 1485 char name[16]; 1486 snd_rawmidi_t *rmidi = device->device_data; 1487 1488 if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) 1489 return -ENOMEM; 1490 down(®ister_mutex); 1491 idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; 1492 if (snd_rawmidi_devices[idx] != NULL) { 1493 up(®ister_mutex); 1494 return -EBUSY; 1495 } 1496 snd_rawmidi_devices[idx] = rmidi; 1497 sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device); 1498 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI, 1499 rmidi->card, rmidi->device, 1500 &snd_rawmidi_reg, name)) < 0) { 1501 snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); 1502 snd_rawmidi_devices[idx] = NULL; 1503 up(®ister_mutex); 1504 return err; 1505 } 1506 if (rmidi->ops && rmidi->ops->dev_register && 1507 (err = rmidi->ops->dev_register(rmidi)) < 0) { 1508 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); 1509 snd_rawmidi_devices[idx] = NULL; 1510 up(®ister_mutex); 1511 return err; 1512 } 1513 #ifdef CONFIG_SND_OSSEMUL 1514 rmidi->ossreg = 0; 1515 if ((int)rmidi->device == midi_map[rmidi->card->number]) { 1516 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, 1517 rmidi->card, 0, &snd_rawmidi_reg, name) < 0) { 1518 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0); 1519 } else { 1520 rmidi->ossreg++; 1521 #ifdef SNDRV_OSS_INFO_DEV_MIDI 1522 snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number, rmidi->name); 1523 #endif 1524 } 1525 } 1526 if ((int)rmidi->device == amidi_map[rmidi->card->number]) { 1527 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, 1528 rmidi->card, 1, &snd_rawmidi_reg, name) < 0) { 1529 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1); 1530 } else { 1531 rmidi->ossreg++; 1532 } 1533 } 1534 #endif /* CONFIG_SND_OSSEMUL */ 1535 up(®ister_mutex); 1536 sprintf(name, "midi%d", rmidi->device); 1537 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); 1538 if (entry) { 1539 entry->private_data = rmidi; 1540 entry->c.text.read_size = 1024; 1541 entry->c.text.read = snd_rawmidi_proc_info_read; 1542 if (snd_info_register(entry) < 0) { 1543 snd_info_free_entry(entry); 1544 entry = NULL; 1545 } 1546 } 1547 rmidi->proc_entry = entry; 1548 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) 1549 if (!rmidi->ops || !rmidi->ops->dev_register) { /* own registration mechanism */ 1550 if (snd_seq_device_new(rmidi->card, rmidi->device, SNDRV_SEQ_DEV_ID_MIDISYNTH, 0, &rmidi->seq_dev) >= 0) { 1551 rmidi->seq_dev->private_data = rmidi; 1552 rmidi->seq_dev->private_free = snd_rawmidi_dev_seq_free; 1553 sprintf(rmidi->seq_dev->name, "MIDI %d-%d", rmidi->card->number, rmidi->device); 1554 snd_device_register(rmidi->card, rmidi->seq_dev); 1555 } 1556 } 1557 #endif 1558 return 0; 1559 } 1560 1561 static int snd_rawmidi_dev_disconnect(snd_device_t *device) 1562 { 1563 snd_rawmidi_t *rmidi = device->device_data; 1564 int idx; 1565 1566 down(®ister_mutex); 1567 idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; 1568 snd_rawmidi_devices[idx] = NULL; 1569 up(®ister_mutex); 1570 return 0; 1571 } 1572 1573 static int snd_rawmidi_dev_unregister(snd_device_t *device) 1574 { 1575 int idx; 1576 snd_rawmidi_t *rmidi = device->device_data; 1577 1578 snd_assert(rmidi != NULL, return -ENXIO); 1579 down(®ister_mutex); 1580 idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; 1581 snd_rawmidi_devices[idx] = NULL; 1582 if (rmidi->proc_entry) { 1583 snd_info_unregister(rmidi->proc_entry); 1584 rmidi->proc_entry = NULL; 1585 } 1586 #ifdef CONFIG_SND_OSSEMUL 1587 if (rmidi->ossreg) { 1588 if ((int)rmidi->device == midi_map[rmidi->card->number]) { 1589 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0); 1590 #ifdef SNDRV_OSS_INFO_DEV_MIDI 1591 snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number); 1592 #endif 1593 } 1594 if ((int)rmidi->device == amidi_map[rmidi->card->number]) 1595 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1); 1596 rmidi->ossreg = 0; 1597 } 1598 #endif /* CONFIG_SND_OSSEMUL */ 1599 if (rmidi->ops && rmidi->ops->dev_unregister) 1600 rmidi->ops->dev_unregister(rmidi); 1601 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); 1602 up(®ister_mutex); 1603 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) 1604 if (rmidi->seq_dev) { 1605 snd_device_free(rmidi->card, rmidi->seq_dev); 1606 rmidi->seq_dev = NULL; 1607 } 1608 #endif 1609 return snd_rawmidi_free(rmidi); 1610 } 1611 1612 /** 1613 * snd_rawmidi_set_ops - set the rawmidi operators 1614 * @rmidi: the rawmidi instance 1615 * @stream: the stream direction, SNDRV_RAWMIDI_STREAM_XXX 1616 * @ops: the operator table 1617 * 1618 * Sets the rawmidi operators for the given stream direction. 1619 */ 1620 void snd_rawmidi_set_ops(snd_rawmidi_t *rmidi, int stream, snd_rawmidi_ops_t *ops) 1621 { 1622 struct list_head *list; 1623 snd_rawmidi_substream_t *substream; 1624 1625 list_for_each(list, &rmidi->streams[stream].substreams) { 1626 substream = list_entry(list, snd_rawmidi_substream_t, list); 1627 substream->ops = ops; 1628 } 1629 } 1630 1631 /* 1632 * ENTRY functions 1633 */ 1634 1635 static int __init alsa_rawmidi_init(void) 1636 { 1637 1638 snd_ctl_register_ioctl(snd_rawmidi_control_ioctl); 1639 snd_ctl_register_ioctl_compat(snd_rawmidi_control_ioctl); 1640 #ifdef CONFIG_SND_OSSEMUL 1641 { int i; 1642 /* check device map table */ 1643 for (i = 0; i < SNDRV_CARDS; i++) { 1644 if (midi_map[i] < 0 || midi_map[i] >= SNDRV_RAWMIDI_DEVICES) { 1645 snd_printk(KERN_ERR "invalid midi_map[%d] = %d\n", i, midi_map[i]); 1646 midi_map[i] = 0; 1647 } 1648 if (amidi_map[i] < 0 || amidi_map[i] >= SNDRV_RAWMIDI_DEVICES) { 1649 snd_printk(KERN_ERR "invalid amidi_map[%d] = %d\n", i, amidi_map[i]); 1650 amidi_map[i] = 1; 1651 } 1652 } 1653 } 1654 #endif /* CONFIG_SND_OSSEMUL */ 1655 return 0; 1656 } 1657 1658 static void __exit alsa_rawmidi_exit(void) 1659 { 1660 snd_ctl_unregister_ioctl(snd_rawmidi_control_ioctl); 1661 snd_ctl_unregister_ioctl_compat(snd_rawmidi_control_ioctl); 1662 } 1663 1664 module_init(alsa_rawmidi_init) 1665 module_exit(alsa_rawmidi_exit) 1666 1667 EXPORT_SYMBOL(snd_rawmidi_output_params); 1668 EXPORT_SYMBOL(snd_rawmidi_input_params); 1669 EXPORT_SYMBOL(snd_rawmidi_drop_output); 1670 EXPORT_SYMBOL(snd_rawmidi_drain_output); 1671 EXPORT_SYMBOL(snd_rawmidi_drain_input); 1672 EXPORT_SYMBOL(snd_rawmidi_receive); 1673 EXPORT_SYMBOL(snd_rawmidi_transmit_empty); 1674 EXPORT_SYMBOL(snd_rawmidi_transmit_peek); 1675 EXPORT_SYMBOL(snd_rawmidi_transmit_ack); 1676 EXPORT_SYMBOL(snd_rawmidi_transmit); 1677 EXPORT_SYMBOL(snd_rawmidi_new); 1678 EXPORT_SYMBOL(snd_rawmidi_set_ops); 1679 EXPORT_SYMBOL(snd_rawmidi_info); 1680 EXPORT_SYMBOL(snd_rawmidi_info_select); 1681 EXPORT_SYMBOL(snd_rawmidi_kernel_open); 1682 EXPORT_SYMBOL(snd_rawmidi_kernel_release); 1683 EXPORT_SYMBOL(snd_rawmidi_kernel_read); 1684 EXPORT_SYMBOL(snd_rawmidi_kernel_write); 1685