NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | ATTRIBUTES | SEE ALSO
#include <ddi/pci/pcimngr.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
The PCI resource manager interface provides an interface (DDI) used by PCI bus drivers to manage PCI resources such as I/O or memory regions. This avoids code duplication in all PCI bus drivers as they can rely on a single, generic PCI resource manager driver for the dynamic resource allocation services defined by the PCI DDI. The PCI DDI defines entry points for dynamic resource allocation, such as resource_alloc() and resource_free(). Thus each PCI bus driver should provide these services. The code to implement these services is rather generic and in order to avoid code duplication in all PCI bus drivers, a PCI resource manager driver exporting the PCIMNGR DDI could be used.
The PCIMNGR DDI is designated by the PCIMNGR_CLASS class represented by the "pcimngr" character string. At initialization time, a PCI bus driver looks for the pcimngr driver in the driver registry. If an entry is found, the PCI bus driver starts an instance of the auxiliary PCI resource manager driver. Once started, the PCI resource manager driver instance exports services to the PCI bus driver in the form of a PciMngrOps structure. This structure contains pointers to indirect functions implementing the exported services. A pointer to the PciMngrOps structure can be retrieved by the PCI bus driver using the the svDeviceEntry() micro-kernel call.
In order to launch a PCI manager driver instance associated to a given PCI bus driver, the pciMngrStart() routine is available in the library:
The node input argument specifies a given PCI bus node. This routine tries to detect the PCI manager driver in the driver registry using a predefined PCI manager driver name. The PCI manager driver name (PCIMNGR_DRV_NAME) is defined by the PCIMNGR DDI as the "sun:pci-generic-pcimngr" string. If the PCI manager driver is found, the driver initialization routine is called. Then, the pciMngrStart routine tries to detect an associated PCI manager driver instance in the device registry. If the driver instance if found, the PCI manager open method is called in order to establish connection between the PCI bus and PCI manager drivers.
Upon successful completion, pciMngrStart() returns K_OK and gives the PCI manager client identifier via the id output argument. Otherwise, an error code is returned. pciMngrStart() returns K_ENOTIMP if the PCI manager driver is not found in the driver registry. Other error codes which can be returned by pciMngrStart() are caused by either svDeviceLookup() or open().
The PCIMNGR DDI defines a "max-devs" (PCIMNGR_PROP_MAX_DEVS) property. This property may optionally be attached to the PCI bus node prior to the PCI manager driver launching. The property value specifies the maximal number of PCI devices which may be connected to the bus. This is a hint for the PCI manager driver which may be used in the resource allocation policy.
In order to shutdown the PCI manager driver instance associated to a given PCI bus driver, the pciMngrStop() routine is available in the library:
The id input argument specifies a given PCI manager driver instance. It is given by the pciMngrStart() routine. The pciMngrStop() routine closes connection to the PCI manager driver and releases the PCI manager driver instance in the device registry.
The PciMngrOps structure is defined below:
typedef struct PciMngrOps { PciMngrVersion version; KnError (*open) (PciMngrId id); KnError (*resource_provision) (PciMngrId id, DevProperty prop); KnError (*resource_add) (PciMngrId id, DevProperty prop); KnError (*node_resource_alloc) (PciMngrId id, DevNode node); void (*node_resource_free) (PciMngrId id, DevNode node); KnError (*resource_alloc) (PciMngrId id, DevNode node, DevProperty prop); void (*resource_free) (PciMngrId id, DevNode node, DevProperty prop); void (*close) (PciMngrId id); } PciMngrOps;
The id input argument is the PCI resource manager dev_id field as returned by the svDeviceEntry() microkernel call. It must be given to all services/operations defined in the PciMngrOps structure.
All services/operations defined in the PciMngrOps structure must be called in the context of the DKI thread.
The version field specifies the highest version number of the PCIMNGR DDI supported by the driver. Currently, only one version is available and therefore the version field is always set to zero (PCIMNGR_VERSION_INITIAL). In the future, the PCIMNGR interface may be extended, but backward compatibility is guaranteed; extra methods may be added to the PciMngrOps structure but the existing methods will remain unchanged.
The open method() is the first call a PCI bus driver must make in order to open connection to the PCI resource manager auxiliary driver. It enables subsequent invocations of all other methods. This function is called first in order to setup the PCI resource manager driver state. The PCI resource manager driver looks at the "bus-num" and "sub-bus-num" properties attached to the bus node and initializes the driver state accordingly in order to handle subsequent allocations of bus numbers. All other resources are set to an empty state. They should be explicitly given to the PCI resource manager via the resource_add() invocation.
Upon successful completion, the open routine returns K_OK.
The open() routine returns K_ENOMEM if the system is out of memory resources.
The open routine returns K_EINVAL if the "bus-num" or "sub-bus-num" property is not found.
The resource_provision() service is used by a PCI bus driver to get provision for a given resource type. The resource is specified by the prop argument. The property name gives the resource type. The property size gives number of windows which may be used for this resource. This function analyzes resource requirements given by the child nodes and fills in the property value according to such requirements.
The following resources may be specified by the prop argument:
(PCI_PROP_IO_REGS)
(PCI_PROP_MEM_RGN)
(PCI64_PROP_MEM_RGN)
This function is typically called by a PCI bus driver at initialization time in order to know resources needed for child devices. This is normally used by a bus driver instance which has been started on a node without statically pre-allocated bus resources. So, the PCI bus driver has to allocate bus resources dynamically. Before doing that, the PCI bus driver issues the resource_provision() call for each type of PCI bus resources. Once the resource provision is done, the PCI bus driver tries to allocate this resource and, if the resource is successfully allocated, the PCI bus driver issues the resource_add() call in order to make the resource available for subsequent allocations through the PCI resource manager service routines.
Upon successful completion, resource_provision() returns K_OK.
The resource_provision() routine returns K_EUNKNOWN if an unknown property name is specified.
The resource_provision() routine returns K_ENOMEM if the system is out of memory resources.
Note that the resource provision feature is optional. If the PCI manager driver does not support such a feature, the K_ENOTIMPL error code is returned by resource_provision().
The resource_add() service adds available resources to the PCI resource manager. Once a resource is added, it becomes available for subsequent allocations.
The prop property specifies available resources to add. The following resource types may be specified by the prop argument:
(PCI_PROP_IO_REGS)
(PCI_PROP_MEM_RGN)
(PCI64_PROP_MEM_RGN)
This function is called by a PCI bus driver in order to make a given resource available for subsequent allocations through the PCI manager service routines. This is typically done at bus driver instance initialization time. Available resources, given to the PCI resource manager driver, may be configured statically as well as allocated dynamically from the parent bus driver.
Upon successful completion, the resource_add routine() returns K_OK.
The resource_add() routine returns K_ENOMEM if the system is out of memory resources.
The resource_add() routine returns K_EUNKNOWN if an unknown property name is specified.
The resource_add() routine returns K_EINVAL if the resource cannot be added.
The node_resource_alloc() service allocates resources specified in properties found in a given device node.
The following resources are taken into account:
(PCI_PROP_BUS_NUM)
(PCI_PROP_SUB_BUS_NUM)
(PCI_PROP_INTR)
(PCI_PROP_IO_REGS)
(PCI_PROP_MEM_RGN)
(PCI64_PROP_MEM_RGN)
This function is called by a PCI bus driver in order to allocate resources for the device node specified by the node argument.
Note that this function may be called not only at bus driver initialization time, but also at run time when a hot-plug device insertion occurs on the bus and, therefore, a new device node is created.
Upon successful completion, the node_resource_alloc() routine returns K_OK.
The node_resource_alloc() routine returns K_ENOMEM if the system is out of memory resources.
The node_resource_alloc() routine returns K_EFAIL if resources are not available.
The node_resource_free() service frees resources found in the given device node. Resources being released are specified by device node properties.
The following resources are taken into account:
(PCI_PROP_BUS_NUM)
(PCI_PROP_SUB_BUS_NUM)
(PCI_PROP_INTR)
(PCI_PROP_IO_REGS)
(PCI_PROP_MEM_RGN)
(PCI64_PROP_MEM_RGN)
This function is called by a PCI bus driver in order to free resources assigned to a given device node. Note that this function is typically called at run time when a hot-plug device removal occurs on the bus and, therefore, an existing device node has to be deleted and resources assigned to it have to be released. Note that the device node state is not altered by node_resource_free(). In other words, all resource properties remain attached to the node.
The resource_alloc() service allocates a given bus resource specified by the prop argument and, if satisfied, adds it to a given device node specified by the node argument.
The following resources may be requested:
(PCI_PROP_BUS_NUM)
(PCI_PROP_SUB_BUS_NUM)
(PCI_PROP_INTR)
(PCI_PROP_IO_REGS)
(PCI_PROP_MEM_RGN)
(PCI64_PROP_MEM_RGN)
Because the dynamic resource allocation is totally managed by the PCI resource manager driver, a PCI bus driver normally simply forwards a dynamic resource allocation request issued by a child PCI driver to the auxiliary PCI manager driver.
Note that it is allowed for a caller to request a zero resource size for an I/O or memory region. This means that the caller has no idea about needed resource size. Usually, this happens for a bus bridge drivers with hot-plug capability. In this case, the PCI manager driver will determine itself the allocated resource size. The mechanism used by the PCI manager driver to take such a decision is driver implementation specific.
Upon successful completion, the resource_alloc() routine returns K_OK and the property is attached to the device node specified by the node argument. If a zero size has been specified in the property value, the size field is updated in order to reflect the really allocated resource size.
The resource_alloc() routine returns K_ENOMEM if the system is out of memory resources.
The resource_alloc() routine returns K_EUNKNOWN if an unknown property name is specified.
The resource_alloc() returns K_EFAIL if resource is not available.
The resource_free() service frees the given bus resource specified by the prop argument and updates a given device node specified by the node argument in order to remove the resource property. So, the property object is detached from the device node and freed.
The following resources may be requested:
(PCI_PROP_BUS_NUM)
(PCI_PROP_SUB_BUS_NUM)
(PCI_PROP_INTR)
(PCI_PROP_IO_REGS)
(PCI_PROP_MEM_RGN)
(PCI64_PROP_MEM_RGN)
Because the dynamic resource allocation is totally managed by the PCI resource manager driver, a PCI bus driver normally simply forwards a resource free request issued by a child PCI driver to the auxiliary PCI manager driver.
The close() service is used by a PCI bus driver to close a connection to the PCI resource manager auxiliary driver. This function is called by the PCI bus driver when it is going to be shuted down. In this case, a PCI bus driver has to shut down the adjacent PCI resource manager driver instance. Typically, a PCI bus driver calls close and then the svDeviceRelease() microkernel call to release the PCI manager driver instance in the device registry.
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | ATTRIBUTES | SEE ALSO