Blame view
drivers/acpi/utils.c
23.7 KB
c942fddf8 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 |
/* * acpi_utils.c - ACPI Utility Functions ($Revision: 10 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> |
1da177e4c Linux-2.6.12-rc2 |
7 8 9 10 |
*/ #include <linux/kernel.h> #include <linux/module.h> |
5a0e3ad6a include cleanup: ... |
11 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/init.h> #include <linux/types.h> |
fbfddae69 ACPI: Add acpi_ha... |
14 15 |
#include <linux/hardirq.h> #include <linux/acpi.h> |
45fef5b88 ACPI: add dynamic... |
16 |
#include <linux/dynamic_debug.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
|
a192a9580 ACPI: Move defini... |
18 |
#include "internal.h" |
2d12b6b38 ACPI / utils: Add... |
19 |
#include "sleep.h" |
a192a9580 ACPI: Move defini... |
20 |
|
1da177e4c Linux-2.6.12-rc2 |
21 |
#define _COMPONENT ACPI_BUS_COMPONENT |
f52fd66d2 ACPI: clean up AC... |
22 |
ACPI_MODULE_NAME("utils"); |
1da177e4c Linux-2.6.12-rc2 |
23 24 25 26 |
/* -------------------------------------------------------------------------- Object Evaluation Helpers -------------------------------------------------------------------------- */ |
4fd7f5188 ACPI: sparse fix,... |
27 28 29 |
static void acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s) { |
1da177e4c Linux-2.6.12-rc2 |
30 |
#ifdef ACPI_DEBUG_OUTPUT |
4fd7f5188 ACPI: sparse fix,... |
31 32 33 34 35 36 |
char prefix[80] = {'\0'}; struct acpi_buffer buffer = {sizeof(prefix), prefix}; acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s ", (char *) prefix, p, acpi_format_exception(s))); |
1da177e4c Linux-2.6.12-rc2 |
37 |
#else |
4fd7f5188 ACPI: sparse fix,... |
38 |
return; |
1da177e4c Linux-2.6.12-rc2 |
39 |
#endif |
4fd7f5188 ACPI: sparse fix,... |
40 |
} |
1da177e4c Linux-2.6.12-rc2 |
41 |
acpi_status |
4be44fcd3 [ACPI] Lindent al... |
42 43 |
acpi_extract_package(union acpi_object *package, struct acpi_buffer *format, struct acpi_buffer *buffer) |
1da177e4c Linux-2.6.12-rc2 |
44 |
{ |
4be44fcd3 [ACPI] Lindent al... |
45 46 47 48 49 50 51 |
u32 size_required = 0; u32 tail_offset = 0; char *format_string = NULL; u32 format_count = 0; u32 i = 0; u8 *head = NULL; u8 *tail = NULL; |
1da177e4c Linux-2.6.12-rc2 |
52 |
|
1da177e4c Linux-2.6.12-rc2 |
53 |
|
4be44fcd3 [ACPI] Lindent al... |
54 55 |
if (!package || (package->type != ACPI_TYPE_PACKAGE) || (package->package.count < 1)) { |
cece92969 ACPI: un-export A... |
56 57 |
printk(KERN_WARNING PREFIX "Invalid package argument "); |
d550d98d3 ACPI: delete trac... |
58 |
return AE_BAD_PARAMETER; |
1da177e4c Linux-2.6.12-rc2 |
59 60 61 |
} if (!format || !format->pointer || (format->length < 1)) { |
cece92969 ACPI: un-export A... |
62 63 |
printk(KERN_WARNING PREFIX "Invalid format argument "); |
d550d98d3 ACPI: delete trac... |
64 |
return AE_BAD_PARAMETER; |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 |
} if (!buffer) { |
cece92969 ACPI: un-export A... |
68 69 |
printk(KERN_WARNING PREFIX "Invalid buffer argument "); |
d550d98d3 ACPI: delete trac... |
70 |
return AE_BAD_PARAMETER; |
1da177e4c Linux-2.6.12-rc2 |
71 |
} |
4be44fcd3 [ACPI] Lindent al... |
72 |
format_count = (format->length / sizeof(char)) - 1; |
1da177e4c Linux-2.6.12-rc2 |
73 |
if (format_count > package->package.count) { |
cece92969 ACPI: un-export A... |
74 75 76 77 |
printk(KERN_WARNING PREFIX "Format specifies more objects [%d]" " than exist in package [%d]. ", format_count, package->package.count); |
d550d98d3 ACPI: delete trac... |
78 |
return AE_BAD_DATA; |
1da177e4c Linux-2.6.12-rc2 |
79 |
} |
50dd09697 ACPI: Remove unne... |
80 |
format_string = format->pointer; |
1da177e4c Linux-2.6.12-rc2 |
81 82 83 84 |
/* * Calculate size_required. */ |
4be44fcd3 [ACPI] Lindent al... |
85 |
for (i = 0; i < format_count; i++) { |
1da177e4c Linux-2.6.12-rc2 |
86 87 |
union acpi_object *element = &(package->package.elements[i]); |
1da177e4c Linux-2.6.12-rc2 |
88 89 90 91 92 |
switch (element->type) { case ACPI_TYPE_INTEGER: switch (format_string[i]) { case 'N': |
439913fff ACPI: replace acp... |
93 94 |
size_required += sizeof(u64); tail_offset += sizeof(u64); |
1da177e4c Linux-2.6.12-rc2 |
95 96 |
break; case 'S': |
4be44fcd3 [ACPI] Lindent al... |
97 |
size_required += |
439913fff ACPI: replace acp... |
98 |
sizeof(char *) + sizeof(u64) + |
4be44fcd3 [ACPI] Lindent al... |
99 100 |
sizeof(char); tail_offset += sizeof(char *); |
1da177e4c Linux-2.6.12-rc2 |
101 102 |
break; default: |
cece92969 ACPI: un-export A... |
103 |
printk(KERN_WARNING PREFIX "Invalid package element" |
e7e92ec93 ACPI: Fix spellin... |
104 |
" [%d]: got number, expecting" |
cece92969 ACPI: un-export A... |
105 106 107 |
" [%c] ", i, format_string[i]); |
d550d98d3 ACPI: delete trac... |
108 |
return AE_BAD_DATA; |
1da177e4c Linux-2.6.12-rc2 |
109 110 111 112 113 114 115 |
} break; case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: switch (format_string[i]) { case 'S': |
4be44fcd3 [ACPI] Lindent al... |
116 117 118 119 120 |
size_required += sizeof(char *) + (element->string.length * sizeof(char)) + sizeof(char); tail_offset += sizeof(char *); |
1da177e4c Linux-2.6.12-rc2 |
121 122 |
break; case 'B': |
4be44fcd3 [ACPI] Lindent al... |
123 |
size_required += |
d93de3455 ACPI: remove unne... |
124 |
sizeof(u8 *) + element->buffer.length; |
4be44fcd3 [ACPI] Lindent al... |
125 |
tail_offset += sizeof(u8 *); |
1da177e4c Linux-2.6.12-rc2 |
126 127 |
break; default: |
cece92969 ACPI: un-export A... |
128 |
printk(KERN_WARNING PREFIX "Invalid package element" |
a6fc67202 ACPI: Enable ACPI... |
129 |
" [%d] got string/buffer," |
e7e92ec93 ACPI: Fix spellin... |
130 131 |
" expecting [%c] ", |
cece92969 ACPI: un-export A... |
132 |
i, format_string[i]); |
d550d98d3 ACPI: delete trac... |
133 |
return AE_BAD_DATA; |
1da177e4c Linux-2.6.12-rc2 |
134 135 |
} break; |
e3ec483a7 ACPI: add ACPI_TY... |
136 137 138 139 140 141 142 143 144 145 146 147 148 |
case ACPI_TYPE_LOCAL_REFERENCE: switch (format_string[i]) { case 'R': size_required += sizeof(void *); tail_offset += sizeof(void *); break; default: printk(KERN_WARNING PREFIX "Invalid package element" " [%d] got reference," " expecting [%c] ", i, format_string[i]); return AE_BAD_DATA; |
e3ec483a7 ACPI: add ACPI_TY... |
149 150 |
} break; |
1da177e4c Linux-2.6.12-rc2 |
151 152 153 |
case ACPI_TYPE_PACKAGE: default: |
4be44fcd3 [ACPI] Lindent al... |
154 155 156 157 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%d ", i)); |
1da177e4c Linux-2.6.12-rc2 |
158 |
/* TBD: handle nested packages... */ |
d550d98d3 ACPI: delete trac... |
159 |
return AE_SUPPORT; |
1da177e4c Linux-2.6.12-rc2 |
160 161 162 163 164 165 |
} } /* * Validate output buffer. */ |
e83dda062 ACPI: improve acp... |
166 |
if (buffer->length == ACPI_ALLOCATE_BUFFER) { |
2d0acb4af ACPI: Clean up me... |
167 |
buffer->pointer = ACPI_ALLOCATE_ZEROED(size_required); |
e83dda062 ACPI: improve acp... |
168 169 |
if (!buffer->pointer) return AE_NO_MEMORY; |
1da177e4c Linux-2.6.12-rc2 |
170 |
buffer->length = size_required; |
e83dda062 ACPI: improve acp... |
171 172 173 174 175 176 177 178 |
} else { if (buffer->length < size_required) { buffer->length = size_required; return AE_BUFFER_OVERFLOW; } else if (buffer->length != size_required || !buffer->pointer) { return AE_BAD_PARAMETER; } |
1da177e4c Linux-2.6.12-rc2 |
179 180 181 182 183 184 185 186 |
} head = buffer->pointer; tail = buffer->pointer + tail_offset; /* * Extract package data. */ |
4be44fcd3 [ACPI] Lindent al... |
187 |
for (i = 0; i < format_count; i++) { |
1da177e4c Linux-2.6.12-rc2 |
188 189 190 |
u8 **pointer = NULL; union acpi_object *element = &(package->package.elements[i]); |
1da177e4c Linux-2.6.12-rc2 |
191 192 193 194 195 |
switch (element->type) { case ACPI_TYPE_INTEGER: switch (format_string[i]) { case 'N': |
439913fff ACPI: replace acp... |
196 |
*((u64 *) head) = |
4be44fcd3 [ACPI] Lindent al... |
197 |
element->integer.value; |
439913fff ACPI: replace acp... |
198 |
head += sizeof(u64); |
1da177e4c Linux-2.6.12-rc2 |
199 200 |
break; case 'S': |
4be44fcd3 [ACPI] Lindent al... |
201 |
pointer = (u8 **) head; |
1da177e4c Linux-2.6.12-rc2 |
202 |
*pointer = tail; |
439913fff ACPI: replace acp... |
203 |
*((u64 *) tail) = |
4be44fcd3 [ACPI] Lindent al... |
204 |
element->integer.value; |
439913fff ACPI: replace acp... |
205 206 |
head += sizeof(u64 *); tail += sizeof(u64); |
1da177e4c Linux-2.6.12-rc2 |
207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
/* NULL terminate string */ *tail = (char)0; tail += sizeof(char); break; default: /* Should never get here */ break; } break; case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: switch (format_string[i]) { case 'S': |
4be44fcd3 [ACPI] Lindent al... |
221 |
pointer = (u8 **) head; |
1da177e4c Linux-2.6.12-rc2 |
222 |
*pointer = tail; |
4be44fcd3 [ACPI] Lindent al... |
223 224 225 |
memcpy(tail, element->string.pointer, element->string.length); head += sizeof(char *); |
1da177e4c Linux-2.6.12-rc2 |
226 227 228 229 230 231 |
tail += element->string.length * sizeof(char); /* NULL terminate string */ *tail = (char)0; tail += sizeof(char); break; case 'B': |
4be44fcd3 [ACPI] Lindent al... |
232 |
pointer = (u8 **) head; |
1da177e4c Linux-2.6.12-rc2 |
233 |
*pointer = tail; |
4be44fcd3 [ACPI] Lindent al... |
234 235 236 |
memcpy(tail, element->buffer.pointer, element->buffer.length); head += sizeof(u8 *); |
d93de3455 ACPI: remove unne... |
237 |
tail += element->buffer.length; |
1da177e4c Linux-2.6.12-rc2 |
238 239 240 241 242 243 |
break; default: /* Should never get here */ break; } break; |
e3ec483a7 ACPI: add ACPI_TY... |
244 245 246 247 248 249 250 251 252 253 254 255 |
case ACPI_TYPE_LOCAL_REFERENCE: switch (format_string[i]) { case 'R': *(void **)head = (void *)element->reference.handle; head += sizeof(void *); break; default: /* Should never get here */ break; } break; |
1da177e4c Linux-2.6.12-rc2 |
256 257 258 259 260 261 262 |
case ACPI_TYPE_PACKAGE: /* TBD: handle nested packages... */ default: /* Should never get here */ break; } } |
d550d98d3 ACPI: delete trac... |
263 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
264 |
} |
1da177e4c Linux-2.6.12-rc2 |
265 |
|
4be44fcd3 [ACPI] Lindent al... |
266 |
EXPORT_SYMBOL(acpi_extract_package); |
1da177e4c Linux-2.6.12-rc2 |
267 268 |
acpi_status |
4be44fcd3 [ACPI] Lindent al... |
269 270 |
acpi_evaluate_integer(acpi_handle handle, acpi_string pathname, |
27663c585 ACPI: Change acpi... |
271 |
struct acpi_object_list *arguments, unsigned long long *data) |
1da177e4c Linux-2.6.12-rc2 |
272 |
{ |
4be44fcd3 [ACPI] Lindent al... |
273 |
acpi_status status = AE_OK; |
40599072d ACPI: scheduling ... |
274 |
union acpi_object element; |
4be44fcd3 [ACPI] Lindent al... |
275 |
struct acpi_buffer buffer = { 0, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
276 |
|
1da177e4c Linux-2.6.12-rc2 |
277 |
if (!data) |
d550d98d3 ACPI: delete trac... |
278 |
return AE_BAD_PARAMETER; |
1da177e4c Linux-2.6.12-rc2 |
279 |
|
1da177e4c Linux-2.6.12-rc2 |
280 |
buffer.length = sizeof(union acpi_object); |
40599072d ACPI: scheduling ... |
281 |
buffer.pointer = &element; |
1da177e4c Linux-2.6.12-rc2 |
282 283 284 |
status = acpi_evaluate_object(handle, pathname, arguments, &buffer); if (ACPI_FAILURE(status)) { acpi_util_eval_error(handle, pathname, status); |
d550d98d3 ACPI: delete trac... |
285 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
286 |
} |
40599072d ACPI: scheduling ... |
287 |
if (element.type != ACPI_TYPE_INTEGER) { |
1da177e4c Linux-2.6.12-rc2 |
288 |
acpi_util_eval_error(handle, pathname, AE_BAD_DATA); |
d550d98d3 ACPI: delete trac... |
289 |
return AE_BAD_DATA; |
1da177e4c Linux-2.6.12-rc2 |
290 |
} |
40599072d ACPI: scheduling ... |
291 |
*data = element.integer.value; |
1da177e4c Linux-2.6.12-rc2 |
292 |
|
27663c585 ACPI: Change acpi... |
293 294 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu] ", *data)); |
1da177e4c Linux-2.6.12-rc2 |
295 |
|
d550d98d3 ACPI: delete trac... |
296 |
return AE_OK; |
1da177e4c Linux-2.6.12-rc2 |
297 |
} |
1da177e4c Linux-2.6.12-rc2 |
298 |
|
4be44fcd3 [ACPI] Lindent al... |
299 |
EXPORT_SYMBOL(acpi_evaluate_integer); |
1da177e4c Linux-2.6.12-rc2 |
300 |
|
1da177e4c Linux-2.6.12-rc2 |
301 |
acpi_status |
4be44fcd3 [ACPI] Lindent al... |
302 303 304 305 |
acpi_evaluate_reference(acpi_handle handle, acpi_string pathname, struct acpi_object_list *arguments, struct acpi_handle_list *list) |
1da177e4c Linux-2.6.12-rc2 |
306 |
{ |
4be44fcd3 [ACPI] Lindent al... |
307 308 309 310 311 |
acpi_status status = AE_OK; union acpi_object *package = NULL; union acpi_object *element = NULL; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; u32 i = 0; |
1da177e4c Linux-2.6.12-rc2 |
312 |
|
1da177e4c Linux-2.6.12-rc2 |
313 314 |
if (!list) { |
d550d98d3 ACPI: delete trac... |
315 |
return AE_BAD_PARAMETER; |
1da177e4c Linux-2.6.12-rc2 |
316 317 318 319 320 321 322 |
} /* Evaluate object. */ status = acpi_evaluate_object(handle, pathname, arguments, &buffer); if (ACPI_FAILURE(status)) goto end; |
50dd09697 ACPI: Remove unne... |
323 |
package = buffer.pointer; |
1da177e4c Linux-2.6.12-rc2 |
324 325 |
if ((buffer.length == 0) || !package) { |
1da177e4c Linux-2.6.12-rc2 |
326 327 328 329 330 |
status = AE_BAD_DATA; acpi_util_eval_error(handle, pathname, status); goto end; } if (package->type != ACPI_TYPE_PACKAGE) { |
1da177e4c Linux-2.6.12-rc2 |
331 332 333 334 335 |
status = AE_BAD_DATA; acpi_util_eval_error(handle, pathname, status); goto end; } if (!package->package.count) { |
1da177e4c Linux-2.6.12-rc2 |
336 337 338 339 340 341 |
status = AE_BAD_DATA; acpi_util_eval_error(handle, pathname, status); goto end; } if (package->package.count > ACPI_MAX_HANDLES) { |
09e150869 ACPI / utils: Fix... |
342 |
kfree(package); |
d550d98d3 ACPI: delete trac... |
343 |
return AE_NO_MEMORY; |
1da177e4c Linux-2.6.12-rc2 |
344 345 346 347 348 349 350 351 |
} list->count = package->package.count; /* Extract package data. */ for (i = 0; i < list->count; i++) { element = &(package->package.elements[i]); |
cd0b22482 ACPICA: Fixes for... |
352 |
if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { |
1da177e4c Linux-2.6.12-rc2 |
353 |
status = AE_BAD_DATA; |
1da177e4c Linux-2.6.12-rc2 |
354 355 356 |
acpi_util_eval_error(handle, pathname, status); break; } |
b6a163875 ACPICA: Warn if p... |
357 |
if (!element->reference.handle) { |
b6a163875 ACPICA: Warn if p... |
358 |
status = AE_NULL_ENTRY; |
c48cf1b9d ACPI / utils: Dro... |
359 |
acpi_util_eval_error(handle, pathname, status); |
b6a163875 ACPICA: Warn if p... |
360 361 |
break; } |
1da177e4c Linux-2.6.12-rc2 |
362 363 364 365 366 |
/* Get the acpi_handle. */ list->handles[i] = element->reference.handle; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p] ", |
4be44fcd3 [ACPI] Lindent al... |
367 |
list->handles[i])); |
1da177e4c Linux-2.6.12-rc2 |
368 |
} |
4be44fcd3 [ACPI] Lindent al... |
369 |
end: |
1da177e4c Linux-2.6.12-rc2 |
370 371 372 373 |
if (ACPI_FAILURE(status)) { list->count = 0; //kfree(list->handles); } |
02438d877 ACPI: delete acpi... |
374 |
kfree(buffer.pointer); |
1da177e4c Linux-2.6.12-rc2 |
375 |
|
d550d98d3 ACPI: delete trac... |
376 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
377 |
} |
1da177e4c Linux-2.6.12-rc2 |
378 |
|
4be44fcd3 [ACPI] Lindent al... |
379 |
EXPORT_SYMBOL(acpi_evaluate_reference); |
38ac0f1b9 ACPI: Add _PLD su... |
380 381 |
acpi_status |
8ede06aba ACPI: Use ACPICA ... |
382 |
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld) |
38ac0f1b9 ACPI: Add _PLD su... |
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
{ acpi_status status; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *output; status = acpi_evaluate_object(handle, "_PLD", NULL, &buffer); if (ACPI_FAILURE(status)) return status; output = buffer.pointer; if (!output || output->type != ACPI_TYPE_PACKAGE || !output->package.count || output->package.elements[0].type != ACPI_TYPE_BUFFER |
8ede06aba ACPI: Use ACPICA ... |
398 |
|| output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) { |
38ac0f1b9 ACPI: Add _PLD su... |
399 400 401 |
status = AE_TYPE; goto out; } |
8ede06aba ACPI: Use ACPICA ... |
402 403 404 405 |
status = acpi_decode_pld_buffer( output->package.elements[0].buffer.pointer, output->package.elements[0].buffer.length, pld); |
38ac0f1b9 ACPI: Add _PLD su... |
406 407 408 409 410 |
out: kfree(buffer.pointer); return status; } EXPORT_SYMBOL(acpi_get_physical_device_location); |
275c58d77 ACPI: Add an inte... |
411 412 |
/** |
700b8422f ACPI: Drop acpi_e... |
413 |
* acpi_evaluate_ost: Evaluate _OST for hotplug operations |
275c58d77 ACPI: Add an inte... |
414 415 416 417 418 419 420 421 422 423 |
* @handle: ACPI device handle * @source_event: source event code * @status_code: status code * @status_buf: optional detailed information (NULL if none) * * Evaluate _OST for hotplug operations. All ACPI hotplug handlers * must call this function when evaluating _OST for hotplug operations. * When the platform does not support _OST, this function has no effect. */ acpi_status |
05730c195 ACPI: rename acpi... |
424 425 |
acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, struct acpi_buffer *status_buf) |
275c58d77 ACPI: Add an inte... |
426 |
{ |
275c58d77 ACPI: Add an inte... |
427 428 429 430 431 432 |
union acpi_object params[3] = { {.type = ACPI_TYPE_INTEGER,}, {.type = ACPI_TYPE_INTEGER,}, {.type = ACPI_TYPE_BUFFER,} }; struct acpi_object_list arg_list = {3, params}; |
275c58d77 ACPI: Add an inte... |
433 434 435 436 437 438 439 440 441 442 |
params[0].integer.value = source_event; params[1].integer.value = status_code; if (status_buf != NULL) { params[2].buffer.pointer = status_buf->pointer; params[2].buffer.length = status_buf->length; } else { params[2].buffer.pointer = NULL; params[2].buffer.length = 0; } |
05730c195 ACPI: rename acpi... |
443 |
return acpi_evaluate_object(handle, "_OST", &arg_list, NULL); |
275c58d77 ACPI: Add an inte... |
444 |
} |
05730c195 ACPI: rename acpi... |
445 |
EXPORT_SYMBOL(acpi_evaluate_ost); |
fbfddae69 ACPI: Add acpi_ha... |
446 447 |
/** |
45fef5b88 ACPI: add dynamic... |
448 |
* acpi_handle_path: Return the object path of handle |
8373f8c6a ACPI / utils: Des... |
449 |
* @handle: ACPI device handle |
45fef5b88 ACPI: add dynamic... |
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
* * Caller must free the returned buffer */ static char *acpi_handle_path(acpi_handle handle) { struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, .pointer = NULL }; if (in_interrupt() || acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) return NULL; return buffer.pointer; } /** |
fbfddae69 ACPI: Add acpi_ha... |
467 |
* acpi_handle_printk: Print message with ACPI prefix and object path |
8373f8c6a ACPI / utils: Des... |
468 469 470 |
* @level: log level * @handle: ACPI device handle * @fmt: format string |
fbfddae69 ACPI: Add acpi_ha... |
471 472 473 474 475 476 477 478 479 480 481 |
* * This function is called through acpi_handle_<level> macros and prints * a message with ACPI prefix and object path. This function acquires * the global namespace mutex to obtain an object path. In interrupt * context, it shows the object path as <n/a>. */ void acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) { struct va_format vaf; va_list args; |
fbfddae69 ACPI: Add acpi_ha... |
482 483 484 485 486 |
const char *path; va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; |
45fef5b88 ACPI: add dynamic... |
487 488 |
path = acpi_handle_path(handle); printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf); |
fbfddae69 ACPI: Add acpi_ha... |
489 490 |
va_end(args); |
45fef5b88 ACPI: add dynamic... |
491 |
kfree(path); |
fbfddae69 ACPI: Add acpi_ha... |
492 493 |
} EXPORT_SYMBOL(acpi_handle_printk); |
952c63e95 ACPI: introduce h... |
494 |
|
45fef5b88 ACPI: add dynamic... |
495 496 497 |
#if defined(CONFIG_DYNAMIC_DEBUG) /** * __acpi_handle_debug: pr_debug with ACPI prefix and object path |
8373f8c6a ACPI / utils: Des... |
498 499 500 |
* @descriptor: Dynamic Debug descriptor * @handle: ACPI device handle * @fmt: format string |
45fef5b88 ACPI: add dynamic... |
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
* * This function is called through acpi_handle_debug macro and debug * prints a message with ACPI prefix and object path. This function * acquires the global namespace mutex to obtain an object path. In * interrupt context, it shows the object path as <n/a>. */ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...) { struct va_format vaf; va_list args; const char *path; va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; path = acpi_handle_path(handle); __dynamic_pr_debug(descriptor, "ACPI: %s: %pV", path ? path : "<n/a>", &vaf); va_end(args); kfree(path); } EXPORT_SYMBOL(__acpi_handle_debug); #endif |
952c63e95 ACPI: introduce h... |
527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
/** * acpi_has_method: Check whether @handle has a method named @name * @handle: ACPI device handle * @name: name of object or method * * Check whether @handle has a method named @name. */ bool acpi_has_method(acpi_handle handle, char *name) { acpi_handle tmp; return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp)); } EXPORT_SYMBOL(acpi_has_method); |
0db982026 ACPI: introduce h... |
541 542 543 544 545 546 547 548 549 550 551 552 |
acpi_status acpi_execute_simple_method(acpi_handle handle, char *method, u64 arg) { union acpi_object obj = { .type = ACPI_TYPE_INTEGER }; struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, }; obj.integer.value = arg; return acpi_evaluate_object(handle, method, &arg_list, NULL); } EXPORT_SYMBOL(acpi_execute_simple_method); |
7d2421f84 ACPI: introduce t... |
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 |
/** * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations * @handle: ACPI device handle * * Evaluate device's _EJ0 method for hotplug operations. */ acpi_status acpi_evaluate_ej0(acpi_handle handle) { acpi_status status; status = acpi_execute_simple_method(handle, "_EJ0", 1); if (status == AE_NOT_FOUND) acpi_handle_warn(handle, "No _EJ0 support for device "); else if (ACPI_FAILURE(status)) acpi_handle_warn(handle, "Eject failed (0x%x) ", status); return status; } /** * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device * @handle: ACPI device handle * @lock: lock device if non-zero, otherwise unlock device * * Evaluate device's _LCK method if present to lock/unlock device */ acpi_status acpi_evaluate_lck(acpi_handle handle, int lock) { acpi_status status; status = acpi_execute_simple_method(handle, "_LCK", !!lock); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (lock) acpi_handle_warn(handle, "Locking device failed (0x%x) ", status); else acpi_handle_warn(handle, "Unlocking device failed (0x%x) ", status); } return status; } |
a65ac5204 ACPI: introduce h... |
600 601 |
/** |
132565d8e ACPI: utils: Add ... |
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
* acpi_evaluate_reg: Evaluate _REG method to register OpRegion presence * @handle: ACPI device handle * @space_id: ACPI address space id to register OpRegion presence for * @function: Parameter to pass to _REG one of ACPI_REG_CONNECT or * ACPI_REG_DISCONNECT * * Evaluate device's _REG method to register OpRegion presence. */ acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function) { struct acpi_object_list arg_list; union acpi_object params[2]; params[0].type = ACPI_TYPE_INTEGER; params[0].integer.value = space_id; params[1].type = ACPI_TYPE_INTEGER; params[1].integer.value = function; arg_list.count = 2; arg_list.pointer = params; return acpi_evaluate_object(handle, "_REG", &arg_list, NULL); } EXPORT_SYMBOL(acpi_evaluate_reg); /** |
a65ac5204 ACPI: introduce h... |
627 628 |
* acpi_evaluate_dsm - evaluate device's _DSM method * @handle: ACPI device handle |
94116f812 ACPI: Switch to u... |
629 |
* @guid: GUID of requested functions, should be 16 bytes |
a65ac5204 ACPI: introduce h... |
630 631 632 633 |
* @rev: revision number of requested function * @func: requested function number * @argv4: the function specific parameter * |
94116f812 ACPI: Switch to u... |
634 |
* Evaluate device's _DSM method with specified GUID, revision id and |
a65ac5204 ACPI: introduce h... |
635 636 637 638 639 640 |
* function number. Caller needs to free the returned object. * * Though ACPI defines the fourth parameter for _DSM should be a package, * some old BIOSes do expect a buffer or an integer etc. */ union acpi_object * |
94116f812 ACPI: Switch to u... |
641 |
acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 func, |
a65ac5204 ACPI: introduce h... |
642 643 644 645 646 647 648 649 650 651 652 653 |
union acpi_object *argv4) { acpi_status ret; struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; union acpi_object params[4]; struct acpi_object_list input = { .count = 4, .pointer = params, }; params[0].type = ACPI_TYPE_BUFFER; params[0].buffer.length = 16; |
94116f812 ACPI: Switch to u... |
654 |
params[0].buffer.pointer = (u8 *)guid; |
a65ac5204 ACPI: introduce h... |
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 |
params[1].type = ACPI_TYPE_INTEGER; params[1].integer.value = rev; params[2].type = ACPI_TYPE_INTEGER; params[2].integer.value = func; if (argv4) { params[3] = *argv4; } else { params[3].type = ACPI_TYPE_PACKAGE; params[3].package.count = 0; params[3].package.elements = NULL; } ret = acpi_evaluate_object(handle, "_DSM", &input, &buf); if (ACPI_SUCCESS(ret)) return (union acpi_object *)buf.pointer; if (ret != AE_NOT_FOUND) acpi_handle_warn(handle, "failed to evaluate _DSM (0x%x) ", ret); return NULL; } EXPORT_SYMBOL(acpi_evaluate_dsm); /** * acpi_check_dsm - check if _DSM method supports requested functions. * @handle: ACPI device handle |
94116f812 ACPI: Switch to u... |
683 |
* @guid: GUID of requested functions, should be 16 bytes at least |
a65ac5204 ACPI: introduce h... |
684 685 |
* @rev: revision number of requested functions * @funcs: bitmap of requested functions |
a65ac5204 ACPI: introduce h... |
686 687 688 689 690 |
* * Evaluate device's _DSM method to check whether it supports requested * functions. Currently only support 64 functions at maximum, should be * enough for now. */ |
94116f812 ACPI: Switch to u... |
691 |
bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs) |
a65ac5204 ACPI: introduce h... |
692 693 694 695 |
{ int i; u64 mask = 0; union acpi_object *obj; |
a72255983 nfit: make DIMM D... |
696 697 |
if (funcs == 0) return false; |
94116f812 ACPI: Switch to u... |
698 |
obj = acpi_evaluate_dsm(handle, guid, rev, 0, NULL); |
a65ac5204 ACPI: introduce h... |
699 700 701 702 703 704 705 706 |
if (!obj) return false; /* For compatibility, old BIOSes may return an integer */ if (obj->type == ACPI_TYPE_INTEGER) mask = obj->integer.value; else if (obj->type == ACPI_TYPE_BUFFER) for (i = 0; i < obj->buffer.length && i < 8; i++) |
4a798f508 ACPI / util: cast... |
707 |
mask |= (((u64)obj->buffer.pointer[i]) << (i * 8)); |
a65ac5204 ACPI: introduce h... |
708 709 710 711 |
ACPI_FREE(obj); /* * Bit 0 indicates whether there's support for any functions other than |
94116f812 ACPI: Switch to u... |
712 |
* function 0 for the specified GUID and revision. |
a65ac5204 ACPI: introduce h... |
713 714 715 716 717 718 719 |
*/ if ((mask & 0x1) && (mask & funcs) == funcs) return true; return false; } EXPORT_SYMBOL(acpi_check_dsm); |
14ca7a47d acpi-video-detect... |
720 |
|
2d12b6b38 ACPI / utils: Add... |
721 |
/** |
35009c807 ACPI / utils: Int... |
722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 |
* acpi_dev_hid_uid_match - Match device by supplied HID and UID * @adev: ACPI device to match. * @hid2: Hardware ID of the device. * @uid2: Unique ID of the device, pass NULL to not check _UID. * * Matches HID and UID in @adev with given @hid2 and @uid2. * Returns true if matches. */ bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2) { const char *hid1 = acpi_device_hid(adev); const char *uid1 = acpi_device_uid(adev); if (strcmp(hid1, hid2)) return false; if (!uid2) return true; return uid1 && !strcmp(uid1, uid2); } EXPORT_SYMBOL(acpi_dev_hid_uid_match); /** |
c68ae33e7 ACPI / utils: Ren... |
747 |
* acpi_dev_found - Detect presence of a given ACPI device in the namespace. |
2d12b6b38 ACPI / utils: Add... |
748 749 750 751 752 753 754 755 756 757 758 |
* @hid: Hardware ID of the device. * * Return %true if the device was present at the moment of invocation. * Note that if the device is pluggable, it may since have disappeared. * * For this function to work, acpi_bus_scan() must have been executed * which happens in the subsys_initcall() subsection. Hence, do not * call from a subsys_initcall() or earlier (use acpi_get_devices() * instead). Calling from module_init() is fine (which is synonymous * with device_initcall()). */ |
c68ae33e7 ACPI / utils: Ren... |
759 |
bool acpi_dev_found(const char *hid) |
2d12b6b38 ACPI / utils: Add... |
760 761 762 763 764 765 766 767 768 769 770 771 772 773 |
{ struct acpi_device_bus_id *acpi_device_bus_id; bool found = false; mutex_lock(&acpi_device_lock); list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) if (!strcmp(acpi_device_bus_id->bus_id, hid)) { found = true; break; } mutex_unlock(&acpi_device_lock); return found; } |
c68ae33e7 ACPI / utils: Ren... |
774 |
EXPORT_SYMBOL(acpi_dev_found); |
2d12b6b38 ACPI / utils: Add... |
775 |
|
67dcf8a3e ACPI: utils: Intr... |
776 |
struct acpi_dev_match_info { |
8661423ee ACPI / utils: Add... |
777 778 779 780 |
struct acpi_device_id hid[2]; const char *uid; s64 hrv; }; |
418e3ea15 bus_find_device: ... |
781 |
static int acpi_dev_match_cb(struct device *dev, const void *data) |
8661423ee ACPI / utils: Add... |
782 783 |
{ struct acpi_device *adev = to_acpi_device(dev); |
418e3ea15 bus_find_device: ... |
784 |
const struct acpi_dev_match_info *match = data; |
8661423ee ACPI / utils: Add... |
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
unsigned long long hrv; acpi_status status; if (acpi_match_device_ids(adev, match->hid)) return 0; if (match->uid && (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, match->uid))) return 0; if (match->hrv == -1) return 1; status = acpi_evaluate_integer(adev->handle, "_HRV", NULL, &hrv); if (ACPI_FAILURE(status)) return 0; return hrv == match->hrv; } /** * acpi_dev_present - Detect that a given ACPI device is present * @hid: Hardware ID of the device. * @uid: Unique ID of the device, pass NULL to not check _UID * @hrv: Hardware Revision of the device, pass -1 to not check _HRV * * Return %true if a matching device was present at the moment of invocation. * Note that if the device is pluggable, it may since have disappeared. * * Note that unlike acpi_dev_found() this function checks the status * of the device. So for devices which are present in the dsdt, but * which are disabled (their _STA callback returns 0) this function * will return false. * * For this function to work, acpi_bus_scan() must have been executed * which happens in the subsys_initcall() subsection. Hence, do not * call from a subsys_initcall() or earlier (use acpi_get_devices() * instead). Calling from module_init() is fine (which is synonymous * with device_initcall()). */ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) { |
67dcf8a3e ACPI: utils: Intr... |
827 |
struct acpi_dev_match_info match = {}; |
8661423ee ACPI / utils: Add... |
828 829 830 831 832 |
struct device *dev; strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); match.uid = uid; match.hrv = hrv; |
67dcf8a3e ACPI: utils: Intr... |
833 |
dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); |
54e3aca84 ACPI / utils: Dro... |
834 |
put_device(dev); |
8661423ee ACPI / utils: Add... |
835 836 837 |
return !!dev; } EXPORT_SYMBOL(acpi_dev_present); |
67dcf8a3e ACPI: utils: Intr... |
838 |
/** |
817b4d64d ACPI / utils: Int... |
839 |
* acpi_dev_get_first_match_dev - Return the first match of ACPI device |
67dcf8a3e ACPI: utils: Intr... |
840 841 842 843 |
* @hid: Hardware ID of the device. * @uid: Unique ID of the device, pass NULL to not check _UID * @hrv: Hardware Revision of the device, pass -1 to not check _HRV * |
817b4d64d ACPI / utils: Int... |
844 |
* Return the first match of ACPI device if a matching device was present |
67dcf8a3e ACPI: utils: Intr... |
845 846 |
* at the moment of invocation, or NULL otherwise. * |
817b4d64d ACPI / utils: Int... |
847 848 |
* The caller is responsible to call put_device() on the returned device. * |
67dcf8a3e ACPI: utils: Intr... |
849 850 |
* See additional information in acpi_dev_present() as well. */ |
817b4d64d ACPI / utils: Int... |
851 852 853 854 855 856 857 858 859 860 861 |
struct acpi_device * acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) { struct acpi_dev_match_info match = {}; struct device *dev; strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); match.uid = uid; match.hrv = hrv; dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); |
e6374f6b2 acpi: utils: Clea... |
862 |
return dev ? to_acpi_device(dev) : NULL; |
817b4d64d ACPI / utils: Int... |
863 864 |
} EXPORT_SYMBOL(acpi_dev_get_first_match_dev); |
14ca7a47d acpi-video-detect... |
865 866 867 868 869 870 871 872 873 874 875 876 877 878 |
/* * acpi_backlight= handling, this is done here rather then in video_detect.c * because __setup cannot be used in modules. */ char acpi_video_backlight_string[16]; EXPORT_SYMBOL(acpi_video_backlight_string); static int __init acpi_backlight(char *str) { strlcpy(acpi_video_backlight_string, str, sizeof(acpi_video_backlight_string)); return 1; } __setup("acpi_backlight=", acpi_backlight); |
5aa5911a0 ACPI / blacklist:... |
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 |
/** * acpi_match_platform_list - Check if the system matches with a given list * @plat: pointer to acpi_platform_list table terminated by a NULL entry * * Return the matched index if the system is found in the platform list. * Otherwise, return a negative error code. */ int acpi_match_platform_list(const struct acpi_platform_list *plat) { struct acpi_table_header hdr; int idx = 0; if (acpi_disabled) return -ENODEV; for (; plat->oem_id[0]; plat++, idx++) { if (ACPI_FAILURE(acpi_get_table_header(plat->table, 0, &hdr))) continue; if (strncmp(plat->oem_id, hdr.oem_id, ACPI_OEM_ID_SIZE)) continue; if (strncmp(plat->oem_table_id, hdr.oem_table_id, ACPI_OEM_TABLE_ID_SIZE)) continue; if ((plat->pred == all_versions) || (plat->pred == less_than_or_equal && hdr.oem_revision <= plat->oem_revision) || (plat->pred == greater_than_or_equal && hdr.oem_revision >= plat->oem_revision) || (plat->pred == equal && hdr.oem_revision == plat->oem_revision)) return idx; } return -ENODEV; } EXPORT_SYMBOL(acpi_match_platform_list); |