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 #include <string.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include "ACPIPrivate.h"
13 extern "C" {
14 #include "acpi.h"
15 }
16
17
18 static status_t
acpi_install_notify_handler(acpi_device device,uint32 handlerType,acpi_notify_handler handler,void * context)19 acpi_install_notify_handler(acpi_device device, uint32 handlerType,
20 acpi_notify_handler handler, void *context)
21 {
22 return install_notify_handler(device->handle, handlerType, handler,
23 context);
24 }
25
26 static status_t
acpi_remove_notify_handler(acpi_device device,uint32 handlerType,acpi_notify_handler handler)27 acpi_remove_notify_handler(acpi_device device, uint32 handlerType,
28 acpi_notify_handler handler)
29 {
30 return remove_notify_handler(device->handle, handlerType, handler);
31 }
32
33
34 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)35 acpi_install_address_space_handler(acpi_device device, uint32 spaceId,
36 acpi_adr_space_handler handler, acpi_adr_space_setup setup, void *data)
37 {
38 return install_address_space_handler(device->handle, spaceId, handler,
39 setup, data);
40 }
41
42 static status_t
acpi_remove_address_space_handler(acpi_device device,uint32 spaceId,acpi_adr_space_handler handler)43 acpi_remove_address_space_handler(acpi_device device, uint32 spaceId,
44 acpi_adr_space_handler handler)
45 {
46 return remove_address_space_handler(device->handle, spaceId, handler);
47 }
48
49
50 static uint32
acpi_get_object_type(acpi_device device)51 acpi_get_object_type(acpi_device device)
52 {
53 return device->type;
54 }
55
56
57 static status_t
acpi_get_object(acpi_device device,const char * path,acpi_object_type ** return_value)58 acpi_get_object(acpi_device device, const char *path, acpi_object_type **return_value)
59 {
60 if (device->path == NULL)
61 return B_BAD_VALUE;
62 if (path) {
63 char objname[255];
64 snprintf(objname, sizeof(objname), "%s.%s", device->path, path);
65 return get_object(objname, return_value);
66 }
67 return get_object(device->path, return_value);
68 }
69
70
71 static status_t
acpi_evaluate_method(acpi_device device,const char * method,acpi_objects * args,acpi_data * returnValue)72 acpi_evaluate_method(acpi_device device, const char *method,
73 acpi_objects *args, acpi_data *returnValue)
74 {
75 return evaluate_method(device->handle, method, args, returnValue);
76 }
77
78
79 static status_t
acpi_walk_resources(acpi_device device,char * method,acpi_walk_resources_callback callback,void * context)80 acpi_walk_resources(acpi_device device, char *method,
81 acpi_walk_resources_callback callback, void* context)
82 {
83 return walk_resources(device->handle, method, callback, context);
84 }
85
86
87 static status_t
acpi_walk_namespace(acpi_device device,uint32 objectType,uint32 maxDepth,acpi_walk_callback descendingCallback,acpi_walk_callback ascendingCallback,void * context,void ** returnValue)88 acpi_walk_namespace(acpi_device device, uint32 objectType, uint32 maxDepth,
89 acpi_walk_callback descendingCallback,
90 acpi_walk_callback ascendingCallback, void* context, void** returnValue)
91 {
92 return walk_namespace(device->handle, objectType, maxDepth,
93 descendingCallback, ascendingCallback, context, returnValue);
94 }
95
96
97 static status_t
acpi_device_init_driver(device_node * node,void ** cookie)98 acpi_device_init_driver(device_node *node, void **cookie)
99 {
100 ACPI_HANDLE handle = NULL;
101 const char *path = NULL;
102 uint32 type;
103
104 if (gDeviceManager->get_attr_uint32(node, ACPI_DEVICE_TYPE_ITEM, &type, false) != B_OK)
105 return B_ERROR;
106 gDeviceManager->get_attr_string(node, ACPI_DEVICE_PATH_ITEM, &path, false);
107
108 acpi_device_cookie *device = (acpi_device_cookie*)malloc(sizeof(*device));
109 if (device == NULL)
110 return B_NO_MEMORY;
111
112 memset(device, 0, sizeof(*device));
113
114 if (path != NULL && AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) {
115 free(device);
116 return B_ENTRY_NOT_FOUND;
117 }
118
119 device->handle = handle;
120 device->path = path != NULL ? strdup(path) : NULL;
121 device->type = type;
122 device->node = node;
123
124 snprintf(device->name, sizeof(device->name), "acpi_device %s", path);
125 *cookie = device;
126 return B_OK;
127 }
128
129
130 static void
acpi_device_uninit_driver(void * cookie)131 acpi_device_uninit_driver(void *cookie)
132 {
133 acpi_device_cookie *device = (acpi_device_cookie*)cookie;
134
135 free(device->path);
136 free(device);
137 }
138
139
140 static status_t
acpi_device_std_ops(int32 op,...)141 acpi_device_std_ops(int32 op, ...)
142 {
143 switch (op) {
144 case B_MODULE_INIT:
145 case B_MODULE_UNINIT:
146 return B_OK;
147 }
148
149 return B_BAD_VALUE;
150 }
151
152
153 acpi_device_module_info gACPIDeviceModule = {
154 {
155 {
156 ACPI_DEVICE_MODULE_NAME,
157 0,
158 acpi_device_std_ops
159 },
160
161 NULL, // supports device
162 NULL, // register device (our parent registered us)
163 acpi_device_init_driver,
164 acpi_device_uninit_driver,
165 NULL, // register child devices
166 NULL, // rescan devices
167 NULL, // device removed
168 },
169 acpi_install_notify_handler,
170 acpi_remove_notify_handler,
171 acpi_install_address_space_handler,
172 acpi_remove_address_space_handler,
173 acpi_get_object_type,
174 acpi_get_object,
175 acpi_walk_namespace,
176 acpi_evaluate_method,
177 acpi_walk_resources
178 };
179