acpi: add ACPI_DEVICE_ADDR_ITEM and ACPI_DEVICE_CID_ITEM for device nodes
ACPI_DEVICE_HID_ITEM is now optional, instead of an empty string. Change-Id: I352ffaaad377659f650a0b8c0d56e40a68b739c3 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2420 Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
@@ -243,8 +243,8 @@ struct acpi_module_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,
|
status_t (*get_device_info)(const char *path, char** hid,
|
||||||
size_t hidLength);
|
char** cidList, size_t cidListLength);
|
||||||
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);
|
||||||
@@ -303,6 +303,8 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define ACPI_DEVICE_ADDR_ITEM "acpi/addr"
|
||||||
|
#define ACPI_DEVICE_CID_ITEM "acpi/cid"
|
||||||
#define ACPI_DEVICE_HID_ITEM "acpi/hid"
|
#define ACPI_DEVICE_HID_ITEM "acpi/hid"
|
||||||
#define ACPI_DEVICE_PATH_ITEM "acpi/path"
|
#define ACPI_DEVICE_PATH_ITEM "acpi/path"
|
||||||
#define ACPI_DEVICE_TYPE_ITEM "acpi/type"
|
#define ACPI_DEVICE_TYPE_ITEM "acpi/type"
|
||||||
|
|||||||
@@ -112,8 +112,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,
|
status_t (*get_device_info)(const char *path, char **hid,
|
||||||
size_t hidLength);
|
char** cidList, size_t cidListCount);
|
||||||
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);
|
||||||
@@ -213,7 +213,9 @@ status_t get_next_object(uint32 object_type, acpi_handle parent,
|
|||||||
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_info(const char* path, char** hid, char** cidList,
|
||||||
|
size_t cidListCount);
|
||||||
|
status_t get_device_addr(const char* path, uint32* addr);
|
||||||
uint32 get_object_type(const char* path);
|
uint32 get_object_type(const char* path);
|
||||||
status_t get_object(const char* path, acpi_object_type** _returnValue);
|
status_t get_object(const char* path, acpi_object_type** _returnValue);
|
||||||
status_t get_object_typed(const char* path, acpi_object_type** _returnValue,
|
status_t get_object_typed(const char* path, acpi_object_type** _returnValue,
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ extern "C" {
|
|||||||
|
|
||||||
#define ACPI_DEVICE_ID_LENGTH 0x08
|
#define ACPI_DEVICE_ID_LENGTH 0x08
|
||||||
|
|
||||||
extern pci_module_info* gPCIManager;
|
|
||||||
extern dpc_module_info* gDPC;
|
extern dpc_module_info* gDPC;
|
||||||
void* gDPCHandle = NULL;
|
void* gDPCHandle = NULL;
|
||||||
|
|
||||||
@@ -534,30 +533,60 @@ get_device(const char* hid, uint32 index, char* result, size_t resultLength)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
get_device_hid(const char *path, char *hid, size_t bufferLength)
|
get_device_info(const char *path, char** hid, char** cidList,
|
||||||
|
size_t cidListCount)
|
||||||
{
|
{
|
||||||
ACPI_HANDLE handle;
|
ACPI_HANDLE handle;
|
||||||
ACPI_DEVICE_INFO *info;
|
ACPI_DEVICE_INFO *info;
|
||||||
|
|
||||||
TRACE("get_device_hid: path %s, hid %s\n", path, hid);
|
TRACE("get_device_info: path %s\n", path);
|
||||||
if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK)
|
if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
if (bufferLength < ACPI_DEVICE_ID_LENGTH)
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
|
|
||||||
if (AcpiGetObjectInfo(handle, &info) != AE_OK)
|
if (AcpiGetObjectInfo(handle, &info) != AE_OK)
|
||||||
return B_BAD_TYPE;
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
if ((info->Valid & ACPI_VALID_HID) != 0)
|
if ((info->Valid & ACPI_VALID_HID) != 0 && hid != NULL)
|
||||||
strlcpy(hid, info->HardwareId.String, bufferLength);
|
*hid = strndup(info->HardwareId.String, info->HardwareId.Length);
|
||||||
else
|
|
||||||
hid[0] = '\0';
|
if ((info->Valid & ACPI_VALID_CID) != 0 && cidList != NULL) {
|
||||||
|
if (cidListCount > info->CompatibleIdList.Count)
|
||||||
|
cidListCount = info->CompatibleIdList.Count;
|
||||||
|
for (size_t i = 0; i < cidListCount; i++) {
|
||||||
|
cidList[i] = strndup(info->CompatibleIdList.Ids[i].String,
|
||||||
|
info->CompatibleIdList.Ids[i].Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AcpiOsFree(info);
|
AcpiOsFree(info);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
get_device_addr(const char *path, uint32 *addr)
|
||||||
|
{
|
||||||
|
ACPI_HANDLE handle;
|
||||||
|
|
||||||
|
TRACE("get_device_adr: path %s, hid %s\n", path, hid);
|
||||||
|
if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
status_t status = B_BAD_VALUE;
|
||||||
|
acpi_data buf;
|
||||||
|
acpi_object_type object;
|
||||||
|
buf.pointer = &object;
|
||||||
|
buf.length = sizeof(acpi_object_type);
|
||||||
|
if (addr != NULL
|
||||||
|
&& evaluate_method(handle, "_ADR", NULL, &buf) == B_OK
|
||||||
|
&& object.object_type == ACPI_TYPE_INTEGER) {
|
||||||
|
status = B_OK;
|
||||||
|
*addr = object.integer.integer;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
get_object_type(const char* path)
|
get_object_type(const char* path)
|
||||||
{
|
{
|
||||||
@@ -838,7 +867,7 @@ struct acpi_module_info gACPIModule = {
|
|||||||
get_next_entry,
|
get_next_entry,
|
||||||
get_next_object,
|
get_next_object,
|
||||||
get_device,
|
get_device,
|
||||||
get_device_hid,
|
get_device_info,
|
||||||
get_object_type,
|
get_object_type,
|
||||||
get_object,
|
get_object,
|
||||||
get_object_typed,
|
get_object_typed,
|
||||||
|
|||||||
@@ -86,8 +86,7 @@ acpi_enumerate_child_devices(device_node* node, const char* root)
|
|||||||
case ACPI_TYPE_PROCESSOR:
|
case ACPI_TYPE_PROCESSOR:
|
||||||
case ACPI_TYPE_THERMAL:
|
case ACPI_TYPE_THERMAL:
|
||||||
case ACPI_TYPE_DEVICE: {
|
case ACPI_TYPE_DEVICE: {
|
||||||
char hid[16] = "";
|
device_attr attrs[15] = {
|
||||||
device_attr attrs[] = {
|
|
||||||
// info about device
|
// info about device
|
||||||
{ B_DEVICE_BUS, B_STRING_TYPE, { string: "acpi" }},
|
{ B_DEVICE_BUS, B_STRING_TYPE, { string: "acpi" }},
|
||||||
|
|
||||||
@@ -95,24 +94,48 @@ acpi_enumerate_child_devices(device_node* node, const char* root)
|
|||||||
{ ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }},
|
{ ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }},
|
||||||
|
|
||||||
// info about the device
|
// info about the device
|
||||||
{ ACPI_DEVICE_HID_ITEM, B_STRING_TYPE, { string: hid }},
|
|
||||||
{ ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }},
|
{ ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }},
|
||||||
|
|
||||||
// consumer specification
|
{ B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_FIND_MULTIPLE_CHILDREN }},
|
||||||
/*{ B_DRIVER_MAPPING, B_STRING_TYPE, { string:
|
|
||||||
"hid_%" ACPI_DEVICE_HID_ITEM "%" }},
|
|
||||||
{ B_DRIVER_MAPPING "/0", B_STRING_TYPE, { string:
|
|
||||||
"type_%" ACPI_DEVICE_TYPE_ITEM "%" }},*/
|
|
||||||
{ B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: /*B_FIND_CHILD_ON_DEMAND|*/B_FIND_MULTIPLE_CHILDREN }},
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type == ACPI_TYPE_DEVICE)
|
uint32 attrCount = 4;
|
||||||
get_device_hid(result, hid, sizeof(hid));
|
char* hid = NULL;
|
||||||
|
char* cidList[8] = { NULL };
|
||||||
|
if (type == ACPI_TYPE_DEVICE) {
|
||||||
|
if (get_device_info(result, &hid, (char**)&cidList, 8)
|
||||||
|
== B_OK) {
|
||||||
|
if (hid != NULL) {
|
||||||
|
attrs[attrCount].name = ACPI_DEVICE_HID_ITEM;
|
||||||
|
attrs[attrCount].type = B_STRING_TYPE;
|
||||||
|
attrs[attrCount].value.string = hid;
|
||||||
|
attrCount++;
|
||||||
|
}
|
||||||
|
for (int i = 0; cidList[i] != NULL; i++) {
|
||||||
|
attrs[attrCount].name = ACPI_DEVICE_CID_ITEM;
|
||||||
|
attrs[attrCount].type = B_STRING_TYPE;
|
||||||
|
attrs[attrCount].value.string = cidList[i];
|
||||||
|
attrCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32 addr;
|
||||||
|
if (get_device_addr(result, &addr) == B_OK) {
|
||||||
|
attrs[attrCount].name = ACPI_DEVICE_ADDR_ITEM;
|
||||||
|
attrs[attrCount].type = B_UINT32_TYPE;
|
||||||
|
attrs[attrCount].value.ui32 = addr;
|
||||||
|
attrCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (gDeviceManager->register_node(node, ACPI_DEVICE_MODULE_NAME, attrs,
|
status_t status = gDeviceManager->register_node(node,
|
||||||
NULL, &deviceNode) == B_OK)
|
ACPI_DEVICE_MODULE_NAME, attrs, NULL, &deviceNode);
|
||||||
acpi_enumerate_child_devices(deviceNode, result);
|
free(hid);
|
||||||
|
for (int i = 0; cidList[i] != NULL; i++)
|
||||||
|
free(cidList[i]);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
acpi_enumerate_child_devices(deviceNode, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -253,7 +276,7 @@ static struct acpi_root_info sACPIRootModule = {
|
|||||||
get_next_entry,
|
get_next_entry,
|
||||||
get_next_object,
|
get_next_object,
|
||||||
get_device,
|
get_device,
|
||||||
get_device_hid,
|
get_device_info,
|
||||||
get_object_type,
|
get_object_type,
|
||||||
get_object,
|
get_object,
|
||||||
get_object_typed,
|
get_object_typed,
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ dump_acpi_namespace(acpi_ns_device_info *device, char *root, int indenting)
|
|||||||
char result[255];
|
char result[255];
|
||||||
char output[320];
|
char output[320];
|
||||||
char tabs[255] = "";
|
char tabs[255] = "";
|
||||||
char hid[16] = "";
|
|
||||||
int i;
|
int i;
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
for (i = 0; i < indenting; i++)
|
for (i = 0; i < indenting; i++)
|
||||||
@@ -114,12 +113,18 @@ dump_acpi_namespace(acpi_ns_device_info *device, char *root, int indenting)
|
|||||||
strlcat(output, " FIELD UNIT", sizeof(output));
|
strlcat(output, " FIELD UNIT", sizeof(output));
|
||||||
break;
|
break;
|
||||||
case ACPI_TYPE_DEVICE:
|
case ACPI_TYPE_DEVICE:
|
||||||
hid[0] = 0; /* zero-terminate string; get_device_hid can (and will) fail! */
|
{
|
||||||
device->acpi->get_device_hid(result, hid, sizeof(hid));
|
char* hid = NULL;
|
||||||
|
device->acpi->get_device_info(result, &hid, NULL, 0);
|
||||||
strlcat(output, " DEVICE (", sizeof(output));
|
strlcat(output, " DEVICE (", sizeof(output));
|
||||||
strlcat(output, hid, sizeof(output));
|
if (hid != NULL) {
|
||||||
|
strlcat(output, hid, sizeof(output));
|
||||||
|
free(hid);
|
||||||
|
} else
|
||||||
|
strlcat(output, "none", sizeof(output));
|
||||||
strlcat(output, ")", sizeof(output));
|
strlcat(output, ")", sizeof(output));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ACPI_TYPE_EVENT:
|
case ACPI_TYPE_EVENT:
|
||||||
strlcat(output, " EVENT", sizeof(output));
|
strlcat(output, " EVENT", sizeof(output));
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user