From 92aa85ae8deffefaf13f5b492f752e4d66e30ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 21 Nov 2006 23:36:02 +0000 Subject: [PATCH] reverted PCI change, now uses a dependency on the PCI bus manager moved acpi_ns_dump driver into acpi bus manager (also removed from the hd image) the exported fs path is now acpi/namespace added some methods to ACPI bus and device new interfaces ACPI nodes like _TZ_ or _SB_ aren't exposed as devices anymore added a type to the acpi_device_info structure git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19356 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- build/jam/HaikuImage | 2 +- src/add-ons/kernel/bus_managers/acpi/Jamfile | 2 +- .../kernel/bus_managers/acpi/acpi_busman.c | 2 +- .../kernel/bus_managers/acpi/acpi_device.c | 37 ++- .../kernel/bus_managers/acpi/acpi_module.c | 42 ++- .../kernel/bus_managers/acpi/acpi_ns_dump.c | 290 ++++++++++++++++++ .../kernel/bus_managers/acpi/acpi_priv.h | 41 ++- .../kernel/bus_managers/acpi/oshaiku.c | 58 ++-- 8 files changed, 424 insertions(+), 50 deletions(-) create mode 100644 src/add-ons/kernel/bus_managers/acpi/acpi_ns_dump.c diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 3b5ea4a717..dc3a230650 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -98,7 +98,7 @@ BEOS_ADD_ONS_DRIVERS_NET = etherpci ipro1000 rtl8139 rtl8169 sis900 via-rhine wb840 net_stack $(GPL_ONLY)bcm440x $(GPL_ONLY)bcm570x ; -BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button $(X86_ONLY)acpi_ns_dump ; +BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button ; BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi config_manager $(X86_ONLY)acpi $(X86_ONLY)agp usb ; diff --git a/src/add-ons/kernel/bus_managers/acpi/Jamfile b/src/add-ons/kernel/bus_managers/acpi/Jamfile index 69fead9a1c..9e9293c5ab 100644 --- a/src/add-ons/kernel/bus_managers/acpi/Jamfile +++ b/src/add-ons/kernel/bus_managers/acpi/Jamfile @@ -178,7 +178,7 @@ KernelAddon acpi : acpi_busman.c acpi_module.c acpi_device.c + acpi_ns_dump.c : libacpi_ca.a - pci_arch_bus_manager.a ; 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 e567600aea..9f33998d30 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -91,7 +91,7 @@ acpi_std_ops(int32 op,...) break; case B_MODULE_UNINIT: - /*Status = AcpiTerminate();*/ + Status = AcpiTerminate(); if (Status != AE_OK) ERROR("Could not bring system out of ACPI mode. Oh well.\n"); 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 b93e18da7a..cd58800d68 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_device.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_device.c @@ -13,29 +13,59 @@ // information about one ACPI device typedef struct acpi_device_info { char *path; // path + uint32 type; // type device_node_handle node; char name[32]; // name (for fast log) } acpi_device_info; +static uint32 +acpi_get_object_type(acpi_device device) +{ + return device->type; +} + + +static status_t +acpi_get_object(acpi_device device, const char *path, acpi_object_type **return_value) +{ + char objname[255]; + sprintf(objname, "%s.%s", device->path, path); + return get_object(objname, return_value); +} + + +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) +{ + return evaluate_method(device->path, method, return_value, buf_len, args, num_args); +} + + static status_t acpi_device_init_driver(device_node_handle node, void *user_cookie, void **cookie) { char *path; acpi_device_info *device; status_t status = B_OK; + uint32 type; + if (gDeviceManager->get_attr_uint32(node, ACPI_DEVICE_TYPE_ITEM, &type, false) != B_OK) + return B_ERROR; if (gDeviceManager->get_attr_string(node, ACPI_DEVICE_PATH_ITEM, &path, false) != B_OK) return B_ERROR; - + device = malloc(sizeof(*device)); if (device == NULL) { + free(path); return B_NO_MEMORY; } memset(device, 0, sizeof(*device)); device->path = path; + device->type = type; device->node = node; snprintf(device->name, sizeof(device->name), "acpi_device %s", @@ -86,6 +116,7 @@ acpi_device_module_info gACPIDeviceModule = { NULL, // cleanup NULL, // get supported paths }, - - + 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 afb4e14655..47bc4e00dd 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c @@ -7,11 +7,14 @@ #include #include #include "acpi_priv.h" +#include device_manager_info *gDeviceManager; +pci_module_info *gPCIManager; module_dependency module_dependencies[] = { {B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager}, + {B_PCI_MODULE_NAME, (module_info **)&gPCIManager}, {} }; @@ -51,6 +54,9 @@ acpi_module_register_device(device_node_handle parent) //{ PNP_BUS_DEFER_PROBE, B_UINT8_TYPE, { ui8: 1 }}, // don't scan if loaded as we own I/O resources //{ PNP_DRIVER_NO_LIVE_RESCAN, B_UINT8_TYPE, { ui8: 1 }}, + + // tell ns dump driver to register a device in devfs + { B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: ACPI_NS_DUMP_MODULE_NAME }}, {} }; @@ -68,11 +74,17 @@ acpi_enumerate_child_devices(device_node_handle node, const char *root) void *counter = NULL; dprintf("acpi_enumerate_child_devices: recursing from %s\n", root); - + while (get_next_entry(ACPI_TYPE_ANY, root, result, 255, &counter) == B_OK) { uint32 type = get_object_type(result); device_node_handle deviceNode; - + + if (!strcmp("\\_PR_", result) || !strcmp("\\_TZ_", result) + || !strcmp("\\_SI_", result) || !strcmp("\\_SB_", result)) { + acpi_enumerate_child_devices(node, result); + continue; + } + switch (type) { case ACPI_TYPE_DEVICE: { char hid[9] = ""; @@ -93,6 +105,7 @@ acpi_enumerate_child_devices(device_node_handle node, const char *root) { B_DRIVER_BUS, B_STRING_TYPE, { string: "apci" }}, { NULL } }; + get_device_hid(result, hid); if (gDeviceManager->register_device(node, attrs, NULL, &deviceNode) == B_OK) @@ -160,6 +173,13 @@ acpi_module_init(device_node_handle node, void *user_cookie, void **_cookie) } +static status_t +acpi_module_uninit(void *cookie) +{ + return B_OK; +} + + static int32 apci_module_std_ops(int32 op, ...) { @@ -191,7 +211,7 @@ static struct acpi_root_info sACPIModule = { acpi_module_supports_device, acpi_module_register_device, acpi_module_init, - NULL, // uninit + acpi_module_uninit, NULL, // removed NULL, // cleanup acpi_module_get_paths, @@ -201,10 +221,26 @@ static struct acpi_root_info sACPIModule = { NULL, // rescan bus }, + enable_fixed_event, + disable_fixed_event, + fixed_event_status, + reset_fixed_event, + install_fixed_event_handler, + remove_fixed_event_handler, + get_next_entry, + get_device, + get_device_hid, + get_object_type, + get_object, + get_object_typed, + evaluate_object, + evaluate_method, + }; _EXPORT module_info *modules[] = { (module_info *) &acpi_module, (module_info *) &sACPIModule, + (module_info *) &acpi_ns_dump_module, NULL }; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_ns_dump.c b/src/add-ons/kernel/bus_managers/acpi/acpi_ns_dump.c new file mode 100644 index 0000000000..655f095290 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_ns_dump.c @@ -0,0 +1,290 @@ +/* ++++++++++ + ACPI namespace dump. + Nothing special here, just tree enumeration and type identification. ++++++ */ + +#include +#include +#include +#include +#include + +#include "acpi_priv.h" + + +typedef struct acpi_ns_device_info { + device_node_handle node; + acpi_root_info *acpi; + void *acpi_cookie; +} acpi_ns_device_info; + + +static void +dump_acpi_namespace(acpi_ns_device_info *device, char *root, void *buf, size_t* num_bytes, int indenting) { + char result[255]; + char output[255]; + char tabs[255]; + char hid[9]; + int i, depth; + uint32 type; + void *counter = NULL; + + hid[8] = '\0'; + tabs[0] = '\0'; + + for (i = 0; i < indenting; i++) { + sprintf(tabs, "%s| ", tabs); + } + sprintf(tabs, "%s|--- ", tabs); + depth = sizeof(char) * 5 * indenting + sizeof(char); // index into result where the device name will be. + + dprintf("acpi_ns_dump: recursing from %s\n", root); + while (device->acpi->get_next_entry(ACPI_TYPE_ANY, root, result, 255, &counter) == B_OK) { + type = device->acpi->get_object_type(result); + sprintf(output, "%s%s", tabs, result + depth); + switch(type) { + case ACPI_TYPE_ANY: + break; + case ACPI_TYPE_INTEGER: + sprintf(output, "%s INTEGER", output); + break; + case ACPI_TYPE_STRING: + sprintf(output, "%s STRING", output); + break; + case ACPI_TYPE_BUFFER: + sprintf(output, "%s BUFFER", output); + break; + case ACPI_TYPE_PACKAGE: + sprintf(output, "%s PACKAGE", output); + break; + case ACPI_TYPE_FIELD_UNIT: + sprintf(output, "%s FIELD UNIT", output); + break; + case ACPI_TYPE_DEVICE: + device->acpi->get_device_hid(result, hid); + sprintf(output, "%s DEVICE (%s)", output, hid); + break; + case ACPI_TYPE_EVENT: + sprintf(output, "%s EVENT", output); + break; + case ACPI_TYPE_METHOD: + sprintf(output, "%s METHOD", output); + break; + case ACPI_TYPE_MUTEX: + sprintf(output, "%s MUTEX", output); + break; + case ACPI_TYPE_REGION: + sprintf(output, "%s REGION", output); + break; + case ACPI_TYPE_POWER: + sprintf(output, "%s POWER", output); + break; + case ACPI_TYPE_PROCESSOR: + sprintf(output, "%s PROCESSOR", output); + break; + case ACPI_TYPE_THERMAL: + sprintf(output, "%s THERMAL", output); + break; + case ACPI_TYPE_BUFFER_FIELD: + sprintf(output, "%s BUFFER_FIELD", output); + break; + } + sprintf(output, "%s\n", output); + + sprintf((buf + *num_bytes), "%s", output); + *num_bytes += strlen(output); + + dump_acpi_namespace(device, result, buf, num_bytes, indenting + 1); + } +} + + +/* ---------- + acpi_namespace_open - handle open() calls +----- */ + +static status_t +acpi_namespace_open(acpi_ns_device_info *device, uint32 flags, void** cookie) +{ + dprintf("\nacpi_ns_dump: device_open\n"); + *cookie = device; + + return B_OK; +} + + +/* ---------- + acpi_namespace_read - handle read() calls +----- */ +static status_t +acpi_namespace_read (acpi_ns_device_info *device, off_t position, void *buf, size_t* num_bytes) +{ + size_t bytes = 0; + + if (position == 0) { // First read + dump_acpi_namespace(device, "\\", buf, &bytes, 0); + if (bytes <= *num_bytes) { + *num_bytes = bytes; + dprintf("acpi_ns_dump: read %lu bytes\n", *num_bytes); + } else { + *num_bytes = 0; + return B_IO_ERROR; + } + } else { + *num_bytes = 0; + } + + return B_OK; +} + + +/* ---------- + acpi_namespace_write - handle write() calls +----- */ + +static status_t +acpi_namespace_write (void* cookie, off_t position, const void* buffer, size_t* num_bytes) +{ + dprintf("acpi_ns_dump: device_write\n"); + *num_bytes = 0; /* tell caller nothing was written */ + return B_IO_ERROR; +} + + +/* ---------- + acpi_namespace_control - handle ioctl calls +----- */ + +static status_t +acpi_namespace_control (void* cookie, uint32 op, void* arg, size_t len) +{ + dprintf("acpi_ns_dump: device_control\n"); + return B_BAD_VALUE; +} + + +/* ---------- + acpi_namespace_close - handle close() calls +----- */ + +static status_t +acpi_namespace_close (void* cookie) +{ + dprintf("acpi_ns_dump: device_close\n"); + return B_OK; +} + + +/* ----- + acpi_namespace_free - called after the last device is closed, and after + all i/o is complete. +----- */ +static status_t +acpi_namespace_free (void* cookie) +{ + dprintf("acpi_ns_dump: device_free\n"); + + return B_OK; +} + + +static status_t +acpi_namespace_init_device(device_node_handle node, void *user_cookie, void **cookie) +{ + acpi_ns_device_info *device; + status_t res; + + device = (acpi_ns_device_info *)calloc(1, sizeof(*device)); + if (device == NULL) + return B_NO_MEMORY; + + device->node = node; + + // register it everywhere + res = gDeviceManager->init_driver(gDeviceManager->get_parent(node), NULL, + (driver_module_info **)&device->acpi, &device->acpi_cookie); + if (res != B_OK) + goto err; + + *cookie = device; + return B_OK; + +err: + free(device); + return res; +} + + +static status_t +acpi_namespace_uninit_device(acpi_ns_device_info *device) +{ + gDeviceManager->uninit_driver(gDeviceManager->get_parent(device->node)); + free(device); + + return B_OK; +} + + +static status_t +acpi_namespace_added(device_node_handle node) +{ + device_attr attrs[] = { + { B_DRIVER_MODULE, B_STRING_TYPE, { string: ACPI_NS_DUMP_MODULE_NAME }}, + + { PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "namespace" }}, + // we want devfs on top of us (who wouldn't?) + { B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: PNP_DEVFS_MODULE_NAME }}, + // tell which name we want to have in devfs + { PNP_DEVFS_FILENAME, B_STRING_TYPE, { string: "acpi/namespace" }}, + { NULL } + }; + + return gDeviceManager->register_device(node, attrs, NULL, &node); +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + + default: + return B_ERROR; + } +} + + +pnp_devfs_driver_info acpi_ns_dump_module = { + { + { + ACPI_NS_DUMP_MODULE_NAME, + 0, + std_ops + }, + + NULL, + acpi_namespace_added, + acpi_namespace_init_device, + (status_t (*) (void *))acpi_namespace_uninit_device, + NULL + }, + + (status_t (*)(void *, uint32, void **)) &acpi_namespace_open, + acpi_namespace_close, + acpi_namespace_free, + (status_t (*)(void *, uint32, void *, size_t)) &acpi_namespace_control, + + acpi_namespace_read, + acpi_namespace_write, + + NULL, + NULL, + + NULL, + NULL +}; + + 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 6f0c38e170..754369aa40 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h @@ -8,8 +8,8 @@ #define __ACPI_PRIV_H__ #include -#include #include +#include // name of ACPI root module #define ACPI_ROOT_MODULE_NAME "bus_managers/acpi/root/device_v1" @@ -17,6 +17,9 @@ // name of ACPI device modules #define ACPI_DEVICE_MODULE_NAME "bus_managers/acpi/device_v1" +// name of the ACPI namespace device +#define ACPI_NS_DUMP_MODULE_NAME "drivers/power/namespace/acpi/device/v1" + extern device_manager_info *gDeviceManager; @@ -24,17 +27,53 @@ extern device_manager_info *gDeviceManager; typedef struct acpi_device_module_info { driver_module_info info; + /* Namespace Access */ + uint32 (*get_object_type) (acpi_device device); + status_t (*get_object) (acpi_device device, const char *path, acpi_object_type **return_value); + + /* Control method execution and data acquisition */ + status_t (*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_device_module_info; // ACPI root. typedef struct acpi_root_info { bus_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 object_type, const char *base, char *result, size_t len, void **counter); + status_t (*get_device) (const char *hid, uint32 index, char *result); + + status_t (*get_device_hid) (const char *path, char *hid); + uint32 (*get_object_type) (const char *path); + 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); + + /* Control method execution and data acquisition */ + + status_t (*evaluate_object) (const char *object, acpi_object_type *return_value, size_t buf_len); + status_t (*evaluate_method) (const char *object, const char *method, acpi_object_type *return_value, size_t buf_len, acpi_object_type *args, int num_args); } acpi_root_info; + extern struct acpi_module_info acpi_module; +extern pnp_devfs_driver_info acpi_ns_dump_module; + void enable_fixed_event (uint32 event); void disable_fixed_event (uint32 event); diff --git a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c index 13983e2b4b..8217b8822f 100644 --- a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c +++ b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c @@ -128,31 +128,9 @@ #include #ifdef _KERNEL_MODE -# include "pci_controller.h" # include - -void *pci_ram_address(const void *physical_address_in_system_memory); - -status_t pci_io_init(void); -uint8 pci_read_io_8(int mapped_io_addr); -void pci_write_io_8(int mapped_io_addr, uint8 value); -uint16 pci_read_io_16(int mapped_io_addr); -void pci_write_io_16(int mapped_io_addr, uint16 value); -uint32 pci_read_io_32(int mapped_io_addr); -void pci_write_io_32(int mapped_io_addr, uint32 value); - -pci_controller *gController = NULL; -void *gControllerCookie; - -status_t -pci_controller_add(pci_controller *controller, void *cookie) -{ - gController = controller; - gControllerCookie = cookie; - return B_OK; -} - - +#include +extern pci_module_info *gPCIManager; #endif #include "acpi.h" @@ -188,11 +166,6 @@ AcpiOsInitialize (void) #else AcpiGbl_OutputFile = NULL; #endif - - if (pci_io_init() != B_OK) - return AE_ERROR; - if (pci_controller_init() != B_OK) - return AE_ERROR; return AE_OK; } @@ -1072,8 +1045,13 @@ AcpiOsReadPciConfiguration ( { #ifdef _KERNEL_MODE - gController->read_pci_config(gControllerCookie, - PciId->Bus, PciId->Device, PciId->Function, Register, Width/8, Value); + UINT32 val = gPCIManager->read_pci_config( + PciId->Bus, PciId->Device, PciId->Function, Register, Width/8); + switch (Width) { + case 1: *(UINT8*)Value = val; + case 2: *(UINT16*)Value = val; + case 4: *(UINT32*)Value = val; + } #endif return (AE_OK); @@ -1104,7 +1082,7 @@ AcpiOsWritePciConfiguration ( { #ifdef _KERNEL_MODE - gController->write_pci_config(gControllerCookie, + gPCIManager->write_pci_config( PciId->Bus, PciId->Device, PciId->Function, Register, Width/8, Value); #endif @@ -1148,15 +1126,15 @@ AcpiOsReadPort ( switch (Width) { case 8: - *Value = pci_read_io_8(Address); + *Value = gPCIManager->read_io_8(Address); break; case 16: - *Value = pci_read_io_16(Address); + *Value = gPCIManager->read_io_16(Address); break; case 32: - *Value = pci_read_io_32(Address); + *Value = gPCIManager->read_io_32(Address); break; } @@ -1191,15 +1169,15 @@ AcpiOsWritePort ( switch (Width) { case 8: - pci_write_io_8(Address,Value); + gPCIManager->write_io_8(Address,Value); break; case 16: - pci_write_io_16(Address,Value); + gPCIManager->write_io_16(Address,Value); break; case 32: - pci_write_io_32(Address,Value); + gPCIManager->write_io_32(Address,Value); break; } @@ -1232,7 +1210,7 @@ AcpiOsReadMemory ( #ifdef _KERNEL_MODE - memcpy(Value, pci_ram_address(ACPI_TO_POINTER(Address)), Width/8); + memcpy(Value, gPCIManager->ram_address(ACPI_TO_POINTER(Address)), Width/8); #endif @@ -1263,7 +1241,7 @@ AcpiOsWriteMemory ( #ifdef _KERNEL_MODE - memcpy(pci_ram_address(ACPI_TO_POINTER(Address)), &Value, Width/8); + memcpy(gPCIManager->ram_address(ACPI_TO_POINTER(Address)), &Value, Width/8); #endif