From: "Shahid" <z-shahid@runbox.com>
To: "kernel" <linux-kernel@vger.kernel.org>
Subject: testing mouse device driver
Date: Wed, 4 Dec 2002 18:04:26 +0600 [thread overview]
Message-ID: <00d101c29b8d$63e45e80$4b614ccb@zaman> (raw)
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 */
next reply other threads:[~2002-12-04 11:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-12-04 12:04 Shahid [this message]
2002-12-04 13:47 ` testing mouse device driver Alan Cox
2002-12-05 12:46 ` Shahid
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='00d101c29b8d$63e45e80$4b614ccb@zaman' \
--to=z-shahid@runbox.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox