[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


2    Kernel Interfaces, ioctls, and Global Variables That Device Drivers Use

This chapter describes:


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


2.1    Conventions

The following sections describe:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


2.1.1    Conventions for Kernel Interfaces

The descriptions of the kernel interfaces are presented in alphabetical order and in reference-page style. The descriptions can include the following sections.


Name

This section lists the name of the kernel interface, along with a summary description of its purpose. In general, there is one interface described for each reference page. However, in some cases it makes sense to describe more than one interface on the same page if the interfaces are related. When this occurs, this section lists the names of all the interfaces it describes.


Synopsis

This section shows the kernel interface function definition. The style used is that of the function definition, not the function call. This book assumes that you understand how to interpret the function definition and how to write an appropriate call for a specific interface. The following example shows these conventions:

int copyin (user_src, kernel_dest, bcount)
caddr_t user_src;
caddr_t kernel_dest;
u_int bcount;

The kernel interface function definition gives you the following information:

This book uses the word kernel ``interface'' instead of kernel ``routine'' or kernel ``macro.''


Arguments

This section provides descriptions for the arguments associated with a given kernel interface. In most cases, argument descriptions begin with the word specifies to indicate that you pass the argument (with some specified value) to the kernel interface. If the type of the argument appears as a void *, the argument description states that you must define the type.


Description

This section contains explanations of the tasks performed by the kernel interface.


Notes

This section discusses information that falls into the following categories:


Cautions

This section provides information of particular importance when you use the kernel interface. In many cases, the text in this section alerts you to anything that might cause a panic.


Example

This section provides the section where you can find an example of the kernel interface.


Errors

This section provides the possible error constants a given kernel interface can return, along with a short description of the error.


Side Effects

This section describes special processing performed by the kernel interface. For example, the Side Effects section for the uiomove kernel interface describes the members of the uio structure that it can update.


Return Values

This section describes the return values that a given kernel interface can return. In most cases, if the kernel interface returns an error value, this value is described in the Return Values section.


Related Information

This section lists related kernel interfaces, structures, system calls, and so forth.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


2.1.2    Conventions for ioctl Commands

The description of ioctl commands and interfaces (macros) are presented in reference-page style. The description can include the following sections.


Name

This section lists the name of the ioctl command or interface, along with a summary description of its purpose.


Synopsis

For ioctl commands, this section lists the associated header files. For ioctl interfaces, this section shows the interface definition. For example: #include <sys/ioctl.h>

_IO (g, n)
The interface definition shows the header file where the ioctl interface is defined. The definition also shows the arguments passed to the interface.


Arguments

This section provides descriptions for the arguments associated with a given ioctl interface. In most cases, argument descriptions begin with the word specifies to indicate that you pass the argument (with some specified value) to the ioctl interface.


Description

This section describes ioctl commands or interfaces. The description could include information on associated structures and members.


Example

This section provides an example showing how to construct a driver-specific interface that uses the specified ioctl interface.


Related Information

This section lists related kernel interfaces, structures, system calls, and so forth.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


2.1.3    Conventions for Global Variables

The descriptions of the global variables are presented in alphabetical order and in reference-page style. The descriptions can include the following sections.


Name

This section lists the name of the global variable, along with a short description of its purpose.


Synopsis

This section provides the declaration of the global variable.


Location

This section presents the pathname for the header file that defines the global variable.


Description

This section describes the purpose of the global variable.


Notes

This section discusses information about the global variable pertinent to the device driver writer.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


2.2    Kernel Support Interfaces

Table 2-1 summarizes the kernel interfaces that nonSTREAMS device drivers can use.

Note

Device drivers use the following header files most frequently:

#include <sys/types.h>
#include <sys/errno.h>
#include <io/common/devdriver.h>
#include <sys/uio.h>
#include <machine/cpu.h>
#include <sys/conf.h>
#include <sys/sysconfig.h>

Table 2-1: Summary Descriptions of Kernel Support Interfaces

Kernel Interface Summary Description
assert_wait_mesg Asserts that the current kernel thread is about to block (sleep).
atoi Converts an ASCII string to an integer.
BADADDR Probes the address during device autoconfiguration.
bcmp Compares two byte strings.
bcopy Copies a series of bytes with a specified limit.
biodone Indicates that block I/O is complete.
blkclr Zeros a block of memory.
brelse Deallocates a buf structure.
btop Converts bytes to number of pages.
BUF_LOCK Locks the specified I/O buffer.
BUF_UNLOCK Unlocks the specified I/O buffer.
busphys_to_iohandle Converts a valid bus physical address to an I/O handle base.
bzero Zeros a block of memory.
cfgmgr_get_state Determines the configuration state.
cfgmgr_set_status Reports failure to the cfgmgr framework.
clear_wait Clears the wait condition.
configure_driver Configures a device driver that is in the dynamic state.
contig_free Frees a block of memory previously allocated by contig_malloc.
contig_malloc Allocates physically contiguous memory.
copyin Copies data from a user address space to a kernel address space.
copyinstr Copies a null-terminated string from a user address space to a kernel address space.
copyout Copies data from a kernel address space to a user address space.
copyoutstr Copies a null-terminated string from a kernel address space to a user address space.
copystr Copies a null-terminated character string with a specified limit.
copy_to_phys Copies data from a virtual address to a physical address.
create_controller_struct Creates a controller structure for the system (hardware) configuration tree.
create_device_struct Creates a device structure for the system (hardware) configuration tree.
current_task Returns a pointer to the task structure associated with the currently running kernel thread.
current_thread Is a pointer to the currently running kernel thread.
decl_simple_lock_data Declares a simple lock structure.
DELAY Delays the calling interface a specified number of microseconds.
devsw_add Registers driver entry points and reserves a major number.
devsw_del Clears entry points from the device switch table.
devsw_get Obtains a previously reserved major number.
dma_get_curr_sgentry Returns a pointer to the current sg_entry.
dma_get_next_sgentry Returns a pointer to the next sg_entry.
dma_get_private Gets a data element from the DMA private storage space.
dma_kmap_buffer Returns a kernel segment (kseg) address of a DMA buffer.
dma_map_alloc Allocates resources for DMA data transfers.
dma_map_dealloc Releases and deallocates the DMA resources previously allocated for DMA data transfers.
dma_map_load Loads and sets allocated DMA resources and sets up a DMA data path for DMA data transfers.
dma_map_unload Unloads the system DMA resources.
dma_min_boundary Returns system-level information.
dma_put_curr_sgentry Puts a new bus address/byte count pair in the linked list of sg_entry structures.
dma_put_prev_sgentry Updates an internal pointer index to the linked list of sg_entry structures.
dma_put_private Stores a data element in the DMA private storage space.
do_config Initializes the device to its assigned configuration.
drvr_register_flush Registers or deregisters a flush interface.
drvr_register_shutdown Registers or deregisters a shutdown interface.
ffs Finds the first set bit in a mask.
FREE Deallocates (frees) the allocated kernel virtual memory.
fubyte Returns a byte from user address space.
fuibyte Returns a byte from user instruction address space.
fuiword Returns a word from user instruction address space.
fuword Returns a word from user instruction address space.
get_config Returns assigned configuration data for a device.
get_def_partitionmap Calculates a default partition map.
get_info Returns system-specific information.
getnewbuf Allocates a buf structure.
gsignal Sends a signal to a process group.
handler_add Registers a device driver's interrupt handler.
handler_del Deregisters a device driver's interrupt handler.
handler_disable Disables a previously registered interrupt handler.
handler_enable Enables a previously registered interrupt handler.
htonl Converts longword values from host-to-network byte order.
htons Converts word values from host-to-network byte order.
insque Adds an element to the queue.
io_copyin Copies data from bus address space to system memory.
io_copyio Copies data from bus address space to bus address space.
io_copyout Copies data from system memory to bus address space.
iodone Indicates that I/O is complete.
iohandle_to_phys Converts an I/O handle to a valid system physical address.
io_zero Zeros a block of memory in bus address space.
IS_KSEG_VA Determines if the specified address is located in the kernel-unmapped address space.
IS_SEG0_VA Determines if the specified address is located in the user-mapped address space.
IS_SEG1_VA Determines if the specified address is located in the kernel-mapped address space.
kernel_isrthread Starts a fixed priority kernel thread dedicated to interrupt service.
kernel_thread_w_arg Starts a kernel thread with a calling argument passed in.
KSEG_TO_PHYS Converts a kernel-unmapped virtual address to a physical address.
lock_done Releases a complex lock.
lock_init Initializes a complex lock.
lock_read Asserts a complex lock with read-only access.
lock_terminate Terminates, using a complex lock.
lock_try_read Tries to assert a complex lock with read-only access.
lock_try_write Tries to assert a complex lock with write access.
lock_write Asserts a complex lock with write access.
major Returns the device major number.
makedev Returns a dev_t.
MALLOC Allocates a variable-size section of kernel virtual memory.
mb Performs a memory barrier.
minor Returns the device minor number.
minphys Bounds the data transfer size.
mpsleep Blocks (puts to sleep) the current kernel thread.
ntohl Converts longword values from network-to-host byte order.
ntohs Converts word values from network-to-host byte order.
ovbcopy Copies a byte string with a specified limit.
panic Causes a system crash.
physio Implements raw I/O.
PHYS_TO_KSEG Converts a physical address to a kernel-unmapped virtual address.
pmap_extract Extracts a physical page address.
pmap_kernel Returns the physical map handle for the kernel.
pmap_set_modify Sets the modify bits of the specified physical page.
printf Prints text to the console and the error logger.
privileged Checks for proper privileges.
psignal Sends a signal to a process.
queue_init Initializes the specified queue.
READ_BUS_D8 Reads a byte (8 bits) from a device register.
READ_BUS_D16 Reads a word (16 bits) from a device register.
READ_BUS_D32 Reads a longword (32 bits) from a device register.
READ_BUS_D64 Reads a quadword (64 bits) from a device register.
readdisklabel Reads a disk label from a device.
read_io_port Reads data from a device register.
register_callback Registers a callback request (interface).
remque Removes an element from the queue.
rmalloc Allocates size units from the given resource map.
rmfree Frees space previously allocated into the specified resource map.
rmget Allocates size units from the given resource map.
rminit Initializes a resource map.
round_page Rounds the specified address.
rt_post_callout Posts an interface to be called at a lower IPL.
rt_post_callout_ipl Posts an interface to be called at a specified IPL.
select_dequeue Removes the last kernel thread waiting for an event.
select_dequeue_all Removes all kernel threads waiting for an event.
select_enqueue Adds the current kernel thread.
select_wakeup Wakes up a kernel thread.
setdisklabel Sets a disk label.
simple_lock Asserts a simple lock.
simple_lock_init Initializes a simple lock structure.
simple_lock_terminate Terminates, using a simple lock.
simple_lock_try Tries to assert a simple lock.
simple_unlock Releases a simple lock.
sleep Puts a calling process to sleep.
spl Sets the processor priority to mask different levels of interrupts.
strcmp Compares two null-terminated character strings.
strcpy Copies a null-terminated character string.
strlen Returns the number of characters in a null-terminated string.
strncmp Compares two strings, using a specified number of characters.
strncpy Copies a null-terminated character string with a specified limit.
subyte Writes a byte into user address space.
suibyte Writes a byte into user instruction address space.
suiword Writes a word into user instruction address space.
suser Checks whether the current user is the superuser.
suword Writes a word into user address space.
svatophys Converts a system virtual address to a physical address.
swap_lw_bytes Performs a longword byte swap.
swap_word_bytes Performs a short word byte swap.
swap_words Performs a word byte swap.
thread_block Blocks (puts to sleep) the current kernel thread.
thread_halt_self Handles asynchronous traps for self-terminating kernel threads.
thread_set_timeout Sets a timer for the current kernel thread.
thread_terminate Prepares to stop or stops execution of the specified kernel thread.
thread_wakeup Wakes up all kernel threads waiting for the specified event.
thread_wakeup_one Wakes up the first kernel thread waiting on a channel.
timeout Initializes a callout queue element.
trunc_page Truncates the specified address.
uiomove Moves data between user and system virtual space.
unconfigure_driver Unconfigures a device driver that was dynamically configured.
unix_master Forces execution onto the master CPU.
unix_release Releases binding of the kernel thread.
unregister_callback Deregisters a callback request (interface).
untimeout Removes the scheduled interface from the callout queues.
uprintf Is a nonsleeping kernel printf function.
vm_map_pageable Sets pageability of the specified address range.
vtop Converts any virtual address to a physical address.
wakeup Wakes up all processes sleeping on a specified address.
WRITE_BUS_D8 Writes a byte (8 bits) to a device register.
WRITE_BUS_D16 Writes a word (16 bits) to a device register.
WRITE_BUS_D32 Writes a longword (32 bits) to a device register.
WRITE_BUS_D64 Writes a quadword (64 bits) to a device register.
writedisklabel Writes a disk label.
write_io_port Writes data to a device register.

Table 2-2 summarizes the kernel interfaces that STREAMS device drivers can use.

Table 2-2: Summary Descriptions of STREAMS-Related Kernel Support Interfaces

Kernel Interface Summary Description
adjmsg Removes the specified number of bytes from a message.
allocb Allocates a message block.
backq Gets a pointer to the previous queue.
bcanput Tests for flow control in a specified priority band.
bufcall Gets a buffer when allocb fails.
canput Tests for room in a message queue.
copyb Copies a message block.
copymsg Copies a message to a new message.
datamsg Tests whether a message is a data message.
dupb Duplicates a message block descriptor.
dupmsg Duplicates a message.
enableok Enables a queue for service.
esballoc Allocates a message block with a shared buffer.
flushband Flushes messages for a specified priority band.
flushq Removes a message from a queue.
freeb Frees a message block.
freemsg Frees all message blocks in a message.
getq Gets a message from the front of the queue.
insq Inserts a STREAMS message into a queue.
linkb Concatenates two message blocks.
msgdsize Returns the number of bytes in a message.
noenable Prevents a queue from being scheduled.
OTHERQ Gets a pointer to a module's other queue.
pullupmsg Concatenates bytes in a message.
putbq Places a message at the head of a queue.
putctl Puts a control message on a queue.
putctl1 Puts a control message on a queue.
putnext Sends a message to the next module in the stream.
putq Puts a message on a queue.
qenable Enables a queue.
qreply Sends a message in the reverse direction.
qsize Finds the number of messages on a queue.
RD Gets a pointer to a module's read queue.
rmvb Removes a message block from a message block.
rmvq Removes a message block from a queue.
strlog Submits messages for logging.
strqget Gets information about a queue.
strqset Changes information about a queue.
testb Checks for an available buffer.
unbufcall Cancels a pending bufcall request.
unlinkb Removes a message block from the head of a message.
WR Gets a pointer to this module's write queue.

Note

The kernel interface descriptions in this section do not discuss how a kernel interface acquires and releases the appropriate symmetric multiprocessing (SMP) lock. The reasons for this approach are that some kernel interfaces such as read_io_port and write_io_port do not need to acquire an SMP lock; some kernel interfaces need to acquire an SMP lock but the device driver writer does not need to know the intricacies of how the kernel interface acquires the SMP lock.

Unless otherwise noted, the kernel interfaces that need to acquire an SMP lock acquire the lock at the start of execution and release the lock when they complete execution.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


adjmsg

Removes the specified number of bytes from a message


Synopsis

#include <sys/stream.h> int adjmsg (message_ptr, len_to_trim)
MBLKP message_ptr;
int len_to_trim;


Arguments

message_ptr
Specifies a pointer to the message that you want adjmsg to trim.

len_to_trim
Specifies the number of bytes that you want adjmsg to remove (trim) from the message.


Description

The adjmsg interface removes a specified number of bytes from a message. The absolute value of the len_to_trim argument specifies how many bytes that adjmsg removes. If the number of bytes passed to len_to_trim is greater than zero (0), adjmsg removes bytes from the head of the message. If the number of bytes passed to len_to_trim is less than zero (0), adjmsg removes bytes from the tail of the message.

The adjmsg interface fails if the value you pass to the len_to_trim argument is greater than the number of bytes stored in the message pointer argument, message_ptr.


Return Values

If the adjmsg interface successfully trims the message, it returns the value 1. Otherwise, it returns the value zero (0).


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


allocb

Allocates a message block


Synopsis

#include <sys/stream.h> MBLKP allocb (size, pri)
int size;
uint pri;


Arguments

size
Specifies the number of bytes in the message block.

pri
Specifies the priority of the request. You use this argument to determine if the allocation of memory blocks (waits) on the request. If you call the allocb interface at a high priority and it blocks on the request, the system could deadlock. Typically, you pass the constant BPRI_WAITOK, which signifies that allocb can block. If allocb cannot block, you should pass the BPRI_HI constant.


Description

The allocb interface attempts to allocate a STREAMS message block. Buffer allocation fails only when the system is out of memory. If no buffer is available, you can call the bufcall interface, which helps a module recover from a memory allocation failure.


Return Values

Upon successful completion, the allocb interface returns a pointer to the allocated message block. This message block is of type struct msgb *. The msgb data structure is defined in the /usr/sys/include/sys/stream.h file.

If allocb cannot allocate a message block, it returns a NULL pointer.


Related Information

bufcall, esballoc, testb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


assert_wait_mesg

Asserts that the current kernel thread is about to block (sleep)


Synopsis

void assert_wait_mesg (event, interruptible, message)
vm_offset_t event;
boolean_t interruptible;
char *message;


Arguments

event
Specifies the event associated with the current kernel thread.

interruptible
Specifies a Boolean value that indicates how the kernel thread is awakened. You can pass one of the following values:
Value Meaning
TRUE The current kernel thread is interruptible. This value means that a signal can awaken the current kernel thread.
FALSE The current kernel thread is not interruptible. This value means that only the specified event can awaken the current kernel thread.

message
Specifies a mnemonic for the type of wait. The /bin/ps command uses this mnemonic to print out more meaningful messages about a process.


Description

The assert_wait_mesg interface asserts that the current kernel thread is about to block (sleep) until the specified event occurs. This interface sets a thread wait bit in the pointer to the thread structure associated with the current kernel thread. This bit signifies that this kernel thread is on the appropriate wait hash queue, waiting for a wakeup call.

To actually block (put to sleep) the current kernel thread, call thread_block.

To issue a wakeup call on the specified event, call the thread_wakeup_prim or clear_wait interface.


Cautions

You must not call assert_wait_mesg from a device driver's interrupt handler. The reason for this is that at interrupt context there is no process to be put to sleep.


Example

See Writing Device Drivers: Advanced Topics for a code example of the assert_wait_mesg interface.


Return Values

None


Related Information

clear_wait, current_thread, thread, thread_block

Reference Pages Section 1: ps


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


atoi

Converts an ASCII string to an integer


Synopsis

int atoi (s1)
char *s1;


Arguments

s1
Specifies a pointer to a string (an array of characters terminated by a null character).


Description

The atoi interface converts the specified ASCII string to an integer. The string can contain decimal integer constants. Specifically, the atoi interface converts the specified ASCII character string up to the first character inconsistent with the format of a decimal integer to an integer data type. Leading white-space characters are ignored.


Notes

The atoi interface is a modified version of the atoi C library interface that applications call. The kernel version of atoi is intended for use in those few cases in the kernel where the conversion of an ASCII string to an integer is required (for example, generic boot code).


Return Values

The atoi interface returns the converted value of an integer if the specified ASCII string is in the expected form. Otherwise, it returns a negative integer.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


backq

Gets a pointer to the previous queue


Synopsis

#include <sys/stream.h> queue_t * backq (current_queue)
queue_t *current_queue;


Arguments

current_queue
Specifies the pointer to the current queue. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The backq interface returns a pointer to the queue preceding the current queue (the current_queue argument). If the current queue is a read queue, backq returns a pointer to the queue downstream from the current queue, unless the current queue is the stream end. If the current queue is a write queue, backq returns a pointer to the queue upstream from the current queue, unless the current queue is the stream head.


Return Values

Upon successful completion, the backq interface returns a pointer to the queue preceding the current queue. Otherwise, it returns NULL.


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


BADADDR

Probes the address during device autoconfiguration


Synopsis

int BADADDR (addr, length, ptr)
caddr_t addr;
int length;
struct bus_ctlr_common *ptr;


Arguments

addr
Specifies the address of the device registers or memory.

length
Specifies the length (in bytes) of the data to be checked. Valid values are 1, 2, and 4 on 32-bit machines and 4 and 8 on 64-bit machines.

ptr
Specifies a pointer to a bus_ctlr_common structure. You cast this argument as a pointer to either a bus or controller structure.


Description

The BADADDR interface generates a call to a machine-dependent interface that does a read access check of the data at the supplied address and dismisses any machine check exception that may result from the attempted access. You call this interface to probe for memory or I/O devices at a specified address during device autoconfiguration.


Notes

You can use BADADDR in device drivers that are statically configured into the kernel on Digital UNIX. However, you cannot use BADADDR if the driver is dynamically configured into the kernel.

If you implement the driver to be both statically and dynamically configured, you can declare a variable and use it to control the call to BADADDR.

The following code fragment shows the use of such a variable used in the probe interface for the /dev/none driver:


.
.
.
if (none_is_dynamic) { /* Code to handle tasks associated with a dynamically * * configured driver */
.
.
.
} else { /* Code to handle tasks (including the call to BADADDR) * * associated with a statically configured driver */ /* including call to BADADDR */ }
.
.
.

The EISA and ISA buses do not generate a machine check when BADADDR performs a read access to a nonexistent location. These buses always return success when BADADDR performs a read access to their address space.

For the PCI bus and the VMEbus, you must do the following before calling BADADDR:


Return Values

The BADADDR interface returns the value zero (0) if the data is accessible and nonzero if the data is not accessible.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


bcanput

Tests for flow control in a specified priority band


Synopsis

#include <sys/stream.h> int bcanput (message_queue, pri)
queue_t *message_queue;
unsigned char pri;


Arguments

message_queue
Specifies a pointer to the message queue. The typedef queue_t is an alternate name for struct queue_entry *.

pri
Specifies the priority of the message.


Description

The bcanput interface, like the canput interface, searches through the stream (starting at the message queue identified by the message_queue argument) until it finds a queue that contains a service interface where the message can be enqueued or until it reaches the end of the stream. If bcanput finds a service interface in a queue, it tests the queue to determine if there is space in the queue to accommodate a message. If the queue is full, bcanput sets the q_flag member of the queue_entry structure pointer (the message queue) to the constant QWANTW to back-enable the caller's service interface.

If the pri argument is zero (0), bcanput calls the canput interface, which performs the task of checking for space in the message queue.


Notes

You are responsible for both testing a queue with bcanput and not placing a message on the queue if bcanput fails.


Return Values

The bcanput interface returns a value of 1 if a message of priority pri can be placed on the message queue, or if the band does not yet exist on the queue. The interface returns a value of zero (0) if the priority band is flow-controlled.


Related Information

canput, putbq, putnext

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


bcmp

Compares two byte strings


Synopsis

int bcmp (b1, b2, n)
char *b1;
char *b2;
int n;


Arguments

b1
Specifies a pointer to a byte string (array of characters).

b2
Specifies a pointer to a byte string (array of characters).

n
Specifies the number of bytes to be compared.


Description

The bcmp interface compares byte string b1 to byte string b2. The interface compares exactly n bytes. No check is made for null bytes.


Return Values

If the first n bytes of b1 and b2 are equal, the bcmp interface returns the value zero (0). Otherwise, it returns a nonzero integer.


Related Information

strcmp


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


bcopy

Copies a series of bytes with a specified limit


Synopsis

void bcopy (b1, b2, n)
char *b1;
char *b2;
int n;


Arguments

b1
Specifies a pointer to a byte string (array of characters). This pointer can reside in kernel address space or user address space.

b2
Specifies a pointer to a buffer of at least n bytes. This pointer can reside in kernel address space or user address space.

n
Specifies the number of bytes to be copied.


Description

The bcopy interface copies n bytes from string b1 to buffer b2. No check is made for null bytes. The copy is nondestructive, that is, the address ranges of b1 and b2 can overlap.


Example

The following code fragment shows a call to bcopy:


.
.
.
struct tc_slot tc_slot[TC_IOSLOTS];
.
.
.
char *cp;
.
.
.

bcopy(tc_slot[index].modulename, cp, TC_ROMNAMLEN + 1);
.
.
.


Return Values

None


Related Information

blkclr, copystr, ovbcopy, strcpy, strncpy


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


biodone

Indicates that block I/O is complete


Synopsis

void biodone (bp)
struct buf *bp;


Arguments

bp
Specifies a pointer to a buf structure. This structure contains information such as the binary status flags, the major/minor device numbers, and the address of the associated buffer. This buffer is always a special buffer header owned exclusively by the device for handling I/O requests.


Description

The biodone interface is called after an I/O operation to mark the buf structure as completed. It sets the b_flags member to B_SWAP, B_UBC, or B_ASYNC to indicate the type of I/O operation that has completed. Other members may be set as well, depending on the type of I/O operation.

The interface panics if the buf structure is NULL.


Return Values

None


Related Information

buf, iodone


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


blkclr, bzero

Zero a block of memory


Synopsis

void blkclr (b1, n)
char *b1;
unsigned int n;

void bzero (b1, n)
char *b1;
int n;


Arguments

b1
Specifies a pointer to a string of at least n bytes.

n
Specifies the number of bytes to be zeroed.


Description

The blkclr and bzero interfaces zero n bytes of memory beginning at the address specified by b1.


Example

See Writing Device Drivers: Tutorial for code examples of the blkclr and bzero interfaces.


Return Values

None


Related Information

bcopy, copystr, ovbcopy, strcpy, strncpy


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


brelse

Deallocates a buf structure


Synopsis

void brelse (bp)
register struct buf *bp;


Arguments

bp
Specifies a pointer to a buf structure. This structure contains information such as the binary status flags, the major/minor device numbers, and the address of the associated buffer. This buffer is always a special buffer header owned exclusively by the device for handling I/O requests.


Description

The brelse interface deallocates a buf structure that was previously allocated by the getnewbuf interface. The buf structure contains information describing an I/O request. Device drivers call the brelse interface after the I/O request has completed to free the memory used by the buf structure.


Return Values

None


Related Information

buf, getnewbuf


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


btop

Converts bytes to number of pages


Synopsis

int btop (virt_addr)
vm_offset_t virt_addr;


Arguments

virt_addr
Specifies the virtual address.


Description

The btop interface converts the specified byte address to the number of pages.


Return Values

The btop interface returns the number of kernel pages associated with the specified byte address.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


bufcall

Gets a buffer when allocb fails


Synopsis

#include <sys/stream.h> int bufcall (size, pri, function, argument)
int size;
int pri;
int (*function) ();
long argument;


Arguments

size
Specifies the number of bytes in the buffer.

pri
Specifies the priority of the allocb allocation request (no longer used).

function
Specifies a kernel or driver interface to be called when a buffer becomes available.

argument
Specifies an argument to be passed to the kernel or driver interface specified in the function argument.


Description

The bufcall interface serves as a timeout call of indeterminate length. When a buffer allocation request fails, you can use bufcall to schedule the interface passed to the function argument to be called with the argument passed to argument when a buffer becomes available. The interface passed to function can be a routine that calls allocb or it can be implemented to perform something else.


Notes

Even when the bufcall interface calls the interface passed to the function argument, the allocb interface can still fail if another module or device driver allocated the memory before the interface in function was able to call allocb.


Return Values

Upon successful completion, the bufcall interface returns a bufcall id that you can use in a call to the unbufcall interface to cancel the request. If the bufcall scheduling fails (that is, a buffer is not available), the interface passed to function is never called and bufcall returns the value zero (0).


Related Information

allocb, esballoc, testb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


BUF_LOCK

Locks the specified I/O buffer


Synopsis

void BUF_LOCK (bp)
struct buf *bp;


Arguments

bp
Specifies a pointer to a buf structure.


Description

The BUF_LOCK interface locks the specified I/O buffer. The interface masks all disk and tape controller interrupts (by calling the splbio interface). It sets the mutual exclusion buffer lock member, b_lock, of the specified buf structure pointer.

The BUF_LOCK interface then sets the b_flags member of the specified buf structure pointer to B_BUSY to indicate that this buffer is being used. Finally, BUF_LOCK resets the CPU priority level (by calling the splx interface).


Notes

You should make efforts in your device drivers to hold the I/O buffer lock for as short a period of time as possible to allow maximum concurrency. You should also release the I/O buffer lock by calling the BUF_UNLOCK interface before returning from the driver's entry point.


Return Values

None


Related Information

BUF_UNLOCK


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


BUF_UNLOCK

Unlocks the specified I/O buffer


Synopsis

void BUF_UNLOCK (bp)
struct buf *bp;


Arguments

bp
Specifies a pointer to a buf structure.


Description

The BUF_UNLOCK interface unlocks the specified I/O buffer that was locked in a previous call to BUF_LOCK. The interface masks all disk and tape controller interrupts (by calling the splbio interface). It resets the mutual exclusion buffer lock member, b_lock, of the specified buf structure pointer.

The BUF_UNLOCK interface then resets the b_flags member of the specified buf structure pointer to indicate that this buffer is not being used. Finally, BUF_UNLOCK resets the CPU priority level (by calling the splx interface).


Notes

You must have locked the specified I/O buffer by calling BUF_LOCK prior to calling the BUF_UNLOCK interface.


Return Values

None


Related Information

BUF_LOCK


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


busphys_to_iohandle

Converts a valid bus physical address to an I/O handle base


Synopsis

io_handle_t busphys_to_iohandle (addr, flags, ctlr_p)
u_long addr;
int flags;
struct controller *ctlr_p;


Arguments

addr
Specifies the bus physical address that you want busphys_to_iohandle to translate into an I/O handle base.

flags
Specifies flags to indicate the address space in which the bus physical address that you pass to the addr argument resides. You can pass one of the following address space flag values:
Value Meaning
BUS_MEMORY The address is from the bus memory. In this case, busphys_to_iohandle converts the bus physical address to a sparse memory I/O handle base.
BUS_IO The address is from the bus I/O memory. In this case, busphys_to_iohandle converts the bus physical address to a sparse I/O handle base.
DENSE_MEMORY The address is from dense space. In this case, busphys_to_iohandle converts the bus physical address to a dense memory base.

ctlr_p
Specifies a pointer to the controller structure associated with the controller that connects to this device. The busphys_to_iohandle interface uses the controller structure pointer to obtain any hardware resource-related information.


Description

The busphys_to_iohandle interface converts a valid bus physical address to an I/O handle base that a device driver uses to perform I/O copy operations. The form of this address is CPU specific.


Notes

The busphys_to_iohandle interface is a generic interface that maps to a bus-specific interface that actually converts the bus physical address to an I/O handle base. Using this interface to convert the bus physical address makes the device driver more portable across different bus architectures.


Return Values

Upon successful completion, busphys_to_iohandle returns the I/O handle base associated with the bus physical address. If busphys_to_iohandle cannot convert the bus physical address into an I/O handle base, it returns a value of -1.


Related Information

io_copyin, io_copyio, io_copyout, iohandle_to_phys


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


canput

Tests for room in a message queue


Synopsis

#include <sys/stream.h> int canput (message_queue)
queue_t *message_queue;


Arguments

message_queue
Specifies a pointer to the message queue. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The canput interface searches through the stream (starting at the message queue identified by the message_queue argument) until it finds a queue that contains a service interface where the message can be enqueued or until it reaches the end of the stream. If canput finds a service interface in a queue, it tests the queue to determine if there is space in the queue to accommodate a message. If the queue is full, canput sets the q_flag member of the queue_entry structure pointer (the message queue) to the constant QWANTW to back-enable the caller's service interface.


Notes

You are responsible for both testing a queue with canput and not placing a message on the queue if canput fails.


Return Values

The canput interface returns a value of 1 if the message queue is not full. It returns the value zero (0) if the message queue is full.


Related Information

bcanput, putbq, putnext

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


cfgmgr_get_state

Determines the configuration state


Synopsis

int cfgmgr_get_state (driver_name, driver_cfg_state)
char *driver_name;
int *driver_cfg_state;


Arguments

driver_name
Specifies the name of the device driver whose configuration state you want to obtain. This name is a string that matches the string you specified for the entry_name item in the /etc/sysconfigtab database. Typically, third-party driver writers specify the driver name (followed by a colon) in the sysconfigtab file fragment, which gets appended to the /etc/sysconfigtab database during the driver product installation.

driver_cfg_state
Returns one of the following state value bits to the driver_cfg_state argument:
Value Meaning
SUBSYSTEM_DYNAMICALLY_CONFIGURED The specified device driver is in the dynamic configuration state. This means the driver was dynamically configured into the kernel.
SUBSYSTEM_STATICALLY_CONFIGURED The specified device driver is in the static configuration state. This means the driver was statically configured into the kernel.


Description

The cfgmgr_get_state interface obtains the configuration state of the specified device driver. The specified device driver is either in the static configuration state or the dynamic configuration state. The cfgmgr_get_state interface returns the state value in the driver_cfg_state argument. Driver writers should store this state value in an xx_is_dynamic variable or some similarly named variable.

You typically call the cfgmgr_get_state interface in the CFG_OP_CONFIGURE entry point of the device driver's configure interface.


Example

See Writing Device Drivers: Tutorial for a code example of the cfgmgr_get_state interface.


Return Values

Upon successful completion, cfgmgr_get_state returns the value ESUCCESS. This success value indicates that cfgmgr_get_state returned the configuration state of the specified device driver in the driver_cfg_state argument. Otherwise, cfgmgr_get_state returns one of the following error constants defined in /usr/sys/include/sys/sysconfig.h and /usr/sys/include/sys/errno.h:

CFG_FRAME_EEXISTS
The device driver that you specified in the driver_name argument does not exist. In this case, cfgmgr_get_state cannot return the configuration state of the specified device driver in the driver_cfg_state argument.

EINVAL
The device driver that you specified in the driver_name argument is not a valid name.


Related Information

cfgmgr_set_status


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


cfgmgr_set_status

Reports failure to the cfgmgr framework


Synopsis

int cfgmgr_set_status (driver_name)
char *driver_name;


Arguments

driver_name
Specifies the name of the device driver for which you want to report an associated failure. This name is a string that matches the string you specified for the entry_name item in the /etc/sysconfigtab database. Typically, third-party driver writers specify the driver name (followed by a colon) in the sysconfigtab file fragment, which gets appended to the /etc/sysconfigtab database during the driver product installation.


Description

The cfgmgr_set_status interface reports to the cfgmgr framework that a failure has occurred during static configuration. If the specified device driver is in the static configuration state, it does not know that the configuration operation is complete until all register callback requests (interfaces) have successfully completed. Therefore, a device driver calls cfgmgr_set_status to report a possible failure during static configuration to the cfgmgr framework.

Specifically, cfgmgr_set_status performs the following failure operations:

The cfgmgr_set_status interface calls the device driver's configure interface at its CFG_OP_UNCONFIGURE entry point as part of these failure operations. The code associated with the CFG_OP_UNCONFIGURE entry point is responsible for determining how to deallocate any allocated resources during these failure operations.

The cfgmgr_set_status interface does not notify the operator of a configuration failure. Part of the code associated with the CFG_OP_UNCONFIGURE entry point could include an error logging operation to record the fact that a failure has occurred. The reason for doing this is that the cfgmgr framework's task is to accomplish the unconfigure operation of a statically configured device driver.

You call the cfgmgr_set_status interface in the device driver's callback interface when the static configuration operation fails. You register a callback interface by calling the register_callback interface.


Example

See Writing Device Drivers: Tutorial for a code example of the cfgmgr_set_status interface.


Return Values

Upon successful completion, cfgmgr_set_status returns the value ESUCCESS. This success value indicates that cfgmgr_set_status adjusted the state of the device driver and caused the cfgmgr framework to unconfigure the driver. Otherwise, cfgmgr_set_status returns one of the following error constants defined in /usr/sys/include/sys/sysconfig.h and /usr/sys/include/sys/errno.h:

CFG_FRAME_EEXISTS
The device driver that you specified in the driver_name argument does not exist. In this case, cfgmgr_set_status cannot adjust the state and unconfigure the device driver.

CFG_FRAME_ECONFIGURED
The device driver that you specified in the driver_name argument was not statically configured.

EINVAL
The device driver that you specified in the driver_name argument is not in the static configuration state.


Related Information

cfgmgr_get_state, register_callback


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


clear_wait

Clears the wait condition


Synopsis

void clear_wait (thread, result, interrupt_only)
thread_t thread;
int result;
boolean_t interrupt_only;


Arguments

thread
Specifies a pointer to the thread structure associated with the kernel thread to awaken.

result
Specifies the outcome of the wait. You can pass one of the following values:
Value Meaning
THREAD_AWAKENED This is a normal wakeup.
THREAD_TIMED_OUT The timeout period expired.
THREAD_INTERRUPTED The clear_wait interface interrupted the wakeup.

interrupt_only
Specifies a Boolean value that indicates how the clear_wait interface clears the wait condition. You can pass one of the following values:
Value Meaning
TRUE Clears the wait condition only if the kernel thread is waiting in an interruptible state.
FALSE Clears the wait condition under any circumstances.


Description

The clear_wait interface clears the wait condition for the specified kernel thread and starts executing the kernel thread, if appropriate. If the kernel thread is interruptible and is still waiting for the event, clear_wait sets the kernel thread state to TH_RUN and places it on the run queue.


Return Values

None


Related Information

assert_wait_mesg, mpsleep, thread_block, thread_wakeup, thread_wakeup_one


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


configure_driver

Configures a device driver that is in the dynamic state


Synopsis

int configure_driver (driver_name, bus_num, bus_name, driver_struct)
char *driver_name;
int bus_num;
char *bus_name;
struct driver *driver_struct;


Arguments

driver_name
Specifies the name of the device driver. This name is a string that matches the string you specified for the entry_name item in the /etc/sysconfigtab database. Typically, third-party driver writers specify the driver name (followed by a colon) in the sysconfigtab file fragment, which gets appended to the /etc/sysconfigtab database during the driver product installation.

bus_num
Specifies the number of the bus to connect to in the list of controller structures. You should pass the constant DRIVER_WILDNUM to allow the bus configuration code to actually assign the bus number.

bus_name
Specifies the name of the bus to connect to in the list of bus structures. You should pass the constant DRIVER_WILDNAME to allow the bus configuration code to actually assign the bus name.

driver_struct
Specifies the address of the driver structure associated with the controlling device driver. The driver structure name is typically based on the device driver name. For example, the driver structure for the /dev/none driver is nonedriver. The device driver writer initializes this driver structure, usually in the Declarations Section of the device driver.


Description

The configure_driver interface configures a device driver into the system (hardware) configuration tree. The configuration tasks consist of incorporating the bus, controller, and device structures associated with the specific device driver into the system (hardware) configuration tree.


Example

See Writing Device Drivers: Tutorial for a code example of the configure_driver interface.


Return Values

The configure_driver interface can return the following value defined in /usr/sys/include/io/common/devdriver_loadable.h:

LDBL_ENOBUS
The bus you specified in the bus_name argument does not exist in the system (hardware) configuration tree.

The configure_driver interface can also return one of the following status values defined in /usr/sys/include/sys/errno.h. This value is actually returned from the bus-specific controller_configure interface:

ESUCCESS
The bus-specific controller_configure interface successfully completed the autoconfiguration request.

ENODEV
The driver's probe interface did not successfully complete.


Related Information

driver, unconfigure_driver


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


contig_free

Frees a block of memory previously allocated by contig_malloc


Synopsis

#include <sys/malloc.h> void contig_free (addr, size, type)
void *addr;
u_long size;
int type;


Arguments

addr
Specifies the address of the memory being freed. This address was returned in a previous call to contig_malloc.

size
Specifies the size (in bytes) of the memory being freed. You should pass the same value used to allocate this memory in the call to contig_malloc.

type
Specifies the purpose for which the memory is being allocated (or freed). The memory type constants are defined in the file /usr/sys/include/sys/malloc.h. Examples of memory type constants are M_DEVBUF (device driver memory), M_KTABLE (kernel table memory), M_RTABLE (routing tables memory), and so forth.


Description

The contig_free interface frees the memory allocated in a previous call to contig_malloc. If the memory came from the saved memory pool, contig_free puts it back in the saved memory pool; otherwise, the interface frees the memory to the virtual memory subsystem.


Return Values

None


Related Information

contig_malloc


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


contig_malloc

Allocates physically contiguous memory


Synopsis

#include <sys/malloc.h> void * contig_malloc (size, alignment, addrlimit, type, flag)
u_long size;
u_long alignment;
u_long addrlimit;
int type;
int flag;


Arguments

size
Specifies the size of the memory (in bytes) to allocate.

alignment
Specifies the alignment of the memory to be allocated. For example, for a 256-byte alignment you should pass the value 256. A zero (0) value means there is no alignment requirement.

addrlimit
Specifies that the address of all the allocated memory should be less than or equal to this address. A zero (0) value means that there is no address limit requirement.

type
Specifies the purpose for which the memory is being allocated (or freed). The memory type constants are defined in the file /usr/sys/include/sys/malloc.h. Examples of memory type constants are M_DEVBUF (device driver memory), M_KTABLE (kernel table memory), M_RTABLE (routing tables memory), and so forth.

flag
Specifies one of the following flags defined in /usr/sys/include/sys/malloc.h:
Value Meaning
M_ZERO Signifies that contig_malloc should zero the allocated memory.
M_WAITOK Signifies that contig_malloc can block.
M_NOWAIT Signifies that contig_malloc cannot block.


Description

The contig_malloc interface allocates physically contiguous memory during the boot process (before single-user mode). The interface carves out an area of physically contiguous memory from a contiguous memory buffer and allocates memory from this buffer with proper alignment. The call to contig_malloc is the same for statically or dynamically configured drivers. However, the point or points in time in which the statically or dynamically configured driver requests the memory differ.

A statically configured driver typically needs to call contig_malloc only before single-user mode. In this case, contig_malloc obtains the memory from the contiguous memory buffer. When a statically configured driver frees this physically contiguous memory (by calling the contig_free interface), the memory is returned to the virtual memory subsystem.

A dynamically configured driver typically needs physically contiguous memory after single-user mode. As stated previously, contig_malloc carves out an area of physically contiguous memory from a contiguous memory buffer before single-user mode. Thus, this memory would not be available to the dynamically configured driver after single-user mode. To solve this problem, a dynamically configured driver calls contig_malloc by defining the CMA_Option attribute in the sysconfigtab file fragment.

The cma_dd subsystem that Digital provides calls contig_malloc on behalf of dynamically configured device drivers and obtains the memory allocation size (and other information) from the CMA_Option attribute field. In this case, contig_malloc allocates physically contiguous memory from the contiguous memory buffer and places it in a saved memory pool. When a dynamically configured driver needs to call contig_malloc after single-user mode, the physically contiguous memory comes from this saved memory pool. When a dynamically configured driver frees this physically contiguous memory (by calling the contig_free interface), the memory is returned to the saved memory pool (not the virtual memory subsystem). Thus, this physically contiguous memory is available to the dynamically configured driver upon subsequent reload requests that occur after single-user mode.


Return Values

Upon successful completion, contig_malloc returns a pointer to the allocated memory. If contig_malloc cannot allocate the requested memory, it returns a null pointer.


Related Information

contig_free


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copyb

Copies a message block


Synopsis

#include <sys/stream.h> MBLKP copyb (message_block)
MBLKP message_block;


Arguments

message_block
Specifies a pointer to the message block from which copyb copies the data. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The copyb interface allocates a new message block and copies into it the data from the block pointed to by the message block (the message_block argument). The new message block is at least as large as the message block being copied. The copyb interface uses the b_rptr and b_wptr members of the msgb structure pointer to determine how many bytes to copy.


Return Values

Upon successful completion, the copyb interface returns a pointer to the newly allocated message block that contains the copied data. This newly allocated message block is of type struct msgb *. The msgb data structure is defined in the /usr/sys/include/sys/stream.h file.

Otherwise, copyb returns a NULL pointer.


Related Information

allocb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copyin

Copies data from a user address space to a kernel address space


Synopsis

int copyin (user_src, kernel_dest, bcount)
caddr_t user_src;
caddr_t kernel_dest;
u_int bcount;


Arguments

user_src
Specifies the address in user space of the data to be copied.

kernel_dest
Specifies the address in kernel space to copy the data to.

bcount
Specifies the number of bytes to copy.


Description

The copyin interface copies a specified amount of data from the unprotected user address space to the protected kernel address space.


Example

See Writing Device Drivers: Tutorial for a code example of the copyin interface.


Return Values

Upon successful completion, copyin returns a value of zero (0). Otherwise, it can return the following error:

EFAULT
The address in user space that you specified in the user_src argument cannot be accessed.


Related Information

copyinstr, copyout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copyinstr

Copies a null-terminated string from a user address space to a kernel address space


Synopsis

int copyinstr (user_src, kernel_dest, maxlength, lencopied)
char *user_src;
char *kernel_dest;
int maxlength;
int *lencopied;


Arguments

user_src
Specifies the address in user space of the null-terminated string to be copied.

kernel_dest
Specifies the address in kernel space to copy the null-terminated string to.

maxlength
Specifies the maximum number of bytes to copy.

lencopied
Specifies the actual length of the string copied.


Description

The copyinstr interface copies a specified null-terminated string from the unprotected user address space to a specified address in the protected kernel address space.


Cautions

If the string being copied is not null terminated, copyinstr copies maxlength bytes into the kernel address space.


Return Values

Upon successful completion, copyinstr returns the value zero (0) and the actual length of the string copied to the lencopied argument. Otherwise, it returns one of the following error constants defined in /usr/sys/include/sys/errno.h:

EFAULT
The address in user space that you specified in the user_src argument cannot be accessed.

ENAMETOOLONG
The length of the string exceeds the maxlength value.


Related Information

copyoutstr


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copymsg

Copies a message to a new message


Synopsis

#include <sys/stream.h> MBLKP copymsg (message_block)
MBLKP message_block;


Arguments

message_block
Specifies a pointer to the message block from which copymsg copies the data. (Actually, copymsg calls the copyb interface to copy the data.) The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The copymsg interface:


Return Values

Upon successful completion, the copymsg interface returns a pointer to the newly allocated message block that contains the copied data. This newly allocated message block is of type struct msgb *. The msgb data structure is defined in the /usr/sys/include/sys/stream.h file.

Otherwise, copymsg returns a NULL pointer.


Related Information

allocb, copyb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copyout

Copies data from a kernel address space to a user address space


Synopsis

int copyout (kernel_src, user_dest, bcount)
caddr_t kernel_src;
caddr_t user_dest;
u_int bcount;


Arguments

kernel_src
Specifies the address in kernel space of the data to be copied.

user_dest
Specifies the address in user space to copy the data to.

bcount
Specifies the number of bytes to copy.


Description

The copyout interface copies a specified amount of data from the protected kernel address space to the unprotected user address space.


Example

See Writing Device Drivers: Tutorial for a code example of the copyout interface.


Return Values

Upon successful completion, copyout returns the value zero (0). Otherwise, it returns the following error:

EFAULT
The address in kernel space that you specified in the kernel_src argument cannot be accessed; or, the length you specified in bcount is invalid.


Related Information

copyin, copyoutstr


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copyoutstr

Copies a null-terminated string from a kernel address space to a user address space


Synopsis

int copyoutstr (kernel_src, user_dest, maxlength, lencopied)
char *kernel_src;
char *user_dest;
int maxlength;
int *lencopied;


Arguments

kernel_src
Specifies the address in kernel space of the null-terminated string to be copied.

user_dest
Specifies the address in user space to copy the null-terminated string to.

maxlength
Specifies the maximum number of bytes to copy.

lencopied
Specifies the actual length of the string copied.


Description

The copyoutstr interface copies a specified null-terminated string from the protected kernel address space to the unprotected user address space.


Cautions

If the string being copied is not null-terminated, copyoutstr copies maxlength bytes into the user address space.


Return Values

Upon successful completion, copyoutstr returns the value zero (0) and the actual length of the string copied in lencopied. Otherwise, it can return the following errors:

EFAULT
The address in kernel space that you specified in the kernel_src argument cannot be accessed.

ENAMETOOLONG
The length of the string exceeds the maxlength value.


Related Information

copyinstr


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copystr

Copies a null-terminated character string with a specified limit


Synopsis

int copystr (s1, s2, maxlength, ncopiedaddr)
char *s1;
char *s2;
u_int maxlength;
u_int *ncopiedaddr;


Arguments

s1
Specifies a pointer to a string (an array of characters terminated by a null character).

s2
Specifies a pointer to a buffer of at least maxlength characters.

maxlength
Specifies the maximum number of characters to copy.

ncopiedaddr
Specifies the address of an integer to receive the number of copied characters.


Description

The copystr interface copies string s1 to the buffer pointed to by s2. The interface stops after copying a null character or after copying maxlength characters, whichever comes first. The s2 buffer is not padded with null characters to maxlength.

The copystr interface returns the number of characters copied in the location pointed to by ncopiedaddr.

Note that the character size is 1 byte.


Return Values

Upon successful completion, copystr returns the value zero (0). Otherwise, it can return the following error:

ENAMETOOLONG
The string length, s1, exceeds the maximum number of characters, maxlength.


Related Information

bcopy, blkclr, ovbcopy, strcpy, strncpy


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


copy_to_phys

Copies data from a virtual address to a physical address


Synopsis

void copy_to_phys (virt_src, phys_dest, bcount)
vm_offset_t virt_src;
vm_offset_t phys_dest;
unsigned int bcount;


Arguments

virt_src
Specifies the virtual address of the data to be copied.

phys_dest
Specifies the physical address to copy the data to.

bcount
Specifies the number of bytes to copy.


Description

The copy_to_phys interface copies a specified amount of virtually addressed memory to physically addressed memory. The addresses reside only in system memory space and not in the memory space on I/O buses.


Cautions

If there is any overlap between virt_src and phys_dest, the copy_to_phys interface panics.


Return Values

None


Related Information

copyin, copyout, io_copyin, io_copyio, io_copyout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


create_controller_struct

Creates a controller structure for the system (hardware) configuration tree


Synopsis

int create_controller_struct (ctlr_cnfg)
struct controller_config *ctlr_cnfg;


Arguments

ctlr_cnfg
Specifies a pointer to the controller_config structure associated with a specific controller. You set the members of the controller_config structure to appropriate values and then pass the address of the filled-in structure to the create_controller_struct interface.


Description

The create_controller_struct interface creates a controller structure for each instance of a controller that the device driver supports. The interface integrates the controller structure for a specific controller into the list of controller structures that reside in the system configuration tree.


Notes

Typically, you supply the information needed by the create_controller_struct interface by passing to it the address of the filled-in controller_config structure. However, if any of this information needs to be configurable (that is, you want to give a system manager the ability to dynamically change this information), you must:


Example

See Writing Device Drivers: Tutorial for a code example of the create_controller_struct interface.


Return Values

Upon successful completion, create_controller_struct returns ESUCCESS. On failure, it returns EINVAL.


Related Information

controller_config, create_device_struct


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


create_device_struct

Creates a device structure for the system (hardware) configuration tree


Synopsis

int create_device_struct (dev_cnfg)
struct device_config *dev_cnfg;


Arguments

dev_cnfg
Specifies a pointer to the device_config structure associated with a specific device. You set the members of the device_config structure to appropriate values and then pass the address of the filled-in structure to create_device_struct.


Description

The create_device_struct interface creates a device structure for each instance of a device that the device driver supports. The interface integrates the device structure for a specific device into the list of device structures that reside in the system configuration tree.


Notes

Typically, you supply the information needed by the create_device_struct interface by passing to it the address of the filled-in device_config structure. However, if any of this information needs to be configurable (that is, you want to give a system manager the ability to dynamically change this information), you must:


Example

See Writing Device Drivers: Tutorial for a code example of the create_device_struct interface.


Return Values

Upon successful completion, create_device_struct returns ESUCCESS. On failure, it returns EINVAL.


Related Information

create_controller_struct, device_config


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


current_task

Returns a pointer to the task structure associated with the currently running kernel thread


Synopsis

struct task * current_task ()


Arguments

None


Description

The current_task interface returns a pointer to the task structure associated with the currently running kernel thread. A device driver typically calls this interface in preparation for doing a DMA operation to a user's buffer. The device driver uses the pointer returned by current_task in the call to the vm_map_pageable interface.


Cautions

You must not call the current_task interface from a driver's interrupt handler.


Return Values

The current_task interface returns a pointer to the task structure for the currently running kernel thread.


Related Information

round_page, thread, trunc_page, vm_map_pageable


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


current_thread

Is a pointer to the currently running kernel thread


Synopsis

void current_thread ()


Arguments

None


Description

The current_thread interface (macro) is a pointer to the currently running kernel thread. Typically, device drivers use this interface to reference the wait_result member of the thread structure pointer associated with the currently running kernel thread. A device driver calls current_thread after calls to assert_wait_mesg and thread_block. If the device driver needs to set a timeout, then it calls current_thread after calls to assert_wait_mesg, thread_set_timeout, and thread_block.

The kernel can set the wait_result member to one of the following values:

Value Meaning
THREAD_AWAKENED The result of the assert wait is a normal wakeup.
THREAD_TIMED_OUT The specified timeout has expired.
THREAD_INTERRUPTED The wait condition was interrupted by the clear_wait interface.
THREAD_SHOULD_TERMINATE The result of the assert wait is that the current kernel thread should terminate.
THREAD_RESTART The current kernel thread should be restarted.


Example

See Writing Device Drivers: Advanced Topics for a code example of the current_thread interface.


Return Values

None


Related Information

assert_wait_mesg, clear_wait, thread, thread_block, thread_set_timeout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


datamsg

Tests whether a message is a data message


Synopsis

#include <sys/stream.h> int datamsg (type)
unsigned char type;


Arguments

type
Specifies the type of message to be tested. The db_type member of the datab structure contains the message type. You can access this member through the message block as follows:

mp->b_datap->db_type


Description

The datamsg interface tests the type of message to determine if it is a data message type.

The following list identifies the data message value types:
Value Meaning
M_DATA Ordinary data
M_DELAY Requests a real-time delay
M_PROTO Internal control information and data
M_PCPROTO Same meaning as the M_PROTO except for priority


Return Values

If the message is a data message, datamsg returns the value 1. If the message is not a data message, datamsg returns the value zero (0).


Related Information

allocb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


decl_simple_lock_data

Declares a simple lock structure


Synopsis

#include <kern/lock.h> void decl_simple_lock_data (class, name)
char class;
char name;


Arguments

class
Specifies the class of the declaration. For example, you pass the keyword extern if you want to declare the simple lock structure as an external structure.

name
Specifies the name you want the decl_simple_lock_data interface to assign to the declaration of the simple lock structure.


Description

The decl_simple_lock_data interface declares a simple lock structure, slock, of the specified name. You declare a simple lock structure for the purpose of protecting device driver data structures and device register access. You use decl_simple_lock_data to declare a simple lock structure and then pass it to the following simple lock-specific interfaces: simple_lock_init, simple_lock, simple_lock_try, simple_unlock, and simple_lock_terminate.


Example

See Writing Device Drivers: Advanced Topics for a code example of the decl_simple_lock_data interface.


Return Values

None


Related Information

lock.h, simple_lock, simple_lock_init, simple_lock_try, simple_unlock, slock


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DELAY

Delays the calling interface a specified number of microseconds


Synopsis

void DELAY (n)
int n;


Arguments

n
Specifies the number of microseconds for the calling process to spin.


Description

The DELAY interface delays the calling interface a specified number of microseconds. DELAY spins, waiting for the specified number of microseconds to pass before continuing execution. For example, the following code results in a 10000-microsecond (10-millisecond) delay:

 .
 .
 .
 DELAY(10000);
 .
 .
 .

The range of delays is system dependent, due to its relation to the granularity of the system clock. The system defines the number of clock ticks per second in the hz variable. Specifying any value smaller than 1/hz to the DELAY interface results in an unpredictable delay. For any delay value, the actual delay may vary by plus or minus one clock tick.

Using the DELAY interface is discouraged because the processor will be consumed for the specified time interval and therefore is unavailable to service other processes. In cases where device drivers need timing mechanisms, you should use the sleep and timeout interfaces instead of the DELAY interface. The most common usage of the DELAY interface is in the system boot path. Using DELAY in the boot path is often acceptable because there are no other processes in contention for the processor.


Return Values

None


Related Information

hz, sleep, timeout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


devsw_add

Registers driver entry points and reserves a major number


Synopsis

#include <sys/conf.h> int devsw_add (driver_name, driver_reg_instance, major_number, dsent_ptr)
char *driver_name;
int driver_reg_instance;
int major_number;
struct dsent *dsent_ptr;


Arguments

driver_name
Specifies a null-terminated string that represents the name of the device driver whose entry points you want to register and for which you want to reserve an associated major number. The driver name must be at least two characters in length not to exceed DEVSW_NAME_LEN characters, including the null terminator.

This name is a string that matches the string you specified for the entry_name item in the /etc/sysconfigtab database. Typically, third-party driver writers specify the driver name (followed by a colon) in the sysconfigtab file fragment, which gets appended to the /etc/sysconfigtab database during the driver product installation.

driver_reg_instance
Specifies an integer representing a specific reservation instance for this driver. This argument allows a driver to uniquely identify multiple major numbers for the driver.

major_number
Specifies the major number you want to reserve for the driver in the dsent table. You can pass a specific major number or the value -1, in which case the devsw_add interface chooses the major number.

dsent_ptr
Specifies a pointer to the device switch structure that contains pointers to the device driver's entry points for the system service's I/O requests and other information.


Description

The devsw_add interface registers a device driver's I/O services interfaces in and reserves a major number from a free slot in the dsent table. Digital UNIX reserves this major number across boots. The devsw_add interface performs appropriate checks on the values passed to the driver_name, major_number, and dsent_ptr arguments.

You can request that the devsw_add interface reserve a specific major number from a slot in the dsent table by passing a specific number to the major_number argument. If you pass a specific major number, the devsw_add interface determines if a major number has already been assigned to the device driver. If this major number was already assigned to the device driver, the devsw_add interface simply registers the driver's I/O services interfaces in the dsent table and returns the major number as the reserved number. Passing the value -1 to the major_number argument causes the devsw_add interface to reserve a previously reserved major number or the next available major number from a slot in the dsent table.

If the major number you request or if the major number that was previously reserved is too large for the current size of the device switch table, devsw_add returns an error value of -1.

You can make subsequent calls to devsw_add to modify the device switch entry in the device switch table.


Notes

The dsent data structure contains entry points for the block and character I/O services interfaces associated with a specific device driver. This data structure also contains other information such as whether the driver is implemented as a symmetric multiprocessing (SMP) driver.

The devsw_add interface is provided for registering these block and character I/O services interfaces and reserving an associated major number.

A device driver writer registers the driver's I/O services interfaces by declaring an instance of the dsent structure in the driver and setting the appropriate members to the names of the driver's I/O services interfaces. You must specify an interface name for each member of this structure. If the driver does not implement a specific interface, there are typically two interfaces you can specify:


Example

See Writing Device Drivers: Tutorial for a code example of the devsw_add interface.


Return Values

Upon successful completion, the devsw_add interface returns the reserved major number. Otherwise, on an error, the devsw_add interface returns the value -1. The following list describes possible error conditions:


Related Information

devsw_del, devsw_get, dsent


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


devsw_del

Clears entry points from the device switch table


Synopsis

#include <sys/conf.h> int devsw_del (driver_name, driver_reg_instance)
char *driver_name;
int driver_reg_instance;


Arguments

driver_name
Specifies a null-terminated string that represents the name of the device driver whose I/O services interfaces you want to clear from the device switch table. You specified this name in a previous call to the devsw_add interface. The driver name must be at least two characters in length not to exceed DEVSW_NAME_LEN characters, including the null terminator. This name is a string that matches the string you specified for the entry_name item in the /etc/sysconfigtab database. Typically, third-party driver writers specify the driver name (followed by a colon) in the sysconfigtab file fragment, which gets appended to the /etc/sysconfigtab database during the driver product installation.

driver_reg_instance
Specifies an integer representing a specific reservation instance for this driver. This argument allows a driver to uniquely identify multiple major numbers for the driver. This is the integer you passed to the driver_reg_instance argument in a previous call to the devsw_add interface.


Description

The devsw_del interface clears a device driver's I/O services interfaces (and other information) from the device switch table. The interface continues to reserve the major number associated with the device driver.

The devsw_del interface performs appropriate checks on the value passed to the driver_name argument.


Notes

A device driver calls devsw_del to remove access to its associated I/O services interfaces but retain use of its reserved major number. For example, a device driver about to be unloaded might want to call devsw_del.


Example

See Writing Device Drivers: Tutorial for a code example of the devsw_del interface.


Return Values

Upon successful completion, the devsw_del interface returns the major number associated with the device driver whose I/O services interfaces were cleared from the device switch table. Otherwise, on an error, the devsw_del interface returns the value -1. The following list describes possible error conditions:


Related Information

devsw_add, devsw_get, dsent


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


devsw_get

Obtains a previously reserved major number


Synopsis

#include <sys/conf.h> int devsw_get (driver_name, driver_reg_instance)
char *driver_name;
int driver_reg_instance;


Arguments

driver_name
Specifies a null-terminated string that represents the name of the device driver whose major number you want to obtain from the device switch table. This name is a string that matches the string you specified for the entry_name item in the /etc/sysconfigtab database. Typically, third-party driver writers specify the driver name (followed by a colon) in the sysconfigtab file fragment, which gets appended to the /etc/sysconfigtab database during the driver product installation.

driver_reg_instance
Specifies an integer representing a specific reservation instance for this driver. This argument allows a driver to uniquely identify multiple major numbers for the driver.


Description

The devsw_get interface returns the major number associated with the specified device driver.

The devsw_get interface performs appropriate checks on the value passed to the driver_name argument.


Return Values

Upon successful completion, the devsw_get interface returns the major number associated with the specified device driver. Otherwise, on an error, the devsw_get interface returns the value -1. The following list describes possible error conditions:


Related Information

devsw_add, devsw_del, dsent


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_get_curr_sgentry

Returns a pointer to the current sg_entry


Synopsis

#include <io/common/devdriver.h> sg_entry_t dma_get_curr_sgentry (dma_handle)
dma_handle_t dma_handle;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.


Description

The dma_get_curr_sgentry interface returns a pointer to an sg_entry data structure. A device driver can use this pointer to retrieve the current bus address/byte count pair for the mapping of a block of an in-memory I/O buffer onto the controller's I/O bus. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer.

Specifically, dma_get_curr_sgentry returns a pointer to a bus address/byte count pair from the in-kernel DMA mapping data structures. Unlike dma_get_next_sgentry, a call to dma_get_curr_sgentry does not result in incrementing an internal index variable. Thus, subsequent calls to dma_get_curr_sgentry result in a return of the same sg_entry pointer and the same bus address/byte count pair.


Notes

Use of the dma_get_curr_sgentry interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_get_curr_sgentry interface.


Return Values

Upon successful completion, dma_get_curr_sgentry returns a pointer to the sg_entry structure associated with a mapped region of an I/O buffer on the controller's I/O bus. This sg_entry pointer is associated with the current bus address/byte count pair for this DMA handle. Otherwise, dma_get_curr_sgentry returns the value zero (0) to indicate it reached the end of bus address/byte count pairs for this DMA handle.


Related Information

dma_get_next_sgentry, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_get_next_sgentry

Returns a pointer to the next sg_entry


Synopsis

#include <io/common/devdriver.h> sg_entry_t dma_get_next_sgentry (dma_handle)
dma_handle_t dma_handle;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.


Description

The dma_get_next_sgentry interface returns a pointer to an sg_entry data structure. A device driver can use this pointer to retrieve the next valid bus address/byte count pair for the mapping of a block of an in-memory I/O buffer onto the controller's I/O bus. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer.

Specifically, dma_get_next_sgentry returns a pointer to a bus address/byte count pair from the in-kernel DMA mapping data structures. After each call to dma_get_next_sgentry, the interface increments an internal index variable. This contrasts with the dma_get_curr_sgentry interface, which does not perform an increment operation. This increment operation ensures that the next call to dma_get_next_sgentry gets the next sg_entry pointer and thus the next bus address/byte count pair for this DMA handle.


Notes

Use of the dma_get_next_sgentry interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_get_next_sgentry interface.


Return Values

Upon successful completion, dma_get_next_sgentry returns a pointer to the sg_entry structure associated with a mapped region of an I/O buffer on the controller's I/O bus. This sg_entry pointer is associated with the next bus address/byte count pair for this DMA handle. Otherwise, dma_get_next_sgentry returns the value zero (0) to indicate it reached the end of bus address/byte count pairs for this DMA handle.


Related Information

dma_get_curr_sgentry, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_get_private

Gets a data element from the DMA private storage space


Synopsis

#include <io/common/devdriver.h> int dma_get_private (dma_handle, index, data)
dma_handle_t dma_handle;
int index;
u_long *data;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

index
Specifies an index to the DMA private storage area for an internal kernel data structure associated with this DMA handle. Currently, you can pass only the value zero (0) as the index.

data
Specifies the address of the location to retrieve the 64-bit data element from the DMA private storage area. You put this 64-bit data element in the DMA private storage area in a previous call to dma_put_private.


Description

The dma_get_private interface retrieves a 64-bit data element from the DMA private storage area of the internal kernel data structure associated with the specified DMA handle. Device drivers can put a 64-bit data element in the DMA private storage area of this internal kernel data structure by calling dma_put_private. Currently, the internal kernel data structure provides only one member to store a 64-bit data element.

DMA engines that make multiple calls to dma_map_alloc and dma_map_load can use the dma_get_private and dma_put_private pair of interfaces. Each call to dma_map_alloc and dma_map_load returns the address of the allocated DMA handle. The device driver calls dma_put_private to store each returned address as the 64-bit data element in each internal kernel data structure's DMA private storage area. By storing each address as the 64-bit data element in each internal kernel data structure's DMA private storage area, the device driver creates a linked list of DMA handles that it can pass to some lower software layer. This lower software layer then calls dma_get_private to retrieve the resources contained in the linked list of DMA handles.


Notes

Use of the dma_get_private interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Return Values

Upon successful completion, dma_get_private returns the value zero (0). If the index to the private storage area is greater than zero (0), dma_get_private returns the value 1, indicating a failure status.


Related Information

dma_put_private, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_kmap_buffer

Returns a kernel segment (kseg) address of a DMA buffer


Synopsis

#include <io/common/devdriver.h> vm_offset_t dma_kmap_buffer (dma_handle, offset)
dma_handle_t dma_handle;
u_long offset;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

offset
Specifies a byte count offset from the virtual address passed as the virt_addr argument of the dma_map_load interface. This virtual address specifies the beginning of a process's (or kernel) buffer that a DMA transfer operation is done to or from. A device driver determines the smallest DMA transfer size by calling the dma_min_boundary interface. The offset specifies the number of bytes a DMA engine moved. This number is less than the number of bytes the dma_map_load interface loaded.


Description

The dma_kmap_buffer interface takes an offset variable and returns a kseg address. The device driver can use this kseg address to copy and save the data at the offset in the buffer. A device driver calls dma_kmap_buffer when the following occurs:

For example, a SCSI device performs a disconnect in the second byte of a longword on a TURBOchannel-based SCSI subsystem. The device driver uses the kseg address to read the valid data transferred so far, saves it in a dma_min_boundary sized buffer, and merges it back into the DMA buffer once the rest of the transfer has completed.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_kmap_buffer interface.


Return Values

Upon successful completion, dma_kmap_buffer returns a kseg address of the byte offset pointed to by the addition of the following two values:

virt_addr + offset

where:

The dma_kmap_buffer interface returns the value zero (0) to indicate failure to retrieve the kseg address.


Related Information

dma_map_load, dma_min_boundary, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_map_alloc

Allocates resources for DMA data transfers


Synopsis

#include <io/common/devdriver.h> u_long dma_map_alloc (byte_count, ctlr_p, dma_handle_p, flags)
u_long byte_count;
struct controller *ctlr_p;
dma_handle_t *dma_handle_p;
int flags;


Arguments

byte_count
Specifies the maximum size (in bytes) of the data to be transferred during the DMA transfer operation. The kernel uses this size to determine the resources (mapping registers, I/O channels, and other software resources) to allocate.

ctlr_p
Specifies a pointer to the controller structure associated with this controller. The interface uses this pointer to obtain the bus-specific interfaces and data structures that it needs to allocate the necessary mapping resources.

dma_handle_p
Specifies a pointer to a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

Typically, the device driver passes an argument of type dma_handle_t *. The dma_map_alloc interface returns to this variable the address of the DMA handle. The device driver uses this address in a call to dma_map_load.

flags
Specifies special conditions that the device driver needs the system to perform. You can pass the bitwise inclusive OR of the following special condition bits defined in /usr/sys/include/io/common/devdriver.h:
Value Meaning
DMA_GUARD_UPPER Allocates additional resources so that contiguous data overruns are captured by the system map error functions. This bit is probably most useful during device driver development and debugging.
DMA_GUARD_LOWER Allocates additional resources so that contiguous data underruns are captured by the system map error functions. This bit is probably most useful during device driver development and debugging.
DMA_SLEEP Puts the process to sleep if the system cannot allocate the necessary resources to perform a data transfer of size byte_count at the time the driver calls the interface.
DMA_IN Sets up a DMA write into main core memory.
DMA_OUT Sets up a DMA read from main core memory.
DMA_ALL Returns a nonzero value, only if the system can satisfy a DMA transfer of size byte_count.
DMA_CONTIG Signifies a request to the DMA mapping interface to provide a single sg_entry structure mapping of a buffer to which DMA access will be made (on an I/O bus by a DMA engine).


Description

The dma_map_alloc interface allocates the resources (mapping registers, I/O channels, and other hardware and software resources) for DMA data transfers. You specify the size of the DMA data transfer in the byte_count argument.

The dma_map_alloc interface returns to the dma_handle_p argument a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

The dma_map_alloc interface allocates only the necessary resources for a device driver to perform a maximum transfer of size byte_count. However, the maximum transfer size is the size of the returned byte count if the returned byte count is not equal to byte_count. All drivers must be prepared for a returned byte count that is less than byte_count. The reason for this is that system resources can have physical limits that may never satisfy an allocation request of size byte_count. To actually initialize and set up the resources, the driver must make a call to dma_map_load.

The dma_map_alloc interface does not put the process to sleep and returns the value zero (0) if both the following are true:

The DMA_CONTIG flag is a request for contiguous memory space on an I/O bus for a virtually mapped buffer in system memory space that may be physically discontiguous. The call to the dma_map_alloc or dma_map_load interface with the DMA_CONTIG flag will not fail if a contiguous I/O address space cannot be used to map the memory buffer, for example, if more than one sg_entry structure is returned. The device driver can determine if the DMA_CONTIG satisfied the request by comparing the byte count value of the bc member in the first returned sg_entry structure to the requested byte count in the byte_count argument of the dma_map_alloc or dma_map_load interface.

This flag is useful for I/O devices whose DMA typically crosses one or more (8 Kbyte) pages. This is because system hardware scatter-gather resources can be set up and used to do scatter-gather mapping of a virtually contiguous, physically discontiguous I/O buffer during the calls to dma_map_alloc or dma_map_load. This DMA mapping makes a physically discontiguous memory buffer appear physically contiguous to an I/O device on an I/O bus.

Even if an I/O device's DMA engine has scatter-gather resources or support, DMA is typically faster if the system scatter-gather resources are used. This is due to the system's lower overhead to set up scatter-gather resources relative to an I/O device reading and processing multiple scatter-gather data structures.


Notes

Use of the dma_map_alloc interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_map_alloc interface.


Return Values

Upon successful completion, dma_map_alloc returns a byte count (in bytes) that indicates the DMA transfer size it can map. It returns the value zero (0) to indicate a failure.

If the device driver sets flags to DMA_ALL, then dma_map_alloc returns a nonzero value only if the system can satisfy a transfer size of byte_count. This means that if the system cannot support a transfer of size byte_count (even if all DMA resources were made available), dma_map_alloc refuses to allocate any portion of the resources associated with the specified byte_count and returns a byte count of zero (0). This behavior no allocation of resources unless dma_map_alloc can allocate the resources needed to do an uninterruptible transfer of the requested size avoids extra calls to dma_map_dealloc.

If the returned byte count equals byte_count, then dma_map_alloc has allocated all of the resources necessary to allow the DMA transfer, without additional system resource allocation.

If the returned byte count does not equal byte_count, the device driver can perform one of the following tasks:


Related Information

controller, dma_map_dealloc, dma_map_load, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_map_dealloc

Releases and deallocates the DMA resources previously allocated for DMA data transfers


Synopsis

#include <io/common/devdriver.h> int dma_map_dealloc (dma_handle)
dma_handle_t dma_handle;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.


Description

The dma_map_dealloc interface releases and deallocates the resources for DMA data transfers that were previously allocated in a call to dma_map_alloc or dma_map_load.


Notes

Use of the dma_map_dealloc interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_map_dealloc interface.


Return Values

Upon successful completion, dma_map_dealloc returns the value 1. Otherwise, it returns the value zero (0).


Related Information

dma_map_alloc, dma_map_load, dma_map_unload, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_map_load

Loads and sets allocated DMA resources and sets up a DMA data path for DMA data transfers


Synopsis

#include <io/common/devdriver.h> u_long dma_map_load (byte_count, virt_addr, proc_p, ctlr_p, dma_handle_p, max_byte_count, flags)
u_long byte_count;
vm_offset_t virt_addr;
struct proc *proc_p;
struct controller *ctlr_p;
dma_handle_t *dma_handle_p;
u_long max_byte_count;
int flags;


Arguments

byte_count
Specifies the maximum size (in bytes) of the data to be transferred during the DMA transfer operation. The kernel uses this size to determine the resources (mapping registers, I/O channels, and other software resources) to allocate, load, and set.

virt_addr
Specifies the virtual address where the DMA transfer occurs. The interface uses this address with the pointer to the proc structure to obtain the physical addresses of the system memory pages to load into DMA mapping resources.

proc_p
Specifies a pointer to the proc structure associated with the valid context for the virtual address specified in virt_addr. The interface uses this pointer to retrieve the pmap that is needed to translate this virtual address to a physical address. If proc_p is equal to zero (0), the address is a kernel address.

ctlr_p
Specifies a pointer to the controller structure associated with this controller. The dma_map_load interface uses the pointer to get the bus-specific interfaces and data structures that it needs to load and set the necessary mapping resources.

dma_handle_p
Specifies a pointer to a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

Typically, the device driver passes an argument of type dma_handle_t *. If the device driver called dma_map_alloc prior to calling dma_map_load, then dma_map_alloc returns to this argument the address of the allocated DMA handle. The dma_map_load interface can then use this handle to load the appropriate DMA mapping resources. If the device driver did not call dma_map_alloc prior to calling dma_map_load, then you must set the dma_handle_p argument to the value zero (0). Upon completing execution, dma_map_load returns a valid DMA handle to dma_handle_p.

max_byte_count
Specifies the maximum-size byte-count value that should be stored in the bc members of the sg_entry structures.

flags
Specifies special conditions that the device driver needs the system to perform. You can pass the bitwise inclusive OR of the following special condition bits defined in /usr/sys/include/io/common/devdriver.h:
.po -0.5i  
Value Meaning
DMA_GUARD_UPPER Allocates additional resources so that contiguous data overruns are captured by the system map error functions. This bit is probably most useful during device driver development and debugging.
DMA_GUARD_LOWER Allocates additional resources so that contiguous data underruns are captured by the system map error functions. This bit is probably most useful during device driver development and debugging.
DMA_SLEEP Puts the process to sleep if the system cannot allocate the necessary resources to perform a data transfer of size byte_count at the time the driver calls the interface.
DMA_IN Sets up a DMA write into main core memory.
DMA_OUT Sets up a DMA read from main core memory.
DMA_ALL Returns a nonzero value, only if the system can satisfy a DMA transfer of size byte_count.
DMA_CONTIG Signifies a request to the DMA mapping interface to provide a single sg_entry structure mapping of a buffer to which DMA access will be made (on an I/O bus by a DMA engine).


Description

The dma_map_load interface loads and sets the system resources necessary to perform a DMA transfer of size byte_count to the virtual address specified in the virt_addr argument. This virtual address must be valid in the context of the process's proc structure, specified in the proc_p argument.

If the device driver calls dma_map_alloc prior to calling dma_map_load, then dma_map_alloc returns to dma_handle_p the address of the allocated DMA handle. The dma_map_load interface uses this handle to load and set the appropriate DMA mapping resources. If the device driver did not call dma_map_alloc prior to calling dma_map_load, then you must set dma_handle_p to the value zero (0). In this case, dma_map_load allocates the appropriate DMA mapping resources (just as if the allocation were done in a previous call to the dma_map_alloc interface) and loads and sets the resources as necessary.

The DMA_CONTIG flag is a request for contiguous memory space on an I/O bus for a virtually mapped buffer in system memory space that may be physically discontiguous. The call to the dma_map_alloc or dma_map_load interface with the DMA_CONTIG flag will not fail if a contiguous I/O address space cannot be used to map the memory buffer, for example, if more than one sg_entry structure is returned. The device driver can determine if the DMA_CONTIG satisfied the request by comparing the byte count value of the bc member in the first returned sg_entry structure to the requested byte count in the byte_count argument of the dma_map_alloc or dma_map_load interface.

This flag is useful for I/O devices whose DMA typically crosses one or more (8 Kbyte) pages. This is because system hardware scatter-gather resources can be set up and used to do scatter-gather mapping of a virtually contiguous, physically discontiguous I/O buffer during the calls to dma_map_alloc or dma_map_load. This DMA mapping makes a physically discontiguous memory buffer appear physically contiguous to an I/O device on an I/O bus.

Even if an I/O device's DMA engine has scatter-gather resources or support, DMA is typically faster if the system scatter-gather resources are used. This is due to the system's lower overhead to set up scatter-gather resources relative to an I/O device reading and processing multiple scatter-gather data structures.


Notes

Use of the dma_map_load interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_map_load interface.


Return Values

Upon successful completion, dma_map_load returns a byte count (in bytes) that indicates the DMA transfer size it can support. It returns the value zero (0) to indicate a failure.

If the device driver sets flags to DMA_ALL, then dma_map_load returns a nonzero value only if the system can satisfy a transfer size of byte_count. This means that if the system cannot support a transfer of size byte_count (even if all DMA resources were made available), dma_map_load refuses to allocate any portion of the resources associated with the specified byte_count and returns a byte count of zero (0). This behavior no allocation of resources unless dma_map_load can allocate the resources needed to do an uninterruptible transfer of the requested size avoids extra calls to dma_map_dealloc.

If the returned byte count equals byte_count, then dma_map_load has allocated, loaded, and set all of the resources necessary to allow the DMA transfer, without additional system resource allocation.

If the returned byte count does not equal byte_count, the device driver can perform one of the following tasks:


Related Information

dma_map_alloc, dma_map_dealloc, dma_map_unload, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_map_unload

Unloads the system DMA resources


Synopsis

#include <io/common/devdriver.h> int dma_map_unload (flags, dma_handle)
int flags;
dma_handle_t dma_handle;


Arguments

flags
To cause a deallocation of DMA mapping resources, you set the first argument to the special condition bit DMA_DEALLOC.

This bit setting is analogous to setting the dma_handle_p argument to the value zero (0) for dma_map_load to allocate the DMA mapping resources.

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.


Description

The dma_map_unload interface unloads (invalidates) the resources that were loaded and set up in a previous call to dma_map_load. A call to dma_map_unload does not release or deallocate the resources that were allocated in a previous call to dma_map_alloc unless the driver sets the flags argument to the DMA_DEALLOC bit.


Notes

Use of the dma_map_unload interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_map_unload interface.


Return Values

Upon successful completion, dma_map_unload returns the value 1. Otherwise, it returns the value zero (0).


Related Information

dma_map_alloc, dma_map_dealloc, dma_map_load, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_min_boundary

Returns system-level information


Synopsis

#include <io/common/devdriver.h> int dma_min_boundary (ctlr_p)
struct controller *ctlr_p;


Arguments

ctlr_p
Specifies a pointer to the controller structure associated with this controller. The dma_min_boundary interface uses this pointer to obtain the system and bus-specific information needed to return the mask or integer value.


Description

The dma_min_boundary interface returns an integer value that provides the information necessary for a device driver to determine the smallest DMA transfer that can be done atomically on a CPU or bus. The value returned by dma_min_boundary depends on the type of CPU or bus. For example, on a DEC 3000 Model 500 AXP Workstation connected to a TURBOchannel bus, this interface returns a value of 4. This indicates that a TURBOchannel DMA operation is atomic at the longword level (not the byte or word level). On a DEC 2000 Model 300 connected to an EISA bus, for example, this interface returns a value of 1 to indicate byte atomicity. Subbyte atomicity is not supported.

On a DEC 3000 Model 500 AXP Workstation connected to a TURBOchannel bus, this return value of 4 informs a device driver about how to handle a DMA transfer that involves a buffer that begins and/or ends within a nonlongword aligned, nonintegral longword-sized (DMA) transfer. The device driver handles this DMA transfer by redirecting the beginning and/or end of the DMA transfer, respectively, to other buffers that must be merged to the main (aligned longword block) buffer through calls to bcopy.


Return Values

The dma_min_boundary interface returns the value zero (0) to indicate that the system initialization code did not set up this field. Otherwise, dma_min_boundary returns the byte-size atomicity value that the system supports for DMA operations for all controllers on the respective bus.


Related Information

controller


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_put_curr_sgentry

Puts a new bus address/byte count pair in the linked list of sg_entry structures


Synopsis

#include <io/common/devdriver.h> int dma_put_curr_sgentry (dma_handle, sg_entryp)
dma_handle_t dma_handle;
sg_entry_t sg_entryp;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

sg_entryp
Specifies a pointer to the sg_entry structure that contains the bus address/byte count values to replace the corresponding bus address/byte count of the sg_entry structure associated with this DMA handle. You set the bus address/byte count in the ba and bc members of the sg_entry structure and then pass its address to dma_put_curr_sgentry.


Description

The dma_put_curr_sgentry interface puts new bus address/byte count values into the ba and bc members for the existing bus address/byte count pair pointed to by the DMA handle passed in by you. This interface enables device drivers to patch an existing bus address/byte count pair due to an unexpected interruption in a DMA transfer. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer.

This interface is useful for DMA engines that do not have total control of a DMA transfer. For example, a SCSI device doing an unexpected disconnect in the middle of a block transfer can interrupt a SCSI controller. Such a disconnect can require the driver to do one or more patches to the list of bus address/byte count pairs in order to restart the DMA transfer (without starting from the beginning of the list). Device drivers call the dma_put_curr_sgentry and dma_put_prev_sgentry interfaces to accomplish these patch operations. Typically, only buses that do not have byte atomicity transfers (for example, the TURBOchannel bus on Alpha CPUs) require these patch operations.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_put_curr_sgentry interface.


Return Values

Upon successful completion, dma_put_curr_sgentry returns the value 1. Otherwise, dma_put_curr_sgentry returns the value zero (0) to indicate a failure. This failure indicates that the index into the DMA handle points past the end of the last bus address/byte count pair. The DMA handle can point past the end of the valid portion of the list when the previous call to dma_get_next_sgentry returned the pointer to the DMA handle associated with the last byte address/byte count pair.


Related Information

dma_get_curr_sgentry, dma_get_next_sgentry, dma_put_prev_sgentry, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_put_prev_sgentry

Updates an internal pointer index to the linked list of sg_entry structures


Synopsis

#include <io/common/devdriver.h> int dma_put_prev_sgentry (dma_handle, sg_entryp)
dma_handle_t dma_handle;
sg_entry_t sg_entryp;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

sg_entryp
Specifies a pointer to the sg_entry structure that contains the bus address/byte count values to replace the corresponding bus address/byte count of the sg_entry structure associated with this DMA handle. The device driver writer sets the bus address/byte count in the ba and bc members of the sg_entry structure and then passes its address to dma_put_prev_sgentry.


Description

The dma_put_prev_sgentry interface updates an internal pointer index to the linked list of sg_entry structures, and then puts new bus address/byte count values into the existing bus address/byte count pair pointed to by the DMA handle passed in by you. This interface enables device drivers to patch existing bus address/byte count pairs due to an unexpected interruption in a DMA transfer. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer.

This interface is useful for DMA engines that do not have total control of a DMA transfer. For example, a SCSI device doing an unexpected disconnect in the middle of a block transfer can interrupt a SCSI controller. Such a disconnect can require the driver to do one or more patches to the list of bus address/byte count pairs in order to restart the DMA transfer (without starting from the beginning of the list). Device drivers call the dma_put_curr_sgentry and dma_put_prev_sgentry interfaces to accomplish these patch operations. Typically, only buses that do not have byte atomicity transfers (for example, the TURBOchannel bus on Alpha CPUs) require these patch operations.

The dma_put_prev_sgentry differs from dma_put_curr_sgentry in that it updates an internal pointer index before inserting the new bus address/byte count values into the existing bus address/byte count pair. The pointer-index retains this updated value after dma_put_prev_sgentry returns.


Example

See Writing Device Drivers: Tutorial for a code example of the dma_put_prev_sgentry interface.


Return Values

Upon successful completion, dma_put_prev_sgentry returns the value 1. Otherwise, dma_put_prev_sgentry returns the value zero (0) to indicate failure. This failure indicates that the index into the DMA handle points to the first element in the byte address/byte count list. In this case, there is no previous byte address/byte count entry to patch.


Related Information

dma_put_curr_sgentry, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dma_put_private

Stores a data element in the DMA private storage space


Synopsis

#include <io/common/devdriver.h> int dma_put_private (dma_handle, index, data)
dma_handle_t dma_handle;
int index;
u_long data;


Arguments

dma_handle
Specifies a handle to DMA resources associated with the mapping of an in-memory I/O buffer onto a controller's I/O bus. This handle provides the information to access bus address/byte count pairs. A bus address/byte count pair is represented by the ba and bc members of an sg_entry structure pointer. Device driver writers can view the DMA handle as the tag to the allocated system resources needed to perform a DMA operation.

index
Specifies an index to the DMA private storage area for an internal kernel data structure associated with this DMA handle. Currently, you can pass only the value zero (0) as the index.

data
Specifies the address of the location to return the 64-bit data element from the DMA private storage area. The 64-bit data element is put in the DMA private storage area by a previous call to dma_get_private.


Description

The dma_put_private interface stores a 64-bit data element in the DMA private storage area of the internal kernel data structure associated with the specified DMA handle. Device drivers call dma_get_private to retrieve a 64-bit data element from the DMA private storage of this internal kernel data structure. Currently, the internal kernel data structure provides only one member to store a 64-bit data element.

DMA engines that make multiple calls to dma_map_alloc and dma_map_load can use the dma_get_private and dma_put_private pair of interfaces. Each call to dma_map_alloc and dma_map_load returns the address of the allocated DMA handle. The device driver calls dma_put_private to store each returned address as the 64-bit data element in each internal kernel data structure's DMA private storage area. By storing each address as the 64-bit data element in each internal kernel data structure's DMA private storage area, the device driver creates a linked list of DMA handles that it can pass to some lower software layer. This lower software layer then calls dma_get_private to retrieve the resources contained in the linked list of DMA handles.


Notes

Use of the dma_put_private interface makes device drivers more portable between DMA hardware-mapping implementations across different hardware platforms because it masks out any future changes in the kernel- and system-level DMA mapping data structures.


Return Values

Upon successful completion, dma_put_private returns the value 1. If the index to the private storage area is greater than zero (0), dma_put_private returns the value zero (0), indicating a failure status.


Related Information

dma_get_private, sg_entry


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


do_config

Initializes the device to its assigned configuration


Synopsis

void do_config (ctlr_p)
struct controller *ctlr_p;


Arguments

ctlr_p
Specifies a pointer to the controller structure associated with the controller to be configured. The do_config interface obtains the device to initialize through its controller's associated controller structure pointer.


Description

The do_config interface initializes the specified controller based on its power-up resource assignments. If the device uses either an interrupt or a DMA channel, then do_config also performs any setup requirements. For example, for controllers that connect to the EISA bus, do_config initializes the controller according to the parameters specified in the EISA configuration file.


Notes

The do_config interface is a generic interface that maps to a bus-specific interface that actually initializes the specified device. Using this interface to initialize a device makes the driver more portable across different bus architectures. Not all buses support the do_config interface.


Return Values

None


Related Information

controller, get_config, get_info


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


drvr_register_flush

Registers or deregisters a flush interface


Synopsis

void drvr_register_flush (callback, parameter, flags)
void (*callback) ();
caddr_t parameter;
int flags;


Arguments

callback
Specifies the name of the device driver interface to be registered or deregistered by drvr_register_flush. When registered, this is the flush interface that the kernel calls just prior to system shutdown.

parameter
Specifies a parameter that the device driver needs the kernel to pass to the registered driver flush interface. For example, you could pass a pointer to a device structure and the kernel passes this to the driver's registered flush interface.

flags
Specifies whether to register or deregister the device driver's flush interface. You can pass one of the following constants:
Value Meaning
DRVR_REGISTER Registers a device driver's flush interface.
DRVR_UNREGISTER Deregisters a device driver's flush interface.


Description

The drvr_register_flush interface registers or deregisters a flush interface to be called when the system performs a system shutdown. The kernel calls this interface just prior to system shutdown. The drvr_register_flush interface allows device drivers to ensure that all I/O to a bus adapter has been completed. Some bus adapters are asynchronous to the system bus (containing buffers) and need to be cleared out (that is, flushed).


Notes

Device drivers should call the drvr_register_flush interface if it is necessary to call a flush interface before the kernel performs a dump operation. Device drivers should call the drvr_register_shutdown interface if it is necessary to call a shutdown interface that the kernel calls after it performs the dump operation.


Cautions

The drvr_register_flush interface causes a system crash and displays an appropriate message on the console terminal if you specify an invalid bit in the flags argument.

The flush interface that you register should never acquire a simple or complex lock. The reason for this is that on a panic, the kernel's call to the flush interface can cause the CPU to double panic, hang, or both if the callback interface tries to access locks that were taken through active code paths at the time of the panic. This double panic or hang of the CPU would result in no crash dump for diagnosis. A hang of the CPU can require operator intervention to restart the CPU.


Return Values

None


Related Information

drvr_register_shutdown xxflush


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


drvr_register_shutdown

Registers or deregisters a shutdown interface


Synopsis

void drvr_register_shutdown (callback, parameter, flags)
void (*callback) ();
caddr_t parameter;
int flags;


Arguments

callback
Specifies the name of the device driver interface to be registered or deregistered by drvr_register_shutdown. When registered, this is the interface that the kernel calls when the system shuts down or halts.

parameter
Specifies a parameter that you want the kernel to pass to the device driver's registered shutdown interface. For example, you could pass a pointer to a softc structure or a pointer to a unit-specific data structure and the kernel passes it to the driver's registered shutdown interface.

flags
Specifies whether to register or deregister the device driver's shutdown interface. You can pass one of the following constants:
Value Meaning
DRVR_REGISTER Registers a device driver shutdown interface.
DRVR_UNREGISTER Deregisters a device driver's shutdown interface.


Description

The drvr_register_shutdown interface registers or deregisters a shutdown interface for the calling device driver. Device drivers call drvr_register_shutdown to register a device driver shutdown interface that the kernel calls at system shutdown time (or when the user halts the system).

The drvr_register_shutdown interface allows device drivers to register interfaces that turn off the hardware device before the system shuts down. For example, a device driver that operates on a SCSI bus connected to two host CPUs (Available Server Environment) must ensure that the SCSI adapter on the shutdown host CPU is not doing work on the bus.


Notes

Device drivers should call the drvr_register_shutdown interface if it is necessary to call a shutdown interface that the kernel calls after it performs the dump operation. Device drivers should call the drvr_register_flush interface if it is necessary to call a flush interface before the kernel performs a dump operation.


Cautions

The drvr_register_shutdown interface causes a system crash and displays an appropriate message on the console terminal if the device driver writer sets an invalid bit in the flags argument.

The shutdown interface that you register should never acquire a simple or complex lock. The reason for this is that on a panic, the kernel's call to the shutdown interface can cause the CPU to double panic, hang, or both if the callback interface tries to access locks that were taken through active code paths at the time of the panic. This double panic or hang of the CPU would result in no crash dump for diagnosis. A hang of the CPU can require operator intervention to restart the CPU.

After the system has performed the crash dump and a panic occurs, the kernel's call to the shutdown interface can cause the CPU to double panic, hang, or both. This double panic or hang of the CPU can be the result of the following activities:


Return Values

None


Related Information

drvr_register_flush xxshutdown


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dupb

Duplicates a message block descriptor


Synopsis

#include <sys/stream.h> MBLKP dupb (message_block_ptr)
MBLKP message_block_ptr;


Arguments

message_block_ptr
Specifies a pointer to the message block to be duplicated. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The dupb interface creates a new message block structure to reference the message block pointed to by the message_block_ptr argument. Unlike copyb, the dupb interface does not copy the information in the data block, but creates a new structure to point to it. The new message block structure contains the same information as the first message block structure.


Return Values

Upon successful completion, the dupb interface returns a pointer to the newly allocated message block. This newly allocated message block is of type struct msgb *. The msgb data structure is defined in the /usr/sys/include/sys/stream.h file.

Otherwise, dupb returns a NULL pointer.


Related Information

copyb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


dupmsg

Duplicates a message


Synopsis

#include <sys/stream.h> MBLKP dupmsg (message_block_ptr)
MBLKP message_block_ptr;


Arguments

message_block_ptr
Specifies a pointer to the message block. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The dupmsg interface forms a new message by copying the message block descriptors pointed to by the message_block_ptr argument and linking them. The dupmsg interface calls dupb for each message block. The data blocks themselves are not duplicated.


Return Values

Upon successful completion, the dupmsg interface returns a pointer to the newly allocated message block. This newly allocated message block is of type struct msgb *. The msgb data structure is defined in the /usr/sys/include/sys/stream.h file.

Otherwise, dupmsg returns a NULL pointer.


Related Information

copyb, copymsg, dupb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


enableok

Enables a queue for service


Synopsis

#include <sys/stream.h> void enableok (queue_pointer)
queue_t *queue_pointer;


Arguments

queue_pointer
Specifies a pointer to the queue to be rescheduled. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The enableok interface allows the queue associated with the queue_pointer argument to be rescheduled for service. The interface cancels the effect of a previous call to the noenable interface on the queue by turning off the QNOENB flag in the queue.


Return Values

None


Related Information

noenable, qenable

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


esballoc

Allocates a message block with a shared buffer


Synopsis

#include <sys/stream.h> mblk_t * esballoc (base, size, pri, free_rtnp)
unsigned char *base;
int size;
int pri;
frtn_t *free_rtnp;


Arguments

base
Specifies the address of the user-supplied data buffer.

size
Specifies the number of bytes in the data buffer.

pri
Specifies the priority of the allocation request (to be used by the allocb interface, which esballoc calls).

free_rtnp
Specifies the free interface (routine) data structure.


Description

The esballoc interface creates a STREAMS message and attaches a user-supplied data buffer in place of a STREAMS data buffer. The interface calls allocb to obtain a message and data block header. The user-supplied data buffer, pointed to by the base argument, is used as the data buffer for the message.

The free_rtn structure is referenced by the dp_freep member of the datab structure. When the freeb interface is called to free the message, the driver's message free interface (referenced through the free_rtn structure) is called, with arguments, to free the data buffer.

The free_rtn structure is defined as follows:

/* Free return structure for esballoc */
typedef struct free_rtn {
  void    (*free_func)(char *, char *); /* Interface to free buffer */
  char *  free_arg;                     /* Parameter to free_func */
} frtn_t;

Instead of requiring a specific number of arguments, the free_arg member is of type char *. This way, the driver can pass a pointer to a structure if more than one argument is needed.


Notes

The free_func interface must be defined in kernel space and should be declared void. It has no user context and must not sleep.


Return Values

Upon successful completion, the esballoc interface returns a pointer to the newly allocated message block. This message block is of type struct msgb *. The msgb data structure is defined in the /usr/sys/include/sys/stream.h file.

On failure, esballoc returns a NULL pointer.


Related Information

allocb, freeb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


ffs

Finds the first set bit in a mask


Synopsis

int ffs (mask)
long mask;


Arguments

mask
Specifies a bit mask with zero (0) or more bits set.


Description

The ffs interface returns the bit position of the first bit you set in the mask argument. The scan proceeds from the least significant bit to the most significant bit of the mask.


Notes

The ffs interface duplicates the behavior of the ffs instruction on the Digital VAX series computers. It is not present in architectures that implement its function in hardware or through compiler inline substitution.

The ffs interface is useful for translating bits in a bit mask into bit positions. For example, the signal handling code uses it to analyze the signal mask.


Return Values

Upon successful completion, ffs returns the bit position of the first bit set in the mask. If no bits were set in the mask, ffs returns the value zero (0).


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


flushband

Flushes messages for a specified priority band


Synopsis

#include <sys/stream.h> void flushband (queue, pri, flag)
queue_t *queue;
unsigned char pri;
int flag;


Arguments

queue
Specifies a pointer to the queue. The typedef queue_t is an alternate name for struct queue_entry *.

pri
Specifies the priority of the message to be flushed.

flag
Specifies one of the following flag flush values:
Value Meaning
FLUSHDATA Flush only data messages. These data messages are represented by the M_DATA, M_DELAY, M_PROTO, and M_PCPROTO constants.
FLUSHALL Flush all messages. Requests a realtime delay


Description

The flushband interface flushes messages associated with the priority band specified by the pri argument. If pri is zero (0), flushband flushes only normal and high priority messages. Otherwise, flushband flushes messages from the priority band specified by the pri argument according to the value passed to the flag argument.


Return Values

None


Related Information

flushq

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


flushq

Removes a message from a queue


Synopsis

#include <sys/stream.h> void flushq (queue, flag)
queue_t *queue;
int flag;


Arguments

queue
Specifies a pointer to the queue to be flushed. The typedef queue_t is an alternate name for struct queue_entry *.

flag
Specifies one of the following flag flush values:
Value Meaning
FLUSHDATA Flush only data messages. These data messages are represented by the M_DATA, M_DELAY, M_PROTO, and M_PCPROTO constants.
FLUSHALL Flush all messages. Requests a realtime delay


Description

The flushq interface frees messages and their associated data structures by calling the freemsg interface. If the queue's count falls below the low-water mark and the QWANTW bit is set, flushq enables the nearest upstream service procedure.


Return Values

None


Related Information

flushband, freemsg, putq

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


FREE

Deallocates (frees) the allocated kernel virtual memory


Synopsis

#include <sys/malloc.h> FREE (addr, type)
void *addr;
int type;


Arguments

addr
Specifies the memory pointer that points to the allocated memory to be freed. You must have previously set this pointer in the call to MALLOC. You also define the data type for this argument in the call to MALLOC.

type
Specifies the purpose for which the memory is being allocated. The memory types are defined in the file malloc.h. Typically, device drivers use the constant M_DEVBUF to indicate that device driver memory is being allocated (or freed).


Description

The FREE interface (macro) deallocates (frees) the allocated kernel virtual memory, which you allocated in a previous call to MALLOC.


Notes

In previous versions of the operating system, device drivers could call the following memory allocation-related interfaces:

Digital UNIX still provides backwards compatibility with the kalloc, kfree, and kget interfaces and the zinit, zchange, zalloc, zfree, and zget interfaces. However, Digital recommends that for new device drivers you use the MALLOC and FREE interfaces to allocate and to free sections of kernel virtual memory.

A memory corruption can occur if a device driver continues to use the memory after freeing it. Digital UNIX provides a built-in mechanism to debug such erroneous use of memory. You can enable this debugging feature at boot time by providing the following boot parameter: kmem_debug=1. When you enable this debugging feature, the free interface stores the following in the last word of freed memory:

The malloc interface checks the checksum of the memory content before reallocating this corrupted memory. If the checksum of the memory content does not match the corrupted memory, malloc stores the debug information and then causes the kernel to panic. The malloc interface stores the address and size of the corrupted memory and the pc of the interface that last freed it in a kmem_corrupt_data structure.

You should consider the following when using this debugging feature:


Example

See Writing Device Drivers: Tutorial for a code example of the FREE interface.


Return Values

None


Related Information

MALLOC


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


freeb

Frees a message block


Synopsis

#include <sys/stream.h> void freeb (message_block_ptr)
MBLKP message_block_ptr;


Arguments

message_block_ptr
Specifies a pointer to the message block to be deallocated. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The freeb interface deallocates a message block. If the reference count of the db_ref member of the datab structure is greater than the value 1, freeb decrements the count. If db_ref equals the value 1, freeb deallocates the message block and the corresponding data block and buffer.

If the data buffer to be freed was allocated in a call to the esballoc interface, the buffer may be a non-STREAMS resource. In that case, the driver must be notified that the attached data buffer needs to be freed by calling the driver's freeing interface. To make this process independent of the driver used in the stream, freeb finds the free_rtn structure associated with the buffer. The free_rtn structure contains a pointer to the driver-independent interface that releases the buffer. Once this is accomplished, freeb releases the STREAMS resources associated with the buffer.


Return Values

None


Related Information

allocb, dupb, esballoc

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


freemsg

Frees all message blocks in a message


Synopsis

#include <sys/stream.h> void freemsg (message_block_ptr)
MBLKP message_block_ptr;


Arguments

message_block_ptr
Specifies a pointer to the message block to be deallocated. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The freemsg interface calls the freeb interface to free all message and data blocks associated with the message pointed to by the message_block_ptr argument.


Return Values

None


Related Information

freeb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


fubyte

Returns a byte from user address space


Synopsis

int fubyte (user_src)
char *user_src;


Arguments

user_src
Specifies the address in user space from which to read the byte.


Description

The fubyte interface returns 1 byte from the unprotected user address space to the calling program.


Notes

If the size of the return value is larger than 1 byte, the byte actually used for the return value is implementation defined.


Return Values

Upon successful completion, fubyte returns a value greater than zero (0). Otherwise, it returns -1, indicating that the user address specified in user_src cannot be accessed.


Related Information

copyinstr, fuword, subyte, suword


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


fuibyte

Returns a byte from user instruction address space


Notes

The fuibyte interface is for machines that have separate address spaces for code and data. Because the Alpha architecture does not have separate address spaces for code and data, fuibyte is mapped to fubyte. The fuibyte interface is provided for compatibility reasons. See the interface description for fubyte for a complete description of fuibyte.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


fuiword

Returns a word from user instruction address space


Notes

The fuiword interface is for machines that have separate address spaces for code and data. Because the Alpha architecture does not have separate address spaces for code and data, fuiword is mapped to fuword. The fuiword interface is provided for compatibility reasons. See the interface description for fuword for a complete description of fuiword.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


fuword

Returns a word from user instruction address space


Synopsis

int fuword (user_src)
char *user_src;


Arguments

user_src
Specifies the address in user space from which to read the word.


Description

The fuword interface returns one word from the unprotected user address space to the calling program.


Return Values

Upon successful completion, fuword returns a value greater than zero (0). Otherwise, it returns -1, indicating that the user address specified in user_src cannot be accessed.


Related Information

copyinstr, fubyte, subyte, suword


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


get_config

Returns assigned configuration data for a device


Synopsis

int get_config (ctlr_p, config_item, func_type, data_p, handle)
struct controller *ctlr_p;
uint_t config_item;
char *func_type;
void *data_p;
int handle;


Arguments

ctlr_p
Specifies a pointer to the controller structure associated with the controller to be configured. The get_config interface obtains the device whose assigned configuration data you want through its controller's associated controller structure pointer.

config_item
Specifies the configuration data item you want to obtain for the specified device. You can pass one of the following constants:
Value Meaning
RES_MEM Obtains bus memory characteristics.
RES_IRQ Obtains interrupt channel characteristics assigned to the device.
RES_DMA Obtains the DMA channel assigned to the device.
RES_PORT Obtains the I/O port assignments for the device.

func_type
Specifies a bus-specific argument. Some bus or bus adapters do not use this argument. For the EISA bus, this argument specifies the function type string that appears in the device's eisa_option structure.

data_p
Specifies a pointer to a structure appropriate for storing the requested data. The void * data type means that you cast the data_p argument's data type to the structure that stores the requested data.

handle
Specifies a handle returned by get_config if there is more configuration data of the type requested in the config_item argument. You must pass the value zero (0) on the first call to get_config. On subsequent calls to get_config for this configuration data type, you pass the value returned in the previous call to get_config.


Description

The get_config interface returns configuration data information assigned to the specified device.


Notes

The get_config interface is a generic interface that maps to a bus-specific interface that actually returns the assigned configuration data for the specified device. Using this interface to obtain configuration information makes the driver more portable across different bus architectures.


Return Values

If the bus option has only one resource of the requested config_item, get_config stores its value in the data_p argument and returns the value zero (0).

If the bus option has multiple resources of the requested config_item, get_config stores the value at the top of the list in the data_p argument and returns a handle that points to the next element in the list. To obtain the next element in the list, call get_config again and pass the returned handle to the handle argument. After reading all of the elements in the list, get_config returns the value zero (0).

If the bus option does not have a resource of the requested func_type, get_config returns the value -1.


Related Information

controller, do_config, get_info


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


get_def_partitionmap

Calculates a default partition map


Synopsis

int get_def_partitionmap (geom, pmap)
register struct DEVGEOMST *geom;
register struct pt_tbl *pmap;


Arguments

geom
Specifies a pointer to the disk's geometry structure.

pmap
Specifies a pointer to the partition map to be filled in.


Description

The get_def_partitionmap interface calculates a default partition map when supplied with a disk geometry. It uses the disk capacity and sector size for the calculation and ignores other aspects of the geometry. The partitions are layed out as follows:

The get_def_partitionmap interface is called by a disk device driver's open interface and DIOCGDEFPT ioctl command to create a default partition map.


Example

See Writing Device Drivers: Advanced Topics for a code example of the get_def_partitionmap interface.


Return Values

Upon successful completion, get_def_partitionmap returns the value zero (0). Otherwise, it returns the value 1 to indicate the partition map could not be updated.


Related Information

DEVGEOMST, DEVGETGEOM, pt_tbl


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


get_info

Returns system-specific information


Synopsis

#include <devdriver.h> u_int get_info (item_list)
struct item_list *item_list;


Arguments

item_list
Specifies a linked list of information requests.


Description

The get_info interface returns system-specific data assigned to the hardware platform that the driver operates on. For example, a device driver might request system-specific information for the following Alpha hardware platforms: DEC 3000 Model 300 AXP Workstation, DEC 3000 Model 500 AXP Workstation, and DEC 4000 Model 610 AXP System.

The get_info interface checks the function code that you pass in the function member of the item_list data structure. If the hardware platform that the driver operates on supports the system item associated with this function code, get_info returns the system-specific data for the system item in the output_data member of the item_list structure. For example, get_info returns the TURBOchannel clock speed in the output_data member of the item_list structure if you specify the constant GET_TC_SPEED in the function member of the item_list structure.

The get_info interface then performs the identical checks for the rest of the item_list structures in the linked list.


Notes

The get_info interface is a generic interface that maps to a hardware platform-specific interface that actually returns the assigned CPU-specific data for the specified CPU. Using this interface to obtain CPU-specific information makes the driver more portable across different CPU architectures and different CPU types within the same architecture.


Return Values

The return value from the get_info interface depends on the following issues:

If get_info returns the value TRUE, it returns one of the following values in the rtn_status member of the item_list data structure:
Value Meaning
INFO_RETURNED Indicates that the hardware platform that the driver currently operates on supports the requested system item.
NOT_SUPPORTED Indicates that the hardware platform that the driver operates on does not support the requested system item.


Related Information

do_config, get_config, item_list


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


getnewbuf

Allocates a buf structure


Synopsis

struct buf * getnewbuf ()


Arguments

None


Description

The getnewbuf interface allocates a buf structure for performing I/O operations. This interface guarantees that the members of the structure are properly initialized prior to initiating the I/O request. Device drivers call this interface prior to calling physio, which performs the I/O operation.


Return Values

Upon successful completion, getnewbuf returns a pointer to the allocated buf structure. On failure, it returns a NULL pointer.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


getq

Gets a message from the front of the queue


Synopsis

#include <sys/stream.h> MBLKP getq (message_queue)
queue_t *message_queue;


Arguments

message_queue
Specifies a pointer to the message queue from which the message is to be retrieved. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The getq interface is used by a service interface to retrieve its enqueued messages.

A module or driver may include a service interface to process enqueued messages. Once the STREAMS scheduler calls this service it must process all enqueued messages, unless prevented by flow control. The getq interface gets the next available message from the top of the queue pointed to by the message_queue argument. You should call getq in a while loop that should be exited only when there are no more messages.


Return Values

If there is a message to retrieve, getq returns a pointer to it. If no message is queued, getq returns a NULL pointer.


Related Information

bcanput, canput, putbq, putq, qenable

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


gsignal

Sends a signal to a process group


Synopsis

void gsignal (pgroup, signal)
pid_t pgroup;
int signal;


Arguments

pgroup
Specifies the process group to which you want to send a specified signal.

signal
Specifies the signal that you want to send to the specified process group. You can specify any of the signals defined in /usr/sys/include/sys/signal.h.


Description

The gsignal interface sends a signal to a process group, invoking psignal for each process that is a member of the specified process group.


Return Values

None


Related Information

psignal


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


handler_add

Registers a device driver's interrupt handler


Synopsis

ihandler_id_t * handler_add (handler)
ihandler_t *handler;


Arguments

handler
Specifies a pointer to an ihandler_t data structure.


Description

The handler_add interface registers a device driver's interrupt handler and its associated ihandler_t data structure to the bus-specific interrupt-dispatching algorithm. The ih_bus member of the ihandler_t structure specifies the parent bus structure for the bus controlling the driver being loaded. For controller devices, handler_add sets ih_bus to the address of the bus structure for the bus the controller resides on.


Notes

Device drivers call the handler_add interface to register a device driver's interrupt handler.


Example

See Writing Device Drivers: Tutorial for a code example of the handler_add interface.


Return Values

Upon successful completion, the handler_add interface returns an opaque ihandler_id_t key, which is a unique number that identifies the ISIs to be acted on by subsequent calls to handler_del, handler_disable, and handler_enable. To implement this ihandler_id_t key, each call to handler_add causes the handler_key data structure to be allocated.

The handler_add interface returns the value NULL if it cannot allocate the appropriate resources or if it detected an error.


Related Information

handler_del, handler_disable, handler_enable, ihandler_t


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


handler_del

Deregisters a device driver's interrupt handler


Synopsis

int handler_del (id)
ihandler_id_t *id;


Arguments

id
Specifies a pointer to the interrupt handler's entry in the interrupt table.


Description

The handler_del interface deregisters a device driver's interrupt handler from the bus-specific interrupt-dispatching algorithm. In addition, the interface unlinks the handler_key structure associated with the interrupt handler. Prior to deleting the interrupt handler, the device driver should have disabled it by calling handler_disable. If the interrupt handler was not disabled, handler_del returns an error.

The handler_del interface uses the id argument to call a bus-specific adp_handler_del interface to remove the driver's interrupt handler. Deregistration of an interrupt handler can consist of replacing it with the stray interface to indicate that interrupts are no longer expected from this device. The stray interface is a generic interface used as the interrupt handler when there is no corresponding interrupt handler.


Notes

Device drivers that are dynamically configured into the kernel call the handler_del interface to deregister a device driver's interrupt handler. It is not necessary for device drivers that are statically configured into the kernel to call the handler_del interface.


Example

See Writing Device Drivers: Tutorial for a code example of the handler_del interface.


Return Values

Upon successful completion, handler_del returns the value zero (0). Otherwise, it returns the value -1.


Related Information

adp_handler_del, handler_add, handler_disable, handler_enable, ihandler_t


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


handler_disable

Disables a previously registered interrupt handler


Synopsis

int handler_disable (id)
ihandler_id_t *id;


Arguments

id
Specifies a pointer to the interrupt handler's entry in the interrupt table.


Description

The handler_disable interface makes the driver's previously registered interrupt handlers unavailable to the system. You must call handler_disable prior to calling handler_del. The handler_disable interface uses the id argument to call a bus-specific adp_handler_disable interface to perform the bus-specific tasks needed to disable the interrupt handlers.


Notes

Device drivers that are dynamically configured into the kernel should call the handler_disable interface to disable a previously registered interrupt handler. It is not necessary for device drivers that are statically configured into the kernel to call handler_disable.


Example

See Writing Device Drivers: Tutorial for a code example of the handler_disable interface.


Return Values

Upon successful completion, handler_disable returns the value zero (0). Otherwise, it returns the value -1.


Related Information

handler_add, handler_del, handler_enable, ihandler_t


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


handler_enable

Enables a previously registered interrupt handler


Synopsis

int handler_enable (id)
ihandler_id_t *id;


Arguments

id
Specifies a pointer to the interrupt handler's entry in the interrupt table.


Description

The handler_enable interface marks that interrupts are enabled and can be dispatched to the driver's interrupt handlers, as registered in a previous call to handler_add. The id argument passed to handler_enable is used to call a bus-specific adp_handler_enable interface to perform the bus-specific tasks needed to enable the interrupt handlers.


Notes

Device drivers should call the handler_enable interface to enable a previously registered interrupt handler.


Example

See Writing Device Drivers: Tutorial for a code example of the handler_enable interface.


Return Values

Upon successful completion, handler_enable returns the value zero (0). Otherwise, it returns the value -1.


Related Information

adp_handler_enable, handler_add, handler_del, handler_disable, ihandler_t


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


htonl, htons

Convert word and longword values from host-to-network byte order


Synopsis

#include <sys/param.h>

unsigned int htonl (longword)
unsigned int longword;

unsigned short htons (word)
unsigned short word;


Arguments

longword
Specifies a 32-bit value to be conditionally byte swapped.

word
Specifies a 16-bit value to be conditionally byte swapped.


Description

The htonl interface converts the specified longword value from host-to-network byte order. The htons interface converts the specified word value from host-to-network byte order.

The TCP/IP protocols specify the canonical network byte order, which is big endian (meaning that the most significant byte is leftmost in memory).


Return Values

Upon successful completion, the htonl interface returns the converted longword value in network byte order. Similarly, upon successful completion, the htons interface converts the specified word value in network byte order.


Related Information

ntohl


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


insq

Inserts a STREAMS message into a queue


Synopsis

#include <sys/stream.h> int insq (message_queue, message, message_to_be_inserted)
queue_t *message_queue;
MBLKP message;
MBLKP message_to_be_inserted;


Arguments

message_queue
Specifies a pointer to the message queue that contains the message passed to the message argument. The typedef queue_t is an alternate name for struct queue_entry *.

message
Specifies the enqueued message before which the new message is to be inserted. The typedef MBLKP is an alternate name for typedef struct msgb *.

message_to_be_inserted
Specifies the message to be inserted. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The insq interface inserts a STREAMS message into a queue. The message to be inserted (the message_to_be_inserted argument) is placed in the queue (the message_queue argument) immediately before the message associated with the message argument. If the message argument is NULL, insq places the new message at the end of the queue. The interface ignores the queue class of the new message and it updates all flow-control parameters. The insq interface also enables the service procedure unless the QNOENB flag bit is set.


Cautions

If the message argument is non-NULL, it must point to a message on the queue or a system panic could occur.


Return Values

Upon successful completion, insq returns the value 1. On failure, it returns the value zero (0).


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


insque, remque

Add or remove an element from the queue


Synopsis

struct generic_qheader {
                        struct generic_qheader *q_forw;
                        struct generic_qheader *q_back;
                       };

int insque (elem, pred)
struct generic_qheader *elem;
struct generic_qheader *pred;

int remque (elem)
struct generic_qheader *elem;


Arguments

elem
Specifies the address of the queue header that contains the element to be manipulated.

pred
Specifies the address of the queue header that contains the element to precede the one specified by elem in the queue.


Description

The insque interface adds the element that the elem argument specifies to the queue. The interface inserts elem in the next position after pred in the queue.

The remque interface removes the element that the elem argument specifies from the queue it is currently in.

Queues are built from doubly linked lists. Each element is linked into the queue through a queue header. All queue headers are of the generic form struct generic_qheader. A given element may have multiple queue headers. This allows each element to be simultaneously linked onto multiple queues.

Any driver interface that manipulates these queues must call an appropriate spl interface to ensure that the spl level is high enough to block out any interrupts for other device drivers that may access these queues.


Return Values

None


Related Information

spl


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


io_copyin

Copies data from bus address space to system memory


Synopsis

int io_copyin (srcaddr, destaddr, byte_count)
io_handle_t srcaddr;
vm_offset_t destaddr;
u_long byte_count;


Arguments

srcaddr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). For io_copyin, the I/O handle identifies the location in bus address space where the copy originates. You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

