For devices to function properly, the firmware of the device must be compatible with the device driver. You must check the firmware compatibility before installing or upgrading the device driver. The implementation of a device driver must ensure that a device driver is not installed or upgraded if the compatible firmware is not available.
A good device driver design is to encapsulate the firmware in one or more ELF (executable linkable format) modules and use the attach() function to manage the firmware version. To encapsulate a firmware in an ELF module, use the elfwrap(1) command. The firmware ELF modules are linked with a module linkage stub as a misc module. Firmware modules exist in the /kernel/misc directory.
The following flow chart shows the approach to manage the firmware version in the attach() function of the device driver.
Figure 1-1 Managing Firmware Version in the attach() Function
For more information, see the attach (9E) , ddi_modopen (9F) , ddi_modsym (9F) , and ddi_modclose (9F) man pages.
A generic pseudo code of the attach() function that checks for the firmware version is as follows:
static int xxxx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { ..... ddi_modhandle_t modfn; int errno; uint32_t *fwvp; ..... long fw_version; ..... /* Check if firmware update is disabled. * If firmware update is disabled, return. * The setting is stored in a config file. */ if(dip->firmware_disable_update){ return (0); } /* Get the current firmware version. */ fw_version = xxxx_get_firmware_version(dip,...); /* Check if the firmware version is correct and if force update is disabled. */ if(fw_version == REQUIRED_FIRMWARE_VERSION){ if(dip->firmware_force_update == 0){ return (0); } /* Even though the firmware version matches, update is forced. */ } /* Open the firmware file by using ddi_modopen. */ modfn = ddi_modopen(FIRMWARE_FILENAME, KRTLD_MODE_FIRST, &errno); if (errno){ /* handle error */ } /* locate the firmware */ fwvp = ddi_modsym(modfn, FIRMWARE_VERSION_NAME, &errno); if (errno){ /* handle error */ (void) ddi_modclose(modfn); } /* Check if the firmware version in the module is correct. */ if (*fwvp != REQUIRED_FIRMWARE_VERSION){ if(dip->firmware_force_update == 0){ /* close the firmware module file */ (void) ddi_modclose(modfn); return (0); } /* Even tough the firmware version in the module does not match, * update is forced. */ } /* Update the firmware. */ xxx_update_firmware(dip,....); /* Close the FIRMWARE file */ (void) ddi_modclose(modfn); ..... // resume attach }