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 kernel checks whether this driver is busy. This driver is busy if one of the following conditions is true:
A device node that is managed by this driver is open.
Another module that depends on this driver is open. A module depends on this driver if the module was linked using the -N option with this driver named as the argument to that -N option. See the ld(1) man page for more information.
If the driver is busy, then mod_remove(9F) fails and _fini(9E) fails.
If the driver is not busy, then the kernel calls the detach(9E) entry point of the driver.
If detach(9E) fails, then mod_remove(9F) fails and _fini(9E) fails.
If detach(9E) succeeds, then mod_remove(9F) succeeds, and _fini(9E) continues its cleanup work.
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)); }