problem get in work ps2 mouse driver in linux2.4.7

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi, i am nikhil
 i am doing the mouse driver in linux2.4.i have ps2 mouse. i have the code for mouse
driver. i have successfuly compiled it and for testing whther it working or not i did
followwing
1) i remove the configuration of ps2 mouse by removing the mouse while booting    
linux. as i  removed mouse configuration  is not enter in the GUI. ie /dev/mouse    
device not in work
2) then i tried  mknod command: mknod /dev/mymouse c 10 0 as i am using the o as 
    minor number.
3) then i loaded the my module in kernel using insmod command
    i have accessed the mouse irq(12) in SA_INTERRUPT mode.  now i did some     
   changes in /etc/X11/XF86Config-4 file. i have changes input section of mouse        
   option device as /dev/mymouse instead of /dev/mouse
4) after that i do cat /dev/mymouse as it call open method after that read method
    it gives me segmentation fall error
    but when i run startx command the GUI get started. but mouse does no work.
    i not able to indentify the error.
 i also tried using different minor but same is results.
another problem is that when i tried to insert the module while mouse is working:
 it has irq 12, i have to share it with SA_SHIRQ mode. it get share but when i do
anything with mouse(moving or clicking), system get hang. the main problem is the
mouse IRQ does not get free with free_irq function. it just shows the message :
trying to free the irq 12.
same is happened with serial mouse
how should i register the irq with my mouse
please help me if any suggetion feel free to email me on kam_nil@xxxxxxxxx
i have attached the mouse source code got from linux-mag.
/*source code*/

#define MODULE
 #define __KERNEL__
#include<linux/ioport.h>
#include <linux/config.h>
#include <linux/module.h>
#include<linux/sched.h>
#include<linux/poll.h>
#include<linux/interrupt.h>
#include<linux/miscdevice.h>
#include<linux/init.h>
#include<linux/wait.h>
 #include <linux/kernel.h> /* printk() */
#include <linux/malloc.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/ioport.h>
#include <asm/system.h>
#include<asm/segment.h>
#include<asm/io.h>
 
/*Listing 2: Initializing Functions*/
#define OURMOUSE_BASE 0x300
//#define OURMOUSE_BASE 0x23c
//#define OURMOUSE_BASE 0x064

#define OURMOUSE_MINOR 0
#define OURMOUSE_MINOR 246
//#define MOUSE_IRQ 4
//#define MOUSE_IRQ 5
#define MOUSE_IRQ 12
 
 
static int mouse_users = 0; /* User count */
static int mouse_dx = 0; /* Position changes */
static int mouse_dy = 0;
static int mouse_event = 0; /* Mouse has moved */
static int mouse_buttons = 0;
static int major;
static int mouse_intr = MOUSE_IRQ;
static  wait_queue_head_t mouse_wait;
static spinlock_t mouse_lock = SPIN_LOCK_UNLOCKED;
 
static ssize_t mouse_read(struct file *f, char *buffer,size_t count, loff_t
*pos);
static ssize_t write_mouse(struct file *file, const char *buffer, size_t
count, loff_t *ppos);
static unsigned int mouse_poll(struct file *file, poll_table *wait);
static int open_mouse(struct inode *inode, struct file *file);
static int close_mouse(struct inode *inode,struct file *file);

struct file_operations our_mouse_fops = {
    read:mouse_read, /* You can read a mouse */
    write:write_mouse, /* This won't do a lot */
    poll:mouse_poll, /* Poll */
    open:open_mouse, /* Called on open */
    release:close_mouse, /* Called on close */
};
 
 

static struct miscdevice our_mouse = {
 OURMOUSE_MINOR, "ourmouse",&our_mouse_fops
 };

/*__init ourmouse_init(void)*/
static int ourmouse_init(void)
{

    if(check_region(OURMOUSE_BASE, 3))
    {
  return -ENODEV;
  }
    request_region(OURMOUSE_BASE, 3,"ourmouse");
    misc_register(&our_mouse);

    return 0;
}

//Module Wrapper Code
#ifdef MODULE

int init_module(void)
{
    if(ourmouse_init()<0)
    {
          return -ENODEV;
   }
    return 0;
}

