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>
diff --git a/drivers/pcie/host/pcie.c b/drivers/pcie/host/pcie.c
index 79c41e7..9e7d06d 100644
--- a/drivers/pcie/host/pcie.c
+++ b/drivers/pcie/host/pcie.c
@@ -29,7 +29,7 @@
 
 	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 @@
 				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 @@
 				uint32_t id;
 
 				id = pcie_conf_read(bdf, PCIE_CONF_ID);
-				if (id == PCIE_ID_NONE) {
+				if (!PCIE_ID_IS_VALID(id)) {
 					continue;
 				}
 
diff --git a/drivers/pcie/host/shell.c b/drivers/pcie/host/shell.c
index 6b5a5db..307a2c9 100644
--- a/drivers/pcie/host/shell.c
+++ b/drivers/pcie/host/shell.c
@@ -147,7 +147,7 @@
 
 	data = pcie_conf_read(bdf, PCIE_CONF_ID);
 
-	if (data == PCIE_ID_NONE) {
+	if (!PCIE_ID_IS_VALID(data)) {
 		return;
 	}
 
diff --git a/include/zephyr/drivers/pcie/pcie.h b/include/zephyr/drivers/pcie/pcie.h
index 65ef67e..704589a 100644
--- a/include/zephyr/drivers/pcie/pcie.h
+++ b/include/zephyr/drivers/pcie/pcie.h
@@ -37,6 +37,16 @@
  */
 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;