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 = strnlen (s, 256);
  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 #ifdef SOUND_UNAME_A
 115   put_status ("VoxWare Sound Driver:" SOUND_VERSION_STRING
 116               " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY ",\n"
 117               SOUND_UNAME_A ")"
 118               "\n");
 119 #else
 120   put_status ("VoxWare Sound Driver:" SOUND_VERSION_STRING
 121               " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
 122               SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")"
 123               "\n");
 124 #endif
 125 
 126   if (!put_status ("Config options: "))
 127     return;
 128   if (!put_status_int (SELECTED_SOUND_OPTIONS, 16))
 129     return;
 130 
 131   if (!put_status ("\n\nInstalled drivers: \n"))
 132     return;
 133 
 134   for (i = 0; i < num_sound_drivers; i++)
 135     if (sound_drivers[i].card_type != 0)
 136       {
 137         if (!put_status ("Type "))
 138           return;
 139         if (!put_status_int (sound_drivers[i].card_type, 10))
 140           return;
 141         if (!put_status (": "))
 142           return;
 143         if (!put_status (sound_drivers[i].name))
 144           return;
 145 
 146         if (!put_status ("\n"))
 147           return;
 148       }
 149 
 150   if (!put_status ("\n\nCard config: \n"))
 151     return;
 152 
 153   for (i = 0; i < num_sound_cards; i++)
 154     if (snd_installed_cards[i].card_type != 0)
 155       {
 156         int             drv, tmp;
 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 
 176         if (!put_status (" irq "))
 177           return;
 178         tmp = snd_installed_cards[i].config.irq;
 179         if (tmp < 0)
 180           tmp = -tmp;
 181         if (!put_status_int (tmp, 10))
 182           return;
 183 
 184         if (snd_installed_cards[i].config.dma != -1)
 185           {
 186             if (!put_status (" drq "))
 187               return;
 188             if (!put_status_int (snd_installed_cards[i].config.dma, 10))
 189               return;
 190             if (snd_installed_cards[i].config.dma2 != -1)
 191               {
 192                 if (!put_status (","))
 193                   return;
 194                 if (!put_status_int (snd_installed_cards[i].config.dma2, 10))
 195                   return;
 196               }
 197           }
 198 
 199         if (!snd_installed_cards[i].enabled)
 200           if (!put_status (")"))
 201             return;
 202 
 203         if (!put_status ("\n"))
 204           return;
 205       }
 206 
 207   if (!sound_started)
 208     {
 209       put_status ("\n\n***** Sound driver not started *****\n\n");
 210       return;
 211     }
 212 
 213 #ifdef EXCLUDE_AUDIO
 214   if (!put_status ("\nAudio devices: NOT ENABLED IN CONFIG\n"))
 215     return;
 216 #else
 217   if (!put_status ("\nAudio devices:\n"))
 218     return;
 219 
 220   for (i = 0; i < num_audiodevs; i++)
 221     {
 222       if (!put_status_int (i, 10))
 223         return;
 224       if (!put_status (": "))
 225         return;
 226       if (!put_status (audio_devs[i]->name))
 227         return;
 228 
 229       if (audio_devs[i]->flags & DMA_DUPLEX)
 230         if (!put_status (" (DUPLEX)"))
 231           return;
 232 
 233       if (!put_status ("\n"))
 234         return;
 235     }
 236 #endif
 237 
 238 #ifdef EXCLUDE_SEQUENCER
 239   if (!put_status ("\nSynth devices: NOT ENABLED IN CONFIG\n"))
 240     return;
 241 #else
 242   if (!put_status ("\nSynth devices:\n"))
 243     return;
 244 
 245   for (i = 0; i < num_synths; i++)
 246     {
 247       if (!put_status_int (i, 10))
 248         return;
 249       if (!put_status (": "))
 250         return;
 251       if (!put_status (synth_devs[i]->info->name))
 252         return;
 253       if (!put_status ("\n"))
 254         return;
 255     }
 256 #endif
 257 
 258 #ifdef EXCLUDE_MIDI
 259   if (!put_status ("\nMidi devices: NOT ENABLED IN CONFIG\n"))
 260     return;
 261 #else
 262   if (!put_status ("\nMidi devices:\n"))
 263     return;
 264 
 265   for (i = 0; i < num_midis; i++)
 266     {
 267       if (!put_status_int (i, 10))
 268         return;
 269       if (!put_status (": "))
 270         return;
 271       if (!put_status (midi_devs[i]->info.name))
 272         return;
 273       if (!put_status ("\n"))
 274         return;
 275     }
 276 #endif
 277 
 278   if (!put_status ("\nTimers:\n"))
 279     return;
 280 
 281   for (i = 0; i < num_sound_timers; i++)
 282     {
 283       if (!put_status_int (i, 10))
 284         return;
 285       if (!put_status (": "))
 286         return;
 287       if (!put_status (sound_timer_devs[i]->info.name))
 288         return;
 289       if (!put_status ("\n"))
 290         return;
 291     }
 292 
 293   if (!put_status ("\nMixers:\n"))
 294     return;
 295 
 296   for (i = 0; i < num_mixers; i++)
 297     {
 298       if (!put_status_int (i, 10))
 299         return;
 300       if (!put_status (": "))
 301         return;
 302       if (!put_status (mixer_devs[i]->name))
 303         return;
 304       if (!put_status ("\n"))
 305         return;
 306     }
 307 }
 308 
 309 static int
 310 read_status (snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 311 {
 312   /*
 313    * Return at most 'count' bytes from the status_buf.
 314    */
 315   int             l, c;
 316 
 317   l = count;
 318   c = status_len - status_ptr;
 319 
 320   if (l > c)
 321     l = c;
 322   if (l <= 0)
 323     return 0;
 324 
 325   memcpy_tofs (&((buf)[0]), &status_buf[status_ptr], l);
 326   status_ptr += l;
 327 
 328   return l;
 329 }
 330 
 331 int
 332 sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 333 {
 334   DEB (printk ("sound_read_sw(dev=%d, count=%d)\n", dev, count));
 335 
 336   switch (dev & 0x0f)
 337     {
 338     case SND_DEV_STATUS:
 339       return read_status (buf, count);
 340       break;
 341 
 342 #ifndef EXCLUDE_AUDIO
 343     case SND_DEV_DSP:
 344     case SND_DEV_DSP16:
 345     case SND_DEV_AUDIO:
 346       return audio_read (dev, file, buf, count);
 347       break;
 348 #endif
 349 
 350 #ifndef EXCLUDE_SEQUENCER
 351     case SND_DEV_SEQ:
 352     case SND_DEV_SEQ2:
 353       return sequencer_read (dev, file, buf, count);
 354       break;
 355 #endif
 356 
 357 #ifndef EXCLUDE_MIDI
 358     case SND_DEV_MIDIN:
 359       return MIDIbuf_read (dev, file, buf, count);
 360 #endif
 361 
 362     default:
 363       printk ("Sound: Undefined minor device %d\n", dev);
 364     }
 365 
 366   return -EPERM;
 367 }
 368 
 369 int
 370 sound_write_sw (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 371 {
 372 
 373   DEB (printk ("sound_write_sw(dev=%d, count=%d)\n", dev, count));
 374 
 375   switch (dev & 0x0f)
 376     {
 377 
 378 #ifndef EXCLUDE_SEQUENCER
 379     case SND_DEV_SEQ:
 380     case SND_DEV_SEQ2:
 381       return sequencer_write (dev, file, buf, count);
 382       break;
 383 #endif
 384 
 385 #ifndef EXCLUDE_AUDIO
 386     case SND_DEV_DSP:
 387     case SND_DEV_DSP16:
 388     case SND_DEV_AUDIO:
 389       return audio_write (dev, file, buf, count);
 390       break;
 391 #endif
 392 
 393 #ifndef EXCLUDE_MIDI
 394     case SND_DEV_MIDIN:
 395       return MIDIbuf_write (dev, file, buf, count);
 396 #endif
 397 
 398     default:
 399       return -EPERM;
 400     }
 401 
 402   return count;
 403 }
 404 
 405 int
 406 sound_open_sw (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 407 {
 408   int             retval;
 409 
 410   DEB (printk ("sound_open_sw(dev=%d) : usecount=%d\n", dev, sbc_devices[dev].usecount));
 411 
 412   if ((dev >= SND_NDEVS) || (dev < 0))
 413     {
 414       printk ("Invalid minor device %d\n", dev);
 415       return -ENXIO;
 416     }
 417 
 418   switch (dev & 0x0f)
 419     {
 420     case SND_DEV_STATUS:
 421       if (status_busy)
 422         return -EBUSY;
 423       status_busy = 1;
 424       if ((status_buf = (char *) kmalloc (4000, GFP_KERNEL)) == NULL)
 425         return -EIO;
 426       status_len = status_ptr = 0;
 427       init_status ();
 428       break;
 429 
 430     case SND_DEV_CTL:
 431       return 0;
 432       break;
 433 
 434 #ifndef EXCLUDE_SEQUENCER
 435     case SND_DEV_SEQ:
 436     case SND_DEV_SEQ2:
 437       if ((retval = sequencer_open (dev, file)) < 0)
 438         return retval;
 439       break;
 440 #endif
 441 
 442 #ifndef EXCLUDE_MIDI
 443     case SND_DEV_MIDIN:
 444       if ((retval = MIDIbuf_open (dev, file)) < 0)
 445         return retval;
 446       break;
 447 #endif
 448 
 449 #ifndef EXCLUDE_AUDIO
 450     case SND_DEV_DSP:
 451     case SND_DEV_DSP16:
 452     case SND_DEV_AUDIO:
 453       if ((retval = audio_open (dev, file)) < 0)
 454         return retval;
 455       break;
 456 #endif
 457 
 458     default:
 459       printk ("Invalid minor device %d\n", dev);
 460       return -ENXIO;
 461     }
 462 
 463   sbc_devices[dev].usecount++;
 464   in_use++;
 465 
 466   return 0;
 467 }
 468 
 469 void
 470 sound_release_sw (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 471 {
 472 
 473   DEB (printk ("sound_release_sw(dev=%d)\n", dev));
 474 
 475   switch (dev & 0x0f)
 476     {
 477     case SND_DEV_STATUS:
 478       if (status_buf)
 479         kfree (status_buf);
 480       status_buf = NULL;
 481       status_busy = 0;
 482       break;
 483 
 484     case SND_DEV_CTL:
 485       break;
 486 
 487 #ifndef EXCLUDE_SEQUENCER
 488     case SND_DEV_SEQ:
 489     case SND_DEV_SEQ2:
 490       sequencer_release (dev, file);
 491       break;
 492 #endif
 493 
 494 #ifndef EXCLUDE_MIDI
 495     case SND_DEV_MIDIN:
 496       MIDIbuf_release (dev, file);
 497       break;
 498 #endif
 499 
 500 #ifndef EXCLUDE_AUDIO
 501     case SND_DEV_DSP:
 502     case SND_DEV_DSP16:
 503     case SND_DEV_AUDIO:
 504       audio_release (dev, file);
 505       break;
 506 #endif
 507 
 508     default:
 509       printk ("Sound error: Releasing unknown device 0x%02x\n", dev);
 510     }
 511 
 512   sbc_devices[dev].usecount--;
 513   in_use--;
 514 }
 515 
 516 int
 517 sound_ioctl_sw (int dev, struct fileinfo *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 518                 unsigned int cmd, ioctl_arg arg)
 519 {
 520   DEB (printk ("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
 521 
 522   if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0)     /* Mixer ioctl */
 523     if ((dev & 0x0f) != SND_DEV_CTL)
 524       {
 525         int             dtype = dev & 0x0f;
 526         int             mixdev;
 527 
 528         switch (dtype)
 529           {
 530 #ifndef EXCLUDE_AUDIO
 531           case SND_DEV_DSP:
 532           case SND_DEV_DSP16:
 533           case SND_DEV_AUDIO:
 534             mixdev = audio_devs[dev >> 4]->mixer_dev;
 535             if (mixdev < 0 || mixdev >= num_mixers)
 536               return -ENXIO;
 537             return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
 538             break;
 539 #endif
 540 
 541           default:
 542             return mixer_devs[0]->ioctl (0, cmd, arg);
 543           }
 544       }
 545 
 546   switch (dev & 0x0f)
 547     {
 548 
 549     case SND_DEV_CTL:
 550 
 551       if (!num_mixers)
 552         return -ENXIO;
 553 
 554       dev = dev >> 4;
 555 
 556       if (dev >= num_mixers)
 557         return -ENXIO;
 558 
 559       return mixer_devs[dev]->ioctl (dev, cmd, arg);
 560       break;
 561 
 562 #ifndef EXCLUDE_SEQUENCER
 563     case SND_DEV_SEQ:
 564     case SND_DEV_SEQ2:
 565       return sequencer_ioctl (dev, file, cmd, arg);
 566       break;
 567 #endif
 568 
 569 #ifndef EXCLUDE_AUDIO
 570     case SND_DEV_DSP:
 571     case SND_DEV_DSP16:
 572     case SND_DEV_AUDIO:
 573       return audio_ioctl (dev, file, cmd, arg);
 574       break;
 575 #endif
 576 
 577 #ifndef EXCLUDE_MIDI
 578     case SND_DEV_MIDIN:
 579       return MIDIbuf_ioctl (dev, file, cmd, arg);
 580       break;
 581 #endif
 582 
 583     default:
 584       return -EPERM;
 585       break;
 586     }
 587 
 588   return -EPERM;
 589 }
 590 
 591 #endif

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