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

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