NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | Allowed Calling Contexts | ATTRIBUTES | SEE ALSO
#include <ddi/bus/busFi.h>
The function or functions documented here may not be used safely in all application contexts with all APIs provided in the ChorusOS 5.0 product.
See API(5FEA) for details.
DDI
Provides common bus fault injection driver services.
The purpose of a fault injection bus driver is to verify that a device driver is resilient to hardware faults. It helps build and validate hardened device drivers. Basically, a fault injection bus driver is a filter between a real bus driver and its connected device drivers. The existence of such a filter is totally transparent to both bus and device drivers. From a bus driver perspective, the fault injection bus driver looks like a normal device driver instance started on a child device node. From a device driver perspective, the fault injection bus driver looks like a normal parent bus driver providing the requested bus DDI. Thus, a fault injection bus driver typically provides two interfaces:
The standard bus DDI is provided to the device driver being tested. These operations are implemented as wrapper functions which call appropriate methods on the real parent bus driver (in an upstream direction) and call appropriate handlers in the device driver (in a downstream direction).
The bus fault injection DDI allows for a fault-injector client to change this basic behavior by injecting faults to simulate a device malfunction.
By monitoring the device driver requests issued to the bus, a fault injection bus driver is able to perform multiple checks on the validity of those requests and their arguments. This allows you to detect many problems in the device drivers. Typically, a fault injection bus driver is able to check whether:
A bus resource is correctly allocated before being used.
A bus resource is not used twice.
Arguments to a bus DDI call are in the correct range.
All bus resources are freed when the driver closes its connection to the bus.
The common bus fault injection DDI provides the following services to fault injector clients:
Notifying the device driver that it has connected to the bus.
Restarting a failed device driver.
Controlling interrupt delivery to a device driver:
Delivering a spurious interrupt.
Ignoring a device interrupt.
Controlling I/O register access from a device driver:
Corrupting I/O registers load/store operations.
Ignoring an I/O store operation.
Raising an I/O error.
Controlling device memory access from a device driver:
Corrupting content of a memory location.
Raising a memory access error.
Raising bus events to a device driver.
Chaining required fault injection operations into an ordered sequential set.
Managing the chained set of fault injection operations:
Starting a set of operations.
Stopping a running set of operations.
The bus fault injection service routines are defined by the BusFiOps structure. A pointer to the BusFiOps structure is exported by a bus fault injection driver via the svDeviceRegister microkernel call. A fault injector client invokes the svDeviceLookup and svDeviceEntry microkernel calls in order to obtain a pointer to the fault injection service routines vector. Once a pointer is obtained, the driver client is able to invoke the driver service routines (via indirect function calls).
The BusFiOps structure is as follows:
typedef struct BusFiOps { BusFiVersion version; KnError (*open) (BusFiId busId, BusFiConf* conf, BusFiCallbacks* cb, void* cookie); void (*close) (BusFiId busId); KnError (*restart) (BusFiId busId); KnError (*intr_get_access) (BusFiId busId, void* prop, BusFiIntrOps** intrOps, BusFiIntrId* intrId); void (*intr_release) (BusFiIntrId intrId); KnError (*io_get_access) (BusFiId busId, void* ioRegs, BusFiIoOps** ioOps, BusFiIoId* ioId); void (*io_release) (BusFiIoId ioId); KnError (*mem_get_access) (BusFiId busId, void* memRgn, BusFiMemOps** memOps, BusFiMemId* memId); KnError (*mem_release) (BusFiMemId memId); KnError (*bus_evt_raise) (BusFiId busId, BusEvent event, void* arg, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*op_chain) (BusFiId busId, BusFiOpId opId, BusFiOpId nextOp); KnError (*op_start) (BusFiId busId, BusFiOpId opId, BusFiExecHandler execHandler, void* cookie, BusFiRunId* runId); void (*op_stop) (BusFiRunId runId); KnError (*op_free) (BusFiOpId opId); KnError (*chain_free) (BusFiOpId opId); void* (*intr_find) (void* prop, int index); void* (*io_regs_find) (void* prop, int index); void* (*mem_rgn_find) (void* prop, int index); } BusFiOps;
The version field specifies the bus fault injection API version number. The version number is increased by increments each time one of the DDI structures is extended in order to include new service routines.
open must be the first call issued by the client to the fault injection bus driver. It establishes a connection between the fault injection bus driver and its client. The busId argument specifies the fault injection bus driver instance. The conf argument specifies the limits to use when computing random delay for fault injection operations. It points to a BusFiConf structure:
typedef struct BusFiConf { unsigned int minCount; /* lower limit for random count */ unsigned int maxCount; /* upper limit for random count */ KnTimeVal minTimeVal; /* lower limit for random timeval */ KnTimeVal maxTimeVal; /* upper limit for random timeval */ } BusFiConf;
The cb argument specifies the fault injector client notification handlers. It points to a BusFiCallbacks structure:
typedef struct BusFiCallbacks { void (*openNotify) (void* cookie); void (*closeNotify) (void* cookie); } BusFiCallbacks;
The openNotify handler notifies the client that the driver being tested just called its bus driver's open function (initialization).
The closeNotify handler notifies the client that the driver being tested just called its bus driver's close function (shutdown).
The cookie argument specifies a client's cookie. It is an opaque parameter for the fault injection bus driver which is passed back as an argument when calling the client's notification handlers.
Upon successful completion, open returns K_OK. Otherwise, one of the following error code is returned:
The conf argument is invalid.
The fault injection bus driver identified by busId is already in use (opened).
The system is out of memory.
The close routine releases the client/fault injection bus driver connection. It must be the last call issued.
restart tries to restart the tested child driver bound to the device node. It calls the drv_init method of the driver. This operation is typically used by the fault injector client to restart a failed device driver.
Upon successful completion, restart returns K_OK. Otherwise, one of the following error codes is returned:
The child driver is already started.
No child driver is bound to the device node, or it failed to initialize.
Fault injection and control over the driver being tested operations are requested on a per bus resource basis. Bus resources used by a device are specified as properties attached to the device node. The properties used for busFi DDI are the same as those defined by the bus DDI. In addition, the intr_find, io_regs_find and mem_rgn_find services are also exported through the busFi DDI to allow a fault injector client to manage an array of properties. Please refer to bus(9DDI) for details about bus properties management.
When a fault injection bus driver is requested to simulate a fault on a given bus resource used by a device driver, it creates a "fault injection operation". The fault injector client can specify attributes for each created operation by passing a BusFiOpDesc structure to the driver. The BusFiOpDesc structure is described below:
typedef uint32_f BusFiOpAttr; typedef struct BusFiOpDesc { BusFiOpAttr attr; uint32_f count; KnTimeVal timeval; } BusFiOpDesc;
attr is a bit field that should be built by or-ing the following constant values:
The count field is valid and indicates the number of events to wait for before executing the operation.
The timeval field is valid and indicates the delay (specified as a KnTimeVal structure) to wait before executing the operation.
The fault injection bus driver will choose a random delay value (count or timeval) before executing the operation.
The fault injection bus driver will log a message into the system when executing the operation.
The intr_get_access service routine gets access and control over bus interrupt source handling. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The intr argument specifies the bus interrupt source and points to an interrupt property value which is bus class specific.
Typically, the bus class API defines a structure (or a basic type) which specifies the value format for an interrupt resource property attached to the device node. A fault injector client should find such a property (attached to the device node) using the intr argument, obtain a pointer to the property value and specify it in intr_get_access. In cases where the property value specifies multiple interrupt sources (the property value is an array of the interrupt source descriptors), the client should use the intr_find routine in order to obtain a pointer to a given interrupt source descriptor within the array.
Upon successful completion, intr_get_access returns K_OK, and a valid intrOps / intrId pair.
intrOps points to a BusFiIntrOps structure which provides the fault injection service routines specific to the requested interrupt source (see section BusFiIntrOps).
intrId is opaque for the fault injector client. It is passed back to the fault injection bus driver as an argument in subsequent invocations of the BusFiIntrOps and intr_release service routines.
In case of failure, one of the following error codes is returned:
The specified interrupt property is invalid.
The system is out of memory.
The intr_release service routine releases access to the interrupt source.
typedef struct BusFiIntrOps { KnError (*intr_ignore) (BusFiIntrId intrId, BusIntrStatus status, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*intr_trigger) (BusFiIntrId intrId, BusFiOpDesc* opDesc, BusFiOpId* opId); } BusFiIntrOps;
The intr_ignore service routine creates a fault injection operation to prevent delivery of a given interrupt to the driver being tested. The intrId specifies the interrupt source. The status argument specifies the interrupt status to return to the real bus driver in place of the value that would have been returned by the interrupt handler, if called. The status must be:
The interrupt handler of the driver being tested will not be called but the interrupt will be considered claimed (handled) by the underlying bus driver.
The interrupt handler of the driver being tested will not be called, and the interrupt will be considered unclaimed (not handled) by the underlying bus driver. This may be useful to simulate stuck interrupts on an interrupt line.
The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, intr_ignore returns K_OK, and a valid operation identifier in the opId argument. Otherwise, the following error code is returned:
The system is out of memory.
The intr_trigger service routine creates a fault injection operation to simulate the occurrence of a given interrupt and to trigger attached interrupt handlers in the device driver being tested. The intrId argument specifies the interrupt source. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, intr_trigger returns K_OK and a valid operation identifier in the opId argument. Otherwise, the following error code is returned:
The system is out of memory.
The io_get_access service routine gets access and control over the load and store operations performed by the driver being tested on a given bus I/O register range. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The ioRegs argument specifies the bus I/O register range. It points to a property value which is bus class specific.
Typically, the bus class API defines a structure which specifies the value format for an I/O register range resource property attached to the device node. A fault injector client should find such a property (attached to the device node) using the io-regs name, obtain a pointer to the property value and specify it in io_get_access. In cases where the property value specifies multiple I/O ranges (the property value is an array of the I/O range descriptors), the client should use the io_regs_find routine in order to obtain a pointer to a given I/O range descriptor within the array.
Upon successful completion io_get_access returns K_OK and a valid ioOps / ioId pair.
ioOps points to a BusFiIoOps structure which provides the fault injection service routines specific to the requested I/O register range (see section BusFiIoOps).
ioId is opaque for the fault injector client. It is passed back to the fault injection bus driver as an argument in subsequent invocations of the BusFiIoOps and io_release service routines.
In case of failure, one of the following error codes is returned:
The specified I/O register range property is invalid.
The system is out of memory.
The io_release service routine releases access to the I/O register range.
typedef struct BusFiIoOps { KnError (*load_8) (BusFiIoId ioId, BusSize offset, BusFiMask_8* mask, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*load_16) (BusFiIoId ioId, BusSize offset, BusFiMask_16* mask, BusFiOpDesc* opDesc, BusFiOpId* opId)); KnError (*load_32) (BusFiIoId ioId, BusSize offset, BusFiMask_32* mask, BusFiOpDesc* opDesc, BusFiOpId* opId)); KnError (*load_64) (BusFiIoId ioId, BusSize offset, BusFiMask_64* mask, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*store_8) (BusFiIoId ioId, BusSize offset, BusFiMask_8* mask, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*store_16) (BusFiIoId ioId, BusSize offset, BusFiMask_16* mask, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*store_32) (BusFiIoId ioId, BusSize offset, BusFiMask_32* mask, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*store_64) (BusFiIoId ioId, BusSize offset, BusFiMask_64* mask, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*store_ignore) (BusFiIoId ioId, BusSize offset, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*error_raise) (BusFiIoId ioId, BusError* error, BusFiOpDesc* opDesc, BusFiOpId* opId); } BusFiIoOps;
The load_xx set of service routines creates a fault injection operation to corrupt (modify) the value read from a given I/O register by the device driver being tested. The value read from the register is modified using bit mask values before being returned to the caller. The ioId argument specifies the I/O register range. The offset argument specifies the offset of the register within the I/O range that should be corrupted. offset must be in the mapped I/O range, or can be set to BUSFI_OFFSET_ALL to specify any valid offset in the I/O range. The mask argument points to a BusFiMask_xx structure which provides clear and set bitmasks. These bitmasks are used in the following formula to corrupt the loaded value:
returned_value = (loaded_value & clear) | set;
Alternatively, the mask argument may be set to NULL to specify that the fault injection bus driver must choose random clear and set bitmasks to corrupt the value read from the I/O register. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, the load_xx set of routines returns K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
offset is out of the I/O register range.
The system is out of memory.
The store_xx set of service routines creates a fault injection operation to corrupt (modify) the value stored by the device driver being tested into a given I/O register. The value from the caller is modified using bit mask values before being stored into the I/O register. The ioId argument specifies the I/O register range. The offset argument specifies the offset of the register within the I/O range that should be corrupted. offset must be in the mapped I/O range, or can be set to BUSFI_OFFSET_ALL to specify any valid offset in the I/O range. The mask argument points to a BusFiMask_xx structure which provides clear and set bitmasks. These bitmasks are used in the following formula to corrupt the loaded value:
stored_value = (provided_value & clear) | set;
Alternatively, the mask argument may be set to NULL to specify that the fault injection bus driver must choose random "clear" and "set" bitmasks to corrupt the value stored into the I/O register. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, the store_xx set of routines returns K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
offset is out of the I/O register range.
The system is out of memory.
The store_ignore service routine creates a fault injection operation to ignore an I/O store operation requested by the device driver being tested for a given I/O register. The store operation is silently discarded. The ioId argument specifies the I/O register range. The offset argument specifies the offset of the register within the I/O range to which an I/O store should be ignored. offset must be in the mapped I/O range, or can be set to BUSFI_OFFSET_ALL to specify any valid offset in the I/O range. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, the store_ignore routine returns K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
offset is out of the I/O register range.
The system is out of memory.
The error_raise service routine creates a fault injection operation to simulate and raise the given I/O error to the device driver being tested. The ioId argument specifies the I/O register range. The error argument specifies the error to be raised. It points to a BusError structure indicating the error code and the offset within the I/O range where the error occurred. Please refer to bus(9DDI) for details about BusError definition. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, the error_raise routine returns K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
The error argument is invalid.
The system is out of memory.
The mem_get_access service routine gets access and control over a given bus memory region used by the driver being tested. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The memRgn argument specifies the bus memory region. It points to a property value which is bus class specific.
Typically, the bus class API defines a structure which specifies the value format for a memory region resource property attached to the device node. A fault injector client should find such a property (attached to the device node) using the mem-rgn name, obtain a pointer to the property value and specify it in mem_get_access. In cases where the property value specifies multiple memory regions (the property value is an array of the memory region descriptors), the client should use the mem_rgn_find routine in order to obtain a pointer to a given memory region descriptor within the array.
Upon successful completion, mem_get_access returns K_OK, and a valid memOps / memId pair.
memOps points to a BusFiMemOps structure which provides the fault injection service routines specific to the requested memory region (see section BusFiMemOps).
memId is opaque for the fault injector client. It is passed back to the fault injection bus driver as an argument in subsequent invocations of the BusFiMemOps and mem_release service routines.
In case of failure, one of the following error codes is returned:
The specified memory region property is invalid.
The system is out of memory.
The mem_release service routine releases access to the memory region.
typedef struct BusFiMemOps { KnError (*corrupt) (BusFiMemId memId, BusSize offset, BusFiMask_8* mask, BusFiOpDesc* opDesc, BusFiOpId* opId); KnError (*error_raise) (BusFiMemId memId, BusError* error, BusFiOpDesc* opDesc, BusFiOpId* opId); } BusFiMemOps;
The corrupt routine creates a fault injection operation to corrupt (modify) a given byte into a memory region used by the driver being tested. The memory byte is read, modified using bit mask values before being written back to memory. The memId argument specifies the memory region. The offset argument specifies the offset of the byte within the memory region that should be corrupted. offset must be in the mapped memory region range, or can be set to BUSFI_OFFSET_ALL to specify any valid offset in the memory region. The mask argument points to a BusFiMask_8 structure which provides clear and set bitmasks. These bitmasks are used in the following formula to corrupt the loaded value:
corrupted_value = (initial_value & clear) | set;
Alternatively, the mask argument may be set to NULL to specify that the fault injection bus driver must choose random "clear" and "set" bitmasks to corrupt the memory region location. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, the corrupt routine returns K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
offset is out of the memory region, or BUSFI_OP_COUNT attribute is set in opDesc.
The system is out of memory.
The error_raise service routine creates a fault injection operation to simulate and raise the given error to the device driver being tested. The memId argument specifies the memory region. The error argument specifies the error to be raised. It points to a BusError structure indicating the error code and the offset within the memory region where the error occurred. Please refer to bus(9DDI) for details about BusError definition. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, the error_raise routine returns K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
The error argument is invalid, or BUSFI_OP_COUNT attribute is set in opDesc.
The system is out of memory.
The bus_evt_raise service routine creates a fault injection operation to simulate and raise the given bus event to the device driver being tested. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The event and arg arguments specify the event to be raised. Please refer to bus(9DDI) for details about available event values and associated specific arguments. The opDesc argument specifies the required attributes for the created operation (see section Fault injection operation attributes).
Upon successful completion, the bus_evt_raise routine returns K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
The event argument is invalid, or BUSFI_OP_COUNT attribute is set in opDesc.
The system is out of memory.
The op_chain service routine links together previously created fault injection operations in order to obtain a set of operations that will be sequentially executed in a given order. op_chain is the elementary operation that enables two fault injection operations to be linked together. It can be used repeatedly to create sets of any length. In addition, a cyclic set can be built by chaining the last and first operations in the set. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The opId and nextOp arguments specify which fault injection operations are to be chained. opId must be a standalone operation (not chained yet). The operations are chained in such a way that opId will always execute before nextOp in the set.
Upon successful completion, the op_chain routine returns K_OK. Otherwise, one of the following error codes is returned:
The opId operation is already chained to another operation, or opId and nextOp are already chained into different sets.
opId or nextOp are already chained into a started (running) set of operations.
The system is out of memory.
The op_free service routine frees a previously created fault injection operation. The operation is unlinked from its set of operations, if any. The opId argument specifies the fault injection operation to be freed. It must not be chained into a started (running) set of operations.
Upon successful completion, the op_free routine returns K_OK. Otherwise, the following error code is returned:
opId is chained into a started (running) set of operations.
The chain_free service routine frees a previously created fault injection operation and all the operations chained in the same set. The opId argument specifies one of the fault injection operations in the set to be freed. The set of operations must not be started (running).
Upon successful completion, the chain_free routine returns K_OK. Otherwise, the following error code is returned:
opId is chained into a started (running) set of operations.
The op_start service routine starts executing a previously created fault injection operation (or set of operations). The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The opId argument specifies the fault injection operation to be started. In the case that opId is chained in a set of operations, execution of op_start begins with the first operation in the set. The execHandler argument is a handler in the client that is called back to report status or events related to the execution of the operation (or set of operations).
The execHandler may be called in the context of an interrupt so that the API used is restricted to the API of the interrupt handler.
typedef void (*BusFiExecHandler) (void* cookie, BusFiRunId runId, BusFiOpId opId, BusFiReason reason);
The cookie argument is opaque for the fault injection bus driver and is passed back as a first argument to the execHandler handler when called. The second argument of the execHandler handler is the identifier of the running operation (or set of operations). The third argument is the identifier of the operation in the set to which the status/event applies. The last argument contains the reason for the call and indicates the execution status as follows:
The last operation in a set has been executed and has no chained operation. The set is considered terminated and is put in the stopped state. The opId specifies the last executed operation.
The last operation in a cyclic set has been executed and the fault injection driver has looped back to the first operation. The set of operations is still running and opId specifies the last executed operation.
The set of operations has been stopped by the fault injector client using the op_stop service routine. The opId specifies the last executed operation.
The driver being tested has released a bus resource (*_unmap, *_detach) which was used to inject faults. The associated set of operations is stopped and opId specifies the operation associated to the freed resource.
The driver being tested has closed its connection to the bus driver. The remaining set of operations, related to resources not yet released, are stopped. opId specifies the last executed operation.
Upon successful completion, the op_start routine returns K_OK and an identifier for the operation, or set of operations, running is returned into runId (an argument to be passed to the op_stop routine). Otherwise, one of the following error codes is returned:
The opId operation is already started or chained into a running set of operations.
The system is out of memory.
The op_stop service routine stops a previously started fault injection operation or set of operations. The runId argument must be an identifier returned by a previous call to the op_start routine.
The following table specifies the contexts in which a caller is allowed to invoke each service:
Services | Base level | DKI thread | Interrupt | Blocking |
---|---|---|---|---|
BusFiOps.open | - | + | - | + |
BusFiOps.close | - | + | - | + |
BusFiOps.restart | - | + | - | + |
BusFiOps.intr_get_access | - | + | - | + |
BusFiOps.intr_release | - | + | - | + |
BusFiOps.io_get_access | - | + | - | + |
BusFiOps.io_release | - | + | - | + |
BusFiOps.mem_get_access | - | + | - | + |
BusFiOps.mem_release | - | + | - | + |
BusFiOps.bus_evt_raise | - | + | - | + |
BusFiOps.op_chain | - | + | - | + |
BusFiOps.op_start | - | + | - | + |
BusFiOps.op_stop | - | + | - | - |
BusFiOps.op_free | - | + | - | + |
BusFiOps.chain_free | - | + | - | + |
BusFiOps.intr_find | + | + | - | - |
BusFiOps.io_regs_find | + | + | - | - |
BusFiOps.mem_rgn_find | + | + | - | - |
BusFiIntrOps.intr_ignore | - | + | - | + |
BusFiIntrOps.intr_trigger | - | + | - | + |
BusFiIoOps.load_xx | - | + | - | + |
BusFiIoOps.store_xx | - | + | - | + |
BusFiIoOps.store_ignore | - | + | - | + |
BusFiIoOps.error_raise | - | + | - | + |
BusFiMemOps.corrupt | - | + | - | + |
BusFiMemOps.error_raise | - | + | - | + |
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
bus(9DDI), svDeviceRegister(9DKI), svDeviceLookup(9DKI), svDeviceEntry(9DKI), dtreePropFind(9DKI), dtreePropValue(9DKI), svMemAlloc(9DKI), svDkiThreadCall(9DKI)
NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | Allowed Calling Contexts | ATTRIBUTES | SEE ALSO