Writing Device Drivers

Layered Driver Handles – Target Devices

Kernel device consumers must use a layered driver handle (ldi_handle_t) to access a target device through LDI interfaces. The ldi_handle_t type is valid only with LDI interfaces. The LDI allocates and returns this handle when the LDI successfully opens a device. A kernel device consumer can then use this handle to access the target device through the LDI interfaces. The LDI deallocates the handle when the LDI closes the device. See LDI Kernel Interfaces Example for an example.

This section discusses how kernel device consumers can access target devices and retrieve different types of information. See Opening and Closing Target Devices to learn how kernel device consumers can open and close target devices. See Accessing Target Devices to learn how kernel device consumers can perform operations such as read, write, strategy, and ioctl on target devices. Retrieving Target Device Information describes interfaces that retrieve target device information such as device open type and device minor name. Retrieving Target Device Property Values describes interfaces that retrieve values and address of target device properties. See Receiving Asynchronous Device Event Notification to learn how kernel device consumers can receive event notification from target devices.

Opening and Closing Target Devices

This section describes the LDI kernel interfaces for opening and closing target devices. The open interfaces take a pointer to a layered driver handle. The open interfaces attempt to open the target device specified by the device number, device ID, or path name. If the open operation is successful, the open interfaces allocate and return a layered driver handle that can be used to access the target device. The close interface closes the target device associated with the specified layered driver handle and then frees the layered driver handle.

ldi_handle_t

Layered driver handle for target device access. An opaque data structure that is returned when a device is successfully opened.

ldi_open_by_dev(9F)

Open the device specified by the dev_t device number parameter.

ldi_open_by_devid(9F)

Open the device specified by the ddi_devid_t device ID parameter. You also must specify the minor node name to open.

ldi_open_by_name(9F)

Open a device by path name. The path name is a null-terminated string in the kernel address space. The path name must be an absolute path, beginning with a forward slash character (/).

ldi_close(9F)

Close a device that was opened with ldi_open_by_dev(9F), ldi_open_by_devid(9F), or ldi_open_by_name(9F). After ldi_close(9F) returns, the layered driver handle of the device that was closed is no longer valid.

Accessing Target Devices

This section describes the LDI kernel interfaces for accessing target devices. These interfaces enable a kernel device consumer to perform operations on the target device specified by the layered driver handle. Kernel device consumers can perform operations such as read, write, strategy, and ioctl on the target device.

ldi_handle_t

Layered driver handle for target device access. An opaque data structure.

ldi_read(9F)

Pass a read request to the device entry point for the target device. This operation is supported for block, character, and STREAMS devices.

ldi_aread(9F)

Pass an asynchronous read request to the device entry point for the target device. This operation is supported for block and character devices.

ldi_write(9F)

Pass a write request to the device entry point for the target device. This operation is supported for block, character, and STREAMS devices.

ldi_awrite(9F)

Pass an asynchronous write request to the device entry point for the target device. This operation is supported for block and character devices.

ldi_strategy(9F)

Pass a strategy request to the device entry point for the target device. This operation is supported for block and character devices.

ldi_dump(9F)

Pass a dump request to the device entry point for the target device. This operation is supported for block and character devices.

ldi_poll(9F)

Pass a poll request to the device entry point for the target device. This operation is supported for block, character, and STREAMS devices.

ldi_ioctl(9F)

Pass an ioctl request to the device entry point for the target device. This operation is supported for block, character, and STREAMS devices. The LDI supports STREAMS linking and STREAMS ioctl commands. See the “STREAM IOCTLS” section of the ldi_ioctl(9F) man page. See also the ioctl commands in the streamio(7I) man page.

ldi_devmap(9F)

Pass a devmap request to the device entry point for the target device. This operation is supported for block and character devices.

ldi_getmsg(9F)

Get a message block from a stream.

ldi_putmsg(9F)

Put a message block on a stream.

Retrieving Target Device Information

This section describes LDI interfaces that kernel device consumers can use to retrieve device information about a specified target device. A target device is specified by a layered driver handle. A kernel device consumer can receive information such as device number, device open type, device ID, device minor name, and device size.

ldi_get_dev(9F)

Get the dev_t device number for the target device specified by the layered driver handle.

ldi_get_otyp(9F)

Get the open flag that was used to open the target device specified by the layered driver handle. This flag tells you whether the target device is a character device or a block device.

ldi_get_devid(9F)

Get the ddi_devid_t device ID for the target device specified by the layered driver handle. Use ddi_devid_free(9F) to free the ddi_devid_t when you are finished using the device ID.

ldi_get_minor_name(9F)

Retrieve a buffer that contains the name of the minor node that was opened for the target device. Use kmem_free(9F) to release the buffer when you are finished using the minor node name.

ldi_get_size(9F)

Retrieve the partition size of the target device specified by the layered driver handle.

Retrieving Target Device Property Values

This section describes LDI interfaces that kernel device consumers can use to retrieve property information about a specified target device. A target device is specified by a layered driver handle. A kernel device consumer can receive values and addresses of properties and determine whether a property exists.

ldi_prop_exists(9F)

Return 1 if the property exists for the target device specified by the layered driver handle. Return 0 if the property does not exist for the specified target device.

ldi_prop_get_int(9F)

Search for an int integer property that is associated with the target device specified by the layered driver handle. If the integer property is found, return the property value.

ldi_prop_get_int64(9F)

Search for an int64_t integer property that is associated with the target device specified by the layered driver handle. If the integer property is found, return the property value.

ldi_prop_lookup_int_array(9F)

Retrieve the address of an int integer array property value for the target device specified by the layered driver handle.

ldi_prop_lookup_int64_array(9F)

Retrieve the address of an int64_t integer array property value for the target device specified by the layered driver handle.

ldi_prop_lookup_string(9F)

Retrieve the address of a null-terminated string property value for the target device specified by the layered driver handle.

ldi_prop_lookup_string_array(9F)

Retrieve the address of an array of strings. The string array is an array of pointers to null-terminated strings of property values for the target device specified by the layered driver handle.

ldi_prop_lookup_byte_array(9F)

Retrieve the address of an array of bytes. The byte array is a property value of the target device specified by the layered driver handle.

Receiving Asynchronous Device Event Notification

The LDI enables kernel device consumers to register for event notification and to receive event notification from target devices. A kernel device consumer can register an event handler that will be called when the event occurs. The kernel device consumer must open a device and receive a layered driver handle before the kernel device consumer can register for event notification with the LDI event notification interfaces.

The LDI event notification interfaces enable a kernel device consumer to specify an event name and to retrieve an associated kernel event cookie. The kernel device consumer can then pass the layered driver handle (ldi_handle_t), the cookie (ddi_eventcookie_t), and the event handler to ldi_add_event_handler(9F) to register for event notification. When registration completes successfully, the kernel device consumer receives a unique LDI event handler identifier (ldi_callback_id_t). The LDI event handler identifier is an opaque type that can be used only with the LDI event notification interfaces.

The LDI provides a framework to register for events generated by other devices. The LDI itself does not define any event types or provide interfaces for generating events.

The following describes the LDI asynchronous event notification interfaces:

ldi_callback_id_t

Event handler identifier. An opaque type.

ldi_get_eventcookie(9F)

Retrieve an event service cookie for the target device specified by the layered driver handle.

ldi_add_event_handler(9F)

Add the callback handler specified by the ldi_callback_id_t registration identifier. The callback handler is invoked when the event specified by the ddi_eventcookie_t cookie occurs.

ldi_remove_event_handler(9F)

Remove the callback handler specified by the ldi_callback_id_t registration identifier.