Print this page
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/i86pc/io/acpi/acpidev/acpidev_container.c
+++ new/usr/src/uts/i86pc/io/acpi/acpidev/acpidev_container.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25 /*
26 26 * Copyright (c) 2009-2010, Intel Corporation.
27 27 * All rights reserved.
28 28 */
29 29
30 30 /*
31 31 * There are three types of container objects defined in the ACPI Spec as below.
32 32 * PNP0A05: Generic Container Device
33 33 * A device whose settings are totally controlled by its ACPI resource
34 34 * information, and otherwise needs no device or bus-specific driver support.
35 35 * This was originally known as Generic ISA Bus Device.
36 36 * This ID should only be used for containers that do not produce resources
37 37 * for consumption by child devices. Any system resources claimed by a PNP0A05
38 38 * device's _CRS object must be consumed by the container itself.
39 39 * PNP0A06: Generic Container Device
40 40 * This device behaves exactly the same as the PNP0A05 device.
41 41 * This was originally known as Extended I/O Bus.
42 42 * This ID should only be used for containers that do not produce resources
43 43 * for consumption by child devices. Any system resources claimed by a PNP0A06
44 44 * device's _CRS object must be consumed by the container itself.
45 45 * ACPI0004: Module Device.
46 46 * This device is a container object that acts as a bus node in a namespace.
47 47 * A Module Device without any of the _CRS, _PRS and _SRS methods behaves
48 48 * the same way as the Generic Container Devices (PNP0A05 or PNP0A06).
49 49 * If the Module Device contains a _CRS method, only the resources
↓ open down ↓ |
49 lines elided |
↑ open up ↑ |
50 50 * described in the _CRS are available for consumption by its child devices.
51 51 * Also, the Module Device can support _PRS and _SRS methods if _CRS is
52 52 * supported.
53 53 */
54 54
55 55 #include <sys/types.h>
56 56 #include <sys/atomic.h>
57 57 #include <sys/note.h>
58 58 #include <sys/sunddi.h>
59 59 #include <sys/sunndi.h>
60 -#include <sys/acpi/acpi.h>
60 +#include <acpica/include/acpi.h>
61 61 #include <sys/acpica.h>
62 62 #include <sys/acpidev.h>
63 63 #include <sys/acpidev_dr.h>
64 64 #include <sys/acpidev_impl.h>
65 65
66 66 static ACPI_STATUS acpidev_container_probe(acpidev_walk_info_t *infop);
67 67 static acpidev_filter_result_t acpidev_container_filter(
68 68 acpidev_walk_info_t *infop, char *devname, int maxlen);
69 69 static ACPI_STATUS acpidev_container_init(acpidev_walk_info_t *infop);
70 70 static acpidev_filter_result_t acpidev_container_filter_func(
71 71 acpidev_walk_info_t *infop, ACPI_HANDLE hdl, acpidev_filter_rule_t *rulep,
72 72 char *devname, int devnamelen);
73 73
74 74 /*
75 75 * Default class driver for ACPI container objects.
76 76 */
77 77 acpidev_class_t acpidev_class_container = {
78 78 0, /* adc_refcnt */
79 79 ACPIDEV_CLASS_REV1, /* adc_version */
80 80 ACPIDEV_CLASS_ID_CONTAINER, /* adc_class_id */
81 81 "ACPI Container", /* adc_class_name */
82 82 ACPIDEV_TYPE_CONTAINER, /* adc_dev_type */
83 83 NULL, /* adc_private */
84 84 NULL, /* adc_pre_probe */
85 85 NULL, /* adc_post_probe */
86 86 acpidev_container_probe, /* adc_probe */
87 87 acpidev_container_filter, /* adc_filter */
88 88 acpidev_container_init, /* adc_init */
89 89 NULL, /* adc_fini */
90 90 };
91 91
92 92 static char *acpidev_container_device_ids[] = {
93 93 ACPIDEV_HID_MODULE,
94 94 ACPIDEV_HID_CONTAINER1,
95 95 ACPIDEV_HID_CONTAINER2,
96 96 };
97 97
98 98 static char *acpidev_container_uid_formats[] = {
99 99 "CPUSCK%x",
100 100 };
101 101
102 102 /* Filter rule table for container objects. */
103 103 static acpidev_filter_rule_t acpidev_container_filters[] = {
104 104 { /* Ignore all container objects under ACPI root object */
105 105 NULL,
106 106 0,
107 107 ACPIDEV_FILTER_SKIP,
108 108 NULL,
109 109 1,
110 110 1,
111 111 NULL,
112 112 NULL,
113 113 },
114 114 { /* Create node and scan child for all other container objects */
115 115 acpidev_container_filter_func,
116 116 0,
117 117 ACPIDEV_FILTER_DEFAULT,
118 118 &acpidev_class_list_device,
119 119 2,
120 120 INT_MAX,
121 121 NULL,
122 122 ACPIDEV_NODE_NAME_CONTAINER,
123 123 }
124 124 };
125 125
126 126 static ACPI_STATUS
127 127 acpidev_container_probe(acpidev_walk_info_t *infop)
128 128 {
129 129 ACPI_STATUS rc = AE_OK;
130 130 int flags;
131 131
132 132 ASSERT(infop != NULL);
133 133 ASSERT(infop->awi_hdl != NULL);
134 134 ASSERT(infop->awi_info != NULL);
135 135
136 136 if (infop->awi_info->Type != ACPI_TYPE_DEVICE ||
137 137 acpidev_match_device_id(infop->awi_info,
138 138 ACPIDEV_ARRAY_PARAM(acpidev_container_device_ids)) == 0) {
139 139 return (AE_OK);
140 140 }
141 141
142 142 flags = ACPIDEV_PROCESS_FLAG_SCAN;
143 143 switch (infop->awi_op_type) {
144 144 case ACPIDEV_OP_BOOT_PROBE:
145 145 if (acpica_get_devcfg_feature(ACPI_DEVCFG_CONTAINER)) {
146 146 flags |= ACPIDEV_PROCESS_FLAG_CREATE;
147 147 acpidev_dr_check(infop);
148 148 }
149 149 break;
150 150
151 151 case ACPIDEV_OP_BOOT_REPROBE:
152 152 break;
153 153
154 154 case ACPIDEV_OP_HOTPLUG_PROBE:
155 155 if (acpica_get_devcfg_feature(ACPI_DEVCFG_CONTAINER)) {
156 156 flags |= ACPIDEV_PROCESS_FLAG_CREATE |
157 157 ACPIDEV_PROCESS_FLAG_SYNCSTATUS |
158 158 ACPIDEV_PROCESS_FLAG_HOLDBRANCH;
159 159 }
160 160 break;
161 161
162 162 default:
163 163 ACPIDEV_DEBUG(CE_WARN, "!acpidev: unknown operation type %u in "
164 164 "acpidev_container_probe().", infop->awi_op_type);
165 165 rc = AE_BAD_PARAMETER;
166 166 break;
167 167 }
168 168
169 169 if (rc == AE_OK) {
170 170 rc = acpidev_process_object(infop, flags);
171 171 }
172 172 if (ACPI_FAILURE(rc) && rc != AE_NOT_EXIST && rc != AE_ALREADY_EXISTS) {
173 173 cmn_err(CE_WARN,
174 174 "!acpidev: failed to process container object %s.",
175 175 infop->awi_name);
176 176 } else {
177 177 rc = AE_OK;
178 178 }
179 179
180 180 return (rc);
181 181 }
182 182
183 183 static ACPI_STATUS
184 184 acpidev_container_search_dev(ACPI_HANDLE hdl, UINT32 lvl, void *ctx,
185 185 void **retval)
186 186 {
187 187 _NOTE(ARGUNUSED(hdl, retval));
188 188
189 189 int *fp = (int *)ctx;
190 190
191 191 *fp = lvl;
192 192
193 193 return (AE_CTRL_TERMINATE);
194 194 }
195 195
196 196 static acpidev_filter_result_t
197 197 acpidev_container_filter_func(acpidev_walk_info_t *infop, ACPI_HANDLE hdl,
198 198 acpidev_filter_rule_t *rulep, char *devname, int devnamelen)
199 199 {
200 200 ACPI_BUFFER buf;
201 201 void *retval;
202 202 int proc_lvl, cpu_lvl, module_lvl;
203 203 acpidev_filter_result_t res;
204 204 static char *cpu_hids[] = {
205 205 ACPIDEV_HID_CPU,
206 206 };
207 207 static char *module_hids[] = {
208 208 ACPIDEV_HID_MODULE,
209 209 };
210 210
211 211 res = acpidev_filter_default(infop, hdl, rulep, devname, devnamelen);
212 212 /* Return if we don't need to generate a device name. */
213 213 if (devname == NULL || res == ACPIDEV_FILTER_FAILED ||
214 214 res == ACPIDEV_FILTER_SKIP) {
215 215 return (res);
216 216 }
217 217
218 218 /* Try to figure out the most specific device name for the object. */
219 219 retval = NULL;
220 220 proc_lvl = INT_MAX;
221 221 cpu_lvl = INT_MAX;
222 222 module_lvl = INT_MAX;
223 223
224 224 /* Search for ACPI Processor object. */
225 225 (void) AcpiWalkNamespace(ACPI_TYPE_PROCESSOR, hdl, 2,
226 226 acpidev_container_search_dev, NULL, &proc_lvl, &retval);
227 227
228 228 /* Search for CPU Device object. */
229 229 (void) acpidev_get_device_by_id(hdl, ACPIDEV_ARRAY_PARAM(cpu_hids), 2,
230 230 B_FALSE, acpidev_container_search_dev, &cpu_lvl, &retval);
231 231
232 232 /* Search for Module Device object. */
233 233 (void) acpidev_get_device_by_id(hdl, ACPIDEV_ARRAY_PARAM(module_hids),
234 234 2, B_FALSE, acpidev_container_search_dev, &module_lvl, &retval);
235 235
236 236 buf.Pointer = devname;
237 237 buf.Length = devnamelen;
238 238 if (cpu_lvl > proc_lvl) {
239 239 cpu_lvl = proc_lvl;
240 240 }
241 241 if (cpu_lvl == 1) {
242 242 /* CPU as child, most likely a physical CPU. */
243 243 (void) strlcpy(devname, ACPIDEV_NODE_NAME_MODULE_CPU,
244 244 devnamelen);
245 245 } else if (cpu_lvl == 2 && module_lvl == 1) {
246 246 /* CPU as grandchild, most likely a system board. */
247 247 (void) strlcpy(devname, ACPIDEV_NODE_NAME_MODULE_SBD,
248 248 devnamelen);
249 249 } else if (ACPI_FAILURE(AcpiGetName(infop->awi_hdl,
250 250 ACPI_SINGLE_NAME, &buf))) {
251 251 /*
252 252 * Failed to get ACPI object name; use ACPI object name
253 253 * as the default name.
254 254 */
255 255 (void) strlcpy(devname, ACPIDEV_NODE_NAME_CONTAINER,
256 256 devnamelen);
257 257 }
258 258
259 259 return (res);
260 260 }
261 261
262 262 static acpidev_filter_result_t
263 263 acpidev_container_filter(acpidev_walk_info_t *infop, char *devname, int maxlen)
264 264 {
265 265 acpidev_filter_result_t res;
266 266
267 267 ASSERT(infop != NULL);
268 268 if (infop->awi_op_type == ACPIDEV_OP_BOOT_PROBE ||
269 269 infop->awi_op_type == ACPIDEV_OP_BOOT_REPROBE ||
270 270 infop->awi_op_type == ACPIDEV_OP_HOTPLUG_PROBE) {
271 271 res = acpidev_filter_device(infop, infop->awi_hdl,
272 272 ACPIDEV_ARRAY_PARAM(acpidev_container_filters),
273 273 devname, maxlen);
274 274 } else {
275 275 res = ACPIDEV_FILTER_FAILED;
276 276 }
277 277
278 278 return (res);
279 279 }
280 280
281 281 static ACPI_STATUS
282 282 acpidev_container_init(acpidev_walk_info_t *infop)
283 283 {
284 284 static char *compatible[] = {
285 285 ACPIDEV_TYPE_CONTAINER,
286 286 ACPIDEV_HID_VIRTNEX,
287 287 ACPIDEV_TYPE_VIRTNEX,
288 288 };
289 289
290 290 ASSERT(infop != NULL);
291 291 ASSERT(infop->awi_hdl != NULL);
292 292 ASSERT(infop->awi_dip != NULL);
293 293
294 294 if (ACPI_FAILURE(acpidev_set_compatible(infop,
295 295 ACPIDEV_ARRAY_PARAM(compatible)))) {
296 296 return (AE_ERROR);
297 297 }
298 298 if (ACPI_FAILURE(acpidev_set_unitaddr(infop,
299 299 ACPIDEV_ARRAY_PARAM(acpidev_container_uid_formats), NULL))) {
300 300 return (AE_ERROR);
301 301 }
302 302
303 303 return (AE_OK);
304 304 }
↓ open down ↓ |
234 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX