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

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