On Thu, Mar 29, 2007 at 03:04:53PM +0530, Mansha Linux wrote: > On 3/29/07, Rajat Jain <rajat.noida.india@xxxxxxxxx> wrote: > > > >Here is how it works: > > > >1) The driver registers ISR for each device it services, also telling > >the kernel the corresponding device ID. This is done by calling > >request_irq(). > > > >2) When the IRQ occurs, the kernel invokes EACH and every ISR hooked > >onto that IRQ (Not just the ISR that actually services the device). > > > >3) Each ISR receives its original device ID as parameter, it > >determines whether the corresponding device is the one that generated > >the IRQ. > > > > ok. but when the ISR receives the device id and who will pass this device id > to the ISR ?? > Hi Mansha, It seems you don't have a big picture of how interrupts are handled, I've just finished understanding interrupts code ;), so Here's a little explanatoin: * From the device driver side (Also check LDD3, chapter 10): 1) A device driver notifies the system that it want to be signalled when a specific IRQ line is triggered. It does so by calling request_irq(). int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id) 2) As you notice, request_irq() gathers all the needed info from parameters and forms with it an `irqaction' structure (the ISR). This irqaction is added to a doubly linked list of other ISRs sharing the same IRQ using the setup_irq() method. int setup_irq(unsigned int irq, struct irqaction *new) * From hardware and other kernel layers side (code is best source ;)): 1) The hardware has something called IDT (Interrupt Descriptor Table). When a hardware device issues an interrupt, it finds the address of its handler. usually this address is initialized to the appropriate entry in interrupt[] array, aka interrupt[IRQ]. Check: arch/i386/kernel/i8259.c::native_init_IRQ() 2) every handler in interrupt[] just pushes ~IRQ value in stack, saves other registers then calls do_IRQ(). After some sanity checks do_IRQ() calls the specific handler. desc->handle_irq(irq, desc); 3) Above handler is one of handle_simple_irq(), handle_level_irq(), handle_fasteoi_irq(), ... . The thing common in all those different specialized type of handlers is that they call the handle_IRQ_event() function. irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) 4) As you can deduce from parameters, it takes the first irqaction in the ISR list. it follows the list to execute all of ISRs till the list ends. irqreturn_t retval = IRQ_NONE; [...] do { ret = action->handler(irq, action->dev_id); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); [...] return retval; * Now back to your original question, note the first line: ret = action->handler(irq, action->dev_id); Remember, The handler called above was set using using request_irq() and it's called _now_. If the handler deduced that passed dev_id is not its own, it just returns IRQ_NONE. #define IRQ_NONE (0) #define IRQ_HANDLED (1) Now an interrupt will be considered serviced by the system if retval != 0. That's the reason why it's ORed with every handler irqreturn_t value. mm, this could be transofmed to a little article. I Hope it has helped you :). Regards, -- Ahmed S. Darwish http://darwish.07.googlepages.com -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