From 26a39bed4ac4ec371cb65e867ec8e8eea27edff2 Mon Sep 17 00:00:00 2001 From: milek7 Date: Wed, 6 Apr 2022 20:47:38 +0200 Subject: [PATCH] PCI: Allow initialization to be deferred. This is for platforms where information from parsed ACPI namespace is necessary to fully configure PCI subsystem. Change-Id: I8bdcfab6b99cbe7fdbc902b9fc13b44133325961 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5273 Tested-by: Commit checker robot Reviewed-by: Adrien Destugues --- src/add-ons/kernel/bus_managers/pci/pci.cpp | 39 ++++++++++++++++--- src/add-ons/kernel/bus_managers/pci/pci.h | 1 + .../kernel/bus_managers/pci/pci_root.cpp | 2 +- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/pci/pci.cpp b/src/add-ons/kernel/bus_managers/pci/pci.cpp index 4789674c2b..6ab89b3bbf 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci.cpp @@ -473,14 +473,20 @@ pcirefresh(int argc, char **argv) // #pragma mark bus manager init/uninit +static bool sInitDone; + status_t -pci_init(void) +pci_init_deferred(void) { - gPCI = new PCI; + if (sInitDone) + return B_OK; - // pci_controller_init may setup things needed by pci_io_init like mmio addresses - if (pci_controller_init() != B_OK) { + status_t ret = pci_controller_init(); + if (ret == B_DEV_NOT_READY) + return ret; + + if (ret != B_OK) { TRACE(("PCI: pci_controller_init failed\n")); return B_ERROR; } @@ -510,13 +516,36 @@ pci_init(void) add_debugger_command("pcistatus", &pcistatus, "dump and clear pci device status registers"); add_debugger_command("pcirefresh", &pcirefresh, "refresh and print all pci_info"); + sInitDone = true; return B_OK; } +status_t +pci_init(void) +{ + gPCI = new PCI; + + status_t ret = pci_init_deferred(); + if (ret == B_DEV_NOT_READY) { + TRACE(("PCI: init deferred\n")); + return B_OK; + } + + return ret; +} + + void pci_uninit(void) { + delete gPCI; + + if (!sInitDone) + return; + + sInitDone = false; + remove_debugger_command("outw", &write_io); remove_debugger_command("out32", &write_io); remove_debugger_command("outs", &write_io); @@ -533,8 +562,6 @@ pci_uninit(void) remove_debugger_command("pcistatus", &pcistatus); remove_debugger_command("pcirefresh", &pcirefresh); - - delete gPCI; } diff --git a/src/add-ons/kernel/bus_managers/pci/pci.h b/src/add-ons/kernel/bus_managers/pci/pci.h index f099fc1ec3..b3a057b234 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci.h +++ b/src/add-ons/kernel/bus_managers/pci/pci.h @@ -196,6 +196,7 @@ extern "C" { #endif status_t pci_init(void); +status_t pci_init_deferred(void); void pci_uninit(void); long pci_get_nth_pci_info(long index, pci_info *outInfo); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_root.cpp b/src/add-ons/kernel/bus_managers/pci/pci_root.cpp index b1c9213d77..96bd855d20 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_root.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_root.cpp @@ -130,7 +130,7 @@ pci_root_init(device_node* node, void** _cookie) if (res < B_OK) return res; - return B_OK; + return pci_init_deferred(); }