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 ("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   if (!put_status ("\nPCM devices:\n"))
 188     return;
 189 
 190   for (i = 0; i < num_audiodevs; i++)
 191     {
 192       if (!put_status_int (i, 10))
 193         return;
 194       if (!put_status (": "))
 195         return;
 196       if (!put_status (audio_devs[i]->name))
 197         return;
 198       if (!put_status ("\n"))
 199         return;
 200     }
 201 
 202   if (!put_status ("\nSynth devices:\n"))
 203     return;
 204 
 205   for (i = 0; i < num_synths; i++)
 206     {
 207       if (!put_status_int (i, 10))
 208         return;
 209       if (!put_status (": "))
 210         return;
 211       if (!put_status (synth_devs[i]->info->name))
 212         return;
 213       if (!put_status ("\n"))
 214         return;
 215     }
 216 
 217   if (!put_status ("\nMidi devices:\n"))
 218     return;
 219 
 220   for (i = 0; i < num_midis; i++)
 221     {
 222       if (!put_status_int (i, 10))
 223         return;
 224       if (!put_status (": "))
 225         return;
 226       if (!put_status (midi_devs[i]->info.name))
 227         return;
 228       if (!put_status ("\n"))
 229         return;
 230     }
 231 
 232   if (!put_status ("\nMIDI Timers:\n"))
 233     return;
 234 
 235   for (i = 0; i < num_sound_timers; i++)
 236     {
 237       if (!put_status_int (i, 10))
 238         return;
 239       if (!put_status (": "))
 240         return;
 241       if (!put_status (sound_timer_devs[i]->info.name))
 242         return;
 243       if (!put_status ("\n"))
 244         return;
 245     }
 246 
 247   if (!put_status ("\n"))
 248     return;
 249   if (!put_status_int (num_mixers, 10))
 250     return;
 251   if (!put_status (" mixer(s) installed\n"))
 252     return;
 253 }
 254 
 255 static int
 256 read_status (snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 257 {
 258   /*
 259    * Return at most 'count' bytes from the status_buf.
 260    */
 261   int             l, c;
 262 
 263   l = count;
 264   c = status_len - status_ptr;
 265 
 266   if (l > c)
 267     l = c;
 268   if (l <= 0)
 269     return 0;
 270 
 271   COPY_TO_USER (buf, 0, &status_buf[status_ptr], l);
 272   status_ptr += l;
 273 
 274   return l;
 275 }
 276 
 277 int
 278 sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 279 {
 280   DEB (printk ("sound_read_sw(dev=%d, count=%d)\n", dev, count));
 281 
 282   switch (dev & 0x0f)
 283     {
 284     case SND_DEV_STATUS:
 285       return read_status (buf, count);
 286       break;
 287 
 288     case SND_DEV_DSP:
 289     case SND_DEV_DSP16:
 290     case SND_DEV_AUDIO:
 291       return audio_read (dev, file, buf, count);
 292       break;
 293 
 294     case SND_DEV_SEQ:
 295     case SND_DEV_SEQ2:
 296       return sequencer_read (dev, file, buf, count);
 297       break;
 298 
 299 #ifndef EXCLUDE_MIDI
 300     case SND_DEV_MIDIN:
 301       return MIDIbuf_read (dev, file, buf, count);
 302 #endif
 303 
 304 #ifndef EXCLUDE_PSS
 305     case SND_DEV_PSS:
 306       return pss_read (dev, file, buf, count);
 307 #endif
 308 
 309     default:
 310       printk ("Sound: Undefined minor device %d\n", dev);
 311     }
 312 
 313   return RET_ERROR (EPERM);
 314 }
 315 
 316 int
 317 sound_write_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 318 {
 319 
 320   DEB (printk ("sound_write_sw(dev=%d, count=%d)\n", dev, count));
 321 
 322   switch (dev & 0x0f)
 323     {
 324 
 325     case SND_DEV_SEQ:
 326     case SND_DEV_SEQ2:
 327       return sequencer_write (dev, file, buf, count);
 328       break;
 329 
 330     case SND_DEV_DSP:
 331     case SND_DEV_DSP16:
 332     case SND_DEV_AUDIO:
 333       return audio_write (dev, file, buf, count);
 334       break;
 335 
 336 #ifndef EXCLUDE_MIDI
 337     case SND_DEV_MIDIN:
 338       return MIDIbuf_write (dev, file, buf, count);
 339 #endif
 340 
 341 #ifndef EXCLUDE_PSS
 342     case SND_DEV_PSS:
 343       return pss_write (dev, file, buf, count);
 344 #endif
 345 
 346     default:
 347       return RET_ERROR (EPERM);
 348     }
 349 
 350   return count;
 351 }
 352 
 353 int
 354 sound_open_sw (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 355 {
 356   int             retval;
 357 
 358   DEB (printk ("sound_open_sw(dev=%d) : usecount=%d\n", dev, sbc_devices[dev].usecount));
 359 
 360   if ((dev >= SND_NDEVS) || (dev < 0))
 361     {
 362       printk ("Invalid minor device %d\n", dev);
 363       return RET_ERROR (ENXIO);
 364     }
 365 
 366   switch (dev & 0x0f)
 367     {
 368     case SND_DEV_STATUS:
 369       if (status_busy)
 370         return RET_ERROR (EBUSY);
 371       status_busy = 1;
 372       if ((status_buf = (char *) KERNEL_MALLOC (4000)) == NULL)
 373         return RET_ERROR (EIO);
 374       status_len = status_ptr = 0;
 375       init_status ();
 376       break;
 377 
 378     case SND_DEV_CTL:
 379       return 0;
 380       break;
 381 
 382     case SND_DEV_SEQ:
 383     case SND_DEV_SEQ2:
 384       if ((retval = sequencer_open (dev, file)) < 0)
 385         return retval;
 386       break;
 387 
 388 #ifndef EXCLUDE_MIDI
 389     case SND_DEV_MIDIN:
 390       if ((retval = MIDIbuf_open (dev, file)) < 0)
 391         return retval;
 392       break;
 393 #endif
 394 
 395 #ifndef EXCLUDE_PSS
 396     case SND_DEV_PSS:
 397       if ((retval = pss_open (dev, file)) < 0)
 398         return retval;
 399       break;
 400 #endif
 401 
 402     case SND_DEV_DSP:
 403     case SND_DEV_DSP16:
 404     case SND_DEV_AUDIO:
 405       if ((retval = audio_open (dev, file)) < 0)
 406         return retval;
 407       break;
 408 
 409     default:
 410       printk ("Invalid minor device %d\n", dev);
 411       return RET_ERROR (ENXIO);
 412     }
 413 
 414   sbc_devices[dev].usecount++;
 415   in_use++;
 416 
 417   return 0;
 418 }
 419 
 420 void
 421 sound_release_sw (int dev, struct fileinfo *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 422 {
 423 
 424   DEB (printk ("sound_release_sw(dev=%d)\n", dev));
 425 
 426   switch (dev & 0x0f)
 427     {
 428     case SND_DEV_STATUS:
 429       if (status_buf)
 430         KERNEL_FREE (status_buf);
 431       status_buf = NULL;
 432       status_busy = 0;
 433       break;
 434 
 435     case SND_DEV_CTL:
 436       break;
 437 
 438     case SND_DEV_SEQ:
 439     case SND_DEV_SEQ2:
 440       sequencer_release (dev, file);
 441       break;
 442 
 443 #ifndef EXCLUDE_MIDI
 444     case SND_DEV_MIDIN:
 445       MIDIbuf_release (dev, file);
 446       break;
 447 #endif
 448 
 449 #ifndef EXCLUDE_PSS
 450     case SND_DEV_PSS:
 451       pss_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 ((dev & 0x0f) != SND_DEV_CTL && num_mixers > 0)
 476     if ((cmd >> 8) & 0xff == 'M')       /*
 477                                          * Mixer ioctl
 478                                          */
 479       return mixer_devs[0]->ioctl (0, cmd, arg);
 480 
 481   switch (dev & 0x0f)
 482     {
 483 
 484     case SND_DEV_CTL:
 485 
 486       if (!num_mixers)
 487         return RET_ERROR (ENXIO);
 488 
 489       dev = dev >> 4;
 490 
 491       if (dev >= num_mixers)
 492         return RET_ERROR (ENXIO);
 493 
 494       return mixer_devs[dev]->ioctl (dev, cmd, arg);
 495       break;
 496 
 497     case SND_DEV_SEQ:
 498     case SND_DEV_SEQ2:
 499       return sequencer_ioctl (dev, file, cmd, arg);
 500       break;
 501 
 502     case SND_DEV_DSP:
 503     case SND_DEV_DSP16:
 504     case SND_DEV_AUDIO:
 505       return audio_ioctl (dev, file, cmd, arg);
 506       break;
 507 
 508 #ifndef EXCLUDE_MIDI
 509     case SND_DEV_MIDIN:
 510       return MIDIbuf_ioctl (dev, file, cmd, arg);
 511       break;
 512 #endif
 513 
 514 #ifndef EXCLUDE_PSS
 515     case SND_DEV_PSS:
 516       return pss_ioctl (dev, file, cmd, arg);
 517       break;
 518 #endif
 519 
 520     default:
 521       return RET_ERROR (EPERM);
 522       break;
 523     }
 524 
 525   return RET_ERROR (EPERM);
 526 }
 527 
 528 #endif

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