Device Driver Tutorial

Defining the Module Unload Entry Point

The _fini(9E) routine returns type int and takes no arguments. The _fini(9E) routine must call the mod_remove(9F) function and return the success or failure value that is returned by mod_remove(9F).

When mod_remove(9F) is successful, the _fini(9E) routine must undo everything that the _init(9E) routine did. The _fini(9E) routine must call mod_remove(9F) because the _init(9E) routine called mod_install(9F). The _fini(9E) routine must deallocate anything that was allocated, close anything that was opened, and destroy anything that was created in the _init(9E) routine.

The _fini(9E) routine can be called at any time when a module is loaded. In normal operation, the _fini(9E) routine often fails. This behavior is normal because the kernel allows the module to determine whether the module can be unloaded. If mod_remove(9F) is successful, the module determines that devices were detached, and the module can be unloaded. If mod_remove(9F) fails, the module determines that devices were not detached, and the module cannot be unloaded.

The following actions take place when mod_remove(9F) is called:

The mod_remove(9F) function takes an argument that is a modlinkage(9S) structure. See Defining the Module Linkage Structures for information about the modlinkage(9S) structure.

Use the cmn_err(9F) function to write a message to the system log in the same way that you used the cmn_err(9F) function in your _init(9E) entry point.

The following code is the _fini(9E) routine that you should enter into your dummy.c file. The ml structure is discussed in Defining the Module Linkage Structures.

int
_fini(void)
{
    cmn_err(CE_NOTE, "Inside _fini");
    return(mod_remove(&ml));
}