destaddr
Specifies the kernel virtual address where io_copyin copies the data to in-system memory.

byte_count
Specifies the number of bytes in the data block to be copied. The interface assumes that the buffer associated with the data block is physically contiguous.


Description

The io_copyin interface copies data from bus address space to system memory. The interface optimizes the copy operation for 32-bit transfers. The I/O handle you pass to srcaddr identifies where the copy originates in bus address space, and the address you pass to destaddr identifies where the copy occurs in system memory. The io_copyin interface assumes no alignment of data associated with srcaddr and destaddr.


Notes

The io_copyin interface is a generic interface that maps to a bus- and machine-specific interface that actually performs the copy from bus address space to system memory. Using io_copyin to perform the copy operation makes the device driver more portable across different CPU architectures and different CPU types within the same architecture.


Cautions

The I/O handle that you pass to the srcaddr argument of the io_copyin interface must be an I/O handle that references addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass an I/O handle to the srcaddr argument that references addresses residing in some other space (for example, dense space) the results of the copy operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:


Example

See Writing Device Drivers: Tutorial for a code example of the io_copyin interface.


Return Values

Upon successful completion, io_copyin returns IOA_OKAY. It returns the value -1 on failure.


Related Information

io_copyio, io_copyout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


io_copyio

Copies data from bus address space to bus address space


