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) = NULL; 69 struct snd_seq_port_info *pinfo __free(kfree) = NULL; 70 71 clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL); 72 pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); 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(sizeof(*mdev), GFP_KERNEL); 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 midi_devs[mdev->seq_device] = NULL; 215 } 216 snd_use_lock_free(&mdev->use_lock); 217 snd_use_lock_sync(&mdev->use_lock); 218 snd_midi_event_free(mdev->coder); 219 kfree(mdev); 220 } 221 guard(spinlock_irqsave)(®ister_lock); 222 for (index = max_midi_devs - 1; index >= 0; index--) { 223 if (midi_devs[index]) 224 break; 225 } 226 max_midi_devs = index + 1; 227 return 0; 228 } 229 230 231 /* 232 * release the midi device if it was registered 233 */ 234 void 235 snd_seq_oss_midi_clear_all(void) 236 { 237 int i; 238 struct seq_oss_midi *mdev; 239 240 guard(spinlock_irqsave)(®ister_lock); 241 for (i = 0; i < max_midi_devs; i++) { 242 mdev = midi_devs[i]; 243 if (mdev) { 244 snd_midi_event_free(mdev->coder); 245 kfree(mdev); 246 midi_devs[i] = NULL; 247 } 248 } 249 max_midi_devs = 0; 250 } 251 252 253 /* 254 * set up midi tables 255 */ 256 void 257 snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp) 258 { 259 guard(spinlock_irq)(®ister_lock); 260 dp->max_mididev = max_midi_devs; 261 } 262 263 /* 264 * clean up midi tables 265 */ 266 void 267 snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp) 268 { 269 int i; 270 for (i = 0; i < dp->max_mididev; i++) 271 snd_seq_oss_midi_close(dp, i); 272 dp->max_mididev = 0; 273 } 274 275 276 /* 277 * open all midi devices. ignore errors. 278 */ 279 void 280 snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode) 281 { 282 int i; 283 for (i = 0; i < dp->max_mididev; i++) 284 snd_seq_oss_midi_open(dp, i, file_mode); 285 } 286 287 288 /* 289 * get the midi device information 290 */ 291 static struct seq_oss_midi * 292 get_mididev(struct seq_oss_devinfo *dp, int dev) 293 { 294 if (dev < 0 || dev >= dp->max_mididev) 295 return NULL; 296 dev = array_index_nospec(dev, dp->max_mididev); 297 return get_mdev(dev); 298 } 299 300 301 /* 302 * open the midi device if not opened yet 303 */ 304 int 305 snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) 306 { 307 int perm; 308 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 309 struct snd_seq_port_subscribe subs; 310 311 mdev = get_mididev(dp, dev); 312 if (!mdev) 313 return -ENODEV; 314 315 guard(mutex)(&mdev->open_mutex); 316 /* already used? */ 317 if (mdev->opened && mdev->devinfo != dp) 318 return -EBUSY; 319 320 perm = 0; 321 if (is_write_mode(fmode)) 322 perm |= PERM_WRITE; 323 if (is_read_mode(fmode)) 324 perm |= PERM_READ; 325 perm &= mdev->flags; 326 if (perm == 0) 327 return -ENXIO; 328 329 /* already opened? */ 330 if ((mdev->opened & perm) == perm) 331 return 0; 332 333 perm &= ~mdev->opened; 334 335 memset(&subs, 0, sizeof(subs)); 336 337 if (perm & PERM_WRITE) { 338 subs.sender = dp->addr; 339 subs.dest.client = mdev->client; 340 subs.dest.port = mdev->port; 341 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0) 342 mdev->opened |= PERM_WRITE; 343 } 344 if (perm & PERM_READ) { 345 subs.sender.client = mdev->client; 346 subs.sender.port = mdev->port; 347 subs.dest = dp->addr; 348 subs.flags = SNDRV_SEQ_PORT_SUBS_TIMESTAMP; 349 subs.queue = dp->queue; /* queue for timestamps */ 350 if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0) 351 mdev->opened |= PERM_READ; 352 } 353 354 if (!mdev->opened) 355 return -ENXIO; 356 357 mdev->devinfo = dp; 358 return 0; 359 } 360 361 /* 362 * close the midi device if already opened 363 */ 364 int 365 snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev) 366 { 367 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 368 struct snd_seq_port_subscribe subs; 369 370 mdev = get_mididev(dp, dev); 371 if (!mdev) 372 return -ENODEV; 373 guard(mutex)(&mdev->open_mutex); 374 if (!mdev->opened || mdev->devinfo != dp) 375 return 0; 376 377 memset(&subs, 0, sizeof(subs)); 378 if (mdev->opened & PERM_WRITE) { 379 subs.sender = dp->addr; 380 subs.dest.client = mdev->client; 381 subs.dest.port = mdev->port; 382 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs); 383 } 384 if (mdev->opened & PERM_READ) { 385 subs.sender.client = mdev->client; 386 subs.sender.port = mdev->port; 387 subs.dest = dp->addr; 388 snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, &subs); 389 } 390 391 mdev->opened = 0; 392 mdev->devinfo = NULL; 393 return 0; 394 } 395 396 /* 397 * change seq capability flags to file mode flags 398 */ 399 int 400 snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev) 401 { 402 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 403 int mode; 404 405 mdev = get_mididev(dp, dev); 406 if (!mdev) 407 return 0; 408 409 mode = 0; 410 if (mdev->opened & PERM_WRITE) 411 mode |= SNDRV_SEQ_OSS_FILE_WRITE; 412 if (mdev->opened & PERM_READ) 413 mode |= SNDRV_SEQ_OSS_FILE_READ; 414 415 return mode; 416 } 417 418 /* 419 * reset the midi device and close it: 420 * so far, only close the device. 421 */ 422 void 423 snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev) 424 { 425 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 426 427 mdev = get_mididev(dp, dev); 428 if (!mdev) 429 return; 430 if (!mdev->opened) 431 return; 432 433 if (mdev->opened & PERM_WRITE) { 434 struct snd_seq_event ev; 435 int c; 436 437 memset(&ev, 0, sizeof(ev)); 438 ev.dest.client = mdev->client; 439 ev.dest.port = mdev->port; 440 ev.queue = dp->queue; 441 ev.source.port = dp->port; 442 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) { 443 ev.type = SNDRV_SEQ_EVENT_SENSING; 444 snd_seq_oss_dispatch(dp, &ev, 0, 0); 445 } 446 for (c = 0; c < 16; c++) { 447 ev.type = SNDRV_SEQ_EVENT_CONTROLLER; 448 ev.data.control.channel = c; 449 ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF; 450 snd_seq_oss_dispatch(dp, &ev, 0, 0); 451 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) { 452 ev.data.control.param = 453 MIDI_CTL_RESET_CONTROLLERS; 454 snd_seq_oss_dispatch(dp, &ev, 0, 0); 455 ev.type = SNDRV_SEQ_EVENT_PITCHBEND; 456 ev.data.control.value = 0; 457 snd_seq_oss_dispatch(dp, &ev, 0, 0); 458 } 459 } 460 } 461 // snd_seq_oss_midi_close(dp, dev); 462 } 463 464 465 /* 466 * get client/port of the specified MIDI device 467 */ 468 void 469 snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr) 470 { 471 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 472 473 mdev = get_mididev(dp, dev); 474 if (!mdev) 475 return; 476 addr->client = mdev->client; 477 addr->port = mdev->port; 478 } 479 480 481 /* 482 * input callback - this can be atomic 483 */ 484 int 485 snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data) 486 { 487 struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data; 488 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 489 490 if (dp->readq == NULL) 491 return 0; 492 mdev = find_slot(ev->source.client, ev->source.port); 493 if (!mdev) 494 return 0; 495 if (!(mdev->opened & PERM_READ)) 496 return 0; 497 498 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) 499 return send_synth_event(dp, ev, mdev->seq_device); 500 else 501 return send_midi_event(dp, ev, mdev); 502 } 503 504 /* 505 * convert ALSA sequencer event to OSS synth event 506 */ 507 static int 508 send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev) 509 { 510 union evrec ossev; 511 512 memset(&ossev, 0, sizeof(ossev)); 513 514 switch (ev->type) { 515 case SNDRV_SEQ_EVENT_NOTEON: 516 ossev.v.cmd = MIDI_NOTEON; break; 517 case SNDRV_SEQ_EVENT_NOTEOFF: 518 ossev.v.cmd = MIDI_NOTEOFF; break; 519 case SNDRV_SEQ_EVENT_KEYPRESS: 520 ossev.v.cmd = MIDI_KEY_PRESSURE; break; 521 case SNDRV_SEQ_EVENT_CONTROLLER: 522 ossev.l.cmd = MIDI_CTL_CHANGE; break; 523 case SNDRV_SEQ_EVENT_PGMCHANGE: 524 ossev.l.cmd = MIDI_PGM_CHANGE; break; 525 case SNDRV_SEQ_EVENT_CHANPRESS: 526 ossev.l.cmd = MIDI_CHN_PRESSURE; break; 527 case SNDRV_SEQ_EVENT_PITCHBEND: 528 ossev.l.cmd = MIDI_PITCH_BEND; break; 529 default: 530 return 0; /* not supported */ 531 } 532 533 ossev.v.dev = dev; 534 535 switch (ev->type) { 536 case SNDRV_SEQ_EVENT_NOTEON: 537 case SNDRV_SEQ_EVENT_NOTEOFF: 538 case SNDRV_SEQ_EVENT_KEYPRESS: 539 ossev.v.code = EV_CHN_VOICE; 540 ossev.v.note = ev->data.note.note; 541 ossev.v.parm = ev->data.note.velocity; 542 ossev.v.chn = ev->data.note.channel; 543 break; 544 case SNDRV_SEQ_EVENT_CONTROLLER: 545 case SNDRV_SEQ_EVENT_PGMCHANGE: 546 case SNDRV_SEQ_EVENT_CHANPRESS: 547 ossev.l.code = EV_CHN_COMMON; 548 ossev.l.p1 = ev->data.control.param; 549 ossev.l.val = ev->data.control.value; 550 ossev.l.chn = ev->data.control.channel; 551 break; 552 case SNDRV_SEQ_EVENT_PITCHBEND: 553 ossev.l.code = EV_CHN_COMMON; 554 ossev.l.val = ev->data.control.value + 8192; 555 ossev.l.chn = ev->data.control.channel; 556 break; 557 } 558 559 snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode); 560 snd_seq_oss_readq_put_event(dp->readq, &ossev); 561 562 return 0; 563 } 564 565 /* 566 * decode event and send MIDI bytes to read queue 567 */ 568 static int 569 send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev) 570 { 571 char msg[32]; 572 int len; 573 574 snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode); 575 if (!dp->timer->running) 576 len = snd_seq_oss_timer_start(dp->timer); 577 if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { 578 snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev); 579 snd_midi_event_reset_decode(mdev->coder); 580 } else { 581 len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); 582 if (len > 0) 583 snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, msg, len); 584 } 585 586 return 0; 587 } 588 589 590 /* 591 * dump midi data 592 * return 0 : enqueued 593 * non-zero : invalid - ignored 594 */ 595 int 596 snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, struct snd_seq_event *ev) 597 { 598 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 599 600 mdev = get_mididev(dp, dev); 601 if (!mdev) 602 return -ENODEV; 603 if (snd_midi_event_encode_byte(mdev->coder, c, ev)) { 604 snd_seq_oss_fill_addr(dp, ev, mdev->client, mdev->port); 605 return 0; 606 } 607 return -EINVAL; 608 } 609 610 /* 611 * create OSS compatible midi_info record 612 */ 613 int 614 snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf) 615 { 616 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 617 618 mdev = get_mididev(dp, dev); 619 if (!mdev) 620 return -ENXIO; 621 inf->device = dev; 622 inf->dev_type = 0; /* FIXME: ?? */ 623 inf->capabilities = 0; /* FIXME: ?? */ 624 strscpy(inf->name, mdev->name, sizeof(inf->name)); 625 return 0; 626 } 627 628 629 #ifdef CONFIG_SND_PROC_FS 630 /* 631 * proc interface 632 */ 633 static char * 634 capmode_str(int val) 635 { 636 val &= PERM_READ|PERM_WRITE; 637 if (val == (PERM_READ|PERM_WRITE)) 638 return "read/write"; 639 else if (val == PERM_READ) 640 return "read"; 641 else if (val == PERM_WRITE) 642 return "write"; 643 else 644 return "none"; 645 } 646 647 void 648 snd_seq_oss_midi_info_read(struct snd_info_buffer *buf) 649 { 650 int i; 651 652 snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs); 653 for (i = 0; i < max_midi_devs; i++) { 654 struct seq_oss_midi *mdev __free(seq_oss_midi) = NULL; 655 656 snd_iprintf(buf, "\nmidi %d: ", i); 657 mdev = get_mdev(i); 658 if (mdev == NULL) { 659 snd_iprintf(buf, "*empty*\n"); 660 continue; 661 } 662 snd_iprintf(buf, "[%s] ALSA port %d:%d\n", mdev->name, 663 mdev->client, mdev->port); 664 snd_iprintf(buf, " capability %s / opened %s\n", 665 capmode_str(mdev->flags), 666 capmode_str(mdev->opened)); 667 } 668 } 669 #endif /* CONFIG_SND_PROC_FS */ 670