This source file includes following definitions.
- acpi_to_sfi_th
- sfi_to_acpi_th
- sfi_acpi_parse_xsdt
- sfi_acpi_init
- sfi_acpi_get_table
- sfi_acpi_put_table
- sfi_acpi_table_parse
- sfi_acpi_table_show
- sfi_acpi_sysfs_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 #define KMSG_COMPONENT "SFI"
60 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
61
62 #include <linux/kernel.h>
63 #include <linux/sfi_acpi.h>
64 #include "sfi_core.h"
65
66
67
68
69
70
71
72
73
74 static struct acpi_table_xsdt *xsdt_va __read_mostly;
75
76 #define XSDT_GET_NUM_ENTRIES(ptable, entry_type) \
77 ((ptable->header.length - sizeof(struct acpi_table_header)) / \
78 (sizeof(entry_type)))
79
80 static inline struct sfi_table_header *acpi_to_sfi_th(
81 struct acpi_table_header *th)
82 {
83 return (struct sfi_table_header *)th;
84 }
85
86 static inline struct acpi_table_header *sfi_to_acpi_th(
87 struct sfi_table_header *th)
88 {
89 return (struct acpi_table_header *)th;
90 }
91
92
93
94
95
96
97 static int __init sfi_acpi_parse_xsdt(struct sfi_table_header *th)
98 {
99 struct sfi_table_key key = SFI_ANY_KEY;
100 int tbl_cnt, i;
101 void *ret;
102
103 xsdt_va = (struct acpi_table_xsdt *)th;
104 tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
105 for (i = 0; i < tbl_cnt; i++) {
106 ret = sfi_check_table(xsdt_va->table_offset_entry[i], &key);
107 if (IS_ERR(ret)) {
108 disable_sfi();
109 return -1;
110 }
111 }
112
113 return 0;
114 }
115
116 int __init sfi_acpi_init(void)
117 {
118 struct sfi_table_key xsdt_key = { .sig = SFI_SIG_XSDT };
119
120 sfi_table_parse(SFI_SIG_XSDT, NULL, NULL, sfi_acpi_parse_xsdt);
121
122
123 xsdt_va = (struct acpi_table_xsdt *)sfi_get_table(&xsdt_key);
124 return 0;
125 }
126
127 static struct acpi_table_header *sfi_acpi_get_table(struct sfi_table_key *key)
128 {
129 u32 tbl_cnt, i;
130 void *ret;
131
132 tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
133 for (i = 0; i < tbl_cnt; i++) {
134 ret = sfi_check_table(xsdt_va->table_offset_entry[i], key);
135 if (!IS_ERR(ret) && ret)
136 return sfi_to_acpi_th(ret);
137 }
138
139 return NULL;
140 }
141
142 static void sfi_acpi_put_table(struct acpi_table_header *table)
143 {
144 sfi_put_table(acpi_to_sfi_th(table));
145 }
146
147
148
149
150
151
152 int sfi_acpi_table_parse(char *signature, char *oem_id, char *oem_table_id,
153 int(*handler)(struct acpi_table_header *))
154 {
155 struct acpi_table_header *table = NULL;
156 struct sfi_table_key key;
157 int ret = 0;
158
159 if (sfi_disabled)
160 return -1;
161
162 key.sig = signature;
163 key.oem_id = oem_id;
164 key.oem_table_id = oem_table_id;
165
166 table = sfi_acpi_get_table(&key);
167 if (!table)
168 return -EINVAL;
169
170 ret = handler(table);
171 sfi_acpi_put_table(table);
172 return ret;
173 }
174
175 static ssize_t sfi_acpi_table_show(struct file *filp, struct kobject *kobj,
176 struct bin_attribute *bin_attr, char *buf,
177 loff_t offset, size_t count)
178 {
179 struct sfi_table_attr *tbl_attr =
180 container_of(bin_attr, struct sfi_table_attr, attr);
181 struct acpi_table_header *th = NULL;
182 struct sfi_table_key key;
183 ssize_t cnt;
184
185 key.sig = tbl_attr->name;
186 key.oem_id = NULL;
187 key.oem_table_id = NULL;
188
189 th = sfi_acpi_get_table(&key);
190 if (!th)
191 return 0;
192
193 cnt = memory_read_from_buffer(buf, count, &offset,
194 th, th->length);
195 sfi_acpi_put_table(th);
196
197 return cnt;
198 }
199
200
201 void __init sfi_acpi_sysfs_init(void)
202 {
203 u32 tbl_cnt, i;
204 struct sfi_table_attr *tbl_attr;
205
206 tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64);
207 for (i = 0; i < tbl_cnt; i++) {
208 tbl_attr =
209 sfi_sysfs_install_table(xsdt_va->table_offset_entry[i]);
210 tbl_attr->attr.read = sfi_acpi_table_show;
211 }
212
213 return;
214 }