Results 1 to 2 of 2
Hi,
Im trying to write a keyboard interrupt handler... Im using 2.6.35 linux kernel...
Since INIT_WORK does takes only 3 arguments in 2.6.35 kernel, I have my code as follows
...
Enjoy an ad free experience by logging in. Not a member yet? Register.
- 10-18-2011 #1Just Joined!
- Join Date
- Oct 2011
- Posts
- 4
INIT_WORK() with two arguments
Hi,
Im trying to write a keyboard interrupt handler... Im using 2.6.35 linux kernel...
Since INIT_WORK does takes only 3 arguments in 2.6.35 kernel, I have my code as follows
irqreturn_t irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
/*
* This variables are static because they need to be
* accessible (through pointers) to the bottom half routine.
*/
static int initialised = 0;
static unsigned char scancode;
static struct work_struct task;
unsigned char status;
/*
* Read keyboard status
*/
status = inb(0x64);
scancode = inb(0x60);
if (initialised == 0) {
// INIT_WORK(&task, got_char, &scancode);
INIT_WORK(&task, got_char);
initialised = 1;
} else {
// PREPARE_WORK(&task, got_char, &scancode);
PREPARE_WORK(&task, got_char);
}
queue_work(my_workqueue, &task);
return IRQ_HANDLED;
}
The bottom half code is like this
static void got_char(void *scancode)
{
printk(KERN_INFO "Scan Code %x %s.\n",
(int)*((char *)scancode) & 0x7F,
*((char *)scancode) & 0x80 ? "Released" : "Pressed");
}
If INIT_WORK can take only two arguments I wanted to know how to pass the data(scancode) to got_char() function....
- 10-20-2011 #2Just Joined!
- Join Date
- Jul 2011
- Posts
- 16
First thing is, I dont understand why you have created static variables in the interrupt handler. Generally a private data structure is created and an object of that is created statically or dynamically. For example you have two important variable scancode and task, a data structure is defined like this.
struct myprivate {
int scancode;
struct work_struct task;
};
An object for this data structure is created in the init routine of the driver. Say like this we have created.
struct myprivate *myp;
myp = kmalloc(sizeof (*myp);
And the work item is initialized in the init routine like this:
INIT_WORK(&myp->task, got_char);
And in the interrupt routine the work is scheduled like this:
schedule_work(&myp->task);
I assume that you have got the myp pointer through the dev_id parameter of the interrupt handler.
Then this myp->task is sent as parameter to got_char(). Then the container of macro is used and the base address of the struct myprivate object is derived, then you can access the scancode variable. Like this:
static void got_char(struct work_struct *taskp)
{
struct myprivate *myp = container_of(taskp, struct myprivate, task);
printk("Scancode = %d", myp->scancode);
}


Reply With Quote
