Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * OSS compatible sequencer driver
  3  *
  4  * OSS compatible i/o control
  5  *
  6  * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
  7  *
  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.
 12  *
 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.
 17  *
 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
 21  */
 22 
 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"
 30 
 31 static int snd_seq_oss_synth_info_user(struct seq_oss_devinfo *dp, void __user *arg)
 32 {
 33         struct synth_info info;
 34 
 35         if (copy_from_user(&info, arg, sizeof(info)))
 36                 return -EFAULT;
 37         if (snd_seq_oss_synth_make_info(dp, info.device, &info) < 0)
 38                 return -EINVAL;
 39         if (copy_to_user(arg, &info, sizeof(info)))
 40                 return -EFAULT;
 41         return 0;
 42 }
 43 
 44 static int snd_seq_oss_midi_info_user(struct seq_oss_devinfo *dp, void __user *arg)
 45 {
 46         struct midi_info info;
 47 
 48         if (copy_from_user(&info, arg, sizeof(info)))
 49                 return -EFAULT;
 50         if (snd_seq_oss_midi_make_info(dp, info.device, &info) < 0)
 51                 return -EINVAL;
 52         if (copy_to_user(arg, &info, sizeof(info)))
 53                 return -EFAULT;
 54         return 0;
 55 }
 56 
 57 static int snd_seq_oss_oob_user(struct seq_oss_devinfo *dp, void __user *arg)
 58 {
 59         unsigned char ev[8];
 60         struct snd_seq_event tmpev;
 61 
 62         if (copy_from_user(ev, arg, 8))
 63                 return -EFAULT;
 64         memset(&tmpev, 0, sizeof(tmpev));
 65         snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.port, dp->addr.client);
 66         tmpev.time.tick = 0;
 67         if (! snd_seq_oss_process_event(dp, (union evrec *)ev, &tmpev)) {
 68                 snd_seq_oss_dispatch(dp, &tmpev, 0, 0);
 69         }
 70         return 0;
 71 }
 72 
 73 int
 74 snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long carg)
 75 {
 76         int dev, val;
 77         void __user *arg = (void __user *)carg;
 78         int __user *p = arg;
 79 
 80         switch (cmd) {
 81         case SNDCTL_TMR_TIMEBASE:
 82         case SNDCTL_TMR_TEMPO:
 83         case SNDCTL_TMR_START:
 84         case SNDCTL_TMR_STOP:
 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);
 91 
 92         case SNDCTL_SEQ_PANIC:
 93                 debug_printk(("panic\n"));
 94                 snd_seq_oss_reset(dp);
 95                 return -EINVAL;
 96 
 97         case SNDCTL_SEQ_SYNC:
 98                 debug_printk(("sync\n"));
 99                 if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
100                         return 0;
101                 while (snd_seq_oss_writeq_sync(dp->writeq))
102                         ;
103                 if (signal_pending(current))
104                         return -ERESTARTSYS;
105                 return 0;
106 
107         case SNDCTL_SEQ_RESET:
108                 debug_printk(("reset\n"));
109                 snd_seq_oss_reset(dp);
110                 return 0;
111 
112         case SNDCTL_SEQ_TESTMIDI:
113                 debug_printk(("test midi\n"));
114                 if (get_user(dev, p))
115                         return -EFAULT;
116                 return snd_seq_oss_midi_open(dp, dev, dp->file_mode);
117 
118         case SNDCTL_SEQ_GETINCOUNT:
119                 debug_printk(("get in count\n"));
120                 if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
121                         return 0;
122                 return put_user(dp->readq->qlen, p) ? -EFAULT : 0;
123 
124         case SNDCTL_SEQ_GETOUTCOUNT:
125                 debug_printk(("get out count\n"));
126                 if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
127                         return 0;
128                 return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0;
129 
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;
133 
134         case SNDCTL_SEQ_RESETSAMPLES:
135                 debug_printk(("reset samples\n"));
136                 if (get_user(dev, p))
137                         return -EFAULT;
138                 return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
139 
140         case SNDCTL_SEQ_NRSYNTHS:
141                 debug_printk(("nr synths\n"));
142                 return put_user(dp->max_synthdev, p) ? -EFAULT : 0;
143 
144         case SNDCTL_SEQ_NRMIDIS:
145                 debug_printk(("nr midis\n"));
146                 return put_user(dp->max_mididev, p) ? -EFAULT : 0;
147 
148         case SNDCTL_SYNTH_MEMAVL:
149                 debug_printk(("mem avail\n"));
150                 if (get_user(dev, p))
151                         return -EFAULT;
152                 val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
153                 return put_user(val, p) ? -EFAULT : 0;
154 
155         case SNDCTL_FM_4OP_ENABLE:
156                 debug_printk(("4op\n"));
157                 if (get_user(dev, p))
158                         return -EFAULT;
159                 snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
160                 return 0;
161 
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);
166 
167         case SNDCTL_SEQ_OUTOFBAND:
168                 debug_printk(("out of band\n"));
169                 return snd_seq_oss_oob_user(dp, arg);
170 
171         case SNDCTL_MIDI_INFO:
172                 debug_printk(("midi info\n"));
173                 return snd_seq_oss_midi_info_user(dp, arg);
174 
175         case SNDCTL_SEQ_THRESHOLD:
176                 debug_printk(("threshold\n"));
177                 if (! is_write_mode(dp->file_mode))
178                         return 0;
179                 if (get_user(val, p))
180                         return -EFAULT;
181                 if (val < 1)
182                         val = 1;
183                 if (val >= dp->writeq->maxlen)
184                         val = dp->writeq->maxlen - 1;
185                 snd_seq_oss_writeq_set_output(dp->writeq, val);
186                 return 0;
187 
188         case SNDCTL_MIDI_PRETIME:
189                 debug_printk(("pretime\n"));
190                 if (dp->readq == NULL || !is_read_mode(dp->file_mode))
191                         return 0;
192                 if (get_user(val, p))
193                         return -EFAULT;
194                 if (val <= 0)
195                         val = -1;
196                 else
197                         val = (HZ * val) / 10;
198                 dp->readq->pre_event_timeout = val;
199                 return put_user(val, p) ? -EFAULT : 0;
200 
201         default:
202                 debug_printk(("others\n"));
203                 if (! is_write_mode(dp->file_mode))
204                         return -EIO;
205                 return snd_seq_oss_synth_ioctl(dp, 0, cmd, carg);
206         }
207         return 0;
208 }
209 
210 
  This page was automatically generated by the LXR engine.