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"
13extern "C" {
14#include "acpi.h"
15}
16
17
18static status_t
19acpi_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
26static status_t
27acpi_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
34static status_t
35acpi_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
42static status_t
43acpi_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
50static uint32
51acpi_get_object_type(acpi_device device)
52{
53	return device->type;
54}
55
56
57static status_t
58acpi_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
71static status_t
72acpi_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
79static status_t
80acpi_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
87static status_t
88acpi_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
97static status_t
98acpi_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
130static void
131acpi_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
140static status_t
141acpi_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
153acpi_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