aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-07-09 01:46:04 -0400
committerIan Moffett <ian@osmora.org>2024-07-09 01:46:04 -0400
commit54c9c5246e28a8a3d586a5f7346e38648ef2b3f9 (patch)
treef7663e42ac340c660da2845546e101a05258ac54
parentf031ad404e544c9332498a11d9956b27a4acc72b (diff)
kernel: pci: Add PCI device lookups
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/dev/pci/pci.c42
-rw-r--r--sys/include/dev/pci/pci.h16
2 files changed, 58 insertions, 0 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 680e5ac..587881a 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -127,6 +127,48 @@ pci_scan_bus(uint8_t bus)
}
}
+struct pci_device *
+pci_get_device(struct pci_lookup lookup, uint16_t lookup_type)
+{
+ struct pci_device *dev;
+ uint16_t lookup_matches = 0;
+
+ TAILQ_FOREACH(dev, &device_list, link) {
+ if (ISSET(lookup_type, PCI_DEVICE_ID)) {
+ /* Check device ID */
+ if (lookup.device_id == dev->device_id)
+ lookup_matches |= PCI_DEVICE_ID;
+ }
+
+ if (ISSET(lookup_type, PCI_VENDOR_ID)) {
+ /* Check vendor ID */
+ if (lookup.vendor_id == dev->vendor_id)
+ lookup_matches |= PCI_VENDOR_ID;
+ }
+
+ if (ISSET(lookup_type, PCI_CLASS)) {
+ /* Check PCI class */
+ if (lookup.pci_class == dev->pci_class)
+ lookup_matches |= PCI_CLASS;
+ }
+
+ if (ISSET(lookup_type, PCI_SUBCLASS)) {
+ /* Check PCI subclass */
+ if (lookup.pci_subclass == dev->pci_subclass)
+ lookup_matches |= PCI_SUBCLASS;
+ }
+
+ if (lookup_type == lookup_matches) {
+ /* We found the device! */
+ return dev;
+ }
+
+ lookup_matches = 0;
+ }
+
+ return NULL;
+}
+
int
pci_init(void)
{
diff --git a/sys/include/dev/pci/pci.h b/sys/include/dev/pci/pci.h
index 4e2ceec..3d37b05 100644
--- a/sys/include/dev/pci/pci.h
+++ b/sys/include/dev/pci/pci.h
@@ -33,8 +33,22 @@
#include <sys/types.h>
#include <sys/queue.h>
+/* Lookup bits */
+#define PCI_DEVICE_ID BIT(0)
+#define PCI_VENDOR_ID BIT(1)
+#define PCI_CLASS BIT(2)
+#define PCI_SUBCLASS BIT(3)
+
typedef uint32_t pcireg_t;
+/* For PCI lookups */
+struct pci_lookup {
+ uint16_t device_id;
+ uint16_t vendor_id;
+ uint8_t pci_class;
+ uint8_t pci_subclass;
+};
+
struct pci_device {
uint8_t bus;
uint8_t slot;
@@ -51,6 +65,8 @@ struct pci_device {
};
pcireg_t pci_readl(struct pci_device *dev, uint32_t offset);
+struct pci_device *pci_get_device(struct pci_lookup lookup, uint16_t lookup_type);
+
void pci_writel(struct pci_device *dev, uint32_t offset, pcireg_t val);
int pci_init(void);