Synopsis

int io_copyio (srcaddr, destaddr, byte_count)
io_handle_t srcaddr;
io_handle_t destaddr;
u_long byte_count;


Arguments

srcaddr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). For io_copyio, this I/O handle identifies the location in bus address space where the copy originates. You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

destaddr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). In this case, the I/O handle identifies the location in bus address space where the copy occurs.

byte_count
Specifies the number of bytes in the data block to be copied. The interface assumes that the buffer associated with the data block is physically contiguous.


Description

The io_copyio interface copies data from one location in bus address space to another location in bus address space. The I/O handles you pass to srcaddr and destaddr identify the locations in bus address space where the copy originates and where the copy occurs. The io_copyio interface assumes no alignment of data associated with srcaddr and destaddr.


Notes

The io_copyio interface is a generic interface that maps to a bus- and machine-specific interface that actually performs the copy of data from one location in bus address space to another location in bus address space. Using io_copyio to perform the copy operation makes the device driver more portable across different CPU architectures and different CPU types within the same architecture.


Cautions

The I/O handles that you pass to the srcaddr and destaddr arguments of the io_copyio interface must be I/O handles that reference addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass I/O handles to the srcaddr and destaddr arguments that reference addresses residing in some other space (for example, dense space) the results of the copy operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:


