this is the code for the small module that i wrote
------------------------------
----------------------------------
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define SKELETON_MAJOR 32
#define SKELETON_NAME "skeleton"
#define BASEPORT 0x378
#define PARALLEL_PORT_INTERRUPT 7
#define CASE1 1
#define CASE2 2
static int data;
static unsigned int counter = 0;
static char string [128];
static int data;
//static int interruptcount = 0;
DECLARE_WAIT_QUEUE_HEAD(skeleton_wait);
static int data_not_ready = 1;
// open function - called when the "file" /dev/skeleton is opened in userspace
static int skeleton_open (struct inode *inode, struct file *file) {
printk("skeleton_open\n");
// we could do some checking on the flags supplied by "open"
// i.e. O_NONBLOCK
// -> set some flag to disable interruptible_sleep_on in skeleton_read
return 0;
}
// close function - called when the "file" /dev/skeleton is closed in userspace
static int skeleton_release (struct inode *inode, struct file *file) {
printk("skeleton_release\n");
return 0;
}
// read function called when from /dev/skeleton is read
static ssize_t skeleton_read (struct file *file, char *buf,
size_t count, loff_t *ppos) {
int len, err;
// check if we have data - if not, sleep
// wake up in interrupt_handler
while (data_not_ready) {
interruptible_sleep_on(&skeleton_wait);
}
data_not_ready = 1;
printk("read works fine");
if( counter <= 0 )
return 0;
err = copy_to_user(buf,string,counter);
if (err != 0)
return -EFAULT;
len = counter;
counter = 0;
return len;
}
// write function called when to /dev/skeleton is written
static ssize_t skeleton_write (struct file *file, const char *buf,
size_t count, loff_t *ppos) {
int err;
printk("write works fine");
err = copy_from_user(string,buf,count);
if (err != 0)
return -EFAULT;
counter += count;
return count;
}
// ioctl - I/O control
static int skeleton_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) {
int retval = 0;
switch ( cmd ) {
case CASE1:/* for writing data to arg */
if (copy_from_user(&data, (int *)arg, sizeof(int)))
return -EFAULT;
break;
case CASE2:/* for reading data from arg */
if (copy_to_user((int *)arg, &data, sizeof(int)))
return -EFAULT;
break;
default:
retval = -EINVAL;
}
return retval;
}
// interrupt handler
irqreturn_t interrupt_handler (int irqn, void *dev)
{
printk("Press a key ");
return IRQ_HANDLED;
}
// define which file operations are supported
struct file_operations skeleton_fops = {
.owner = THIS_MODULE,
.read = skeleton_read,
.write = skeleton_write,
.ioctl = skeleton_ioctl,
.open = skeleton_open,
.release = skeleton_release,
};
// initialize module (and interrupt)
static int __init skeleton_init_module (void) {
int i;
int ret;
printk("initializing module\n");
//free_irq(7,NULL);
i = register_chrdev (SKELETON_MAJOR, SKELETON_NAME, &skeleton_fops);
if (i != 0) return - EIO;
//disable_irq(7);
ret = request_irq (7, interrupt_handler,0,SKELETON_NAME ,NULL);
printk("ret=%d\n",ret);
//enable_irq(7);
if(ret>=0){
enable_irq(7);
// outb_p(0x10, BASEPORT + 2);
}
else
{
printk("Not Working \n");
}
//printk("Generating interrupt \n");
/*outb(0, BASEPORT);
outb(255, BASEPORT);
outb(0, BASEPORT);*/
printk("Interrupt generated. You should see the handler-message\n");
return 0;
}
// close and cleanup module
static void __exit skeleton_cleanup_module (void) {
printk("cleaning up module\n");
unregister_chrdev (SKELETON_MAJOR, SKELETON_NAME);
//disable_irq(6);
//free_irq(6, NULL);
}
module_init(skeleton_init_module);
module_exit(skeleton_cleanup_module);
MODULE_LICENSE("GPL");
----------------------------------------------------------------------------------------
and after insmod ,i get the following error:
[ 1291.259646] initializing module
> [ 1291.259672] ret=0
> [ 1291.259679] ------------[ cut here ]------------
> [ 1291.259682] WARNING: at
> /build/buildd/linux-2.6.28/
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define SKELETON_MAJOR 32
#define SKELETON_NAME "skeleton"
#define BASEPORT 0x378
#define PARALLEL_PORT_INTERRUPT 7
#define CASE1 1
#define CASE2 2
static int data;
static unsigned int counter = 0;
static char string [128];
static int data;
//static int interruptcount = 0;
DECLARE_WAIT_QUEUE_HEAD(skeleton_wait);
static int data_not_ready = 1;
// open function - called when the "file" /dev/skeleton is opened in userspace
static int skeleton_open (struct inode *inode, struct file *file) {
printk("skeleton_open\n");
// we could do some checking on the flags supplied by "open"
// i.e. O_NONBLOCK
// -> set some flag to disable interruptible_sleep_on in skeleton_read
return 0;
}
// close function - called when the "file" /dev/skeleton is closed in userspace
static int skeleton_release (struct inode *inode, struct file *file) {
printk("skeleton_release\n");
return 0;
}
// read function called when from /dev/skeleton is read
static ssize_t skeleton_read (struct file *file, char *buf,
size_t count, loff_t *ppos) {
int len, err;
// check if we have data - if not, sleep
// wake up in interrupt_handler
while (data_not_ready) {
interruptible_sleep_on(&skeleton_wait);
}
data_not_ready = 1;
printk("read works fine");
if( counter <= 0 )
return 0;
err = copy_to_user(buf,string,counter);
if (err != 0)
return -EFAULT;
len = counter;
counter = 0;
return len;
}
// write function called when to /dev/skeleton is written
static ssize_t skeleton_write (struct file *file, const char *buf,
size_t count, loff_t *ppos) {
int err;
printk("write works fine");
err = copy_from_user(string,buf,count);
if (err != 0)
return -EFAULT;
counter += count;
return count;
}
// ioctl - I/O control
static int skeleton_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) {
int retval = 0;
switch ( cmd ) {
case CASE1:/* for writing data to arg */
if (copy_from_user(&data, (int *)arg, sizeof(int)))
return -EFAULT;
break;
case CASE2:/* for reading data from arg */
if (copy_to_user((int *)arg, &data, sizeof(int)))
return -EFAULT;
break;
default:
retval = -EINVAL;
}
return retval;
}
// interrupt handler
irqreturn_t interrupt_handler (int irqn, void *dev)
{
printk("Press a key ");
return IRQ_HANDLED;
}
// define which file operations are supported
struct file_operations skeleton_fops = {
.owner = THIS_MODULE,
.read = skeleton_read,
.write = skeleton_write,
.ioctl = skeleton_ioctl,
.open = skeleton_open,
.release = skeleton_release,
};
// initialize module (and interrupt)
static int __init skeleton_init_module (void) {
int i;
int ret;
printk("initializing module\n");
//free_irq(7,NULL);
i = register_chrdev (SKELETON_MAJOR, SKELETON_NAME, &skeleton_fops);
if (i != 0) return - EIO;
//disable_irq(7);
ret = request_irq (7, interrupt_handler,0,SKELETON_NAME ,NULL);
printk("ret=%d\n",ret);
//enable_irq(7);
if(ret>=0){
enable_irq(7);
// outb_p(0x10, BASEPORT + 2);
}
else
{
printk("Not Working \n");
}
//printk("Generating interrupt \n");
/*outb(0, BASEPORT);
outb(255, BASEPORT);
outb(0, BASEPORT);*/
printk("Interrupt generated. You should see the handler-message\n");
}
// close and cleanup module
static void __exit skeleton_cleanup_module (void) {
printk("cleaning up module\n");
unregister_chrdev (SKELETON_MAJOR, SKELETON_NAME);
//disable_irq(6);
//free_irq(6, NULL);
}
module_init(skeleton_init_module);
module_exit(skeleton_cleanup_module);
MODULE_LICENSE("GPL");
----------------------------------------------------------------------------------------
and after insmod ,i get the following error:
- Hide quoted text -
[ 1291.259646] initializing module
> [ 1291.259672] ret=0
> [ 1291.259679] ------------[ cut here ]------------
> [ 1291.259682] WARNING: at
> /build/buildd/linux-2.6.28/
kernel/irq/manage.c:225 __enable_irq+0x30/0x70()
> [ 1291.259685] Unbalanced enable for IRQ 7
> [ 1291.259687] Modules linked in: skeleton(+) hid_bright usbhid rfkill_input
> i915 drm binfmt_misc ppdev bridge stp bnep lp parport arc4 ecb snd_hda_intel
> snd_pcm_oss snd_mixer_oss snd_pcm pcmcia snd_seq_dummy b43 snd_seq_oss
> snd_seq_midi snd_rawmidi mac80211 snd_seq_midi_event cfg80211 iTCO_wdt
> iTCO_vendor_support snd_seq snd_timer snd_seq_device yenta_socket
> rsrc_nonstatic ricoh_mmc sdhci_pci sdhci snd pcmcia_core led_class intel_agp
> agpgart soundcore snd_page_alloc pcspkr input_polldev serio_raw uvcvideo
> compat_ioctl32 videodev v4l1_compat video output ohci1394 ieee1394 8139too
> 8139cp mii ssb fbcon tileblit font bitblit softcursor
> [ 1291.259751] Pid: 4400, comm: insmod Not tainted 2.6.28-11-generic
> #42-Ubuntu
> [ 1291.259754] Call Trace:
> [ 1291.259760] [<c0139ab0>] warn_slowpath+0x60/0x80
> [ 1291.259765] [<c0181449>] ? register_handler_proc+0x119/0x130
> [ 1291.259773] [<c02cc3b8>] ? vsnprintf+0x378/0x5c0
> [ 1291.259778] [<c013a2f9>] ? release_console_sem+0x1c9/0x200
> [ 1291.259782] [<c017f570>] __enable_irq+0x30/0x70
> [ 1291.259786] [<c017f5ec>] enable_irq+0x3c/0x60
> [ 1291.259790] [<f7f9c000>] ? skeleton_init_module+0x0/0x96 [skeleton]
> [ 1291.259795] [<f7f9c078>] skeleton_init_module+0x78/0x96 [skeleton]
> [ 1291.259802] [<c010111e>] _stext+0x2e/0x170
> [ 1291.259807] [<c020c015>] ? sysfs_addrm_finish+0x15/0xf0
> [ 1291.259811] [<c020b7e3>] ? sysfs_add_one+0x13/0x50
> [ 1291.259814] [<c020b85f>] ? sysfs_addrm_start+0x3f/0xa0
> [ 1291.259820] [<c01a908c>] ? __vunmap+0x9c/0xe0
> [ 1291.259823] [<c01a908c>] ? __vunmap+0x9c/0xe0
> [ 1291.259832] [<c01a9121>] ? vfree+0x21/0x30
> [ 1291.259837] [<c0163f3a>] ? load_module+0x103a/0x1040
> [ 1291.259848] [<c0163fc8>] sys_init_module+0x88/0x1b0
> [ 1291.259853] [<c01bb5da>] ? sys_close+0x7a/0xc0
> [ 1291.259857] [<c0103f6b>] sysenter_do_call+0x12/0x2f
> [ 1291.259865] [<c0500000>] ? relay_hotcpu_callback+0x6d/0xbd
> [ 1291.259868] ---[ end trace cddcbfa519faa2fe ]---
> [ 1291.259870] Interrupt generated. You should see the handler-message
>
> and the message in the handler doesnt appear.
> i am unable to get what is the problem and how can this be solved.
> [ 1291.259685] Unbalanced enable for IRQ 7
> [ 1291.259687] Modules linked in: skeleton(+) hid_bright usbhid rfkill_input
> i915 drm binfmt_misc ppdev bridge stp bnep lp parport arc4 ecb snd_hda_intel
> snd_pcm_oss snd_mixer_oss snd_pcm pcmcia snd_seq_dummy b43 snd_seq_oss
> snd_seq_midi snd_rawmidi mac80211 snd_seq_midi_event cfg80211 iTCO_wdt
> iTCO_vendor_support snd_seq snd_timer snd_seq_device yenta_socket
> rsrc_nonstatic ricoh_mmc sdhci_pci sdhci snd pcmcia_core led_class intel_agp
> agpgart soundcore snd_page_alloc pcspkr input_polldev serio_raw uvcvideo
> compat_ioctl32 videodev v4l1_compat video output ohci1394 ieee1394 8139too
> 8139cp mii ssb fbcon tileblit font bitblit softcursor
> [ 1291.259751] Pid: 4400, comm: insmod Not tainted 2.6.28-11-generic
> #42-Ubuntu
> [ 1291.259754] Call Trace:
> [ 1291.259760] [<c0139ab0>] warn_slowpath+0x60/0x80
> [ 1291.259765] [<c0181449>] ? register_handler_proc+0x119/0x130
> [ 1291.259773] [<c02cc3b8>] ? vsnprintf+0x378/0x5c0
> [ 1291.259778] [<c013a2f9>] ? release_console_sem+0x1c9/0x200
> [ 1291.259782] [<c017f570>] __enable_irq+0x30/0x70
> [ 1291.259786] [<c017f5ec>] enable_irq+0x3c/0x60
> [ 1291.259790] [<f7f9c000>] ? skeleton_init_module+0x0/0x96 [skeleton]
> [ 1291.259795] [<f7f9c078>] skeleton_init_module+0x78/0x96 [skeleton]
> [ 1291.259802] [<c010111e>] _stext+0x2e/0x170
> [ 1291.259807] [<c020c015>] ? sysfs_addrm_finish+0x15/0xf0
> [ 1291.259811] [<c020b7e3>] ? sysfs_add_one+0x13/0x50
> [ 1291.259814] [<c020b85f>] ? sysfs_addrm_start+0x3f/0xa0
> [ 1291.259820] [<c01a908c>] ? __vunmap+0x9c/0xe0
> [ 1291.259823] [<c01a908c>] ? __vunmap+0x9c/0xe0
> [ 1291.259832] [<c01a9121>] ? vfree+0x21/0x30
> [ 1291.259837] [<c0163f3a>] ? load_module+0x103a/0x1040
> [ 1291.259848] [<c0163fc8>] sys_init_module+0x88/0x1b0
> [ 1291.259853] [<c01bb5da>] ? sys_close+0x7a/0xc0
> [ 1291.259857] [<c0103f6b>] sysenter_do_call+0x12/0x2f
> [ 1291.259865] [<c0500000>] ? relay_hotcpu_callback+0x6d/0xbd
> [ 1291.259868] ---[ end trace cddcbfa519faa2fe ]---
> [ 1291.259870] Interrupt generated. You should see the handler-message
>
> and the message in the handler doesnt appear.
> i am unable to get what is the problem and how can this be solved.
--
---------------------
Harinderjit Singh
Sent from Delhi, DL, India