Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp7285571imu; Wed, 14 Nov 2018 14:53:59 -0800 (PST) X-Google-Smtp-Source: AJdET5dQoPI7p2AwLg+IjtWujfGVtsgYeYHzEokdnLcAfm0/jTJ5pqbx4mG5ZCcksTevu3fnukXp X-Received: by 2002:a17:902:1681:: with SMTP id h1-v6mr3734733plh.170.1542236038980; Wed, 14 Nov 2018 14:53:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542236038; cv=none; d=google.com; s=arc-20160816; b=vK3K9xnKcYGxyuUBlFh0EiOpR/DViblbQcu7yYbCAmPCC1+jxQxWIoXNbh1J667yKo ePnAwDxcu7eJ6BgPU4LfM+rLOMM72RipD74iDs30AlSKhabn/cNgLK7VCcI+IWsszHm3 WIdOJX0t0ez8ZIf8je+vVang/CA0YwGDZz16u3fONi1SZ9InWn49P7tWWCSq4QSNPTxb YblkvWLcnP3F9Fi00s7qgXQpjC8NN4jJDBCGWQhxru5nJwa5bCaX0+OQDRQ/F9hhDhug ijOYxmp+kAf9JRPUrFQotH1PQXbwWidw6fKmDYJ0Ids1L8odW42avm/bvmGILKEQK8IV Or+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=bLMs4Au7DiESCDOxLKd8+oMw9C/A5EHH/t0scKwgs+c=; b=ip7/cNjWVjUniUL8qH1BuItKQahU67UAxwwiOsshsmYdeHbD8//ugIn7qGMtRfIR0k bZyfanud4tXRp90GwJkEfsKv6dLxhbTj9Ze+W6s7clyiImrGxNySs8pP0K/9Jo6F8FGa e7bwuJ0KpAcFK/hIz5QSatCvptAQzdUVHOlt1OiyK2c5VW4Vap0NVCPcLrB+5FykJJ9u hRASb8lHXfkd9hFYyTOE7vzLAEUJEmK9Y1I6X8IxM7hJyfppg8qRInIrUF6ilD74FDnc 5YB1xSqkFT3cK73mq0GOJspqNE0iu4FaYoUfHEdqXtIc8uvpnfh32DVoIXbFBHMUMsYi Ps7w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p3si24871868pgi.0.2018.11.14.14.53.44; Wed, 14 Nov 2018 14:53:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728490AbeKOI6V (ORCPT + 99 others); Thu, 15 Nov 2018 03:58:21 -0500 Received: from mga12.intel.com ([192.55.52.136]:50988 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727086AbeKOI6U (ORCPT ); Thu, 15 Nov 2018 03:58:20 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Nov 2018 14:53:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,234,1539673200"; d="scan'208";a="106314894" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.69]) by fmsmga004.fm.intel.com with ESMTP; 14 Nov 2018 14:53:04 -0800 From: Keith Busch To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org Cc: Greg Kroah-Hartman , Rafael Wysocki , Dave Hansen , Dan Williams , Keith Busch Subject: [PATCH 6/7] acpi: Create subtable parsing infrastructure Date: Wed, 14 Nov 2018 15:49:19 -0700 Message-Id: <20181114224921.12123-7-keith.busch@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20181114224921.12123-2-keith.busch@intel.com> References: <20181114224921.12123-2-keith.busch@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Parsing entries in an ACPI table had assumed a generic header structure that is most common. There is no standard ACPI header, though, so less common types would need custom parsers if they want go walk their subtable entry list. Create the infrastructure for adding different table types so parsing the entries array may be more reused for all ACPI system tables. Signed-off-by: Keith Busch --- drivers/acpi/tables.c | 75 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 61203eebf3a1..15ee77780f68 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -49,6 +49,19 @@ static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; static int acpi_apic_instance __initdata; +enum acpi_subtable_type { + ACPI_SUBTABLE_COMMON, +}; + +union acpi_subtable_headers { + struct acpi_subtable_header common; +}; + +struct acpi_subtable_entry { + union acpi_subtable_headers *hdr; + enum acpi_subtable_type type; +}; + /* * Disable table checksum verification for the early stage due to the size * limitation of the current x86 early mapping implementation. @@ -217,6 +230,45 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } } +static unsigned long __init +acpi_get_entry_type(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return entry->hdr->common.type; + } + WARN_ONCE(1, "invalid acpi type\n"); + return 0; +} + +static unsigned long __init +acpi_get_entry_length(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return entry->hdr->common.length; + } + WARN_ONCE(1, "invalid acpi type\n"); + return 0; +} + +static unsigned long __init +acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return sizeof(entry->hdr->common); + } + WARN_ONCE(1, "invalid acpi type\n"); + return 0; +} + +static enum acpi_subtable_type __init +acpi_get_subtable_type(char *id) +{ + return ACPI_SUBTABLE_COMMON; +} + /** * acpi_parse_entries_array - for each proc_num find a suitable subtable * @@ -246,8 +298,8 @@ acpi_parse_entries_array(char *id, unsigned long table_size, struct acpi_subtable_proc *proc, int proc_num, unsigned int max_entries) { - struct acpi_subtable_header *entry; - unsigned long table_end; + struct acpi_subtable_entry entry; + unsigned long table_end, subtable_len, entry_len; int count = 0; int errs = 0; int i; @@ -270,19 +322,21 @@ acpi_parse_entries_array(char *id, unsigned long table_size, /* Parse all entries looking for a match. */ - entry = (struct acpi_subtable_header *) + entry.type = acpi_get_subtable_type(id); + entry.hdr = (union acpi_subtable_headers *) ((unsigned long)table_header + table_size); + subtable_len = acpi_get_subtable_header_length(&entry); - while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < - table_end) { + while (((unsigned long)entry.hdr) + subtable_len < table_end) { if (max_entries && count >= max_entries) break; for (i = 0; i < proc_num; i++) { - if (entry->type != proc[i].id) + if (acpi_get_entry_type(&entry) != proc[i].id) continue; if (!proc[i].handler || - (!errs && proc[i].handler(entry, table_end))) { + (!errs && proc[i].handler(&entry.hdr->common, + table_end))) { errs++; continue; } @@ -297,13 +351,14 @@ acpi_parse_entries_array(char *id, unsigned long table_size, * If entry->length is 0, break from this loop to avoid * infinite loop. */ - if (entry->length == 0) { + entry_len = acpi_get_entry_length(&entry); + if (entry_len == 0) { pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id); return -EINVAL; } - entry = (struct acpi_subtable_header *) - ((unsigned long)entry + entry->length); + entry.hdr = (union acpi_subtable_headers *) + ((unsigned long)entry.hdr + entry_len); } if (max_entries && count > max_entries) { -- 2.14.4