diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 0c6ba9c58a..39146f8543 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -469,6 +469,7 @@ pci_init(void) if (pci_controller_init() != B_OK) { TRACE(("PCI: pci_controller_init failed\n")); + panic("PCI: pci_controller_init failed\n"); return B_ERROR; } @@ -830,6 +831,15 @@ PCI::_FixupDevices(int domain, uint8 bus) FLOW("PCI: FixupDevices domain %u, bus %u\n", domain, bus); int maxBusDevices = _GetDomainData(domain)->max_bus_devices; + static int recursed = 0; + + if (recursed++ > 10) { + // guard against buggy chipsets + // XXX: is there any official limit ? + dprintf("PCI: FixupDevices: too many recursions (buggy chipset?)\n"); + recursed--; + return; + } for (int dev = 0; dev < maxBusDevices; dev++) { uint16 vendorId = ReadConfig(domain, bus, dev, 0, PCI_vendor_id, 2); @@ -857,9 +867,12 @@ PCI::_FixupDevices(int domain, uint8 bus) int busBehindBridge = ReadConfig(domain, bus, dev, function, PCI_secondary_bus, 1); + TRACE(("PCI: FixupDevices: checking bus %d behind %04x:%04x\n", + busBehindBridge, vendorId, deviceId)); _FixupDevices(domain, busBehindBridge); } } + recursed--; } @@ -981,6 +994,15 @@ PCI::_DiscoverBus(PCIBus *bus) FLOW("PCI: DiscoverBus, domain %u, bus %u\n", bus->domain, bus->bus); int maxBusDevices = _GetDomainData(bus->domain)->max_bus_devices; + static int recursed = 0; + + if (recursed++ > 10) { + // guard against buggy chipsets + // XXX: is there any official limit ? + dprintf("PCI: DiscoverBus: too many recursions (buggy chipset?)\n"); + recursed--; + return; + } for (int dev = 0; dev < maxBusDevices; dev++) { uint16 vendorID = ReadConfig(bus->domain, bus->bus, dev, 0, @@ -995,6 +1017,7 @@ PCI::_DiscoverBus(PCIBus *bus) if (bus->next) _DiscoverBus(bus->next); + recursed--; }