Subject: Advice about network driver needed
To: None <tech-kern@netbsd.org>
From: Lennart Augustsson <lennart@augustsson.net>
List: tech-kern
Date: 12/26/1999 01:20:58
I'm looking at a driver for a USB Ethernet adapter (with the ADMtek Pegasus chip).
In principle the chip looks quite straightforward to handle, but there is a big snag.

It seems that in network drivers most of the processing happens in interrupt routines;
a receiver interrupt to deliver a packet up, a transmitter interrupt to send the next one,
the watchdog routine to reset the chip etc.
All these routines need to access registers in the chip, and here comes the problem.  You
cannot easily access the registers.  An access to a chip register requires a USB bus
transaction, but these take a long time and need to use tsleep() (which is banned in
interrupt context).
So there are several ways to handle this:
 * Use delay() instead of tsleep().  This is totally unacceptable, since it would make the
   driver busy-wait for about 1 ms.  (FYI, the FreeBSD driver does this.)
 * Use a state machine (which can be coded in many ways).  This means that a register access
   will now be a two step operation: start the access and call a completion routine to
   do the rest of the job.  This is quite tedious.. :(
 * Use a kernel thread for driver.  The interrupt routine would then just wake up the
   kernel thread and have it complete the operation.  The problem with this is that
   I think you need at least two threads for the driver to avoid deadlock.  This seems
   excessive.  :(

So, what do all of you kernel hackers think?  State machine or kernel threads?

        -- Lennart
PS. Merry Christmas!