public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* testing mouse device driver
@ 2002-12-04 12:04 Shahid
  2002-12-04 13:47 ` Alan Cox
  0 siblings, 1 reply; 3+ messages in thread
From: Shahid @ 2002-12-04 12:04 UTC (permalink / raw)
  To: kernel

hi everybody,

                    I am trying to develop a mouse
device driver for Linux. my linux verison is Redhat
7.2. In writing the code i followed a tutorial by Alan
Cox on developing mouse driver, where actually Alan
Cox gives every code needed to build a mouse driver.
You can find out out this tutorial in linux's kernel
documentation and also in the site - www.linux-mag.com
.

                    i worked on the codes of the
tutorial. The tutorial uses an imaginary mouse port
base address and irq number and i have to make few
changes to compile the code and loading it as a module
with insmod. However when i am able to load it as
module, i wanted to test the driver. As my pc mouse
uses ps/2 port - so i use 0x064h as ps/2 ports base
address and irq number 12 (ps/2 ports interrupt
number, i get it from a list in the /proc/interrupts).
But then for testing i boot linux with the mouse
device removed. So in the boot process, kudzu appears
reporting ps/2 mouse device removed. From that screen
i choose remove configuration as i ant to use my own
driver for the mouse. Then after entering into linux,
first i make a node in the /dev directory for the
mouse device by the following command -

                    mknod  ourmouse  c  10  0

    here i used the major number for misc devices(as
the code registers mouse as misc devices) and use the
minor number 0 for mouse. Then i compile the code to
make mouse.o object file, then whenever i am trying to
loading the mdule with insmod the an error message
like the following appears -

this module can't be loaded, it can taint the kernel
invalid i/o or irq number used a parameter


   i also tried with 0x23Ch as port address and 5 as
irq number, which i got from the kernel source file -
logimouse.c and logimouse.h....... but i got the same
result.
i am really desperate to test that driver and i tried
in many ways.......so u can help me a while?

below is my source code.  If u think u need the
tutorial to solve the problem and can't retrieve it
from the site or linux documentation, then also feel
free to contact with me. my e-mail address is:
z-shahid@runbox.com
thanx in advance for ur response.

best regards -

Shahid, Dhaka.


/*source code*/


#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/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 <asm/system.h>
#include<asm/segment.h>
#include<asm/io.h>



/*Listing 1: File Operations*/
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 = {
    NULL,        /* Mice don't seek */
    mouse_read,  /* You can read a mouse */
    write_mouse, /* This won't do a lot */
    NULL,        /* No readdir - not a directory */
    mouse_poll,  /* Poll */
    NULL,        /* No ioctl calls */
    NULL,        /* No mmap */
    open_mouse,  /* Called on open */
    NULL,        /* Flush - 2.2 only */
    close_mouse, /* Called on close */
    NULL,        /* No media change on a mouse */
    NULL,        /* Asynchronous I/O - we will add this later*/
    NULL
};

/*=====================================================*/

/*Listing 2: Initializing Functions*/
/*#define OURMOUSE_BASE   0x300*/
/*#define OURMOUSE_BASE   0x23c*/
#define OURMOUSE_BASE 0x064

#define OURMOUSE_MINOR 0

/*#define MOUSE_IRQ 5*/
#define MOUSE_IRQ 12


static struct miscdevice our_mouse = {
 OURMOUSE_MINOR, "ourmouse",&our_mouse_fops, &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;
}

/*=====================================================*/

/*Listing 3: 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);
}

#endif


/*===================================================*/

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 mouse_intr = MOUSE_IRQ;

/*Listing 4: The Interrupt Handler*/
static struct wait_queue *mouse_wait;
static spinlock_t mouse_lock = SPIN_LOCK_UNLOCKED;

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)
    {
            /* Something happened */
            spin_lock(&mouse_lock);
            mouse_event = 1;
            mouse_dx += delta_x;
            mouse_dy += delta_y;
            mouse_buttons = new_buttons;
            spin_unlock(&mouse_lock);

            wake_up_interruptible(&mouse_wait);
    }
}


/*======================================================*/


/*Listing 5: Managing Interrupts*/

static int open_mouse(struct inode *inode, struct file *file)
{
    if(mouse_users++)
        return 0;
    if(request_irq(mouse_intr, ourmouse_interrupt, 0,
       "ourmouse", NULL))
    {
        mouse_users--;
        return -EBUSY;
    }
    mouse_dx = 0;
    mouse_dy = 0;
    mouse_buttons = 0;
    mouse_event = 0;
    MOD_INC_USE_COUNT;
    return 0;
}


/*========================================================*/



/*Listing 6: 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;
}


/*======================================================*/


/*Listing 7: Filling in the Write Handler*/
static ssize_t write_mouse(struct file *file, const char *buffer, size_t
count, loff_t *ppos)
{
    return -EINVAL;
}



/*=====================================================*/


/*Listing 8: 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;
}


/*===================================================*/


/*Listing 9: 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 -EAGAIN;
    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;

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;

for(n=3; n < count; n++)
        if(put_user(0x00, buffer+n))
                return -EFAULT;

return count;
}

/* all quiet on the western front */




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: testing mouse device driver
  2002-12-04 12:04 testing mouse device driver Shahid
@ 2002-12-04 13:47 ` Alan Cox
  2002-12-05 12:46   ` Shahid
  0 siblings, 1 reply; 3+ messages in thread
From: Alan Cox @ 2002-12-04 13:47 UTC (permalink / raw)
  To: Shahid; +Cc: Linux Kernel Mailing List


Minor 0 is dynamic - you probably want to pick another minor number or
look in /proc/misc to see which minor was chosen.

The PS/2 port is rather special btw and tied in with the keyboard so
isnt one you can treat seperately. Fortunately no PS/2 mouse should need
any 2.4 kernel hacks, just user space stuff to handle different command
streams


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: testing mouse device driver
  2002-12-04 13:47 ` Alan Cox
