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 / midibuf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  9.6 KB  |  444 lines

  1. /*
  2.  * sound/midibuf.c
  3.  *
  4.  * Device file manager for /dev/midi#
  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. #include "sound_config.h"
  31.  
  32. #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
  33.  
  34. /*
  35.  * Don't make MAX_QUEUE_SIZE larger than 4000
  36.  */
  37.  
  38. #define MAX_QUEUE_SIZE    4000
  39.  
  40. DEFINE_WAIT_QUEUES (midi_sleeper[MAX_MIDI_DEV], midi_sleep_flag[MAX_MIDI_DEV]);
  41. DEFINE_WAIT_QUEUES (input_sleeper[MAX_MIDI_DEV], input_sleep_flag[MAX_MIDI_DEV]);
  42.  
  43. struct midi_buf
  44.   {
  45.     int             len, head, tail;
  46.     unsigned char   queue[MAX_QUEUE_SIZE];
  47.   };
  48.  
  49. struct midi_parms
  50.   {
  51.     int             prech_timeout;    /*
  52.                      * Timeout before the first ch
  53.                      */
  54.   };
  55.  
  56. static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] =
  57. {NULL};
  58. static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] =
  59. {NULL};
  60. static struct midi_parms parms[MAX_MIDI_DEV];
  61.  
  62. static void     midi_poll (unsigned long dummy);
  63.  
  64. DEFINE_TIMER (poll_timer, midi_poll);
  65. static volatile int open_devs = 0;
  66.  
  67. #define DATA_AVAIL(q) (q->len)
  68. #define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
  69.  
  70. #define QUEUE_BYTE(q, data) \
  71.     if (SPACE_AVAIL(q)) \
  72.     { \
  73.       unsigned long flags; \
  74.       DISABLE_INTR(flags); \
  75.       q->queue[q->tail] = (data); \
  76.       q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
  77.       RESTORE_INTR(flags); \
  78.     }
  79.  
  80. #define REMOVE_BYTE(q, data) \
  81.     if (DATA_AVAIL(q)) \
  82.     { \
  83.       unsigned long flags; \
  84.       DISABLE_INTR(flags); \
  85.       data = q->queue[q->head]; \
  86.       q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
  87.       RESTORE_INTR(flags); \
  88.     }
  89.  
  90. void
  91. drain_midi_queue (int dev)
  92. {
  93.  
  94.   /*
  95.    * Give the Midi driver time to drain its output queues
  96.    */
  97.  
  98.   if (midi_devs[dev]->buffer_status != NULL)
  99.     while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
  100.        midi_devs[dev]->buffer_status (dev))
  101.       DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], HZ / 10);
  102. }
  103.  
  104. static void
  105. midi_input_intr (int dev, unsigned char data)
  106. {
  107.   if (midi_in_buf[dev] == NULL)
  108.     return;
  109.  
  110.   if (data == 0xfe)        /*
  111.                  * Active sensing
  112.                  */
  113.     return;            /*
  114.                  * Ignore
  115.                  */
  116.  
  117.   if (SPACE_AVAIL (midi_in_buf[dev]))
  118.     {
  119.       QUEUE_BYTE (midi_in_buf[dev], data);
  120.       if (SOMEONE_WAITING (input_sleeper[dev], input_sleep_flag[dev]))
  121.     WAKE_UP (input_sleeper[dev], input_sleep_flag[dev]);
  122.     }
  123.  
  124. }
  125.  
  126. static void
  127. midi_output_intr (int dev)
  128. {
  129.   /*
  130.    * Currently NOP
  131.    */
  132. }
  133.  
  134. static void
  135. midi_poll (unsigned long dummy)
  136. {
  137.   unsigned long   flags;
  138.   int             dev;
  139.  
  140.   DISABLE_INTR (flags);
  141.   if (open_devs)
  142.     {
  143.       for (dev = 0; dev < num_midis; dev++)
  144.     if (midi_out_buf[dev] != NULL)
  145.       {
  146.         while (DATA_AVAIL (midi_out_buf[dev]) &&
  147.            midi_devs[dev]->putc (dev,
  148.              midi_out_buf[dev]->queue[midi_out_buf[dev]->head]))
  149.           {
  150.         midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
  151.         midi_out_buf[dev]->len--;
  152.           }
  153.  
  154.         if (DATA_AVAIL (midi_out_buf[dev]) < 100 &&
  155.         SOMEONE_WAITING (midi_sleeper[dev], midi_sleep_flag[dev]))
  156.           WAKE_UP (midi_sleeper[dev], midi_sleep_flag[dev]);
  157.       }
  158.       ACTIVATE_TIMER (poll_timer, midi_poll, 1);    /*
  159.                              * Come back later
  160.                              */
  161.     }
  162.   RESTORE_INTR (flags);
  163. }
  164.  
  165. int
  166. MIDIbuf_open (int dev, struct fileinfo *file)
  167. {
  168.   int             mode, err;
  169.   unsigned long   flags;
  170.  
  171.   dev = dev >> 4;
  172.   mode = file->mode & O_ACCMODE;
  173.  
  174.   if (num_midis > MAX_MIDI_DEV)
  175.     {
  176.       printk ("Sound: FATAL ERROR: Too many midi interfaces\n");
  177.       num_midis = MAX_MIDI_DEV;
  178.     }
  179.  
  180.   if (dev < 0 || dev >= num_midis)
  181.     {
  182.       printk ("Sound: Nonexistent MIDI interface %d\n", dev);
  183.       return RET_ERROR (ENXIO);
  184.     }
  185.  
  186.   /*
  187.  *    Interrupts disabled. Be careful
  188.  */
  189.  
  190.   DISABLE_INTR (flags);
  191.   if ((err = midi_devs[dev]->open (dev, mode,
  192.                    midi_input_intr, midi_output_intr)) < 0)
  193.     {
  194.       RESTORE_INTR (flags);
  195.       return err;
  196.     }
  197.  
  198.   parms[dev].prech_timeout = 0;
  199.  
  200.   RESET_WAIT_QUEUE (midi_sleeper[dev], midi_sleep_flag[dev]);
  201.   RESET_WAIT_QUEUE (input_sleeper[dev], input_sleep_flag[dev]);
  202.  
  203.   midi_in_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
  204.  
  205.   if (midi_in_buf[dev] == NULL)
  206.     {
  207.       printk ("midi: Can't allocate buffer\n");
  208.       midi_devs[dev]->close (dev);
  209.       RESTORE_INTR (flags);
  210.       return RET_ERROR (EIO);
  211.     }
  212.   midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
  213.  
  214.   midi_out_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
  215.  
  216.   if (midi_out_buf[dev] == NULL)
  217.     {
  218.       printk ("midi: Can't allocate buffer\n");
  219.       midi_devs[dev]->close (dev);
  220.       KERNEL_FREE (midi_in_buf[dev]);
  221.       midi_in_buf[dev] = NULL;
  222.       RESTORE_INTR (flags);
  223.       return RET_ERROR (EIO);
  224.     }
  225.   midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
  226.   if (!open_devs)
  227.     ACTIVATE_TIMER (poll_timer, midi_poll, 1);    /*
  228.                          * Come back later
  229.                          */
  230.   open_devs++;
  231.   RESTORE_INTR (flags);
  232.  
  233.   return err;
  234. }
  235.  
  236. void
  237. MIDIbuf_release (int dev, struct fileinfo *file)
  238. {
  239.   int             mode;
  240.   unsigned long   flags;
  241.  
  242.   dev = dev >> 4;
  243.   mode = file->mode & O_ACCMODE;
  244.  
  245.   DISABLE_INTR (flags);
  246.  
  247.   /*
  248.  * Wait until the queue is empty
  249.  */
  250.  
  251.   if (mode != OPEN_READ)
  252.     {
  253.       midi_devs[dev]->putc (dev, 0xfe);    /*
  254.                          * Active sensing to shut the
  255.                          * devices
  256.                          */
  257.  
  258.       while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
  259.          DATA_AVAIL (midi_out_buf[dev]))
  260.     DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0);    /*
  261.                                  * Sync
  262.                                  */
  263.  
  264.       drain_midi_queue (dev);    /*
  265.                  * Ensure the output queues are empty
  266.                  */
  267.     }
  268.  
  269.   midi_devs[dev]->close (dev);
  270.   KERNEL_FREE (midi_in_buf[dev]);
  271.   KERNEL_FREE (midi_out_buf[dev]);
  272.   midi_in_buf[dev] = NULL;
  273.   midi_out_buf[dev] = NULL;
  274.   open_devs--;
  275.   RESTORE_INTR (flags);
  276. }
  277.  
  278. int
  279. MIDIbuf_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
  280. {
  281.   unsigned long   flags;
  282.   int             c, n, i;
  283.   unsigned char   tmp_data;
  284.  
  285.   dev = dev >> 4;
  286.  
  287.   if (!count)
  288.     return 0;
  289.  
  290.   DISABLE_INTR (flags);
  291.  
  292.   c = 0;
  293.  
  294.   while (c < count)
  295.     {
  296.       n = SPACE_AVAIL (midi_out_buf[dev]);
  297.  
  298.       if (n == 0)        /*
  299.                  * No space just now. We have to sleep
  300.                  */
  301.     {
  302.       DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0);
  303.       if (PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]))
  304.         {
  305.           RESTORE_INTR (flags);
  306.           return RET_ERROR (EINTR);
  307.         }
  308.  
  309.       n = SPACE_AVAIL (midi_out_buf[dev]);
  310.     }
  311.  
  312.       if (n > (count - c))
  313.     n = count - c;
  314.  
  315.       for (i = 0; i < n; i++)
  316.     {
  317.       COPY_FROM_USER (&tmp_data, buf, c, 1);
  318.       QUEUE_BYTE (midi_out_buf[dev], tmp_data);
  319.       c++;
  320.     }
  321.     }
  322.  
  323.   RESTORE_INTR (flags);
  324.  
  325.   return c;
  326. }
  327.  
  328.  
  329. int
  330. MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
  331. {
  332.   int             n, c = 0;
  333.   unsigned long   flags;
  334.   unsigned char   tmp_data;
  335.  
  336.   dev = dev >> 4;
  337.  
  338.   DISABLE_INTR (flags);
  339.  
  340.   if (!DATA_AVAIL (midi_in_buf[dev]))    /*
  341.                      * No data yet, wait
  342.                      */
  343.     {
  344.       DO_SLEEP (input_sleeper[dev], input_sleep_flag[dev],
  345.         parms[dev].prech_timeout);
  346.       if (PROCESS_ABORTING (input_sleeper[dev], input_sleep_flag[dev]))
  347.     c = RET_ERROR (EINTR);    /*
  348.                  * The user is getting restless
  349.                  */
  350.     }
  351.  
  352.   if (c == 0 && DATA_AVAIL (midi_in_buf[dev]))    /*
  353.                          * Got some bytes
  354.                          */
  355.     {
  356.       n = DATA_AVAIL (midi_in_buf[dev]);
  357.       if (n > count)
  358.     n = count;
  359.       c = 0;
  360.  
  361.       while (c < n)
  362.     {
  363.       REMOVE_BYTE (midi_in_buf[dev], tmp_data);
  364.       COPY_TO_USER (buf, c, &tmp_data, 1);
  365.       c++;
  366.     }
  367.     }
  368.  
  369.   RESTORE_INTR (flags);
  370.  
  371.   return c;
  372. }
  373.  
  374. int
  375. MIDIbuf_ioctl (int dev, struct fileinfo *file,
  376.            unsigned int cmd, unsigned int arg)
  377. {
  378.   int             val;
  379.  
  380.   dev = dev >> 4;
  381.  
  382.   switch (cmd)
  383.     {
  384.  
  385.     case SNDCTL_MIDI_PRETIME:
  386.       val = IOCTL_IN (arg);
  387.       if (val < 0)
  388.     val = 0;
  389.  
  390.       val = (HZ * val) / 10;
  391.       parms[dev].prech_timeout = val;
  392.       return IOCTL_OUT (arg, val);
  393.       break;
  394.  
  395.     default:
  396.       return midi_devs[dev]->ioctl (dev, cmd, arg);
  397.     }
  398. }
  399.  
  400. #ifdef ALLOW_SELECT
  401. int
  402. MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
  403. {
  404.   dev = dev >> 4;
  405.  
  406.   switch (sel_type)
  407.     {
  408.     case SEL_IN:
  409.       if (!DATA_AVAIL (midi_in_buf[dev]))
  410.     {
  411.       input_sleep_flag[dev].mode = WK_SLEEP;
  412.       select_wait (&input_sleeper[dev], wait);
  413.       return 0;
  414.     }
  415.       return 1;
  416.       break;
  417.  
  418.     case SEL_OUT:
  419.       if (SPACE_AVAIL (midi_out_buf[dev]))
  420.     {
  421.       midi_sleep_flag[dev].mode = WK_SLEEP;
  422.       select_wait (&midi_sleeper[dev], wait);
  423.       return 0;
  424.     }
  425.       return 1;
  426.       break;
  427.  
  428.     case SEL_EX:
  429.       return 0;
  430.     }
  431.  
  432.   return 0;
  433. }
  434.  
  435. #endif /* ALLOW_SELECT */
  436.  
  437. long
  438. MIDIbuf_init (long mem_start)
  439. {
  440.   return mem_start;
  441. }
  442.  
  443. #endif
  444.