Load a capability module
#include <pci/pci.h> pci_err_t pci_device_read_cap( pci_bdf_t bdf, pci_cap_t *cap, uint_t idx );
Once you've found a desired capability index (by using pci_device_read_capid() or pci_device_find_capid()), you can call pci_device_read_cap() using the idx parameter in order to initialize the cap argument and trigger the loading of the capabilities module.
Although there's no need to call pci_device_read_cap() more than once for each capability, you can call it again using the pci_cap_t returned on the first successful call.
If pci_device_read_cap() fails on a subsequent call using the cap returned from an initial call (i.e., with cap = NULL), the pci_cap_t initially received is destroyed, and you must make a new call with cap = NULL.
After a successful call to pci_device_read_cap(), you can use the APIs for the capability module using the returned pci_cap_t argument in order to configure the capability as desired.
Finally, once the capability has been configured (as applicable), you can enable the capability by calling pci_device_cfg_cap_enable(). If a device supports a capability for which there's no capability module, pci_device_read_cap() returns an error indicating that the capability can't be used.
When you no longer need the pci_cap_t returned from a successful pci_device_read_cap() call, you can release it with free().
The following internal errors are specifically related to internal resource availability and use, and are atypical:
If any error occurs, you should consider the contents of the capargument to be invalid data.
#include <pci/pci.h> #include <pci/cap_pcie.h> int_t cap_pcie_idx = pci_device_find_capid(bdf, CAPID_PCIe); if (cap_pcie_idx >= 0) { pci_cap_t pcie_cap = NULL; pci_err_t r = pci_device_read_cap(bdf, &pcie_cap, cap_pcie_idx); if (r == PCI_ERR_OK) { /* enable and use the capability */ /* done with the capability */ free(pcie_cap); } }
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | No |
Signal handler | No |
Thread | Yes |