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 manager 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])                /*
  71                                  * Killed in action. Inform the client
  72                                  */
  73     {
  74 
  75       mbox[dev]->key = PM_ERROR;
  76       mbox[dev]->parm1 = RET_ERROR (EIO);
  77 
  78       if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
  79         WAKE_UP (appl_proc, appl_wait_flag);
  80     }
  81 
  82   pmgr_opened[dev] = 0;
  83 }
  84 
  85 int
  86 pmgr_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88   unsigned long   flags;
  89   int             ok = 0;
  90 
  91   if (count != sizeof (struct patmgr_info))
  92     {
  93       printk ("PATMGR%d: Invalid read count\n", dev);
  94       return RET_ERROR (EIO);
  95     }
  96 
  97   while (!ok && !PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
  98     {
  99       DISABLE_INTR (flags);
 100 
 101       while (!(mbox[dev] && msg_direction[dev] == A_TO_S) &&
 102              !PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
 103         {
 104           DO_SLEEP (server_procs[dev], server_wait_flag[dev], 0);
 105         }
 106 
 107       if (mbox[dev] && msg_direction[dev] == A_TO_S)
 108         {
 109           COPY_TO_USER (buf, 0, (char *) mbox[dev], count);
 110           msg_direction[dev] = 0;
 111           ok = 1;
 112         }
 113 
 114       RESTORE_INTR (flags);
 115 
 116     }
 117 
 118   if (!ok)
 119     return RET_ERROR (EINTR);
 120   return count;
 121 }
 122 
 123 int
 124 pmgr_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126   unsigned long   flags;
 127 
 128   if (count < 4)
 129     {
 130       printk ("PATMGR%d: Write count < 4\n", dev);
 131       return RET_ERROR (EIO);
 132     }
 133 
 134   COPY_FROM_USER (mbox[dev], buf, 0, 4);
 135 
 136   if (*(unsigned char *) mbox[dev] == SEQ_FULLSIZE)
 137     {
 138       int             tmp_dev;
 139 
 140       tmp_dev = ((unsigned short *) mbox[dev])[2];
 141       if (tmp_dev != dev)
 142         return RET_ERROR (ENXIO);
 143 
 144       return synth_devs[dev]->load_patch (dev, *(unsigned short *) mbox[dev],
 145                                           buf, 4, count, 1);
 146     }
 147 
 148   if (count != sizeof (struct patmgr_info))
 149     {
 150       printk ("PATMGR%d: Invalid write count\n", dev);
 151       return RET_ERROR (EIO);
 152     }
 153 
 154   /*
 155    * If everything went OK, there should be a preallocated buffer in the
 156    * mailbox and a client waiting.
 157    */
 158 
 159   DISABLE_INTR (flags);
 160 
 161   if (mbox[dev] && !msg_direction[dev])
 162     {
 163       COPY_FROM_USER (&((char *) mbox[dev])[4], buf, 4, count - 4);
 164       msg_direction[dev] = S_TO_A;
 165 
 166       if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
 167         {
 168           WAKE_UP (appl_proc, appl_wait_flag);
 169         }
 170     }
 171 
 172   RESTORE_INTR (flags);
 173 
 174   return count;
 175 }
 176 
 177 int
 178 pmgr_access (int dev, struct patmgr_info *rec)
     /* [previous][next][first][last][top][bottom][index][help] */
 179 {
 180   unsigned long   flags;
 181   int             err = 0;
 182 
 183   DISABLE_INTR (flags);
 184 
 185   if (mbox[dev])
 186     printk ("  PATMGR: Server %d mbox full. Why?\n", dev);
 187   else
 188     {
 189       rec->key = PM_K_COMMAND;
 190       mbox[dev] = rec;
 191       msg_direction[dev] = A_TO_S;
 192 
 193       if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
 194         {
 195           WAKE_UP (server_procs[dev], server_wait_flag[dev]);
 196         }
 197 
 198       DO_SLEEP (appl_proc, appl_wait_flag, 0);
 199 
 200       if (msg_direction[dev] != S_TO_A)
 201         {
 202           rec->key = PM_ERROR;
 203           rec->parm1 = RET_ERROR (EIO);
 204         }
 205       else if (rec->key == PM_ERROR)
 206         {
 207           err = rec->parm1;
 208           if (err > 0)
 209             err = -err;
 210         }
 211 
 212       mbox[dev] = NULL;
 213       msg_direction[dev] = 0;
 214     }
 215 
 216   RESTORE_INTR (flags);
 217 
 218   return err;
 219 }
 220 
 221 int
 222 pmgr_inform (int dev, int event, unsigned long p1, unsigned long p2,
     /* [previous][next][first][last][top][bottom][index][help] */
 223              unsigned long p3, unsigned long p4)
 224 {
 225   unsigned long   flags;
 226   int             err = 0;
 227 
 228   if (!pmgr_opened[dev])
 229     return 0;
 230 
 231   DISABLE_INTR (flags);
 232 
 233   if (mbox[dev])
 234     printk ("  PATMGR: Server %d mbox full. Why?\n", dev);
 235   else
 236     {
 237       mbox[dev] =
 238         (struct patmgr_info *) KERNEL_MALLOC (sizeof (struct patmgr_info));
 239 
 240       mbox[dev]->key = PM_K_EVENT;
 241       mbox[dev]->command = event;
 242       mbox[dev]->parm1 = p1;
 243       mbox[dev]->parm2 = p2;
 244       mbox[dev]->parm3 = p3;
 245       msg_direction[dev] = A_TO_S;
 246 
 247       if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
 248         {
 249           WAKE_UP (server_procs[dev], server_wait_flag[dev]);
 250         }
 251 
 252       DO_SLEEP (appl_proc, appl_wait_flag, 0);
 253       if (mbox[dev])
 254         KERNEL_FREE (mbox[dev]);
 255       mbox[dev] = NULL;
 256       msg_direction[dev] = 0;
 257     }
 258 
 259   RESTORE_INTR (flags);
 260 
 261   return err;
 262 }
 263 
 264 #endif

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