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