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