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

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