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 if (maj == snd_major) { 382 cardnum = SNDRV_MINOR_CARD(iminor(inode)); 383 cardnum %= SNDRV_CARDS; 384 device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI; 385 device %= SNDRV_MINOR_RAWMIDIS; 386 #ifdef CONFIG_SND_OSSEMUL 387 } else if (maj == SOUND_MAJOR) { 388 cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); 389 cardnum %= SNDRV_CARDS; 390 device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ? 391 midi_map[cardnum] : amidi_map[cardnum]; 392 #endif 393 } else 394 return -ENXIO; 395 396 rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device]; 397 if (rmidi == NULL) 398 return -ENODEV; 399 #ifdef CONFIG_SND_OSSEMUL 400 if (maj == SOUND_MAJOR && !rmidi->ossreg) 401 return -ENXIO; 402 #endif 403 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 404 return -EINVAL; /* invalid combination */ 405 card = rmidi->card; 406 err = snd_card_file_add(card, file); 407 if (err < 0) 408 return -ENODEV; 409 fflags = snd_rawmidi_file_flags(file); 410 if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */ 411 fflags |= SNDRV_RAWMIDI_LFLG_APPEND; 412 fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK; 413 rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL); 414 if (rawmidi_file == NULL) { 415 snd_card_file_remove(card, file); 416 return -ENOMEM; 417 } 418 init_waitqueue_entry(&wait, current); 419 add_wait_queue(&rmidi->open_wait, &wait); 420 down(&rmidi->open_mutex); 421 while (1) { 422 subdevice = -1; 423 down_read(&card->controls_rwsem); 424 list_for_each(list, &card->ctl_files) { 425 kctl = snd_ctl_file(list); 426 if (kctl->pid == current->pid) { 427 subdevice = kctl->prefer_rawmidi_subdevice; 428 break; 429 } 430 } 431 up_read(&card->controls_rwsem); 432 err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file); 433 if (err >= 0) 434 break; 435 if (err == -EAGAIN) { 436 if (file->f_flags & O_NONBLOCK) { 437 err = -EBUSY; 438 break; 439 } 440 } else 441 break; 442 set_current_state(TASK_INTERRUPTIBLE); 443 up(&rmidi->open_mutex); 444 schedule(); 445 down(&rmidi->open_mutex); 446 if (signal_pending(current)) { 447 err = -ERESTARTSYS; 448 break; 449 } 450 } 451 #ifdef CONFIG_SND_OSSEMUL 452 if (rawmidi_file->input && rawmidi_file->input->runtime) 453 rawmidi_file->input->runtime->oss = (maj == SOUND_MAJOR); 454 if (rawmidi_file->output && rawmidi_file->output->runtime) 455 rawmidi_file->output->runtime->oss = (maj == SOUND_MAJOR); 456 #endif 457 remove_wait_queue(&rmidi->open_wait, &wait); 458 if (err >= 0) { 459 file->private_data = rawmidi_file; 460 } else { 461 snd_card_file_remove(card, file); 462 kfree(rawmidi_file); 463 } 464 up(&rmidi->open_mutex); 465 return err; 466 } 467 468 int snd_rawmidi_kernel_release(snd_rawmidi_file_t * rfile) 469 { 470 snd_rawmidi_t *rmidi; 471 snd_rawmidi_substream_t *substream; 472 snd_rawmidi_runtime_t *runtime; 473 474 snd_assert(rfile != NULL, return -ENXIO); 475 snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); 476 rmidi = rfile->rmidi; 477 down(&rmidi->open_mutex); 478 if (rfile->input != NULL) { 479 substream = rfile->input; 480 rfile->input = NULL; 481 runtime = substream->runtime; 482 snd_rawmidi_input_trigger(substream, 0); 483 substream->ops->close(substream); 484 if (runtime->private_free != NULL) 485 runtime->private_free(substream); 486 snd_rawmidi_runtime_free(substream); 487 substream->opened = 0; 488 rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_opened--; 489 } 490 if (rfile->output != NULL) { 491 substream = rfile->output; 492 rfile->output = NULL; 493 if (--substream->use_count == 0) { 494 runtime = substream->runtime; 495 if (substream->active_sensing) { 496 unsigned char buf = 0xfe; 497 /* sending single active sensing message to shut the device up */ 498 snd_rawmidi_kernel_write(substream, &buf, 1); 499 } 500 if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS) 501 snd_rawmidi_output_trigger(substream, 0); 502 substream->ops->close(substream); 503 if (runtime->private_free != NULL) 504 runtime->private_free(substream); 505 snd_rawmidi_runtime_free(substream); 506 substream->opened = 0; 507 substream->append = 0; 508 } 509 rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; 510 } 511 up(&rmidi->open_mutex); 512 module_put(rmidi->card->module); 513 return 0; 514 } 515 516 static int snd_rawmidi_release(struct inode *inode, struct file *file) 517 { 518 snd_rawmidi_file_t *rfile; 519 snd_rawmidi_t *rmidi; 520 int err; 521 522 rfile = file->private_data; 523 err = snd_rawmidi_kernel_release(rfile); 524 rmidi = rfile->rmidi; 525 wake_up(&rmidi->open_wait); 526 kfree(rfile); 527 snd_card_file_remove(rmidi->card, file); 528 return err; 529 } 530 531 int snd_rawmidi_info(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t *info) 532 { 533 snd_rawmidi_t *rmidi; 534 535 if (substream == NULL) 536 return -ENODEV; 537 rmidi = substream->rmidi; 538 memset(info, 0, sizeof(*info)); 539 info->card = rmidi->card->number; 540 info->device = rmidi->device; 541 info->subdevice = substream->number; 542 info->stream = substream->stream; 543 info->flags = rmidi->info_flags; 544 strcpy(info->id, rmidi->id); 545 strcpy(info->name, rmidi->name); 546 strcpy(info->subname, substream->name); 547 info->subdevices_count = substream->pstr->substream_count; 548 info->subdevices_avail = (substream->pstr->substream_count - 549 substream->pstr->substream_opened); 550 return 0; 551 } 552 553 static int snd_rawmidi_info_user(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t __user * _info) 554 { 555 snd_rawmidi_info_t info; 556 int err; 557 if ((err = snd_rawmidi_info(substream, &info)) < 0) 558 return err; 559 if (copy_to_user(_info, &info, sizeof(snd_rawmidi_info_t))) 560 return -EFAULT; 561 return 0; 562 } 563 564 int snd_rawmidi_info_select(snd_card_t *card, snd_rawmidi_info_t *info) 565 { 566 snd_rawmidi_t *rmidi; 567 snd_rawmidi_str_t *pstr; 568 snd_rawmidi_substream_t *substream; 569 struct list_head *list; 570 if (info->device >= SNDRV_RAWMIDI_DEVICES) 571 return -ENXIO; 572 rmidi = snd_rawmidi_devices[card->number * SNDRV_RAWMIDI_DEVICES + info->device]; 573 if (info->stream < 0 || info->stream > 1) 574 return -EINVAL; 575 pstr = &rmidi->streams[info->stream]; 576 if (pstr->substream_count == 0) 577 return -ENOENT; 578 if (info->subdevice >= pstr->substream_count) 579 return -ENXIO; 580 list_for_each(list, &pstr->substreams) { 581 substream = list_entry(list, snd_rawmidi_substream_t, list); 582 if ((unsigned int)substream->number == info->subdevice) 583 return snd_rawmidi_info(substream, info); 584 } 585 return -ENXIO; 586 } 587 588 static int snd_rawmidi_info_select_user(snd_card_t *card, 589 snd_rawmidi_info_t __user *_info) 590 { 591 int err; 592 snd_rawmidi_info_t info; 593 if (get_user(info.device, &_info->device)) 594 return -EFAULT; 595 if (get_user(info.stream, &_info->stream)) 596 return -EFAULT; 597 if (get_user(info.subdevice, &_info->subdevice)) 598 return -EFAULT; 599 if ((err = snd_rawmidi_info_select(card, &info)) < 0) 600 return err; 601 if (copy_to_user(_info, &info, sizeof(snd_rawmidi_info_t))) 602 return -EFAULT; 603 return 0; 604 } 605 606 int snd_rawmidi_output_params(snd_rawmidi_substream_t * substream, 607 snd_rawmidi_params_t * params) 608 { 609 char *newbuf; 610 snd_rawmidi_runtime_t *runtime = substream->runtime; 611 612 if (substream->append && substream->use_count > 1) 613 return -EBUSY; 614 snd_rawmidi_drain_output(substream); 615 if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) { 616 return -EINVAL; 617 } 618 if (params->avail_min < 1 || params->avail_min > params->buffer_size) { 619 return -EINVAL; 620 } 621 if (params->buffer_size != runtime->buffer_size) { 622 if ((newbuf = (char *) kmalloc(params->buffer_size, GFP_KERNEL)) == NULL) 623 return -ENOMEM; 624 kfree(runtime->buffer); 625 runtime->buffer = newbuf; 626 runtime->buffer_size = params->buffer_size; 627 } 628 runtime->avail_min = params->avail_min; 629 substream->active_sensing = !params->no_active_sensing; 630 return 0; 631 } 632 633 int snd_rawmidi_input_params(snd_rawmidi_substream_t * substream, 634 snd_rawmidi_params_t * params) 635 { 636 char *newbuf; 637 snd_rawmidi_runtime_t *runtime = substream->runtime; 638 639 snd_rawmidi_drain_input(substream); 640 if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) { 641 return -EINVAL; 642 } 643 if (params->avail_min < 1 || params->avail_min > params->buffer_size) { 644 return -EINVAL; 645 } 646 if (params->buffer_size != runtime->buffer_size) { 647 if ((newbuf = (char *) kmalloc(params->buffer_size, GFP_KERNEL)) == NULL) 648 return -ENOMEM; 649 kfree(runtime->buffer); 650 runtime->buffer = newbuf; 651 runtime->buffer_size = params->buffer_size; 652 } 653 runtime->avail_min = params->avail_min; 654 return 0; 655 } 656 657 static int snd_rawmidi_output_status(snd_rawmidi_substream_t * substream, 658 snd_rawmidi_status_t * status) 659 { 660 snd_rawmidi_runtime_t *runtime = substream->runtime; 661 662 memset(status, 0, sizeof(*status)); 663 status->stream = SNDRV_RAWMIDI_STREAM_OUTPUT; 664 spin_lock_irq(&runtime->lock); 665 status->avail = runtime->avail; 666 spin_unlock_irq(&runtime->lock); 667 return 0; 668 } 669 670 static int snd_rawmidi_input_status(snd_rawmidi_substream_t * substream, 671 snd_rawmidi_status_t * status) 672 { 673 snd_rawmidi_runtime_t *runtime = substream->runtime; 674 675 memset(status, 0, sizeof(*status)); 676 status->stream = SNDRV_RAWMIDI_STREAM_INPUT; 677 spin_lock_irq(&runtime->lock); 678 status->avail = runtime->avail; 679 status->xruns = runtime->xruns; 680 runtime->xruns = 0; 681 spin_unlock_irq(&runtime->lock); 682 return 0; 683 } 684 685 static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 686 { 687 snd_rawmidi_file_t *rfile; 688 void __user *argp = (void __user *)arg; 689 690 rfile = file->private_data; 691 if (((cmd >> 8) & 0xff) != 'W') 692 return -ENOTTY; 693 switch (cmd) { 694 case SNDRV_RAWMIDI_IOCTL_PVERSION: 695 return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0; 696 case SNDRV_RAWMIDI_IOCTL_INFO: 697 { 698 snd_rawmidi_stream_t stream; 699 snd_rawmidi_info_t __user *info = argp; 700 if (get_user(stream, &info->stream)) 701 return -EFAULT; 702 switch (stream) { 703 case SNDRV_RAWMIDI_STREAM_INPUT: 704 return snd_rawmidi_info_user(rfile->input, info); 705 case SNDRV_RAWMIDI_STREAM_OUTPUT: 706 return snd_rawmidi_info_user(rfile->output, info); 707 default: 708 return -EINVAL; 709 } 710 } 711 case SNDRV_RAWMIDI_IOCTL_PARAMS: 712 { 713 snd_rawmidi_params_t params; 714 if (copy_from_user(¶ms, argp, sizeof(snd_rawmidi_params_t))) 715 return -EFAULT; 716 switch (params.stream) { 717 case SNDRV_RAWMIDI_STREAM_OUTPUT: 718 if (rfile->output == NULL) 719 return -EINVAL; 720 return snd_rawmidi_output_params(rfile->output, ¶ms); 721 case SNDRV_RAWMIDI_STREAM_INPUT: 722 if (rfile->input == NULL) 723 return -EINVAL; 724 return snd_rawmidi_input_params(rfile->input, ¶ms); 725 default: 726 return -EINVAL; 727 } 728 } 729 case SNDRV_RAWMIDI_IOCTL_STATUS: 730 { 731 int err = 0; 732 snd_rawmidi_status_t status; 733 if (copy_from_user(&status, argp, sizeof(snd_rawmidi_status_t))) 734 return -EFAULT; 735 switch (status.stream) { 736 case SNDRV_RAWMIDI_STREAM_OUTPUT: 737 if (rfile->output == NULL) 738 return -EINVAL; 739 err = snd_rawmidi_output_status(rfile->output, &status); 740 break; 741 case SNDRV_RAWMIDI_STREAM_INPUT: 742 if (rfile->input == NULL) 743 return -EINVAL; 744 err = snd_rawmidi_input_status(rfile->input, &status); 745 break; 746 default: 747 return -EINVAL; 748 } 749 if (err < 0) 750 return err; 751 if (copy_to_user(argp, &status, sizeof(snd_rawmidi_status_t))) 752 return -EFAULT; 753 return 0; 754 } 755 case SNDRV_RAWMIDI_IOCTL_DROP: 756 { 757 int val; 758 if (get_user(val, (int __user *) argp)) 759 return -EFAULT; 760 switch (val) { 761 case SNDRV_RAWMIDI_STREAM_OUTPUT: 762 if (rfile->output == NULL) 763 return -EINVAL; 764 return snd_rawmidi_drop_output(rfile->output); 765 default: 766 return -EINVAL; 767 } 768 } 769 case SNDRV_RAWMIDI_IOCTL_DRAIN: 770 { 771 int val; 772 if (get_user(val, (int __user *) argp)) 773 return -EFAULT; 774 switch (val) { 775 case SNDRV_RAWMIDI_STREAM_OUTPUT: 776 if (rfile->output == NULL) 777 return -EINVAL; 778 return snd_rawmidi_drain_output(rfile->output); 779 case SNDRV_RAWMIDI_STREAM_INPUT: 780 if (rfile->input == NULL) 781 return -EINVAL; 782 return snd_rawmidi_drain_input(rfile->input); 783 default: 784 return -EINVAL; 785 } 786 } 787 #ifdef CONFIG_SND_DEBUG 788 default: 789 snd_printk(KERN_WARNING "rawmidi: unknown command = 0x%x\n", cmd); 790 #endif 791 } 792 return -ENOTTY; 793 } 794 795 static int snd_rawmidi_control_ioctl(snd_card_t * card, 796 snd_ctl_file_t * control, 797 unsigned int cmd, 798 unsigned long arg) 799 { 800 void __user *argp = (void __user *)arg; 801 unsigned int tmp; 802 803 tmp = card->number * SNDRV_RAWMIDI_DEVICES; 804 switch (cmd) { 805 case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE: 806 { 807 int device; 808 809 if (get_user(device, (int __user *)argp)) 810 return -EFAULT; 811 device = device < 0 ? 0 : device + 1; 812 while (device < SNDRV_RAWMIDI_DEVICES) { 813 if (snd_rawmidi_devices[tmp + device]) 814 break; 815 device++; 816 } 817 if (device == SNDRV_RAWMIDI_DEVICES) 818 device = -1; 819 if (put_user(device, (int __user *)argp)) 820 return -EFAULT; 821 return 0; 822 } 823 case SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE: 824 { 825 int val; 826 827 if (get_user(val, (int __user *)argp)) 828 return -EFAULT; 829 control->prefer_rawmidi_subdevice = val; 830 return 0; 831 } 832 case SNDRV_CTL_IOCTL_RAWMIDI_INFO: 833 return snd_rawmidi_info_select_user(card, argp); 834 } 835 return -ENOIOCTLCMD; 836 } 837 838 /** 839 * snd_rawmidi_receive - receive the input data from the device 840 * @substream: the rawmidi substream 841 * @buffer: the buffer pointer 842 * @count: the data size to read 843 * 844 * Reads the data from the internal buffer. 845 * 846 * Returns the size of read data, or a negative error code on failure. 847 */ 848 int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count) 849 { 850 unsigned long flags; 851 int result = 0, count1; 852 snd_rawmidi_runtime_t *runtime = substream->runtime; 853 854 if (runtime->buffer == NULL) { 855 snd_printd("snd_rawmidi_receive: input is not active!!!\n"); 856 return -EINVAL; 857 } 858 spin_lock_irqsave(&runtime->lock, flags); 859 if (count == 1) { /* special case, faster code */ 860 substream->bytes++; 861 if (runtime->avail < runtime->buffer_size) { 862 runtime->buffer[runtime->hw_ptr++] = buffer[0]; 863 runtime->hw_ptr %= runtime->buffer_size; 864 runtime->avail++; 865 result++; 866 } else { 867 runtime->xruns++; 868 } 869 } else { 870 substream->bytes += count; 871 count1 = runtime->buffer_size - runtime->hw_ptr; 872 if (count1 > count) 873 count1 = count; 874 if (count1 > (int)(runtime->buffer_size - runtime->avail)) 875 count1 = runtime->buffer_size - runtime->avail; 876 memcpy(runtime->buffer + runtime->hw_ptr, buffer, count1); 877 runtime->hw_ptr += count1; 878 runtime->hw_ptr %= runtime->buffer_size; 879 runtime->avail += count1; 880 count -= count1; 881 result += count1; 882 if (count > 0) { 883 buffer += count1; 884 count1 = count; 885 if (count1 > (int)(runtime->buffer_size - runtime->avail)) { 886 count1 = runtime->buffer_size - runtime->avail; 887 runtime->xruns += count - count1; 888 } 889 if (count1 > 0) { 890 memcpy(runtime->buffer, buffer, count1); 891 runtime->hw_ptr = count1; 892 runtime->avail += count1; 893 result += count1; 894 } 895 } 896 } 897 if (result > 0) { 898 if (runtime->event) 899 tasklet_hi_schedule(&runtime->tasklet); 900 else if (snd_rawmidi_ready(substream)) 901 wake_up(&runtime->sleep); 902 } 903 spin_unlock_irqrestore(&runtime->lock, flags); 904 return result; 905 } 906 907 static long snd_rawmidi_kernel_read1(snd_rawmidi_substream_t *substream, 908 unsigned char *buf, long count, int kernel) 909 { 910 unsigned long flags; 911 long result = 0, count1; 912 snd_rawmidi_runtime_t *runtime = substream->runtime; 913 914 while (count > 0 && runtime->avail) { 915 count1 = runtime->buffer_size - runtime->appl_ptr; 916 if (count1 > count) 917 count1 = count; 918 spin_lock_irqsave(&runtime->lock, flags); 919 if (count1 > (int)runtime->avail) 920 count1 = runtime->avail; 921 if (kernel) { 922 memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1); 923 } else { 924 spin_unlock_irqrestore(&runtime->lock, flags); 925 if (copy_to_user((char __user *)buf + result, 926 runtime->buffer + runtime->appl_ptr, count1)) { 927 return result > 0 ? result : -EFAULT; 928 } 929 spin_lock_irqsave(&runtime->lock, flags); 930 } 931 runtime->appl_ptr += count1; 932 runtime->appl_ptr %= runtime->buffer_size; 933 runtime->avail -= count1; 934 spin_unlock_irqrestore(&runtime->lock, flags); 935 result += count1; 936 count -= count1; 937 } 938 return result; 939 } 940 941 long snd_rawmidi_kernel_read(snd_rawmidi_substream_t *substream, unsigned char *buf, long count) 942 { 943 snd_rawmidi_input_trigger(substream, 1); 944 return snd_rawmidi_kernel_read1(substream, buf, count, 1); 945 } 946 947 static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, loff_t *offset) 948 { 949 long result; 950 int count1; 951 snd_rawmidi_file_t *rfile; 952 snd_rawmidi_substream_t *substream; 953 snd_rawmidi_runtime_t *runtime; 954 955 rfile = file->private_data; 956 substream = rfile->input; 957 if (substream == NULL) 958 return -EIO; 959 runtime = substream->runtime; 960 snd_rawmidi_input_trigger(substream, 1); 961 result = 0; 962 while (count > 0) { 963 spin_lock_irq(&runtime->lock); 964 while (!snd_rawmidi_ready(substream)) { 965 wait_queue_t wait; 966 if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) { 967 spin_unlock_irq(&runtime->lock); 968 return result > 0 ? result : -EAGAIN; 969 } 970 init_waitqueue_entry(&wait, current); 971 add_wait_queue(&runtime->sleep, &wait); 972 set_current_state(TASK_INTERRUPTIBLE); 973 spin_unlock_irq(&runtime->lock); 974 schedule(); 975 remove_wait_queue(&runtime->sleep, &wait); 976 if (signal_pending(current)) 977 return result > 0 ? result : -ERESTARTSYS; 978 if (!runtime->avail) 979 return result > 0 ? result : -EIO; 980 spin_lock_irq(&runtime->lock); 981 } 982 spin_unlock_irq(&runtime->lock); 983 count1 = snd_rawmidi_kernel_read1(substream, 984 (unsigned char __force *)buf, 985 count, 0); 986 if (count1 < 0) 987 return result > 0 ? result : count1; 988 result += count1; 989 buf += count1; 990 count -= count1; 991 } 992 return result; 993 } 994 995 /** 996 * snd_rawmidi_transmit_empty - check whether the output buffer is empty 997 * @substream: the rawmidi substream 998 * 999 * Returns 1 if the internal output buffer is empty, 0 if not. 1000 */ 1001 int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream) 1002 { 1003 snd_rawmidi_runtime_t *runtime = substream->runtime; 1004 int result; 1005 unsigned long flags; 1006 1007 if (runtime->buffer == NULL) { 1008 snd_printd("snd_rawmidi_transmit_empty: output is not active!!!\n"); 1009 return 1; 1010 } 1011 spin_lock_irqsave(&runtime->lock, flags); 1012 result = runtime->avail >= runtime->buffer_size; 1013 spin_unlock_irqrestore(&runtime->lock, flags); 1014 return result; 1015 } 1016 1017 /** 1018 * snd_rawmidi_transmit_peek - copy data from the internal buffer 1019 * @substream: the rawmidi substream 1020 * @buffer: the buffer pointer 1021 * @count: data size to transfer 1022 * 1023 * Copies data from the internal output buffer to the given buffer. 1024 * 1025 * Call this in the interrupt handler when the midi output is ready, 1026 * and call snd_rawmidi_transmit_ack() after the transmission is 1027 * finished. 1028 * 1029 * Returns the size of copied data, or a negative error code on failure. 1030 */ 1031 int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count) 1032 { 1033 unsigned long flags; 1034 int result, count1; 1035 snd_rawmidi_runtime_t *runtime = substream->runtime; 1036 1037 if (runtime->buffer == NULL) { 1038 snd_printd("snd_rawmidi_transmit_peek: output is not active!!!\n"); 1039 return -EINVAL; 1040 } 1041 result = 0; 1042 spin_lock_irqsave(&runtime->lock, flags); 1043 if (runtime->avail >= runtime->buffer_size) { 1044 /* warning: lowlevel layer MUST trigger down the hardware */ 1045 goto __skip; 1046 } 1047 if (count == 1) { /* special case, faster code */ 1048 *buffer = runtime->buffer[runtime->hw_ptr]; 1049 result++; 1050 } else { 1051 count1 = runtime->buffer_size - runtime->hw_ptr; 1052 if (count1 > count) 1053 count1 = count; 1054 if (count1 > (int)(runtime->buffer_size - runtime->avail)) 1055 count1 = runtime->buffer_size - runtime->avail; 1056 memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1); 1057 count -= count1; 1058 result += count1; 1059 if (count > 0) { 1060 if (count > (int)(runtime->buffer_size - runtime->avail - count1)) 1061 count = runtime->buffer_size - runtime->avail - count1; 1062 memcpy(buffer + count1, runtime->buffer, count); 1063 result += count; 1064 } 1065 } 1066 __skip: 1067 spin_unlock_irqrestore(&runtime->lock, flags); 1068 return result; 1069 } 1070 1071 /** 1072 * snd_rawmidi_transmit_ack - acknowledge the transmission 1073 * @substream: the rawmidi substream 1074 * @count: the tranferred count 1075 * 1076 * Advances the hardware pointer for the internal output buffer with 1077 * the given size and updates the condition. 1078 * Call after the transmission is finished. 1079 * 1080 * Returns the advanced size if successful, or a negative error code on failure. 1081 */ 1082 int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count) 1083 { 1084 unsigned long flags; 1085 snd_rawmidi_runtime_t *runtime = substream->runtime; 1086 1087 if (runtime->buffer == NULL) { 1088 snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n"); 1089 return -EINVAL; 1090 } 1091 spin_lock_irqsave(&runtime->lock, flags); 1092 snd_assert(runtime->avail + count <= runtime->buffer_size, ); 1093 runtime->hw_ptr += count; 1094 runtime->hw_ptr %= runtime->buffer_size; 1095 runtime->avail += count; 1096 substream->bytes += count; 1097 if (count > 0) { 1098 if (runtime->drain || snd_rawmidi_ready(substream)) 1099 wake_up(&runtime->sleep); 1100 } 1101 spin_unlock_irqrestore(&runtime->lock, flags); 1102 return count; 1103 } 1104 1105 /** 1106 * snd_rawmidi_transmit - copy from the buffer to the device 1107 * @substream: the rawmidi substream 1108 * @buffer: the buffer pointer 1109 * @count: the data size to transfer 1110 * 1111 * Copies data from the buffer to the device and advances the pointer. 1112 * 1113 * Returns the copied size if successful, or a negative error code on failure. 1114 */ 1115 int snd_rawmidi_transmit(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count) 1116 { 1117 count = snd_rawmidi_transmit_peek(substream, buffer, count); 1118 if (count < 0) 1119 return count; 1120 return snd_rawmidi_transmit_ack(substream, count); 1121 } 1122 1123 static long snd_rawmidi_kernel_write1(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count, int kernel) 1124 { 1125 unsigned long flags; 1126 long count1, result; 1127 snd_rawmidi_runtime_t *runtime = substream->runtime; 1128 1129 snd_assert(buf != NULL, return -EINVAL); 1130 snd_assert(runtime->buffer != NULL, return -EINVAL); 1131 1132 result = 0; 1133 spin_lock_irqsave(&runtime->lock, flags); 1134 if (substream->append) { 1135 if ((long)runtime->avail < count) { 1136 spin_unlock_irqrestore(&runtime->lock, flags); 1137 return -EAGAIN; 1138 } 1139 } 1140 while (count > 0 && runtime->avail > 0) { 1141 count1 = runtime->buffer_size - runtime->appl_ptr; 1142 if (count1 > count) 1143 count1 = count; 1144 if (count1 > (long)runtime->avail) 1145 count1 = runtime->avail; 1146 if (kernel) { 1147 memcpy(runtime->buffer + runtime->appl_ptr, buf, count1); 1148 } else { 1149 spin_unlock_irqrestore(&runtime->lock, flags); 1150 if (copy_from_user(runtime->buffer + runtime->appl_ptr, 1151 (char __user *)buf, count1)) { 1152 spin_lock_irqsave(&runtime->lock, flags); 1153 result = result > 0 ? result : -EFAULT; 1154 goto __end; 1155 } 1156 spin_lock_irqsave(&runtime->lock, flags); 1157 } 1158 runtime->appl_ptr += count1; 1159 runtime->appl_ptr %= runtime->buffer_size; 1160 runtime->avail -= count1; 1161 result += count1; 1162 buf += count1; 1163 count -= count1; 1164 } 1165 __end: 1166 count1 = runtime->avail < runtime->buffer_size; 1167 spin_unlock_irqrestore(&runtime->lock, flags); 1168 if (count1) 1169 snd_rawmidi_output_trigger(substream, 1); 1170 return result; 1171 } 1172 1173 long snd_rawmidi_kernel_write(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count) 1174 { 1175 return snd_rawmidi_kernel_write1(substream, buf, count, 1); 1176 } 1177 1178 static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) 1179 { 1180 long result, timeout; 1181 int count1; 1182 snd_rawmidi_file_t *rfile; 1183 snd_rawmidi_runtime_t *runtime; 1184 snd_rawmidi_substream_t *substream; 1185 1186 rfile = file->private_data; 1187 substream = rfile->output; 1188 runtime = substream->runtime; 1189 /* we cannot put an atomic message to our buffer */ 1190 if (substream->append && count > runtime->buffer_size) 1191 return -EIO; 1192 result = 0; 1193 while (count > 0) { 1194 spin_lock_irq(&runtime->lock); 1195 while (!snd_rawmidi_ready_append(substream, count)) { 1196 wait_queue_t wait; 1197 if (file->f_flags & O_NONBLOCK) { 1198 spin_unlock_irq(&runtime->lock); 1199 return result > 0 ? result : -EAGAIN; 1200 } 1201 init_waitqueue_entry(&wait, current); 1202 add_wait_queue(&runtime->sleep, &wait); 1203 set_current_state(TASK_INTERRUPTIBLE); 1204 spin_unlock_irq(&runtime->lock); 1205 timeout = schedule_timeout(30 * HZ); 1206 remove_wait_queue(&runtime->sleep, &wait); 1207 if (signal_pending(current)) 1208 return result > 0 ? result : -ERESTARTSYS; 1209 if (!runtime->avail && !timeout) 1210 return result > 0 ? result : -EIO; 1211 spin_lock_irq(&runtime->lock); 1212 } 1213 spin_unlock_irq(&runtime->lock); 1214 count1 = snd_rawmidi_kernel_write1(substream, 1215 (unsigned char __force *)buf, 1216 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 = kzalloc(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 = kzalloc(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