patch-2.1.77 linux/drivers/sound/sequencer.c
Next file: linux/drivers/sound/softoss.c
Previous file: linux/drivers/sound/sb_mixer.c
Back to the patch index
Back to the overall index
- Lines: 510
- Date:
Tue Dec 30 11:02:39 1997
- Orig file:
v2.1.76/linux/drivers/sound/sequencer.c
- Orig date:
Tue Dec 2 09:49:39 1997
diff -u --recursive --new-file v2.1.76/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c
@@ -10,6 +10,9 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
#include <linux/config.h>
@@ -1517,303 +1520,207 @@
*/
}
-int
-sequencer_ioctl(int dev, struct fileinfo *file,
- unsigned int cmd, caddr_t arg)
+int sequencer_ioctl(int dev, struct fileinfo *file,
+ unsigned int cmd, caddr_t arg)
{
- int midi_dev, orig_dev, val;
- int mode = file->mode & O_ACCMODE;
+ int midi_dev, orig_dev, val, err;
+ int mode = file->mode & O_ACCMODE;
+ struct synth_info inf;
+ struct seq_event_rec event_rec;
+ unsigned long flags;
orig_dev = dev = dev >> 4;
- switch (cmd)
- {
- case SNDCTL_TMR_TIMEBASE:
- case SNDCTL_TMR_TEMPO:
- case SNDCTL_TMR_START:
- case SNDCTL_TMR_STOP:
- case SNDCTL_TMR_CONTINUE:
- case SNDCTL_TMR_METRONOME:
- case SNDCTL_TMR_SOURCE:
-
- if (seq_mode != SEQ_2)
- return -EINVAL;
- return tmr->ioctl(tmr_no, cmd, arg);
- break;
-
- case SNDCTL_TMR_SELECT:
-
- if (seq_mode != SEQ_2)
- return -EINVAL;
- pending_timer = *(int *) arg;
-
- if (pending_timer < 0 || pending_timer >= num_sound_timers || sound_timer_devs[pending_timer] == NULL)
- {
- pending_timer = -1;
- return -EINVAL;
- }
- return (*(int *) arg = pending_timer);
- break;
-
- case SNDCTL_SEQ_PANIC:
- seq_panic();
- break;
-
- case SNDCTL_SEQ_SYNC:
-
- if (mode == OPEN_READ)
+ switch (cmd) {
+ case SNDCTL_TMR_TIMEBASE:
+ case SNDCTL_TMR_TEMPO:
+ case SNDCTL_TMR_START:
+ case SNDCTL_TMR_STOP:
+ case SNDCTL_TMR_CONTINUE:
+ case SNDCTL_TMR_METRONOME:
+ case SNDCTL_TMR_SOURCE:
+ if (seq_mode != SEQ_2)
+ return -EINVAL;
+ return tmr->ioctl(tmr_no, cmd, arg);
+
+ case SNDCTL_TMR_SELECT:
+ if (seq_mode != SEQ_2)
+ return -EINVAL;
+ if (__get_user(pending_timer, (int *)arg))
+ return -EFAULT;
+ if (pending_timer < 0 || pending_timer >= num_sound_timers || sound_timer_devs[pending_timer] == NULL) {
+ pending_timer = -1;
+ return -EINVAL;
+ }
+ return __put_user(pending_timer, (int *)arg);
+
+ case SNDCTL_SEQ_PANIC:
+ seq_panic();
+ break;
+
+ case SNDCTL_SEQ_SYNC:
+ if (mode == OPEN_READ)
+ return 0;
+ while (qlen > 0 && !signal_pending(current))
+ seq_sync();
+ return qlen ? -EINTR : 0;
+
+ case SNDCTL_SEQ_RESET:
+ seq_reset();
+ return 0;
+
+ case SNDCTL_SEQ_TESTMIDI:
+ if (__get_user(midi_dev, (int *)arg))
+ return -EFAULT;
+ if (midi_dev < 0 || midi_dev >= max_mididev)
+ return -ENXIO;
+
+ if (!midi_opened[midi_dev] &&
+ (err = midi_devs[midi_dev]->open(midi_dev, mode, sequencer_midi_input,
+ sequencer_midi_output)) < 0)
+ return err;
+ midi_opened[midi_dev] = 1;
+ return 0;
+
+ case SNDCTL_SEQ_GETINCOUNT:
+ if (mode == OPEN_WRITE)
+ return 0;
+ return __put_user(iqlen, (int *)arg);
+
+ case SNDCTL_SEQ_GETOUTCOUNT:
+ if (mode == OPEN_READ)
return 0;
- while (qlen > 0 && !signal_pending(current))
- seq_sync();
- if (qlen)
- return -EINTR;
- else
- return 0;
- break;
-
- case SNDCTL_SEQ_RESET:
-
- seq_reset();
- return 0;
- break;
-
- case SNDCTL_SEQ_TESTMIDI:
- midi_dev = *(int *) arg;
- if (midi_dev < 0 || midi_dev >= max_mididev)
- return -ENXIO;
-
- if (!midi_opened[midi_dev])
- {
- int err, mode;
-
- mode = file->mode & O_ACCMODE;
- if ((err = midi_devs[midi_dev]->open(midi_dev, mode,
- sequencer_midi_input,
- sequencer_midi_output)) < 0)
- return err;
- }
- midi_opened[midi_dev] = 1;
-
- return 0;
- break;
-
- case SNDCTL_SEQ_GETINCOUNT:
- if (mode == OPEN_WRITE)
- return 0;
- return (*(int *) arg = iqlen);
- break;
-
- case SNDCTL_SEQ_GETOUTCOUNT:
-
- if (mode == OPEN_READ)
- return 0;
- return (*(int *) arg = SEQ_MAX_QUEUE - qlen);
- break;
-
- case SNDCTL_SEQ_GETTIME:
- if (seq_mode == SEQ_2)
- return tmr->ioctl(tmr_no, cmd, arg);
-
- if (softsynthp != NULL)
- return (*(int *) arg = softsynthp(SSYN_GETTIME, 0, 0, 0));
- else
- return (*(int *) arg = jiffies - seq_time);
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- /*
- * If *arg == 0, just return the current rate
- */
- if (seq_mode == SEQ_2)
- return tmr->ioctl(tmr_no, cmd, arg);
-
- val = *(int *) arg;
- if (val != 0)
- return -EINVAL;
-
- return (*(int *) arg = HZ);
- break;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- case SNDCTL_SYNTH_REMOVESAMPLE:
- case SNDCTL_SYNTH_CONTROL:
- {
- int err;
-
- dev = *(int *) arg;
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- {
- return -ENXIO;
- }
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- {
- return -EBUSY;
- }
- err = synth_devs[dev]->ioctl(dev, cmd, arg);
- return err;
- }
- break;
-
- case SNDCTL_SEQ_NRSYNTHS:
- return (*(int *) arg = max_synthdev);
- break;
-
- case SNDCTL_SEQ_NRMIDIS:
- return (*(int *) arg = max_mididev);
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- {
- int dev;
-
- dev = *(int *) arg;
-
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
-
- return (*(int *) arg = synth_devs[dev]->ioctl(dev, cmd, arg));
- }
- break;
-
- case SNDCTL_FM_4OP_ENABLE:
- {
- int dev;
-
- dev = *(int *) arg;
-
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)))
- return -ENXIO;
-
- synth_devs[dev]->ioctl(dev, cmd, arg);
- return 0;
- }
- break;
-
- case SNDCTL_SYNTH_INFO:
- {
- struct synth_info inf;
- int dev;
-
- memcpy((char *) &inf, (&((char *) arg)[0]), sizeof(inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_synthdev)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
-
- return synth_devs[dev]->ioctl(dev, cmd, arg);
- }
- break;
-
-
- /* Like SYNTH_INFO but returns ID in the name field */
- case SNDCTL_SYNTH_ID:
- {
- struct synth_info inf;
- int dev;
-
- memcpy((char *) &inf, (&((char *) arg)[0]), sizeof(inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_synthdev)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
-
- memcpy((char *) &inf, (char *) synth_devs[dev]->info, sizeof(inf));
- strcpy(inf.name, synth_devs[dev]->id);
- inf.device = dev;
- memcpy((&((char *) arg)[0]), (char *) &inf, sizeof(inf));
- return 0;
- }
- break;
-
- case SNDCTL_SEQ_OUTOFBAND:
- {
- struct seq_event_rec event_rec;
- unsigned long flags;
-
- memcpy((char *) &event_rec, (&((char *) arg)[0]), sizeof(event_rec));
-
- save_flags(flags);
- cli();
- play_event(event_rec.arr);
- restore_flags(flags);
-
- return 0;
- }
- break;
-
- case SNDCTL_MIDI_INFO:
- {
- struct midi_info inf;
- int dev;
- char *pp;
-
- memcpy((char *) &inf, (&((char *) arg)[0]), sizeof(inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_mididev)
- return -ENXIO;
-
- midi_devs[dev]->info.device = dev;
- pp = (char *) &midi_devs[dev]->info;
- memcpy((&((char *) arg)[0]), pp, sizeof(inf));
- return 0;
- }
- break;
-
- case SNDCTL_SEQ_THRESHOLD:
- {
- int tmp;
-
- tmp = *(int *) arg;
-
- if (tmp < 1)
- tmp = 1;
- if (tmp >= SEQ_MAX_QUEUE)
- tmp = SEQ_MAX_QUEUE - 1;
- output_threshold = tmp;
- return 0;
- }
- break;
-
- case SNDCTL_MIDI_PRETIME:
- {
- int val;
-
- val = *(int *) arg;
-
- if (val < 0)
- val = 0;
-
- val = (HZ * val) / 10;
- pre_event_timeout = val;
- return (*(int *) arg = val);
- }
- break;
-
- default:
- if (mode == OPEN_READ)
- return -EIO;
-
- if (!synth_devs[0])
- return -ENXIO;
- if (!(synth_open_mask & (1 << 0)))
- return -ENXIO;
- return synth_devs[0]->ioctl(0, cmd, arg);
- break;
- }
-
+ val = SEQ_MAX_QUEUE - qlen;
+ return __put_user(val, (int *)arg);
+
+ case SNDCTL_SEQ_GETTIME:
+ if (seq_mode == SEQ_2)
+ return tmr->ioctl(tmr_no, cmd, arg);
+ if (softsynthp != NULL)
+ val = softsynthp(SSYN_GETTIME, 0, 0, 0);
+ else
+ val = jiffies - seq_time;
+ return __put_user(val, (int *)arg);
+
+ case SNDCTL_SEQ_CTRLRATE:
+ /*
+ * If *arg == 0, just return the current rate
+ */
+ if (seq_mode == SEQ_2)
+ return tmr->ioctl(tmr_no, cmd, arg);
+
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != 0)
+ return -EINVAL;
+ return __put_user(HZ, (int *)arg);
+
+ case SNDCTL_SEQ_RESETSAMPLES:
+ case SNDCTL_SYNTH_REMOVESAMPLE:
+ case SNDCTL_SYNTH_CONTROL:
+ if (__get_user(dev, (int *)arg))
+ return -EFAULT;
+ if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+ return synth_devs[dev]->ioctl(dev, cmd, arg);
+
+ case SNDCTL_SEQ_NRSYNTHS:
+ return __put_user(max_synthdev, (int *)arg);
+
+ case SNDCTL_SEQ_NRMIDIS:
+ return __put_user(max_mididev, (int *)arg);
+
+ case SNDCTL_SYNTH_MEMAVL:
+ if (__get_user(dev, (int *)arg))
+ return -EFAULT;
+ if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+ val = synth_devs[dev]->ioctl(dev, cmd, arg);
+ return __put_user(val, (int *)arg);
+
+ case SNDCTL_FM_4OP_ENABLE:
+ if (__get_user(dev, (int *)arg))
+ return -EFAULT;
+ if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)))
+ return -ENXIO;
+ synth_devs[dev]->ioctl(dev, cmd, arg);
+ return 0;
+
+ case SNDCTL_SYNTH_INFO:
+ if (__get_user(dev, (int *)(&(((struct synth_info *)arg)->device))))
+ return -EFAULT;
+ if (dev < 0 || dev >= max_synthdev)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+ return synth_devs[dev]->ioctl(dev, cmd, arg);
+
+ /* Like SYNTH_INFO but returns ID in the name field */
+ case SNDCTL_SYNTH_ID:
+ if (__get_user(dev, (int *)(&(((struct synth_info *)arg)->device))))
+ return -EFAULT;
+ if (dev < 0 || dev >= max_synthdev)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+ memcpy(&inf, synth_devs[dev]->info, sizeof(inf));
+ strncpy(inf.name, synth_devs[dev]->id, sizeof(inf.name));
+ inf.device = dev;
+ return __copy_to_user(arg, &inf, sizeof(inf));
+
+ case SNDCTL_SEQ_OUTOFBAND:
+ if (__copy_from_user(&event_rec, arg, sizeof(event_rec)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ play_event(event_rec.arr);
+ restore_flags(flags);
+ return 0;
+
+ case SNDCTL_MIDI_INFO:
+ if (__get_user(dev, (int *)(&(((struct synth_info *)arg)->device))))
+ return -EFAULT;
+ if (dev < 0 || dev >= max_mididev)
+ return -ENXIO;
+ midi_devs[dev]->info.device = dev;
+ return __copy_to_user(arg, &midi_devs[dev]->info, sizeof(struct synth_info));
+
+ case SNDCTL_SEQ_THRESHOLD:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val < 1)
+ val = 1;
+ if (val >= SEQ_MAX_QUEUE)
+ val = SEQ_MAX_QUEUE - 1;
+ output_threshold = val;
+ return 0;
+
+ case SNDCTL_MIDI_PRETIME:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val < 0)
+ val = 0;
+ val = (HZ * val) / 10;
+ pre_event_timeout = val;
+ return __put_user(val, (int *)arg);
+
+ default:
+ if (mode == OPEN_READ)
+ return -EIO;
+ if (!synth_devs[0])
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << 0)))
+ return -ENXIO;
+ if (!synth_devs[0]->ioctl)
+ return -EINVAL;
+ return synth_devs[0]->ioctl(0, cmd, arg);
+ }
return -EINVAL;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov