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   int             retval;
 411 
 412   DEB (printk ("sound_open_sw(dev=%d)\n", dev));
 413 
 414   if ((dev >= SND_NDEVS) || (dev < 0))
 415     {
 416       printk ("Invalid minor device %d\n", dev);
 417       return -ENXIO;
 418     }
 419 
 420   switch (dev & 0x0f)
 421     {
 422     case SND_DEV_STATUS:
 423       if (status_busy)
 424         return -EBUSY;
 425       status_busy = 1;
 426       if ((status_buf = (char *) kmalloc (4000, GFP_KERNEL)) == NULL)
 427         return -EIO;
 428       status_len = status_ptr = 0;
 429       init_status ();
 430       break;
 431 
 432     case SND_DEV_CTL:
 433       if ((dev & 0xf0) && ((dev & 0xf0) >> 4) >= num_mixers)
 434         return -ENXIO;
 435       return 0;
 436       break;
 437 
 438 #ifdef CONFIG_SEQUENCER
 439     case SND_DEV_SEQ:
 440     case SND_DEV_SEQ2:
 441       if ((retval = sequencer_open (dev, file)) < 0)
 442         return retval;
 443       break;
 444 #endif
 445 
 446 #ifdef CONFIG_MIDI
 447     case SND_DEV_MIDIN:
 448       if ((retval = MIDIbuf_open (dev, file)) < 0)
 449         return retval;
 450       break;
 451 #endif
 452 
 453 #ifdef CONFIG_AUDIO
 454     case SND_DEV_DSP:
 455     case SND_DEV_DSP16:
 456     case SND_DEV_AUDIO:
 457       if ((retval = audio_open (dev, file)) < 0)
 458         return retval;
 459       break;
 460 #endif
 461 
 462     default:
 463       printk ("Invalid minor device %d\n", dev);
 464       return -ENXIO;
 465     }
 466 
 467   in_use++;
 468 
 469   return 0;
 470 }
 471 
 472 void
 473 sound_release_sw (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 474 {
 475 
 476   DEB (printk ("sound_release_sw(dev=%d)\n", dev));
 477 
 478   switch (dev & 0x0f)
 479     {
 480     case SND_DEV_STATUS:
 481       if (status_buf)
 482         kfree (status_buf);
 483       status_buf = NULL;
 484       status_busy = 0;
 485       break;
 486 
 487     case SND_DEV_CTL:
 488       break;
 489 
 490 #ifdef CONFIG_SEQUENCER
 491     case SND_DEV_SEQ:
 492     case SND_DEV_SEQ2:
 493       sequencer_release (dev, file);
 494       break;
 495 #endif
 496 
 497 #ifdef CONFIG_MIDI
 498     case SND_DEV_MIDIN:
 499       MIDIbuf_release (dev, file);
 500       break;
 501 #endif
 502 
 503 #ifdef CONFIG_AUDIO
 504     case SND_DEV_DSP:
 505     case SND_DEV_DSP16:
 506     case SND_DEV_AUDIO:
 507       audio_release (dev, file);
 508       break;
 509 #endif
 510 
 511     default:
 512       printk ("Sound error: Releasing unknown device 0x%02x\n", dev);
 513     }
 514   in_use--;
 515 }
 516 
 517 int
 518 sound_ioctl_sw (int dev, struct fileinfo *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 519                 unsigned int cmd, caddr_t arg)
 520 {
 521   DEB (printk ("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
 522 
 523   if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0)     /* Mixer ioctl */
 524     if ((dev & 0x0f) != SND_DEV_CTL)
 525       {
 526         int             dtype = dev & 0x0f;
 527         int             mixdev;
 528 
 529         switch (dtype)
 530           {
 531 #ifdef CONFIG_AUDIO
 532           case SND_DEV_DSP:
 533           case SND_DEV_DSP16:
 534           case SND_DEV_AUDIO:
 535             mixdev = audio_devs[dev >> 4]->mixer_dev;
 536             if (mixdev < 0 || mixdev >= num_mixers)
 537               return -ENXIO;
 538             return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
 539             break;
 540 #endif
 541 
 542           default:
 543             return mixer_devs[0]->ioctl (0, cmd, arg);
 544           }
 545       }
 546 
 547   switch (dev & 0x0f)
 548     {
 549 
 550     case SND_DEV_CTL:
 551 
 552       if (!num_mixers)
 553         return -ENXIO;
 554 
 555       dev = dev >> 4;
 556 
 557       if (dev >= num_mixers)
 558         return -ENXIO;
 559 
 560       return mixer_devs[dev]->ioctl (dev, cmd, arg);
 561       break;
 562 
 563 #ifdef CONFIG_SEQUENCER
 564     case SND_DEV_SEQ:
 565     case SND_DEV_SEQ2:
 566       return sequencer_ioctl (dev, file, cmd, arg);
 567       break;
 568 #endif
 569 
 570 #ifdef CONFIG_AUDIO
 571     case SND_DEV_DSP:
 572     case SND_DEV_DSP16:
 573     case SND_DEV_AUDIO:
 574       return audio_ioctl (dev, file, cmd, arg);
 575       break;
 576 #endif
 577 
 578 #ifdef CONFIG_MIDI
 579     case SND_DEV_MIDIN:
 580       return MIDIbuf_ioctl (dev, file, cmd, arg);
 581       break;
 582 #endif
 583 
 584     }
 585 
 586   return -EPERM;
 587 }

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