home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / drivers / sound / patmgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-09  |  6.0 KB  |  263 lines

  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)
  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)
  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)
  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)
  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)
  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,
  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
  263.