!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/sound/   drwxr-xr-x
Free 318.37 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     pas2_pcm.c (9.05 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * pas2_pcm.c Audio routines for PAS16
 *
 *
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.
 *
 *
 * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
 * Alan Cox       : Swatted a double allocation of device bug. Made a few
 *             more things module options.
 * Bartlomiej Zolnierkiewicz : Added __init to pas_pcm_init()
 */

#include <linux/init.h>
#include "sound_config.h"

#include "pas2.h"

#ifndef DEB
#define DEB(WHAT)
#endif

#define PAS_PCM_INTRBITS (0x08)
/*
 * Sample buffer timer interrupt enable
 */

#define PCM_NON    0
#define PCM_DAC    1
#define PCM_ADC    2

static unsigned long pcm_speed = 0;    /* sampling rate */
static unsigned char pcm_channels = 1;    /* channels (1 or 2) */
static unsigned char pcm_bits = 8;    /* bits/sample (8 or 16) */
static unsigned char pcm_filter = 0;    /* filter FLAG */
static unsigned char pcm_mode = PCM_NON;
static unsigned long pcm_count = 0;
static unsigned short pcm_bitsok = 8;    /* mask of OK bits */
static int      pcm_busy = 0;
int             pas_audiodev = -1;
static int      open_mode = 0;

static int pcm_set_speed(int arg)
{
    int foo, tmp;
    unsigned long flags;

    if (arg == 0)
        return pcm_speed;

    if (arg > 44100)
        arg = 44100;
    if (arg < 5000)
        arg = 5000;

    if (pcm_channels & 2)
    {
        foo = (596590 + (arg / 2)) / arg;
        arg = (596590 + (foo / 2)) / foo;
    }
    else
    {
        foo = (1193180 + (arg / 2)) / arg;
        arg = (1193180 + (foo / 2)) / foo;
    }

    pcm_speed = arg;

    tmp = pas_read(0x0B8A);

    /*
     * Set anti-aliasing filters according to sample rate. You really *NEED*
     * to enable this feature for all normal recording unless you want to
     * experiment with aliasing effects.
     * These filters apply to the selected "recording" source.
     * I (pfw) don't know the encoding of these 5 bits. The values shown
     * come from the SDK found on ftp.uwp.edu:/pub/msdos/proaudio/.
     *
     * I cleared bit 5 of these values, since that bit controls the master
     * mute flag. (Olav Wölfelschneider)
     *
     */
#if !defined NO_AUTO_FILTER_SET
    tmp &= 0xe0;
    if (pcm_speed >= 2 * 17897)
        tmp |= 0x01;
    else if (pcm_speed >= 2 * 15909)
        tmp |= 0x02;
    else if (pcm_speed >= 2 * 11931)
        tmp |= 0x09;
    else if (pcm_speed >= 2 * 8948)
        tmp |= 0x11;
    else if (pcm_speed >= 2 * 5965)
        tmp |= 0x19;
    else if (pcm_speed >= 2 * 2982)
        tmp |= 0x04;
    pcm_filter = tmp;
#endif

    save_flags(flags);
    cli();

    pas_write(tmp & ~(0x40 | 0x80), 0x0B8A);
    pas_write(0x00 | 0x30 | 0x04, 0x138B);
    pas_write(foo & 0xff, 0x1388);
    pas_write((foo >> 8) & 0xff, 0x1388);
    pas_write(tmp, 0x0B8A);

    restore_flags(flags);

    return pcm_speed;
}

static int pcm_set_channels(int arg)
{

    if ((arg != 1) && (arg != 2))
        return pcm_channels;

    if (arg != pcm_channels)
    {
        pas_write(pas_read(0xF8A) ^ 0x20, 0xF8A);

        pcm_channels = arg;
        pcm_set_speed(pcm_speed);    /* The speed must be reinitialized */
    }
    return pcm_channels;
}

static int pcm_set_bits(int arg)
{
    if (arg == 0)
        return pcm_bits;

    if ((arg & pcm_bitsok) != arg)
        return pcm_bits;

    if (arg != pcm_bits)
    {
        pas_write(pas_read(0x8389) ^ 0x04, 0x8389);

        pcm_bits = arg;
    }
    return pcm_bits;
}

static int pas_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
    int val, ret;

    DEB(printk("pas2_pcm.c: static int pas_audio_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));

    switch (cmd) 
    {
    case SOUND_PCM_WRITE_RATE:
        if (get_user(val, (int *)arg)) 
            return -EFAULT;
        ret = pcm_set_speed(val);
        break;

    case SOUND_PCM_READ_RATE:
        ret = pcm_speed;
        break;
        
    case SNDCTL_DSP_STEREO:
        if (get_user(val, (int *)arg)) 
            return -EFAULT;
        ret = pcm_set_channels(val + 1) - 1;
        break;

    case SOUND_PCM_WRITE_CHANNELS:
        if (get_user(val, (int *)arg)) 
            return -EFAULT;
        ret = pcm_set_channels(val);
        break;

    case SOUND_PCM_READ_CHANNELS:
        ret = pcm_channels;
        break;

    case SNDCTL_DSP_SETFMT:
        if (get_user(val, (int *)arg))
            return -EFAULT;
        ret = pcm_set_bits(val);
        break;
        
    case SOUND_PCM_READ_BITS:
        ret = pcm_bits;
        break;
  
    default:
        return -EINVAL;
    }
    return put_user(ret, (int *)arg);
}

static void pas_audio_reset(int dev)
{
    DEB(printk("pas2_pcm.c: static void pas_audio_reset(void)\n"));

    pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);    /* Disable PCM */
}

static int pas_audio_open(int dev, int mode)
{
    int             err;
    unsigned long   flags;

    DEB(printk("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode));

    save_flags(flags);
    cli();
    if (pcm_busy)
    {
        restore_flags(flags);
        return -EBUSY;
    }
    pcm_busy = 1;
    restore_flags(flags);

    if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0)
        return err;


    pcm_count = 0;
    open_mode = mode;

    return 0;
}

static void pas_audio_close(int dev)
{
    unsigned long   flags;

    DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n"));

    save_flags(flags);
    cli();

    pas_audio_reset(dev);
    pas_remove_intr(PAS_PCM_INTRBITS);
    pcm_mode = PCM_NON;

    pcm_busy = 0;
    restore_flags(flags);
}

static void pas_audio_output_block(int dev, unsigned long buf, int count,
               int intrflag)
{
    unsigned long   flags, cnt;

    DEB(printk("pas2_pcm.c: static void pas_audio_output_block(char *buf = %P, int count = %X)\n", buf, count));

    cnt = count;
    if (audio_devs[dev]->dmap_out->dma > 3)
        cnt >>= 1;

    if (audio_devs[dev]->flags & DMA_AUTOMODE &&
        intrflag &&
        cnt == pcm_count)
        return;

    save_flags(flags);
    cli();

    pas_write(pas_read(0xF8A) & ~0x40,
          0xF8A);

    /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */

    if (audio_devs[dev]->dmap_out->dma > 3)
        count >>= 1;

    if (count != pcm_count)
    {
        pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
        pas_write(0x40 | 0x30 | 0x04, 0x138B);
        pas_write(count & 0xff, 0x1389);
        pas_write((count >> 8) & 0xff, 0x1389);
        pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);

        pcm_count = count;
    }
    pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
#ifdef NO_TRIGGER
    pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
#endif

    pcm_mode = PCM_DAC;

    restore_flags(flags);
}

static void pas_audio_start_input(int dev, unsigned long buf, int count,
              int intrflag)
{
    unsigned long   flags;
    int             cnt;

    DEB(printk("pas2_pcm.c: static void pas_audio_start_input(char *buf = %P, int count = %X)\n", buf, count));

    cnt = count;
    if (audio_devs[dev]->dmap_out->dma > 3)
        cnt >>= 1;

    if (audio_devs[pas_audiodev]->flags & DMA_AUTOMODE &&
        intrflag &&
        cnt == pcm_count)
        return;

    save_flags(flags);
    cli();

    /* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */

    if (audio_devs[dev]->dmap_out->dma > 3)
        count >>= 1;

    if (count != pcm_count)
    {
        pas_write(pas_read(0x0B8A) & ~0x80, 0x0B8A);
        pas_write(0x40 | 0x30 | 0x04, 0x138B);
        pas_write(count & 0xff, 0x1389);
        pas_write((count >> 8) & 0xff, 0x1389);
        pas_write(pas_read(0x0B8A) | 0x80, 0x0B8A);

        pcm_count = count;
    }
    pas_write(pas_read(0x0B8A) | 0x80 | 0x40, 0x0B8A);
#ifdef NO_TRIGGER
    pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
#endif

    pcm_mode = PCM_ADC;

    restore_flags(flags);
}

#ifndef NO_TRIGGER
static void pas_audio_trigger(int dev, int state)
{
    unsigned long   flags;

    save_flags(flags);
    cli();
    state &= open_mode;

    if (state & PCM_ENABLE_OUTPUT)
        pas_write(pas_read(0xF8A) | 0x40 | 0x10, 0xF8A);
    else if (state & PCM_ENABLE_INPUT)
        pas_write((pas_read(0xF8A) | 0x40) & ~0x10, 0xF8A);
    else
        pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);

    restore_flags(flags);
}
#endif

