diff options
author | Ian Moffett <ian@osmora.org> | 2024-07-09 01:46:04 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-07-09 01:46:04 -0400 |
commit | 54c9c5246e28a8a3d586a5f7346e38648ef2b3f9 (patch) | |
tree | f7663e42ac340c660da2845546e101a05258ac54 | |
parent | f031ad404e544c9332498a11d9956b27a4acc72b (diff) |
kernel: pci: Add PCI device lookups
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | sys/dev/pci/pci.c | 42 | ||||
-rw-r--r-- | sys/include/dev/pci/pci.h | 16 |
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); |