The qotd_detach() routine is almost all new. The qotd_detach() routine must first get the soft state because the qotd_detach() routine needs to check the flags member of the state structure.
The first flag the qotd_detach() routine checks is the QOTD_CHANGED flag. The QOTD_CHANGED flag indicates whether the device is in the initial state. The QOTD_CHANGED flag is set in the qotd_rw() routine and in the qotd_ioctl() entry point. The QOTD_CHANGED flag is set any time the user does anything to the device other than simply inspect the device. If the QOTD_CHANGED flag is set, the size or content of the storage buffer has been modified. See Writing New Data for more information on the QOTD_CHANGED flag. When the QOTD_CHANGED flag is set, the detach operation fails because the device might contain data that is valuable to the user and the device should not be removed. If the QOTD_CHANGED flag is set, the qotd_detach() routine returns an error that the device is busy.
Once the quotation has been modified, the device cannot be detached until the user runs the qotdctl command with the -r option. The -r option reinitializes the quotation and indicates that the user is no longer interested in the contents of the device. See Exercising the Driver's I/O Controls for more information about the qotdctl command.
The qotd_detach() routine then checks the four flags that were set in the qotd_attach() routine. If the QOTD_DIDCV flag is set, the qotd_detach() routine calls the cv_destroy(9F) function. If the QOTD_DIDMUTEX flag is set, the qotd_detach() routine calls the mutex_destroy(9F) function. If the QOTD_DIDALLOC flag is set, the qotd_detach() routine calls the ddi_umem_free(9F) function. Finally, if the QOTD_DIDMINOR flag is set, the qotd_detach() routine calls the ddi_remove_minor_node(9F) function.