113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/* sfi_acpi.c Simple Firmware Interface - ACPI extensions */ 213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/* 413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang This file is provided under a dual BSD/GPLv2 license. When using or 613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang redistributing this file, you may do so under either license. 713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang GPL LICENSE SUMMARY 913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 1013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang Copyright(c) 2009 Intel Corporation. All rights reserved. 1113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 1213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang This program is free software; you can redistribute it and/or modify 1313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang it under the terms of version 2 of the GNU General Public License as 1413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang published by the Free Software Foundation. 1513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 1613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang This program is distributed in the hope that it will be useful, but 1713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang WITHOUT ANY WARRANTY; without even the implied warranty of 1813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang General Public License for more details. 2013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 2113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang You should have received a copy of the GNU General Public License 2213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang along with this program; if not, write to the Free Software 2313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 2413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang The full GNU General Public License is included in this distribution 2513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang in the file called LICENSE.GPL. 2613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 2713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang BSD LICENSE 2813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 2913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang Copyright(c) 2009 Intel Corporation. All rights reserved. 3013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 3113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang Redistribution and use in source and binary forms, with or without 3213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang modification, are permitted provided that the following conditions 3313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang are met: 3413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 3513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * Redistributions of source code must retain the above copyright 3613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang notice, this list of conditions and the following disclaimer. 3713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * Redistributions in binary form must reproduce the above copyright 3813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang notice, this list of conditions and the following disclaimer in 3913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang the documentation and/or other materials provided with the 4013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang distribution. 4113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * Neither the name of Intel Corporation nor the names of its 4213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang contributors may be used to endorse or promote products derived 4313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang from this software without specific prior written permission. 4413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 4513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 4613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 4713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 4813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 4913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 5013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 5113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 5213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 5313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 5513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 5713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang*/ 5813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 5913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#define KMSG_COMPONENT "SFI" 6013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 6113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 6213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include <linux/kernel.h> 6313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include <acpi/acpi.h> 6413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 6513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include <linux/sfi.h> 6613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#include "sfi_core.h" 6713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 6813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/* 6913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * SFI can access ACPI-defined tables via an optional ACPI XSDT. 7013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * 7113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * This allows re-use, and avoids re-definition, of standard tables. 7213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * For example, the "MCFG" table is defined by PCI, reserved by ACPI, 7313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * and is expected to be present many SFI-only systems. 7413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang */ 7513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 7613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic struct acpi_table_xsdt *xsdt_va __read_mostly; 7713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 7813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang#define XSDT_GET_NUM_ENTRIES(ptable, entry_type) \ 7913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang ((ptable->header.length - sizeof(struct acpi_table_header)) / \ 8013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang (sizeof(entry_type))) 8113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 8213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic inline struct sfi_table_header *acpi_to_sfi_th( 8313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang struct acpi_table_header *th) 8413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{ 8513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return (struct sfi_table_header *)th; 8613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang} 8713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 8813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic inline struct acpi_table_header *sfi_to_acpi_th( 8913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang struct sfi_table_header *th) 9013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{ 9113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return (struct acpi_table_header *)th; 9213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang} 9313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 9413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/* 9513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * sfi_acpi_parse_xsdt() 9613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * 9713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * Parse the ACPI XSDT for later access by sfi_acpi_table_parse(). 9813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang */ 9913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic int __init sfi_acpi_parse_xsdt(struct sfi_table_header *th) 10013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{ 10113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang struct sfi_table_key key = SFI_ANY_KEY; 10213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang int tbl_cnt, i; 10313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang void *ret; 10413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 10513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang xsdt_va = (struct acpi_table_xsdt *)th; 10613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64); 10713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang for (i = 0; i < tbl_cnt; i++) { 10813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang ret = sfi_check_table(xsdt_va->table_offset_entry[i], &key); 10913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang if (IS_ERR(ret)) { 11013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang disable_sfi(); 11113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return -1; 11213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang } 11313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang } 11413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 11513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return 0; 11613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang} 11713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 11813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangint __init sfi_acpi_init(void) 11913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{ 12013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang struct sfi_table_key xsdt_key = { .sig = SFI_SIG_XSDT }; 12113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 12213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang sfi_table_parse(SFI_SIG_XSDT, NULL, NULL, sfi_acpi_parse_xsdt); 12313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 12413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang /* Only call the get_table to keep the table mapped */ 12513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang xsdt_va = (struct acpi_table_xsdt *)sfi_get_table(&xsdt_key); 12613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return 0; 12713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang} 12813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 12913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic struct acpi_table_header *sfi_acpi_get_table(struct sfi_table_key *key) 13013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{ 13113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang u32 tbl_cnt, i; 13213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang void *ret; 13313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 13413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64); 13513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang for (i = 0; i < tbl_cnt; i++) { 13613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang ret = sfi_check_table(xsdt_va->table_offset_entry[i], key); 13713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang if (!IS_ERR(ret) && ret) 13813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return sfi_to_acpi_th(ret); 13913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang } 14013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 14113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return NULL; 14213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang} 14313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 14413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangstatic void sfi_acpi_put_table(struct acpi_table_header *table) 14513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{ 14613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang sfi_put_table(acpi_to_sfi_th(table)); 14713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang} 14813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 14913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang/* 15013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * sfi_acpi_table_parse() 15113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * 15213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang * Find specified table in XSDT, run handler on it and return its return value 15313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang */ 15413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tangint sfi_acpi_table_parse(char *signature, char *oem_id, char *oem_table_id, 15513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang int(*handler)(struct acpi_table_header *)) 15613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang{ 15713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang struct acpi_table_header *table = NULL; 15813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang struct sfi_table_key key; 15913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang int ret = 0; 16013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 16113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang if (sfi_disabled) 16213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return -1; 16313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 16413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang key.sig = signature; 16513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang key.oem_id = oem_id; 16613e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang key.oem_table_id = oem_table_id; 16713e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 16813e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang table = sfi_acpi_get_table(&key); 16913e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang if (!table) 17013e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return -EINVAL; 17113e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang 17213e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang ret = handler(table); 17313e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang sfi_acpi_put_table(table); 17413e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang return ret; 17513e82d023c4c3f13ab1e665cbb917a7ebba8935cFeng Tang} 176dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 177dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tangstatic ssize_t sfi_acpi_table_show(struct file *filp, struct kobject *kobj, 178dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang struct bin_attribute *bin_attr, char *buf, 179dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang loff_t offset, size_t count) 180dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang{ 181dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang struct sfi_table_attr *tbl_attr = 182dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang container_of(bin_attr, struct sfi_table_attr, attr); 183dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang struct acpi_table_header *th = NULL; 184dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang struct sfi_table_key key; 185dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang ssize_t cnt; 186dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 187dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang key.sig = tbl_attr->name; 188dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang key.oem_id = NULL; 189dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang key.oem_table_id = NULL; 190dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 191dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang th = sfi_acpi_get_table(&key); 192dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang if (!th) 193dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang return 0; 194dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 195dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang cnt = memory_read_from_buffer(buf, count, &offset, 196dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang th, th->length); 197dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang sfi_acpi_put_table(th); 198dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 199dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang return cnt; 200dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang} 201dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 202dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 203dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tangvoid __init sfi_acpi_sysfs_init(void) 204dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang{ 205dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang u32 tbl_cnt, i; 206dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang struct sfi_table_attr *tbl_attr; 207dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 208dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64); 209dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang for (i = 0; i < tbl_cnt; i++) { 210dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang tbl_attr = 211dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang sfi_sysfs_install_table(xsdt_va->table_offset_entry[i]); 212dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang tbl_attr->attr.read = sfi_acpi_table_show; 213dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang } 214dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang 215dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang return; 216dce80a56268fffd6b5ea57b3f6ba3d027a68f05eFeng Tang} 217