!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:     qpmouse.c (8.42 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * linux/drivers/char/qpmouse.c
 *
 * Driver for a 82C710 C&T mouse interface chip.
 *
 * Based on the PS/2 driver by Johan Myreen.
 *
 * Corrections in device setup for some laptop mice & trackballs.
 * 02Feb93  (troyer@saifr00.cfsat.Honeywell.COM,mch@wimsey.bc.ca)
 *
 * Modified by Johan Myreen (jem@iki.fi) 04Aug93
 *   to include support for QuickPort mouse.
 *
 * Changed references to "QuickPort" with "82C710" since "QuickPort"
 * is not what this driver is all about -- QuickPort is just a
 * connector type, and this driver is for the mouse port on the Chips
 * & Technologies 82C710 interface chip. 15Nov93 jem@iki.fi
 *
 * Added support for SIGIO. 28Jul95 jem@iki.fi
 *
 * Rearranged SIGIO support to use code from tty_io.  9Sept95 ctm@ardi.com
 *
 * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/smp_lock.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/semaphore.h>

#include <linux/pc_keyb.h>        /* mouse enable command.. */


/*
 * We use the same minor number as the PS/2 mouse for (bad) historical
 * reasons..
 */
#define PSMOUSE_MINOR      1                   /* Minor device # for this mouse */
#define QP_BUF_SIZE    2048

struct qp_queue {
    unsigned long head;
    unsigned long tail;
    wait_queue_head_t proc_list;
    struct fasync_struct *fasync;
    unsigned char buf[QP_BUF_SIZE];
};

static struct qp_queue *queue;

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

    save_flags(flags);
    cli();
    result = queue->buf[queue->tail];
    queue->tail = (queue->tail + 1) & (QP_BUF_SIZE-1);
    restore_flags(flags);
    return result;
}


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

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

    retval = fasync_helper(fd, filp, on, &queue->fasync);
    if (retval < 0)
        return retval;
    return 0;
}

/*
 *    82C710 Interface
 */

#define QP_DATA         0x310        /* Data Port I/O Address */
#define QP_STATUS       0x311        /* Status Port I/O Address */

#define QP_DEV_IDLE     0x01        /* Device Idle */
#define QP_RX_FULL      0x02        /* Device Char received */
#define QP_TX_IDLE      0x04        /* Device XMIT Idle */
#define QP_RESET        0x08        /* Device Reset */
#define QP_INTS_ON      0x10        /* Device Interrupt On */
#define QP_ERROR_FLAG   0x20        /* Device Error */
#define QP_CLEAR        0x40        /* Device Clear */
#define QP_ENABLE       0x80        /* Device Enable */

#define QP_IRQ          12

static int qp_present;
static int qp_count;
static int qp_data = QP_DATA;
static int qp_status = QP_STATUS;

static int poll_qp_status(void);
static int probe_qp(void);

/*
 * Interrupt handler for the 82C710 mouse port. A character
 * is waiting in the 82C710.
 */

static void qp_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
{
    int head = queue->head;
    int maxhead = (queue->tail-1) & (QP_BUF_SIZE-1);

    add_mouse_randomness(queue->buf[head] = inb(qp_data));
    if (head != maxhead) {
        head++;
        head &= QP_BUF_SIZE-1;
    }
    queue->head = head;
    kill_fasync(&queue->fasync, SIGIO, POLL_IN);
    wake_up_interruptible(&queue->proc_list);
}

static int release_qp(struct inode * inode, struct file * file)
{
    unsigned char status;

    lock_kernel();
    fasync_qp(-1, file, 0);
    if (!--qp_count) {
        if (!poll_qp_status())
            printk(KERN_WARNING "Warning: Mouse device busy in release_qp()\n");
        status = inb_p(qp_status);
        outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
        if (!poll_qp_status())
            printk(KERN_WARNING "Warning: Mouse device busy in release_qp()\n");
        free_irq(QP_IRQ, NULL);
    }
    unlock_kernel();
    return 0;
}

/*
 * Install interrupt handler.
 * Enable the device, enable interrupts. 
 */

