1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * OSS compatible sequencer driver 4 * 5 * synth device handlers 6 * 7 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de> 8 */ 9 10 #include "seq_oss_synth.h" 11 #include "seq_oss_midi.h" 12 #include "../seq_lock.h" 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/slab.h> 16 #include <linux/nospec.h> 17 18 /* 19 * constants 20 */ 21 #define SNDRV_SEQ_OSS_MAX_SYNTH_NAME 30 22 #define MAX_SYSEX_BUFLEN 128 23 24 25 /* 26 * definition of synth info records 27 */ 28 29 /* sysex buffer */ 30 struct seq_oss_synth_sysex { 31 int len; 32 int skip; 33 unsigned char buf[MAX_SYSEX_BUFLEN]; 34 }; 35 36 /* synth info */ 37 struct seq_oss_synth { 38 int seq_device; 39 40 /* for synth_info */ 41 int synth_type; 42 int synth_subtype; 43 int nr_voices; 44 45 char name[SNDRV_SEQ_OSS_MAX_SYNTH_NAME]; 46 struct snd_seq_oss_callback oper; 47 48 int opened; 49 50 void *private_data; 51 snd_use_lock_t use_lock; 52 }; 53 54 55 /* 56 * device table 57 */ 58 static int max_synth_devs; 59 static struct seq_oss_synth *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS]; 60 static struct seq_oss_synth midi_synth_dev = { 61 .seq_device = -1, 62 .synth_type = SYNTH_TYPE_MIDI, 63 .synth_subtype = 0, 64 .nr_voices = 16, 65 .name = "MIDI", 66 }; 67 68 static DEFINE_SPINLOCK(register_lock); 69 70 /* 71 * prototypes 72 */ 73 static struct seq_oss_synth *get_synthdev(struct seq_oss_devinfo *dp, int dev); 74 static void reset_channels(struct seq_oss_synthinfo *info); 75 76 /* 77 * global initialization 78 */ 79 void __init 80 snd_seq_oss_synth_init(void) 81 { 82 snd_use_lock_init(&midi_synth_dev.use_lock); 83 } 84 85 /* 86 * registration of the synth device 87 */ 88 int 89 snd_seq_oss_synth_probe(struct device *_dev) 90 { 91 struct snd_seq_device *dev = to_seq_dev(_dev); 92 int i; 93 struct seq_oss_synth *rec; 94 struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev); 95 unsigned long flags; 96 97 rec = kzalloc(sizeof(*rec), GFP_KERNEL); 98 if (!rec) 99 return -ENOMEM; 100 rec->seq_device = -1; 101 rec->synth_type = reg->type; 102 rec->synth_subtype = reg->subtype; 103 rec->nr_voices = reg->nvoices; 104 rec->oper = reg->oper; 105 rec->private_data = reg->private_data; 106 rec->opened = 0; 107 snd_use_lock_init(&rec->use_lock); 108 109 /* copy and truncate the name of synth device */ 110 strscpy(rec->name, dev->name, sizeof(rec->name)); 111 112 /* registration */ 113 spin_lock_irqsave(®ister_lock, flags); 114 for (i = 0; i < max_synth_devs; i++) { 115 if (synth_devs[i] == NULL) 116 break; 117 } 118 if (i >= max_synth_devs) { 119 if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) { 120 spin_unlock_irqrestore(®ister_lock, flags); 121 pr_err("ALSA: seq_oss: no more synth slot\n"); 122 kfree(rec); 123 return -ENOMEM; 124 } 125 max_synth_devs++; 126 } 127 rec->seq_device = i; 128 synth_devs[i] = rec; 129 spin_unlock_irqrestore(®ister_lock, flags); 130 dev->driver_data = rec; 131 #ifdef SNDRV_OSS_INFO_DEV_SYNTH 132 if (i < SNDRV_CARDS) 133 snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name); 134 #endif 135 return 0; 136 } 137 138 139 int 140 snd_seq_oss_synth_remove(struct device *_dev) 141 { 142 struct snd_seq_device *dev = to_seq_dev(_dev); 143 int index; 144 struct seq_oss_synth *rec = dev->driver_data; 145 unsigned long flags; 146 147 spin_lock_irqsave(®ister_lock, flags); 148 for (index = 0; index < max_synth_devs; index++) { 149 if (synth_devs[index] == rec) 150 break; 151 } 152 if (index >= max_synth_devs) { 153 spin_unlock_irqrestore(®ister_lock, flags); 154 pr_err("ALSA: seq_oss: can't unregister synth\n"); 155 return -EINVAL; 156 } 157 synth_devs[index] = NULL; 158 if (index == max_synth_devs - 1) { 159 for (index--; index >= 0; index--) { 160 if (synth_devs[index]) 161 break; 162 } 163 max_synth_devs = index + 1; 164 } 165 spin_unlock_irqrestore(®ister_lock, flags); 166 #ifdef SNDRV_OSS_INFO_DEV_SYNTH 167 if (rec->seq_device < SNDRV_CARDS) 168 snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_SYNTH, rec->seq_device); 169 #endif 170 171 snd_use_lock_sync(&rec->use_lock); 172 kfree(rec); 173 174 return 0; 175 } 176 177 178 /* 179 */ 180 static struct seq_oss_synth * 181 get_sdev(int dev) 182 { 183 struct seq_oss_synth *rec; 184 unsigned long flags; 185 186 spin_lock_irqsave(®ister_lock, flags); 187 rec = synth_devs[dev]; 188 if (rec) 189 snd_use_lock_use(&rec->use_lock); 190 spin_unlock_irqrestore(®ister_lock, flags); 191 return rec; 192 } 193 194 195 /* 196 * set up synth tables 197 */ 198 199 void 200 snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp) 201 { 202 int i; 203 struct seq_oss_synth *rec; 204 struct seq_oss_synthinfo *info; 205 206 dp->max_synthdev = max_synth_devs; 207 dp->synth_opened = 0; 208 memset(dp->synths, 0, sizeof(dp->synths)); 209 for (i = 0; i < dp->max_synthdev; i++) { 210 rec = get_sdev(i); 211 if (rec == NULL) 212 continue; 213 if (rec->oper.open == NULL || rec->oper.close == NULL) { 214 snd_use_lock_free(&rec->use_lock); 215 continue; 216 } 217 info = &dp->synths[i]; 218 info->arg.app_index = dp->port; 219 info->arg.file_mode = dp->file_mode; 220 info->arg.seq_mode = dp->seq_mode; 221 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) 222 info->arg.event_passing = SNDRV_SEQ_OSS_PROCESS_EVENTS; 223 else 224 info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS; 225 info->opened = 0; 226 if (!try_module_get(rec->oper.owner)) { 227 snd_use_lock_free(&rec->use_lock); 228 continue; 229 } 230 if (rec->oper.open(&info->arg, rec->private_data) < 0) { 231 module_put(rec->oper.owner); 232 snd_use_lock_free(&rec->use_lock); 233 continue; 234 } 235 info->nr_voices = rec->nr_voices; 236 if (info->nr_voices > 0) { 237 info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL); 238 if (!info->ch) { 239 rec->oper.close(&info->arg); 240 module_put(rec->oper.owner); 241 snd_use_lock_free(&rec->use_lock); 242 continue; 243 } 244 reset_channels(info); 245 } 246 info->opened++; 247 rec->opened++; 248 dp->synth_opened++; 249 snd_use_lock_free(&rec->use_lock); 250 } 251 } 252 253 254 /* 255 * set up synth tables for MIDI emulation - /dev/music mode only 256 */ 257 258 void 259 snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo *dp) 260 { 261 int i; 262 263 if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) 264 return; 265 266 for (i = 0; i < dp->max_mididev; i++) { 267 struct seq_oss_synthinfo *info; 268 info = &dp->synths[dp->max_synthdev]; 269 if (snd_seq_oss_midi_open(dp, i, dp->file_mode) < 0) 270 continue; 271 info->arg.app_index = dp->port; 272 info->arg.file_mode = dp->file_mode; 273 info->arg.seq_mode = dp->seq_mode; 274 info->arg.private_data = info; 275 info->is_midi = 1; 276 info->midi_mapped = i; 277 info->arg.event_passing = SNDRV_SEQ_OSS_PASS_EVENTS; 278 snd_seq_oss_midi_get_addr(dp, i, &info->arg.addr); 279 info->opened = 1; 280 midi_synth_dev.opened++; 281 dp->max_synthdev++; 282 if (dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) 283 break; 284 } 285 } 286 287 288 /* 289 * clean up synth tables 290 */ 291 292 void 293 snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp) 294 { 295 int i; 296 struct seq_oss_synth *rec; 297 struct seq_oss_synthinfo *info; 298 299 if (snd_BUG_ON(dp->max_synthdev > SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)) 300 return; 301 for (i = 0; i < dp->max_synthdev; i++) { 302 info = &dp->synths[i]; 303 if (! info->opened) 304 continue; 305 if (info->is_midi) { 306 if (midi_synth_dev.opened > 0) { 307 snd_seq_oss_midi_close(dp, info->midi_mapped); 308 midi_synth_dev.opened--; 309 } 310 } else { 311 rec = get_sdev(i); 312 if (rec == NULL) 313 continue; 314 if (rec->opened > 0) { 315 rec->oper.close(&info->arg); 316 module_put(rec->oper.owner); 317 rec->opened = 0; 318 } 319 snd_use_lock_free(&rec->use_lock); 320 } 321 kfree(info->sysex); 322 info->sysex = NULL; 323 kfree(info->ch); 324 info->ch = NULL; 325 } 326 dp->synth_opened = 0; 327 dp->max_synthdev = 0; 328 } 329 330 static struct seq_oss_synthinfo * 331 get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev) 332 { 333 if (dev < 0 || dev >= dp->max_synthdev) 334 return NULL; 335 dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS); 336 return &dp->synths[dev]; 337 } 338 339 /* 340 * return synth device information pointer 341 */ 342 static struct seq_oss_synth * 343 get_synthdev(struct seq_oss_devinfo *dp, int dev) 344 { 345 struct seq_oss_synth *rec; 346 struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev); 347 348 if (!info) 349 return NULL; 350 if (!info->opened) 351 return NULL; 352 if (info->is_midi) { 353 rec = &midi_synth_dev; 354 snd_use_lock_use(&rec->use_lock); 355 } else { 356 rec = get_sdev(dev); 357 if (!rec) 358 return NULL; 359 } 360 if (! rec->opened) { 361 snd_use_lock_free(&rec->use_lock); 362 return NULL; 363 } 364 return rec; 365 } 366 367 368 /* 369 * reset note and velocity on each channel. 370 */ 371 static void 372 reset_channels(struct seq_oss_synthinfo *info) 373 { 374 int i; 375 if (info->ch == NULL || ! info->nr_voices) 376 return; 377 for (i = 0; i < info->nr_voices; i++) { 378 info->ch[i].note = -1; 379 info->ch[i].vel = 0; 380 } 381 } 382 383 384 /* 385 * reset synth device: 386 * call reset callback. if no callback is defined, send a heartbeat 387 * event to the corresponding port. 388 */ 389 void 390 snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev) 391 { 392 struct seq_oss_synth *rec; 393 struct seq_oss_synthinfo *info; 394 395 info = get_synthinfo_nospec(dp, dev); 396 if (!info || !info->opened) 397 return; 398 if (info->sysex) 399 info->sysex->len = 0; /* reset sysex */ 400 reset_channels(info); 401 if (info->is_midi) { 402 if (midi_synth_dev.opened <= 0) 403 return; 404 snd_seq_oss_midi_reset(dp, info->midi_mapped); 405 /* reopen the device */ 406 snd_seq_oss_midi_close(dp, dev); 407 if (snd_seq_oss_midi_open(dp, info->midi_mapped, 408 dp->file_mode) < 0) { 409 midi_synth_dev.opened--; 410 info->opened = 0; 411 kfree(info->sysex); 412 info->sysex = NULL; 413 kfree(info->ch); 414 info->ch = NULL; 415 } 416 return; 417 } 418 419 rec = get_sdev(dev); 420 if (rec == NULL) 421 return; 422 if (rec->oper.reset) { 423 rec->oper.reset(&info->arg); 424 } else { 425 struct snd_seq_event ev; 426 memset(&ev, 0, sizeof(ev)); 427 snd_seq_oss_fill_addr(dp, &ev, info->arg.addr.client, 428 info->arg.addr.port); 429 ev.type = SNDRV_SEQ_EVENT_RESET; 430 snd_seq_oss_dispatch(dp, &ev, 0, 0); 431 } 432 snd_use_lock_free(&rec->use_lock); 433 } 434 435 436 /* 437 * load a patch record: 438 * call load_patch callback function 439 */ 440 int 441 snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt, 442 const char __user *buf, int p, int c) 443 { 444 struct seq_oss_synth *rec; 445 struct seq_oss_synthinfo *info; 446 int rc; 447 448 info = get_synthinfo_nospec(dp, dev); 449 if (!info) 450 return -ENXIO; 451 452 if (info->is_midi) 453 return 0; 454 if ((rec = get_synthdev(dp, dev)) == NULL) 455 return -ENXIO; 456 457 if (rec->oper.load_patch == NULL) 458 rc = -ENXIO; 459 else 460 rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c); 461 snd_use_lock_free(&rec->use_lock); 462 return rc; 463 } 464 465 /* 466 * check if the device is valid synth device and return the synth info 467 */ 468 struct seq_oss_synthinfo * 469 snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev) 470 { 471 struct seq_oss_synth *rec; 472 473 rec = get_synthdev(dp, dev); 474 if (rec) { 475 snd_use_lock_free(&rec->use_lock); 476 return get_synthinfo_nospec(dp, dev); 477 } 478 return NULL; 479 } 480 481 482 /* 483 * receive OSS 6 byte sysex packet: 484 * the full sysex message will be sent if it reaches to the end of data 485 * (0xff). 486 */ 487 int 488 snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, struct snd_seq_event *ev) 489 { 490 int i, send; 491 unsigned char *dest; 492 struct seq_oss_synth_sysex *sysex; 493 struct seq_oss_synthinfo *info; 494 495 info = snd_seq_oss_synth_info(dp, dev); 496 if (!info) 497 return -ENXIO; 498 499 sysex = info->sysex; 500 if (sysex == NULL) { 501 sysex = kzalloc(sizeof(*sysex), GFP_KERNEL); 502 if (sysex == NULL) 503 return -ENOMEM; 504 info->sysex = sysex; 505 } 506 507 send = 0; 508 dest = sysex->buf + sysex->len; 509 /* copy 6 byte packet to the buffer */ 510 for (i = 0; i < 6; i++) { 511 if (buf[i] == 0xff) { 512 send = 1; 513 break; 514 } 515 dest[i] = buf[i]; 516 sysex->len++; 517 if (sysex->len >= MAX_SYSEX_BUFLEN) { 518 sysex->len = 0; 519 sysex->skip = 1; 520 break; 521 } 522 } 523 524 if (sysex->len && send) { 525 if (sysex->skip) { 526 sysex->skip = 0; 527 sysex->len = 0; 528 return -EINVAL; /* skip */ 529 } 530 /* copy the data to event record and send it */ 531 ev->flags = SNDRV_SEQ_EVENT_LENGTH_VARIABLE; 532 if (snd_seq_oss_synth_addr(dp, dev, ev)) 533 return -EINVAL; 534 ev->data.ext.len = sysex->len; 535 ev->data.ext.ptr = sysex->buf; 536 sysex->len = 0; 537 return 0; 538 } 539 540 return -EINVAL; /* skip */ 541 } 542 543 /* 544 * fill the event source/destination addresses 545 */ 546 int 547 snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev) 548 { 549 struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev); 550 551 if (!info) 552 return -EINVAL; 553 snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client, 554 info->arg.addr.port); 555 return 0; 556 } 557 558 559 /* 560 * OSS compatible ioctl 561 */ 562 int 563 snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr) 564 { 565 struct seq_oss_synth *rec; 566 struct seq_oss_synthinfo *info; 567 int rc; 568 569 info = get_synthinfo_nospec(dp, dev); 570 if (!info || info->is_midi) 571 return -ENXIO; 572 if ((rec = get_synthdev(dp, dev)) == NULL) 573 return -ENXIO; 574 if (rec->oper.ioctl == NULL) 575 rc = -ENXIO; 576 else 577 rc = rec->oper.ioctl(&info->arg, cmd, addr); 578 snd_use_lock_free(&rec->use_lock); 579 return rc; 580 } 581 582 583 /* 584 * send OSS raw events - SEQ_PRIVATE and SEQ_VOLUME 585 */ 586 int 587 snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev) 588 { 589 struct seq_oss_synthinfo *info; 590 591 info = snd_seq_oss_synth_info(dp, dev); 592 if (!info || info->is_midi) 593 return -ENXIO; 594 ev->type = SNDRV_SEQ_EVENT_OSS; 595 memcpy(ev->data.raw8.d, data, 8); 596 return snd_seq_oss_synth_addr(dp, dev, ev); 597 } 598 599 600 /* 601 * create OSS compatible synth_info record 602 */ 603 int 604 snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf) 605 { 606 struct seq_oss_synth *rec; 607 struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev); 608 609 if (!info) 610 return -ENXIO; 611 612 if (info->is_midi) { 613 struct midi_info minf; 614 if (snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf)) 615 return -ENXIO; 616 inf->synth_type = SYNTH_TYPE_MIDI; 617 inf->synth_subtype = 0; 618 inf->nr_voices = 16; 619 inf->device = dev; 620 strscpy(inf->name, minf.name, sizeof(inf->name)); 621 } else { 622 if ((rec = get_synthdev(dp, dev)) == NULL) 623 return -ENXIO; 624 inf->synth_type = rec->synth_type; 625 inf->synth_subtype = rec->synth_subtype; 626 inf->nr_voices = rec->nr_voices; 627 inf->device = dev; 628 strscpy(inf->name, rec->name, sizeof(inf->name)); 629 snd_use_lock_free(&rec->use_lock); 630 } 631 return 0; 632 } 633 634 635 #ifdef CONFIG_SND_PROC_FS 636 /* 637 * proc interface 638 */ 639 void 640 snd_seq_oss_synth_info_read(struct snd_info_buffer *buf) 641 { 642 int i; 643 struct seq_oss_synth *rec; 644 645 snd_iprintf(buf, "\nNumber of synth devices: %d\n", max_synth_devs); 646 for (i = 0; i < max_synth_devs; i++) { 647 snd_iprintf(buf, "\nsynth %d: ", i); 648 rec = get_sdev(i); 649 if (rec == NULL) { 650 snd_iprintf(buf, "*empty*\n"); 651 continue; 652 } 653 snd_iprintf(buf, "[%s]\n", rec->name); 654 snd_iprintf(buf, " type 0x%x : subtype 0x%x : voices %d\n", 655 rec->synth_type, rec->synth_subtype, 656 rec->nr_voices); 657 snd_iprintf(buf, " capabilities : ioctl %s / load_patch %s\n", 658 enabled_str((long)rec->oper.ioctl), 659 enabled_str((long)rec->oper.load_patch)); 660 snd_use_lock_free(&rec->use_lock); 661 } 662 } 663 #endif /* CONFIG_SND_PROC_FS */ 664