Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'support-package'

  • Loading branch information...
commit 8049cb975d9fd17735f69440b03308fc94f3cf55 2 parents 9ceb252 + b3f863c
@Lekensteyn Lekensteyn authored
Showing with 63 additions and 23 deletions.
  1. +2 −0  README
  2. +61 −23 acpi_call.c
View
2  README
@@ -22,6 +22,8 @@ The status after a call can be read back from /proc/acpi/call:
* '0xNN' - the call succeeded, and returned an integer
* '"..."' - the call succeeded, and returned a string
* '{0xNN, ...}' - the call succeeded, and returned a buffer
+* '[...]' - the call succeeded, and returned a package which may contain the
+ above types (integer, string and buffer) and other package types
Copyright (c) 2010: Michal Kottman
View
84 acpi_call.c
@@ -17,6 +17,64 @@ static char result_buffer[BUFFER_SIZE];
static u8 temporary_buffer[BUFFER_SIZE];
+static size_t get_avail_bytes(void) {
+ return BUFFER_SIZE - strlen(result_buffer);
+}
+static char *get_buffer_end(void) {
+ return result_buffer + strlen(result_buffer);
+}
+/** Appends the contents of an acpi_object to the result buffer
+@param result An acpi object holding result data
+@returns 0 if the result could fully be saved, a higher value otherwise
+*/
+static int acpi_result_to_string(union acpi_object *result) {
+ if (result->type == ACPI_TYPE_INTEGER) {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "0x%x", (int)result->integer.value);
+ } else if (result->type == ACPI_TYPE_STRING) {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "\"%*s\"", result->string.length, result->string.pointer);
+ } else if (result->type == ACPI_TYPE_BUFFER) {
+ int i;
+ // do not store more than data if it does not fit. The first element is
+ // just 4 chars, but there is also two bytes from the curly brackets
+ int show_values = min(result->buffer.length, get_avail_bytes() / 6);
+
+ sprintf(get_buffer_end(), "{");
+ for (i = 0; i < show_values; i++)
+ sprintf(get_buffer_end(),
+ i == 0 ? "0x%02x" : ", 0x%02x", result->buffer.pointer[i]);
+
+ if (result->buffer.length > show_values) {
+ // if data was truncated, show a trailing comma if there is space
+ snprintf(get_buffer_end(), get_avail_bytes(), ",");
+ return 1;
+ } else {
+ // in case show_values == 0, but the buffer is too small to hold
+ // more values (i.e. the buffer cannot have anything more than "{")
+ snprintf(get_buffer_end(), get_avail_bytes(), "}");
+ }
+ } else if (result->type == ACPI_TYPE_PACKAGE) {
+ int i;
+ sprintf(get_buffer_end(), "[");
+ for (i=0; i<result->package.count; i++) {
+ if (i > 0)
+ snprintf(get_buffer_end(), get_avail_bytes(), ", ");
+
+ // abort if there is no more space available
+ if (!get_avail_bytes() || acpi_result_to_string(&result->package.elements[i]))
+ return 1;
+ }
+ snprintf(get_buffer_end(), get_avail_bytes(), "]");
+ } else {
+ snprintf(get_buffer_end(), get_avail_bytes(),
+ "Object type 0x%x\n", result->type);
+ }
+
+ // return 0 if there are still bytes available, 1 otherwise
+ return !get_avail_bytes();
+}
+
/**
@param method The full name of ACPI method to call
@param argc The number of parameters
@@ -28,7 +86,6 @@ static void do_acpi_call(const char * method, int argc, union acpi_object *argv)
acpi_handle handle;
struct acpi_object_list arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *result;
printk(KERN_INFO "acpi_call: Calling %s\n", method);
@@ -54,29 +111,10 @@ static void do_acpi_call(const char * method, int argc, union acpi_object *argv)
printk(KERN_ERR "acpi_call: Method call failed: %s\n", result_buffer);
return;
}
- result = buffer.pointer;
- if (result->type == ACPI_TYPE_INTEGER) {
- sprintf(result_buffer, "0x%x", (int)result->integer.value);
- } else if (result->type == ACPI_TYPE_STRING) {
- snprintf(result_buffer, BUFFER_SIZE, "\"%*s\"", result->string.length, result->string.pointer);
- } else if (result->type == ACPI_TYPE_BUFFER) {
- int i;
- int show_values = result->buffer.length;
- // do not store more than data if it does not fit. The first element is
- // just 4 chars, but there is also two bytes from the curly brackets
- if (show_values > BUFFER_SIZE / 6)
- show_values = BUFFER_SIZE / 6;
- sprintf(result_buffer, "{");
- for (i = 0; i < show_values; i++)
- sprintf(result_buffer + strlen(result_buffer),
- i == 0 ? "0x%02x" : ", 0x%02x", result->buffer.pointer[i]);
- // if data was truncated, show a trailing comma
- strcpy(result_buffer + strlen(result_buffer),
- result->buffer.length > BUFFER_SIZE / 6 ? "," : "}");
- } else {
- sprintf(result_buffer, "Object type 0x%x\n", result->type);
- }
+ // reset the result buffer
+ *result_buffer = '\0';
+ acpi_result_to_string(buffer.pointer);
kfree(buffer.pointer);
printk(KERN_INFO "acpi_call: Call successful: %s\n", result_buffer);
Please sign in to comment.
Something went wrong with that request. Please try again.