xref: /titanic_52/usr/src/uts/intel/io/acpica/events/evxfregn.c (revision 385cc6b4ad1792caef3f84eb61eed3f27085801f)
1ae115bc7Smrj /******************************************************************************
2ae115bc7Smrj  *
3ae115bc7Smrj  * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
4ae115bc7Smrj  *                         Address Spaces.
5ae115bc7Smrj  *
6ae115bc7Smrj  *****************************************************************************/
7ae115bc7Smrj 
826f3cdf0SGordon Ross /*
9*385cc6b4SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
10ae115bc7Smrj  * All rights reserved.
11ae115bc7Smrj  *
1226f3cdf0SGordon Ross  * Redistribution and use in source and binary forms, with or without
1326f3cdf0SGordon Ross  * modification, are permitted provided that the following conditions
1426f3cdf0SGordon Ross  * are met:
1526f3cdf0SGordon Ross  * 1. Redistributions of source code must retain the above copyright
1626f3cdf0SGordon Ross  *    notice, this list of conditions, and the following disclaimer,
1726f3cdf0SGordon Ross  *    without modification.
1826f3cdf0SGordon Ross  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1926f3cdf0SGordon Ross  *    substantially similar to the "NO WARRANTY" disclaimer below
2026f3cdf0SGordon Ross  *    ("Disclaimer") and any redistribution must be conditioned upon
2126f3cdf0SGordon Ross  *    including a substantially similar Disclaimer requirement for further
2226f3cdf0SGordon Ross  *    binary redistribution.
2326f3cdf0SGordon Ross  * 3. Neither the names of the above-listed copyright holders nor the names
2426f3cdf0SGordon Ross  *    of any contributors may be used to endorse or promote products derived
2526f3cdf0SGordon Ross  *    from this software without specific prior written permission.
26ae115bc7Smrj  *
2726f3cdf0SGordon Ross  * Alternatively, this software may be distributed under the terms of the
2826f3cdf0SGordon Ross  * GNU General Public License ("GPL") version 2 as published by the Free
2926f3cdf0SGordon Ross  * Software Foundation.
30ae115bc7Smrj  *
3126f3cdf0SGordon Ross  * NO WARRANTY
3226f3cdf0SGordon Ross  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3326f3cdf0SGordon Ross  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3426f3cdf0SGordon Ross  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3526f3cdf0SGordon Ross  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3626f3cdf0SGordon Ross  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3726f3cdf0SGordon Ross  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3826f3cdf0SGordon Ross  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3926f3cdf0SGordon Ross  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4026f3cdf0SGordon Ross  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4126f3cdf0SGordon Ross  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4226f3cdf0SGordon Ross  * POSSIBILITY OF SUCH DAMAGES.
4326f3cdf0SGordon Ross  */
44ae115bc7Smrj 
45*385cc6b4SJerry Jelinek #define EXPORT_ACPI_INTERFACES
46ae115bc7Smrj 
47ae115bc7Smrj #include "acpi.h"
48aa2aa9a6SDana Myers #include "accommon.h"
49ae115bc7Smrj #include "acnamesp.h"
50ae115bc7Smrj #include "acevents.h"
51ae115bc7Smrj 
52ae115bc7Smrj #define _COMPONENT          ACPI_EVENTS
53ae115bc7Smrj         ACPI_MODULE_NAME    ("evxfregn")
54ae115bc7Smrj 
55ae115bc7Smrj 
56ae115bc7Smrj /*******************************************************************************
57ae115bc7Smrj  *
58ae115bc7Smrj  * FUNCTION:    AcpiInstallAddressSpaceHandler
59ae115bc7Smrj  *
60ae115bc7Smrj  * PARAMETERS:  Device          - Handle for the device
61ae115bc7Smrj  *              SpaceId         - The address space ID
62ae115bc7Smrj  *              Handler         - Address of the handler
63ae115bc7Smrj  *              Setup           - Address of the setup function
64ae115bc7Smrj  *              Context         - Value passed to the handler on each access
65ae115bc7Smrj  *
66ae115bc7Smrj  * RETURN:      Status
67ae115bc7Smrj  *
68ae115bc7Smrj  * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
69ae115bc7Smrj  *
7026f3cdf0SGordon Ross  * NOTE: This function should only be called after AcpiEnableSubsystem has
7126f3cdf0SGordon Ross  * been called. This is because any _REG methods associated with the Space ID
7226f3cdf0SGordon Ross  * are executed here, and these methods can only be safely executed after
7326f3cdf0SGordon Ross  * the default handlers have been installed and the hardware has been
7426f3cdf0SGordon Ross  * initialized (via AcpiEnableSubsystem.)
7526f3cdf0SGordon Ross  *
76ae115bc7Smrj  ******************************************************************************/
77ae115bc7Smrj 
78ae115bc7Smrj ACPI_STATUS
79ae115bc7Smrj AcpiInstallAddressSpaceHandler (
80ae115bc7Smrj     ACPI_HANDLE             Device,
81ae115bc7Smrj     ACPI_ADR_SPACE_TYPE     SpaceId,
82ae115bc7Smrj     ACPI_ADR_SPACE_HANDLER  Handler,
83ae115bc7Smrj     ACPI_ADR_SPACE_SETUP    Setup,
84ae115bc7Smrj     void                    *Context)
85ae115bc7Smrj {
86ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node;
87ae115bc7Smrj     ACPI_STATUS             Status;
88ae115bc7Smrj 
89ae115bc7Smrj 
90ae115bc7Smrj     ACPI_FUNCTION_TRACE (AcpiInstallAddressSpaceHandler);
91ae115bc7Smrj 
92ae115bc7Smrj 
93ae115bc7Smrj     /* Parameter validation */
94ae115bc7Smrj 
95ae115bc7Smrj     if (!Device)
96ae115bc7Smrj     {
97ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
98ae115bc7Smrj     }
99ae115bc7Smrj 
100ae115bc7Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
101ae115bc7Smrj     if (ACPI_FAILURE (Status))
102ae115bc7Smrj     {
103ae115bc7Smrj         return_ACPI_STATUS (Status);
104ae115bc7Smrj     }
105ae115bc7Smrj 
106ae115bc7Smrj     /* Convert and validate the device handle */
107ae115bc7Smrj 
10826f3cdf0SGordon Ross     Node = AcpiNsValidateHandle (Device);
109ae115bc7Smrj     if (!Node)
110ae115bc7Smrj     {
111ae115bc7Smrj         Status = AE_BAD_PARAMETER;
112ae115bc7Smrj         goto UnlockAndExit;
113ae115bc7Smrj     }
114ae115bc7Smrj 
115ae115bc7Smrj     /* Install the handler for all Regions for this Space ID */
116ae115bc7Smrj 
117*385cc6b4SJerry Jelinek     Status = AcpiEvInstallSpaceHandler (
118*385cc6b4SJerry Jelinek         Node, SpaceId, Handler, Setup, Context);
119ae115bc7Smrj     if (ACPI_FAILURE (Status))
120ae115bc7Smrj     {
121ae115bc7Smrj         goto UnlockAndExit;
122ae115bc7Smrj     }
123ae115bc7Smrj 
124ae115bc7Smrj     /* Run all _REG methods for this address space */
125ae115bc7Smrj 
126*385cc6b4SJerry Jelinek     AcpiEvExecuteRegMethods (Node, SpaceId, ACPI_REG_CONNECT);
127ae115bc7Smrj 
12826f3cdf0SGordon Ross 
129ae115bc7Smrj UnlockAndExit:
130ae115bc7Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
131ae115bc7Smrj     return_ACPI_STATUS (Status);
132ae115bc7Smrj }
133ae115bc7Smrj 
134ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallAddressSpaceHandler)
135ae115bc7Smrj 
136ae115bc7Smrj 
137ae115bc7Smrj /*******************************************************************************
138ae115bc7Smrj  *
139ae115bc7Smrj  * FUNCTION:    AcpiRemoveAddressSpaceHandler
140ae115bc7Smrj  *
141ae115bc7Smrj  * PARAMETERS:  Device          - Handle for the device
142ae115bc7Smrj  *              SpaceId         - The address space ID
143ae115bc7Smrj  *              Handler         - Address of the handler
144ae115bc7Smrj  *
145ae115bc7Smrj  * RETURN:      Status
146ae115bc7Smrj  *
147ae115bc7Smrj  * DESCRIPTION: Remove a previously installed handler.
148ae115bc7Smrj  *
149ae115bc7Smrj  ******************************************************************************/
150ae115bc7Smrj 
151ae115bc7Smrj ACPI_STATUS
152ae115bc7Smrj AcpiRemoveAddressSpaceHandler (
153ae115bc7Smrj     ACPI_HANDLE             Device,
154ae115bc7Smrj     ACPI_ADR_SPACE_TYPE     SpaceId,
155ae115bc7Smrj     ACPI_ADR_SPACE_HANDLER  Handler)
156ae115bc7Smrj {
157ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
158ae115bc7Smrj     ACPI_OPERAND_OBJECT     *HandlerObj;
159ae115bc7Smrj     ACPI_OPERAND_OBJECT     *RegionObj;
160ae115bc7Smrj     ACPI_OPERAND_OBJECT     **LastObjPtr;
161ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node;
162ae115bc7Smrj     ACPI_STATUS             Status;
163ae115bc7Smrj 
164ae115bc7Smrj 
165ae115bc7Smrj     ACPI_FUNCTION_TRACE (AcpiRemoveAddressSpaceHandler);
166ae115bc7Smrj 
167ae115bc7Smrj 
168ae115bc7Smrj     /* Parameter validation */
169ae115bc7Smrj 
170ae115bc7Smrj     if (!Device)
171ae115bc7Smrj     {
172ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
173ae115bc7Smrj     }
174ae115bc7Smrj 
175ae115bc7Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
176ae115bc7Smrj     if (ACPI_FAILURE (Status))
177ae115bc7Smrj     {
178ae115bc7Smrj         return_ACPI_STATUS (Status);
179ae115bc7Smrj     }
180ae115bc7Smrj 
181ae115bc7Smrj     /* Convert and validate the device handle */
182ae115bc7Smrj 
18326f3cdf0SGordon Ross     Node = AcpiNsValidateHandle (Device);
184ae115bc7Smrj     if (!Node ||
185ae115bc7Smrj         ((Node->Type != ACPI_TYPE_DEVICE)    &&
186ae115bc7Smrj          (Node->Type != ACPI_TYPE_PROCESSOR) &&
187ae115bc7Smrj          (Node->Type != ACPI_TYPE_THERMAL)   &&
188ae115bc7Smrj          (Node != AcpiGbl_RootNode)))
189ae115bc7Smrj     {
190ae115bc7Smrj         Status = AE_BAD_PARAMETER;
191ae115bc7Smrj         goto UnlockAndExit;
192ae115bc7Smrj     }
193ae115bc7Smrj 
194ae115bc7Smrj     /* Make sure the internal object exists */
195ae115bc7Smrj 
196ae115bc7Smrj     ObjDesc = AcpiNsGetAttachedObject (Node);
197ae115bc7Smrj     if (!ObjDesc)
198ae115bc7Smrj     {
199ae115bc7Smrj         Status = AE_NOT_EXIST;
200ae115bc7Smrj         goto UnlockAndExit;
201ae115bc7Smrj     }
202ae115bc7Smrj 
203ae115bc7Smrj     /* Find the address handler the user requested */
204ae115bc7Smrj 
205*385cc6b4SJerry Jelinek     HandlerObj = ObjDesc->CommonNotify.Handler;
206*385cc6b4SJerry Jelinek     LastObjPtr = &ObjDesc->CommonNotify.Handler;
207ae115bc7Smrj     while (HandlerObj)
208ae115bc7Smrj     {
209ae115bc7Smrj         /* We have a handler, see if user requested this one */
210ae115bc7Smrj 
211ae115bc7Smrj         if (HandlerObj->AddressSpace.SpaceId == SpaceId)
212ae115bc7Smrj         {
213ae115bc7Smrj             /* Handler must be the same as the installed handler */
214ae115bc7Smrj 
215ae115bc7Smrj             if (HandlerObj->AddressSpace.Handler != Handler)
216ae115bc7Smrj             {
217ae115bc7Smrj                 Status = AE_BAD_PARAMETER;
218ae115bc7Smrj                 goto UnlockAndExit;
219ae115bc7Smrj             }
220ae115bc7Smrj 
221ae115bc7Smrj             /* Matched SpaceId, first dereference this in the Regions */
222ae115bc7Smrj 
223ae115bc7Smrj             ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
224aa2aa9a6SDana Myers                 "Removing address handler %p(%p) for region %s "
225aa2aa9a6SDana Myers                 "on Device %p(%p)\n",
226ae115bc7Smrj                 HandlerObj, Handler, AcpiUtGetRegionName (SpaceId),
227ae115bc7Smrj                 Node, ObjDesc));
228ae115bc7Smrj 
229ae115bc7Smrj             RegionObj = HandlerObj->AddressSpace.RegionList;
230ae115bc7Smrj 
231ae115bc7Smrj             /* Walk the handler's region list */
232ae115bc7Smrj 
233ae115bc7Smrj             while (RegionObj)
234ae115bc7Smrj             {
235ae115bc7Smrj                 /*
236ae115bc7Smrj                  * First disassociate the handler from the region.
237ae115bc7Smrj                  *
238ae115bc7Smrj                  * NOTE: this doesn't mean that the region goes away
239ae115bc7Smrj                  * The region is just inaccessible as indicated to
240ae115bc7Smrj                  * the _REG method
241ae115bc7Smrj                  */
242ae115bc7Smrj                 AcpiEvDetachRegion (RegionObj, TRUE);
243ae115bc7Smrj 
244ae115bc7Smrj                 /*
245ae115bc7Smrj                  * Walk the list: Just grab the head because the
246ae115bc7Smrj                  * DetachRegion removed the previous head.
247ae115bc7Smrj                  */
248ae115bc7Smrj                 RegionObj = HandlerObj->AddressSpace.RegionList;
249ae115bc7Smrj 
250ae115bc7Smrj             }
251ae115bc7Smrj 
252ae115bc7Smrj             /* Remove this Handler object from the list */
253ae115bc7Smrj 
254ae115bc7Smrj             *LastObjPtr = HandlerObj->AddressSpace.Next;
255ae115bc7Smrj 
256ae115bc7Smrj             /* Now we can delete the handler object */
257ae115bc7Smrj 
258ae115bc7Smrj             AcpiUtRemoveReference (HandlerObj);
259ae115bc7Smrj             goto UnlockAndExit;
260ae115bc7Smrj         }
261ae115bc7Smrj 
262ae115bc7Smrj         /* Walk the linked list of handlers */
263ae115bc7Smrj 
264ae115bc7Smrj         LastObjPtr = &HandlerObj->AddressSpace.Next;
265ae115bc7Smrj         HandlerObj = HandlerObj->AddressSpace.Next;
266ae115bc7Smrj     }
267ae115bc7Smrj 
268ae115bc7Smrj     /* The handler does not exist */
269ae115bc7Smrj 
270ae115bc7Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
271ae115bc7Smrj         "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n",
272ae115bc7Smrj         Handler, AcpiUtGetRegionName (SpaceId), SpaceId, Node, ObjDesc));
273ae115bc7Smrj 
274ae115bc7Smrj     Status = AE_NOT_EXIST;
275ae115bc7Smrj 
276ae115bc7Smrj UnlockAndExit:
277ae115bc7Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
278ae115bc7Smrj     return_ACPI_STATUS (Status);
279ae115bc7Smrj }
280ae115bc7Smrj 
281ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiRemoveAddressSpaceHandler)
282