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"
31 static int snd_seq_oss_synth_info_user(struct seq_oss_devinfo
*dp
, void __user
*arg
)
33 struct synth_info info
;
35 if (copy_from_user(&info
, arg
, sizeof(info
)))
37 if (snd_seq_oss_synth_make_info(dp
, info
.device
, &info
) < 0)
39 if (copy_to_user(arg
, &info
, sizeof(info
)))
44 static int snd_seq_oss_midi_info_user(struct seq_oss_devinfo
*dp
, void __user
*arg
)
46 struct midi_info info
;
48 if (copy_from_user(&info
, arg
, sizeof(info
)))
50 if (snd_seq_oss_midi_make_info(dp
, info
.device
, &info
) < 0)
52 if (copy_to_user(arg
, &info
, sizeof(info
)))
57 static int snd_seq_oss_oob_user(struct seq_oss_devinfo
*dp
, void __user
*arg
)
60 struct snd_seq_event tmpev
;
62 if (copy_from_user(ev
, arg
, 8))
64 memset(&tmpev
, 0, sizeof(tmpev
));
65 snd_seq_oss_fill_addr(dp
, &tmpev
, dp
->addr
.port
, dp
->addr
.client
);
67 if (! snd_seq_oss_process_event(dp
, (union evrec
*)ev
, &tmpev
)) {
68 snd_seq_oss_dispatch(dp
, &tmpev
, 0, 0);
74 snd_seq_oss_ioctl(struct seq_oss_devinfo
*dp
, unsigned int cmd
, unsigned long carg
)
77 void __user
*arg
= (void __user
*)carg
;
81 case SNDCTL_TMR_TIMEBASE
:
82 case SNDCTL_TMR_TEMPO
:
83 case SNDCTL_TMR_START
:
85 case SNDCTL_TMR_CONTINUE
:
86 case SNDCTL_TMR_METRONOME
:
87 case SNDCTL_TMR_SOURCE
:
88 case SNDCTL_TMR_SELECT
:
89 case SNDCTL_SEQ_CTRLRATE
:
90 return snd_seq_oss_timer_ioctl(dp
->timer
, cmd
, arg
);
92 case SNDCTL_SEQ_PANIC
:
93 debug_printk(("panic\n"));
94 snd_seq_oss_reset(dp
);
98 debug_printk(("sync\n"));
99 if (! is_write_mode(dp
->file_mode
) || dp
->writeq
== NULL
)
101 while (snd_seq_oss_writeq_sync(dp
->writeq
))
103 if (signal_pending(current
))
107 case SNDCTL_SEQ_RESET
:
108 debug_printk(("reset\n"));
109 snd_seq_oss_reset(dp
);
112 case SNDCTL_SEQ_TESTMIDI
:
113 debug_printk(("test midi\n"));
114 if (get_user(dev
, p
))
116 return snd_seq_oss_midi_open(dp
, dev
, dp
->file_mode
);
118 case SNDCTL_SEQ_GETINCOUNT
:
119 debug_printk(("get in count\n"));
120 if (dp
->readq
== NULL
|| ! is_read_mode(dp
->file_mode
))
122 return put_user(dp
->readq
->qlen
, p
) ? -EFAULT
: 0;
124 case SNDCTL_SEQ_GETOUTCOUNT
:
125 debug_printk(("get out count\n"));
126 if (! is_write_mode(dp
->file_mode
) || dp
->writeq
== NULL
)
128 return put_user(snd_seq_oss_writeq_get_free_size(dp
->writeq
), p
) ? -EFAULT
: 0;
130 case SNDCTL_SEQ_GETTIME
:
131 debug_printk(("get time\n"));
132 return put_user(snd_seq_oss_timer_cur_tick(dp
->timer
), p
) ? -EFAULT
: 0;
134 case SNDCTL_SEQ_RESETSAMPLES
:
135 debug_printk(("reset samples\n"));
136 if (get_user(dev
, p
))
138 return snd_seq_oss_synth_ioctl(dp
, dev
, cmd
, carg
);
140 case SNDCTL_SEQ_NRSYNTHS
:
141 debug_printk(("nr synths\n"));
142 return put_user(dp
->max_synthdev
, p
) ? -EFAULT
: 0;
144 case SNDCTL_SEQ_NRMIDIS
:
145 debug_printk(("nr midis\n"));
146 return put_user(dp
->max_mididev
, p
) ? -EFAULT
: 0;
148 case SNDCTL_SYNTH_MEMAVL
:
149 debug_printk(("mem avail\n"));
150 if (get_user(dev
, p
))
152 val
= snd_seq_oss_synth_ioctl(dp
, dev
, cmd
, carg
);
153 return put_user(val
, p
) ? -EFAULT
: 0;
155 case SNDCTL_FM_4OP_ENABLE
:
156 debug_printk(("4op\n"));
157 if (get_user(dev
, p
))
159 snd_seq_oss_synth_ioctl(dp
, dev
, cmd
, carg
);
162 case SNDCTL_SYNTH_INFO
:
163 case SNDCTL_SYNTH_ID
:
164 debug_printk(("synth info\n"));
165 return snd_seq_oss_synth_info_user(dp
, arg
);
167 case SNDCTL_SEQ_OUTOFBAND
:
168 debug_printk(("out of band\n"));
169 return snd_seq_oss_oob_user(dp
, arg
);
171 case SNDCTL_MIDI_INFO
:
172 debug_printk(("midi info\n"));
173 return snd_seq_oss_midi_info_user(dp
, arg
);
175 case SNDCTL_SEQ_THRESHOLD
:
176 debug_printk(("threshold\n"));
177 if (! is_write_mode(dp
->file_mode
))
179 if (get_user(val
, p
))
183 if (val
>= dp
->writeq
->maxlen
)
184 val
= dp
->writeq
->maxlen
- 1;
185 snd_seq_oss_writeq_set_output(dp
->writeq
, val
);
188 case SNDCTL_MIDI_PRETIME
:
189 debug_printk(("pretime\n"));
190 if (dp
->readq
== NULL
|| !is_read_mode(dp
->file_mode
))
192 if (get_user(val
, p
))
197 val
= (HZ
* val
) / 10;
198 dp
->readq
->pre_event_timeout
= val
;
199 return put_user(val
, p
) ? -EFAULT
: 0;
202 debug_printk(("others\n"));
203 if (! is_write_mode(dp
->file_mode
))
205 return snd_seq_oss_synth_ioctl(dp
, 0, cmd
, carg
);