Example

See Writing Device Drivers: Tutorial for a code example of the io_copyio interface.


Return Values

Upon successful completion, io_copyio returns IOA_OKAY. It returns the value -1 on failure.


Related Information

io_copyin, io_copyout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


io_copyout

Copies data from system memory to bus address space


Synopsis

int io_copyout (srcaddr, destaddr, byte_count)
vm_offset_t srcaddr;
io_handle_t destaddr;
u_long byte_count;


Arguments

srcaddr
Specifies the kernel virtual address where the copy originates in system memory.

destaddr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). For io_copyout, the I/O handle identifies the location in bus address space where the copy occurs. You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

byte_count
Specifies the number of bytes in the data block to be copied. The interface assumes that the buffer associated with the data block is physically contiguous.


Description

The io_copyout interface copies data from system memory to bus address space. The interface optimizes the copy operation for 32-bit transfers. The address you pass to srcaddr identifies the kernel virtual address where the copy originates in system memory, and the I/O handle you pass to destaddr identifies the address where the copy occurs in bus address space. The io_copyout interface assumes no alignment of data associated with srcaddr and destaddr.


Notes

The io_copyout interface is a generic interface that maps to a bus- and machine-specific interface that actually performs the copy to bus address space. Using io_copyout to perform the copy operation makes the device driver more portable across different CPU architectures and different CPU types within the same architecture.


Cautions

The I/O handle that you pass to the destaddr argument of the io_copyout interface must be an I/O handle that references addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass an I/O handle to the destaddr argument that references addresses residing in some other space (for example, dense space) the results of the copy operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:


Example

See Writing Device Drivers: Tutorial for a code example of the io_copyout interface.


Return Values

Upon successful completion, io_copyout returns IOA_OKAY. It returns the value -1 on failure.


Related Information

io_copyin, io_copyio


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


io_zero

Zeros a block of memory in bus address space


Synopsis

int io_zero (destaddr, byte_count)
io_handle_t destaddr;
u_long byte_count;


Arguments

destaddr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). For io_zero, this I/O handle identifies the location in bus address space where the zero operation occurs. You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

byte_count
Specifies the number of bytes in the data block to be zeroed. The interface assumes that the buffer associated with the data block is physically contiguous.


Description

The io_zero interface zeros byte_count bytes of memory beginning at the bus address specified by destaddr. The I/O handle you pass to destaddr identifies where the zero operation occurs in bus address space. The interface optimizes the copy operation for 32-bit transfers.


Notes

The io_zero interface is a generic interface that maps to a machine-specific interface that actually writes zeros to some location in bus address space. Using io_zero to perform the zero operation makes the device driver more portable across different CPU architectures and different CPU types within the same architecture.


Cautions

The I/O handle that you pass to the destaddr argument of the io_zero interface must be an I/O handle that references addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass an I/O handle to the destaddr argument that references addresses residing in some other space (for example, dense space) the results of the copy operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:


Return Values

Upon successful completion, io_zero returns IOA_OKAY. It returns the value -1 on failure.


Related Information

io_copyin, io_copyio, io_copyout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


iodone

Indicates that I/O is complete


Synopsis

void iodone (bp)
struct buf *bp;


Arguments

bp
Specifies a pointer to a buf structure.


Description

The iodone interface indicates that I/O is complete and reschedules the process that initiated the I/O.


Return Values

None


Related Information

biodone, buf


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


iohandle_to_phys

Converts an I/O handle to a valid system physical address


Synopsis

u_long iohandle_to_phys (io_handle, flags)
io_handle_t io_handle;
long flags;


Arguments

io_handle
Specifies the I/O handle that you want converted to a valid system physical address. To convert the I/O handle to a valid system physical address, you must pass the bitwise inclusive OR of one of the valid conversion flag bits and one of the data type flag bits described in the flags argument. See the bus-specific device driver book for the type of I/O handle associated with that bus.

flags
Specifies a flag that indicates the conversion type and data size. This flag is the bitwise inclusive OR of a valid conversion type value and a valid data size value. See the Description section for a discussion of these values.


Description

The iohandle_to_phys interface converts an I/O handle to a valid system physical address that a device driver uses to perform I/O copy operations. You use this physical address in the I/O copy operations associated with calls to bcopy, copyin, copyout, or a copy interface that you supply. Do not use the physical address returned by iohandle_to_phys in calls to io_copyin, io_copyio, and io_copyout. These interfaces take an I/O handle instead of a physical address and are to bus address space what bcopy is to system memory.
To indicate the conversion type, pass one of the following conversion type values defined in /usr/sys/include/io/common/devdriver.h:
Value Meaning
HANDLE_DENSE_SPACE Converts the I/O handle to a dense space physical address.
HANDLE_SPARSE_SPACE Converts the I/O handle to a sparse space physical address.
HANDLE_BUSPHYS_ADDR Converts the I/O handle to a bus physical address.

In addition to one of the conversion type values, you OR in one of the following data size values defined in /usr/sys/include/io/common/devdriver.h. This bit is required for compatibility across Alpha CPU architectures. Some Alpha CPUs encode size information in the physical address used in I/O or memory bus accesses.

Value Meaning
HANDLE_BYTE Converts the I/O handle to a system physical address that points to a byte address. This byte address resides in bus address space (either I/O space or memory space).
HANDLE_WORD Converts the I/O handle to a system physical address that points to a word address. This word address resides in bus address space (either I/O space or memory space).
HANDLE_LONGWORD Converts the I/O handle to a system physical address that points to a longword address. This longword address resides in bus address space (either I/O space or memory space).
HANDLE_QUADWORD Converts the I/O handle to a system physical address that points to a quadword address. This quadword address resides in bus address space (either I/O space or memory space).
HANDLE_TRIBYTE Converts the I/O handle to a system physical address that points to a tribyte address. This tribyte address resides in bus address space (either I/O space or memory space).


Notes

The iohandle_to_phys interface is a generic interface that maps to a bus- and machine-specific interface that actually converts the I/O handle to a system physical address. Using this interface to convert the I/O handle makes the device driver more portable across different bus architectures, different CPU architectures, and different CPU types within the same CPU architecture.


Return Values

Upon successful completion, iohandle_to_phys returns the physical address indicated by the conversion type value that you passed to the flags argument. If a failure occurs, iohandle_to_phys returns the value zero (0). A return value of zero (0) can occur as a result of the following conditions:


Related Information

io_copyin, io_copyio, io_copyout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


IS_KSEG_VA, IS_SEG0_VA, IS_SEG1_VA

Determine if the specified address is located in the kernel-unmapped address space, the user-mapped address space, and the kernel-mapped address space.


Synopsis

void IS_KSEG_VA (addr)
unsigned long addr;

void IS_SEG0_VA (addr)
unsigned long addr;

void IS_SEG1_VA (addr)
unsigned long addr;


Arguments

addr
Specifies the virtual address.


Description

The IS_KSEG_VA interface determines if the specified address is located in the kernel-unmapped address space. The IS_SEG0_VA interface determines if the specified address is located in the user-mapped address space. The IS_SEG1_VA interface determines if the specified address is located in the kernel-mapped address space.


Example

The following code fragment shows a call to IS_KSEG_VA:


