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