root/drivers/sound/sound_switch.c

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

DEFINITIONS

This source file includes following definitions.
  1. put_status
  2. put_status_int
  3. init_status
  4. read_status
  5. sound_read_sw
  6. sound_write_sw
  7. sound_open_sw
  8. sound_release_sw
  9. sound_ioctl_sw

   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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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

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