Problems writting a CHAR Driver with interruptible_sleep (wait_queu

Raul Dias (chaos@swi.com.br)
Thu, 12 Aug 1999 14:51:33 -0300 (EST)


Hi,

This is the first time I write something with/to the kernel, so it
could be something basic.

I am trying to be as clear as possible, so, if I am not, let me know.
:-)

I am writting a CHAR DRIVER (kernel 2.2) for an ISA board that I
designed myself.

One of things that it should do is data acquisition.

Here is how it should work:

When a user tries to read the device (/dev/chaos0),
the chaos_read() function (responsable for file reading in the module)
have to do an "outb(board)" to "ask" the board to acquire data.

then it goes to sleep with an interruptible_sleep_on();

When the DATA is ready, it does an interrupt.
The interrupt handler uses a wake_up_interruptible() to wake the
process on chaos_read() that will actually read the data (inb) and
output it.

Everything is fine, except that:

sometimes, after a few reads, the interrupt occurs before the proccess
complete the "interruptible_sleep_on()" call.

Then, the interrupt handler tries to wake it up, but it has not
slept yet.

And, for worst, it goes to sleep after that, but the interrupt has
already happen to wake it.
The only way to wake it again is stopping the reading (^C).

the read function has something like this:
....
outb (ioport, 0xFF); /* Ask for data */
interruptible_sleep_on (&wait_q); /* waits for the interrupt */
data = inb (ioport); /* grabs the data */
...

I can't do something like:
....
outb (ioport, 0xFF); /* Ask for data */
data = inb (ioport); /* grabs the data */
...

Note that:

If the data is not ready, it would give the wrong information.

I need the data as fast as I can get (that's fundamental in the
project), so I am trying to avoid a delay loop, and I guess it would
slow things a bit in the system also.

What I need to solve this, is a way to detect (in the interrupt
handler) that the function is not sleeping yet.
And, to wake it when it gets to sleep after the handler exits.

I tried to flag them, but the interrupt seens happen just after the
"interruptible_sleep_on()" starts.
So, flags didn't worked.

Thanks for your time,

Raul Dias

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/