static int open_qp(struct inode * inode, struct file * file)
{
    unsigned char status;

    if (!qp_present)
        return -EINVAL;

    if (qp_count++)
        return 0;

    if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse", NULL)) {
        qp_count--;
        return -EBUSY;
    }

    status = inb_p(qp_status);
    status |= (QP_ENABLE|QP_RESET);
    outb_p(status, qp_status);
    status &= ~(QP_RESET);
    outb_p(status, qp_status);

    queue->head = queue->tail = 0;          /* Flush input queue */
    status |= QP_INTS_ON;
    outb_p(status, qp_status);              /* Enable interrupts */

    while (!poll_qp_status()) {
        printk(KERN_ERR "Error: Mouse device busy in open_qp()\n");
        qp_count--;
        status &= ~(QP_ENABLE|QP_INTS_ON);
        outb_p(status, qp_status);
        free_irq(QP_IRQ, NULL);
        return -EBUSY;
    }

    outb_p(AUX_ENABLE_DEV, qp_data);    /* Wake up mouse */
    return 0;
}

/*
 * Write to the 82C710 mouse device.
 */

static ssize_t write_qp(struct file * file, const char * buffer,
            size_t count, loff_t *ppos)
{
    ssize_t i = count;

    while (i--) {
        char c;
        if (!poll_qp_status())
            return -EIO;
        get_user(c, buffer++);
        outb_p(c, qp_data);
    }
    file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
    return count;
}

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

/*
 * Wait for device to send output char and flush any input char.
 */

#define MAX_RETRIES (60)

static int poll_qp_status(void)
{
    int retries=0;

    while ((inb(qp_status)&(QP_RX_FULL|QP_TX_IDLE|QP_DEV_IDLE))
               != (QP_DEV_IDLE|QP_TX_IDLE)
               && retries < MAX_RETRIES) {

        if (inb_p(qp_status)&(QP_RX_FULL))
            inb_p(qp_data);
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout((5*HZ + 99) / 100);
        retries++;
    }
    return !(retries==MAX_RETRIES);
}

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

static ssize_t read_qp(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;
}

struct file_operations qp_fops = {
    owner:        THIS_MODULE,
    read:        read_qp,
    write:        write_qp,
    poll:        poll_qp,
    open:        open_qp,
    release:    release_qp,
    fasync:        fasync_qp,
};

/*
 * Initialize driver.
 */
static struct miscdevice qp_mouse = {
    minor:        PSMOUSE_MINOR,
    name:        "QPmouse",
    fops:        &qp_fops,
};

/*
 * Function to read register in 82C710.
 */

static inline unsigned char read_710(unsigned char index)
{
    outb_p(index, 0x390);            /* Write index */
    return inb_p(0x391);            /* Read the data */
}


/*
 * See if we can find a 82C710 device. Read mouse address.
 */

static int __init probe_qp(void)
{
    outb_p(0x55, 0x2fa);            /* Any value except 9, ff or 36 */
    outb_p(0xaa, 0x3fa);            /* Inverse of 55 */
    outb_p(0x36, 0x3fa);            /* Address the chip */
    outb_p(0xe4, 0x3fa);            /* 390/4; 390 = config address */
    outb_p(0x1b, 0x2fa);            /* Inverse of e4 */
    if (read_710(0x0f) != 0xe4)        /* Config address found? */
      return 0;                /* No: no 82C710 here */
    qp_data = read_710(0x0d)*4;        /* Get mouse I/O address */
    qp_status = qp_data+1;
    outb_p(0x0f, 0x390);
    outb_p(0x0f, 0x391);            /* Close config mode */
    return 1;
}

static char msg_banner[] __initdata = KERN_INFO "82C710 type pointing device detected -- driver installed.\n";
static char msg_nomem[]  __initdata = KERN_ERR "qpmouse: no queue memory.\n";

static int __init qpmouse_init_driver(void)
{
    if (!probe_qp())
        return -EIO;

    printk(msg_banner);

/*    printk("82C710 address = %x (should be 0x310)\n", qp_data); */
    queue = (struct qp_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
    if (queue == NULL) {
        printk(msg_nomem);
        return -ENOMEM;
    }
    qp_present = 1;
    misc_register(&qp_mouse);
    memset(queue, 0, sizeof(*queue));
    queue->head = queue->tail = 0;
    init_waitqueue_head(&queue->proc_list);
    return 0;
}

static void __exit qpmouse_exit_driver(void)
{
    misc_deregister(&qp_mouse);
    kfree(queue);
}

module_init(qpmouse_init_driver);
module_exit(qpmouse_exit_driver);


MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;

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