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

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