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 handler
   5  */
   6 /*
   7  * Copyright by Hannu Savolainen 1993-1996
   8  *
   9  * Redistribution and use in source and binary forms, with or without
  10  * modification, are permitted provided that the following conditions are
  11  * met: 1. Redistributions of source code must retain the above copyright
  12  * notice, this list of conditions and the following disclaimer. 2.
  13  * Redistributions in binary form must reproduce the above copyright notice,
  14  * this list of conditions and the following disclaimer in the documentation
  15  * and/or other materials provided with the distribution.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 #include <linux/config.h>
  30 
  31 
  32 #include "sound_config.h"
  33 
  34 struct sbc_device
  35   {
  36     int             usecount;
  37   };
  38 
  39 static int      in_use = 0;     /* Total # of open devices */
  40 
  41 /*
  42  * /dev/sndstatus -device
  43  */
  44 static char    *status_buf = NULL;
  45 static int      status_len, status_ptr;
  46 static int      status_busy = 0;
  47 
  48 static int
  49 put_status (char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51   int             l = strnlen (s, 256);
  52 
  53   if (status_len + l >= 4000)
  54     return 0;
  55 
  56   memcpy (&status_buf[status_len], s, l);
  57   status_len += l;
  58 
  59   return 1;
  60 }
  61 
  62 static int
  63 put_status_int (unsigned int val, int radix)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65   int             l, v;
  66 
  67   static char     hx[] = "0123456789abcdef";
  68   char            buf[11];
  69 
  70   if (!val)
  71     return put_status ("0");
  72 
  73   l = 0;
  74   buf[10] = 0;
  75 
  76   while (val)
  77     {
  78       v = val % radix;
  79       val = val / radix;
  80 
  81       buf[9 - l] = hx[v];
  82       l++;
  83     }
  84 
  85   if (status_len + l >= 4000)
  86     return 0;
  87 
  88   memcpy (&status_buf[status_len], &buf[10 - l], l);
  89   status_len += l;
  90 
  91   return 1;
  92 }
  93 
  94 static void
  95 init_status (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97   /*
  98    * Write the status information to the status_buf and update status_len.
  99    * There is a limit of 4000 bytes for the data.
 100    */
 101 
 102   int             i;
 103 
 104   status_ptr = 0;
 105 
 106 #ifdef SOUND_UNAME_A
 107   put_status ("Sound Driver:" SOUND_VERSION_STRING
 108               " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY ",\n"
 109               SOUND_UNAME_A ")"
 110               "\n");
 111 #else
 112   put_status ("Sound Driver:" SOUND_VERSION_STRING
 113               " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
 114               SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")"
 115               "\n");
 116 #endif
 117 
 118   put_status ("Kernel: ");
 119   put_status (system_utsname.sysname);
 120   put_status (" ");
 121   put_status (system_utsname.nodename);
 122   put_status (" ");
 123   put_status (system_utsname.release);
 124   put_status (" ");
 125   put_status (system_utsname.version);
 126   put_status (" ");
 127   put_status (system_utsname.machine);
 128   put_status ("\n");
 129 
 130   if (!put_status ("Config options: "))
 131     return;
 132   if (!put_status_int (SELECTED_SOUND_OPTIONS, 16))
 133     return;
 134 
 135   if (!put_status ("\n\nInstalled drivers: \n"))
 136     return;
 137 
 138   for (i = 0; i < num_sound_drivers; i++)
 139     if (sound_drivers[i].card_type != 0)
 140       {
 141         if (!put_status ("Type "))
 142           return;
 143         if (!put_status_int (sound_drivers[i].card_type, 10))
 144           return;
 145         if (!put_status (": "))
 146           return;
 147         if (!put_status (sound_drivers[i].name))
 148           return;
 149 
 150         if (!put_status ("\n"))
 151           return;
 152       }
 153 
 154   if (!put_status ("\nCard config: \n"))
 155     return;
 156 
 157   for (i = 0; i < num_sound_cards; i++)
 158     if (snd_installed_cards[i].card_type != 0)
 159       {
 160         int             drv, tmp;
 161 
 162         if (!snd_installed_cards[i].enabled)
 163           if (!put_status ("("))
 164             return;
 165 
 166         /*
 167          * if (!put_status_int(snd_installed_cards[i].card_type, 10)) return;
 168          * if (!put_status (": ")) return;
 169          */
 170 
 171         if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) != -1)
 172           if (!put_status (sound_drivers[drv].name))
 173             return;
 174 
 175         if (!put_status (" at 0x"))
 176           return;
 177         if (!put_status_int (snd_installed_cards[i].config.io_base, 16))
 178           return;
 179 
 180         if (!put_status (" irq "))
 181           return;
 182         tmp = snd_installed_cards[i].config.irq;
 183         if (tmp < 0)
 184           tmp = -tmp;
 185         if (!put_status_int (tmp, 10))
 186           return;
 187 
 188         if (snd_installed_cards[i].config.dma != -1)
 189           {
 190             if (!put_status (" drq "))
 191               return;
 192             if (!put_status_int (snd_installed_cards[i].config.dma, 10))
 193               return;
 194             if (snd_installed_cards[i].config.dma2 != -1)
 195               {
 196                 if (!put_status (","))
 197                   return;
 198                 if (!put_status_int (snd_installed_cards[i].config.dma2, 10))
 199                   return;
 200               }
 201           }
 202 
 203         if (!snd_installed_cards[i].enabled)
 204           if (!put_status (")"))
 205             return;
 206 
 207         if (!put_status ("\n"))
 208           return;
 209       }
 210 
 211   if (!sound_started)
 212     {
 213       put_status ("\n\n***** Sound driver not started *****\n\n");
 214       return;
 215     }
 216 
 217 #ifndef CONFIG_AUDIO
 218   if (!put_status ("\nAudio devices: NOT ENABLED IN CONFIG\n"))
 219     return;
 220 #else
 221   if (!put_status ("\nAudio devices:\n"))
 222     return;
 223 
 224   for (i = 0; i < num_audiodevs; i++)
 225     {
 226       if (!put_status_int (i, 10))
 227         return;
 228       if (!put_status (": "))
 229         return;
 230       if (!put_status (audio_devs[i]->name))
 231         return;
 232 
 233       if (audio_devs[i]->flags & DMA_DUPLEX)
 234         if (!put_status (" (DUPLEX)"))
 235           return;
 236 
 237       if (!put_status ("\n"))
 238         return;
 239     }
 240 #endif
 241 
 242 #ifndef CONFIG_SEQUENCER
 243   if (!put_status ("\nSynth devices: NOT ENABLED IN CONFIG\n"))
 244     return;
 245 #else
 246   if (!put_status ("\nSynth devices:\n"))
 247     return;
 248 
 249   for (i = 0; i < num_synths; i++)
 250     {
 251       if (!put_status_int (i, 10))
 252         return;
 253       if (!put_status (": "))
 254         return;
 255       if (!put_status (synth_devs[i]->info->name))
 256         return;
 257       if (!put_status ("\n"))
 258         return;
 259     }
 260 #endif
 261 
 262 #ifndef CONFIG_MIDI
 263   if (!put_status ("\nMidi devices: NOT ENABLED IN CONFIG\n"))
 264     return;
 265 #else
 266   if (!put_status ("\nMidi devices:\n"))
 267     return;
 268 
 269   for (i = 0; i < num_midis; i++)
 270     {
 271       if (!put_status_int (i, 10))
 272         return;
 273       if (!put_status (": "))
 274         return;
 275       if (!put_status (midi_devs[i]->info.name))
 276         return;
 277       if (!put_status ("\n"))
 278         return;
 279     }
 280 #endif
 281 
 282   if (!put_status ("\nTimers:\n"))
 283     return;
 284 
 285   for (i = 0; i < num_sound_timers; i++)
 286     {
 287       if (!put_status_int (i, 10))
 288         return;
 289       if (!put_status (": "))
 290         return;
 291       if (!put_status (sound_timer_devs[i]->info.name))
 292         return;
 293       if (!put_status ("\n"))
 294         return;
 295     }
 296 
 297   if (!put_status ("\nMixers:\n"))
 298     return;
 299 
 300   for (i = 0; i < num_mixers; i++)
 301     {
 302       if (!put_status_int (i, 10))
 303         return;
 304       if (!put_status (": "))
 305         return;
 306       if (!put_status (mixer_devs[i]->name))
 307         return;
 308       if (!put_status ("\n"))
 309         return;
 310     }
 311 }
 312 
 313 static int
 314 read_status (char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 315 {
 316   /*
 317    * Return at most 'count' bytes from the status_buf.
 318    */
 319   int             l, c;
 320 
 321   l = count;
 322   c = status_len - status_ptr;
 323 
 324   if (l > c)
 325     l = c;
 326   if (l <= 0)
 327     return 0;
 328 
 329   memcpy_tofs (&((buf)[0]), &status_buf[status_ptr], l);
 330   status_ptr += l;
 331 
 332   return l;
 333 }
 334 
 335 int
 336 sound_read_sw (int dev, struct fileinfo *file, char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 337 {
 338   DEB (printk ("sound_read_sw(dev=%d, count=%d)\n", dev, count));
 339 
 340   switch (dev & 0x0f)
 341     {
 342     case SND_DEV_STATUS:
 343       return read_status (buf, count);
 344       break;
 345 
 346 #ifdef CONFIG_AUDIO
 347     case SND_DEV_DSP:
 348     case SND_DEV_DSP16:
 349     case SND_DEV_AUDIO:
 350       return audio_read (dev, file, buf, count);
 351       break;
 352 #endif
 353 
 354 #ifdef CONFIG_SEQUENCER
 355     case SND_DEV_SEQ:
 356     case SND_DEV_SEQ2:
 357       return sequencer_read (dev, file, buf, count);
 358       break;
 359 #endif
 360 
 361 #ifdef CONFIG_MIDI
 362     case SND_DEV_MIDIN:
 363       return MIDIbuf_read (dev, file, buf, count);
 364 #endif
 365 
 366     default:
 367       printk ("Sound: Undefined minor device %d\n", dev);
 368     }
 369 
 370   return -EPERM;
 371 }
 372 
 373 int
 374 sound_write_sw (int dev, struct fileinfo *file, const char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 375 {
 376 
 377   DEB (printk ("sound_write_sw(dev=%d, count=%d)\n", dev, count));
 378 
 379   switch (dev & 0x0f)
 380     {
 381 
 382 #ifdef CONFIG_SEQUENCER
 383     case SND_DEV_SEQ:
 384     case SND_DEV_SEQ2:
 385       return sequencer_write (dev, file, buf, count);
 386       break;
 387 #endif
 388 
 389 #ifdef CONFIG_AUDIO
 390     case SND_DEV_DSP:
 391     case SND_DEV_DSP16:
 392     case SND_DEV_AUDIO:
 393       return audio_write (dev, file, buf, count);
 394       break;
 395 #endif
 396 
 397 #ifdef CONFIG_MIDI
 398     case SND_DEV_MIDIN:
 399       return MIDIbuf_write (dev, file, buf, count);
 400 #endif
 401 
 402     }
 403 
 404   return -EPERM;
 405 }
 406 
 407 int
 408 sound_open_sw (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 409 {
 410   DEB (printk ("sound_open_sw(dev=%d)\n", dev));
 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       if ((dev & 0xf0) && ((dev & 0xf0) >> 4) >= num_mixers)
 432         return -ENXIO;
 433       return 0;
 434       break;
 435 
 436 #ifdef CONFIG_SEQUENCER
 437     case SND_DEV_SEQ:
 438     case SND_DEV_SEQ2:
 439     {
 440       int retval;
 441 
 442       if ((retval = sequencer_open (dev, file)) < 0)
 443         return retval;
 444       break;
 445     }
 446 #endif
 447 
 448 #ifdef CONFIG_MIDI
 449     case SND_DEV_MIDIN:
 450     {
 451       int retval;
 452 
 453       if ((retval = MIDIbuf_open (dev, file)) < 0)
 454         return retval;
 455       break;
 456     }
 457 #endif
 458 
 459 #ifdef CONFIG_AUDIO
 460     case SND_DEV_DSP:
 461     case SND_DEV_DSP16:
 462     case SND_DEV_AUDIO:
 463     {
 464       int retval;
 465 
 466       if ((retval = audio_open (dev, file)) < 0)
 467         return retval;
 468       break;
 469     }
 470 #endif
 471 
 472     default:
 473       printk ("Invalid minor device %d\n", dev);
 474       return -ENXIO;
 475     }
 476 
 477   in_use++;
 478 
 479   return 0;
 480 }
 481 
 482 void
 483 sound_release_sw (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 484 {
 485 
 486   DEB (printk ("sound_release_sw(dev=%d)\n", dev));
 487 
 488   switch (dev & 0x0f)
 489     {
 490     case SND_DEV_STATUS:
 491       if (status_buf)
 492         kfree (status_buf);
 493       status_buf = NULL;
 494       status_busy = 0;
 495       break;
 496 
 497     case SND_DEV_CTL:
 498       break;
 499 
 500 #ifdef CONFIG_SEQUENCER
 501     case SND_DEV_SEQ:
 502     case SND_DEV_SEQ2:
 503       sequencer_release (dev, file);
 504       break;
 505 #endif
 506 
 507 #ifdef CONFIG_MIDI
 508     case SND_DEV_MIDIN:
 509       MIDIbuf_release (dev, file);
 510       break;
 511 #endif
 512 
 513 #ifdef CONFIG_AUDIO
 514     case SND_DEV_DSP:
 515     case SND_DEV_DSP16:
 516     case SND_DEV_AUDIO:
 517       audio_release (dev, file);
 518       break;
 519 #endif
 520 
 521     default:
 522       printk ("Sound error: Releasing unknown device 0x%02x\n", dev);
 523     }
 524   in_use--;
 525 }
 526 
 527 int
 528 sound_ioctl_sw (int dev, struct fileinfo *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 529                 unsigned int cmd, caddr_t arg)
 530 {
 531   DEB (printk ("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
 532 
 533   if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0)     /* Mixer ioctl */
 534     if ((dev & 0x0f) != SND_DEV_CTL)
 535       {
 536 #ifdef CONFIG_AUDIO
 537         int             dtype = dev & 0x0f;
 538         int             mixdev;
 539 
 540         switch (dtype)
 541           {
 542           case SND_DEV_DSP:
 543           case SND_DEV_DSP16:
 544           case SND_DEV_AUDIO:
 545             mixdev = audio_devs[dev >> 4]->mixer_dev;
 546             if (mixdev < 0 || mixdev >= num_mixers)
 547               return -ENXIO;
 548             return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
 549           }
 550 #endif
 551           return mixer_devs[0]->ioctl (0, cmd, arg);
 552       }
 553 
 554   switch (dev & 0x0f)
 555     {
 556 
 557     case SND_DEV_CTL:
 558 
 559       if (!num_mixers)
 560         return -ENXIO;
 561 
 562       dev = dev >> 4;
 563 
 564       if (dev >= num_mixers)
 565         return -ENXIO;
 566 
 567       return mixer_devs[dev]->ioctl (dev, cmd, arg);
 568       break;
 569 
 570 #ifdef CONFIG_SEQUENCER
 571     case SND_DEV_SEQ:
 572     case SND_DEV_SEQ2:
 573       return sequencer_ioctl (dev, file, cmd, arg);
 574       break;
 575 #endif
 576 
 577 #ifdef CONFIG_AUDIO
 578     case SND_DEV_DSP:
 579     case SND_DEV_DSP16:
 580     case SND_DEV_AUDIO:
 581       return audio_ioctl (dev, file, cmd, arg);
 582       break;
 583 #endif
 584 
 585 #ifdef CONFIG_MIDI
 586     case SND_DEV_MIDIN:
 587       return MIDIbuf_ioctl (dev, file, cmd, arg);
 588       break;
 589 #endif
 590 
 591     }
 592 
 593   return -EPERM;
 594 }

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