Last month I walked through the steps of writing a
serviceable mouse driver that contained a
couple of bugs and that would not work with asynchronous I/O. In this month’s column I’ll smooth things
out a bit. But first, I think we should take a look at some bugs.
Last month I walked through the steps of writing a
serviceable mouse driver that contained a
couple of bugs and that would not work with asynchronous I/O. In this month’s column I’ll smooth things
out a bit. But first, I think we should take a look at some bugs.
Last month I walked through the steps of writing a serviceable mouse driver that contained a couple of bugs and that would not work with asynchronous I/O. In this month’s column I’ll smooth things out a bit. But first, I think we should take a look at some bugs.
The most obvious one isn’t really a driver bug but a failure to consider certain cases. Imagine that you accidentally bumped this mouse and sent it skittering across your desk. The mouse_read routine in our driver would add up all that movement and report it in steps of ±127 until it reported the entire movement. Clearly, there is a point beyond which mouse movement isn’t really worth reporting, so we’re going to need to add this as a limit to the interrupt handler (Listing One).
By adding these checks we limit the range of accumulated movement to something sensible.
The Subtle Bug
The second bug is a bit more subtle, and that is perhaps why this is such a common mistake when writing kernel drivers. The mouse_read routine has a race condition when testing the mouse event flag. Consider what happens when we execute:
while(!mouse_event) {
and an interrupt occurs just after this point. The interrupt generates a mouse event and wakes up the mouse_read routine. However, the following line in mouse_ read is:
interruptible_sleep_on (&mouse_wait);
which sleeps on the queue, after deciding that…
Please log in to view this content.
Not Yet a Member?
Register with LinuxMagazine.com and get free access to the entire archive, including: