pcie: Add helper macro to identify valid identifiers

PCI(e) host controllers behave in different ways (some more buggy than
others) in what value they use to indicate that an endpoint is not
present. In most cases the VID/DID is all ones (PCIE_ID_NONE) but in
others it's all zeroes, and some may even have the VID all zeroes and
the DID all ones, or vice-versa.

Add a macro to easily test for all these possibilities. The "all ones"
and "all zeroes" cases have been verified to exist on actual HW
supported by Zephyr, however the test for the mixed cases is simply
based on what Linux considers valid values (drivers/pci/probe.c in the
Linux kernel tree).

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2022-11-18 16:31:20 +02:00 committed by Carles Cufí
parent 18aee8703b
commit a2c8fdca33
3 changed files with 14 additions and 4 deletions

View File

@ -29,7 +29,7 @@ bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id)
data = pcie_conf_read(bdf, PCIE_CONF_ID);
if (data == PCIE_ID_NONE) {
if (!PCIE_ID_IS_VALID(data)) {
return false;
}
@ -356,7 +356,7 @@ pcie_bdf_t pcie_bdf_lookup(pcie_id_t id)
uint32_t data;
data = pcie_conf_read(bdf, PCIE_CONF_ID);
if (data == PCIE_ID_NONE) {
if (!PCIE_ID_IS_VALID(data)) {
continue;
}
@ -386,7 +386,7 @@ static int pcie_init(const struct device *dev)
uint32_t id;
id = pcie_conf_read(bdf, PCIE_CONF_ID);
if (id == PCIE_ID_NONE) {
if (!PCIE_ID_IS_VALID(id)) {
continue;
}

View File

@ -147,7 +147,7 @@ static void show(const struct shell *sh, pcie_bdf_t bdf, bool dump)
data = pcie_conf_read(bdf, PCIE_CONF_ID);
if (data == PCIE_ID_NONE) {
if (!PCIE_ID_IS_VALID(data)) {
return;
}

View File

@ -37,6 +37,16 @@ typedef uint32_t pcie_bdf_t;
*/
typedef uint32_t pcie_id_t;
/* Helper macro to exclude invalid PCIe identifiers. We should really only
* need to look for PCIE_ID_NONE, but because of some broken PCI host controllers
* we have try cases where both VID & DID are zero or just one of them is
* zero (0x0000) and the other is all ones (0xFFFF).
*/
#define PCIE_ID_IS_VALID(id) ((id != PCIE_ID_NONE) && \
(id != PCIE_ID(0x0000, 0x0000)) && \
(id != PCIE_ID(0xFFFF, 0x0000)) && \
(id != PCIE_ID(0x0000, 0xFFFF)))
struct pcie_dev {
pcie_bdf_t bdf;
pcie_id_t id;