|
@@ -318,6 +318,45 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static
|
|
|
+struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
|
|
|
+ u32 *id_out, u8 type_mask,
|
|
|
+ int index)
|
|
|
+{
|
|
|
+ struct acpi_iort_node *parent;
|
|
|
+ struct acpi_iort_id_mapping *map;
|
|
|
+
|
|
|
+ if (!node->mapping_offset || !node->mapping_count ||
|
|
|
+ index >= node->mapping_count)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
|
|
|
+ node->mapping_offset);
|
|
|
+
|
|
|
+ /* Firmware bug! */
|
|
|
+ if (!map->output_reference) {
|
|
|
+ pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
|
|
|
+ node, node->type);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
|
|
|
+ map->output_reference);
|
|
|
+
|
|
|
+ if (!(IORT_TYPE_MASK(parent->type) & type_mask))
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
|
|
|
+ if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
|
|
|
+ node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
|
|
|
+ *id_out = map[index].output_base;
|
|
|
+ return parent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node,
|
|
|
u32 rid_in, u32 *rid_out,
|
|
|
u8 type_mask)
|