void cleanup_module(void)
{

    misc_deregister(&our_mouse);
    release_region(OURMOUSE_BASE, 3);
release_irq(mouse_intr,(void*)&our_mouse);
}

#endif
 
 
static void ourmouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    char delta_x;
    char delta_y;
    unsigned char new_buttons;

    delta_x = inb(OURMOUSE_BASE);
    delta_y = inb(OURMOUSE_BASE+1);
    new_buttons = inb(OURMOUSE_BASE+2);

    if(delta_x || delta_y || new_buttons != mouse_buttons)
    {
            spin_lock(&mouse_lock);
            mouse_event = 1;
            mouse_dx += delta_x;
            mouse_dy += delta_y;
     if(mouse_dx < -4096)
     mouse_dx=-4049;
     if(mouse_dx > 4096)
     mouse_dx=4046;
     if(mouse_dx > 4096)
     mouse_dy=4046;
            if(mouse_dy < -4096)
     mouse_dx=-4046;
            mouse_buttons = new_buttons;
            spin_unlock(&mouse_lock);

            wake_up_interruptible(&mouse_wait);
    }
 }
 
 
//Managing Interrupts

static int open_mouse(struct inode *inode, struct file *file)
{
    /*if(mouse_users++)
        return 0;*/
// free_irq(12,NULL);
    if(request_irq(mouse_intr, ourmouse_interrupt,SA_SHIRQ,"ourmouse",
(void*)&our_mouse))
    {
        mouse_users--;
        return -EBUSY;
    }
    mouse_dx = 0;
    mouse_dy = 0;
    mouse_buttons = 0;
    mouse_event = 0;
    MOD_INC_USE_COUNT;
    return 0;
}
 
 
 
//The close_mouse Function
static int close_mouse(struct inode *inode,struct file *file)
{
    if(--mouse_users)
            return 0;
    free_irq(mouse_intr, NULL);
    MOD_DEC_USE_COUNT;
    return 0;
}
 
 
//Filling in the Write Handler
static ssize_t write_mouse(struct file *file, const char *buffer, size_t
count, loff_t *ppos)
{
    return -EINVAL;
}
 

//The poll function
static unsigned int mouse_poll(struct file *file, poll_table *wait)
{

    poll_wait(file,&mouse_wait, wait);
    if(mouse_event)
            return POLLIN | POLLRDNORM;
    return 0;
}
 

//Waiting for an Event
static ssize_t mouse_read(struct file *f, char *buffer,size_t count, loff_t
*pos)
{
    int dx, dy;
    unsigned char button;
    unsigned long flags;
    int n;

    if(count < 3)
        return -EINVAL;
 
 
 
/*Wait for an event */
/*struct task_struct *current;*/
while(!mouse_event)
{
    if(f->f_flags&O_NDELAY)
    {
 return -EWOULDBLOCK;
    }
    interruptible_sleep_on(&mouse_wait);
    if(signal_pending(current))
    {
 return -ERESTARTSYS;
    }
}

/*Reading the Event*/
/* mouse_read continued */

/* Grab the event */

spin_lock_irqsave(&mouse_lock, flags);

dx = mouse_dx;
dy = mouse_dy;
button = mouse_buttons;
printk("dx=%d & dy=%d",dx,dy);
if(dx<=-127)
        dx=-127;
if(dx>=127)
        dx=127;
if(dy<=-127)
        dy=-127;
if(dy>=127)
        dy=127;

mouse_dx -= dx;
mouse_dy -= dy;

if (mouse_dx == 0 && mouse_dy == 0)
        mouse_event = 0;

spin_unlock_irqrestore(&mouse_lock, flags);

/*Copying Results to the Buffer*/
/* mouse_read continued */

if(put_user(button|0x80, buffer))
        return -EFAULT;
if(put_user((char)dx, buffer+1))
        return -EFAULT;
if(put_user((char)dy, buffer+2))
        return -EFAULT;
printk("exiting from read function");
for(n=3; n < count; n++)
        if(put_user(0x00, buffer+n))
                return -EFAULT;

return count;
}

 


Yahoo! Messenger - Communicate instantly..."Ping" your friends today! Download Messenger Now

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux