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