Print this page
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/pciex/pcie_acpi.c
+++ new/usr/src/uts/intel/io/pciex/pcie_acpi.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 #include <sys/sysmacros.h>
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
26 26 #include <sys/types.h>
27 27 #include <sys/kmem.h>
28 28 #include <sys/ddi.h>
29 29 #include <sys/sunddi.h>
30 30 #include <sys/sunndi.h>
31 31 #include <sys/promif.h>
32 32 #include <sys/pcie.h>
33 33 #include <sys/pci_cap.h>
34 34 #include <sys/pcie_impl.h>
35 35 #include <sys/pcie_acpi.h>
36 -#include <sys/acpi/acpi.h>
36 +#include <acpica/include/acpi.h>
37 37 #include <sys/acpica.h>
38 38
39 39 ACPI_STATUS pcie_acpi_eval_osc(dev_info_t *dip, ACPI_HANDLE osc_hdl,
40 40 uint32_t *osc_flags);
41 41 static ACPI_STATUS pcie_acpi_find_osc(ACPI_HANDLE busobj,
42 42 ACPI_HANDLE *osc_hdlp);
43 43
44 44 #ifdef DEBUG
45 45 static void pcie_dump_acpi_obj(ACPI_HANDLE pcibus_obj);
46 46 static ACPI_STATUS pcie_walk_obj_namespace(ACPI_HANDLE hdl, uint32_t nl,
47 47 void *context, void **ret);
48 48 static ACPI_STATUS pcie_print_acpi_name(ACPI_HANDLE hdl, uint32_t nl,
49 49 void *context, void **ret);
50 50 #endif /* DEBUG */
51 51
52 52 int
53 53 pcie_acpi_osc(dev_info_t *dip, uint32_t *osc_flags)
54 54 {
55 55 ACPI_HANDLE pcibus_obj;
56 56 int status = AE_ERROR;
57 57 ACPI_HANDLE osc_hdl;
58 58 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
59 59 pcie_x86_priv_t *osc_p = (pcie_x86_priv_t *)bus_p->bus_plat_private;
60 60
61 61 /* Mark this so we know _OSC has been called for this device */
62 62 osc_p->bus_osc = B_TRUE;
63 63
64 64 /*
65 65 * (1) Find the ACPI device node for this bus node.
66 66 */
67 67 status = acpica_get_handle(dip, &pcibus_obj);
68 68 if (status != AE_OK) {
69 69 PCIE_DBG("No ACPI device found (dip %p)\n", (void *)dip);
70 70 return (DDI_FAILURE);
71 71 }
72 72
73 73 /*
74 74 * (2) Check if _OSC method is present.
75 75 */
76 76 if (pcie_acpi_find_osc(pcibus_obj, &osc_hdl) != AE_OK) {
77 77 /* no _OSC method present */
78 78 PCIE_DBG("no _OSC method present for dip %p\n",
79 79 (void *)dip);
80 80 return (DDI_FAILURE);
81 81 }
82 82
83 83 /*
84 84 * (3) _OSC method exists; evaluate _OSC.
85 85 */
86 86 if (pcie_acpi_eval_osc(dip, osc_hdl, osc_flags) != AE_OK) {
87 87 PCIE_DBG("Failed to evaluate _OSC method for dip 0x%p\n",
88 88 (void *)dip);
89 89 return (DDI_FAILURE);
90 90 }
91 91
92 92 osc_p->bus_osc_hp = (*osc_flags & OSC_CONTROL_PCIE_NAT_HP) ?
93 93 B_TRUE : B_FALSE;
94 94 osc_p->bus_osc_aer = (*osc_flags & OSC_CONTROL_PCIE_ADV_ERR) ?
95 95 B_TRUE : B_FALSE;
96 96
97 97 #ifdef DEBUG
98 98 if (pcie_debug_flags > 1)
99 99 pcie_dump_acpi_obj(pcibus_obj);
100 100 #endif /* DEBUG */
101 101
102 102 return (DDI_SUCCESS);
103 103 }
104 104
105 105 static ACPI_STATUS
106 106 pcie_acpi_find_osc(ACPI_HANDLE busobj, ACPI_HANDLE *osc_hdlp)
107 107 {
108 108 ACPI_HANDLE parentobj = busobj;
109 109 ACPI_STATUS status = AE_NOT_FOUND;
110 110
111 111 *osc_hdlp = NULL;
112 112
113 113 /*
114 114 * Walk up the ACPI device tree looking for _OSC method.
115 115 */
116 116 do {
117 117 busobj = parentobj;
118 118 if ((status = AcpiGetHandle(busobj, "_OSC", osc_hdlp)) == AE_OK)
119 119 break;
120 120 } while (AcpiGetParent(busobj, &parentobj) == AE_OK);
121 121
122 122 if (*osc_hdlp == NULL)
123 123 status = AE_NOT_FOUND;
124 124
125 125 return (status);
126 126 }
127 127
128 128 /* UUID for for PCI/PCI-X/PCI-Exp hierarchy as defined in PCI fw ver 3.0 */
129 129 static uint8_t pcie_uuid[16] =
130 130 {0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40,
131 131 0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66};
132 132
133 133 /*
134 134 * Evaluate _OSC method.
135 135 */
136 136 ACPI_STATUS
137 137 pcie_acpi_eval_osc(dev_info_t *dip, ACPI_HANDLE osc_hdl, uint32_t *osc_flags)
138 138 {
139 139 ACPI_STATUS status;
140 140 ACPI_OBJECT_LIST arglist;
141 141 ACPI_OBJECT args[4];
142 142 UINT32 caps_buffer[3];
143 143 ACPI_BUFFER rb;
144 144 UINT32 *rbuf;
145 145 UINT32 tmp_ctrl;
146 146
147 147 /* construct argument list */
148 148 arglist.Count = 4;
149 149 arglist.Pointer = args;
150 150
151 151 /* arg0 - UUID */
152 152 args[0].Type = ACPI_TYPE_BUFFER;
153 153 args[0].Buffer.Length = 16; /* size of UUID string */
154 154 args[0].Buffer.Pointer = pcie_uuid;
155 155
156 156 /* arg1 - Revision ID */
157 157 args[1].Type = ACPI_TYPE_INTEGER;
158 158 args[1].Integer.Value = PCIE_OSC_REVISION_ID;
159 159
160 160 /* arg2 - Count */
161 161 args[2].Type = ACPI_TYPE_INTEGER;
162 162 args[2].Integer.Value = 3; /* no. of DWORDS in caps_buffer */
163 163
164 164 /* arg3 - Capabilities Buffer */
165 165 args[3].Type = ACPI_TYPE_BUFFER;
166 166 args[3].Buffer.Length = 12;
167 167 args[3].Buffer.Pointer = (void *)caps_buffer;
168 168
169 169 /* Initialize Capabilities Buffer */
170 170
171 171 /* DWORD1: no query flag set */
172 172 caps_buffer[0] = 0;
173 173 /* DWORD2: Support Field */
174 174 caps_buffer[1] = OSC_SUPPORT_FIELD_INIT;
175 175 /* DWORD3: Control Field */
176 176 caps_buffer[2] = OSC_CONTROL_FIELD_INIT;
177 177
178 178 /* If hotplug is supported add the corresponding control fields */
179 179 if (*osc_flags & OSC_CONTROL_PCIE_NAT_HP)
180 180 caps_buffer[2] |= (OSC_CONTROL_PCIE_NAT_HP |
181 181 OSC_CONTROL_PCIE_NAT_PM);
182 182
183 183 tmp_ctrl = caps_buffer[2];
184 184 rb.Length = ACPI_ALLOCATE_BUFFER;
185 185 rb.Pointer = NULL;
186 186
187 187 status = AcpiEvaluateObjectTyped(osc_hdl, NULL, &arglist, &rb,
188 188 ACPI_TYPE_BUFFER);
189 189 if (status != AE_OK) {
190 190 PCIE_DBG("Failed to execute _OSC method (status %d)\n",
191 191 status);
192 192 return (status);
193 193 }
194 194
195 195 /* LINTED pointer alignment */
196 196 rbuf = (UINT32 *)((ACPI_OBJECT *)rb.Pointer)->Buffer.Pointer;
197 197
198 198 /* check the STATUS word in the capability buffer */
199 199 if (rbuf[0] & OSC_STATUS_ERRORS) {
200 200 PCIE_DBG("_OSC method failed (STATUS %d)\n", rbuf[0]);
201 201 AcpiOsFree(rb.Pointer);
202 202 return (AE_ERROR);
203 203 }
204 204
205 205 *osc_flags = rbuf[2];
206 206
207 207 PCIE_DBG("_OSC method evaluation completed for 0x%p: "
208 208 "STATUS 0x%x SUPPORT 0x%x CONTROL req 0x%x, CONTROL ret 0x%x\n",
209 209 (void *)dip, rbuf[0], rbuf[1], tmp_ctrl, rbuf[2]);
210 210
211 211 AcpiOsFree(rb.Pointer);
212 212
213 213 return (AE_OK);
214 214 }
215 215
216 216 /*
217 217 * Checks if _OSC method has been called for this device.
218 218 */
219 219 boolean_t
220 220 pcie_is_osc(dev_info_t *dip)
221 221 {
222 222 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
223 223 pcie_x86_priv_t *osc_p = (pcie_x86_priv_t *)bus_p->bus_plat_private;
224 224 return (osc_p->bus_osc);
225 225 }
226 226
227 227 #ifdef DEBUG
228 228 static void
229 229 pcie_dump_acpi_obj(ACPI_HANDLE pcibus_obj)
230 230 {
231 231 int status;
232 232 ACPI_BUFFER retbuf;
233 233
234 234 if (pcibus_obj == NULL)
235 235 return;
236 236
237 237 /* print the full path name */
238 238 retbuf.Pointer = NULL;
239 239 retbuf.Length = ACPI_ALLOCATE_BUFFER;
240 240 status = AcpiGetName(pcibus_obj, ACPI_FULL_PATHNAME, &retbuf);
241 241 if (status != AE_OK)
242 242 return;
243 243 PCIE_DBG("PCIE BUS PATHNAME: %s\n", (char *)retbuf.Pointer);
244 244 AcpiOsFree(retbuf.Pointer);
245 245
246 246 /* dump all the methods for this bus node */
247 247 PCIE_DBG(" METHODS: \n");
248 248 status = AcpiWalkNamespace(ACPI_TYPE_METHOD, pcibus_obj, 1,
249 249 pcie_print_acpi_name, NULL, " ", NULL);
250 250 /* dump all the child devices */
251 251 status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, pcibus_obj, 1,
252 252 pcie_walk_obj_namespace, NULL, NULL, NULL);
253 253 }
254 254
255 255 /*ARGSUSED*/
256 256 static ACPI_STATUS
257 257 pcie_walk_obj_namespace(ACPI_HANDLE hdl, uint32_t nl, void *context,
258 258 void **ret)
259 259 {
260 260 int status;
261 261 ACPI_BUFFER retbuf;
262 262 char buf[32];
263 263
264 264 /* print the full path name */
265 265 retbuf.Pointer = NULL;
266 266 retbuf.Length = ACPI_ALLOCATE_BUFFER;
267 267 status = AcpiGetName(hdl, ACPI_FULL_PATHNAME, &retbuf);
268 268 if (status != AE_OK)
269 269 return (status);
270 270 buf[0] = 0;
271 271 while (nl--)
272 272 (void) strcat(buf, " ");
273 273 PCIE_DBG("%sDEVICE: %s\n", buf, (char *)retbuf.Pointer);
274 274 AcpiOsFree(retbuf.Pointer);
275 275
276 276 /* dump all the methods for this device */
277 277 PCIE_DBG("%s METHODS: \n", buf);
278 278 status = AcpiWalkNamespace(ACPI_TYPE_METHOD, hdl, 1,
279 279 pcie_print_acpi_name, NULL, (void *)buf, NULL);
280 280 return (status);
281 281 }
282 282
283 283 /*ARGSUSED*/
284 284 static ACPI_STATUS
285 285 pcie_print_acpi_name(ACPI_HANDLE hdl, uint32_t nl, void *context, void **ret)
286 286 {
287 287 int status;
288 288 ACPI_BUFFER retbuf;
289 289 char name[16];
290 290
291 291 retbuf.Pointer = name;
292 292 retbuf.Length = 16;
293 293 status = AcpiGetName(hdl, ACPI_SINGLE_NAME, &retbuf);
294 294 if (status == AE_OK)
295 295 PCIE_DBG("%s %s \n", (char *)context, name);
296 296 return (AE_OK);
297 297 }
298 298 #endif /* DEBUG */
↓ open down ↓ |
252 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX