no interrupts generated on my parallel port driver

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

 



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/


[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