Re: Interrupt fires when module is unloaded

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

 



It's a mess, but you are welcome to it :-)

//-------------------------------cut here---------------------
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
//#include <linux/proc_fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>

MODULE_LICENSE("GPL");

#define NUM_DEVICES (1)
#define DEVNAME "foobar"
#define DEVPROCNAME "foobar_mem"
#define FOOBAR_MAJOR (248)
#define FOOBAR_MINOR (0)
 
int foobar_init(void); 
void foobar_exit(void); 
int foobar_release(struct inode *, struct file*);
ssize_t foobar_read(struct file *, char __user *, size_t, loff_t *); 
ssize_t foobar_write(struct file *, const char __user *, size_t, loff_t *);
int foobar_read_procmem(char * buf, char **start, off_t offset, int count, int * eof, void * data); 
int foobar_open(struct inode * inode, struct file * file);
void set_port_and_irq(void);
static irqreturn_t irqhandler(int irq, void * data);
int foobar_set_irq(void);

int port_address = -1;
module_param(port_address, int, 0); 

unsigned int irq = 0; 
module_param(irq, uint, 0);

int irqavail = -1;

static struct file_operations foobar_i_fops = 
  {
    .owner = THIS_MODULE, 
    .read =  foobar_read, 
    .write = foobar_write,
    .open = foobar_open,
    .release = foobar_release,
  };


static dev_t g_dev;
unsigned dev_id = (unsigned)&foobar_i_fops;

int foobar_init(void)
{
  int result = 0; 
  
  result = register_chrdev(0, DEVNAME, &foobar_i_fops); 
  g_dev = MKDEV(result, FOOBAR_MINOR); 
  if(result < 0)
  {
      printk(KERN_WARNING "foobar: can't get device number, returning %d", result); 
      return result; 
  }
    
  printk(KERN_WARNING "foobar: Module %s got device number %d, minor is %d, result is %d\n", THIS_MODULE->name, MAJOR(g_dev), MINOR(g_dev), result); 
  g_dev = MKDEV(MAJOR(g_dev), FOOBAR_MINOR + NUM_DEVICES);

  set_port_and_irq();
  printk(KERN_WARNING "Port address is 0x%x, IRQ is %d\n", port_address, irq);
  return 0; 
}

void set_port_and_irq(void)
{
  if(irq < 0)
      switch(port_address)
{
case 0x378:
 irq = 7; 
 break; 

case 0x278:
 irq = 2; 
 break; 
}

    switch(irq)
      {
      case 2:
port_address = 0x278; 
break; 

      case 7:
port_address = 0x378; 
break; 
 
     }    
}

void foobar_exit(void)
{
  int major = MAJOR(g_dev); 

  if(irqavail == 0)
    {
      printk(KERN_WARNING "Freeing irq %d, dev_id is 0x%x\n", irq, dev_id);
      free_irq(irq, (void*)dev_id);
    }
  
  printk(KERN_WARNING "unregister_chrdev(%d) called for %s, dev # is %d\n", major, DEVNAME, g_dev); 

  unregister_chrdev(major, DEVNAME); 
}

int foobar_set_irq(void)
{
  irqavail = request_irq(irq, irqhandler, IRQF_SHARED, DEVNAME, (void*)dev_id);
  printk(KERN_WARNING "IRQ:%d\tPort Address:0x%x\tAvailable:%s\n", irq, port_address, irqavail == 0 ? "true" : "false"); 

  return irqavail;
}

static irqreturn_t irqhandler(int irq, void * data)
{
  printk(KERN_WARNING "Interrupt is fired, IRQ is %d, data is 0x%p\n", irq, data);
  return IRQ_HANDLED;
}

int foobar_open(struct inode * inode, struct file * file)
{
  return foobar_set_irq(); 
}


int foobar_release(struct inode * inode, struct file * filp)
{
  printk(KERN_WARNING "foobar_release() is called, fil is 0x%p, inode is 0x%p\n", filp, inode);
  return 0;

ssize_t foobar_read(struct file * filp, char __user * buf, size_t count, loff_t * f_pos)
{
  printk(KERN_WARNING "Read is called\n");
  return 0;
}

ssize_t foobar_write(struct file * filp, const char __user * buf, size_t count, loff_t *f_pos)
{
  unsigned long address = (unsigned long)port_address;
  printk(KERN_WARNING "Write is called, address is 0x%lx\n", address);
  outb_p(0x10, address + 2); 
  outb_p(0x00, address); 
  outb_p(0xff, address);
  udelay(5);
  outb_p(0x00, address + 2);
  if(f_pos)
    * f_pos = 0; 
  return count; 
}

module_init(foobar_init); 
module_exit(foobar_exit); 





On Mon, Jan 6, 2014 at 4:27 PM, Rajat Sharma <fs.rajat@xxxxxxxxx> wrote:
It would be nice to post the code when asking for debugging help. Looks like your interrupts are in masked state but when you unload the driver they are getting unmasked and hence you are receiving them on unload.

-Rajat


On Mon, Jan 6, 2014 at 4:09 PM, Eric Fowler <eric.fowler@xxxxxxxxx> wrote:
I am trying to figure out interrupts by writing a shadow of Rubini's 'short' program. Recall that Rubini tells us to enable parallel port interrupts by wiring pins 9&10 together, then writing binary data to the parallel port's address. 

I am doing that, but: 
- I don't see interrupts when I write to the port
- I do see one interrupt when I unload the driver (in the fop's .release method)
- This happens whether or not the pins are wired up. 

What is going on here?



_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies





--
cc:NSA
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[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