STREAMS-UX Programmer's Guide (February 2007)

Modules and Drivers
Entry Points
Chapter 4
71
In the close routine the module or driver should free any resources it allocated in the open path and clear any
pending timeouts or bufcalls. The close routine must take appropriate action for messages still left in the
module or driver queue. For drivers the read-side queue can have messages resulting from device interrupts.
Driver developers need to make sure these messages are handled properly prior to actually closing the driver.
The close routine can sleep at an uninterruptible priority level or with PCATCH set, as it has user context.
Ioctl
The ioctl (2) system call is used for performing I/O control operations on a character device. For traditional
UNIX character I/O devices the IOCTL calls are handled transparently by the kernel, that is, the ioctl calls
on a device are handled by the driver for that device. STREAMS IOCTLs are an addition to the regular UNIX
character input/output mechanism. They differ from the UNIX I/O mechanism in following manner:
A stream may have multiple modules at any point, and each module may define its own IOCTL
commands. Thus, the ioctls that can be used on a Stream can very depending on the modules present on
the stream.
The stream head processes a large number of stream head ioctl commands that are independent of any
module or driver present on the stream. These ioctl commands are described in streamio (7).
When modules and drivers receive information associated with an ioctl, there is no user context
pertaining to the ioctl call as the information is received in the form of a message in the put procedure.
This prevents modules and drivers to perform copyin() or copyout() operations and associate any
kernel data with currently running process.
The most straightforward examples of STREAMS IOCTLs are for commands like I_PUSH and I_POP where
there is no data sharing between user process and a stream. These IOCTLs are Stream Head IOCTLs and are
mainly described in streamio (7). But, for other IOCTLs where the user process needs to share data between
user-space and kernel-space, the I_STR IOCTL and the transparent IOCTL mechanism provide the additional
control. The I_STR IOCTL mechanism uses only a single pair of messages to share the data between
user-space and kernel-space and is described in “I_STR IOCTL Processing” on page 72 section. The
transparent mechanism may use multiple pair of messages to share the data between user-space and
kernel-space as described in Transparent IOCTL Processing” on page 75 section.
General IOCTL Processing
Most of the IOCTL commands described in streamio (7) are processed by the stream head and are not sent
downstream for further processing by a module/driver. Commands that require further processing by a
module or driver and commands unrecognized by the stream head are sent downstream in the form of an
M_IOCTL message, created by the stream head. Each of the module which recognizes the IOCTL command in
the M_IOCTL message must take the required action.
In general, the IOCTL processing requiring an action from a module/driver can be described as follows.
Stream head blocks the user process issuing the ioctl (2) system call, creates the M_IOCTL message and
sends it downstream. The user process remains blocked on the ioctl (2) system call until one of the following
conditions occur:
A module or driver on the stream, recognizes the IOCTL command and responds with a positive
acknowledgement (M_IOCACK message) or a negative acknowledgement (M_IOCNAK message).
The IOCTL request times out.
The user process interrupts the IOCTL request.
An error occurs.