From 35f6af0388812fb8b50d0d38555d58014d20e41f Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Sun, 16 Dec 2007 22:49:45 +0000 Subject: [PATCH] PCI bus enumeration shouldn't be required on x86, thus enable it only for PPC an M68k git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23137 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/bus_managers/pci/pci.cpp | 53 +++++++++++++++++++-- src/add-ons/kernel/bus_managers/pci/pci.h | 3 ++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 6f5ccc9ba4..7f044a6ddf 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -310,7 +310,11 @@ pci_uninit(void) PCI::PCI() : fRootBus(0) , fDomainCount(0) + , fBusEnumeration(false) { + #if defined(__POWERPC__) || defined(__M68K__) + fBusEnumeration = true; + #endif } @@ -329,8 +333,16 @@ PCI::InitBus() ppnext = &bus->next; } - for (int i = 0; i < fDomainCount; i++) { - EnumerateBus(i, 0); + if (fBusEnumeration) { + for (int i = 0; i < fDomainCount; i++) { + EnumerateBus(i, 0); + } + } + + if (1) { + for (int i = 0; i < fDomainCount; i++) { + FixupDevices(i, 0); + } } if (fRootBus) { @@ -508,8 +520,6 @@ PCI::EnumerateBus(int domain, uint8 bus, uint8 *subordinate_bus) if (device_id == 0xffff) continue; - pci_fixup_device(this, domain, bus, dev, func); - uint8 base_class = ReadPciConfig(domain, bus, dev, func, PCI_class_base, 1); uint8 sub_class = ReadPciConfig(domain, bus, dev, func, PCI_class_sub, 1); if (base_class != PCI_bridge || sub_class != PCI_pci) @@ -555,6 +565,41 @@ PCI::EnumerateBus(int domain, uint8 bus, uint8 *subordinate_bus) } +void +PCI::FixupDevices(int domain, uint8 bus) +{ + TRACE(("PCI: FixupDevices domain %u, bus %u\n", domain, bus)); + + int maxBusDevices = GetDomainData(domain)->max_bus_devices; + + for (int dev = 0; dev < maxBusDevices; dev++) { + uint16 vendorId = ReadPciConfig(domain, bus, dev, 0, PCI_vendor_id, 2); + if (vendorId == 0xffff) + continue; + + uint8 type = ReadPciConfig(domain, bus, dev, 0, PCI_header_type, 1); + int nfunc = (type & PCI_multifunction) ? 8 : 1; + for (int func = 0; func < nfunc; func++) { + uint16 deviceId = ReadPciConfig(domain, bus, dev, func, PCI_device_id, 2); + if (deviceId == 0xffff) + continue; + + pci_fixup_device(this, domain, bus, dev, func); + + uint8 base_class = ReadPciConfig(domain, bus, dev, func, PCI_class_base, 1); + if (base_class != PCI_bridge) + continue; + uint8 sub_class = ReadPciConfig(domain, bus, dev, func, PCI_class_sub, 1); + if (sub_class != PCI_pci) + continue; + + int busBehindBridge = ReadPciConfig(domain, bus, dev, func, PCI_secondary_bus, 1); + + FixupDevices(domain, busBehindBridge); + } + } +} + void PCI::DiscoverBus(PCIBus *bus) diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index b099682031..225f702508 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -83,6 +83,8 @@ class PCI { void EnumerateBus(int domain, uint8 bus, uint8 *subordinate_bus = NULL); + void FixupDevices(int domain, uint8 bus); + void DiscoverBus(PCIBus *bus); void DiscoverDevice(PCIBus *bus, uint8 dev, uint8 func); @@ -111,6 +113,7 @@ class PCI { domain_data fDomainData[MAX_PCI_DOMAINS]; int fDomainCount; + bool fBusEnumeration; }; #endif // __cplusplus