Specifications

D
evice Driver Programming
17-32
Ensuring that all I/O operations have been completed
This function is especially important for a device that uses DMA because
the process might exit after the close and a pending DMA could over-
write the memory of a different process.
The device identifier allocated by the driver should not be used after the close routine
has been invoked. A user-level device driver has no way to prevent access to the device
after the close call; unauthorized access to the device can produce unexpected results.
You must carefully consider whether the user-level driver handles the occurrence of a
fork(2) system call after a user process has opened a device controlled by the driver. If
a user process were to make a fork(2) system call after opening the device, the child
and the parent processes would share access to the opened device and the user-level
device driver. The reason is that parent and child processes share access to attached shared
memory regions and all of the user-level driver routines. After the call to fork(2), two
processes have access to the device, but it seems to the user-level device driver that only
one process has access. The driver’s close routine is responsible for freeing driver
resources that are allocated to a process that has opened the device. It is very difficult to
determine when these resources can be freed if a process that has opened the device can
subsequently invoke fork(2).
There are two techniques for determining when you can free driver resources. One
technique is to make an IPC_STAT shmctl(2) system call in the driver’s close
routine. The IPC_STAT command allows you to determine how many processes are
associated with the device’s shared memory regions. The other technique is to obtain the
running process’s lightweight process identifier (LWP ID) and compare it with the LWP
ID of the lightweight process that opened the device. (See the
_lwp_global_self(2) system manual page for more information about LWP IDs.
This LWP ID can be stored in the private data area that is described in “Overview of Data
Structures” on page 17-5). It is suggested that you consider limiting access to the device to
the parent process. If you do not design the driver to handle a call to fork(2) after the
device has been opened, it is very important that you provide documentation that warns
users of the consequences.
Specification
int xx_close(dev_desc)
int dev_desc
;
Parameter
dev_desc the identifier for the device for which the close operation is being performed
Return Value
The driver’s close routine returns EUD_NOERROR if the close operation has been success-
fully completed. It returns the appropriate user-level device driver error code if an error
occurs (see “Overview of the Device Configuration Program” on page 17-14 for a listing
of the error codes as defined in <userdriv.h>).