diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index f49ec73cb9..1c22d082e2 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -15,55 +15,30 @@ typedef struct acpi_object_type acpi_object_type; #define B_ACPI_MODULE_NAME "bus_managers/acpi/v1" -struct acpi_module_info { - module_info info; - - /* Fixed Event Management */ - - void (*enable_fixed_event)(uint32 event); - void (*disable_fixed_event)(uint32 event); - - uint32 (*fixed_event_status) (uint32 event); - /* Returns 1 if event set, 0 otherwise */ - void (*reset_fixed_event) (uint32 event); - - status_t (*install_fixed_event_handler)(uint32 event, - interrupt_handler *handler, void *data); - status_t (*remove_fixed_event_handler)(uint32 event, - interrupt_handler *handler); - - /* Namespace Access */ - - status_t (*get_next_entry)(uint32 objectType, const char *base, - char *result, size_t length, void **_counter); - status_t (*get_device)(const char *hid, uint32 index, char *result, - size_t resultLength); - - status_t (*get_device_hid)(const char *path, char *hid, size_t hidLength); - uint32 (*get_object_type)(const char *path); - status_t (*get_object)(const char *path, - acpi_object_type **_returnValue); - status_t (*get_object_typed)(const char *path, - acpi_object_type **_returnValue, uint32 objectType); - - /* Control method execution and data acquisition */ - - status_t (*evaluate_object)(const char *object, - acpi_object_type *returnValue, size_t bufferLength); - status_t (*evaluate_method)(const char *object, const char *method, - acpi_object_type *returnValue, size_t bufferLength, - acpi_object_type *args, int numArgs); - - /* Power state setting */ - - status_t (*prepare_sleep_state)(uint8 state, void (*wakeFunc)(void), - size_t size); - status_t (*enter_sleep_state)(uint8 state); -}; +/* This must be uint64 for 64 bit! */ +typedef uint32 acpi_physical_address; +typedef uint32 acpi_io_address; +typedef uint32 acpi_size; +/* Actually a ptr to a NS Node */ +typedef void * acpi_handle; #ifndef __ACTYPES_H__ +/* Address Space (Operation Region) Types */ + +enum { + ACPI_ADR_SPACE_SYSTEM_MEMORY = 0, + ACPI_ADR_SPACE_SYSTEM_IO = 1, + ACPI_ADR_SPACE_PCI_CONFIG = 2, + ACPI_ADR_SPACE_EC = 3, + ACPI_ADR_SPACE_SMBUS = 4, + ACPI_ADR_SPACE_CMOS = 5, + ACPI_ADR_SPACE_PCI_BAR_TARGET = 6, + ACPI_ADR_SPACE_DATA_TABLE = 7, + ACPI_ADR_SPACE_FIXED_HARDWARE = 127 +}; + /* ACPI fixed event types */ enum { @@ -91,7 +66,8 @@ enum { ACPI_TYPE_POWER, ACPI_TYPE_PROCESSOR, ACPI_TYPE_THERMAL, - ACPI_TYPE_BUFFER_FIELD + ACPI_TYPE_BUFFER_FIELD, + ACPI_TYPE_LOCAL_REFERENCE = 0x14 }; /* ACPI control method arg type */ @@ -112,6 +88,12 @@ struct acpi_object_type { uint32 count; acpi_object_type *objects; } package; + struct + { + uint32 type; + uint32 actual_type; + acpi_handle handle; + } reference; struct { uint32 cpu_id; int pblk_address; @@ -124,8 +106,127 @@ struct acpi_object_type { } data; }; + +/* + * List of objects, used as a parameter list for control method evaluation + */ +typedef struct acpi_objects { + uint32 count; + acpi_object_type *pointer; +} acpi_objects; + + +typedef struct acpi_data { + acpi_size length; /* Length in bytes of the buffer */ + void *pointer; /* pointer to buffer */ +} acpi_data; + + +enum { + ACPI_ALLOCATE_BUFFER = -1, +}; + + #endif // __ACTYPES_H__ + +typedef uint32 (*acpi_event_handler)(void *Context); + +typedef status_t (*acpi_adr_space_handler)(uint32 function, + acpi_physical_address address, uint32 bitWidth, int *value, + void *handlerContext, void *regionContext); + +typedef status_t (*acpi_adr_space_setup)(acpi_handle regionHandle, + uint32 function, void *handlerContext, void **regionContext); + +typedef void (*acpi_notify_handler)(acpi_handle device, uint32 value, + void *context); + + +struct acpi_module_info { + module_info info; + + status_t (*get_handle)(acpi_handle parent, char *pathname, + acpi_handle *retHandle); + + /* Global Lock */ + + status_t (*acquire_global_lock)(uint16 timeout, uint32 *handle); + status_t (*release_global_lock)(uint32 handle); + + /* Notify Handler */ + + status_t (*install_notify_handler)(acpi_handle device, + uint32 handlerType, acpi_notify_handler handler, + void *context); + status_t (*remove_notify_handler)(acpi_handle device, + uint32 handlerType, acpi_notify_handler handler); + + /* GPE Handler */ + + status_t (*enable_gpe)(acpi_handle handle, uint32 gpeNumber, + uint32 flags); + status_t (*set_gpe_type)(acpi_handle handle, uint32 gpeNumber, + uint8 type); + status_t (*install_gpe_handler)(acpi_handle handle, uint32 gpeNumber, + uint32 type, acpi_event_handler handler, void *data); + status_t (*remove_gpe_handler)(acpi_handle handle, uint32 gpeNumber, + acpi_event_handler address); + + /* Address Space Handler */ + + status_t (*install_address_space_handler)(acpi_handle handle, + uint32 spaceId, + acpi_adr_space_handler handler, + acpi_adr_space_setup setup, void *data); + status_t (*remove_address_space_handler)(acpi_handle handle, + uint32 spaceId, + acpi_adr_space_handler handler); + + /* Fixed Event Management */ + + void (*enable_fixed_event)(uint32 event); + void (*disable_fixed_event)(uint32 event); + + uint32 (*fixed_event_status) (uint32 event); + /* Returns 1 if event set, 0 otherwise */ + void (*reset_fixed_event) (uint32 event); + + status_t (*install_fixed_event_handler)(uint32 event, + interrupt_handler *handler, void *data); + status_t (*remove_fixed_event_handler)(uint32 event, + interrupt_handler *handler); + + /* Namespace Access */ + + status_t (*get_next_entry)(uint32 objectType, const char *base, + char *result, size_t length, void **_counter); + status_t (*get_device)(const char *hid, uint32 index, char *result, + size_t resultLength); + + status_t (*get_device_hid)(const char *path, char *hid, + size_t hidLength); + uint32 (*get_object_type)(const char *path); + status_t (*get_object)(const char *path, + acpi_object_type **_returnValue); + status_t (*get_object_typed)(const char *path, + acpi_object_type **_returnValue, uint32 objectType); + + /* Control method execution and data acquisition */ + + status_t (*evaluate_object)(const char* object, + acpi_object_type *returnValue, size_t bufferLength); + status_t (*evaluate_method)(acpi_handle handle, const char *method, + acpi_objects *args, acpi_data *returnValue); + + /* Power state setting */ + + status_t (*prepare_sleep_state)(uint8 state, void (*wakeFunc)(void), + size_t size); + status_t (*enter_sleep_state)(uint8 state); +}; + + /* Sleep states */ enum { @@ -143,12 +244,29 @@ enum { #define ACPI_DEVICE_TYPE_ITEM "acpi/type" -typedef struct acpi_device_info *acpi_device; +typedef struct acpi_device_cookie *acpi_device; // Interface to one ACPI device. typedef struct acpi_device_module_info { driver_module_info info; + /* Notify Handler */ + + status_t (*install_notify_handler)(acpi_device device, + uint32 handlerType, acpi_notify_handler handler, + void *context); + status_t (*remove_notify_handler)(acpi_device device, + uint32 handlerType, acpi_notify_handler handler); + + /* Address Space Handler */ + status_t (*install_address_space_handler)(acpi_device device, + uint32 spaceId, + acpi_adr_space_handler handler, + acpi_adr_space_setup setup, void *data); + status_t (*remove_address_space_handler)(acpi_device device, + uint32 spaceId, + acpi_adr_space_handler handler); + /* Namespace Access */ uint32 (*get_object_type)(acpi_device device); status_t (*get_object)(acpi_device device, const char *path, @@ -156,8 +274,7 @@ typedef struct acpi_device_module_info { /* Control method execution and data acquisition */ status_t (*evaluate_method)(acpi_device device, const char *method, - acpi_object_type *returnValue, size_t bufferLength, - acpi_object_type *args, int numArgs); + acpi_objects *args, acpi_data *returnValue); } acpi_device_module_info; 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 21c2a40efc..87042680dd 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -1,4 +1,5 @@ /* + * Copyright 2009, Clemens Zeidler, haiku@clemens-zeidler.de * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. * Copyright 2006, Bryan Varner. All rights reserved. * Copyright 2005, Nathan Whitehorn. All rights reserved. @@ -171,6 +172,98 @@ acpi_std_ops(int32 op,...) } +status_t +get_handle(acpi_handle parent, char *pathname, acpi_handle *retHandle) +{ + return AcpiGetHandle(parent, pathname, retHandle) == AE_OK + ? B_OK : B_ERROR; +} + + +status_t +acquire_global_lock(uint16 timeout, uint32 *handle) +{ + return AcpiAcquireGlobalLock(timeout, (UINT32*)handle) == AE_OK + ? B_OK : B_ERROR; +} + + +status_t +release_global_lock(uint32 handle) +{ + return AcpiReleaseGlobalLock(handle) == AE_OK ? B_OK : B_ERROR; +} + + +status_t +install_notify_handler(acpi_handle device, uint32 handlerType, + acpi_notify_handler handler, void *context) +{ + return AcpiInstallNotifyHandler(device, handlerType, + (ACPI_NOTIFY_HANDLER)handler, context) == AE_OK ? B_OK : B_ERROR; +} + + +status_t +remove_notify_handler(acpi_handle device, uint32 handlerType, + acpi_notify_handler handler) +{ + return AcpiRemoveNotifyHandler(device, handlerType, + (ACPI_NOTIFY_HANDLER)handler) == AE_OK ? B_OK : B_ERROR; +} + + +status_t +enable_gpe(acpi_handle handle, uint32 gpeNumber, uint32 flags) +{ + return AcpiEnableGpe(handle, gpeNumber, flags) == AE_OK ? B_OK : B_ERROR; +} + + +status_t +set_gpe_type(acpi_handle handle, uint32 gpeNumber, uint8 type) +{ + return AcpiSetGpeType(handle, gpeNumber, type) == AE_OK ? B_OK : B_ERROR; +} + + +status_t +install_gpe_handler(acpi_handle handle, uint32 gpeNumber, uint32 type, + acpi_event_handler handler, void *data) +{ + return AcpiInstallGpeHandler(handle, gpeNumber, type, + (ACPI_EVENT_HANDLER)handler, data) == AE_OK ? B_OK : B_ERROR; +} + + +status_t +remove_gpe_handler(acpi_handle handle, uint32 gpeNumber, + acpi_event_handler address) +{ + return AcpiRemoveGpeHandler(handle, gpeNumber, (ACPI_EVENT_HANDLER)address) + == AE_OK ? B_OK : B_ERROR; +} + + +status_t +install_address_space_handler(acpi_handle handle, uint32 spaceId, + acpi_adr_space_handler handler, acpi_adr_space_setup setup, void *data) +{ + return AcpiInstallAddressSpaceHandler(handle, spaceId, + (ACPI_ADR_SPACE_HANDLER)handler, (ACPI_ADR_SPACE_SETUP)setup, data) + == AE_OK ? B_OK : B_ERROR; +} + + +status_t +remove_address_space_handler(acpi_handle handle, uint32 spaceId, + acpi_adr_space_handler handler) +{ + return AcpiRemoveAddressSpaceHandler(handle, spaceId, + (ACPI_ADR_SPACE_HANDLER)handler) == AE_OK ? B_OK : B_ERROR; +} + + void enable_fixed_event(uint32 event) { @@ -391,29 +484,16 @@ evaluate_object(const char* object, acpi_object_type* returnValue, status_t -evaluate_method(const char* object, const char* method, - acpi_object_type *returnValue, size_t bufferLength, acpi_object_type *args, - int numArgs) +evaluate_method(acpi_handle handle, const char* method, + acpi_objects *args, acpi_data *returnValue) { - ACPI_BUFFER buffer; ACPI_STATUS status; - ACPI_OBJECT_LIST acpiArgs; - ACPI_HANDLE handle; - - if (AcpiGetHandle(NULL, (ACPI_STRING)object, &handle) != AE_OK) - return B_ENTRY_NOT_FOUND; - - buffer.Pointer = returnValue; - buffer.Length = bufferLength; - - acpiArgs.Count = numArgs; - acpiArgs.Pointer = (ACPI_OBJECT *)args; - + status = AcpiEvaluateObject(handle, (ACPI_STRING)method, - args != NULL ? &acpiArgs : NULL, returnValue != NULL ? &buffer : NULL); + (ACPI_OBJECT_LIST*)args, (ACPI_BUFFER*)returnValue); if (status == AE_BUFFER_OVERFLOW) dprintf("evaluate_method: the passed buffer is too small!\n"); - + return status == AE_OK ? B_OK : B_ERROR; } @@ -475,6 +555,17 @@ struct acpi_module_info gACPIModule = { acpi_std_ops }, + get_handle, + acquire_global_lock, + release_global_lock, + install_notify_handler, + remove_notify_handler, + enable_gpe, + set_gpe_type, + install_gpe_handler, + remove_gpe_handler, + install_address_space_handler, + remove_address_space_handler, enable_fixed_event, disable_fixed_event, fixed_event_status, diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_device.c b/src/add-ons/kernel/bus_managers/acpi/acpi_device.c index 6f5e0453d5..3848478230 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_device.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_device.c @@ -1,4 +1,5 @@ /* + * Copyright 2009, Clemens Zeidler. All rights reserved. * Copyright 2006, Jérôme Duval. All rights reserved. * * Distributed under the terms of the MIT License. @@ -9,15 +10,40 @@ #include #include "acpi_priv.h" +#include "acpi.h" -// information about one ACPI device -typedef struct acpi_device_info { - char *path; // path - uint32 type; // type - device_node *node; - char name[32]; // name (for fast log) -} acpi_device_info; +static status_t +acpi_install_notify_handler(acpi_device device, uint32 handlerType, + acpi_notify_handler handler, void *context) +{ + return install_notify_handler(device->handle, handlerType, handler, + context); +} + +static status_t +acpi_remove_notify_handler(acpi_device device, uint32 handlerType, + acpi_notify_handler handler) +{ + return remove_notify_handler(device->handle, handlerType, handler); +} + + +static status_t +acpi_install_address_space_handler(acpi_device device, uint32 spaceId, + acpi_adr_space_handler handler, acpi_adr_space_setup setup, void *data) +{ + return install_address_space_handler(device->handle, spaceId, handler, + setup, data); +} + +static status_t +acpi_remove_address_space_handler(acpi_device device, uint32 spaceId, + acpi_adr_space_handler handler) +{ + return remove_address_space_handler(device->handle, spaceId, handler); +} + static uint32 acpi_get_object_type(acpi_device device) @@ -39,18 +65,19 @@ acpi_get_object(acpi_device device, const char *path, acpi_object_type **return_ static status_t -acpi_evaluate_method(acpi_device device, const char *method, acpi_object_type *return_value, - size_t buf_len, acpi_object_type *args, int num_args) +acpi_evaluate_method(acpi_device device, const char *method, + acpi_objects *args, acpi_data *returnValue) { - return evaluate_method(device->path, method, return_value, buf_len, args, num_args); + return evaluate_method(device->handle, method, args, returnValue); } static status_t acpi_device_init_driver(device_node *node, void **cookie) { + ACPI_HANDLE handle; const char *path; - acpi_device_info *device; + acpi_device_cookie *device; status_t status = B_OK; uint32 type; @@ -62,9 +89,13 @@ acpi_device_init_driver(device_node *node, void **cookie) device = malloc(sizeof(*device)); if (device == NULL) return B_NO_MEMORY; - + memset(device, 0, sizeof(*device)); + if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) + return B_ENTRY_NOT_FOUND; + + device->handle = handle; device->path = strdup(path); device->type = type; device->node = node; @@ -81,7 +112,7 @@ acpi_device_init_driver(device_node *node, void **cookie) static void acpi_device_uninit_driver(void *cookie) { - acpi_device_info *device = cookie; + acpi_device_cookie *device = cookie; free(device->path); free(device); @@ -100,6 +131,7 @@ acpi_device_std_ops(int32 op, ...) return B_BAD_VALUE; } + acpi_device_module_info gACPIDeviceModule = { { { @@ -116,6 +148,10 @@ acpi_device_module_info gACPIDeviceModule = { NULL, // rescan devices NULL, // device removed }, + acpi_install_notify_handler, + acpi_remove_notify_handler, + acpi_install_address_space_handler, + acpi_remove_address_space_handler, acpi_get_object_type, acpi_get_object, acpi_evaluate_method, 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 158d93057e..5305705d9a 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c @@ -1,4 +1,5 @@ /* + * Copyright 2009, Clemens Zeidler. All rights reserved. * Copyright 2006, Jérôme Duval. All rights reserved. * * Distributed under the terms of the MIT License. @@ -22,7 +23,6 @@ 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}, @@ -217,6 +217,17 @@ static struct acpi_root_info sACPIRootModule = { NULL, // device removed }, + get_handle, + acquire_global_lock, + release_global_lock, + install_notify_handler, + remove_notify_handler, + enable_gpe, + set_gpe_type, + install_gpe_handler, + remove_gpe_handler, + install_address_space_handler, + remove_address_space_handler, enable_fixed_event, disable_fixed_event, fixed_event_status, diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h index 228289520e..f9642f523a 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h @@ -1,10 +1,14 @@ /* + * Copyright 2009, Clemens Zeidler. All rights reserved. * Copyright 2006, Jérôme Duval. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef __ACPI_PRIV_H__ #define __ACPI_PRIV_H__ +#include +__BEGIN_DECLS + #include #include #include @@ -21,11 +25,56 @@ extern device_manager_info *gDeviceManager; +// information about one ACPI device +typedef struct acpi_device_cookie { + char *path; // path + acpi_handle handle; + uint32 type; // type + device_node *node; + char name[32]; // name (for fast log) +} acpi_device_cookie; + // ACPI root. typedef struct acpi_root_info { driver_module_info info; + + status_t (*get_handle)(acpi_handle parent, char *pathname, + acpi_handle *retHandle); + + /* Global Lock */ + status_t (*acquire_global_lock)(uint16 timeout, uint32 *handle); + status_t (*release_global_lock)(uint32 handle); + /* Notify Handler */ + + status_t (*install_notify_handler)(acpi_handle device, + uint32 handlerType, acpi_notify_handler handler, + void *context); + status_t (*remove_notify_handler)(acpi_handle device, + uint32 handlerType, acpi_notify_handler handler); + + /* GPE Handler */ + + status_t (*enable_gpe)(acpi_handle handle, uint32 gpeNumber, + uint32 flags); + status_t (*set_gpe_type)(acpi_handle handle, uint32 gpeNumber, + uint8 type); + status_t (*install_gpe_handler)(acpi_handle handle, uint32 gpeNumber, + uint32 type, acpi_event_handler handler, void *data); + status_t (*remove_gpe_handler)(acpi_handle handle, uint32 gpeNumber, + acpi_event_handler address); + + /* Address Space Handler */ + + status_t (*install_address_space_handler)(acpi_handle handle, + uint32 spaceId, + acpi_adr_space_handler handler, + acpi_adr_space_setup setup, void *data); + status_t (*remove_address_space_handler)(acpi_handle handle, + uint32 spaceId, + acpi_adr_space_handler handler); + /* Fixed Event Management */ void (*enable_fixed_event) (uint32 event); @@ -56,11 +105,10 @@ typedef struct acpi_root_info { /* Control method execution and data acquisition */ - status_t (*evaluate_object)(const char *object, + status_t (*evaluate_object)(const char* object, acpi_object_type *returnValue, size_t bufferLength); - status_t (*evaluate_method)(const char *object, const char *method, - acpi_object_type *returnValue, size_t bufferLength, - acpi_object_type *args, int numArgs); + status_t (*evaluate_method)(acpi_handle handle, const char *method, + acpi_objects *args, acpi_data *returnValue); } acpi_root_info; @@ -71,6 +119,28 @@ extern struct device_module_info acpi_ns_dump_module; extern acpi_device_module_info gACPIDeviceModule; +status_t get_handle(acpi_handle parent, char *pathname, acpi_handle *retHandle); + +status_t acquire_global_lock(uint16 timeout, uint32 *handle); +status_t release_global_lock(uint32 handle); + +status_t install_notify_handler(acpi_handle device, uint32 handlerType, + acpi_notify_handler handler, void *context); +status_t remove_notify_handler(acpi_handle device, uint32 handlerType, + acpi_notify_handler handler); + +status_t enable_gpe(acpi_handle handle, uint32 gpeNumber, uint32 flags); +status_t set_gpe_type(acpi_handle handle, uint32 gpeNumber, uint8 type); +status_t install_gpe_handler(acpi_handle handle, uint32 gpeNumber, uint32 type, + acpi_event_handler handler, void *data); +status_t remove_gpe_handler(acpi_handle handle, uint32 gpeNumber, + acpi_event_handler address); + +status_t install_address_space_handler(acpi_handle handle, uint32 spaceId, + acpi_adr_space_handler handler, acpi_adr_space_setup setup, void *data); +status_t remove_address_space_handler(acpi_handle handle, uint32 spaceId, + acpi_adr_space_handler handler); + void enable_fixed_event(uint32 event); void disable_fixed_event(uint32 event); @@ -92,10 +162,11 @@ status_t get_object(const char *path, acpi_object_type **return_value); status_t get_object_typed(const char *path, acpi_object_type **return_value, uint32 object_type); -status_t evaluate_object(const char *object, acpi_object_type *returnValue, +status_t evaluate_object(const char* object, acpi_object_type *returnValue, size_t bufferLength); -status_t evaluate_method(const char *object, const char *method, - acpi_object_type *returnValue, size_t bufferLength, acpi_object_type *args, - int numArgs); +status_t evaluate_method(acpi_handle handle, const char *method, + acpi_objects *args, acpi_data *returnValue); + +__END_DECLS #endif /* __ACPI_PRIV_H__ */ diff --git a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c index 79d5cf526b..8d58edf241 100644 --- a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c +++ b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c @@ -125,14 +125,14 @@ #include #include #include - + #ifdef _KERNEL_MODE #include #include #include extern pci_module_info *gPCIManager; #include -extern dpc_module_info *gDPC; +dpc_module_info *gDPC = NULL; extern void *gDPCHandle; #endif