static int pas_audio_prepare_for_input(int dev, int bsize, int bcount)
{
    pas_audio_reset(dev);
    return 0;
}

static int pas_audio_prepare_for_output(int dev, int bsize, int bcount)
{
    pas_audio_reset(dev);
    return 0;
}

static struct audio_driver pas_audio_driver =
{
    owner:        THIS_MODULE,
    open:        pas_audio_open,
    close:        pas_audio_close,
    output_block:    pas_audio_output_block,
    start_input:    pas_audio_start_input,
    ioctl:        pas_audio_ioctl,
    prepare_for_input:    pas_audio_prepare_for_input,
    prepare_for_output:    pas_audio_prepare_for_output,
    halt_io:        pas_audio_reset,
    trigger:    pas_audio_trigger
};

void __init pas_pcm_init(struct address_info *hw_config)
{
    DEB(printk("pas2_pcm.c: long pas_pcm_init()\n"));

    pcm_bitsok = 8;
    if (pas_read(0xEF8B) & 0x08)
        pcm_bitsok |= 16;

    pcm_set_speed(DSP_DEFAULT_SPEED);

    if ((pas_audiodev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
                    "Pro Audio Spectrum",
                    &pas_audio_driver,
                    sizeof(struct audio_driver),
                    DMA_AUTOMODE,
                    AFMT_U8 | AFMT_S16_LE,
                    NULL,
                    hw_config->dma,
                    hw_config->dma)) < 0)
        printk(KERN_WARNING "PAS16: Too many PCM devices available\n");
}

void pas_pcm_interrupt(unsigned char status, int cause)
{
    if (cause == 1)
    {
        /*
         * Halt the PCM first. Otherwise we don't have time to start a new
         * block before the PCM chip proceeds to the next sample
         */

        if (!(audio_devs[pas_audiodev]->flags & DMA_AUTOMODE))
            pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);

        switch (pcm_mode)
        {
            case PCM_DAC:
                DMAbuf_outputintr(pas_audiodev, 1);
                break;

            case PCM_ADC:
                DMAbuf_inputintr(pas_audiodev);
                break;

            default:
                printk(KERN_WARNING "PAS: Unexpected PCM interrupt\n");
        }
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0164 ]--