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