acpi_powerres.c (78993) | acpi_powerres.c (79357) |
---|---|
1/*- 2 * Copyright (c) 2001 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2001 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/dev/acpica/acpi_powerres.c 78993 2001-06-29 20:32:29Z msmith $ | 26 * $FreeBSD: head/sys/dev/acpica/acpi_powerres.c 79357 2001-07-06 09:00:07Z msmith $ |
27 */ 28 29#include "opt_acpi.h" /* XXX trim includes */ 30#include <sys/param.h> 31#include <sys/kernel.h> 32#include <sys/proc.h> 33#include <sys/lock.h> 34#include <sys/malloc.h> --- 37 unchanged lines hidden (view full) --- 72MALLOC_DEFINE(M_ACPIPWR, "acpipwr", "ACPI power resources"); 73 74/* 75 * Hooks for the ACPI CA debugging infrastructure 76 */ 77#define _COMPONENT ACPI_POWER 78MODULE_NAME("POWERRES") 79 | 27 */ 28 29#include "opt_acpi.h" /* XXX trim includes */ 30#include <sys/param.h> 31#include <sys/kernel.h> 32#include <sys/proc.h> 33#include <sys/lock.h> 34#include <sys/malloc.h> --- 37 unchanged lines hidden (view full) --- 72MALLOC_DEFINE(M_ACPIPWR, "acpipwr", "ACPI power resources"); 73 74/* 75 * Hooks for the ACPI CA debugging infrastructure 76 */ 77#define _COMPONENT ACPI_POWER 78MODULE_NAME("POWERRES") 79 |
80/* return values from _STA on a power resource */ 81#define ACPI_PWR_OFF 0 82#define ACPI_PWR_ON 1 83 |
|
80/* 81 * A relationship between a power resource and a consumer. 82 */ 83struct acpi_powerreference { 84 struct acpi_powerconsumer *ar_consumer; 85 struct acpi_powerresource *ar_resource; 86 TAILQ_ENTRY(acpi_powerreference) ar_rlink; /* link on resource list */ 87 TAILQ_ENTRY(acpi_powerreference) ar_clink; /* link on consumer */ --- 13 unchanged lines hidden (view full) --- 101 * A power resource. 102 */ 103struct acpi_powerresource { 104 TAILQ_ENTRY(acpi_powerresource) ap_link; 105 TAILQ_HEAD(,acpi_powerreference) ap_references; 106 ACPI_HANDLE ap_resource; /* the resource's handle */ 107 ACPI_INTEGER ap_systemlevel; 108 ACPI_INTEGER ap_order; | 84/* 85 * A relationship between a power resource and a consumer. 86 */ 87struct acpi_powerreference { 88 struct acpi_powerconsumer *ar_consumer; 89 struct acpi_powerresource *ar_resource; 90 TAILQ_ENTRY(acpi_powerreference) ar_rlink; /* link on resource list */ 91 TAILQ_ENTRY(acpi_powerreference) ar_clink; /* link on consumer */ --- 13 unchanged lines hidden (view full) --- 105 * A power resource. 106 */ 107struct acpi_powerresource { 108 TAILQ_ENTRY(acpi_powerresource) ap_link; 109 TAILQ_HEAD(,acpi_powerreference) ap_references; 110 ACPI_HANDLE ap_resource; /* the resource's handle */ 111 ACPI_INTEGER ap_systemlevel; 112 ACPI_INTEGER ap_order; |
109 int ap_state; 110#define ACPI_PWR_OFF 0 111#define ACPI_PWR_ON 1 | |
112}; 113 114TAILQ_HEAD(acpi_powerresource_list, acpi_powerresource) acpi_powerresources; 115TAILQ_HEAD(acpi_powerconsumer_list, acpi_powerconsumer) acpi_powerconsumers; 116 117static ACPI_STATUS acpi_pwr_register_consumer(ACPI_HANDLE consumer); 118static ACPI_STATUS acpi_pwr_deregister_consumer(ACPI_HANDLE consumer); 119static ACPI_STATUS acpi_pwr_register_resource(ACPI_HANDLE res); --- 46 unchanged lines hidden (view full) --- 166 167 /* get the Power Resource object */ 168 if ((status = acpi_EvaluateIntoBuffer(res, NULL, NULL, &buf)) != AE_OK) { 169 DEBUG_PRINT(TRACE_OBJECTS, ("no power resource object\n")); 170 goto out; 171 } 172 obj = buf.Pointer; 173 if (obj->Common.Type != ACPI_TYPE_POWER) { | 113}; 114 115TAILQ_HEAD(acpi_powerresource_list, acpi_powerresource) acpi_powerresources; 116TAILQ_HEAD(acpi_powerconsumer_list, acpi_powerconsumer) acpi_powerconsumers; 117 118static ACPI_STATUS acpi_pwr_register_consumer(ACPI_HANDLE consumer); 119static ACPI_STATUS acpi_pwr_deregister_consumer(ACPI_HANDLE consumer); 120static ACPI_STATUS acpi_pwr_register_resource(ACPI_HANDLE res); --- 46 unchanged lines hidden (view full) --- 167 168 /* get the Power Resource object */ 169 if ((status = acpi_EvaluateIntoBuffer(res, NULL, NULL, &buf)) != AE_OK) { 170 DEBUG_PRINT(TRACE_OBJECTS, ("no power resource object\n")); 171 goto out; 172 } 173 obj = buf.Pointer; 174 if (obj->Common.Type != ACPI_TYPE_POWER) { |
174 DEBUG_PRINT(TRACE_OBJECTS, ("bad power resource object\n")); 175 status = AE_TYPE; 176 goto out; | 175 DEBUG_PRINT(TRACE_OBJECTS, ("questionable power resource object %s\n", acpi_name(res))); 176 /* XXX ACPI CA seems to return ACPI_TYPE_ANY, needs to be fixed */ 177 rp->ap_systemlevel = 0; 178 rp->ap_order = 0; 179 } else { 180 rp->ap_systemlevel = obj->PowerResource.SystemLevel; 181 rp->ap_order = obj->PowerResource.ResourceOrder; |
177 } | 182 } |
178 rp->ap_systemlevel = obj->PowerResource.SystemLevel; 179 rp->ap_order = obj->PowerResource.ResourceOrder; | |
180 | 183 |
181 /* get the current state of the resource */ 182 if ((status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &rp->ap_state)) != AE_OK) { 183 /* XXX is this an error? */ 184 DEBUG_PRINT(TRACE_OBJECTS, ("can't get current power resource state\n")); 185 goto out; 186 } 187 | |
188 /* sort the resource into the list */ 189 status = AE_OK; 190 srp = TAILQ_FIRST(&acpi_powerresources); 191 if ((srp == NULL) || (rp->ap_order < srp->ap_order)) { 192 TAILQ_INSERT_HEAD(&acpi_powerresources, rp, ap_link); | 184 /* sort the resource into the list */ 185 status = AE_OK; 186 srp = TAILQ_FIRST(&acpi_powerresources); 187 if ((srp == NULL) || (rp->ap_order < srp->ap_order)) { 188 TAILQ_INSERT_HEAD(&acpi_powerresources, rp, ap_link); |
193 goto out; | 189 goto done; |
194 } 195 TAILQ_FOREACH(srp, &acpi_powerresources, ap_link) 196 if (rp->ap_order < srp->ap_order) { 197 TAILQ_INSERT_BEFORE(srp, rp, ap_link); | 190 } 191 TAILQ_FOREACH(srp, &acpi_powerresources, ap_link) 192 if (rp->ap_order < srp->ap_order) { 193 TAILQ_INSERT_BEFORE(srp, rp, ap_link); |
198 goto out; | 194 goto done; |
199 } 200 TAILQ_INSERT_TAIL(&acpi_powerresources, rp, ap_link); | 195 } 196 TAILQ_INSERT_TAIL(&acpi_powerresources, rp, ap_link); |
201 DEBUG_PRINT(TRACE_OBJECTS, ("registered power resource %s\n", acpi_name(res))); | |
202 | 197 |
198 done: 199 DEBUG_PRINT(TRACE_OBJECTS, ("registered power resource %s\n", acpi_name(res))); |
|
203 out: 204 if (obj != NULL) 205 AcpiOsFree(obj); 206 if ((status != AE_OK) && (rp != NULL)) 207 free(rp, M_ACPIPWR); 208 return_ACPI_STATUS(status); 209} 210 --- 181 unchanged lines hidden (view full) --- 392 } else { 393 reslist_object = NULL; 394 } 395 396 /* 397 * Now we are ready to switch, so kill off any current power resource references. 398 */ 399 res_changed = 0; | 200 out: 201 if (obj != NULL) 202 AcpiOsFree(obj); 203 if ((status != AE_OK) && (rp != NULL)) 204 free(rp, M_ACPIPWR); 205 return_ACPI_STATUS(status); 206} 207 --- 181 unchanged lines hidden (view full) --- 389 } else { 390 reslist_object = NULL; 391 } 392 393 /* 394 * Now we are ready to switch, so kill off any current power resource references. 395 */ 396 res_changed = 0; |
400 TAILQ_FOREACH(pr, &pc->ac_references, ar_clink) { 401 TAILQ_REMOVE(&pr->ar_resource->ap_references, pr, ar_rlink); | 397 while((pr = TAILQ_FIRST(&pc->ac_references)) != NULL) { |
402 res_changed = 1; | 398 res_changed = 1; |
399 DEBUG_PRINT(TRACE_OBJECTS, ("removing reference to %s\n", acpi_name(pr->ar_resource->ap_resource))); 400 TAILQ_REMOVE(&pr->ar_resource->ap_references, pr, ar_rlink); 401 TAILQ_REMOVE(&pc->ac_references, pr, ar_clink); 402 free(pr, M_ACPIPWR); |
|
403 } 404 405 /* 406 * Add new power resource references, if we have any. Traverse the 407 * package that we got from evaluating reslist_handle, and look up each 408 * of the resources that are referenced. 409 */ 410 if (reslist_object != NULL) { --- 30 unchanged lines hidden (view full) --- 441/* 442 * Called to create a reference between a power consumer and a power resource 443 * identified in the object. 444 */ 445static void 446acpi_pwr_reference_resource(ACPI_OBJECT *obj, void *arg) 447{ 448 struct acpi_powerconsumer *pc = (struct acpi_powerconsumer *)arg; | 403 } 404 405 /* 406 * Add new power resource references, if we have any. Traverse the 407 * package that we got from evaluating reslist_handle, and look up each 408 * of the resources that are referenced. 409 */ 410 if (reslist_object != NULL) { --- 30 unchanged lines hidden (view full) --- 441/* 442 * Called to create a reference between a power consumer and a power resource 443 * identified in the object. 444 */ 445static void 446acpi_pwr_reference_resource(ACPI_OBJECT *obj, void *arg) 447{ 448 struct acpi_powerconsumer *pc = (struct acpi_powerconsumer *)arg; |
449 struct acpi_powerreference *pr; 450 struct acpi_powerresource *rp; 451 ACPI_HANDLE res; 452 ACPI_STATUS status; |
|
449 450 FUNCTION_TRACE(__func__); 451 | 453 454 FUNCTION_TRACE(__func__); 455 |
452 DEBUG_PRINT(TRACE_OBJECTS, ("called to create a reference using object type %d\n", 453 obj->Type)); | 456 /* check the object type */ 457 if (obj->Type != ACPI_TYPE_STRING) { 458 DEBUG_PRINT(TRACE_OBJECTS, ("don't know how to create a power reference to object type %d\n", 459 obj->Type)); 460 return_VOID; 461 } |
454 | 462 |
463 DEBUG_PRINT(TRACE_OBJECTS, ("building reference from %s to %s\n", 464 acpi_name(pc->ac_consumer), obj->String.Pointer)); 465 466 /* get the handle of the resource */ 467 if (ACPI_FAILURE(status = AcpiGetHandle(NULL, obj->String.Pointer, &res))) { 468 DEBUG_PRINT(TRACE_OBJECTS, ("couldn't find power resource %s\n", 469 obj->String.Pointer)); 470 return_VOID; 471 } 472 473 /* create/look up the resource */ 474 if (ACPI_FAILURE(status = acpi_pwr_register_resource(res))) { 475 DEBUG_PRINT(TRACE_OBJECTS, ("couldn't register power resource %s - %s\n", 476 obj->String.Pointer, acpi_strerror(status))); 477 return_VOID; 478 } 479 if ((rp = acpi_pwr_find_resource(res)) == NULL) { 480 DEBUG_PRINT(TRACE_OBJECTS, ("power resource list corrupted\n")); 481 return_VOID; 482 } 483 DEBUG_PRINT(TRACE_OBJECTS, ("found power resource %s\n", acpi_name(rp->ap_resource))); 484 485 /* create a reference between the consumer and resource */ 486 if ((pr = malloc(sizeof(*pr), M_ACPIPWR, M_NOWAIT | M_ZERO)) == NULL) { 487 DEBUG_PRINT(TRACE_OBJECTS, ("couldn't allocate memory for a power consumer reference\n")); 488 return_VOID; 489 } 490 pr->ar_consumer = pc; 491 pr->ar_resource = rp; 492 TAILQ_INSERT_TAIL(&pc->ac_references, pr, ar_clink); 493 TAILQ_INSERT_TAIL(&rp->ap_references, pr, ar_rlink); 494 |
|
455 return_VOID; 456} 457 458 459/* 460 * Switch power resources to conform to the desired state. 461 * 462 * Consumers may have modified the power resource list in an arbitrary --- 7 unchanged lines hidden (view full) --- 470 int cur; 471 472 FUNCTION_TRACE(__func__); 473 474 /* 475 * Sweep the list forwards turning things on. 476 */ 477 TAILQ_FOREACH(rp, &acpi_powerresources, ap_link) { | 495 return_VOID; 496} 497 498 499/* 500 * Switch power resources to conform to the desired state. 501 * 502 * Consumers may have modified the power resource list in an arbitrary --- 7 unchanged lines hidden (view full) --- 510 int cur; 511 512 FUNCTION_TRACE(__func__); 513 514 /* 515 * Sweep the list forwards turning things on. 516 */ 517 TAILQ_FOREACH(rp, &acpi_powerresources, ap_link) { |
478 if (rp->ap_state != ACPI_PWR_ON) 479 continue; /* not turning this one on */ | 518 if (TAILQ_FIRST(&rp->ap_references) == NULL) { 519 DEBUG_PRINT(TRACE_OBJECTS, ("%s has no references, not turning on\n", 520 acpi_name(rp->ap_resource))); 521 continue; 522 } |
480 481 /* we could cache this if we trusted it not to change under us */ 482 if ((status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur)) != AE_OK) { 483 DEBUG_PRINT(TRACE_OBJECTS, ("can't get status of %s - %d\n", 484 acpi_name(rp->ap_resource), status)); 485 continue; /* XXX is this correct? Always switch if in doubt? */ 486 } 487 488 /* 489 * Switch if required. Note that we ignore the result of the switch 490 * effort; we don't know what to do if it fails, so checking wouldn't 491 * help much. 492 */ | 523 524 /* we could cache this if we trusted it not to change under us */ 525 if ((status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur)) != AE_OK) { 526 DEBUG_PRINT(TRACE_OBJECTS, ("can't get status of %s - %d\n", 527 acpi_name(rp->ap_resource), status)); 528 continue; /* XXX is this correct? Always switch if in doubt? */ 529 } 530 531 /* 532 * Switch if required. Note that we ignore the result of the switch 533 * effort; we don't know what to do if it fails, so checking wouldn't 534 * help much. 535 */ |
493 if (cur != ACPI_PWR_ON) 494 AcpiEvaluateObject(rp->ap_resource, "_ON", NULL, NULL); | 536 if (cur != ACPI_PWR_ON) { 537 if (ACPI_FAILURE(status = AcpiEvaluateObject(rp->ap_resource, "_ON", NULL, NULL))) { 538 DEBUG_PRINT(TRACE_OBJECTS, ("failed to switch %s on - %s\n", 539 acpi_name(rp->ap_resource), acpi_strerror(status))); 540 } else { 541 DEBUG_PRINT(TRACE_OBJECTS, ("switched %s on\n", acpi_name(rp->ap_resource))); 542 } 543 } else { 544 DEBUG_PRINT(TRACE_OBJECTS, ("%s is already on\n", acpi_name(rp->ap_resource))); 545 } |
495 } 496 497 /* 498 * Sweep the list backwards turning things off. 499 */ 500 TAILQ_FOREACH_REVERSE(rp, &acpi_powerresources, acpi_powerresource_list, ap_link) { | 546 } 547 548 /* 549 * Sweep the list backwards turning things off. 550 */ 551 TAILQ_FOREACH_REVERSE(rp, &acpi_powerresources, acpi_powerresource_list, ap_link) { |
501 if (rp->ap_state != ACPI_PWR_OFF) 502 continue; /* not turning this one off */ | 552 if (TAILQ_FIRST(&rp->ap_references) != NULL) { 553 DEBUG_PRINT(TRACE_OBJECTS, ("%s has references, not turning off\n", 554 acpi_name(rp->ap_resource))); 555 continue; 556 } |
503 504 /* we could cache this if we trusted it not to change under us */ 505 if ((status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur)) != AE_OK) { 506 DEBUG_PRINT(TRACE_OBJECTS, ("can't get status of %s - %d\n", 507 acpi_name(rp->ap_resource), status)); 508 continue; /* XXX is this correct? Always switch if in doubt? */ 509 } 510 511 /* 512 * Switch if required. Note that we ignore the result of the switch 513 * effort; we don't know what to do if it fails, so checking wouldn't 514 * help much. 515 */ | 557 558 /* we could cache this if we trusted it not to change under us */ 559 if ((status = acpi_EvaluateInteger(rp->ap_resource, "_STA", &cur)) != AE_OK) { 560 DEBUG_PRINT(TRACE_OBJECTS, ("can't get status of %s - %d\n", 561 acpi_name(rp->ap_resource), status)); 562 continue; /* XXX is this correct? Always switch if in doubt? */ 563 } 564 565 /* 566 * Switch if required. Note that we ignore the result of the switch 567 * effort; we don't know what to do if it fails, so checking wouldn't 568 * help much. 569 */ |
516 if (cur != ACPI_PWR_OFF) 517 AcpiEvaluateObject(rp->ap_resource, "_OFF", NULL, NULL); | 570 if (cur != ACPI_PWR_OFF) { 571 if (ACPI_FAILURE(status = AcpiEvaluateObject(rp->ap_resource, "_OFF", NULL, NULL))) { 572 DEBUG_PRINT(TRACE_OBJECTS, ("failed to switch %s off - %s\n", 573 acpi_name(rp->ap_resource), acpi_strerror(status))); 574 } else { 575 DEBUG_PRINT(TRACE_OBJECTS, ("switched %s off\n", acpi_name(rp->ap_resource))); 576 } 577 } else { 578 DEBUG_PRINT(TRACE_OBJECTS, ("%s is already off\n", acpi_name(rp->ap_resource))); 579 } |
518 } 519 return_ACPI_STATUS(AE_OK); 520} 521 522/* 523 * Find a power resource's control structure. 524 */ 525static struct acpi_powerresource * --- 28 unchanged lines hidden --- | 580 } 581 return_ACPI_STATUS(AE_OK); 582} 583 584/* 585 * Find a power resource's control structure. 586 */ 587static struct acpi_powerresource * --- 28 unchanged lines hidden --- |