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(); }