1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * OSS compatible sequencer driver 4 * 5 * MIDI device handlers 6 * 7 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de> 8 */ 9 10 #include <sound/asoundef.h> 11 #include "seq_oss_midi.h" 12 #include "seq_oss_readq.h" 13 #include "seq_oss_timer.h" 14 #include "seq_oss_event.h" 15 #include <sound/seq_midi_event.h> 16 #include "../seq_lock.h" 17 #include <linux/init.h> 18 #include <linux/slab.h> 19 #include <linux/nospec.h> 20 21 22 /* 23 * constants 24 */ 25 #define SNDRV_SEQ_OSS_MAX_MIDI_NAME 30 26 27 /* 28 * definition of midi device record 29 */ 30 struct seq_oss_midi { 31 int seq_device; /* device number */ 32 int client; /* sequencer client number */ 33 int port; /* sequencer port number */ 34 unsigned int flags; /* port capability */ 35 int opened; /* flag for opening */ 36 unsigned char name[SNDRV_SEQ_OSS_MAX_MIDI_NAME]; 37 struct snd_midi_event *coder; /* MIDI event coder */ 38 struct seq_oss_devinfo *devinfo; /* assigned OSSseq device */ 39 snd_use_lock_t use_lock; 40 struct mutex open_mutex; 41 }; 42 43 DEFINE_FREE(seq_oss_midi, struct seq_oss_midi *, if (!IS_ERR_OR_NULL(_T)) snd_use_lock_free(&(_T)->use_lock)) 44 45 /* 46 * midi device table 47 */ 48 static int max_midi_devs; 49 static struct seq_oss_midi *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS]; 50 51 static DEFINE_SPINLOCK(register_lock); 52 53 /* 54 * prototypes 55 */ 56 static struct seq_oss_midi *get_mdev(int dev); 57 static struct seq_oss_midi *get_mididev(struct seq_oss_devinfo *dp, int dev); 58 static int send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev); 59 static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev); 60 61 /* 62 * look up the existing ports 63 * this looks a very exhausting job. 64 */ 65 int 66 snd_seq_oss_midi_lookup_ports(int client) 67 { 68 struct snd_seq_client_info *clinfo __free(kfree) = 69 kzalloc_obj(*clinfo); 70 struct snd_seq_port_info *pinfo __free(kfree) = 71 kzalloc_obj(*pinfo); 72 73 if (!clinfo || !pinfo) 74 return -ENOMEM; 75 clinfo->client = -1; 76 while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) { 77 if (clinfo->client == client) 78 continue; /* ignore myself */ 79 pinfo->addr.client = clinfo->client; 80 pinfo->addr.port = -1; 81 while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0) 82 snd_seq_oss_midi_check_new_port(pinfo); 83 } 84 return 0; 85 } 86 87 88 /* 89 */ 90 static struct seq_oss_midi * 91 get_mdev(int dev) 92 { 93 struct seq_oss_midi *mdev; 94 95 guard(spinlock_irqsave)(®ister_lock); 96 mdev = midi_devs[dev]; 97 if (mdev) 98 snd_use_lock_use(&mdev->use_lock); 99 return mdev; 100 } 101 102 /* 103 * look for the identical slot 104 */ 105 static struct seq_oss_midi * 106 find_slot(int client, int port) 107 { 108 int i; 109 struct seq_oss_midi *mdev; 110 111 guard(spinlock_irqsave)(®ister_lock); 112 for (i = 0; i < max_midi_devs; i++) { 113 mdev = midi_devs[i]; 114 if (mdev && mdev->client == client && mdev->port == port) { 115 /* found! */ 116 snd_use_lock_use(&mdev->use_lock); 117 return mdev; 118 } 119 } 120 return NULL; 121 } 122 123 124 #define PERM_WRITE (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE) 125 #define PERM_READ (SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ) 126 /* 127 * register a new port if it doesn't exist yet 128 */ 129 int 130 snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) 131 { 132 int i; 133 struct seq_oss_midi *mdev; 134 135 /* the port must include generic midi */ 136 if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC)) 137 return 0; 138 /* either read or write subscribable */ 139 if ((pinfo->capability & PERM_WRITE) != PERM_WRITE && 140 (pinfo->capability & PERM_READ) != PERM_READ) 141 return 0; 142 143 /* 144 * look for the identical slot 145 */ 146 mdev = find_slot(pinfo->addr.client, pinfo->addr.port); 147 if (mdev) { 148 /* already exists */ 149 snd_use_lock_free(&mdev->use_lock); 150 return 0; 151 } 152 153 /* 154 * allocate midi info record 155 */ 156 mdev = kzalloc_obj(*mdev); 157 if (!mdev) 158 return -ENOMEM; 159 160 /* copy the port information */ 161 mdev->client = pinfo->addr.client; 162 mdev->port = pinfo->addr.port; 163 mdev->flags = pinfo->capability; 164 mdev->opened = 0; 165 snd_use_lock_init(&mdev->use_lock); 166 mutex_init(&mdev->open_mutex); 167 168 /* copy and truncate the name of synth device */ 169 strscpy(mdev->name, pinfo->name, sizeof(mdev->name)); 170 171 /* create MIDI coder */ 172 if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { 173 pr_err("ALSA: seq_oss: can't malloc midi coder\n"); 174 kfree(mdev); 175 return -ENOMEM; 176 } 177 /* OSS sequencer adds running status to all sequences */ 178 snd_midi_event_no_status(mdev->coder, 1); 179 180 /* 181 * look for en empty slot 182 */ 183 guard(spinlock_irqsave)(®ister_lock); 184 for (i = 0; i < max_midi_devs; i++) { 185 if (midi_devs[i] == NULL) 186 break; 187 } 188 if (i >= max_midi_devs) { 189 if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) { 190 snd_midi_event_free(mdev->coder); 191 kfree(mdev); 192 return -ENOMEM; 193 } 194 max_midi_devs++; 195 } 196 mdev->seq_device = i; 197 midi_devs[mdev->seq_device] = mdev; 198 199 return 0; 200 } 201 202 /* 203 * release the midi device if it was registered 204 */ 205 int 206 snd_seq_oss_midi_check_exit_port(int client, int port) 207 { 208 struct seq_oss_midi *mdev; 209 int index; 210 211 mdev = find_slot(client, port); 212 if (mdev) { 213 scoped_guard(spinlock_irqsave, ®ister_lock) { 214 /* Only one callback may release the device. */ 215 if (midi_devs[mdev->seq_device] != mdev) { 216 snd_use_lock_free(&mdev->use_lock); 217 return 0; 218 } 219 midi_devs[mdev->seq_device] = NULL; 220 } 221 snd_use_lock_free(&mdev->use_lock); 222 snd_use_lock_sync(&mdev->use_lock); 223 snd_midi_event_free(mdev->coder); 224 kfree(mdev); 225 } 226 guard(spinlock_irqsave)(®ister_lock); 227 for (index = max_midi_devs - 1; index >= 0; index--) { 228 if (midi_devs[index]) 229 break; 230 } 231 max_midi_devs = index + 1; 232 return 0; 233 } 234 235 236 /* 237 * release the midi device if it was registered 238 */ 239 void 240 snd_seq_oss_midi_clear_all(void) 241 { 242 int i; 243 struct seq_oss_midi *mdev; 244 245 guard(spinlock_irqsave)(®ister_lock); 246 for (i = 0; i < max_midi_devs; i++) { 247 mdev = midi_devs[i]; 248 if (mdev) { 249 snd_midi_event_free(mdev->coder); 250 kfree(mdev); 251 midi_devs[i] = NULL; 252 } 253 } 254 max_midi_devs = 0; 255 } 256 257 258 /* 259 * set up midi tables 260 */ 261 void 262 snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp) 263 { 264 guard(spinlock_irq)(®ister_lock); 265 dp->max_mididev = max_midi_devs; 266 } 267 268 /* 269 * clean up midi tables 270 */ 271 void 272 snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp) 273 { 274 int i; 275 for (i = 0; i < dp->max_mididev; i++) 276 snd_seq_oss_midi_close(dp, i); 277 dp->max_mididev = 0; 278 } 279 280 281 /* 282 * open all midi devices. ignore errors. 283 */ 284 void 285 snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode) 286 { 287 int i; 288 for (i = 0; i < dp->max_mididev; i++) 289 snd_seq_oss_midi_open(dp, i, file_mode); 290 } 291 292 293 /* 294 * get the midi device information 295 */ 296 static struct seq_oss_midi * 297 get_mididev(struct seq_oss_devinfo *dp, int dev) 298 { 299 if (dev < 0 || dev >= dp->max_mididev) 300 return NULL; 301 dev = array_index_nospec(dev, dp->max_mididev); 302 return get_mdev(dev); 303 } 304 305 306 /* 307 * open the midi device if not opened yet 308 */ 309 int 310 snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) 311 { 312 int perm; 313 struct snd_seq_port_subscribe subs; 314 struct seq_oss_midi *mdev __free(seq_oss_midi) = 315 get_mididev(dp, dev); 316 317 if (!mdev) 318 return -ENODEV; 319 320 guard(mutex)(&mdev->open_mutex); 321 /* already used? */ 322 if (mdev->opened && mdev->devinfo != dp) 323 return -EBUSY; 324 325 perm = 0; 326 if (is_write_mode(fmode)) 327 perm |= PERM_WRITE; 328 if (is_read_mode(fmode)) 329 perm |= PERM_READ; 330 perm &= mdev->flags; 331 if (perm == 0) 332 return -ENXIO; 333 334 /* already opened? */ 335 if ((mdev->opened & perm) == perm) 336 return 0; 337 338 perm &= ~mdev->opened; 339 340 memset(&subs, 0, sizeof(subs)); 341 342 if (perm & PERM_WRITE) { 343 subs.sender = dp->addr; 344 subs.dest.client = mdev->client; 345 subs.dest.port = mdev->port; 346 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0) 347 mdev->opened |= PERM_WRITE; 348 } 349 if (perm & PERM_READ) { 350 subs.sender.client = mdev->client; 351 subs.sender.port = mdev->port; 352 subs.dest = dp->addr; 353 subs.flags = SNDRV_SEQ_PORT_SUBS_TIMESTAMP; 354 subs.queue = dp->queue; /* queue for timestamps */ 355 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0) 356 mdev->opened |= PERM_READ; 357 } 358 359 if (!mdev->opened) 360 return -ENXIO; 361 362 mdev->devinfo = dp; 363 return 0; 364 } 365 366 /* 367 * close the midi device if already opened 368 */ 369 int 370 snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev) 371 { 372 struct snd_seq_port_subscribe subs; 373 struct seq_oss_midi *mdev __free(seq_oss_midi) = 374 get_mididev(dp, dev); 375 376 if (!mdev) 377 return -ENODEV; 378 guard(mutex)(&mdev->open_mutex); 379 if (!mdev->opened || mdev->devinfo != dp) 380 return 0; 381 382 memset(&subs, 0, sizeof(subs)); 383 if (mdev->opened & PERM_WRITE) { 384 subs.sender = dp->addr; 385 subs.dest.client = mdev->client; 386 subs.dest.port = mdev->port; 387 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs); 388 } 389 if (mdev->opened & PERM_READ) { 390 subs.sender.client = mdev->client; 391 subs.sender.port = mdev->port; 392 subs.dest = dp->addr; 393 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs); 394 } 395 396 mdev->opened = 0; 397 mdev->devinfo = NULL; 398 return 0; 399 } 400 401 /* 402 * change seq capability flags to file mode flags 403 */ 404 int 405 snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev) 406 { 407 int mode; 408 struct seq_oss_midi *mdev __free(seq_oss_midi) = 409 get_mididev(dp, dev); 410 411 if (!mdev) 412 return 0; 413 414 mode = 0; 415 if (mdev->opened & PERM_WRITE) 416 mode |= SNDRV_SEQ_OSS_FILE_WRITE; 417 if (mdev->opened & PERM_READ) 418 mode |= SNDRV_SEQ_OSS_FILE_READ; 419 420 return mode; 421 } 422 423 /* 424 * reset the midi device and close it: 425 * so far, only close the device. 426 */ 427 void 428 snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev) 429 { 430 struct seq_oss_midi *mdev __free(seq_oss_midi) = 431 get_mididev(dp, dev); 432 433 if (!mdev) 434 return; 435 if (!mdev->opened) 436 return; 437 438 if (mdev->opened & PERM_WRITE) { 439 struct snd_seq_event ev; 440 int c; 441 442 memset(&ev, 0, sizeof(ev)); 443 ev.dest.client = mdev->client; 444 ev.dest.port = mdev->port; 445 ev.queue = dp->queue; 446 ev.source.port = dp->port; 447 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) { 448 ev.type = SNDRV_SEQ_EVENT_SENSING; 449 snd_seq_oss_dispatch(dp, &ev, 0, 0); 450 } 451 for (c = 0; c < 16; c++) { 452 ev.type = SNDRV_SEQ_EVENT_CONTROLLER; 453 ev.data.control.channel = c; 454 ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF; 455 snd_seq_oss_dispatch(dp, &ev, 0, 0); 456 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) { 457 ev.data.control.param = 458 MIDI_CTL_RESET_CONTROLLERS; 459 snd_seq_oss_dispatch(dp, &ev, 0, 0); 460 ev.type = SNDRV_SEQ_EVENT_PITCHBEND; 461 ev.data.control.value = 0; 462 snd_seq_oss_dispatch(dp, &ev, 0, 0); 463 } 464 } 465 } 466 // snd_seq_oss_midi_close(dp, dev); 467 } 468 469 470 /* 471 * get client/port of the specified MIDI device 472 */ 473 void 474 snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr) 475 { 476 struct seq_oss_midi *mdev __free(seq_oss_midi) = 477 get_mididev(dp, dev); 478 479 if (!mdev) 480 return; 481 addr->client = mdev->client; 482 addr->port = mdev->port; 483 } 484 485 486 /* 487 * input callback - this can be atomic 488 */ 489 int 490 snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data) 491 { 492 struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data; 493 494 if (dp->readq == NULL) 495 return 0; 496 struct seq_oss_midi *mdev __free(seq_oss_midi) = 497 find_slot(ev->source.client, ev->source.port); 498 if (!mdev) 499 return 0; 500 if (!(mdev->opened & PERM_READ)) 501 return 0; 502 503 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) 504 return send_synth_event(dp, ev, mdev->seq_device); 505 else 506 return send_midi_event(dp, ev, mdev); 507 } 508 509 /* 510 * convert ALSA sequencer event to OSS synth event 511 */ 512 static int 513 send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev) 514 { 515 union evrec ossev; 516 517 memset(&ossev, 0, sizeof(ossev)); 518 519 switch (ev->type) { 520 case SNDRV_SEQ_EVENT_NOTEON: 521 ossev.v.cmd = MIDI_NOTEON; break; 522 case SNDRV_SEQ_EVENT_NOTEOFF: 523 ossev.v.cmd = MIDI_NOTEOFF; break; 524 case SNDRV_SEQ_EVENT_KEYPRESS: 525 ossev.v.cmd = MIDI_KEY_PRESSURE; break; 526 case SNDRV_SEQ_EVENT_CONTROLLER: 527 ossev.l.cmd = MIDI_CTL_CHANGE; break; 528 case SNDRV_SEQ_EVENT_PGMCHANGE: 529 ossev.l.cmd = MIDI_PGM_CHANGE; break; 530 case SNDRV_SEQ_EVENT_CHANPRESS: 531 ossev.l.cmd = MIDI_CHN_PRESSURE; break; 532 case SNDRV_SEQ_EVENT_PITCHBEND: 533 ossev.l.cmd = MIDI_PITCH_BEND; break; 534 default: 535 return 0; /* not supported */ 536 } 537 538 ossev.v.dev = dev; 539 540 switch (ev->type) { 541 case SNDRV_SEQ_EVENT_NOTEON: 542 case SNDRV_SEQ_EVENT_NOTEOFF: 543 case SNDRV_SEQ_EVENT_KEYPRESS: 544 ossev.v.code = EV_CHN_VOICE; 545 ossev.v.note = ev->data.note.note; 546 ossev.v.parm = ev->data.note.velocity; 547 ossev.v.chn = ev->data.note.channel; 548 break; 549 case SNDRV_SEQ_EVENT_CONTROLLER: 550 case SNDRV_SEQ_EVENT_PGMCHANGE: 551 case SNDRV_SEQ_EVENT_CHANPRESS: 552 ossev.l.code = EV_CHN_COMMON; 553 ossev.l.p1 = ev->data.control.param; 554 ossev.l.val = ev->data.control.value; 555 ossev.l.chn = ev->data.control.channel; 556 break; 557 case SNDRV_SEQ_EVENT_PITCHBEND: 558 ossev.l.code = EV_CHN_COMMON; 559 ossev.l.val = ev->data.control.value + 8192; 560 ossev.l.chn = ev->data.control.channel; 561 break; 562 } 563 564 snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode); 565 snd_seq_oss_readq_put_event(dp->readq, &ossev); 566 567 return 0; 568 } 569 570 /* 571 * decode event and send MIDI bytes to read queue 572 */ 573 static int 574 send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev) 575 { 576 char msg[32]; 577 int len; 578 579 snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode); 580 if (!dp->timer->running) 581 len = snd_seq_oss_timer_start(dp->timer); 582 if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { 583 snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev); 584 snd_midi_event_reset_decode(mdev->coder); 585 } else { 586 len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); 587 if (len > 0) 588 snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, msg, len); 589 } 590 591 return 0; 592 } 593 594 595 /* 596 * dump midi data 597 * return 0 : enqueued 598 * non-zero : invalid - ignored 599 */ 600 int 601 snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, 602 struct snd_seq_event *ev, snd_use_lock_t **lockp) 603 { 604 struct seq_oss_midi *mdev __free(seq_oss_midi) = 605 get_mididev(dp, dev); 606 607 if (!mdev) 608 return -ENODEV; 609 if (snd_midi_event_encode_byte(mdev->coder, c, ev)) { 610 snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port); 611 /* the caller must release this later */ 612 *lockp = &mdev->use_lock; 613 snd_use_lock_use(*lockp); 614 return 0; 615 } 616 return -EINVAL; 617 } 618 619 /* 620 * create OSS compatible midi_info record 621 */ 622 int 623 snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf) 624 { 625 struct seq_oss_midi *mdev __free(seq_oss_midi) = 626 get_mididev(dp, dev); 627 628 if (!mdev) 629 return -ENXIO; 630 inf->device = dev; 631 inf->dev_type = 0; /* FIXME: ?? */ 632 inf->capabilities = 0; /* FIXME: ?? */ 633 strscpy(inf->name, mdev->name, sizeof(inf->name)); 634 return 0; 635 } 636 637 638 #ifdef CONFIG_SND_PROC_FS 639 /* 640 * proc interface 641 */ 642 static char * 643 capmode_str(int val) 644 { 645 val &= PERM_READ|PERM_WRITE; 646 if (val == (PERM_READ|PERM_WRITE)) 647 return "read/write"; 648 else if (val == PERM_READ) 649 return "read"; 650 else if (val == PERM_WRITE) 651 return "write"; 652 else 653 return "none"; 654 } 655 656 void 657 snd_seq_oss_midi_info_read(struct snd_info_buffer *buf) 658 { 659 int i; 660 661 snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs); 662 for (i = 0; i < max_midi_devs; i++) { 663 snd_iprintf(buf, "\nmidi %d: ", i); 664 struct seq_oss_midi *mdev __free(seq_oss_midi) = 665 get_mdev(i); 666 if (mdev == NULL) { 667 snd_iprintf(buf, "*empty*\n"); 668 continue; 669 } 670 snd_iprintf(buf, "[%s] ALSA port %d:%d\n", mdev->name, 671 mdev->client, mdev->port); 672 snd_iprintf(buf, " capability %s / opened %s\n", 673 capmode_str(mdev->flags), 674 capmode_str(mdev->opened)); 675 } 676 } 677 #endif /* CONFIG_SND_PROC_FS */ 678