During today's PSARC meeting, we talked about best practices.  One of 
the ones that seemed pretty stale and incomplete was the one for device 
drivers (see 
http://www.opensolaris.org/os/community/arc/bestpractices/bp-device-drivers/ 
)

So I've undertaken to write a replacement.  Here's a draft.  Note that 
this is not in the format for BPs.  We can correct that later -- mostly 
I want to offer this up for a general review/comment/feedback at this 
point, and once we have the content mostly stable, I'll submit a new 
case for it.

So, here's what I have.  Some of the items listed below may never have 
been expressed in any other document before:

Device Drivers Best Practices
-----------------------------

1.  DDI conformance.  Device drivers for bundled device drivers SHOULD
    adhere to the documented DDI, using only header files, functions, 
macros,
    structures, and fields that are documented.  Note that this precludes
    taking the sizeof() certain structures (struct msgb, struct datab, 
struct
    buf) which are intended to be dynamically allocated.  Unbundled device
    drivers MUST adhere to the documented DDI, or obtain contracts for any
    exceptions required.

2.  Proper use of bus/device type specific APIs where applicable.  Drivers
    SHOULD, when possible, use the latest driver frameworks for certain
    types of driver, rather than reimplementing common functionality.  For
    example, NIC drivers should use the GLD, and SCSI drivers should use the
    SCSA framework and USB drivers should use the USB framework.

3.  Independence from firmware initialization.  Device drivers should not
    depend on firmware to initialize devices.  While certain portions of
    the device may be initialized by OS or BIOS (assignment of PCI
    addresses to BARs for example), device drivers should not rely on
    firmware to perform any device specific initialization.

4.  Support for DDI_SUSPEND and DDI_RESUME.  Device drivers must properly
    support DDI_SUSPEND and DDI_RESUME, including dealing with a potential
    loss of power in between.  Note that system firmware may not execute
    on resume, so adherence to #3 above will help greatly.  Pseudo-drivers
    generally don't have to worry about this, and certain kinds of hardware
    drivers may be able to rely on their bus parents to properly shutdown
    the device.

5.  Support for quiesce(9e).  In order to facilitate fast-reboot, 
drivers should
    support the quiesce(9e) DDI entry point.  (Not applicable to Solaris 
10 or
    earlier.)

6.  Support for power management.  If possible, devices should support
    fine grained power management to reduce overall power consumption on
    the platform.  See power(9e).

7.  Portability.  Device drivers should avoid assumptions about the
    platform they are to run on.  A driver should be coded to operate
    properly on either SPARC or x86 CPUs.  Drivers should not make 
assumptions
    about the cache, endian, or word size attributes of the host 
platform, and
    proerly make use of Solaris interfaces such as ddi_dma_sync(9f),
    ddi_get32(9f), etc.

8.  MP safety.  All device drivers must be MP-hot.  That is, they must 
assume
    that entry points and interrupts can all run synchronously, and make use
    of synchronization guards (mutex_enter(9f) or similar) to ensure correct
    operation.

9.  Fault tolerance.  Device drivers MUST NEVER panic in response to bad
    data received from a source outside of the kernel address space.  That
    means that data received from a physical device (disk, network, etc.)
    must be validated before used in the kernel, as well as data that comes
    from user-space.  Device drivers should use watchdogs or similar to 
guard
    against device failure.  Device drivers should make use of FMA 
interfaces
    to handle and report fault conditions.

10. Userland interaction.  Device drivers that interact with userland must
    be able to deal with either 32-bit or 64-bit applications, performing
    any word size conversions as necessary.   (Note that no conversion is
    necessary when the kernel is running in 32-bit mode.)  See
    ddi_get_model(9F).

11. Avoiding polling.  Drivers should avoid polling whenever possible,
    particularly in long running situations.  Polling prevents the CPU
    from reaching idle state, and increases power consumption for the
    entire platform.

12. Do not depend on the system clock rate.  The value of HZ can be 
different
    across reboots.  drv_usectohz(9f) can be used if an absolute time is
    required.

13. Minimize time running in interrupt context.  This is a general guideline
    for all device drivers.

14. Avoid use of custom tracing or debugging facilities.  Use DTrace
    instead.

15. Observability.  Drivers SHOULD properly report their operation via
    the appropriate kstat(9s)'s for their driver type.  This includes
    correct accounting of I/O times (kstat_io(9s)) and interrupts
    (kstat_intr(9s)).

16. Proper support for dynamic loading & unloading.  Device drivers must
    support being modunload(1M)'ed through correct support for _fini(9e).
    This also means that drivers must support detach(9e) properly.

17. Proper support for hotplug where applicable.  A driver for a removable
    system peripheral must support hot insertion and removal.  Via
    attach(9e) and detach(9e).  Note that PCI and PCI express busses are
    hotpluggable on some platforms.





_______________________________________________
driver-discuss mailing list
driver-discuss@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/driver-discuss

Reply via email to