Find the answer to your Linux question:
Results 1 to 2 of 2
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1

    INIT_WORK() with two arguments


    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....

  2. #2
    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:
    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);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts