Greg, The code we are dealing with is in the QSPI driver which is in the 2.4 kernel. QDLYR |= QDLYR_SPE; // This line triggers a serial Motorola SPI bus transfer interruptible_sleep_on(&wqueue); // This line calls the kernel to sleep till the // 'end-of'SPI-tranfer' interrupt. The driver's interrupt routine does: ... if (qir & QIR_SPIF) { wake_up(&wqueue); /* transfer finished */ } The problem is: occasionally a delay (higher-priority interrupt handling) occurs between the start of the QSPI transfer (QDLYR |= QDLYR_SPE;) and the sleep call ( wake_up(&wqueue) ). So the the QSPI transfer-finished interrupt occurs and is handled *before* we go to sleep. Then we sleep forever! Richard's 'fix' was to 'time-out' the sleep call, so it always returns even if the interrupt was missed, so he calls interruptible_sleep_on_timeout() instead of interruptible_sleep_on(). Following your suggestion, we could stop interrupts, start the QSPI transfer, clear interupts, and call interruptible_sleep_on. But an interrupt immediately after we allow interrupts could delay the sleep call till after the QSPI finished interrupt occured. Hmmmm, a real Catch22. One possible solution, too ugly to really consider: (1) stop interrupts (2) initiate the QSPI transfer (3) set a global 'qflag' (4) call interruptible_sleep_on() (5) Hack the kernel 'sleep code' so after it puts us to sleep, it sees that 'qflag' is TRUE and turns on interrupts again for us. Nooooo, we really don't want to do that! Some sort of solution like this is needed. How about a modified kernel sleep function that would allow a driver to pass a call-back function address, to be called right after the kernel puts us to sleep. The address could be passed in the interruptible_sleep_on() call, so its a simple implementation. Then the kernel could put us to sleep, call our call-back fuction (which starts the QSPI transfer and returns). Then we would always catch the interrupt. The kernel could immediatley toss the call-back function address, so its only a minor kernel change. The sleep function call could be modified to allow an optional 2nd parameter. You think Linus would go for this if I proposed it formally? Regards, Ron Fial >Forgive me for coming into this half way through but :-) >It sounds like what you need is to protect against interrupts >around the interruptible_sleep_on(). The usual > > save_flags(flags); cli(); > ... > restore_flags(flags); > >is simple and easy to use... Or am I missing something here? > >You can in fact do even better, by setting the task state to >be TASK_INTERRUPTIBLE and calling schedule you can avoid >the cli/restore set. I'll leave the exact implementation >as an exercise for the reader :-) > >Regards >Greg > This message resent by the uclinux-dev@uclinux.org list server http://www.uClinux.org/