root/sound/core/seq/oss/seq_oss_ioctl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_seq_oss_synth_info_user
  2. snd_seq_oss_midi_info_user
  3. snd_seq_oss_oob_user
  4. snd_seq_oss_ioctl

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * OSS compatible sequencer driver
   4  *
   5  * OSS compatible i/o control
   6  *
   7  * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
   8  */
   9 
  10 #include "seq_oss_device.h"
  11 #include "seq_oss_readq.h"
  12 #include "seq_oss_writeq.h"
  13 #include "seq_oss_timer.h"
  14 #include "seq_oss_synth.h"
  15 #include "seq_oss_midi.h"
  16 #include "seq_oss_event.h"
  17 
  18 static int snd_seq_oss_synth_info_user(struct seq_oss_devinfo *dp, void __user *arg)
  19 {
  20         struct synth_info info;
  21 
  22         if (copy_from_user(&info, arg, sizeof(info)))
  23                 return -EFAULT;
  24         if (snd_seq_oss_synth_make_info(dp, info.device, &info) < 0)
  25                 return -EINVAL;
  26         if (copy_to_user(arg, &info, sizeof(info)))
  27                 return -EFAULT;
  28         return 0;
  29 }
  30 
  31 static int snd_seq_oss_midi_info_user(struct seq_oss_devinfo *dp, void __user *arg)
  32 {
  33         struct midi_info info;
  34 
  35         if (copy_from_user(&info, arg, sizeof(info)))
  36                 return -EFAULT;
  37         if (snd_seq_oss_midi_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_oob_user(struct seq_oss_devinfo *dp, void __user *arg)
  45 {
  46         unsigned char ev[8];
  47         struct snd_seq_event tmpev;
  48 
  49         if (copy_from_user(ev, arg, 8))
  50                 return -EFAULT;
  51         memset(&tmpev, 0, sizeof(tmpev));
  52         snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.client, dp->addr.port);
  53         tmpev.time.tick = 0;
  54         if (! snd_seq_oss_process_event(dp, (union evrec *)ev, &tmpev)) {
  55                 snd_seq_oss_dispatch(dp, &tmpev, 0, 0);
  56         }
  57         return 0;
  58 }
  59 
  60 int
  61 snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long carg)
  62 {
  63         int dev, val;
  64         void __user *arg = (void __user *)carg;
  65         int __user *p = arg;
  66 
  67         switch (cmd) {
  68         case SNDCTL_TMR_TIMEBASE:
  69         case SNDCTL_TMR_TEMPO:
  70         case SNDCTL_TMR_START:
  71         case SNDCTL_TMR_STOP:
  72         case SNDCTL_TMR_CONTINUE:
  73         case SNDCTL_TMR_METRONOME:
  74         case SNDCTL_TMR_SOURCE:
  75         case SNDCTL_TMR_SELECT:
  76         case SNDCTL_SEQ_CTRLRATE:
  77                 return snd_seq_oss_timer_ioctl(dp->timer, cmd, arg);
  78 
  79         case SNDCTL_SEQ_PANIC:
  80                 snd_seq_oss_reset(dp);
  81                 return -EINVAL;
  82 
  83         case SNDCTL_SEQ_SYNC:
  84                 if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
  85                         return 0;
  86                 while (snd_seq_oss_writeq_sync(dp->writeq))
  87                         ;
  88                 if (signal_pending(current))
  89                         return -ERESTARTSYS;
  90                 return 0;
  91 
  92         case SNDCTL_SEQ_RESET:
  93                 snd_seq_oss_reset(dp);
  94                 return 0;
  95 
  96         case SNDCTL_SEQ_TESTMIDI:
  97                 if (get_user(dev, p))
  98                         return -EFAULT;
  99                 return snd_seq_oss_midi_open(dp, dev, dp->file_mode);
 100 
 101         case SNDCTL_SEQ_GETINCOUNT:
 102                 if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
 103                         return 0;
 104                 return put_user(dp->readq->qlen, p) ? -EFAULT : 0;
 105 
 106         case SNDCTL_SEQ_GETOUTCOUNT:
 107                 if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
 108                         return 0;
 109                 return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0;
 110 
 111         case SNDCTL_SEQ_GETTIME:
 112                 return put_user(snd_seq_oss_timer_cur_tick(dp->timer), p) ? -EFAULT : 0;
 113 
 114         case SNDCTL_SEQ_RESETSAMPLES:
 115                 if (get_user(dev, p))
 116                         return -EFAULT;
 117                 return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
 118 
 119         case SNDCTL_SEQ_NRSYNTHS:
 120                 return put_user(dp->max_synthdev, p) ? -EFAULT : 0;
 121 
 122         case SNDCTL_SEQ_NRMIDIS:
 123                 return put_user(dp->max_mididev, p) ? -EFAULT : 0;
 124 
 125         case SNDCTL_SYNTH_MEMAVL:
 126                 if (get_user(dev, p))
 127                         return -EFAULT;
 128                 val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
 129                 return put_user(val, p) ? -EFAULT : 0;
 130 
 131         case SNDCTL_FM_4OP_ENABLE:
 132                 if (get_user(dev, p))
 133                         return -EFAULT;
 134                 snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
 135                 return 0;
 136 
 137         case SNDCTL_SYNTH_INFO:
 138         case SNDCTL_SYNTH_ID:
 139                 return snd_seq_oss_synth_info_user(dp, arg);
 140 
 141         case SNDCTL_SEQ_OUTOFBAND:
 142                 return snd_seq_oss_oob_user(dp, arg);
 143 
 144         case SNDCTL_MIDI_INFO:
 145                 return snd_seq_oss_midi_info_user(dp, arg);
 146 
 147         case SNDCTL_SEQ_THRESHOLD:
 148                 if (! is_write_mode(dp->file_mode))
 149                         return 0;
 150                 if (get_user(val, p))
 151                         return -EFAULT;
 152                 if (val < 1)
 153                         val = 1;
 154                 if (val >= dp->writeq->maxlen)
 155                         val = dp->writeq->maxlen - 1;
 156                 snd_seq_oss_writeq_set_output(dp->writeq, val);
 157                 return 0;
 158 
 159         case SNDCTL_MIDI_PRETIME:
 160                 if (dp->readq == NULL || !is_read_mode(dp->file_mode))
 161                         return 0;
 162                 if (get_user(val, p))
 163                         return -EFAULT;
 164                 if (val <= 0)
 165                         val = -1;
 166                 else
 167                         val = (HZ * val) / 10;
 168                 dp->readq->pre_event_timeout = val;
 169                 return put_user(val, p) ? -EFAULT : 0;
 170 
 171         default:
 172                 if (! is_write_mode(dp->file_mode))
 173                         return -EIO;
 174                 return snd_seq_oss_synth_ioctl(dp, 0, cmd, carg);
 175         }
 176         return 0;
 177 }
 178 

/* [<][>][^][v][top][bottom][index][help] */