From a08f40f82858531d79aae148af1083d15745847c Mon Sep 17 00:00:00 2001 From: beveloper Date: Wed, 17 Sep 2003 20:38:39 +0000 Subject: [PATCH] added basic bus scanning git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4741 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/bus_managers/pci/pci.c | 65 ++++++++++++++++++++--- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/pci/pci.c b/src/add-ons/kernel/bus_managers/pci/pci.c index b66e7eeb99..e4bda900ed 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.c +++ b/src/add-ons/kernel/bus_managers/pci/pci.c @@ -3,19 +3,70 @@ #include #include "pci_priv.h" -bool gIrqRouterAvailable = false; +bool gIrqRouterAvailable = false; +spinlock gConfigLock = 0; -void pci_scan_bus(uint8 bus); -long get_nth_pci_info(long index, pci_info *outInfo); -status_t pci_module_init(void); -status_t pci_module_uninit(void); -int32 std_ops(int32 op, ...); -status_t pci_module_rescan(void); +void pci_scan_device(uint8 bus, uint8 dev, uint8 func); +void pci_scan_bus(uint8 bus); +long get_nth_pci_info(long index, pci_info *outInfo); +status_t pci_module_init(void); +status_t pci_module_uninit(void); +int32 std_ops(int32 op, ...); +status_t pci_module_rescan(void); + +void +pci_scan_device(uint8 bus, uint8 dev, uint8 func) +{ + uint16 vendorID; + uint16 deviceID; + uint8 base_class, sub_class; + + deviceID = pci_read_config(bus, dev, 0, PCI_device_id, 2); + if (deviceID == 0xffff) + return; + + dprintf("PCI: pci_scan_device, bus %u, device %u, function %u\n", bus, dev, func); + + vendorID = pci_read_config(bus, dev, 0, PCI_vendor_id, 2); + + base_class = pci_read_config(bus, dev, func, PCI_class_base, 1); + sub_class = pci_read_config(bus, dev, func, PCI_class_sub, 1); + + dprintf("PCI: vendor 0x%04x, device 0x%04x, base_class 0x%02x, sub_class 0x%02x\n", + vendorID, deviceID, base_class, sub_class); + + if (base_class == PCI_bridge) { + uint8 secondary_bus = pci_read_config(bus, dev, func, PCI_secondary_bus, 1); + pci_scan_bus(secondary_bus); + } +} void pci_scan_bus(uint8 bus) { + uint8 dev; + + dprintf("PCI: pci_scan_bus, bus %u\n", bus); + + for (dev = 0; dev < gMaxBusDevices; dev++) { + uint16 vendorID = pci_read_config(bus, dev, 0, PCI_vendor_id, 2); + uint16 deviceID; + uint8 type, func, nfunc; + if (vendorID == 0xffff) + continue; + + deviceID = pci_read_config(bus, dev, 0, PCI_device_id, 2); + type = pci_read_config(bus, dev, 0, PCI_header_type, 1); + type &= PCI_header_type_mask; + if ((type & PCI_multifunction) == 0 /*&& !pci_quirk_multifunction(vendorID, deviceID) */) + nfunc = 1; + else + nfunc = 8; + + for (func = 0; func < nfunc; func++) + pci_scan_device(bus, dev, func); + } }