Driver Programming Interface - Which way to go?

David Olofson (audiality@swipnet.se)
Thu, 05 Aug 1999 04:11:17 +0200


Hi!

Working on my driver programming interface, but I'm not sure what is the
best way to implement it. Runtime or compile time RT/standard switching?
Would like some comments on the different ways to do this.

The problem
-----------
Drivers need spinlocks, waitqueues, copy_to/from_user etc, which means
serious trouble if a driver should be executed in a context that
preempts the kernel. (Which is what RTLinux tasks and interrupt handlers
do.) I've modified the es1370 driver to use RTL safe sync and waitqueues
to work as a standard driver with an RTL interrupt handler, and moving
it entirely to RTL is no big deal.

However, my idea of using the same binary code and automatically running
the drivers under RTLinux or Linux respectively, complicates things a
bit. My current hack detects the current context automatically for each
call, which isn't exactly efficient when there's lots of little kernel
calls and macros all over the place...

The solution
------------
Basically, there are 3 ways to do it (unless I'm missing something
useful):

1) Fully automatic context detection
(Drivers are "ported" by little more than search/replace to use the
new
functions rather than the standard Linux calls.)
+ Sync works transparently across Linux and RTLinux
+ Easy driver conversion - little more than search/replace
+ Same binary code transparently reusable for both RT and "normal"
mode
- Overhead for context detection

2) Semi automatic context detection
(Drivers have to detect and remember the context in which they are
opened,
and then use the sync function call table specified by the driver
API.)
+ Sync works across Linux and RTLinux
+ Call through function pointers instead of conditionals
+ Drivers may be optimized by selecting irq handlers and file op
callbacks
WRT the context in which they are used.
- Driver code has to keep track of context
- Optimization of drivers means more code

3) No context detection - compile time selection
(Drivers are configured to compile as RT or standard drivers. RT
drivers
can be used by "standard" Linux through an RT<->non RT interface.)
+ No context check overhead for sync calls
+ Easy driver conversion - little more than search/replace
+ Overhead only for RT drivers used from standard Linux
+ Optimizations for RT/standard can be selected at compile time
- RT drivers are always RT drivers, even when used by non RT tasks
- RT/standard cannot be switched without a recompile of the driver

IMHO, 2) has no significant advantage over 1) and 3), while adding
complexity to the driver code, which is a Bad Thing (TM), so it's ruled
out right away.

My current hack is based on 1), but after seeing the amount of extra
code for all kernel calls used by converted drivers, I think 3) looks
like a better alternative. 1) looks nice and sexy from the driver code
POV, makes it very easy to convert drivers, and lets them run
transparently across Linux and RTLinux. But I don't like the overhead of
the context checks...

And 3) has the only significant drawback of requiring a recompile of the
driver to keep it off RTLinux when not needed for RT (which can be
worked around [when using modules] by always compiling RT capable
drivers in two versions - RT and normal), so I think it's a viable
alternative. (Another way would be to include/load both versions and
select the right one depending on who's opening the device.)

Comments? Better ideas?

//David

-
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/