* 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:
@@ -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,23 +97,18 @@ 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)
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +124,7 @@ acpi_PkgInt(acpi_object_type* res, int idx, int* dst)
|
|||||||
if (obj == NULL || obj->object_type != ACPI_TYPE_INTEGER)
|
if (obj == NULL || obj->object_type != ACPI_TYPE_INTEGER)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
*dst = obj->data.integer;
|
*dst = obj->data.integer;
|
||||||
|
|
||||||
return B_OK;
|
return 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,21 +218,30 @@ 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");
|
|
||||||
TRACE("supported device found %s\n", name);
|
// Test all known IDs
|
||||||
return 0.6;
|
|
||||||
|
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);
|
||||||
|
return 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -258,7 +265,10 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
|||||||
TRACE("init driver\n");
|
TRACE("init driver\n");
|
||||||
|
|
||||||
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;
|
||||||
@@ -268,7 +278,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
|||||||
mutex_init(&sc->ec_lock, "ec lock");
|
mutex_init(&sc->ec_lock, "ec lock");
|
||||||
device_node* parent = gDeviceManager->get_parent_node(dev);
|
device_node* parent = gDeviceManager->get_parent_node(dev);
|
||||||
gDeviceManager->get_driver(parent, (driver_module_info**)&sc->ec_acpi,
|
gDeviceManager->get_driver(parent, (driver_module_info**)&sc->ec_acpi,
|
||||||
(void**) &sc->ec_handle);
|
(void**)&sc->ec_handle);
|
||||||
gDeviceManager->put_node(parent);
|
gDeviceManager->put_node(parent);
|
||||||
|
|
||||||
SmallResourceData resourceData(sc->ec_acpi, sc->ec_handle, "_CRS");
|
SmallResourceData resourceData(sc->ec_acpi, sc->ec_handle, "_CRS");
|
||||||
@@ -279,19 +289,16 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
|||||||
io_port portData;
|
io_port portData;
|
||||||
|
|
||||||
if (get_module(B_ACPI_MODULE_NAME, (module_info**)&sc->ec_acpi_module)
|
if (get_module(B_ACPI_MODULE_NAME, (module_info**)&sc->ec_acpi_module)
|
||||||
!= B_OK)
|
!= B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
acpi_data buf;
|
acpi_data buf;
|
||||||
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");
|
||||||
@@ -312,7 +317,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
acpi_object_type* obj;
|
acpi_object_type* obj;
|
||||||
obj = (acpi_object_type*) buf.pointer;
|
obj = (acpi_object_type*)buf.pointer;
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@@ -327,7 +332,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
|||||||
sc->ec_gpehandle = acpi_GetReference(sc->ec_acpi_module, NULL,
|
sc->ec_gpehandle = acpi_GetReference(sc->ec_acpi_module, NULL,
|
||||||
&obj->data.package.objects[0]);
|
&obj->data.package.objects[0]);
|
||||||
if (sc->ec_gpehandle == NULL
|
if (sc->ec_gpehandle == NULL
|
||||||
|| acpi_PkgInt32(obj, 1, (uint32*) &sc->ec_gpebit) != B_OK)
|
|| acpi_PkgInt32(obj, 1, (uint32*)&sc->ec_gpebit) != B_OK)
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -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,8 +389,7 @@ 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,
|
||||||
&EcGpeHandler);
|
&EcGpeHandler);
|
||||||
@@ -401,7 +403,7 @@ error:
|
|||||||
static void
|
static void
|
||||||
embedded_controller_uninit_driver(void* driverCookie)
|
embedded_controller_uninit_driver(void* driverCookie)
|
||||||
{
|
{
|
||||||
acpi_ec_cookie* sc = (struct acpi_ec_cookie*) driverCookie;
|
acpi_ec_cookie* sc = (struct acpi_ec_cookie*)driverCookie;
|
||||||
mutex_destroy(&sc->ec_lock);
|
mutex_destroy(&sc->ec_lock);
|
||||||
free(sc);
|
free(sc);
|
||||||
put_module(B_ACPI_MODULE_NAME);
|
put_module(B_ACPI_MODULE_NAME);
|
||||||
@@ -411,7 +413,7 @@ embedded_controller_uninit_driver(void* driverCookie)
|
|||||||
static status_t
|
static status_t
|
||||||
embedded_controller_register_child_devices(void* _cookie)
|
embedded_controller_register_child_devices(void* _cookie)
|
||||||
{
|
{
|
||||||
device_node* node = ((acpi_ec_cookie*) _cookie)->ec_dev;
|
device_node* node = ((acpi_ec_cookie*)_cookie)->ec_dev;
|
||||||
|
|
||||||
int pathID = gDeviceManager->create_id(ACPI_EC_PATHID_GENERATOR);
|
int pathID = gDeviceManager->create_id(ACPI_EC_PATHID_GENERATOR);
|
||||||
if (pathID < 0) {
|
if (pathID < 0) {
|
||||||
@@ -436,7 +438,7 @@ embedded_controller_init_device(void* driverCookie, void** cookie)
|
|||||||
static void
|
static void
|
||||||
embedded_controller_uninit_device(void* _cookie)
|
embedded_controller_uninit_device(void* _cookie)
|
||||||
{
|
{
|
||||||
acpi_ec_cookie *device = (acpi_ec_cookie*)_cookie;
|
acpi_ec_cookie* device = (acpi_ec_cookie*)_cookie;
|
||||||
free(device);
|
free(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,27 +484,28 @@ struct device_module_info embedded_controller_device_module = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
EcGpeQueryHandler(void* context)
|
EcGpeQueryHandler(void* context)
|
||||||
{
|
{
|
||||||
struct acpi_ec_cookie* sc = (struct acpi_ec_cookie*) context;
|
struct acpi_ec_cookie* sc = (struct acpi_ec_cookie*)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,37 +536,32 @@ 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)
|
||||||
{
|
{
|
||||||
struct acpi_ec_cookie *sc = (acpi_ec_cookie*)context;
|
struct acpi_ec_cookie* sc = (acpi_ec_cookie*)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
|
||||||
@@ -596,10 +590,9 @@ EcSpaceHandler(uint32 function, acpi_physical_address address, uint32 width,
|
|||||||
int* value, void* context, void* regionContext)
|
int* value, void* context, void* regionContext)
|
||||||
{
|
{
|
||||||
TRACE("enter EcSpaceHandler\n");
|
TRACE("enter EcSpaceHandler\n");
|
||||||
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:
|
||||||
@@ -636,7 +629,7 @@ EcSpaceHandler(uint32 function, acpi_physical_address address, uint32 width,
|
|||||||
*value |= ((int) ecData) << i;
|
*value |= ((int) ecData) << i;
|
||||||
break;
|
break;
|
||||||
case ACPI_WRITE:
|
case ACPI_WRITE:
|
||||||
ecData = (uint8) ((*value) >> i);
|
ecData = (uint8)((*value) >> i);
|
||||||
status = EcWrite(sc, ecAddr, &ecData);
|
status = EcWrite(sc, ecAddr, &ecData);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -644,9 +637,8 @@ 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);
|
||||||
@@ -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>
|
||||||
@@ -39,12 +40,13 @@
|
|||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "acpi.h"
|
# include "acpi.h"
|
||||||
#include "accommon.h"
|
# include "accommon.h"
|
||||||
#include "acnamesp.h"
|
# include "acnamesp.h"
|
||||||
#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)
|
||||||
@@ -145,7 +147,7 @@ struct acpi_ec_cookie {
|
|||||||
acpi_handle ec_gpehandle;
|
acpi_handle ec_gpehandle;
|
||||||
uint8 ec_gpebit;
|
uint8 ec_gpebit;
|
||||||
|
|
||||||
int ec_data_pci_address;
|
int ec_data_pci_address;
|
||||||
int ec_csr_pci_address;
|
int ec_csr_pci_address;
|
||||||
|
|
||||||
int ec_glk;
|
int ec_glk;
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
@@ -205,7 +207,7 @@ EcLock(struct acpi_ec_cookie *sc)
|
|||||||
static void
|
static void
|
||||||
EcUnlock(struct acpi_ec_cookie *sc)
|
EcUnlock(struct acpi_ec_cookie *sc)
|
||||||
{
|
{
|
||||||
mutex_unlock(&sc->ec_lock);
|
mutex_unlock(&sc->ec_lock);
|
||||||
if (sc->ec_glk)
|
if (sc->ec_glk)
|
||||||
sc->ec_acpi_module->release_global_lock(sc->ec_glkhandle);
|
sc->ec_acpi_module->release_global_lock(sc->ec_glkhandle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,24 +22,24 @@
|
|||||||
# define TRACE(x) ;
|
# define TRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
device_manager_info *gDeviceManager = NULL;
|
|
||||||
pci_module_info *gPCIManager = NULL;
|
device_manager_info* gDeviceManager = NULL;
|
||||||
|
pci_module_info* gPCIManager = NULL;
|
||||||
dpc_module_info* gDPC = NULL;
|
dpc_module_info* gDPC = NULL;
|
||||||
|
|
||||||
module_dependency module_dependencies[] = {
|
module_dependency module_dependencies[] = {
|
||||||
{B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager},
|
{B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager},
|
||||||
{B_PCI_MODULE_NAME, (module_info **)&gPCIManager},
|
{B_PCI_MODULE_NAME, (module_info**)&gPCIManager},
|
||||||
{B_DPC_MODULE_NAME, (module_info **)&gDPC},
|
{B_DPC_MODULE_NAME, (module_info**)&gDPC},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -50,9 +51,8 @@ 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,27 +60,27 @@ 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
acpi_enumerate_child_devices(device_node *node, const char *root)
|
acpi_enumerate_child_devices(device_node* node, const char* root)
|
||||||
{
|
{
|
||||||
char result[255];
|
char result[255];
|
||||||
void *counter = NULL;
|
void* counter = NULL;
|
||||||
device_node *parent = NULL;
|
device_node* parent = NULL;
|
||||||
|
|
||||||
TRACE(("acpi_enumerate_child_devices: recursing from %s\n", root));
|
TRACE(("acpi_enumerate_child_devices: recursing from %s\n", 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;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACPI_TYPE_POWER:
|
case ACPI_TYPE_POWER:
|
||||||
@@ -113,8 +113,7 @@ 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:
|
||||||
@@ -129,22 +128,21 @@ 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, "\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
acpi_module_init(device_node *node, void **_cookie)
|
acpi_module_init(device_node* node, void** _cookie)
|
||||||
{
|
{
|
||||||
*_cookie = node;
|
*_cookie = node;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -152,7 +150,7 @@ acpi_module_init(device_node *node, void **_cookie)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_module_uninit(void *cookie)
|
acpi_module_uninit(void* cookie)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +161,7 @@ acpi_module_std_ops(int32 op, ...)
|
|||||||
switch (op) {
|
switch (op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT:
|
||||||
{
|
{
|
||||||
module_info *module;
|
module_info* module;
|
||||||
return get_module(B_ACPI_MODULE_NAME, &module);
|
return get_module(B_ACPI_MODULE_NAME, &module);
|
||||||
// this serializes our module initialization
|
// this serializes our module initialization
|
||||||
}
|
}
|
||||||
@@ -221,12 +219,13 @@ static struct acpi_root_info sACPIRootModule = {
|
|||||||
evaluate_method,
|
evaluate_method,
|
||||||
};
|
};
|
||||||
|
|
||||||
_EXPORT module_info *modules[] = {
|
|
||||||
(module_info *)&gACPIModule,
|
module_info* modules[] = {
|
||||||
(module_info *)&sACPIRootModule,
|
(module_info*)&gACPIModule,
|
||||||
(module_info *)&acpi_ns_dump_module,
|
(module_info*)&sACPIRootModule,
|
||||||
(module_info *)&gACPIDeviceModule,
|
(module_info*)&acpi_ns_dump_module,
|
||||||
(module_info*) &embedded_controller_driver_module,
|
(module_info*)&gACPIDeviceModule,
|
||||||
(module_info*) &embedded_controller_device_module,
|
(module_info*)&embedded_controller_driver_module,
|
||||||
|
(module_info*)&embedded_controller_device_module,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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,15 +24,17 @@ __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"
|
||||||
|
|
||||||
|
|
||||||
extern device_manager_info *gDeviceManager;
|
__BEGIN_DECLS
|
||||||
extern pci_module_info *gPCIManager;
|
|
||||||
|
extern device_manager_info* gDeviceManager;
|
||||||
|
extern pci_module_info* gPCIManager;
|
||||||
|
|
||||||
// information about one ACPI device
|
// information about one ACPI device
|
||||||
typedef struct acpi_device_cookie {
|
typedef struct acpi_device_cookie {
|
||||||
char *path; // path
|
char* path; // path
|
||||||
acpi_handle handle;
|
acpi_handle handle;
|
||||||
uint32 type; // type
|
uint32 type; // type
|
||||||
device_node *node;
|
device_node* node;
|
||||||
char name[32]; // name (for fast log)
|
char name[32]; // name (for fast log)
|
||||||
} acpi_device_cookie;
|
} acpi_device_cookie;
|
||||||
|
|
||||||
@@ -41,11 +43,11 @@ typedef struct acpi_device_cookie {
|
|||||||
typedef struct acpi_root_info {
|
typedef struct acpi_root_info {
|
||||||
driver_module_info info;
|
driver_module_info info;
|
||||||
|
|
||||||
status_t (*get_handle)(acpi_handle parent, char *pathname,
|
status_t (*get_handle)(acpi_handle parent, char* pathname,
|
||||||
acpi_handle *retHandle);
|
acpi_handle* retHandle);
|
||||||
|
|
||||||
/* Global Lock */
|
/* Global Lock */
|
||||||
status_t (*acquire_global_lock)(uint16 timeout, uint32 *handle);
|
status_t (*acquire_global_lock)(uint16 timeout, uint32* handle);
|
||||||
status_t (*release_global_lock)(uint32 handle);
|
status_t (*release_global_lock)(uint32 handle);
|
||||||
|
|
||||||
/* Notify Handler */
|
/* Notify Handler */
|
||||||
@@ -63,62 +65,60 @@ typedef struct acpi_root_info {
|
|||||||
status_t (*set_gpe_type)(acpi_handle handle, uint32 gpeNumber,
|
status_t (*set_gpe_type)(acpi_handle handle, uint32 gpeNumber,
|
||||||
uint8 type);
|
uint8 type);
|
||||||
status_t (*install_gpe_handler)(acpi_handle handle, uint32 gpeNumber,
|
status_t (*install_gpe_handler)(acpi_handle handle, uint32 gpeNumber,
|
||||||
uint32 type, acpi_event_handler handler, void *data);
|
uint32 type, acpi_event_handler handler, void* data);
|
||||||
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);
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
||||||
void (*enable_fixed_event) (uint32 event);
|
void (*enable_fixed_event)(uint32 event);
|
||||||
void (*disable_fixed_event) (uint32 event);
|
void (*disable_fixed_event)(uint32 event);
|
||||||
|
|
||||||
uint32 (*fixed_event_status) (uint32 event);
|
uint32 (*fixed_event_status)(uint32 event);
|
||||||
/* Returns 1 if event set, 0 otherwise */
|
/* Returns 1 if event set, 0 otherwise */
|
||||||
void (*reset_fixed_event) (uint32 event);
|
void (*reset_fixed_event)(uint32 event);
|
||||||
|
|
||||||
status_t (*install_fixed_event_handler)(uint32 event,
|
status_t (*install_fixed_event_handler)(uint32 event,
|
||||||
interrupt_handler *handler, void *data);
|
interrupt_handler* handler, void* data);
|
||||||
status_t (*remove_fixed_event_handler)(uint32 event,
|
status_t (*remove_fixed_event_handler)(uint32 event,
|
||||||
interrupt_handler *handler);
|
interrupt_handler* handler);
|
||||||
|
|
||||||
/* Namespace Access */
|
/* Namespace Access */
|
||||||
|
|
||||||
status_t (*get_next_entry)(uint32 object_type, const char *base,
|
status_t (*get_next_entry)(uint32 object_type, const char* base,
|
||||||
char *result, size_t len, void **counter);
|
char* result, size_t len, 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,
|
||||||
uint32 (*get_object_type)(const char *path);
|
size_t hidLength);
|
||||||
status_t (*get_object)(const char *path,
|
uint32 (*get_object_type)(const char* path);
|
||||||
acpi_object_type **_returnValue);
|
status_t (*get_object)(const char* path,
|
||||||
status_t (*get_object_typed)(const char *path,
|
acpi_object_type** _returnValue);
|
||||||
acpi_object_type **_returnValue, uint32 objectType);
|
status_t (*get_object_typed)(const char* path,
|
||||||
|
acpi_object_type** _returnValue, uint32 objectType);
|
||||||
status_t (*ns_handle_to_pathname)(acpi_handle targetHandle,
|
status_t (*ns_handle_to_pathname)(acpi_handle targetHandle,
|
||||||
acpi_data *buffer);
|
acpi_data* buffer);
|
||||||
|
|
||||||
/* Control method execution and data acquisition */
|
/* Control method execution and data acquisition */
|
||||||
|
|
||||||
status_t (*evaluate_object)(const char* object,
|
status_t (*evaluate_object)(const char* object,
|
||||||
acpi_object_type *returnValue, size_t bufferLength);
|
acpi_object_type* returnValue, size_t bufferLength);
|
||||||
status_t (*evaluate_method)(acpi_handle handle, const char *method,
|
status_t (*evaluate_method)(acpi_handle handle, const char* method,
|
||||||
acpi_objects *args, acpi_data *returnValue);
|
acpi_objects* args, acpi_data* returnValue);
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
|
|
||||||
@@ -132,26 +132,26 @@ extern struct device_module_info embedded_controller_device_module;
|
|||||||
extern acpi_device_module_info gACPIDeviceModule;
|
extern acpi_device_module_info gACPIDeviceModule;
|
||||||
|
|
||||||
|
|
||||||
status_t get_handle(acpi_handle parent, char *pathname, acpi_handle *retHandle);
|
status_t get_handle(acpi_handle parent, char* pathname, acpi_handle* retHandle);
|
||||||
|
|
||||||
status_t acquire_global_lock(uint16 timeout, uint32 *handle);
|
status_t acquire_global_lock(uint16 timeout, uint32* handle);
|
||||||
status_t release_global_lock(uint32 handle);
|
status_t release_global_lock(uint32 handle);
|
||||||
|
|
||||||
status_t install_notify_handler(acpi_handle device, uint32 handlerType,
|
status_t install_notify_handler(acpi_handle device, uint32 handlerType,
|
||||||
acpi_notify_handler handler, void *context);
|
acpi_notify_handler handler, void* context);
|
||||||
status_t remove_notify_handler(acpi_handle device, uint32 handlerType,
|
status_t remove_notify_handler(acpi_handle device, uint32 handlerType,
|
||||||
acpi_notify_handler handler);
|
acpi_notify_handler handler);
|
||||||
|
|
||||||
status_t enable_gpe(acpi_handle handle, uint32 gpeNumber, uint32 flags);
|
status_t enable_gpe(acpi_handle handle, uint32 gpeNumber, uint32 flags);
|
||||||
status_t set_gpe_type(acpi_handle handle, uint32 gpeNumber, uint8 type);
|
status_t set_gpe_type(acpi_handle handle, uint32 gpeNumber, uint8 type);
|
||||||
status_t install_gpe_handler(acpi_handle handle, uint32 gpeNumber, uint32 type,
|
status_t install_gpe_handler(acpi_handle handle, uint32 gpeNumber, uint32 type,
|
||||||
acpi_event_handler handler, void *data);
|
acpi_event_handler handler, void* data);
|
||||||
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);
|
||||||
@@ -160,29 +160,30 @@ void disable_fixed_event(uint32 event);
|
|||||||
uint32 fixed_event_status(uint32 event);
|
uint32 fixed_event_status(uint32 event);
|
||||||
void reset_fixed_event(uint32 event);
|
void reset_fixed_event(uint32 event);
|
||||||
|
|
||||||
status_t install_fixed_event_handler(uint32 event, interrupt_handler *handler,
|
status_t install_fixed_event_handler(uint32 event, interrupt_handler* handler,
|
||||||
void *data);
|
void* data);
|
||||||
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);
|
||||||
|
|
||||||
status_t evaluate_object(const char* object, acpi_object_type *returnValue,
|
status_t evaluate_object(const char* object, acpi_object_type* returnValue,
|
||||||
size_t bufferLength);
|
size_t bufferLength);
|
||||||
status_t evaluate_method(acpi_handle handle, const char *method,
|
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__ */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user