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
snd_seq_oss_synth_init(void)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
snd_seq_oss_synth_probe(struct device * _dev)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
snd_seq_oss_synth_remove(struct device * _dev)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 *
get_sdev(int dev)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
snd_seq_oss_synth_setup(struct seq_oss_devinfo * dp)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
snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo * dp)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
snd_seq_oss_synth_cleanup(struct seq_oss_devinfo * dp)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 *
get_synthinfo_nospec(struct seq_oss_devinfo * dp,int dev)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 *
get_synthdev(struct seq_oss_devinfo * dp,int dev)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
reset_channels(struct seq_oss_synthinfo * info)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
snd_seq_oss_synth_reset(struct seq_oss_devinfo * dp,int dev)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
snd_seq_oss_synth_load_patch(struct seq_oss_devinfo * dp,int dev,int fmt,const char __user * buf,int p,int c)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 *
snd_seq_oss_synth_info(struct seq_oss_devinfo * dp,int dev)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
snd_seq_oss_synth_sysex(struct seq_oss_devinfo * dp,int dev,unsigned char * buf,struct snd_seq_event * ev)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
snd_seq_oss_synth_addr(struct seq_oss_devinfo * dp,int dev,struct snd_seq_event * ev)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
snd_seq_oss_synth_ioctl(struct seq_oss_devinfo * dp,int dev,unsigned int cmd,unsigned long addr)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
snd_seq_oss_synth_raw_event(struct seq_oss_devinfo * dp,int dev,unsigned char * data,struct snd_seq_event * ev)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
snd_seq_oss_synth_make_info(struct seq_oss_devinfo * dp,int dev,struct synth_info * inf)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
snd_seq_oss_synth_info_read(struct snd_info_buffer * buf)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