I'm writing a custom parallel port driver. The code is shown below. But
I'm having problems getting the interrupts to show up for my device to
handle.
With the default parport driver interrupts are being generated just fine
after i set port 0x378+2 to 0x10 from userspace using outb. But when I
do something similar in my driver I get no interrupts being recognised
at all in /proc/interrupts. Do you see any missing steps in my code?
Thanks,
Anton
======================================================
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/wait.h>
#include <linux/delay.h> /* mdelay */
#include <asm/atomic.h> /* atomic_t*/
#include <asm/io.h> /* outb*/
#include <linux/ioport.h>
#define DRIVER_AUTHOR "Anton Wilson"
#define DRIVER_NAME "guidance"
#define DRIVER_DESC "Driver used to wait for parallel port interrupts"
#define NO_INTERRUPT_YET 0
#define INTERRUPT_OCCURED 1
#define PARALLEL_TIMEOUT 3
#define PORTS 3
int guidance_major;
atomic_t interrupt_received = ATOMIC_INIT(NO_INTERRUPT_YET);
atomic_t irq_registered = ATOMIC_INIT(0);
DECLARE_WAIT_QUEUE_HEAD(guidance_queue);
unsigned long base = 0;
int guidance_irq = 0;
static irqreturn_t guidance_interrupt(int irq, void *dev_id, struct
pt_regs *regs)
{
atomic_set(&interrupt_received, INTERRUPT_OCCURED);
wake_up_interruptible(&guidance_queue);
printk("interrupt\n");
return IRQ_HANDLED;
}
static struct file_operations guidance_fops=
{
.owner = THIS_MODULE,
//llseek rasid_lseek,
.read= guidance_read,
//write: rasid_write,
.ioctl = guidance_ioctl,
.open = guidance_open,
.release = guidance_release
};
static void guidance_exit(void)
{
if(atomic_read(&irq_registered)==1)
free_irq(guidance_irq, guidance_interrupt);
printk("parallel port guidance driver removed\n");
unregister_chrdev(guidance_major, DRIVER_NAME);
release_region(base, PORTS);
}
static int guidance_init(void)
{
int result;
//int err;
guidance_irq = 7;
base = 0x378;
if( (result = (int) request_region(base, PORTS, DRIVER_NAME)) == 0)
{
printk("Got a bad region %d\n", result);
goto exit;
}
guidance_major = register_chrdev(0, DRIVER_NAME, &guidance_fops); /*
The system will assign a major*/
if(guidance_major < 0)
{
printk("count not register device %d\n", guidance_major);
goto error_exit;
}
result = request_irq(guidance_irq, guidance_interrupt,
SA_INTERRUPT | SA_SHIRQ, "guidance",
guidance_interrupt);
if(result < 0)
{
printk("irq request failed %d\n", result);
goto error2_exit;
}
outb_p(0x10,base+2); /* Enable interrupts*/
atomic_set(&irq_registered, 1);
printk("parallel port guidance driver inserted and registered
irq\n");
return 0;
error2_exit:
unregister_chrdev(guidance_major, DRIVER_NAME);
error_exit:
release_region(base,3);
exit:
return -1;
}
module_init(guidance_init);
module_exit(guidance_exit);
/* Module information */
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
---
[This E-mail scanned for viruses by Declude Virus]
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/