nsxfname.c 9.97 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8
/******************************************************************************
 *
 * Module Name: nsxfname - Public interfaces to the ACPI subsystem
 *                         ACPI Namespace oriented interfaces
 *
 *****************************************************************************/

/*
9
 * Copyright (C) 2000 - 2004, R. Byron Moore
10
 * All rights reserved.
Linus Torvalds's avatar
Linus Torvalds committed
11
 *
12 13 14 15 16 17 18 19 20 21 22 23 24 25
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
Linus Torvalds's avatar
Linus Torvalds committed
26
 *
27 28 29
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
Linus Torvalds's avatar
Linus Torvalds committed
30
 *
31 32 33 34 35 36 37 38 39 40 41 42
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
Linus Torvalds's avatar
Linus Torvalds committed
43 44 45
 */


46 47
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
Linus Torvalds's avatar
Linus Torvalds committed
48 49


Linus Torvalds's avatar
Linus Torvalds committed
50
#define _COMPONENT          ACPI_NAMESPACE
Andy Grover's avatar
Andy Grover committed
51
	 ACPI_MODULE_NAME    ("nsxfname")
Linus Torvalds's avatar
Linus Torvalds committed
52 53


Andy Grover's avatar
Andy Grover committed
54
/******************************************************************************
Linus Torvalds's avatar
Linus Torvalds committed
55
 *
56
 * FUNCTION:    acpi_get_handle
Linus Torvalds's avatar
Linus Torvalds committed
57 58
 *
 * PARAMETERS:  Parent          - Object to search under (search scope).
59
 *              path_name       - Pointer to an asciiz string containing the
Linus Torvalds's avatar
Linus Torvalds committed
60
 *                                  name
61
 *              ret_handle      - Where the return handle is placed
Linus Torvalds's avatar
Linus Torvalds committed
62 63 64 65 66 67 68 69 70 71
 *
 * RETURN:      Status
 *
 * DESCRIPTION: This routine will search for a caller specified name in the
 *              name space.  The caller can restrict the search region by
 *              specifying a non NULL parent.  The parent value is itself a
 *              namespace handle.
 *
 ******************************************************************************/

Linus Torvalds's avatar
Linus Torvalds committed
72
acpi_status
Linus Torvalds's avatar
Linus Torvalds committed
73
acpi_get_handle (
74 75 76
	acpi_handle                     parent,
	acpi_string                     pathname,
	acpi_handle                     *ret_handle)
Linus Torvalds's avatar
Linus Torvalds committed
77
{
78 79 80
	acpi_status                     status;
	struct acpi_namespace_node      *node = NULL;
	struct acpi_namespace_node      *prefix_node = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
81 82


Andy Grover's avatar
Andy Grover committed
83
	ACPI_FUNCTION_ENTRY ();
Linus Torvalds's avatar
Linus Torvalds committed
84 85


Linus Torvalds's avatar
Linus Torvalds committed
86 87
	/* Parameter Validation */

Linus Torvalds's avatar
Linus Torvalds committed
88 89 90 91 92 93 94
	if (!ret_handle || !pathname) {
		return (AE_BAD_PARAMETER);
	}

	/* Convert a parent handle to a prefix node */

	if (parent) {
Andy Grover's avatar
Andy Grover committed
95 96 97 98
		status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
		if (ACPI_FAILURE (status)) {
			return (status);
		}
Linus Torvalds's avatar
Linus Torvalds committed
99

Linus Torvalds's avatar
Linus Torvalds committed
100
		prefix_node = acpi_ns_map_handle_to_node (parent);
Linus Torvalds's avatar
Linus Torvalds committed
101
		if (!prefix_node) {
Andy Grover's avatar
Andy Grover committed
102
			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
Linus Torvalds's avatar
Linus Torvalds committed
103 104 105
			return (AE_BAD_PARAMETER);
		}

Andy Grover's avatar
Andy Grover committed
106 107 108 109
		status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
		if (ACPI_FAILURE (status)) {
			return (status);
		}
Linus Torvalds's avatar
Linus Torvalds committed
110 111 112 113
	}

	/* Special case for root, since we can't search for it */

Andy Grover's avatar
Andy Grover committed
114
	if (ACPI_STRCMP (pathname, ACPI_NS_ROOT_PATH) == 0) {
Linus Torvalds's avatar
Linus Torvalds committed
115 116 117 118 119 120 121
		*ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node);
		return (AE_OK);
	}

	/*
	 *  Find the Node and convert to a handle
	 */
Andy Grover's avatar
Andy Grover committed
122 123
	status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
			  &node);
Linus Torvalds's avatar
Linus Torvalds committed
124 125 126 127 128 129 130 131 132 133

	*ret_handle = NULL;
	if (ACPI_SUCCESS (status)) {
		*ret_handle = acpi_ns_convert_entry_to_handle (node);
	}

	return (status);
}


Andy Grover's avatar
Andy Grover committed
134
/******************************************************************************
Linus Torvalds's avatar
Linus Torvalds committed
135
 *
136
 * FUNCTION:    acpi_get_name
Linus Torvalds's avatar
Linus Torvalds committed
137 138
 *
 * PARAMETERS:  Handle          - Handle to be converted to a pathname
139
 *              name_type       - Full pathname or single segment
Andy Grover's avatar
Andy Grover committed
140
 *              Buffer          - Buffer for returned path
Linus Torvalds's avatar
Linus Torvalds committed
141 142 143 144
 *
 * RETURN:      Pointer to a string containing the fully qualified Name.
 *
 * DESCRIPTION: This routine returns the fully qualified name associated with
145
 *              the Handle parameter.  This and the acpi_pathname_to_handle are
Linus Torvalds's avatar
Linus Torvalds committed
146 147 148 149
 *              complementary functions.
 *
 ******************************************************************************/

Linus Torvalds's avatar
Linus Torvalds committed
150
acpi_status
Linus Torvalds's avatar
Linus Torvalds committed
151
acpi_get_name (
152 153 154
	acpi_handle                     handle,
	u32                             name_type,
	struct acpi_buffer              *buffer)
Linus Torvalds's avatar
Linus Torvalds committed
155
{
156 157
	acpi_status                     status;
	struct acpi_namespace_node      *node;
Linus Torvalds's avatar
Linus Torvalds committed
158 159


Andy Grover's avatar
Andy Grover committed
160
	/* Parameter validation */
Linus Torvalds's avatar
Linus Torvalds committed
161

Andy Grover's avatar
Andy Grover committed
162
	if (name_type > ACPI_NAME_TYPE_MAX) {
Linus Torvalds's avatar
Linus Torvalds committed
163 164 165
		return (AE_BAD_PARAMETER);
	}

Andy Grover's avatar
Andy Grover committed
166 167 168
	status = acpi_ut_validate_buffer (buffer);
	if (ACPI_FAILURE (status)) {
		return (status);
Linus Torvalds's avatar
Linus Torvalds committed
169 170 171 172 173
	}

	if (name_type == ACPI_FULL_PATHNAME) {
		/* Get the full pathname (From the namespace root) */

Andy Grover's avatar
Andy Grover committed
174
		status = acpi_ns_handle_to_pathname (handle, buffer);
Linus Torvalds's avatar
Linus Torvalds committed
175 176 177 178 179
		return (status);
	}

	/*
	 * Wants the single segment ACPI name.
Andy Grover's avatar
Andy Grover committed
180
	 * Validate handle and convert to a namespace Node
Linus Torvalds's avatar
Linus Torvalds committed
181
	 */
Andy Grover's avatar
Andy Grover committed
182 183 184 185 186
	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE (status)) {
		return (status);
	}

Linus Torvalds's avatar
Linus Torvalds committed
187
	node = acpi_ns_map_handle_to_node (handle);
Linus Torvalds's avatar
Linus Torvalds committed
188 189 190 191 192
	if (!node) {
		status = AE_BAD_PARAMETER;
		goto unlock_and_exit;
	}

Andy Grover's avatar
Andy Grover committed
193
	/* Validate/Allocate/Clear caller buffer */
Linus Torvalds's avatar
Linus Torvalds committed
194

195
	status = acpi_ut_initialize_buffer (buffer, ACPI_PATH_SEGMENT_LENGTH);
Andy Grover's avatar
Andy Grover committed
196
	if (ACPI_FAILURE (status)) {
Linus Torvalds's avatar
Linus Torvalds committed
197 198 199 200 201
		goto unlock_and_exit;
	}

	/* Just copy the ACPI name from the Node and zero terminate it */

202
	ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node),
Linus Torvalds's avatar
Linus Torvalds committed
203
			 ACPI_NAME_SIZE);
Andy Grover's avatar
Andy Grover committed
204
	((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0;
Linus Torvalds's avatar
Linus Torvalds committed
205 206 207 208 209
	status = AE_OK;


unlock_and_exit:

Andy Grover's avatar
Andy Grover committed
210
	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
Linus Torvalds's avatar
Linus Torvalds committed
211 212 213 214
	return (status);
}


Andy Grover's avatar
Andy Grover committed
215
/******************************************************************************
Linus Torvalds's avatar
Linus Torvalds committed
216
 *
217
 * FUNCTION:    acpi_get_object_info
Linus Torvalds's avatar
Linus Torvalds committed
218 219 220 221 222 223 224 225 226 227 228 229
 *
 * PARAMETERS:  Handle          - Object Handle
 *              Info            - Where the info is returned
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Returns information about an object as gleaned from the
 *              namespace node and possibly by running several standard
 *              control methods (Such as in the case of a device.)
 *
 ******************************************************************************/

Linus Torvalds's avatar
Linus Torvalds committed
230
acpi_status
Linus Torvalds's avatar
Linus Torvalds committed
231
acpi_get_object_info (
232
	acpi_handle                     handle,
Andy Grover's avatar
Andy Grover committed
233
	struct acpi_buffer              *buffer)
Linus Torvalds's avatar
Linus Torvalds committed
234
{
235 236
	acpi_status                     status;
	struct acpi_namespace_node      *node;
Andy Grover's avatar
Andy Grover committed
237 238 239 240
	struct acpi_device_info         info;
	struct acpi_device_info         *return_info;
	struct acpi_compatible_id_list *cid_list = NULL;
	acpi_size                       size;
Linus Torvalds's avatar
Linus Torvalds committed
241 242 243 244


	/* Parameter validation */

Andy Grover's avatar
Andy Grover committed
245
	if (!handle || !buffer) {
Linus Torvalds's avatar
Linus Torvalds committed
246 247 248
		return (AE_BAD_PARAMETER);
	}

Andy Grover's avatar
Andy Grover committed
249 250 251 252 253
	status = acpi_ut_validate_buffer (buffer);
	if (ACPI_FAILURE (status)) {
		return (status);
	}

Andy Grover's avatar
Andy Grover committed
254 255 256 257
	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE (status)) {
		return (status);
	}
Linus Torvalds's avatar
Linus Torvalds committed
258

Linus Torvalds's avatar
Linus Torvalds committed
259
	node = acpi_ns_map_handle_to_node (handle);
Linus Torvalds's avatar
Linus Torvalds committed
260
	if (!node) {
Andy Grover's avatar
Andy Grover committed
261
		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
Linus Torvalds's avatar
Linus Torvalds committed
262 263 264
		return (AE_BAD_PARAMETER);
	}

Andy Grover's avatar
Andy Grover committed
265 266 267 268 269 270 271 272
	/* Init return structure */

	size = sizeof (struct acpi_device_info);
	ACPI_MEMSET (&info, 0, size);

	info.type  = node->type;
	info.name  = node->name.integer;
	info.valid = 0;
Linus Torvalds's avatar
Linus Torvalds committed
273

Andy Grover's avatar
Andy Grover committed
274 275 276 277
	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE (status)) {
		return (status);
	}
Linus Torvalds's avatar
Linus Torvalds committed
278

Andy Grover's avatar
Andy Grover committed
279
	/* If not a device, we are all done */
Linus Torvalds's avatar
Linus Torvalds committed
280

Andy Grover's avatar
Andy Grover committed
281 282 283 284 285 286 287 288 289
	if (info.type == ACPI_TYPE_DEVICE) {
		/*
		 * Get extra info for ACPI Devices objects only:
		 * Run the Device _HID, _UID, _CID, _STA, and _ADR methods.
		 *
		 * Note: none of these methods are required, so they may or may
		 * not be present for this device.  The Info.Valid bitfield is used
		 * to indicate which methods were found and ran successfully.
		 */
Linus Torvalds's avatar
Linus Torvalds committed
290

Andy Grover's avatar
Andy Grover committed
291
		/* Execute the Device._HID method */
Linus Torvalds's avatar
Linus Torvalds committed
292

Andy Grover's avatar
Andy Grover committed
293 294 295 296
		status = acpi_ut_execute_HID (node, &info.hardware_id);
		if (ACPI_SUCCESS (status)) {
			info.valid |= ACPI_VALID_HID;
		}
Linus Torvalds's avatar
Linus Torvalds committed
297

Andy Grover's avatar
Andy Grover committed
298
		/* Execute the Device._UID method */
Linus Torvalds's avatar
Linus Torvalds committed
299

Andy Grover's avatar
Andy Grover committed
300 301 302 303
		status = acpi_ut_execute_UID (node, &info.unique_id);
		if (ACPI_SUCCESS (status)) {
			info.valid |= ACPI_VALID_UID;
		}
Linus Torvalds's avatar
Linus Torvalds committed
304

Andy Grover's avatar
Andy Grover committed
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
		/* Execute the Device._CID method */

		status = acpi_ut_execute_CID (node, &cid_list);
		if (ACPI_SUCCESS (status)) {
			size += ((acpi_size) cid_list->count - 1) *
					 sizeof (struct acpi_compatible_id);
			info.valid |= ACPI_VALID_CID;
		}

		/* Execute the Device._STA method */

		status = acpi_ut_execute_STA (node, &info.current_status);
		if (ACPI_SUCCESS (status)) {
			info.valid |= ACPI_VALID_STA;
		}

		/* Execute the Device._ADR method */

		status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
				  &info.address);
		if (ACPI_SUCCESS (status)) {
			info.valid |= ACPI_VALID_ADR;
		}

329 330 331 332 333 334 335
		/* Execute the Device._sx_d methods */

		status = acpi_ut_execute_sxds (node, info.highest_dstates);
		if (ACPI_SUCCESS (status)) {
			info.valid |= ACPI_VALID_STA;
		}

Andy Grover's avatar
Andy Grover committed
336
		status = AE_OK;
Linus Torvalds's avatar
Linus Torvalds committed
337 338
	}

Andy Grover's avatar
Andy Grover committed
339 340 341 342 343
	/* Validate/Allocate/Clear caller buffer */

	status = acpi_ut_initialize_buffer (buffer, size);
	if (ACPI_FAILURE (status)) {
		goto cleanup;
Linus Torvalds's avatar
Linus Torvalds committed
344 345
	}

Andy Grover's avatar
Andy Grover committed
346
	/* Populate the return buffer */
Linus Torvalds's avatar
Linus Torvalds committed
347

Andy Grover's avatar
Andy Grover committed
348 349 350 351 352
	return_info = buffer->pointer;
	ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info));

	if (cid_list) {
		ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
Linus Torvalds's avatar
Linus Torvalds committed
353 354
	}

Andy Grover's avatar
Andy Grover committed
355 356 357 358 359 360

cleanup:
	if (cid_list) {
		ACPI_MEM_FREE (cid_list);
	}
	return (status);
Linus Torvalds's avatar
Linus Torvalds committed
361 362
}