NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | Allowed Calling Contexts | ATTRIBUTES | SEE ALSO
#include <ddi/pci/pciFi.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 PCI 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. 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 the bus and the device drivers. From a bus driver perspective, the fault injection bus driver looks like a normal instance of a device driver 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 PCI DDI. Thus, a PCI fault injection bus driver usually provides two interfaces:
The standard PCI 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 (upstream) and call appropriate handlers in the device driver (downstream).
The PCI fault injection DDI allows 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 PCI 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 PCI bus resource is correctly allocated before being used.
A PCI bus resource is not used twice.
The arguments to a PCI DDI call are in the correct range.
All PCI bus resources are freed when the driver closes its connection to the bus.
The PCI bus fault injection DDI provides all services defined by the common bus fault injection DDI, plus some PCI-specific services:
Notifying the device driver that it has connected to the PCI bus.
Restarting a failed device driver.
Controlling interrupt delivery to a device driver:
Delivering a spurious interrupt.
Ignoring a device interrupt.
Controlling access to the PCI configuration space from a device driver:
Corrupting configuration register load/store operations.
Ignoring a configuration store operation.
Controlling I/O register access from a device driver:
Corrupting I/O register load/store operations.
Ignoring an I/O store operation.
Raising an I/O error.
Controlling (32- and 64-bit address) 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.
Refusing allocation of a PCI bus resource 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 PCI fault injection service routines are defined by the PciFiOps structure. A pointer to the PciFiOps structure is exported by a PCI 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 routine vector. Once the pointer is obtained, the driver client is able to invoke the driver service routines (via indirect function calls).
The PciFiOps structure is the following:
typedef struct PciFiOps { PciFiVersion version; KnError (*open) (PciFiId busId, PciFiConf* conf, PciFiCallbacks* cb, void* cookie); void (*close) (PciFiId busId); KnError (*restart) (PciFiId busId); KnError (*intr_get_access) (PciFiId busId, PciPropIntr* intr, PciFiIntrOps** intrOps, PciFiIntrId* intrId); void (*intr_release) (PciFiIntrId intrId); KnError (*io_get_access) (PciFiId busId, PciPropIoRegs* ioRegs, PciFiIoOps** ioOps, PciFiIoId* ioId); void (*io_release) (PciFiIoId ioId); KnError (*mem_get_access) (PciFiId busId, PciPropMemRgn* memRgn, PciFiMemOps** memOps, PciFiMemId* memId); KnError (*mem_release) (PciFiMemId memId); KnError (*mem64_get_access) (PciFiId busId, Pci64PropMemRgn* memRgn, PciFi64MemOps** memOps, PciFi64MemId* memId); KnError (*mem64_release) (PciFi64MemId memId); KnError (*conf_get_access) (PciFiId busId, uint8_f busNum, uint8_f devNum, uint8_f funcNum, PciFiConfOps** confOps, PciFiConfId* confId); KnError (*conf_release) (PciFiConfId confId); KnError (*bus_evt_raise) (PciFiId busId, PciBusEvent event, void* arg, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*resource_refuse) (PciFiId busId, char* propName, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*op_chain) (PciFiId busId, PciFiOpId opId, PciFiOpId nextOp); KnError (*op_start) (PciFiId busId, PciFiOpId opId, PciFiExecHandler execHandler, void* cookie, PciFiRunId* runId); void (*op_stop) (PciFiRunId runId); KnError (*op_free) (PciFiOpId opId); KnError (*chain_free) (PciFiOpId opId); } PciFiOps;
The version field specifies the version number of the PCI fault injection API. The version number is increased by increments each time one of the DDI structures is extended 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 PCI fault injection bus driver instance. The conf argument specifies the limits to use when computing random delays for fault injection operations. It points to a PciFiConf structure which it inherits from the 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 PciFiCallbacks structure which it inherits from the 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 has just called its bus driver's open function (initialization).
The closeNotify handler notifies the client that the driver being tested has just called its bus driver's close function (shutdown).
The cookie argument specifies a client's cookie. This 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 codes 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 child driver tested which is 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, an error code is returned as described below:
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 operations tested are requested for each PCI bus resource. The PCI bus resources used by a device are specified as properties attached to the device node. The properties used for pciFi DDI are those defined by the PCI DDI. Please refer to pci(9DDI) for more details about PCI bus properties.
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 operation created by passing a PciFiOpDesc structure to the driver. The PciFiOpDesc inherits from the BusFiOpDesc structure, 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 for 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 obtains access and control over the source handling of a given bus interrupt. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The intr argument specifies the PCI interrupt source. It points to a PciPropIntr interrupt property value.
Typically, a fault injector client should find such a property (attached to the device node) using the "intr" name, obtain a pointer to the property value and specify it in intr_get_access.
Upon successful completion, intr_get_access returns K_OK, and a valid intrOps / intrId pair.
intrOps points to a PciFiIntrOps structure which provides the fault injection service routines specific to the interrupt source requested (see section PciFiIntrOps).
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 PciFiIntrOps 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.
PciFiIntrOps provides the fault injection services defined for PCI interrupt sources and inherits from the BusFiIntrOps:
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 in:
The interrupt handler of the device driver tested will not be called, but the interrupt will be considered to be claimed (handled) by the underlying bus driver.
The interrupt handler of the device driver tested will not be called, and the interrupt will be considered to be unclaimed (not handled) by the underlying bus driver. This may be useful to simulate interrupts on an interrupt line which are "stuck".
The opDesc argument specifies the required attributes for the operation created (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 operation created (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 conf_get_access service routine obtains access and control over the load and store operations performed by the driver tested on its device PCI configuration space. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The busNum, devNum and funcNum arguments specify the PCI configuration space.
Typically, a fault injector client should find these numbers as properties attached to the device node (or to the device's parent node for busNum) using the bus-num, dev-num and func-num names, obtain a pointer to the property values and specify them in conf_get_access.
Upon successful completion, conf_get_access returns K_OK, and a valid confOps / confId pair.
confOps points to a PciFiConfOps structure which provides the fault injection service routines specific to the requested configuration space (see section PciFiConfOps).
confId 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 PciFiConfOps and conf_release service routines.
In case of failure, an error code is returned as described below:
The specified configuration space is invalid.
The system is out of memory.
The conf_release service routine releases access to the configuration space.
typedef struct PciFiConfOps { KnError (*load_8) (PciFiConfId confId, uint8_f offset, PciFiMask_8* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*load_16) (PciFiConfId confId, uint8_f offset, PciFiMask_16* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*load_32) (PciFiConfId confId, uint8_f offset, PciFiMask_32* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_8) (PciFiConfId confId, uint8_f offset, PciFiMask_8* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_16) (PciFiConfId confId, uint8_f offset, PciFiMask_16* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_32) (PciFiConfId confId, uint8_f offset, PciFiMask_32* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_ignore) (PciFiConfId confId, uint8_f offset, PciFiOpDesc* opDesc, PciFiOpId* opId); } PciFiConfOps;
The load_xx set of service routines create a fault injection operation to corrupt (modify) the value read from the configuration space by the device driver being tested. The value read is modified using bit mask values before being returned to the caller. The confId argument specifies the configuration space. The offset argument specifies the offset of the register within the configuration header to be corrupted. offset must be in the mapped range, or can be set to PCIFI_OFFSET_ALL to specify any valid offset in the configuration space. The mask argument points to a PciFiMask_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 configuration value loaded. 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 return K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
offset is outside the mapped configuration space.
The system is out of memory.
The store_xx set of service routines creates a fault injection operation to corrupt (modify) the value stored in a given configuration space location by the device driver being tested. The value from the caller is modified using bit mask values before being stored. The confId argument specifies the configuration space. The offset argument specifies the offset of the register within the configuration header to be corrupted. offset must be in the range of the mapped configuration space, or can be set to PCIFI_OFFSET_ALL to specify any valid offset in that range. The mask argument points to a PciFiMask_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. The opDesc argument specifies the required attributes for the operation created (see section Fault injection operation attributes).
Upon successful completion, the store_xx set of routines return K_OK, and a valid operation identifier in the opId argument. Otherwise, one of the following error codes is returned:
offset is out of range of the mapped configuration space.
The system is out of memory.
The store_ignore service routine creates a fault injection operation to ignore a store operation to configuration space requested by the device driver being tested. The store operation is silently discarded. The confId argument specifies the configuration space. The offset argument specifies the offset of the register within the range of the configuration space for which a store should be ignored. offset must be in the range of the mapped configuration space, or it can be set to PCIFI_OFFSET_ALL to specify any valid offset in that space. The opDesc argument specifies the required attributes for the operation created (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 range of the configuration space.
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 tested driver on a given PCI I/O register range. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The ioRegs argument specifies the range of the PCI I/O register and points to PciPropIoRegs.
Typically, 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.
Upon successful completion, io_get_access returns K_OK, and a valid ioOps / ioId pair.
ioOps points to a PciFiIoOps structure which provides the fault injection service routines specific to the range of the requested I/O register (see section PciFiIoOps).
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 PciFiIoOps 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 PciFiIoOps { KnError (*load_8) (PciFiIoId ioId, PciSize offset, PciFiMask_8* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*load_16) (PciFiIoId ioId, PciSize offset, PciFiMask_16* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*load_32) (PciFiIoId ioId, PciSize offset, PciFiMask_32* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*load_64) (PciFiIoId ioId, PciSize offset, PciFiMask_64* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_8) (PciFiIoId ioId, PciSize offset, PciFiMask_8* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_16) (PciFiIoId ioId, PciSize offset, PciFiMask_16* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_32) (PciFiIoId ioId, PciSize offset, PciFiMask_32* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_64) (PciFiIoId ioId, PciSize offset, PciFiMask_64* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*store_ignore) (PciFiIoId ioId, PciSize offset, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*error_raise) (PciFiIoId ioId, PciBusError* error, PciFiOpDesc* opDesc, PciFiOpId* opId); } PciFiIoOps;
The load_xx set of service routines create 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 to be corrupted. offset must be in the mapped I/O range, or can be set to PCIFI_OFFSET_ALL to specify any valid offset in the I/O range. The mask argument points to a PciFiMask_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 operation created (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 in a given I/O register by the device driver being tested. The value from the caller is modified using bitmask values before being stored in 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 to be corrupted. offset must be in the mapped I/O range, or can be set to PCIFI_OFFSET_ALL to specify any valid offset in the I/O range. The mask argument points to a PciFiMask_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 in 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 for a given I/O register by the device driver being tested. 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 for which an I/O store should be ignored. offset must be in the mapped I/O range or can be set to PCIFI_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 tested. The ioId argument specifies the I/O register range. The error argument specifies the error to be raised. It points to a PciError structure indicating the error code and the offset within the I/O range where the error occurred. Please refer to pci(9DDI) for the definition of PciError. 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 tested. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The memRgn argument specifies the PCI bus memory region. It points to a PciPropMemRgn property value.
Typically, 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.
Upon successful completion, mem_get_access returns K_OK, and a valid memOps / memId pair.
memOps points to a PciFiMemOps structure which provides the fault injection service routines specific to the requested PCI memory region (see section PciFiMemOps).
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 PciFiMemOps and mem_release service routines.
In case of failure, an error code is returned as described below:
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 PciFiMemOps { KnError (*corrupt) (PciFiMemId memId, PciSize offset, PciFiMask_8* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*error_raise) (PciFiMemId memId, PciBusError* error, PciFiOpDesc* opDesc, PciFiOpId* opId); } PciFiMemOps;
The corrupt routine creates a fault injection operation to corrupt (modify) a given byte in a PCI memory region which is used by the driver being tested. The memory byte is read and modified using bit mask values before being written back to PCI memory. The memId argument specifies the memory region. The offset argument specifies the offset of the byte that should be corrupted within the memory region. offset must be in the range of the mapped PCI memory region, or it can be set to PCIFI_OFFSET_ALL to specify any valid offset in the memory region. The mask argument points to a PciFiMask_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 operation created (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 outside the memory region, or the PCIFI_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 tested. The memId argument specifies the memory region. The error argument specifies the PCI error to be raised. It points to a PciError structure indicating the error code and the offset within the memory region where the error occurred. Please refer to pci(9DDI) for the definition of PciError. The opDesc argument specifies the required attributes for the operation created (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 the PCIFI_OP_COUNT attribute is set in opDesc.
The system is out of memory.
The mem64_get_access and mem64_release service routines are defined to deal with the 64-bit address PCI memory region. These services use types defined in PCI DDI for 64-bit PCI memory regions, and behave in exactly the same way as their counterparts for 32-bit PCI memory regions.
The memOps returned points to a PciFiMem64Ops structure which provides the fault injection service routines which are specific to the requested 64-bit PCI memory region:
typedef struct PciFi64MemOps { KnError (*corrupt) (PciFi64MemId memId, Pci64Size offset, PciFiMask_8* mask, PciFiOpDesc* opDesc, PciFiOpId* opId); KnError (*error_raise) (PciFi64MemId memId, Pci64BusError* error, PciFiOpDesc* opDesc, PciFiOpId* opId); } PciFi64MemOps;
The corrupt and error_raise routines provide services for 64-bit PCI memory regions with exactly the same semantics as their counterparts for 32-bit PCI memory regions (see section PciFiMemOps above).
The bus_evt_raise service routine creates a fault injection operation to simulate and raise the given PCI bus event to the device driver tested. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The event and arg arguments specify the PCI event to be raised. Please refer to pci(9DDI) for details about available PCI event values and the associated specific arguments. The opDesc argument specifies the required attributes for the operation created (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 the PCIFI_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 executed sequentially. op_chain is the elementary operation allowing you to link two fault injection operations together, however it can be used repeatedly to create sets of any length. In addition, a cyclic set can be built by chaining the first and the last operations in the set. The busId argument specifies the fault injection bus driver instance (taken from svDeviceEntry). The opId and nextOp arguments specify the fault injection operations to be chained. opId must be a stand-alone operation, that is, it should not be chained. 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 set of operations which is already running.
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. The opId argument specifies the fault injection operation to be freed. It must not be chained into a set of operations which is already running.
Upon successful completion, op_free routine returns K_OK. Otherwise, the following error code is returned:
opId is chained into a set of operations which is already running.
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 which one of the fault injection operation in the set is to be freed. The set of operations must not be running.
Upon successful completion, the chain_free routine returns K_OK. Otherwise, the following error code is returned:
opId is chained into a set of operations which is already running.
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. If opId is chained in a set of operations, execution will begin with the first operation in the set (which may be different from opId). 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 back in the context of an interrupt. Therefore the API used in such a handler is restricted to an interrupt handler.
The PCI fault injection execution handler inherits from the common bus execution 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 the first argument to the execHandler handler when called. The second argument of the execHandler handler is the identifier of the operation, or set of operations, running. The third argument is the identifier of the operation in the set to which the status/event applies. The last argument gives the reason for the call and indicates the execution status, as follows:
The last operation in a set has been executed and it has no chained operations. The set is considered to be terminated and is put in the stopped state. The opId specifies the last operation to be executed.
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 the opId specifies the last operation to be executed.
The set of operations has been stopped by the fault injector client using the op_stop service routine. The opId specifies the last operation to be executed.
The tested driver has released a PCI bus resource (*_unmap, *_detach) which was used to inject faults. The associated set of operations is stopped and the opId specifies the operation associated to the freed resource.
The driver tested has closed its connection to the bus driver. The remaining set of operations, relating to resources which have not yet been released, is stopped. The opId specifies the last operation to be executed.
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 has already started or is chained into a set of operations which are already running.
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 |
---|---|---|---|---|
PciFiOps.open | - | + | - | + |
PciFiOps.close | - | + | - | + |
PciFiOps.restart | - | + | - | + |
PciFiOps.intr_get_access | - | + | - | + |
PciFiOps.intr_release | - | + | - | + |
PciFiOps.conf_get_access | - | + | - | + |
PciFiOps.conf_release | - | + | - | + |
PciFiOps.io_get_access | - | + | - | + |
PciFiOps.io_release | - | + | - | + |
PciFiOps.mem_get_access | - | + | - | + |
PciFiOps.mem_release | - | + | - | + |
PciFiOps.mem64_get_access | - | + | - | + |
PciFiOps.mem64_release | - | + | - | + |
PciFiOps.bus_evt_raise | - | + | - | + |
PciFiOps.resource_refuse | - | + | - | + |
PciFiOps.op_chain | - | + | - | + |
PciFiOps.op_start | - | + | - | + |
PciFiOps.op_stop | - | + | - | - |
PciFiOps.op_free | - | + | - | + |
PciFiOps.chain_free | - | + | - | + |
PciFiIntrOps.intr_ignore | - | + | - | + |
PciFiIntrOps.intr_trigger | - | + | - | + |
PciFiConfOps.load_xx | - | + | - | + |
PciFiConfOps.store_xx | - | + | - | + |
PciFiConfOps.store_ignore | - | + | - | + |
PciFiIoOps.load_xx | - | + | - | + |
PciFiIoOps.store_xx | - | + | - | + |
PciFiIoOps.store_ignore | - | + | - | + |
PciFiIoOps.error_raise | - | + | - | + |
PciFiMemOps.corrupt | - | + | - | + |
PciFiMemOps.error_raise | - | + | - | + |
PciFiMem64Ops.corrupt | - | + | - | + |
PciFiMem64Ops.error_raise | - | + | - | + |
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
bus(9DDI), pci(9DDI), busFi(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