xref: /haiku/src/add-ons/kernel/bus_managers/acpi/Device.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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 (path) {
61 		char objname[255];
62 		snprintf(objname, sizeof(objname), "%s.%s", device->path, path);
63 		return get_object(objname, return_value);
64 	}
65 	return get_object(device->path, return_value);
66 }
67 
68 
69 static status_t
70 acpi_evaluate_method(acpi_device device, const char *method,
71 	acpi_objects *args, acpi_data *returnValue)
72 {
73 	return evaluate_method(device->handle, method, args, returnValue);
74 }
75 
76 
77 static status_t
78 acpi_device_init_driver(device_node *node, void **cookie)
79 {
80 	ACPI_HANDLE handle;
81 	const char *path;
82 	uint32 type;
83 
84 	if (gDeviceManager->get_attr_uint32(node, ACPI_DEVICE_TYPE_ITEM, &type, false) != B_OK)
85 		return B_ERROR;
86 	if (gDeviceManager->get_attr_string(node, ACPI_DEVICE_PATH_ITEM, &path, false) != B_OK)
87 		return B_ERROR;
88 
89 	acpi_device_cookie *device = (acpi_device_cookie*)malloc(sizeof(*device));
90 	if (device == NULL)
91 		return B_NO_MEMORY;
92 
93 	memset(device, 0, sizeof(*device));
94 
95 	if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) {
96 		free(device);
97 		return B_ENTRY_NOT_FOUND;
98 	}
99 
100 	device->handle = handle;
101 	device->path = strdup(path);
102 	device->type = type;
103 	device->node = node;
104 
105 	snprintf(device->name, sizeof(device->name), "acpi_device %s", path);
106 	*cookie = device;
107 	return B_OK;
108 }
109 
110 
111 static void
112 acpi_device_uninit_driver(void *cookie)
113 {
114 	acpi_device_cookie *device = (acpi_device_cookie*)cookie;
115 
116 	free(device->path);
117 	free(device);
118 }
119 
120 
121 static status_t
122 acpi_device_std_ops(int32 op, ...)
123 {
124 	switch (op) {
125 		case B_MODULE_INIT:
126 		case B_MODULE_UNINIT:
127 			return B_OK;
128 	}
129 
130 	return B_BAD_VALUE;
131 }
132 
133 
134 acpi_device_module_info gACPIDeviceModule = {
135 	{
136 		{
137 			ACPI_DEVICE_MODULE_NAME,
138 			0,
139 			acpi_device_std_ops
140 		},
141 
142 		NULL,		// supports device
143 		NULL,		// register device (our parent registered us)
144 		acpi_device_init_driver,
145 		acpi_device_uninit_driver,
146 		NULL,	// register child devices
147 		NULL,	// rescan devices
148 		NULL,	// device removed
149 	},
150 	acpi_install_notify_handler,
151 	acpi_remove_notify_handler,
152 	acpi_install_address_space_handler,
153 	acpi_remove_address_space_handler,
154 	acpi_get_object_type,
155 	acpi_get_object,
156 	acpi_evaluate_method,
157 };
158