diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c index 645247d60f..ff33e943a3 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -105,12 +105,6 @@ acpi_std_ops(int32 op,...) return ENOSYS; } - - if (gDPC->new_dpc_queue(&gDPCHandle, "acpi_task", B_NORMAL_PRIORITY) != B_OK) { - ERROR("AcpiInitializeSubsystem failed (new_dpc_queue() failed!)\n"); - goto err; - } - #ifdef ACPI_DEBUG_OUTPUT AcpiDbgLevel = ACPI_DEBUG_ALL | ACPI_LV_VERBOSE; AcpiDbgLayer = ACPI_ALL_COMPONENTS; @@ -158,9 +152,13 @@ acpi_std_ops(int32 op,...) ERROR("Could not bring system out of ACPI mode. Oh well.\n"); /* This isn't so terrible. We'll just fail silently */ - if (gDPCHandle != NULL) { - gDPC->delete_dpc_queue(gDPCHandle); - gDPCHandle = NULL; + if (gDPC != NULL) { + if (gDPCHandle != NULL) { + gDPC->delete_dpc_queue(gDPCHandle); + gDPCHandle = NULL; + } + + put_module(B_DPC_MODULE_NAME); } break; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c index 3f88b26bb7..ff363cd3c7 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c @@ -20,14 +20,13 @@ # define TRACE(x) ; #endif -device_manager_info *gDeviceManager; -pci_module_info *gPCIManager; -dpc_module_info *gDPC; +device_manager_info *gDeviceManager = NULL; +pci_module_info *gPCIManager = NULL; +dpc_module_info *gDPC = NULL; module_dependency module_dependencies[] = { {B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager}, {B_PCI_MODULE_NAME, (module_info **)&gPCIManager}, - {B_DPC_MODULE_NAME, (module_info **)&gDPC}, {} }; diff --git a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c index 004ed1aa48..305617a473 100644 --- a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c +++ b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c @@ -751,8 +751,14 @@ AcpiOsInstallInterruptHandler(UINT32 InterruptNumber, DEBUG_FUNCTION_F("vector: %lu; handler: %p; data: %p", (uint32)InterruptNumber, ServiceRoutine, Context); #ifdef _KERNEL_MODE - /* It so happens that the Haiku and ACPI-CA interrupt handler routines - return the same values with the same meanings */ + if (Context != NULL) { + // we don't get the context parameter when + panic("ACPI: cannot add interrupt handler with non-null context"); + return AE_ERROR; + } + + /* It so happens that the Haiku and ACPI-CA interrupt handler routines + return the same values with the same meanings */ return install_io_interrupt_handler(InterruptNumber, (interrupt_handler)ServiceRoutine, Context, 0) == B_OK ? AE_OK : AE_ERROR; @@ -781,11 +787,8 @@ AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber, DEBUG_FUNCTION_F("vector: %lu; handler: %p", (uint32)InterruptNumber, ServiceRoutine); #ifdef _KERNEL_MODE - panic("AcpiOsRemoveInterruptHandler()\n"); - /*remove_io_interrupt_handler(InterruptNumber, - (interrupt_handler)ServiceRoutine, NULL);*/ - /* Crap. We don't get the Context argument back. */ - #warning Sketchy code! + remove_io_interrupt_handler(InterruptNumber, + (interrupt_handler)ServiceRoutine, NULL); return AE_OK; #else return AE_ERROR; @@ -822,6 +825,20 @@ AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, break; } + if (gDPC == NULL && get_module(B_DPC_MODULE_NAME, + (module_info **)&gDPC) != B_OK) { + dprintf("failed to get dpc module for os execution\n"); + return AE_ERROR; + } + + if (gDPCHandle == NULL) { + if (gDPC->new_dpc_queue(&gDPCHandle, "acpi_task", + B_NORMAL_PRIORITY) != B_OK) { + dprintf("failed to create os execution queue\n"); + return AE_ERROR; + } + } + if (gDPC->queue_dpc(gDPCHandle, Function, Context) != B_OK) return AE_ERROR; @@ -1199,7 +1216,10 @@ AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT32 Value, UINT32 Width) UINT32 AcpiOsGetThreadId(void) { - return find_thread(NULL); + // ACPI treats a 0 return as an error, + // but we are thread 0 in early boot + thread_id thread = find_thread(NULL); + return thread == 0 ? 1 : thread; }