2009/2/25 Michael Blizek <michi1@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>: > On 17:44 Wed 25 Feb , Denis Borisevich wrote: >> Hi! >> I've done some tests and here is what I figured out: the interrupts >> assigned to the device controlled by the ahci driver keep going even >> without my driver loaded and even with all my boards removed from >> system physically. So it seems that everything ok. >> But I have another question concerning interrupts: >> Let's take the situation I described in my first and second posts - I >> have a system with the PCI board which I develop driver for. This >> board shares interrupt with the device controlled by ahci driver. The >> question is why every interrupt I got on this line is interpreted by >> my driver as the interrupt which belongs to it? > > If an interrupt is shared, the kernel does not know which device a raised > interrupt belongs to. For this reason, it is delivered to every driver which > has an interrupt handler for this interrupt. > >> Here is the code I use: >> >> === CODE BELOW === >> >> to register ISR: >> struct my_dev *board; >> request_irq(board->irq, my_interrupt_handler, IRQF_SHARED, "my_module", board); >> >> ISR: >> static irqreturn_t my_interrupt_handler(int irq, void *dev_id) >> { >> struct my_dev *board; >> int i, retval = IRQ_NONE; >> >> // find out which board got an interrupt >> for (i = 0; i < MAX_BOARDS; i++) >> if (dev_id == &my_boards[i]) { >> board = dev_id; >> break; >> } >> >> // Check if interrupt was issued by another device (in case of shared >> // interrupt line). >> if (i == MAX_BOARDS) >> goto handled; >> if (board == NULL) >> goto handled; >> >> // if we are here then it's our interrupt >> retval = IRQ_HANDLED; >> >> /* here goes some checks on the device registers >> to know if there is interrupts pending in it. >> these checks are sure to be right. If there's no >> interrupt, then debug message "no interrupt" is >> printed. >> */ >> ....... >> /* here goes the interrupt handling, if the previous check >> was successful >> */ >> ....... >> >> handled: >> return retval; >> } >> >> === CODE ABOVE === >> >> So, what do I have now. When no program touches my device (it is >> idling) and the ahci driver is loaded I have this "no interrupt" >> message in dmesg output 20-30 times per second. When some application >> uses my device I have the proper printouts (the kind of interrupt and >> so on) and bunch of these "no interrupt". When I install my board into >> another PCI slot (and get another interrupt line) I never see these >> "no interrupt" messages, but only the ones concerning to the actual >> interrupt handling in my driver. Which indicates that driver works as >> intended. The questions is why the dev_id parameter of >> my_interrupt_handler() holds the data which belongs to one of the >> boards controlled by my driver (which is the reason why the check in >> the very beginning of ISR routine is passed)? > > The dev_id is the what you passed it request_irq. You do not need the loop, > because you will not be called if dev_id is not your device. The 2 > if...goto handled should never happen. What you need to do in the interrupt > handler is to ask the device if it has raised the interrupt and do the > interrupt handling if necessary. Something like this: > > static irqreturn_t my_interrupt_handler(int irq, void *dev_id) > { > struct my_dev *board = dev_id; > > int interrupts_pending = do_some_check; > > if (interrupts_pending == 0) { > /* probably another device which is sharing the interrupt has > * raised thi irq > */ > return IRQ_NONE; > } > > /* here goes the interrupt handling */ > > return IRQ_HANDLED; > } > > -Michi > > -- > programing a layer 3+4 network protocol for mesh networks > see http://michaelblizek.twilightparadox.com > > I see. Thanks for your help. Have you any idea why the ahci driver behaves this way? -- Denis -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