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

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