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