Interrupt fires when module is unloaded
Eric Fowler
eric.fowler at gmail.com
Mon Jan 6 19:32:41 EST 2014
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 at gmail.com> 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 at gmail.com> 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 at kernelnewbies.org
>> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>>
>>
>
--
cc:NSA
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140106/a44f0319/attachment-0001.html
More information about the Kernelnewbies
mailing list