@ 2002-12-05 12:46   ` Shahid
  0 siblings, 0 replies; 3+ messages in thread
From: Shahid @ 2002-12-05 12:46 UTC (permalink / raw)
  To: Alan Cox; +Cc: kernel


----- Original Message -----
From: "Alan Cox" <alan@lxorguk.ukuu.org.uk>
To: "Shahid" <z-shahid@runbox.com>
Cc: "Linux Kernel Mailing List" <linux-kernel@vger.kernel.org>
Sent: Wednesday, December 04, 2002 7:47 PM
Subject: Re: testing mouse device driver


>
> Minor 0 is dynamic - you probably want to pick another minor number or
> look in /proc/misc to see which minor was chosen.
>
> The PS/2 port is rather special btw and tied in with the keyboard so
> isnt one you can treat seperately. Fortunately no PS/2 mouse should need
> any 2.4 kernel hacks, just user space stuff to handle different command
> streams
>

  /******* Eid Mubarok and greetings to all of this kernel mailing list
                        on the occasion of the Holy Eid
*********/

hi,
        thanx for ur quick response. Actually what i need (a part of my
academic project), is just to comile ur code and load it as a module and
then to see whether the bare mouse specific events occur. but the painful
reality is, i failed to do so. FYI,  i just a sophomore undergraduate
student, and i don't find any resourse inside or outside my faculty to help
me to do this. So i had to come in the kernel mailing list, though i am
almost a newbie.

        i tried with minor numbers other than 0. first i tried with ,inor
number 1, cauze this is the number i got in /proc/misc allocated for psaux,
in that file. but the result is same. now while i try to load the module,
the error message is:

        init_module: no such device, invalid parameters
        hint: invalid IO or irq number


        then i arbitary tried with some other minor numbers, but the result
is same.
So plz help me to just load the module. as u r the author, certainly u
compiled that code and load the module. so plz tell me ur parameters, i.e.
the port address and major-minor number and irq number, or other hints so
that i load that module.
TIK

regards -
Shahid



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-12-05 12:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-04 12:04 testing mouse device driver Shahid
2002-12-04 13:47 ` Alan Cox
2002-12-05 12:46   ` Shahid

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox