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