diff options
author | Liav A <liavalb@gmail.com> | 2022-01-15 09:15:46 +0200 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-19 21:54:41 +0200 |
commit | c1d3b557d5c6dc7bee53388f3b2e1db82b799ed8 (patch) | |
tree | 8a2f3080f4e5018fdceec355349d0bdf78ab2415 /Kernel/Bus/PCI/Controller | |
parent | 518473846a0ca84a5f1be8b39b5764207c11c195 (diff) | |
download | serenity-c1d3b557d5c6dc7bee53388f3b2e1db82b799ed8.zip |
Kernel/PCI: Don't try to enumerate 255 functions on the host bridge
There can only be a limited number of functions (only 8).
Also, consider the start bus of the PCI domain when trying to enumerate
other host bridges on bus 0, device 0, functions 1-7 (function 0 is the
main host bridge).
Diffstat (limited to 'Kernel/Bus/PCI/Controller')
-rw-r--r-- | Kernel/Bus/PCI/Controller/HostBridge.cpp | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/Kernel/Bus/PCI/Controller/HostBridge.cpp b/Kernel/Bus/PCI/Controller/HostBridge.cpp index 0535195cc9..1803637293 100644 --- a/Kernel/Bus/PCI/Controller/HostBridge.cpp +++ b/Kernel/Bus/PCI/Controller/HostBridge.cpp @@ -109,19 +109,22 @@ UNMAP_AFTER_INIT void HostBridge::enumerate_attached_devices(Function<void(Devic m_enumerated_buses.set(m_domain.start_bus(), true); enumerate_bus(callback, m_domain.start_bus(), true); - // Handle Multiple PCI host bridges on slot 0, device 0. + // Handle Multiple PCI host bridges on bus 0, device 0, functions 1-7 (function 0 + // is the main host bridge). // If we happen to miss some PCI buses because they are not reachable through // recursive PCI-to-PCI bridges starting from bus 0, we might find them here. if ((read8_field(0, 0, 0, PCI::RegisterOffset::HEADER_TYPE) & 0x80) != 0) { - for (int bus_as_function_number = 1; bus_as_function_number < 256; ++bus_as_function_number) { + for (int bus_as_function_number = 1; bus_as_function_number < 8; ++bus_as_function_number) { if (read16_field(0, 0, bus_as_function_number, PCI::RegisterOffset::VENDOR_ID) == PCI::none_value) continue; if (read16_field(0, 0, bus_as_function_number, PCI::RegisterOffset::CLASS) != 0x6) continue; - if (m_enumerated_buses.get(bus_as_function_number)) + if (Checked<u8>::addition_would_overflow(m_domain.start_bus(), bus_as_function_number)) + break; + if (m_enumerated_buses.get(m_domain.start_bus() + bus_as_function_number)) continue; - enumerate_bus(callback, bus_as_function_number, false); - m_enumerated_buses.set(bus_as_function_number, true); + enumerate_bus(callback, m_domain.start_bus() + bus_as_function_number, false); + m_enumerated_buses.set(m_domain.start_bus() + bus_as_function_number, true); } } } |