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 static struct wait_queue *server_procs[MAX_SYNTH_DEV] =
  36 {NULL};
  37 static volatile struct snd_wait server_wait_flag[MAX_SYNTH_DEV] =
  38 {
  39   {0}};
  40 
  41 static struct patmgr_info *mbox[MAX_SYNTH_DEV] =
  42 {NULL};
  43 static volatile int msg_direction[MAX_SYNTH_DEV] =
  44 {0};
  45 
  46 static int      pmgr_opened[MAX_SYNTH_DEV] =
  47 {0};
  48 
  49 #define A_TO_S  1
  50 #define S_TO_A  2
  51 
  52 static struct wait_queue *appl_proc = NULL;
  53 static volatile struct snd_wait appl_wait_flag =
  54 {0};
  55 
  56 int
  57 pmgr_open (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59   if (dev < 0 || dev >= num_synths)
  60     return -ENXIO;
  61 
  62   if (pmgr_opened[dev])
  63     return -EBUSY;
  64   pmgr_opened[dev] = 1;
  65 
  66   server_wait_flag[dev].mode = WK_NONE;
  67 
  68   return 0;
  69 }
  70 
  71 void
  72 pmgr_release (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74 
  75   if (mbox[dev])                /*
  76                                  * Killed in action. Inform the client
  77                                  */
  78     {
  79 
  80       mbox[dev]->key = PM_ERROR;
  81       mbox[dev]->parm1 = -EIO;
  82 
  83       if ((appl_wait_flag.mode & WK_SLEEP))
  84         {
  85           appl_wait_flag.mode = WK_WAKEUP;
  86           wake_up (&appl_proc);
  87         };
  88     }
  89 
  90   pmgr_opened[dev] = 0;
  91 }
  92 
  93 int
  94 pmgr_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96   unsigned long   flags;
  97   int             ok = 0;
  98 
  99   if (count != sizeof (struct patmgr_info))
 100     {
 101       printk ("PATMGR%d: Invalid read count\n", dev);
 102       return -EIO;
 103     }
 104 
 105   while (!ok && !(current->signal & ~current->blocked))
 106     {
 107       save_flags (flags);
 108       cli ();
 109 
 110       while (!(mbox[dev] && msg_direction[dev] == A_TO_S) &&
 111              !(current->signal & ~current->blocked))
 112         {
 113 
 114           {
 115             unsigned long   tl;
 116 
 117             if (0)
 118               current->timeout = tl = jiffies + (0);
 119             else
 120               tl = 0xffffffff;
 121             server_wait_flag[dev].mode = WK_SLEEP;
 122             interruptible_sleep_on (&server_procs[dev]);
 123             if (!(server_wait_flag[dev].mode & WK_WAKEUP))
 124               {
 125                 if (jiffies >= tl)
 126                   server_wait_flag[dev].mode |= WK_TIMEOUT;
 127               }
 128             server_wait_flag[dev].mode &= ~WK_SLEEP;
 129           };
 130         }
 131 
 132       if (mbox[dev] && msg_direction[dev] == A_TO_S)
 133         {
 134           memcpy_tofs (&((buf)[0]), (char *) mbox[dev], count);
 135           msg_direction[dev] = 0;
 136           ok = 1;
 137         }
 138 
 139       restore_flags (flags);
 140 
 141     }
 142 
 143   if (!ok)
 144     return -EINTR;
 145   return count;
 146 }
 147 
 148 int
 149 pmgr_write (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 150 {
 151   unsigned long   flags;
 152 
 153   if (count < 4)
 154     {
 155       printk ("PATMGR%d: Write count < 4\n", dev);
 156       return -EIO;
 157     }
 158 
 159   memcpy_fromfs ((char *) mbox[dev], &((buf)[0]), 4);
 160 
 161   if (*(unsigned char *) mbox[dev] == SEQ_FULLSIZE)
 162     {
 163       int             tmp_dev;
 164 
 165       tmp_dev = ((unsigned short *) mbox[dev])[2];
 166       if (tmp_dev != dev)
 167         return -ENXIO;
 168 
 169       return synth_devs[dev]->load_patch (dev, *(unsigned short *) mbox[dev],
 170                                           buf, 4, count, 1);
 171     }
 172 
 173   if (count != sizeof (struct patmgr_info))
 174     {
 175       printk ("PATMGR%d: Invalid write count\n", dev);
 176       return -EIO;
 177     }
 178 
 179   /*
 180    * If everything went OK, there should be a preallocated buffer in the
 181    * mailbox and a client waiting.
 182    */
 183 
 184   save_flags (flags);
 185   cli ();
 186 
 187   if (mbox[dev] && !msg_direction[dev])
 188     {
 189       memcpy_fromfs (&((char *) mbox[dev])[4], &((buf)[4]), count - 4);
 190       msg_direction[dev] = S_TO_A;
 191 
 192       if ((appl_wait_flag.mode & WK_SLEEP))
 193         {
 194           {
 195             appl_wait_flag.mode = WK_WAKEUP;
 196             wake_up (&appl_proc);
 197           };
 198         }
 199     }
 200 
 201   restore_flags (flags);
 202 
 203   return count;
 204 }
 205 
 206 int
 207 pmgr_access (int dev, struct patmgr_info *rec)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209   unsigned long   flags;
 210   int             err = 0;
 211 
 212   save_flags (flags);
 213   cli ();
 214 
 215   if (mbox[dev])
 216     printk ("  PATMGR: Server %d mbox full. Why?\n", dev);
 217   else
 218     {
 219       rec->key = PM_K_COMMAND;
 220       mbox[dev] = rec;
 221       msg_direction[dev] = A_TO_S;
 222 
 223       if ((server_wait_flag[dev].mode & WK_SLEEP))
 224         {
 225           {
 226             server_wait_flag[dev].mode = WK_WAKEUP;
 227             wake_up (&server_procs[dev]);
 228           };
 229         }
 230 
 231 
 232       {
 233         unsigned long   tl;
 234 
 235         if (0)
 236           current->timeout = tl = jiffies + (0);
 237         else
 238           tl = 0xffffffff;
 239         appl_wait_flag.mode = WK_SLEEP;
 240         interruptible_sleep_on (&appl_proc);
 241         if (!(appl_wait_flag.mode & WK_WAKEUP))
 242           {
 243             if (jiffies >= tl)
 244               appl_wait_flag.mode |= WK_TIMEOUT;
 245           }
 246         appl_wait_flag.mode &= ~WK_SLEEP;
 247       };
 248 
 249       if (msg_direction[dev] != S_TO_A)
 250         {
 251           rec->key = PM_ERROR;
 252           rec->parm1 = -EIO;
 253         }
 254       else if (rec->key == PM_ERROR)
 255         {
 256           err = rec->parm1;
 257           if (err > 0)
 258             err = -err;
 259         }
 260 
 261       mbox[dev] = NULL;
 262       msg_direction[dev] = 0;
 263     }
 264 
 265   restore_flags (flags);
 266 
 267   return err;
 268 }
 269 
 270 int
 271 pmgr_inform (int dev, int event, unsigned long p1, unsigned long p2,
     /* [previous][next][first][last][top][bottom][index][help] */
 272              unsigned long p3, unsigned long p4)
 273 {
 274   unsigned long   flags;
 275   int             err = 0;
 276 
 277   if (!pmgr_opened[dev])
 278     return 0;
 279 
 280   save_flags (flags);
 281   cli ();
 282 
 283   if (mbox[dev])
 284     printk ("  PATMGR: Server %d mbox full. Why?\n", dev);
 285   else
 286     {
 287       if ((mbox[dev] =
 288            (struct patmgr_info *) kmalloc (sizeof (struct patmgr_info), GFP_KERNEL)) == NULL)
 289         {
 290           printk ("pmgr: Couldn't allocate memory for a message\n");
 291           return 0;
 292         }
 293 
 294       mbox[dev]->key = PM_K_EVENT;
 295       mbox[dev]->command = event;
 296       mbox[dev]->parm1 = p1;
 297       mbox[dev]->parm2 = p2;
 298       mbox[dev]->parm3 = p3;
 299       msg_direction[dev] = A_TO_S;
 300 
 301       if ((server_wait_flag[dev].mode & WK_SLEEP))
 302         {
 303           {
 304             server_wait_flag[dev].mode = WK_WAKEUP;
 305             wake_up (&server_procs[dev]);
 306           };
 307         }
 308 
 309 
 310       {
 311         unsigned long   tl;
 312 
 313         if (0)
 314           current->timeout = tl = jiffies + (0);
 315         else
 316           tl = 0xffffffff;
 317         appl_wait_flag.mode = WK_SLEEP;
 318         interruptible_sleep_on (&appl_proc);
 319         if (!(appl_wait_flag.mode & WK_WAKEUP))
 320           {
 321             if (jiffies >= tl)
 322               appl_wait_flag.mode |= WK_TIMEOUT;
 323           }
 324         appl_wait_flag.mode &= ~WK_SLEEP;
 325       };
 326       if (mbox[dev])
 327         kfree (mbox[dev]);
 328       mbox[dev] = NULL;
 329       msg_direction[dev] = 0;
 330     }
 331 
 332   restore_flags (flags);
 333 
 334   return err;
 335 }
 336 
 337 #endif

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