1 /* 2 * Copyright 2009, Clemens Zeidler. All rights reserved. 3 * Copyright 2006, Jérôme Duval. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include "ACPIPrivate.h" 13 14 #include <dpc.h> 15 #include <PCI.h> 16 17 18 //#define TRACE_ACPI_MODULE 19 #ifdef TRACE_ACPI_MODULE 20 # define TRACE(x) dprintf x 21 #else 22 # define TRACE(x) ; 23 #endif 24 25 26 device_manager_info* gDeviceManager = NULL; 27 pci_module_info* gPCIManager = NULL; 28 dpc_module_info* gDPC = NULL; 29 30 module_dependency module_dependencies[] = { 31 {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager}, 32 {B_PCI_MODULE_NAME, (module_info**)&gPCIManager}, 33 {B_DPC_MODULE_NAME, (module_info**)&gDPC}, 34 {} 35 }; 36 37 38 static float 39 acpi_module_supports_device(device_node* parent) 40 { 41 // make sure parent is really device root 42 const char* bus; 43 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) 44 return B_ERROR; 45 46 if (strcmp(bus, "root")) 47 return 0.0; 48 49 return 1.0; 50 } 51 52 53 static status_t 54 acpi_module_register_device(device_node* parent) 55 { 56 device_attr attrs[] = { 57 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI" }}, 58 59 { B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_KEEP_DRIVER_LOADED }}, 60 {} 61 }; 62 63 return gDeviceManager->register_node(parent, ACPI_ROOT_MODULE_NAME, attrs, 64 NULL, NULL); 65 } 66 67 68 static status_t 69 acpi_enumerate_child_devices(device_node* node, const char* root) 70 { 71 char result[255]; 72 void* counter = NULL; 73 74 TRACE(("acpi_enumerate_child_devices: recursing from %s\n", root)); 75 76 while (get_next_entry(ACPI_TYPE_ANY, root, result, 77 sizeof(result), &counter) == B_OK) { 78 uint32 type = get_object_type(result); 79 device_node* deviceNode; 80 81 switch (type) { 82 case ACPI_TYPE_POWER: 83 case ACPI_TYPE_PROCESSOR: 84 case ACPI_TYPE_THERMAL: 85 case ACPI_TYPE_DEVICE: { 86 char hid[16] = ""; 87 device_attr attrs[] = { 88 // info about device 89 { B_DEVICE_BUS, B_STRING_TYPE, { string: "acpi" }}, 90 91 // location on ACPI bus 92 { ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }}, 93 94 // info about the device 95 { ACPI_DEVICE_HID_ITEM, B_STRING_TYPE, { string: hid }}, 96 { ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }}, 97 98 // consumer specification 99 /*{ B_DRIVER_MAPPING, B_STRING_TYPE, { string: 100 "hid_%" ACPI_DEVICE_HID_ITEM "%" }}, 101 { B_DRIVER_MAPPING "/0", B_STRING_TYPE, { string: 102 "type_%" ACPI_DEVICE_TYPE_ITEM "%" }},*/ 103 { B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: /*B_FIND_CHILD_ON_DEMAND|*/B_FIND_MULTIPLE_CHILDREN }}, 104 { NULL } 105 }; 106 107 if (type == ACPI_TYPE_DEVICE) 108 get_device_hid(result, hid, sizeof(hid)); 109 110 if (gDeviceManager->register_node(node, ACPI_DEVICE_MODULE_NAME, attrs, 111 NULL, &deviceNode) == B_OK) 112 acpi_enumerate_child_devices(deviceNode, result); 113 break; 114 } 115 default: 116 acpi_enumerate_child_devices(node, result); 117 break; 118 } 119 120 } 121 122 return B_OK; 123 } 124 125 126 static status_t 127 acpi_module_register_child_devices(void* cookie) 128 { 129 device_node* node = (device_node*)cookie; 130 131 status_t status = gDeviceManager->publish_device(node, "acpi/namespace", 132 ACPI_NS_DUMP_DEVICE_MODULE_NAME); 133 if (status != B_OK) 134 return status; 135 136 return acpi_enumerate_child_devices(node, "\\"); 137 } 138 139 140 static status_t 141 acpi_module_init(device_node* node, void** _cookie) 142 { 143 *_cookie = node; 144 return B_OK; 145 } 146 147 148 static void 149 acpi_module_uninit(void* cookie) 150 { 151 } 152 153 154 static int32 155 acpi_module_std_ops(int32 op, ...) 156 { 157 switch (op) { 158 case B_MODULE_INIT: 159 { 160 module_info* module; 161 return get_module(B_ACPI_MODULE_NAME, &module); 162 // this serializes our module initialization 163 } 164 165 case B_MODULE_UNINIT: 166 return put_module(B_ACPI_MODULE_NAME); 167 } 168 169 return B_BAD_VALUE; 170 } 171 172 173 static struct acpi_root_info sACPIRootModule = { 174 { 175 { 176 ACPI_ROOT_MODULE_NAME, 177 0, 178 acpi_module_std_ops 179 }, 180 181 acpi_module_supports_device, 182 acpi_module_register_device, 183 acpi_module_init, 184 acpi_module_uninit, 185 acpi_module_register_child_devices, 186 NULL, // rescan devices 187 NULL, // device removed 188 }, 189 190 get_handle, 191 acquire_global_lock, 192 release_global_lock, 193 install_notify_handler, 194 remove_notify_handler, 195 update_all_gpes, 196 enable_gpe, 197 disable_gpe, 198 clear_gpe, 199 set_gpe, 200 finish_gpe, 201 install_gpe_handler, 202 remove_gpe_handler, 203 install_address_space_handler, 204 remove_address_space_handler, 205 enable_fixed_event, 206 disable_fixed_event, 207 fixed_event_status, 208 reset_fixed_event, 209 install_fixed_event_handler, 210 remove_fixed_event_handler, 211 get_next_entry, 212 get_device, 213 get_device_hid, 214 get_object_type, 215 get_object, 216 get_object_typed, 217 ns_handle_to_pathname, 218 evaluate_object, 219 evaluate_method, 220 get_irq_routing_table, 221 get_current_resources, 222 get_possible_resources, 223 set_current_resources, 224 walk_resources, 225 prepare_sleep_state, 226 enter_sleep_state, 227 reboot, 228 get_table 229 }; 230 231 232 module_info* modules[] = { 233 (module_info*)&gACPIModule, 234 (module_info*)&sACPIRootModule, 235 (module_info*)&acpi_ns_dump_module, 236 (module_info*)&gACPIDeviceModule, 237 (module_info*)&embedded_controller_driver_module, 238 (module_info*)&embedded_controller_device_module, 239 NULL 240 }; 241