* embedded_controller_support() now actually checks all entries of the

supporting ID array (just that it only contains one entry).
* Fixed missing malloc() result check in embedded_controller_init_driver().
* Style fixes.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36529 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-04-29 15:09:38 +00:00
parent 7b8344c61e
commit d3a302aae8
5 changed files with 248 additions and 260 deletions
@@ -1,4 +1,4 @@
/*- /*
* Copyright (c) 2009 Clemens Zeidler * Copyright (c) 2009 Clemens Zeidler
* Copyright (c) 2003-2007 Nate Lawson * Copyright (c) 2003-2007 Nate Lawson
* Copyright (c) 2000 Michael Smith * Copyright (c) 2000 Michael Smith
@@ -27,6 +27,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include "acpi_embedded_controller.h" #include "acpi_embedded_controller.h"
#include <stdio.h> #include <stdio.h>
@@ -40,6 +41,7 @@
#include "SmallResourceData.h" #include "SmallResourceData.h"
#define ACPI_EC_DRIVER_NAME "drivers/power/acpi_embedded_controller/driver_v1" #define ACPI_EC_DRIVER_NAME "drivers/power/acpi_embedded_controller/driver_v1"
#define ACPI_EC_DEVICE_NAME "drivers/power/acpi_embedded_controller/device_v1" #define ACPI_EC_DEVICE_NAME "drivers/power/acpi_embedded_controller/device_v1"
@@ -59,9 +61,9 @@ bus_space_read_1(int address)
void void
bus_space_write_1(int address, uint8 v) bus_space_write_1(int address, uint8 value)
{ {
gPCIManager->write_io_8(address, v); gPCIManager->write_io_8(address, value);
} }
@@ -74,12 +76,9 @@ acpi_GetInteger(acpi_device_module_info* acpi, acpi_device& acpiCookie,
buf.pointer = &object; buf.pointer = &object;
buf.length = sizeof(acpi_object_type); buf.length = sizeof(acpi_object_type);
/* // Assume that what we've been pointed at is an Integer object, or
* Assume that what we've been pointed at is an Integer object, or // a method that will return an Integer.
* a method that will return an Integer.
*/
status_t status = acpi->evaluate_method(acpiCookie, path, NULL, &buf); status_t status = acpi->evaluate_method(acpiCookie, path, NULL, &buf);
if (status == B_OK) { if (status == B_OK) {
if (object.object_type == ACPI_TYPE_INTEGER) if (object.object_type == ACPI_TYPE_INTEGER)
*number = object.data.integer; *number = object.data.integer;
@@ -98,20 +97,15 @@ acpi_GetReference(acpi_module_info* acpi, acpi_handle scope,
return NULL; return NULL;
switch (obj->object_type) { switch (obj->object_type) {
case ACPI_TYPE_LOCAL_REFERENCE: case ACPI_TYPE_LOCAL_REFERENCE:
case ACPI_TYPE_ANY: case ACPI_TYPE_ANY:
return obj->data.reference.handle; return obj->data.reference.handle;
case ACPI_TYPE_STRING: case ACPI_TYPE_STRING:
{ {
// The String object usually contains a fully-qualified path, so
/* // scope can be NULL.
* The String object usually contains a fully-qualified path, so // TODO: This may not always be the case.
* scope can be NULL.
*
* XXX This may not always be the case.
*/
acpi_handle handle; acpi_handle handle;
if (acpi->get_handle(scope, obj->data.string.string, &handle) if (acpi->get_handle(scope, obj->data.string.string, &handle)
== B_OK) == B_OK)
@@ -148,6 +142,9 @@ acpi_PkgInt32(acpi_object_type* res, int idx, uint32* dst)
} }
// #pragma mark -
static status_t static status_t
embedded_controller_open(void* initCookie, const char* path, int flags, embedded_controller_open(void* initCookie, const char* path, int flags,
void** cookie) void** cookie)
@@ -198,6 +195,7 @@ embedded_controller_free(void* cookie)
// #pragma mark - driver module API // #pragma mark - driver module API
int32 int32
acpi_get_type(device_node* dev) acpi_get_type(device_node* dev)
{ {
@@ -220,22 +218,31 @@ acpi_get_type(device_node* dev)
static float static float
embedded_controller_support(device_node* dev) embedded_controller_support(device_node* dev)
{ {
static const char* ec_ids[] = { "PNP0C09", NULL }; TRACE("embedded_controller_support()\n");
/* Check that this is a device. */ // Check that this is a device
TRACE("before acpi_get_type...");
if (acpi_get_type(dev) != ACPI_TYPE_DEVICE) if (acpi_get_type(dev) != ACPI_TYPE_DEVICE)
return 0.0; return 0.0;
const char* name; const char* name;
if (gDeviceManager->get_attr_string(dev, ACPI_DEVICE_HID_ITEM, &name, false) if (gDeviceManager->get_attr_string(dev, ACPI_DEVICE_HID_ITEM, &name, false)
!= B_OK || strcmp(name, ec_ids[0])) != B_OK)
return 0.0; return 0.0;
TRACE("after\n");
// Test all known IDs
static const char* kEmbeddedControllerIDs[] = { "PNP0C09" };
for (size_t i = 0; i < sizeof(kEmbeddedControllerIDs)
/ sizeof(kEmbeddedControllerIDs[0]); i++) {
if (!strcmp(name, kEmbeddedControllerIDs[i])) {
TRACE("supported device found %s\n", name); TRACE("supported device found %s\n", name);
return 0.6; return 0.6;
} }
}
return 0.0;
}
static status_t static status_t
@@ -259,6 +266,9 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
acpi_ec_cookie* sc; acpi_ec_cookie* sc;
sc = (acpi_ec_cookie*)malloc(sizeof(acpi_ec_cookie)); sc = (acpi_ec_cookie*)malloc(sizeof(acpi_ec_cookie));
if (sc == NULL)
return B_NO_MEMORY;
memset(sc, 0, sizeof(acpi_ec_cookie)); memset(sc, 0, sizeof(acpi_ec_cookie));
*_driverCookie = sc; *_driverCookie = sc;
@@ -286,12 +296,9 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
buf.pointer = NULL; buf.pointer = NULL;
buf.length = ACPI_ALLOCATE_BUFFER; buf.length = ACPI_ALLOCATE_BUFFER;
// Read the unit ID to check for duplicate attach and the
/* // global lock value to see if we should acquire it when
* Read the unit ID to check for duplicate attach and the // accessing the EC.
* global lock value to see if we should acquire it when
* accessing the EC.
*/
status_t status = acpi_GetInteger(sc->ec_acpi, sc->ec_handle, "_UID", status_t status = acpi_GetInteger(sc->ec_acpi, sc->ec_handle, "_UID",
&sc->ec_uid); &sc->ec_uid);
if (status != B_OK) if (status != B_OK)
@@ -300,11 +307,9 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
if (status != B_OK) if (status != B_OK)
sc->ec_glk = 0; sc->ec_glk = 0;
/* // Evaluate the _GPE method to find the GPE bit used by the EC to
* Evaluate the _GPE method to find the GPE bit used by the EC to // signal status (SCI). If it's a package, it contains a reference
* signal status (SCI). If it's a package, it contains a reference // and GPE bit, similar to _PRW.
* and GPE bit, similar to _PRW.
*/
status = sc->ec_acpi->evaluate_method(sc->ec_handle, "_GPE", NULL, &buf); status = sc->ec_acpi->evaluate_method(sc->ec_handle, "_GPE", NULL, &buf);
if (status != B_OK) { if (status != B_OK) {
TRACE("can't evaluate _GPE\n"); TRACE("can't evaluate _GPE\n");
@@ -337,7 +342,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
sc->ec_suspending = FALSE; sc->ec_suspending = FALSE;
/* Attach bus resources for data and command/status ports. */ // Attach bus resources for data and command/status ports.
if (resourceData.ReadIOPort(&portData) != B_OK) if (resourceData.ReadIOPort(&portData) != B_OK)
goto error; goto error;
@@ -348,10 +353,8 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
sc->ec_csr_pci_address = portData.minimumBase; sc->ec_csr_pci_address = portData.minimumBase;
/* // Install a handler for this EC's GPE bit. We want edge-triggered
* Install a handler for this EC's GPE bit. We want edge-triggered // behavior.
* behavior.
*/
TRACE("attaching GPE handler\n"); TRACE("attaching GPE handler\n");
status = sc->ec_acpi_module->install_gpe_handler(sc->ec_gpehandle, status = sc->ec_acpi_module->install_gpe_handler(sc->ec_gpehandle,
sc->ec_gpebit, ACPI_GPE_EDGE_TRIGGERED, &EcGpeHandler, sc); sc->ec_gpebit, ACPI_GPE_EDGE_TRIGGERED, &EcGpeHandler, sc);
@@ -360,7 +363,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
goto error; goto error;
} }
/* Install address space handler */ // Install address space handler
TRACE("attaching address space handler\n"); TRACE("attaching address space handler\n");
status = sc->ec_acpi->install_address_space_handler(sc->ec_handle, status = sc->ec_acpi->install_address_space_handler(sc->ec_handle,
ACPI_ADR_SPACE_EC, &EcSpaceHandler, &EcSpaceSetup, sc); ACPI_ADR_SPACE_EC, &EcSpaceHandler, &EcSpaceSetup, sc);
@@ -369,7 +372,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
goto error; goto error;
} }
/* Enable runtime GPEs for the handler. */ // Enable runtime GPEs for the handler.
status = sc->ec_acpi_module->set_gpe_type(sc->ec_gpehandle, sc->ec_gpebit, status = sc->ec_acpi_module->set_gpe_type(sc->ec_gpehandle, sc->ec_gpebit,
ACPI_GPE_TYPE_RUNTIME); ACPI_GPE_TYPE_RUNTIME);
if (status != B_OK) { if (status != B_OK) {
@@ -386,7 +389,6 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
return 0; return 0;
error: error:
if (buf.pointer)
free(buf.pointer); free(buf.pointer);
sc->ec_acpi_module->remove_gpe_handler(sc->ec_gpehandle, sc->ec_gpebit, sc->ec_acpi_module->remove_gpe_handler(sc->ec_gpehandle, sc->ec_gpebit,
@@ -482,6 +484,9 @@ struct device_module_info embedded_controller_device_module = {
}; };
// #pragma mark -
static void static void
EcGpeQueryHandler(void* context) EcGpeQueryHandler(void* context)
{ {
@@ -489,20 +494,18 @@ EcGpeQueryHandler(void* context)
ASSERT(context != NULL);//, ("EcGpeQueryHandler called with NULL")); ASSERT(context != NULL);//, ("EcGpeQueryHandler called with NULL"));
/* Serialize user access with EcSpaceHandler(). */ // Serialize user access with EcSpaceHandler().
status_t status = EcLock(sc); status_t status = EcLock(sc);
if (status != B_OK) { if (status != B_OK) {
TRACE("GpeQuery lock error.\n"); TRACE("GpeQuery lock error.\n");
return; return;
} }
/* // Send a query command to the EC to find out which _Qxx call it
* Send a query command to the EC to find out which _Qxx call it // wants to make. This command clears the SCI bit and also the
* wants to make. This command clears the SCI bit and also the // interrupt source since we are edge-triggered. To prevent the GPE
* interrupt source since we are edge-triggered. To prevent the GPE // that may arise from running the query from causing another query
* that may arise from running the query from causing another query // to be queued, we clear the pending flag only after running it.
* to be queued, we clear the pending flag only after running it.
*/
status = EcCommand(sc, EC_COMMAND_QUERY); status = EcCommand(sc, EC_COMMAND_QUERY);
sc->ec_sci_pending = FALSE; sc->ec_sci_pending = FALSE;
if (status != B_OK) { if (status != B_OK) {
@@ -512,19 +515,17 @@ EcGpeQueryHandler(void* context)
} }
uint8 data = EC_GET_DATA(sc); uint8 data = EC_GET_DATA(sc);
/* // We have to unlock before running the _Qxx method below since that
* We have to unlock before running the _Qxx method below since that // method may attempt to read/write from EC address space, causing
* method may attempt to read/write from EC address space, causing // recursive acquisition of the lock.
* recursive acquisition of the lock.
*/
EcUnlock(sc); EcUnlock(sc);
/* Ignore the value for "no outstanding event". (13.3.5) */ // Ignore the value for "no outstanding event". (13.3.5)
TRACE("query ok,%s running _Q%02X\n", data ? "" : " not", data); TRACE("query ok,%s running _Q%02X\n", data ? "" : " not", data);
if (data == 0) if (data == 0)
return; return;
/* Evaluate _Qxx to respond to the controller. */ // Evaluate _Qxx to respond to the controller.
char qxx[5]; char qxx[5];
snprintf(qxx, sizeof(qxx), "_Q%02X", data); snprintf(qxx, sizeof(qxx), "_Q%02X", data);
AcpiUtStrupr(qxx); AcpiUtStrupr(qxx);
@@ -535,9 +536,8 @@ EcGpeQueryHandler(void* context)
} }
/* /*! The GPE handler is called when IBE/OBF or SCI events occur. We are
* The GPE handler is called when IBE/OBF or SCI events occur. We are called from an unknown lock context.
* called from an unknown lock context.
*/ */
static uint32 static uint32
EcGpeHandler(void* context) EcGpeHandler(void* context)
@@ -547,25 +547,21 @@ EcGpeHandler(void* context)
ASSERT(context != NULL);//, ("EcGpeHandler called with NULL")); ASSERT(context != NULL);//, ("EcGpeHandler called with NULL"));
TRACE("gpe handler start\n"); TRACE("gpe handler start\n");
/* // Notify EcWaitEvent() that the status register is now fresh. If we
* Notify EcWaitEvent() that the status register is now fresh. If we // didn't do this, it wouldn't be possible to distinguish an old IBE
* didn't do this, it wouldn't be possible to distinguish an old IBE // from a new one, for example when doing a write transaction (writing
* from a new one, for example when doing a write transaction (writing // address and then data values.)
* address and then data values.)
*/
atomic_add(&sc->ec_gencount, 1); atomic_add(&sc->ec_gencount, 1);
sc->ec_condition_var.NotifyAll(); sc->ec_condition_var.NotifyAll();
/* // If the EC_SCI bit of the status register is set, queue a query handler.
* If the EC_SCI bit of the status register is set, queue a query handler. // It will run the query and _Qxx method later, under the lock.
* It will run the query and _Qxx method later, under the lock.
*/
EC_STATUS EcStatus = EC_GET_CSR(sc); EC_STATUS EcStatus = EC_GET_CSR(sc);
if ((EcStatus & EC_EVENT_SCI) && !sc->ec_sci_pending) { if ((EcStatus & EC_EVENT_SCI) && !sc->ec_sci_pending) {
TRACE("gpe queueing query handler\n"); TRACE("gpe queueing query handler\n");
ACPI_STATUS s = AcpiOsExecute(OSL_GPE_HANDLER, EcGpeQueryHandler, ACPI_STATUS status = AcpiOsExecute(OSL_GPE_HANDLER, EcGpeQueryHandler,
context); context);
if (s == AE_OK) if (status == AE_OK)
sc->ec_sci_pending = TRUE; sc->ec_sci_pending = TRUE;
else else
dprintf("EcGpeHandler: queuing GPE query handler failed\n"); dprintf("EcGpeHandler: queuing GPE query handler failed\n");
@@ -578,10 +574,8 @@ static acpi_status
EcSpaceSetup(acpi_handle region, uint32 function, void* context, EcSpaceSetup(acpi_handle region, uint32 function, void* context,
void** regionContext) void** regionContext)
{ {
/* // If deactivating a region, always set the output to NULL. Otherwise,
* If deactivating a region, always set the output to NULL. Otherwise, // just pass the context through.
* just pass the context through.
*/
if (function == ACPI_REGION_DEACTIVATE) if (function == ACPI_REGION_DEACTIVATE)
*regionContext = NULL; *regionContext = NULL;
else else
@@ -599,7 +593,6 @@ EcSpaceHandler(uint32 function, acpi_physical_address address, uint32 width,
struct acpi_ec_cookie* sc = (struct acpi_ec_cookie*)context; struct acpi_ec_cookie* sc = (struct acpi_ec_cookie*)context;
uint8 ecData; uint8 ecData;
if (width % 8 != 0 || value == NULL || context == NULL) if (width % 8 != 0 || value == NULL || context == NULL)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
if (address + (width / 8) - 1 > 0xFF) if (address + (width / 8) - 1 > 0xFF)
@@ -622,12 +615,12 @@ EcSpaceHandler(uint32 function, acpi_physical_address address, uint32 width,
} }
} */ } */
/* Serialize with EcGpeQueryHandler() at transaction granularity. */ // Serialize with EcGpeQueryHandler() at transaction granularity.
status = EcLock(sc); status = EcLock(sc);
if (status != B_OK) if (status != B_OK)
return AE_NOT_ACQUIRED; return AE_NOT_ACQUIRED;
/* Perform the transaction(s), based on width. */ // Perform the transaction(s), based on width.
for (uint32 i = 0; i < width; i += 8, ecAddr++) { for (uint32 i = 0; i < width; i += 8, ecAddr++) {
switch (function) { switch (function) {
case ACPI_READ: case ACPI_READ:
@@ -644,10 +637,9 @@ EcSpaceHandler(uint32 function, acpi_physical_address address, uint32 width,
status = AE_BAD_PARAMETER; status = AE_BAD_PARAMETER;
break; break;
} }
if (status != AE_OK) { if (status != AE_OK)
break; break;
} }
}
EcUnlock(sc); EcUnlock(sc);
return status; return status;
@@ -673,27 +665,25 @@ EcCheckStatus(struct acpi_ec_cookie* sc, const char* msg, EC_EVENT event)
static acpi_status static acpi_status
EcWaitEvent(struct acpi_ec_cookie* sc, EC_EVENT event, int32 gen_count) EcWaitEvent(struct acpi_ec_cookie* sc, EC_EVENT event, int32 generationCount)
{ {
acpi_status status = AE_NO_HARDWARE_RESPONSE; acpi_status status = AE_NO_HARDWARE_RESPONSE;
int32 count, i; int32 count, i;
// int need_poll = cold || rebooting || ec_polled_mode || sc->ec_suspending; // int need_poll = cold || rebooting || ec_polled_mode || sc->ec_suspending;
int need_poll = ec_polled_mode || sc->ec_suspending; int needPoll = ec_polled_mode || sc->ec_suspending;
/* // The main CPU should be much faster than the EC. So the status should
* The main CPU should be much faster than the EC. So the status should // be "not ready" when we start waiting. But if the main CPU is really
* be "not ready" when we start waiting. But if the main CPU is really // slow, it's possible we see the current "ready" response. Since that
* slow, it's possible we see the current "ready" response. Since that // can't be distinguished from the previous response in polled mode,
* can't be distinguished from the previous response in polled mode, // this is a potential issue. We really should have interrupts enabled
* this is a potential issue. We really should have interrupts enabled // during boot so there is no ambiguity in polled mode.
* during boot so there is no ambiguity in polled mode. //
* // If this occurs, we add an additional delay before actually entering
* If this occurs, we add an additional delay before actually entering // the status checking loop, hopefully to allow the EC to go to work
* the status checking loop, hopefully to allow the EC to go to work // and produce a non-stale status.
* and produce a non-stale status. if (needPoll) {
*/
if (need_poll) {
static int once; static int once;
if (EcCheckStatus(sc, "pre-check", event) == B_OK) { if (EcCheckStatus(sc, "pre-check", event) == B_OK) {
@@ -705,11 +695,12 @@ EcWaitEvent(struct acpi_ec_cookie* sc, EC_EVENT event, int32 gen_count)
} }
} }
/* Wait for event by polling or GPE (interrupt). */ // Wait for event by polling or GPE (interrupt).
if (need_poll) { if (needPoll) {
count = (ec_timeout * 1000) / EC_POLL_DELAY; count = (ec_timeout * 1000) / EC_POLL_DELAY;
if (count == 0) if (count == 0)
count = 1; count = 1;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
status = EcCheckStatus(sc, "poll", event); status = EcCheckStatus(sc, "poll", event);
if (status == AE_OK) if (status == AE_OK)
@@ -717,38 +708,32 @@ EcWaitEvent(struct acpi_ec_cookie* sc, EC_EVENT event, int32 gen_count)
spin(EC_POLL_DELAY); spin(EC_POLL_DELAY);
} }
} else { } else {
bigtime_t slp_ival = system_time() + ec_timeout * 1000; bigtime_t sleepInterval = system_time() + ec_timeout * 1000;
/* // Wait for the GPE to signal the status changed, checking the
* Wait for the GPE to signal the status changed, checking the // status register each time we get one. It's possible to get a
* status register each time we get one. It's possible to get a // GPE for an event we're not interested in here (i.e., SCI for
* GPE for an event we're not interested in here (i.e., SCI for // EC query).
* EC query).
*/
status_t waitStatus = B_NO_ERROR; status_t waitStatus = B_NO_ERROR;
while (waitStatus != B_TIMED_OUT) { while (waitStatus != B_TIMED_OUT) {
if (gen_count != sc->ec_gencount) { if (generationCount != sc->ec_gencount) {
/* // Record new generation count. It's possible the GPE was
* Record new generation count. It's possible the GPE was // just to notify us that a query is needed and we need to
* just to notify us that a query is needed and we need to // wait for a second GPE to signal the completion of the
* wait for a second GPE to signal the completion of the // event we are actually waiting for.
* event we are actually waiting for. generationCount = sc->ec_gencount;
*/
gen_count = sc->ec_gencount;
status = EcCheckStatus(sc, "sleep", event); status = EcCheckStatus(sc, "sleep", event);
if (status == AE_OK) if (status == AE_OK)
break; break;
} }
waitStatus = sc->ec_condition_var.Wait(B_ABSOLUTE_TIMEOUT, waitStatus = sc->ec_condition_var.Wait(B_ABSOLUTE_TIMEOUT,
slp_ival); sleepInterval);
} }
/* // We finished waiting for the GPE and it never arrived. Try to
* We finished waiting for the GPE and it never arrived. Try to // read the register once and trust whatever value we got. This is
* read the register once and trust whatever value we got. This is // the best we can do at this point. Then, force polled mode on
* the best we can do at this point. Then, force polled mode on // since this system doesn't appear to generate GPEs.
* since this system doesn't appear to generate GPEs.
*/
if (status != AE_OK) { if (status != AE_OK) {
status = EcCheckStatus(sc, "sleep_end", event); status = EcCheckStatus(sc, "sleep_end", event);
TRACE("wait timed out (%sresponse), forcing polled mode\n", TRACE("wait timed out (%sresponse), forcing polled mode\n",
@@ -766,11 +751,11 @@ EcWaitEvent(struct acpi_ec_cookie* sc, EC_EVENT event, int32 gen_count)
static acpi_status static acpi_status
EcCommand(struct acpi_ec_cookie* sc, EC_COMMAND cmd) EcCommand(struct acpi_ec_cookie* sc, EC_COMMAND cmd)
{ {
/* Don't use burst mode if user disabled it. */ // Don't use burst mode if user disabled it.
if (!ec_burst_mode && cmd == EC_COMMAND_BURST_ENABLE) if (!ec_burst_mode && cmd == EC_COMMAND_BURST_ENABLE)
return AE_ERROR; return AE_ERROR;
/* Decide what to wait for based on command type. */ // Decide what to wait for based on command type.
EC_EVENT event; EC_EVENT event;
switch (cmd) { switch (cmd) {
case EC_COMMAND_READ: case EC_COMMAND_READ:
@@ -787,13 +772,13 @@ EcCommand(struct acpi_ec_cookie* sc, EC_COMMAND cmd)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
} }
/* Run the command and wait for the chosen event. */ // Run the command and wait for the chosen event.
TRACE("running command %#x\n", cmd); TRACE("running command %#x\n", cmd);
u_int gen_count = sc->ec_gencount; u_int gen_count = sc->ec_gencount;
EC_SET_CSR(sc, cmd); EC_SET_CSR(sc, cmd);
acpi_status status = EcWaitEvent(sc, event, gen_count); acpi_status status = EcWaitEvent(sc, event, gen_count);
if (status == AE_OK) { if (status == AE_OK) {
/* If we succeeded, burst flag should now be present. */ // If we succeeded, burst flag should now be present.
if (cmd == EC_COMMAND_BURST_ENABLE) { if (cmd == EC_COMMAND_BURST_ENABLE) {
EC_STATUS ec_status = EC_GET_CSR(sc); EC_STATUS ec_status = EC_GET_CSR(sc);
if ((ec_status & EC_FLAG_BURST_MODE) == 0) if ((ec_status & EC_FLAG_BURST_MODE) == 0)
@@ -811,7 +796,7 @@ EcRead(struct acpi_ec_cookie* sc, uint8 address, uint8* readData)
{ {
TRACE("read from %#x\n", address); TRACE("read from %#x\n", address);
/* If we can't start burst mode, continue anyway. */ // If we can't start burst mode, continue anyway.
acpi_status status = EcCommand(sc, EC_COMMAND_BURST_ENABLE); acpi_status status = EcCommand(sc, EC_COMMAND_BURST_ENABLE);
if (status == AE_OK) { if (status == AE_OK) {
uint8 data = EC_GET_DATA(sc); uint8 data = EC_GET_DATA(sc);
@@ -825,10 +810,10 @@ EcRead(struct acpi_ec_cookie* sc, uint8 address, uint8* readData)
if (status != AE_OK) if (status != AE_OK)
return status; return status;
u_int gen_count = sc->ec_gencount; u_int generationCount = sc->ec_gencount;
EC_SET_DATA(sc, address); EC_SET_DATA(sc, address);
status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL, gen_count); status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL, generationCount);
if (status != AE_OK) { if (status != AE_OK) {
TRACE("EcRead: failed waiting to get data\n"); TRACE("EcRead: failed waiting to get data\n");
return status; return status;
@@ -864,17 +849,17 @@ EcWrite(struct acpi_ec_cookie* sc, uint8 address, uint8* writeData)
if (status != AE_OK) if (status != AE_OK)
return status; return status;
u_int gen_count = sc->ec_gencount; u_int generationCount = sc->ec_gencount;
EC_SET_DATA(sc, address); EC_SET_DATA(sc, address);
status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count); status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, generationCount);
if (status != AE_OK) { if (status != AE_OK) {
TRACE("EcRead: failed waiting for sent address\n"); TRACE("EcRead: failed waiting for sent address\n");
return status; return status;
} }
gen_count = sc->ec_gencount; generationCount = sc->ec_gencount;
EC_SET_DATA(sc, *writeData); EC_SET_DATA(sc, *writeData);
status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count); status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, generationCount);
if (status != AE_OK) { if (status != AE_OK) {
TRACE("EcWrite: failed waiting for sent data\n"); TRACE("EcWrite: failed waiting for sent data\n");
return status; return status;
@@ -29,6 +29,7 @@
#ifndef ACPI_EMBEDDED_CONTROLLER_H #ifndef ACPI_EMBEDDED_CONTROLLER_H
#define ACPI_EMBEDDED_CONTROLLER_H #define ACPI_EMBEDDED_CONTROLLER_H
#include <ctype.h> #include <ctype.h>
#include <ACPI.h> #include <ACPI.h>
@@ -45,6 +46,7 @@ extern "C" {
# include "acpi_priv.h" # include "acpi_priv.h"
} }
// #define TRACE_EMBEDDED_CONTROLLER // #define TRACE_EMBEDDED_CONTROLLER
#ifdef TRACE_EMBEDDED_CONTROLLER #ifdef TRACE_EMBEDDED_CONTROLLER
# define TRACE(x...) dprintf("EC: " x) # define TRACE(x...) dprintf("EC: " x)
@@ -159,7 +161,6 @@ struct acpi_ec_cookie {
}; };
/* /*
* XXX njl * XXX njl
* I couldn't find it in the spec but other implementations also use a * I couldn't find it in the spec but other implementations also use a
@@ -186,6 +187,7 @@ static int ec_polled_mode = 0;
static int ec_timeout = EC_TIMEOUT; static int ec_timeout = EC_TIMEOUT;
static status_t static status_t
EcLock(struct acpi_ec_cookie *sc) EcLock(struct acpi_ec_cookie *sc)
{ {
@@ -5,6 +5,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -21,6 +22,7 @@
# define TRACE(x) ; # define TRACE(x) ;
#endif #endif
device_manager_info* gDeviceManager = NULL; device_manager_info* gDeviceManager = NULL;
pci_module_info* gPCIManager = NULL; pci_module_info* gPCIManager = NULL;
dpc_module_info* gDPC = NULL; dpc_module_info* gDPC = NULL;
@@ -36,9 +38,8 @@ module_dependency module_dependencies[] = {
static float static float
acpi_module_supports_device(device_node* parent) acpi_module_supports_device(device_node* parent)
{ {
const char *bus;
// make sure parent is really device root // make sure parent is really device root
const char* bus;
if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
return B_ERROR; return B_ERROR;
@@ -52,7 +53,6 @@ acpi_module_supports_device(device_node *parent)
static status_t static status_t
acpi_module_register_device(device_node* parent) acpi_module_register_device(device_node* parent)
{ {
device_attr attrs[] = { device_attr attrs[] = {
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI" }}, { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI" }},
@@ -60,9 +60,8 @@ acpi_module_register_device(device_node *parent)
{} {}
}; };
io_resource *resources = NULL; return gDeviceManager->register_node(parent, ACPI_ROOT_MODULE_NAME, attrs,
NULL, NULL);
return gDeviceManager->register_node(parent, ACPI_ROOT_MODULE_NAME, attrs, resources, NULL);
} }
@@ -78,7 +77,8 @@ acpi_enumerate_child_devices(device_node *node, const char *root)
// get a reference on the parent // get a reference on the parent
parent = gDeviceManager->get_parent_node(node); parent = gDeviceManager->get_parent_node(node);
while (get_next_entry(ACPI_TYPE_ANY, root, result, sizeof(result), &counter) == B_OK) { while (get_next_entry(ACPI_TYPE_ANY, root, result,
sizeof(result), &counter) == B_OK) {
uint32 type = get_object_type(result); uint32 type = get_object_type(result);
device_node* deviceNode; device_node* deviceNode;
@@ -114,7 +114,6 @@ acpi_enumerate_child_devices(device_node *node, const char *root)
if (gDeviceManager->register_node(node, ACPI_DEVICE_MODULE_NAME, attrs, if (gDeviceManager->register_node(node, ACPI_DEVICE_MODULE_NAME, attrs,
NULL, &deviceNode) == B_OK) NULL, &deviceNode) == B_OK)
acpi_enumerate_child_devices(deviceNode, result); acpi_enumerate_child_devices(deviceNode, result);
break; break;
} }
default: default:
@@ -131,13 +130,12 @@ acpi_enumerate_child_devices(device_node *node, const char *root)
static status_t static status_t
acpi_module_register_child_devices(void* cookie) acpi_module_register_child_devices(void* cookie)
{ {
status_t err;
device_node* node = cookie; device_node* node = cookie;
err = gDeviceManager->publish_device(node, "acpi/namespace", ACPI_NS_DUMP_DEVICE_MODULE_NAME); status_t status = gDeviceManager->publish_device(node, "acpi/namespace",
if (err != B_OK) { ACPI_NS_DUMP_DEVICE_MODULE_NAME);
return err; if (status != B_OK)
} return status;
return acpi_enumerate_child_devices(node, "\\"); return acpi_enumerate_child_devices(node, "\\");
} }
@@ -221,7 +219,8 @@ static struct acpi_root_info sACPIRootModule = {
evaluate_method, evaluate_method,
}; };
_EXPORT module_info *modules[] = {
module_info* modules[] = {
(module_info*)&gACPIModule, (module_info*)&gACPIModule,
(module_info*)&sACPIRootModule, (module_info*)&sACPIRootModule,
(module_info*)&acpi_ns_dump_module, (module_info*)&acpi_ns_dump_module,
@@ -6,8 +6,8 @@
#ifndef __ACPI_PRIV_H__ #ifndef __ACPI_PRIV_H__
#define __ACPI_PRIV_H__ #define __ACPI_PRIV_H__
#include <sys/cdefs.h> #include <sys/cdefs.h>
__BEGIN_DECLS
#include <device_manager.h> #include <device_manager.h>
#include <KernelExport.h> #include <KernelExport.h>
@@ -24,6 +24,8 @@ __BEGIN_DECLS
#define ACPI_NS_DUMP_DEVICE_MODULE_NAME "bus_managers/acpi/namespace/device_v1" #define ACPI_NS_DUMP_DEVICE_MODULE_NAME "bus_managers/acpi/namespace/device_v1"
__BEGIN_DECLS
extern device_manager_info* gDeviceManager; extern device_manager_info* gDeviceManager;
extern pci_module_info* gPCIManager; extern pci_module_info* gPCIManager;
@@ -70,12 +72,10 @@ typedef struct acpi_root_info {
/* Address Space Handler */ /* Address Space Handler */
status_t (*install_address_space_handler)(acpi_handle handle, status_t (*install_address_space_handler)(acpi_handle handle,
uint32 spaceId, uint32 spaceID, acpi_adr_space_handler handler,
acpi_adr_space_handler handler,
acpi_adr_space_setup setup, void* data); acpi_adr_space_setup setup, void* data);
status_t (*remove_address_space_handler)(acpi_handle handle, status_t (*remove_address_space_handler)(acpi_handle handle,
uint32 spaceId, uint32 spaceID, acpi_adr_space_handler handler);
acpi_adr_space_handler handler);
/* Fixed Event Management */ /* Fixed Event Management */
@@ -98,7 +98,8 @@ typedef struct acpi_root_info {
status_t (*get_device)(const char* hid, uint32 index, char* result, status_t (*get_device)(const char* hid, uint32 index, char* result,
size_t resultLength); size_t resultLength);
status_t (*get_device_hid)(const char *path, char *hid, size_t hidLength); status_t (*get_device_hid)(const char* path, char* hid,
size_t hidLength);
uint32 (*get_object_type)(const char* path); uint32 (*get_object_type)(const char* path);
status_t (*get_object)(const char* path, status_t (*get_object)(const char* path,
acpi_object_type** _returnValue); acpi_object_type** _returnValue);
@@ -117,8 +118,7 @@ typedef struct acpi_root_info {
/* Resource info */ /* Resource info */
status_t (*get_irq_routing_table)(acpi_handle busDeviceHandle, status_t (*get_irq_routing_table)(acpi_handle busDeviceHandle,
acpi_data *retBuffer); acpi_data* returnValue);
} acpi_root_info; } acpi_root_info;
@@ -149,9 +149,9 @@ status_t install_gpe_handler(acpi_handle handle, uint32 gpeNumber, uint32 type,
status_t remove_gpe_handler(acpi_handle handle, uint32 gpeNumber, status_t remove_gpe_handler(acpi_handle handle, uint32 gpeNumber,
acpi_event_handler address); acpi_event_handler address);
status_t install_address_space_handler(acpi_handle handle, uint32 spaceId, status_t install_address_space_handler(acpi_handle handle, uint32 spaceID,
acpi_adr_space_handler handler, acpi_adr_space_setup setup, void* data); acpi_adr_space_handler handler, acpi_adr_space_setup setup, void* data);
status_t remove_address_space_handler(acpi_handle handle, uint32 spaceId, status_t remove_address_space_handler(acpi_handle handle, uint32 spaceID,
acpi_adr_space_handler handler); acpi_adr_space_handler handler);
void enable_fixed_event(uint32 event); void enable_fixed_event(uint32 event);
@@ -165,14 +165,14 @@ status_t install_fixed_event_handler(uint32 event, interrupt_handler *handler,
status_t remove_fixed_event_handler(uint32 event, interrupt_handler* handler); status_t remove_fixed_event_handler(uint32 event, interrupt_handler* handler);
status_t get_next_entry(uint32 object_type, const char* base, char* result, status_t get_next_entry(uint32 object_type, const char* base, char* result,
size_t length, void **counter); size_t length, void** _counter);
status_t get_device(const char* hid, uint32 index, char* result, status_t get_device(const char* hid, uint32 index, char* result,
size_t resultLength); size_t resultLength);
status_t get_device_hid(const char* path, char* hid, size_t hidLength); status_t get_device_hid(const char* path, char* hid, size_t hidLength);
uint32 get_object_type(const char* path); uint32 get_object_type(const char* path);
status_t get_object(const char *path, acpi_object_type **return_value); status_t get_object(const char* path, acpi_object_type** _returnValue);
status_t get_object_typed(const char *path, acpi_object_type **return_value, status_t get_object_typed(const char* path, acpi_object_type** _returnValue,
uint32 object_type); uint32 object_type);
status_t ns_handle_to_pathname(acpi_handle targetHandle, acpi_data* buffer); status_t ns_handle_to_pathname(acpi_handle targetHandle, acpi_data* buffer);
@@ -182,7 +182,8 @@ status_t evaluate_method(acpi_handle handle, const char *method,
acpi_objects* args, acpi_data* returnValue); acpi_objects* args, acpi_data* returnValue);
status_t get_irq_routing_table(acpi_handle busDeviceHandle, status_t get_irq_routing_table(acpi_handle busDeviceHandle,
acpi_data *retBuffer); acpi_data* returnValue);
__END_DECLS __END_DECLS
#endif /* __ACPI_PRIV_H__ */ #endif /* __ACPI_PRIV_H__ */
+12 -11
View File
@@ -1,3 +1,7 @@
/*
* Copyright 2010, Clemens Zeidler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef IRQ_ROUTING_TABLE_H #ifndef IRQ_ROUTING_TABLE_H
#define IRQ_ROUTING_TABLE_H #define IRQ_ROUTING_TABLE_H
@@ -9,8 +13,7 @@
#include "util/Vector.h" #include "util/Vector.h"
struct irq_routing_entry struct irq_routing_entry {
{
int device_address; int device_address;
int8 pin; int8 pin;
@@ -26,8 +29,7 @@ struct irq_routing_entry
typedef Vector<irq_routing_entry> IRQRoutingTable; typedef Vector<irq_routing_entry> IRQRoutingTable;
struct irq_descriptor struct irq_descriptor {
{
irq_descriptor(); irq_descriptor();
// bit 0 is interrupt 0, bit 2 is interrupt 2, and so on // bit 0 is interrupt 0, bit 2 is interrupt 2, and so on
int16 irq; int16 irq;
@@ -39,15 +41,14 @@ struct irq_descriptor
}; };
/* Similar to bus_managers/acpi/include/acrestyp.h definition */ // Similar to bus_managers/acpi/include/acrestyp.h definition
typedef struct acpi_prt typedef struct acpi_prt {
{
uint32 length; uint32 length;
uint32 pin; uint32 pin;
int address; /* here for 64-bit alignment */ int address; // here for 64-bit alignment
uint32 sourceIndex; uint32 sourceIndex;
char source[4]; /* pad to 64 bits so sizeof() works in char source[4]; // pad to 64 bits so sizeof() works in
all cases */ // all cases
} acpi_pci_routing_table; } acpi_pci_routing_table;
@@ -68,4 +69,4 @@ status_t read_possible_irq(acpi_module_info* acpi, acpi_handle device,
status_t set_acpi_irq(acpi_module_info* acpi, acpi_handle device, status_t set_acpi_irq(acpi_module_info* acpi, acpi_handle device,
irq_descriptor* descriptor); irq_descriptor* descriptor);
#endif #endif // IRQ_ROUTING_TABLE_H