The qotd_attach() entry point first allocates and gets the device soft state. The qotd_attach() routine then creates a minor node. All of this code is the same as in Version 2 of the Quote Of The Day driver. If the call to ddi_create_minor_node(9F) is successful, the qotd_attach() routine sets the QOTD_DIDMINOR flag in the new flags member of the qotd_state state structure.
Version 3 of the Quote Of The Day driver defines four new constants that keep track of four different events. A routine can test these flags to determine whether to deallocate, close, or remove resources. All four of these flags are set in the qotd_attach() entry point. All four of these conditions are checked in the qotd_detach() entry point, and the appropriate action is taken for each condition.
Note that operations are undone in the qotd_detach() entry point in the opposite order in which they were done in the qotd_attach() entry point. The qotd_attach() routine creates a minor node, allocates memory for the quotation, initializes a mutex, and initializes a condition variable. The qotd_detach() routine destroys the condition variable, destroys the mutex, frees the memory, and removes the minor node.
After the minor node is created, the qotd_attach() routine allocates memory for the quotation. For information on allocating and freeing memory in this driver, see Allocating and Freeing Kernel Memory. If memory is allocated, the qotd_attach() routine sets the QOTD_DIDALLOC flag in the flags member of the state structure.
The qotd_attach() routine then calls the mutex_init(9F) function to initialize a mutex. If this operation is successful, the qotd_attach() routine sets the QOTD_DIDMUTEX flag. The qotd_attach() routine then calls the cv_init(9F) function to initialize a condition variable. If this operation is successful, the qotd_attach() routine sets the QOTD_DIDCV flag.
The qotd_attach() routine then calls the strlcpy(9F) function to copy the initial quotation string to the new quotation member of the device state structure. Note that the strlcpy(9F) function is used instead of the strncpy(9F) function. The strncpy(9F) function can be wasteful because it always copies n characters, even if the destination is smaller than n characters. Try using strncpy(9F) instead of strlcpy(9F) and note the difference in the behavior of the driver.
Finally, the initial quotation length is copied to the new quotation length member of the state structure. The remainder of the qotd_attach() routine is the same as in Version 2.