diff mbox

[V2] acpi: method: refine _EVT test

Message ID 1438592416-21945-1-git-send-email-alex.hung@canonical.com
State Accepted
Headers show

Commit Message

Alex Hung Aug. 3, 2015, 9 a.m. UTC
According to ACPI spec, _EVT's events should be in adjacent _AEI
control method.  This patch also reduces lengthy testing time.

This was modified from a patch from Fan Wu <wufan@codeaurora.org>
Most changes are styles, comments and some small code refactoring.

Signed-off-by: Alex Hung <alex.hung@canonical.com>
---
 src/acpi/method/method.c | 127 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 102 insertions(+), 25 deletions(-)

Comments

Colin Ian King Aug. 3, 2015, 11:04 a.m. UTC | #1
On 03/08/15 10:00, Alex Hung wrote:
> According to ACPI spec, _EVT's events should be in adjacent _AEI
> control method.  This patch also reduces lengthy testing time.
> 
> This was modified from a patch from Fan Wu <wufan@codeaurora.org>
> Most changes are styles, comments and some small code refactoring.
> 
> Signed-off-by: Alex Hung <alex.hung@canonical.com>
> ---
>  src/acpi/method/method.c | 127 +++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 102 insertions(+), 25 deletions(-)
> 
> diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c
> index 638e937..34463d5 100644
> --- a/src/acpi/method/method.c
> +++ b/src/acpi/method/method.c
> @@ -27,6 +27,7 @@
>  #include <inttypes.h>
>  #include "fwts_acpi_object_eval.h"
>  
> +
>  /*
>   * ACPI methods + objects used in Linux ACPI driver:
>   *
> @@ -260,6 +261,7 @@
>  #define	METHOD_MANDITORY	1
>  #define METHOD_OPTIONAL		2
>  #define METHOD_MOBILE		4
> +#define METHOD_SILENT		8
>  
>  #define ACPI_TYPE_INTBUF	(ACPI_TYPE_INVALID + 1)
>  
> @@ -530,25 +532,27 @@ static int method_evaluate_method(fwts_framework *fw,
>  		}
>  		return FWTS_OK;
>  	} else {
> -		/* Manditory not-found test are a failure */
> -		if (test_type & METHOD_MANDITORY) {
> -			fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodNotExist",
> -				"Object %s did not exist.", name);
> -		}
> +		if (!(test_type & METHOD_SILENT)) {
> +			/* Manditory not-found test are a failure */
> +			if (test_type & METHOD_MANDITORY) {
> +				fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodNotExist",
> +					"Object %s did not exist.", name);
> +			}
>  
> -		/* Mobile specific tests on non-mobile platform? */
> -		if ((test_type & METHOD_MOBILE) && (!fadt_mobile_platform)) {
> -			fwts_skipped(fw,
> -				"Machine is not a mobile platform, skipping "
> -				"test for non-existant mobile platform "
> -				"related object %s.", name);
> -		} else {
> -			fwts_skipped(fw,
> -				"Skipping test for non-existant object %s.",
> -				name);
> +			/* Mobile specific tests on non-mobile platform? */
> +			if ((test_type & METHOD_MOBILE) && (!fadt_mobile_platform)) {
> +				fwts_skipped(fw,
> +					"Machine is not a mobile platform, skipping "
> +					"test for non-existant mobile platform "
> +					"related object %s.", name);
> +			} else {
> +				fwts_skipped(fw,
> +					"Skipping test for non-existant object %s.",
> +					name);
> +			}
>  		}
> -
>  		return FWTS_NOT_EXIST;
> +
>  	}
>  }
>  
> @@ -958,20 +962,93 @@ static int method_test_AEI(fwts_framework *fw)
>  		"_AEI", NULL, 0, method_test_AEI_return, NULL);
>  }
>  
> -static int method_test_EVT(fwts_framework *fw)
> +static void check_evt_event (
> +	fwts_framework *fw,
> +	ACPI_RESOURCE_GPIO *gpio)
>  {
>  	ACPI_OBJECT arg[1];
> -	int ret, i;
> -
> -	arg[0].Type = ACPI_TYPE_INTEGER;
> -	for (i = 0; i < 65535; i++) {
> -		arg[0].Integer.Value = i;
> -		ret = method_evaluate_method(fw, METHOD_OPTIONAL,
> -			"_EVT", arg, 1, method_test_NULL_return, NULL);
> +	ACPI_HANDLE evt_handle;
> +	ACPI_STATUS status;
> +	char path[256];
> +	uint16_t i;
>  
> -		if (ret != FWTS_OK)
> +	/* Skip the leading spaces in ResourceSource. */
> +	for (i = 0; i < gpio->ResourceSource.StringLength; i++) {
> +		if (gpio->ResourceSource.StringPtr[i] != ' ')
>  			break;
>  	}
> +
> +	if (i == gpio->ResourceSource.StringLength) {
> +		fwts_log_warning(fw, "Invalid ResourceSource");
> +		return;
> +	}
> +
> +	/* Get the handle of return;the _EVT method. */
> +	snprintf (path, 251, "%s._EVT", &gpio->ResourceSource.StringPtr[i]);
> +
> +	status = AcpiGetHandle (NULL, path, &evt_handle);
> +	if (ACPI_FAILURE(status)) {
> +		fwts_log_warning(fw, "Failed to find valid handle for _EVT method (0x%x), %s",	status, path);
> +		return;
> +	}
> +
> +	/* Call the _EVT method with all the pins defined for the GpioInt */
> +	for (i = 0; i < gpio->PinTableLength; i++) {
> +		ACPI_OBJECT_LIST arg_list;
> +
> +		arg[0].Type = ACPI_TYPE_INTEGER;
> +		arg[0].Integer.Value = gpio->PinTable[i];
> +		arg_list.Count = 1;
> +		arg_list.Pointer = arg;
> +
> +		method_evaluate_found_method(fw, path, method_test_NULL_return, NULL, &arg_list);
> +	}
> +}
> +
> +static void method_test_EVT_return (
> +	fwts_framework *fw,
> +	char *name,
> +	ACPI_BUFFER *buf,
> +	ACPI_OBJECT *obj,
> +	void *private)
> +{
> +	ACPI_RESOURCE *resource;
> +	ACPI_STATUS   status;
> +
> +	FWTS_UNUSED(private);
> +
> +	if (method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
> +		return;
> +
> +	status = AcpiBufferToResource(obj->Buffer.Pointer, obj->Buffer.Length, &resource);
> +	if (ACPI_FAILURE(status))
> +		return;
> +
> +	do {
> +		if (!resource->Length) {
> +			fwts_log_warning(fw, "Invalid zero length descriptor in resource list\n");
> +			break;
> +		}
> +
> +		if (resource->Type == ACPI_RESOURCE_TYPE_GPIO &&
> +				resource->Data.Gpio.ConnectionType == ACPI_RESOURCE_GPIO_TYPE_INT)
> +				check_evt_event(fw, &resource->Data.Gpio);
> +
> +		resource = ACPI_NEXT_RESOURCE(resource);
> +	} while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG);
> +}
> +
> +static int method_test_EVT(fwts_framework *fw)
> +{
> +	int ret;
> +
> +	/* Only test the _EVT method with pins defined in AEI. */
> +	ret = method_evaluate_method(fw, METHOD_OPTIONAL | METHOD_SILENT,
> +		"_AEI", NULL, 0, method_test_EVT_return, NULL);
> +
> +	if (ret == FWTS_NOT_EXIST)
> +		fwts_skipped(fw, "Skipping test for non-existant object _EVT.");
> +
>  	return ret;
>  }
>  
> 
Acked-by: Colin Ian King <colin.king@canonical.com>
Ivan Hu Aug. 4, 2015, 6:40 a.m. UTC | #2
On 2015年08月03日 17:00, Alex Hung wrote:
> According to ACPI spec, _EVT's events should be in adjacent _AEI
> control method.  This patch also reduces lengthy testing time.
>
> This was modified from a patch from Fan Wu <wufan@codeaurora.org>
> Most changes are styles, comments and some small code refactoring.
>
> Signed-off-by: Alex Hung <alex.hung@canonical.com>
> ---
>   src/acpi/method/method.c | 127 +++++++++++++++++++++++++++++++++++++----------
>   1 file changed, 102 insertions(+), 25 deletions(-)
>
> diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c
> index 638e937..34463d5 100644
> --- a/src/acpi/method/method.c
> +++ b/src/acpi/method/method.c
> @@ -27,6 +27,7 @@
>   #include <inttypes.h>
>   #include "fwts_acpi_object_eval.h"
>   
> +
>   /*
>    * ACPI methods + objects used in Linux ACPI driver:
>    *
> @@ -260,6 +261,7 @@
>   #define	METHOD_MANDITORY	1
>   #define METHOD_OPTIONAL		2
>   #define METHOD_MOBILE		4
> +#define METHOD_SILENT		8
>   
>   #define ACPI_TYPE_INTBUF	(ACPI_TYPE_INVALID + 1)
>   
> @@ -530,25 +532,27 @@ static int method_evaluate_method(fwts_framework *fw,
>   		}
>   		return FWTS_OK;
>   	} else {
> -		/* Manditory not-found test are a failure */
> -		if (test_type & METHOD_MANDITORY) {
> -			fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodNotExist",
> -				"Object %s did not exist.", name);
> -		}
> +		if (!(test_type & METHOD_SILENT)) {
> +			/* Manditory not-found test are a failure */
> +			if (test_type & METHOD_MANDITORY) {
> +				fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodNotExist",
> +					"Object %s did not exist.", name);
> +			}
>   
> -		/* Mobile specific tests on non-mobile platform? */
> -		if ((test_type & METHOD_MOBILE) && (!fadt_mobile_platform)) {
> -			fwts_skipped(fw,
> -				"Machine is not a mobile platform, skipping "
> -				"test for non-existant mobile platform "
> -				"related object %s.", name);
> -		} else {
> -			fwts_skipped(fw,
> -				"Skipping test for non-existant object %s.",
> -				name);
> +			/* Mobile specific tests on non-mobile platform? */
> +			if ((test_type & METHOD_MOBILE) && (!fadt_mobile_platform)) {
> +				fwts_skipped(fw,
> +					"Machine is not a mobile platform, skipping "
> +					"test for non-existant mobile platform "
> +					"related object %s.", name);
> +			} else {
> +				fwts_skipped(fw,
> +					"Skipping test for non-existant object %s.",
> +					name);
> +			}
>   		}
> -
>   		return FWTS_NOT_EXIST;
> +
>   	}
>   }
>   
> @@ -958,20 +962,93 @@ static int method_test_AEI(fwts_framework *fw)
>   		"_AEI", NULL, 0, method_test_AEI_return, NULL);
>   }
>   
> -static int method_test_EVT(fwts_framework *fw)
> +static void check_evt_event (
> +	fwts_framework *fw,
> +	ACPI_RESOURCE_GPIO *gpio)
>   {
>   	ACPI_OBJECT arg[1];
> -	int ret, i;
> -
> -	arg[0].Type = ACPI_TYPE_INTEGER;
> -	for (i = 0; i < 65535; i++) {
> -		arg[0].Integer.Value = i;
> -		ret = method_evaluate_method(fw, METHOD_OPTIONAL,
> -			"_EVT", arg, 1, method_test_NULL_return, NULL);
> +	ACPI_HANDLE evt_handle;
> +	ACPI_STATUS status;
> +	char path[256];
> +	uint16_t i;
>   
> -		if (ret != FWTS_OK)
> +	/* Skip the leading spaces in ResourceSource. */
> +	for (i = 0; i < gpio->ResourceSource.StringLength; i++) {
> +		if (gpio->ResourceSource.StringPtr[i] != ' ')
>   			break;
>   	}
> +
> +	if (i == gpio->ResourceSource.StringLength) {
> +		fwts_log_warning(fw, "Invalid ResourceSource");
> +		return;
> +	}
> +
> +	/* Get the handle of return;the _EVT method. */
> +	snprintf (path, 251, "%s._EVT", &gpio->ResourceSource.StringPtr[i]);
> +
> +	status = AcpiGetHandle (NULL, path, &evt_handle);
> +	if (ACPI_FAILURE(status)) {
> +		fwts_log_warning(fw, "Failed to find valid handle for _EVT method (0x%x), %s",	status, path);
> +		return;
> +	}
> +
> +	/* Call the _EVT method with all the pins defined for the GpioInt */
> +	for (i = 0; i < gpio->PinTableLength; i++) {
> +		ACPI_OBJECT_LIST arg_list;
> +
> +		arg[0].Type = ACPI_TYPE_INTEGER;
> +		arg[0].Integer.Value = gpio->PinTable[i];
> +		arg_list.Count = 1;
> +		arg_list.Pointer = arg;
> +
> +		method_evaluate_found_method(fw, path, method_test_NULL_return, NULL, &arg_list);
> +	}
> +}
> +
> +static void method_test_EVT_return (
> +	fwts_framework *fw,
> +	char *name,
> +	ACPI_BUFFER *buf,
> +	ACPI_OBJECT *obj,
> +	void *private)
> +{
> +	ACPI_RESOURCE *resource;
> +	ACPI_STATUS   status;
> +
> +	FWTS_UNUSED(private);
> +
> +	if (method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
> +		return;
> +
> +	status = AcpiBufferToResource(obj->Buffer.Pointer, obj->Buffer.Length, &resource);
> +	if (ACPI_FAILURE(status))
> +		return;
> +
> +	do {
> +		if (!resource->Length) {
> +			fwts_log_warning(fw, "Invalid zero length descriptor in resource list\n");
> +			break;
> +		}
> +
> +		if (resource->Type == ACPI_RESOURCE_TYPE_GPIO &&
> +				resource->Data.Gpio.ConnectionType == ACPI_RESOURCE_GPIO_TYPE_INT)
> +				check_evt_event(fw, &resource->Data.Gpio);
> +
> +		resource = ACPI_NEXT_RESOURCE(resource);
> +	} while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG);
> +}
> +
> +static int method_test_EVT(fwts_framework *fw)
> +{
> +	int ret;
> +
> +	/* Only test the _EVT method with pins defined in AEI. */
> +	ret = method_evaluate_method(fw, METHOD_OPTIONAL | METHOD_SILENT,
> +		"_AEI", NULL, 0, method_test_EVT_return, NULL);
> +
> +	if (ret == FWTS_NOT_EXIST)
> +		fwts_skipped(fw, "Skipping test for non-existant object _EVT.");
> +
>   	return ret;
>   }
>   
Acked-by: Ivan Hu<ivan.hu@canonical.com>
diff mbox

Patch

diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c
index 638e937..34463d5 100644
--- a/src/acpi/method/method.c
+++ b/src/acpi/method/method.c
@@ -27,6 +27,7 @@ 
 #include <inttypes.h>
 #include "fwts_acpi_object_eval.h"
 
+
 /*
  * ACPI methods + objects used in Linux ACPI driver:
  *
@@ -260,6 +261,7 @@ 
 #define	METHOD_MANDITORY	1
 #define METHOD_OPTIONAL		2
 #define METHOD_MOBILE		4
+#define METHOD_SILENT		8
 
 #define ACPI_TYPE_INTBUF	(ACPI_TYPE_INVALID + 1)
 
@@ -530,25 +532,27 @@  static int method_evaluate_method(fwts_framework *fw,
 		}
 		return FWTS_OK;
 	} else {
-		/* Manditory not-found test are a failure */
-		if (test_type & METHOD_MANDITORY) {
-			fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodNotExist",
-				"Object %s did not exist.", name);
-		}
+		if (!(test_type & METHOD_SILENT)) {
+			/* Manditory not-found test are a failure */
+			if (test_type & METHOD_MANDITORY) {
+				fwts_failed(fw, LOG_LEVEL_MEDIUM, "MethodNotExist",
+					"Object %s did not exist.", name);
+			}
 
-		/* Mobile specific tests on non-mobile platform? */
-		if ((test_type & METHOD_MOBILE) && (!fadt_mobile_platform)) {
-			fwts_skipped(fw,
-				"Machine is not a mobile platform, skipping "
-				"test for non-existant mobile platform "
-				"related object %s.", name);
-		} else {
-			fwts_skipped(fw,
-				"Skipping test for non-existant object %s.",
-				name);
+			/* Mobile specific tests on non-mobile platform? */
+			if ((test_type & METHOD_MOBILE) && (!fadt_mobile_platform)) {
+				fwts_skipped(fw,
+					"Machine is not a mobile platform, skipping "
+					"test for non-existant mobile platform "
+					"related object %s.", name);
+			} else {
+				fwts_skipped(fw,
+					"Skipping test for non-existant object %s.",
+					name);
+			}
 		}
-
 		return FWTS_NOT_EXIST;
+
 	}
 }
 
@@ -958,20 +962,93 @@  static int method_test_AEI(fwts_framework *fw)
 		"_AEI", NULL, 0, method_test_AEI_return, NULL);
 }
 
-static int method_test_EVT(fwts_framework *fw)
+static void check_evt_event (
+	fwts_framework *fw,
+	ACPI_RESOURCE_GPIO *gpio)
 {
 	ACPI_OBJECT arg[1];
-	int ret, i;
-
-	arg[0].Type = ACPI_TYPE_INTEGER;
-	for (i = 0; i < 65535; i++) {
-		arg[0].Integer.Value = i;
-		ret = method_evaluate_method(fw, METHOD_OPTIONAL,
-			"_EVT", arg, 1, method_test_NULL_return, NULL);
+	ACPI_HANDLE evt_handle;
+	ACPI_STATUS status;
+	char path[256];
+	uint16_t i;
 
-		if (ret != FWTS_OK)
+	/* Skip the leading spaces in ResourceSource. */
+	for (i = 0; i < gpio->ResourceSource.StringLength; i++) {
+		if (gpio->ResourceSource.StringPtr[i] != ' ')
 			break;
 	}
+
+	if (i == gpio->ResourceSource.StringLength) {
+		fwts_log_warning(fw, "Invalid ResourceSource");
+		return;
+	}
+
+	/* Get the handle of return;the _EVT method. */
+	snprintf (path, 251, "%s._EVT", &gpio->ResourceSource.StringPtr[i]);
+
+	status = AcpiGetHandle (NULL, path, &evt_handle);
+	if (ACPI_FAILURE(status)) {
+		fwts_log_warning(fw, "Failed to find valid handle for _EVT method (0x%x), %s",	status, path);
+		return;
+	}
+
+	/* Call the _EVT method with all the pins defined for the GpioInt */
+	for (i = 0; i < gpio->PinTableLength; i++) {
+		ACPI_OBJECT_LIST arg_list;
+
+		arg[0].Type = ACPI_TYPE_INTEGER;
+		arg[0].Integer.Value = gpio->PinTable[i];
+		arg_list.Count = 1;
+		arg_list.Pointer = arg;
+
+		method_evaluate_found_method(fw, path, method_test_NULL_return, NULL, &arg_list);
+	}
+}
+
+static void method_test_EVT_return (
+	fwts_framework *fw,
+	char *name,
+	ACPI_BUFFER *buf,
+	ACPI_OBJECT *obj,
+	void *private)
+{
+	ACPI_RESOURCE *resource;
+	ACPI_STATUS   status;
+
+	FWTS_UNUSED(private);
+
+	if (method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
+		return;
+
+	status = AcpiBufferToResource(obj->Buffer.Pointer, obj->Buffer.Length, &resource);
+	if (ACPI_FAILURE(status))
+		return;
+
+	do {
+		if (!resource->Length) {
+			fwts_log_warning(fw, "Invalid zero length descriptor in resource list\n");
+			break;
+		}
+
+		if (resource->Type == ACPI_RESOURCE_TYPE_GPIO &&
+				resource->Data.Gpio.ConnectionType == ACPI_RESOURCE_GPIO_TYPE_INT)
+				check_evt_event(fw, &resource->Data.Gpio);
+
+		resource = ACPI_NEXT_RESOURCE(resource);
+	} while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG);
+}
+
+static int method_test_EVT(fwts_framework *fw)
+{
+	int ret;
+
+	/* Only test the _EVT method with pins defined in AEI. */
+	ret = method_evaluate_method(fw, METHOD_OPTIONAL | METHOD_SILENT,
+		"_AEI", NULL, 0, method_test_EVT_return, NULL);
+
+	if (ret == FWTS_NOT_EXIST)
+		fwts_skipped(fw, "Skipping test for non-existant object _EVT.");
+
 	return ret;
 }