1a3114836SGerry Liu /*
2a3114836SGerry Liu  * CDDL HEADER START
3a3114836SGerry Liu  *
4a3114836SGerry Liu  * The contents of this file are subject to the terms of the
5a3114836SGerry Liu  * Common Development and Distribution License (the "License").
6a3114836SGerry Liu  * You may not use this file except in compliance with the License.
7a3114836SGerry Liu  *
8a3114836SGerry Liu  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a3114836SGerry Liu  * or http://www.opensolaris.org/os/licensing.
10a3114836SGerry Liu  * See the License for the specific language governing permissions
11a3114836SGerry Liu  * and limitations under the License.
12a3114836SGerry Liu  *
13a3114836SGerry Liu  * When distributing Covered Code, include this CDDL HEADER in each
14a3114836SGerry Liu  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a3114836SGerry Liu  * If applicable, add the following below this CDDL HEADER, with the
16a3114836SGerry Liu  * fields enclosed by brackets "[]" replaced with your own identifying
17a3114836SGerry Liu  * information: Portions Copyright [yyyy] [name of copyright owner]
18a3114836SGerry Liu  *
19a3114836SGerry Liu  * CDDL HEADER END
20a3114836SGerry Liu  */
21a3114836SGerry Liu 
22a3114836SGerry Liu /*
23*26f3cdf0SGordon Ross  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
24a3114836SGerry Liu  * Copyright (c) 2010, Intel Corporation.
25a3114836SGerry Liu  * All rights reserved.
26a3114836SGerry Liu  */
27a3114836SGerry Liu 
28a3114836SGerry Liu #include <sys/types.h>
29a3114836SGerry Liu #include <sys/atomic.h>
30a3114836SGerry Liu #include <sys/bitmap.h>
31a3114836SGerry Liu #include <sys/cmn_err.h>
32a3114836SGerry Liu #include <sys/note.h>
33a3114836SGerry Liu #include <sys/sunndi.h>
34a3114836SGerry Liu #include <sys/fastboot_impl.h>
35a3114836SGerry Liu #include <sys/sysevent.h>
36a3114836SGerry Liu #include <sys/sysevent/dr.h>
37a3114836SGerry Liu #include <sys/sysevent/eventdefs.h>
38a3114836SGerry Liu #include <sys/acpi/acpi.h>
39a3114836SGerry Liu #include <sys/acpica.h>
40a3114836SGerry Liu #include <sys/acpidev.h>
41a3114836SGerry Liu #include <sys/acpidev_dr.h>
42a3114836SGerry Liu #include <sys/acpinex.h>
43a3114836SGerry Liu 
44a3114836SGerry Liu int acpinex_event_support_remove = 0;
45a3114836SGerry Liu 
46a3114836SGerry Liu static volatile uint_t acpinex_dr_event_cnt = 0;
47a3114836SGerry Liu static ulong_t acpinex_object_type_mask[BT_BITOUL(ACPI_TYPE_NS_NODE_MAX + 1)];
48a3114836SGerry Liu 
49a3114836SGerry Liu /*
50a3114836SGerry Liu  * Generate DR_REQ event to syseventd.
51a3114836SGerry Liu  * Please refer to sys/sysevent/dr.h for message definition.
52a3114836SGerry Liu  */
53a3114836SGerry Liu static int
acpinex_event_generate_event(dev_info_t * dip,ACPI_HANDLE hdl,int req,int event,char * objname)54a3114836SGerry Liu acpinex_event_generate_event(dev_info_t *dip, ACPI_HANDLE hdl, int req,
55a3114836SGerry Liu     int event, char *objname)
56a3114836SGerry Liu {
57a3114836SGerry Liu 	int rv = 0;
58a3114836SGerry Liu 	sysevent_id_t eid;
59a3114836SGerry Liu 	sysevent_value_t evnt_val;
60a3114836SGerry Liu 	sysevent_attr_list_t *evnt_attr_list = NULL;
61a3114836SGerry Liu 	char *attach_pnt;
62a3114836SGerry Liu 	char event_type[32];
63a3114836SGerry Liu 
64a3114836SGerry Liu 	/* Add "attachment point" attribute. */
65a3114836SGerry Liu 	attach_pnt = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
66a3114836SGerry Liu 	if (ACPI_FAILURE(acpidev_dr_get_attachment_point(hdl,
67a3114836SGerry Liu 	    attach_pnt, MAXPATHLEN))) {
68a3114836SGerry Liu 		cmn_err(CE_WARN,
69a3114836SGerry Liu 		    "!acpinex: failed to generate AP name for %s.", objname);
70a3114836SGerry Liu 		kmem_free(attach_pnt, MAXPATHLEN);
71a3114836SGerry Liu 		return (-1);
72a3114836SGerry Liu 	}
73a3114836SGerry Liu 	ASSERT(attach_pnt[0] != '\0');
74a3114836SGerry Liu 	evnt_val.value_type = SE_DATA_TYPE_STRING;
75a3114836SGerry Liu 	evnt_val.value.sv_string = attach_pnt;
76a3114836SGerry Liu 	rv = sysevent_add_attr(&evnt_attr_list, DR_AP_ID, &evnt_val, KM_SLEEP);
77a3114836SGerry Liu 	if (rv != 0) {
78a3114836SGerry Liu 		cmn_err(CE_WARN,
79a3114836SGerry Liu 		    "!acpinex: failed to add attr [%s] for %s event.",
80a3114836SGerry Liu 		    DR_AP_ID, EC_DR);
81a3114836SGerry Liu 		kmem_free(attach_pnt, MAXPATHLEN);
82a3114836SGerry Liu 		return (rv);
83a3114836SGerry Liu 	}
84a3114836SGerry Liu 
85a3114836SGerry Liu 	/* Add "request type" attribute. */
86a3114836SGerry Liu 	evnt_val.value_type = SE_DATA_TYPE_STRING;
87a3114836SGerry Liu 	evnt_val.value.sv_string = SE_REQ2STR(req);
88a3114836SGerry Liu 	rv = sysevent_add_attr(&evnt_attr_list, DR_REQ_TYPE, &evnt_val,
89a3114836SGerry Liu 	    KM_SLEEP);
90a3114836SGerry Liu 	if (rv != 0) {
91a3114836SGerry Liu 		cmn_err(CE_WARN,
92a3114836SGerry Liu 		    "!acpinex: failed to add attr [%s] for %s event.",
93a3114836SGerry Liu 		    DR_REQ_TYPE, EC_DR);
94a3114836SGerry Liu 		sysevent_free_attr(evnt_attr_list);
95a3114836SGerry Liu 		kmem_free(attach_pnt, MAXPATHLEN);
96a3114836SGerry Liu 		return (rv);
97a3114836SGerry Liu 	}
98a3114836SGerry Liu 
99a3114836SGerry Liu 	/* Add "acpi-event-type" attribute. */
100a3114836SGerry Liu 	switch (event) {
101a3114836SGerry Liu 	case ACPI_NOTIFY_BUS_CHECK:
102a3114836SGerry Liu 		(void) snprintf(event_type, sizeof (event_type),
103a3114836SGerry Liu 		    ACPIDEV_EVENT_TYPE_BUS_CHECK);
104a3114836SGerry Liu 		break;
105a3114836SGerry Liu 	case ACPI_NOTIFY_DEVICE_CHECK:
106a3114836SGerry Liu 		(void) snprintf(event_type, sizeof (event_type),
107a3114836SGerry Liu 		    ACPIDEV_EVENT_TYPE_DEVICE_CHECK);
108a3114836SGerry Liu 		break;
109a3114836SGerry Liu 	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
110a3114836SGerry Liu 		(void) snprintf(event_type, sizeof (event_type),
111a3114836SGerry Liu 		    ACPIDEV_EVENT_TYPE_DEVICE_CHECK_LIGHT);
112a3114836SGerry Liu 		break;
113a3114836SGerry Liu 	case ACPI_NOTIFY_EJECT_REQUEST:
114a3114836SGerry Liu 		(void) snprintf(event_type, sizeof (event_type),
115a3114836SGerry Liu 		    ACPIDEV_EVENT_TYPE_EJECT_REQUEST);
116a3114836SGerry Liu 		break;
117a3114836SGerry Liu 	default:
118a3114836SGerry Liu 		cmn_err(CE_WARN,
119a3114836SGerry Liu 		    "!acpinex: unknown ACPI event type %d.", event);
120a3114836SGerry Liu 		sysevent_free_attr(evnt_attr_list);
121a3114836SGerry Liu 		kmem_free(attach_pnt, MAXPATHLEN);
122a3114836SGerry Liu 		return (-1);
123a3114836SGerry Liu 	}
124a3114836SGerry Liu 	evnt_val.value_type = SE_DATA_TYPE_STRING;
125a3114836SGerry Liu 	evnt_val.value.sv_string = event_type;
126a3114836SGerry Liu 	rv = sysevent_add_attr(&evnt_attr_list, ACPIDEV_EVENT_TYPE_ATTR_NAME,
127a3114836SGerry Liu 	    &evnt_val, KM_SLEEP);
128a3114836SGerry Liu 	if (rv != 0) {
129a3114836SGerry Liu 		cmn_err(CE_WARN,
130a3114836SGerry Liu 		    "!acpinex: failed to add attr [%s] for %s event.",
131a3114836SGerry Liu 		    ACPIDEV_EVENT_TYPE_ATTR_NAME, EC_DR);
132a3114836SGerry Liu 		sysevent_free_attr(evnt_attr_list);
133a3114836SGerry Liu 		kmem_free(attach_pnt, MAXPATHLEN);
134a3114836SGerry Liu 		return (rv);
135a3114836SGerry Liu 	}
136a3114836SGerry Liu 
137a3114836SGerry Liu 	rv = ddi_log_sysevent(dip, DDI_VENDOR_SUNW, EC_DR, ESC_DR_REQ,
138a3114836SGerry Liu 	    evnt_attr_list, &eid, KM_SLEEP);
139a3114836SGerry Liu 	if (rv != DDI_SUCCESS) {
140a3114836SGerry Liu 		cmn_err(CE_WARN,
141a3114836SGerry Liu 		    "!acpinex: failed to log DR_REQ event for %s.", objname);
142a3114836SGerry Liu 		rv = -1;
143a3114836SGerry Liu 	}
144a3114836SGerry Liu 
145a3114836SGerry Liu 	nvlist_free(evnt_attr_list);
146a3114836SGerry Liu 	kmem_free(attach_pnt, MAXPATHLEN);
147a3114836SGerry Liu 
148a3114836SGerry Liu 	return (rv);
149a3114836SGerry Liu }
150a3114836SGerry Liu 
151a3114836SGerry Liu /*
152a3114836SGerry Liu  * Event handler for ACPI EJECT_REQUEST notifications.
153a3114836SGerry Liu  * EJECT_REQUEST notifications should be generated on the device to be ejected,
154a3114836SGerry Liu  * so no need to scan subtree of it.
155a3114836SGerry Liu  * It also invokes ACPI _OST method to update event status if call_ost is true.
156a3114836SGerry Liu  */
157a3114836SGerry Liu static void
acpinex_event_handle_eject_request(ACPI_HANDLE hdl,acpinex_softstate_t * sp,boolean_t call_ost)158a3114836SGerry Liu acpinex_event_handle_eject_request(ACPI_HANDLE hdl, acpinex_softstate_t *sp,
159a3114836SGerry Liu     boolean_t call_ost)
160a3114836SGerry Liu {
161a3114836SGerry Liu 	int code;
162a3114836SGerry Liu 	char *objname;
163a3114836SGerry Liu 
164a3114836SGerry Liu 	ASSERT(hdl != NULL);
165a3114836SGerry Liu 	objname = acpidev_get_object_name(hdl);
166a3114836SGerry Liu 
167a3114836SGerry Liu 	ASSERT(sp != NULL);
168a3114836SGerry Liu 	ASSERT(sp->ans_dip != NULL && sp->ans_hdl != NULL);
169a3114836SGerry Liu 	if (sp == NULL || sp->ans_dip == NULL || sp->ans_hdl == NULL) {
170a3114836SGerry Liu 		if (call_ost) {
171a3114836SGerry Liu 			(void) acpidev_eval_ost(hdl, ACPI_NOTIFY_EJECT_REQUEST,
172a3114836SGerry Liu 			    ACPI_OST_STA_FAILURE, NULL, 0);
173a3114836SGerry Liu 		}
174a3114836SGerry Liu 		ACPINEX_DEBUG(CE_WARN,
175a3114836SGerry Liu 		    "!acpinex: softstate data structure is invalid.");
176a3114836SGerry Liu 		cmn_err(CE_WARN,
177a3114836SGerry Liu 		    "!acpinex: failed to handle EJECT_REQUEST event from %s.",
178a3114836SGerry Liu 		    objname);
179a3114836SGerry Liu 		acpidev_free_object_name(objname);
180a3114836SGerry Liu 		return;
181a3114836SGerry Liu 	}
182a3114836SGerry Liu 
183a3114836SGerry Liu 	if (acpinex_event_support_remove == 0) {
184a3114836SGerry Liu 		cmn_err(CE_WARN,
185a3114836SGerry Liu 		    "!acpinex: hot-removing of device %s is unsupported.",
186a3114836SGerry Liu 		    objname);
187a3114836SGerry Liu 		code = ACPI_OST_STA_EJECT_NOT_SUPPORT;
188a3114836SGerry Liu 	} else if (acpinex_event_generate_event(sp->ans_dip, hdl,
189a3114836SGerry Liu 	    SE_OUTGOING_RES, ACPI_NOTIFY_EJECT_REQUEST, objname) != 0) {
190a3114836SGerry Liu 		cmn_err(CE_WARN, "!acpinex: failed to generate ESC_DR_REQ "
191a3114836SGerry Liu 		    "event for device eject request from %s.", objname);
192a3114836SGerry Liu 		code = ACPI_OST_STA_FAILURE;
193a3114836SGerry Liu 	} else {
194a3114836SGerry Liu 		cmn_err(CE_NOTE, "!acpinex: generate ESC_DR_REQ event for "
195a3114836SGerry Liu 		    "device eject request from %s.", objname);
196a3114836SGerry Liu 		code = ACPI_OST_STA_EJECT_IN_PROGRESS;
197a3114836SGerry Liu 	}
198a3114836SGerry Liu 	if (call_ost) {
199a3114836SGerry Liu 		(void) acpidev_eval_ost(hdl, ACPI_NOTIFY_EJECT_REQUEST,
200a3114836SGerry Liu 		    code, NULL, 0);
201a3114836SGerry Liu 	}
202a3114836SGerry Liu 
203a3114836SGerry Liu 	acpidev_free_object_name(objname);
204a3114836SGerry Liu }
205a3114836SGerry Liu 
206a3114836SGerry Liu struct acpinex_event_check_arg {
207a3114836SGerry Liu 	acpinex_softstate_t	*softstatep;
208a3114836SGerry Liu 	int			event_type;
209a3114836SGerry Liu 	uint32_t		device_insert;
210a3114836SGerry Liu 	uint32_t		device_remove;
211a3114836SGerry Liu 	uint32_t		device_fail;
212a3114836SGerry Liu };
213a3114836SGerry Liu 
214a3114836SGerry Liu static ACPI_STATUS
acpinex_event_handle_check_one(ACPI_HANDLE hdl,UINT32 lvl,void * ctx,void ** retval)215a3114836SGerry Liu acpinex_event_handle_check_one(ACPI_HANDLE hdl, UINT32 lvl, void *ctx,
216a3114836SGerry Liu     void **retval)
217a3114836SGerry Liu {
218a3114836SGerry Liu 	_NOTE(ARGUNUSED(lvl, retval));
219a3114836SGerry Liu 
220a3114836SGerry Liu 	char *objname;
221a3114836SGerry Liu 	int status, psta, csta;
222a3114836SGerry Liu 	acpidev_data_handle_t dhdl;
223a3114836SGerry Liu 	struct acpinex_event_check_arg *argp;
224a3114836SGerry Liu 
225a3114836SGerry Liu 	ASSERT(hdl != NULL);
226a3114836SGerry Liu 	ASSERT(ctx != NULL);
227a3114836SGerry Liu 	argp = (struct acpinex_event_check_arg *)ctx;
228a3114836SGerry Liu 
229a3114836SGerry Liu 	dhdl = acpidev_data_get_handle(hdl);
230a3114836SGerry Liu 	if (dhdl == NULL) {
231a3114836SGerry Liu 		/* Skip subtree if failed to get the data handle. */
232a3114836SGerry Liu 		ACPINEX_DEBUG(CE_NOTE,
233a3114836SGerry Liu 		    "!acpinex: failed to get data associated with %p.", hdl);
234a3114836SGerry Liu 		return (AE_CTRL_DEPTH);
235a3114836SGerry Liu 	} else if (!acpidev_data_dr_capable(dhdl)) {
236a3114836SGerry Liu 		return (AE_OK);
237a3114836SGerry Liu 	}
238a3114836SGerry Liu 
239a3114836SGerry Liu 	objname = acpidev_get_object_name(hdl);
240a3114836SGerry Liu 
241a3114836SGerry Liu 	status = 0;
242a3114836SGerry Liu 	/* Query previous device status. */
243a3114836SGerry Liu 	psta = acpidev_data_get_status(dhdl);
244a3114836SGerry Liu 	if (acpidev_check_device_enabled(psta)) {
245a3114836SGerry Liu 		status |= 0x1;
246a3114836SGerry Liu 	}
247a3114836SGerry Liu 	/* Query current device status. */
248a3114836SGerry Liu 	csta = acpidev_query_device_status(hdl);
249a3114836SGerry Liu 	if (acpidev_check_device_enabled(csta)) {
250a3114836SGerry Liu 		status |= 0x2;
251a3114836SGerry Liu 	}
252a3114836SGerry Liu 
253a3114836SGerry Liu 	switch (status) {
254a3114836SGerry Liu 	case 0x0:
255a3114836SGerry Liu 		/*FALLTHROUGH*/
256a3114836SGerry Liu 	case 0x3:
257a3114836SGerry Liu 		/* No status changes, keep on walking. */
258a3114836SGerry Liu 		acpidev_free_object_name(objname);
259a3114836SGerry Liu 		return (AE_OK);
260a3114836SGerry Liu 
261a3114836SGerry Liu 	case 0x1:
262a3114836SGerry Liu 		/* Surprising removal. */
263a3114836SGerry Liu 		cmn_err(CE_WARN,
264a3114836SGerry Liu 		    "!acpinex: device %s has been surprisingly removed.",
265a3114836SGerry Liu 		    objname);
266a3114836SGerry Liu 		if (argp->event_type == ACPI_NOTIFY_BUS_CHECK) {
267a3114836SGerry Liu 			/*
268a3114836SGerry Liu 			 * According to ACPI spec, BUS_CHECK notification
269a3114836SGerry Liu 			 * should be triggered for hot-adding events only.
270a3114836SGerry Liu 			 */
271a3114836SGerry Liu 			ACPINEX_DEBUG(CE_WARN,
272a3114836SGerry Liu 			    "!acpinex: device %s has been surprisingly removed "
273a3114836SGerry Liu 			    "when handling BUS_CHECK event.", objname);
274a3114836SGerry Liu 		}
275a3114836SGerry Liu 		acpidev_free_object_name(objname);
276a3114836SGerry Liu 		argp->device_remove++;
277a3114836SGerry Liu 		return (AE_CTRL_DEPTH);
278a3114836SGerry Liu 
279a3114836SGerry Liu 	case 0x2:
280a3114836SGerry Liu 		/* Hot-adding. */
281a3114836SGerry Liu 		ACPINEX_DEBUG(CE_NOTE,
282a3114836SGerry Liu 		    "!acpinex: device %s has been inserted.", objname);
283a3114836SGerry Liu 		argp->device_insert++;
284a3114836SGerry Liu 		if (acpinex_event_generate_event(argp->softstatep->ans_dip, hdl,
285a3114836SGerry Liu 		    SE_INCOMING_RES, argp->event_type, objname) != 0) {
286a3114836SGerry Liu 			cmn_err(CE_WARN,
287a3114836SGerry Liu 			    "!acpinex: failed to generate ESC_DR_REQ event for "
288a3114836SGerry Liu 			    "device insert request from %s.", objname);
289a3114836SGerry Liu 			argp->device_fail++;
290a3114836SGerry Liu 		} else {
291a3114836SGerry Liu 			cmn_err(CE_NOTE, "!acpinex: generate ESC_DR_REQ event "
292a3114836SGerry Liu 			    "for device insert request from %s.", objname);
293a3114836SGerry Liu 		}
294a3114836SGerry Liu 		acpidev_free_object_name(objname);
295a3114836SGerry Liu 		return (AE_OK);
296a3114836SGerry Liu 
297a3114836SGerry Liu 	default:
298a3114836SGerry Liu 		ASSERT(0);
299a3114836SGerry Liu 		break;
300a3114836SGerry Liu 	}
301a3114836SGerry Liu 
302a3114836SGerry Liu 	return (AE_ERROR);
303a3114836SGerry Liu }
304a3114836SGerry Liu 
305a3114836SGerry Liu /*
306a3114836SGerry Liu  * Event handler for BUS_CHECK/DEVICE_CHECK/DEVICE_CHECK_LIGHT notifications.
307a3114836SGerry Liu  * These events may be signaled on parent/ancestor of devices to be hot-added,
308a3114836SGerry Liu  * so need to scan ACPI namespace to figure out devices in question.
309a3114836SGerry Liu  * It also invokes ACPI _OST method to update event status if call_ost is true.
310a3114836SGerry Liu  */
311a3114836SGerry Liu static void
acpinex_event_handle_check_request(int event,ACPI_HANDLE hdl,acpinex_softstate_t * sp,boolean_t call_ost)312a3114836SGerry Liu acpinex_event_handle_check_request(int event, ACPI_HANDLE hdl,
313a3114836SGerry Liu     acpinex_softstate_t *sp, boolean_t call_ost)
314a3114836SGerry Liu {
315a3114836SGerry Liu 	ACPI_STATUS rv;
316a3114836SGerry Liu 	int code;
317a3114836SGerry Liu 	char *objname;
318a3114836SGerry Liu 	struct acpinex_event_check_arg arg;
319a3114836SGerry Liu 
320a3114836SGerry Liu 	ASSERT(hdl != NULL);
321a3114836SGerry Liu 	objname = acpidev_get_object_name(hdl);
322a3114836SGerry Liu 
323a3114836SGerry Liu 	ASSERT(sp != NULL);
324a3114836SGerry Liu 	ASSERT(sp->ans_dip != NULL && sp->ans_hdl != NULL);
325a3114836SGerry Liu 	if (sp == NULL || sp->ans_dip == NULL || sp->ans_hdl == NULL) {
326a3114836SGerry Liu 		if (call_ost) {
327a3114836SGerry Liu 			(void) acpidev_eval_ost(hdl, event,
328a3114836SGerry Liu 			    ACPI_OST_STA_FAILURE, NULL, 0);
329a3114836SGerry Liu 		}
330a3114836SGerry Liu 		ACPINEX_DEBUG(CE_WARN,
331a3114836SGerry Liu 		    "!acpinex: softstate data structure is invalid.");
332a3114836SGerry Liu 		cmn_err(CE_WARN, "!acpinex: failed to handle "
333a3114836SGerry Liu 		    "BUS/DEVICE_CHECK event from %s.", objname);
334a3114836SGerry Liu 		acpidev_free_object_name(objname);
335a3114836SGerry Liu 		return;
336a3114836SGerry Liu 	}
337a3114836SGerry Liu 
338a3114836SGerry Liu 	bzero(&arg, sizeof (arg));
339a3114836SGerry Liu 	arg.event_type = event;
340a3114836SGerry Liu 	arg.softstatep = sp;
341a3114836SGerry Liu 	rv = acpinex_event_handle_check_one(hdl, 0, &arg, NULL);
342a3114836SGerry Liu 	if (ACPI_SUCCESS(rv)) {
343a3114836SGerry Liu 		rv = AcpiWalkNamespace(ACPI_TYPE_DEVICE, hdl,
344a3114836SGerry Liu 		    ACPIDEV_MAX_ENUM_LEVELS,
345a3114836SGerry Liu 		    &acpinex_event_handle_check_one, NULL, &arg, NULL);
346a3114836SGerry Liu 	}
347a3114836SGerry Liu 
348a3114836SGerry Liu 	if (ACPI_FAILURE(rv)) {
349a3114836SGerry Liu 		/* Failed to scan the ACPI namespace. */
350a3114836SGerry Liu 		cmn_err(CE_WARN, "!acpinex: failed to handle event %d from %s.",
351a3114836SGerry Liu 		    event, objname);
352a3114836SGerry Liu 		code = ACPI_OST_STA_FAILURE;
353a3114836SGerry Liu 	} else if (arg.device_remove != 0) {
354a3114836SGerry Liu 		/* Surprising removal happened. */
355a3114836SGerry Liu 		ACPINEX_DEBUG(CE_WARN,
356a3114836SGerry Liu 		    "!acpinex: some devices have been surprisingly removed.");
357a3114836SGerry Liu 		code = ACPI_OST_STA_NOT_SUPPORT;
358a3114836SGerry Liu 	} else if (arg.device_fail != 0) {
359a3114836SGerry Liu 		/* Failed to handle some devices. */
360a3114836SGerry Liu 		ACPINEX_DEBUG(CE_WARN,
361a3114836SGerry Liu 		    "!acpinex: failed to check status of some devices.");
362a3114836SGerry Liu 		code = ACPI_OST_STA_FAILURE;
363a3114836SGerry Liu 	} else if (arg.device_insert == 0) {
364a3114836SGerry Liu 		/* No hot-added devices found. */
365a3114836SGerry Liu 		cmn_err(CE_WARN,
366a3114836SGerry Liu 		    "!acpinex: no hot-added devices under %s found.", objname);
367a3114836SGerry Liu 		code = ACPI_OST_STA_FAILURE;
368a3114836SGerry Liu 	} else {
369a3114836SGerry Liu 		code = ACPI_OST_STA_INSERT_IN_PROGRESS;
370a3114836SGerry Liu 	}
371a3114836SGerry Liu 	if (call_ost) {
372a3114836SGerry Liu 		(void) acpidev_eval_ost(hdl, event, code, NULL, 0);
373a3114836SGerry Liu 	}
374a3114836SGerry Liu 
375a3114836SGerry Liu 	acpidev_free_object_name(objname);
376a3114836SGerry Liu }
377a3114836SGerry Liu 
378a3114836SGerry Liu static void
acpinex_event_system_handler(ACPI_HANDLE hdl,UINT32 type,void * arg)379a3114836SGerry Liu acpinex_event_system_handler(ACPI_HANDLE hdl, UINT32 type, void *arg)
380a3114836SGerry Liu {
381a3114836SGerry Liu 	acpinex_softstate_t *sp;
382a3114836SGerry Liu 
383a3114836SGerry Liu 	ASSERT(hdl != NULL);
384a3114836SGerry Liu 	ASSERT(arg != NULL);
385a3114836SGerry Liu 	sp = (acpinex_softstate_t *)arg;
386a3114836SGerry Liu 
387a3114836SGerry Liu 	acpidev_dr_lock_all();
388a3114836SGerry Liu 	mutex_enter(&sp->ans_lock);
389a3114836SGerry Liu 
390a3114836SGerry Liu 	switch (type) {
391a3114836SGerry Liu 	case ACPI_NOTIFY_BUS_CHECK:
392a3114836SGerry Liu 		/*
393a3114836SGerry Liu 		 * Bus Check. This notification is performed on a device object
394a3114836SGerry Liu 		 * to indicate to OSPM that it needs to perform the Plug and
395a3114836SGerry Liu 		 * Play re-enumeration operation on the device tree starting
396a3114836SGerry Liu 		 * from the point where it has been notified. OSPM will only
397a3114836SGerry Liu 		 * perform this operation at boot, and when notified. It is
398a3114836SGerry Liu 		 * the responsibility of the ACPI AML code to notify OSPM at
399a3114836SGerry Liu 		 * any other times that this operation is required. The more
400a3114836SGerry Liu 		 * accurately and closer to the actual device tree change the
401a3114836SGerry Liu 		 * notification can be done, the more efficient the operating
402a3114836SGerry Liu 		 * system response will be; however, it can also be an issue
403a3114836SGerry Liu 		 * when a device change cannot be confirmed. For example, if
404a3114836SGerry Liu 		 * the hardware cannot notice a device change for a particular
405a3114836SGerry Liu 		 * location during a system sleeping state, it issues a Bus
406a3114836SGerry Liu 		 * Check notification on wake to inform OSPM that it needs to
407a3114836SGerry Liu 		 * check the configuration for a device change.
408a3114836SGerry Liu 		 */
409a3114836SGerry Liu 		/*FALLTHROUGH*/
410a3114836SGerry Liu 	case ACPI_NOTIFY_DEVICE_CHECK:
411a3114836SGerry Liu 		/*
412a3114836SGerry Liu 		 * Device Check. Used to notify OSPM that the device either
413a3114836SGerry Liu 		 * appeared or disappeared. If the device has appeared, OSPM
414a3114836SGerry Liu 		 * will re-enumerate from the parent. If the device has
415a3114836SGerry Liu 		 * disappeared, OSPM will invalidate the state of the device.
416a3114836SGerry Liu 		 * OSPM may optimize out re-enumeration. If _DCK is present,
417a3114836SGerry Liu 		 * then Notify(object,1) is assumed to indicate an undock
418a3114836SGerry Liu 		 * request.
419a3114836SGerry Liu 		 */
420a3114836SGerry Liu 		/*FALLTHROUGH*/
421a3114836SGerry Liu 	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
422a3114836SGerry Liu 		/*
423a3114836SGerry Liu 		 * Device Check Light. Used to notify OSPM that the device
424a3114836SGerry Liu 		 * either appeared or disappeared. If the device has appeared,
425a3114836SGerry Liu 		 * OSPM will re-enumerate from the device itself, not the
426a3114836SGerry Liu 		 * parent. If the device has disappeared, OSPM will invalidate
427a3114836SGerry Liu 		 * the state of the device.
428a3114836SGerry Liu 		 */
429a3114836SGerry Liu 		atomic_inc_uint(&acpinex_dr_event_cnt);
430a3114836SGerry Liu 		acpinex_event_handle_check_request(type, hdl, sp, B_TRUE);
431a3114836SGerry Liu 		break;
432a3114836SGerry Liu 
433a3114836SGerry Liu 	case ACPI_NOTIFY_EJECT_REQUEST:
434a3114836SGerry Liu 		/*
435a3114836SGerry Liu 		 * Eject Request. Used to notify OSPM that the device should
436a3114836SGerry Liu 		 * be ejected, and that OSPM needs to perform the Plug and Play
437a3114836SGerry Liu 		 * ejection operation. OSPM will run the _EJx method.
438a3114836SGerry Liu 		 */
439a3114836SGerry Liu 		atomic_inc_uint(&acpinex_dr_event_cnt);
440a3114836SGerry Liu 		acpinex_event_handle_eject_request(hdl, sp, B_TRUE);
441a3114836SGerry Liu 		break;
442a3114836SGerry Liu 
443a3114836SGerry Liu 	default:
444a3114836SGerry Liu 		ACPINEX_DEBUG(CE_NOTE,
445a3114836SGerry Liu 		    "!acpinex: unhandled event(%d) on hdl %p under %s.",
446a3114836SGerry Liu 		    type, hdl, sp->ans_path);
447a3114836SGerry Liu 		(void) acpidev_eval_ost(hdl, type, ACPI_OST_STA_NOT_SUPPORT,
448a3114836SGerry Liu 		    NULL, 0);
449a3114836SGerry Liu 		break;
450a3114836SGerry Liu 	}
451a3114836SGerry Liu 
452a3114836SGerry Liu 	if (acpinex_dr_event_cnt != 0) {
453a3114836SGerry Liu 		/*
454a3114836SGerry Liu 		 * Disable fast reboot if a CPU/MEM/IOH hotplug event happens.
455a3114836SGerry Liu 		 * Note: this is a temporary solution and will be revised when
456a3114836SGerry Liu 		 * fast reboot can support CPU/MEM/IOH DR operations in the
457a3114836SGerry Liu 		 * future.
458a3114836SGerry Liu 		 *
459a3114836SGerry Liu 		 * ACPI BIOS generates some static ACPI tables, such as MADT,
460a3114836SGerry Liu 		 * SRAT and SLIT, to describe the system hardware configuration
461a3114836SGerry Liu 		 * on power-on. When a CPU/MEM/IOH hotplug event happens, those
462a3114836SGerry Liu 		 * static tables won't be updated and will become stale.
463a3114836SGerry Liu 		 *
464a3114836SGerry Liu 		 * If we reset the system by fast reboot, BIOS will have no
465a3114836SGerry Liu 		 * chance to regenerate those staled static tables. Fast reboot
466a3114836SGerry Liu 		 * can't tolerate such inconsistency between staled ACPI tables
467a3114836SGerry Liu 		 * and real hardware configuration yet.
468a3114836SGerry Liu 		 *
469a3114836SGerry Liu 		 * A temporary solution is introduced to disable fast reboot if
470a3114836SGerry Liu 		 * CPU/MEM/IOH hotplug event happens. This solution should be
471a3114836SGerry Liu 		 * revised when fast reboot is enhanced to support CPU/MEM/IOH
472a3114836SGerry Liu 		 * DR operations.
473a3114836SGerry Liu 		 */
474a3114836SGerry Liu 		fastreboot_disable(FBNS_HOTPLUG);
475a3114836SGerry Liu 	}
476a3114836SGerry Liu 
477a3114836SGerry Liu 	mutex_exit(&sp->ans_lock);
478a3114836SGerry Liu 	acpidev_dr_unlock_all();
479a3114836SGerry Liu }
480a3114836SGerry Liu 
481a3114836SGerry Liu /*
482a3114836SGerry Liu  * Install event handler for ACPI system events.
483a3114836SGerry Liu  * Acpinex driver handles ACPI system events for its children,
484a3114836SGerry Liu  * device specific events will be handled by device drivers.
485a3114836SGerry Liu  * Return DDI_SUCCESS on success, and DDI_FAILURE on failure.
486a3114836SGerry Liu  */
487a3114836SGerry Liu static int
acpinex_event_install_handler(ACPI_HANDLE hdl,void * arg,ACPI_DEVICE_INFO * infop,acpidev_data_handle_t dhdl)488a3114836SGerry Liu acpinex_event_install_handler(ACPI_HANDLE hdl, void *arg,
489a3114836SGerry Liu     ACPI_DEVICE_INFO *infop, acpidev_data_handle_t dhdl)
490a3114836SGerry Liu {
491*26f3cdf0SGordon Ross 	ACPI_STATUS status;
492a3114836SGerry Liu 	int rc = DDI_SUCCESS;
493a3114836SGerry Liu 
494a3114836SGerry Liu 	ASSERT(hdl != NULL);
495a3114836SGerry Liu 	ASSERT(dhdl != NULL);
496a3114836SGerry Liu 	ASSERT(infop != NULL);
497a3114836SGerry Liu 
498a3114836SGerry Liu 	/*
499a3114836SGerry Liu 	 * Check whether the event handler has already been installed on the
500a3114836SGerry Liu 	 * device object. With the introduction of ACPI Alias objects, which are
501a3114836SGerry Liu 	 * similar to symlinks in file systems, there may be multiple name
502a3114836SGerry Liu 	 * objects in the ACPI namespace pointing to the same underlying device
503a3114836SGerry Liu 	 * object. Those Alias objects need to be filtered out, otherwise
504a3114836SGerry Liu 	 * it will attempt to install the event handler multiple times on the
505a3114836SGerry Liu 	 * same device object which will fail.
506a3114836SGerry Liu 	 */
507a3114836SGerry Liu 	if (acpidev_data_get_flag(dhdl, ACPIDEV_DATA_HANDLER_READY)) {
508a3114836SGerry Liu 		return (DDI_SUCCESS);
509a3114836SGerry Liu 	}
510*26f3cdf0SGordon Ross 	status = AcpiInstallNotifyHandler(hdl, ACPI_SYSTEM_NOTIFY,
511*26f3cdf0SGordon Ross 	    acpinex_event_system_handler, arg);
512*26f3cdf0SGordon Ross 	if (status == AE_OK || status == AE_ALREADY_EXISTS) {
513a3114836SGerry Liu 		acpidev_data_set_flag(dhdl, ACPIDEV_DATA_HANDLER_READY);
514a3114836SGerry Liu 	} else {
515a3114836SGerry Liu 		char *objname;
516a3114836SGerry Liu 
517a3114836SGerry Liu 		objname = acpidev_get_object_name(hdl);
518a3114836SGerry Liu 		cmn_err(CE_WARN,
519a3114836SGerry Liu 		    "!acpinex: failed to install system event handler for %s.",
520a3114836SGerry Liu 		    objname);
521a3114836SGerry Liu 		acpidev_free_object_name(objname);
522a3114836SGerry Liu 		rc = DDI_FAILURE;
523a3114836SGerry Liu 	}
524a3114836SGerry Liu 
525a3114836SGerry Liu 	return (rc);
526a3114836SGerry Liu }
527a3114836SGerry Liu 
528a3114836SGerry Liu /*
529a3114836SGerry Liu  * Uninstall event handler for ACPI system events.
530a3114836SGerry Liu  * Return DDI_SUCCESS on success, and DDI_FAILURE on failure.
531a3114836SGerry Liu  */
532a3114836SGerry Liu static int
acpinex_event_uninstall_handler(ACPI_HANDLE hdl,ACPI_DEVICE_INFO * infop,acpidev_data_handle_t dhdl)533a3114836SGerry Liu acpinex_event_uninstall_handler(ACPI_HANDLE hdl, ACPI_DEVICE_INFO *infop,
534a3114836SGerry Liu     acpidev_data_handle_t dhdl)
535a3114836SGerry Liu {
536a3114836SGerry Liu 	ASSERT(hdl != NULL);
537a3114836SGerry Liu 	ASSERT(dhdl != NULL);
538a3114836SGerry Liu 	ASSERT(infop != NULL);
539a3114836SGerry Liu 
540a3114836SGerry Liu 	if (!acpidev_data_get_flag(dhdl, ACPIDEV_DATA_HANDLER_READY)) {
541a3114836SGerry Liu 		return (DDI_SUCCESS);
542a3114836SGerry Liu 	}
543a3114836SGerry Liu 	if (ACPI_SUCCESS(AcpiRemoveNotifyHandler(hdl, ACPI_SYSTEM_NOTIFY,
544a3114836SGerry Liu 	    acpinex_event_system_handler))) {
545a3114836SGerry Liu 		acpidev_data_clear_flag(dhdl, ACPIDEV_DATA_HANDLER_READY);
546a3114836SGerry Liu 	} else {
547a3114836SGerry Liu 		char *objname;
548a3114836SGerry Liu 
549a3114836SGerry Liu 		objname = acpidev_get_object_name(hdl);
550a3114836SGerry Liu 		cmn_err(CE_WARN, "!acpinex: failed to uninstall system event "
551a3114836SGerry Liu 		    "handler for %s.", objname);
552a3114836SGerry Liu 		acpidev_free_object_name(objname);
553a3114836SGerry Liu 		return (DDI_FAILURE);
554a3114836SGerry Liu 	}
555a3114836SGerry Liu 
556a3114836SGerry Liu 	return (DDI_SUCCESS);
557a3114836SGerry Liu }
558a3114836SGerry Liu 
559a3114836SGerry Liu /*
560a3114836SGerry Liu  * Install/uninstall ACPI system event handler for child objects of hdl.
561a3114836SGerry Liu  * Return DDI_SUCCESS on success, and DDI_FAILURE on failure.
562a3114836SGerry Liu  */
563a3114836SGerry Liu static int
acpinex_event_walk(boolean_t init,acpinex_softstate_t * sp,ACPI_HANDLE hdl)564a3114836SGerry Liu acpinex_event_walk(boolean_t init, acpinex_softstate_t *sp, ACPI_HANDLE hdl)
565a3114836SGerry Liu {
566a3114836SGerry Liu 	int rc;
567a3114836SGerry Liu 	int retval = DDI_SUCCESS;
568a3114836SGerry Liu 	dev_info_t *dip;
569a3114836SGerry Liu 	ACPI_HANDLE child = NULL;
570a3114836SGerry Liu 	ACPI_OBJECT_TYPE type;
571a3114836SGerry Liu 	ACPI_DEVICE_INFO *infop;
572a3114836SGerry Liu 	acpidev_data_handle_t dhdl;
573a3114836SGerry Liu 
574a3114836SGerry Liu 	/* Walk all child objects. */
575a3114836SGerry Liu 	ASSERT(hdl != NULL);
576a3114836SGerry Liu 	while (ACPI_SUCCESS(AcpiGetNextObject(ACPI_TYPE_ANY, hdl, child,
577a3114836SGerry Liu 	    &child))) {
578a3114836SGerry Liu 		/* Skip unwanted object types. */
579a3114836SGerry Liu 		if (ACPI_FAILURE(AcpiGetType(child, &type)) ||
580a3114836SGerry Liu 		    type > ACPI_TYPE_NS_NODE_MAX ||
581a3114836SGerry Liu 		    BT_TEST(acpinex_object_type_mask, type) == 0) {
582a3114836SGerry Liu 			continue;
583a3114836SGerry Liu 		}
584a3114836SGerry Liu 
585a3114836SGerry Liu 		/* Get data associated with the object. Skip it if fails. */
586a3114836SGerry Liu 		dhdl = acpidev_data_get_handle(child);
587a3114836SGerry Liu 		if (dhdl == NULL) {
588a3114836SGerry Liu 			ACPINEX_DEBUG(CE_NOTE, "!acpinex: failed to get data "
589a3114836SGerry Liu 			    "associated with %p, skip.", child);
590a3114836SGerry Liu 			continue;
591a3114836SGerry Liu 		}
592a3114836SGerry Liu 
593a3114836SGerry Liu 		/* Query ACPI object info for the object. */
594a3114836SGerry Liu 		if (ACPI_FAILURE(AcpiGetObjectInfo(child, &infop))) {
595a3114836SGerry Liu 			cmn_err(CE_WARN,
596a3114836SGerry Liu 			    "!acpidnex: failed to get object info for %p.",
597a3114836SGerry Liu 			    child);
598a3114836SGerry Liu 			continue;
599a3114836SGerry Liu 		}
600a3114836SGerry Liu 
601a3114836SGerry Liu 		if (init) {
602a3114836SGerry Liu 			rc = acpinex_event_install_handler(child, sp, infop,
603a3114836SGerry Liu 			    dhdl);
604a3114836SGerry Liu 			if (rc != DDI_SUCCESS) {
605a3114836SGerry Liu 				ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to "
606a3114836SGerry Liu 				    "install handler for child %p of %s.",
607a3114836SGerry Liu 				    child, sp->ans_path);
608a3114836SGerry Liu 				retval = DDI_FAILURE;
609a3114836SGerry Liu 			/*
610a3114836SGerry Liu 			 * Try to handle descendants if both of the
611a3114836SGerry Liu 			 * following two conditions are true:
612a3114836SGerry Liu 			 * 1) Device corresponding to the current object is
613a3114836SGerry Liu 			 *    enabled. If the device is absent/disabled,
614a3114836SGerry Liu 			 *    no notification should be generated from
615a3114836SGerry Liu 			 *    descendant objects of it.
616a3114836SGerry Liu 			 * 2) No Solaris device node has been created for the
617a3114836SGerry Liu 			 *    current object yet. If the device node has been
618a3114836SGerry Liu 			 *    created for the current object, notification
619a3114836SGerry Liu 			 *    events from child objects should be handled by
620a3114836SGerry Liu 			 *    the corresponding driver.
621a3114836SGerry Liu 			 */
622a3114836SGerry Liu 			} else if (acpidev_check_device_enabled(
623a3114836SGerry Liu 			    acpidev_data_get_status(dhdl)) &&
624a3114836SGerry Liu 			    ACPI_FAILURE(acpica_get_devinfo(child, &dip))) {
625a3114836SGerry Liu 				rc = acpinex_event_walk(B_TRUE, sp, child);
626a3114836SGerry Liu 				if (rc != DDI_SUCCESS) {
627a3114836SGerry Liu 					ACPINEX_DEBUG(CE_WARN,
628a3114836SGerry Liu 					    "!acpinex: failed to install "
629a3114836SGerry Liu 					    "handler for descendants of %s.",
630a3114836SGerry Liu 					    sp->ans_path);
631a3114836SGerry Liu 					retval = DDI_FAILURE;
632a3114836SGerry Liu 				}
633a3114836SGerry Liu 			}
634a3114836SGerry Liu 		} else {
635a3114836SGerry Liu 			rc = DDI_SUCCESS;
636a3114836SGerry Liu 			/* Uninstall handler for descendants if needed. */
637a3114836SGerry Liu 			if (ACPI_FAILURE(acpica_get_devinfo(child, &dip))) {
638a3114836SGerry Liu 				rc = acpinex_event_walk(B_FALSE, sp, child);
639a3114836SGerry Liu 			}
640a3114836SGerry Liu 			if (rc == DDI_SUCCESS) {
641a3114836SGerry Liu 				rc = acpinex_event_uninstall_handler(child,
642a3114836SGerry Liu 				    infop, dhdl);
643a3114836SGerry Liu 			}
644a3114836SGerry Liu 			/* Undo will be done by caller in case of failure. */
645a3114836SGerry Liu 			if (rc != DDI_SUCCESS) {
646a3114836SGerry Liu 				ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to "
647a3114836SGerry Liu 				    "uninstall handler for descendants of %s.",
648a3114836SGerry Liu 				    sp->ans_path);
649a3114836SGerry Liu 				AcpiOsFree(infop);
650a3114836SGerry Liu 				retval = DDI_FAILURE;
651a3114836SGerry Liu 				break;
652a3114836SGerry Liu 			}
653a3114836SGerry Liu 		}
654a3114836SGerry Liu 
655a3114836SGerry Liu 		/* Release cached resources. */
656a3114836SGerry Liu 		AcpiOsFree(infop);
657a3114836SGerry Liu 	}
658a3114836SGerry Liu 
659a3114836SGerry Liu 	return (retval);
660a3114836SGerry Liu }
661a3114836SGerry Liu 
662a3114836SGerry Liu int
acpinex_event_scan(acpinex_softstate_t * sp,boolean_t init)663a3114836SGerry Liu acpinex_event_scan(acpinex_softstate_t *sp, boolean_t init)
664a3114836SGerry Liu {
665a3114836SGerry Liu 	int rc;
666a3114836SGerry Liu 
667a3114836SGerry Liu 	ASSERT(sp != NULL);
668a3114836SGerry Liu 	ASSERT(sp->ans_hdl != NULL);
669a3114836SGerry Liu 	ASSERT(sp->ans_dip != NULL);
670a3114836SGerry Liu 	if (sp == NULL || sp->ans_hdl == NULL || sp->ans_dip == NULL) {
671a3114836SGerry Liu 		ACPINEX_DEBUG(CE_WARN,
672a3114836SGerry Liu 		    "!acpinex: invalid parameter to acpinex_event_scan().");
673a3114836SGerry Liu 		return (DDI_FAILURE);
674a3114836SGerry Liu 	}
675a3114836SGerry Liu 
676a3114836SGerry Liu 	/* Lock current device node and walk all child device nodes of it. */
677a3114836SGerry Liu 	mutex_enter(&sp->ans_lock);
678a3114836SGerry Liu 
679a3114836SGerry Liu 	rc = acpinex_event_walk(init, sp, sp->ans_hdl);
680a3114836SGerry Liu 	if (rc != DDI_SUCCESS) {
681a3114836SGerry Liu 		if (init) {
682a3114836SGerry Liu 			ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to "
683a3114836SGerry Liu 			    "configure child objects of %s.", sp->ans_path);
684a3114836SGerry Liu 			rc = DDI_FAILURE;
685a3114836SGerry Liu 		} else {
686a3114836SGerry Liu 			ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to "
687a3114836SGerry Liu 			    "unconfigure child objects of %s.", sp->ans_path);
688a3114836SGerry Liu 			/* Undo in case of errors */
689a3114836SGerry Liu 			(void) acpinex_event_walk(B_TRUE, sp, sp->ans_hdl);
690a3114836SGerry Liu 			rc = DDI_FAILURE;
691a3114836SGerry Liu 		}
692a3114836SGerry Liu 	}
693a3114836SGerry Liu 
694a3114836SGerry Liu 	mutex_exit(&sp->ans_lock);
695a3114836SGerry Liu 
696a3114836SGerry Liu 	return (rc);
697a3114836SGerry Liu }
698a3114836SGerry Liu 
699a3114836SGerry Liu void
acpinex_event_init(void)700a3114836SGerry Liu acpinex_event_init(void)
701a3114836SGerry Liu {
702a3114836SGerry Liu 	/*
703a3114836SGerry Liu 	 * According to ACPI specifications, notification is only supported on
704a3114836SGerry Liu 	 * Device, Processor and ThermalZone. Currently we only need to handle
705a3114836SGerry Liu 	 * Device and Processor objects.
706a3114836SGerry Liu 	 */
707a3114836SGerry Liu 	BT_SET(acpinex_object_type_mask, ACPI_TYPE_PROCESSOR);
708a3114836SGerry Liu 	BT_SET(acpinex_object_type_mask, ACPI_TYPE_DEVICE);
709a3114836SGerry Liu }
710a3114836SGerry Liu 
711a3114836SGerry Liu void
acpinex_event_fini(void)712a3114836SGerry Liu acpinex_event_fini(void)
713a3114836SGerry Liu {
714a3114836SGerry Liu 	bzero(acpinex_object_type_mask, sizeof (acpinex_object_type_mask));
715a3114836SGerry Liu }
716