1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: tbfind - find table 5 * 6 * Copyright (C) 2000 - 2020, Intel Corp. 7 * 8 *****************************************************************************/ 9 10 #include <acpi/acpi.h> 11 #include "accommon.h" 12 #include "actables.h" 13 14 #define _COMPONENT ACPI_TABLES 15 ACPI_MODULE_NAME("tbfind") 16 17 /******************************************************************************* 18 * 19 * FUNCTION: acpi_tb_find_table 20 * 21 * PARAMETERS: signature - String with ACPI table signature 22 * oem_id - String with the table OEM ID 23 * oem_table_id - String with the OEM Table ID 24 * table_index - Where the table index is returned 25 * 26 * RETURN: Status and table index 27 * 28 * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the 29 * Signature, OEM ID and OEM Table ID. Returns an index that can 30 * be used to get the table header or entire table. 31 * 32 ******************************************************************************/ 33 acpi_status 34 acpi_tb_find_table(char *signature, 35 char *oem_id, char *oem_table_id, u32 *table_index) 36 { 37 acpi_status status = AE_OK; 38 struct acpi_table_header header; 39 u32 i; 40 41 ACPI_FUNCTION_TRACE(tb_find_table); 42 43 /* Validate the input table signature */ 44 45 if (!acpi_ut_valid_nameseg(signature)) { 46 return_ACPI_STATUS(AE_BAD_SIGNATURE); 47 } 48 49 /* Don't allow the OEM strings to be too long */ 50 51 if ((strlen(oem_id) > ACPI_OEM_ID_SIZE) || 52 (strlen(oem_table_id) > ACPI_OEM_TABLE_ID_SIZE)) { 53 return_ACPI_STATUS(AE_AML_STRING_LIMIT); 54 } 55 56 /* Normalize the input strings */ 57 58 memset(&header, 0, sizeof(struct acpi_table_header)); 59 ACPI_COPY_NAMESEG(header.signature, signature); 60 strncpy(header.oem_id, oem_id, ACPI_OEM_ID_SIZE); 61 strncpy(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE); 62 63 /* Search for the table */ 64 65 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 66 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { 67 if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature), 68 header.signature, ACPI_NAMESEG_SIZE)) { 69 70 /* Not the requested table */ 71 72 continue; 73 } 74 75 /* Table with matching signature has been found */ 76 77 if (!acpi_gbl_root_table_list.tables[i].pointer) { 78 79 /* Table is not currently mapped, map it */ 80 81 status = 82 acpi_tb_validate_table(&acpi_gbl_root_table_list. 83 tables[i]); 84 if (ACPI_FAILURE(status)) { 85 goto unlock_and_exit; 86 } 87 88 if (!acpi_gbl_root_table_list.tables[i].pointer) { 89 continue; 90 } 91 } 92 93 /* Check for table match on all IDs */ 94 95 if (!memcmp 96 (acpi_gbl_root_table_list.tables[i].pointer->signature, 97 header.signature, ACPI_NAMESEG_SIZE) && (!oem_id[0] 98 || 99 !memcmp 100 (acpi_gbl_root_table_list. 101 tables[i]. 102 pointer->oem_id, 103 header.oem_id, 104 ACPI_OEM_ID_SIZE)) 105 && (!oem_table_id[0] 106 || !memcmp(acpi_gbl_root_table_list.tables[i].pointer-> 107 oem_table_id, header.oem_table_id, 108 ACPI_OEM_TABLE_ID_SIZE))) { 109 *table_index = i; 110 111 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, 112 "Found table [%4.4s]\n", 113 header.signature)); 114 goto unlock_and_exit; 115 } 116 } 117 status = AE_NOT_FOUND; 118 119 unlock_and_exit: 120 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 121 return_ACPI_STATUS(status); 122 } 123