home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / drivers / sound / patmgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-19  |  6.0 KB  |  265 lines

  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)
  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])        /*
  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)
  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)
  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)
  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,
  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
  265.