[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10. Device Interface

The GNU Mach microkernel provides a simple device interface that allows the user space programs to access the underlying hardware devices. Each device has a unique name, which is a string up to 127 characters long. To open a device, the device master port has to be supplied. The device master port is only available through the bootstrap port. Anyone who has control over the device master port can use all hardware devices.

Data type: device_t
This is a mach_port_t and used to hold the port name of a device port that represents the device. Operations on the device are implemented as remote procedure calls to the device port. Each device provides a sequence of records. The length of a record is specific to the device. Data can be transferred "out-of-line" or "in-line" (see section 4.2.4 Memory).

All constants and functions in this chapter are defined in `device/device.h'.

10.1 Device Reply Server  Handling device reply messages.
10.2 Device Open  Opening hardware devices.
10.3 Device Close  Closing hardware devices.
10.4 Device Read  Reading data from the device.
10.5 Device Write  Writing data to the device.
10.6 Device Map  Mapping devices into virtual memory.
10.7 Device Status  Querying and manipulating a device.
10.8 Device Filter  Filtering packets arriving on a device.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.1 Device Reply Server

Beside the usual synchronous interface, an asynchronous interface is provided. For this, the caller has to receive and handle the reply messages seperately from the function call.

Function: boolean_t device_reply_server (msg_header_t *in_msg, msg_header_t *out_msg)
The function device_reply_server is produced by the remote procedure call generator to handle a received message. This function does all necessary argument handling, and actually calls one of the following functions: ds_device_open_reply, ds_device_read_reply, ds_device_read_reply_inband, ds_device_write_reply and ds_device_write_reply_inband.

The in_msg argument is the message that has been received from the kernel. The out_msg is a reply message, but this is not used for this server.

The function returns TRUE to indicate that the message in question was applicable to this interface, and that the appropriate routine was called to interpret the message. It returns FALSE to indicate that the message did not apply to this interface, and that no other action was taken.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.2 Device Open

Function: kern_return_t device_open (mach_port_t master_port, dev_mode_t mode, dev_name_t name, device_t *device)
The function device_open opens the device name and returns a port to it in device. The open count for the device is incremented by one. If the open count was 0, the open handler for the device is invoked.

master_port must hold the master device port. name specifies the device to open, and is a string up to 128 characters long. mode is the open mode. It is a bitwise-or of the following constants:

D_READ
Request read access for the device.

D_WRITE
Request write access for the device.

D_NODELAY
Do not delay an open.

The function returns D_SUCCESS if the device was successfully opened, D_INVALID_OPERATION if master_port is not the master device port, D_WOULD_BLOCK is the device is busy and D_NOWAIT was specified in mode, D_ALREADY_OPEN if the device is already open in an incompatible mode and D_NO_SUCH_DEVICE if name does not denote a know device.

Function: kern_return_t device_open_request (mach_port_t master_port, mach_port_t reply_port, dev_mode_t mode, dev_name_t name)
Function: kern_return_t ds_device_open_reply (mach_port_t reply_port, kern_return_t return, device_t *device)
This is the asynchronous form of the device_open function. device_open_request performs the open request. The meaning for the parameters is as in device_open. Additionally, the caller has to supply a reply port to which the ds_device_open_reply message is sent by the kernel when the open has been performed. The return value of the open operation is stored in return_code.

As neither function receives a reply message, only message transmission errors apply. If no error occurs, KERN_SUCCESS is returned.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.3 Device Close

Function: kern_return_t device_close (device_t device)
The function device_close decrements the open count of the device by one. If the open count drops to zero, the close handler for the device is called. The device to close is specified by its port device.

The function returns D_SUCCESS if the device was successfully closed and D_NO_SUCH_DEVICE if device does not denote a device port.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.4 Device Read

Function: kern_return_t device_read (device_t device, dev_mode_t mode, recnum_t recnum, int bytes_wanted, io_buf_ptr_t *data, mach_msg_type_number_t *data_count)
The function device_read reads bytes_wanted bytes from device, and stores them in a buffer allocated with vm_allocate, which address is returned in data. The caller must deallocated it if it is no longer needed. The number of bytes actually returned is stored in data_count.

If mode is D_NOWAIT, the operation does not block. Otherwise mode should be 0. recnum is the record number to be read, its meaning is device specific.

The function returns D_SUCCESS if some data was successfully read, D_WOULD_BLOCK if no data is currently available and D_NOWAIT is specified, and D_NO_SUCH_DEVICE if device does not denote a device port.

Function: kern_return_t device_read_inband (device_t device, dev_mode_t mode, recnum_t recnum, int bytes_wanted, io_buf_ptr_inband_t *data, mach_msg_type_number_t *data_count)
The device_read_inband function works as the device_read function, except that the data is returned "in-line" in the reply IPC message (see section 4.2.4 Memory).

Function: kern_return_t device_read_request (device_t device, mach_port_t reply_port, dev_mode_t mode, recnum_t recnum, int bytes_wanted)
Function: kern_return_t ds_device_read_reply (mach_port_t reply_port, kern_return_t return_code, io_buf_ptr_t data, mach_msg_type_number_t data_count)
This is the asynchronous form of the device_read function. device_read_request performs the read request. The meaning for the parameters is as in device_read. Additionally, the caller has to supply a reply port to which the ds_device_read_reply message is sent by the kernel when the read has been performed. The return value of the read operation is stored in return_code.

As neither function receives a reply message, only message transmission errors apply. If no error occurs, KERN_SUCCESS is returned.

Function: kern_return_t device_read_request_inband (device_t device, mach_port_t reply_port, dev_mode_t mode, recnum_t recnum, int bytes_wanted)
Function: kern_return_t ds_device_read_reply_inband (mach_port_t reply_port, kern_return_t return_code, io_buf_ptr_t data, mach_msg_type_number_t data_count)
The device_read_request_inband and ds_device_read_reply_inband functions work as the device_read_request and ds_device_read_reply functions, except that the data is returned "in-line" in the reply IPC message (see section 4.2.4 Memory).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.5 Device Write

Function: kern_return_t device_write (device_t device, dev_mode_t mode, recnum_t recnum, io_buf_ptr_t data, mach_msg_type_number_t data_count, int *bytes_written)
The function device_write writes data_count bytes from the buffer data to device. The number of bytes actually written is returned in bytes_written.

If mode is D_NOWAIT, the function returns without waiting for I/O completion. Otherwise mode should be 0. recnum is the record number to be written, its meaning is device specific.

The function returns D_SUCCESS if some data was successfully written and D_NO_SUCH_DEVICE if device does not denote a device port or the device is dead or not completely open.

Function: kern_return_t device_write_inband (device_t device, dev_mode_t mode, recnum_t recnum, int bytes_wanted, io_buf_ptr_inband_t *data, mach_msg_type_number_t *data_count)
The device_write_inband function works as the device_write function, except that the data is sent "in-line" in the request IPC message (see section 4.2.4 Memory).

Function: kern_return_t device_write_request (device_t device, mach_port_t reply_port, dev_mode_t mode, recnum_t recnum, io_buf_ptr_t data, mach_msg_type_number_t data_count)
Function: kern_return_t ds_device_write_reply (mach_port_t reply_port, kern_return_t return_code, int bytes_written)
This is the asynchronous form of the device_write function. device_write_request performs the write request. The meaning for the parameters is as in device_write. Additionally, the caller has to supply a reply port to which the ds_device_write_reply message is sent by the kernel when the write has been performed. The return value of the write operation is stored in return_code.

As neither function receives a reply message, only message transmission errors apply. If no error occurs, KERN_SUCCESS is returned.

Function: kern_return_t device_write_request_inband (device_t device, mach_port_t reply_port, dev_mode_t mode, recnum_t recnum, io_buf_ptr_t data, mach_msg_type_number_t data_count)
Function: kern_return_t ds_device_write_reply_inband (mach_port_t reply_port, kern_return_t return_code, int bytes_written)
The device_write_request_inband and ds_device_write_reply_inband functions work as the device_write_request and ds_device_write_reply functions, except that the data is sent "in-line" in the request IPC message (see section 4.2.4 Memory).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.6 Device Map

Function: kern_return_t device_map (device_t device, vm_prot_t prot, vm_offset_t offset, vm_size_t size, mach_port_t *pager, int unmap)
The function device_map creates a new memory manager for device and returns a port to it in pager. The memory manager is usable as a memory object in a vm_map call. The call is device dependant.

The protection for the memory object is specified by prot. The memory object starts at offset within the device and extends size bytes. unmap is currently unused.

The function returns D_SUCCESS if some data was successfully written and D_NO_SUCH_DEVICE if device does not denote a device port or the device is dead or not completely open.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.7 Device Status

Function: kern_return_t device_set_status (device_t device, dev_flavor_t flavor, dev_status_t status, mach_msg_type_number_t status_count)
The function device_set_status sets the status of a device. The possible values for flavor and their interpretation is device specific.

The function returns D_SUCCESS if some data was successfully written and D_NO_SUCH_DEVICE if device does not denote a device port or the device is dead or not completely open.

Function: kern_return_t device_get_status (device_t device, dev_flavor_t flavor, dev_status_t status, mach_msg_type_number_t *status_count)
The function device_get_status gets the status of a device. The possible values for flavor and their interpretation is device specific.

The function returns D_SUCCESS if some data was successfully written and D_NO_SUCH_DEVICE if device does not denote a device port or the device is dead or not completely open.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.8 Device Filter

Function: kern_return_t device_set_filter (device_t device, mach_port_t receive_port, mach_msg_type_name_t receive_port_type, int priority, filter_array_t filter, mach_msg_type_number_t filter_count)
The function device_set_filter makes it possible to filter out selected data arriving at the device and forward it to a port. filter is a list of filter commands, which are applied to incoming data to determine if the data should be sent to receive_port. The IPC type of the send right is specified by receive_port_right, it is either MACH_MSG_TYPE_MAKE_SEND or MACH_MSG_TYPE_MOVE_SEND. The priority value is used to order multiple filters.

There can be up to NET_MAX_FILTER commands in filter. The actual number of commands is passed in filter_count. For the purpose of the filter test, an internal stack is provided. After all commands have been processed, the value on the top of the stack determines if the data is forwarded or the next filter is tried.

Each word of the command list specifies a data (push) operation (high order NETF_NBPO bits) as well as a binary operator (low order NETF_NBPA bits). The value to be pushed onto the stack is chosen as follows.

NETF_PUSHLIT
Use the next short word of the filter as the value.

NETF_PUSHZERO
Use 0 as the value.

NETF_PUSHWORD+N
Use short word N of the "data" portion of the message as the value.

NETF_PUSHHDR+N
Use short word N of the "header" portion of the message as the value.

NETF_PUSHIND+N
Pops the top long word from the stack and then uses short word N of the "data" portion of the message as the value.

NETF_PUSHHDRIND+N
Pops the top long word from the stack and then uses short word N of the "header" portion of the message as the value.

NETF_PUSHSTK+N
Use long word N of the stack (where the top of stack is long word 0) as the value.

NETF_NOPUSH
Don't push a value.

The unsigned value so chosen is promoted to a long word before being pushed. Once a value is pushed (except for the case of NETF_NOPUSH), the top two long words of the stack are popped and a binary operator applied to them (with the old top of stack as the second operand). The result of the operator is pushed on the stack. These operators are:

NETF_NOP
Don't pop off any values and do no operation.

NETF_EQ
Perform an equal comparison.

NETF_LT
Perform a less than comparison.

NETF_LE
Perform a less than or equal comparison.

NETF_GT
Perform a greater than comparison.

NETF_GE
Perform a greater than or equal comparison.

NETF_AND
Perform a bitise boolean AND operation.

NETF_OR
Perform a bitise boolean inclusive OR operation.

NETF_XOR
Perform a bitise boolean exclusive OR operation.

NETF_NEQ
Perform a not equal comparison.

NETF_LSH
Perform a left shift operation.

NETF_RSH
Perform a right shift operation.

NETF_ADD
Perform an addition.

NETF_SUB
Perform a subtraction.

NETF_COR
Perform an equal comparison. If the comparison is TRUE, terminate the filter list. Otherwise, pop the result of the comparison off the stack.

NETF_CAND
Perform an equal comparison. If the comparison is FALSE, terminate the filter list. Otherwise, pop the result of the comparison off the stack.

NETF_CNOR
Perform a not equal comparison. If the comparison is FALSE, terminate the filter list. Otherwise, pop the result of the comparison off the stack.

NETF_CNAND
Perform a not equal comparison. If the comparison is TRUE, terminate the filter list. Otherwise, pop the result of the comparison off the stack. The scan of the filter list terminates when the filter list is emptied, or a NETF_C... operation terminates the list. At this time, if the final value of the top of the stack is TRUE, then the message is accepted for the filter.

The function returns D_SUCCESS if some data was successfully written, D_INVALID_OPERATION if receive_port is not a valid send right, and D_NO_SUCH_DEVICE if device does not denote a device port or the device is dead or not completely open.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Alfred M. Szmidt on January, 22 2005 using texi2html