1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Virtual Raw MIDI client on Sequencer 4 * 5 * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>, 6 * Jaroslav Kysela <perex@perex.cz> 7 */ 8 9 /* 10 * Virtual Raw MIDI client 11 * 12 * The virtual rawmidi client is a sequencer client which associate 13 * a rawmidi device file. The created rawmidi device file can be 14 * accessed as a normal raw midi, but its MIDI source and destination 15 * are arbitrary. For example, a user-client software synth connected 16 * to this port can be used as a normal midi device as well. 17 * 18 * The virtual rawmidi device accepts also multiple opens. Each file 19 * has its own input buffer, so that no conflict would occur. The drain 20 * of input/output buffer acts only to the local buffer. 21 * 22 */ 23 24 #include <linux/init.h> 25 #include <linux/wait.h> 26 #include <linux/module.h> 27 #include <linux/slab.h> 28 #include <sound/core.h> 29 #include <sound/rawmidi.h> 30 #include <sound/info.h> 31 #include <sound/control.h> 32 #include <sound/minors.h> 33 #include <sound/seq_kernel.h> 34 #include <sound/seq_midi_event.h> 35 #include <sound/seq_virmidi.h> 36 37 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); 38 MODULE_DESCRIPTION("Virtual Raw MIDI client on Sequencer"); 39 MODULE_LICENSE("GPL"); 40 41 /* 42 * initialize an event record 43 */ 44 static void snd_virmidi_init_event(struct snd_virmidi *vmidi, 45 struct snd_seq_event *ev) 46 { 47 memset(ev, 0, sizeof(*ev)); 48 ev->source.port = vmidi->port; 49 switch (vmidi->seq_mode) { 50 case SNDRV_VIRMIDI_SEQ_DISPATCH: 51 ev->dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; 52 break; 53 case SNDRV_VIRMIDI_SEQ_ATTACH: 54 /* FIXME: source and destination are same - not good.. */ 55 ev->dest.client = vmidi->client; 56 ev->dest.port = vmidi->port; 57 break; 58 } 59 ev->type = SNDRV_SEQ_EVENT_NONE; 60 } 61 62 /* 63 * decode input event and put to read buffer of each opened file 64 */ 65 66 /* callback for snd_seq_dump_var_event(), bridging to snd_rawmidi_receive() */ 67 static int dump_to_rawmidi(void *ptr, void *buf, int count) 68 { 69 return snd_rawmidi_receive(ptr, buf, count); 70 } 71 72 static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, 73 struct snd_seq_event *ev, 74 bool atomic) 75 { 76 struct snd_virmidi *vmidi; 77 unsigned char msg[4]; 78 int len; 79 80 if (atomic) 81 rcu_read_lock(); 82 else 83 down_read(&rdev->filelist_sem); 84 list_for_each_entry_rcu(vmidi, &rdev->filelist, list, 85 lockdep_is_held(&rdev->filelist_sem)) { 86 if (!READ_ONCE(vmidi->trigger)) 87 continue; 88 if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { 89 if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) 90 continue; 91 snd_seq_dump_var_event(ev, dump_to_rawmidi, vmidi->substream); 92 snd_midi_event_reset_decode(vmidi->parser); 93 } else { 94 len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev); 95 if (len > 0) 96 snd_rawmidi_receive(vmidi->substream, msg, len); 97 } 98 } 99 if (atomic) 100 rcu_read_unlock(); 101 else 102 up_read(&rdev->filelist_sem); 103 104 return 0; 105 } 106 107 /* 108 * event handler of virmidi port 109 */ 110 static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct, 111 void *private_data, int atomic, int hop) 112 { 113 struct snd_virmidi_dev *rdev; 114 115 rdev = private_data; 116 if (!(rdev->flags & SNDRV_VIRMIDI_USE)) 117 return 0; /* ignored */ 118 return snd_virmidi_dev_receive_event(rdev, ev, atomic); 119 } 120 121 /* 122 * trigger rawmidi stream for input 123 */ 124 static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) 125 { 126 struct snd_virmidi *vmidi = substream->runtime->private_data; 127 128 WRITE_ONCE(vmidi->trigger, !!up); 129 } 130 131 /* process rawmidi bytes and send events; 132 * we need no lock here for vmidi->event since it's handled only in this work 133 */ 134 static void snd_vmidi_output_work(struct work_struct *work) 135 { 136 struct snd_virmidi *vmidi; 137 struct snd_rawmidi_substream *substream; 138 unsigned char input; 139 int ret; 140 141 vmidi = container_of(work, struct snd_virmidi, output_work); 142 substream = vmidi->substream; 143 144 /* discard the outputs in dispatch mode unless subscribed */ 145 if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH && 146 !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) { 147 snd_rawmidi_proceed(substream); 148 return; 149 } 150 151 while (READ_ONCE(vmidi->trigger)) { 152 if (snd_rawmidi_transmit(substream, &input, 1) != 1) 153 break; 154 if (!snd_midi_event_encode_byte(vmidi->parser, input, 155 &vmidi->event)) 156 continue; 157 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { 158 ret = snd_seq_kernel_client_dispatch(vmidi->client, 159 &vmidi->event, 160 false, 0); 161 vmidi->event.type = SNDRV_SEQ_EVENT_NONE; 162 if (ret < 0) 163 break; 164 } 165 /* rawmidi input might be huge, allow to have a break */ 166 cond_resched(); 167 } 168 } 169 170 /* 171 * trigger rawmidi stream for output 172 */ 173 static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, int up) 174 { 175 struct snd_virmidi *vmidi = substream->runtime->private_data; 176 177 WRITE_ONCE(vmidi->trigger, !!up); 178 if (up) 179 queue_work(system_highpri_wq, &vmidi->output_work); 180 } 181 182 /* 183 * open rawmidi handle for input 184 */ 185 static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) 186 { 187 struct snd_virmidi_dev *rdev = substream->rmidi->private_data; 188 struct snd_rawmidi_runtime *runtime = substream->runtime; 189 struct snd_virmidi *vmidi; 190 191 vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL); 192 if (vmidi == NULL) 193 return -ENOMEM; 194 vmidi->substream = substream; 195 if (snd_midi_event_new(0, &vmidi->parser) < 0) { 196 kfree(vmidi); 197 return -ENOMEM; 198 } 199 vmidi->seq_mode = rdev->seq_mode; 200 vmidi->client = rdev->client; 201 vmidi->port = rdev->port; 202 runtime->private_data = vmidi; 203 scoped_guard(rwsem_write, &rdev->filelist_sem) { 204 list_add_tail_rcu(&vmidi->list, &rdev->filelist); 205 } 206 vmidi->rdev = rdev; 207 return 0; 208 } 209 210 /* 211 * open rawmidi handle for output 212 */ 213 static int snd_virmidi_output_open(struct snd_rawmidi_substream *substream) 214 { 215 struct snd_virmidi_dev *rdev = substream->rmidi->private_data; 216 struct snd_rawmidi_runtime *runtime = substream->runtime; 217 struct snd_virmidi *vmidi; 218 219 vmidi = kzalloc_obj(*vmidi); 220 if (vmidi == NULL) 221 return -ENOMEM; 222 vmidi->substream = substream; 223 if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &vmidi->parser) < 0) { 224 kfree(vmidi); 225 return -ENOMEM; 226 } 227 vmidi->seq_mode = rdev->seq_mode; 228 vmidi->client = rdev->client; 229 vmidi->port = rdev->port; 230 snd_virmidi_init_event(vmidi, &vmidi->event); 231 vmidi->rdev = rdev; 232 INIT_WORK(&vmidi->output_work, snd_vmidi_output_work); 233 runtime->private_data = vmidi; 234 return 0; 235 } 236 237 /* 238 * close rawmidi handle for input 239 */ 240 static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) 241 { 242 struct snd_virmidi_dev *rdev = substream->rmidi->private_data; 243 struct snd_virmidi *vmidi = substream->runtime->private_data; 244 245 scoped_guard(rwsem_write, &rdev->filelist_sem) { 246 list_del_rcu(&vmidi->list); 247 } 248 /* wait for a grace period so that lockless readers in the atomic 249 * delivery path (snd_virmidi_dev_receive_event()) are no longer 250 * traversing this entry before its parser and memory are freed 251 */ 252 synchronize_rcu(); 253 snd_midi_event_free(vmidi->parser); 254 substream->runtime->private_data = NULL; 255 kfree(vmidi); 256 return 0; 257 } 258 259 /* 260 * close rawmidi handle for output 261 */ 262 static int snd_virmidi_output_close(struct snd_rawmidi_substream *substream) 263 { 264 struct snd_virmidi *vmidi = substream->runtime->private_data; 265 266 WRITE_ONCE(vmidi->trigger, false); /* to be sure */ 267 cancel_work_sync(&vmidi->output_work); 268 snd_midi_event_free(vmidi->parser); 269 substream->runtime->private_data = NULL; 270 kfree(vmidi); 271 return 0; 272 } 273 274 /* 275 * drain output work queue 276 */ 277 static void snd_virmidi_output_drain(struct snd_rawmidi_substream *substream) 278 { 279 struct snd_virmidi *vmidi = substream->runtime->private_data; 280 281 flush_work(&vmidi->output_work); 282 } 283 284 /* 285 * subscribe callback - allow output to rawmidi device 286 */ 287 static int snd_virmidi_subscribe(void *private_data, 288 struct snd_seq_port_subscribe *info) 289 { 290 struct snd_virmidi_dev *rdev; 291 292 rdev = private_data; 293 if (!try_module_get(rdev->card->module)) 294 return -EFAULT; 295 rdev->flags |= SNDRV_VIRMIDI_SUBSCRIBE; 296 return 0; 297 } 298 299 /* 300 * unsubscribe callback - disallow output to rawmidi device 301 */ 302 static int snd_virmidi_unsubscribe(void *private_data, 303 struct snd_seq_port_subscribe *info) 304 { 305 struct snd_virmidi_dev *rdev; 306 307 rdev = private_data; 308 rdev->flags &= ~SNDRV_VIRMIDI_SUBSCRIBE; 309 module_put(rdev->card->module); 310 return 0; 311 } 312 313 314 /* 315 * use callback - allow input to rawmidi device 316 */ 317 static int snd_virmidi_use(void *private_data, 318 struct snd_seq_port_subscribe *info) 319 { 320 struct snd_virmidi_dev *rdev; 321 322 rdev = private_data; 323 if (!try_module_get(rdev->card->module)) 324 return -EFAULT; 325 rdev->flags |= SNDRV_VIRMIDI_USE; 326 return 0; 327 } 328 329 /* 330 * unuse callback - disallow input to rawmidi device 331 */ 332 static int snd_virmidi_unuse(void *private_data, 333 struct snd_seq_port_subscribe *info) 334 { 335 struct snd_virmidi_dev *rdev; 336 337 rdev = private_data; 338 rdev->flags &= ~SNDRV_VIRMIDI_USE; 339 module_put(rdev->card->module); 340 return 0; 341 } 342 343 344 /* 345 * Register functions 346 */ 347 348 static const struct snd_rawmidi_ops snd_virmidi_input_ops = { 349 .open = snd_virmidi_input_open, 350 .close = snd_virmidi_input_close, 351 .trigger = snd_virmidi_input_trigger, 352 }; 353 354 static const struct snd_rawmidi_ops snd_virmidi_output_ops = { 355 .open = snd_virmidi_output_open, 356 .close = snd_virmidi_output_close, 357 .trigger = snd_virmidi_output_trigger, 358 .drain = snd_virmidi_output_drain, 359 }; 360 361 /* 362 * create a sequencer client and a port 363 */ 364 static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) 365 { 366 int client; 367 struct snd_seq_port_callback pcallbacks; 368 int err; 369 370 if (rdev->client >= 0) 371 return 0; 372 373 struct snd_seq_port_info *pinfo __free(kfree) = 374 kzalloc_obj(*pinfo); 375 if (!pinfo) 376 return -ENOMEM; 377 378 client = snd_seq_create_kernel_client(rdev->card, rdev->device, 379 "%s %d-%d", rdev->rmidi->name, 380 rdev->card->number, 381 rdev->device); 382 if (client < 0) 383 return client; 384 rdev->client = client; 385 386 /* create a port */ 387 pinfo->addr.client = client; 388 sprintf(pinfo->name, "VirMIDI %d-%d", rdev->card->number, rdev->device); 389 /* set all capabilities */ 390 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 391 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; 392 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 393 pinfo->direction = SNDRV_SEQ_PORT_DIR_BIDIRECTION; 394 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC 395 | SNDRV_SEQ_PORT_TYPE_SOFTWARE 396 | SNDRV_SEQ_PORT_TYPE_PORT; 397 pinfo->midi_channels = 16; 398 memset(&pcallbacks, 0, sizeof(pcallbacks)); 399 pcallbacks.owner = THIS_MODULE; 400 pcallbacks.private_data = rdev; 401 pcallbacks.subscribe = snd_virmidi_subscribe; 402 pcallbacks.unsubscribe = snd_virmidi_unsubscribe; 403 pcallbacks.use = snd_virmidi_use; 404 pcallbacks.unuse = snd_virmidi_unuse; 405 pcallbacks.event_input = snd_virmidi_event_input; 406 pinfo->kernel = &pcallbacks; 407 err = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, pinfo); 408 if (err < 0) { 409 snd_seq_delete_kernel_client(client); 410 rdev->client = -1; 411 return err; 412 } 413 414 rdev->port = pinfo->addr.port; 415 return 0; /* success */ 416 } 417 418 419 /* 420 * release the sequencer client 421 */ 422 static void snd_virmidi_dev_detach_seq(struct snd_virmidi_dev *rdev) 423 { 424 if (rdev->client >= 0) { 425 snd_seq_delete_kernel_client(rdev->client); 426 rdev->client = -1; 427 } 428 } 429 430 /* 431 * register the device 432 */ 433 static int snd_virmidi_dev_register(struct snd_rawmidi *rmidi) 434 { 435 struct snd_virmidi_dev *rdev = rmidi->private_data; 436 int err; 437 438 switch (rdev->seq_mode) { 439 case SNDRV_VIRMIDI_SEQ_DISPATCH: 440 err = snd_virmidi_dev_attach_seq(rdev); 441 if (err < 0) 442 return err; 443 break; 444 case SNDRV_VIRMIDI_SEQ_ATTACH: 445 if (rdev->client == 0) 446 return -EINVAL; 447 /* should check presence of port more strictly.. */ 448 break; 449 default: 450 pr_err("ALSA: seq_virmidi: seq_mode is not set: %d\n", rdev->seq_mode); 451 return -EINVAL; 452 } 453 return 0; 454 } 455 456 457 /* 458 * unregister the device 459 */ 460 static int snd_virmidi_dev_unregister(struct snd_rawmidi *rmidi) 461 { 462 struct snd_virmidi_dev *rdev = rmidi->private_data; 463 464 if (rdev->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH) 465 snd_virmidi_dev_detach_seq(rdev); 466 return 0; 467 } 468 469 /* 470 * 471 */ 472 static const struct snd_rawmidi_global_ops snd_virmidi_global_ops = { 473 .dev_register = snd_virmidi_dev_register, 474 .dev_unregister = snd_virmidi_dev_unregister, 475 }; 476 477 /* 478 * free device 479 */ 480 static void snd_virmidi_free(struct snd_rawmidi *rmidi) 481 { 482 struct snd_virmidi_dev *rdev = rmidi->private_data; 483 kfree(rdev); 484 } 485 486 /* 487 * create a new device 488 * 489 */ 490 /* exported */ 491 int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmidi) 492 { 493 struct snd_rawmidi *rmidi; 494 struct snd_virmidi_dev *rdev; 495 int err; 496 497 *rrmidi = NULL; 498 err = snd_rawmidi_new(card, "VirMidi", device, 499 16, /* may be configurable */ 500 16, /* may be configurable */ 501 &rmidi); 502 if (err < 0) 503 return err; 504 strscpy(rmidi->name, rmidi->id); 505 rdev = kzalloc_obj(*rdev); 506 if (rdev == NULL) { 507 snd_device_free(card, rmidi); 508 return -ENOMEM; 509 } 510 rdev->card = card; 511 rdev->rmidi = rmidi; 512 rdev->device = device; 513 rdev->client = -1; 514 init_rwsem(&rdev->filelist_sem); 515 INIT_LIST_HEAD(&rdev->filelist); 516 rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; 517 rmidi->private_data = rdev; 518 rmidi->private_free = snd_virmidi_free; 519 rmidi->ops = &snd_virmidi_global_ops; 520 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_virmidi_input_ops); 521 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_virmidi_output_ops); 522 rmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT | 523 SNDRV_RAWMIDI_INFO_OUTPUT | 524 SNDRV_RAWMIDI_INFO_DUPLEX; 525 *rrmidi = rmidi; 526 return 0; 527 } 528 EXPORT_SYMBOL(snd_virmidi_new); 529