xref: /linux/sound/core/seq/oss/seq_oss_synth.c (revision 2c1ed907520c50326b8f604907a8478b27881a2e)
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(&register_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(&register_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(&register_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(&register_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(&register_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(&register_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(&register_lock, flags);
180 	rec = synth_devs[dev];
181 	if (rec)
182 		snd_use_lock_use(&rec->use_lock);
183 	spin_unlock_irqrestore(&register_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