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