.
.
.
caddr_t virt_addr; [1] unsigned phys_addr; [2]
.
.
.
if(IS_KSEG_VA(virt_addr)) { [3]

phys_addr = KSEG_TO_PHYS(virt_addr); [4]
.
.
.

  1. Declares a variable to store the user buffer's virtual address. [Return to example]

  2. Declares a variable to store the physical address returned by KSEG_TO_PHYS. [Return to example]

  3. Before calling KSEG_TO_PHYS, calls IS_KSEG_VA to determine if the virtual address is from the kernel-unmapped address space. [Return to example]

  4. If the virtual address is from the kernel-unmapped address space, then calls KSEG_TO_PHYS to convert the address to a corresponding physical address. [Return to example]


Return Values

None


Related Information

KSEG_TO_PHYS, PHYS_TO_KSEG


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


kernel_isrthread

Starts a fixed priority kernel thread dedicated to interrupt service


Synopsis

thread_t kernel_isrthread (task, start, pri)
task_t task;
void (*start) ();
int pri;


Arguments

task
Specifies a pointer to a task structure. This pointer identifies the task in which the kernel_isrthread interface starts the newly created kernel thread dedicated to interrupt service handling.

start
Specifies a pointer to an interface that is the entry point for the newly created kernel thread.

pri
Specifies the scheduling priority level for the newly created kernel thread.

The following priority usage table describes the possible scheduling priorities. The first column shows a range of priorities. The second column shows an associated scheduling priority constant defined in <src/kernel/kern/sched.h> (if applicable). The third column describes the usage of the priority ranges. To specify a scheduling priority of 38, you pass the constant BASEPRI_SYSTEM as shown in the example. To specify a scheduling priority of 33, you can pass the following: BASEPRI_HIGHEST + 1.

Priority Constant Usage
0
.
.
.
31
N/A Realtime kernel threads
32
.
.
.
38
BASEPRI_HIGHEST
.
.
.
BASEPRI_SYSTEM
Operating system kernel threads
44
.
.
.
64
BASEPRI_USER
.
.
.
BASEPRI_LOWEST
User kernel threads


Description

The kernel_isrthread interface creates and starts a kernel thread at the specified entry point. This kernel thread handles only interrupt service requests in the specified task and at the specified priority level. A device driver should always attach a kernel thread to the ``first task.''


Example

See Writing Device Drivers: Advanced Topics for a code example of the kernel_isrthread interface.


Return Values

Upon successful completion, kernel_isrthread returns a pointer to the thread structure associated with the kernel thread started at the specified entry point. Device drivers can use this pointer as a handle to a specific kernel thread in calls to other kernel threads-related interfaces.


Related Information

kernel_thread_w_arg, task, thread


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


kernel_thread_w_arg

Starts a kernel thread with a calling argument passed in


Synopsis

thread_t kernel_thread_w_arg (task, start, argument)
task_t task;
void (*start) ();
void *argument;


Arguments

task
Specifies a pointer to a task structure. This pointer identifies the task in which the kernel_thread_w_arg interface starts the newly created kernel thread.

start
Specifies a pointer to an interface that is the entry point for the newly created kernel thread.

argument
Specifies the argument that kernel_thread_w_arg passes to the entry point specified in start.


Description

The kernel_thread_w_arg interface creates and starts a kernel thread in the specified task at the specified entry point with a specified argument. The kernel_thread_w_arg interface passes the specified argument to the newly created kernel thread. The kernel_thread_w_arg interface creates and starts a kernel thread with timeshare scheduling. A kernel thread created with timeshare scheduling means that its priority degrades if it consumes an inordinate amount of CPU resources. A device driver should call kernel_thread_w_arg only for long-running tasks. A device driver should always attach a kernel thread to the ``first task.''


Notes

This interface is actually a convenience wrapper for the thread_create interface (which creates the kernel thread) and the thread_start interface (which starts the newly created kernel thread).

The kernel_thread_w_arg interface behaves identically to kernel_isrthread except that with kernel_thread_w_arg you can pass an argument to the entry point for the newly created kernel thread.


Example

See Writing Device Drivers: Advanced Topics for a code example of the kernel_thread_w_arg interface.


Return Values

Upon successful completion, kernel_thread_w_arg returns a pointer to the thread structure associated with the kernel thread started at the specified entry point. Device drivers can use this pointer as a handle to a specific kernel thread in calls to other kernel threads-related interfaces.


Related Information

kernel_isrthread, task, thread


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


KSEG_TO_PHYS

Converts a kernel-unmapped virtual address to a physical address


Synopsis

vm_offset_t KSEG_TO_PHYS (addr)
vm_offset_t addr;


Arguments

addr
Specifies the buffer virtual address to convert to a physical address.


Description

The KSEG_TO_PHYS interface converts a kernel-unmapped virtual address to a kernel physical address. Device drivers can use this physical address in DMA operations. Prior to calling KSEG_TO_PHYS, device driver writers often call one of the following interfaces to determine whether the address passed is a virtual address in the addressed kernel segment:



Example

The following code fragment shows a call to KSEG_TO_PHYS:


.
.
.
caddr_t virt_addr; [1] unsigned phys_addr; [2]
.
.
.
if(IS_KSEG_VA(virt_addr)) { [3]

phys_addr = KSEG_TO_PHYS(virt_addr); [4]
.
.
.

  1. Declares a variable to store the user buffer's virtual address. [Return to example]

  2. Declares a variable to store the physical address returned by KSEG_TO_PHYS. [Return to example]

  3. Before calling KSEG_TO_PHYS, calls IS_KSEG_VA to determine if the virtual address is from the kernel-unmapped address space. [Return to example]

  4. If the virtual address is from the kernel-unmapped address space, then calls KSEG_TO_PHYS to convert the address to a corresponding physical address. [Return to example]


Return Values

Upon successful completion, KSEG_TO_PHYS returns the physical address.


Related Information

IS_KSEG_VA, PHYS_TO_KSEG


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


linkb

Concatenates two message blocks


Synopsis

#include <sys/stream.h> void linkb (message, message_to_be_added)
MBLKP message;
MBLKP message_to_be_added;


Arguments

message
Specifies the message to which the message in message_to_be_added is to be added. The typedef MBLKP is an alternate name for typedef struct msgb *.

message_to_be_added
Specifies the message to be added. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The linkb interface creates a new message by adding the message specified in the message_to_be_added argument to the tail of the message specified in the message argument. The continuation pointer (the b_cont member of the msgb structure) of the first message is set to point to the second message (the message_to_be_added argument).


Return Values

None


Related Information

unlinkb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lock_done

Releases a complex lock


Synopsis

#include <kern/lock.h> void lock_done (lock_structptr)
lock_t lock_structptr;


Arguments

lock_structptr
Specifies a pointer to the complex lock structure, lock. The lock structure is an opaque data structure; that is, its associated members are referenced and manipulated by the Digital UNIX operating system and not by the user of the complex lock mechanism.


Description

The lock_done interface releases a lock that was previously asserted by one of the following complex locking interfaces: lock_read, lock_try_read, lock_try_write, and lock_write.


Notes

You must hold the lock on the resource before calling lock_done.


Example

See Writing Device Drivers: Advanced Topics for a code example of the lock_done interface.


Return Values

None


Related Information

lock, lock.h, lock_init, lock_read, lock_terminate, lock_try_read, lock_try_write, lock_write


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lock_init

Initializes a complex lock


Synopsis

#include <kern/lock.h> void lock_init (lock_structptr, can_sleep)
lock_t lock_structptr;
boolean_t can_sleep;


Arguments

lock_structptr
Specifies a pointer to the complex lock structure, lock. The lock structure is an opaque data structure; that is, its associated members are referenced and manipulated by the Digital UNIX operating system and not by the user of the complex lock mechanism.

can_sleep
Specifies a Boolean value that indicates whether to allow kernel threads to block (sleep) if the complex lock is asserted. You can pass to this argument only the value TRUE (allow kernel threads to block if the lock is asserted).


Description

The lock_init interface initializes a complex lock. You identify this lock by declaring a pointer to a complex lock structure and passing it as the first argument. The complex lock structure pointer must be initialized before you can assert read and write operations on the complex lock.


Example

See Writing Device Drivers: Advanced Topics for a code example of the lock_init interface.


Return Values

None


Related Information

lock_done, lock, lock.h, lock_read, lock_terminate, lock_try_read, lock_try_write, lock_write


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lock_read

Asserts a complex lock with read-only access


Synopsis

#include <kern/lock.h> void lock_read (lock_structptr)
lock_t lock_structptr;


Arguments

lock_structptr
Specifies a pointer to the complex lock structure, lock. This is the lock structure associated with the resource on which you want to assert a complex lock with read-only access.

The lock structure is an opaque data structure; that is, its associated members are referenced and manipulated by the Digital UNIX operating system and not by the user of the complex lock mechanism.


Description

The lock_read interface asserts a lock with read-only access for the resource associated with the specified lock structure pointer. The lock_read interface allows multiple kernel threads to access the resource read-only at the same time. When a read lock is asserted, the protected resource is guaranteed not to change.

To release a previously asserted read lock, call the lock_done interface.


Notes

You must call lock_init (once only) prior to calling lock_read to initialize the lock structure pointer for the resource. A resource, from the device driver's standpoint, is data that more than one kernel thread can manipulate. You can store the resource in variables (global) and data structure members.


Example

See Writing Device Drivers: Advanced Topics for a code example of the lock_read interface.


Return Values

None


Related Information

lock_done, lock, lock.h, lock_terminate, lock_try_read, lock_try_write, lock_write,


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lock_terminate

Terminates, using a complex lock


Synopsis

#include <kern/lock.h> void lock_terminate (lock_structptr)
lock_t lock_structptr;


Arguments

lock_structptr
Specifies a pointer to the complex lock structure, lock. The lock structure is an opaque data structure; that is, its associated members are referenced and manipulated by the Digital UNIX operating system and not by the user of the complex lock mechanism.


Description

The lock_terminate interface determines that the driver is done using the complex lock forever. The complex lock must be free (that is, the driver does not hold the lock) before calling lock_terminate. The device driver must not reference the specified complex lock after calling lock_terminate.


Notes

You must call lock_init (once only) prior to calling lock_terminate to initialize the lock structure pointer for the resource. A resource, from the device driver's standpoint, is data that more than one kernel thread can manipulate. You can store the resource in variables (global) and data structure members.


Example

See Writing Device Drivers: Advanced Topics for a code example of the lock_terminate interface.


Return Values

None


Related Information

lock_done, lock_init, lock, lock.h, lock_try_read, lock_try_write, lock_write


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lock_try_read

Tries to assert a complex lock with read-only access


Synopsis

#include <kern/lock.h> boolean_t lock_try_read (lock_structptr)
lock_t lock_structptr;


Arguments

lock_structptr
Specifies a pointer to the complex lock structure, lock. This is the lock structure associated with the resource on which you want to try to assert a complex lock with read-only access.

The lock structure is an opaque data structure; that is, its associated members are referenced and manipulated by the Digital UNIX operating system and not by the user of the complex lock mechanism.


Description

The lock_try_read interface tries to assert a complex lock (without blocking) with read-only access for the resource associated with the specified lock structure pointer. To release a complex lock with read-only access successfully asserted by lock_try_read, call the lock_done interface.


Notes

You must call lock_init (once only) prior to calling lock_try_read to initialize the lock structure pointer for the resource. A resource, from the device driver's standpoint, is data that more than one kernel thread can manipulate. You can store the resource in variables (global) and data structure members.


Example

See Writing Device Drivers: Advanced Topics for a code example of the lock_try_read interface.


Return Values

The lock_try_read interface returns one of the following values:

Value Meaning
TRUE The attempt to acquire the read-only complex lock was successful.
FALSE The attempt to acquire the read-only complex lock was unsuccessful.


Related Information

lock_done, lock, lock.h, lock_try_write, lock_write


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lock_try_write

Tries to assert a complex lock with write access


Synopsis

#include <kern/lock.h> boolean_t lock_try_write (lock_structptr)
lock_t lock_structptr;


Arguments

lock_structptr
Specifies a pointer to the complex lock structure, lock. This is the lock structure associated with the resource on which you want to try to assert write access.

The lock structure is an opaque data structure; that is, its associated members are referenced and manipulated by the Digital UNIX operating system and not by the user of the complex lock mechanism.


Description

The lock_try_write interface tries to assert a complex lock (without blocking) with write access for the resource associated with the specified lock structure pointer. To release a complex lock with write access successfully asserted by lock_try_write, call the lock_done interface.


Notes

You must call lock_init (once only) prior to calling lock_try_write to initialize the lock structure pointer for the resource. A resource, from the device driver's standpoint, is data that more than one kernel thread can manipulate. You can store the resource in variables (global) and data structure members.


Example

See Writing Device Drivers: Advanced Topics for a code example of the lock_try_write interface.


Return Values

The lock_try_write interface returns one of the following values:

Value Meaning
TRUE The attempt to acquire the write complex lock was successful.
FALSE The attempt to acquire the write complex lock was unsuccessful.


Related Information

lock_done, lock, lock.h, lock_terminate, lock_try_read, lock_write


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lock_write

Asserts a complex lock with write access


Synopsis

#include <kern/lock.h> void lock_write (lock_structptr)
lock_t lock_structptr;


Arguments

lock_structptr
Specifies a pointer to the complex lock structure, lock. This is the lock structure associated with the resource on which you want to assert a complex lock with write access.

The lock structure is an opaque data structure; that is, its associated members are referenced and manipulated by the Digital UNIX operating system and not by the user of the complex lock mechanism.


Description

The lock_write interface asserts a lock with exclusive write access for the resource associated with the specified lock structure pointer. This means that once a write lock is asserted, no other kernel thread can gain read or write access to the resource until it is released.

To release a complex write lock successfully asserted by lock_write, call the lock_done interface.


Notes

You must call lock_init (once only) prior to calling lock_write to initialize the lock structure pointer for the resource. A resource, from the device driver's standpoint, is data that more than one kernel thread can manipulate. You can store the resource in variables (global) and data structure members.


Example

See Writing Device Drivers: Advanced Topics for a code example of the lock_write interface.


Return Values

None


Related Information

lock_done, lock, lock.h, lock_read, lock_terminate, lock_try_read, lock_try_write


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


major

Returns the device major number


Synopsis

#include <sys/types.h> int major (device)
dev_t device;


Arguments

device
Specifies the number of the device whose associated major device number the major interface will obtain.


Description

The major interface returns the device major number associated with the device specified by the device argument. Device driver writers use the dev_t data type to represent a device's major and minor numbers. This data type is an abstraction of the internal representations of the major and minor numbers. Driver writers do not need to know how the system internally represents the major and minor numbers. To ensure maximum portability of the device driver, use the major interface to extract the major number portion of this internal representation.


Example

See Writing Device Drivers: Tutorial for a code example of the major interface.


Return Values

Upon successful completion, major returns the major number portion of the dev_t passed as the argument.


Related Information

makedev, minor


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


makedev

Returns a dev_t


Synopsis

#include <sys/types.h> dev_t makedev (major, minor)
int major;
int minor;


Arguments

major
Specifies the major number for the device.

minor
Specifies the minor number for the device.


Description

The makedev interface returns a device number of type dev_t based on the numbers specified for the major and minor arguments.


Return Values

Upon successful completion, makedev returns a dev_t that represents the major and minor device numbers passed as arguments.


Related Information

major, minor


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


MALLOC

Allocates a variable-size section of kernel virtual memory


Synopsis

#include <sys/malloc.h> MALLOC (addr, cast, size, type, flags)
addr; cast; u_long size;
int type;
int flags;


Arguments

addr
Specifies the memory pointer that points to the allocated memory. You specify the addr argument's data type in the cast argument.

cast
Specifies the data type of the addr argument and the type of the memory pointer returned by MALLOC.

size
Specifies the size of the memory (in bytes) to allocate. Typically, you pass the size as a constant to speed up the memory allocation.

type
Specifies the purpose for which the memory is being allocated. The memory types are defined in the file malloc.h. Typically, device drivers use the constant M_DEVBUF to indicate that device driver memory is being allocated (or freed).

flags
Specifies one of the following flag constants defined in /usr/sys/include/sys/malloc.h:
Value Meaning
M_WAITOK Allocates memory from the virtual memory subsystem if there is not enough memory in the preallocated pool. This constant signifies that MALLOC can block.
M_NOWAIT Does not allocate memory from the virtual memory subsystem if there is not enough memory in the preallocated pool. This constant signifies that MALLOC cannot block.
M_ZERO Allocates zero-filled memory. You pass this bit value by ORing it to M_WAITOK or M_NOWAIT.


Description

The MALLOC interface (macro) allocates at least size bytes from the kernel memory and returns the address of the allocated memory. A device driver can allocate the memory in interrupt and process context.

The MALLOC interface (macro) maintains a pool of preallocated memory for quick allocation. If there is not enough memory in the pool, MALLOC allocates memory from the virtual memory subsystem by calling kmem_alloc, which can potentially block (sleep). There is a kernel thread that allocates and frees memory to and from the preallocated pool.

The MALLOC interface (macro) is actually a wrapper that calls malloc. A device driver should not directly call the malloc interface.

The type argument allows the memory allocator to keep track of memory usage by a subsystem.

If the allocation size is greater than 16K, you must pass M_WAITOK to the flags argument. You cannot allocate more than 16K bytes of memory in interrupt context.


Notes

In previous versions of the operating system, device drivers could call the following memory allocation-related interfaces:

Digital UNIX still provides backwards compatibility with the kalloc, kfree, and kget interfaces and the zinit, zchange, zalloc, zfree, and zget interfaces. However, Digital recommends that for new device drivers you use the MALLOC and FREE interfaces to allocate and to free sections of kernel virtual memory.

A memory corruption can occur if a device driver continues to use the memory after freeing it. Digital UNIX provides a built-in mechanism to debug such erroneous use of memory. You can enable this debugging feature at boot time by providing the following boot parameter: kmem_debug=1. When you enable this debugging feature, the free interface stores the following in the last word of freed memory:

The malloc interface checks the checksum of the memory content before reallocating this corrupted memory. If the checksum of the memory content does not match the corrupted memory, malloc stores the debug information and then causes the kernel to panic. The malloc interface stores the address and size of the corrupted memory and the pc of the interface that last freed it in a kmem_corrupt_data structure.

You should consider the following when using this debugging feature:


Cautions

A device driver must not call MALLOC in interrupt context with the flags argument set to M_WAITOK. If flags is set to M_WAITOK, MALLOC checks if the kernel thread is in interrupt context. If so, MALLOC returns a null pointer and displays a message on the console terminal.

The M_WAITOK flag implies that it is valid to allocate memory from the virtual memory subsystem if there is not enough memory in the preallocated pool. To be able to allocate memory from the virtual memory subsystem (which can page fault), the device driver must be in process context.


Example

See Writing Device Drivers: Tutorial for a code example of the MALLOC interface.


Return Values

Upon successful completion, MALLOC returns the address of the allocated memory. The return type associated with this address is the same as that specified for the addr argument. If the memory allocation request cannot be fulfilled, MALLOC returns a null pointer in the addr argument.


Related Information

FREE


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


mb

Performs a memory barrier


Synopsis

void mb ()


Arguments

None


Description

The Alpha architecture does not guarantee read/write ordering. That is, the memory subsystem is free to complete read and write operations in any order that is optimal, without regard for the order in which they were issued. Read/write ordering is not the same as cache coherency, which is handled separately and is not an issue.

The Alpha architecture also contains a write buffer (as do many high-performance RISC CPUs, including the MIPS R3000). This write buffer can coalesce multiple writes to identical or adjacent addresses into a single write, effectively losing earlier write requests. Similarly, multiple reads to the same identical or adjacent addresses can be coalesced into a single read.

This coalescing has implications for multiprocessor systems, as well as systems with off-board I/O or DMA engines that can read or modify memory asynchronously or that can require multiple writes to actually issue multiple data items. The mb (memory barrier) interface guarantees ordering of operations. The mb interface is derived from the MB instruction, which is described in the Alpha Architecture Reference Manual.

The mb interface is a superset of the wbflush interface that ULTRIX drivers use. For compatibility, wbflush is aliased to mb on Digital UNIX Alpha systems.

You call mb in a device driver under the following circumstances:

Device drivers and the Digital UNIX operating system are the primary users of the mb interface. However, some user programs, such as a graphics program that directly maps the frame buffer and manipulates registers, might need to call mb. The Digital UNIX operating system does not provide a C library interface for mb. User programs that require use of mb should use the following asm construct:

#include <c_asm.h>

asm ("mb");


Notes

In most situations that would require a cache flush on other CPU architectures, you should call the mb interface on Digital UNIX Alpha systems. The reason is not that mb is equivalent to a cache flush (as it is not). Rather, a common reason for doing a cache flush is to make data that the host CPU wrote available in main memory for access by the DMA device or to access from the host CPU data that was put in main memory by a DMA device. In each case, on an Alpha CPU you should use a memory barrier to synchronize with that event.

One example of using mb occurs with an ethernet network controller. Each ethernet network controller has a unique ethernet hardware address that is typically contained in a ROM on the ethernet controller board. The ethernet hardware address is a multibyte sequence typically consisting of at least 10 bytes. Frequently this multibyte ethernet hardware address is read from the controller hardware by the driver's probe interface by issuing a sequence of reads to the same controller register. Each successive read returns the next byte of the ethernet hardware address. In such instances, a call to mb should be inserted between each of these read operations to ensure that successive read operations do not get coalesced into fewer actual reads as seen by the ethernet controller.


Example

See Writing Device Drivers: Tutorial for a code example of the mb interface.


Return Values

None


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


minor

Returns the device minor number


Synopsis

#include <sys/types.h> int minor (device)
dev_t device;


Arguments

device
Specifies the number of the device whose associated minor device number the minor interface will obtain.


Description

The minor interface returns the device minor number associated with the device specified by the device argument. Device driver writers use the dev_t data type to represent a device's major and minor numbers. This data type is an abstraction of the internal representations of the major and minor numbers. Driver writers do not need to know how the system internally represents the major and minor numbers. To ensure maximum portability of the device driver, use the minor interface to extract the minor number portion of this internal representation.


Example

See Writing Device Drivers: Tutorial for a code example of the minor interface.


Return Values

Upon successful completion, minor returns the minor number portion of the dev_t passed as the argument.


Related Information

major, makedev


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


minphys

Bounds the data transfer size


Synopsis

void minphys (bp)
struct buf *bp;


Arguments

bp
Specifies a pointer to a buf structure.


Description

The minphys interface bounds the data transfer size by checking the b_bcount member of the buf structure pointed to by the bp argument. If the b_bcount member is greater than 63 * 1024, minphys sets b_bcount to 63 * 1024.


Return Values

The minphys interface does not return a value. However, it may change the contents of the b_bcount member of the buf structure.


Related Information

physio


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


mpsleep

Blocks (puts to sleep) the current kernel thread


Synopsis

int mpsleep (channel, pri, wmesg, timo, lockp, flags)
caddr_t channel;
long pri;
char *wmesg;
long timo;
void *lockp;
long flags;


Arguments

channel
Specifies an address associated with the calling kernel thread to be put to sleep.

pri
Specifies whether the sleep request is interruptible. Setting this argument to the PCATCH flag causes the process to sleep in an interruptible state (that is, the kernel thread can take asynchronous signals). Not setting the PCATCH flag causes the process to sleep in an uninterruptible state (that is, the kernel thread cannot take asynchronous signals).

wmesg
Specifies the wait message.

timo
Specifies the maximum amount of time the kernel thread should block (sleep). If you pass the value zero (0), mpsleep assumes there is no timeout.

lockp
Specifies a pointer to a simple or complex lock structure. You should replace the void * data type with simple_lock_t or lock_t if you want to acquire the lock. If you do not want to release a lock, pass the value zero (0).

flags
Specifies the lock type. You can pass the bitwise inclusive OR of the following valid lock bits defined in the param.h file:
Value Meaning
MS_LOCK_SIMPLE Calls mpsleep with a simple lock asserted.
MS_LOCK_READ Calls mpsleep with a read-only lock asserted on entry.
MS_LOCK_WRITE Calls mpsleep with a write lock asserted.
MS_LOCK_ON_ERROR Forces mpsleep to relock the lock on failure.
MS_LOCK_NO_RELOCK Forces mpsleep not to relock after blocking (sleeping).


Description

The mpsleep interface blocks (puts to sleep) the current kernel thread until a wakeup is issued on the address you specified in the channel argument. This interface is the symmetric multiprocessor (SMP) sleep call. The kernel thread blocks (sleeps) a maximum of timo divided by hz seconds. The value zero (0) means there is no timeout.

If you pass the PCATCH flag to the pri argument, mpsleep checks signals before and after blocking (sleeping). Otherwise, mpsleep does not check signals.

The mpsleep interface allows you to specify a pointer to a simple or complex lock structure that is associated with some resource. This interface unlocks this resource prior to blocking (sleeping). The flags argument specifies the lock type. The mpsleep interface releases the lock when the current kernel thread successfully performs an assert wait on the specified channel.


Notes

The mpsleep interface cannot be called from within a device driver's ISI because it is illegal to block at interrupt context.


Return Values

The mpsleep interface returns the value zero (0) if awakened (success) and EWOULDBLOCK if the timeout specified in the timo argument expires (failure). On success, mpsleep relocks the lock if you did not set MS_LOCK_NO_RELOCK in flags. On failure, it leaves the lock unlocked. If you set the flags argument to MS_LOCK_ON_ERROR, mpsleep relocks the lock on failures.


Related Information

assert_wait_mesg, clear_wait, thread_block, thread_wakeup, thread_wakeup_one


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


msgdsize

Returns the number of bytes in a message


Synopsis

#include <sys/stream.h> int msgdsize (message_block_ptr)
MBLKP message_block_ptr;


Arguments

message_block_ptr
Specifies a pointer to the message block to be evaluated. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The msgdsize interface counts the number of bytes in a data message. Only bytes included in the data blocks with a message type of M_DATA (ordinary data) is included in the count.


Return Values

Upon successful completion, the msgdsize interface returns the number of data bytes in a message, expressed as an integer.


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


noenable

Prevents a queue from being scheduled


Synopsis

#include <sys/stream.h> void noenable (queue)
queue_t *queue;


Arguments

queue
Specifies the pointer to the queue that you want to prevent from being scheduled. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The noenable interface prevents the queue associated with the queue argument from being scheduled for service by the insq, putbq, or putq interfaces when enqueuing an ordinary priority message. You can enable the queue again by calling the enableok interface.


Return Values

None


Related Information

enableok, insq, putbq, putq, qenable

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


ntohl, ntohs

Convert longword and word values from network-to-host byte order


Synopsis

#include <sys/param.h>

unsigned int ntohl (longword)
unsigned int longword;

unsigned short ntohs (word)
unsigned short word;


Arguments

longword
Specifies a 32-bit value to be conditionally byte swapped.

word
Specifies a 16-bit value to be conditionally byte swapped.


Description

The ntohl interface converts the specified longword value from network-to-host byte order. The ntohs interface converts the specified word value from network-to-host byte order.

The TCP/IP protocols specify the canonical network byte order, which is big endian (meaning that the most significant byte is leftmost in memory).


Return Values

Upon successful completion, the ntohl interface returns the converted longword value in host byte order. Similarly, upon successful completion, the ntohs interface returns the converted word value in host byte order.


Related Information

htonl


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


OTHERQ

Gets a pointer to a module's other queue


Synopsis

#include <sys/stream.h> queue_t * OTHERQ (queue)
queue_t *queue;


Arguments

queue
Specifies the pointer to one of the two queues that make up a STREAMS module or driver. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The OTHERQ interface returns a pointer to the other of the two queue structures that make up a STREAMS module or driver. If the queue argument points to the read queue, the OTHERQ interface returns the write queue. If the queue argument points to the write queue, the OTHERQ interface returns the read queue.


Return Values

Upon successful completion, the OTHERQ interface returns a pointer to the other of the two queue structures that make up a STREAMS module or driver.


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


ovbcopy

Copies a byte string with a specified limit


Synopsis

void ovbcopy (b1, b2, n)
char *b1;
char *b2;
int n;


Arguments

b1
Specifies a pointer to a string of bytes.

b2
Specifies a pointer to a buffer of at least n bytes.

n
Specifies the number of bytes to be copied.


Description

The ovbcopy interface copies n bytes from string b1 to buffer b2. No check is made for null bytes.

The address ranges of b1 and b2 can overlap.


Notes

In most cases, ovbcopy is not as efficient as bcopy.


Return Values

None


Related Information

bcopy, blkclr, copystr, strcpy, strncpy


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


panic

Causes a system crash


Synopsis

void panic (message)
char *message;


Arguments

message
Specifies the message you want the panic interface to display on the console terminal.


Description

The panic interface causes a system crash, usually because of fatal errors. It sends to the console terminal and error logger the specified message and, possibly, other system-dependent information (for example, register dumps). It also causes a crash dump to be generated. After displaying the message, panic reboots the system if the console environment variables are set appropriately.


Return Values

None


Related Information

printf


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


physio

Implements raw I/O


Synopsis

int physio (strategy, bp, device, rwflag, mincnt, uio)
int (*strategy) ();
register struct buf *bp;
dev_t device;
int rwflag;
void (*mincnt) ();
register struct uio *uio;


Arguments

strategy
Specifies the block device driver's strategy interface for the device.

bp
Specifies a pointer to a buf structure. This structure contains information such as the binary status flags, the major/minor device numbers, and the address of the associated buffer. This buffer is always a special buffer header owned exclusively by the device for handling I/O requests.

device
Specifies the device number.

rwflag
Specifies the read/write flag.

mincnt
Specifies a pointer to a minphys interface.

uio
Specifies a pointer to a uio structure.


Description

The physio interface implements raw I/O. This interface maps the raw I/O request directly into the user buffer, without using bcopy. The memory pages in the user address space are locked while the transfer is processed.


Example

See Writing Device Drivers: Tutorial for a code example of the physio interface.


Return Values

The physio interface can return one of the following values:

EAIO
The internal Alpha I/O operation completed.

EFAULT
An error occurred in mapping the raw I/O request.

EIO
There is no such device or address on which to perform the I/O request.


Related Information

xxstrategy, minphys


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


PHYS_TO_KSEG

Converts a physical address to a kernel-unmapped virtual address


Synopsis

vm_offset_t PHYS_TO_KSEG (addr)
vm_offset_t addr;


Arguments

addr
Specifies the physical address to convert to a kernel-unmapped virtual address.


Description

The PHYS_TO_KSEG interface converts a kernel physical address to a kernel-unmapped virtual address.


Example

The following code fragment shows a call to PHYS_TO_KSEG:


.
.
.
caddr_t virt_addr; [1] unsigned phys_addr; [2]
.
.
.

virt_addr = PHYS_TO_KSEG(phys_addr); [3]
.
.
.

  1. Declares a variable to store the virtual address returned by PHYS_TO_KSEG. [Return to example]

  2. Declares a variable to store the physical address. This address might have been obtained from a call to KSEG_TO_PHYS. [Return to example]

  3. Calls PHYS_TO_KSEG to convert the physical address to a corresponding virtual address. [Return to example]


Return Values

Upon successful completion, PHYS_TO_KSEG returns the virtual address associated with the specified physical address.


Related Information

IS_KSEG_VA, KSEG_TO_PHYS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


pmap_extract

Extracts a physical page address


Synopsis

vm_offset_t pmap_extract (pmap, virt_addr)
pmap_t pmap;
vm_offset_t virt_addr;


Arguments

pmap
Specifies the physical map.

virt_addr
Specifies the virtual address associated with the physical map.


Description

The pmap_extract interface extracts the physical page address associated with the specified pmap (physical map) and virt_addr (virtual address) arguments. The virtual address includes the offset within a page.


Return Values

The pmap_extract interface returns the value zero (0) if no valid translation exists for the specified virtual address in the specified physical map.


Related Information

pmap_kernel, pmap_set_modify


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


pmap_kernel

Returns the physical map handle for the kernel


Synopsis

pmap_t pmap_kernel ()


Arguments

None


Description

The pmap_kernel interface returns the physical map handle for the kernel.


Return Values

The pmap_kernel interface returns the physical map handle for the kernel.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


pmap_set_modify

Sets the modify bits of the specified physical page


Synopsis

void pmap_set_modify (phys_page)
vm_offset_t phys_page;


Arguments

phys_page
Specifies the physical page that was previously modified.


Description

The pmap_set_modify interface informs the pmap module that the specified physical page was modified through a back-door mechanism.


Return Values

None


Related Information

pmap_extract, pmap_kernel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


printf, uprintf

Write formatted text to some output device


Synopsis

void printf (format, var_arglist)
char *format;
va_dcl var_arglist;

void uprintf (format, var_arglist)
char *format;
va_dcl var_arglist;


Arguments

format
Specifies a pointer to a string that contains two types of objects. One object is ordinary characters such as ``hello, world'', which are copied to the output stream. The other object is a conversion specification such as %d, %o, or %x. Each conversion specification causes the interfaces described here to convert and print for the next argument in the var_arglist argument. The printf formats %d and %x will print 32 bits of data. To obtain 64 bits of data, use %ld and %lx.

var_arglist
Specifies the argument list.


Description

The printf and uprintf interfaces are scaled-down versions of the corresponding C library interfaces. The printf interface prints diagnostic information directly on the console terminal and writes ASCII text to the error logger. Because printf is not interrupt driven, all system activities are suspended when you call it.

The uprintf interface prints to the current user's terminal. Interrupt service interfaces should never call uprintf. It does not perform any space checking, so you should not use this interface to print verbose messages. The uprintf interface does not log messages to the error logger.
You introduce conversion specifications by using the percent sign (%). Following the %, you can include:

A field width or precision can be an asterisk (*) instead of a digit string. If you use an asterisk, you can include an argument that supplies the field width or precision.

The flag characters and their meanings are as follows:

-
The result of the conversion is left justified within the field.

+
The result of a signed conversion always begins with a sign (+ or -).

blank
If the first character of a signed conversion is not a sign, the printf and uprintf interfaces pad the value on the left with a blank. If the blank and plus sign (+) flags both appear, these interfaces ignore the blank flag.

#
The result has been converted to a different format. The value is to be converted to an alternative form.

For c, d, s, and u conversions, this flag has no effect.

For x or X conversions, the printf and uprintf interfaces pad a nonzero result on the left with 0x or 0X.


These interfaces support the following formats that device driver writers find particularly useful:

b
Allows decoding of error registers.

c
Prints the character argument.

d o x
Converts the integer argument to decimal, octal, or hexadecimal notation, respectively.

s
Prints the character argument. The printf and uprintf interfaces print the argument until encountering a null character or until printing the number of characters specified by the precision. If the precision is zero or the precision has not been specified, these interfaces print the character argument until encountering a null character.

u
Converts the unsigned integer argument to a decimal value. The result must be in the range of 0 through 4294967295, where the upper bound is defined by MAXUINT.

%
Prints a percent sign (%). The interfaces convert no argument.


The following line shows the format of the printf interface with the % b conversion character:

printf("reg=%b\n", regval, "<base><arg>*");

In this case, base and arg are defined as:

<base>
The output base expressed as a control character. For example, \10 gives octal and \20 gives hexadecimal.

<arg>
A sequence of characters. The first character gives the bit number to be inspected (origin 1). The second and subsequent characters (up to a control character, that is, a character <=32) give the name of the register.

The following shows a call to printf:

printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");

This example would produce the following output:

reg=2<BITTWO,BITONE>


The following shows the format of the printf interface with the % r and % R conversion characters:

printf("%r R", val, reg_desc);

r
Allows formatted printing of bit fields. This code outputs a string of the format:

"<bit field descriptions>"

R
Allows formatted printing of bit fields. This code outputs a string of the format:

"0x%x<bit field descriptions>"

You use a reg_desc structure to describe the individual bit fields. To describe multiple bit fields within a single word, you can declare multiple reg_desc structures. The reg_desc structure is defined as follows:

struct reg_desc {
  unsigned rd_mask;             /* mask to extract field */
  int rd_shift;                 /* shift for extracted   */
                                /* value, - >>, + <<     */
  char *rd_name;                /* field name            */
  char *rd_format;              /* format to print field */
  struct reg_values *rd_values; /* symbolic names of     */
                                /* values                */
};

rd_mask
Specifies an appropriate mask to isolate the bit field within a word ANDed with the val argument.

rd_shift
Specifies a shift amount to be done to the isolated bit field. The shift is done before printing the isolated bit field with the rd_format member and before searching for symbolic value names in the rd_values member.

rd_name
If non-NULL, specifies a bit field name to label any output from rd_format or searching rd_values. If neither rd_format nor rd_values is non-NULL, rd_name is printed only if the isolated bit field is non-NULL.

rd_format
If non-NULL, specifies that the shifted bit field value is printed using this format.


rd_values
If non-NULL, specifies a pointer to a table that matches numeric values with symbolic names. The interface searches the rd_values member and prints the symbolic name if it finds a match. If it does not find a match, it prints ``???''.

The following is a sample reg_desc entry:

  struct reg_desc dsc[] = {
        /* mask      shift      name   format  values */
        { VPNMASK,     0,       "VA",   "0x%x", NULL },
        { PIDMASK,  PIDSHIFT,   "PID",  "%d",   NULL },
        { 0,            0,      NULL,   NULL,   NULL },
  };

The printf and uprintf interfaces also accept a field number, zero filling to length. For example:

printf(" %8x\n",regval);

The maximum field size is 11.


Notes

Some device drivers might have used the tprintf interface to print on a specified terminal or on the system console if no terminal was provided. Digital recommends that you discontinue use of tprintf because it will not be supported in future releases of the Digital UNIX operating system.


Return Values

None


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


privileged

Checks for proper privileges


Synopsis

int privileged (privilege, error_code)
int privilege;
int error_code;


Arguments

privilege
Specifies the privilege to check against. This privilege must be one of the constants defined in /usr/sys/include/sys/security.h. For example, you would specify SEC_FILESYS for disk drivers that must manipulate partition tables on disk drives.

error_code
Specifies the value used to control auditing. You can pass one of the following values: -1, 0, 1, or one of the system's error codes. An example of an error code is the constant EPERM.


Description

The privileged interface checks for an appropriate privilege when the security feature is enabled. Use privileged with a privilege number and with the error_code argument set to the constant EPERM to emulate the traditional behavior of the suser interface. Set error_code to a value of zero (0) if you want to check the privilege but not fail the operation if the user does not have the proper privilege. A value of -1 turns off all auditing as well.


Return Values

The privileged interface returns the value zero (0) if the process does not have privilege. It returns the value 1 if the process does have privilege.


Related Information

errno.h, security.h, suser


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


psignal

Sends a signal to a process


Synopsis

void psignal (process, signal)
struct proc *process;
int signal;


Arguments

process
Specifies a pointer to a proc structure.

signal
Specifies the signal that you want to send to the specified process. You can specify any of the signals defined in /usr/sys/include/sys/signal.h.


Description

The psignal interface posts a signal to the specified process. The posting of a signal causes that signal to be added to the set of pending signals for the specified process. Depending on the state of the process and the state of the process's signals, the specified signal may be ignored, masked, caught by a tracing parent, or caught by the actual target process. If the signal is to be delivered to the target process, psignal examines and modifies the process state to prepare the execution of the appropriate signal handler.


Return Values

None


Related Information

gsignal


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


pullupmsg

Concatenates bytes in a message


Synopsis

#include <sys/stream.h> int pullupmsg (message_block_ptr, len)
MBLKP message_block_ptr;
int len;


Arguments

message_block_ptr
Specifies a pointer to the message block whose associated data blocks are to be concatenated. The typedef MBLKP is an alternate name for typedef struct msgb *.

len
Specifies the number of bytes to concatenate.


Description

The pullupmsg interface tries to combine multiple data blocks into a single block. The interface concatenates and aligns the first len data bytes of the message pointed to by the message_block_ptr argument. If len equals the value -1, pullupmsg concatenates all data. If len bytes of the same message type cannot be found, pullupmsg fails and returns the value zero (0).


Return Values

Upon successful completion, the pullupmsg interface returns the value 1. On failure, it returns the value zero (0).


Related Information

allocb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


putbq

Places a message at the head of a queue


Synopsis

#include <sys/stream.h> int putbq (queue_pointer, message_block_ptr)
queue_t *queue_pointer;
MBLKP message_block_ptr;


Arguments

queue_pointer
Specifies a pointer to the queue. The typedef queue_t is an alternate name for struct queue_entry *.

message_block_ptr
Specifies a pointer to the message block. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The putbq interface places a message at the beginning of the appropriate section of the message queue. There are always sections for high priority and ordinary messages. If other priority bands are used, each will have its own section of the queue, in priority band order, after high priority messages and before ordinary messages. You can use putbq only for ordinary and priority band messages. High priority messages are not subject to flow-control and thus cannot be put back on the queue.

Typically, you call putbq when the bcanput or canput interface determines that the message cannot be passed on to the next stream component. The flow-control parameters are updated to reflect the change in the queue's status. If the QNOENB flag bit is not set, putbq enables the service interface.


Return Values

Upon successful completion, putbq returns the value 1. On failure, it returns the value zero (0).


Related Information

bcanput, canput, getq, putq

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


putctl

Puts a control message on a queue


Synopsis

#include <sys/stream.h> int putctl (queue_pointer, type)
queue_t *queue_pointer;
int type;


Arguments

queue_pointer
Specifies a pointer to the queue to which the message is to be sent. The typedef queue_t is an alternate name for struct queue_entry *.

type
Specifies a message type (must be control and not a data type).


Description

The putctl interface tests the type argument to make sure a data type was not specified. It then attempts to allocate a message block. The putctl interface fails if a message block cannot be allocated or if the type argument is M_DELAY, M_PROTO, or M_PCPROTO.


Notes

The putctl interface calls the putctl_comm interface, which actually performs the work of sending the control message.


Return Values

Upon successful completion, putctl returns the value 1. The putctl interface fails if a message block cannot be allocated or if the type argument is M_DELAY, M_PROTO, or M_PCPROTO.


Related Information

datamsg, putctl1

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


putctl1

Puts a control message with a 1-byte parameter on a queue


Synopsis

#include <sys/stream.h> int putctl1 (queue_pointer, type, parameter)
queue_t *queue_pointer;
int type;
int parameter;


Arguments

queue_pointer
Specifies a pointer to the queue to which the message is to be sent. The typedef queue_t is an alternate name for struct queue_entry *.

type
Specifies a message type (must be control and not a data type).

parameter
Specifies a 1-byte parameter.


Description

Like the putctl interface, the putctl1 interface tests the type argument to make sure a data type was not specified. It then attempts to allocate a message block. In addition, the putctl1 interface can send a 1-byte parameter in the parameter argument. You can use the parameter for any purpose. For example, you can use this argument to specify how long the delay will be when sending an M_DELAY message. The putctl1 interface fails if a message block cannot be allocated or if the type argument is M_DELAY, M_PROTO, or M_PCPROTO.


Notes

The putctl1 interface calls the putctl_comm interface, which actually performs the work of sending the control message.


Return Values

Upon successful completion, putctl1 returns the value 1. The putctl1 interface fails if a message block cannot be allocated or if the type argument is M_DELAY, M_PROTO, or M_PCPROTO.


Related Information

allocb, datamsg, putctl

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


putnext

Sends a message to the next module in the stream


Synopsis

#include <sys/stream.h> void putnext (queue_pointer, message_ptr)
queue_t *queue_pointer;
MBLKP message_ptr;


Arguments

queue_pointer
Specifies a pointer to the queue from which the message will be sent. The typedef queue_t is an alternate name for struct queue_entry *.

message_ptr
Specifies a pointer to the message block to be passed. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The putnext interface passes a message to the puthere interface of the next queue in the stream.


Return Values

None


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


putq

Puts a message on a queue


Synopsis

#include <sys/stream.h> int putq (queue_pointer, message_ptr)
queue_t *queue_pointer;
MBLKP message_ptr;


Arguments

queue_pointer
Specifies a pointer to the queue to which the message is to be added. The typedef queue_t is an alternate name for struct queue_entry *.

message_ptr
Specifies a pointer to the message block to be placed on the queue. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The putq interface puts a message on a driver's queue after the module's put interface has finished processing the message. The putq interface places the message after any other messages of the same priority and then updates any flow-control parameters. If the QNOENB flag bit is not set, putq enables the service interface. If no processing is done, the putq interface can be used as the module's put interface.


Return Values

Upon successful completion, putq returns the value 1. On failure, it returns the value zero (0).


Related Information

putbq, qenable, rmvq

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


qenable

Enables a queue


Synopsis

#include <sys/stream.h> void qenable (queue_pointer)
queue_t *queue_pointer;


Arguments

queue_pointer
Specifies a pointer to the queue to be enabled. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The qenable interface puts the queue associated with the queue_pointer argument on the linked list of those whose service interfaces are ready to be called by the STREAMS scheduler.


Return Values

None


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


qreply

Sends a message in the reverse direction


Synopsis

#include <sys/stream.h> void qreply (queue_pointer, message_ptr)
queue_t *queue_pointer;
MBLKP message_ptr;


Arguments

queue_pointer
Specifies a pointer to the queue. The typedef queue_t is an alternate name for struct queue_entry *.

message_ptr
Specifies a pointer to the message block to be sent in the opposite direction. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The qreply interface sends a message on a stream in the opposite direction from the queue specified in the queue_pointer argument. It calls the OTHERQ interface to find the queue's module partner.


Return Values

None


Related Information

OTHERQ, putnext

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


qsize

Finds the number of messages on a queue


Synopsis

#include <sys/stream.h> int qsize (queue_pointer)
queue_t *queue_pointer;


Arguments

queue_pointer
Specifies a pointer to the queue to be evaluated. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The qsize interface evaluates the queue associated with the queue_pointer argument and returns the number of messages it contains.


Return Values

If there are no messages in the queue, qsize returns the value zero (0). Otherwise, it returns the integer representing the number of messages on the queue.


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


queue_init

Initializes the specified queue


Synopsis

void queue_init (queue_pointer)
queue_t queue_pointer;


Arguments

queue_pointer
Specifies a pointer to a queue_entry structure. This structure contains a links member that specifies a queue_entry structure. This structure contains a generic doubly linked list (queue).


Description

The queue_init interface initializes the specified queue. Device drivers call this interface prior to calling select_enqueue to initialize the links member of the sel_queue data structure. This member specifies a queue_entry structure. This structure contains a generic doubly linked list (queue).


Return Values

None


Related Information

select_enqueue, select.h, sel_queue


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


RD

Gets a pointer to a module's read queue


Synopsis

#include <sys/stream.h> queue_t * RD (queue_pointer)
queue_t *queue_pointer;


Arguments

queue_pointer
Specifies a pointer to the write queue whose read queue is to be returned. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The RD interface accepts a write queue pointer as an argument and returns a pointer to the read queue of the same module.


Cautions

Make sure the queue_pointer argument is a pointer to a write queue. The RD interface does not check for queue type. A system panic could occur if queue_pointer is not a write queue.


Return Values

Upon successful completion, RD returns the pointer to the read queue.


Related Information

WR

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


READ_BUS_D8, READ_BUS_D16, READ_BUS_D32, READ_BUS_D64

Perform byte, word, longword, and quadword bus I/O read operations


Synopsis

unsigned char READ_BUS_D8 (dev_addr)
io_handle_t dev_addr;
unsigned short READ_BUS_D16 (dev_addr)
io_handle_t dev_addr;
unsigned int READ_BUS_D32 (dev_addr)
io_handle_t dev_addr;
unsigned long READ_BUS_D64 (dev_addr)
io_handle_t dev_addr;


Arguments

dev_addr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). This I/O handle references a device register in the bus address space where the read operation originates. You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle.


Description

The READ_BUS_D8 interface (macro) reads a byte (8 bits) from a device register located in the bus I/O address space. The READ_BUS_D16 interface (macro) reads a word (16 bits) from a device register located in the bus I/O address space. The READ_BUS_D32 interface (macro) reads a longword (32 bits) from a device register located in the bus I/O address space. The READ_BUS_D64 interface (macro) reads a quadword (64 bits) from a device register located in the bus I/O address space. These are convenience interfaces that call read_io_port, which is a generic interface that maps to a bus- and machine-specific interface that actually performs the task of reading the byte, word, longword, or quadword. Use of these interfaces to read data from a device register makes the device driver more portable across different bus architectures, different CPU architectures, and different CPU types within the same CPU architecture.

In addition to dev_addr, the READ_BUS_D8, READ_BUS_D16, READ_BUS_D32, and READ_BUS_D64 interfaces automatically pass values to the width and flags arguments of read_io_port. The following list identifies these values:


Cautions

The I/O handle that you pass to the dev_addr argument of the READ_BUS_D8, READ_BUS_D16, READ_BUS_D32, and READ_BUS_D64 interfaces must be an I/O handle that references addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass an I/O handle to the dev_addr argument that references addresses residing in some other space (for example, dense space) the results of the read operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:

The read_io_port and write_io_port interfaces (and by extension, the Digital-supplied macros built from these interfaces) do not support unaligned data accesses that cross longword boundaries. You can access unaligned data by providing an interface (macro) that checks the lower bits of an I/O address to determine the byte boundary of the I/O read or write operation to be performed and the width of the data to be read or written. If an alignment problem exists, you can break up the read or write operation into separate byte-size reads or writes.

The READ_DEVICECSR_USHORT example interface is a macro that reads an unsigned word of data from a device register. The READ_DEVICECSR_USHORT interface (macro) is called instead of directly calling the Digital-supplied READ_BUS_D16 interface (macro). The READ_DEVICECSR_USHORT interface (macro) first masks out the lower 2 bits of the base address. If the lower 2 bits are both high (indicating an address on a tribyte boundary), the driver must break up the read operation into 2-byte read operations. The driver must also perform appropriate bit-shifting operations to read high and low bytes that are then ORed together.

#define READ_DEVICECSR_USHORT(a)
(
 (u_short)(
   (((u_short)(a)&3) == 3)  
/*
   (((u_short)(a)&1) == 1)  This can be used in drivers with 16-bit
                            CSRs to check if a word read operation
                            crosses a 16-bit register boundary.
*/
  ?
          ( (READ_BUS_D8( (io_handle_t)sc->regbase + (a)+1) << 8)
            | READ_BUS_D8( (io_handle_t)sc->regbase + (a) )
          )
  :
          ( READ_BUS_D16((io_handle_t)sc->regbase + (a))
          );
)


Return Values

Upon successful completion, these interfaces return the requested data from the device register located in the bus address space: READ_BUS_D8 returns a byte (8 bits), READ_BUS_D16 returns a word (16 bits), READ_BUS_D32 returns a longword (32 bits), and READ_BUS_D64 returns a quadword (64 bits).


Related Information

read_io_port


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


readdisklabel

Reads a disk label from a device


Synopsis

char * readdisklabel (dev, strategy, lp)
dev_t dev;
int (*strategy) ();
register struct disklabel *lp;


Arguments

dev
Specifies the major and minor numbers for this device. Device driver writers use the dev_t data type to represent a device's major and minor numbers. This data type is an abstraction of the internal representations of the major and minor numbers. Driver writers do not need to know how the system internally represents the major and minor numbers.

strategy
Specifies the device driver's strategy interface.

lp
Specifies a pointer to the disklabel structure, initialized by the readdisklabel interface.


Description

The readdisklabel interface reads a disklabel structure for a given device, using the device driver's strategy interface to perform the read.

The device driver's open interface calls readdisklabel to read the disk label from the disk into memory.


Example

See Writing Device Drivers: Advanced Topics for a code example of the readdisklabel interface.


Return Values

Upon successful completion, readdisklabel returns the NULL string. Otherwise, it returns one of the following messages:

I/O error
The device driver's strategy interface failed.

no disk label
The device driver's strategy interface returns a NULL disklabel.

disk label corrupted
The disklabel structure contains too many partitions or the checksum is not zero (0).


Related Information

disklabel, setdisklabel, writedisklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


read_io_port

Reads data from a device register


Synopsis

#include <io/common/devdriver.h> long read_io_port (dev_addr, width, flags)
io_handle_t dev_addr;
int width;
int flags;


Arguments

dev_addr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). This I/O handle references a device register in the bus address space where the read operation originates. You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

width
Specifies the width (in bytes) of the data to be read. Valid values are 1, 2, 3, 4, and 8. Not all CPU platforms or bus adapters support all of these values.

flags
Specifies flags to indicate special processing requests. Currently, no flags are used.


Description

The read_io_port interface reads data of the specified width from a device register located in bus address space. The I/O handle you pass to dev_addr identifies where the read operation originates.


Notes

The read_io_port interface is a generic interface that maps to a bus- and machine-specific interface that actually performs the read operation. Using this interface to read data from a device register makes the device driver more portable across different bus architectures, different CPU architectures, and different CPU types within the same CPU architecture.

You must call the mb interface immediately after calling the read_io_port interface under certain circumstances. For discussions and examples of these circumstances, see the Memory Barrier Issues section in Writing Device Drivers: Tutorial.


Cautions

The I/O handle that you pass to the dev_addr argument of the read_io_port interface must be an I/O handle that references addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass an I/O handle to the dev_addr argument that references addresses residing in some other space (for example, dense space) the results of the read operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:

The read_io_port and write_io_port interfaces (and by extension, the Digital-supplied macros built from these interfaces) do not support unaligned data accesses that cross longword boundaries. You can access unaligned data by providing an interface (macro) that checks the lower bits of an I/O address to determine the byte boundary of the I/O read or write operation to be performed and the width of the data to be read or written. If an alignment problem exists, you can break up the read or write operation into separate byte-size reads or writes.

The READ_DEVICECSR_USHORT example interface is a macro that reads an unsigned word of data from a device register. The READ_DEVICECSR_USHORT interface (macro) is called instead of directly calling the Digital-supplied READ_BUS_D16 interface (macro). The READ_DEVICECSR_USHORT interface (macro) first masks out the lower 2 bits of the base address. If the lower 2 bits are both high (indicating an address on a tribyte boundary), the driver must break up the read operation into 2-byte read operations. The driver must also perform appropriate bit-shifting operations to read high and low bytes that are then ORed together.

#define READ_DEVICECSR_USHORT(a)
(
 (u_short)(
   (((u_short)(a)&3) == 3)  
/*
   (((u_short)(a)&1) == 1)  This can be used in drivers with 16-bit
                            CSRs to check if a word read operation
                            crosses a 16-bit register boundary.
*/
  ?
          ( (READ_BUS_D8( (io_handle_t)sc->regbase + (a)+1) << 8)
            | READ_BUS_D8( (io_handle_t)sc->regbase + (a) )
          )
  :
          ( READ_BUS_D16((io_handle_t)sc->regbase + (a))
          );
)


Example

See Writing Device Drivers: Tutorial for a code example of the read_io_port interface.


Return Values

Upon successful completion, read_io_port returns the requested data from the device register located in the bus address space: a byte (8 bits), a word (16 bits), a longword (32 bits), or a quadword (64 bits). This interface returns data justified to the low-order byte lane. For example, a byte (8 bits) is always returned in byte lane 0 and a word (16 bits) is always returned in byte lanes 0 and 1.


Related Information

write_io_port


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


register_callback

Registers a callback request (interface)


Synopsis

int register_callback (function, point, order, argument)
void (*function) ();
int point;
int order;
ulong argument;


Arguments

function
Specifies the name of the request (interface) that you want called at a later time.

point
Specifies the dispatch point at which the kernel calls this callback request (the driver's xxcallback interface). The kernel passes the value associated with this dispatch point to the driver's xxcallback interface when it calls it. The Description section provides brief descriptions of the defined dispatch point definitions that device drivers use.

order
Specifies the order in which you want callback requests (the driver's xxcallback interfaces) registered for the same dispatch point to be executed. The kernel passes the value associated with this order to the driver's xxcallback interface when it calls it. You use this argument to control the order of execution of multiple xxcallback interfaces within each dispatch point. The register_callback interface executes a device driver's xxcallback interfaces for the same dispatch point in increasing numerical order of the value specified in the order argument. The Description section provides brief descriptions of the defined order definitions that device driver use.

argument
Specifies an argument that you want the kernel to pass to the driver's xxcallback interface when the kernel calls it. You pass the integer constant 0L to indicate that you do not want to pass an argument.


Description

The register_callback interface registers a device driver's xxcallback interface. The kernel calls a driver's xxcallback interface when execution reaches the point specified in the point and order arguments. The kernel passes the values specified in the point and argument arguments to the driver's xxcallback interface. Device drivers implement one or more xxcallback interfaces to handle the different dispatch points in the boot path.

The dispatch point constants you can pass to the point argument are defined in the /usr/sys/include/sys/sysconfig.h file. The following table lists the dispatch point constants that device drivers can use:
Value Meaning
CFG_PT_PRECONFIG The dispatch point is hardware preconfiguration. Driver tasks that do not require completion of hardware configuration can be performed at this dispatch point.
CFG_PT_POSTCONFIG The dispatch point is hardware post configuration. Driver tasks that require completion of hardware configuration can be performed at this dispatch point.
CFG_PT_ROOTFS_AVAIL The dispatch point is root file system available. Driver tasks that require completion of the root file system mount operation can be performed at this dispatch point.

The order constants you can pass to the order argument are defined in the /usr/sys/include/sys/sysconfig.h file. The following table lists the order constants that device drivers can use:
Value Meaning
CFG_ORD_NOMINAL This callback request (interface) is registered at the lowest priority. Typically, you pass this constant with an appropriate offset. The kernel executes callback requests (interfaces) registered at this priority last.
CFG_ORD_MAXIMUM This callback request (interface) is registered at the highest priority. Typically, you pass this constant with an appropriate offset. The kernel executes callback requests (interfaces) registered at this priority first.


Notes

The kernel maintains an internal callback list that stores the values you pass to the register_callback interface. These callbacks remain registered until the user removes them.

Only statically configured device drivers need to implement xxcallback interfaces. Thus, only statically configured device drivers need to call the register_callback interface.

You typically call the cfgmgr_get_state interface to determine if the device driver is in the dynamic configuration state or the static configuration state.


Example

See Writing Device Drivers: Tutorial for a code example of the register_callback interface.


Return Values

Upon successful completion, the register_callback interface returns the value ESUCCESS. Otherwise, register_callback returns one of the following error constants defined in /usr/sys/include/sys/errno.h:

ENOMEM
The system limit on the maximum number of callback requests was exceeded. To change the maximum number of callback requests, set the new value for the boot-time tunable parameter max_callbacks in the cm subsystem (located in the /etc/sysconfigtab database) and reboot the system. You can use the sysconfigdb utility to accomplish this task.

EINVAL
The value you passed to the point argument is outside the minimum and maximum range.


Related Information

cfgmgr_get_state, sysconfig.h, unregister_callback, xxcallback, xxconfigure


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


rmalloc

Allocates size units from the given resource map


Synopsis

long rmalloc (map_struct, size)
struct map *map_struct;
long size;


Arguments

map_struct
Specifies a pointer to a map structure that was previously initialized by a call to rminit.

size
Specifies the size of the units to allocate.


Description

The rmalloc interface allocates size units from the given resource map. In a map, the addresses are increasing, and the list is terminated by a zero size. The actual units managed by the map are arbitrary and can be map registers, bytes, blocks, and so forth.


Notes

The caller is responsible for providing any locking necessary for the map structure that the system passes to this interface.


Return Values

The rmalloc interface returns the base of the allocated space. The interface returns an error if no space could be allocated.


Related Information

rmfree, rmget, rminit


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


rmfree

Frees space previously allocated into the specified resource map


Synopsis

void rmfree (map_struct, size, addr)
struct map *map_struct;
long size;
long addr;


Arguments

map_struct
Specifies a pointer to a map structure that was previously initialized by a call to rminit.

size
Specifies the size of the units to free.

addr
Specifies the address at which to free the previously allocated space.


Description

The rmfree interface frees the space previously allocated with a call to rmalloc. The rmfree interface frees a space of the size specified by the size argument at the address specified by the addr argument.


Notes

The caller is responsible for providing any locking necessary for the map structure that the system passes to this interface.


Return Values

None


Related Information

rmalloc, rmget, rminit


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


rmget

Allocates size units from the given resource map


Synopsis

int rmget (map_struct, size, addr)
struct map *map_struct;
long size;
long addr;


Arguments

map_struct
Specifies a pointer to a map structure that was previously initialized by a call to rminit.

size
Specifies the size of the units to allocate.

addr
Specifies the address at which to allocate the space.


Description

The rmget interface allocates the number of units specified in size starting at the address specified in addr.


Notes

The caller is responsible for providing any locking necessary for the map structure that the system passes to this interface.


Return Values

Upon successful completion, rmget returns the starting address, addr. Otherwise, it returns the value zero (0).


Related Information

rmalloc, rmfree, rminit


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


rminit

Initializes a resource map


Synopsis

void rminit (map_struct, size, addr, name, mapsize)
struct map *map_struct;
long size;
long addr;
char *name;
int mapsize;


Arguments

map_struct
Specifies a pointer to a map structure to be initialized by a call to rminit.

size
Specifies the size elements used to initialize the resource map.

addr
Specifies the address that identifies the start of the free elements.

name
Specifies the name for the resource map. The rminit interface uses this name in warning messages when the map overflows.

mapsize
Specifies the maximum number of fragments.


Description

The rminit interface initializes the specified resource map to have mapsize - 2 segments. The interface also identifies this resource map with the string passed to the name argument. It prints this name if the slots become so fragmented that space is lost.

The resource map itself is initialized with size elements free starting at the address specified in addr.


Notes

The caller is responsible for providing any locking necessary for the map structure that the system passes to this interface.


Return Values

None


Related Information

rmalloc, rmfree, rmget


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


rmvb

Removes a message block from a message block


Synopsis

#include <sys/stream.h> MBLKP rmvb (message_block_ptr, message_to_be_removed)
MBLKP message_block_ptr;
MBLKP message_to_be_removed;


Arguments

message_block_ptr
Specifies a pointer to the message block from which a message block is to be removed. The typedef MBLKP is an alternate name for typedef struct msgb *.

message_to_be_removed
Specifies a pointer to the message block to be removed. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The rmvb interface removes a message block (the message_to_be_removed argument) from a message block (the message_block_ptr argument) and returns a pointer to the altered message block. The rmvb interface does not free the message block; it merely removes the message block. It is the module's or driver's responsibility to free the message block.


Return Values

Upon successful completion, rmvb returns a pointer to the message block (minus the removed message block). The pointer is NULL if the message_to_be_removed argument was the only message block before the call to the rmvb interface. If the message block passed to message_to_be_removed does not exist, rmvb returns the value -1.


Related Information

rmvq

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


rmvq

Removes a message block from a queue


Synopsis

#include <sys/stream.h> void rmvq (queue_pointer, message_to_be_removed)
queue_t *queue_pointer;
MBLKP message_to_be_removed;


Arguments

queue_pointer
Specifies a pointer to the queue that contains the message block to be removed. The typedef queue_t is an alternate name for struct queue_entry *.

message_to_be_removed
Specifies a pointer to the message block to be removed. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The rmvq interface removes a message block from a queue. You can remove a message block from anywhere on a queue. To prevent modules and drivers from having to deal with the internals of message linking on a queue, you can call either rmvq or getq to remove a message block from a queue.


Cautions

Make sure the message block pointer you pass to the message_to_be_removed argument exists to avoid a possible system panic.


Return Values

None


Related Information

getq, rmvb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


round_page

Rounds the specified address


Synopsis

#include <mach/vm_param.h> vm_offset_t round_page (address)
vm_offset_t address;


Arguments

address
Specifies the address (or byte count) that is being rounded.


Description

The round_page interface rounds the specified address (or byte count) to a multiple of the page size. For example, round_page would round a 1-byte count to be equal to the size of one page. This interface shields the driver writer from having to know the page size of the system, which could vary in different CPU architectures and on different CPU types within the same architecture. Typically, a device driver calls round_page in preparation for doing a DMA operation to a user's buffer. The value returned by this interface is used in the call to the vm_map_pageable interface. To use this interface, the driver writer must include the <mach/vm_param.h> header file in the driver.


Return Values

The round_page interface returns the rounded address or byte count.


Related Information

current_task, trunc_page, vm_map_pageable


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


select_dequeue

Removes the last kernel thread waiting for an event


Synopsis

void select_dequeue (selq)
sel_queue_t *selq;


Arguments

selq
Specifies a pointer to an sel_queue structure.


Description

The select_dequeue interface removes the last kernel thread waiting for an event to occur on the specified device. This interface is called to terminate a select call. Typically, a driver's xxselect interface calls select_dequeue when the kernel sets the scanning argument (for the driver's xxselect interface) to the value zero (0). This value causes the kernel to unblock any kernel threads suspended when selecting events for this device.


Return Values

None


Related Information

poll.h, select.h, select_dequeue_all, select_enqueue, sel_queue, xxselect

Reference Pages Section 2: select


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


select_dequeue_all

Removes all kernel threads waiting for an event


Synopsis

void select_dequeue_all (selq)
sel_queue_t *selq;


Arguments

selq
Specifies a pointer to an sel_queue structure.


Description

The select_dequeue_all interface is similar in functionality to the select_dequeue interface. The difference is that select_dequeue_all removes all kernel threads (not just the last one) while waiting for an event on the specified device.


Return Values

None


Related Information

poll.h, select.h, select_dequeue, select_enqueue, sel_queue, xxselect

Reference Pages Section 2: select


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


select_enqueue

Adds the current kernel thread


Synopsis

void select_enqueue (selq)
sel_queue_t *selq;


Arguments

selq
Specifies a pointer to an sel_queue structure.


Description

The select_enqueue interface adds the current kernel thread to the list of kernel threads waiting for a select event on the specified device. This interface is called when a driver's xxselect interface has been called and the requested event cannot be immediately satisfied. For example, the requested event cannot be immediately satisfied when xxselect is called for the following reasons:

By calling select_enqueue, the driver's xxselect interface ensures that the kernel thread issuing the select call will be blocked until the requested event can be satisfied or the select call terminates.


Cautions

You must call the queue_init interface to initialize the sel_queue structure pointer prior to calling select_enqueue. Failure to do so causes the kernel to panic.


Return Values

None


Related Information

poll.h, queue_init, select.h, select_dequeue, select_dequeue_all, sel_queue, xxselect

Reference Pages Section 2: select


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


select_wakeup

Wakes up a kernel thread


Synopsis

void select_wakeup (selq)
sel_queue_t *selq;


Arguments

selq
Specifies a pointer to an sel_queue structure.


Description

The select_wakeup interface wakes up a kernel thread that is suspended while waiting for an event on the specified device. A user-level process can use the select system call to cause the process to be suspended while waiting for an event to happen on a device. For example, a graphics application may issue a select call while waiting for mouse or keyboard input to arrive. In this case the process would issue the select system call, which would indirectly call the graphics driver's select interface (through the driver's select entry point in the dsent table) to determine if any input is available. If input is available, the select call may return immediately. If no input is currently available, the graphics driver would suspend the process until input arrived.

For this example, when the graphics driver has received input (typically through its interrupt handler), it causes any processes suspended from calling select to continue by calling the select_wakeup interface. This causes any process currently suspended on the select channel (as specified by the selq argument) to resume.


Return Values

None


Related Information

select_dequeue, select_dequeue_all, select_enqueue, xxselect

Reference Pages Section 2: select


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


setdisklabel

Sets a disk label


Synopsis

int setdisklabel (old_lp, new_lp, openmask)
register struct disklabel *old_lp;
register struct disklabel *new_lp;
u_int openmask;


Arguments

old_lp
Specifies the old disklabel structure for the device.

new_lp
Specifies the new disklabel structure that contains the user's changes.

openmask
Specifies a bit mask in which each set bit represents an open partition and each cleared bit represents a partition that is not open.


Description

The setdisklabel interface sets the in-memory copy of the disklabel structure to the new values specified by the user.

The DIOCWDINFO and DIOCSDINFO ioctl commands call setdisklabel to set the in-memory disk label and to check the validity of the new settings.


Example

See Writing Device Drivers: Advanced Topics for a code example of the setdisklabel interface.


Return Values

Upon successful completion, setdisklabel returns the value zero (0). Otherwise, it returns EBUSY if:


Related Information

disklabel, readdisklabel, writedisklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


simple_lock

Asserts a simple lock


Synopsis

#include <kern/lock.h> void simple_lock (slock_ptr)
simple_lock_t slock_ptr;


Arguments

slock_ptr
Specifies a pointer to a simple lock structure. You can declare this simple lock structure by using the decl_simple_lock_data interface.


Description

The simple_lock interface asserts a lock with exclusive access for the resource associated with the specified slock structure pointer. This means that no other kernel thread can gain access to the locked resource until you call simple_unlock to release it. Because simple locks are spin locks, simple_lock does not return until the lock has been obtained.


Notes

You must call simple_lock_init (once only) prior to calling simple_lock to initialize the simple lock structure for the resource. A resource, from the device driver's standpoint, is data that more than one kernel thread can manipulate. You can store the resource in variables (global) and data structure members.


Example

See Writing Device Drivers: Advanced Topics for a code example of the simple_lock interface.


Return Values

None


Related Information

decl_simple_lock_data, lock.h, simple_lock_init, simple_lock_terminate, simple_lock_try, simple_unlock, slock


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


simple_lock_init

Initializes a simple lock structure


Synopsis

#include <kern/lock.h> void simple_lock_init (slock_ptr)
simple_lock_t slock_ptr;


Arguments

slock_ptr
Specifies a pointer to a simple lock structure. You can declare this simple lock structure by using the decl_simple_lock_data interface.


Description

The simple_lock_init interface initializes the simple lock structure that you previously declared with the decl_simple_lock_data interface. You need to initialize the simple lock structure only once. After you initialize the simple lock structure, you can call simple_lock to assert exclusive access on the associated resource.


Example

See Writing Device Drivers: Advanced Topics for a code example of the simple_lock_init interface.


Return Values

None


Related Information

decl_simple_lock_data, lock.h, simple_lock, simple_lock_terminate, simple_lock_try, simple_unlock, slock


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


simple_lock_terminate

Terminates, using a simple lock


Synopsis

#include <kern/lock.h> void simple_lock_terminate (slock_ptr)
simple_lock_t slock_ptr;


Arguments

slock_ptr
Specifies a pointer to a simple lock structure. You can declare this simple lock structure by using the decl_simple_lock_data interface.


Description

The simple_lock_terminate interface determines that the driver is done using the simple lock permanently. The simple lock must be free (that is, the driver does not hold the lock) before calling simple_lock_terminate. The device driver must not reference the specified simple lock after calling simple_lock_terminate.


Notes

You must call simple_lock_init (once only) prior to calling simple_lock_terminate to initialize the simple lock structure for the resource. A resource, from the device driver's standpoint, is data that more than one kernel thread can manipulate. You can store the resource in variables (global) and data structure members.


Example

See Writing Device Drivers: Advanced Topics for a code example of the simple_lock_terminate interface.


Return Values

None


Related Information

decl_simple_lock_data, simple_lock_init, lock.h, simple_lock_try, simple_unlock, slock


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


simple_lock_try

Tries to assert a simple lock


Synopsis

#include <kern/lock.h> boolean_t simple_lock_try (slock_ptr)
simple_lock_t slock_ptr;


Arguments

slock_ptr
Specifies a pointer to a simple lock structure. You can declare this simple lock structure by using the decl_simple_lock_data interface.


Description

The simple_lock_try interface tries to assert a lock with read and write access for the resource associated with the specified simple lock. The main difference between this interface and simple_lock is that simple_lock_try returns immediately if the resource is already locked while simple_lock spins until the lock has been obtained. Thus, call simple_lock_try when you need a simple lock but the code cannot spin until the lock is obtained.

To release a simple lock successfully asserted by simple_lock_try, call the simple_unlock interface.


Example

See Writing Device Drivers: Advanced Topics for a code example of the simple_lock_try interface.


Return Values

The simple_lock_try interface returns one of the following values:
Value Meaning
TRUE The simple_lock_try interface successfully asserted the simple lock.
FALSE The simple_lock_try interface failed to assert the simple lock.


Related Information

decl_simple_lock_data, lock.h, simple_lock, simple_lock_init, simple_lock_terminate, simple_unlock, slock


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


simple_unlock

Releases a simple lock


Synopsis

#include <kern/lock.h> void simple_unlock (slock_ptr)
simple_lock_t slock_ptr;


Arguments

slock_ptr
Specifies a pointer to a simple lock structure. You passed this pointer in a previous call to the simple_lock interface.


Description

The simple_unlock interface releases a simple lock for the resource associated with the specified simple lock structure pointer. This simple lock was previously asserted by calling the simple_lock or simple_lock_try interface.


Example

See Writing Device Drivers: Advanced Topics for a code example of the simple_unlock interface.


Return Values

None


Related Information

decl_simple_lock_data, lock.h, simple_lock, simple_lock_terminate, simple_lock_try, slock


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


sleep

Puts a calling process to sleep


Synopsis

void sleep (channel, pri)
caddr_t channel;
long pri;


Arguments

channel
Specifies a unique address associated with the calling kernel thread to be put to sleep.

pri
Specifies whether the sleep request is interruptible. Setting this argument to the PCATCH flag causes the process to sleep in an interruptible state (that is, the kernel thread can take asynchronous signals). Not setting the PCATCH flag causes the process to sleep in an uninterruptible state (that is, the kernel thread cannot take asynchronous signals).


Description

The sleep interface puts a calling process to sleep on the address specified by the channel argument. Some common addresses are the lbolt argument, a buf structure, and a proc structure. This address should be unique to prevent unexpected wake/sleep cycles, which can occur if different processes are sleeping on the same address accidentally. If you set the PCATCH flag in the pri argument, the sleep interface puts signals on the queue and does not wake up the sleeping process.

The sleep and wakeup interfaces block and then wake up a process. Generally, device drivers call these interfaces to wait for the transfer to complete an interrupt from the device. That is, the write interface of the device driver sleeps on the address of a known location, and the device's interrupt service interface wakes the process when the device interrupts. It is the responsibility of the wakened process to check if the condition for which it was sleeping has been removed.


Notes

Digital UNIX provides two ways to put a process to sleep: interruptible and uninterruptible. The sleep interface performs an uninterruptible sleep operation if you do not set the PCATCH flag and an interruptible sleep operation if you set the PCATCH flag. This means that device drivers cannot call sleep at interrupt context because at interrupt context there is no calling process to be put to sleep. Thus, a device driver's Interrupt Service Interface (ISI) and those interfaces called from within the ISI must not call the sleep interface.

On the Digital UNIX operating system you cannot use pri to set the scheduling priority of the calling process.


Example

See Writing Device Drivers: Tutorial for a code example of the sleep interface.


Return Values

None


Related Information

param.h, wakeup


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


spl

Sets the processor priority to mask different levels of interrupts


Synopsis

#include <machine/cpu.h>

int getspl ();
int splbio ();
int splclock ();
int spldevhigh ();
int splextreme ();
int splhigh ();
int splimp ();
int splnet ();
int splnone ();
int splsched ();
int splsoftclock ();
int spltty ();
int splvm ();
int splx (x)
int x;


Arguments

x
Specifies a CPU priority level. This level must be a value returned by a previous call to one of the spl interfaces.


Description

The spl interfaces set the CPU priority to various interrupt levels. The current CPU priority level determines which types of interrupts are masked (disabled) and which are unmasked (enabled). Historically, seven levels of interrupts were supported, with eight different spl interfaces to handle the possible cases. For example, calling spl0 would unmask all interrupts and calling spl7 would mask all interrupts. Calling an spl interface between 0 and 7 would mask all interrupts at that level and at all lower levels.

Specific interrupt levels were assigned for different device types. For example, before handling a given interrupt, a device driver would set the CPU priority level to mask all other interrupts of the same level or lower. This setting meant that the device driver could be interrupted only by interrupt requests from devices of a higher priority.

Digital UNIX currently supports the naming of spl interfaces to indicate the associated device types. Named spl interfaces make it easier to determine which interface you should use to set the priority level for a given device type. The following table summarizes the uses for the different spl interfaces:

spl Interface Meaning
getspl Gets the spl value.
splbio Masks all disk and tape controller interrupts.
splclock Masks all hardware clock interrupts.
spldevhigh Masks all device and software interrupts.
splextreme Blocks against all but halt interrupts.
splhigh Masks all interrupts except for realtime devices, machine checks, and halt interrupts.
splimp Masks all Ethernet hardware interrupts.
splnet Masks all network software interrupts.
splnone Unmasks (enables) all interrupts.
splsched Masks all scheduling interrupts (usually the hardware clock).
splsoftclock Masks all software clock interrupts.
spltty Masks all tty (terminal device) interrupts.
splvm Masks all virtual memory clock interrupts.
splx Resets the CPU priority to the level specified by the argument.


Notes

The binding of any spl interface with a specific CPU priority level is highly machine dependent. With the exceptions of the splhigh and splnone interfaces, knowledge of the explicit bindings is not required to create new device drivers. You always use splhigh to mask (disable) all interrupts and splnone to unmask (enable) all interrupts.


Example

The following code fragment shows the use of spl interfaces as part of a disk strategy interface:

int s;
 .
 .
 .
s = splbio(); /* Mask (disable) all disk interrupts */
 .
 .
 .
[Code to deal with data that can be modified by the disk interrupt
code]
 .
 .
 .
splx(s); /* Restore CPU priority to what it was */


Return Values

Upon successful completion, each spl interface returns an integer value that represents the CPU priority level that existed before it was changed by a call to the specified spl interface.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strcmp

Compares two null-terminated character strings


Synopsis

int strcmp (s1, s2)
char *s1;
char *s2;


Arguments

s1
Specifies a pointer to a string (an array of characters terminated by a null character).

s2
Specifies a pointer to a string (an array of characters terminated by a null character).


Description

The strcmp interface lexicographically compares string s1 to string s2. The interface does not continue the comparison beyond the first null character it finds. A fatal error occurs if you call strcmp with strings that are not null terminated.


Example

See Writing Device Drivers: Tutorial for a code example of the strcmp interface.


Return Values

If string s1 is less than string s2, strcmp returns an integer less than zero. If s1 and s2 are equal, the interface returns the value zero (0). If s1 is greater than s2, it returns an integer greater than zero.


Related Information

bcmp


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strcpy

Copies a null-terminated character string


Synopsis

char * strcpy (s1, s2)
char *s1;
char *s2;


Arguments

s1
Specifies a pointer to a buffer large enough to hold the string s2.

s2
Specifies a pointer to a string (an array of characters terminated by a null character).


Description

The strcpy interface copies string s2 to buffer s1. The interface stops copying after it copies a null character. Note that the character size is 1 byte.


Example

See Writing Device Drivers: Tutorial for a code example of the strcpy interface.


Return Values

The interface returns a pointer to the location following the end of the destination buffer, s1.


Related Information

bcopy, blkclr, copystr, ovbcopy, strncpy


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strlen

Returns the number of characters in a null-terminated string


Synopsis

int strlen (s)
char *s;


Arguments

s
Specifies a pointer to a string (an array of characters terminated by a null character).


Description

The strlen interface returns the number of characters in s. The count does not include the terminating null character.

Note that the character size is 1 byte.


Example

See Writing Device Drivers: Tutorial for a code example of the strlen interface.


Return Values

The strlen interface returns the number of characters in s, not counting the terminating null character.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strlog

Submits messages for logging


Synopsis

#include <sys/stream.h>
#include <sys/strlog.h> int strlog (driverid, minorid, level, flags, format, arg1, ...)
short driverid;
short minorid;
char level;
unsigned short flags;
char *format;
unsigned arg1;


Arguments

driverid
Specifies the identification number of the driver or module submitting the message.

minorid
Specifies the identification number for a particular minor device.

level
Specifies the tracing level for selective screening of low-priority messages.

flags
Specifies a flag value. The following list are the valid flag values:
Value Meaning
SL_ERROR Pass the message to the error logger.
SL_TRACE Pass the message to the tracer.
SL_CONSOLE Print the message on the console terminal.

format
Specifies a printf style format string. The % s, % e, % g, and % G formats are not allowed.

arg1
Specifies zero or more arguments to the printf interface.


Description

The strlog interface submits formatted messages to the log driver. You can retrieve the messages with the getmsg system call. The flags argument specifies the type of message and where it is to be sent. The strace command receives messages from the log driver and sends them to the standard output. The strerr daemon receives error messages from the log driver and appends them to a file called /var/adm/streams/error.mm-dd , where mm-dd identifies the date of the error message.


Return Values

The strlog interface returns the value zero (0) if the message is not seen by all the readers. Otherwise, it returns the value 1.


Related Information

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strncmp

Compares two strings, using a specified number of characters


Synopsis

int strncmp (s1, s2, n)
char *s1;
char *s2;
int n;


Arguments

s1
Specifies a pointer to a string (an array of characters terminated by a null character).

s2
Specifies a pointer to a string (an array of characters terminated by a null character).

n
Specifies the number of bytes to be compared.


Description

The strncmp interface compares string s1 to string s2, using the number of characters specified in n.


Example

See Writing Device Drivers: Tutorial for a code example of the strncmp interface.


Return Values

If string s1 is equal to the null character ( \0 ), strncmp returns the value zero (0). Otherwise, it returns the difference between the number of characters in s1 and s2.


Related Information

strcmp


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strncpy

Copies a null-terminated character string with a specified limit


Synopsis

char * strncpy (s1, s2, n)
char *s1;
char *s2;
int n;


Arguments

s1
Specifies a pointer to a buffer of at least n bytes.

s2
Specifies a pointer to a string (an array of characters terminated by a null character).

n
Specifies the number of characters to be copied.


Description

The strncpy interface copies string s2 to buffer s1. The interface stops copying after it copies a null character or n characters, whichever comes first. If the length of s2 as determined by the null character is less than n, the interface pads s1 with null characters.


Example

See Writing Device Drivers: Tutorial for a code example of the strncpy interface.


Return Values

The strncpy interface returns a pointer to /NULL at the end of the first string (or to the location following the last copied character if there is no NULL). The copied string will not be null terminated if the length of s2 is n characters or more.


Related Information

bcopy, blkclr, copystr, ovbcopy, strcpy


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strqget

Gets information about a queue


Synopsis

#include <sys/stream.h> int strqget (queue_pointer, what, pri, val)
queue_t *queue_pointer;
qfields_t what;
unsigned char pri;
long *val;


Arguments

queue_pointer
Specifies a pointer to the queue for which you want to obtain information. The typedef queue_t is an alternate name for struct queue_entry *.

what
Specifies which member of the queue structure to return information about. The valid values are specified in the qfields enumerated data type. See the Description section for the definition of this enumerated data type.

pri
Specifies the priority of the request.

val
Specifies the value for the requested member.


Description

The strqget interface gives modules and drivers a way to obtain information about a queue or a particular band of a queue without directly accessing STREAMS data structures. The values that can be returned are defined in the following enumerated data type:

typedef enum qfields {
        QHIWAT  = 0,
        QLOWAT  = 1,
        QMAXPSZ = 2,
        QMINPSZ = 3,
        QCOUNT  = 4,
        QFIRST  = 5,
        QLAST   = 6,
        QFLAG   = 7,
        QBAD    = 8
} qfields_t;


Return Values

Upon successful completion, strqget returns the value zero (0). On failure, strqget returns an error number.


Related Information

strqset

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


strqset

Changes information about a queue


Synopsis

#include <sys/stream.h> int strqset (queue_pointer, what, pri, val)
queue_t *queue_pointer;
qfields_t what;
unsigned char pri;
long *val;


Arguments

queue_pointer
Specifies a pointer to the queue for which you want to change information. The typedef queue_t is an alternate name for struct queue_entry *.

what
Specifies which member of the queue structure to return information about. The valid values are specified in the qfields enumerated data type. See the Description section for the definition of this enumerated data type.

pri
Specifies the priority of the request.

val
Specifies the value for the member to be changed.


Description

The strqset interface gives modules and drivers a way to change information about a queue or a particular band of a queue without directly accessing STREAMS data structures. The values that can be returned are defined in the following enumerated data type:

typedef enum qfields {
        QHIWAT  = 0,
        QLOWAT  = 1,
        QMAXPSZ = 2,
        QMINPSZ = 3,
        QCOUNT  = 4,
        QFIRST  = 5,
        QLAST   = 6,
        QFLAG   = 7,
        QBAD    = 8
} qfields_t;


Return Values

Upon successful completion, strqset returns the value zero (0). On failure, strqset returns an error number. If the what argument is read-only, strqset returns the error constant EPERM.


Related Information

strqget

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


subyte

Writes a byte into user address space


Synopsis

int subyte (user_dest, byte)
char *user_dest;
char byte;


Arguments

user_dest
Specifies the address in user space to write the byte.

byte
Specifies the byte to be written.


Description

The subyte interface copies 1 byte from the protected kernel address space to the unprotected user address space.


Return Values

Upon successful completion, subyte returns the value zero (0). Otherwise, it returns a -1, indicating that the user address specified in user_dest could not be accessed.


Related Information

copyout, copyoutstr, fubyte, fuword, suword


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


suibyte

Writes a byte into user instruction address space


Notes

The suibyte interface is for use on machines that have separate address spaces for code and data. Because the Alpha architecture does not have separate address spaces for code and data, suibyte is mapped to subyte. The suibyte interface is provided for compatibility reasons. See the interface description for subyte for a complete description of suibyte.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


suiword

Writes a word into user instruction address space


Notes

The suiword interface is for use on machines that have separate address spaces for code and data. Because the Alpha architecture does not have separate address spaces for code and data, suiword is mapped to suword. The suiword interface is provided for compatibility reasons. See the interface description for suword for a complete description of suiword.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


suser

Checks whether the current user is the superuser


Synopsis

#include <sys/proc.h>
#include <sys/acct.h> int suser (cred, ac_flag)
struct u_cred *cred;
struct flag_field *ac_flag;


Arguments

cred
Specifies a pointer to the credentials for the current process.

ac_flag
Specifies a pointer to a flag_field structure that contains accounting flags.


Description

The suser interface checks whether the current user is the superuser. If the test succeeds and ac_flag is not a null pointer, the ASU flag is set in the flag_field structure pointed to by ac_flag. The most common value for ac_flag is as follows:

&u.u_acflag


Notes

You use the suser interface only if the security feature is not enabled. If the security feature is enabled, use the privileged interface to determine if the current process has the appropriate privilege.


Errors

EPERM
The current user is not the superuser.


Return Values

If the current user is the superuser, the suser interface returns the value zero (0). Otherwise, it returns an error.


Related Information

privileged


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


suword

Writes a word into user address space


Synopsis

int suword (user_dest, word)
char *user_dest;
int word;


Arguments

user_dest
Specifies the address in user space to write the word.

word
Specifies the word to be written.


Description

The suword interface copies one word from the protected kernel address space to the unprotected user address space.


Return Values

Upon successful completion, suword returns the value zero (0). Otherwise, it returns a -1, indicating that the user address specified in user_dest could not be accessed.


Related Information

copyout, copyoutstr, fubyte, fuword, subyte


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


svatophys

Converts a system virtual address to a physical address


Synopsis

kern_return_t svatophys (kern_addr, phys_addr)
vm_offset_t kern_addr;
vm_offset_t *phys_addr;


Arguments

kern_addr
Specifies the kernel virtual address.

phys_addr
Specifies a pointer to the physical address to be filled in.


Description

The svatophys interface converts a system virtual address to the corresponding physical address. All address and data structure manipulation done within the kernel is performed using system virtual addresses. Typically, system virtual addresses are a means of mapping physical memory and I/O space, which often consists of device registers and DMA buffers. In contrast to this, devices are usually unaware of any virtual addressing and for this reason utilize physical addresses. You use the svatophys interface to perform this address translation.

As an example of where you can use this address translation, a disk device driver can utilize DMA buffers to transfer blocks of data to the disk (for the case of a write operation). The data to be written to disk is present in system memory at a system virtual address known to the driver. To initiate the DMA operation, the disk driver can set up a command packet to specify a write operation to the underlying disk controller hardware. This write command packet contains (among other things) the location of the DMA buffer as a physical address and the length of the buffer. Here, the driver calls the svatophys interface to translate the system virtual address of the DMA buffer to a physical address in the command packet issued to the disk driver.


Return Values

The svatophys interface returns the following:

KERN_SUCCESS
The address translation has been completed successfully.

KERN_INVALID_ADDRESS
Unable to perform address translation. This value indicates that the address specified by the kern_addr argument is not a valid kernel or system virtual address.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


swap_lw_bytes, swap_word_bytes, swap_words

Perform byte-swapping operations


Synopsis

unsigned int swap_lw_bytes (buffer)
unsigned int buffer;

unsigned int swap_word_bytes (buffer)
unsigned int buffer;

unsigned int swap_words (buffer)
unsigned int buffer;


Arguments

buffer
Specifies a 32-bit (4 bytes) quantity.


Description

The swap_lw_bytes interface performs a longword byte swap. The swap_word_bytes interface performs a short word byte swap. The swap_words interface performs a word byte swap. Many computer vendors support devices that use a big endian model of byte ordering. Because Digital devices support the little endian model of byte ordering, there is a need for these byte-swapping interfaces. In addition, some buses (for example, the VMEbus) can have specific or implied byte ordering that may require the use of these interfaces.

Figure 2-1 compares the byte swapping performed by these interfaces. For the purposes of the following discussion, a longword is equal to 4 bytes; a short word is equal to 2 bytes; and 1 byte is equal to 8 bits. The swap_lw_bytes interface takes the 32-bit quantity specified by the buffer argument and swaps all 4 bytes. The swap_word_bytes interface takes the 32-bit quantity specified by the buffer argument and swaps the individual bytes that make up each word of the 32-bit quantity. The swap_words interface takes the 32-bit quantity specified by the buffer argument and swaps the two 16-bit words.

Figure 2-1: Byte Swapping


Return Values

Upon successful completion, these interfaces return the result of the byte swapping.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


testb

Checks for an available buffer


Synopsis

#include <sys/stream.h> int testb (size, pri)
int size;
uint pri;


Arguments

size
Specifies the size of the requested buffer.

pri
Specifies the priority of the allocb request.


Description

The testb interface determines if a call to the allocb interface is likely to succeed if a buffer of size bytes at priority pri is requested. Even if testb returns successfully, the call to allocb can fail.


Return Values

If a buffer of the requested size is available, testb returns the value 1. If a buffer of the requested size is not available, testb returns the value zero (0).


Related Information

allocb, bufcall,

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


thread_block

Blocks (puts to sleep) the current kernel thread


Synopsis

void thread_block ()


Arguments

None


Description

The thread_block interface blocks (puts to sleep) the current kernel thread and selects the next kernel thread to start (run). The interface schedules the next kernel thread onto this CPU.

When a kernel thread is waiting for an event, it should block. In general, a kernel thread is blocked when the thread wait bit in the thread structure pointer associated with the current kernel thread is set. This bit signifies that this kernel thread is on the appropriate wait hash queue, waiting for a wakeup call. This allows the CPU to execute another kernel thread while this kernel thread is blocked.


Example

See Writing Device Drivers: Advanced Topics for a code example of the thread_block interface.


Return Values

None


Related Information

assert_wait_mesg, current_thread


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


thread_halt_self

Handles asynchronous traps for self-terminating kernel threads


Synopsis

void thread_halt_self ()


Arguments

None


Description

The thread_halt_self interface performs the work associated with a variety of asynchronous traps (ASTs) for a kernel thread that terminates itself. A kernel thread terminates itself (or one kernel thread terminates another kernel thread) by calling the thread_terminate interface.

The thread_halt_self interface examines the AST-related member of the thread structure pointer associated with the kernel thread that wants to terminate itself. This thread structure pointer was returned in a previous call to kernel_isrthread or kernel_thread_w_arg and passed by you to the thread_terminate interface. This AST-related member is set to a bit that identifies the specific AST trap associated with this kernel thread. Based on the AST bit set in this member, thread_halt_self does the appropriate cleanup work before the kernel thread exits from the kernel.


Notes

A kernel thread that terminates itself must call thread_halt_self immediately after the call to thread_terminate. The reason for this is that thread_terminate only prepares the self-terminating kernel thread to stop execution. The thread_halt_self interface completes the work needed to stop execution (by performing the appropriate cleanup work) of the self-terminating kernel thread.


Example

See Writing Device Drivers: Advanced Topics for a code example of the thread_halt_self interface.


Return Values

None


Related Information

thread_terminate


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


thread_set_timeout

Sets a timer for the current kernel thread


Synopsis

void thread_set_timeout (timeout_interval)
int timeout_interval;


Arguments

timeout_interval
Specfies the amount of time to wait for an event. The time is used in conjunction with the assert_wait interface.


Description

The thread_set_timeout interface must be called as follows:

  1. Lock the resource.

  2. Call assert_wait_mesg to assert that the current kernel thread is about to block.

  3. Unlock the resource.

  4. Call thread_set_timeout to set the time of delay for the current kernel thread.

  5. Call thread_block to block (put to sleep) the current kernel thread.

The time you specify to wait for the event is automatically canceled when the kernel thread awakes.


Example

See Writing Device Drivers: Advanced Topics for a code example of the thread_set_timeout interface.


Return Values

None


Related Information

assert_wait_mesg, current_thread, thread_block


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


thread_terminate

Prepares to stop or stops execution of the specified kernel thread


Synopsis

kern_return_t thread_terminate (thread_to_terminate)
thread_t thread_to_terminate;


Arguments

thread_to_terminate
Specifies a pointer to the thread structure associated with the kernel thread that you want to terminate. This pointer was returned in a previous call to the kernel_isrthread or kernel_thread_w_arg interface.


Description

The thread_terminate interface prepares to stop or permanently stops execution of the specified kernel thread. You created and started this kernel thread in a previous call to the kernel_isrthread or kernel_thread_w_arg interface. These interfaces return a pointer to the thread structure associated with the newly created and started kernel thread. Device drivers use this pointer as a handle to identify the specific kernel thread that thread_terminate stops executing.

Typically, a kernel thread terminates itself. However, one kernel thread can terminate another kernel thread. A kernel thread that terminates itself must call thread_halt_self immediately after the call to thread_terminate. The reason for this is that thread_terminate only prepares the self-terminating kernel thread to stop execution. The thread_halt_self interface completes the work needed to stop execution (by performing the appropriate cleanup work) of the self-terminating kernel thread.

Specifically, the thread_terminate interface works as follows:


Notes

You do not need to terminate every kernel thread that you create. You should not terminate a kernel thread that is waiting for some event. The basic rule is that you should terminate only those kernel threads that you do not need anymore. For example, if a dynamically configured device driver uses kernel threads, you should terminate them in the CFG_OP_UNCONFIGURE entry point of the loadable driver's configure interface. The kernel threads are no longer needed after the driver is unconfigured.

Note that the thread_terminate interface (for kernel threads that terminate other kernel threads) not only permanently stops execution of the specified kernel thread, but it also frees any resources associated with that kernel thread; thus, this kernel thread can no longer be used.


Return Values

Upon successfully terminating the specified kernel thread, thread_terminate returns the constant KERN_SUCCESS. If the thread structure pointer passed to the thread_to_terminate argument does not identify a valid kernel thread, thread_terminate returns the constant KERN_INVALID_ARGUMENT. On any other error, thread_terminate returns the constant KERN_FAILURE.


Related Information

kernel_isrthread, kernel_thread_w_arg, task, thread, thread_halt_self


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


thread_wakeup

Wakes up all kernel threads waiting for the specified event


Synopsis

void thread_wakeup (event)
vm_offset_t event;


Arguments

event
Specifies the event associated with the current kernel thread.


Description

The thread_wakeup interface wakes up all kernel threads waiting for the event specified in the event argument. This interface is actually a convenience wrapper for the thread_wakeup_prim interface with the one_thread argument set to FALSE (wake up all kernel threads) and the result argument set to THREAD_AWAKENED (wakeup is normal).


Example

See Writing Device Drivers: Advanced Topics for a code example of the thread_wakeup interface.


Return Values

None


Related Information

assert_wait_mesg, clear_wait, thread_block, thread_wakeup_one


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


thread_wakeup_one

Wakes up the first kernel thread waiting on a channel


Synopsis

void thread_wakeup_one (event)
vm_offset_t event;


Arguments

event
Specifies the event associated with the current kernel thread.


Description

The thread_wakeup_one interface wakes up only the first kernel thread in the hash chain waiting for the event specified in the event argument. This interface is actually a convenience wrapper for the thread_wakeup_prim interface with the one_thread argument set to TRUE (wake up only the first kernel thread) and the result argument set to THREAD_AWAKENED (wakeup is normal).


Example

See Writing Device Drivers: Advanced Topics for a code example of the thread_wakeup_one interface.


Return Values

None


Related Information

assert_wait_mesg, clear_wait, thread_block, thread_wakeup


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


timeout

Initializes a callout queue element


Synopsis

void timeout (function, argument, time)
int (*function) ();
caddr_t argument;
register int time;


Arguments

function
Specifies a pointer to the interface to be called.

argument
Specifies a single argument to be passed to the called interface.

time
Specifies the amount of time to delay before calling the specified interface. You express time as time (in seconds) * hz.


Description

The timeout interface initializes a callout queue element to make it easy to execute the specified interface at the time specified in the time argument. You often use callout interfaces for infrequent polling or error handling. The interface you specify will be called on the interrupt stack (not in processor context) as dispatched from the softclock interface.

The global variable hz contains the number of clock ticks per second. This variable is a second's worth of clock ticks.

Thus, if you wanted a 4-minute timeout, you would pass 4 * 60 * hz as the third argument to the timeout interface as follows:

 /* A 4-minute timeout */
 .
 .
 .
 timeout(lptout, (caddr_t)dev, 4 * 60 * hz);


Notes

The granularity of the time delay is dependent on the hardware. For example, the granularity of some Alpha CPUs is 1024 clock ticks per second. Other Alpha CPUs have a granularity of 1200 clock ticks per second. Still other Alpha CPUs exhibit a granularity of 128 clock ticks per second. Because the granularity of the time delay is dependent on the hardware, Digital provides the hz and lbolt global variables. Use the hz global variable to determine the number of clock ticks per second for a specific Alpha CPU. Use the lbolt global variable as a periodic wakeup mechanism.


Example

See Writing Device Drivers: Tutorial for a code example of the timeout interface.


Return Values

None


Related Information

hz, lbolt, untimeout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


trunc_page

Truncates the specified address


Synopsis

#include <mach/vm_param.h> vm_offset_t trunc_page (address)
vm_offset_t address;


Arguments

address
Specifies the address that is being truncated to a page boundary.


Description

The trunc_page interface truncates the specified address to be aligned on a page boundary. This interface shields the driver writer from having to know the page size of the system, which could vary in different CPU architectures and on different CPU types within the same architecture. Typically, a device driver calls trunc_page in preparation for doing a DMA operation on a user's buffer. The value returned by this interface is used in the call to the vm_map_pageable interface. To use this interface, the driver writer must include the <mach/vm_param.h> header file in the driver.


Return Values

The trunc_page interface returns an address truncated to a page boundary.


Related Information

current_task, round_page, vm_map_pageable


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


uiomove

Moves data between user and system virtual space


Synopsis

#include <sys/uio.h> int uiomove (kern_buf, nbytes, uio)
caddr_t kern_buf;
int nbytes;
struct uio *uio;


Arguments

kern_buf
Specifies a pointer to the kernel buffer in system virtual space.

nbytes
Specifies the number of bytes of data to be moved.

uio
Specifies a pointer to a uio structure. This structure describes the current position within a logical user buffer in user virtual space.


Description

The uiomove interface moves data between user and system virtual space. Data can be moved in either direction. Accessibility to the logical user buffer is verified before the move is made. Accessibility to the kernel buffer is always assumed.

The kernel buffer must always be of sufficient size to accommodate the data. It cannot be less than the number of bytes requested to be moved. Data corruption or a system panic may result if this condition occurs.

The size of the logical user buffer, as described by the uio structure, may be less than, equal to, or greater than the number of bytes requested. The number of bytes actually moved is truncated whenever this size is not sufficient to fulfill a request. In all other cases, only the bytes requested are moved.

Normally there is no need for device drivers to set up uio structures or worry about their composition or content. The uio structures are usually set up externally to drivers. Their addresses are passed in through the dsent table as arguments to driver read and write interfaces. The user logical buffers they describe are accessed only by kernel interfaces external to the driver, for example, uiomove. The external uio structures are quite often updated by such accesses.

The uiomove interface always updates the uio structure to reflect the number of bytes actually moved. The structure continues to describe the current position within the logical user buffer. The structure members that are subject to change are listed in the Side Effects section.


Notes

You can also use the uiomove interface to move data only within system virtual space. In such cases, you still specify a pointer to a uio structure. However, in these cases, the structure describes a logical buffer in system virtual space.


Example

See Writing Device Drivers: Tutorial for a code example of the uiomove interface.


Side Effects

The uiomove interface can update the following members of the uio structure:

uio_iov
Specifies the address of the current logical buffer segment.

uio_iovcnt
Specifies the number of remaining logical buffer segments.

uio_resid
Specifies the size of the remaining logical buffer.

uio_offset
Specifies the current offset into the full logical buffer.

The uiomove interface can update the following members of uio_iov (the logical buffer segment descriptor vector):

iov_base
Specifies the address of the current byte within the current logical buffer segment.

iov_len
Specifies the remaining size of the current segment.


Return Values

A zero (0) value is returned whenever the user virtual space described by the uio structure is accessible and the data is successfully moved. Otherwise, an EFAULT error value is returned, indicating an inability to fully access the user virtual space from within the context of the current process. A partial move may have occurred before the logical user buffer became inaccessible. The uio structure is appropriately updated to reflect such partial moves.

The EFAULT return value is suitable for placement in the u_error member of the user structure. Following failure of a system call, this member contains the error code automatically returned in errno to the current process. Device driver writers should explicitly set this value when it is returned and disallow the requested operation. This setting lets the current process determine the appropriate reason (``bad address'') why its request could not be satisfied.


Related Information

copyin, copyout, fubyte, subyte, uio


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


unbufcall

Cancels a pending bufcall request


Synopsis

#include <sys/stream.h> void unbufcall (id)
int id;


Arguments

id
Specifies a nonzero identifier for the request to be canceled. This nonzero identifier is returned to the module from a previous call to the bufcall interface.


Description

The unbufcall interface cancels a pending bufcall request. The id argument is a nonzero identifier for the request to be canceled. This nonzero identifier is returned to the module from a previous call to the bufcall interface.

The unbufcall interface will not return until the pending callback is canceled or has run. Because of this, locks acquired by the callback interface should not be held across the call to unbufcall or a deadlock condition can occur.


Return Values

None


Related Information

bufcall

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


unconfigure_driver

Unconfigures a device driver that was dynamically configured


Synopsis

int unconfigure_driver (bus_name, bus_num, driver_struct, target_name, target_num)
char *bus_name;
int bus_num;
struct driver *driver_struct;
char *target_name;
int target_num;


Arguments

bus_name
Specifies the name of the bus to search for in the system configuration tree. You specified this name in a previous call to the configure_driver interface. You can specify the bus name or the wildcard constant DRIVER_WILDNAME.

bus_num
Specifies the bus number to search for in the hardware topology tree. You specified this number in a previous call to the configure_driver interface.

driver_struct
Specifies the address of the driver structure associated with the controlling device driver. The driver structure name is typically based on the device driver name. For example, the driver structure for the /dev/none driver is nonedriver. You set the members of the driver structure (usually in the driver's declaration section) to appropriate values and then pass the address of the filled in structure to unconfigure_driver.

target_name
Specifies the controller name to search for in the hardware topology tree. You specified this name in a previous call to the configure_driver interface.

target_num
Specifies the controller number to search for in the hardware topology tree. You specified this number in a previous call to the configure_driver interface.


Description

The unconfigure_driver interface unconfigures a device driver that was dynamically configured into the kernel from the system (hardware) configuration tree. The unconfiguration tasks consist of marking the bus, controller, and device structures associated with the specific device driver as unused and available. The unconfigure_driver interface does not remove these structures from the hardware topology tree.


Example

See Writing Device Drivers: Tutorial for a code example of the unconfigure_driver interface.


Return Values

The unconfigure_driver interface can return one of the following constants defined in /usr/sys/include/sys/errno.h:

ESUCCESS
The unconfigure_driver interface successfully unconfigured the specified device driver.

ENODEV
The unconfigure_driver interface cannot unconfigure the specified device driver because there is no such device.


Related Information

configure_driver, driver


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


unix_master

Forces execution onto the master CPU


Synopsis

void unix_master ()


Arguments

None


Description

The unix_master interface forces execution of the kernel thread onto the master CPU (also called the boot CPU). In other words, unix_master binds the kernel thread to the master CPU. To release the kernel thread from the bind to the master CPU, call the unix_release interface. You can make recursive calls to unix_master as long as you make an equal number of calls to unix_release.

The unix_master interface provides another way besides the simple and complex lock interfaces to make a device driver symmetric multiprocessing (SMP) safe. Although calling unix_master is not optimal for performance on an SMP CPU, it does provide third-party device driver writers with an easy way to make their drivers SMP safe without using the lock interfaces.


Notes

Device drivers should not directly call the unix_master and unix_release interfaces. One exception to this recommendation is when you want a device driver's kernel threads to run only on the master CPU. This situation occurs when your driver creates and starts its own kernel threads and you set the d_funnel member of the dsent or dsent table to the value DEV_FUNNEL. In this case, each kernel thread must call unix_master once to ensure that the kernel thread runs only on the master CPU. Remember to make a corresponding call to unix_release.


Cautions

To avoid deadlock, do not call the unix_master interface under the following circumstances:


Return Values

None


Related Information

unix_release


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


unix_release

Releases binding of the kernel thread


Synopsis

void unix_release ()


Arguments

None


Description

The unix_release interface releases a kernel thread from being bound to the master CPU. This binding was enforced in a previous call to the unix_master interface.


Cautions

You can make recursive calls to unix_master as long as you make an equal number of calls to unix_release.


Return Values

None


Related Information

unix_master


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


unlinkb

Removes a message block from the head of a message


Synopsis

#include <sys/stream.h> MBLKP unlinkb (message_ptr)
MBLKP message_ptr;


Arguments

message_ptr
Specifies a pointer to the message block from which the first message block is to be removed. The typedef MBLKP is an alternate name for typedef struct msgb *.


Description

The unlinkb interface removes the first message block from the message block pointed to by the message_ptr argument. The interface returns a pointer to the new message block, minus the removed message block.


Return Values

Upon successful completion, unlinkb returns a pointer to the new message block with the first message block removed. If there is only one message block in the specified message block, unlinkb returns NULL.


Related Information

linkb

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


unregister_callback

Deregisters a callback request (interface)


Synopsis

int unregister_callback (function, point, order, argument)
void (*function) ();
int point;
int order;
ulong argument;


Arguments

function
Specifies the name of the request (interface) that you want to deregister. You must have previously registered this callback request (interface) by calling register_callback.

point
Specifies the execution point at which the kernel calls the callback request (interface) previously registered by calling register_callback. The execution point you pass to this argument must match the value you passed to the point argument in the call to register_callback.

order
Specifies the order value that you specified in a previous call to register_callback.

argument
Specifies an argument that you want the kernel to pass to the callback request (interface) that you previously registered by calling register_callback. The argument you pass to this argument must match the value you passed to argument in the call to register_callback. You would pass the integer constant 0L if you passed this in the previous call to register_callback to indicate there is no argument.


Description

The unregister_callback interface deregisters a device driver's xxcallback interface. The device driver previously registered its xxcallback interface or interfaces by calling the register_callback interface. The values you pass to unregister_callback must be the same ones you previously passed to register_callback to deregister a specific xxcallback interface. Device drivers call unregister_callback to deregister the xxcallback interface when it is no longer needed.

A device driver typically calls unregister_callback when it encounters a fatal error during static or dynamic configuration. The cfgmgr framework executes xxcallback interfaces scheduled to run after single-user mode each time the system goes from multiuser mode to single-user mode and back to multiuser mode. You should unregister any xxcallback interfaces if you do not want this to occur.


Notes

The kernel maintains an internal callback list that stores the values you pass to the register_callback interface. These callbacks remain registered until the user removes them.

The unregister_callback interface searches through the callback list for the specified callback request (interface), the specified point, the specified order, and the specified argument and removes that request (interface) from the list.


Return Values

Upon successful completion, the unregister_callback interface returns the value ESUCCESS. Otherwise, unregister_callback returns the following error constant defined in /usr/sys/include/sys/errno.h:

EINVAL
The value you passed to the point argument is outside the minimum and maximum range.

The callback you specified to be removed does not exist in the callback list.


Related Information

register_callback, sysconfig.h, xxcallback, xxconfigure


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


untimeout

Removes the scheduled interface from the callout queues


Synopsis

boolean_t untimeout (function, argument)
int (*function) ();
caddr_t argument;


Arguments

function
Specifies a pointer to the interface to be removed from the callout queues.

argument
Specifies a single argument to be passed to the called interface.


Description

The untimeout interface removes the scheduled interface from the callout queue. The specified interface was placed on the callout queue in a previous call to the timeout interface. The argument formal parameter must match the argument parameter you specified in the previous call to timeout.

If the specified interface is not in the callout queue, untimeout returns without removing any scheduled interfaces.


Example

See Writing Device Drivers: Tutorial for a code example of the untimeout interface.


Return Values

The untimeout interface returns the value TRUE on success and the value FALSE on failure.


Related Information

timeout


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


vm_map_pageable

Sets pageability of the specified address range


Synopsis

kern_return_t vm_map_pageable (map, start, end, access_type)
vm_map_t map;
vm_offset_t start;
vm_offset_t end;
vm_prot_t access_type;


Arguments

map
Specifies the address map associated with an individual process.

start
Specifies the starting address of an address range. Typically, this is the address of the user's buffer where the DMA operation occurs.

end
Specifies the ending address of a consecutive range of addresses beginning with the start argument.

access_type
Specifies the access mode to be set for memory specified by the start and end arguments. You can set this argument to VM_PROT_NONE or to the bitwise inclusive OR of the protection bits VM_PROT_READ and VM_PROT_WRITE. These bits are defined in the file <mach/vm_prot.h> and have the following meanings:

Value Meaning
VM_PROT_NONE Modifies the memory attributes so that the specified range of addresses is no longer locked. This should be done after the DMA operation has completed.
VM_PROT_READ Verifies that the specifed range of addresses are readable by the specified process. If so, the range of addresses are locked in memory to remain stable throughout the DMA operation.
VM_PROT_WRITE Verifies that the specifed range of addresses is writeable by the specified process. If so, the range of addresses are locked in memory to remain stable throughout the DMA operation.
VM_PROT_READ | VM_PROT_WRITE Verifies that the specifed range of addresses is readable and writeable by the specified process. If so, the range of addresses are locked in memory to remain stable throughout the DMA operation.


Description

The vm_map_pageable interface ensures that the address range you specified in the start and end arguments is accessible. If the address range is accessible by the specified process, the memory associated with this address range will have its locked attributes modified as specified by the access_type argument. A device driver can call this interface prior to performing a DMA operation to ensure that:


Notes

Historically, some ULTRIX device drivers used the useracc kernel interface to perform tasks similar to those performed by vm_map_pageable. For example, both useracc and vm_map_pageable verify that the currently running process has access permissions to the specified memory. However, vm_map_pageable locks the associated memory so that it remains available throughout the DMA operation. In contrast, useracc does not lock the corresponding memory. This leaves the memory vulnerable to having its access permissions changed, which could result in a system panic during the DMA operation.


Example

The following code fragment shows how the vm_map_pageable interface ensures that the user's buffer is accessible to cause the corresponding memory to be locked:

   if (vm_map_pageable(current_task()->map,
           trunc_page(bp->b_un.b_addr),
           round_page(bp->b_un.b_addr + (int)bp->b_bcount),
           (bp->b_flags == B_READ ? VM_PROT_READ : VM_PROT_WRITE))) {
/***************************************************
 * Here you implement the code to perform the      *
 * actual DMA operation.  Upon conclusion of the   *
 * DMA operation, add the following code to        *
 * release the locked attribute.                   *
 ***************************************************/

        if (vm_map_pageable(current_task()->map,
                trunc_page(bp->b_un.b_addr),
                round_page(bp->b_un.b_addr + (int)bp->b_bcount),
                VM_PROT_NONE)) {

The following example shows a comparable use of a call to useracc. The Notes section provides reasons for not using this call on Digital UNIX systems.

        if (useracc(bp->b_un.b_addr, (int)bp->b_bcount,
                (bp->b_flags & B_READ))) {


Return Values

Upon successful completion, the vm_map_pageable interface returns the value zero (0). Otherwise, it returns a nonzero value to indicate an error.


Related Information

current_task, round_page, trunc_page


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


vtop

Converts any virtual address to a physical address


Synopsis

vm_offset_t vtop (proc_p, virt_addr)
struct proc *proc_p;
vm_offset_t virt_addr;


Arguments

proc_p
Specifies a pointer to a proc structure. The vtop interface uses the proc structure pointer to obtain the pmap.

virt_addr
Specifies the virtual address that vtop converts to a physical address.


Description

The vtop interface converts a specified virtual address to a physical address.


Cautions

The vtop interface panics and displays the following message on the console terminal if the proc structure pointer you pass is NULL and the virtual address is in user space:

vtop: user address passed with null proc pointer


Return Values

Upon successful completion, vtop returns the physical address associated with the specified virtual address.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


wakeup

Wakes up all processes sleeping on a specified address


Synopsis

void wakeup (channel)
caddr_t channel;


Arguments

channel
Specifies the address on which the wakeup is to be issued.


Description

The wakeup interface wakes up all processes sleeping on the address specified by the channel argument. All processes sleeping on this address are awakened and made scheduable according to the priorities they specified when they went to sleep. It is possible that there are no processes sleeping on the channel at the time the wakeup is issued. This situation can occur for a variety of reasons and does not represent an error condition.

The sleep and wakeup interfaces block and unblock a process. Generally, a device driver issues these interfaces on behalf of a process requesting I/O while a transfer is in progress. That is, a process requesting I/O is put to sleep on an address associated with the request by the appropriate device driver interface. When the transfer has asynchronously completed, the device driver interrupt service interface issues a wakeup on the address associated with the completed request. This action makes the relevant process scheduable.

The process resumes execution within the relevant device driver interface at the point immediately following the request to sleep. The driver, on behalf of the process, can then determine whether the condition for which it was sleeping (in this example completion of an I/O request) has been removed. If so, it can continue on to complete the I/O request. Otherwise, the appropriate driver interface can decide to put the process back to sleep to await removal of the indicated condition.


Example

See Writing Device Drivers: Tutorial for a code example of the wakeup interface.


Return Values

None


Related Information

lbolt, mpsleep, sleep


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


WR

Gets a pointer to this module's write queue


Synopsis

#include <sys/stream.h> queue_t * WR (queue_pointer)
queue_t *queue_pointer;


Arguments

queue_pointer
Specifies a pointer to the read queue whose write queue is to be returned. The typedef queue_t is an alternate name for struct queue_entry *.


Description

The WR interface accepts a read queue pointer as an argument and returns a pointer to the write queue of the same module.


Cautions

Make sure the queue_pointer argument is a pointer to a read queue. The WR interface does not check for queue type. A system panic could occur if queue_pointer is not a read queue.


Return Values

Upon successful completion, WR returns the pointer to the write queue.


Related Information

OTHERQ, RD

Programmer's Guide: STREAMS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


WRITE_BUS_D8, WRITE_BUS_D16, WRITE_BUS_D32, WRITE_BUS_D64

Perform byte, word, longword, and quadword bus I/O write operations


Synopsis

void WRITE_BUS_D8 (dev_addr, data)
io_handle_t dev_addr;
long data;
void WRITE_BUS_D16 (dev_addr, data)
io_handle_t dev_addr;
long data;
void WRITE_BUS_D32 (dev_addr, data)
io_handle_t dev_addr;
long data;
void WRITE_BUS_D64 (dev_addr, data)
io_handle_t dev_addr;
long data;


Arguments

dev_addr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). This I/O handle references a device register in the bus address space where the write operation occurs.

data
Specifies the data to be written to the specified device register in bus address space.


Description

The WRITE_BUS_D8 interface writes a byte (8 bits) to a device register located in the bus I/O address space. The WRITE_BUS_D16 interface writes a word (16 bits) to a device register located in the bus I/O address space. The WRITE_BUS_D32 interface writes a longword (32 bits) to a device register located in the bus I/O address space. The WRITE_BUS_D64 interface writes a quadword (64 bits) to a device register located in the bus I/O address space. These are convenience interfaces that call write_io_port, which is a generic interface that maps to a bus- and machine-specific interface that actually performs the task of writing the byte, word, longword, or quadword to a device register. Use of these interfaces to write data to a device register makes the device driver more portable across different bus architectures, different CPU architectures, and different CPU types within the same CPU architecture.

The WRITE_BUS_D8, WRITE_BUS_D16, WRITE_BUS_D32, and WRITE_BUS_D64 interfaces automatically pass values to the width and flags arguments of write_io_port. The following list identifies these values:


Cautions

The I/O handle that you pass to the dev_addr argument of the WRITE_BUS_D8, WRITE_BUS_D16, WRITE_BUS_D32, and WRITE_BUS_D64 interfaces must be an I/O handle that references addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass an I/O handle to the dev_addr argument that references addresses residing in some other space (for example, dense space) the results of the copy operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:

The read_io_port and write_io_port interfaces (and by extension, the Digital-supplied macros built from these interfaces) do not support unaligned data accesses that cross longword boundaries. You can access unaligned data by providing an interface (macro) that checks the lower bits of an I/O address to determine the byte boundary of the I/O read or write operation to be performed and the width of the data to be read or written. If an alignment problem exists, you can break up the read or write operation into separate byte-size reads or writes.

The WRITE_DEVICECSR_USHORT interface (macro) is an example of a support interface (macro) that writes an unsigned word of data to a device register. The WRITE_DEVICECSR_USHORT interface (macro) is called instead of directly calling the Digital-provided interface (macro) WRITE_BUS_D16. The WRITE_DEVICECSR_USHORT interface (macro) first masks out the lower 2 bits of the base address. If the lower 2 bits are both high (indicating an address on a tribyte boundary), the driver must break up the write operation into 2-byte write operations. The driver must also perform appropriate bit-shifting operations to write high and low bytes that are then ORed together.

#define WRITE_DEVICECSR_USHORT(a, data)
(
  (u_short)(
    (((u_short)(a)&3) == 3)
/*
  (((u_short)(a)&1) == 1)  This can be used in drivers with 16-bit
                           CSRs to check if a word write operation
                           crosses a 16-bit register boundary
*/
   ?
           ( WRITE_BUS_D8( (io_handle_t)sc->regbase + (a), data),
              mb(),
             WRITE_BUS_D8( (io_handle_t)sc->regbase + (a)+1,
                           (u_short)(data) >> 8),
              mb()
            )
   :
           ( WRITE_BUS_D16( (io_handle_t)sc->regbase + (a), data),
              mb()
           );
)


Return Values

None


Related Information

write_io_port


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


writedisklabel

Writes a disk label


Synopsis

int writedisklabel (dev, strategy, lp)
dev_t dev;
int (*strategy) ();
register struct disklabel *lp;


Arguments

dev
Specifies the major and minor numbers for this device. Device driver writers use the dev_t data type to represent a device's major and minor numbers. This data type is an abstraction of the internal representations of the major and minor numbers. Driver writers do not need to know how the system internally represents the major and minor numbers.

strategy
Specifies the device driver's strategy interface.

lp
Specifies a pointer to the disklabel structure to be written.


Description

The writedisklabel interface writes a disklabel to a device, using the device driver's strategy interface.

The DIOCWDINFO ioctl command calls writedisklabel to write the disk label to disk. The device driver should first call setdisklabel to validate the new settings.


Example

See Writing Device Drivers: Advanced Topics for a code example of the writedisklabel interface.


Return Values

Upon successful completion, writedisklabel returns the value zero (0). Otherwise, it returns one of the following values:

EXDEV
The interface tries to write the disklabel to any partition other than partition zero.

ESRCH
An error occurred while writing the disklabel.


Related Information

disklabel, readdisklabel, setdisklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


write_io_port

Writes data to a device register


Synopsis

#include <io/common/devdriver.h> void write_io_port (dev_addr, width, flags, data)
io_handle_t dev_addr;
int width;
int flags;
long data;


Arguments

dev_addr
Specifies an I/O handle that you can use to reference a device register or memory located in bus address space (either I/O space or memory space). This I/O handle references a device register in the bus address space where the write operation occurs. You can perform standard C mathematical operations (addition and subtraction only) on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

width
Specifies the width (in bytes) of the data to be written. Valid values are 1, 2, 3, 4, and 8. Not all CPU platforms or bus adapters support all of these values.

flags
Specifies flags to indicate special processing requests. Currently, no flags are used.

data
Specifies the data to be written to the specified device register in bus address space.


Description

The write_io_port interface writes the data of the specified width to the specified device register in bus address space. This interface shifts the data to the appropriate byte lanes before performing the write to bus address space. The I/O handle you pass to dev_addr identifies where the write operation occurs.


Notes

The write_io_port interface is a generic interface that maps to a bus- and machine-specific interface that actually performs the write operation. Using this interface to write data to a device register makes the device driver more portable across different bus architectures, different CPU architectures, and different CPU types within the same CPU architecture.

You must call the mb interface immediately after calling the write_io_port interface under certain circumstances. For discussions and examples of these circumstances, see the Memory Barrier Issues section in Writing Device Drivers: Tutorial.


Cautions

The I/O handle that you pass to the dev_addr argument of the write_io_port interface must be an I/O handle that references addresses residing in sparse space. All Alpha CPUs support sparse space. As a result, all bus configuration code should supply an I/O handle that references bus address space.

If you pass an I/O handle to the dev_addr argument that references addresses residing in some other space (for example, dense space) the results of the write operation are unpredictable.

Digital UNIX provides the following interfaces that allow device drivers to perform copy operations and zero blocks of memory on addresses that reside in dense space:

The read_io_port and write_io_port interfaces (and by extension, the Digital-supplied macros built from these interfaces) do not support unaligned data accesses that cross longword boundaries. You can access unaligned data by providing an interface (macro) that checks the lower bits of an I/O address to determine the byte boundary of the I/O read or write operation to be performed and the width of the data to be read or written. If an alignment problem exists, you can break up the read or write operation into separate byte-size reads or writes.

The WRITE_DEVICECSR_USHORT interface (macro) is an example of a support interface (macro) that writes an unsigned word of data to a device register. The WRITE_DEVICECSR_USHORT interface (macro) is called instead of directly calling the Digital-provided interface (macro) WRITE_BUS_D16. The WRITE_DEVICECSR_USHORT interface (macro) first masks out the lower 2 bits of the base address. If the lower 2 bits are both high (indicating an address on a tribyte boundary), the driver must break up the write operation into 2-byte write operations. The driver must also perform appropriate bit-shifting operations to write high and low bytes that are then ORed together.

#define WRITE_DEVICECSR_USHORT(a, data)
(
  (u_short)(
    (((u_short)(a)&3) == 3)
/*
  (((u_short)(a)&1) == 1)  This can be used in drivers with 16-bit
                           CSRs to check if a word write operation
                           crosses a 16-bit register boundary
*/
   ?
           ( WRITE_BUS_D8( (io_handle_t)sc->regbase + (a), data),
              mb(),
             WRITE_BUS_D8( (io_handle_t)sc->regbase + (a)+1,
                           (u_short)(data) >> 8),
              mb()
            )
   :
           ( WRITE_BUS_D16( (io_handle_t)sc->regbase + (a), data),
              mb()
           );
)


Example

See Writing Device Drivers: Tutorial for a code example of the write_io_port interface.


Return Values

None


Related Information

read_io_port


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


2.3    ioctl Commands

When defining ioctl commands that your driver supports, use a set of macros defined in /usr/sys/include/sys/ioctl.h to construct these definitions. These macros instruct the kernel on how much data, if any, is transferred between the application program making the ioctl system call and the device driver. Table 2-3 describes the macros defined in /usr/sys/include/sys/ioctl.h as well as some ioctl commands defined in /usr/sys/include/sys/ioctl_compat.h.

Table 2-3: Summary Descriptions of ioctl Commands

ioctl Macro/Command Summary Description
DEVGETGEOM Obtains device geometry information.
DEVGETINFO Obtains information about a device.
DEVIOCGET Obtains information about a device.
DIOCGCURPT Returns the current partition map for a disk.
DIOCGDEFPT Returns the default partition map for a disk.
DIOCGDINFO Returns a disk label.
DIOCGPART Returns information about a single disk partition.
DIOCSDINFO Sets a disklabel structure.
DIOCWDINFO Writes a disk label.
DIOCWLABEL Sets a write-enable label on a disk.
_IO Defines ioctl types for device control operations.
_IOR Defines ioctl types for device control operations.
_IOW Defines ioctl types for device control operations.
_IOWR Defines ioctl types for device control operations.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DEVGETGEOM

Obtains device geometry information


Synopsis

#include <io/common/devio.h>
#include <sys/ioctl.h>


Description

The DEVGETGEOM ioctl command obtains generic device geometry information by polling the underlying device driver. DEVGETGEOM uses the following union defined in the file /usr/sys/include/io/common/devio.h:

typedef union devgeom {
 struct {
     unsigned long   dev_size;
     unsigned short  ntracks;
     unsigned short  nsectors;
     unsigned short  ncylinders;
     unsigned long   attributes;
     unsigned long   sector_size;
     unsigned long   min_trans;
     unsigned long   max_trans;
     unsigned long   prefer_trans;
    } geom_info;
    unsigned char       pad[108];
} DEVGEOMST;

This union contains two members: a geom_info data structure and a pad array that allocates space to allow for future expansion. The following list describes the members of the geom_info structure:

dev_size
Specifies the total number of sectors/blocks on the device available for use.

ntracks
Specifies the number of tracks per cylinder. This number may not actually reflect the number of tracks per cylinder but is an estimate (RAID devices).

nsectors
Specifies an average number of sectors per track.

ncylinders
Specifies an average number of cylinders per track.

attributes
Specifies one of the following device attributes: DEVGEOM_REMOVE (a removable device) or DEVGEOM_DYNAMIC (a dynamic geometry device).

sector_size
Specifies the number of bytes in the sector.

min_trans
Specifies the minimum number of bytes for the transfer size.

max_trans
Specifies the maximum number of bytes for the transfer size.

prefer_trans
Specifies the preferred number of bytes for the transfer size.


Example

The following code example shows how a disk device driver can use the DEVGETGEOM ioctl command. The example uses the attributes, dev_size, and sector_size members of the geom_info structure.


.
.
.
cdisk_ioctl(dev, cmd, data, flag) dev_t dev; /* major/minor number */ register int cmd; /* ioctl command */ caddr_t data; /* User data buffer - already copied in */ int flag; /* unused */
.
.
.
switch (cmd) {
.
.
.
/* * Disk geometry info. */ case DEVGETGEOM: { DEVGEOMST *devgeom = (DEVGEOMST *)data;
.
.
.
bzero((caddr_t)devgeom, sizeof(DEVGEOMST)); if(inqp->rmb) devgeom->geom_info.attributes |= DEVGEOM_REMOVE; /* * HSX00 and HSX01 FIB RAID devices are flagged * as having "dynamic geometry" because the * geometry of the underlying device can change * depending on the configuration of units. */ if ( dd->dd_flags & SZ_DYNAMIC_GEOM != 0) devgeom->geom_info.attributes |= DEVGEOM_DYNAMIC; /* * Get disk size via read capacity command. */ read_cap_data = (DIR_READ_CAP_DATA *) ccmn_get_dbuf((U32)sizeof(DIR_READ_CAP_DATA)); if(cdisk_read_capacity(pd, read_cap_data) == 0) { BTOL(&read_cap_data->lbn3, nblocks); /* * RDCAP returns the address of the last LBN. * Add one to get the number of LBNs. */ devgeom->geom_info.dev_size = ++nblocks; /* * Get the sector size. */ BTOL(&read_cap_data->block_len3, blk_len); devgeom->geom_info.sector_size = blk_len ;
.
.
.


Related Information

DEVIOCGET


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DEVGETINFO

Obtains information about a device


Synopsis

#include <sys/devgetinfo.h>


Description

The DEVGETINFO ioctl command returns information about a device by polling the underlying device driver. The DEVGETINFO ioctl command queries the device for as much information as it can, initializes members of the appropriate data structures within the device_info_t union, then assigns the address of this union to the user's data buffer.

The device_info_t union is the top-level definition of the information returned to the DEVGETINFO ioctl command. It has the following definition:

typedef union device_info {
    int version;
    v1_device_info_t v1;
    uchar_t pad[1024];
} device_info_t;

The v1_device_info_t structure contains all the information returned to the user data buffer by the DEVGETINFO ioctl command. This structure is contained within the device_info_t structure so that the same interface can be used for various versions of the data structure. It has the following definition:

typedef struct v1_device_info  {
    int version;
    short category;
    short bus;
    char interface[DEV_STRING_SIZE];
    char device[DEV_STRING_SIZE];
    char dev_name[DEV_STRING_SIZE];
    ulong_t soft_count;
    ulong_t hard_count;
    v1_devtype_info_t devinfo;
    v1_bustype_info_t businfo;
    uchar_t private[DEV_PRIVATE_LEN];
} v1_device_info_t;

The v1_devtype_info_t union returns device-specific information. The contents of the v1_devtype_info_t union depends on the device type, either disk, tape, or other device type. The structure has the following definition:

typedef union v1_devtype_info {
    v1_disk_dev_info_t disk;
    v1_tape_dev_info_t tape;
    uchar_t devdata[DEV_TYPE_LEN];
} v1_devtype_info_t;

The v1_bustype_info_t structure returns information about the bus type. It has the following definition:

typedef struct v1_bustype_info {
    int adpt_num;
    int nexus_num;
    int bus_num;
    int ctlr_num;
    int rctlr_num;
    int slave_num;
    int unit_num;
    int pad0;
    union {
        v1_scsi_bus_info_t scsi;
        uchar_t busdata[DEV_BUS_LEN];
    } bus;
} v1_bustype_info_t;

For disk devices, the v1_devtype_info_t union contains a v1_disk_dev_info_t structure, defined as follows:

typedef struct v1_disk_dev_info {
    ulong_t status;
    ulong_t capacity;
    ulong_t blocksz;
    uchar_t class;
    uchar_t part_num;
    uchar_t raid_level;
    uchar_t pad0;
    ushort_t media_changes;
    ushort_t pad1;
    union {
        struct {
            uchar_t density_code;
            uchar_t flags;
        } scsi;
        uchar_t archdata[DEV_ARCH_LEN];
    } arch;
} v1_disk_dev_info_t;

For tape devices, the v1_devtype_info_t union contains a v1_tape_dev_info_t structure, defined as follows:

typedef struct v1_tape_dev_info {
    uint_t  media_status;
    uint_t  unit_status;
    long    recordsz;
    long    density_bpi;
    long    density_bpi_wrt;
    long    position;
    long    fm_cnt;
    uchar_t class;
    uchar_t pad[7];
    union {
        struct {
            uint_t  blocking_factor;
            uchar_t valid_flags;
            uchar_t density_code;
            uchar_t buffered_mode;
            uchar_t speed;
            uchar_t compression_code;
        } scsi;
        uchar_t archdata[DEV_ARCH_LEN];
    } arch;
} v1_tape_dev_info_t;


Notes

The DEVGETINFO ioctl command replaces the DEVIOCGET ioctl command. Your driver may still support DEVIOCGET for backwards compatibility, but Digital recommends that you use the DEVGETINFO ioctl command. The DEVIOCGET ioctl command may not be supported in future releases.


Example

The following example shows how a device driver can return generic information about any device type. For information on filling in bus-specific information and polling a disk device for device-specific information, see Writing Device Drivers: Advanced Topics.


.
.
.
case DEVGETINFO: { struct device *device; [1] v1_device_info_t *devi_p; devi_p = (v1_device_info_t *)data; [2] bzero((caddr_t)devi_p,sizeof(*devi_p)); /**************************************************** * fill in generic information ****************************************************/ devi_p->version = VERSION_1; [3] devi_p->category = DEV_DISK; devi_p->bus = FILLIN; bcopy("XXX", devi_p->interface, 3); bcopy("xxxdev", devi_p->device, 6); bcopy("xx", devi_p->dev_name, 2); devi_p->soft_count = devp->soft_err_cnt; devi_p->hard_count = devp->hard_err_cnt;
.
.
.

  1. Declares the data structures and unions that this ioctl command returns. [Return to example]

  2. Assigns the address of the data buffer to the devi_p variable, casting the data buffer to a device information structure. In this way, information is returned to the caller. [Return to example]

  3. Provides general information about the device from hard-coded values, such as the version number and device category, or from device-specific data structures, such as the soft and hard error counts. [Return to example]


Related Information

device_info_t, v1_bustype_info_t, v1_device_info_t, v1_devtype_info_t, v1_disk_dev_info_t, v1_tape_dev_info_t


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DEVIOCGET

Obtains information about a device


Synopsis

#include <io/common/devio.h>
#include <sys/ioctl.h>


Description

The DEVIOCGET ioctl command obtains information about a device. This command obtains generic device information by polling the underlying device driver. DEVIOCGET uses the following structure defined in the file /usr/sys/include/io/common/devio.h:

struct  devget  {
        short      category;
        short      bus;
        char       interface[DEV_SIZE];
        char       device[DEV_SIZE];
        short      adpt_num;
        short      nexus_num;
        short      bus_num;
        short      ctlr_num;
        short      rctlr_num;
        short      slave_num;
        char       dev_name[DEV_SIZE];
        short      unit_num;
        unsigned   soft_count;
        unsigned   hard_count;
        long       stat;
        long       category_stat;
};

The following list describes the members of this structure:

category
Specifies the general class of the device. This member can be set to one of the following values: DEV_TAPE (tape category), DEV_DISK (disk category), DEV_TERMINAL (terminal category), DEV_PRINTER (printer category), or DEV_SPECIAL (special category).

bus
Specifies the communications bus type. For example, this member would be set to the value DEV_SCSI for SCSI devices.

interface
Specifies a string of up to eight characters that identifies the controller interface type.

device
This member is set to the device string.

adpt_num
This member is set to the adapter number.

nexus_num
This member is set to the nexus, or node, on the adapter number.

bus_num
This member is set to the bus number that the device controller resides on.

ctlr_num
This member is set to the specific controller number for the controller of this device. This controller number is the specific controller number on this bus.

rctlr_num
This member is set to the remote controller number.

slave_num
This member is set to the device unit number. For a disk device, this unit number is the physical device unit number. For a terminal device, this number is the terminal line number.

dev_name
This member is set to the device name type, which is a string of up to eight characters. For example, Digital defines the strings rz and tz to represent disk and tape devices, respectively.

unit_num
This member is set to the kernel configuration representation of a device unit number. The value in this member is frequently the same as the slave_num member. The difference is that slave_num represents the physical unit number, while the unit_num member represents a logical unit number for the device.

soft_count
This member is set to a driver counter of soft (noncritical) errors.

hard_count
This member is set to a driver counter of hardware errors.

stat
This member is set to the device status. This member is used primarily to represent drive status for tape devices. Some examples of drive status include the following: the drive is at the bottom or end of tape, or the drive is write-protected.

category_stat
This member is set to generic device status values, which are defined in /usr/sys/include/io/common/devio.h. The values are organized according to the following device types: tapes, disks, and communications devices.


Notes

The DEVGETINFO ioctl command replaces the DEVIOCGET ioctl command. Your driver may still support DEVIOCGET for backwards compatibility, but Digital recommends that you use the DEVGETINFO ioctl command. The DEVIOCGET ioctl command may not be supported in future releases.


Example

The following example prints out the device type and unit number:

 .
 .
 .
struct devget dev_st; [1]
if (ioctl (fd, DEVIOCGET, &dev_st) < 0) {
          printf ("DEVIOCGET failed\n");
          exit(1);
} [2]
printf ("Device type = %s\n",dev_st.device); [3]
printf ("Unit number = %d\n",dev_st.unit_num); [4]

  1. Declares a structure of type devget. [Return to example]

  2. Determines whether the call to ioctl succeeds or fails. Note that fd is an open file descriptor for the associated device special file. [Return to example]

  3. Obtains the device type. [Return to example]

  4. Obtains the unit number. [Return to example]


Related Information

DEVGETGEOM


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DIOCGCURPT

Returns the current partition map for a disk


Synopsis

#include <sys/disklabel.h>


Description

The DIOCGCURPT ioctl command returns the current partition map to the user data buffer in a pt_tbl structure. The pt_tbl structure contains an array of partition structures, up to the maximum partitions allowed on the device.


Example

See Writing Device Drivers: Advanced Topics for an example of how a disk device driver implements the DIOCGCURPT command.


Related Information

disklabel, pt_tbl


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DIOCGDEFPT

Returns the default partition map for a disk


Synopsis

#include <sys/disklabel.h>


Description

The DIOCGDEFPT ioctl command returns a disk's default partition map to the user data buffer. This information is returned in a pt_tbl structure, which contains an array of partition structures, up to the maximum number of partitions allowed on the device. The DIOCGDEFPT ioctl command can return the partition map regardless of whether a valid disklabel exists on the disk.


Example

See Writing Device Drivers: Advanced Topics for an example of how a disk device driver implements the DIOCGDEFPT command.


Related Information

disklabel, get_def_partitionmap, pt_tbl


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DIOCGDINFO

Returns a disk label


Synopsis

#include <sys/disklabel.h>


Description

The DIOCGDINFO ioctl command returns a disklabel structure to the user data buffer. If the disk label is not valid, it returns EINVAL.


Example

See Writing Device Drivers: Advanced Topics for an example of how a disk device driver implements the DIOCGDINFO command.


Related Information

disklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DIOCGPART

Returns information about a single disk partition


Synopsis

#include <sys/disklabel.h>


Description

The DIOCGPART ioctl command returns information about a device and partition. This information is returned in a partinfo structure, which contains pointers to the disklabel and partition structures for a single partition on a disk. If the disk does not have a disk label, the DIOCGPART ioctl command returns EINVAL.


Example

See Writing Device Drivers: Advanced Topics for an example of how a disk device driver implements the DIOCGPART command.


Related Information

disklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DIOCSDINFO

Sets a disklabel structure


Synopsis

#include <sys/disklabel.h>


Description

The DIOCSDINFO ioctl command sets the in-memory disklabel structure to the value specified in the user data buffer. Only users with root privileges are allowed to change the disklabel structure.


Example

See Writing Device Drivers: Advanced Topics for an example of how a disk device driver implements the DIOCSDINFO command.


Related Information

disklabel, setdisklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DIOCWDINFO

Writes a disk label


Synopsis

#include <sys/disklabel.h>


Description

The DIOCWDINFO ioctl command writes a disklabel structure and updates the in-memory copy of the structure. The command turns off write-protection for the duration of the request, but does not check to see if the user has root privileges.


Example

See Writing Device Drivers: Advanced Topics for an example of how a disk device driver implements the DIOCWDINFO command.


Related Information

disklabel, writedisklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


DIOCWLABEL

Sets a write-enable label on a disk


Synopsis

#include <sys/disklabel.h>


Description

The DIOCWLABEL ioctl command turns the write-protect flag on and off for the block where the disk label is kept.


Example

See Writing Device Drivers: Advanced Topics for an example of how a disk device driver implements the DIOCWLABEL command.


Related Information

disklabel


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


_IO

Defines ioctl types for device control operations


Synopsis

#include <sys/ioctl.h>

_IO (g, n)


Arguments

g
Specifies the group that this ioctl type belongs to. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive). You can pass the value zero (0) to this argument if a new ioctl group is not being defined.

n
Specifies the specific ioctl type within the group. These types should be sequentially assigned numbers for each different ioctl operation the driver supports. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive).


Description

The _IO macro defines ioctl types for situations where no data is actually transferred between the application program and the kernel. For example, this could occur in a device control operation.


Example

The following example uses the _IO macro to construct an ioctl called DN_OPERATION1. Note that DN_OPERATION1 passes the value zero (0) for the group that this ioctl belongs to and the value 1 to identify the specific ioctl type within the group.

#define DN_OPERATION1    _IO(0,1)


Related Information

_IOR, _IOW, _IOWR


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


_IOR

Defines ioctl types for device control operations


Synopsis

#include <sys/ioctl.h>

_IOR (g, n, t)


Arguments

g
Specifies the group that this ioctl type belongs to. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive). You can pass the value zero (0) to this argument if a new ioctl group is not being defined.

n
Specifies the specific ioctl type within the group. These types should be sequentially assigned numbers for each different ioctl operation the driver supports. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive).

t
Specifies the data structure size, which cannot exceed 128 bytes. You use this argument to size how much data is passed from the kernel back to the user application. The kernel determines the number of bytes to transfer by passing the value in this argument to the sizeof operator.


Description

The _IOR macro defines ioctl types for situations where data is transferred from the kernel into the user's buffer. Typically, this data consists of device control or status information returned to the application program.


Example

The following example uses the _IOR macro to construct an ioctl called DN_GETCOUNT. Note that DN_GETCOUNT passes the value zero (0) for the group that this ioctl belongs to and the value 2 to identify the specific ioctl type within the group. The DN_GETCOUNT ioctl also passes the data type int, which the kernel passes to the sizeof operator to determine how much data is passed from the kernel back to the user application.

#define DN_GETCOUNT    _IOR(0,2,int)


Related Information

DEVIOCGET, _IO, _IOW, _IOWR


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


_IOW

Defines ioctl types for device control operations


Synopsis

#include <sys/ioctl.h>

_IOW (g, n, t)


Arguments

g
Specifies the group that this ioctl type belongs to. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive). You can pass the value zero (0) to this argument if a new ioctl group is not being defined.

n
Specifies the specific ioctl type within the group. These types should be sequentially assigned numbers for each different ioctl operation the driver supports. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive).

t
Specifies the size of the data passed from the user application back to the kernel. The kernel determines the number of bytes to transfer by passing the value in this argument to the sizeof operator.


Description

The _IOW macro defines ioctl types for situations where data is transferred from the user's buffer into the kernel. Typically, this data consists of device control or status information passed to the driver from the application program.


Example

The following example uses the _IOW macro to construct an ioctl called DN_SETCOUNT. Note that DN_SETCOUNT passes the value zero (0) for the group that this ioctl belongs to and the value 3 to identify the specific ioctl type within the group. The DN_SETCOUNT ioctl also passes the data type int, which the kernel passes to the sizeof operator to determine how much data is passed from the user application back to the kernel.

#define DN_SETCOUNT    _IOR(0,3,int)


Related Information

_IO, _IOR, _IOWR


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


_IOWR

Defines ioctl types for device control operations


Synopsis

#include <sys/ioctl.h>

_IOWR (g, n, t)


Arguments

g
Specifies the group that this ioctl type belongs to. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive). You can pass the value zero (0) to this argument if a new ioctl group is not being defined.

n
Specifies the specific ioctl type within the group. These types should be sequentially assigned numbers for each different ioctl operation the driver supports. This argument must be a nonnegative 8-bit number (that is, in the range 0-255 inclusive).

t
Specifies the size of the data passed from the user application back to the kernel. The kernel determines the number of bytes to transfer by passing the value in this argument to the sizeof operator. Upon completion of the ioctl operation, this same data structure contains the data returned from the driver back to the user level application.


Description

The _IOWR macro defines ioctl types for situations where data is transferred from the user's buffer into the kernel. The driver then performs the appropriate ioctl operation and returns data of the same size back up to the user-level application. Typically, this data consists of device control or status information passed to the driver from the application program.


Example

The following example uses the _IOWR macro to construct an ioctl called DN_SETVERIFY. Note that DN_SETVERIFY passes the value zero (0) for the group that this ioctl belongs to and the value 4 to identify the specific ioctl type within the group. The DN_SETVERIFY ioctl also passes the data type int, which the kernel passes to the sizeof operator to determine how much data is passed from the user application back to the kernel.

#define DN_SETVERIFY    _IOWR(0,4,int)


Related Information

_IO, _IOR, _IOW


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


2.4    Global Variables

Table 2-4 summarizes the global variables that device drivers use.

Table 2-4: Summary Descriptions of Global Variables

Global Variable Summary Description
cpu Provides a unique logical processor-type family identifier.
hz Stores the number of clock ticks per second.
lbolt Is a periodic wakeup mechanism.
page_size Is the virtual page size.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


cpu

Provides a unique logical processor-type family identifier


Synopsis

extern int cpu;


Description

The cpu global variable provides a unique logical family identifier of the processor type of the running system. The logical system name can represent a single processor or a family of processor types. For example, the constant DEC_3000_500 represents the DEC 3000 Model 500 AXP Workstation. The defined processor names appear in the following file: /usr/sys/include/arch/alpha/hal/cpuconf.h.

You use the cpu global variable to conditionally execute processor-specific code. For example, the following code fragment calls a system-specific initialization interface for the DEC 3000 Model 500 AXP Workstation:

 .
 .
 .
if (cpu == DEC_3000_500) {
        init_3000_500();
}
 .
 .
 .


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


hz

Stores the number of clock ticks per second


Synopsis

extern int hz;


Location

/usr/sys/include/sys/kernel.h


Description

The hz global variable is set to the number of clock ticks per second. The value is useful for timing purposes. For example, if a device driver wants to schedule an interface to be run in 2 seconds, you could use the following call:

 .
 .
 .
timeout(lptout, (caddr_t)dev, 2*hz);
 .
 .
 .


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


lbolt

Is a periodic wakeup mechanism


Synopsis

extern time_t lbolt;


Location

/usr/sys/include/sys/kernel.h


Description

You use the lbolt global variable as a periodic wakeup mechanism. Wakeups are done on the lbolt variable once per second. For example, if a driver was polling for an event once per second, you could use the following code:

 .
 .
 .
sleep((caddr_t) &lbolt, PZERO);
 .
 .
 .


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


page_size

Is the virtual page size


Synopsis

extern vm_size_t page_size;


Location

/usr/sys/include/mach/vm_param.h


Description

The page_size global variable is the size of a virtual page on a CPU. A device driver can use this global variable to partition I/O transfers so that they never cross a virtual page boundary. You should use this global variable only when: