root/drivers/sound/patmgr.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pmgr_open
  2. pmgr_release
  3. pmgr_read
  4. pmgr_write
  5. pmgr_access
  6. pmgr_inform

   1 /*
   2  * sound/patmgr.c
   3  * 
   4  * The patch maneger interface for the /dev/sequencer
   5  * 
   6  * Copyright by Hannu Savolainen 1993
   7  * 
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions are
  10  * met: 1. Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer. 2.
  12  * Redistributions in binary form must reproduce the above copyright notice,
  13  * this list of conditions and the following disclaimer in the documentation
  14  * and/or other materials provided with the distribution.
  15  * 
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  * 
  28  */
  29 
  30 #define PATMGR_C
  31 #include "sound_config.h"
  32 
  33 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SEQUENCER)
  34 
  35 DEFINE_WAIT_QUEUES (server_procs[MAX_SYNTH_DEV],
  36                     server_wait_flag[MAX_SYNTH_DEV]);
  37 
  38 static struct patmgr_info *mbox[MAX_SYNTH_DEV] =
  39 {NULL};
  40 static volatile int msg_direction[MAX_SYNTH_DEV] =
  41 {0};
  42 
  43 static int      pmgr_opened[MAX_SYNTH_DEV] =
  44 {0};
  45 
  46 #define A_TO_S  1
  47 #define S_TO_A  2
  48 
  49 DEFINE_WAIT_QUEUE (appl_proc, appl_wait_flag);
  50 
  51 int
  52 pmgr_open (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54   if (dev < 0 || dev >= num_synths)
  55     return RET_ERROR (ENXIO);
  56 
  57   if (pmgr_opened[dev])
  58     return RET_ERROR (EBUSY);
  59   pmgr_opened[dev] = 1;
  60 
  61   RESET_WAIT_QUEUE (server_procs[dev], server_wait_flag[dev]);
  62 
  63   return 0;
  64 }
  65 
  66 void
  67 pmgr_release (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69 
  70   if (mbox[dev])                /* Killed in action. Inform the client */
  71     {
  72 
  73       mbox[dev]->key = PM_ERROR;
  74       mbox[dev]->parm1 = RET_ERROR (EIO);
  75 
  76       if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
  77         WAKE_UP (appl_proc, appl_wait_flag);
  78     }
  79 
  80   pmgr_opened[dev] = 0;
  81 }
  82 
  83 int
  84 pmgr_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  85 {
  86   unsigned long   flags;
  87   int             ok = 0;
  88 
  89   if (count != sizeof (struct patmgr_info))
  90     {
  91       printk ("PATMGR%d: Invalid read count\n", dev);
  92       return RET_ERROR (EIO);
  93     }
  94 
  95   while (!ok && !PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
  96     {
  97       DISABLE_INTR (flags);
  98 
  99       while (!(mbox[dev] && msg_direction[dev] == A_TO_S) &&
 100              !PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
 101         {
 102           DO_SLEEP (server_procs[dev], server_wait_flag[dev], 0);
 103         }
 104 
 105       if (mbox[dev] && msg_direction[dev] == A_TO_S)
 106         {
 107           COPY_TO_USER (buf, 0, (char *) mbox[dev], count);
 108           msg_direction[dev] = 0;
 109           ok = 1;
 110         }
 111 
 112       RESTORE_INTR (flags);
 113 
 114     }
 115 
 116   if (!ok)
 117     return RET_ERROR (EINTR);
 118   return count;
 119 }
 120 
 121 int
 122 pmgr_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124   unsigned long   flags;
 125 
 126   if (count < 4)
 127     {
 128       printk ("PATMGR%d: Write count < 4\n", dev);
 129       return RET_ERROR (EIO);
 130     }
 131 
 132   COPY_FROM_USER (mbox[dev], buf, 0, 4);
 133 
 134   if (*(unsigned char *) mbox[dev] == SEQ_FULLSIZE)
 135     {
 136       int             tmp_dev;
 137 
 138       tmp_dev = ((unsigned short *) mbox[dev])[2];
 139       if (tmp_dev != dev)
 140         return RET_ERROR (ENXIO);
 141 
 142       return synth_devs[dev]->load_patch (dev, *(unsigned short *) mbox[dev],
 143                                           buf, 4, count, 1);
 144     }
 145 
 146   if (count != sizeof (struct patmgr_info))
 147     {
 148       printk ("PATMGR%d: Invalid write count\n", dev);
 149       return RET_ERROR (EIO);
 150     }
 151 
 152   /*
 153    * If everything went OK, there should be a preallocated buffer in the
 154    * mailbox and a client waiting.
 155    */
 156 
 157   DISABLE_INTR (flags);
 158 
 159   if (mbox[dev] && !msg_direction[dev])
 160     {
 161       COPY_FROM_USER (&((char *) mbox[dev])[4], buf, 4, count - 4);
 162       msg_direction[dev] = S_TO_A;
 163 
 164       if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
 165         {
 166           WAKE_UP (appl_proc, appl_wait_flag);
 167         }
 168     }
 169 
 170   RESTORE_INTR (flags);
 171 
 172   return count;
 173 }
 174 
 175 int
 176 pmgr_access (int dev, struct patmgr_info *rec)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178   unsigned long   flags;
 179   int             err = 0;
 180 
 181   DISABLE_INTR (flags);
 182 
 183   if (mbox[dev])
 184     printk ("  PATMGR: Server %d mbox full. Why?\n", dev);
 185   else
 186     {
 187       rec->key = PM_K_COMMAND;
 188       mbox[dev] = rec;
 189       msg_direction[dev] = A_TO_S;
 190 
 191       if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
 192         {
 193           WAKE_UP (server_procs[dev], server_wait_flag[dev]);
 194         }
 195 
 196       DO_SLEEP (appl_proc, appl_wait_flag, 0);
 197 
 198       if (msg_direction[dev] != S_TO_A)
 199         {
 200           rec->key = PM_ERROR;
 201           rec->parm1 = RET_ERROR (EIO);
 202         }
 203       else if (rec->key == PM_ERROR)
 204         {
 205           err = rec->parm1;
 206           if (err > 0)
 207             err = -err;
 208         }
 209 
 210       mbox[dev] = NULL;
 211       msg_direction[dev] = 0;
 212     }
 213 
 214   RESTORE_INTR (flags);
 215 
 216   return err;
 217 }
 218 
 219 int
 220 pmgr_inform (int dev, int event, unsigned long p1, unsigned long p2,
     /* [previous][next][first][last][top][bottom][index][help] */
 221              unsigned long p3, unsigned long p4)
 222 {
 223   unsigned long   flags;
 224   int             err = 0;
 225 
 226   if (!pmgr_opened[dev])
 227     return 0;
 228 
 229   DISABLE_INTR (flags);
 230 
 231   if (mbox[dev])
 232     printk ("  PATMGR: Server %d mbox full. Why?\n", dev);
 233   else
 234     {
 235       mbox[dev] =
 236         (struct patmgr_info *) KERNEL_MALLOC (sizeof (struct patmgr_info));
 237 
 238       mbox[dev]->key = PM_K_EVENT;
 239       mbox[dev]->command = event;
 240       mbox[dev]->parm1 = p1;
 241       mbox[dev]->parm2 = p2;
 242       mbox[dev]->parm3 = p3;
 243       msg_direction[dev] = A_TO_S;
 244 
 245       if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
 246         {
 247           WAKE_UP (server_procs[dev], server_wait_flag[dev]);
 248         }
 249 
 250       DO_SLEEP (appl_proc, appl_wait_flag, 0);
 251       if (mbox[dev])
 252         KERNEL_FREE (mbox[dev]);
 253       mbox[dev] = NULL;
 254       msg_direction[dev] = 0;
 255     }
 256 
 257   RESTORE_INTR (flags);
 258 
 259   return err;
 260 }
 261 
 262 #endif

/* [previous][next][first][last][top][bottom][index][help] */