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