> > clear_bit(COMPLETION_RUN, ->flags); > > xfer bytes > > if (test_and_set_bit(COMPLETION_RUN, ->flags) == 0) > > run_completion_routine(); > > ->active-ignore-irq = 0; > > > > and in the IRQ case after checking we are not active-ignore-IRQ we > > similarly do > > > > if (test_and_set_bit(COMPLETION_RUN, ->flags) == 0) > > run_completion_routine_irq(); > > > > Now if we are unlucky and the IRQ gets in between the last byte of > > transfer and clearing the active ignore IRQ flag we will still run the > > completion handler > > I don't really get this. What happens if the IRQ is shared and the > other device raises interrupt while the data transfer is still in > progress? What prevents it from running the completion routine? Before the transfer begins you set your flag to indicate you want to ignore this IRQ. You then set the flag indicating completion has not occurred. Next you do the data transfer An IRQ during the transfer will not complete as we are ignoring the IRQ/polling at the driver level. On completion either a) the IRQ beats the test_and_set_bit in which case it runs the completion or b) the test_and_set_bit in the I/O path beats the IRQ handler in which case the IRQ handler will not run the completion as the bit is atomically set or c) the IRQ beats the clearing of the ignore irq flag in which case it won't execute the handler but the data transfer path will I'm sure there are even simpler ways we can do this they key is to make sure that whatever the event order we only run the completion path once, and it doesn't matter which path runs it. - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html