2 * OSS compatible sequencer driver
4 * OSS compatible i/o control
6 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
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.
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.
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
23 #include "seq_oss_device.h"
24 #include "seq_oss_readq.h"
25 #include "seq_oss_writeq.h"
26 #include "seq_oss_timer.h"
27 #include "seq_oss_synth.h"
28 #include "seq_oss_midi.h"
29 #include "seq_oss_event.h"
32 snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
35 struct synth_info inf;
36 struct midi_info minf;
38 void __user *arg = (void __user *)carg;
39 snd_seq_event_t tmpev;
42 case SNDCTL_TMR_TIMEBASE:
43 case SNDCTL_TMR_TEMPO:
44 case SNDCTL_TMR_START:
46 case SNDCTL_TMR_CONTINUE:
47 case SNDCTL_TMR_METRONOME:
48 case SNDCTL_TMR_SOURCE:
49 case SNDCTL_TMR_SELECT:
50 case SNDCTL_SEQ_CTRLRATE:
51 return snd_seq_oss_timer_ioctl(dp->timer, cmd, arg);
53 case SNDCTL_SEQ_PANIC:
54 debug_printk(("panic\n"));
55 snd_seq_oss_reset(dp);
59 debug_printk(("sync\n"));
60 if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
62 while (snd_seq_oss_writeq_sync(dp->writeq))
64 if (signal_pending(current))
68 case SNDCTL_SEQ_RESET:
69 debug_printk(("reset\n"));
70 snd_seq_oss_reset(dp);
73 case SNDCTL_SEQ_TESTMIDI:
74 debug_printk(("test midi\n"));
75 if (get_user(dev, (int *)arg))
77 return snd_seq_oss_midi_open(dp, dev, dp->file_mode);
79 case SNDCTL_SEQ_GETINCOUNT:
80 debug_printk(("get in count\n"));
81 if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
83 return put_user(dp->readq->qlen, (int *)arg) ? -EFAULT : 0;
85 case SNDCTL_SEQ_GETOUTCOUNT:
86 debug_printk(("get out count\n"));
87 if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
89 return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), (int *)arg) ? -EFAULT : 0;
91 case SNDCTL_SEQ_GETTIME:
92 debug_printk(("get time\n"));
93 return put_user(snd_seq_oss_timer_cur_tick(dp->timer), (int *)arg) ? -EFAULT : 0;
95 case SNDCTL_SEQ_RESETSAMPLES:
96 debug_printk(("reset samples\n"));
97 if (get_user(dev, (int *)arg))
99 return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
101 case SNDCTL_SEQ_NRSYNTHS:
102 debug_printk(("nr synths\n"));
103 return put_user(dp->max_synthdev, (int *)arg) ? -EFAULT : 0;
105 case SNDCTL_SEQ_NRMIDIS:
106 debug_printk(("nr midis\n"));
107 return put_user(dp->max_mididev, (int *)arg) ? -EFAULT : 0;
109 case SNDCTL_SYNTH_MEMAVL:
110 debug_printk(("mem avail\n"));
111 if (get_user(dev, (int *)arg))
113 val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
114 return put_user(val, (int *)arg) ? -EFAULT : 0;
116 case SNDCTL_FM_4OP_ENABLE:
117 debug_printk(("4op\n"));
118 if (get_user(dev, (int *)arg))
120 snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
123 case SNDCTL_SYNTH_INFO:
124 case SNDCTL_SYNTH_ID:
125 debug_printk(("synth info\n"));
126 if (copy_from_user(&inf, arg, sizeof(inf)))
128 if (snd_seq_oss_synth_make_info(dp, inf.device, &inf) < 0)
130 if (copy_to_user(arg, &inf, sizeof(inf)))
134 case SNDCTL_SEQ_OUTOFBAND:
135 debug_printk(("out of bound\n"));
136 if (copy_from_user(ev, arg, 8))
138 memset(&tmpev, 0, sizeof(tmpev));
139 snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.port, dp->addr.client);
141 if (! snd_seq_oss_process_event(dp, (evrec_t*)ev, &tmpev)) {
142 snd_seq_oss_dispatch(dp, &tmpev, 0, 0);
146 case SNDCTL_MIDI_INFO:
147 debug_printk(("midi info\n"));
148 if (copy_from_user(&minf, arg, sizeof(minf)))
150 if (snd_seq_oss_midi_make_info(dp, minf.device, &minf) < 0)
152 if (copy_to_user(arg, &minf, sizeof(minf)))
156 case SNDCTL_SEQ_THRESHOLD:
157 debug_printk(("threshold\n"));
158 if (! is_write_mode(dp->file_mode))
160 if (get_user(val, (int *)arg))
164 if (val >= dp->writeq->maxlen)
165 val = dp->writeq->maxlen - 1;
166 snd_seq_oss_writeq_set_output(dp->writeq, val);
169 case SNDCTL_MIDI_PRETIME:
170 debug_printk(("pretime\n"));
171 if (dp->readq == NULL || !is_read_mode(dp->file_mode))
173 if (get_user(val, (int *)arg))
178 val = (HZ * val) / 10;
179 dp->readq->pre_event_timeout = val;
180 return put_user(val, (int *)arg) ? -EFAULT : 0;
183 debug_printk(("others\n"));
184 if (! is_write_mode(dp->file_mode))
186 return snd_seq_oss_synth_ioctl(dp, 0, cmd, carg);