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 / sound_switch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-21  |  8.9 KB  |  418 lines

  1. /*
  2.  * sound/sound_switch.c
  3.  * 
  4.  * The system call switch
  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. #ifdef CONFIGURE_SOUNDCARD
  33.  
  34. struct sbc_device
  35. {
  36.   int             usecount;
  37. };
  38.  
  39. static struct sbc_device sbc_devices[SND_NDEVS] = {{0}};
  40.  
  41. static int      in_use = 0;    /* Total # of open device files (excluding
  42.                  * minor 0) */
  43.  
  44. /*
  45.  * /dev/sndstatus -device
  46.  */
  47. static char    *status_buf = NULL;
  48. static int      status_len, status_ptr;
  49. static int      status_busy = 0;
  50.  
  51. static int
  52. put_status (char *s)
  53. {
  54.   int             l;
  55.  
  56.   for (l=0;l<256,s[l];l++);    /* l=strlen(s); */
  57.  
  58.   if (status_len + l >= 4000)
  59.     return 0;
  60.  
  61.   memcpy (&status_buf[status_len], s, l);
  62.   status_len += l;
  63.  
  64.   return 1;
  65. }
  66.  
  67. static int
  68. put_status_int (unsigned int val, int radix)
  69. {
  70.   int             l, v;
  71.  
  72.   static char hx[] = "0123456789abcdef";
  73.   char buf[11];
  74.  
  75.   if (!val) return put_status("0");
  76.  
  77.   l = 0;
  78.   buf[10]=0;
  79.  
  80.   while (val)
  81.   {
  82.       v = val % radix;
  83.       val = val / radix;
  84.  
  85.       buf[9-l] = hx[v];
  86.       l++;
  87.   }
  88.  
  89.   if (status_len + l >= 4000)
  90.     return 0;
  91.  
  92.   memcpy (&status_buf[status_len], &buf[10-l], l);
  93.   status_len += l;
  94.  
  95.   return 1;
  96. }
  97.  
  98. static void
  99. init_status (void)
  100. {
  101.   /*
  102.    * Write the status information to the status_buf and update status_len.
  103.    * There is a limit of 4000 bytes for the data.
  104.    */
  105.  
  106.   int             i;
  107.  
  108.   status_ptr = 0;
  109.  
  110.   put_status ("Sound Driver:" SOUND_VERSION_STRING
  111.           " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
  112.           SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")"
  113.           "\n");
  114.  
  115.   if (!put_status ("Config options: "))
  116.     return;
  117.   if (!put_status_int(SELECTED_SOUND_OPTIONS, 16))
  118.      return;
  119.  
  120.   if (!put_status ("\n\nHW config: \n"))
  121.     return;
  122.  
  123.   for (i = 0; i < (num_sound_drivers - 1); i++)
  124.     {
  125.       if (!supported_drivers[i].enabled) 
  126.       if (!put_status ("("))
  127.     return;
  128.  
  129.       if (!put_status ("Type ")) return;
  130.       if (!put_status_int(supported_drivers[i].card_type, 10)) return;
  131.       if (!put_status (": ")) return;
  132.       if (!put_status (supported_drivers[i].name)) return;
  133.       if (!put_status (" at 0x")) return;
  134.       if (!put_status_int(supported_drivers[i].config.io_base, 16)) return;
  135.       if (!put_status (" irq ")) return;
  136.       if (!put_status_int(supported_drivers[i].config.irq, 10)) return;
  137.       if (!put_status (" drq ")) return;
  138.       if (!put_status_int(supported_drivers[i].config.dma, 10)) return;
  139.  
  140.       if (!supported_drivers[i].enabled) 
  141.       if (!put_status (")"))
  142.     return;
  143.  
  144.       if (!put_status ("\n"))
  145.     return;
  146.     }
  147.  
  148.   if (!put_status ("\nPCM devices:\n"))
  149.     return;
  150.  
  151.   for (i = 0; i < num_dspdevs; i++)
  152.     {
  153.       if (!put_status_int(i, 10)) return;
  154.       if (!put_status(": "))return;
  155.       if (!put_status(dsp_devs[i]->name))return;
  156.       if (!put_status("\n"))return;
  157.     }
  158.  
  159.   if (!put_status ("\nSynth devices:\n"))
  160.     return;
  161.  
  162.   for (i = 0; i < num_synths; i++)
  163.     {
  164.       if (!put_status_int(i, 10)) return;
  165.       if (!put_status(": "))return;
  166.       if (!put_status(synth_devs[i]->info->name))return;
  167.       if (!put_status("\n"))return;
  168.     }
  169.  
  170.   if (!put_status ("\nMidi devices:\n"))
  171.     return;
  172.  
  173.   for (i = 0; i < num_midis; i++)
  174.     {
  175.       if (!put_status_int(i, 10)) return;
  176.       if (!put_status(": "))return;
  177.       if (!put_status(midi_devs[i]->info.name))return;
  178.       if (!put_status("\n"))return;
  179.     }
  180.  
  181.   if (num_mixers)
  182.     {
  183.       if (!put_status ("\nMixer(s) installed\n"))
  184.     return;
  185.     }
  186.   else
  187.     {
  188.       if (!put_status ("\nNo mixers installed\n"))
  189.     return;
  190.     }
  191. }
  192.  
  193. static int
  194. read_status (snd_rw_buf *buf, int count)
  195. {
  196.   /*
  197.    * Return at most 'count' bytes from the status_buf.
  198.    */
  199.   int             l, c;
  200.  
  201.   l = count;
  202.   c = status_len - status_ptr;
  203.  
  204.   if (l > c)
  205.     l = c;
  206.   if (l <= 0)
  207.     return 0;
  208.  
  209.   COPY_TO_USER(buf, 0, &status_buf[status_ptr], l);
  210.   status_ptr += l;
  211.  
  212.   return l;
  213. }
  214.  
  215. int
  216. sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf *buf, int count)
  217. {
  218.   DEB (printk ("sound_read_sw(dev=%d, count=%d)\n", dev, count));
  219.  
  220.   switch (dev & 0x0f)
  221.     {
  222.     case SND_DEV_STATUS:
  223.       return read_status (buf, count);
  224.       break;
  225.  
  226.     case SND_DEV_DSP:
  227.     case SND_DEV_DSP16:
  228.     case SND_DEV_AUDIO:
  229.       return audio_read (dev, file, buf, count);
  230.       break;
  231.  
  232.     case SND_DEV_SEQ:
  233.       return sequencer_read (dev, file, buf, count);
  234.       break;
  235.  
  236. #ifndef EXCLUDE_MPU401
  237.     case SND_DEV_MIDIN:
  238.       return MIDIbuf_read (dev, file, buf, count);
  239. #endif
  240.  
  241.     default:
  242.       printk ("Sound: Undefined minor device %d\n", dev);
  243.     }
  244.  
  245.   return RET_ERROR (EPERM);
  246. }
  247.  
  248. int
  249. sound_write_sw (int dev, struct fileinfo *file, snd_rw_buf *buf, int count)
  250. {
  251.  
  252.   DEB (printk ("sound_write_sw(dev=%d, count=%d)\n", dev, count));
  253.  
  254.   switch (dev & 0x0f)
  255.     {
  256.  
  257.     case SND_DEV_SEQ:
  258.       return sequencer_write (dev, file, buf, count);
  259.       break;
  260.  
  261.     case SND_DEV_DSP:
  262.     case SND_DEV_DSP16:
  263.     case SND_DEV_AUDIO:
  264.       return audio_write (dev, file, buf, count);
  265.       break;
  266.  
  267.     default:
  268.       return RET_ERROR (EPERM);
  269.     }
  270.  
  271.   return count;
  272. }
  273.  
  274. int
  275. sound_open_sw (int dev, struct fileinfo *file)
  276. {
  277.   int             retval;
  278.   DEB (printk ("sound_open_sw(dev=%d) : usecount=%d\n", dev, sbc_devices[dev].usecount));
  279.  
  280.   if ((dev >= SND_NDEVS) || (dev < 0))
  281.     {
  282.       printk ("Invalid minor device %d\n", dev);
  283.       return RET_ERROR (ENXIO);
  284.     }
  285.  
  286.   switch (dev & 0x0f)
  287.     {
  288.     case SND_DEV_STATUS:
  289.       if (status_busy)
  290.     return RET_ERROR (EBUSY);
  291.       status_busy = 1;
  292.       if ((status_buf = (char *) KERNEL_MALLOC (4000)) == NULL)
  293.     return RET_ERROR (EIO);
  294.       status_len = status_ptr = 0;
  295.       init_status ();
  296.       break;
  297.  
  298.     case SND_DEV_CTL:
  299.       return 0;
  300.       break;
  301.  
  302.     case SND_DEV_SEQ:
  303.       if ((retval = sequencer_open (dev, file)) < 0)
  304.     return retval;
  305.       break;
  306.  
  307. #ifndef EXCLUDE_MPU401
  308.     case SND_DEV_MIDIN:
  309.       if ((retval = MIDIbuf_open (dev, file)) < 0)
  310.     return retval;
  311.       break;
  312. #endif
  313.  
  314.     case SND_DEV_DSP:
  315.     case SND_DEV_DSP16:
  316.     case SND_DEV_AUDIO:
  317.       if ((retval = audio_open (dev, file)) < 0)
  318.     return retval;
  319.       break;
  320.  
  321.     default:
  322.       printk ("Invalid minor device %d\n", dev);
  323.       return RET_ERROR (ENXIO);
  324.     }
  325.  
  326.   sbc_devices[dev].usecount++;
  327.   in_use++;
  328.  
  329.   return 0;
  330. }
  331.  
  332. void
  333. sound_release_sw (int dev, struct fileinfo *file)
  334. {
  335.  
  336.   DEB (printk ("sound_release_sw(dev=%d)\n", dev));
  337.  
  338.   switch (dev & 0x0f)
  339.     {
  340.     case SND_DEV_STATUS:
  341.       if (status_buf)
  342.     KERNEL_FREE (status_buf);
  343.       status_buf = NULL;
  344.       status_busy = 0;
  345.       break;
  346.  
  347.     case SND_DEV_CTL:
  348.       break;
  349.  
  350.     case SND_DEV_SEQ:
  351.       sequencer_release (dev, file);
  352.       break;
  353.  
  354. #ifndef EXCLUDE_MPU401
  355.     case SND_DEV_MIDIN:
  356.       MIDIbuf_release (dev, file);
  357.       break;
  358. #endif
  359.  
  360.     case SND_DEV_DSP:
  361.     case SND_DEV_DSP16:
  362.     case SND_DEV_AUDIO:
  363.       audio_release (dev, file);
  364.       break;
  365.  
  366.     default:
  367.       printk ("Sound error: Releasing unknown device 0x%02x\n", dev);
  368.     }
  369.  
  370.   sbc_devices[dev].usecount--;
  371.   in_use--;
  372. }
  373.  
  374. int
  375. sound_ioctl_sw (int dev, struct fileinfo *file,
  376.          unsigned int cmd, unsigned long arg)
  377. {
  378.   DEB (printk ("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
  379.  
  380.   switch (dev & 0x0f)
  381.     {
  382.  
  383.     case SND_DEV_CTL:
  384.  
  385.       if (!num_mixers)
  386.     return RET_ERROR (ENXIO);
  387.  
  388.       if ((dev >> 4) >= num_mixers)
  389.     return RET_ERROR (ENXIO);
  390.  
  391.       return mixer_devs[dev >> 4]->ioctl (dev >> 4, cmd, arg);
  392.       break;
  393.  
  394.     case SND_DEV_SEQ:
  395.       return sequencer_ioctl (dev, file, cmd, arg);
  396.       break;
  397.  
  398.     case SND_DEV_DSP:
  399.     case SND_DEV_DSP16:
  400.     case SND_DEV_AUDIO:
  401.       return audio_ioctl (dev, file, cmd, arg);
  402.       break;
  403.  
  404. #ifndef EXCLUDE_MPU401
  405.     case SND_DEV_MIDIN:
  406.       return MIDIbuf_ioctl (dev, file, cmd, arg);
  407.       break;
  408. #endif
  409.  
  410.     default:
  411.       return RET_ERROR (EPERM);
  412.       break;
  413.     }
  414.  
  415.   return RET_ERROR (EPERM);
  416. }
  417. #endif
  418.