Go to the first, previous, next, last section, table of contents.
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.
For each device opened, a port is created that represants 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-band" or "inband".
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.
device_reply_server
is produced by the
remote procedure call generator to 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.
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
D_WRITE
D_NODELAY
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.
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.
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.
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.
device_read_inband
function works as the device_read
function, except that the data is returned "inband" in the reply IPC
message.
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.
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 "inband" in the reply IPC message.
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.
device_write_inband
function works as the device_write
function, except that the data is sent "inband" in the request IPC
message.
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.
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 "inband" in the request IPC message.
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.
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.
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.
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
NETF_PUSHZERO
NETF_PUSHWORD+N
NETF_PUSHHDR+N
NETF_PUSHIND+N
NETF_PUSHHDRIND+N
NETF_PUSHSTK+N
NETF_NOPUSH
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
NETF_EQ
NETF_LT
NETF_LE
NETF_GT
NETF_GE
NETF_AND
NETF_OR
NETF_XOR
NETF_NEQ
NETF_LSH
NETF_RSH
NETF_ADD
NETF_SUB
NETF_COR
TRUE
, terminate
the filter list. Otherwise, pop the result of the comparison off the
stack.
NETF_CAND
FALSE
,
terminate the filter list. Otherwise, pop the result of the comparison
off the stack.
NETF_CNOR
FALSE
,
terminate the filter list. Otherwise, pop the result of the comparison
off the stack.
NETF_CNAND
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.
Go to the first, previous, next, last section, table of contents.