xref: /haiku/src/add-ons/kernel/bus_managers/acpi/Device.cpp (revision f7c507c3a6fbf3a44c59500543926a9088724968)
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
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
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
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
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
51 acpi_get_object_type(acpi_device device)
52 {
53 	return device->type;
54 }
55 
56 
57 static status_t
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
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
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
88 acpi_device_init_driver(device_node *node, void **cookie)
89 {
90 	ACPI_HANDLE handle = NULL;
91 	const char *path = NULL;
92 	uint32 type;
93 
94 	if (gDeviceManager->get_attr_uint32(node, ACPI_DEVICE_TYPE_ITEM, &type, false) != B_OK)
95 		return B_ERROR;
96 	gDeviceManager->get_attr_string(node, ACPI_DEVICE_PATH_ITEM, &path, false);
97 
98 	acpi_device_cookie *device = (acpi_device_cookie*)malloc(sizeof(*device));
99 	if (device == NULL)
100 		return B_NO_MEMORY;
101 
102 	memset(device, 0, sizeof(*device));
103 
104 	if (path != NULL && AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) {
105 		free(device);
106 		return B_ENTRY_NOT_FOUND;
107 	}
108 
109 	device->handle = handle;
110 	device->path = path != NULL ? strdup(path) : NULL;
111 	device->type = type;
112 	device->node = node;
113 
114 	snprintf(device->name, sizeof(device->name), "acpi_device %s", path);
115 	*cookie = device;
116 	return B_OK;
117 }
118 
119 
120 static void
121 acpi_device_uninit_driver(void *cookie)
122 {
123 	acpi_device_cookie *device = (acpi_device_cookie*)cookie;
124 
125 	free(device->path);
126 	free(device);
127 }
128 
129 
130 static status_t
131 acpi_device_std_ops(int32 op, ...)
132 {
133 	switch (op) {
134 		case B_MODULE_INIT:
135 		case B_MODULE_UNINIT:
136 			return B_OK;
137 	}
138 
139 	return B_BAD_VALUE;
140 }
141 
142 
143 acpi_device_module_info gACPIDeviceModule = {
144 	{
145 		{
146 			ACPI_DEVICE_MODULE_NAME,
147 			0,
148 			acpi_device_std_ops
149 		},
150 
151 		NULL,		// supports device
152 		NULL,		// register device (our parent registered us)
153 		acpi_device_init_driver,
154 		acpi_device_uninit_driver,
155 		NULL,	// register child devices
156 		NULL,	// rescan devices
157 		NULL,	// device removed
158 	},
159 	acpi_install_notify_handler,
160 	acpi_remove_notify_handler,
161 	acpi_install_address_space_handler,
162 	acpi_remove_address_space_handler,
163 	acpi_get_object_type,
164 	acpi_get_object,
165 	acpi_evaluate_method,
166 	acpi_walk_resources
167 };
168