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