I am trying to implement asynchronous notification in a device driver.
I have 2 questions.
First question: where do I call kill_fasync()?
The driver, /usr/src/linux-2.4.7-10/drivers/acorn/char/mouse_ps2.c, calls
kill_fasync() within its psaux_interrupt(), which is the interrupt handler
registered via request_irq().
If I understand the concepts correctly, an interrupt handler runs at
interrupt
time and doesn't execute in the context of a process. Therefore, when
psaux_interrupt() calls kill_fasync(), the process which is supposed to
receive a SIGIO may not be running. Is this still OK (that is, to call
kill_fasync() within the interrupt handler)? Will the kernel hang or crash?
Will the process receive the SIGIO?
Second question: can I send SIGIO to more than one process?
The hardware that I am working on can receive 3 types of interrupts. My
interrupt handler can determine which type is received. I would like to
provide some sort of ioctl mechanism to allow a process to specify that it
wishes to receive a SIGIO for a particular type. This way, 2 or more
processes can open the same hardware unit and register an interest in a
certain type. For example, process A could register for types 1 and 3 while
process B could register for type 2. Or process A only ask for type 1 while
process B is only interested in type 2; no asynchronous notification will be
raised for type 3.
I am thinking of writing my interrupt handler as follows:
void
interrupt_handler (int irq, void* dev_id, struct pt_regs* regs)
{
struct myDev* dev = dev_id;
....
switch (type) {
default:
blah();
break;
case 1:
if (dev->type1_fown)
send_sigio (dev->type1_fown, fd, band);
break;
case 2:
if (dev->type2_fown)
send_sigio (dev->type2_fown, fd, band);
break;
case 3:
if (dev->type3_fown)
send_sigio (dev->type3_fown, fd, band);
break;
}
...
}
The type?_fown will initially be set to NULL; each device has its own set of
these 3 pointers. A process can use an ioctl() call, which will set the
appropriate type?_fown to contain the process's pid, etc. The ioctl() will
return an error if another process has already registered for the same type
on the same hardware unit.
Am I doing this correctly? It seems to me that F_SETOWN allows only one
process to be filp->f_owner. I hope send_sigio() will remain stable.
Please reply to me directly (mailto:fungchai@stts.com.sg) as I am not
subscribed to the mailing list.
Thanks in advance.
Best regards,
Fung-Chai LIM
ST Training & Simulation Pte Ltd
24 Ang Mo Kio Street 65
Singapore 569061
Telephone: (65) 6413-1368
mailto:fungchai@stts.com.sg
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/