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
AcpiInstallAddressSpaceHandler(ACPI_HANDLE Device,ACPI_ADR_SPACE_TYPE SpaceId,ACPI_ADR_SPACE_HANDLER Handler,ACPI_ADR_SPACE_SETUP Setup,void * Context)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
ACPI_EXPORT_SYMBOL(AcpiInstallAddressSpaceHandler)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