提交 b7a69806 编写于 作者: B Bob Moore 提交者: Len Brown

ACPICA: _CID support for PCI Root Bridge detection.

Implemented _CID support for PCI Root Bridge detection. If the _HID
does not match the predefined root bridge IDs, the _CID list (if present)
 is now obtained and also checked for an ID match
Signed-off-by: NAlexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: NLen Brown <len.brown@intel.com>
上级 d1fdda83
...@@ -48,6 +48,11 @@ ...@@ -48,6 +48,11 @@
#define _COMPONENT ACPI_EVENTS #define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evrgnini") ACPI_MODULE_NAME("evrgnini")
/* Local prototypes */
static u8 acpi_ev_match_pci_root_bridge(char *id);
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_system_memory_region_setup * FUNCTION: acpi_ev_system_memory_region_setup
...@@ -62,6 +67,7 @@ ACPI_MODULE_NAME("evrgnini") ...@@ -62,6 +67,7 @@ ACPI_MODULE_NAME("evrgnini")
* DESCRIPTION: Setup a system_memory operation region * DESCRIPTION: Setup a system_memory operation region
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ev_system_memory_region_setup(acpi_handle handle, acpi_ev_system_memory_region_setup(acpi_handle handle,
u32 function, u32 function,
...@@ -168,9 +174,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, ...@@ -168,9 +174,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
union acpi_operand_object *handler_obj; union acpi_operand_object *handler_obj;
struct acpi_namespace_node *parent_node; struct acpi_namespace_node *parent_node;
struct acpi_namespace_node *pci_root_node; struct acpi_namespace_node *pci_root_node;
struct acpi_namespace_node *pci_device_node;
union acpi_operand_object *region_obj = union acpi_operand_object *region_obj =
(union acpi_operand_object *)handle; (union acpi_operand_object *)handle;
struct acpi_device_id object_hID;
ACPI_FUNCTION_TRACE(ev_pci_config_region_setup); ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);
...@@ -215,27 +221,14 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, ...@@ -215,27 +221,14 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
pci_root_node = parent_node; pci_root_node = parent_node;
while (pci_root_node != acpi_gbl_root_node) { while (pci_root_node != acpi_gbl_root_node) {
status =
acpi_ut_execute_HID(pci_root_node, &object_hID); /* Get the _HID/_CID in order to detect a root_bridge */
if (ACPI_SUCCESS(status)) {
/* if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
* Got a valid _HID string, check if this is a PCI root.
* New for ACPI 3.0: check for a PCI Express root also.
*/
if (!
(ACPI_STRNCMP
(object_hID.value, PCI_ROOT_HID_STRING,
sizeof(PCI_ROOT_HID_STRING)))
||
!(ACPI_STRNCMP
(object_hID.value,
PCI_EXPRESS_ROOT_HID_STRING,
sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
/* Install a handler for this PCI root bridge */ /* Install a handler for this PCI root bridge */
status = status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
if (status == AE_SAME_HANDLER) { if (status == AE_SAME_HANDLER) {
/* /*
...@@ -245,8 +238,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, ...@@ -245,8 +238,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
*/ */
status = AE_OK; status = AE_OK;
} else { } else {
ACPI_EXCEPTION((AE_INFO, ACPI_EXCEPTION((AE_INFO, status,
status,
"Could not install PciConfig handler for Root Bridge %4.4s", "Could not install PciConfig handler for Root Bridge %4.4s",
acpi_ut_get_node_name acpi_ut_get_node_name
(pci_root_node))); (pci_root_node)));
...@@ -254,7 +246,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, ...@@ -254,7 +246,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
} }
break; break;
} }
}
pci_root_node = acpi_ns_get_parent_node(pci_root_node); pci_root_node = acpi_ns_get_parent_node(pci_root_node);
} }
...@@ -282,14 +273,25 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, ...@@ -282,14 +273,25 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
/* /*
* For PCI_Config space access, we need the segment, bus, * For PCI_Config space access, we need the segment, bus,
* device and function numbers. Acquire them here. * device and function numbers. Acquire them here.
*
* Find the parent device object. (This allows the operation region to be
* within a subscope under the device, such as a control method.)
*/ */
pci_device_node = region_obj->region.node;
while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
pci_device_node = acpi_ns_get_parent_node(pci_device_node);
}
if (!pci_device_node) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
/* /*
* Get the PCI device and function numbers from the _ADR object * Get the PCI device and function numbers from the _ADR object
* contained in the parent's scope. * contained in the parent's scope.
*/ */
status = status =
acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node, acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
&pci_value); &pci_value);
/* /*
...@@ -327,6 +329,91 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, ...@@ -327,6 +329,91 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ev_match_pci_root_bridge
*
* PARAMETERS: Id - The HID/CID in string format
*
* RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
*
* DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
*
******************************************************************************/
static u8 acpi_ev_match_pci_root_bridge(char *id)
{
/*
* Check if this is a PCI root.
* ACPI 3.0+: check for a PCI Express root also.
*/
if (!(ACPI_STRNCMP(id,
PCI_ROOT_HID_STRING,
sizeof(PCI_ROOT_HID_STRING))) ||
!(ACPI_STRNCMP(id,
PCI_EXPRESS_ROOT_HID_STRING,
sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
return (TRUE);
}
return (FALSE);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_is_pci_root_bridge
*
* PARAMETERS: Node - Device node being examined
*
* RETURN: TRUE if device is a PCI/PCI-Express Root Bridge
*
* DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
* examining the _HID and _CID for the device.
*
******************************************************************************/
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
{
acpi_status status;
struct acpi_device_id hid;
struct acpi_compatible_id_list *cid;
acpi_native_uint i;
/*
* Get the _HID and check for a PCI Root Bridge
*/
status = acpi_ut_execute_HID(node, &hid);
if (ACPI_FAILURE(status)) {
return (FALSE);
}
if (acpi_ev_match_pci_root_bridge(hid.value)) {
return (TRUE);
}
/*
* The _HID did not match.
* Get the _CID and check for a PCI Root Bridge
*/
status = acpi_ut_execute_CID(node, &cid);
if (ACPI_FAILURE(status)) {
return (FALSE);
}
/* Check all _CIDs in the returned list */
for (i = 0; i < cid->count; i++) {
if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) {
ACPI_FREE(cid);
return (TRUE);
}
}
ACPI_FREE(cid);
return (FALSE);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_pci_bar_region_setup * FUNCTION: acpi_ev_pci_bar_region_setup
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册