1ae115bc7Smrj /******************************************************************************
2ae115bc7Smrj *
3ae115bc7Smrj * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4ae115bc7Smrj *
5ae115bc7Smrj *****************************************************************************/
6ae115bc7Smrj
726f3cdf0SGordon Ross /*
8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp.
9ae115bc7Smrj * All rights reserved.
10ae115bc7Smrj *
1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without
1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions
1326f3cdf0SGordon Ross * are met:
1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright
1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer,
1626f3cdf0SGordon Ross * without modification.
1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below
1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon
2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further
2126f3cdf0SGordon Ross * binary redistribution.
2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names
2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived
2426f3cdf0SGordon Ross * from this software without specific prior written permission.
25ae115bc7Smrj *
2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the
2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free
2826f3cdf0SGordon Ross * Software Foundation.
29ae115bc7Smrj *
3026f3cdf0SGordon Ross * NO WARRANTY
3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES.
4226f3cdf0SGordon Ross */
43ae115bc7Smrj
44ae115bc7Smrj #include "acpi.h"
45aa2aa9a6SDana Myers #include "accommon.h"
46ae115bc7Smrj #include "acevents.h"
47ae115bc7Smrj #include "acnamesp.h"
48ae115bc7Smrj
49ae115bc7Smrj #define _COMPONENT ACPI_EVENTS
50ae115bc7Smrj ACPI_MODULE_NAME ("evrgnini")
51ae115bc7Smrj
52db2bae30SDana Myers /* Local prototypes */
53db2bae30SDana Myers
54db2bae30SDana Myers static BOOLEAN
55db2bae30SDana Myers AcpiEvIsPciRootBridge (
56db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node);
57db2bae30SDana Myers
58ae115bc7Smrj
59ae115bc7Smrj /*******************************************************************************
60ae115bc7Smrj *
61ae115bc7Smrj * FUNCTION: AcpiEvSystemMemoryRegionSetup
62ae115bc7Smrj *
63ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in
64ae115bc7Smrj * Function - Start or stop
65ae115bc7Smrj * HandlerContext - Address space handler context
66ae115bc7Smrj * RegionContext - Region specific context
67ae115bc7Smrj *
68ae115bc7Smrj * RETURN: Status
69ae115bc7Smrj *
70ae115bc7Smrj * DESCRIPTION: Setup a SystemMemory operation region
71ae115bc7Smrj *
72ae115bc7Smrj ******************************************************************************/
73ae115bc7Smrj
74ae115bc7Smrj ACPI_STATUS
AcpiEvSystemMemoryRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)75ae115bc7Smrj AcpiEvSystemMemoryRegionSetup (
76ae115bc7Smrj ACPI_HANDLE Handle,
77ae115bc7Smrj UINT32 Function,
78ae115bc7Smrj void *HandlerContext,
79ae115bc7Smrj void **RegionContext)
80ae115bc7Smrj {
81ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
82ae115bc7Smrj ACPI_MEM_SPACE_CONTEXT *LocalRegionContext;
83ae115bc7Smrj
84ae115bc7Smrj
85ae115bc7Smrj ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
86ae115bc7Smrj
87ae115bc7Smrj
88ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE)
89ae115bc7Smrj {
90ae115bc7Smrj if (*RegionContext)
91ae115bc7Smrj {
92ae115bc7Smrj LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
93ae115bc7Smrj
94ae115bc7Smrj /* Delete a cached mapping if present */
95ae115bc7Smrj
96ae115bc7Smrj if (LocalRegionContext->MappedLength)
97ae115bc7Smrj {
98ae115bc7Smrj AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress,
99ae115bc7Smrj LocalRegionContext->MappedLength);
100ae115bc7Smrj }
101ae115bc7Smrj ACPI_FREE (LocalRegionContext);
102ae115bc7Smrj *RegionContext = NULL;
103ae115bc7Smrj }
104ae115bc7Smrj return_ACPI_STATUS (AE_OK);
105ae115bc7Smrj }
106ae115bc7Smrj
107ae115bc7Smrj /* Create a new context */
108ae115bc7Smrj
109ae115bc7Smrj LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
110ae115bc7Smrj if (!(LocalRegionContext))
111ae115bc7Smrj {
112ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY);
113ae115bc7Smrj }
114ae115bc7Smrj
115ae115bc7Smrj /* Save the region length and address for use in the handler */
116ae115bc7Smrj
117ae115bc7Smrj LocalRegionContext->Length = RegionDesc->Region.Length;
118ae115bc7Smrj LocalRegionContext->Address = RegionDesc->Region.Address;
119ae115bc7Smrj
120ae115bc7Smrj *RegionContext = LocalRegionContext;
121ae115bc7Smrj return_ACPI_STATUS (AE_OK);
122ae115bc7Smrj }
123ae115bc7Smrj
124ae115bc7Smrj
125ae115bc7Smrj /*******************************************************************************
126ae115bc7Smrj *
127ae115bc7Smrj * FUNCTION: AcpiEvIoSpaceRegionSetup
128ae115bc7Smrj *
129ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in
130ae115bc7Smrj * Function - Start or stop
131ae115bc7Smrj * HandlerContext - Address space handler context
132ae115bc7Smrj * RegionContext - Region specific context
133ae115bc7Smrj *
134ae115bc7Smrj * RETURN: Status
135ae115bc7Smrj *
136ae115bc7Smrj * DESCRIPTION: Setup a IO operation region
137ae115bc7Smrj *
138ae115bc7Smrj ******************************************************************************/
139ae115bc7Smrj
140ae115bc7Smrj ACPI_STATUS
AcpiEvIoSpaceRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)141ae115bc7Smrj AcpiEvIoSpaceRegionSetup (
142ae115bc7Smrj ACPI_HANDLE Handle,
143ae115bc7Smrj UINT32 Function,
144ae115bc7Smrj void *HandlerContext,
145ae115bc7Smrj void **RegionContext)
146ae115bc7Smrj {
147ae115bc7Smrj ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
148ae115bc7Smrj
149ae115bc7Smrj
150ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE)
151ae115bc7Smrj {
152ae115bc7Smrj *RegionContext = NULL;
153ae115bc7Smrj }
154ae115bc7Smrj else
155ae115bc7Smrj {
156ae115bc7Smrj *RegionContext = HandlerContext;
157ae115bc7Smrj }
158ae115bc7Smrj
159ae115bc7Smrj return_ACPI_STATUS (AE_OK);
160ae115bc7Smrj }
161ae115bc7Smrj
162ae115bc7Smrj
163ae115bc7Smrj /*******************************************************************************
164ae115bc7Smrj *
165ae115bc7Smrj * FUNCTION: AcpiEvPciConfigRegionSetup
166ae115bc7Smrj *
167ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in
168ae115bc7Smrj * Function - Start or stop
169ae115bc7Smrj * HandlerContext - Address space handler context
170ae115bc7Smrj * RegionContext - Region specific context
171ae115bc7Smrj *
172ae115bc7Smrj * RETURN: Status
173ae115bc7Smrj *
174ae115bc7Smrj * DESCRIPTION: Setup a PCI_Config operation region
175ae115bc7Smrj *
176ae115bc7Smrj * MUTEX: Assumes namespace is not locked
177ae115bc7Smrj *
178ae115bc7Smrj ******************************************************************************/
179ae115bc7Smrj
180ae115bc7Smrj ACPI_STATUS
AcpiEvPciConfigRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)181ae115bc7Smrj AcpiEvPciConfigRegionSetup (
182ae115bc7Smrj ACPI_HANDLE Handle,
183ae115bc7Smrj UINT32 Function,
184ae115bc7Smrj void *HandlerContext,
185ae115bc7Smrj void **RegionContext)
186ae115bc7Smrj {
187ae115bc7Smrj ACPI_STATUS Status = AE_OK;
18826f3cdf0SGordon Ross UINT64 PciValue;
189ae115bc7Smrj ACPI_PCI_ID *PciId = *RegionContext;
190ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerObj;
191ae115bc7Smrj ACPI_NAMESPACE_NODE *ParentNode;
192ae115bc7Smrj ACPI_NAMESPACE_NODE *PciRootNode;
193db2bae30SDana Myers ACPI_NAMESPACE_NODE *PciDeviceNode;
194ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle;
195ae115bc7Smrj
196ae115bc7Smrj
197ae115bc7Smrj ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
198ae115bc7Smrj
199ae115bc7Smrj
200ae115bc7Smrj HandlerObj = RegionObj->Region.Handler;
201ae115bc7Smrj if (!HandlerObj)
202ae115bc7Smrj {
203ae115bc7Smrj /*
204ae115bc7Smrj * No installed handler. This shouldn't happen because the dispatch
205ae115bc7Smrj * routine checks before we get here, but we check again just in case.
206ae115bc7Smrj */
207ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
208ae115bc7Smrj "Attempting to init a region %p, with no handler\n", RegionObj));
209ae115bc7Smrj return_ACPI_STATUS (AE_NOT_EXIST);
210ae115bc7Smrj }
211ae115bc7Smrj
212ae115bc7Smrj *RegionContext = NULL;
213ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE)
214ae115bc7Smrj {
215ae115bc7Smrj if (PciId)
216ae115bc7Smrj {
217ae115bc7Smrj ACPI_FREE (PciId);
218ae115bc7Smrj }
219ae115bc7Smrj return_ACPI_STATUS (Status);
220ae115bc7Smrj }
221ae115bc7Smrj
22226f3cdf0SGordon Ross ParentNode = RegionObj->Region.Node->Parent;
223ae115bc7Smrj
224ae115bc7Smrj /*
225ae115bc7Smrj * Get the _SEG and _BBN values from the device upon which the handler
226ae115bc7Smrj * is installed.
227ae115bc7Smrj *
228ae115bc7Smrj * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
229ae115bc7Smrj * This is the device the handler has been registered to handle.
230ae115bc7Smrj */
231ae115bc7Smrj
232ae115bc7Smrj /*
233ae115bc7Smrj * If the AddressSpace.Node is still pointing to the root, we need
234ae115bc7Smrj * to scan upward for a PCI Root bridge and re-associate the OpRegion
235ae115bc7Smrj * handlers with that device.
236ae115bc7Smrj */
237ae115bc7Smrj if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
238ae115bc7Smrj {
239ae115bc7Smrj /* Start search from the parent object */
240ae115bc7Smrj
241ae115bc7Smrj PciRootNode = ParentNode;
242ae115bc7Smrj while (PciRootNode != AcpiGbl_RootNode)
243ae115bc7Smrj {
244db2bae30SDana Myers /* Get the _HID/_CID in order to detect a RootBridge */
245db2bae30SDana Myers
246db2bae30SDana Myers if (AcpiEvIsPciRootBridge (PciRootNode))
247ae115bc7Smrj {
248ae115bc7Smrj /* Install a handler for this PCI root bridge */
249ae115bc7Smrj
250db2bae30SDana Myers Status = AcpiInstallAddressSpaceHandler (
251db2bae30SDana Myers (ACPI_HANDLE) PciRootNode,
252ae115bc7Smrj ACPI_ADR_SPACE_PCI_CONFIG,
253ae115bc7Smrj ACPI_DEFAULT_HANDLER, NULL, NULL);
254ae115bc7Smrj if (ACPI_FAILURE (Status))
255ae115bc7Smrj {
256ae115bc7Smrj if (Status == AE_SAME_HANDLER)
257ae115bc7Smrj {
258ae115bc7Smrj /*
259aa2aa9a6SDana Myers * It is OK if the handler is already installed on the
260aa2aa9a6SDana Myers * root bridge. Still need to return a context object
261aa2aa9a6SDana Myers * for the new PCI_Config operation region, however.
262ae115bc7Smrj */
263ae115bc7Smrj Status = AE_OK;
264ae115bc7Smrj }
265ae115bc7Smrj else
266ae115bc7Smrj {
267ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status,
268aa2aa9a6SDana Myers "Could not install PciConfig handler "
269aa2aa9a6SDana Myers "for Root Bridge %4.4s",
270ae115bc7Smrj AcpiUtGetNodeName (PciRootNode)));
271ae115bc7Smrj }
272ae115bc7Smrj }
273ae115bc7Smrj break;
274ae115bc7Smrj }
275ae115bc7Smrj
27626f3cdf0SGordon Ross PciRootNode = PciRootNode->Parent;
277ae115bc7Smrj }
278ae115bc7Smrj
279ae115bc7Smrj /* PCI root bridge not found, use namespace root node */
280ae115bc7Smrj }
281ae115bc7Smrj else
282ae115bc7Smrj {
283ae115bc7Smrj PciRootNode = HandlerObj->AddressSpace.Node;
284ae115bc7Smrj }
285ae115bc7Smrj
286ae115bc7Smrj /*
287ae115bc7Smrj * If this region is now initialized, we are done.
288ae115bc7Smrj * (InstallAddressSpaceHandler could have initialized it)
289ae115bc7Smrj */
290ae115bc7Smrj if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
291ae115bc7Smrj {
292ae115bc7Smrj return_ACPI_STATUS (AE_OK);
293ae115bc7Smrj }
294ae115bc7Smrj
295ae115bc7Smrj /* Region is still not initialized. Create a new context */
296ae115bc7Smrj
297ae115bc7Smrj PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
298ae115bc7Smrj if (!PciId)
299ae115bc7Smrj {
300ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY);
301ae115bc7Smrj }
302ae115bc7Smrj
303ae115bc7Smrj /*
304aa2aa9a6SDana Myers * For PCI_Config space access, we need the segment, bus, device and
305aa2aa9a6SDana Myers * function numbers. Acquire them here.
306db2bae30SDana Myers *
307db2bae30SDana Myers * Find the parent device object. (This allows the operation region to be
308db2bae30SDana Myers * within a subscope under the device, such as a control method.)
309ae115bc7Smrj */
310db2bae30SDana Myers PciDeviceNode = RegionObj->Region.Node;
311db2bae30SDana Myers while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
312db2bae30SDana Myers {
31326f3cdf0SGordon Ross PciDeviceNode = PciDeviceNode->Parent;
314db2bae30SDana Myers }
315db2bae30SDana Myers
316db2bae30SDana Myers if (!PciDeviceNode)
317db2bae30SDana Myers {
318db2bae30SDana Myers ACPI_FREE (PciId);
319db2bae30SDana Myers return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
320db2bae30SDana Myers }
321ae115bc7Smrj
322ae115bc7Smrj /*
32326f3cdf0SGordon Ross * Get the PCI device and function numbers from the _ADR object
32426f3cdf0SGordon Ross * contained in the parent's scope.
325ae115bc7Smrj */
326aa2aa9a6SDana Myers Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
327aa2aa9a6SDana Myers PciDeviceNode, &PciValue);
328ae115bc7Smrj
329ae115bc7Smrj /*
330aa2aa9a6SDana Myers * The default is zero, and since the allocation above zeroed the data,
331aa2aa9a6SDana Myers * just do nothing on failure.
332ae115bc7Smrj */
333ae115bc7Smrj if (ACPI_SUCCESS (Status))
334ae115bc7Smrj {
335ae115bc7Smrj PciId->Device = ACPI_HIWORD (ACPI_LODWORD (PciValue));
336ae115bc7Smrj PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
337ae115bc7Smrj }
338ae115bc7Smrj
339ae115bc7Smrj /* The PCI segment number comes from the _SEG method */
340ae115bc7Smrj
341aa2aa9a6SDana Myers Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
342aa2aa9a6SDana Myers PciRootNode, &PciValue);
343ae115bc7Smrj if (ACPI_SUCCESS (Status))
344ae115bc7Smrj {
345ae115bc7Smrj PciId->Segment = ACPI_LOWORD (PciValue);
346ae115bc7Smrj }
347ae115bc7Smrj
348ae115bc7Smrj /* The PCI bus number comes from the _BBN method */
349ae115bc7Smrj
350aa2aa9a6SDana Myers Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
351aa2aa9a6SDana Myers PciRootNode, &PciValue);
352ae115bc7Smrj if (ACPI_SUCCESS (Status))
353ae115bc7Smrj {
354ae115bc7Smrj PciId->Bus = ACPI_LOWORD (PciValue);
355ae115bc7Smrj }
356ae115bc7Smrj
35726f3cdf0SGordon Ross /* Complete/update the PCI ID for this device */
358ae115bc7Smrj
35926f3cdf0SGordon Ross Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
36026f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
36126f3cdf0SGordon Ross {
36226f3cdf0SGordon Ross ACPI_FREE (PciId);
36326f3cdf0SGordon Ross return_ACPI_STATUS (Status);
36426f3cdf0SGordon Ross }
365ae115bc7Smrj
366ae115bc7Smrj *RegionContext = PciId;
367ae115bc7Smrj return_ACPI_STATUS (AE_OK);
368ae115bc7Smrj }
369ae115bc7Smrj
370ae115bc7Smrj
371ae115bc7Smrj /*******************************************************************************
372ae115bc7Smrj *
373db2bae30SDana Myers * FUNCTION: AcpiEvIsPciRootBridge
374db2bae30SDana Myers *
375db2bae30SDana Myers * PARAMETERS: Node - Device node being examined
376db2bae30SDana Myers *
377db2bae30SDana Myers * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge
378db2bae30SDana Myers *
379db2bae30SDana Myers * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
380db2bae30SDana Myers * examining the _HID and _CID for the device.
381db2bae30SDana Myers *
382db2bae30SDana Myers ******************************************************************************/
383db2bae30SDana Myers
384db2bae30SDana Myers static BOOLEAN
AcpiEvIsPciRootBridge(ACPI_NAMESPACE_NODE * Node)385db2bae30SDana Myers AcpiEvIsPciRootBridge (
386db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node)
387db2bae30SDana Myers {
388db2bae30SDana Myers ACPI_STATUS Status;
389*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID *Hid;
390*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID_LIST *Cid;
391db2bae30SDana Myers UINT32 i;
39257190917SDana Myers BOOLEAN Match;
393db2bae30SDana Myers
394db2bae30SDana Myers
395aa2aa9a6SDana Myers /* Get the _HID and check for a PCI Root Bridge */
396aa2aa9a6SDana Myers
397db2bae30SDana Myers Status = AcpiUtExecute_HID (Node, &Hid);
398db2bae30SDana Myers if (ACPI_FAILURE (Status))
399db2bae30SDana Myers {
400db2bae30SDana Myers return (FALSE);
401db2bae30SDana Myers }
402db2bae30SDana Myers
40357190917SDana Myers Match = AcpiUtIsPciRootBridge (Hid->String);
40457190917SDana Myers ACPI_FREE (Hid);
40557190917SDana Myers
40657190917SDana Myers if (Match)
407db2bae30SDana Myers {
408db2bae30SDana Myers return (TRUE);
409db2bae30SDana Myers }
410db2bae30SDana Myers
411aa2aa9a6SDana Myers /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
412aa2aa9a6SDana Myers
413db2bae30SDana Myers Status = AcpiUtExecute_CID (Node, &Cid);
414db2bae30SDana Myers if (ACPI_FAILURE (Status))
415db2bae30SDana Myers {
416db2bae30SDana Myers return (FALSE);
417db2bae30SDana Myers }
418db2bae30SDana Myers
419db2bae30SDana Myers /* Check all _CIDs in the returned list */
420db2bae30SDana Myers
421db2bae30SDana Myers for (i = 0; i < Cid->Count; i++)
422db2bae30SDana Myers {
42357190917SDana Myers if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
424db2bae30SDana Myers {
425db2bae30SDana Myers ACPI_FREE (Cid);
426db2bae30SDana Myers return (TRUE);
427db2bae30SDana Myers }
428db2bae30SDana Myers }
429db2bae30SDana Myers
430db2bae30SDana Myers ACPI_FREE (Cid);
431db2bae30SDana Myers return (FALSE);
432db2bae30SDana Myers }
433db2bae30SDana Myers
434db2bae30SDana Myers
435db2bae30SDana Myers /*******************************************************************************
436db2bae30SDana Myers *
437ae115bc7Smrj * FUNCTION: AcpiEvPciBarRegionSetup
438ae115bc7Smrj *
439ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in
440ae115bc7Smrj * Function - Start or stop
441ae115bc7Smrj * HandlerContext - Address space handler context
442ae115bc7Smrj * RegionContext - Region specific context
443ae115bc7Smrj *
444ae115bc7Smrj * RETURN: Status
445ae115bc7Smrj *
446ae115bc7Smrj * DESCRIPTION: Setup a PciBAR operation region
447ae115bc7Smrj *
448ae115bc7Smrj * MUTEX: Assumes namespace is not locked
449ae115bc7Smrj *
450ae115bc7Smrj ******************************************************************************/
451ae115bc7Smrj
452ae115bc7Smrj ACPI_STATUS
AcpiEvPciBarRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)453ae115bc7Smrj AcpiEvPciBarRegionSetup (
454ae115bc7Smrj ACPI_HANDLE Handle,
455ae115bc7Smrj UINT32 Function,
456ae115bc7Smrj void *HandlerContext,
457ae115bc7Smrj void **RegionContext)
458ae115bc7Smrj {
459ae115bc7Smrj ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
460ae115bc7Smrj
461ae115bc7Smrj
462ae115bc7Smrj return_ACPI_STATUS (AE_OK);
463ae115bc7Smrj }
464ae115bc7Smrj
465ae115bc7Smrj
466ae115bc7Smrj /*******************************************************************************
467ae115bc7Smrj *
468ae115bc7Smrj * FUNCTION: AcpiEvCmosRegionSetup
469ae115bc7Smrj *
470ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in
471ae115bc7Smrj * Function - Start or stop
472ae115bc7Smrj * HandlerContext - Address space handler context
473ae115bc7Smrj * RegionContext - Region specific context
474ae115bc7Smrj *
475ae115bc7Smrj * RETURN: Status
476ae115bc7Smrj *
477ae115bc7Smrj * DESCRIPTION: Setup a CMOS operation region
478ae115bc7Smrj *
479ae115bc7Smrj * MUTEX: Assumes namespace is not locked
480ae115bc7Smrj *
481ae115bc7Smrj ******************************************************************************/
482ae115bc7Smrj
483ae115bc7Smrj ACPI_STATUS
AcpiEvCmosRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)484ae115bc7Smrj AcpiEvCmosRegionSetup (
485ae115bc7Smrj ACPI_HANDLE Handle,
486ae115bc7Smrj UINT32 Function,
487ae115bc7Smrj void *HandlerContext,
488ae115bc7Smrj void **RegionContext)
489ae115bc7Smrj {
490ae115bc7Smrj ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
491ae115bc7Smrj
492ae115bc7Smrj
493ae115bc7Smrj return_ACPI_STATUS (AE_OK);
494ae115bc7Smrj }
495ae115bc7Smrj
496ae115bc7Smrj
497ae115bc7Smrj /*******************************************************************************
498ae115bc7Smrj *
499ae115bc7Smrj * FUNCTION: AcpiEvDefaultRegionSetup
500ae115bc7Smrj *
501ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in
502ae115bc7Smrj * Function - Start or stop
503ae115bc7Smrj * HandlerContext - Address space handler context
504ae115bc7Smrj * RegionContext - Region specific context
505ae115bc7Smrj *
506ae115bc7Smrj * RETURN: Status
507ae115bc7Smrj *
508ae115bc7Smrj * DESCRIPTION: Default region initialization
509ae115bc7Smrj *
510ae115bc7Smrj ******************************************************************************/
511ae115bc7Smrj
512ae115bc7Smrj ACPI_STATUS
AcpiEvDefaultRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)513ae115bc7Smrj AcpiEvDefaultRegionSetup (
514ae115bc7Smrj ACPI_HANDLE Handle,
515ae115bc7Smrj UINT32 Function,
516ae115bc7Smrj void *HandlerContext,
517ae115bc7Smrj void **RegionContext)
518ae115bc7Smrj {
519ae115bc7Smrj ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
520ae115bc7Smrj
521ae115bc7Smrj
522ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE)
523ae115bc7Smrj {
524ae115bc7Smrj *RegionContext = NULL;
525ae115bc7Smrj }
526ae115bc7Smrj else
527ae115bc7Smrj {
528ae115bc7Smrj *RegionContext = HandlerContext;
529ae115bc7Smrj }
530ae115bc7Smrj
531ae115bc7Smrj return_ACPI_STATUS (AE_OK);
532ae115bc7Smrj }
533ae115bc7Smrj
534ae115bc7Smrj
535ae115bc7Smrj /*******************************************************************************
536ae115bc7Smrj *
537ae115bc7Smrj * FUNCTION: AcpiEvInitializeRegion
538ae115bc7Smrj *
539ae115bc7Smrj * PARAMETERS: RegionObj - Region we are initializing
540ae115bc7Smrj * AcpiNsLocked - Is namespace locked?
541ae115bc7Smrj *
542ae115bc7Smrj * RETURN: Status
543ae115bc7Smrj *
544ae115bc7Smrj * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
545ae115bc7Smrj * for execution at a later time
546ae115bc7Smrj *
547ae115bc7Smrj * Get the appropriate address space handler for a newly
548ae115bc7Smrj * created region.
549ae115bc7Smrj *
550ae115bc7Smrj * This also performs address space specific initialization. For
551ae115bc7Smrj * example, PCI regions must have an _ADR object that contains
552ae115bc7Smrj * a PCI address in the scope of the definition. This address is
553ae115bc7Smrj * required to perform an access to PCI config space.
554ae115bc7Smrj *
555ae115bc7Smrj * MUTEX: Interpreter should be unlocked, because we may run the _REG
556ae115bc7Smrj * method for this region.
557ae115bc7Smrj *
558ae115bc7Smrj ******************************************************************************/
559ae115bc7Smrj
560ae115bc7Smrj ACPI_STATUS
AcpiEvInitializeRegion(ACPI_OPERAND_OBJECT * RegionObj,BOOLEAN AcpiNsLocked)561ae115bc7Smrj AcpiEvInitializeRegion (
562ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj,
563ae115bc7Smrj BOOLEAN AcpiNsLocked)
564ae115bc7Smrj {
565ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerObj;
566ae115bc7Smrj ACPI_OPERAND_OBJECT *ObjDesc;
567ae115bc7Smrj ACPI_ADR_SPACE_TYPE SpaceId;
568ae115bc7Smrj ACPI_NAMESPACE_NODE *Node;
569ae115bc7Smrj ACPI_STATUS Status;
570ae115bc7Smrj
571ae115bc7Smrj
572ae115bc7Smrj ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);
573ae115bc7Smrj
574ae115bc7Smrj
575ae115bc7Smrj if (!RegionObj)
576ae115bc7Smrj {
577ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER);
578ae115bc7Smrj }
579ae115bc7Smrj
580ae115bc7Smrj if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
581ae115bc7Smrj {
582ae115bc7Smrj return_ACPI_STATUS (AE_OK);
583ae115bc7Smrj }
584ae115bc7Smrj
585*385cc6b4SJerry Jelinek RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
586ae115bc7Smrj
58726f3cdf0SGordon Ross Node = RegionObj->Region.Node->Parent;
588ae115bc7Smrj SpaceId = RegionObj->Region.SpaceId;
589ae115bc7Smrj
590ae115bc7Smrj /*
591ae115bc7Smrj * The following loop depends upon the root Node having no parent
592*385cc6b4SJerry Jelinek * ie: AcpiGbl_RootNode->Parent being set to NULL
593ae115bc7Smrj */
594ae115bc7Smrj while (Node)
595ae115bc7Smrj {
596ae115bc7Smrj /* Check to see if a handler exists */
597ae115bc7Smrj
598ae115bc7Smrj HandlerObj = NULL;
599ae115bc7Smrj ObjDesc = AcpiNsGetAttachedObject (Node);
600ae115bc7Smrj if (ObjDesc)
601ae115bc7Smrj {
602ae115bc7Smrj /* Can only be a handler if the object exists */
603ae115bc7Smrj
604ae115bc7Smrj switch (Node->Type)
605ae115bc7Smrj {
606ae115bc7Smrj case ACPI_TYPE_DEVICE:
607ae115bc7Smrj case ACPI_TYPE_PROCESSOR:
608ae115bc7Smrj case ACPI_TYPE_THERMAL:
609ae115bc7Smrj
610*385cc6b4SJerry Jelinek HandlerObj = ObjDesc->CommonNotify.Handler;
611ae115bc7Smrj break;
612ae115bc7Smrj
61326f3cdf0SGordon Ross case ACPI_TYPE_METHOD:
61426f3cdf0SGordon Ross /*
61526f3cdf0SGordon Ross * If we are executing module level code, the original
61626f3cdf0SGordon Ross * Node's object was replaced by this Method object and we
61726f3cdf0SGordon Ross * saved the handler in the method object.
61826f3cdf0SGordon Ross *
61926f3cdf0SGordon Ross * See AcpiNsExecModuleCode
62026f3cdf0SGordon Ross */
62126f3cdf0SGordon Ross if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
62226f3cdf0SGordon Ross {
62326f3cdf0SGordon Ross HandlerObj = ObjDesc->Method.Dispatch.Handler;
62426f3cdf0SGordon Ross }
62526f3cdf0SGordon Ross break;
62626f3cdf0SGordon Ross
627ae115bc7Smrj default:
628*385cc6b4SJerry Jelinek
629ae115bc7Smrj /* Ignore other objects */
630*385cc6b4SJerry Jelinek
631ae115bc7Smrj break;
632ae115bc7Smrj }
633ae115bc7Smrj
634*385cc6b4SJerry Jelinek HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj);
635*385cc6b4SJerry Jelinek if (HandlerObj)
636ae115bc7Smrj {
637ae115bc7Smrj /* Found correct handler */
638ae115bc7Smrj
639ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
640ae115bc7Smrj "Found handler %p for region %p in obj %p\n",
641ae115bc7Smrj HandlerObj, RegionObj, ObjDesc));
642ae115bc7Smrj
643ae115bc7Smrj Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
644ae115bc7Smrj AcpiNsLocked);
645ae115bc7Smrj
646ae115bc7Smrj /*
647aa2aa9a6SDana Myers * Tell all users that this region is usable by
648aa2aa9a6SDana Myers * running the _REG method
649ae115bc7Smrj */
650ae115bc7Smrj if (AcpiNsLocked)
651ae115bc7Smrj {
652ae115bc7Smrj Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
653ae115bc7Smrj if (ACPI_FAILURE (Status))
654ae115bc7Smrj {
655ae115bc7Smrj return_ACPI_STATUS (Status);
656ae115bc7Smrj }
657ae115bc7Smrj }
658ae115bc7Smrj
65926f3cdf0SGordon Ross Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
660ae115bc7Smrj
661ae115bc7Smrj if (AcpiNsLocked)
662ae115bc7Smrj {
663ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
664ae115bc7Smrj if (ACPI_FAILURE (Status))
665ae115bc7Smrj {
666ae115bc7Smrj return_ACPI_STATUS (Status);
667ae115bc7Smrj }
668ae115bc7Smrj }
669ae115bc7Smrj
670ae115bc7Smrj return_ACPI_STATUS (AE_OK);
671ae115bc7Smrj }
672ae115bc7Smrj }
673ae115bc7Smrj
674aa2aa9a6SDana Myers /* This node does not have the handler we need; Pop up one level */
675aa2aa9a6SDana Myers
67626f3cdf0SGordon Ross Node = Node->Parent;
677ae115bc7Smrj }
678ae115bc7Smrj
679ae115bc7Smrj /* If we get here, there is no handler for this region */
680ae115bc7Smrj
681ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
682ae115bc7Smrj "No handler for RegionType %s(%X) (RegionObj %p)\n",
683ae115bc7Smrj AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
684ae115bc7Smrj
685ae115bc7Smrj return_ACPI_STATUS (AE_NOT_EXIST);
686ae115bc7Smrj }
687