!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/char/   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:     qtronix.c (13.12 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *
 * BRIEF MODULE DESCRIPTION
 *    Qtronix 990P infrared keyboard driver.
 *
 *
 * Copyright 2001 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *             ppopov@mvista.com or source@mvista.com
 *
 *
 *  The bottom portion of this driver was take from 
 *  pc_keyb.c  Please see that file for copyrights.
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/config.h>

/* 
 * NOTE:  
 *
 *    This driver has only been tested with the Consumer IR
 *    port of the ITE 8172 system controller.
 *
 *    You do not need this driver if you are using the ps/2 or
 *    USB adapter that the keyboard ships with.  You only need 
 *    this driver if your board has a IR port and the keyboard
 *    data is being sent directly to the IR.  In that case,
 *    you also need some low-level IR support. See it8172_cir.c.
 *    
 */

#ifdef CONFIG_QTRONIX_KEYBOARD

#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>

#include <asm/it8172/it8172.h>
#include <asm/it8172/it8172_int.h>
#include <asm/it8172/it8172_cir.h>

#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/signal.h>
#include <linux/init.h>
#include <linux/kbd_ll.h>
#include <linux/delay.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kbd_kern.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
#include <linux/pc_keyb.h>

#include <asm/keyboard.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/system.h>

#define leading1 0
#define leading2 0xF

#define KBD_CIR_PORT 0
#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */

static int data_index;
struct cir_port *cir;
static unsigned char kbdbytes[5];
static unsigned char cir_data[32]; /* we only need 16 chars */

static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs);
static int handle_data(unsigned char *p_data);
static inline void handle_mouse_event(unsigned char scancode);
static inline void handle_keyboard_event(unsigned char scancode, int down);
static int __init psaux_init(void);

static struct aux_queue *queue;    /* Mouse data buffer. */
static int aux_count = 0;

/*
 * Keys accessed through the 'Fn' key
 * The Fn key does not produce a key-up sequence. So, the first
 * time the user presses it, it will be key-down event. The key
 * stays down until the user presses it again.
 */
#define NUM_FN_KEYS 56
static unsigned char fn_keys[NUM_FN_KEYS] = {
    0,0,0,0,0,0,0,0,        /* 0 7   */
    8,9,10,93,0,0,0,0,      /* 8 15  */
    0,0,0,0,0,0,0,5,        /* 16 23 */
    6,7,91,0,0,0,0,0,       /* 24 31 */
    0,0,0,0,0,2,3,4,        /* 32 39 */
    92,0,0,0,0,0,0,0,       /* 40 47 */
    0,0,0,0,11,0,94,95        /* 48 55 */

};

void init_qtronix_990P_kbd(void)
{
    int retval;

    cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL);
    if (!cir) {
        printk("Unable to initialize Qtronix keyboard\n");
        return;
    }

    /* 
     * revisit
     * this should be programmable, somehow by the, by the user.
     */
    cir->port = KBD_CIR_PORT;
    cir->baud_rate = 0x1d;
    cir->rdwos = 0;
    cir->rxdcr = 0x3;
    cir->hcfs = 0;
    cir->fifo_tl = 0;
    cir->cfq = 0x1d;
    cir_port_init(cir);

    retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler, 
            (unsigned long )(SA_INTERRUPT|SA_SHIRQ), 
            (const char *)"Qtronix IR Keyboard", (void *)cir);

    if (retval) {
        printk("unable to allocate cir %d irq %d\n", 
                cir->port, IT8172_CIR0_IRQ);
    }
#ifdef CONFIG_PSMOUSE
    psaux_init();
#endif
}

static inline unsigned char BitReverse(unsigned short key)
{
    unsigned char rkey = 0;
    rkey |= (key & 0x1) << 7;
    rkey |= (key & 0x2) << 5;
    rkey |= (key & 0x4) << 3;
    rkey |= (key & 0x8) << 1;
    rkey |= (key & 0x10) >> 1;
    rkey |= (key & 0x20) >> 3;
    rkey |= (key & 0x40) >> 5;
    rkey |= (key & 0x80) >> 7;
    return rkey;

}


static inline u_int8_t UpperByte(u_int8_t data)
{
    return (data >> 4);
}


static inline u_int8_t LowerByte(u_int8_t data)
{
    return (data & 0xF);
}


int CheckSumOk(u_int8_t byte1, u_int8_t byte2, 
        u_int8_t byte3, u_int8_t byte4, u_int8_t byte5)
{
    u_int8_t CheckSum;

    CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5;
    if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) )
        return 0;
    else
        return 1;
}


static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
    struct cir_port *cir;
    int j;
    unsigned char int_status;

    cir = (struct cir_port *)dev_id;
    int_status = get_int_status(cir);;
    if (int_status & 0x4) {
        clear_fifo(cir);
        return;
    }

    while (cir_get_rx_count(cir)) {

        cir_data[data_index] = cir_read_data(cir);

        if (data_index == 0) {/* expecting first byte */
            if (cir_data[data_index] != leading1) {
                //printk("!leading byte %x\n", cir_data[data_index]);
                set_rx_active(cir);
                clear_fifo(cir);
                continue;
            }
        }
        if (data_index == 1) {
            if ((cir_data[data_index] & 0xf) != leading2) {
                set_rx_active(cir);
                data_index = 0; /* start over */
                clear_fifo(cir);
                continue;
            }
        }

        if ( (cir_data[data_index] == 0xff)) { /* last byte */
            //printk("data_index %d\n", data_index);
            set_rx_active(cir);
#if 0
            for (j=0; j<=data_index; j++) {
                printk("rx_data %d:  %x\n", j, cir_data[j]);
            }
#endif
            data_index = 0;
            handle_data(cir_data);
            return;
        }
        else if (data_index>16) {
            set_rx_active(cir);
#if 0
            printk("warning: data_index %d\n", data_index);
            for (j=0; j<=data_index; j++) {
                printk("rx_data %d:  %x\n", j, cir_data[j]);
            }
#endif
            data_index = 0;
            clear_fifo(cir);
            return;
        }
        data_index++;
    }
}


#define NUM_KBD_BYTES 5
static int handle_data(unsigned char *p_data)
{
    u_int32_t bit_bucket;
    u_int32_t i, j;
    u_int32_t got_bits, next_byte;
    int down = 0;

    /* Reorganize the bit stream */
    for (i=0; i<16; i++)
        p_data[i] = BitReverse(~p_data[i]);

    /* 
     * We've already previously checked that p_data[0]
     * is equal to leading1 and that (p_data[1] & 0xf)
     * is equal to leading2. These twelve bits are the
     * leader code.  We can now throw them away (the 12
     * bits) and continue parsing the stream.
     */
    bit_bucket = p_data[1] << 12;
    got_bits = 4;
    next_byte = 2;

    /* 
     * Process four bits at a time
     */
    for (i=0; i<NUM_KBD_BYTES; i++) {

        kbdbytes[i]=0;

        for (j=0; j<8; j++) /* 8 bits per byte */
        {
            if (got_bits < 4) {
                bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
                got_bits += 8;
            }

            if ((bit_bucket & 0xF000) == 0x8000) { 
                /* Convert 1000b to 1 */
                kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1);
                got_bits -= 4;
                bit_bucket = bit_bucket << 4;
            }
            else if ((bit_bucket & 0xC000) == 0x8000) {
                /* Convert 10b to 0 */
                kbdbytes[i] =  kbdbytes[i] >> 1;
                got_bits -= 2;
                bit_bucket = bit_bucket << 2;
            }
            else {
                /* bad serial stream */
                return 1;
            }

            if (next_byte > 16) {
                //printk("error: too many bytes\n");
                return 1;
            }
        }
    }


    if (!CheckSumOk(kbdbytes[0], kbdbytes[1], 
                kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
        //printk("checksum failed\n");
        return 1;
    }

    if (kbdbytes[1] & 0x08) {
        //printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]);
        handle_mouse_event(kbdbytes[1]);
        handle_mouse_event(kbdbytes[2]);
        handle_mouse_event(kbdbytes[3]);
    }
    else {
        if (kbdbytes[2] == 0) down = 1;
#if 0
        if (down)
            printk("down %d\n", kbdbytes[3]);
        else
            printk("up %d\n", kbdbytes[3]);
#endif
        handle_keyboard_event(kbdbytes[3], down);
    }
    return 0;
}


spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
static unsigned char handle_kbd_event(void);


int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
{
    printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
    return 0;
}

int kbd_getkeycode(unsigned int scancode)
{
    return scancode;
}


int kbd_translate(unsigned char scancode, unsigned char *keycode,
            char raw_mode)
{
    static int prev_scancode = 0;

    if (scancode == 0x00 || scancode == 0xff) {
        prev_scancode = 0;
        return 0;
    }

    /* todo */
    if (!prev_scancode && scancode == 160) { /* Fn key down */
        //printk("Fn key down\n");
        prev_scancode = 160;
        return 0;
    }
    else if (prev_scancode && scancode == 160) { /* Fn key up */
        //printk("Fn key up\n");
        prev_scancode = 0;
        return 0;
    }

    /* todo */
    if (prev_scancode == 160) {
        if (scancode <= NUM_FN_KEYS) {
            *keycode = fn_keys[scancode];
            //printk("fn keycode %d\n", *keycode);
        }
        else
            return 0;
    } 
    else if (scancode <= 127) {
        *keycode = scancode;
    }
    else
        return 0;


     return 1;
}

char kbd_unexpected_up(unsigned char keycode)
{
    //printk("kbd_unexpected_up\n");
    return 0;
}

static unsigned char kbd_exists = 1;

static inline void handle_keyboard_event(unsigned char scancode, int down)
{
    kbd_exists = 1;
    handle_scancode(scancode, down);
    tasklet_schedule(&keyboard_tasklet);
}    


void kbd_leds(unsigned char leds)
{
}

/* dummy */
void kbd_init_hw(void)
{
}



static inline void handle_mouse_event(unsigned char scancode)
{
    if(scancode == AUX_RECONNECT){
        queue->head = queue->tail = 0;  /* Flush input queue */
    //    __aux_write_ack(AUX_ENABLE_DEV);  /* ping the mouse :) */
        return;
    }

    add_mouse_randomness(scancode);
    if (aux_count) {
        int head = queue->head;

        queue->buf[head] = scancode;
        head = (head + 1) & (AUX_BUF_SIZE-1);
        if (head != queue->tail) {
            queue->head = head;
            kill_fasync(&queue->fasync, SIGIO, POLL_IN);
            wake_up_interruptible(&queue->proc_list);
        }
    }
}

static unsigned char get_from_queue(void)
{
    unsigned char result;
    unsigned long flags;

    spin_lock_irqsave(&kbd_controller_lock, flags);
    result = queue->buf[queue->tail];
    queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
    spin_unlock_irqrestore(&kbd_controller_lock, flags);
    return result;
}


static inline int queue_empty(void)
{
    return queue->head == queue->tail;
}

static int fasync_aux(int fd, struct file *filp, int on)
{
    int retval;

    //printk("fasync_aux\n");
    retval = fasync_helper(fd, filp, on, &queue->fasync);
    if (retval < 0)
        return retval;
    return 0;
}


/*
 * Random magic cookie for the aux device
 */
#define AUX_DEV ((void *)queue)

static int release_aux(struct inode * inode, struct file * file)
{
    lock_kernel();
    fasync_aux(-1, file, 0);
    aux_count--;
    unlock_kernel();
    return 0;
}

static int open_aux(struct inode * inode, struct file * file)
{
    if (aux_count++) {
        return 0;
    }
    queue->head = queue->tail = 0;        /* Flush input queue */
    return 0;
}

/*
 * Put bytes from input queue to buffer.
 */

static ssize_t read_aux(struct file * file, char * buffer,
            size_t count, loff_t *ppos)
{
    DECLARE_WAITQUEUE(wait, current);
    ssize_t i = count;
    unsigned char c;

    if (queue_empty()) {
        if (file->f_flags & O_NONBLOCK)
            return -EAGAIN;
        add_wait_queue(&queue->proc_list, &wait);
repeat:
        set_current_state(TASK_INTERRUPTIBLE);
        if (queue_empty() && !signal_pending(current)) {
            schedule();
            goto repeat;
        }
        current->state = TASK_RUNNING;
        remove_wait_queue(&queue->proc_list, &wait);
    }
    while (i > 0 && !queue_empty()) {
        c = get_from_queue();
        put_user(c, buffer++);
        i--;
    }
    if (count-i) {
        file->f_dentry->d_inode->i_atime = CURRENT_TIME;
        return count-i;
    }
    if (signal_pending(current))
        return -ERESTARTSYS;
    return 0;
}

/*
 * Write to the aux device.
 */

static ssize_t write_aux(struct file * file, const char * buffer,
             size_t count, loff_t *ppos)
{
    /*
     * The ITE boards this was tested on did not have the
     * transmit wires connected.
     */
    return count;
}

static unsigned int aux_poll(struct file *file, poll_table * wait)
{
    poll_wait(file, &queue->proc_list, wait);
    if (!queue_empty())
        return POLLIN | POLLRDNORM;
    return 0;
}

struct file_operations psaux_fops = {
    read:        read_aux,
    write:        write_aux,
    poll:        aux_poll,
    open:        open_aux,
    release:    release_aux,
    fasync:        fasync_aux,
};

/*
 * Initialize driver.
 */
static struct miscdevice psaux_mouse = {
    PSMOUSE_MINOR, "psaux", &psaux_fops
};

static int __init psaux_init(void)
{
    misc_register(&psaux_mouse);
    queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
    memset(queue, 0, sizeof(*queue));
    queue->head = queue->tail = 0;
    init_waitqueue_head(&queue->proc_list);

    return 0;
}
#endif

:: 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.0545 ]--